Skip to main content

conspire/domain/vem/block/solid/hyperelastic/
mod.rs

1use crate::{
2    constitutive::solid::hyperelastic::Hyperelastic,
3    fem::{ElementModelError, solid::hyperelastic::HyperelasticElements},
4    math::{HessianAccumulate, Scalar},
5    vem::{
6        NodalCoordinates,
7        block::{
8            Block,
9            element::{VirtualElementError, solid::hyperelastic::HyperelasticVirtualElement},
10            solid::NodalStiffnessesSolidSymmetric,
11        },
12    },
13};
14
15impl<C, F> HyperelasticElements<3> for Block<C, F>
16where
17    C: Hyperelastic,
18    F: HyperelasticVirtualElement<C>,
19{
20    fn helmholtz_free_energy(
21        &self,
22        nodal_coordinates: &NodalCoordinates,
23    ) -> Result<Scalar, ElementModelError> {
24        match self
25            .elements()
26            .iter()
27            .zip(self.elements_nodes())
28            .map(|(element, nodes)| {
29                element.helmholtz_free_energy(
30                    self.constitutive_model(),
31                    Self::element_coordinates(nodal_coordinates, nodes),
32                )
33            })
34            .sum()
35        {
36            Ok(helmholtz_free_energy) => Ok(helmholtz_free_energy),
37            Err(error) => Err(ElementModelError::Upstream(
38                format!("{error}"),
39                format!("{self:?}"),
40            )),
41        }
42    }
43    fn nodal_stiffnesses_symmetric_into(
44        &self,
45        nodal_coordinates: &NodalCoordinates,
46        nodal_stiffnesses: &mut NodalStiffnessesSolidSymmetric,
47    ) -> Result<(), ElementModelError> {
48        match self
49            .elements()
50            .iter()
51            .zip(self.elements_nodes())
52            .try_for_each(|(element, nodes)| {
53                element
54                    .nodal_stiffnesses(
55                        self.constitutive_model(),
56                        Self::element_coordinates(nodal_coordinates, 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                                if node_a <= node_b {
66                                    nodal_stiffnesses.accumulate(node_a, node_b, nodal_stiffness)
67                                }
68                            })
69                    });
70                Ok::<(), VirtualElementError>(())
71            }) {
72            Ok(()) => Ok(()),
73            Err(error) => Err(ElementModelError::Upstream(
74                format!("{error}"),
75                format!("{self:?}"),
76            )),
77        }
78    }
79}