conspire/domain/fem/block/solid/elastic/
mod.rs1use 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}