conspire/constitutive/solid/hyperelastic/saint_venant_kirchhoff/
mod.rs1#[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}