conspire/domain/fem/block/element/solid/
mod.rs

1pub 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}