Skip to main content

conspire/domain/
from.rs

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}