Skip to main content

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

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