Skip to main content

conspire/domain/fem/block/solid/hyperelastic_viscoplastic/
mod.rs

1use crate::{
2    constitutive::solid::hyperelastic_viscoplastic::HyperelasticViscoplastic,
3    fem::{
4        ElementModelError, NodalCoordinates,
5        block::{
6            Block,
7            element::solid::hyperelastic_viscoplastic::HyperelasticViscoplasticFiniteElement,
8            solid::elastic_viscoplastic::ViscoplasticStateVariables,
9        },
10        solid::{
11            elastic_viscoplastic::ElasticViscoplasticElements,
12            hyperelastic_viscoplastic::HyperelasticViscoplasticElements,
13        },
14    },
15    math::{Scalar, Tensor},
16};
17
18impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize, Y>
19    HyperelasticViscoplasticElements<ViscoplasticStateVariables<G, Y>, 3>
20    for Block<C, F, G, M, N, P>
21where
22    C: HyperelasticViscoplastic<Y>,
23    F: HyperelasticViscoplasticFiniteElement<C, G, M, N, P, Y>,
24    Self: ElasticViscoplasticElements<ViscoplasticStateVariables<G, Y>, 3>,
25    Y: Tensor,
26{
27    fn helmholtz_free_energy(
28        &self,
29        nodal_coordinates: &NodalCoordinates<3>,
30        state_variables: &ViscoplasticStateVariables<G, Y>,
31    ) -> Result<Scalar, ElementModelError> {
32        match self
33            .elements()
34            .iter()
35            .zip(self.connectivity())
36            .zip(state_variables)
37            .map(|((element, nodes), state_variables_element)| {
38                element.helmholtz_free_energy(
39                    self.constitutive_model(),
40                    &Self::element_coordinates(nodal_coordinates, nodes),
41                    state_variables_element,
42                )
43            })
44            .sum()
45        {
46            Ok(helmholtz_free_energy) => Ok(helmholtz_free_energy),
47            Err(error) => Err(ElementModelError::Upstream(
48                format!("{error}"),
49                format!("{self:?}"),
50            )),
51        }
52    }
53}