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

1#[cfg(test)]
2mod test;
3
4use crate::{
5    constitutive::{
6        Constitutive, ConstitutiveError, Parameters,
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!("model.md")]
17#[derive(Debug)]
18pub struct SaintVenantKirchhoff<P> {
19    parameters: P,
20}
21
22impl<P> Constitutive<P> for SaintVenantKirchhoff<P>
23where
24    P: Parameters,
25{
26    fn new(parameters: P) -> Self {
27        Self { parameters }
28    }
29}
30
31impl<P> Solid for SaintVenantKirchhoff<P>
32where
33    P: Parameters,
34{
35    fn bulk_modulus(&self) -> &Scalar {
36        self.parameters.get(0)
37    }
38    fn shear_modulus(&self) -> &Scalar {
39        self.parameters.get(1)
40    }
41}
42
43impl<P> Elastic for SaintVenantKirchhoff<P>
44where
45    P: Parameters,
46{
47    #[doc = include_str!("second_piola_kirchhoff_stress.md")]
48    fn second_piola_kirchhoff_stress(
49        &self,
50        deformation_gradient: &DeformationGradient,
51    ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
52        let _jacobian = self.jacobian(deformation_gradient)?;
53        let (deviatoric_strain, strain_trace) =
54            ((deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5)
55                .deviatoric_and_trace();
56        Ok(deviatoric_strain * (2.0 * self.shear_modulus())
57            + IDENTITY_00 * (self.bulk_modulus() * strain_trace))
58    }
59    #[doc = include_str!("second_piola_kirchhoff_tangent_stiffness.md")]
60    fn second_piola_kirchhoff_tangent_stiffness(
61        &self,
62        deformation_gradient: &DeformationGradient,
63    ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
64        let _jacobian = self.jacobian(deformation_gradient)?;
65        let scaled_deformation_gradient_transpose =
66            deformation_gradient.transpose() * self.shear_modulus();
67        Ok(SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
68            &scaled_deformation_gradient_transpose,
69            &IDENTITY_00,
70        ) + SecondPiolaKirchhoffTangentStiffness::dyad_il_jk(
71            &IDENTITY_00,
72            &scaled_deformation_gradient_transpose,
73        ) + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
74            &(IDENTITY_00 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())),
75            deformation_gradient,
76        ))
77    }
78}
79
80impl<P> Hyperelastic for SaintVenantKirchhoff<P>
81where
82    P: Parameters,
83{
84    #[doc = include_str!("helmholtz_free_energy_density.md")]
85    fn helmholtz_free_energy_density(
86        &self,
87        deformation_gradient: &DeformationGradient,
88    ) -> Result<Scalar, ConstitutiveError> {
89        let _jacobian = self.jacobian(deformation_gradient)?;
90        let strain = (deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5;
91        Ok(self.shear_modulus() * strain.squared_trace()
92            + 0.5
93                * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())
94                * strain.trace().powi(2))
95    }
96}