conspire/constitutive/solid/hyperviscoelastic/saint_venant_kirchhoff/
mod.rs1#[cfg(test)]
2mod test;
3
4use super::*;
5
6#[derive(Debug)]
24pub struct SaintVenantKirchhoff<P> {
25 parameters: P,
26}
27
28impl<P> Constitutive<P> for SaintVenantKirchhoff<P>
29where
30 P: Parameters,
31{
32 fn new(parameters: P) -> Self {
33 Self { parameters }
34 }
35}
36
37impl<P> Solid for SaintVenantKirchhoff<P>
38where
39 P: Parameters,
40{
41 fn bulk_modulus(&self) -> &Scalar {
42 self.parameters.get(0)
43 }
44 fn shear_modulus(&self) -> &Scalar {
45 self.parameters.get(1)
46 }
47}
48
49impl<P> Viscous for SaintVenantKirchhoff<P>
50where
51 P: Parameters,
52{
53 fn bulk_viscosity(&self) -> &Scalar {
54 self.parameters.get(2)
55 }
56 fn shear_viscosity(&self) -> &Scalar {
57 self.parameters.get(3)
58 }
59}
60
61impl<P> Viscoelastic for SaintVenantKirchhoff<P>
62where
63 P: Parameters,
64{
65 fn second_piola_kirchhoff_stress(
71 &self,
72 deformation_gradient: &DeformationGradient,
73 deformation_gradient_rate: &DeformationGradientRate,
74 ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
75 let _jacobian = self.jacobian(deformation_gradient)?;
76 let (deviatoric_strain, strain_trace) =
77 ((deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5)
78 .deviatoric_and_trace();
79 let first_term = deformation_gradient_rate.transpose() * deformation_gradient;
80 let (deviatoric_strain_rate, strain_rate_trace) =
81 ((&first_term + first_term.transpose()) * 0.5).deviatoric_and_trace();
82 Ok(deviatoric_strain * (2.0 * self.shear_modulus())
83 + deviatoric_strain_rate * (2.0 * self.shear_viscosity())
84 + IDENTITY_00
85 * (self.bulk_modulus() * strain_trace + self.bulk_viscosity() * strain_rate_trace))
86 }
87 fn second_piola_kirchhoff_rate_tangent_stiffness(
93 &self,
94 deformation_gradient: &DeformationGradient,
95 _: &DeformationGradientRate,
96 ) -> Result<SecondPiolaKirchhoffRateTangentStiffness, ConstitutiveError> {
97 let _jacobian = self.jacobian(deformation_gradient)?;
98 let scaled_deformation_gradient_transpose =
99 deformation_gradient.transpose() * self.shear_viscosity();
100 Ok(SecondPiolaKirchhoffRateTangentStiffness::dyad_ik_jl(
101 &scaled_deformation_gradient_transpose,
102 &IDENTITY_00,
103 ) + SecondPiolaKirchhoffRateTangentStiffness::dyad_il_jk(
104 &IDENTITY_00,
105 &scaled_deformation_gradient_transpose,
106 ) + SecondPiolaKirchhoffRateTangentStiffness::dyad_ij_kl(
107 &(IDENTITY_00 * (self.bulk_viscosity() - TWO_THIRDS * self.shear_viscosity())),
108 deformation_gradient,
109 ))
110 }
111}
112
113impl<P> ElasticHyperviscous for SaintVenantKirchhoff<P>
114where
115 P: Parameters,
116{
117 fn viscous_dissipation(
123 &self,
124 deformation_gradient: &DeformationGradient,
125 deformation_gradient_rate: &DeformationGradientRate,
126 ) -> Result<Scalar, ConstitutiveError> {
127 let _jacobian = self.jacobian(deformation_gradient)?;
128 let first_term = deformation_gradient_rate.transpose() * deformation_gradient;
129 let strain_rate = (&first_term + first_term.transpose()) * 0.5;
130 Ok(self.shear_viscosity() * strain_rate.squared_trace()
131 + 0.5
132 * (self.bulk_viscosity() - TWO_THIRDS * self.shear_viscosity())
133 * strain_rate.trace().powi(2))
134 }
135}
136
137impl<P> Hyperviscoelastic for SaintVenantKirchhoff<P>
138where
139 P: Parameters,
140{
141 fn helmholtz_free_energy_density(
147 &self,
148 deformation_gradient: &DeformationGradient,
149 ) -> Result<Scalar, ConstitutiveError> {
150 let _jacobian = self.jacobian(deformation_gradient)?;
151 let strain = (deformation_gradient.right_cauchy_green() - IDENTITY_00) * 0.5;
152 Ok(self.shear_modulus() * strain.squared_trace()
153 + 0.5
154 * (self.bulk_modulus() - TWO_THIRDS * self.shear_modulus())
155 * strain.trace().powi(2))
156 }
157}