conspire/domain/cbm/block/node/solid/elastic/
mod.rs1use 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}