1use crate::{
2 domain::{Blocks, Model, NodalReferenceCoordinates, nodal_coordinates},
3 geometry::{
4 Coordinates,
5 mesh::{Connectivities, Connectivity, Mesh},
6 },
7};
8
9pub(crate) trait FromConnectivities<const D: usize, M>: Sized {
10 fn from_connectivities(
11 connectivities: Vec<Connectivity>,
12 constitutive_models: M,
13 coordinates: &NodalReferenceCoordinates<D>,
14 ) -> Result<Self, String>;
15}
16
17impl<const D: usize, B1, M1, B2, M2> FromConnectivities<D, (M1, M2)> for Blocks<B1, B2>
18where
19 B1: FromConnectivities<D, M1>,
20 B2: FromConnectivities<D, M2>,
21{
22 fn from_connectivities(
23 mut connectivities: Vec<Connectivity>,
24 (constitutive_models_1, constitutive_models_2): (M1, M2),
25 coordinates: &NodalReferenceCoordinates<D>,
26 ) -> Result<Self, String> {
27 let last = connectivities
28 .pop()
29 .ok_or_else(|| "mesh has too few blocks for this model type".to_string())?;
30 let block_1 = B1::from_connectivities(connectivities, constitutive_models_1, coordinates)?;
31 let block_2 = B2::from_connectivities(vec![last], constitutive_models_2, coordinates)?;
32 Ok(Blocks(block_1, block_2))
33 }
34}
35
36impl<const D: usize, B, M> TryFrom<(Mesh<D>, M)> for Model<B, D>
37where
38 B: FromConnectivities<D, M>,
39{
40 type Error = String;
41 fn try_from((mesh, constitutive_models): (Mesh<D>, M)) -> Result<Self, Self::Error> {
42 let (connectivities, coordinates): (Connectivities, Coordinates<D>) = mesh.into();
43 let coordinates = nodal_coordinates(coordinates);
44 Ok(Self {
45 blocks: B::from_connectivities(
46 connectivities.into_members(),
47 constitutive_models,
48 &coordinates,
49 )?,
50 coordinates,
51 })
52 }
53}