Skip to main content

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