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}