ndmesh/geometry/single_element/
geometry.rs1#[cfg(feature = "serde")]
3use crate::traits::ConvertToSerializable;
4use crate::types::Scalar;
5#[cfg(feature = "serde")]
6use ndelement::{
7 ciarlet::{CiarletElement, lagrange},
8 map::IdentityMap,
9 traits::FiniteElement,
10 types::Continuity,
11};
12use ndelement::{
13 reference_cell,
14 traits::{ElementFamily, MappedFiniteElement},
15 types::ReferenceCellType,
16};
17use rlst::{DynArray, rlst_dynamic_array};
18use std::fmt::{Debug, Formatter};
19
20pub struct SingleElementGeometry<T: Scalar, E: MappedFiniteElement> {
22 points: DynArray<T, 2>,
23 cells: DynArray<usize, 2>,
24 elements: Vec<E>,
25}
26
27impl<T: Scalar, E: MappedFiniteElement> Debug for SingleElementGeometry<T, E> {
28 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
29 f.debug_struct("SingleElementGeometry")
30 .field("points", &self.points)
31 .field("cells", &self.cells)
32 .finish()
33 }
34}
35
36#[cfg(feature = "serde")]
37#[derive(serde::Serialize, Debug, serde::Deserialize)]
38#[serde(bound = "for<'de2> T: serde::Deserialize<'de2>")]
39pub struct SerializableGeometry<T: Scalar + serde::Serialize>
40where
41 for<'de2> T: serde::Deserialize<'de2>,
42{
43 points: (Vec<T>, [usize; 2]),
44 cells: (Vec<usize>, [usize; 2]),
45 elements: Vec<(ReferenceCellType, usize)>,
46}
47
48#[cfg(feature = "serde")]
49impl<T: Scalar + serde::Serialize> ConvertToSerializable
50 for SingleElementGeometry<T, CiarletElement<T, IdentityMap, T>>
51where
52 for<'de2> T: serde::Deserialize<'de2>,
53{
54 type SerializableType = SerializableGeometry<T>;
55 fn to_serializable(&self) -> SerializableGeometry<T> {
56 SerializableGeometry {
57 points: (self.points.data().unwrap().to_vec(), self.points.shape()),
58 cells: (self.cells.data().unwrap().to_vec(), self.cells.shape()),
59 elements: self
60 .elements
61 .iter()
62 .map(|e| (e.cell_type(), e.lagrange_superdegree()))
63 .collect::<Vec<_>>(),
64 }
65 }
66 fn from_serializable(s: SerializableGeometry<T>) -> Self {
67 Self {
68 points: {
69 let (data, shape) = &s.points;
70 let mut p = DynArray::<T, 2>::from_shape(*shape);
71 p.data_mut().unwrap().copy_from_slice(data.as_slice());
72 p
73 },
74 cells: {
75 let (data, shape) = &s.cells;
76 let mut c = DynArray::<usize, 2>::from_shape(*shape);
77 c.data_mut().unwrap().copy_from_slice(data.as_slice());
78 c
79 },
80 elements: s
81 .elements
82 .iter()
83 .map(|(cell, degree)| {
84 lagrange::create(
85 *cell,
86 *degree,
87 Continuity::Standard,
88 lagrange::Variant::Equispaced,
89 )
90 })
91 .collect::<Vec<_>>(),
92 }
93 }
94}
95
96impl<T: Scalar, E: MappedFiniteElement> SingleElementGeometry<T, E> {
97 pub fn new(
99 cell_type: ReferenceCellType,
100 points: DynArray<T, 2>,
101 cells_input: &[usize],
102 element_family: &impl ElementFamily<T = T, CellType = ReferenceCellType, FiniteElement = E>,
103 ) -> Self {
104 let mut elements = vec![];
105 for et in reference_cell::entity_types(cell_type)
106 .iter()
107 .skip(1)
108 .filter(|i| !i.is_empty())
109 {
110 for c in et.iter().skip(1) {
111 if *c != et[0] {
112 panic!("Unsupported cell type for SingleElementGeometry: {cell_type:?}");
113 }
114 }
115 elements.push(element_family.element(et[0]));
116 }
117 let points_per_cell = elements[elements.len() - 1].dim();
118 let mut cells = rlst_dynamic_array!(
119 usize,
120 [points_per_cell, cells_input.len() / points_per_cell]
121 );
122 cells.data_mut().unwrap().copy_from_slice(cells_input);
123 Self {
124 points,
125 cells,
126 elements,
127 }
128 }
129 pub fn dim(&self) -> usize {
131 self.points().shape()[0]
132 }
133 pub fn points(&self) -> &DynArray<T, 2> {
135 &self.points
136 }
137 pub fn cells(&self) -> &DynArray<usize, 2> {
139 &self.cells
140 }
141 pub fn entity_element(&self, tdim: usize) -> &E {
143 &self.elements[tdim - 1]
144 }
145 pub fn element(&self) -> &E {
147 &self.elements[self.elements.len() - 1]
148 }
149}