Skip to content

Commit

Permalink
Merge pull request #1088 from aprokop/kdop_2d
Browse files Browse the repository at this point in the history
Add KDOP<2,4> and KDOP<2,8>
  • Loading branch information
aprokop authored May 16, 2024
2 parents 8aae58e + 5fb410e commit c4fdba5
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 27 deletions.
93 changes: 74 additions & 19 deletions src/geometry/ArborX_KDOP.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,38 @@ namespace Details
template <int DIM, int k, typename Coordinate>
struct KDOP_Directions;

template <typename Coordinate>
struct KDOP_Directions<2, 4, Coordinate>
{
static constexpr int n_directions = 2;
static KOKKOS_FUNCTION auto const &directions()
{
using Direction = Vector<2, Coordinate>;
static constexpr Kokkos::Array<Direction, n_directions> directions = {
Direction{1, 0},
Direction{0, 1},
};
return directions;
}
};

template <typename Coordinate>
struct KDOP_Directions<2, 8, Coordinate>
{
static constexpr int n_directions = 4;
static KOKKOS_FUNCTION auto const &directions()
{
using Direction = Vector<2, Coordinate>;
static constexpr Kokkos::Array<Direction, n_directions> directions = {
Direction{1, 0},
Direction{0, 1},
Direction{1, 1},
Direction{1, -1},
};
return directions;
}
};

