diff --git a/src/amdis/AdaptionInterface.hpp b/src/amdis/AdaptionInterface.hpp new file mode 100644 index 0000000000000000000000000000000000000000..66a0baf6c7a370088d50d5a79333555c1dae9944 --- /dev/null +++ b/src/amdis/AdaptionInterface.hpp @@ -0,0 +1,69 @@ +#pragma once + +#include <amdis/common/ConceptsBase.hpp> + +namespace AMDiS +{ + /** + * \addtogroup Concepts + * @{ + **/ + + namespace Concepts + { + namespace Definition + { + struct InterpolateData + { + template <class Data> + auto requires_(Data const& data) -> decltype( + const_cast<Data&>(data).preAdapt(true), + const_cast<Data&>(data).postAdapt(true) + ); + }; + + struct UpdateData + { + template <class Basis> + auto requires_(Basis const& basis) -> decltype( + const_cast<Basis&>(basis).update(basis.gridView()) + ); + }; + + } // end namespace Definition + + template <class Data> + constexpr bool InterpolateData = models<Definition::InterpolateData(Data)>; + + template <class Basis> + constexpr bool UpdateData = models<Definition::UpdateData(Basis)>; + + } // end namespace Concepts + + /// @} + + + /** + * \addtogroup Adaption + * @{ + **/ + + /// \brief Interface for transfer between grid changes + class AdaptionInterface + { + public: + virtual ~AdaptionInterface() = default; + + /// Prepare the grid and the data for the adaption + virtual bool preAdapt() = 0; + + /// Do the grid adaption + virtual bool adapt() = 0; + + // Perform data adaption to the new grid + virtual void postAdapt() = 0; + }; + + /// @} + +} // end namespace AMDiS diff --git a/src/amdis/CMakeLists.txt b/src/amdis/CMakeLists.txt index d13f729273157a36b29e8265059b81940b22935d..c21899d28f5d04dc8c23f965a5070db433dc66f0 100644 --- a/src/amdis/CMakeLists.txt +++ b/src/amdis/CMakeLists.txt @@ -17,6 +17,8 @@ install(FILES AdaptBase.hpp AdaptInfo.hpp AdaptInstationary.hpp + AdaptionInterface.hpp + AdaptiveGlobalBasis.hpp AdaptStationary.hpp AMDiS.hpp Assembler.hpp diff --git a/src/amdis/GridTransfer.hpp b/src/amdis/GridTransfer.hpp index c9166572bf80e7f8266a7bf4afead0ffb2ff85e5..3c61106ea698c0703dc03e62341106b89d2cadff 100644 --- a/src/amdis/GridTransfer.hpp +++ b/src/amdis/GridTransfer.hpp @@ -1,9 +1,10 @@ #pragma once +#include <functional> #include <list> +#include <amdis/AdaptionInterface.hpp> #include <amdis/Output.hpp> -#include <amdis/linearalgebra/DOFVectorInterface.hpp> namespace AMDiS { @@ -12,35 +13,26 @@ namespace AMDiS * @{ **/ - /// \brief Interface for transfer between grid changes to be registered in a \ref GridTransferManager - class GridTransferInterface - { - public: - virtual ~GridTransferInterface() = default; - - /// Attach a data container to the grid transfer, that gets interpolated during grid change - virtual void attach(DOFVectorInterface*) = 0; - - /// Remove a data constainer from the grid transfer. Throws a warning if container not found. - virtual void detach(DOFVectorInterface*) = 0; - - /// Prepare the grid and the data for the adaption - virtual bool preAdapt() = 0; - - /// Do the grid adaption - virtual bool adapt() = 0; - - // Perform data adaption to the new grid - virtual void postAdapt() = 0; - }; - - - /// \brief Implementation of \ref GridTransferInterface for concrete Grid type. + /// \brief Implementation of \ref AdaptionInterface for concrete Grid type. template <class Grid> class GridTransfer - : public GridTransferInterface + : public AdaptionInterface { using Self = GridTransfer; + using Key = std::uintptr_t; + + struct InterpolateCallback + { + std::function<void(bool)> preAdapt; + std::function<void(bool)> postAdapt; + int count = 0; + }; + + struct UpdateCallback + { + std::function<void(void)> update; + int count = 0; + }; public: /// Bind a (mutable) grid to this GridTransfer. Must be called before any xxxAdapt() method. @@ -63,20 +55,57 @@ namespace AMDiS return grid_ != nullptr; } - /// Implements \ref GridTransferInterface::attach - void attach(DOFVectorInterface* vec) override + /// Register data to GridTransfer. + /** + * This inserts a callback that is called in \ref preAdapt() and another that is + * called in \ref postAdapt() step. + * + * *Requirement:* + * - Data must be a model of \ref Concepts::InterpolateData + **/ + template <class Data, + REQUIRES(Concepts::InterpolateData<Data>)> + void attach(Data& data) { - data_.push_back(vec); + auto it = interpolateCallbacks_.emplace(Key(&data), InterpolateCallback{ + [&data](bool mightCoarsen) -> void { data.preAdapt(mightCoarsen); }, + [&data](bool refined) -> void { data.postAdapt(refined); }}); + + it.first->second.count++; } - /// Implements \ref GridTransferInterface::detach - void detach(DOFVectorInterface* vec) override + /// Register data to GridTransfer. + /** + * This inserts a callback that is called after the \ref adapt() step. + * The callback calls `data.update(data.gridView())`. + * + * *Requirement:* + * - Data must be a model of \ref Concepts::UpdateData + **/ + template <class Data, + REQUIRES(Concepts::UpdateData<Data>)> + void attach(Data& data) { - auto it = std::find(data_.begin(), data_.end(), vec); - if (it != data_.end()) - data_.erase(it); - else - warning("DOFVector to detach not found"); + auto it = updateCallbacks_.emplace(Key(&data), UpdateCallback{ + [&data]() -> void { data.update(data.gridView()); }}); + + it.first->second.count++; + } + + /// Unregister data from GridTransfer. Data is identified by its address. + template <class Data, + REQUIRES(Concepts::InterpolateData<Data>)> + void detach(Data& data) + { + eraseCallback(interpolateCallbacks_, Key(&data)); + } + + /// Unregister data from GridTransfer. Data is identified by its address. + template <class Data, + REQUIRES(Concepts::UpdateData<Data>)> + void detach(Data& data) + { + eraseCallback(updateCallbacks_, Key(&data)); } /// Implements \ref GridTransferInterface::preAdapt @@ -85,8 +114,8 @@ namespace AMDiS { assert(bound()); mightCoarsen_ = grid_->preAdapt(); - for (auto* vec : this->data_) - vec->preAdapt(mightCoarsen_); + for (auto&& data : interpolateCallbacks_) + data.second.preAdapt(mightCoarsen_); return mightCoarsen_; } @@ -105,9 +134,12 @@ namespace AMDiS { assert(bound()); if (mightCoarsen_ || refined_) { - for (auto* vec : this->data_) - vec->postAdapt(refined_); + for (auto&& data : updateCallbacks_) + data.second.update(); + for (auto&& data : interpolateCallbacks_) + data.second.postAdapt(refined_); } + grid_->postAdapt(); changeIndex_++; } @@ -118,12 +150,27 @@ namespace AMDiS return changeIndex_; } + private: + // remove entry from map if count <= 1, otherwise reduce count by 1 + template <class Map> + void eraseCallback(Map& map, Key key) + { + auto it = map.find(key); + if (it == map.end()) + warning("Data to detach not found"); + else if (it->second.count > 1) + it->second.count--; + else + map.erase(it); + } + private: /// A grid this GridTransfer is bound to in \ref bind() Grid* grid_ = nullptr; /// A list of data containers handled during grid adaption - std::list<DOFVectorInterface*> data_; + std::map<Key,InterpolateCallback> interpolateCallbacks_; + std::map<Key,UpdateCallback> updateCallbacks_; /// Flag set during \ref preAdapt(), indicating whether any element might be coarsened in \ref adapt() bool mightCoarsen_ = false; diff --git a/src/amdis/GridTransferManager.hpp b/src/amdis/GridTransferManager.hpp index 5721bf3ba9e176a7fad427c51390ae0cae3ff1ff..23f6a389c74b71fb1eee8e93b53f4828c925cb19 100644 --- a/src/amdis/GridTransferManager.hpp +++ b/src/amdis/GridTransferManager.hpp @@ -4,6 +4,7 @@ #include <map> #include <memory> +#include <amdis/AdaptionInterface.hpp> #include <amdis/GridTransfer.hpp> #include <amdis/common/ConcurrentCache.hpp> @@ -17,12 +18,9 @@ namespace AMDiS /// Static administration class for automatic handling of DOFVectors during grid adaption class GridTransferManager { - template <class, class> - friend class DOFVectorBase; - using Self = GridTransferManager; using Key = std::uintptr_t; - using Data = std::unique_ptr<GridTransferInterface>; + using Data = std::shared_ptr<AdaptionInterface>; private: // Constructors. Since this is a static class you cannot call any constructor. @@ -41,56 +39,56 @@ namespace AMDiS * Takes a grid as argument. Marking of the grid needs to be performed prior to calling this. * Returns true if the grid changed during adaptation. **/ - template <class Grid, class ...Bases> - static bool adapt(Grid& grid, Bases&... bases) + template <class Grid> + static bool adapt(Grid& grid) { - auto gridTransfer = GridTransferManager::gridTransfer(grid); - bool adapted = gridTransfer.preAdapt(); - adapted |= gridTransfer.adapt(); - // call basis.update(basis.gridView()) on all bases - (void)std::initializer_list<int>({0, (bases.update(bases.gridView()),0)...}); - gridTransfer.postAdapt(); + auto transfer = gridTransfer(grid); + bool adapted = transfer->preAdapt(); + adapted |= transfer->adapt(); + transfer->postAdapt(); return adapted; } - /// Returns the GridTransfer corresponding to a Grid, to be used during the adaptation cycle + /// Returns the GridTransfer bound to a Grid, to be used during the adaptation cycle template <class Grid> - static GridTransfer<Grid>& gridTransfer(Grid& grid) + static std::shared_ptr<GridTransfer<Grid>> gridTransfer(Grid& grid) { - GridTransfer<Grid>* gridTransfer - = dynamic_cast<GridTransfer<Grid>*>(Self::gridTransferInterface(grid)); - gridTransfer->bind(grid); - return *gridTransfer; + auto transfer = get(grid); + transfer->bind(grid); + return transfer; } - private: - // DOFVector registration methods. They are called automaticly by the DOFVectors. - template <class Vec> - static void attach(Vec& vec) + public: + template <class Grid, class Data> + static void attach(Grid const& grid, Data& data) { - auto const& grid = vec.basis().gridView().grid(); - Self::gridTransferInterface(grid)->attach(&vec); + get(grid)->attach(data); } - template <class Vec> - static void detach(Vec& vec) + template <class Grid, class Data> + static void detach(Grid const& grid, Data& data) { - auto const& grid = vec.basis().gridView().grid(); - Self::gridTransferInterface(grid)->detach(&vec); + get(grid)->detach(data); } - // Returns the GridTransferInterface class, - // used for attaching and detaching DOFVectors to a GridTransfer + + private: + /// \brief Returns the GridTransfer class, used for attaching and detaching Data + /** + * NOTE: The returned GridTransfer is not yet bound to a grid, since a + * mutable reference `Grid&` is needed for the binding. + **/ template <class Grid> - static GridTransferInterface* gridTransferInterface(Grid const &grid) + static std::shared_ptr<GridTransfer<Grid>> get(Grid const& grid) { Key key = Key(&grid); GridTransferCache cache; - auto& gridTransferInterfaceUniquePtr = cache.get(key, [&](Key const&) + auto& gridTransferInterface = cache.get(key, [&](Key const&) { return std::make_unique<GridTransfer<Grid>>(); }); - return gridTransferInterfaceUniquePtr.get(); + + return std::dynamic_pointer_cast<GridTransfer<Grid>>(gridTransferInterface); } private: diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp index b4578993f8c93b557b0b8ac862bd0943c15da194..97046397ba315ccdddc8a42294718ec9ef0e5c4c 100644 --- a/src/amdis/ProblemStat.hpp +++ b/src/amdis/ProblemStat.hpp @@ -387,7 +387,7 @@ namespace AMDiS void adoptGlobalBasis(std::shared_ptr<GlobalBasis> const& globalBasis) { globalBasis_ = globalBasis; - initGlobalBasis(*globalBasis_); + initGlobalBasis(); } void adoptGrid(std::shared_ptr<Grid> const& grid) @@ -408,7 +408,7 @@ namespace AMDiS void createGlobalBasisImpl(std::true_type); void createGlobalBasisImpl(std::false_type); - void initGlobalBasis(GlobalBasis const& globalBasis); + void initGlobalBasis(); public: // implementation of iteration interface methods diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp index 26f18a5ae91bacf8a97e1c12bb5e1a4d7c3e67b4..47c857fdd06ff07208a8b492adf0a9ba43deac13 100644 --- a/src/amdis/ProblemStat.inc.hpp +++ b/src/amdis/ProblemStat.inc.hpp @@ -50,7 +50,7 @@ void ProblemStat<Traits>::initialize( if (globalRefinements > 0) { grid_->globalRefine(globalRefinements); if (globalBasis_) - globalBasis_->update(gridView()); + globalBasis_->update(globalBasis_->gridView()); } } @@ -143,7 +143,7 @@ template <class Traits> void ProblemStat<Traits>::createGlobalBasis() { createGlobalBasisImpl(Dune::Std::is_detected<HasCreate,Traits,GridView>{}); - initGlobalBasis(*globalBasis_); + initGlobalBasis(); } @@ -164,7 +164,7 @@ void ProblemStat<Traits>::createGlobalBasisImpl(std::false_type) template <class Traits> -void ProblemStat<Traits>::initGlobalBasis(GlobalBasis const& globalBasis) +void ProblemStat<Traits>::initGlobalBasis() { dirichletBCs_.init(*globalBasis_, *globalBasis_); periodicBCs_.init(*globalBasis_, *globalBasis_); @@ -367,7 +367,7 @@ globalCoarsen(int n) for (const auto& element : elements(grid_->leafGridView())) grid_->mark(-1, element); - adapted |= GridTransferManager::adapt(*grid_, *globalBasis_); + adapted |= GridTransferManager::adapt(*grid_); } msg("globalCoarsen needed {} seconds", t.elapsed()); @@ -389,7 +389,6 @@ globalRefine(int refCount) /*then*/ [&](auto id) { // TODO(FM): Add a way to pass a GridTransfer as ADH with *globalBasis_ argument id(grid_)->globalRefine(refCount, GridTransferManager::gridTransfer(*grid_)); - globalBasis_->update(this->gridView()); }, /*else*/ [&](auto id) { for (int i = 0; i < refCount; ++i) { @@ -397,7 +396,7 @@ globalRefine(int refCount) for (const auto& element : elements(grid_->leafGridView())) grid_->mark(1, element); - adapted |= GridTransferManager::adapt(*id(grid_), *id(globalBasis_)); + adapted |= GridTransferManager::adapt(*id(grid_)); } }); @@ -412,7 +411,7 @@ adaptGrid(AdaptInfo& adaptInfo) { Dune::Timer t; - bool adapted = GridTransferManager::adapt(*grid_, *globalBasis_); + bool adapted = GridTransferManager::adapt(*grid_); msg("adaptGrid needed {} seconds", t.elapsed()); return adapted ? MESH_ADAPTED : Flag(0); diff --git a/src/amdis/common/ConceptsBase.hpp b/src/amdis/common/ConceptsBase.hpp index 86a2befda56702954f81fffd1c0ae465c7a5e623..aa8615011aee93b8adcd6cc6203fa9d5066a51b9 100644 --- a/src/amdis/common/ConceptsBase.hpp +++ b/src/amdis/common/ConceptsBase.hpp @@ -8,8 +8,8 @@ #define REQUIRES_(...) #define CONCEPT constexpr #else - #define REQUIRES(...) std::enable_if_t<__VA_ARGS__ , int>* = nullptr - #define REQUIRES_(...) std::enable_if_t<__VA_ARGS__ , int>* + #define REQUIRES(...) std::enable_if_t<__VA_ARGS__ , int> = 0 + #define REQUIRES_(...) std::enable_if_t<__VA_ARGS__ , int> #define CONCEPT constexpr #endif diff --git a/src/amdis/linearalgebra/DOFVectorBase.hpp b/src/amdis/linearalgebra/DOFVectorBase.hpp index 91e1c57dd0191329fc1b84f2629124293987484d..37feaab60fb8d0dc87e08a1eb26dd5b19e1e9125 100644 --- a/src/amdis/linearalgebra/DOFVectorBase.hpp +++ b/src/amdis/linearalgebra/DOFVectorBase.hpp @@ -57,12 +57,12 @@ namespace AMDiS public: /// Constructor. Constructs new BaseVector. - DOFVectorBase(GlobalBasis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + DOFVectorBase(GlobalBasis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) : basis_(&basis) , dataTransfer_(DataTransferFactory::create(op, basis)) { compress(); - GridTransferManager::attach(*this); + attachToGridTransfer(); operators_.init(basis); } @@ -74,7 +74,7 @@ namespace AMDiS , operators_(that.operators_) , dataTransfer_(that.dataTransfer_) { - GridTransferManager::attach(*this); + attachToGridTransfer(); } /// Move constructor @@ -85,24 +85,24 @@ namespace AMDiS , operators_(std::move(that.operators_)) , dataTransfer_(std::move(that.dataTransfer_)) { - GridTransferManager::attach(*this); + attachToGridTransfer(); } /// Destructor ~DOFVectorBase() override { - GridTransferManager::detach(*this); + detachFromGridTransfer(); } /// Copy assignment operator Self& operator=(Self const& that) { - GridTransferManager::detach(*this); + detachFromGridTransfer(); basis_ = that.basis_; backend_.resize(that.size()); backend_ = that.backend_; dataTransfer_ = that.dataTransfer_; - GridTransferManager::attach(*this); + attachToGridTransfer(); return *this; } @@ -225,9 +225,22 @@ namespace AMDiS dataTransfer_->postAdapt(*this, refined); } + private: + void attachToGridTransfer() + { + GridTransferManager::attach(basis_->gridView().grid(), *this); + GridTransferManager::attach(basis_->gridView().grid(), *basis_); + } + + void detachFromGridTransfer() + { + GridTransferManager::detach(basis_->gridView().grid(), *basis_); + GridTransferManager::detach(basis_->gridView().grid(), *this); + } + private: /// The finite element space / basis associated with the data vector - GlobalBasis const* basis_; + GlobalBasis* basis_; /// Data backend Backend backend_; diff --git a/src/amdis/linearalgebra/eigen/DOFVector.hpp b/src/amdis/linearalgebra/eigen/DOFVector.hpp index a2f71979522400d047d9172b810e3f1c75aa16fa..d961943fdd43453fdaa5e64ef70cadaf0aef5cdb 100644 --- a/src/amdis/linearalgebra/eigen/DOFVector.hpp +++ b/src/amdis/linearalgebra/eigen/DOFVector.hpp @@ -91,7 +91,7 @@ namespace AMDiS using Super = DOFVectorBase<BasisType, EigenVector<ValueType>>; public: - DOFVector(BasisType const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + DOFVector(BasisType& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) : Super(basis, op) {} @@ -102,7 +102,7 @@ namespace AMDiS /// Constructor a dofvector from given basis and name template <class ValueType = double, class Basis> DOFVector<Basis, ValueType> - makeDOFVector(Basis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + makeDOFVector(Basis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) { return {basis, op}; } diff --git a/src/amdis/linearalgebra/istl/DOFVector.hpp b/src/amdis/linearalgebra/istl/DOFVector.hpp index 5d54f7edc15ba75280cf9c9c6672cef652b23e86..b6a858033d41584cda7799ccba820e52dcb0711d 100644 --- a/src/amdis/linearalgebra/istl/DOFVector.hpp +++ b/src/amdis/linearalgebra/istl/DOFVector.hpp @@ -100,7 +100,7 @@ namespace AMDiS using Super = DOFVectorBase<BasisType, IstlVector<ValueType>>; public: - DOFVector(BasisType const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + DOFVector(BasisType& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) : Super(basis, op) {} @@ -111,7 +111,7 @@ namespace AMDiS /// Constructor a dofvector from given basis and name template <class ValueType = double, class Basis> DOFVector<Basis, ValueType> - makeDOFVector(Basis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + makeDOFVector(Basis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) { return {basis, op}; } diff --git a/src/amdis/linearalgebra/mtl/DOFVector.hpp b/src/amdis/linearalgebra/mtl/DOFVector.hpp index 35be3d71ec1d816fa5d35835ece04831036b0f25..f7c1a9e52fc8e9132cc507971376db7c188542ba 100644 --- a/src/amdis/linearalgebra/mtl/DOFVector.hpp +++ b/src/amdis/linearalgebra/mtl/DOFVector.hpp @@ -91,7 +91,7 @@ namespace AMDiS using Super = DOFVectorBase<BasisType, MtlVector<ValueType>>; public: - DOFVector(BasisType const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + DOFVector(BasisType& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) : Super(basis, op) {} @@ -102,7 +102,7 @@ namespace AMDiS /// Constructor a dofvector from given basis and name template <class ValueType = double, class Basis> DOFVector<Basis, ValueType> - makeDOFVector(Basis const& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) + makeDOFVector(Basis& basis, DataTransferOperation op = DataTransferOperation::INTERPOLATE) { return {basis, op}; } diff --git a/test/DOFVectorTest.cpp b/test/DOFVectorTest.cpp index 61721ef05a6c2e1fd3bf95b396b4c35090a5a5db..1d69bc4b53b1e96a2d3089c8124596d4d2e733fa 100644 --- a/test/DOFVectorTest.cpp +++ b/test/DOFVectorTest.cpp @@ -74,7 +74,7 @@ int main(int argc, char** argv) test_dofvector(basis, vec1); for (auto const& e : elements(gridView)) grid.mark(1, e); - GridTransferManager::adapt(grid, basis); + GridTransferManager::adapt(grid); AMDIS_TEST_EQ(vec1.size(), basis.dimension()); } diff --git a/test/DataTransferTest.hpp b/test/DataTransferTest.hpp index d2478feb52b31f002ac0c38816c6e5f641315821..e9c7c3d3e1f84d531a3be9ee076e9dbe1d05e7ba 100644 --- a/test/DataTransferTest.hpp +++ b/test/DataTransferTest.hpp @@ -60,29 +60,29 @@ auto makeProblem(typename BasisCreator::GlobalBasis::GridView::Grid& grid, Fcts using Problem = ProblemStat<BasisCreator>; // make problem - Problem prob("test", grid); - prob.initialize(INIT_ALL); + auto prob = std::make_unique<Problem>("test", grid); + prob->initialize(INIT_ALL); - auto& globalBasis = *prob.globalBasis(); + auto& globalBasis = *prob->globalBasis(); auto localView = globalBasis.localView(); // interpolate given function to initial grid int k = 0; for_each_leaf_node(localView.tree(), [&](auto const& node, auto tp) { - interpolate(globalBasis, tp, prob.solution(tp).coefficients(), funcs[k]); + interpolate(globalBasis, tp, prob->solution(tp).coefficients(), funcs[k]); k++; }); - return prob; + return std::move(prob); } template <class Problem, class Fcts> double calcError(Problem const& prob, Fcts const& funcs) { - auto& globalBasis = *prob.globalBasis(); + auto& globalBasis = *prob->globalBasis(); auto localView = globalBasis.localView(); - auto sol = prob.solution().coefficients(); + auto const& sol = prob->solution().coefficients(); std::vector<double> ref; ref.resize(globalBasis.size()); double error = 0; @@ -122,7 +122,7 @@ bool unchanged_test(Fcts<BasisCreator> const& funcs, bool simplex = true) auto e = *gridPtr->leafGridView().template begin<0>(); gridPtr->mark(-1, e); AdaptInfo adaptInfo("adapt"); - prob.adaptGrid(adaptInfo); + prob->adaptGrid(adaptInfo); auto error = calcError(prob, funcs); return error < AMDIS_TEST_TOL; @@ -137,7 +137,7 @@ bool coarsen_test(Fcts<BasisCreator> const& funcs, bool simplex = true) auto gridPtr = makeGrid<BasisCreator>(simplex, (d > 2 ? 2 : 4)); auto prob = makeProblem<BasisCreator, Fcts<BasisCreator>>(*gridPtr, funcs); - prob.globalCoarsen(1); + prob->globalCoarsen(1); auto error = calcError(prob, funcs); return error < AMDIS_TEST_TOL; @@ -152,7 +152,7 @@ bool refine_test(Fcts<BasisCreator> const& funcs, bool simplex = true) auto gridPtr = makeGrid<BasisCreator>(simplex, (d > 2 ? 1 : 3)); auto prob = makeProblem<BasisCreator, Fcts<BasisCreator>>(*gridPtr, funcs); - prob.globalRefine(1); + prob->globalRefine(1); auto error = calcError(prob, funcs); return error < AMDIS_TEST_TOL;