Skip to main content

conspire/domain/fem/from/
mod.rs

1#[cfg(test)]
2mod test;
3
4use crate::{
5    domain::from::FromConnectivities,
6    fem::{
7        ElasticViscoplasticAndElastic, Model, NodalReferenceCoordinates,
8        block::{
9            Block,
10            element::{
11                ElementNodalReferenceCoordinates, FiniteElement,
12                planar::PlanarElementNodalReferenceCoordinates,
13            },
14        },
15        nodal_coordinates,
16    },
17    geometry::{
18        Coordinates,
19        mesh::{Connectivities, Connectivity, Mesh, PrimitiveConnectivity},
20    },
21};
22
23fn block<C, F, const D: usize, const G: usize, const N: usize, const P: usize>(
24    constitutive_model: C,
25    connectivity: Connectivity,
26    coordinates: &NodalReferenceCoordinates<D>,
27) -> Result<Block<C, F, G, D, N, P>, String>
28where
29    Block<C, F, G, D, N, P>: for<'a> From<(
30        C,
31        PrimitiveConnectivity<D, N>,
32        &'a NodalReferenceCoordinates<D>,
33    )>,
34    PrimitiveConnectivity<D, N>: TryFrom<Connectivity, Error = &'static str>,
35{
36    Ok(Block::from((
37        constitutive_model,
38        PrimitiveConnectivity::<D, N>::try_from(connectivity)?,
39        coordinates,
40    )))
41}
42
43impl<C, F, const G: usize, const N: usize, const P: usize> FromConnectivities<3, C>
44    for Block<C, F, G, 3, N, P>
45where
46    F: FiniteElement<G, 3, N, P> + From<ElementNodalReferenceCoordinates<N>>,
47    PrimitiveConnectivity<3, N>: TryFrom<Connectivity, Error = &'static str>,
48{
49    fn from_connectivities(
50        mut connectivities: Vec<Connectivity>,
51        constitutive_model: C,
52        coordinates: &NodalReferenceCoordinates<3>,
53    ) -> Result<Self, String> {
54        if connectivities.len() != 1 {
55            return Err(format!(
56                "mesh has {} blocks, model type expects 1",
57                connectivities.len()
58            ));
59        }
60        block(constitutive_model, connectivities.remove(0), coordinates)
61    }
62}
63
64impl<C, F, const G: usize, const N: usize, const P: usize> FromConnectivities<2, C>
65    for Block<C, F, G, 2, N, P>
66where
67    F: FiniteElement<G, 2, N, P> + From<PlanarElementNodalReferenceCoordinates<N>>,
68    PrimitiveConnectivity<2, N>: TryFrom<Connectivity, Error = &'static str>,
69{
70    fn from_connectivities(
71        mut connectivities: Vec<Connectivity>,
72        constitutive_model: C,
73        coordinates: &NodalReferenceCoordinates<2>,
74    ) -> Result<Self, String> {
75        if connectivities.len() != 1 {
76            return Err(format!(
77                "mesh has {} blocks, model type expects 1",
78                connectivities.len()
79            ));
80        }
81        block(constitutive_model, connectivities.remove(0), coordinates)
82    }
83}
84
85impl<
86    C1,
87    C2,
88    F1,
89    F2,
90    const G1: usize,
91    const N1: usize,
92    const P1: usize,
93    const G2: usize,
94    const N2: usize,
95    const P2: usize,
96> TryFrom<(Mesh<3>, (C1, C2))>
97    for Model<
98        ElasticViscoplasticAndElastic<Block<C1, F1, G1, 3, N1, P1>, Block<C2, F2, G2, 3, N2, P2>>,
99        3,
100    >
101where
102    F1: FiniteElement<G1, 3, N1, P1> + From<ElementNodalReferenceCoordinates<N1>>,
103    F2: FiniteElement<G2, 3, N2, P2> + From<ElementNodalReferenceCoordinates<N2>>,
104    PrimitiveConnectivity<3, N1>: TryFrom<Connectivity, Error = &'static str>,
105    PrimitiveConnectivity<3, N2>: TryFrom<Connectivity, Error = &'static str>,
106{
107    type Error = String;
108    fn try_from(
109        (mesh, (constitutive_model_1, constitutive_model_2)): (Mesh<3>, (C1, C2)),
110    ) -> Result<Self, Self::Error> {
111        let (connectivities, coordinates): (Connectivities, Coordinates<3>) = mesh.into();
112        let coordinates = nodal_coordinates(coordinates);
113        let mut connectivities = connectivities.into_members().into_iter();
114        if connectivities.len() != 2 {
115            return Err(format!(
116                "mesh has {} blocks, model type expects 2",
117                connectivities.len()
118            ));
119        }
120        Ok(Self {
121            blocks: ElasticViscoplasticAndElastic(
122                block(
123                    constitutive_model_1,
124                    connectivities.next().unwrap(),
125                    &coordinates,
126                )?,
127                block(
128                    constitutive_model_2,
129                    connectivities.next().unwrap(),
130                    &coordinates,
131                )?,
132            ),
133            coordinates,
134        })
135    }
136}