ndgrid/grid/
local_grid.rs

1//! Serial grids
2#[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/// Grid entity
22#[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    /// Create new
31    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/// Grid entity iterator
75#[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    /// Create new
84    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/// Local grid on a process
102#[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>")]
112/// A serde serializable grid
113pub 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    /// Create new
180    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}