Skip to main content

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

1use crate::{
2    constitutive::{ConstitutiveError, solid::hyperviscoelastic::Hyperviscoelastic},
3    fem::block::element::{
4        Element, ElementNodalCoordinates, FiniteElementError,
5        solid::elastic_hyperviscous::ElasticHyperviscousFiniteElement, surface::SurfaceElement,
6    },
7    math::{Quantity, Tensor},
8    units::Energy,
9};
10
11pub trait HyperviscoelasticFiniteElement<
12    C,
13    const G: usize,
14    const M: usize,
15    const N: usize,
16    const P: usize,
17> where
18    C: Hyperviscoelastic,
19    Self: ElasticHyperviscousFiniteElement<C, G, M, N, P>,
20{
21    fn helmholtz_free_energy(
22        &self,
23        constitutive_model: &C,
24        nodal_coordinates: &ElementNodalCoordinates<N>,
25    ) -> Result<Quantity<Energy>, FiniteElementError>;
26}
27
28impl<C, const G: usize, const N: usize, const O: usize, const P: usize>
29    HyperviscoelasticFiniteElement<C, G, 3, N, P> for Element<3, G, N, O>
30where
31    C: Hyperviscoelastic,
32    Self: ElasticHyperviscousFiniteElement<C, G, 3, N, P>,
33{
34    fn helmholtz_free_energy(
35        &self,
36        constitutive_model: &C,
37        nodal_coordinates: &ElementNodalCoordinates<N>,
38    ) -> Result<Quantity<Energy>, FiniteElementError> {
39        helmholtz_free_energy::<_, _, _, _, _, O, _>(self, constitutive_model, nodal_coordinates)
40    }
41}
42
43impl<C, const G: usize, const N: usize, const O: usize, const P: usize>
44    HyperviscoelasticFiniteElement<C, G, 2, N, P> for SurfaceElement<G, N, O>
45where
46    C: Hyperviscoelastic,
47    Self: ElasticHyperviscousFiniteElement<C, G, 2, N, P>,
48{
49    fn helmholtz_free_energy(
50        &self,
51        constitutive_model: &C,
52        nodal_coordinates: &ElementNodalCoordinates<N>,
53    ) -> Result<Quantity<Energy>, FiniteElementError> {
54        helmholtz_free_energy::<_, _, _, _, _, O, _>(self, constitutive_model, nodal_coordinates)
55    }
56}
57
58fn helmholtz_free_energy<
59    C,
60    F,
61    const G: usize,
62    const M: usize,
63    const N: usize,
64    const O: usize,
65    const P: usize,
66>(
67    element: &F,
68    constitutive_model: &C,
69    nodal_coordinates: &ElementNodalCoordinates<N>,
70) -> Result<Quantity<Energy>, FiniteElementError>
71where
72    C: Hyperviscoelastic,
73    F: ElasticHyperviscousFiniteElement<C, G, M, N, P>,
74{
75    element
76        .deformation_gradients(nodal_coordinates)
77        .iter()
78        .zip(element.integration_weights())
79        .map(|(deformation_gradient, integration_weight)| {
80            Ok::<_, ConstitutiveError>(
81                constitutive_model.helmholtz_free_energy_density(deformation_gradient)?
82                    * integration_weight,
83            )
84        })
85        .sum::<Result<_, ConstitutiveError>>()
86        .map_err(|error| FiniteElementError::upstream(error, element))
87}