conspire/domain/fem/block/element/cohesive/
mod.rs1pub mod elastic;
2pub mod linear;
3
4use crate::{
5 fem::block::element::{
6 ElementNodalCoordinates, ElementNodalEitherCoordinates, FiniteElement,
7 ShapeFunctionsAtIntegrationPoints, surface::SurfaceFiniteElement,
8 },
9 math::{ScalarList, Tensor},
10 mechanics::{CurrentCoordinate, NormalGradients},
11};
12use std::fmt::{self, Debug, Formatter};
13
14pub type Separation = CurrentCoordinate;
15pub type Separations<const P: usize> = ElementNodalCoordinates<P>;
16
17const M: usize = 2;
18
19pub struct CohesiveElement<const G: usize, const N: usize, const O: usize> {
20 integration_weights: ScalarList<G>,
21}
22
23impl<const G: usize, const N: usize, const O: usize> Debug for CohesiveElement<G, N, O> {
24 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
25 let element = match (G, N, O) {
26 (3, 6, 1) => "LinearCohesiveWedge",
27 (4, 8, 1) => "LinearCohesiveHexahedron",
28 _ => panic!(),
29 };
30 write!(f, "{element} {{ G: {G}, N: {N} }}",)
31 }
32}
33
34impl<const G: usize, const N: usize, const O: usize, const P: usize> SurfaceFiniteElement<G, N, P>
35 for CohesiveElement<G, N, O>
36where
37 Self: FiniteElement<G, M, N, P>,
38{
39}
40
41pub trait CohesiveFiniteElement<const G: usize, const N: usize, const P: usize>
42where
43 Self: SurfaceFiniteElement<G, N, P>,
44{
45 fn nodal_mid_surface<const I: usize>(
46 nodal_coordinates: &ElementNodalEitherCoordinates<I, N>,
47 ) -> ElementNodalEitherCoordinates<I, P>;
48 fn nodal_separations(nodal_coordinates: &ElementNodalCoordinates<N>) -> Separations<P>;
49 fn normal_gradients_full(
50 nodal_mid_surface: &ElementNodalCoordinates<P>,
51 ) -> NormalGradients<N, G>;
52 fn separations(nodal_coordinates: &ElementNodalCoordinates<N>) -> Separations<G> {
53 Self::shape_functions_at_integration_points()
54 .into_iter()
55 .map(|shape_functions| {
56 Self::nodal_separations(nodal_coordinates)
57 .into_iter()
58 .zip(shape_functions.iter())
59 .map(|(nodal_separation, shape_function)| nodal_separation * shape_function)
60 .sum()
61 })
62 .collect()
63 }
64 fn signed_shape_functions() -> ShapeFunctionsAtIntegrationPoints<G, N> {
65 Self::shape_functions_at_integration_points()
66 .into_iter()
67 .map(|shape_functions| {
68 shape_functions
69 .iter()
70 .chain(shape_functions.iter())
71 .zip(Self::signs())
72 .map(|(shape_function, sign)| shape_function * sign)
73 .collect()
74 })
75 .collect()
76 }
77 fn signs() -> ScalarList<N>;
78}