ndgrid/traits/
grid.rs

1//! Traits for a mesh entity
2use super::{Entity, GeometryMap};
3#[cfg(feature = "mpi")]
4use crate::types::GraphPartitioner;
5use crate::types::{Ownership, Scalar};
6#[cfg(feature = "mpi")]
7use mpi::traits::Communicator;
8#[cfg(feature = "mpi")]
9use rlst::distributed_tools::IndexLayout;
10use rlst::{Array, ValueArrayImpl};
11use std::fmt::Debug;
12use std::hash::Hash;
13use std::iter::Iterator;
14#[cfg(feature = "mpi")]
15use std::rc::Rc;
16
17/// A grid provides access to entities, their geometrical and their topological properties.
18pub trait Grid {
19    /// Scalar type
20    type T: Scalar;
21
22    /// Type used as identifier of different entity types
23    type Entity<'a>: Entity<EntityDescriptor = Self::EntityDescriptor, T = Self::T>
24    where
25        Self: 'a;
26
27    /// Geometry map type
28    type GeometryMap<'a>: GeometryMap<T = Self::T>
29    where
30        Self: 'a;
31
32    /// Type used as identifier of different entity types
33    type EntityDescriptor: Debug + PartialEq + Eq + Clone + Copy + Hash;
34
35    /// Iterator over sub-entities
36    type EntityIter<'a>: Iterator<Item = Self::Entity<'a>>
37    where
38        Self: 'a;
39
40    /// Dimension of the geometry of this grid
41    fn geometry_dim(&self) -> usize;
42
43    /// Dimension of the topology of this grid
44    fn topology_dim(&self) -> usize;
45
46    /// An entity in this grid
47    fn entity(
48        &self,
49        entity_type: Self::EntityDescriptor,
50        local_index: usize,
51    ) -> Option<Self::Entity<'_>>;
52
53    /// The entity types of topological dimension `dim` contained in this grid
54    fn entity_types(&self, tdim: usize) -> &[Self::EntityDescriptor];
55
56    /// Number of entities of type `entity_type`
57    fn entity_count(&self, entity_type: Self::EntityDescriptor) -> usize;
58
59    /// Number of cells in the grid
60    fn cell_count(&self) -> usize {
61        self.entity_types(self.topology_dim())
62            .iter()
63            .map(|&t| self.entity_count(t))
64            .sum()
65    }
66
67    /// Return the cell types in the grid
68    fn cell_types(&self) -> &[Self::EntityDescriptor] {
69        let tdim = self.topology_dim();
70        self.entity_types(tdim)
71    }
72
73    /// Owned cell count
74    ///
75    /// Note. The default implementation iterates through all grid to count the number of owned elements.
76    /// Override this method if a more efficient implementation is available.
77    fn owned_cell_count(&self) -> usize {
78        self.cell_types()
79            .iter()
80            .map(|t| {
81                self.entity_iter(*t)
82                    .filter(|e| matches!(e.ownership(), Ownership::Owned))
83                    .count()
84            })
85            .sum()
86    }
87
88    /// Iterator over entities
89    fn entity_iter(&self, entity_type: Self::EntityDescriptor) -> Self::EntityIter<'_>;
90
91    /// An entity in this grid from an insertion id
92    fn entity_from_id(
93        &self,
94        entity_type: Self::EntityDescriptor,
95        id: usize,
96    ) -> Option<Self::Entity<'_>>;
97
98    /// Geometry map from reference entity to physical entities at the given points
99    ///
100    /// `points` should have shape [entity_topology_dim, npts] and use column-major ordering
101    fn geometry_map<Array2Impl: ValueArrayImpl<Self::T, 2>>(
102        &self,
103        entity_type: Self::EntityDescriptor,
104        geometry_degree: usize,
105        points: &Array<Array2Impl, 2>,
106    ) -> Self::GeometryMap<'_>;
107}
108
109/// Definition of an MPI parallel grid
110#[cfg(feature = "mpi")]
111pub trait ParallelGrid {
112    /// Type of the Grid
113    type T: Scalar;
114
115    /// Local grid type
116    type LocalGrid: Grid<T = Self::T>;
117
118    /// Communicator
119    type C: Communicator;
120
121    /// MPI communicator
122    fn comm(&self) -> &Self::C;
123
124    /// Local grid on the current process
125    fn local_grid(&self) -> &Self::LocalGrid;
126
127    /// Return the cell index layout that describes where each global cell lives
128    fn cell_layout(&self) -> Rc<IndexLayout<'_, Self::C>>;
129
130    /// Return the global number of cells
131    fn global_cell_count(&self) -> usize {
132        self.cell_layout().number_of_global_indices()
133    }
134}
135
136/// A grid that can be be distributed across processes
137#[cfg(feature = "mpi")]
138pub trait DistributableGrid {
139    /// Parallel grid type when distrubuted
140    type ParallelGrid<'a, C: Communicator + 'a>: ParallelGrid<C = C>;
141
142    /// Distribute this grid in parallel
143    fn distribute<'a, C: Communicator>(
144        &self,
145        comm: &'a C,
146        partitioner: GraphPartitioner,
147    ) -> Self::ParallelGrid<'a, C>;
148}