Program Listing for File grid2D_overlay.hpp

Return to documentation for file (rcppsw/ds/grid2D_overlay.hpp)

#pragma once

/*******************************************************************************
 * Includes
 ******************************************************************************/
#include <limits>

#include "rcppsw/ds/base_grid2D.hpp"
#include "rcppsw/ds/base_grid_overlay.hpp"
#include "rcppsw/er/client.hpp"

/*******************************************************************************
 * Namespaces/Decls
 ******************************************************************************/
namespace rcppsw::ds {

/*******************************************************************************
 * Class Definitions
 ******************************************************************************/
template <typename T>
class grid2D_overlay final : public base_grid2D<T>,
                             public base_grid_overlay<math::vector2d>,
                             public er::client<grid2D_overlay<T>> {
 public:
  using typename base_grid2D<T>::index_range;
  using typename base_grid2D<T>::grid_view;
  using typename base_grid2D<T>::const_grid_view;
  using typename base_grid2D<T>::grid_type;
  using typename base_grid2D<T>::coord_type;

  using base_grid2D<T>::access;

  using base_grid_overlay<math::vector2d>::resolution;
  using base_grid_overlay<math::vector2d>::originr;
  using base_grid_overlay<math::vector2d>::origind;

  grid2D_overlay(const math::vector2d& origin,
                 const math::vector2d& dims,
                 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(dims),
        m_cells(boost::extents[static_cast<typename index_range::index>(xdsize())]
                              [typename index_range::index(ydsize())]) {
    RCPPSW_UNUSED double remx = std::remainder(mc_dim.x(), resolution().v());
    RCPPSW_UNUSED double remy = std::remainder(mc_dim.y(), 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());
  }

  T& access(size_t i, size_t j) override {
    return m_cells[static_cast<typename index_range::index>(i)]
        [static_cast<typename index_range::index>(j)];
  }

  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());
  }

  double xrsize(void) const { return mc_dim.x(); }

  double yrsize(void) const { return mc_dim.y(); }

  const math::vector2d& rdims2D(void) const { return mc_dim; }

  coord_type ddims2D(void) const {
    return math::dvec2zvec(mc_dim, resolution().v());
  }

 private:
  size_t xsize(void) const override { return xdsize(); }
  size_t ysize(void) const override { return ydsize(); }

  grid_type& grid(void) override { return m_cells; }
  const grid_type& grid(void) const override { return m_cells; }

  /* clang-format off */
  const math::vector2d          mc_dim;

  grid_type                     m_cells;
  /* clang-format on */
};

} /* namespace rcppsw::ds */