diff --git a/src/scheme/PolynomialReconstruction.cpp b/src/scheme/PolynomialReconstruction.cpp index e3fe0193092fa5daccda3009c5c65d97b5afb31e..7557c284e1fa86fd65d21480642850ea6f5a3504 100644 --- a/src/scheme/PolynomialReconstruction.cpp +++ b/src/scheme/PolynomialReconstruction.cpp @@ -102,12 +102,11 @@ class PolynomialReconstruction::MutableDiscreteFunctionDPkVariant template <MeshConcept MeshType> [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> PolynomialReconstruction::_build( - const size_t degree, - const bool preconditioning, - const bool row_weighting, const std::shared_ptr<const MeshType>& p_mesh, const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) const { + const size_t degree = m_descriptor.degree(); + if (degree != 1) { throw NotImplementedError("only degree 1 is available"); } @@ -282,7 +281,7 @@ PolynomialReconstruction::_build( } } - if (row_weighting) { + if (m_descriptor.rowWeighting()) { // Add row weighting (give more importance to cells that are // closer to j) for (size_t i = 0; i < stencil_cell_list.size(); ++i) { @@ -299,7 +298,7 @@ PolynomialReconstruction::_build( const SmallMatrix<double>& X = X_pool[t]; - if (preconditioning) { + if (m_descriptor.preconditioning()) { // Add column weighting preconditioning (increase the presition) SmallArray<double>& G = G_pool[t]; @@ -447,9 +446,6 @@ PolynomialReconstruction::_build( std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> PolynomialReconstruction::build( - const size_t degree, - const bool preconditioning, - const bool row_weighting, const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) const { if (not hasSameMesh(discrete_function_variant_list)) { @@ -458,9 +454,6 @@ PolynomialReconstruction::build( auto mesh_v = getCommonMesh(discrete_function_variant_list); - return std::visit( - [&](auto&& p_mesh) { - return this->_build(degree, preconditioning, row_weighting, p_mesh, discrete_function_variant_list); - }, - mesh_v->variant()); + return std::visit([&](auto&& p_mesh) { return this->_build(p_mesh, discrete_function_variant_list); }, + mesh_v->variant()); } diff --git a/src/scheme/PolynomialReconstruction.hpp b/src/scheme/PolynomialReconstruction.hpp index 74bb827854facd86fc7e51191468908b72d6b481..c0da0f26074cce3e38457d9fa1901ed6ef194e43 100644 --- a/src/scheme/PolynomialReconstruction.hpp +++ b/src/scheme/PolynomialReconstruction.hpp @@ -7,6 +7,7 @@ #include <algebra/SmallVector.hpp> #include <mesh/MeshTraits.hpp> #include <scheme/DiscreteFunctionDPkVariant.hpp> +#include <scheme/PolynomialReconstructionDescriptor.hpp> #warning MOVE TO .cpp WHEN FINISHED #include <algebra/Givens.hpp> @@ -26,11 +27,10 @@ class PolynomialReconstruction private: class MutableDiscreteFunctionDPkVariant; + const PolynomialReconstructionDescriptor m_descriptor; + template <MeshConcept MeshType> [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> _build( - const size_t degree, - const bool preconditioning, - const bool row_weighting, const std::shared_ptr<const MeshType>& p_mesh, const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) const; @@ -266,15 +266,11 @@ class PolynomialReconstruction } [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> build( - const size_t degree, - const bool preconditioning, - const bool row_weighting, const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) const; -#warning add reconstruction descriptor/option to handle the options to be used for reconstruction template <typename... DiscreteFunctionT> [[nodiscard]] std::vector<std::shared_ptr<const DiscreteFunctionDPkVariant>> - build(const size_t degree, const bool preconditioning, const bool row_weighting, DiscreteFunctionT... input) const + build(DiscreteFunctionT... input) const { std::vector<std::shared_ptr<const DiscreteFunctionVariant>> variant_vector; auto convert = [&variant_vector](auto&& df) { @@ -294,10 +290,11 @@ class PolynomialReconstruction }; (convert(std::forward<DiscreteFunctionT>(input)), ...); - return this->build(degree, preconditioning, row_weighting, variant_vector); + return this->build(variant_vector); } - PolynomialReconstruction() {} + PolynomialReconstruction(const PolynomialReconstructionDescriptor& descriptor) : m_descriptor{descriptor} {} + ~PolynomialReconstruction() = default; }; #endif // POLYNOMIAL_RECONSTRUCTION_HPP diff --git a/src/scheme/PolynomialReconstructionDescriptor.hpp b/src/scheme/PolynomialReconstructionDescriptor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..a7394500106b2f8a43c5e62f9ee74912b4d8fee5 --- /dev/null +++ b/src/scheme/PolynomialReconstructionDescriptor.hpp @@ -0,0 +1,68 @@ +#ifndef POLYNOMIAL_RECONSTRUCTION_DESCRIPTOR_HPP +#define POLYNOMIAL_RECONSTRUCTION_DESCRIPTOR_HPP + +#include <utils/PugsMacros.hpp> + +#include <cstddef> + +class PolynomialReconstructionDescriptor +{ + private: + size_t m_degree; + bool m_preconditioning = true; + bool m_row_weighting = true; + + public: + PUGS_INLINE + size_t + degree() const + { + return m_degree; + } + + PUGS_INLINE + bool + preconditioning() const + { + return m_preconditioning; + } + + PUGS_INLINE + bool + rowWeighting() const + { + return m_row_weighting; + } + + PUGS_INLINE + void + setDegree(const size_t degree) + { + m_degree = degree; + } + + PUGS_INLINE + void + setPreconditioning(const bool preconditioning) + { + m_preconditioning = preconditioning; + } + + PUGS_INLINE + void + setRowWeighting(const bool row_weighting) + { + m_row_weighting = row_weighting; + } + + PolynomialReconstructionDescriptor(const size_t degree) : m_degree{degree} {} + + PolynomialReconstructionDescriptor() = delete; + + PolynomialReconstructionDescriptor(const PolynomialReconstructionDescriptor&) = default; + PolynomialReconstructionDescriptor(PolynomialReconstructionDescriptor&&) = default; + + ~PolynomialReconstructionDescriptor() = default; +}; + +#endif // POLYNOMIAL_RECONSTRUCTION_DESCRIPTOR_HPP diff --git a/src/scheme/test_reconstruction.cpp b/src/scheme/test_reconstruction.cpp index 1267aabecc233fc3b042b026e2dd6897afe2b1c6..6639b84938fc94609b8d7ccf98f50389ece9f37d 100644 --- a/src/scheme/test_reconstruction.cpp +++ b/src/scheme/test_reconstruction.cpp @@ -8,13 +8,14 @@ test_reconstruction(const std::shared_ptr<const MeshVariant>& mesh_v, const std::shared_ptr<const DiscreteFunctionVariant>& discrete_function_v) { std::cout << "** one variable at a time (30 times)\n"; + PolynomialReconstructionDescriptor descriptor{1}; std::visit( [&](auto&& p_mesh) { std::visit( [&](auto&& discrete_function) { using DiscreteFunctionT = std::decay_t<decltype(discrete_function)>; - PolynomialReconstruction reconstruction; + PolynomialReconstruction reconstruction{descriptor}; if constexpr (is_discrete_function_P0_v<DiscreteFunctionT>) { Timer t; for (size_t i = 0; i < 30; ++i) { @@ -35,12 +36,13 @@ void test_reconstruction_one(const std::shared_ptr<const MeshVariant>& mesh_v, const std::shared_ptr<const DiscreteFunctionVariant>& discrete_function_v) { + PolynomialReconstructionDescriptor descriptor{1}; std::visit( [&](auto&& p_mesh) { std::visit( [&](auto&& discrete_function) { using DiscreteFunctionT = std::decay_t<decltype(discrete_function)>; - PolynomialReconstruction reconstruction; + PolynomialReconstruction reconstruction{descriptor}; if constexpr (is_discrete_function_P0_v<DiscreteFunctionT>) { for (size_t i = 0; i < 30; ++i) { auto res = reconstruction.build(*p_mesh, discrete_function); @@ -55,6 +57,7 @@ test_reconstruction_one(const std::shared_ptr<const MeshVariant>& mesh_v, void test_reconstruction(const std::vector<std::shared_ptr<const DiscreteFunctionVariant>>& discrete_function_variant_list) { + PolynomialReconstructionDescriptor descriptor{1}; { std::cout << "** variable list one by one (50 times)\n"; Timer t; @@ -65,7 +68,7 @@ test_reconstruction(const std::vector<std::shared_ptr<const DiscreteFunctionVari std::visit( [&](auto&& p_mesh) { using DiscreteFunctionT = std::decay_t<decltype(discrete_function)>; - PolynomialReconstruction reconstruction; + PolynomialReconstruction reconstruction{descriptor}; if constexpr (is_discrete_function_P0_v<DiscreteFunctionT>) { for (size_t i = 0; i < 50; ++i) { auto res = reconstruction.build(*p_mesh, discrete_function); @@ -84,10 +87,11 @@ test_reconstruction(const std::vector<std::shared_ptr<const DiscreteFunctionVari { std::cout << "** variable list at once (50 times)\n"; - PolynomialReconstruction reconstruction; + + PolynomialReconstruction reconstruction{descriptor}; Timer t; for (size_t i = 0; i < 50; ++i) { - auto res = reconstruction.build(1, true, true, discrete_function_variant_list); + auto res = reconstruction.build(discrete_function_variant_list); } t.pause(); std::cout << "t = " << t << '\n'; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4c94f8a3974de5399bbeee7ea7f79eeb13d94aa2..b242c06dc5ff8c5d0882b46f962926890b51e433 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -206,6 +206,7 @@ add_executable (mpi_unit_tests test_ParallelChecker_read.cpp test_Partitioner.cpp test_PolynomialReconstruction.cpp + test_PolynomialReconstructionDescriptor.cpp test_RandomEngine.cpp test_StencilBuilder.cpp test_SubItemArrayPerItemVariant.cpp diff --git a/tests/test_PolynomialReconstruction.cpp b/tests/test_PolynomialReconstruction.cpp index 2f25f0168cd8f390e0baa129eb3fa0070cf1222e..d9b33b9111aa0e17175a84b4e0406d89f4f218e8 100644 --- a/tests/test_PolynomialReconstruction.cpp +++ b/tests/test_PolynomialReconstruction.cpp @@ -23,6 +23,8 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") { SECTION("degree 1") { + PolynomialReconstructionDescriptor descriptor{1}; + SECTION("1D") { using R1 = TinyVector<1>; @@ -43,7 +45,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { fh[cell_id] = R_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, fh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(fh); auto dpk_fh = reconstructions[0]->get<DiscreteFunctionDPk<1, const double>>(); @@ -92,7 +94,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { uh[cell_id] = R3_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, uh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(uh); auto dpk_uh = reconstructions[0]->get<DiscreteFunctionDPk<1, const R3>>(); @@ -143,7 +145,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { Ah[cell_id] = R3x3_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, Ah); + auto reconstructions = PolynomialReconstruction{descriptor}.build(Ah); auto dpk_Ah = reconstructions[0]->get<DiscreteFunctionDPk<1, const R3x3>>(); @@ -200,7 +202,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") } }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, Vh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(Vh); auto dpk_Vh = reconstructions[0]->get<DiscreteFunctionDPkVector<1, const double>>(); @@ -288,9 +290,9 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") }); auto reconstructions = - PolynomialReconstruction{}.build(1, true, true, std::make_shared<DiscreteFunctionVariant>(fh), uh, - std::make_shared<DiscreteFunctionP0<R3x3>>(Ah), - DiscreteFunctionVariant(Vh)); + PolynomialReconstruction{descriptor}.build(std::make_shared<DiscreteFunctionVariant>(fh), uh, + std::make_shared<DiscreteFunctionP0<R3x3>>(Ah), + DiscreteFunctionVariant(Vh)); auto dpk_fh = reconstructions[0]->get<DiscreteFunctionDPk<1, const double>>(); @@ -415,7 +417,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { fh[cell_id] = R_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, fh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(fh); auto dpk_fh = reconstructions[0]->get<DiscreteFunctionDPk<2, const double>>(); @@ -475,7 +477,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { uh[cell_id] = R3_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, uh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(uh); auto dpk_uh = reconstructions[0]->get<DiscreteFunctionDPk<2, const R3>>(); @@ -534,7 +536,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { Ah[cell_id] = R2x2_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, Ah); + auto reconstructions = PolynomialReconstruction{descriptor}.build(Ah); auto dpk_Ah = reconstructions[0]->get<DiscreteFunctionDPk<2, const R2x2>>(); @@ -602,7 +604,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") } }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, Vh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(Vh); auto dpk_Vh = reconstructions[0]->get<DiscreteFunctionDPkVector<2, const double>>(); @@ -669,7 +671,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { fh[cell_id] = R_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, fh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(fh); auto dpk_fh = reconstructions[0]->get<DiscreteFunctionDPk<3, const double>>(); @@ -738,7 +740,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { uh[cell_id] = R3_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, uh); + auto reconstructions = PolynomialReconstruction{descriptor}.build(uh); auto dpk_uh = reconstructions[0]->get<DiscreteFunctionDPk<3, const R3>>(); @@ -809,7 +811,8 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") parallel_for( mesh.numberOfCells(), PUGS_LAMBDA(const CellId cell_id) { Ah[cell_id] = R2x2_affine(xj[cell_id]); }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, Ah); + descriptor.setRowWeighting(false); + auto reconstructions = PolynomialReconstruction{descriptor}.build(Ah); auto dpk_Ah = reconstructions[0]->get<DiscreteFunctionDPk<3, const R2x2>>(); @@ -890,7 +893,8 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") } }); - auto reconstructions = PolynomialReconstruction{}.build(1, true, true, Vh); + descriptor.setPreconditioning(false); + auto reconstructions = PolynomialReconstruction{descriptor}.build(Vh); auto dpk_Vh = reconstructions[0]->get<DiscreteFunctionDPkVector<3, const double>>(); @@ -959,7 +963,7 @@ TEST_CASE("PolynomialReconstruction", "[scheme]") auto p_mesh2 = MeshDataBaseForTests::get().cartesian1DMesh()->get<Mesh<1>>(); DiscreteFunctionP0<double> f2{p_mesh2}; - REQUIRE_THROWS_WITH(PolynomialReconstruction{}.build(1, true, true, f1, f2), + REQUIRE_THROWS_WITH(PolynomialReconstruction{descriptor}.build(f1, f2), "error: cannot reconstruct functions living of different meshes simultaneously"); } } diff --git a/tests/test_PolynomialReconstructionDescriptor.cpp b/tests/test_PolynomialReconstructionDescriptor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6b7cd2853c783449f8b8f9167c06241a47b00b38 --- /dev/null +++ b/tests/test_PolynomialReconstructionDescriptor.cpp @@ -0,0 +1,82 @@ +#include <catch2/catch_approx.hpp> +#include <catch2/catch_test_macros.hpp> +#include <catch2/matchers/catch_matchers_all.hpp> + +#include <scheme/PolynomialReconstructionDescriptor.hpp> + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("PolynomialReconstructionDescriptor", "[scheme]") +{ + SECTION("degree 1") + { + PolynomialReconstructionDescriptor descriptor{1}; + + REQUIRE(descriptor.degree() == 1); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + } + + SECTION("degree 4") + { + PolynomialReconstructionDescriptor descriptor{4}; + + REQUIRE(descriptor.degree() == 4); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + } + + SECTION("utlities") + { + PolynomialReconstructionDescriptor descriptor{3}; + + REQUIRE(descriptor.degree() == 3); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + + SECTION("set degree") + { + descriptor.setDegree(2); + + REQUIRE(descriptor.degree() == 2); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + + descriptor.setDegree(4); + + REQUIRE(descriptor.degree() == 4); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + } + + SECTION("set preconditioning") + { + descriptor.setPreconditioning(false); + + REQUIRE(descriptor.degree() == 3); + REQUIRE(descriptor.preconditioning() == false); + REQUIRE(descriptor.rowWeighting() == true); + + descriptor.setPreconditioning(true); + + REQUIRE(descriptor.degree() == 3); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + } + + SECTION("set row weighting") + { + descriptor.setRowWeighting(false); + + REQUIRE(descriptor.degree() == 3); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == false); + + descriptor.setRowWeighting(true); + + REQUIRE(descriptor.degree() == 3); + REQUIRE(descriptor.preconditioning() == true); + REQUIRE(descriptor.rowWeighting() == true); + } + } +}