1#[cfg(test)]
4pub mod test;
5
6use crate::{
7 defeat_message,
8 math::{
9 Rank2, Tensor, TensorRank1, TensorRank1List, TensorRank1List2D, TensorRank1RefVec,
10 TensorRank1Vec, TensorRank1Vec2D, TensorRank2, TensorRank2List, TensorRank2List2D,
11 TensorRank2Vec, TensorRank2Vec2D, TensorRank4, TensorRank4List, TensorRank4Vec,
12 },
13};
14use std::fmt::{self, Debug, Display, Formatter};
15
16pub use crate::math::Scalar;
17
18pub enum DeformationError {
20 InvalidJacobian(Scalar),
21}
22
23impl Debug for DeformationError {
24 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25 let error = match self {
26 Self::InvalidJacobian(jacobian) => {
27 format!("\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m")
28 }
29 };
30 write!(f, "\n{error}\n\x1b[0;2;31m{}\x1b[0m\n", defeat_message())
31 }
32}
33
34impl Display for DeformationError {
35 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
36 let error = match self {
37 Self::InvalidJacobian(jacobian) => {
38 format!("\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m")
39 }
40 };
41 write!(f, "{error}\x1b[0m")
42 }
43}
44
45pub trait Deformation<const I: usize, const J: usize> {
47 fn jacobian(&self) -> Result<Scalar, DeformationError>;
53 fn left_cauchy_green(&self) -> TensorRank2<3, I, I>;
59 fn right_cauchy_green(&self) -> TensorRank2<3, J, J>;
65}
66
67impl<const I: usize, const J: usize> Deformation<I, J> for DeformationGradientGeneral<I, J> {
68 fn jacobian(&self) -> Result<Scalar, DeformationError> {
69 let jacobian = self.determinant();
70 if jacobian > 0.0 {
71 Ok(jacobian)
72 } else {
73 Err(DeformationError::InvalidJacobian(jacobian))
74 }
75 }
76 fn left_cauchy_green(&self) -> TensorRank2<3, I, I> {
77 self.iter()
78 .map(|deformation_gradient_i| {
79 self.iter()
80 .map(|deformation_gradient_j| deformation_gradient_i * deformation_gradient_j)
81 .collect()
82 })
83 .collect()
84 }
85 fn right_cauchy_green(&self) -> TensorRank2<3, J, J> {
86 let deformation_gradient_transpose = self.transpose();
87 deformation_gradient_transpose
88 .iter()
89 .map(|deformation_gradient_transpose_i| {
90 deformation_gradient_transpose
91 .iter()
92 .map(|deformation_gradient_transpose_j| {
93 deformation_gradient_transpose_i * deformation_gradient_transpose_j
94 })
95 .collect()
96 })
97 .collect()
98 }
99}
100
101pub type Basis = TensorRank1List<3, 1, 3>;
103
104pub type Bases<const N: usize> = TensorRank1List2D<3, 1, 3, N>;
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 CauchyTangentStiffness1 = TensorRank4<3, 1, 1, 1, 2>;
118
119pub type CauchyTangentStiffnessElastic = TensorRank4<3, 1, 1, 1, 2>;
121
122pub type CauchyRateTangentStiffness = TensorRank4<3, 1, 1, 1, 0>;
124
125pub type Coordinate<const I: usize> = TensorRank1<3, I>;
127
128pub type CoordinateList<const I: usize, const N: usize> = TensorRank1List<3, I, N>;
130
131pub type Coordinates<const I: usize> = TensorRank1Vec<3, I>;
133
134pub type CoordinatesRef<'a, const I: usize> = TensorRank1RefVec<'a, 3, I>;
136
137pub type CurrentCoordinate = TensorRank1<3, 1>;
139
140pub type CurrentCoordinates<const W: usize> = TensorRank1List<3, 1, W>;
142
143pub type CurrentCoordinatesRef<'a> = TensorRank1RefVec<'a, 3, 1>;
145
146pub type CurrentVelocity = TensorRank1<3, 1>;
148
149pub type DeformationGradient = TensorRank2<3, 1, 0>;
151
152pub type DeformationGradient2 = TensorRank2<3, 2, 0>;
154
155pub type DeformationGradientElastic = TensorRank2<3, 1, 2>;
157
158pub type DeformationGradientGeneral<const I: usize, const J: usize> = TensorRank2<3, I, J>;
160
161pub type DeformationGradientPlastic = TensorRank2<3, 2, 0>;
163
164pub type DeformationGradientRate = TensorRank2<3, 1, 0>;
166
167pub type DeformationGradientRatePlastic = TensorRank2<3, 2, 0>;
169
170pub type DeformationGradientList<const W: usize> = TensorRank2List<3, 1, 0, W>;
172
173pub type DeformationGradientRateList<const W: usize> = TensorRank2List<3, 1, 0, W>;
175
176pub type DeformationGradients = TensorRank2Vec<3, 1, 0>;
178
179pub type DeformationGradientsPlastic = TensorRank2Vec<3, 2, 0>;
181
182pub type DeformationGradientRates = TensorRank2Vec<3, 1, 0>;
184
185pub type DeformationGradientRatesPlastic = TensorRank2Vec<3, 2, 0>;
187
188pub type Displacement = TensorRank1<3, 1>;
190
191pub type FirstPiolaKirchhoffStress = TensorRank2<3, 1, 0>;
193
194pub type FirstPiolaKirchhoffStress1 = TensorRank2<3, 1, 2>;
196
197pub type FirstPiolaKirchhoffStress2 = TensorRank2<3, 2, 0>;
199
200pub type FirstPiolaKirchhoffStressElastic = FirstPiolaKirchhoffStress1;
202
203pub type FirstPiolaKirchhoffStressList<const N: usize> = TensorRank2List<3, 1, 0, N>;
205
206pub type FirstPiolaKirchhoffStresses = TensorRank2Vec<3, 1, 0>;
208
209pub type FirstPiolaKirchhoffTangentStiffness = TensorRank4<3, 1, 0, 1, 0>;
211
212pub type FirstPiolaKirchhoffTangentStiffness1 = TensorRank4<3, 1, 2, 1, 2>;
214
215pub type FirstPiolaKirchhoffTangentStiffness2 = TensorRank4<3, 2, 0, 2, 0>;
217
218pub type FirstPiolaKirchhoffTangentStiffnessElastic = FirstPiolaKirchhoffTangentStiffness1;
220
221pub type FirstPiolaKirchhoffTangentStiffnessList<const N: usize> =
223 TensorRank4List<3, 1, 0, 1, 0, N>;
224
225pub type FirstPiolaKirchhoffTangentStiffnesses = TensorRank4Vec<3, 1, 0, 1, 0>;
227
228pub type FirstPiolaKirchhoffRateTangentStiffness = TensorRank4<3, 1, 0, 1, 0>;
230
231pub type FirstPiolaKirchhoffRateTangentStiffnesses<const W: usize> =
233 TensorRank4List<3, 1, 0, 1, 0, W>;
234
235pub type Force = TensorRank1<3, 1>;
237
238pub type ForceList<const N: usize> = TensorRank1List<3, 1, N>;
240
241pub type Forces = TensorRank1Vec<3, 1>;
243
244pub type FrameSpin = TensorRank2<3, 1, 1>;
246
247pub type HeatFlux = TensorRank1<3, 0>;
249
250pub type HeatFluxes<const N: usize> = TensorRank1List<3, 0, N>;
252
253pub type HeatFluxTangent = TensorRank2<3, 0, 0>;
255
256pub type HeatFluxTangents<const N: usize> = TensorRank2List<3, 0, 0, N>;
258
259pub type LeftCauchyGreenDeformation = TensorRank2<3, 1, 1>;
261
262pub type MandelStress = TensorRank2<3, 0, 0>;
264
265pub type MandelStressElastic = TensorRank2<3, 2, 2>;
267
268pub type Normal = TensorRank1<3, 1>;
270
271pub type Normals<const N: usize> = TensorRank1List<3, 1, N>;
273
274pub type NormalGradients<const O: usize, const P: usize> = TensorRank2List2D<3, 1, 1, O, P>;
276
277pub type NormalRate = TensorRank1<3, 1>;
279
280pub type NormalRates<const N: usize> = TensorRank1List<3, 1, N>;
282
283pub type ReferenceCoordinate = TensorRank1<3, 0>;
285
286pub type ReferenceCoordinates<const W: usize> = TensorRank1List<3, 0, W>;
288
289pub type ReferenceNormal = TensorRank1<3, 0>;
291
292pub type ReferenceNormals<const N: usize> = TensorRank1List<3, 0, N>;
294
295pub type RightCauchyGreenDeformation = TensorRank2<3, 0, 0>;
297
298pub type RotationCurrentConfiguration = TensorRank2<3, 1, 1>;
300
301pub type RotationCurrentConfigurationList<const N: usize> = TensorRank2List<3, 1, 1, N>;
303
304pub type RotationRateCurrentConfiguration = TensorRank2<3, 1, 1>;
306
307pub type RotationReferenceConfiguration = TensorRank2<3, 0, 0>;
309
310pub type Separation = Displacement;
312
313pub type SecondPiolaKirchhoffStress = TensorRank2<3, 0, 0>;
315
316pub type SecondPiolaKirchhoffStressElastic = TensorRank2<3, 2, 2>;
318
319pub type SecondPiolaKirchhoffTangentStiffness = TensorRank4<3, 0, 0, 1, 0>;
321
322pub type SecondPiolaKirchhoffTangentStiffnessElastic = TensorRank4<3, 2, 2, 1, 2>;
324
325pub type SecondPiolaKirchhoffRateTangentStiffness = TensorRank4<3, 0, 0, 1, 0>;
327
328pub type Stiffness = TensorRank2<3, 1, 1>;
330
331pub type StiffnessList<const N: usize> = TensorRank2List<3, 1, 1, N>;
333
334pub type StiffnessList2D<const N: usize> = TensorRank2List2D<3, 1, 1, N, N>;
336
337pub type Stiffnesses = TensorRank2Vec2D<3, 1, 1>;
339
340pub type StretchingRate = TensorRank2<3, 1, 1>;
342
343pub type StretchingRatePlastic = TensorRank2<3, 2, 2>;
345
346pub type SurfaceBasis<const I: usize> = TensorRank1List<3, I, 2>;
348
349pub type SurfaceBases<const I: usize, const N: usize> = TensorRank1List2D<3, I, 2, N>;
351
352pub type TemperatureGradient = TensorRank1<3, 0>;
354
355pub type TemperatureGradients<const N: usize> = TensorRank1List<3, 0, N>;
357
358pub type Times = crate::math::Vector;
360
361pub type Traction = TensorRank1<3, 1>;
363
364pub type TractionList<const N: usize> = TensorRank1List<3, 1, N>;
366
367pub type Vector<const I: usize> = TensorRank1<3, I>;
369
370pub type VectorList<const I: usize, const W: usize> = TensorRank1List<3, I, W>;
372
373pub type VectorList2D<const I: usize, const W: usize, const X: usize> =
375 TensorRank1List2D<3, I, W, X>;
376
377pub type Vectors<const I: usize> = TensorRank1Vec<3, I>;
379
380pub type Vectors2D<const I: usize> = TensorRank1Vec2D<3, I>;