conspire/constitutive/solid/thermoelastic/almansi_hamel/
mod.rs

1#[cfg(test)]
2mod test;
3
4use super::*;
5
6/// The Almansi-Hamel thermoelastic 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 Almansi-Hamel strain measure is given by $`\mathbf{e}=\tfrac{1}{2}(\mathbf{1}-\mathbf{B}^{-1})`$.
23#[derive(Debug)]
24pub struct AlmansiHamel {
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 AlmansiHamel {
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 AlmansiHamel {
45    /// Calculates and returns the Cauchy stress.
46    ///
47    /// ```math
48    /// \boldsymbol{\sigma}(\mathbf{F}, T) = \frac{2\mu}{J}\,\mathbf{e}' + \frac{\kappa}{J}\,\mathrm{tr}(\mathbf{e})\mathbf{1} - \frac{3\alpha\kappa}{J}(T - T_\mathrm{ref})\mathbf{1}
49    /// ```
50    fn cauchy_stress(
51        &self,
52        deformation_gradient: &DeformationGradient,
53        temperature: &Scalar,
54    ) -> Result<CauchyStress, ConstitutiveError> {
55        let jacobian = self.jacobian(deformation_gradient)?;
56        let inverse_deformation_gradient = deformation_gradient.inverse();
57        let strain = (IDENTITY
58            - inverse_deformation_gradient.transpose() * &inverse_deformation_gradient)
59            * 0.5;
60        let (deviatoric_strain, strain_trace) = strain.deviatoric_and_trace();
61        Ok(deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
62            + IDENTITY
63                * (self.bulk_modulus() / jacobian
64                    * (strain_trace
65                        - 3.0
66                            * self.coefficient_of_thermal_expansion()
67                            * (temperature - self.reference_temperature()))))
68    }
69    /// Calculates and returns the tangent stiffness associated with the Cauchy stress.
70    ///
71    /// ```math
72    /// \mathcal{T}_{ijkL}(\mathbf{F}, T) = \frac{\mu}{J}\left[B_{jk}^{-1}F_{iL}^{-T} + B_{ik}^{-1}F_{jL}^{-T} - \frac{2}{3}\,\delta_{ij}B_{km}^{-1}F_{mL}^{-T} - 2e_{ij}'F_{kL}^{-T}\right] + \frac{\kappa}{J}\left\{\delta_{ij}B_{km}^{-1}F_{mL}^{-T} - \Big[\mathrm{tr}(\mathbf{e}) - 3\alpha(T - T_\mathrm{ref})\Big]\delta_{ij}F_{kL}^{-T}\right\}
73    /// ```
74    fn cauchy_tangent_stiffness(
75        &self,
76        deformation_gradient: &DeformationGradient,
77        temperature: &Scalar,
78    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
79        let jacobian = self.jacobian(deformation_gradient)?;
80        let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
81        let inverse_left_cauchy_green_deformation = &inverse_transpose_deformation_gradient
82            * inverse_transpose_deformation_gradient.transpose();
83        let strain = (IDENTITY - &inverse_left_cauchy_green_deformation) * 0.5;
84        let (deviatoric_strain, strain_trace) = strain.deviatoric_and_trace();
85        Ok((CauchyTangentStiffness::dyad_il_jk(
86            &inverse_transpose_deformation_gradient,
87            &inverse_left_cauchy_green_deformation,
88        ) + CauchyTangentStiffness::dyad_ik_jl(
89            &inverse_left_cauchy_green_deformation,
90            &inverse_transpose_deformation_gradient,
91        )) * (self.shear_modulus() / jacobian)
92            + CauchyTangentStiffness::dyad_ij_kl(
93                &IDENTITY,
94                &(inverse_left_cauchy_green_deformation
95                    * &inverse_transpose_deformation_gradient
96                    * ((self.bulk_modulus() - self.shear_modulus() * TWO_THIRDS) / jacobian)),
97            )
98            - CauchyTangentStiffness::dyad_ij_kl(
99                &(deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
100                    + IDENTITY
101                        * (self.bulk_modulus() / jacobian
102                            * (strain_trace
103                                - 3.0
104                                    * self.coefficient_of_thermal_expansion()
105                                    * (temperature - self.reference_temperature())))),
106                &inverse_transpose_deformation_gradient,
107            ))
108    }
109    fn coefficient_of_thermal_expansion(&self) -> &Scalar {
110        &self.coefficient_of_thermal_expansion
111    }
112    fn reference_temperature(&self) -> &Scalar {
113        &self.reference_temperature
114    }
115}