conspire/domain/vem/block/
mod.rs

1pub 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}