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