1#[cfg(feature = "serde")]
3use crate::traits::ConvertToSerializable;
4use crate::{
5 traits::{Entity, Grid},
6 types::Ownership,
7};
8#[cfg(feature = "serde")]
9use itertools::izip;
10use rlst::{Array, ValueArrayImpl};
11#[cfg(feature = "serde")]
12use std::hash::Hash;
13use std::{collections::HashMap, fmt::Debug};
14
15mod single_element;
16pub use single_element::{SingleElementGrid, SingleElementGridBuilder};
17
18mod mixed;
19pub use mixed::{MixedGrid, MixedGridBuilder};
20
21#[derive(Debug)]
23pub struct GridEntity<E: Entity> {
24 serial_entity: E,
25 ownership: Ownership,
26 global_index: usize,
27}
28
29impl<E: Entity> GridEntity<E> {
30 pub fn new(serial_entity: E, ownership: &[Ownership], global_indices: &[usize]) -> Self {
32 let index = serial_entity.local_index();
33 Self {
34 serial_entity,
35 ownership: ownership[index],
36 global_index: global_indices[index],
37 }
38 }
39}
40impl<E: Entity> Entity for GridEntity<E> {
41 type T = E::T;
42 type EntityDescriptor = E::EntityDescriptor;
43 type Topology<'a>
44 = E::Topology<'a>
45 where
46 Self: 'a;
47 type Geometry<'a>
48 = E::Geometry<'a>
49 where
50 Self: 'a;
51 fn entity_type(&self) -> E::EntityDescriptor {
52 self.serial_entity.entity_type()
53 }
54 fn local_index(&self) -> usize {
55 self.serial_entity.local_index()
56 }
57 fn global_index(&self) -> usize {
58 self.global_index
59 }
60 fn geometry(&self) -> Self::Geometry<'_> {
61 self.serial_entity.geometry()
62 }
63 fn topology(&self) -> Self::Topology<'_> {
64 self.serial_entity.topology()
65 }
66 fn ownership(&self) -> Ownership {
67 self.ownership
68 }
69 fn id(&self) -> Option<usize> {
70 self.serial_entity.id()
71 }
72}
73
74#[derive(Debug)]
76pub struct GridEntityIter<'a, E: Entity, EntityIter: Iterator<Item = E>> {
77 iter: EntityIter,
78 ownership: &'a [Ownership],
79 global_indices: &'a [usize],
80}
81
82impl<'a, E: Entity, EntityIter: Iterator<Item = E>> GridEntityIter<'a, E, EntityIter> {
83 pub fn new(iter: EntityIter, ownership: &'a [Ownership], global_indices: &'a [usize]) -> Self {
85 Self {
86 iter,
87 ownership,
88 global_indices,
89 }
90 }
91}
92impl<E: Entity, EntityIter: Iterator<Item = E>> Iterator for GridEntityIter<'_, E, EntityIter> {
93 type Item = GridEntity<E>;
94
95 fn next(&mut self) -> Option<GridEntity<E>> {
96 let entity = self.iter.next();
97 entity.map(|e| GridEntity::new(e, self.ownership, self.global_indices))
98 }
99}
100
101#[derive(Debug)]
103pub struct LocalGrid<G: Grid + Sync> {
104 serial_grid: G,
105 ownership: HashMap<G::EntityDescriptor, Vec<Ownership>>,
106 global_indices: HashMap<G::EntityDescriptor, Vec<usize>>,
107}
108
109#[cfg(feature = "serde")]
110#[derive(serde::Serialize, Debug, serde::Deserialize)]
111#[serde(bound = "for<'de2> S: serde::Deserialize<'de2>")]
112pub struct SerializableLocalGrid<EntityDescriptor: serde::Serialize, S: serde::Serialize>
114where
115 for<'de2> S: serde::Deserialize<'de2>,
116 for<'de2> EntityDescriptor: serde::Deserialize<'de2>,
117{
118 serial_grid: S,
119 ownership_keys: Vec<EntityDescriptor>,
120 ownership_values: Vec<Vec<Ownership>>,
121 global_indices_keys: Vec<EntityDescriptor>,
122 global_indices_values: Vec<Vec<usize>>,
123}
124
125#[cfg(feature = "serde")]
126impl<
127 S: serde::Serialize,
128 EntityDescriptor: Debug + PartialEq + Eq + Clone + Copy + Hash + serde::Serialize,
129 G: Grid<EntityDescriptor = EntityDescriptor> + Sync + ConvertToSerializable<SerializableType = S>,
130> ConvertToSerializable for LocalGrid<G>
131where
132 for<'de2> S: serde::Deserialize<'de2>,
133 for<'de2> EntityDescriptor: serde::Deserialize<'de2>,
134{
135 type SerializableType = SerializableLocalGrid<G::EntityDescriptor, S>;
136 fn to_serializable(&self) -> SerializableLocalGrid<G::EntityDescriptor, S> {
137 let mut ownership_keys = vec![];
138 let mut ownership_values = vec![];
139 for (i, j) in &self.ownership {
140 ownership_keys.push(*i);
141 ownership_values.push(j.clone());
142 }
143 let mut global_indices_keys = vec![];
144 let mut global_indices_values = vec![];
145 for (i, j) in &self.global_indices {
146 global_indices_keys.push(*i);
147 global_indices_values.push(j.clone());
148 }
149 SerializableLocalGrid {
150 serial_grid: self.serial_grid.to_serializable(),
151 ownership_keys,
152 ownership_values,
153 global_indices_keys,
154 global_indices_values,
155 }
156 }
157 fn from_serializable(s: SerializableLocalGrid<G::EntityDescriptor, S>) -> Self {
158 Self {
159 serial_grid: G::from_serializable(s.serial_grid),
160 ownership: {
161 let mut m = HashMap::new();
162 for (i, j) in izip!(s.ownership_keys, s.ownership_values) {
163 m.insert(i, j);
164 }
165 m
166 },
167 global_indices: {
168 let mut m = HashMap::new();
169 for (i, j) in izip!(s.global_indices_keys, s.global_indices_values) {
170 m.insert(i, j);
171 }
172 m
173 },
174 }
175 }
176}
177
178impl<G: Grid + Sync> LocalGrid<G> {
179 pub fn new(
181 serial_grid: G,
182 ownership: HashMap<G::EntityDescriptor, Vec<Ownership>>,
183 global_indices: HashMap<G::EntityDescriptor, Vec<usize>>,
184 ) -> Self {
185 Self {
186 serial_grid,
187 ownership,
188 global_indices,
189 }
190 }
191}
192impl<G: Grid + Sync> Grid for LocalGrid<G> {
193 type T = G::T;
194 type Entity<'a>
195 = GridEntity<G::Entity<'a>>
196 where
197 Self: 'a;
198 type GeometryMap<'a>
199 = G::GeometryMap<'a>
200 where
201 Self: 'a;
202 type EntityDescriptor = G::EntityDescriptor;
203 type EntityIter<'a>
204 = GridEntityIter<'a, G::Entity<'a>, G::EntityIter<'a>>
205 where
206 Self: 'a;
207
208 fn geometry_dim(&self) -> usize {
209 self.serial_grid.geometry_dim()
210 }
211 fn topology_dim(&self) -> usize {
212 self.serial_grid.topology_dim()
213 }
214
215 fn entity(
216 &self,
217 entity_type: Self::EntityDescriptor,
218 serial_index: usize,
219 ) -> Option<Self::Entity<'_>> {
220 self.serial_grid.entity(entity_type, serial_index).map(|e| {
221 GridEntity::new(
222 e,
223 &self.ownership[&entity_type],
224 &self.global_indices[&entity_type],
225 )
226 })
227 }
228
229 fn entity_types(&self, dim: usize) -> &[Self::EntityDescriptor] {
230 self.serial_grid.entity_types(dim)
231 }
232
233 fn entity_count(&self, entity_type: Self::EntityDescriptor) -> usize {
234 self.serial_grid.entity_count(entity_type)
235 }
236
237 fn entity_iter(&self, entity_type: Self::EntityDescriptor) -> Self::EntityIter<'_> {
238 GridEntityIter::new(
239 self.serial_grid.entity_iter(entity_type),
240 &self.ownership[&entity_type],
241 &self.global_indices[&entity_type],
242 )
243 }
244
245 fn entity_from_id(
246 &self,
247 entity_type: Self::EntityDescriptor,
248 id: usize,
249 ) -> Option<Self::Entity<'_>> {
250 self.serial_grid.entity_from_id(entity_type, id).map(|e| {
251 GridEntity::new(
252 e,
253 &self.ownership[&entity_type],
254 &self.global_indices[&entity_type],
255 )
256 })
257 }
258
259 fn geometry_map<Array2Impl: ValueArrayImpl<Self::T, 2>>(
260 &self,
261 entity_type: Self::EntityDescriptor,
262 geometry_degree: usize,
263 points: &Array<Array2Impl, 2>,
264 ) -> Self::GeometryMap<'_> {
265 self.serial_grid
266 .geometry_map(entity_type, geometry_degree, points)
267 }
268}