conspire/constitutive/solid/elastic_viscoplastic/almansi_hamel_eulerian/
mod.rs1#[cfg(test)]
2mod test;
3
4use crate::{
5 constitutive::{
6 ConstitutiveError,
7 fluid::{
8 plastic::Plastic,
9 viscoplastic::{
10 Viscoplastic, ViscoplasticEvolution, ViscoplasticStateVariables,
11 default_plastic_evolution,
12 },
13 },
14 solid::{
15 Solid, TWO_THIRDS,
16 elastic_viscoplastic::{ElasticPlasticOrViscoplastic, ElasticViscoplastic},
17 },
18 },
19 math::{IDENTITY, Quantity, Rank2, TensorArray, TensorRank4},
20 mechanics::{
21 CauchyStress, CauchyTangentStiffness, DeformationGradient, DeformationGradientPlastic,
22 MandelStressElastic, Scalar,
23 },
24 units::{Rate, Stress},
25};
26
27#[doc = include_str!("doc.md")]
28#[derive(Clone, Debug)]
29pub struct AlmansiHamelEulerian {
30 pub bulk_modulus: Quantity<Stress>,
32 pub shear_modulus: Quantity<Stress>,
34 pub yield_stress: Quantity<Stress>,
36 pub hardening_slope: Quantity<Stress>,
38 pub rate_sensitivity: Scalar,
40 pub reference_flow_rate: Quantity<Rate>,
42}
43
44impl Solid for AlmansiHamelEulerian {
45 fn bulk_modulus(&self) -> Quantity<Stress> {
46 self.bulk_modulus
47 }
48 fn shear_modulus(&self) -> Quantity<Stress> {
49 self.shear_modulus
50 }
51}
52
53impl Plastic for AlmansiHamelEulerian {
54 fn initial_yield_stress(&self) -> Quantity<Stress> {
55 self.yield_stress
56 }
57 fn hardening_slope(&self) -> Quantity<Stress> {
58 self.hardening_slope
59 }
60}
61
62impl Viscoplastic<Quantity> for AlmansiHamelEulerian {
63 fn initial_state(&self) -> ViscoplasticStateVariables<Quantity> {
64 (DeformationGradientPlastic::identity(), Quantity::default()).into()
65 }
66 fn plastic_evolution(
67 &self,
68 mandel_stress: MandelStressElastic,
69 state_variables: &ViscoplasticStateVariables<Quantity>,
70 ) -> Result<ViscoplasticEvolution<Quantity>, ConstitutiveError> {
71 default_plastic_evolution(self, mandel_stress, state_variables)
72 }
73 fn rate_sensitivity(&self) -> Scalar {
74 self.rate_sensitivity
75 }
76 fn reference_flow_rate(&self) -> Quantity<Rate> {
77 self.reference_flow_rate
78 }
79}
80
81impl ElasticPlasticOrViscoplastic for AlmansiHamelEulerian {
82 #[doc = include_str!("cauchy_stress.md")]
83 fn cauchy_stress(
84 &self,
85 deformation_gradient: &DeformationGradient,
86 deformation_gradient_p: &DeformationGradientPlastic,
87 ) -> Result<CauchyStress, ConstitutiveError> {
88 let jacobian = self.jacobian(deformation_gradient)?;
89 let deformation_gradient_e = deformation_gradient * deformation_gradient_p.inverse();
90 let inverse_deformation_gradient_e = deformation_gradient_e.inverse();
91 let (deviatoric_strain_e, strain_trace_e) = ((IDENTITY
92 - inverse_deformation_gradient_e.transpose() * &inverse_deformation_gradient_e)
93 * 0.5)
94 .deviatoric_and_trace();
95 Ok(
96 deviatoric_strain_e * (2.0 * self.shear_modulus() / jacobian)
97 + IDENTITY * (self.bulk_modulus() * strain_trace_e / jacobian),
98 )
99 }
100 #[doc = include_str!("cauchy_tangent_stiffness.md")]
101 fn cauchy_tangent_stiffness(
102 &self,
103 deformation_gradient: &DeformationGradient,
104 deformation_gradient_p: &DeformationGradientPlastic,
105 ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
106 let jacobian = self.jacobian(deformation_gradient)?;
107 let inverse_transpose_deformation_gradient = deformation_gradient.inverse_transpose();
108 let deformation_gradient_e = deformation_gradient * deformation_gradient_p.inverse();
109 let inverse_transpose_deformation_gradient_e = deformation_gradient_e.inverse_transpose();
110 let inverse_left_cauchy_green_deformation_e = &inverse_transpose_deformation_gradient_e
111 * inverse_transpose_deformation_gradient_e.transpose();
112 let scaled_inverse_left_cauchy_green_deformation_e =
113 &inverse_left_cauchy_green_deformation_e * (self.shear_modulus() / jacobian);
114 let strain_e = (IDENTITY - &inverse_left_cauchy_green_deformation_e) * 0.5;
115 let (deviatoric_strain_e, strain_trace_e) = strain_e.deviatoric_and_trace();
116 Ok((TensorRank4::dyad_il_jk(
117 &inverse_transpose_deformation_gradient,
118 &scaled_inverse_left_cauchy_green_deformation_e,
119 ) + TensorRank4::dyad_ik_jl(
120 &scaled_inverse_left_cauchy_green_deformation_e,
121 &inverse_transpose_deformation_gradient,
122 )) + TensorRank4::dyad_ij_kl(
123 &IDENTITY,
124 &(inverse_left_cauchy_green_deformation_e
125 * &inverse_transpose_deformation_gradient
126 * ((self.bulk_modulus() - self.shear_modulus() * TWO_THIRDS) / jacobian)),
127 ) - TensorRank4::dyad_ij_kl(
128 &(deviatoric_strain_e * (2.0 * self.shear_modulus() / jacobian)
129 + IDENTITY * (self.bulk_modulus() * strain_trace_e / jacobian)),
130 &inverse_transpose_deformation_gradient,
131 ))
132 }
133}
134
135impl ElasticViscoplastic<Quantity> for AlmansiHamelEulerian {}