conspire/constitutive/solid/hyperelastic/mooney_rivlin/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 constitutive::{
6 ConstitutiveError,
7 solid::{FIVE_THIRDS, Solid, TWO_THIRDS, elastic::Elastic, hyperelastic::Hyperelastic},
8 },
9 math::{IDENTITY, Quantity, Rank2, TensorRank4},
10 mechanics::{CauchyStress, CauchyTangentStiffness, Deformation, DeformationGradient},
11 units::{EnergyDensity, Stress},
12};
13
14#[doc = include_str!("doc.md")]
15#[derive(Clone, Debug)]
16pub struct MooneyRivlin {
17 pub bulk_modulus: Quantity<Stress>,
19 pub shear_modulus: Quantity<Stress>,
21 pub extra_modulus: Quantity<Stress>,
23}
24
25impl MooneyRivlin {
26 pub fn extra_modulus(&self) -> Quantity<Stress> {
28 self.extra_modulus
29 }
30}
31
32impl Solid for MooneyRivlin {
33 fn bulk_modulus(&self) -> Quantity<Stress> {
34 self.bulk_modulus
35 }
36 fn shear_modulus(&self) -> Quantity<Stress> {
37 self.shear_modulus
38 }
39}
40
41impl Elastic for MooneyRivlin {
42 #[doc = include_str!("cauchy_stress.md")]
43 fn cauchy_stress(
44 &self,
45 deformation_gradient: &DeformationGradient,
46 ) -> Result<CauchyStress, ConstitutiveError> {
47 let jacobian = self.jacobian(deformation_gradient)?;
48 let isochoric_left_cauchy_green_deformation =
49 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
50 Ok(((isochoric_left_cauchy_green_deformation.deviatoric()
51 * (self.shear_modulus() - self.extra_modulus())
52 - isochoric_left_cauchy_green_deformation
53 .inverse()
54 .deviatoric()
55 * self.extra_modulus())
56 + IDENTITY * (self.bulk_modulus() * 0.5 * (jacobian.powi(2) - 1.0)))
57 / jacobian)
58 }
59 #[doc = include_str!("cauchy_tangent_stiffness.md")]
60 fn cauchy_tangent_stiffness(
61 &self,
62 deformation_gradient: &DeformationGradient,
63 ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
64 let jacobian = self.jacobian(deformation_gradient)?;
65 let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
66 let scaled_delta_shear_modulus =
67 (self.shear_modulus() - self.extra_modulus()) / jacobian.powf(FIVE_THIRDS);
68 let inverse_isochoric_left_cauchy_green_deformation =
69 (deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS)).inverse();
70 let deviatoric_inverse_isochoric_left_cauchy_green_deformation =
71 inverse_isochoric_left_cauchy_green_deformation.deviatoric();
72 let term_1 = TensorRank4::dyad_ij_kl(
73 &inverse_isochoric_left_cauchy_green_deformation,
74 &inverse_transpose_deformation_gradient,
75 ) * TWO_THIRDS
76 - TensorRank4::dyad_ik_jl(
77 &inverse_isochoric_left_cauchy_green_deformation,
78 &inverse_transpose_deformation_gradient,
79 )
80 - TensorRank4::dyad_il_jk(
81 &inverse_transpose_deformation_gradient,
82 &inverse_isochoric_left_cauchy_green_deformation,
83 );
84 let term_3 = TensorRank4::dyad_ij_kl(
85 &deviatoric_inverse_isochoric_left_cauchy_green_deformation,
86 &inverse_transpose_deformation_gradient,
87 );
88 let term_2 = TensorRank4::dyad_ij_kl(
89 &IDENTITY,
90 &((deviatoric_inverse_isochoric_left_cauchy_green_deformation * TWO_THIRDS)
91 * &inverse_transpose_deformation_gradient),
92 );
93 Ok((TensorRank4::dyad_ik_jl(&IDENTITY, deformation_gradient)
94 + TensorRank4::dyad_il_jk(deformation_gradient, &IDENTITY)
95 - TensorRank4::dyad_ij_kl(&IDENTITY, deformation_gradient) * (TWO_THIRDS))
96 * scaled_delta_shear_modulus
97 + TensorRank4::dyad_ij_kl(
98 &(IDENTITY * (0.5 * self.bulk_modulus() * (jacobian + 1.0 / jacobian))
99 - deformation_gradient.left_cauchy_green().deviatoric()
100 * (scaled_delta_shear_modulus * FIVE_THIRDS)),
101 &inverse_transpose_deformation_gradient,
102 )
103 - (term_1 + term_2 - term_3) * self.extra_modulus() / jacobian)
104 }
105}
106
107impl Hyperelastic for MooneyRivlin {
108 #[doc = include_str!("helmholtz_free_energy_density.md")]
109 fn helmholtz_free_energy_density(
110 &self,
111 deformation_gradient: &DeformationGradient,
112 ) -> Result<Quantity<EnergyDensity>, ConstitutiveError> {
113 let jacobian = self.jacobian(deformation_gradient)?;
114 let isochoric_left_cauchy_green_deformation =
115 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
116 Ok(0.5
117 * ((self.shear_modulus() - self.extra_modulus())
118 * (isochoric_left_cauchy_green_deformation.trace() - 3.0)
119 + self.extra_modulus()
120 * (isochoric_left_cauchy_green_deformation.second_invariant() - 3.0)
121 + self.bulk_modulus() * (0.5 * (jacobian.powi(2) - 1.0) - jacobian.ln())))
122 }
123}