#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #ifdef HAVE_DUNE_UGGRID #include #else #include #endif #include #include #include "Tests.hpp" using namespace AMDiS; template auto makeGrid(bool simplex, int globalRefines = 0) { using Grid = typename BasisCreator::GlobalBasis::GridView::Grid; static constexpr int d = Grid::dimension; // problem dimension using DomainType = typename Dune::FieldVector; // constants DomainType lowerLeft; lowerLeft = 0.0; // lower left grid corner DomainType upperRight; upperRight = 1.0; // upper right grid corner std::array s; s.fill(1); // number of elements on each axis // make grid std::unique_ptr gridPtr; if (simplex) { gridPtr = std::unique_ptr{ Dune::StructuredGridFactory::createSimplexGrid(lowerLeft, upperRight, s)}; } else { gridPtr = std::unique_ptr{ Dune::StructuredGridFactory::createCubeGrid(lowerLeft, upperRight, s)}; } gridPtr->globalRefine(globalRefines); return gridPtr; } template auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts const& funcs) { using Problem = ProblemStat; // make problem Problem prob("test", grid); prob.initialize(INIT_ALL); auto& globalBasis = *prob.globalBasis(); auto localView = globalBasis.localView(); // interpolate given function to initial grid int k = 0; AMDiS::forEachLeafNode_(localView.tree(), [&](auto const& node, auto tp) { interpolate(globalBasis, tp, prob.solution(tp).coefficients(), funcs[k]); k++; }); return prob; } template double calcError(Problem const& prob, Fcts const& funcs) { auto& globalBasis = *prob.globalBasis(); auto localView = globalBasis.localView(); auto sol = prob.solution().coefficients(); std::vector ref; ref.resize(globalBasis.size()); double error = 0; double maxError = 0; int k = 0; // interpolate given function onto reference vector AMDiS::forEachLeafNode_(localView.tree(), [&](auto const& node, auto tp) { interpolate(globalBasis, tp, ref, funcs[k]); k++; }); // compare the solution with the reference for (std::size_t i = 0; i < ref.size(); ++i) { error = std::abs(ref[i]-sol[i]); maxError = std::max(maxError, error); } return maxError; } template using Fcts = std::vector)> >; /// Test data transfer for the case where no grid changes are made template bool unchanged_test(Fcts const& funcs, bool simplex = true) { using Grid = typename BasisCreator::GlobalBasis::GridView::Grid; static constexpr int d = Grid::dimension; // problem dimension auto gridPtr = makeGrid(simplex, (d > 2 ? 3 : 5)); auto prob = makeProblem>(*gridPtr, funcs); // mark a single element for coarsening -> no adaptation is done auto e = *gridPtr->leafGridView().template begin<0>(); gridPtr->mark(-1, e); AdaptInfo adaptInfo("adapt"); prob.adaptGrid(adaptInfo); auto error = calcError(prob, funcs); return error < AMDIS_TEST_TOL; } /// Test data transfer for the case of global coarsening template bool coarsen_test(Fcts const& funcs, bool simplex = true) { using Grid = typename BasisCreator::GlobalBasis::GridView::Grid; static constexpr int d = Grid::dimension; // problem dimension auto gridPtr = makeGrid(simplex, (d > 2 ? 2 : 4)); auto prob = makeProblem>(*gridPtr, funcs); prob.globalCoarsen(1); auto error = calcError(prob, funcs); return error < AMDIS_TEST_TOL; } /// Test data transfer for the case of global refinement template bool refine_test(Fcts const& funcs, bool simplex = true) { using Grid = typename BasisCreator::GlobalBasis::GridView::Grid; static constexpr int d = Grid::dimension; // problem dimension auto gridPtr = makeGrid(simplex, (d > 2 ? 1 : 3)); auto prob = makeProblem>(*gridPtr, funcs); prob.globalRefine(1); auto error = calcError(prob, funcs); return error < AMDIS_TEST_TOL; } template using Lagrange3 = LagrangeBasis; template using TaylorHood = TaylorHoodBasis; constexpr double pi = 3.141592653589793238463;