Skip to main content

conspire/constitutive/diffusion/
mod.rs

1//! Diffusion constitutive models.
2
3use std::fmt::Debug;
4
5use crate::{
6    constitutive::ConstitutiveError,
7    math::{Quantity, Reference, TensorRank1, TensorRank1List, TensorRank2, TensorRank2List},
8    units::{
9        Capacitance, CapacitancePerArea, CapacitancePerVolume, Charge, ChargeDensity,
10        Concentration, ConcentrationPerLength, Conductance, ConductancePerArea,
11        ConductancePerVolume, Current, CurrentDensity, CurrentPerVolume, Diffusivity,
12        ElectricDisplacement, ElectricField, ElectricPotential, ElectricalConductivity, Energy,
13        EnergyDensity, MolarFlowRate, MolarFlowRateConcentration,
14        MolarFlowRateConcentrationDensity, MolarFlux, MolarFluxPerLength, Permittivity, Power,
15        PowerDensity, PowerPerArea, PowerPerAreaTemperature, PowerPerLengthTemperature,
16        PowerPerTemperature, PowerPerVolumeTemperature, PowerTemperature, PowerTemperatureDensity,
17        Rate, ReciprocalLength, Temperature, TemperaturePerLength, Unit, UnitMul, Velocity, Volume,
18        VolumetricFlowRate,
19    },
20};
21
22/// A balance law, named by the unit of its residual, and the units that follow.
23pub trait Diffusive
24where
25    Self: Unit,
26{
27    /// The unit of the field whose gradient drives the flux.
28    type Field: Unit;
29    /// The unit of the gradient of the field.
30    type Gradient: Unit;
31    /// The unit of the flux.
32    type Flux: Unit + UnitMul<ReciprocalLength, Output = Self::FluxPerLength>;
33    /// The unit of the flux per length.
34    type FluxPerLength: Unit + UnitMul<Volume, Output = Self>;
35    /// The unit of the tangent of the flux.
36    type Tangent: Unit + UnitMul<ReciprocalLength, Output = Self::TangentPerLength>;
37    /// The unit of the tangent per length.
38    type TangentPerLength: Unit + UnitMul<ReciprocalLength, Output = Self::TangentPerArea>;
39    /// The unit of the tangent per area.
40    type TangentPerArea: Unit + UnitMul<Volume, Output = Self::Stiffness>;
41    /// The unit of the energy density.
42    type EnergyDensity: Unit + UnitMul<Volume, Output = Self::Energy>;
43    /// The unit of the energy.
44    type Energy: Unit;
45    /// The unit of the nodal stiffness.
46    type Stiffness: Unit;
47}
48
49impl Diffusive for Power {
50    type Field = Temperature;
51    type Gradient = TemperaturePerLength;
52    type Flux = PowerPerArea;
53    type FluxPerLength = PowerDensity;
54    type Tangent = PowerPerLengthTemperature;
55    type TangentPerLength = PowerPerAreaTemperature;
56    type TangentPerArea = PowerPerVolumeTemperature;
57    type EnergyDensity = PowerTemperatureDensity;
58    type Energy = PowerTemperature;
59    type Stiffness = PowerPerTemperature;
60}
61
62impl Diffusive for MolarFlowRate {
63    type Field = Concentration;
64    type Gradient = ConcentrationPerLength;
65    type Flux = MolarFlux;
66    type FluxPerLength = MolarFluxPerLength;
67    type Tangent = Diffusivity;
68    type TangentPerLength = Velocity;
69    type TangentPerArea = Rate;
70    type EnergyDensity = MolarFlowRateConcentrationDensity;
71    type Energy = MolarFlowRateConcentration;
72    type Stiffness = VolumetricFlowRate;
73}
74
75impl Diffusive for Charge {
76    type Field = ElectricPotential;
77    type Gradient = ElectricField;
78    type Flux = ElectricDisplacement;
79    type FluxPerLength = ChargeDensity;
80    type Tangent = Permittivity;
81    type TangentPerLength = CapacitancePerArea;
82    type TangentPerArea = CapacitancePerVolume;
83    type EnergyDensity = EnergyDensity;
84    type Energy = Energy;
85    type Stiffness = Capacitance;
86}
87
88impl Diffusive for Current {
89    type Field = ElectricPotential;
90    type Gradient = ElectricField;
91    type Flux = CurrentDensity;
92    type FluxPerLength = CurrentPerVolume;
93    type Tangent = ElectricalConductivity;
94    type TangentPerLength = ConductancePerArea;
95    type TangentPerArea = ConductancePerVolume;
96    type EnergyDensity = PowerDensity;
97    type Energy = Power;
98    type Stiffness = Conductance;
99}
100
101/// The gradient of the field.
102pub type DiffusionGradient<C> =
103    TensorRank1<3, Reference, <<C as Diffusion>::Balance as Diffusive>::Gradient>;
104
105/// A list of gradients of the field.
106pub type DiffusionGradients<C, const N: usize> =
107    TensorRank1List<3, Reference, N, <<C as Diffusion>::Balance as Diffusive>::Gradient>;
108
109/// The flux.
110pub type DiffusionFlux<C> =
111    TensorRank1<3, Reference, <<C as Diffusion>::Balance as Diffusive>::Flux>;
112
113/// A list of fluxes.
114pub type DiffusionFluxes<C, const N: usize> =
115    TensorRank1List<3, Reference, N, <<C as Diffusion>::Balance as Diffusive>::Flux>;
116
117/// The tangent to the flux.
118pub type DiffusionTangent<C> =
119    TensorRank2<3, Reference, Reference, <<C as Diffusion>::Balance as Diffusive>::Tangent>;
120
121/// A list of tangents to the flux.
122pub type DiffusionTangents<C, const N: usize> =
123    TensorRank2List<3, Reference, Reference, N, <<C as Diffusion>::Balance as Diffusive>::Tangent>;
124
125/// Required methods for diffusion constitutive models.
126///
127/// The flux is $`-\kappa\nabla\phi`$ for a field $`\phi`$, so that the tangent
128/// is negative, and the potential is the energy density whose derivative with
129/// respect to the gradient is the negative flux.
130pub trait Diffusion
131where
132    Self: Clone + Debug,
133{
134    /// The balance law the flux enters.
135    type Balance: Diffusive;
136    /// Calculates and returns the potential.
137    fn potential(
138        &self,
139        gradient: &DiffusionGradient<Self>,
140    ) -> Result<Quantity<<Self::Balance as Diffusive>::EnergyDensity>, ConstitutiveError>;
141    /// Calculates and returns the flux.
142    fn flux(
143        &self,
144        gradient: &DiffusionGradient<Self>,
145    ) -> Result<DiffusionFlux<Self>, ConstitutiveError>;
146    /// Calculates and returns the tangent to the flux.
147    fn tangent(
148        &self,
149        gradient: &DiffusionGradient<Self>,
150    ) -> Result<DiffusionTangent<Self>, ConstitutiveError>;
151}