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 */