Skip to main content

conspire/constitutive/solid/elastic/hencky/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        ConstitutiveError,
7        solid::{Solid, TWO_THIRDS, elastic::Elastic},
8    },
9    math::{ContractThirdFourthWithFirstSecond, IDENTITY_00, Quantity, Rank2, TensorRank4},
10    mechanics::{
11        Deformation, DeformationGradient, SecondPiolaKirchhoffStress,
12        SecondPiolaKirchhoffTangentStiffness,
13    },
14    units::Stress,
15};
16
17#[doc = include_str!("doc.md")]
18#[derive(Clone, Debug)]
19pub struct Hencky {
20    /// The bulk modulus $`\kappa`$.
21    pub bulk_modulus: Quantity<Stress>,
22    /// The shear modulus $`\mu`$.
23    pub shear_modulus: Quantity<Stress>,
24}
25
26impl Solid for Hencky {
27    fn bulk_modulus(&self) -> Quantity<Stress> {
28        self.bulk_modulus
29    }
30    fn shear_modulus(&self) -> Quantity<Stress> {
31        self.shear_modulus
32    }
33}
34
35impl Elastic for Hencky {
36    #[doc = include_str!("second_piola_kirchhoff_stress.md")]
37    fn second_piola_kirchhoff_stress(
38        &self,
39        deformation_gradient: &DeformationGradient,
40    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
41        let _jacobian = self.jacobian(deformation_gradient)?;
42        let (deviatoric_strain, strain_trace) = (deformation_gradient
43            .right_cauchy_green()
44            .logm()
45            .map_err(|error| ConstitutiveError::upstream(error, self))?
46            * 0.5)
47            .deviatoric_and_trace();
48        Ok(deviatoric_strain * (2.0 * self.shear_modulus())
49            + IDENTITY_00 * (self.bulk_modulus() * strain_trace))
50    }
51    #[doc = include_str!("second_piola_kirchhoff_tangent_stiffness.md")]
52    fn second_piola_kirchhoff_tangent_stiffness(
53        &self,
54        deformation_gradient: &DeformationGradient,
55    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
56        let _jacobian = self.jacobian(deformation_gradient)?;
57        let right_cauchy_green = deformation_gradient.right_cauchy_green();
58        let deformation_gradient_transpose = deformation_gradient.transpose();
59        let scaled_deformation_gradient_transpose =
60            &deformation_gradient_transpose * self.shear_modulus();
61        Ok((right_cauchy_green
62            .dlogm()
63            .map_err(|error| ConstitutiveError::upstream(error, self))?
64            .contract_third_fourth_with_first_second(
65                &(TensorRank4::dyad_il_jk(&IDENTITY_00, &scaled_deformation_gradient_transpose)
66                    + TensorRank4::dyad_ik_jl(
67                        &scaled_deformation_gradient_transpose,
68                        &IDENTITY_00,
69                    )),
70            ))
71            + (TensorRank4::dyad_ij_kl(
72                &(IDENTITY_00 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())),
73                &deformation_gradient_transpose.inverse(),
74            )))
75    }
76}