conspire/domain/fem/from/
mod.rs1#[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}