conspire/constitutive/solid/hyperelastic/yeoh/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 constitutive::{
6 Constitutive, ConstitutiveError, Parameters,
7 solid::{FIVE_THIRDS, Solid, TWO_THIRDS, elastic::Elastic, hyperelastic::Hyperelastic},
8 },
9 math::{IDENTITY, Rank2},
10 mechanics::{CauchyStress, CauchyTangentStiffness, Deformation, DeformationGradient, Scalar},
11};
12
13const SEVEN_THIRDS: Scalar = 7.0 / 3.0;
14
15#[doc = include_str!("doc.md")]
16#[derive(Debug)]
17pub struct Yeoh<P> {
18 parameters: P,
19}
20
21impl<P> Yeoh<P>
22where
23 P: Parameters,
24{
25 pub fn moduli(&self) -> &[Scalar] {
27 self.parameters.get_slice(1..)
29 }
30 pub fn extra_moduli(&self) -> &[Scalar] {
32 self.parameters.get_slice(2..)
34 }
35}
36
37impl<P> Constitutive<P> for Yeoh<P>
38where
39 P: Parameters,
40{
41 fn new(parameters: P) -> Self {
42 Self { parameters }
43 }
44}
45
46impl<P> Solid for Yeoh<P>
47where
48 P: Parameters,
49{
50 fn bulk_modulus(&self) -> &Scalar {
51 self.parameters.get(0)
52 }
53 fn shear_modulus(&self) -> &Scalar {
54 self.parameters.get(1)
55 }
56}
57
58impl<P> Elastic for Yeoh<P>
59where
60 P: Parameters,
61{
62 #[doc = include_str!("cauchy_stress.md")]
63 fn cauchy_stress(
64 &self,
65 deformation_gradient: &DeformationGradient,
66 ) -> Result<CauchyStress, ConstitutiveError> {
67 let jacobian = self.jacobian(deformation_gradient)?;
68 let (deviatoric_left_cauchy_green_deformation, left_cauchy_green_deformation_trace) =
69 deformation_gradient
70 .left_cauchy_green()
71 .deviatoric_and_trace();
72 let scalar_term = left_cauchy_green_deformation_trace / jacobian.powf(TWO_THIRDS) - 3.0;
73 Ok(deviatoric_left_cauchy_green_deformation
74 * self
75 .moduli()
76 .iter()
77 .enumerate()
78 .map(|(n, modulus)| ((n as Scalar) + 1.0) * modulus * scalar_term.powi(n as i32))
79 .sum::<Scalar>()
80 / jacobian.powf(FIVE_THIRDS)
81 + IDENTITY * self.bulk_modulus() * 0.5 * (jacobian - 1.0 / jacobian))
82 }
83 #[doc = include_str!("cauchy_tangent_stiffness.md")]
84 fn cauchy_tangent_stiffness(
85 &self,
86 deformation_gradient: &DeformationGradient,
87 ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
88 let jacobian = self.jacobian(deformation_gradient)?;
89 let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
90 let left_cauchy_green_deformation = deformation_gradient.left_cauchy_green();
91 let scalar_term = left_cauchy_green_deformation.trace() / jacobian.powf(TWO_THIRDS) - 3.0;
92 let scaled_modulus = self
93 .moduli()
94 .iter()
95 .enumerate()
96 .map(|(n, modulus)| ((n as Scalar) + 1.0) * modulus * scalar_term.powi(n as i32))
97 .sum::<Scalar>()
98 / jacobian.powf(FIVE_THIRDS);
99 let deviatoric_left_cauchy_green_deformation = left_cauchy_green_deformation.deviatoric();
100 let last_term = CauchyTangentStiffness::dyad_ij_kl(
101 &deviatoric_left_cauchy_green_deformation,
102 &((left_cauchy_green_deformation.deviatoric()
103 * &inverse_transpose_deformation_gradient)
104 * (2.0
105 * self
106 .extra_moduli()
107 .iter()
108 .enumerate()
109 .map(|(n, modulus)| {
110 ((n as Scalar) + 2.0)
111 * ((n as Scalar) + 1.0)
112 * modulus
113 * scalar_term.powi(n as i32)
114 })
115 .sum::<Scalar>()
116 / jacobian.powf(SEVEN_THIRDS))),
117 );
118 Ok(
119 (CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, deformation_gradient)
120 + CauchyTangentStiffness::dyad_il_jk(deformation_gradient, &IDENTITY)
121 - CauchyTangentStiffness::dyad_ij_kl(&IDENTITY, deformation_gradient)
122 * (TWO_THIRDS))
123 * scaled_modulus
124 + CauchyTangentStiffness::dyad_ij_kl(
125 &(IDENTITY * (0.5 * self.bulk_modulus() * (jacobian + 1.0 / jacobian))
126 - deviatoric_left_cauchy_green_deformation
127 * (scaled_modulus * FIVE_THIRDS)),
128 &inverse_transpose_deformation_gradient,
129 )
130 + last_term,
131 )
132 }
133}
134
135impl<P> Hyperelastic for Yeoh<P>
136where
137 P: Parameters,
138{
139 #[doc = include_str!("helmholtz_free_energy_density.md")]
140 fn helmholtz_free_energy_density(
141 &self,
142 deformation_gradient: &DeformationGradient,
143 ) -> Result<Scalar, ConstitutiveError> {
144 let jacobian = self.jacobian(deformation_gradient)?;
145 let scalar_term =
146 deformation_gradient.left_cauchy_green().trace() / jacobian.powf(TWO_THIRDS) - 3.0;
147 Ok(0.5
148 * (self
149 .moduli()
150 .iter()
151 .enumerate()
152 .map(|(n, modulus)| modulus * scalar_term.powi((n + 1) as i32))
153 .sum::<Scalar>()
154 + self.bulk_modulus() * (0.5 * (jacobian.powi(2) - 1.0) - jacobian.ln())))
155 }
156}