conspire/domain/vem/block/
mod.rs1pub mod element;
2pub mod solid;
3
4use crate::{
5 defeat_message,
6 math::{
7 Scalar, TestError,
8 optimize::{
9 EqualityConstraint, FirstOrderOptimization, FirstOrderRootFinding, OptimizationError,
10 SecondOrderOptimization, ZerothOrderRootFinding,
11 },
12 },
13 vem::{
14 NodalCoordinates, NodalReferenceCoordinates,
15 block::element::{ElementNodalCoordinates, VirtualElement},
16 },
17};
18use std::{
19 any::type_name,
20 fmt::{self, Debug, Display, Formatter},
21};
22
23pub type Connectivity = Vec<Vec<usize>>;
24
25pub struct Block<C, F> {
26 constitutive_model: C,
27 coordinates: NodalReferenceCoordinates,
28 elements: Vec<F>,
29 elements_faces: Connectivity,
30 elements_nodes: Connectivity,
31 faces_nodes: Connectivity,
32}
33
34impl<C, F> Block<C, F> {
35 fn constitutive_model(&self) -> &C {
36 &self.constitutive_model
37 }
38 fn coordinates(&self) -> &NodalReferenceCoordinates {
39 &self.coordinates
40 }
41 fn elements(&self) -> &[F] {
42 &self.elements
43 }
44 fn element_coordinates<'a>(
45 coordinates: &'a NodalCoordinates,
46 nodes: &[usize],
47 ) -> ElementNodalCoordinates<'a> {
48 nodes.iter().map(|&node| &coordinates[node]).collect()
49 }
50 pub fn elements_faces(&self) -> &[Vec<usize>] {
51 &self.elements_faces
52 }
53 fn elements_nodes(&self) -> &[Vec<usize>] {
54 &self.elements_nodes
55 }
56 pub fn faces_nodes(&self) -> &[Vec<usize>] {
57 &self.faces_nodes
58 }
59}
60
61impl<C, F> Debug for Block<C, F> {
62 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
63 write!(
64 f,
65 "Block {{ constitutive model: {}, elements: [Virtual; {}] }}",
66 type_name::<C>()
67 .rsplit("::")
68 .next()
69 .unwrap()
70 .split("<")
71 .next()
72 .unwrap(),
73 self.elements().len()
74 )
75 }
76}
77
78pub trait VirtualElementBlock<C, F>
79where
80 F: VirtualElement,
81 Self: From<(C, NodalReferenceCoordinates, Connectivity, Connectivity)>,
82{
83}
84
85impl<C, F> From<(C, NodalReferenceCoordinates, Connectivity, Connectivity)> for Block<C, F>
86where
87 F: VirtualElement,
88{
89 fn from(
90 (constitutive_model, coordinates, elements_faces, faces_nodes): (
91 C,
92 NodalReferenceCoordinates,
93 Connectivity,
94 Connectivity,
95 ),
96 ) -> Self {
97 let (elements, elements_nodes) = elements_faces
98 .iter()
99 .map(|element_faces| {
100 let element_coordinates = element_faces
101 .iter()
102 .map(|&face| {
103 faces_nodes[face]
104 .iter()
105 .map(|&node| coordinates[node].clone())
106 .collect()
107 })
108 .collect();
109 let mut element_nodes = element_faces
110 .iter()
111 .flat_map(|&face| faces_nodes[face].clone())
112 .collect::<Vec<_>>();
113 element_nodes.sort();
114 element_nodes.dedup();
115 (
116 <F>::from((
117 element_coordinates,
118 element_faces,
119 &element_nodes,
120 &faces_nodes,
121 )),
122 element_nodes,
123 )
124 })
125 .unzip();
126 Self {
127 constitutive_model,
128 coordinates,
129 elements,
130 elements_faces,
131 elements_nodes,
132 faces_nodes,
133 }
134 }
135}
136
137pub enum VirtualElementBlockError {
138 Upstream(String, String),
139}
140
141impl From<VirtualElementBlockError> for String {
142 fn from(error: VirtualElementBlockError) -> Self {
143 match error {
144 VirtualElementBlockError::Upstream(error, block) => {
145 format!(
146 "{error}\x1b[0;91m\n\
147 In virtual element block: {block}."
148 )
149 }
150 }
151 }
152}
153
154impl From<VirtualElementBlockError> for TestError {
155 fn from(error: VirtualElementBlockError) -> Self {
156 Self {
157 message: error.to_string(),
158 }
159 }
160}
161
162impl Debug for VirtualElementBlockError {
163 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
164 let error = match self {
165 Self::Upstream(error, block) => {
166 format!(
167 "{error}\x1b[0;91m\n\
168 In block: {block}."
169 )
170 }
171 };
172 write!(f, "\n{error}\n\x1b[0;2;31m{}\x1b[0m\n", defeat_message())
173 }
174}
175
176impl Display for VirtualElementBlockError {
177 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
178 let error = match self {
179 Self::Upstream(error, block) => {
180 format!(
181 "{error}\x1b[0;91m\n\
182 In block: {block}."
183 )
184 }
185 };
186 write!(f, "{error}\x1b[0m")
187 }
188}
189
190pub trait ZerothOrderRoot<C, E, X> {
191 fn root(
192 &self,
193 equality_constraint: EqualityConstraint,
194 solver: impl ZerothOrderRootFinding<X>,
195 ) -> Result<X, OptimizationError>;
196}
197
198pub trait FirstOrderRoot<C, E, F, J, X> {
199 fn root(
200 &self,
201 equality_constraint: EqualityConstraint,
202 solver: impl FirstOrderRootFinding<F, J, X>,
203 ) -> Result<X, OptimizationError>;
204}
205
206pub trait FirstOrderMinimize<C, E, X> {
207 fn minimize(
208 &self,
209 equality_constraint: EqualityConstraint,
210 solver: impl FirstOrderOptimization<Scalar, X>,
211 ) -> Result<X, OptimizationError>;
212}
213
214pub trait SecondOrderMinimize<C, E, J, H, X> {
215 fn minimize(
216 &self,
217 equality_constraint: EqualityConstraint,
218 solver: impl SecondOrderOptimization<Scalar, J, H, X>,
219 ) -> Result<X, OptimizationError>;
220}