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, TestError},
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)) => Err(
61 ConstitutiveError::InvalidJacobian(jacobian, format!("{self:?}")),
62 ),
63 Ok(jacobian) => Ok(jacobian),
64 }
65 }
66 fn new(parameters: P) -> Self;
68}
69
70pub enum ConstitutiveError {
72 Custom(String, String),
73 InvalidJacobian(Scalar, String),
74 Upstream(String, String),
75}
76
77impl From<ConstitutiveError> for String {
78 fn from(error: ConstitutiveError) -> Self {
79 match error {
80 ConstitutiveError::InvalidJacobian(jacobian, constitutive_model) => format!(
81 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
82 In constitutive model: {constitutive_model}."
83 ),
84 _ => todo!(),
85 }
86 }
87}
88
89impl From<ConstitutiveError> for TestError {
90 fn from(error: ConstitutiveError) -> Self {
91 Self {
92 message: error.to_string(),
93 }
94 }
95}
96
97impl Debug for ConstitutiveError {
98 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
99 let error = match self {
100 Self::Custom(message, constitutive_model) => format!(
101 "\x1b[1;91m{message}\x1b[0;91m\n\
102 In constitutive model: {constitutive_model}."
103 ),
104 Self::InvalidJacobian(jacobian, constitutive_model) => {
105 format!(
106 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
107 In constitutive model: {constitutive_model}."
108 )
109 }
110 Self::Upstream(error, constitutive_model) => {
111 format!(
112 "{error}\x1b[0;91m\n\
113 In constitutive model: {constitutive_model}."
114 )
115 }
116 };
117 write!(f, "\n{}\n\x1b[0;2;31m{}\x1b[0m\n", error, defeat_message())
118 }
119}
120
121impl Display for ConstitutiveError {
122 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
123 let error = match self {
124 Self::Custom(message, constitutive_model) => format!(
125 "\x1b[1;91m{message}\x1b[0;91m\n\
126 In constitutive model: {constitutive_model}."
127 ),
128 Self::InvalidJacobian(jacobian, constitutive_model) => {
129 format!(
130 "\x1b[1;91mInvalid Jacobian: {jacobian:.6e}.\x1b[0;91m\n\
131 In constitutive model: {constitutive_model}."
132 )
133 }
134 Self::Upstream(error, constitutive_model) => {
135 format!(
136 "{error}\x1b[0;91m\n\
137 In constitutive model: {constitutive_model}."
138 )
139 }
140 };
141 write!(f, "{error}\x1b[0m")
142 }
143}
144
145impl PartialEq for ConstitutiveError {
146 fn eq(&self, other: &Self) -> bool {
147 match self {
148 Self::Custom(a, b) => match other {
149 Self::Custom(c, d) => a == c && b == d,
150 _ => false,
151 },
152 Self::InvalidJacobian(a, b) => match other {
153 Self::InvalidJacobian(c, d) => a == c && b == d,
154 _ => false,
155 },
156 Self::Upstream(a, b) => match other {
157 Self::Upstream(c, d) => a == c && b == d,
158 _ => false,
159 },
160 }
161 }
162}