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, element::FiniteElementError,
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::{Differentiable, Quantity, Tensor},
16    units::Energy,
17};
18
19impl<C, F, const G: usize, const M: usize, const N: usize, const P: usize, Y>
20    HyperelasticViscoplasticElements<ViscoplasticStateVariables<G, Y>, 3>
21    for Block<C, F, G, M, N, P>
22where
23    C: HyperelasticViscoplastic<Y>,
24    F: HyperelasticViscoplasticFiniteElement<C, G, M, N, P, Y>,
25    Self: ElasticViscoplasticElements<ViscoplasticStateVariables<G, Y>, 3>,
26    Y: Differentiable + Tensor,
27{
28    fn helmholtz_free_energy(
29        &self,
30        nodal_coordinates: &NodalCoordinates<3>,
31        state_variables: &ViscoplasticStateVariables<G, Y>,
32    ) -> Result<Quantity<Energy>, ElementModelError> {
33        self.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::<Result<_, FiniteElementError>>()
45            .map_err(|error| ElementModelError::upstream(error, self))
46    }
47}