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
19#[derive(Clone)]
20pub struct CohesiveElement<const G: usize, const N: usize, const O: usize> {
21 integration_weights: ScalarList<G>,
22}
23
24impl<const G: usize, const N: usize, const O: usize> Debug for CohesiveElement<G, N, O> {
25 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
26 let element = match (G, N, O) {
27 (3, 6, 1) => "LinearCohesiveWedge",
28 (4, 8, 1) => "LinearCohesiveHexahedron",
29 _ => panic!(),
30 };
31 write!(f, "{element} {{ G: {G}, N: {N} }}",)
32 }
33}
34
35impl<const G: usize, const N: usize, const O: usize, const P: usize> SurfaceFiniteElement<G, N, P>
36 for CohesiveElement<G, N, O>
37where
38 Self: FiniteElement<G, M, N, P>,
39{
40}
41
42pub trait CohesiveFiniteElement<const G: usize, const N: usize, const P: usize>
43where
44 Self: SurfaceFiniteElement<G, N, P>,
45{
46 fn nodal_mid_surface<const I: usize>(
47 nodal_coordinates: &ElementNodalEitherCoordinates<I, N>,
48 ) -> ElementNodalEitherCoordinates<I, P>;
49 fn nodal_separations(nodal_coordinates: &ElementNodalCoordinates<N>) -> Separations<P>;
50 fn normal_gradients_full(
51 nodal_mid_surface: &ElementNodalCoordinates<P>,
52 ) -> NormalGradients<N, G>;
53 fn separations(nodal_coordinates: &ElementNodalCoordinates<N>) -> Separations<G> {
54 Self::shape_functions_at_integration_points()
55 .into_iter()
56 .map(|shape_functions| {
57 Self::nodal_separations(nodal_coordinates)
58 .into_iter()
59 .zip(shape_functions.iter())
60 .map(|(nodal_separation, shape_function)| nodal_separation * shape_function)
61 .sum()
62 })
63 .collect()
64 }
65 fn signed_shape_functions() -> ShapeFunctionsAtIntegrationPoints<G, N> {
66 Self::shape_functions_at_integration_points()
67 .into_iter()
68 .map(|shape_functions| {
69 shape_functions
70 .iter()
71 .chain(shape_functions.iter())
72 .zip(Self::signs())
73 .map(|(shape_function, sign)| shape_function * sign)
74 .collect()
75 })
76 .collect()
77 }
78 fn signs() -> ScalarList<N>;
79}