Skip to main content

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

1use crate::{
2    constitutive::{ConstitutiveError, solid::hyperviscoelastic::Hyperviscoelastic},
3    domain::block::element::solid::hyperviscoelastic::HyperviscoelasticElement,
4    math::{Quantity, Tensor},
5    units::Energy,
6    vem::block::element::{
7        Element, ElementNodalCoordinates, VirtualElement, VirtualElementError,
8        solid::{SolidElement, elastic_hyperviscous::ElasticHyperviscousVirtualElement},
9    },
10};
11
12pub trait HyperviscoelasticVirtualElement<C>
13where
14    C: Hyperviscoelastic,
15    Self: ElasticHyperviscousVirtualElement<C> + HyperviscoelasticElement<C>,
16{
17}
18
19impl<T, C> HyperviscoelasticVirtualElement<C> for T
20where
21    C: Hyperviscoelastic,
22    T: ElasticHyperviscousVirtualElement<C> + HyperviscoelasticElement<C>,
23{
24}
25
26impl<C> HyperviscoelasticElement<C> for Element
27where
28    C: Hyperviscoelastic,
29{
30    fn helmholtz_free_energy(
31        &self,
32        constitutive_model: &C,
33        nodal_coordinates: &ElementNodalCoordinates,
34    ) -> Result<Quantity<Energy>, VirtualElementError> {
35        let tetrahedra_energy = self
36            .tetrahedra()
37            .iter()
38            .zip(self.tetrahedra_coordinates(nodal_coordinates).iter())
39            .map(|(tetrahedron, tetrahedron_coordinates)| {
40                tetrahedron.helmholtz_free_energy(constitutive_model, tetrahedron_coordinates)
41            })
42            .sum::<Result<Quantity<Energy>, _>>()
43            .map_err(|error| self.upstream(error))?;
44        let polyhedron_energy = self
45            .deformation_gradients(nodal_coordinates)
46            .iter()
47            .zip(self.integration_weights())
48            .map(|(deformation_gradient, integration_weight)| {
49                Ok::<_, ConstitutiveError>(
50                    constitutive_model.helmholtz_free_energy_density(deformation_gradient)?
51                        * integration_weight,
52                )
53            })
54            .sum::<Result<Quantity<Energy>, _>>()
55            .map_err(|error| self.upstream(error))?;
56        Ok(polyhedron_energy * (1.0 - self.stabilization())
57            + tetrahedra_energy * self.stabilization())
58    }
59}