conspire/constitutive/solid/thermohyperelastic/saint_venant_kirchhoff/
mod.rs1#[cfg(test)]
2mod test;
3use crate::math::{Quantity, TensorRank4};
4use crate::units::{EnergyDensity, ReciprocalTemperature, Stress, Temperature};
5
6use super::*;
7
8#[doc = include_str!("doc.md")]
9#[derive(Clone, Debug)]
10pub struct SaintVenantKirchhoff {
11 pub bulk_modulus: Quantity<Stress>,
13 pub shear_modulus: Quantity<Stress>,
15 pub coefficient_of_thermal_expansion: Quantity<ReciprocalTemperature>,
17 pub reference_temperature: Quantity<Temperature>,
19}
20
21impl Solid for SaintVenantKirchhoff {
22 fn bulk_modulus(&self) -> Quantity<Stress> {
23 self.bulk_modulus
24 }
25 fn shear_modulus(&self) -> Quantity<Stress> {
26 self.shear_modulus
27 }
28}
29
30impl Thermoelastic for SaintVenantKirchhoff {
31 #[doc = include_str!("second_piola_kirchhoff_stress.md")]
32 fn second_piola_kirchhoff_stress(
33 &self,
34 deformation_gradient: &DeformationGradient,
35 temperature: Quantity<Temperature>,
36 ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
37 let _jacobian = self.jacobian(deformation_gradient)?;
38 let (deviatoric_strain, strain_trace) =
39 ((deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5)
40 .deviatoric_and_trace();
41 Ok(deviatoric_strain * (2.0 * self.shear_modulus())
42 + IDENTITY_00
43 * (self.bulk_modulus()
44 * (strain_trace
45 - 3.0
46 * self.coefficient_of_thermal_expansion()
47 * (temperature - self.reference_temperature()))))
48 }
49 #[doc = include_str!("second_piola_kirchhoff_tangent_stiffness.md")]
50 fn second_piola_kirchhoff_tangent_stiffness(
51 &self,
52 deformation_gradient: &DeformationGradient,
53 _: Quantity<Temperature>,
54 ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
55 let _jacobian = self.jacobian(deformation_gradient)?;
56 let scaled_deformation_gradient_transpose =
57 deformation_gradient.transpose() * self.shear_modulus();
58 Ok(
59 TensorRank4::dyad_ik_jl(&scaled_deformation_gradient_transpose, &IDENTITY_00)
60 + TensorRank4::dyad_il_jk(&IDENTITY_00, &scaled_deformation_gradient_transpose)
61 + TensorRank4::dyad_ij_kl(
62 &(IDENTITY_00 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())),
63 deformation_gradient,
64 ),
65 )
66 }
67 fn coefficient_of_thermal_expansion(&self) -> Quantity<ReciprocalTemperature> {
68 self.coefficient_of_thermal_expansion
69 }
70 fn reference_temperature(&self) -> Quantity<Temperature> {
71 self.reference_temperature
72 }
73}
74
75impl Thermohyperelastic for SaintVenantKirchhoff {
76 #[doc = include_str!("helmholtz_free_energy_density.md")]
77 fn helmholtz_free_energy_density(
78 &self,
79 deformation_gradient: &DeformationGradient,
80 temperature: Quantity<Temperature>,
81 ) -> Result<Quantity<EnergyDensity>, ConstitutiveError> {
82 let _jacobian = self.jacobian(deformation_gradient)?;
83 let strain = (deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5;
84 let strain_trace = strain.trace();
85 Ok(self.shear_modulus() * strain.squared_trace()
86 + 0.5
87 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())
88 * strain_trace.powi(2)
89 - 3.0
90 * self.bulk_modulus()
91 * self.coefficient_of_thermal_expansion()
92 * (temperature - self.reference_temperature())
93 * strain_trace)
94 }
95}