Skip to main content

ndfunctionspace/
traits.rs

1//! Function space traits
2#[cfg(feature = "mpi")]
3use mpi::traits::Communicator;
4use ndelement::traits::FiniteElement;
5use ndmesh::{traits::Mesh, types::Ownership};
6use rlst::RlstScalar;
7use std::fmt::Debug;
8use std::hash::Hash;
9
10/// Function space.
11///
12/// There will be three ways that the degrees of freedom (DOFs) are numbered:
13///
14/// 1. The local DOF numbering is the numbering of the DOFs on a single cell.
15/// 2. The process DOF numbering is the numbering of the DOFs local to the current process.
16///    This includes owned and ghost DOFs.
17/// 3. The global DOF numbering is the numberinf of the DOFs across all processes. Note that
18///    if the mpi feature is not enabaled, then this is the same as the process DOF numbering.
19///
20/// DOFs included in function spaces are either owned or ghosts. Owned DOFs are owned by the
21/// current process. Ghost DOFs are owned by another process but information about them
22/// is known by the current process because (eg) they neighbour a cell on this process.
23/// If the mpi feature is disabled, all DOFs will be owned DOFs.
24pub trait FunctionSpace {
25    /// Scalar type
26    type T: RlstScalar;
27    /// Scalar type for geometry
28    type TMesh: RlstScalar;
29    /// Type used as identifier of different entity types
30    type EntityDescriptor: Debug + PartialEq + Eq + Clone + Copy + Hash;
31    /// The type for the mesh this function space is defined on
32    type Mesh: Mesh<EntityDescriptor = Self::EntityDescriptor, T = Self::TMesh>;
33    /// The type for the finite element this mesh is defined by
34    type FiniteElement: FiniteElement<CellType = Self::EntityDescriptor, T = Self::T>;
35
36    /// The mesh that this function space is defined on
37    fn mesh(&self) -> &Self::Mesh;
38
39    /// The finite elements used in this function space
40    fn elements(&self) -> &[Self::FiniteElement];
41
42    /// A list of entity indices that use the element with the given index
43    fn entities_by_element(&self, element_index: usize) -> Option<&[usize]>;
44
45    /// Get the process DOF numbers associated with the given entity
46    fn entity_dofs(
47        &self,
48        entity_type: Self::EntityDescriptor,
49        entity_number: usize,
50    ) -> Option<&[usize]>;
51
52    /// Get the process DOF numbers associated with the closure of the given entity
53    ///
54    /// The closure of an entity includes the lower dimensional entities that are on the
55    /// boundary of the entity. For example, the closure of a triangle includes its
56    /// edges and vertices.
57    fn entity_closure_dofs(
58        &self,
59        entity_type: Self::EntityDescriptor,
60        entity_number: usize,
61    ) -> Option<&[usize]>;
62
63    /// Get the number of process DOFs
64    ///
65    /// This count includes owned and ghost DOFs
66    fn process_size(&self) -> usize;
67
68    /// Get the number of owned process DOFs
69    fn process_owned_size(&self) -> usize;
70
71    /// Get the number of DOFs on all processes
72    fn global_size(&self) -> usize;
73
74    /// Get the global DOF index associated with a process DOF index
75    fn global_dof_index(&self, process_dof_index: usize) -> usize;
76
77    /// Get ownership of a process DOF
78    fn ownership(&self, process_dof_index: usize) -> Ownership;
79}
80
81/// MPI parallel function space.
82#[cfg(feature = "mpi")]
83pub trait ParallelFunctionSpace {
84    /// Process space type   
85    type ProcessSpace: FunctionSpace;
86
87    /// Communicator
88    type C: Communicator;
89
90    /// MPI communicator
91    fn comm(&self) -> &Self::C;
92
93    /// Space on the current process
94    fn process_space(&self) -> &Self::ProcessSpace;
95
96    /// Get the number of DOFs on all processes
97    fn global_size(&self) -> usize;
98}