Skip to main content

conspire/constitutive/solid/thermoelastic/
mod.rs

1//! Thermoelastic solid constitutive models.
2//!
3//! ---
4//!
5#![doc = include_str!("doc.md")]
6
7#[cfg(feature = "doc")]
8pub mod doc;
9
10#[cfg(test)]
11pub mod test;
12
13use super::*;
14use crate::{
15    math::Quantity,
16    units::{ReciprocalTemperature, Temperature},
17};
18
19mod almansi_hamel;
20
21pub use almansi_hamel::AlmansiHamel;
22
23/// Required methods for thermoelastic solid constitutive models.
24pub trait Thermoelastic
25where
26    Self: Solid,
27{
28    /// Calculates and returns the Cauchy stress.
29    ///
30    /// ```math
31    /// \boldsymbol{\sigma} = J^{-1}\mathbf{P}\cdot\mathbf{F}^T
32    /// ```
33    fn cauchy_stress(
34        &self,
35        deformation_gradient: &DeformationGradient,
36        temperature: Quantity<Temperature>,
37    ) -> Result<CauchyStress, ConstitutiveError> {
38        Ok(deformation_gradient
39            * self.second_piola_kirchhoff_stress(deformation_gradient, temperature)?
40            * deformation_gradient.transpose()
41            / deformation_gradient.determinant())
42    }
43    /// Calculates and returns the tangent stiffness associated with the Cauchy stress.
44    ///
45    /// ```math
46    /// \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}
47    /// ```
48    fn cauchy_tangent_stiffness(
49        &self,
50        deformation_gradient: &DeformationGradient,
51        temperature: Quantity<Temperature>,
52    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
53        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
54        let cauchy_stress = self.cauchy_stress(deformation_gradient, temperature)?;
55        let some_stress = &cauchy_stress * &deformation_gradient_inverse_transpose;
56        Ok(self
57            .second_piola_kirchhoff_tangent_stiffness(deformation_gradient, temperature)?
58            .contract_first_second_with_second(deformation_gradient, deformation_gradient)
59            / deformation_gradient.determinant()
60            - CauchyTangentStiffness::dyad_ij_kl(
61                &cauchy_stress,
62                &deformation_gradient_inverse_transpose,
63            )
64            + CauchyTangentStiffness::dyad_il_kj(&some_stress, &IDENTITY)
65            + CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, &some_stress))
66    }
67    /// Calculates and returns the first Piola-Kirchhoff stress.
68    ///
69    /// ```math
70    /// \mathbf{P} = J\boldsymbol{\sigma}\cdot\mathbf{F}^{-T}
71    /// ```
72    fn first_piola_kirchhoff_stress(
73        &self,
74        deformation_gradient: &DeformationGradient,
75        temperature: Quantity<Temperature>,
76    ) -> Result<FirstPiolaKirchhoffStress, ConstitutiveError> {
77        Ok(self.cauchy_stress(deformation_gradient, temperature)?
78            * deformation_gradient.inverse_transpose()
79            * deformation_gradient.determinant())
80    }
81    /// Calculates and returns the tangent stiffness associated with the first Piola-Kirchhoff stress.
82    ///
83    /// ```math
84    /// \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}
85    /// ```
86    fn first_piola_kirchhoff_tangent_stiffness(
87        &self,
88        deformation_gradient: &DeformationGradient,
89        temperature: Quantity<Temperature>,
90    ) -> Result<FirstPiolaKirchhoffTangentStiffness, ConstitutiveError> {
91        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
92        let first_piola_kirchhoff_stress =
93            self.first_piola_kirchhoff_stress(deformation_gradient, temperature)?;
94        Ok(self
95            .cauchy_tangent_stiffness(deformation_gradient, temperature)?
96            .contract_second_with_first(&deformation_gradient_inverse_transpose)
97            * deformation_gradient.determinant()
98            + FirstPiolaKirchhoffTangentStiffness::dyad_ij_kl(
99                &first_piola_kirchhoff_stress,
100                &deformation_gradient_inverse_transpose,
101            )
102            - FirstPiolaKirchhoffTangentStiffness::dyad_il_kj(
103                &first_piola_kirchhoff_stress,
104                &deformation_gradient_inverse_transpose,
105            ))
106    }
107    /// Calculates and returns the second Piola-Kirchhoff stress.
108    ///
109    /// ```math
110    /// \mathbf{S} = \mathbf{F}^{-1}\cdot\mathbf{P}
111    /// ```
112    fn second_piola_kirchhoff_stress(
113        &self,
114        deformation_gradient: &DeformationGradient,
115        temperature: Quantity<Temperature>,
116    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
117        Ok(deformation_gradient.inverse()
118            * self.cauchy_stress(deformation_gradient, temperature)?
119            * deformation_gradient.inverse_transpose()
120            * deformation_gradient.determinant())
121    }
122    /// Calculates and returns the tangent stiffness associated with the second Piola-Kirchhoff stress.
123    ///
124    /// ```math
125    /// \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}
126    /// ```
127    fn second_piola_kirchhoff_tangent_stiffness(
128        &self,
129        deformation_gradient: &DeformationGradient,
130        temperature: Quantity<Temperature>,
131    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
132        let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
133        let deformation_gradient_inverse = deformation_gradient_inverse_transpose.transpose();
134        let second_piola_kirchhoff_stress =
135            self.second_piola_kirchhoff_stress(deformation_gradient, temperature)?;
136        Ok(self
137            .cauchy_tangent_stiffness(deformation_gradient, temperature)?
138            .contract_first_second_with_second(
139                &deformation_gradient_inverse,
140                &deformation_gradient_inverse,
141            )
142            * deformation_gradient.determinant()
143            + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
144                &second_piola_kirchhoff_stress,
145                &deformation_gradient_inverse_transpose,
146            )
147            - SecondPiolaKirchhoffTangentStiffness::dyad_il_kj(
148                &second_piola_kirchhoff_stress,
149                &deformation_gradient_inverse_transpose,
150            )
151            - SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
152                &deformation_gradient_inverse,
153                &second_piola_kirchhoff_stress,
154            ))
155    }
156    /// Returns the coefficient of thermal expansion.
157    fn coefficient_of_thermal_expansion(&self) -> Quantity<ReciprocalTemperature>;
158    /// Returns the reference temperature.
159    fn reference_temperature(&self) -> Quantity<Temperature>;
160}