Skip to main content

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

1use crate::{
2    constitutive::solid::elastic::Elastic,
3    domain::feti::block::element::{
4        DecomposableElements, ElementSystem, ElementSystems, positions,
5    },
6    fem::{
7        ElementModelError, NodalCoordinates,
8        block::{
9            Block,
10            element::{FiniteElementError, solid::elastic::ElasticFiniteElement},
11        },
12    },
13};
14
15impl<C, F, const G: usize, const N: usize, const P: usize, R> DecomposableElements
16    for Block<C, F, G, 3, N, P, R>
17where
18    C: Elastic,
19    F: ElasticFiniteElement<C, G, 3, N, P>,
20{
21    fn element_systems(
22        &self,
23        nodal_coordinates: &NodalCoordinates<3>,
24    ) -> Result<ElementSystems, ElementModelError> {
25        let elements = self
26            .connectivity()
27            .iter()
28            .zip(self.elements())
29            .map(|(nodes, element)| {
30                let coordinates = Self::element_coordinates(nodal_coordinates, nodes);
31                let forces = element.nodal_forces(self.constitutive_model(), &coordinates)?;
32                let stiffnesses =
33                    element.nodal_stiffnesses(self.constitutive_model(), &coordinates)?;
34                Ok::<_, FiniteElementError>(ElementSystem::pack(
35                    nodes.to_vec(),
36                    |a, i| forces[a][i].value(),
37                    |a, b, i, j| stiffnesses[a][b][i][j].value(),
38                ))
39            })
40            .collect::<Result<Vec<_>, _>>()
41            .map_err(|error| ElementModelError::upstream(error, self))?;
42        Ok(ElementSystems {
43            positions: positions(nodal_coordinates),
44            elements,
45        })
46    }
47}
48
49#[cfg(test)]
50mod test;