1#[cfg(test)]
4pub mod test;
5
6use crate::{
7 defeat_message,
8 math::{
9 Rank2, Tensor, TensorRank0, TensorRank0List, TensorRank1, TensorRank1List,
10 TensorRank1List2D, TensorRank2, TensorRank2List, TensorRank2List2D, TensorRank2Vec,
11 TensorRank4, TensorRank4List,
12 },
13};
14use std::fmt::{self, Debug, Display, Formatter};
15
16pub enum DeformationError {
18 InvalidJacobian(Scalar, DeformationGradient),
19}
20
21impl Debug for DeformationError {
22 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
23 let error = match self {
24 Self::InvalidJacobian(jacobian, deformation_gradient) => {
25 format!(
26 "\x1b[1;91mInvalid Jacobian: {:.6e}.\x1b[0;91m\n\
27 From deformation gradient: {}.",
28 jacobian, deformation_gradient
29 )
30 }
31 };
32 write!(f, "\n{}\n\x1b[0;2;31m{}\x1b[0m\n", error, defeat_message())
33 }
34}
35
36impl Display for DeformationError {
37 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
38 let error = match self {
39 Self::InvalidJacobian(jacobian, deformation_gradient) => {
40 format!(
41 "\x1b[1;91mInvalid Jacobian: {:.6e}.\x1b[0;91m\n\
42 From deformation gradient: {}.",
43 jacobian, deformation_gradient
44 )
45 }
46 };
47 write!(f, "{}\x1b[0m", error)
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 Scalar = TensorRank0;
224
225pub type Scalars<const W: usize> = TensorRank0List<W>;
227
228pub type SecondPiolaKirchhoffStress = TensorRank2<3, 0, 0>;
230
231pub type SecondPiolaKirchhoffTangentStiffness = TensorRank4<3, 0, 0, 1, 0>;
233
234pub type SecondPiolaKirchhoffRateTangentStiffness = TensorRank4<3, 0, 0, 1, 0>;
236
237pub type Stiffness = TensorRank2<3, 1, 1>;
239
240pub type Stiffnesses<const W: usize> = TensorRank2List2D<3, 1, 1, W, W>;
242
243pub type StretchingRate = TensorRank2<3, 1, 1>;
245
246pub type StretchingRatePlastic = TensorRank2<3, 2, 2>;
248
249pub type TemperatureGradient = TensorRank1<3, 1>;
251
252pub type Times = crate::math::Vector;
254
255pub type Traction = TensorRank1<3, 1>;
257
258pub type Vector<const I: usize> = TensorRank1<3, I>;
260
261pub type Vectors<const I: usize, const W: usize> = TensorRank1List<3, I, W>;
263
264pub type Vectors2D<const I: usize, const W: usize, const X: usize> = TensorRank1List2D<3, I, W, X>;