1#[cfg(test)]
4pub mod test;
5
6pub mod fluid;
7pub mod hybrid;
8pub mod multiphysics;
9pub mod solid;
10pub mod thermal;
11
12use crate::{
13 defeat_message,
14 math::{TestError, optimize::OptimizeError},
15 mechanics::{Deformation, DeformationError, DeformationGradient, Scalar},
16};
17use std::{
18 fmt::{self, Debug, Display, Formatter},
19 ops::{Index, RangeFrom},
20};
21
22pub trait Parameters
24where
25 Self: Copy + fmt::Debug,
26{
27 fn get(&self, index: usize) -> &Scalar;
28 fn get_slice(&self, index: RangeFrom<usize>) -> &[Scalar];
29}
30
31impl<const N: usize> Parameters for [Scalar; N] {
32 fn get(&self, index: usize) -> &Scalar {
33 self.index(index)
34 }
35 fn get_slice(&self, index: RangeFrom<usize>) -> &[Scalar] {
36 self.index(index)
37 }
38}
39
40impl<const N: usize> Parameters for &[Scalar; N] {
41 fn get(&self, index: usize) -> &Scalar {
42 self.index(index)
43 }
44 fn get_slice(&self, index: RangeFrom<usize>) -> &[Scalar] {
45 self.index(index)
46 }
47}
48
49pub trait Constitutive<P>
51where
52 Self: Debug,
53{
54 fn jacobian(
56 &self,
57 deformation_gradient: &DeformationGradient,
58 ) -> Result<Scalar, ConstitutiveError> {
59 match deformation_gradient.jacobian() {
60 Err(DeformationError::InvalidJacobian(jacobian, deformation_gradient)) => {
61 Err(ConstitutiveError::InvalidJacobian(
62 jacobian,
63 deformation_gradient,
64 format!("{:?}", self),
65 ))
66 }
67 Ok(jacobian) => Ok(jacobian),
68 }
69 }
70 fn new(parameters: P) -> Self;
72}
73
74pub enum ConstitutiveError {
76 Custom(String, DeformationGradient, String),
77 InvalidJacobian(Scalar, DeformationGradient, String),
78 MaximumStepsReached(usize, String),
79 NotMinimum(String, String),
80}
81
82impl From<ConstitutiveError> for OptimizeError {
83 fn from(error: ConstitutiveError) -> OptimizeError {
84 match error {
85 ConstitutiveError::InvalidJacobian(
86 jacobian,
87 deformation_gradient,
88 constitutive_model,
89 ) => OptimizeError::Generic(format!(
90 "\x1b[1;91mInvalid Jacobian: {:.6e}.\x1b[0;91m\n\
91 From deformation gradient: {}.\n\
92 In constitutive model: {}.",
93 jacobian, deformation_gradient, constitutive_model
94 )),
95 _ => todo!(),
96 }
97 }
98}
99
100impl From<ConstitutiveError> for TestError {
101 fn from(error: ConstitutiveError) -> Self {
102 Self {
103 message: error.to_string(),
104 }
105 }
106}
107
108impl From<OptimizeError> for ConstitutiveError {
109 fn from(error: OptimizeError) -> Self {
110 match error {
111 OptimizeError::Generic(_) => todo!("Generic"),
112 OptimizeError::MaximumStepsReached(_, _) => todo!("MaximumStepsReached"),
113 OptimizeError::NotMinimum(_, _) => todo!("NotMinimum"),
114 OptimizeError::SingularMatrix => todo!("SingularMatrix"),
115 }
116 }
117}
118
119impl Debug for ConstitutiveError {
120 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
121 let error = match self {
122 Self::Custom(message, deformation_gradient, constitutive_model) => format!(
123 "\x1b[1;91m{}\x1b[0;91m\n\
124 From deformation gradient: {}.\n\
125 In constitutive model: {}.",
126 message, deformation_gradient, constitutive_model
127 ),
128 Self::InvalidJacobian(jacobian, deformation_gradient, constitutive_model) => {
129 format!(
130 "\x1b[1;91mInvalid Jacobian: {:.6e}.\x1b[0;91m\n\
131 From deformation gradient: {}.\n\
132 In constitutive model: {}.",
133 jacobian, deformation_gradient, constitutive_model
134 )
135 }
136 Self::MaximumStepsReached(steps, constitutive_model) => {
137 format!(
138 "\x1b[1;91mMaximum number of steps ({}) reached.\x1b[0;91m\n\
139 In constitutive model: {}.",
140 steps, constitutive_model
141 )
142 }
143 Self::NotMinimum(deformation_gradient, constitutive_model) => {
144 format!(
145 "\x1b[1;91mThe obtained solution is not a minimum.\x1b[0;91m\n\
146 {}\nIn constitutive model: {}.",
147 deformation_gradient, constitutive_model
148 )
149 }
150 };
151 write!(f, "\n{}\n\x1b[0;2;31m{}\x1b[0m\n", error, defeat_message())
152 }
153}
154
155impl Display for ConstitutiveError {
156 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
157 let error = match self {
158 Self::Custom(message, deformation_gradient, constitutive_model) => format!(
159 "\x1b[1;91m{}\x1b[0;91m\n\
160 From deformation gradient: {}.\n\
161 In constitutive model: {}.",
162 message, deformation_gradient, constitutive_model
163 ),
164 Self::InvalidJacobian(jacobian, deformation_gradient, constitutive_model) => {
165 format!(
166 "\x1b[1;91mInvalid Jacobian: {:.6e}.\x1b[0;91m\n\
167 From deformation gradient: {}.\n\
168 In constitutive model: {}.",
169 jacobian, deformation_gradient, constitutive_model
170 )
171 }
172 Self::MaximumStepsReached(steps, constitutive_model) => {
173 format!(
174 "\x1b[1;91mMaximum number of steps ({}) reached.\x1b[0;91m\n\
175 In constitutive model: {}.",
176 steps, constitutive_model
177 )
178 }
179 Self::NotMinimum(deformation_gradient, constitutive_model) => {
180 format!(
181 "\x1b[1;91mThe obtained solution is not a minimum.\x1b[0;91m\n\
182 {}\nIn constitutive model: {}.",
183 deformation_gradient, constitutive_model
184 )
185 }
186 };
187 write!(f, "{}\x1b[0m", error)
188 }
189}
190
191impl PartialEq for ConstitutiveError {
192 fn eq(&self, other: &Self) -> bool {
193 match self {
194 Self::Custom(a, b, c) => match other {
195 Self::Custom(d, e, f) => a == d && b == e && c == f,
196 _ => false,
197 },
198 Self::InvalidJacobian(a, b, c) => match other {
199 Self::InvalidJacobian(d, e, f) => a == d && b == e && c == f,
200 _ => false,
201 },
202 Self::MaximumStepsReached(_, _) => todo!(),
203 Self::NotMinimum(_, _) => todo!(),
204 }
205 }
206}