conspire/constitutive/solid/thermohyperelastic/saint_venant_kirchhoff/
mod.rs

1#[cfg(test)]
2mod test;
3
4use super::*;
5
6/// The Saint Venant-Kirchhoff thermohyperelastic constitutive model.
7///
8/// **Parameters**
9/// - The bulk modulus $`\kappa`$.
10/// - The shear modulus $`\mu`$.
11/// - The coefficient of thermal expansion $`\alpha`$.
12/// - The reference temperature $`T_\mathrm{ref}`$.
13///
14/// **External variables**
15/// - The deformation gradient $`\mathbf{F}`$.
16/// - The temperature $`T`$.
17///
18/// **Internal variables**
19/// - None.
20///
21/// **Notes**
22/// - The Green-Saint Venant strain measure is given by $`\mathbf{E}=\tfrac{1}{2}(\mathbf{C}-\mathbf{1})`$.
23#[derive(Debug)]
24pub struct SaintVenantKirchhoff {
25    /// The bulk modulus $`\kappa`$.
26    pub bulk_modulus: Scalar,
27    /// The shear modulus $`\mu`$.
28    pub shear_modulus: Scalar,
29    /// The coefficient of thermal expansion $`\alpha`$.
30    pub coefficient_of_thermal_expansion: Scalar,
31    /// The reference temperature $`T_\mathrm{ref}`$.
32    pub reference_temperature: Scalar,
33}
34
35impl Solid for SaintVenantKirchhoff {
36    fn bulk_modulus(&self) -> &Scalar {
37        &self.bulk_modulus
38    }
39    fn shear_modulus(&self) -> &Scalar {
40        &self.shear_modulus
41    }
42}
43
44impl Thermoelastic for SaintVenantKirchhoff {
45    /// Calculates and returns the second Piola-Kirchhoff stress.
46    ///
47    /// ```math
48    /// \mathbf{S}(\mathbf{F}, T) = 2\mu\mathbf{E}' + \kappa\,\mathrm{tr}(\mathbf{E})\mathbf{1} - 3\alpha\kappa(T - T_\mathrm{ref})\mathbf{1}
49    /// ```
50    fn second_piola_kirchhoff_stress(
51        &self,
52        deformation_gradient: &DeformationGradient,
53        temperature: &Scalar,
54    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
55        let _jacobian = self.jacobian(deformation_gradient)?;
56        let (deviatoric_strain, strain_trace) =
57            ((deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5)
58                .deviatoric_and_trace();
59        Ok(deviatoric_strain * (2.0 * self.shear_modulus())
60            + IDENTITY_00
61                * (self.bulk_modulus()
62                    * (strain_trace
63                        - 3.0
64                            * self.coefficient_of_thermal_expansion()
65                            * (temperature - self.reference_temperature()))))
66    }
67    /// Calculates and returns the tangent stiffness associated with the second Piola-Kirchhoff stress.
68    ///
69    /// ```math
70    /// \mathcal{G}_{IJkL}(\mathbf{F}) = \mu\,\delta_{JL}F_{kI} + \mu\,\delta_{IL}F_{kJ} + \left(\kappa - \frac{2}{3}\,\mu\right)\delta_{IJ}F_{kL}
71    /// ```
72    fn second_piola_kirchhoff_tangent_stiffness(
73        &self,
74        deformation_gradient: &DeformationGradient,
75        _: &Scalar,
76    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
77        let _jacobian = self.jacobian(deformation_gradient)?;
78        let scaled_deformation_gradient_transpose =
79            deformation_gradient.transpose() * self.shear_modulus();
80        Ok(SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
81            &scaled_deformation_gradient_transpose,
82            &IDENTITY_00,
83        ) + SecondPiolaKirchhoffTangentStiffness::dyad_il_jk(
84            &IDENTITY_00,
85            &scaled_deformation_gradient_transpose,
86        ) + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
87            &(IDENTITY_00 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())),
88            deformation_gradient,
89        ))
90    }
91    fn coefficient_of_thermal_expansion(&self) -> &Scalar {
92        &self.coefficient_of_thermal_expansion
93    }
94    fn reference_temperature(&self) -> &Scalar {
95        &self.reference_temperature
96    }
97}
98
99impl Thermohyperelastic for SaintVenantKirchhoff {
100    /// Calculates and returns the Helmholtz free energy density.
101    ///
102    /// ```math
103    /// a(\mathbf{F}, T) = \mu\,\mathrm{tr}(\mathbf{E}^2) + \frac{1}{2}\left(\kappa - \frac{2}{3}\,\mu\right)\mathrm{tr}(\mathbf{E})^2 - 3\alpha\kappa\,\mathrm{tr}(\mathbf{E})(T - T_\mathrm{ref})
104    /// ```
105    fn helmholtz_free_energy_density(
106        &self,
107        deformation_gradient: &DeformationGradient,
108        temperature: &Scalar,
109    ) -> Result<Scalar, ConstitutiveError> {
110        let _jacobian = self.jacobian(deformation_gradient)?;
111        let strain = (deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5;
112        let strain_trace = strain.trace();
113        Ok(self.shear_modulus() * strain.squared_trace()
114            + 0.5
115                * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())
116                * strain_trace.powi(2)
117            - 3.0
118                * self.bulk_modulus()
119                * self.coefficient_of_thermal_expansion()
120                * (temperature - self.reference_temperature())
121                * strain_trace)
122    }
123}