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 DampingList2D, 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>;
24pub type ElementNodalDampingsSolid<const N: usize> = DampingList2D<N>;
25
26pub trait SolidFiniteElement<const G: usize, const M: usize, const N: usize, const P: usize>
27where
28 Self: FiniteElement<G, M, N, P>,
29{
30 fn deformation_gradients(
31 &self,
32 nodal_coordinates: &ElementNodalCoordinates<N>,
33 ) -> DeformationGradientList<G>;
34 fn deformation_gradient_rates(
35 &self,
36 nodal_coordinates: &ElementNodalCoordinates<N>,
37 nodal_velocities: &ElementNodalVelocities<N>,
38 ) -> DeformationGradientRateList<G>;
39}
40
41impl<const G: usize, const N: usize, const O: usize, const P: usize> SolidFiniteElement<G, 3, N, P>
42 for Element<3, G, N, O>
43where
44 Self: FiniteElement<G, 3, N, P>,
45{
46 fn deformation_gradients(
47 &self,
48 nodal_coordinates: &ElementNodalCoordinates<N>,
49 ) -> DeformationGradientList<G> {
50 self.gradient_vectors()
51 .iter()
52 .map(|gradient_vectors| {
53 nodal_coordinates
54 .iter()
55 .zip(gradient_vectors)
56 .map(|(nodal_coordinate, gradient_vector)| {
57 DeformationGradient::from((nodal_coordinate, gradient_vector))
58 })
59 .sum()
60 })
61 .collect()
62 }
63 fn deformation_gradient_rates(
64 &self,
65 _: &ElementNodalCoordinates<N>,
66 nodal_velocities: &ElementNodalVelocities<N>,
67 ) -> DeformationGradientRateList<G> {
68 self.gradient_vectors()
69 .iter()
70 .map(|gradient_vectors| {
71 nodal_velocities
72 .iter()
73 .zip(gradient_vectors)
74 .map(|(nodal_velocity, gradient_vector)| {
75 DeformationGradientRate::from((nodal_velocity, gradient_vector))
76 })
77 .sum()
78 })
79 .collect()
80 }
81}
82
83impl<const G: usize, const N: usize, const O: usize> SolidFiniteElement<G, 2, N, N>
84 for SurfaceElement<G, N, O>
85where
86 Self: SurfaceFiniteElement<G, N, N>,
87{
88 fn deformation_gradients(
89 &self,
90 nodal_coordinates: &ElementNodalCoordinates<N>,
91 ) -> DeformationGradientList<G> {
92 self.gradient_vectors()
93 .iter()
94 .zip(
95 Self::normals(nodal_coordinates)
96 .iter()
97 .zip(self.reference_normals()),
98 )
99 .map(|(gradient_vectors, normal_and_reference_normal)| {
100 nodal_coordinates
101 .iter()
102 .zip(gradient_vectors)
103 .map(|(nodal_coordinate, gradient_vector)| {
104 DeformationGradient::from((nodal_coordinate, gradient_vector))
105 })
106 .sum::<DeformationGradient>()
107 + DeformationGradient::from(normal_and_reference_normal)
108 })
109 .collect()
110 }
111 fn deformation_gradient_rates(
112 &self,
113 nodal_coordinates: &ElementNodalCoordinates<N>,
114 nodal_velocities: &ElementNodalVelocities<N>,
115 ) -> DeformationGradientRateList<G> {
116 self.gradient_vectors()
117 .iter()
118 .zip(
119 Self::normal_rates(nodal_coordinates, nodal_velocities)
120 .iter()
121 .zip(self.reference_normals()),
122 )
123 .map(|(gradient_vectors, normal_rate_and_reference_normal)| {
124 nodal_velocities
125 .iter()
126 .zip(gradient_vectors)
127 .map(|(nodal_velocity, gradient_vector)| {
128 DeformationGradientRate::from((nodal_velocity, gradient_vector))
129 })
130 .sum::<DeformationGradientRate>()
131 + DeformationGradientRate::from(normal_rate_and_reference_normal)
132 })
133 .collect()
134 }
135}