1pub mod block;
4mod from;
5pub mod solid;
6pub mod thermal;
7
8use crate::math::{
9 Style, StyledError, TensorRank1Vec, TensorRank1Vec2D,
10 assert::AssertionError,
11 optimize::{
12 EqualityConstraint, FirstOrderOptimization, FirstOrderRootFinding, OptimizationError,
13 SecondOrderOptimization, ZerothOrderRootFinding,
14 },
15 styled_error,
16};
17use std::fmt::Debug;
18
19pub type NodalCoordinates<const D: usize> = TensorRank1Vec<D, 1>;
20pub type NodalCoordinatesHistory<const D: usize> = TensorRank1Vec2D<D, 1>;
21pub type NodalReferenceCoordinates<const D: usize> = TensorRank1Vec<D, 0>;
22pub type NodalVelocities<const D: usize> = TensorRank1Vec<D, 1>;
23pub type NodalVelocitiesHistory<const D: usize> = TensorRank1Vec2D<D, 1>;
24
25#[derive(Debug)]
26pub struct Model<B, const D: usize> {
27 blocks: B,
28 coordinates: NodalReferenceCoordinates<D>,
29}
30
31#[derive(Debug)]
32pub struct Blocks<B1, B2>(B1, B2);
33
34#[derive(Debug)]
35pub struct ElasticViscoplasticAndElastic<B1, B2>(B1, B2);
36
37pub trait ElementModel<const D: usize>
38where
39 Self: Debug,
40{
41 fn coordinates(&self) -> &NodalReferenceCoordinates<D>;
42}
43
44pub trait Elements
45where
46 Self: Debug,
47{
48 fn node_neighbors(&self, neighbors: &mut [Vec<usize>]);
49}
50
51impl<B, const D: usize> Elements for Model<B, D>
52where
53 B: Elements,
54{
55 fn node_neighbors(&self, neighbors: &mut [Vec<usize>]) {
56 self.blocks.node_neighbors(neighbors)
57 }
58}
59
60impl<B1, B2> Elements for Blocks<B1, B2>
61where
62 B1: Elements,
63 B2: Elements,
64{
65 fn node_neighbors(&self, neighbors: &mut [Vec<usize>]) {
66 self.0.node_neighbors(neighbors);
67 self.1.node_neighbors(neighbors)
68 }
69}
70
71impl<B1, B2> Elements for ElasticViscoplasticAndElastic<B1, B2>
72where
73 B1: Elements,
74 B2: Elements,
75{
76 fn node_neighbors(&self, neighbors: &mut [Vec<usize>]) {
77 self.0.node_neighbors(neighbors);
78 self.1.node_neighbors(neighbors)
79 }
80}
81
82impl<B, const D: usize> Model<B, D> {
83 pub fn blocks(&self) -> &B {
84 &self.blocks
85 }
86}
87
88impl<B, const D: usize> ElementModel<D> for Model<B, D>
89where
90 B: Debug,
91{
92 fn coordinates(&self) -> &NodalReferenceCoordinates<D> {
93 &self.coordinates
94 }
95}
96
97pub enum ElementModelError {
98 Upstream(String, String),
99}
100
101impl From<ElementModelError> for String {
102 fn from(error: ElementModelError) -> Self {
103 error.message(&Style::detect())
104 }
105}
106
107impl StyledError for ElementModelError {
108 fn message(&self, style: &Style) -> String {
109 let c = style.frame;
110 match self {
111 Self::Upstream(error, model) => format!(
112 "{error}{c}\n\
113 In element model: {model}."
114 ),
115 }
116 }
117}
118
119styled_error!(ElementModelError);
120
121pub trait ZerothOrderRoot<X> {
122 fn root(
123 &self,
124 equality_constraint: EqualityConstraint,
125 solver: impl ZerothOrderRootFinding<X>,
126 ) -> Result<X, OptimizationError>;
127}
128
129pub trait FirstOrderRoot<F, J, X> {
130 fn root(
131 &self,
132 equality_constraint: EqualityConstraint,
133 solver: impl FirstOrderRootFinding<F, J, X>,
134 ) -> Result<X, OptimizationError>;
135}
136
137pub trait FirstOrderMinimize<F, X> {
138 fn minimize(
139 &self,
140 equality_constraint: EqualityConstraint,
141 solver: impl FirstOrderOptimization<F, X>,
142 ) -> Result<X, OptimizationError>;
143}
144
145pub trait SecondOrderMinimize<F, J, H, X> {
146 fn minimize(
147 &self,
148 equality_constraint: EqualityConstraint,
149 solver: impl SecondOrderOptimization<F, J, H, X>,
150 ) -> Result<X, OptimizationError>;
151}
152
153impl<B, const D: usize> From<(B, NodalReferenceCoordinates<D>)> for Model<B, D> {
154 fn from((blocks, coordinates): (B, NodalReferenceCoordinates<D>)) -> Self {
155 Self {
156 blocks,
157 coordinates,
158 }
159 }
160}
161
162impl From<ElementModelError> for AssertionError {
163 fn from(error: ElementModelError) -> Self {
164 Self {
165 message: error.to_string(),
166 }
167 }
168}