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