Skip to main content

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

1use super::super::{
2    Block,
3    node::solid::{elastic::ElasticElement, hyperelastic::HyperelasticElement},
4};
5use crate::{
6    constitutive::{ConstitutiveError, solid::hyperelastic::Hyperelastic},
7    domain::{ElementModelError, NodalCoordinates, solid::NodalStiffnessesSolidSymmetric},
8    math::{HessianAccumulate, Quantity},
9    units::Energy,
10};
11
12pub use crate::domain::solid::hyperelastic::HyperelasticElements;
13
14impl<C> HyperelasticElements<3> for Block<C>
15where
16    C: Hyperelastic,
17{
18    fn helmholtz_free_energy(
19        &self,
20        nodal_coordinates: &NodalCoordinates<3>,
21    ) -> Result<Quantity<Energy>, ElementModelError> {
22        self.nodes
23            .iter()
24            .map(|node| node.helmholtz_free_energy(&self.constitutive_model, nodal_coordinates))
25            .sum::<Result<_, ConstitutiveError>>()
26            .map_err(|error| ElementModelError::upstream(error, self))
27    }
28    fn nodal_stiffnesses_symmetric_into(
29        &self,
30        nodal_coordinates: &NodalCoordinates<3>,
31        nodal_stiffnesses: &mut NodalStiffnessesSolidSymmetric<3>,
32    ) -> Result<(), ElementModelError> {
33        self.nodes
34            .iter()
35            .try_for_each(|node| {
36                node.nodal_stiffnesses(&self.constitutive_model, nodal_coordinates)?
37                    .into_iter()
38                    .zip(node.neighbors())
39                    .for_each(|(row, &neighbor_a)| {
40                        row.into_iter()
41                            .zip(node.neighbors())
42                            .for_each(|(block, &neighbor_b)| {
43                                if neighbor_a <= neighbor_b {
44                                    nodal_stiffnesses.accumulate(neighbor_a, neighbor_b, block)
45                                }
46                            })
47                    });
48                Ok::<(), ConstitutiveError>(())
49            })
50            .map_err(|error| ElementModelError::upstream(error, self))
51    }
52}