conspire/constitutive/cohesive/elastic/
mod.rs1use crate::{
4 constitutive::{Constitutive, ConstitutiveError, cohesive::Cohesive},
5 math::{Current, Quantity, Tensor, TensorArray, TensorRank2, TensorTuple},
6 mechanics::{Normal, Separation, Traction},
7 units::{Length, Stress, StressPerLength},
8};
9
10type Dyad = TensorRank2<3, Current, Current>;
11type DyadSeparation = TensorRank2<3, Current, Current, Length>;
12
13pub(crate) type StiffnessCohesive = TensorTuple<
14 TensorRank2<3, Current, Current, StressPerLength>,
15 TensorRank2<3, Current, Current, Stress>,
16>;
17
18pub trait Elastic
20where
21 Self: Cohesive,
22{
23 fn traction(
24 &self,
25 separation: Separation,
26 normal: Normal,
27 ) -> Result<Traction, ConstitutiveError> {
28 let normal_component = &separation * &normal;
29 let normal_separation = &normal * normal_component;
30 let tangential_separation = separation - normal_separation;
31 let tangential_component = tangential_separation.norm();
32 let (normal_traction, tangential_traction) =
33 self.tractions(normal_component, tangential_component)?;
34 if !tangential_component.is_zero() {
35 Ok(normal * normal_traction
36 + (tangential_separation / tangential_component) * tangential_traction)
37 } else {
38 Ok(normal * normal_traction)
39 }
40 }
41 fn tractions(
43 &self,
44 normal_separation: Quantity<Length>,
45 tangential_separation: Quantity<Length>,
46 ) -> Result<(Quantity<Stress>, Quantity<Stress>), ConstitutiveError>;
47 fn stiffness(
48 &self,
49 separation: Separation,
50 normal: Normal,
51 ) -> Result<StiffnessCohesive, ConstitutiveError> {
52 let normal_component = &separation * &normal;
53 let normal_separation = &normal * normal_component;
54 let tangential_separation = &separation - normal_separation;
55 let tangential_component = tangential_separation.norm();
56 let (normal_traction, tangential_traction) =
57 self.tractions(normal_component, tangential_component)?;
58 let (k_nn, k_tt) = self.stiffnesses(normal_component, tangential_component)?;
59 let (tangent, ratio, q_t) = if !tangential_component.is_zero() {
60 (
61 tangential_separation / tangential_component,
62 normal_component / tangential_component,
63 tangential_traction / tangential_component,
64 )
65 } else {
66 (Normal::zero(), Quantity::zero(), k_tt)
67 };
68 let nn = Dyad::from((&normal, &normal));
69 let nu = DyadSeparation::from((&normal, &separation));
70 let tt = Dyad::from((&tangent, &tangent));
71 let tu = DyadSeparation::from((&tangent, &separation));
72 let identity = Dyad::identity();
73 let stiffness_u = nn * (k_nn - q_t) + tt * (k_tt - q_t) + &identity * q_t;
74 let stiffness_n = nu * (k_nn - q_t)
75 + identity * (normal_traction - tangential_traction * ratio)
76 - tu * ((k_tt - q_t) * ratio);
77 Ok(TensorTuple(stiffness_u, stiffness_n))
78 }
79 fn stiffnesses(
81 &self,
82 normal_separation: Quantity<Length>,
83 tangential_separation: Quantity<Length>,
84 ) -> Result<(Quantity<StressPerLength>, Quantity<StressPerLength>), ConstitutiveError>;
85}
86
87#[derive(Clone, Debug)]
89pub struct LinearElastic {
90 pub normal_stiffness: Quantity<StressPerLength>,
92 pub tangential_stiffness: Quantity<StressPerLength>,
94}
95
96impl Constitutive for LinearElastic {}
97
98impl Cohesive for LinearElastic {}
99
100impl LinearElastic {
101 fn normal_stiffness(&self) -> Quantity<StressPerLength> {
103 self.normal_stiffness
104 }
105 fn tangential_stiffness(&self) -> Quantity<StressPerLength> {
107 self.tangential_stiffness
108 }
109}
110
111impl Elastic for LinearElastic {
112 fn tractions(
113 &self,
114 normal_separation: Quantity<Length>,
115 tangential_separation: Quantity<Length>,
116 ) -> Result<(Quantity<Stress>, Quantity<Stress>), ConstitutiveError> {
117 Ok((
118 self.normal_stiffness() * normal_separation,
119 self.tangential_stiffness() * tangential_separation,
120 ))
121 }
122 fn stiffnesses(
123 &self,
124 _normal_separation: Quantity<Length>,
125 _tangential_separation: Quantity<Length>,
126 ) -> Result<(Quantity<StressPerLength>, Quantity<StressPerLength>), ConstitutiveError> {
127 Ok((self.normal_stiffness(), self.tangential_stiffness()))
128 }
129}