Skip to main content

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

1use 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}