conspire/constitutive/solid/hyperelastic/gent/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 constitutive::{
6 ConstitutiveError,
7 solid::{Solid, TWO_THIRDS, elastic::Elastic, hyperelastic::Hyperelastic},
8 },
9 math::{IDENTITY, Quantity, Rank2, TensorRank4},
10 mechanics::{CauchyStress, CauchyTangentStiffness, Deformation, DeformationGradient, Scalar},
11 units::{EnergyDensity, Stress},
12};
13
14#[doc = include_str!("doc.md")]
15#[derive(Clone, Debug)]
16pub struct Gent {
17 pub bulk_modulus: Quantity<Stress>,
19 pub shear_modulus: Quantity<Stress>,
21 pub extensibility: Scalar,
23}
24
25impl Gent {
26 pub fn extensibility(&self) -> Scalar {
28 self.extensibility
29 }
30}
31
32impl Solid for Gent {
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 Gent {
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 let (
51 deviatoric_isochoric_left_cauchy_green_deformation,
52 isochoric_left_cauchy_green_deformation_trace,
53 ) = isochoric_left_cauchy_green_deformation.deviatoric_and_trace();
54 let denominator =
55 self.extensibility() - isochoric_left_cauchy_green_deformation_trace + 3.0;
56 if denominator <= 0.0 {
57 Err(ConstitutiveError::custom(
58 "Maximum extensibility reached.",
59 self,
60 ))
61 } else {
62 Ok((deviatoric_isochoric_left_cauchy_green_deformation
63 * self.shear_modulus()
64 * self.extensibility()
65 / jacobian)
66 / denominator
67 + IDENTITY * self.bulk_modulus() * 0.5 * (jacobian - 1.0 / jacobian))
68 }
69 }
70 #[doc = include_str!("cauchy_tangent_stiffness.md")]
71 fn cauchy_tangent_stiffness(
72 &self,
73 deformation_gradient: &DeformationGradient,
74 ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
75 let jacobian = self.jacobian(deformation_gradient)?;
76 let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
77 let isochoric_left_cauchy_green_deformation =
78 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
79 let (
80 deviatoric_isochoric_left_cauchy_green_deformation,
81 isochoric_left_cauchy_green_deformation_trace,
82 ) = isochoric_left_cauchy_green_deformation.deviatoric_and_trace();
83 let denominator =
84 self.extensibility() - isochoric_left_cauchy_green_deformation_trace + 3.0;
85 if denominator <= 0.0 {
86 Err(ConstitutiveError::custom(
87 "Maximum extensibility reached.",
88 self,
89 ))
90 } else {
91 let prefactor = self.shear_modulus() * self.extensibility() / jacobian / denominator;
92 Ok((TensorRank4::dyad_ik_jl(&IDENTITY, deformation_gradient)
93 + TensorRank4::dyad_il_jk(deformation_gradient, &IDENTITY)
94 - TensorRank4::dyad_ij_kl(&IDENTITY, deformation_gradient) * (TWO_THIRDS)
95 + TensorRank4::dyad_ij_kl(
96 &deviatoric_isochoric_left_cauchy_green_deformation,
97 deformation_gradient,
98 ) * (2.0 / denominator))
99 * (prefactor / jacobian.powf(TWO_THIRDS))
100 + TensorRank4::dyad_ij_kl(
101 &(IDENTITY * (0.5 * self.bulk_modulus() * (jacobian + 1.0 / jacobian))
102 - deviatoric_isochoric_left_cauchy_green_deformation
103 * prefactor
104 * ((5.0
105 + 2.0 * isochoric_left_cauchy_green_deformation_trace
106 / denominator)
107 / 3.0)),
108 &inverse_transpose_deformation_gradient,
109 ))
110 }
111 }
112}
113
114impl Hyperelastic for Gent {
115 #[doc = include_str!("helmholtz_free_energy_density.md")]
116 fn helmholtz_free_energy_density(
117 &self,
118 deformation_gradient: &DeformationGradient,
119 ) -> Result<Quantity<EnergyDensity>, ConstitutiveError> {
120 let jacobian = self.jacobian(deformation_gradient)?;
121 let factor = (deformation_gradient.left_cauchy_green().trace() / jacobian.powf(TWO_THIRDS)
122 - 3.0)
123 / self.extensibility();
124 if factor >= 1.0 {
125 Err(ConstitutiveError::custom(
126 "Maximum extensibility reached.",
127 self,
128 ))
129 } else {
130 Ok(0.5
131 * (-self.shear_modulus() * self.extensibility() * (1.0 - factor).ln()
132 + self.bulk_modulus() * (0.5 * (jacobian.powi(2) - 1.0) - jacobian.ln())))
133 }
134 }
135}