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

1use crate::{
2    constitutive::solid::hyperelastic::Hyperelastic,
3    math::Scalar,
4    vem::{
5        NodalCoordinates,
6        block::{
7            Block, VirtualElementBlockError,
8            element::solid::hyperelastic::HyperelasticVirtualElement,
9            solid::SolidVirtualElementBlock,
10        },
11    },
12};
13
14pub trait HyperelasticVirtualElementBlock<C, F>
15where
16    C: Hyperelastic,
17    F: HyperelasticVirtualElement<C>,
18{
19    fn helmholtz_free_energy(
20        &self,
21        nodal_coordinates: &NodalCoordinates,
22    ) -> Result<Scalar, VirtualElementBlockError>;
23}
24
25impl<C, F> HyperelasticVirtualElementBlock<C, F> for Block<C, F>
26where
27    C: Hyperelastic,
28    F: HyperelasticVirtualElement<C>,
29    Self: SolidVirtualElementBlock<C, F>,
30{
31    fn helmholtz_free_energy(
32        &self,
33        nodal_coordinates: &NodalCoordinates,
34    ) -> Result<Scalar, VirtualElementBlockError> {
35        match self
36            .elements()
37            .iter()
38            .zip(self.elements_nodes())
39            .map(|(element, nodes)| {
40                element.helmholtz_free_energy(
41                    self.constitutive_model(),
42                    Self::element_coordinates(nodal_coordinates, nodes),
43                )
44            })
45            .sum()
46        {
47            Ok(helmholtz_free_energy) => Ok(helmholtz_free_energy),
48            Err(error) => Err(VirtualElementBlockError::Upstream(
49                format!("{error}"),
50                format!("{self:?}"),
51            )),
52        }
53    }
54}