Skip to main content

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

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