diff --git a/test/common/geometry/CMakeLists.txt b/test/common/geometry/CMakeLists.txt index ac824ae957e986a0a54d9df85c0461d5faf32434..ae96d62fc480d20f3ec458f0744270e00643dd51 100644 --- a/test/common/geometry/CMakeLists.txt +++ b/test/common/geometry/CMakeLists.txt @@ -1,4 +1,5 @@ dune_add_test(SOURCES test_1d3d_intersection.cc LABELS unit) +dune_add_test(SOURCES test_1d2d_intersection.cc LABELS unit) dune_add_test(SOURCES test_2d3d_intersection.cc LABELS unit) dune_add_test(SOURCES test_graham_convex_hull.cc LABELS unit) dune_add_test(SOURCES test_makegeometry.cc LABELS unit) diff --git a/test/common/geometry/test_1d2d_intersection.cc b/test/common/geometry/test_1d2d_intersection.cc new file mode 100644 index 0000000000000000000000000000000000000000..bc0612d1c1d15d25b4dbeb2042fba5490c927761 --- /dev/null +++ b/test/common/geometry/test_1d2d_intersection.cc @@ -0,0 +1,110 @@ +#include <config.h> + +#include <iostream> +#include <algorithm> +#include <initializer_list> + +#include <dune/common/exceptions.hh> +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/fvector.hh> +#include <dune/geometry/multilineargeometry.hh> + +#include <dumux/common/geometry/geometryintersection.hh> + + +#ifndef DOXYGEN +template<int dimworld = 2> +Dune::MultiLinearGeometry<double, 1, dimworld> +makeLine(std::initializer_list<Dune::FieldVector<double, dimworld>>&& c) +{ + return {Dune::GeometryTypes::line, c}; +} + +template<int dimworld = 2> +bool testIntersection(const Dune::MultiLinearGeometry<double, dimworld, dimworld>& polygon, + const Dune::MultiLinearGeometry<double, 1, dimworld>& line, + bool foundExpected = true) +{ + using Test = Dumux::GeometryIntersection<Dune::MultiLinearGeometry<double,dimworld,dimworld>, + Dune::MultiLinearGeometry<double,1,dimworld> >; + typename Test::IntersectionType intersection; + bool found = Test::intersection(polygon, line, intersection); + if (!found && foundExpected) + std::cerr << "Failed detecting intersection with " << line.corner(0) << " " << line.corner(1) << std::endl; + else if (found && foundExpected) + std::cout << "Found intersection with " << line.corner(0) << " " << line.corner(1) << std::endl; + else if (found && !foundExpected) + std::cerr << "Found false positive: intersection with " << line.corner(0) << " " << line.corner(1) << std::endl; + else if (!found && !foundExpected) + std::cout << "No intersection with " << line.corner(0) << " " << line.corner(1) << std::endl; + return (found == foundExpected); +} +#endif + +int main (int argc, char *argv[]) try +{ + // maybe initialize mpi + Dune::MPIHelper::instance(argc, argv); + + constexpr int dimworld = 2; + constexpr int dim = 2; + + // we test quadrilateral-line & triangle-line intersections + using CornerStorage = std::vector<Dune::FieldVector<double, dimworld>>; + CornerStorage quadCorners({ {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0}, {1.0, 1.0} }); + CornerStorage triaCorners({ {0.0, 0.0}, {1.0, 0.0}, {0.0, 1.0} }); + + using Geometry = Dune::MultiLinearGeometry<double, dim, dimworld>; + Geometry quad(Dune::GeometryTypes::cube(dimworld), quadCorners); + Geometry triangle(Dune::GeometryTypes::simplex(dimworld), triaCorners); + + // collect returns to determine exit code + std::vector<bool> returns; + + // the tests + returns.push_back(testIntersection(quad, makeLine({ {0.0, 0.0}, {1.0, 0.0} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.0, 0.0}, {0.0, 1.0} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.0, 0.0}, {1.0, 1.0} }))); + + returns.push_back(testIntersection(quad, makeLine({ {1.0, 0.0}, {1.0, 1.0} }))); + returns.push_back(testIntersection(quad, makeLine({ {1.0, 1.0}, {0.0, 1.0} }))); + + returns.push_back(testIntersection(quad, makeLine({ {0.5, 0.0}, {0.5, 1.0} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.0, 0.5}, {1.0, 0.5} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.5, 0.5}, {0.5, 2.0} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.5, 0.5}, {0.5, -2.0} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.5, 0.5}, {-2.0, 0.5} }))); + returns.push_back(testIntersection(quad, makeLine({ {0.5, 0.5}, {2.0, 0.5} }))); + + returns.push_back(testIntersection(quad, makeLine({ {0.5, 0.0}, {0.5, -2.0} }), false)); + returns.push_back(testIntersection(quad, makeLine({ {0.5, 1.0}, {0.5, 2.0} }), false)); + + returns.push_back(testIntersection(triangle, makeLine({ {0.0, 0.0}, {1.0, 0.0} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.0, 0.0}, {0.0, 1.0} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.0, 0.0}, {1.0, 1.0} }))); + + returns.push_back(testIntersection(triangle, makeLine({ {0.5, 0.0}, {0.5, 1.0} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.0, 0.5}, {1.0, 0.5} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.5, 0.5}, {0.0, 0.0} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.0, 0.0}, {0.5, 0.5} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.5, 0.5}, {-2.0, 0.5} }))); + returns.push_back(testIntersection(triangle, makeLine({ {0.5, 0.5}, {0.5, -2.0} }))); + + returns.push_back(testIntersection(triangle, makeLine({ {1.0, 1.0}, {0.0, 1.0} }), false)); + returns.push_back(testIntersection(triangle, makeLine({ {1.0, 0.0}, {1.0, 1.0} }), false)); + + // determine the exit code + if (std::any_of(returns.begin(), returns.end(), [](bool i){ return !i; })) + return 1; + + std::cout << "All tests passed!" << std::endl; + + return 0; +} +// ////////////////////////////////// +// Error handler +// ///////////////////////////////// +catch (const Dune::Exception& e) { + std::cout << e << std::endl; + return 1; +}