conspire/constitutive/solid/elastic_hyperviscous/almansi_hamel/
mod.rs1#[cfg(test)]
2mod test;
3
4use super::*;
5
6#[derive(Debug)]
24pub struct AlmansiHamel<P> {
25 parameters: P,
26}
27
28impl<P> Constitutive<P> for AlmansiHamel<P>
29where
30 P: Parameters,
31{
32 fn new(parameters: P) -> Self {
33 Self { parameters }
34 }
35}
36
37impl<P> Solid for AlmansiHamel<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 AlmansiHamel<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 AlmansiHamel<P>
62where
63 P: Parameters,
64{
65 fn cauchy_stress(
71 &self,
72 deformation_gradient: &DeformationGradient,
73 deformation_gradient_rate: &DeformationGradientRate,
74 ) -> Result<CauchyStress, ConstitutiveError> {
75 let jacobian = self.jacobian(deformation_gradient)?;
76 let inverse_deformation_gradient = deformation_gradient.inverse();
77 let strain = (IDENTITY
78 - inverse_deformation_gradient.transpose() * &inverse_deformation_gradient)
79 * 0.5;
80 let (deviatoric_strain, strain_trace) = strain.deviatoric_and_trace();
81 let velocity_gradient = deformation_gradient_rate * inverse_deformation_gradient;
82 let strain_rate = (&velocity_gradient + velocity_gradient.transpose()) * 0.5;
83 let (deviatoric_strain_rate, strain_rate_trace) = strain_rate.deviatoric_and_trace();
84 Ok(deviatoric_strain * (2.0 * self.shear_modulus() / jacobian)
85 + deviatoric_strain_rate * (2.0 * self.shear_viscosity() / jacobian)
86 + IDENTITY
87 * ((self.bulk_modulus() * strain_trace
88 + self.bulk_viscosity() * strain_rate_trace)
89 / jacobian))
90 }
91 fn cauchy_rate_tangent_stiffness(
97 &self,
98 deformation_gradient: &DeformationGradient,
99 _: &DeformationGradientRate,
100 ) -> Result<CauchyRateTangentStiffness, ConstitutiveError> {
101 let jacobian = self.jacobian(deformation_gradient)?;
102 let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
103 let scaled_deformation_gradient_inverse_transpose =
104 &deformation_gradient_inverse_transpose * self.shear_viscosity() / jacobian;
105 Ok(CauchyRateTangentStiffness::dyad_ik_jl(
106 &IDENTITY,
107 &scaled_deformation_gradient_inverse_transpose,
108 ) + CauchyRateTangentStiffness::dyad_il_jk(
109 &scaled_deformation_gradient_inverse_transpose,
110 &IDENTITY,
111 ) + CauchyRateTangentStiffness::dyad_ij_kl(
112 &(IDENTITY
113 * ((self.bulk_viscosity() - TWO_THIRDS * self.shear_viscosity()) / jacobian)),
114 &deformation_gradient_inverse_transpose,
115 ))
116 }
117}
118
119impl<P> ElasticHyperviscous for AlmansiHamel<P>
120where
121 P: Parameters,
122{
123 fn viscous_dissipation(
129 &self,
130 deformation_gradient: &DeformationGradient,
131 deformation_gradient_rate: &DeformationGradientRate,
132 ) -> Result<Scalar, ConstitutiveError> {
133 let _jacobian = self.jacobian(deformation_gradient)?;
134 let velocity_gradient = deformation_gradient_rate * deformation_gradient.inverse();
135 let strain_rate = (&velocity_gradient + velocity_gradient.transpose()) * 0.5;
136 Ok(self.shear_viscosity() * strain_rate.squared_trace()
137 + 0.5
138 * (self.bulk_viscosity() - TWO_THIRDS * self.shear_viscosity())
139 * strain_rate.trace().powi(2))
140 }
141}