Skip to main content

conspire/domain/cbm/block/node/solid/viscoelastic/
mod.rs

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