From 19a4676e41c439af3f4b206ebaf8c7dc9931b51e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Del=20Pino?= <stephane.delpino44@gmail.com> Date: Fri, 4 Feb 2022 14:38:15 +0100 Subject: [PATCH] Add missing tests and check that required formula exist at runtime The check would previously occur only for non-release builds --- src/analysis/QuadratureManager.hpp | 72 ++++++++++++++++--- tests/test_CubeGaussQuadrature.cpp | 4 ++ tests/test_PrismGaussQuadrature.cpp | 4 ++ tests/test_PyramidGaussQuadrature.cpp | 4 ++ tests/test_SquareGaussQuadrature.cpp | 4 ++ .../test_TensorialGaussLegendreQuadrature.cpp | 30 ++++++++ .../test_TensorialGaussLobattoQuadrature.cpp | 24 +++++++ tests/test_TetrahedronGaussQuadrature.cpp | 4 ++ tests/test_TriangleGaussQuadrature.cpp | 4 ++ 9 files changed, 142 insertions(+), 8 deletions(-) diff --git a/src/analysis/QuadratureManager.hpp b/src/analysis/QuadratureManager.hpp index b0f81c543..04655f291 100644 --- a/src/analysis/QuadratureManager.hpp +++ b/src/analysis/QuadratureManager.hpp @@ -47,6 +47,10 @@ class QuadratureManager const QuadratureFormula<1>& getLineFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxLineDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxLineDegree(quadrature_descriptor.type())) + " on lines"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: case QuadratureType::GaussLegendre: { @@ -56,28 +60,40 @@ class QuadratureManager case QuadratureType::GaussLobatto: { return m_line_gauss_lobatto_formula_list[quadrature_descriptor.degree() / 2]; } + // LCOV_EXCL_START default: { - throw UnexpectedError("invalid quadrature type"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on lines"); } + // LCOV_EXCL_STOP } } const QuadratureFormula<2>& getTriangleFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxTriangleDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxTriangleDegree(quadrature_descriptor.type())) + " on triangles"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: { return m_triangle_gauss_formula_list[quadrature_descriptor.degree() - 1]; } + // LCOV_EXCL_START default: { - throw UnexpectedError(quadrature_descriptor.name() + " is not defined on triangles"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on triangles"); } + // LCOV_EXCL_STOP } } const QuadratureFormula<2>& getSquareFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxSquareDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxSquareDegree(quadrature_descriptor.type())) + " on squares"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: { return m_square_gauss_formula_list[quadrature_descriptor.degree() / 2]; @@ -88,54 +104,78 @@ class QuadratureManager case QuadratureType::GaussLobatto: { return m_square_gauss_lobatto_formula_list[quadrature_descriptor.degree() / 2]; } + // LCOV_EXCL_START default: { - throw UnexpectedError("invalid quadrature type"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on squares"); } + // LCOV_EXCL_STOP } } const QuadratureFormula<3>& getTetrahedronFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxTetrahedronDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxTetrahedronDegree(quadrature_descriptor.type())) + " on tetrahedra"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: { return m_tetrahedron_gauss_formula_list[quadrature_descriptor.degree() - 1]; } + // LCOV_EXCL_START default: { - throw UnexpectedError(quadrature_descriptor.name() + " is not defined on tetrahedron"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on tetrahedra"); } + // LCOV_EXCL_STOP } } const QuadratureFormula<3>& getPrismFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxPrismDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxPrismDegree(quadrature_descriptor.type())) + " on prisms"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: { return m_prism_gauss_formula_list[quadrature_descriptor.degree() - 1]; } + // LCOV_EXCL_START default: { - throw UnexpectedError(quadrature_descriptor.name() + " is not defined on prism"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on prisms"); } + // LCOV_EXCL_STOP } } const QuadratureFormula<3>& getPyramidFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxPyramidDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxPyramidDegree(quadrature_descriptor.type())) + " on pyramids"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: { return m_pyramid_gauss_formula_list[quadrature_descriptor.degree() - 1]; } + // LCOV_EXCL_START default: { - throw UnexpectedError(quadrature_descriptor.name() + " is not defined on pyramid"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on pyramid"); } + // LCOV_EXCL_STOP } } const QuadratureFormula<3>& getCubeFormula(const IQuadratureDescriptor& quadrature_descriptor) const { + if (quadrature_descriptor.degree() > maxCubeDegree(quadrature_descriptor.type())) { + throw NormalError(::name(quadrature_descriptor.type()) + " quadrature formulae handle degrees up to " + + std::to_string(maxCubeDegree(quadrature_descriptor.type())) + " on cubes"); + } switch (quadrature_descriptor.type()) { case QuadratureType::Gauss: { return m_cube_gauss_formula_list[quadrature_descriptor.degree() / 2]; @@ -147,9 +187,11 @@ class QuadratureManager case QuadratureType::GaussLobatto: { return m_cube_gauss_lobatto_formula_list[quadrature_descriptor.degree() / 2]; } + // LCOV_EXCL_START default: { - throw UnexpectedError("invalid quadrature type"); + throw UnexpectedError(::name(quadrature_descriptor.type()) + " is not defined on cubes"); } + // LCOV_EXCL_STOP } } @@ -164,9 +206,11 @@ class QuadratureManager case QuadratureType::GaussLobatto: { return m_line_gauss_lobatto_formula_list.size() * 2 - 1; } + // LCOV_EXCL_START default: { throw UnexpectedError("invalid quadrature type"); } + // LCOV_EXCL_STOP } } @@ -183,9 +227,11 @@ class QuadratureManager case QuadratureType::GaussLobatto: { return m_square_gauss_lobatto_formula_list.size() * 2 - 1; } + // LCOV_EXCL_START default: { throw UnexpectedError("invalid quadrature type"); } + // LCOV_EXCL_STOP } } @@ -196,9 +242,11 @@ class QuadratureManager case QuadratureType::Gauss: { return m_triangle_gauss_formula_list.size(); } + // LCOV_EXCL_START default: { - throw UnexpectedError(name(type) + " is not defined on triangle"); + throw UnexpectedError(::name(type) + " is not defined on triangle"); } + // LCOV_EXCL_STOP } } @@ -215,9 +263,11 @@ class QuadratureManager case QuadratureType::GaussLobatto: { return m_cube_gauss_lobatto_formula_list.size() * 2 - 1; } + // LCOV_EXCL_START default: { throw UnexpectedError("invalid quadrature type"); } + // LCOV_EXCL_STOP } } @@ -228,9 +278,11 @@ class QuadratureManager case QuadratureType::Gauss: { return m_prism_gauss_formula_list.size(); } + // LCOV_EXCL_START default: { throw UnexpectedError(::name(type) + " is not defined on prism"); } + // LCOV_EXCL_STOP } } @@ -241,9 +293,11 @@ class QuadratureManager case QuadratureType::Gauss: { return m_pyramid_gauss_formula_list.size(); } + // LCOV_EXCL_START default: { throw UnexpectedError(::name(type) + " is not defined on pyramid"); } + // LCOV_EXCL_STOP } } @@ -254,9 +308,11 @@ class QuadratureManager case QuadratureType::Gauss: { return m_tetrahedron_gauss_formula_list.size(); } + // LCOV_EXCL_START default: { throw UnexpectedError(::name(type) + " is not defined on tetrahedron"); } + // LCOV_EXCL_STOP } } diff --git a/tests/test_CubeGaussQuadrature.cpp b/tests/test_CubeGaussQuadrature.cpp index 1db30eb17..d4221fe32 100644 --- a/tests/test_CubeGaussQuadrature.cpp +++ b/tests/test_CubeGaussQuadrature.cpp @@ -488,6 +488,10 @@ TEST_CASE("CubeGaussQuadrature", "[analysis]") SECTION("max implemented degree") { REQUIRE(QuadratureManager::instance().maxCubeDegree(QuadratureType::Gauss) == CubeGaussQuadrature::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getCubeFormula( + GaussQuadratureDescriptor(CubeGaussQuadrature ::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(CubeGaussQuadrature ::max_degree) + " on cubes"); } SECTION("Access functions") diff --git a/tests/test_PrismGaussQuadrature.cpp b/tests/test_PrismGaussQuadrature.cpp index ceff287e5..000edeed6 100644 --- a/tests/test_PrismGaussQuadrature.cpp +++ b/tests/test_PrismGaussQuadrature.cpp @@ -682,5 +682,9 @@ TEST_CASE("PrismGaussQuadrature", "[analysis]") SECTION("max implemented degree") { REQUIRE(QuadratureManager::instance().maxPrismDegree(QuadratureType::Gauss) == PrismGaussQuadrature::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getPrismFormula( + GaussQuadratureDescriptor(PrismGaussQuadrature ::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(PrismGaussQuadrature ::max_degree) + " on prisms"); } } diff --git a/tests/test_PyramidGaussQuadrature.cpp b/tests/test_PyramidGaussQuadrature.cpp index e648c96fb..ea022b136 100644 --- a/tests/test_PyramidGaussQuadrature.cpp +++ b/tests/test_PyramidGaussQuadrature.cpp @@ -566,5 +566,9 @@ TEST_CASE("PyramidGaussQuadrature", "[analysis]") { REQUIRE(QuadratureManager::instance().maxPyramidDegree(QuadratureType::Gauss) == PyramidGaussQuadrature::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getPyramidFormula( + GaussQuadratureDescriptor(PyramidGaussQuadrature ::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(PyramidGaussQuadrature ::max_degree) + " on pyramids"); } } diff --git a/tests/test_SquareGaussQuadrature.cpp b/tests/test_SquareGaussQuadrature.cpp index 5e6b9d6e5..74f442a31 100644 --- a/tests/test_SquareGaussQuadrature.cpp +++ b/tests/test_SquareGaussQuadrature.cpp @@ -459,6 +459,10 @@ TEST_CASE("SquareGaussQuadrature", "[analysis]") SECTION("max implemented degree") { REQUIRE(QuadratureManager::instance().maxSquareDegree(QuadratureType::Gauss) == SquareGaussQuadrature::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getSquareFormula( + GaussQuadratureDescriptor(SquareGaussQuadrature ::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(SquareGaussQuadrature ::max_degree) + " on squares"); } SECTION("Access functions") diff --git a/tests/test_TensorialGaussLegendreQuadrature.cpp b/tests/test_TensorialGaussLegendreQuadrature.cpp index aa8708ec6..342a4fbaa 100644 --- a/tests/test_TensorialGaussLegendreQuadrature.cpp +++ b/tests/test_TensorialGaussLegendreQuadrature.cpp @@ -3,6 +3,7 @@ #include <catch2/matchers/catch_matchers_all.hpp> #include <analysis/GaussLegendreQuadratureDescriptor.hpp> +#include <analysis/GaussQuadratureDescriptor.hpp> #include <analysis/QuadratureManager.hpp> #include <analysis/TensorialGaussLegendreQuadrature.hpp> #include <utils/Exceptions.hpp> @@ -519,6 +520,15 @@ TEST_CASE("TensorialGaussLegendreQuadrature", "[analysis]") { REQUIRE(QuadratureManager::instance().maxLineDegree(QuadratureType::GaussLegendre) == TensorialGaussLegendreQuadrature<1>::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getLineFormula( + GaussLegendreQuadratureDescriptor(TensorialGaussLegendreQuadrature<1>::max_degree + 1)), + "error: Gauss-Legendre quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLegendreQuadrature<1>::max_degree) + " on lines"); + + REQUIRE_THROWS_WITH(QuadratureManager::instance().getLineFormula( + GaussQuadratureDescriptor(TensorialGaussLegendreQuadrature<1>::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLegendreQuadrature<1>::max_degree) + " on lines"); } } @@ -569,6 +579,16 @@ TEST_CASE("TensorialGaussLegendreQuadrature", "[analysis]") REQUIRE(integrate(px7y6, l7, 0, 1, 0.2, 0.8) == Catch::Approx(std::pow(0.8, 7) - std::pow(0.2, 7))); } + + SECTION("max implemented degree") + { + REQUIRE(QuadratureManager::instance().maxSquareDegree(QuadratureType::GaussLegendre) == + TensorialGaussLegendreQuadrature<2>::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getSquareFormula( + GaussLegendreQuadratureDescriptor(TensorialGaussLegendreQuadrature<2>::max_degree + 1)), + "error: Gauss-Legendre quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLegendreQuadrature<2>::max_degree) + " on squares"); + } } SECTION("3D") @@ -624,5 +644,15 @@ TEST_CASE("TensorialGaussLegendreQuadrature", "[analysis]") Catch::Approx((std::pow(0.8, 7) - std::pow(0.2, 7)) * (0.7 - -0.1) + (0.8 - 0.2) * (std::pow(0.7, 8) - std::pow(-0.1, 8)))); } + + SECTION("max implemented degree") + { + REQUIRE(QuadratureManager::instance().maxCubeDegree(QuadratureType::GaussLegendre) == + TensorialGaussLegendreQuadrature<3>::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getCubeFormula( + GaussLegendreQuadratureDescriptor(TensorialGaussLegendreQuadrature<3>::max_degree + 1)), + "error: Gauss-Legendre quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLegendreQuadrature<3>::max_degree) + " on cubes"); + } } } diff --git a/tests/test_TensorialGaussLobattoQuadrature.cpp b/tests/test_TensorialGaussLobattoQuadrature.cpp index e038b692e..9ee4028cf 100644 --- a/tests/test_TensorialGaussLobattoQuadrature.cpp +++ b/tests/test_TensorialGaussLobattoQuadrature.cpp @@ -294,6 +294,10 @@ TEST_CASE("TensorialGaussLobattoQuadrature", "[analysis]") { REQUIRE(QuadratureManager::instance().maxLineDegree(QuadratureType::GaussLobatto) == TensorialGaussLobattoQuadrature<1>::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getLineFormula( + GaussLobattoQuadratureDescriptor(TensorialGaussLobattoQuadrature<1>::max_degree + 1)), + "error: Gauss-Lobatto quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLobattoQuadrature<1>::max_degree) + " on lines"); } } @@ -344,6 +348,16 @@ TEST_CASE("TensorialGaussLobattoQuadrature", "[analysis]") REQUIRE(integrate(px7y6, l7, 0, 1, 0.2, 0.8) == Catch::Approx(std::pow(0.8, 7) - std::pow(0.2, 7))); } + + SECTION("max implemented degree") + { + REQUIRE(QuadratureManager::instance().maxSquareDegree(QuadratureType::GaussLobatto) == + TensorialGaussLobattoQuadrature<2>::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getSquareFormula( + GaussLobattoQuadratureDescriptor(TensorialGaussLobattoQuadrature<2>::max_degree + 1)), + "error: Gauss-Lobatto quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLobattoQuadrature<2>::max_degree) + " on squares"); + } } SECTION("3D") @@ -399,6 +413,16 @@ TEST_CASE("TensorialGaussLobattoQuadrature", "[analysis]") Catch::Approx((std::pow(0.8, 7) - std::pow(0.2, 7)) * (0.7 - -0.1) + (0.8 - 0.2) * (std::pow(0.7, 8) - std::pow(-0.1, 8)))); } + + SECTION("max implemented degree") + { + REQUIRE(QuadratureManager::instance().maxCubeDegree(QuadratureType::GaussLobatto) == + TensorialGaussLobattoQuadrature<3>::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getCubeFormula( + GaussLobattoQuadratureDescriptor(TensorialGaussLobattoQuadrature<3>::max_degree + 1)), + "error: Gauss-Lobatto quadrature formulae handle degrees up to " + + std::to_string(TensorialGaussLobattoQuadrature<3>::max_degree) + " on cubes"); + } } SECTION("Access functions") diff --git a/tests/test_TetrahedronGaussQuadrature.cpp b/tests/test_TetrahedronGaussQuadrature.cpp index 605d1dc1f..a412c1368 100644 --- a/tests/test_TetrahedronGaussQuadrature.cpp +++ b/tests/test_TetrahedronGaussQuadrature.cpp @@ -679,5 +679,9 @@ TEST_CASE("TetrahedronGaussQuadrature", "[analysis]") { REQUIRE(QuadratureManager::instance().maxTetrahedronDegree(QuadratureType::Gauss) == TetrahedronGaussQuadrature::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getTetrahedronFormula( + GaussQuadratureDescriptor(TetrahedronGaussQuadrature ::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(TetrahedronGaussQuadrature ::max_degree) + " on tetrahedra"); } } diff --git a/tests/test_TriangleGaussQuadrature.cpp b/tests/test_TriangleGaussQuadrature.cpp index 3d7b5dffa..4ed18d602 100644 --- a/tests/test_TriangleGaussQuadrature.cpp +++ b/tests/test_TriangleGaussQuadrature.cpp @@ -624,5 +624,9 @@ TEST_CASE("TriangleGaussQuadrature", "[analysis]") { REQUIRE(QuadratureManager::instance().maxTriangleDegree(QuadratureType::Gauss) == TriangleGaussQuadrature::max_degree); + REQUIRE_THROWS_WITH(QuadratureManager::instance().getTriangleFormula( + GaussQuadratureDescriptor(TriangleGaussQuadrature::max_degree + 1)), + "error: Gauss quadrature formulae handle degrees up to " + + std::to_string(TriangleGaussQuadrature::max_degree) + " on triangles"); } } -- GitLab