Skip to main content

conspire/constitutive/solid/elastic/almansi_hamel_eulerian/
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, Quantity, Rank2, TensorRank4},
10    mechanics::{CauchyStress, CauchyTangentStiffness, DeformationGradient},
11    units::Stress,
12};
13
14#[doc = include_str!("doc.md")]
15#[derive(Clone, Debug)]
16pub struct AlmansiHamelEulerian {
17    /// The bulk modulus $`\kappa`$.
18    pub bulk_modulus: Quantity<Stress>,
19    /// The shear modulus $`\mu`$.
20    pub shear_modulus: Quantity<Stress>,
21}
22
23impl Solid for AlmansiHamelEulerian {
24    fn bulk_modulus(&self) -> Quantity<Stress> {
25        self.bulk_modulus
26    }
27    fn shear_modulus(&self) -> Quantity<Stress> {
28        self.shear_modulus
29    }
30}
31
32impl Elastic for AlmansiHamelEulerian {
33    #[doc = include_str!("cauchy_stress.md")]
34    fn cauchy_stress(
35        &self,
36        deformation_gradient: &DeformationGradient,
37    ) -> Result<CauchyStress, ConstitutiveError> {
38        let jacobian = self.jacobian(deformation_gradient)?;
39        let inverse_deformation_gradient = deformation_gradient.inverse();
40        let strain = (IDENTITY
41            - inverse_deformation_gradient.transpose() * &inverse_deformation_gradient)
42            * 0.5;
43        let (deviatoric_strain, strain_trace) = strain.deviatoric_and_trace();
44        Ok(deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
45            + IDENTITY * (self.bulk_modulus() * strain_trace / jacobian))
46    }
47    #[doc = include_str!("cauchy_tangent_stiffness.md")]
48    fn cauchy_tangent_stiffness(
49        &self,
50        deformation_gradient: &DeformationGradient,
51    ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
52        let jacobian = self.jacobian(deformation_gradient)?;
53        let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
54        let inverse_left_cauchy_green_deformation = &inverse_transpose_deformation_gradient
55            * inverse_transpose_deformation_gradient.transpose();
56        let scaled_inverse_left_cauchy_green_deformation =
57            &inverse_left_cauchy_green_deformation * (self.shear_modulus() / jacobian);
58        let strain = (IDENTITY - &inverse_left_cauchy_green_deformation) * 0.5;
59        let (deviatoric_strain, strain_trace) = strain.deviatoric_and_trace();
60        Ok((TensorRank4::dyad_il_jk(
61            &inverse_transpose_deformation_gradient,
62            &scaled_inverse_left_cauchy_green_deformation,
63        ) + TensorRank4::dyad_ik_jl(
64            &scaled_inverse_left_cauchy_green_deformation,
65            &inverse_transpose_deformation_gradient,
66        )) + TensorRank4::dyad_ij_kl(
67            &IDENTITY,
68            &(inverse_left_cauchy_green_deformation
69                * &inverse_transpose_deformation_gradient
70                * ((self.bulk_modulus() - self.shear_modulus() * TWO_THIRDS) / jacobian)),
71        ) - TensorRank4::dyad_ij_kl(
72            &(deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
73                + IDENTITY * (self.bulk_modulus() * strain_trace / jacobian)),
74            &inverse_transpose_deformation_gradient,
75        ))
76    }
77}