Program Listing for File mesh.h
↰ Return to documentation for file (framework/mesh/mesh/mesh.h)
// SPDX-FileCopyrightText: 2024 The OpenSn Authors <https://open-sn.github.io/opensn/>
// SPDX-License-Identifier: MIT
#pragma once
#include "framework/mesh/mesh/cell.h"
#include "framework/data_types/ndarray.h"
#include "framework/math/geometry.h"
#include <memory>
#include <array>
#include <map>
#include <cstddef>
namespace opensn
{
class GridFaceHistogram;
class MeshGenerator;
class LogicalVolume;
constexpr std::string_view
ToString(CoordinateSystemType type) noexcept
{
switch (type)
{
case CoordinateSystemType::UNDEFINED:
return "UNDEFINED";
case CoordinateSystemType::CARTESIAN:
return "CARTESIAN";
case CoordinateSystemType::CYLINDRICAL:
return "CYLINDRICAL";
case CoordinateSystemType::SPHERICAL:
return "SPHERICAL";
default:
return "UNKNOWN";
}
}
enum MeshType : int
{
ORTHOGONAL,
UNSTRUCTURED
};
constexpr std::string_view
ToString(MeshType type) noexcept
{
switch (type)
{
case ORTHOGONAL:
return "UNDEFINED";
case UNSTRUCTURED:
return "CARTESIAN";
default:
return "UNKNOWN";
}
}
enum BoundaryID : int
{
XMIN = 0,
XMAX = 1,
YMIN = 2,
YMAX = 3,
ZMIN = 4,
ZMAX = 5
};
struct OrthoMeshAttributes
{
size_t Nx = 0;
size_t Ny = 0;
size_t Nz = 0;
};
/// Encapsulates all the necessary information required to fully define a computational domain.
class Mesh
{
using GlobalVertexIDMap = std::map<uint64_t, Vector3>;
public:
Mesh();
unsigned int GetDimension() const { return dim_; }
void SetDimension(const unsigned int dim) { dim_ = dim; }
MeshType GetType() const { return mesh_type_; }
void SetType(const MeshType type) { mesh_type_ = type; }
CoordinateSystemType GetCoordinateSystem() const { return coord_sys_; }
void SetCoordinateSystem(const CoordinateSystemType coord_sys) { coord_sys_ = coord_sys; }
GeometryType GetGeometryType() const;
bool Extruded() const { return extruded_; }
void SetExtruded(const bool extruded) { extruded_ = extruded; }
/// Gets and orthogonal mesh interface object.
std::array<size_t, 3> GetIJKInfo() const;
void SetOrthoAttributes(const OrthoMeshAttributes& attrs) { ortho_attributes_ = attrs; }
void SetGlobalVertexCount(const uint64_t count) { global_vertex_count_ = count; }
uint64_t GetGlobalVertexCount() const { return global_vertex_count_; }
/// Get vertex using global vertex ID
Vector3& GlobalVertex(const uint64_t global_id) { return global_vertex_id_map_.at(global_id); }
/// Get vertex using global vertex ID
const Vector3& GlobalVertex(const uint64_t global_id) const
{
return global_vertex_id_map_.at(global_id);
}
/// Add global vertex providing global ID and location in 3D space
void AddGlobalVertex(const uint64_t global_id, const Vector3& pos)
{
global_vertex_id_map_.insert(std::make_pair(global_id, pos));
}
int GetNumPartitions() const { return num_partitions_; }
size_t GetGlobalNumberOfCells() const;
std::map<std::string, uint64_t>& GetBoundaryNameMap() { return boundary_name_map_; }
const std::map<std::string, uint64_t>& GetBoundaryNameMap() const { return boundary_name_map_; }
std::map<uint64_t, std::string>& GetBoundaryIDMap() { return boundary_id_map_; }
const std::map<uint64_t, std::string>& GetBoundaryIDMap() const { return boundary_id_map_; }
/// Returns the unique boundary ids present in the problem.
std::vector<uint64_t> GetUniqueBoundaryIDs() const;
/// Compute the geometric data for the cells and faces in the mesh.
void ComputeGeometricInfo();
/// Method to be called if cells and nodes have been transferred to another grid.
void ClearCellReferences();
/**
* Makes a boundary id given a name. If the boundary name already exists, the associated
* boundary id will be returned. Other the id will be set to one more than the maximum boundary
* id.
*/
uint64_t MakeBoundaryID(const std::string& boundary_name) const;
/**
* Associate boundary name with a boundary ID
*
* \param id Boundary ID
* \param name Boundary name to associate with ``id``
*/
void SetBoundaryName(std::uint64_t id, const std::string& name);
/// Defines the standard x/y/z min/max boundaries.
void SetOrthogonalBoundaries();
/// Returns the the total number of ghost cells
size_t GhostCellCount() const { return global_cell_id_to_nonlocal_id_map_.size(); }
/**
* Adds a new cell to the appropriate category (local or ghost).
* @param new_cell The cell to add.
*/
void AddGlobalCell(std::shared_ptr<Cell> new_cell);
/// Returns a reference to a cell given its global cell index.
Cell& GetGlobalCell(uint64_t cell_global_index);
/// Returns a const reference to a cell given its global cell index.
const Cell& GetGlobalCell(uint64_t cell_global_index) const;
/**
* Returns the cell global ids of all ghost cells. These are cells that neighbors to this
* partition's cells but are on a different partition.
*/
std::vector<uint64_t> GetGhostGlobalIDs() const;
/**
* Returns the local storage address of a ghost cell. If the ghost is not truly a ghost then -1 is
* returned, but is wasteful and therefore the user of this function should implement code to
* prevent it.
*/
uint64_t GetGhostLocalID(uint64_t cell_global_index) const;
/**
* Populates a face histogram.
*
* \param master_tolerance Multiple histograms will only be attempted
* if the ratio of the maximum dofs-per-face to the average dofs-per-face
* is greater than this value. Default 1.2.
*
* \param slave_tolerance While traversing a sorted list of dofs-per-face,
* a new bin will only be generated when the ratio of the listed dofs-per-face
* to a running bin average exceeds this value. Defualt 1.1.
*
* The function populates face_categories which is a structure containing
* pairs. Pair.first is the max dofs-per-face for the category and Pair.second
* is the number of faces in this category.
*/
std::shared_ptr<GridFaceHistogram> MakeGridFaceHistogram(double master_tolerance = 100.0,
double slave_tolerance = 1.1) const;
std::size_t GetLocalCellCount() const;
const Cell& GetLocalCell(uint64_t id) const;
Cell& GetLocalCell(uint64_t id);
std::vector<std::shared_ptr<Cell>>& GetLocalCells();
const std::vector<std::shared_ptr<Cell>>& GetLocalCells() const;
/// Returns whether the cell with the given global id is locally owned.
bool IsCellLocal(uint64_t global_id) const noexcept
{
return global_cell_id_to_local_id_map_.contains(global_id);
}
/**
* Given a global id of a cell, returns the local id if the cell is local, otherwise throws
* an out_of_range error.
*/
size_t MapCellGlobalID2LocalID(uint64_t global_id) const;
/// Creates a mapping of the current face local ids to the adjacent face's local ids.
void FindAssociatedVertices(const CellFace& cur_face, std::vector<short>& dof_mapping) const;
/// Creates a mapping of the current face local ids to the adjacent cell's local ids.
void FindAssociatedCellVertices(const CellFace& cur_face, std::vector<short>& dof_mapping) const;
/// Counts the number of cells within a logical volume across all partitions.
size_t CountCellsInLogicalVolume(const LogicalVolume& log_vol) const;
/// Checks whether a point is within a cell.
bool CheckPointInsideCell(const Cell& cell, const Vector3& point) const;
/// Checks whether a point is within a cell face.
bool CheckPointInsideCellFace(const Cell& cell, size_t face_i, const Vector3& point) const;
/// Provides a mapping from cell ijk indices to global ids.
NDArray<uint64_t, 3> MakeIJKToGlobalIDMapping() const;
/**
* Determines the bounding box size of each cell and returns it as a list of 3-component vectors,
* one Vector3 for each cell.
*/
std::vector<Vector3> MakeCellOrthoSizes() const;
/// Returns the bounding box corners for the locally owned cells.
std::pair<Vector3, Vector3> GetLocalBoundingBox() const;
/// Sets block ids for all cells to the specified block id.
void SetUniformBlockID(unsigned int blk_id);
/// Sets block IDs using a logical volume.
void SetBlockIDFromLogicalVolume(const LogicalVolume& log_vol, unsigned int blk_id, bool sense);
/// Assign all boundary faces to a single name
void SetUniformBoundaryID(const std::string& boundary_name);
/// Sets boundary ids using a logical volume.
void SetBoundaryIDFromLogicalVolume(const LogicalVolume& log_vol,
const std::string& boundary_name,
bool sense = true);
/// Computes the centroid from nodes specified by the given list.
Vector3 ComputeCentroidFromListOfNodes(const std::vector<uint64_t>& list) const;
/**
* Get the face vertices of a tetrahedron contained within the given face and
* side of a polyhedron.
*/
std::array<std::array<Vector3, 3>, 4>
GetTetrahedralFaceVertices(const Cell& cell, const CellFace& face, size_t side) const;
/// Compute volume per block IDs
std::map<unsigned int, double> ComputeVolumePerBlockID() const;
private:
/// Spatial dimension
unsigned int dim_;
MeshType mesh_type_;
CoordinateSystemType coord_sys_;
bool extruded_;
OrthoMeshAttributes ortho_attributes_;
std::map<uint64_t, std::string> boundary_id_map_;
std::map<std::string, uint64_t> boundary_name_map_;
int num_partitions_;
uint64_t global_vertex_count_;
///
GlobalVertexIDMap global_vertex_id_map_;
/// Locally owned cells
std::vector<std::shared_ptr<Cell>> local_cells_;
/// Locally stored ghost cells
std::vector<std::shared_ptr<Cell>> ghost_cells_;
std::map<uint64_t, uint64_t> global_cell_id_to_local_id_map_;
/// Global to ghost ID map
std::map<uint64_t, uint64_t> global_cell_id_to_nonlocal_id_map_;
public:
/// Returns a new instance of the spatial discretization.
static std::shared_ptr<Mesh> New() { return std::make_shared<Mesh>(); }
/// Returns the spatial dimensionality of the cell.
static int GetCellDimension(const Cell& cell);
/**
* Given the current cell, cell A, and its adjacent cell, cell B, with cell B adjacent to
* A at the `f`-th face of cell A. Will determine the `af`-th index of the face on cell B
* that interface with the `f`-th face of cell A.
*/
static size_t MapCellFace(const Cell& cur_cell, const Cell& adj_cell, unsigned int f);
};
} // namespace opensn