Skip to main content

conspire/domain/fem/block/solid/elastic/
mod.rs

1use crate::{
2    constitutive::solid::elastic::Elastic,
3    fem::{
4        ElementModelError, NodalCoordinates,
5        block::{
6            Block,
7            element::{
8                FiniteElementError, planar::PlanarElasticFiniteElement,
9                solid::elastic::ElasticFiniteElement,
10            },
11        },
12        solid::{NodalForcesSolid, NodalStiffnessesSolid, elastic::ElasticElements},
13    },
14};
15
16impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize> ElasticElements<3>
17    for Block<C, F, G, M, N, P>
18where
19    C: Elastic,
20    F: ElasticFiniteElement<C, G, M, N, P>,
21{
22    fn nodal_forces_into(
23        &self,
24        nodal_coordinates: &NodalCoordinates<3>,
25        nodal_forces: &mut NodalForcesSolid<3>,
26    ) -> Result<(), ElementModelError> {
27        match self
28            .elements()
29            .iter()
30            .zip(self.connectivity())
31            .try_for_each(|(element, nodes)| {
32                element
33                    .nodal_forces(
34                        self.constitutive_model(),
35                        &Self::element_coordinates(nodal_coordinates, nodes),
36                    )?
37                    .into_iter()
38                    .zip(nodes)
39                    .for_each(|(nodal_force, &node)| nodal_forces[node] += nodal_force);
40                Ok::<(), FiniteElementError>(())
41            }) {
42            Ok(()) => Ok(()),
43            Err(error) => Err(ElementModelError::Upstream(
44                format!("{error}"),
45                format!("{self:?}"),
46            )),
47        }
48    }
49    fn nodal_stiffnesses_into(
50        &self,
51        nodal_coordinates: &NodalCoordinates<3>,
52        nodal_stiffnesses: &mut NodalStiffnessesSolid<3>,
53    ) -> Result<(), ElementModelError> {
54        match self
55            .elements()
56            .iter()
57            .zip(self.connectivity())
58            .try_for_each(|(element, nodes)| {
59                element
60                    .nodal_stiffnesses(
61                        self.constitutive_model(),
62                        &Self::element_coordinates(nodal_coordinates, nodes),
63                    )?
64                    .into_iter()
65                    .zip(nodes)
66                    .for_each(|(object, &node_a)| {
67                        object
68                            .into_iter()
69                            .zip(nodes)
70                            .for_each(|(nodal_stiffness, &node_b)| {
71                                nodal_stiffnesses[node_a][node_b] += nodal_stiffness
72                            })
73                    });
74                Ok::<(), FiniteElementError>(())
75            }) {
76            Ok(()) => Ok(()),
77            Err(error) => Err(ElementModelError::Upstream(
78                format!("{error}"),
79                format!("{self:?}"),
80            )),
81        }
82    }
83}
84
85impl<C, F, const G: usize, const N: usize, const P: usize> ElasticElements<2>
86    for Block<C, F, G, 2, N, P>
87where
88    C: Elastic,
89    F: PlanarElasticFiniteElement<C, G, N, P>,
90{
91    fn nodal_forces_into(
92        &self,
93        nodal_coordinates: &NodalCoordinates<2>,
94        nodal_forces: &mut NodalForcesSolid<2>,
95    ) -> Result<(), ElementModelError> {
96        match self
97            .elements()
98            .iter()
99            .zip(self.connectivity())
100            .try_for_each(|(element, nodes)| {
101                element
102                    .nodal_forces(
103                        self.constitutive_model(),
104                        &Self::element_coordinates(nodal_coordinates, nodes),
105                    )?
106                    .into_iter()
107                    .zip(nodes)
108                    .for_each(|(nodal_force, &node)| nodal_forces[node] += nodal_force);
109                Ok::<(), FiniteElementError>(())
110            }) {
111            Ok(()) => Ok(()),
112            Err(error) => Err(ElementModelError::Upstream(
113                format!("{error}"),
114                format!("{self:?}"),
115            )),
116        }
117    }
118    fn nodal_stiffnesses_into(
119        &self,
120        nodal_coordinates: &NodalCoordinates<2>,
121        nodal_stiffnesses: &mut NodalStiffnessesSolid<2>,
122    ) -> Result<(), ElementModelError> {
123        match self
124            .elements()
125            .iter()
126            .zip(self.connectivity())
127            .try_for_each(|(element, nodes)| {
128                element
129                    .nodal_stiffnesses(
130                        self.constitutive_model(),
131                        &Self::element_coordinates(nodal_coordinates, nodes),
132                    )?
133                    .into_iter()
134                    .zip(nodes)
135                    .for_each(|(object, &node_a)| {
136                        object
137                            .into_iter()
138                            .zip(nodes)
139                            .for_each(|(nodal_stiffness, &node_b)| {
140                                nodal_stiffnesses[node_a][node_b] += nodal_stiffness
141                            })
142                    });
143                Ok::<(), FiniteElementError>(())
144            }) {
145            Ok(()) => Ok(()),
146            Err(error) => Err(ElementModelError::Upstream(
147                format!("{error}"),
148                format!("{self:?}"),
149            )),
150        }
151    }
152}