conspire/domain/vem/block/solid/hyperelastic/
mod.rs1use 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}