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