Skip to main content

conspire/domain/fem/from/
mod.rs

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