Program Listing for File field_layout.h

↰ Return to documentation for file (src/pcms/field/field_layout.h)

#ifndef PCMS_FIELD_LAYOUT_H
#define PCMS_FIELD_LAYOUT_H
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "pcms/discretization/discretization.h"
#include "pcms/utility/types.h"
#include "pcms/utility/arrays.h"
#include "pcms/field/coordinate_system.hpp"
#include "pcms/field/coordinate_view.hpp"

namespace pcms
{

constexpr int ent_offsets_len = 5;
using EntOffsetsArray = std::array<size_t, ent_offsets_len>;

using ReversePartitionMap = std::map<pcms::LO, std::vector<pcms::LO>>;

class FieldLayout
{
public:
  // Optional identifier for this layout. Set once at construction (via a From*
  // factory) and empty by default. Consumers that need to identify a layout by
  // a stable name use it; it carries no meaning within the field layer itself.
  [[nodiscard]] const std::string& GetName() const noexcept { return name_; }
  void SetName(std::string name) { name_ = std::move(name); }

  virtual std::shared_ptr<const Discretization> GetDiscretization()
    const noexcept = 0;

  // number of components
  int virtual GetNumComponents() const = 0;

  // nodes for standard lagrange FEM
  LO virtual GetNumOwnedDofHolder() const = 0;
  GO virtual GetNumGlobalDofHolder() const = 0;

  // size of buffer that needs to be allocated to represent the field
  // # components * NumDOFHolder
  LO OwnedSize() const { return GetNumComponents() * GetNumOwnedDofHolder(); };
  GO GlobalSize() const
  {
    return GetNumComponents() * GetNumGlobalDofHolder();
  };

  virtual Rank1View<const bool, HostMemorySpace> GetOwnedHost() const = 0;
  virtual GlobalIDView<HostMemorySpace> GetGidsHost() const = 0;

  // Maps each local DOF holder to its contiguous active index, ordered by GID
  // within each entity block. Components are not included in the permutation.
  // For local GIDs [102, 7, 41, 19], the permutation is [3, 0, 2, 1]. Thus
  // holder i, component c is read from values(permutation(i), c), or from
  // flat_values[permutation(i) * num_components + c].
  Kokkos::View<const LO*, HostMemorySpace> GetGlobalToLocalPermutationHost()
    const;
  Kokkos::View<const LO*, DeviceMemorySpace> GetGlobalToLocalPermutation()
    const;

  // returns true if the field layout is distributed
  // if the field layout is distributed, the owned and global dofs are the same
  [[nodiscard]] virtual bool IsDistributed() const = 0;

  virtual EntOffsetsArray GetEntOffsets() const = 0;

  [[nodiscard]] const std::shared_ptr<const CoordinateSystem>&
  GetCoordinateSystem() const
  {
    if (system_ == nullptr) {
      throw pcms_error("FieldLayout::GetCoordinateSystem: layout has no "
                       "coordinate system set");
    }
    return system_;
  }

  virtual CoordinateView<DeviceMemorySpace> GetDOFHolderCoordinates() const = 0;

  virtual int GetDimension() const = 0;

  virtual Rank1View<const LO, HostMemorySpace>
  GetDOFHolderClassificationDimensionsHost() const = 0;

  virtual Rank1View<const LO, HostMemorySpace>
  GetDOFHolderClassificationIdsHost() const = 0;

  virtual ~FieldLayout() noexcept = default;

protected:
  // Builds the global-to-local permutation from GetGidsHost()/GetEntOffsets().
  // Derived layouts that support GetGlobalToLocalPermutation() must call this
  // from their constructor, once their GIDs and entity offsets are available;
  // building eagerly keeps first access free of the data race that lazy
  // construction of the mutable cache would introduce.
  void BuildGlobalToLocalPermutation();

  void SetCoordinateSystem(
    std::shared_ptr<const CoordinateSystem> coordinate_system)
  {
    if (coordinate_system == nullptr) {
      throw pcms_error(
        "FieldLayout::SetCoordinateSystem: coordinate system must not be null");
    }
    system_ = std::move(coordinate_system);
  }

private:
  std::shared_ptr<const CoordinateSystem> system_;
  std::string name_;
  Kokkos::View<LO*, HostMemorySpace> global_to_local_host_;
  Kokkos::View<LO*, DeviceMemorySpace> global_to_local_;
};

} // namespace pcms
#endif // PCMS_FIELD_LAYOUT_H