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