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