Skip to main content

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

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