1#[cfg(test)]
4pub mod test;
5
6use crate::{
7 defeat_message,
8 math::{
9 Rank2, Tensor, TensorRank0List, TensorRank1, TensorRank1List, TensorRank1List2D,
10 TensorRank2, TensorRank2List, TensorRank2List2D, TensorRank2Vec, TensorRank4,
11 TensorRank4List,
12 },
13};
14use std::fmt::{self, Debug, Display, Formatter};
15
16pub use crate::math::Scalar;
17
18pub enum DeformationError {
20 InvalidJacobian(Scalar, DeformationGradient),
21}
22
23impl Debug for DeformationError {
24 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25 let error = match self {
26 Self::InvalidJacobian(jacobian, deformation_gradient) => {
27 format!(
28 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
29 From deformation gradient: {deformation_gradient}.",
30 )
31 }
32 };
33 write!(f, "\n{error}\n\x1b[0;2;31m{}\x1b[0m\n", defeat_message())
34 }
35}
36
37impl Display for DeformationError {
38 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
39 let error = match self {
40 Self::InvalidJacobian(jacobian, deformation_gradient) => {
41 format!(
42 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
43 From deformation gradient: {deformation_gradient}."
44 )
45 }
46 };
47 write!(f, "{error}\x1b[0m")
48 }
49}
50
51pub trait Deformation {
53 fn jacobian(&self) -> Result<Scalar, DeformationError>;
59 fn left_cauchy_green(&self) -> LeftCauchyGreenDeformation;
65 fn right_cauchy_green(&self) -> RightCauchyGreenDeformation;
71}
72
73impl Deformation for DeformationGradient {
74 fn jacobian(&self) -> Result<Scalar, DeformationError> {
75 let jacobian = self.determinant();
76 if jacobian > 0.0 {
77 Ok(jacobian)
78 } else {
79 Err(DeformationError::InvalidJacobian(jacobian, self.clone()))
80 }
81 }
82 fn left_cauchy_green(&self) -> LeftCauchyGreenDeformation {
83 self.iter()
84 .map(|deformation_gradient_i| {
85 self.iter()
86 .map(|deformation_gradient_j| deformation_gradient_i * deformation_gradient_j)
87 .collect()
88 })
89 .collect()
90 }
91 fn right_cauchy_green(&self) -> RightCauchyGreenDeformation {
92 let deformation_gradient_transpose = self.transpose();
93 deformation_gradient_transpose
94 .iter()
95 .map(|deformation_gradient_transpose_i| {
96 deformation_gradient_transpose
97 .iter()
98 .map(|deformation_gradient_transpose_j| {
99 deformation_gradient_transpose_i * deformation_gradient_transpose_j
100 })
101 .collect()
102 })
103 .collect()
104 }
105}
106
107pub type CauchyStress = TensorRank2<3, 1, 1>;
109
110pub type CauchyStresses<const W: usize> = TensorRank2List<3, 1, 1, W>;
112
113pub type CauchyTangentStiffness = TensorRank4<3, 1, 1, 1, 0>;
115
116pub type CauchyRateTangentStiffness = TensorRank4<3, 1, 1, 1, 0>;
118
119pub type Coordinates<const I: usize, const W: usize> = TensorRank1List<3, I, W>;
121
122pub type CurrentCoordinate = TensorRank1<3, 1>;
124
125pub type CurrentCoordinates<const W: usize> = TensorRank1List<3, 1, W>;
127
128pub type CurrentVelocity = TensorRank1<3, 1>;
130
131pub type DeformationGradient = TensorRank2<3, 1, 0>;
133
134pub type DeformationGradientElastic = TensorRank2<3, 1, 2>;
136
137pub type DeformationGradientGeneral<const I: usize, const J: usize> = TensorRank2<3, I, J>;
139
140pub type DeformationGradientPlastic = TensorRank2<3, 2, 0>;
142
143pub type DeformationGradientRate = TensorRank2<3, 1, 0>;
145
146pub type DeformationGradientRatePlastic = TensorRank2<3, 2, 0>;
148
149pub type DeformationGradientList<const W: usize> = TensorRank2List<3, 1, 0, W>;
151
152pub type DeformationGradientRateList<const W: usize> = TensorRank2List<3, 1, 0, W>;
154
155pub type DeformationGradients = TensorRank2Vec<3, 1, 0>;
157
158pub type DeformationGradientRates = TensorRank2Vec<3, 1, 0>;
160
161pub type Displacement = TensorRank1<3, 1>;
163
164pub type FirstPiolaKirchhoffStress = TensorRank2<3, 1, 0>;
166
167pub type FirstPiolaKirchhoffStresses<const W: usize> = TensorRank2List<3, 1, 0, W>;
169
170pub type FirstPiolaKirchhoffTangentStiffness = TensorRank4<3, 1, 0, 1, 0>;
172
173pub type FirstPiolaKirchhoffTangentStiffnesses<const W: usize> = TensorRank4List<3, 1, 0, 1, 0, W>;
175
176pub type FirstPiolaKirchhoffRateTangentStiffness = TensorRank4<3, 1, 0, 1, 0>;
178
179pub type FirstPiolaKirchhoffRateTangentStiffnesses<const W: usize> =
181 TensorRank4List<3, 1, 0, 1, 0, W>;
182
183pub type Force = TensorRank1<3, 1>;
185
186pub type Forces<const W: usize> = TensorRank1List<3, 1, W>;
188
189pub type FrameSpin = TensorRank2<3, 1, 1>;
191
192pub type HeatFlux = TensorRank1<3, 1>;
194
195pub type LeftCauchyGreenDeformation = TensorRank2<3, 1, 1>;
197
198pub type MandelStress = TensorRank2<3, 2, 2>;
200
201pub type Normal = TensorRank1<3, 1>;
203
204pub type ReferenceCoordinate = TensorRank1<3, 0>;
206
207pub type ReferenceCoordinates<const W: usize> = TensorRank1List<3, 0, W>;
209
210pub type RightCauchyGreenDeformation = TensorRank2<3, 0, 0>;
212
213pub type RotationCurrentConfiguration = TensorRank2<3, 1, 1>;
215
216pub type RotationRateCurrentConfiguration = TensorRank2<3, 1, 1>;
218
219pub type RotationReferenceConfiguration = TensorRank2<3, 0, 0>;
221
222pub type Scalars<const W: usize> = TensorRank0List<W>;
224
225pub type SecondPiolaKirchhoffStress = TensorRank2<3, 0, 0>;
227
228pub type SecondPiolaKirchhoffTangentStiffness = TensorRank4<3, 0, 0, 1, 0>;
230
231pub type SecondPiolaKirchhoffRateTangentStiffness = TensorRank4<3, 0, 0, 1, 0>;
233
234pub type Stiffness = TensorRank2<3, 1, 1>;
236
237pub type Stiffnesses<const W: usize> = TensorRank2List2D<3, 1, 1, W, W>;
239
240pub type StretchingRate = TensorRank2<3, 1, 1>;
242
243pub type StretchingRatePlastic = TensorRank2<3, 2, 2>;
245
246pub type TemperatureGradient = TensorRank1<3, 1>;
248
249pub type Times = crate::math::Vector;
251
252pub type Traction = TensorRank1<3, 1>;
254
255pub type Vector<const I: usize> = TensorRank1<3, I>;
257
258pub type Vectors<const I: usize, const W: usize> = TensorRank1List<3, I, W>;
260
261pub type Vectors2D<const I: usize, const W: usize, const X: usize> = TensorRank1List2D<3, I, W, X>;