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::{Scalar, TestError, optimize::OptimizeError},
15 mechanics::{Deformation, DeformationError, DeformationGradient},
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: {jacobian:.6e}.\x1b[0;91m\n\
91 From deformation gradient: {deformation_gradient}.\n\
92 In constitutive model: {constitutive_model}."
93 )),
94 _ => todo!(),
95 }
96 }
97}
98
99impl From<ConstitutiveError> for TestError {
100 fn from(error: ConstitutiveError) -> Self {
101 Self {
102 message: error.to_string(),
103 }
104 }
105}
106
107impl From<OptimizeError> for ConstitutiveError {
108 fn from(error: OptimizeError) -> Self {
109 match error {
110 OptimizeError::Generic(_) => todo!("Generic"),
111 OptimizeError::MaximumStepsReached(_, _) => todo!("MaximumStepsReached"),
112 OptimizeError::NotMinimum(_, _) => todo!("NotMinimum"),
113 OptimizeError::SingularMatrix => todo!("SingularMatrix"),
114 }
115 }
116}
117
118impl Debug for ConstitutiveError {
119 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
120 let error = match self {
121 Self::Custom(message, deformation_gradient, constitutive_model) => format!(
122 "\x1b[1;91m{message}\x1b[0;91m\n\
123 From deformation gradient: {deformation_gradient}.\n\
124 In constitutive model: {constitutive_model}."
125 ),
126 Self::InvalidJacobian(jacobian, deformation_gradient, constitutive_model) => {
127 format!(
128 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
129 From deformation gradient: {deformation_gradient}.\n\
130 In constitutive model: {constitutive_model}."
131 )
132 }
133 Self::MaximumStepsReached(steps, constitutive_model) => {
134 format!(
135 "\x1b[1;91mMaximum number of steps ({steps}) reached.\x1b[0;91m\n\
136 In constitutive model: {constitutive_model}."
137 )
138 }
139 Self::NotMinimum(deformation_gradient, constitutive_model) => {
140 format!(
141 "\x1b[1;91mThe obtained solution is not a minimum.\x1b[0;91m\n\
142 {deformation_gradient}\nIn constitutive model: {constitutive_model}."
143 )
144 }
145 };
146 write!(f, "\n{}\n\x1b[0;2;31m{}\x1b[0m\n", error, defeat_message())
147 }
148}
149
150impl Display for ConstitutiveError {
151 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
152 let error = match self {
153 Self::Custom(message, deformation_gradient, constitutive_model) => format!(
154 "\x1b[1;91m{message}\x1b[0;91m\n\
155 From deformation gradient: {deformation_gradient}.\n\
156 In constitutive model: {constitutive_model}."
157 ),
158 Self::InvalidJacobian(jacobian, deformation_gradient, constitutive_model) => {
159 format!(
160 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
161 From deformation gradient: {deformation_gradient}.\n\
162 In constitutive model: {constitutive_model}."
163 )
164 }
165 Self::MaximumStepsReached(steps, constitutive_model) => {
166 format!(
167 "\x1b[1;91mMaximum number of steps ({steps}) reached.\x1b[0;91m\n\
168 In constitutive model: {constitutive_model}."
169 )
170 }
171 Self::NotMinimum(deformation_gradient, constitutive_model) => {
172 format!(
173 "\x1b[1;91mThe obtained solution is not a minimum.\x1b[0;91m\n\
174 {deformation_gradient}\nIn constitutive model: {constitutive_model}."
175 )
176 }
177 };
178 write!(f, "{error}\x1b[0m")
179 }
180}
181
182impl PartialEq for ConstitutiveError {
183 fn eq(&self, other: &Self) -> bool {
184 match self {
185 Self::Custom(a, b, c) => match other {
186 Self::Custom(d, e, f) => a == d && b == e && c == f,
187 _ => false,
188 },
189 Self::InvalidJacobian(a, b, c) => match other {
190 Self::InvalidJacobian(d, e, f) => a == d && b == e && c == f,
191 _ => false,
192 },
193 Self::MaximumStepsReached(_, _) => todo!(),
194 Self::NotMinimum(_, _) => todo!(),
195 }
196 }
197}