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}