CartesianHMesh#
The CartesianHMesh is a Cartesian mesh that mirrors the auxiliary grid used for moving particles between MPI ranks. This mesh is a build in Cartesian mesh that can be used for applications where such a mesh is appropriate.
Mesh#
-
class CartesianHMesh : public NESO::Particles::HMesh#
- #include <cartesian_h_mesh.hpp>
Example mesh that duplicates a MeshHierarchy as a HMesh for examples and testing.
This mesh consists of square or cube coarse cells with a given number per dimension. These coarse cells have the specified cell extent passed to the constructor. Each of these coarse cells is subdivided into smaller squares/cubes by the number of times specifed by the subdivision order. The resulting mesh of fine cells is distributed over an MPI Cartesian communicator.
The sides of the mesh are labelled as follows in 2D:
In 3D the bottom face is labelled 4 and the top face is labelled 5.- 2 - 3 1 - 0 - y | -> x
The face cells are given a contiguous linear index which is determined by computing the linear index on each face then adding an offset computed from the total number of face cells on all the preceeding faces. i.e. cells on face 0 are indexed in the xz plane with x as the fastest running dimension then z.
Some of the face cell indexing methods in this class use a tuple form of indexing a face cell. In 2D this tuple is [face, l0] and in 3D this tuple is [face, l0, l1]. Here “face” is the index of the face the cell exists on. l0 is the coordinate in the first dimension of the face, e.g. x on face 0 and l1 is the second coordinate on the face, e.g. z on face 0.
In 2D the vertices of each cell are labelled as
When converting to VTK coordinates we extract vertices in the following order:3 - 2 | | 0 - 1 and in 3D Top 7 - 6 | | 4 - 5 Bottom 3 - 2 | | 0 - 1 y ^ | -> x
2D: Face Vertices 0 0, 1 1 1, 2 2 3, 2 3 0, 3 3D Face Vertices 0 0, 1, 5, 4 1 1, 2, 6, 5 2 3, 2, 6, 7 3 0, 3, 7, 4 4 0, 1, 2, 3 5 4, 5, 6, 7
Public Functions
-
CartesianHMesh(const CartesianHMesh &st) = delete#
Disable (implicit) copies.
-
CartesianHMesh &operator=(CartesianHMesh const &a) = delete#
Disable (implicit) copies.
- CartesianHMesh(
- MPI_Comm comm,
- const int ndim,
- std::vector<int> &dims,
- const double extent = 1.0,
- const int subdivision_order = 1,
- const int stencil_width = 0
Construct a mesh over a given MPI communicator with a specified shape. If the passed MPI communicator is a Cartesian communicator then a new Cartesian communicator will be created with the same dims and periods as this passed communicator. This allows users to bypass the decomposition processes by explicitly specifying what should happen.
- Parameters:
comm – MPI Communicator to use for decomposition.
ndim – Number of dimensions.
dims – Number of coarse cells in each dimension.
extent – Width of each coarse cell in each dimension.
subdivision_order – Number of times to subdivide each coarse cell to produce the fine cells.
stencil_width – Width of the stencil, in number of cells, used to determine MPI neighbours.
-
virtual MPI_Comm get_comm()#
Get the MPI communicator of the mesh.
- Returns:
MPI communicator.
-
virtual int get_ndim()#
Get the number of dimensions of the mesh.
- Returns:
Number of mesh dimensions.
-
virtual std::vector<int> &get_dims()#
Get the Mesh dimensions.
- Returns:
Mesh dimensions.
-
virtual int get_subdivision_order()#
Get the subdivision order of the mesh.
- Returns:
Subdivision order.
-
virtual double get_cell_width_coarse()#
Get the mesh width of the coarse cells in the MeshHierarchy.
- Returns:
MeshHierarchy coarse cell width.
-
virtual double get_cell_width_fine()#
Get the mesh width of the fine cells in the MeshHierarchy.
- Returns:
MeshHierarchy fine cell width.
-
virtual double get_inverse_cell_width_coarse()#
Get the inverse mesh width of the coarse cells in the MeshHierarchy.
- Returns:
MeshHierarchy inverse coarse cell width.
-
virtual double get_inverse_cell_width_fine()#
Get the inverse mesh width of the fine cells in the MeshHierarchy.
- Returns:
MeshHierarchy inverse fine cell width.
-
virtual int get_ncells_coarse()#
Get the global number of coarse cells.
- Returns:
Global number of coarse cells.
-
virtual int get_ncells_fine()#
Get the number of fine cells per coarse cell.
- Returns:
Number of fine cells per coarse cell.
-
virtual std::vector<int> &get_local_communication_neighbours()#
Get a std::vector of MPI ranks which should be used to setup local communication patterns.
- Returns:
std::vector of MPI ranks.
-
virtual void get_point_in_subdomain(double *point)#
Get a point in the domain that should be in, or at least close to, the sub-domain on this MPI process. Useful for parallel initialisation.
- Parameters:
point – Pointer to array of size equal to at least the number of mesh dimensions.
-
virtual std::shared_ptr<MeshHierarchy> get_mesh_hierarchy()#
Get the MeshHierarchy instance placed over the mesh.
- Returns:
MeshHierarchy placed over the mesh.
-
virtual int get_cell_count()#
- Returns:
The number of “cell” NESO-Particles should consider.
-
int get_cart_cell_count()#
- Returns:
The number of Cartesian cells owned by this MPI rank.
-
void mesh_tuple_to_mh_tuple(const INT *index_mesh, INT *index_mh)#
Convert a mesh index (index_x, index_y, …) for this cartesian mesh to the format for a MeshHierarchy: (coarse_x, coarse_y,.., fine_x, fine_y,…).
- Parameters:
index_mesh – Input tuple index on mesh.
index_mh – Output tuple index on MeshHierarchy.
-
virtual void free()#
Free the mesh and any associated communicators.
-
std::vector<std::array<int, 3>> get_owned_cells()#
Get a vector of the cells owned by this MPI rank.
- Returns:
vector of owned cells in order of the cell ids of the cells.
- std::array<int, 3> get_global_cell_tuple_index(
- const INT linear_cell_index
Get the global index in tuple form from a local linear cell id.
- Parameters:
linear_cell_index – Local linear cell index.
- Returns:
Global tuple of cell index.
-
int get_face_id_owning_rank(const INT face_id)#
- Parameters:
face_id – Face id to compute owning rank for.
- Returns:
Owning rank for passed face id.
-
int get_mesh_tuple_owning_rank(const INT *index_mesh)#
- Parameters:
index_mesh – Cartesian mesh index to find owning rank for.
- Returns:
Owning rank of passed mesh index.
-
void get_face_id_as_tuple(const INT face_id, INT *face_index_tuple)#
Convert a face cell id into a face index and local coordinate index for the face.
- Parameters:
face_id – [in] Linear face id to convert.
face_index_tuple – [inout] Index of the face on which the cell lies.
-
INT get_face_linear_index_from_tuple(const INT *face_index_tuple)#
Convert the face geom tuple id to a linear index.
- Parameters:
face_index_tuple – Tuple describing the face geom.
- void get_mesh_tuple_owning_face_tuple(
- const INT *face_index_tuple,
- INT *mesh_tuple
Get the mesh cell as a mesh tuple which has the passed face geometry index as a face.
- Parameters:
face_index_tuple – [in] Tuple which desribes the cell on the face.
mesh_tuple – [inout] Mesh tuple that describes the cell which owns the face.
-
std::vector<double> get_vtk_cell_points(const INT index)#
Get the coordinates of the vertices of a cell in a form that can be passed directly to NESO::Particles::VTK::UnstructuredCell.
- Parameters:
index – Local index of cell to collect vertex coordinates for.
-
std::vector<double> get_vtk_cell_points(const INT *index_tuple)#
Get the coordinates of the vertices of a cell in a form that can be passed directly to NESO::Particles::VTK::UnstructuredCell.
- Parameters:
index_tuple – Global index in tuple form of cell to collect vertex coordinates for.
-
std::vector<VTK::UnstructuredCell> get_vtk_cell_data()#
Get VTK data for all cells.
- Returns:
Vector of VTK data which can be passed to our VTKHDF implementation.
- std::vector<double> get_vtk_face_cell_points(
- const INT *face_index_tuple
Get the VTK data for a single face cell.
- Parameters:
face_index_tuple – Index of the face cell in tuple form.
- Returns:
Vertex coordinates in form VTK::UnstructuredCell can use.
-
std::vector<double> get_vtk_face_cell_points(const INT face_index)#
Get the VTK data for a single face cell.
- Parameters:
face_index – Index of the face cell in linear form.
- Returns:
Vertex coordinates in form VTK::UnstructuredCell can use.
-
const std::vector<INT> &get_owned_face_cells()#
- Returns:
The linear face cell ids of the face cells this MPI rank owns.
-
VTK::UnstructuredCell get_vtk_face_cell_data(const INT face_cell)#
Get VTK data for a face cell.
- Parameters:
face_cell – Linear cell index of owned face cell.
- Returns:
VTK::UnstructuredCell data for requested cell.
-
std::map<INT, VTK::UnstructuredCell> get_vtk_face_cell_data()#
Get VTK data for all face cells.
- Returns:
Map from face linear INX to VTK data which can be passed to our VTKHDF implementation once linearised into a vector (see flatten_map).
-
MPI_Comm get_face_owning_ranks_comm()#
- Returns:
A MPI communicator containing ranks that own face cells. This communicator is MPI_COMM_NULL on ranks that do not own face cells.
- const std::vector<INT> &get_all_face_cells_on_face(
- const INT face_index
- Parameters:
face_index – Face index, e.g. [0,1,2,3] in 2D or [0,1,2,3,4,5] of face to get all owned face cells for.
- Returns:
All owned face cells, in linear index form, for the passed face index.
-
template<typename INT_TYPE>
inline std::vector<INT> get_face_cells( - const std::vector<INT_TYPE> &faces
Get the face cells which are owned by this MPI rank and exist on one of the given faces.
- Parameters:
faces – Vector of faces to get all face cells for.
- Returns:
the Locally owned face cells which exist on given faces.
-
void get_global_face_index_bounds(INT &bound_lower, INT &bound_upper)#
Get the bounds of global face indices over the entire mesh.
- Parameters:
bound_lower – [inout] Lowest global face index.
bound_upper – [inout] Largest global face index plus one.
Public Members
-
int cell_starts[3] = {0, 0, 0}#
Holds the first cell this rank owns in each dimension.
-
int cell_ends[3] = {1, 1, 1}#
Holds the last cell+1 this ranks owns in each dimension.
-
std::vector<int> cell_counts = {0, 0, 0}#
Global number of cells in each dimension.
-
int cell_counts_local[3] = {0, 0, 0}#
Local number of cells in each dimension.
-
double global_extents[3] = {0.0, 0.0, 0.0}#
Global extents of the mesh.
-
int stencil_width#
Width of the stencil used to determine which MPI ranks are neighbours.
-
const int ndim#
Number of dimensions of the mesh.
-
std::vector<int> dims#
Vector holding the number of coarse cells in each dimension.
-
const int subdivision_order#
Subdivision order to determine number of fine cells per coarse cell.
-
const double cell_width_coarse#
Width of coarse cells, uniform in all dimensions.
-
const double cell_width_fine#
Width of fine cells, uniform in all dimensions.
-
const double inverse_cell_width_coarse#
Inverse of the coarse cell width.
-
const double inverse_cell_width_fine#
Inverse of the fine cell width.
-
const int ncells_coarse#
Global number of coarse cells.
-
const int ncells_fine#
Number of fine cells per coarse cell.
-
bool single_cell_mode#
Is this mesh running in a mode where it exposes one NP cell per MPI rank.
-
int ncells_face_global = {0}#
The total number of ndim-1 cells on boundaries (global)
-
CartesianHMesh(const CartesianHMesh &st) = delete#
Helper Functions#
Helper functions for CartesianHMesh.
- CartesianHMeshSharedPtr mesh,
- const int npart_per_cell,
- std::vector<std::vector<double>> &positions,
- std::vector<int> &cells,
- std::optional<std::mt19937> rng_in = std::nullopt
Helper function to quickly initialise a uniform distribution of particles on a CartesianHMesh.
- Parameters:
mesh – [in] CartesianHMesh on which to spawn particles.
npart_per_cell – [in] Number of particle positions to sample for each mesh cell.
positions – [inout] Ouput particle positions indexed by dimension then particle.
cells – [inout] Ouput particle cell ids indexed by particle.
rng_in – [in] Optional input RNG to use.
Surface and Volume Functions#
This section contains details regarding functions defined on a CartesianHMesh. To use these functions see the projection and evaluation implementations for the volume and surfaces.
-
class CartesianHMeshFunction : public NESO::Particles::GenericFunction#
- #include <cartesian_h_mesh_function.hpp>
Generic function type to represent functions on CartesianHMesh.
Public Functions
- CartesianHMeshSharedPtr mesh,
- SYCLTargetSharedPtr sycl_target,
- const int ndim,
- const std::vector<INT> &cells,
- const std::string function_space,
- const int polynomial_order,
- const int boundary_group
Create a function on a mesh on the passed entities.
- Parameters:
mesh – Host mesh to create function on.
sycl_target – Compute device holding the DOFs.
ndim – Number of spatial dimensions function exists in.
cells – Locally owned mesh entities to create function over.
function_space – Type of function to create.
polynomial_order – Polynomial order of function to create.
boundary_group – Label, e.g. boundary group, for subset of the mesh this function is defined over.
-
virtual void write_vtkhdf(const std::string filename) override#
Write the function to a vtkhdf file. This function must be called collectively on the communicator.
- Parameters:
filename – Output file name which should have vtkhdf extension.
Public Members
-
CartesianHMeshSharedPtr mesh#
The mesh this function is defined on.
Boundary Conditions#
This section contains details regarding boundary conditions for the CartesianHMesh.
-
class CartesianPeriodic#
- #include <cartesian_periodic.hpp>
Periodic boundary conditions implementation designed to work with a CartesianHMesh.
Public Functions
-
CartesianPeriodic(const CartesianPeriodic &st) = delete#
Disable (implicit) copies.
-
CartesianPeriodic &operator=(CartesianPeriodic const &a) = delete#
Disable (implicit) copies.
- SYCLTargetSharedPtr sycl_target,
- std::shared_ptr<CartesianHMesh> mesh,
- ParticleDatSharedPtr<REAL> position_dat
Construct instance to apply periodic boundary conditions to particles within the passed ParticleDat.
- Parameters:
sycl_target – SYCLTarget to use as compute device.
mesh – CartedianHMesh instance to use a domain for the particles.
position_dat – ParticleDat containing particle positions.
- SYCLTargetSharedPtr sycl_target,
- std::shared_ptr<CartesianHMesh> mesh,
- ParticleDatSharedPtr<REAL> position_dat,
- std::vector<int> masks
Construct instance to apply periodic boundary conditions to particles within the passed ParticleDat.
- Parameters:
sycl_target – SYCLTarget to use as compute device.
mesh – CartedianHMesh instance to use a domain for the particles.
position_dat – ParticleDat containing particle positions.
masks – Vector of ints that indicate if the dimension is periodic or not.
- std::shared_ptr<CartesianHMesh> mesh,
- ParticleGroupSharedPtr particle_group
Construct instance to apply periodic boundary conditions to particles within the passed ParticleDat.
- Parameters:
mesh – CartedianHMesh instance to use a domain for the particles.
particle_group – ParticleGroup to apply periodic boundary conditions to.
- std::shared_ptr<CartesianHMesh> mesh,
- ParticleGroupSharedPtr particle_group,
- std::vector<int> masks
Construct instance to apply periodic boundary conditions to particles within the passed ParticleDat.
- Parameters:
mesh – CartedianHMesh instance to use a domain for the particles.
particle_group – ParticleGroup to apply periodic boundary conditions to.
masks – Vector of ints that indicate if the dimension is periodic or not.
-
void execute()#
Apply periodic boundary conditions to the particle positions in the ParticleDat this instance was created with.
-
CartesianPeriodic(const CartesianPeriodic &st) = delete#
Boundary Intersection#
This section contains details regarding intersections between particle trajectories and the boundary of the Cartesian mesh.
-
class CartesianTrajectoryIntersection#
- #include <cartesian_trajectory_intersection.hpp>
This type implements trajectory intersection detection between particles and a CartesianHMesh. Instances of this type are used to create and work with functions defined on the surfaces of the CartesianHMesh.
Public Functions
- SYCLTargetSharedPtr sycl_target,
- CartesianHMeshSharedPtr mesh,
- std::map<int, std::vector<int>> boundary_groups,
- REAL tolerance = 1.0e-14
- Parameters:
sycl_target – Compute device to use for interactions.
mesh – CartesianHMesh to detect intersections with.
boundary_groups – Map from boundary group to edges/faces indices that form the group.
tolerance – Tolerance for intersection tests, default 1E-14.
Prepare a ParticleGroup such that it, or sub groups based on it, can be passed to pre_integration and post_integration. Must be called collectively on the communicator.
- Parameters:
particle_group – ParticleGroup to prepare.
This method should be called with a collection of particles prior to updating the positions of these particles. Must be called collectively on the communicator.
- Parameters:
particles – ParticleGroup or ParticleSubGroup of particles whose positions are about to be updated, e.g. in a time stepping operation.
This method should be called with a collection of particles prior to updating the positions of these particles. Must be called collectively on the communicator.
- Parameters:
particles – ParticleGroup or ParticleSubGroup of particles whose positions are about to be updated, e.g. in a time stepping operation.
- std::shared_ptr<ParticleGroup> particles
Call after updating to find particles whose trajectories intersect the CartesianHMesh boundary. Must be called collectively on the communicator.
- Parameters:
particles – Collection of particles, either a ParticleGroup or ParticleSubGroup, to identify trajectory-boundary intersections of.
- Returns:
Map from boundary groups ids, which were passed in the constructor, to a ParticleSubGroup of particles which crossed the boundary elements which form the boundary group.
- std::shared_ptr<ParticleSubGroup> particles
Call after updating to find particles whose trajectories intersect the CartesianHMesh boundary. Must be called collectively on the communicator.
- Parameters:
particles – Collection of particles, either a ParticleGroup or ParticleSubGroup, to identify trajectory-boundary intersections of.
- Returns:
Map from boundary groups ids, which were passed in the constructor, to a ParticleSubGroup of particles which crossed the boundary elements which form the boundary group.
-
void free()#
Explicitly free the resources, e.g. MPI communicators without relying on collective destructor calls. Should be called collectively on the communicator.
- CartesianHMeshFunctionSharedPtr create_function(
- const int group,
- const std::string function_space,
- const int polynomial_order
Create a function on a boundary group. Must be called collectively on the communicator.
- Parameters:
group – ID of boundary group to create function on.
function_space – Family of function to create, e.g. “DG”.
polynomial_order – Order of function to create, e.g. 0.
- Returns:
Function object on boundary.
- ParticleSubGroupSharedPtr particle_sub_group,
- Sym<REAL> sym,
- const int component,
- const bool is_ephemeral,
- CartesianHMeshFunctionSharedPtr func
Project particle data onto a function defined on the surface. Uses the standardarised boundary interface on the sub group. This function call is equivalent to calling:
function_project_initialise(func); function_project_contribute(particle_sub_group, sym, component,
is_ephemeral, func); function_project_finalise(func);
Must be called collectively on the communicator.
- Parameters:
particle_sub_group – ParticleSubGroup to project onto function.
sym – Sym<REAL> Particle property to use as source weights.
component – Component of particle property to use as source weights.
is_ephemeral – Indicate if the particle weights are in an EphemeralDat or ParticleDat.
func – Function to project onto.
- CartesianHMeshFunctionSharedPtr func
A function_project call is equivalent to calling:
function_project_initialise(func); function_project_contribute(particle_sub_group, sym, component,
is_ephemeral, func); function_project_finalise(func);
This method initialises the destination function for projection. Must be called collectively on the communicator.
- Parameters:
func – Function to project onto.
- ParticleSubGroupSharedPtr particle_sub_group,
- Sym<REAL> sym,
- const int component,
- const bool is_ephemeral,
- CartesianHMeshFunctionSharedPtr func
A function_project call is equivalent to calling:
function_project_initialise(func); function_project_contribute(particle_sub_group, sym, component,
is_ephemeral, func); function_project_finalise(func);
This method adds the contributions from the particles in the particle_sub_group to the projection. Must be called collectively on the communicator.
- Parameters:
particle_sub_group – ParticleSubGroup to project onto function.
sym – Sym<REAL> Particle property to use as source weights.
component – Component of particle property to use as source weights.
is_ephemeral – Indicate if the particle weights are in an EphemeralDat or ParticleDat.
func – Function to project onto.
A function_project call is equivalent to calling:
function_project_initialise(func); function_project_contribute(particle_sub_group, sym, component,
is_ephemeral, func); function_project_finalise(func);
This method must be called after all contributions to the projection have been made with function_project_contribute. Must be called collectively on the communicator.
- Parameters:
func – Function to project onto.
- ParticleSubGroupSharedPtr particle_sub_group,
- Sym<REAL> sym,
- const int component,
- const bool is_ephemeral,
- CartesianHMeshFunctionSharedPtr func
Evaluate particle data from a function defined on the surface. Uses the standardarised boundary interface on the sub group. Must be called collectively on the communicator.
- Parameters:
particle_sub_group – ParticleSubGroup to containing destination particles for evaluation.
sym – Sym<REAL> Particle property to overwrite with function evaluations.
component – Component of particle property to write evalauations to.
is_ephemeral – Indicate if the particle evaluations are in an EphemeralDat or ParticleDat.
func – Function to evaluate at particle locations.
Public Members
-
SYCLTargetSharedPtr sycl_target#
Compute device used to find intersections.
-
CartesianHMeshSharedPtr mesh#
The underlying mesh.
-
std::map<int, std::vector<int>> boundary_groups#
Map from boundary group to faces/edges that form the group.
-
REAL tolerance#
Tolerance for intersection tests.
Public Static Attributes
-
static const Sym<REAL> previous_position_sym = Sym<REAL>("NESO_PARTICLES_CART_H_MESH_PREVIOUS_POS")#
The Sym for the particle property which holds the position of each particle before the positions were updated in a time stepping loop. These positions are populated on call to pre_integration.
Cell Subdivision#
Here exist implementation for subdividing CartesianHMesh cells into smaller cells and mapping particles into these smaller cells. For use in cases such as DSMC.