Skip to main content

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

1use crate::{
2    constitutive::solid::hyperelastic::Hyperelastic,
3    domain::{ElementModelError, solid::hyperelastic::HyperelasticElements},
4    math::{HessianAccumulate, Quantity},
5    units::Energy,
6    vem::{
7        NodalCoordinates,
8        block::{
9            Block,
10            element::{VirtualElementError, solid::hyperelastic::HyperelasticVirtualElement},
11            solid::NodalStiffnessesSolidSymmetric,
12        },
13    },
14};
15
16impl<C, F> HyperelasticElements<3> for Block<C, F>
17where
18    C: Hyperelastic,
19    F: HyperelasticVirtualElement<C>,
20{
21    fn helmholtz_free_energy(
22        &self,
23        nodal_coordinates: &NodalCoordinates,
24    ) -> Result<Quantity<Energy>, ElementModelError> {
25        self.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::<Result<_, VirtualElementError>>()
35            .map_err(|error| ElementModelError::upstream(error, self))
36    }
37    fn nodal_stiffnesses_symmetric_into(
38        &self,
39        nodal_coordinates: &NodalCoordinates,
40        nodal_stiffnesses: &mut NodalStiffnessesSolidSymmetric,
41    ) -> Result<(), ElementModelError> {
42        self.elements()
43            .iter()
44            .zip(self.elements_nodes())
45            .try_for_each(|(element, nodes)| {
46                element
47                    .nodal_stiffnesses(
48                        self.constitutive_model(),
49                        &Self::element_coordinates(nodal_coordinates, nodes),
50                    )?
51                    .into_iter()
52                    .zip(nodes)
53                    .for_each(|(object, &node_a)| {
54                        object
55                            .into_iter()
56                            .zip(nodes)
57                            .for_each(|(nodal_stiffness, &node_b)| {
58                                if node_a <= node_b {
59                                    nodal_stiffnesses.accumulate(node_a, node_b, nodal_stiffness)
60                                }
61                            })
62                    });
63                Ok::<(), VirtualElementError>(())
64            })
65            .map_err(|error| ElementModelError::upstream(error, self))
66    }
67}