conspire/constitutive/solid/hyperelastic/hencky/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        Constitutive, ConstitutiveError,
7        solid::{Solid, TWO_THIRDS, elastic::Elastic, hyperelastic::Hyperelastic},
8    },
9    math::{ContractThirdFourthIndicesWithFirstSecondIndicesOf, IDENTITY, Rank2},
10    mechanics::{CauchyStress, CauchyTangentStiffness, Deformation, DeformationGradient, Scalar},
11};
12
13#[doc = include_str!("doc.md")]
14#[derive(Debug)]
15pub struct Hencky {
16    pub bulk_modulus: Scalar,
18    pub shear_modulus: Scalar,
20}
21
22impl Solid for Hencky {
23    fn bulk_modulus(&self) -> &Scalar {
24        &self.bulk_modulus
25    }
26    fn shear_modulus(&self) -> &Scalar {
27        &self.shear_modulus
28    }
29}
30
31impl Elastic for Hencky {
32    #[doc = include_str!("cauchy_stress.md")]
33    fn cauchy_stress(
34        &self,
35        deformation_gradient: &DeformationGradient,
36    ) -> Result<CauchyStress, ConstitutiveError> {
37        let jacobian = self.jacobian(deformation_gradient)?;
38        let (deviatoric_strain, strain_trace) =
39            (deformation_gradient.left_cauchy_green().logm() * 0.5).deviatoric_and_trace();
40        Ok(deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
41            + IDENTITY * (self.bulk_modulus() * strain_trace / jacobian))
42    }
43    #[doc = include_str!("cauchy_tangent_stiffness.md")]
44    fn cauchy_tangent_stiffness(
45        &self,
46        deformation_gradient: &DeformationGradient,
47    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
48        let jacobian = self.jacobian(deformation_gradient)?;
49        let left_cauchy_green = deformation_gradient.left_cauchy_green();
50        let (deviatoric_strain, strain_trace) =
51            (left_cauchy_green.logm() * 0.5).deviatoric_and_trace();
52        let scaled_deformation_gradient = deformation_gradient * self.shear_modulus() / jacobian;
53        Ok((left_cauchy_green
54            .dlogm()
55            .contract_third_fourth_indices_with_first_second_indices_of(
56                &(CauchyTangentStiffness::dyad_il_jk(&scaled_deformation_gradient, &IDENTITY)
57                    + CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, &scaled_deformation_gradient)),
58            ))
59            + (CauchyTangentStiffness::dyad_ij_kl(
60                &(IDENTITY
61                    * ((self.bulk_modulus() - TWO_THIRDS * self.shear_modulus()) / jacobian)
62                    - deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
63                    - IDENTITY * (self.bulk_modulus() * strain_trace / jacobian)),
64                &deformation_gradient.inverse_transpose(),
65            )))
66    }
67}
68
69impl Hyperelastic for Hencky {
70    #[doc = include_str!("helmholtz_free_energy_density.md")]
71    fn helmholtz_free_energy_density(
72        &self,
73        deformation_gradient: &DeformationGradient,
74    ) -> Result<Scalar, ConstitutiveError> {
75        let _jacobian = self.jacobian(deformation_gradient)?;
76        let strain = deformation_gradient.left_cauchy_green().logm() * 0.5;
77        Ok(self.shear_modulus() * strain.squared_trace()
78            + 0.5
79                * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())
80                * strain.trace().powi(2))
81    }
82}