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