diff --git a/dune/fufem/test/CMakeLists.txt b/dune/fufem/test/CMakeLists.txt index f27a906f449bc2ba1cfb37cd8a45ff0282b81096..3ca8e185dfd915af31db580a77082dcfd6727790 100644 --- a/dune/fufem/test/CMakeLists.txt +++ b/dune/fufem/test/CMakeLists.txt @@ -24,6 +24,7 @@ set(GRID_BASED_TESTS subgridxyfunctionalassemblertest sumfunctiontest tensortest + transferoperatorassemblertest ) if (ADOLC_FOUND) diff --git a/dune/fufem/test/transferoperatorassemblertest.cc b/dune/fufem/test/transferoperatorassemblertest.cc new file mode 100644 index 0000000000000000000000000000000000000000..dd97c8265d8d70870865be90649e599496da6d69 --- /dev/null +++ b/dune/fufem/test/transferoperatorassemblertest.cc @@ -0,0 +1,121 @@ +#include <config.h> + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/parametertree.hh> +#include <dune/common/fmatrix.hh> + +#include <dune/istl/bcrsmatrix.hh> + +#include <dune/alugrid/grid.hh> +#include <dune/grid/uggrid.hh> +#if HAVE_DUNE_SUBGRID +#include <dune/subgrid/subgrid.hh> +#endif + +#include <dune/fufem/assemblers/transferoperatorassembler.hh> +#include <dune/fufem/utilities/gridconstruction.hh> + +using namespace Dune; + +constexpr size_t level = 3; + +template <class Grid, size_t D> +auto createGrid() { + ParameterTree config; + if (D == 2) { + config["type"] = "rectangle"; + config["lowerCorner"] = "0.0 0.0"; + config["upperCorner"] = "1.0 1.0"; + config["elements"] = "1 1"; + config["tetrahedral"] = "1"; + } else + DUNE_THROW(NotImplemented, "No grid config available for this dim."); + + auto grid = GridConstruction<Grid, D>::createGrid(config); + + for (size_t r = 0; r < level; ++r) + grid->globalRefine(1); + + return grid; +} + +template <class Grid, size_t D> +bool test(const Grid& grid) { + using TOA = TransferOperatorAssembler<Grid>; + using Matrix = BCRSMatrix<FieldMatrix<double, 1, 1>>; + using Hierarchy = std::vector<std::shared_ptr<Matrix>>; + Hierarchy hierarchy; + TOA toa(grid); + toa.assembleMatrixHierarchy(hierarchy); + + for (size_t i = 0; i < level; ++i) { + const auto& m = hierarchy[i]; + auto M = size_t(pow(pow(2, i) + 1, D)); + auto N = size_t(pow(pow(2, i + 1) + 1, D)); + if (m->M() != M || m->N() != N) { + std::string error_msg = "Transfer dimensions are " + + std::to_string(m->M()) + "," + + std::to_string(m->N()) + " but expected was " + + std::to_string(M) + "," + std::to_string(N); + DUNE_THROW(Exception, error_msg); + return false; + } + } + return true; +} + +template <class Grid, size_t D> +bool test(const Grid& grid, std::string id) { + std::cout << "Testing " << id << "grid in " << D << "D..."; + try { + test<Grid, D>(grid); + std::cout << " succeeded." << std::endl; + } catch (Exception e) { + std::cout << " failed: " << e << std::endl; + return false; + } + return true; +} + +template <class Grid, size_t D> +bool testWithGrid(std::string id = "") { + auto grid = std::shared_ptr<Grid>(createGrid<Grid, D>()); + return test<Grid, D>(*grid, id); +} + +#if HAVE_DUNE_SUBGRID +template <class HostGrid, size_t D> +bool testWithSubGrid(std::string id = "") { + auto hostGrid = std::shared_ptr<HostGrid>(createGrid<HostGrid, 2>()); + using Grid = SubGrid<2, HostGrid, false>; + Grid grid(*hostGrid); + return test<Grid, D>(grid, std::string("Subgrid of ") + id); +} +#endif + +template <size_t D> +using MyALUGrid = Dune::ALUGrid<2, 2, ALUGridElementType::simplex, + ALUGridRefinementType::nonconforming>; + +template <size_t D> +bool testDim() { + bool passed = true; + passed = passed && testWithGrid<Dune::UGGrid<D>, D>("UG"); + passed = passed && testWithGrid<MyALUGrid<D>, D>("ALU"); + +#if HAVE_DUNE_SUBGRID + passed = passed && testWithSubGrid<Dune::UGGrid<D>, D>("UG"); + passed = passed && testWithSubGrid<MyALUGrid<D>, D>("ALU"); +#endif + return passed; +} + +int main(int argc, char* argv[]) { + bool passed = true; + Dune::MPIHelper::instance(argc, argv); + + passed = passed && testDim<2>(); + // passed = passed && testDim<3>(); + + return passed ? 0 : 1; +}