conspire/constitutive/solid/thermoelastic/
mod.rs

1//! Thermoelastic constitutive models.
2
3#[cfg(test)]
4pub mod test;
5
6mod almansi_hamel;
7
8pub use almansi_hamel::AlmansiHamel;
9
10use super::*;
11
12/// Required methods for thermoelastic constitutive models.
13pub trait Thermoelastic
14where
15    Self: Solid,
16{
17    /// Calculates and returns the Cauchy stress.
18    ///
19    /// ```math
20    /// \boldsymbol{\sigma} = J^{-1}\mathbf{P}\cdot\mathbf{F}^T
21    /// ```
22    fn cauchy_stress(
23        &self,
24        deformation_gradient: &DeformationGradient,
25        temperature: &Scalar,
26    ) -> Result<CauchyStress, ConstitutiveError> {
27        Ok(deformation_gradient
28            * self.second_piola_kirchhoff_stress(deformation_gradient, temperature)?
29            * deformation_gradient.transpose()
30            / deformation_gradient.determinant())
31    }
32    /// Calculates and returns the tangent stiffness associated with the Cauchy stress.
33    ///
34    /// ```math
35    /// \mathcal{T}_{ijkL} = \frac{\partial\sigma_{ij}}{\partial F_{kL}} = J^{-1} \mathcal{G}_{MNkL} F_{iM} F_{jN} - \sigma_{ij} F_{kL}^{-T} + \left(\delta_{jk}\sigma_{is} + \delta_{ik}\sigma_{js}\right)F_{sL}^{-T}
36    /// ```
37    fn cauchy_tangent_stiffness(
38        &self,
39        deformation_gradient: &DeformationGradient,
40        temperature: &Scalar,
41    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
42        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
43        let cauchy_stress = self.cauchy_stress(deformation_gradient, temperature)?;
44        let some_stress = &cauchy_stress * &deformation_gradient_inverse_transpose;
45        Ok(self
46            .second_piola_kirchhoff_tangent_stiffness(deformation_gradient, temperature)?
47            .contract_first_second_indices_with_second_indices_of(
48                deformation_gradient,
49                deformation_gradient,
50            )
51            / deformation_gradient.determinant()
52            - CauchyTangentStiffness::dyad_ij_kl(
53                &cauchy_stress,
54                &deformation_gradient_inverse_transpose,
55            )
56            + CauchyTangentStiffness::dyad_il_kj(&some_stress, &IDENTITY)
57            + CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, &some_stress))
58    }
59    /// Calculates and returns the first Piola-Kirchhoff stress.
60    ///
61    /// ```math
62    /// \mathbf{P} = J\boldsymbol{\sigma}\cdot\mathbf{F}^{-T}
63    /// ```
64    fn first_piola_kirchhoff_stress(
65        &self,
66        deformation_gradient: &DeformationGradient,
67        temperature: &Scalar,
68    ) -> Result<FirstPiolaKirchhoffStress, ConstitutiveError> {
69        Ok(self.cauchy_stress(deformation_gradient, temperature)?
70            * deformation_gradient.inverse_transpose()
71            * deformation_gradient.determinant())
72    }
73    /// Calculates and returns the tangent stiffness associated with the first Piola-Kirchhoff stress.
74    ///
75    /// ```math
76    /// \mathcal{C}_{iJkL} = \frac{\partial P_{iJ}}{\partial F_{kL}} = J \mathcal{T}_{iskL} F_{sJ}^{-T} + P_{iJ} F_{kL}^{-T} - P_{iL} F_{kJ}^{-T}
77    /// ```
78    fn first_piola_kirchhoff_tangent_stiffness(
79        &self,
80        deformation_gradient: &DeformationGradient,
81        temperature: &Scalar,
82    ) -> Result<FirstPiolaKirchhoffTangentStiffness, ConstitutiveError> {
83        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
84        let first_piola_kirchhoff_stress =
85            self.first_piola_kirchhoff_stress(deformation_gradient, temperature)?;
86        Ok(self
87            .cauchy_tangent_stiffness(deformation_gradient, temperature)?
88            .contract_second_index_with_first_index_of(&deformation_gradient_inverse_transpose)
89            * deformation_gradient.determinant()
90            + FirstPiolaKirchhoffTangentStiffness::dyad_ij_kl(
91                &first_piola_kirchhoff_stress,
92                &deformation_gradient_inverse_transpose,
93            )
94            - FirstPiolaKirchhoffTangentStiffness::dyad_il_kj(
95                &first_piola_kirchhoff_stress,
96                &deformation_gradient_inverse_transpose,
97            ))
98    }
99    /// Calculates and returns the second Piola-Kirchhoff stress.
100    ///
101    /// ```math
102    /// \mathbf{S} = \mathbf{F}^{-1}\cdot\mathbf{P}
103    /// ```
104    fn second_piola_kirchhoff_stress(
105        &self,
106        deformation_gradient: &DeformationGradient,
107        temperature: &Scalar,
108    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
109        Ok(deformation_gradient.inverse()
110            * self.cauchy_stress(deformation_gradient, temperature)?
111            * deformation_gradient.inverse_transpose()
112            * deformation_gradient.determinant())
113    }
114    /// Calculates and returns the tangent stiffness associated with the second Piola-Kirchhoff stress.
115    ///
116    /// ```math
117    /// \mathcal{G}_{IJkL} = \frac{\partial S_{IJ}}{\partial F_{kL}} = \mathcal{C}_{mJkL}F_{mI}^{-T} - S_{LJ}F_{kI}^{-T} = J \mathcal{T}_{mnkL} F_{mI}^{-T} F_{nJ}^{-T} + S_{IJ} F_{kL}^{-T} - S_{IL} F_{kJ}^{-T} -S_{LJ} F_{kI}^{-T}
118    /// ```
119    fn second_piola_kirchhoff_tangent_stiffness(
120        &self,
121        deformation_gradient: &DeformationGradient,
122        temperature: &Scalar,
123    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
124        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
125        let deformation_gradient_inverse = deformation_gradient_inverse_transpose.transpose();
126        let second_piola_kirchhoff_stress =
127            self.second_piola_kirchhoff_stress(deformation_gradient, temperature)?;
128        Ok(self
129            .cauchy_tangent_stiffness(deformation_gradient, temperature)?
130            .contract_first_second_indices_with_second_indices_of(
131                &deformation_gradient_inverse,
132                &deformation_gradient_inverse,
133            )
134            * deformation_gradient.determinant()
135            + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
136                &second_piola_kirchhoff_stress,
137                &deformation_gradient_inverse_transpose,
138            )
139            - SecondPiolaKirchhoffTangentStiffness::dyad_il_kj(
140                &second_piola_kirchhoff_stress,
141                &deformation_gradient_inverse_transpose,
142            )
143            - SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
144                &deformation_gradient_inverse,
145                &second_piola_kirchhoff_stress,
146            ))
147    }
148    /// Returns the coefficient of thermal expansion.
149    fn coefficient_of_thermal_expansion(&self) -> &Scalar;
150    /// Returns the reference temperature.
151    fn reference_temperature(&self) -> &Scalar;
152}