Program Listing for File grid3D_overlay.hpp
↰ Return to documentation for file (rcppsw/ds/grid3D_overlay.hpp)
#pragma once
/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <limits>
#include "rcppsw/ds/base_grid3D.hpp"
#include "rcppsw/ds/base_grid_overlay.hpp"
#include "rcppsw/er/client.hpp"
/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::ds {
/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
template <typename T>
class grid3D_overlay : public base_grid3D<T>,
                       public base_grid_overlay<math::vector3d>,
                       public er::client<grid3D_overlay<T>> {
 public:
  using typename base_grid3D<T>::index_range;
  using typename base_grid3D<T>::grid_view;
  using typename base_grid3D<T>::const_grid_view;
  using typename base_grid3D<T>::grid_type;
  using typename base_grid3D<T>::coord_type;
  using base_grid3D<T>::access;
  using base_grid_overlay<math::vector3d>::resolution;
  using base_grid_overlay<math::vector3d>::originr;
  using base_grid_overlay<math::vector3d>::origind;
  grid3D_overlay(const math::vector3d& origin,
                 const math::vector3d& dim,
                 const types::discretize_ratio& grid_res,
                 const types::discretize_ratio& field_res)
      : base_grid_overlay(origin, grid_res, field_res),
        ER_CLIENT_INIT(),
        mc_dim(dim),
        m_cells(boost::extents[static_cast<typename index_range::index>(xdsize())]
                              [typename index_range::index(ydsize())]
                              [typename index_range::index(zdsize())]) {
    double remx = std::remainder(mc_dim.x(), resolution().v());
    double remy = std::remainder(mc_dim.y(), resolution().v());
    double remz = std::remainder(mc_dim.z(), resolution().v());
    /*
     * Some values of dimensions and grid resolution might not be able to be
     * represented exactly, so we can't just assert that the mod result =
     * 0.0. Instead, we verify that IF the mod result is > 0.0 that it is also
     * VERY close to the grid resolution.
     */
    ER_ASSERT(remx <= 1.0 / ONEE9,
              "X dimension (%f) not an even multiple of resolution (%f)",
              mc_dim.x(),
              resolution().v());
    ER_ASSERT(remy <= 1.0 / ONEE9,
              "Y dimension (%f) not an even multiple of resolution (%f)",
              mc_dim.y(),
              resolution().v());
    ER_ASSERT(remz <= 1.0 / ONEE9,
              "Z dimension (%f) not an even multiple of resolution (%f)",
              mc_dim.z(),
              resolution().v());
  }
  virtual ~grid3D_overlay(void) = default;
  size_t xdsize(void) const {
    return static_cast<size_t>(mc_dim.x() / resolution().v());
  }
  size_t ydsize(void) const {
    return static_cast<size_t>(mc_dim.y() / resolution().v());
  }
  size_t zdsize(void) const {
    return static_cast<size_t>(mc_dim.z() / resolution().v());
  }
  double xrsize(void) const { return mc_dim.x(); }
  double yrsize(void) const { return mc_dim.y(); }
  double zrsize(void) const { return mc_dim.z(); }
  const math::vector3d& rdims3D(void) const { return mc_dim; }
  coord_type ddims3D(void) const {
    return math::dvec2zvec(mc_dim, resolution().v());
  }
  T& access(size_t i, size_t j, size_t k) override {
    return m_cells[static_cast<typename index_range::index>(i)]
                  [static_cast<typename index_range::index>(j)]
                  [static_cast<typename index_range::index>(k)];
  }
 private:
  size_t xsize(void) const override { return xdsize(); }
  size_t ysize(void) const override { return ydsize(); }
  size_t zsize(void) const override { return zdsize(); }
  grid_type& grid(void) override { return m_cells; }
  const grid_type& grid(void) const override { return m_cells; }
  /* clang-format off */
  const math::vector3d          mc_dim;
  grid_type                     m_cells;
  /* clang-format on */
};
} /* namespace rcppsw::ds */