conspire/domain/fem/block/element/solid/
mod.rs1pub mod elastic;
2pub mod elastic_hyperviscous;
3pub mod elastic_viscoplastic;
4pub mod hyperelastic;
5pub mod hyperviscoelastic;
6pub mod viscoelastic;
7pub mod viscoplastic;
8
9use crate::{
10 fem::block::element::{
11 Element, ElementNodalCoordinates, ElementNodalVelocities, FiniteElement,
12 surface::{SurfaceElement, SurfaceFiniteElement},
13 },
14 math::Tensor,
15 mechanics::{
16 DeformationGradient, DeformationGradientList, DeformationGradientRate,
17 DeformationGradientRateList, ForceList, StiffnessList2D,
18 },
19};
20
21pub type ElementNodalForcesSolid<const N: usize> = ForceList<N>;
22pub type ElementNodalStiffnessesSolid<const N: usize> = StiffnessList2D<N>;
23
24pub trait SolidFiniteElement<const G: usize, const M: usize, const N: usize, const P: usize>
25where
26 Self: FiniteElement<G, M, N, P>,
27{
28 fn deformation_gradients(
29 &self,
30 nodal_coordinates: &ElementNodalCoordinates<N>,
31 ) -> DeformationGradientList<G>;
32 fn deformation_gradient_rates(
33 &self,
34 nodal_coordinates: &ElementNodalCoordinates<N>,
35 nodal_velocities: &ElementNodalVelocities<N>,
36 ) -> DeformationGradientRateList<G>;
37}
38
39impl<const G: usize, const N: usize, const O: usize, const P: usize> SolidFiniteElement<G, 3, N, P>
40 for Element<G, N, O>
41where
42 Self: FiniteElement<G, 3, N, P>,
43{
44 fn deformation_gradients(
45 &self,
46 nodal_coordinates: &ElementNodalCoordinates<N>,
47 ) -> DeformationGradientList<G> {
48 self.gradient_vectors()
49 .iter()
50 .map(|gradient_vectors| {
51 nodal_coordinates
52 .iter()
53 .zip(gradient_vectors)
54 .map(|(nodal_coordinate, gradient_vector)| {
55 (nodal_coordinate, gradient_vector).into()
56 })
57 .sum()
58 })
59 .collect()
60 }
61 fn deformation_gradient_rates(
62 &self,
63 _: &ElementNodalCoordinates<N>,
64 nodal_velocities: &ElementNodalVelocities<N>,
65 ) -> DeformationGradientRateList<G> {
66 self.gradient_vectors()
67 .iter()
68 .map(|gradient_vectors| {
69 nodal_velocities
70 .iter()
71 .zip(gradient_vectors)
72 .map(|(nodal_velocity, gradient_vector)| {
73 (nodal_velocity, gradient_vector).into()
74 })
75 .sum()
76 })
77 .collect()
78 }
79}
80
81impl<const G: usize, const N: usize, const O: usize> SolidFiniteElement<G, 2, N, N>
82 for SurfaceElement<G, N, O>
83where
84 Self: SurfaceFiniteElement<G, N, N>,
85{
86 fn deformation_gradients(
87 &self,
88 nodal_coordinates: &ElementNodalCoordinates<N>,
89 ) -> DeformationGradientList<G> {
90 self.gradient_vectors()
91 .iter()
92 .zip(
93 Self::normals(nodal_coordinates)
94 .iter()
95 .zip(self.reference_normals()),
96 )
97 .map(|(gradient_vectors, normal_and_reference_normal)| {
98 nodal_coordinates
99 .iter()
100 .zip(gradient_vectors)
101 .map(|(nodal_coordinate, gradient_vector)| {
102 (nodal_coordinate, gradient_vector).into()
103 })
104 .sum::<DeformationGradient>()
105 + DeformationGradient::from(normal_and_reference_normal)
106 })
107 .collect()
108 }
109 fn deformation_gradient_rates(
110 &self,
111 nodal_coordinates: &ElementNodalCoordinates<N>,
112 nodal_velocities: &ElementNodalVelocities<N>,
113 ) -> DeformationGradientRateList<G> {
114 self.gradient_vectors()
115 .iter()
116 .zip(
117 Self::normal_rates(nodal_coordinates, nodal_velocities)
118 .iter()
119 .zip(self.reference_normals()),
120 )
121 .map(|(gradient_vectors, normal_rate_and_reference_normal)| {
122 nodal_velocities
123 .iter()
124 .zip(gradient_vectors)
125 .map(|(nodal_velocity, gradient_vector)| {
126 (nodal_velocity, gradient_vector).into()
127 })
128 .sum::<DeformationGradientRate>()
129 + DeformationGradientRate::from(normal_rate_and_reference_normal)
130 })
131 .collect()
132 }
133}