1#[cfg(feature = "serde")]
3use crate::traits::ConvertToSerializable;
4use crate::types::Scalar;
5use itertools::izip;
6#[cfg(feature = "serde")]
7use ndelement::{
8 ciarlet::{CiarletElement, lagrange},
9 map::IdentityMap,
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::collections::HashMap;
19use std::fmt::{Debug, Formatter};
20
21pub struct MixedGeometry<T: Scalar, E: MappedFiniteElement> {
23 points: DynArray<T, 2>,
24 cells: Vec<DynArray<usize, 2>>,
25 elements: Vec<HashMap<ReferenceCellType, E>>,
26 pub(crate) insertion_indices_to_element_indices: Vec<usize>,
27 pub(crate) insertion_indices_to_cell_indices: Vec<usize>,
28}
29
30impl<T: Scalar, E: MappedFiniteElement> Debug for MixedGeometry<T, E> {
31 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), std::fmt::Error> {
32 f.debug_struct("MixedGeometry")
33 .field("points", &self.points)
34 .field("cells", &self.cells)
35 .finish()
36 }
37}
38
39#[cfg(feature = "serde")]
40#[derive(serde::Serialize, Debug, serde::Deserialize)]
41#[serde(bound = "for<'de2> T: serde::Deserialize<'de2>")]
42pub struct SerializableGeometry<T: Scalar + serde::Serialize>
43where
44 for<'de2> T: serde::Deserialize<'de2>,
45{
46 points: (Vec<T>, [usize; 2]),
47 cells: Vec<(Vec<usize>, [usize; 2])>,
48 elements: Vec<HashMap<ReferenceCellType, usize>>,
49 insertion_indices_to_element_indices: Vec<usize>,
50 insertion_indices_to_cell_indices: Vec<usize>,
51}
52
53#[cfg(feature = "serde")]
54impl<T: Scalar + serde::Serialize> ConvertToSerializable
55 for MixedGeometry<T, CiarletElement<T, IdentityMap, T>>
56where
57 for<'de2> T: serde::Deserialize<'de2>,
58{
59 type SerializableType = SerializableGeometry<T>;
60 fn to_serializable(&self) -> SerializableGeometry<T> {
61 SerializableGeometry {
62 points: (self.points.data().unwrap().to_vec(), self.points.shape()),
63 cells: self
64 .cells
65 .iter()
66 .map(|c| (c.data().unwrap().to_vec(), c.shape()))
67 .collect::<Vec<_>>(),
68 elements: self
69 .elements
70 .iter()
71 .map(|a| {
72 a.iter()
73 .map(|(b, c)| (*b, c.lagrange_superdegree()))
74 .collect::<HashMap<_, _>>()
75 })
76 .collect::<Vec<_>>(),
77 insertion_indices_to_element_indices: self.insertion_indices_to_element_indices.clone(),
78 insertion_indices_to_cell_indices: self.insertion_indices_to_cell_indices.clone(),
79 }
80 }
81 fn from_serializable(s: SerializableGeometry<T>) -> Self {
82 Self {
83 points: {
84 let (data, shape) = &s.points;
85 let mut p = DynArray::<T, 2>::from_shape(*shape);
86 p.data_mut().unwrap().copy_from_slice(data.as_slice());
87 p
88 },
89 cells: s
90 .cells
91 .iter()
92 .map(|(data, shape)| {
93 let mut c = DynArray::<usize, 2>::from_shape(*shape);
94 c.data_mut().unwrap().copy_from_slice(data.as_slice());
95 c
96 })
97 .collect::<Vec<_>>(),
98 elements: s
99 .elements
100 .iter()
101 .map(|a| {
102 a.iter()
103 .map(|(cell, degree)| {
104 (
105 *cell,
106 lagrange::create(*cell, *degree, Continuity::Standard),
107 )
108 })
109 .collect::<HashMap<_, _>>()
110 })
111 .collect::<Vec<_>>(),
112 insertion_indices_to_element_indices: s.insertion_indices_to_element_indices,
113 insertion_indices_to_cell_indices: s.insertion_indices_to_cell_indices,
114 }
115 }
116}
117
118impl<T: Scalar, E: MappedFiniteElement> MixedGeometry<T, E> {
119 pub fn new(
121 cell_types_in: &[ReferenceCellType],
122 points: DynArray<T, 2>,
123 cells_input: &[usize],
124 element_families: &[impl ElementFamily<
125 T = T,
126 CellType = ReferenceCellType,
127 FiniteElement = E,
128 >],
129 cell_families: &[usize],
130 ) -> Self {
131 let mut element_info = HashMap::new();
132 let mut elements = vec![];
133 let mut cells = vec![];
134 let mut cell_counts = vec![];
135 let mut points_per_cell = vec![];
136 let mut insertion_indices_to_element_indices = vec![];
137 let mut insertion_indices_to_cell_indices = vec![];
138
139 let mut start = 0;
140
141 for (findex, cell_type) in izip!(cell_families, cell_types_in) {
142 let eindex = *element_info.entry((findex, cell_type)).or_insert_with(|| {
143 let n = elements.len();
144
145 let mut new_e = HashMap::new();
146 for et in reference_cell::entity_types(*cell_type)
147 .iter()
148 .skip(1)
149 .filter(|i| !i.is_empty())
150 {
151 for e in et {
152 new_e
153 .entry(*e)
154 .or_insert(element_families[*findex].element(*e));
155 }
156 }
157 points_per_cell.push(new_e[cell_type].dim());
158 elements.push(new_e);
159 cells.push(vec![]);
160 cell_counts.push(0);
161 n
162 });
163
164 insertion_indices_to_element_indices.push(eindex);
165 insertion_indices_to_cell_indices.push(cell_counts[eindex]);
166 for i in 0..points_per_cell[eindex] {
167 cells[eindex].push(cells_input[start + i]);
168 }
169 cell_counts[eindex] += 1;
170 start += points_per_cell[eindex];
171 }
172 let cells = izip!(cell_counts, points_per_cell, cells)
173 .map(|(ncells, npts, c_in)| {
174 let mut c = rlst_dynamic_array!(usize, [npts, ncells]);
175 c.data_mut().unwrap().copy_from_slice(&c_in);
176 c
177 })
178 .collect::<Vec<_>>();
179 Self {
180 points,
181 cells,
182 elements,
183 insertion_indices_to_element_indices,
184 insertion_indices_to_cell_indices,
185 }
186 }
187 pub fn dim(&self) -> usize {
189 self.points().shape()[0]
190 }
191 pub fn points(&self) -> &DynArray<T, 2> {
193 &self.points
194 }
195 pub fn cells(&self, element_index: usize) -> &DynArray<usize, 2> {
197 &self.cells[element_index]
198 }
199 pub fn element(&self, element_index: usize) -> &E {
201 for (ct, e) in &self.elements[element_index] {
202 if reference_cell::dim(*ct) == self.dim() {
203 return e;
204 }
205 }
206 panic!("Could not find element");
207 }
208 pub fn element_count(&self) -> usize {
210 self.elements.len()
211 }
212}