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