Program Listing for File cell.h

Return to documentation for file (framework/mesh/cell/cell.h)

// SPDX-FileCopyrightText: 2024 The OpenSn Authors <https://open-sn.github.io/opensn/>
// SPDX-License-Identifier: MIT

#pragma once

#include "framework/data_types/vector3.h"
#include "framework/data_types/byte_array.h"
#include <limits>
#include <tuple>
#include <vector>
#include <cstdint>

// Appending cell types to namespace
namespace opensn
{

class Cell;
class MeshContinuum;

enum class CellType
{
  GHOST = 0,
  SLAB = 1,

  TRIANGLE = 4,
  QUADRILATERAL = 5,
  POLYGON = 6,

  TETRAHEDRON = 7,
  HEXAHEDRON = 8,
  WEDGE = 9,
  PYRAMID = 10,
  POLYHEDRON = 20,

  POINT = 99
};

/// Provides the text name associated with a cell type.
std::string CellTypeName(CellType type);

/**
 * Node on a face.
 * This class represents a node on a face. It stores the cell local index, the face index
 * within the cell and the index of the node relative to the face as compact 64-bit integer. This
 * class abstracts the node for usage with std::map and std::set.
 */
class FaceNode
{
public:
  /// Default constructor.
  constexpr FaceNode() = default;
  /// Member constructor.
  constexpr FaceNode(std::uint32_t cell_idx, std::uint16_t face_idx, std::uint16_t face_node_idx)
    : value_(0)
  {
    value_ |= static_cast<std::uint64_t>(cell_idx) << 32;
    value_ |= static_cast<std::uint64_t>(face_idx) << 16;
    value_ |= static_cast<std::uint64_t>(face_node_idx);
  }

  /// Comparison operator for ordering.
  constexpr bool operator<(const FaceNode& other) const { return value_ < other.value_; }

  /// Equality operator.
  constexpr bool operator==(const FaceNode& other) const { return value_ == other.value_; }

  /// Get cell local index.
  constexpr std::uint32_t GetCellIndex() const { return static_cast<std::uint32_t>(value_ >> 32); }

  /// Get face index.
  constexpr std::uint16_t GetFaceIndex() const
  {
    return static_cast<std::uint16_t>((value_ >> 16) & 0xFFFFU);
  }

  /// Get face node index.
  constexpr std::uint16_t GetFaceNodeIndex() const
  {
    return static_cast<std::uint16_t>(value_ & 0xFFFFU);
  }

  /// Check if the face node is initialized.
  constexpr bool IsInitialized() const
  {
    return value_ != std::numeric_limits<std::uint64_t>::max();
  }

private:
  /// Core value.
  std::uint64_t value_ = std::numeric_limits<std::uint64_t>::max();
};

/**
 * In this paradigm a face is an object which largely is considered to be planar (meaning all the
 * vertices lay in the same plane).
 */
class CellFace
{
public:
  /// Determines the neighbor's partition and whether it's local or not.
  bool IsNeighborLocal(const MeshContinuum* grid) const;

  /// Determines the neighbor's partition.
  int GetNeighborPartitionID(const MeshContinuum* grid) const;

  /// Determines the neighbor's local id.
  std::uint32_t GetNeighborLocalID(const MeshContinuum* grid) const;

  /// Determines the neighbor's associated face.
  int GetNeighborAdjacentFaceIndex(const MeshContinuum* grid) const;

  /// Computes the geometric info on the face.
  void ComputeGeometricInfo(const MeshContinuum* grid, const Cell& cell);

  /// Serializes a face into a vector of bytes.
  ByteArray Serialize() const;

  /// Provides string information of the face.
  std::string ToString() const;

  void ComputeGeometricInfo(const MeshContinuum* grid, const Cell& cell, unsigned int f);

  /// Flag indicating whether face has a neighbor
  bool has_neighbor = false;
  /// If face has neighbor, contains the global_id, otherwise, contains boundary_id.
  uint64_t neighbor_id = std::numeric_limits<uint64_t>::max();

  /// The average/geometric normal
  Vector3 normal;
  /// The face centroid
  Vector3 centroid;
  /// The area of the face
  double area = 0.0;

  /// A list of the vertices
  std::vector<uint64_t> vertex_ids;

public:
  /// Deserializes a face from a set of raw data
  static CellFace DeSerialize(const ByteArray& raw, size_t& address);
};

/// Generic mesh cell object
class Cell
{
public:
  Cell(const Cell& other) = default;
  Cell(Cell&& other) noexcept = default;

  explicit Cell(CellType cell_type, CellType cell_sub_type);

  virtual ~Cell() = default;

  Cell& operator=(const Cell& other);

  CellType GetType() const { return cell_type_; }
  CellType GetSubType() const { return cell_sub_type_; }

  /// Computes the geometric info on the cell.
  void ComputeGeometricInfo(const MeshContinuum* grid);

  /// Serializes a cell into a vector of bytes.
  ByteArray Serialize() const;

  /// Provides string information of the cell.
  std::string ToString() const;

  uint64_t global_id = 0;
  std::uint32_t local_id = 0;
  int partition_id = 0;
  int num_parition = 0;
  unsigned int block_id = std::numeric_limits<unsigned int>::max();

  Vector3 centroid;
  double volume = 0.0;

  std::vector<uint64_t> vertex_ids;
  std::vector<CellFace> faces;

private:
  /// Primary type, i.e. SLAB, POLYGON, POLYHEDRON
  const CellType cell_type_;
  /// Subtype i.e. SLAB, QUADRILATERAL, HEXAHEDRON
  const CellType cell_sub_type_;

public:
  /// Deserializes a cell from a vector of bytes.
  static Cell DeSerialize(const ByteArray& raw, size_t& address);
};

} // namespace opensn

namespace std
{

/// Print face node.
ostream& operator<<(ostream& out, const opensn::FaceNode& n);

} // namespace std