conspire/domain/vem/block/element/solid/elastic_hyperviscous/
mod.rs1use crate::{
2 constitutive::{ConstitutiveError, solid::elastic_hyperviscous::ElasticHyperviscous},
3 domain::block::element::solid::elastic_hyperviscous::ElasticHyperviscousElement,
4 math::{Quantity, Tensor},
5 units::Power,
6 vem::block::element::{
7 Element, ElementNodalCoordinates, ElementNodalVelocities, VirtualElement,
8 VirtualElementError,
9 solid::{SolidElement, viscoelastic::ViscoelasticVirtualElement},
10 },
11};
12
13pub trait ElasticHyperviscousVirtualElement<C>
14where
15 C: ElasticHyperviscous,
16 Self: ViscoelasticVirtualElement<C> + ElasticHyperviscousElement<C>,
17{
18}
19
20impl<T, C> ElasticHyperviscousVirtualElement<C> for T
21where
22 C: ElasticHyperviscous,
23 T: ViscoelasticVirtualElement<C> + ElasticHyperviscousElement<C>,
24{
25}
26
27impl<C> ElasticHyperviscousElement<C> for Element
28where
29 C: ElasticHyperviscous,
30{
31 fn viscous_dissipation(
32 &self,
33 constitutive_model: &C,
34 nodal_coordinates: &ElementNodalCoordinates,
35 nodal_velocities: &ElementNodalVelocities,
36 ) -> Result<Quantity<Power>, VirtualElementError> {
37 let tetrahedra_dissipation = self
38 .tetrahedra()
39 .iter()
40 .zip(
41 self.tetrahedra_coordinates(nodal_coordinates)
42 .iter()
43 .zip(self.tetrahedra_coordinates(nodal_velocities).iter()),
44 )
45 .map(
46 |(tetrahedron, (tetrahedron_coordinates, tetrahedron_velocities))| {
47 tetrahedron.viscous_dissipation(
48 constitutive_model,
49 tetrahedron_coordinates,
50 tetrahedron_velocities,
51 )
52 },
53 )
54 .sum::<Result<Quantity<Power>, _>>()
55 .map_err(|error| self.upstream(error))?;
56 let polyhedron_dissipation = self
57 .deformation_gradients(nodal_coordinates)
58 .iter()
59 .zip(
60 self.deformation_gradient_rates(nodal_coordinates, nodal_velocities)
61 .iter()
62 .zip(self.integration_weights()),
63 )
64 .map(
65 |(deformation_gradient, (deformation_gradient_rate, integration_weight))| {
66 Ok::<_, ConstitutiveError>(
67 constitutive_model
68 .viscous_dissipation(deformation_gradient, deformation_gradient_rate)?
69 * integration_weight,
70 )
71 },
72 )
73 .sum::<Result<Quantity<Power>, _>>()
74 .map_err(|error| self.upstream(error))?;
75 Ok(polyhedron_dissipation * (1.0 - self.stabilization())
76 + tetrahedra_dissipation * self.stabilization())
77 }
78 fn dissipation_potential(
79 &self,
80 constitutive_model: &C,
81 nodal_coordinates: &ElementNodalCoordinates,
82 nodal_velocities: &ElementNodalVelocities,
83 ) -> Result<Quantity<Power>, VirtualElementError> {
84 let tetrahedra_potential = self
85 .tetrahedra()
86 .iter()
87 .zip(
88 self.tetrahedra_coordinates(nodal_coordinates)
89 .iter()
90 .zip(self.tetrahedra_coordinates(nodal_velocities).iter()),
91 )
92 .map(
93 |(tetrahedron, (tetrahedron_coordinates, tetrahedron_velocities))| {
94 tetrahedron.dissipation_potential(
95 constitutive_model,
96 tetrahedron_coordinates,
97 tetrahedron_velocities,
98 )
99 },
100 )
101 .sum::<Result<Quantity<Power>, _>>()
102 .map_err(|error| self.upstream(error))?;
103 let polyhedron_potential = self
104 .deformation_gradients(nodal_coordinates)
105 .iter()
106 .zip(
107 self.deformation_gradient_rates(nodal_coordinates, nodal_velocities)
108 .iter()
109 .zip(self.integration_weights()),
110 )
111 .map(
112 |(deformation_gradient, (deformation_gradient_rate, integration_weight))| {
113 Ok::<_, ConstitutiveError>(
114 constitutive_model.dissipation_potential(
115 deformation_gradient,
116 deformation_gradient_rate,
117 )? * integration_weight,
118 )
119 },
120 )
121 .sum::<Result<Quantity<Power>, _>>()
122 .map_err(|error| self.upstream(error))?;
123 Ok(polyhedron_potential * (1.0 - self.stabilization())
124 + tetrahedra_potential * self.stabilization())
125 }
126}