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

1use crate::{
2    constitutive::{ConstitutiveError, solid::hyperelastic_viscoplastic::HyperelasticViscoplastic},
3    fem::block::element::{
4        Element, ElementNodalCoordinates, FiniteElement, FiniteElementError,
5        solid::{
6            SolidFiniteElement, elastic_viscoplastic::ElasticViscoplasticFiniteElement,
7            viscoplastic::ViscoplasticStateVariables,
8        },
9    },
10    math::{Scalar, Tensor},
11};
12
13pub trait HyperelasticViscoplasticFiniteElement<
14    C,
15    const G: usize,
16    const M: usize,
17    const N: usize,
18    const P: usize,
19    Y,
20> where
21    C: HyperelasticViscoplastic<Y>,
22    Self: ElasticViscoplasticFiniteElement<C, G, M, N, P, Y>,
23    Y: Tensor,
24{
25    fn helmholtz_free_energy(
26        &self,
27        constitutive_model: &C,
28        nodal_coordinates: &ElementNodalCoordinates<N>,
29        state_variables: &ViscoplasticStateVariables<G, Y>,
30    ) -> Result<Scalar, FiniteElementError>;
31}
32
33impl<C, const G: usize, const N: usize, const O: usize, const P: usize, Y>
34    HyperelasticViscoplasticFiniteElement<C, G, 3, N, P, Y> for Element<G, N, O>
35where
36    C: HyperelasticViscoplastic<Y>,
37    Self: ElasticViscoplasticFiniteElement<C, G, 3, N, P, Y>,
38    Y: Tensor,
39{
40    fn helmholtz_free_energy(
41        &self,
42        constitutive_model: &C,
43        nodal_coordinates: &ElementNodalCoordinates<N>,
44        state_variables: &ViscoplasticStateVariables<G, Y>,
45    ) -> Result<Scalar, FiniteElementError> {
46        match self
47            .deformation_gradients(nodal_coordinates)
48            .iter()
49            .zip(state_variables)
50            .zip(self.integration_weights())
51            .map(
52                |((deformation_gradient, state_variable), integration_weight)| {
53                    let (deformation_gradient_p, _) = state_variable.into();
54                    Ok::<_, ConstitutiveError>(
55                        constitutive_model.helmholtz_free_energy_density(
56                            deformation_gradient,
57                            deformation_gradient_p,
58                        )? * integration_weight,
59                    )
60                },
61            )
62            .sum()
63        {
64            Ok(helmholtz_free_energy) => Ok(helmholtz_free_energy),
65            Err(error) => Err(FiniteElementError::Upstream(
66                format!("{error}"),
67                format!("{self:?}"),
68            )),
69        }
70    }
71}