template <typename Coordinate>
struct KDOP_Directions<3, 6, Coordinate>
{
Expand Down Expand Up @@ -218,33 +250,56 @@ struct expand<KDOPTag, BoxTag, KDOP, Box>
{
KOKKOS_FUNCTION static void apply(KDOP &kdop, Box const &box)
{
constexpr int DIM = GeometryTraits::dimension_v<KDOP>;
static_assert(DIM == 2 || DIM == 3);

// NOTE if any of the ranges is invalid, the code below would actually
// expand the KDOP which is not what we want.
// We may revisit this later and decide passing a valid box becomes a
// precondition but this would be a breaking change (going from a wide to a
// narrow contract).
for (int i = 0; i < 3; ++i)
if (box.minCorner()[i] > box.maxCorner()[i])
for (int d = 0; d < DIM; ++d)
if (box.minCorner()[d] > box.maxCorner()[d])
return;

auto const xmin = box.minCorner()[0];
auto const ymin = box.minCorner()[1];
auto const zmin = box.minCorner()[2];
auto const xmax = box.maxCorner()[0];
auto const ymax = box.maxCorner()[1];
auto const zmax = box.maxCorner()[2];
for (auto const &point : {
Point{xmin, ymin, zmin},
Point{xmin, ymax, zmin},
Point{xmin, ymin, zmax},
Point{xmin, ymax, zmax},
Point{xmax, ymin, zmin},
Point{xmax, ymax, zmin},
Point{xmax, ymin, zmax},
Point{xmax, ymax, zmax},
})
using Point = std::decay_t<decltype(box.minCorner())>;
if constexpr (DIM == 3)
{
Details::expand(kdop, point);
auto const xmin = box.minCorner()[0];
auto const ymin = box.minCorner()[1];
auto const zmin = box.minCorner()[2];
auto const xmax = box.maxCorner()[0];
auto const ymax = box.maxCorner()[1];
auto const zmax = box.maxCorner()[2];
for (auto const &point : {
Point{xmin, ymin, zmin},
Point{xmin, ymax, zmin},
Point{xmin, ymin, zmax},
Point{xmin, ymax, zmax},
Point{xmax, ymin, zmin},
Point{xmax, ymax, zmin},
Point{xmax, ymin, zmax},
Point{xmax, ymax, zmax},
})
{
Details::expand(kdop, point);
}
}
else
{
auto const xmin = box.minCorner()[0];
auto const ymin = box.minCorner()[1];
auto const xmax = box.maxCorner()[0];
auto const ymax = box.maxCorner()[1];
for (auto const &point : {
Point{xmin, ymin},
Point{xmin, ymax},
Point{xmax, ymin},
Point{xmax, ymax},
})
{
Details::expand(kdop, point);
}
}
}
};
Expand Down
97 changes: 89 additions & 8 deletions test/tstKDOP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,103 @@
* SPDX-License-Identifier: BSD-3-Clause *
****************************************************************************/

#include <ArborX_Box.hpp>
#include <ArborX_DetailsAlgorithms.hpp>
#include <ArborX_HyperBox.hpp>
#include <ArborX_HyperPoint.hpp>
#include <ArborX_KDOP.hpp>
#include <ArborX_Point.hpp>

#include "BoostTest_CUDA_clang_workarounds.hpp"
#include <boost/test/unit_test.hpp>

#include <tuple>
#include <type_traits>

using ArborX::Box;
using ArborX::Point;
using ArborX::Experimental::KDOP;

using KDOP_types =
std::tuple<KDOP<3, 6>, KDOP<3, 14>, KDOP<3, 18>, KDOP<3, 26>>;

BOOST_AUTO_TEST_SUITE(DiscreteOrientedPolytopes)

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_KDOP, KDOP_t, KDOP_types)
using KDOP_2D_types = std::tuple<KDOP<2, 4>, KDOP<2, 8>>;

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_kdop_kdop_2D, KDOP_t, KDOP_2D_types)
{
using Point = ArborX::ExperimentalHyperGeometry::Point<2>;
KDOP_t x;
BOOST_TEST(!intersects(x, x));
expand(x, Point{1, 0});
expand(x, Point{0, 1});
BOOST_TEST(intersects(x, x));
BOOST_TEST(!intersects(x, KDOP_t{}));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_kdop_box_2D, KDOP_t, KDOP_2D_types)
{
using Point = ArborX::ExperimentalHyperGeometry::Point<2>;
using Box = ArborX::ExperimentalHyperGeometry::Box<2>;

KDOP_t x;
BOOST_TEST(!intersects(x, Box{}));
BOOST_TEST(!intersects(x, Box{{0, 0}, {1, 1}}));
expand(x, Point{1, 0});
expand(x, Point{0, 1});
BOOST_TEST(!intersects(x, Box{}));
BOOST_TEST(intersects(x, Box{{0, 0}, {1, 1}}));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_point_kdop_2D, KDOP_t, KDOP_2D_types)
{
using Point = ArborX::ExperimentalHyperGeometry::Point<2>;
{
KDOP_t x;
BOOST_TEST(!intersects(Point{1, 1}, x));
}
{
KDOP_t x; // rombus
expand(x, Point{0.5f, 0});
expand(x, Point{0.5f, 1});
expand(x, Point{0, 0.5f});
expand(x, Point{1, 0.5f});
// unit square corners
BOOST_TEST(intersects(Point{0, 0}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
BOOST_TEST(intersects(Point{1, 0}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
BOOST_TEST(intersects(Point{0, 1}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
BOOST_TEST(intersects(Point{1, 1}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
// rombus corners
BOOST_TEST(intersects(Point{0.5f, 0}, x));
BOOST_TEST(intersects(Point{0.5f, 1}, x));
BOOST_TEST(intersects(Point{0, 0.5f}, x));
BOOST_TEST(intersects(Point{1, 0.5f}, x));
// unit square center
BOOST_TEST(intersects(Point{0.5f, 0.5f}, x));
// mid rombus diagonals
BOOST_TEST(intersects(Point{0.75f, 0.25f}, x));
BOOST_TEST(intersects(Point{0.25f, 0.25f}, x));
BOOST_TEST(intersects(Point{0.25f, 0.75f}, x));
BOOST_TEST(intersects(Point{0.75f, 0.75f}, x));
// slightly outside of the diagonals
BOOST_TEST(intersects(Point{0.8f, 0.2f}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
BOOST_TEST(intersects(Point{0.2f, 0.2f}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
BOOST_TEST(intersects(Point{0.2f, 0.8f}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
BOOST_TEST(intersects(Point{0.8f, 0.8f}, x) ==
(std::is_same_v<KDOP_t, KDOP<2, 4>>));
}
}

using KDOP_3D_types =
std::tuple<KDOP<3, 6>, KDOP<3, 14>, KDOP<3, 18>, KDOP<3, 26>>;

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_kdop_kdop_3D, KDOP_t, KDOP_3D_types)
{
using ArborX::Point;

KDOP_t x;
BOOST_TEST(!intersects(x, x));
expand(x, Point{1, 0, 0});
Expand All @@ -38,8 +115,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_KDOP, KDOP_t, KDOP_types)
BOOST_TEST(!intersects(x, KDOP_t{}));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_box, KDOP_t, KDOP_types)
BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_kdop_box_3D, KDOP_t, KDOP_3D_types)
{
using ArborX::Box;
using ArborX::Point;

KDOP_t x;
BOOST_TEST(!intersects(x, Box{}));
BOOST_TEST(!intersects(x, Box{{0, 0, 0}, {1, 1, 1}}));
Expand All @@ -50,8 +130,9 @@ BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_box, KDOP_t, KDOP_types)
BOOST_TEST(intersects(x, Box{{0, 0, 0}, {1, 1, 1}}));
}

BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_point, KDOP_t, KDOP_types)
BOOST_AUTO_TEST_CASE_TEMPLATE(intersects_point_kdop, KDOP_t, KDOP_3D_types)
{
using ArborX::Point;
{
KDOP_t x;
BOOST_TEST(!intersects(Point{1, 1, 1}, x));
Expand Down

0 comments on commit c4fdba5

Please sign in to comment.