conspire/constitutive/solid/hyperelastic/saint_venant_kirchhoff/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        Constitutive, ConstitutiveError,
7        solid::{Solid, TWO_THIRDS, elastic::Elastic, hyperelastic::Hyperelastic},
8    },
9    math::{IDENTITY_00, Rank2},
10    mechanics::{
11        Deformation, DeformationGradient, Scalar, SecondPiolaKirchhoffStress,
12        SecondPiolaKirchhoffTangentStiffness,
13    },
14};
15
16#[doc = include_str!("doc.md")]
17#[derive(Debug)]
18pub struct SaintVenantKirchhoff {
19    /// The bulk modulus $`\kappa`$.
20    pub bulk_modulus: Scalar,
21    /// The shear modulus $`\mu`$.
22    pub shear_modulus: Scalar,
23}
24
25impl Solid for SaintVenantKirchhoff {
26    fn bulk_modulus(&self) -> &Scalar {
27        &self.bulk_modulus
28    }
29    fn shear_modulus(&self) -> &Scalar {
30        &self.shear_modulus
31    }
32}
33
34impl Elastic for SaintVenantKirchhoff {
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 (deviatoric_strain, strain_trace) =
42            ((deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5)
43                .deviatoric_and_trace();
44        Ok(deviatoric_strain * (2.0 * self.shear_modulus())
45            + IDENTITY_00 * (self.bulk_modulus() * strain_trace))
46    }
47    #[doc = include_str!("second_piola_kirchhoff_tangent_stiffness.md")]
48    fn second_piola_kirchhoff_tangent_stiffness(
49        &self,
50        deformation_gradient: &DeformationGradient,
51    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
52        let _jacobian = self.jacobian(deformation_gradient)?;
53        let scaled_deformation_gradient_transpose =
54            deformation_gradient.transpose() * self.shear_modulus();
55        Ok(SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
56            &scaled_deformation_gradient_transpose,
57            &IDENTITY_00,
58        ) + SecondPiolaKirchhoffTangentStiffness::dyad_il_jk(
59            &IDENTITY_00,
60            &scaled_deformation_gradient_transpose,
61        ) + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
62            &(IDENTITY_00 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())),
63            deformation_gradient,
64        ))
65    }
66}
67
68impl Hyperelastic for SaintVenantKirchhoff {
69    #[doc = include_str!("helmholtz_free_energy_density.md")]
70    fn helmholtz_free_energy_density(
71        &self,
72        deformation_gradient: &DeformationGradient,
73    ) -> Result<Scalar, ConstitutiveError> {
74        let _jacobian = self.jacobian(deformation_gradient)?;
75        let strain = (deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5;
76        Ok(self.shear_modulus() * strain.squared_trace()
77            + 0.5
78                * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())
79                * strain.trace().powi(2))
80    }
81}