conspire/constitutive/solid/hyperelastic/fung/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 constitutive::{
6 Constitutive, ConstitutiveError,
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
13#[doc = include_str!("doc.md")]
14#[derive(Debug)]
15pub struct Fung {
16 pub bulk_modulus: Scalar,
18 pub shear_modulus: Scalar,
20 pub extra_modulus: Scalar,
22 pub exponent: Scalar,
24}
25
26impl Fung {
27 pub fn extra_modulus(&self) -> &Scalar {
29 &self.extra_modulus
30 }
31 pub fn exponent(&self) -> &Scalar {
33 &self.exponent
34 }
35}
36
37impl Solid for Fung {
38 fn bulk_modulus(&self) -> &Scalar {
39 &self.bulk_modulus
40 }
41 fn shear_modulus(&self) -> &Scalar {
42 &self.shear_modulus
43 }
44}
45
46impl Elastic for Fung {
47 #[doc = include_str!("cauchy_stress.md")]
48 fn cauchy_stress(
49 &self,
50 deformation_gradient: &DeformationGradient,
51 ) -> Result<CauchyStress, ConstitutiveError> {
52 let jacobian = self.jacobian(deformation_gradient)?;
53 let isochoric_left_cauchy_green_deformation =
54 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
55 let (
56 deviatoric_isochoric_left_cauchy_green_deformation,
57 isochoric_left_cauchy_green_deformation_trace,
58 ) = isochoric_left_cauchy_green_deformation.deviatoric_and_trace();
59 Ok(deviatoric_isochoric_left_cauchy_green_deformation
60 * ((self.shear_modulus()
61 + self.extra_modulus()
62 * ((self.exponent() * (isochoric_left_cauchy_green_deformation_trace - 3.0))
63 .exp()
64 - 1.0))
65 / jacobian)
66 + IDENTITY * self.bulk_modulus() * 0.5 * (jacobian - 1.0 / jacobian))
67 }
68 #[doc = include_str!("cauchy_tangent_stiffness.md")]
69 fn cauchy_tangent_stiffness(
70 &self,
71 deformation_gradient: &DeformationGradient,
72 ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
73 let jacobian = self.jacobian(deformation_gradient)?;
74 let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
75 let isochoric_left_cauchy_green_deformation =
76 deformation_gradient.left_cauchy_green() / jacobian.powf(TWO_THIRDS);
77 let (
78 deviatoric_isochoric_left_cauchy_green_deformation,
79 isochoric_left_cauchy_green_deformation_trace,
80 ) = isochoric_left_cauchy_green_deformation.deviatoric_and_trace();
81 let exponential =
82 (self.exponent() * (isochoric_left_cauchy_green_deformation_trace - 3.0)).exp();
83 let scaled_shear_modulus_0 = (self.shear_modulus()
84 + self.extra_modulus() * (exponential - 1.0))
85 / jacobian.powf(FIVE_THIRDS);
86 Ok(
87 (CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, deformation_gradient)
88 + CauchyTangentStiffness::dyad_il_jk(deformation_gradient, &IDENTITY)
89 - CauchyTangentStiffness::dyad_ij_kl(&IDENTITY, deformation_gradient)
90 * (TWO_THIRDS))
91 * scaled_shear_modulus_0
92 + CauchyTangentStiffness::dyad_ij_kl(
93 &deviatoric_isochoric_left_cauchy_green_deformation,
94 &((&deviatoric_isochoric_left_cauchy_green_deformation
95 * &inverse_transpose_deformation_gradient)
96 * (2.0 * self.exponent() * self.extra_modulus() * exponential / jacobian)),
97 )
98 + CauchyTangentStiffness::dyad_ij_kl(
99 &(IDENTITY * (0.5 * self.bulk_modulus() * (jacobian + 1.0 / jacobian))
100 - deformation_gradient.left_cauchy_green().deviatoric()
101 * (scaled_shear_modulus_0 * FIVE_THIRDS)),
102 &inverse_transpose_deformation_gradient,
103 ),
104 )
105 }
106}
107
108impl Hyperelastic for Fung {
109 #[doc = include_str!("helmholtz_free_energy_density.md")]
110 fn helmholtz_free_energy_density(
111 &self,
112 deformation_gradient: &DeformationGradient,
113 ) -> Result<Scalar, ConstitutiveError> {
114 let jacobian = self.jacobian(deformation_gradient)?;
115 let scalar_term =
116 deformation_gradient.left_cauchy_green().trace() / jacobian.powf(TWO_THIRDS) - 3.0;
117 Ok(0.5
118 * ((self.shear_modulus() - self.extra_modulus()) * scalar_term
119 + self.extra_modulus() / self.exponent()
120 * ((self.exponent() * scalar_term).exp() - 1.0)
121 + self.bulk_modulus() * (0.5 * (jacobian.powi(2) - 1.0) - jacobian.ln())))
122 }
123}