Skip to main content

ndmesh/traits/
mesh.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 mesh provides access to entities, their geometrical and their topological properties.
18pub trait Mesh {
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 mesh
41    fn geometry_dim(&self) -> usize;
42
43    /// Dimension of the topology of this mesh
44    fn topology_dim(&self) -> usize;
45
46    /// An entity in this mesh
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 mesh
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 mesh
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 mesh
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 mesh 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 mesh 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 mesh
110#[cfg(feature = "mpi")]
111pub trait ParallelMesh {
112    /// Type of the Mesh
113    type T: Scalar;
114
115    /// Local mesh type
116    type LocalMesh: Mesh<T = Self::T>;
117
118    /// Communicator
119    type C: Communicator;
120
121    /// MPI communicator
122    fn comm(&self) -> &Self::C;
123
124    /// Local mesh on the current process
125    fn local_mesh(&self) -> &Self::LocalMesh;
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 mesh that can be be distributed across processes
137#[cfg(feature = "mpi")]
138pub trait DistributableMesh {
139    /// Parallel mesh type when distrubuted
140    type ParallelMesh<'a, C: Communicator + 'a>: ParallelMesh<C = C>;
141
142    /// Distribute this mesh in parallel
143    fn distribute<'a, C: Communicator>(
144        &self,
145        comm: &'a C,
146        partitioner: GraphPartitioner,
147    ) -> Self::ParallelMesh<'a, C>;
148}