conspire/domain/cbm/block/node/solid/viscoelastic/
mod.rs1use super::{super::Node, SolidElement};
2use crate::{
3 constitutive::{ConstitutiveError, solid::viscoelastic::Viscoelastic},
4 domain::{NodalCoordinates, NodalVelocities},
5 math::{ContractSecondFourthWithFirst, Current, TensorRank1, TensorRank2},
6 units::{Force, ForcePerVelocity},
7};
8
9pub use crate::domain::block::element::solid::viscoelastic::ViscoelasticElement;
10
11type NodalForce = TensorRank1<3, Current, Force>;
12type NodalDamping = TensorRank2<3, Current, Current, ForcePerVelocity>;
13
14impl<C> ViscoelasticElement<C> for Node
15where
16 C: Viscoelastic,
17{
18 type Forces = Vec<NodalForce>;
19 type Dampings = Vec<Vec<NodalDamping>>;
20 type Error = ConstitutiveError;
21 fn nodal_forces(
22 &self,
23 constitutive_model: &C,
24 nodal_coordinates: &NodalCoordinates<3>,
25 nodal_velocities: &NodalVelocities<3>,
26 ) -> Result<Vec<NodalForce>, ConstitutiveError> {
27 let first_piola_kirchhoff_stress = constitutive_model.first_piola_kirchhoff_stress(
28 &self.deformation_gradients(nodal_coordinates),
29 &self.deformation_gradient_rates(nodal_coordinates, nodal_velocities),
30 )?;
31 Ok(self
32 .gradient_vectors()
33 .iter()
34 .map(|gradient_vector| (&first_piola_kirchhoff_stress * gradient_vector) * self.volume)
35 .collect())
36 }
37 fn nodal_stiffnesses(
38 &self,
39 constitutive_model: &C,
40 nodal_coordinates: &NodalCoordinates<3>,
41 nodal_velocities: &NodalVelocities<3>,
42 ) -> Result<Vec<Vec<NodalDamping>>, ConstitutiveError> {
43 let first_piola_kirchhoff_rate_tangent_stiffness = constitutive_model
44 .first_piola_kirchhoff_rate_tangent_stiffness(
45 &self.deformation_gradients(nodal_coordinates),
46 &self.deformation_gradient_rates(nodal_coordinates, nodal_velocities),
47 )?;
48 Ok(self
49 .gradient_vectors()
50 .iter()
51 .map(|gradient_vector_a| {
52 self.gradient_vectors()
53 .iter()
54 .map(|gradient_vector_b| {
55 first_piola_kirchhoff_rate_tangent_stiffness
56 .contract_second_fourth_with_first(gradient_vector_a, gradient_vector_b)
57 * self.volume
58 })
59 .collect()
60 })
61 .collect())
62 }
63}