conspire/constitutive/solid/elastic_plastic/
mod.rs1use crate::{
4 constitutive::{ConstitutiveError, fluid::plastic::Plastic, solid::Solid},
5 math::{
6 ContractFirstSecondIndicesWithSecondIndicesOf, ContractSecondIndexWithFirstIndexOf,
7 IDENTITY, Rank2,
8 },
9 mechanics::{
10 CauchyStress, CauchyTangentStiffness, DeformationGradient, DeformationGradientPlastic,
11 FirstPiolaKirchhoffStress, FirstPiolaKirchhoffTangentStiffness, Scalar,
12 SecondPiolaKirchhoffStress, SecondPiolaKirchhoffTangentStiffness,
13 },
14};
15
16pub enum AppliedLoad<'a> {
18 UniaxialStress(fn(Scalar) -> Scalar, &'a [Scalar]),
20 }
23
24pub trait ElasticPlasticOrViscoplastic
26where
27 Self: Solid + Plastic,
28{
29 fn cauchy_stress(
35 &self,
36 deformation_gradient: &DeformationGradient,
37 deformation_gradient_p: &DeformationGradientPlastic,
38 ) -> Result<CauchyStress, ConstitutiveError> {
39 Ok(deformation_gradient
40 * self.second_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?
41 * deformation_gradient.transpose()
42 / deformation_gradient.determinant())
43 }
44 fn cauchy_tangent_stiffness(
50 &self,
51 deformation_gradient: &DeformationGradient,
52 deformation_gradient_p: &DeformationGradientPlastic,
53 ) -> Result<CauchyTangentStiffness, ConstitutiveError> {
54 let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
55 let cauchy_stress = self.cauchy_stress(deformation_gradient, deformation_gradient_p)?;
56 let some_stress = &cauchy_stress * &deformation_gradient_inverse_transpose;
57 Ok(self
58 .second_piola_kirchhoff_tangent_stiffness(deformation_gradient, deformation_gradient_p)?
59 .contract_first_second_indices_with_second_indices_of(
60 deformation_gradient,
61 deformation_gradient,
62 )
63 / deformation_gradient.determinant()
64 - CauchyTangentStiffness::dyad_ij_kl(
65 &cauchy_stress,
66 &deformation_gradient_inverse_transpose,
67 )
68 + CauchyTangentStiffness::dyad_il_kj(&some_stress, &IDENTITY)
69 + CauchyTangentStiffness::dyad_ik_jl(&IDENTITY, &some_stress))
70 }
71 fn first_piola_kirchhoff_stress(
77 &self,
78 deformation_gradient: &DeformationGradient,
79 deformation_gradient_p: &DeformationGradientPlastic,
80 ) -> Result<FirstPiolaKirchhoffStress, ConstitutiveError> {
81 Ok(
82 self.cauchy_stress(deformation_gradient, deformation_gradient_p)?
83 * deformation_gradient.inverse_transpose()
84 * deformation_gradient.determinant(),
85 )
86 }
87 fn first_piola_kirchhoff_tangent_stiffness(
93 &self,
94 deformation_gradient: &DeformationGradient,
95 deformation_gradient_p: &DeformationGradientPlastic,
96 ) -> Result<FirstPiolaKirchhoffTangentStiffness, ConstitutiveError> {
97 let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
98 let first_piola_kirchhoff_stress =
99 self.first_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?;
100 Ok(self
101 .cauchy_tangent_stiffness(deformation_gradient, deformation_gradient_p)?
102 .contract_second_index_with_first_index_of(&deformation_gradient_inverse_transpose)
103 * deformation_gradient.determinant()
104 + FirstPiolaKirchhoffTangentStiffness::dyad_ij_kl(
105 &first_piola_kirchhoff_stress,
106 &deformation_gradient_inverse_transpose,
107 )
108 - FirstPiolaKirchhoffTangentStiffness::dyad_il_kj(
109 &first_piola_kirchhoff_stress,
110 &deformation_gradient_inverse_transpose,
111 ))
112 }
113 fn second_piola_kirchhoff_stress(
119 &self,
120 deformation_gradient: &DeformationGradient,
121 deformation_gradient_p: &DeformationGradientPlastic,
122 ) -> Result<SecondPiolaKirchhoffStress, ConstitutiveError> {
123 Ok(deformation_gradient.inverse()
124 * self.first_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?)
125 }
126 fn second_piola_kirchhoff_tangent_stiffness(
132 &self,
133 deformation_gradient: &DeformationGradient,
134 deformation_gradient_p: &DeformationGradientPlastic,
135 ) -> Result<SecondPiolaKirchhoffTangentStiffness, ConstitutiveError> {
136 let deformation_gradient_inverse_transpose = deformation_gradient.inverse_transpose();
137 let deformation_gradient_inverse = deformation_gradient_inverse_transpose.transpose();
138 let second_piola_kirchhoff_stress =
139 self.second_piola_kirchhoff_stress(deformation_gradient, deformation_gradient_p)?;
140 Ok(self
141 .cauchy_tangent_stiffness(deformation_gradient, deformation_gradient_p)?
142 .contract_first_second_indices_with_second_indices_of(
143 &deformation_gradient_inverse,
144 &deformation_gradient_inverse,
145 )
146 * deformation_gradient.determinant()
147 + SecondPiolaKirchhoffTangentStiffness::dyad_ij_kl(
148 &second_piola_kirchhoff_stress,
149 &deformation_gradient_inverse_transpose,
150 )
151 - SecondPiolaKirchhoffTangentStiffness::dyad_il_kj(
152 &second_piola_kirchhoff_stress,
153 &deformation_gradient_inverse_transpose,
154 )
155 - SecondPiolaKirchhoffTangentStiffness::dyad_ik_jl(
156 &deformation_gradient_inverse,
157 &second_piola_kirchhoff_stress,
158 ))
159 }
160}
161
162pub trait ElasticPlastic
164where
165 Self: ElasticPlasticOrViscoplastic,
166{
167}