conspire/constitutive/solid/hyperelastic/gent/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 constitutive::{
6 Constitutive, ConstitutiveError, Parameters,
7 solid::{Solid, TWO_THIRDS, elastic::Elastic, hyperelastic::Hyperelastic},
8 },
9 math::{IDENTITY, Rank2},
10 mechanics::{CauchyStress, CauchyTangentStiffness, Deformation, DeformationGradient, Scalar},
11};
12
13#[doc = include_str!("doc.md")]
14#[derive(Debug)]
15pub struct Gent<P> {
16 parameters: P,
17}
18
19impl<P> Gent<P>
20where
21 P: Parameters,
22{
23 pub fn extensibility(&self) -> &Scalar {
25 self.parameters.get(2)
26 }
27}
28
29impl<P> Constitutive<P> for Gent<P>
30where
31 P: Parameters,
32{
33 fn new(parameters: P) -> Self {
34 Self { parameters }
35 }
36}
37
38impl<P> Solid for Gent<P>
39where
40 P: Parameters,
41{
42 fn bulk_modulus(&self) -> &Scalar {
43 self.parameters.get(0)
44 }
45 fn shear_modulus(&self) -> &Scalar {
46 self.parameters.get(1)
47 }
48}
49
50impl<P> Elastic for Gent<P>
51where
52 P: Parameters,
53{
54 #[doc = include_str!("cauchy_stress.md")]
55 fn cauchy_stress(
56 &self,
57 deformation_gradient: &DeformationGradient,
58 ) -> Result<CauchyStress, ConstitutiveError> {
59 let jacobian = self.jacobian(deformation_gradient)?;
60 let isochoric_left_cauchy_green_deformation =
61 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
62 let (
63 deviatoric_isochoric_left_cauchy_green_deformation,
64 isochoric_left_cauchy_green_deformation_trace,
65 ) = isochoric_left_cauchy_green_deformation.deviatoric_and_trace();
66 let denominator =
67 self.extensibility() - isochoric_left_cauchy_green_deformation_trace + 3.0;
68 if denominator <= 0.0 {
69 Err(ConstitutiveError::Custom(
70 "Maximum extensibility reached.".to_string(),
71 deformation_gradient.clone(),
72 format!("{:?}", &self),
73 ))
74 } else {
75 Ok((deviatoric_isochoric_left_cauchy_green_deformation
76 * self.shear_modulus()
77 * self.extensibility()
78 / jacobian)
79 / denominator
80 + IDENTITY * self.bulk_modulus() * 0.5 * (jacobian - 1.0 / jacobian))
81 }
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 isochoric_left_cauchy_green_deformation =
91 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
92 let (
93 deviatoric_isochoric_left_cauchy_green_deformation,
94 isochoric_left_cauchy_green_deformation_trace,
95 ) = isochoric_left_cauchy_green_deformation.deviatoric_and_trace();
96 let denominator =
97 self.extensibility() - isochoric_left_cauchy_green_deformation_trace + 3.0;
98 if denominator <= 0.0 {
99 Err(ConstitutiveError::Custom(
100 "Maximum extensibility reached.".to_string(),
101 deformation_gradient.clone(),
102 format!("{:?}", &self),
103 ))
104 } else {
105 let prefactor = self.shear_modulus() * self.extensibility() / jacobian / denominator;
106 Ok(
107 (CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, deformation_gradient)
108 + CauchyTangentStiffness::dyad_il_jk(deformation_gradient, &IDENTITY)
109 - CauchyTangentStiffness::dyad_ij_kl(&IDENTITY, deformation_gradient)
110 * (TWO_THIRDS)
111 + CauchyTangentStiffness::dyad_ij_kl(
112 &deviatoric_isochoric_left_cauchy_green_deformation,
113 deformation_gradient,
114 ) * (2.0 / denominator))
115 * (prefactor / jacobian.powf(TWO_THIRDS))
116 + CauchyTangentStiffness::dyad_ij_kl(
117 &(IDENTITY * (0.5 * self.bulk_modulus() * (jacobian + 1.0 / jacobian))
118 - deviatoric_isochoric_left_cauchy_green_deformation
119 * prefactor
120 * ((5.0
121 + 2.0 * isochoric_left_cauchy_green_deformation_trace
122 / denominator)
123 / 3.0)),
124 &inverse_transpose_deformation_gradient,
125 ),
126 )
127 }
128 }
129}
130
131impl<P> Hyperelastic for Gent<P>
132where
133 P: Parameters,
134{
135 #[doc = include_str!("helmholtz_free_energy_density.md")]
136 fn helmholtz_free_energy_density(
137 &self,
138 deformation_gradient: &DeformationGradient,
139 ) -> Result<Scalar, ConstitutiveError> {
140 let jacobian = self.jacobian(deformation_gradient)?;
141 let factor = (deformation_gradient.left_cauchy_green().trace() / jacobian.powf(TWO_THIRDS)
142 - 3.0)
143 / self.extensibility();
144 if factor >= 1.0 {
145 Err(ConstitutiveError::Custom(
146 "Maximum extensibility reached.".to_string(),
147 deformation_gradient.clone(),
148 format!("{:?}", &self),
149 ))
150 } else {
151 Ok(0.5
152 * (-self.shear_modulus() * self.extensibility() * (1.0 - factor).ln()
153 + self.bulk_modulus() * (0.5 * (jacobian.powi(2) - 1.0) - jacobian.ln())))
154 }
155 }
156}