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;
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/// Grid entity
21#[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    /// Create new
30    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/// Grid entity iterator
74#[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    /// Create new
83    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/// Local grid on a process
101#[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>")]
111/// A serde serializable grid
112pub 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    /// Create new
179    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}