conspire/constitutive/
mod.rs1#[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, TensorError, TestError},
15 mechanics::{Deformation, DeformationError, DeformationGradientGeneral},
16};
17use std::fmt::{self, Debug, Display, Formatter};
18
19pub trait Constitutive
21where
22 Self: Clone + Debug,
23{
24 fn jacobian<const I: usize, const J: usize>(
26 &self,
27 deformation_gradient: &DeformationGradientGeneral<I, J>,
28 ) -> Result<Scalar, ConstitutiveError> {
29 match deformation_gradient.jacobian() {
30 Err(DeformationError::InvalidJacobian(jacobian)) => Err(
31 ConstitutiveError::InvalidJacobian(jacobian, format!("{self:?}")),
32 ),
33 Ok(jacobian) => Ok(jacobian),
34 }
35 }
36}
37
38pub enum ConstitutiveError {
40 Custom(String, String),
41 InvalidJacobian(Scalar, String),
42 Upstream(String, String),
43}
44
45impl From<ConstitutiveError> for String {
46 fn from(error: ConstitutiveError) -> Self {
47 match error {
48 ConstitutiveError::Custom(message, constitutive_model) => format!(
49 "\x1b[1;91m{message}\x1b[0;91m\n\
50 In constitutive model: {constitutive_model}."
51 ),
52 ConstitutiveError::InvalidJacobian(jacobian, constitutive_model) => format!(
53 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
54 In constitutive model: {constitutive_model}."
55 ),
56 ConstitutiveError::Upstream(error, constitutive_model) => format!(
57 "{error}\x1b[0;91m\n\
58 In constitutive model: {constitutive_model}."
59 ),
60 }
61 }
62}
63
64impl From<ConstitutiveError> for TestError {
65 fn from(error: ConstitutiveError) -> Self {
66 Self {
67 message: error.to_string(),
68 }
69 }
70}
71
72impl From<TensorError> for ConstitutiveError {
73 fn from(error: TensorError) -> Self {
74 ConstitutiveError::Custom(
75 error.to_string(),
76 "unknown (temporary error handling)".to_string(),
77 )
78 }
79}
80
81impl Debug for ConstitutiveError {
82 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
83 let error = match self {
84 Self::Custom(message, constitutive_model) => format!(
85 "\x1b[1;91m{message}\x1b[0;91m\n\
86 In constitutive model: {constitutive_model}."
87 ),
88 Self::InvalidJacobian(jacobian, constitutive_model) => {
89 format!(
90 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
91 In constitutive model: {constitutive_model}."
92 )
93 }
94 Self::Upstream(error, constitutive_model) => {
95 format!(
96 "{error}\x1b[0;91m\n\
97 In constitutive model: {constitutive_model}."
98 )
99 }
100 };
101 write!(f, "\n{}\n\x1b[0;2;31m{}\x1b[0m\n", error, defeat_message())
102 }
103}
104
105impl Display for ConstitutiveError {
106 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
107 let error = match self {
108 Self::Custom(message, constitutive_model) => format!(
109 "\x1b[1;91m{message}\x1b[0;91m\n\
110 In constitutive model: {constitutive_model}."
111 ),
112 Self::InvalidJacobian(jacobian, constitutive_model) => {
113 format!(
114 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
115 In constitutive model: {constitutive_model}."
116 )
117 }
118 Self::Upstream(error, constitutive_model) => {
119 format!(
120 "{error}\x1b[0;91m\n\
121 In constitutive model: {constitutive_model}."
122 )
123 }
124 };
125 write!(f, "{error}\x1b[0m")
126 }
127}
128
129impl PartialEq for ConstitutiveError {
130 fn eq(&self, other: &Self) -> bool {
131 match self {
132 Self::Custom(a, b) => match other {
133 Self::Custom(c, d) => a == c && b == d,
134 _ => false,
135 },
136 Self::InvalidJacobian(a, b) => match other {
137 Self::InvalidJacobian(c, d) => a == c && b == d,
138 _ => false,
139 },
140 Self::Upstream(a, b) => match other {
141 Self::Upstream(c, d) => a == c && b == d,
142 _ => false,
143 },
144 }
145 }
146}