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

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