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