Skip to main content

conspire/domain/fem/block/solid/hyperelastic/internal_variables/
mod.rs

1use crate::{
2    constitutive::solid::hyperelastic::internal_variables::HyperelasticIV,
3    fem::{
4        ElementModelError, NodalCoordinates,
5        block::{
6            Block, element::FiniteElementError,
7            element::solid::hyperelastic::internal_variables::HyperelasticIVFiniteElement,
8        },
9        solid::{
10            elastic::internal_variables::{ElasticIVElements, InternalVariablesField},
11            hyperelastic::internal_variables::HyperelasticIVElements,
12        },
13    },
14    math::{Erase, Jacobian, Matrix, Quantity, Scalar, Solution, Tensor, Vector},
15    units::{Dimensionless, Energy, UnitDiv},
16};
17use std::ops::{Div, Mul};
18
19impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize, V, E>
20    HyperelasticIVElements<G, V, 3> for Block<C, F, G, M, N, P>
21where
22    C: HyperelasticIV<V>,
23    C::Residual: Erase<Erased = E>,
24    F: HyperelasticIVFiniteElement<C, G, M, N, P, V, E>,
25    Self: ElasticIVElements<G, V, 3>,
26    E: Tensor,
27    for<'a> &'a C::Residual: Div<C::TangentVv, Output = V>,
28    for<'a> &'a V: Mul<Quantity<Dimensionless>, Output = V> + Mul<Scalar, Output = V>,
29    for<'a> &'a Matrix: Mul<&'a V, Output = Vector>,
30    V: Erase<Erased = E> + Jacobian + Solution,
31    <V as Tensor>::Unit: UnitDiv<<V as Tensor>::Unit, Output = Dimensionless>,
32{
33    fn helmholtz_free_energy(
34        &self,
35        nodal_coordinates: &NodalCoordinates<3>,
36        internal_variables: &InternalVariablesField<G, V>,
37    ) -> Result<Quantity<Energy>, ElementModelError> {
38        self.elements()
39            .iter()
40            .zip(self.connectivity())
41            .zip(internal_variables)
42            .map(|((element, nodes), internal_variables_element)| {
43                element.helmholtz_free_energy(
44                    self.constitutive_model(),
45                    &Self::element_coordinates(nodal_coordinates, nodes),
46                    internal_variables_element,
47                )
48            })
49            .sum::<Result<_, FiniteElementError>>()
50            .map_err(|error| ElementModelError::upstream(error, self))
51    }
52}