Skip to main content

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

1use crate::{
2    constitutive::solid::viscoelastic::Viscoelastic,
3    fem::{
4        ElementModelError, NodalCoordinates, NodalVelocities,
5        block::{
6            Block,
7            element::{FiniteElementError, solid::viscoelastic::ViscoelasticFiniteElement},
8        },
9        solid::{NodalDampingsSolid, NodalForcesSolid, viscoelastic::ViscoelasticElements},
10    },
11};
12
13impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize> ViscoelasticElements<3>
14    for Block<C, F, G, M, N, P>
15where
16    C: Viscoelastic,
17    F: ViscoelasticFiniteElement<C, G, M, N, P>,
18{
19    fn nodal_forces_into(
20        &self,
21        nodal_coordinates: &NodalCoordinates<3>,
22        nodal_velocities: &NodalVelocities<3>,
23        nodal_forces: &mut NodalForcesSolid<3>,
24    ) -> Result<(), ElementModelError> {
25        self.elements()
26            .iter()
27            .zip(self.connectivity())
28            .try_for_each(|(element, nodes)| {
29                element
30                    .nodal_forces(
31                        self.constitutive_model(),
32                        &Self::element_coordinates(nodal_coordinates, nodes),
33                        &Self::element_coordinates(nodal_velocities, nodes),
34                    )?
35                    .into_iter()
36                    .zip(nodes)
37                    .for_each(|(nodal_force, &node)| nodal_forces[node] += nodal_force);
38                Ok::<(), FiniteElementError>(())
39            })
40            .map_err(|error| ElementModelError::upstream(error, self))
41    }
42    fn nodal_stiffnesses_into(
43        &self,
44        nodal_coordinates: &NodalCoordinates<3>,
45        nodal_velocities: &NodalVelocities<3>,
46        nodal_stiffnesses: &mut NodalDampingsSolid<3>,
47    ) -> Result<(), ElementModelError> {
48        self.elements()
49            .iter()
50            .zip(self.connectivity())
51            .try_for_each(|(element, nodes)| {
52                element
53                    .nodal_stiffnesses(
54                        self.constitutive_model(),
55                        &Self::element_coordinates(nodal_coordinates, nodes),
56                        &Self::element_coordinates(nodal_velocities, nodes),
57                    )?
58                    .into_iter()
59                    .zip(nodes)
60                    .for_each(|(object, &node_a)| {
61                        object
62                            .into_iter()
63                            .zip(nodes)
64                            .for_each(|(nodal_stiffness, &node_b)| {
65                                nodal_stiffnesses[node_a][node_b] += nodal_stiffness
66                            })
67                    });
68                Ok::<(), FiniteElementError>(())
69            })
70            .map_err(|error| ElementModelError::upstream(error, self))
71    }
72}