diff --git a/src/amdis/CMakeLists.txt b/src/amdis/CMakeLists.txt index 45e875a5359a865729daeeb9077b3abe1f06eed2..6ac8d9c5e3c396ced25e78011c0270ea5399619c 100644 --- a/src/amdis/CMakeLists.txt +++ b/src/amdis/CMakeLists.txt @@ -36,6 +36,8 @@ install(FILES LinearAlgebra.hpp LocalAssembler.hpp LocalAssemblerBase.hpp + Marker.hpp + Marker.inc.hpp Mesh.hpp Operations.hpp Operators.hpp diff --git a/src/amdis/Marker.hpp b/src/amdis/Marker.hpp new file mode 100644 index 0000000000000000000000000000000000000000..75bcad474b7e6e016476b911744a9f6b47e9dfb8 --- /dev/null +++ b/src/amdis/Marker.hpp @@ -0,0 +1,333 @@ +#pragma once + +#include <string> + +#include <dune/grid/common/grid.hh> + +#include <amdis/AdaptInfo.hpp> +#include <amdis/Flag.hpp> +#include <amdis/Initfile.hpp> + +namespace AMDiS { + + + /** + * \ingroup Adaption + * + * \brief + * Base class for all scalar markers. + */ + template <class Traits> + class Marker + { + protected: + using GlobalBasis = typename Traits::GlobalBasis; + using GridView = typename GlobalBasis::GridView; + using Grid = typename GridView::Grid; + using IndexSet = typename GridView::IndexSet; + using Element = typename GridView::template Codim<0>::Entity; + using Estimates = std::vector<double>; + + public: + /// Constructor. + Marker() {} + + /// Constructor. + Marker(std::string name, std::string component, Estimates const& est, + std::shared_ptr<Grid> const& grid) + : name_(name) + , component_(component) + , grid_(grid) + , est_(est) + , maximumMarking_(false) + { + Parameters::get(name_ + "->p", p_); + Parameters::get(name_ + "->info", info_); + Parameters::get(name_ + "->max refinement level", maxRefineLevel_); + Parameters::get(name_ + "->min refinement level", minRefineLevel_); + } + + /// destructor + virtual ~Marker() {} + + /// Marks element with newMark. If \ref maximumMarking_ is set, the element + /// is marked only if the new mark is bigger than the old one. The return + /// value specifies whether the element has been marked, or not. + void mark(Element const& elem, int newMark) + { + int oldMark = grid_->getMark(elem); + + if (!maximumMarking_ || (newMark > oldMark)) { + bool marked = grid_->mark(newMark, elem); + if (marked) { + if (oldMark > 0) { + elMarkRefine_--; + } else if (oldMark < 0) { + elMarkCoarsen_--; + } + + if (newMark > 0) { + elMarkRefine_++; + } else if (newMark < 0) { + elMarkCoarsen_++; + } + } else { + msg("Marking failed"); + } + } + } + + /// Can be used by sub classes. Called before traversal. + virtual void initMarking(AdaptInfo& adaptInfo); + + /// Can be used by sub classes. Called after traversal. + virtual void finishMarking(AdaptInfo& adaptInfo); + + /// Marks one element. + virtual void markElement(AdaptInfo& adaptInfo, Element const& elem); + + /// Marking of the mesh. + virtual Flag markGrid(AdaptInfo& adaptInfo); + + /// Sets \ref maximumMarking. + void setMaximumMarking(bool maxMark) + { + maximumMarking_ = maxMark; + } + + int getElMarkRefine() + { + return elMarkRefine_; + } + + int getElMarkCoarsen() + { + return elMarkCoarsen_; + } + + /// Returns \ref name of the Marker + std::string getName() const + { + return name_; + } + + /// Creates a scalar marker depending on the strategy set in parameters. + static std::shared_ptr<Marker<Traits> > createMarker(std::string name, std::string component, Estimates const& est, std::shared_ptr<Grid> const& grid); + + protected: + /// Name of the scalar marker. + std::string name_; + + /// Problem component to work on + std::string component_; + + /// Pointer to the grid + std::shared_ptr<Grid> grid_; + + /// Pointer to the local error estimates + Estimates est_; + + /// estimation sum + double estSum_ = 0.0; + + /// estmation maximum + double estMax_ = 0.0; + + /// If true, elements are marked only if the new value is bigger than + /// the current marking. + bool maximumMarking_; + + /// Lower limit for error estimation, from which an element is marked for + /// refinement + double markRLimit_; + + /// Upper limit for error estimation, from which an element is marked for + /// coarsening + double markCLimit_; + + /// power in estimator norm TODO: is this info necessary in marker? + double p_ = 2.0; + + /// Info level. + int info_ = 10; + + /// Counter for elements marked for refinement + int elMarkRefine_ = 0; + + /// Counter for elements marked for coarsening + int elMarkCoarsen_ = 0; + + /// Maximal level of all elements. + int maxRefineLevel_ = -1; + + /// Minimal level of all elements. + int minRefineLevel_ = -1; + + bool refineAllowed_ = true; + + bool coarsenAllowed_ = false; + }; + + + /** + * \ingroup Adaption + * + * \brief + * Global refinement. + */ + template <class Traits> + class GRMarker + : public Marker<Traits> + { + using Super = Marker<Traits>; + using Grid = typename Super::Grid; + using Element = typename Super::Element; + using Estimates = typename Super::Estimates; + + public: + /// Constructor. + GRMarker(std::string name, std::string component, Estimates const& est, + std::shared_ptr<Grid> const& grid) + : Marker<Traits>(std::move(name), std::move(component), est, grid) + {} + + /// Implementation of Marker::markElement(). + virtual void markElement(AdaptInfo& adaptInfo, Element const& elem) + { + if (this->refineAllowed_) + this->mark(elem, 1); + } + }; + + + /** + * \ingroup Adaption + * + * \brief + * Maximum strategy. + */ + + template <class Traits> + class MSMarker + : public Marker<Traits> + { + using Super = Marker<Traits>; + using Grid = typename Super::Grid; + using Estimates = typename Super::Estimates; + + public: + /// Constructor. + MSMarker(std::string name, std::string component, Estimates const& est, + std::shared_ptr<Grid> const& grid) + : Super{std::move(name), std::move(component), est, grid} + { + Parameters::get(this->name_ + "->MSGamma", msGamma_); + Parameters::get(this->name_ + "->MSGammaC", msGammaC_); + } + + /// Implementation of Marker::initMarking(). + void initMarking(AdaptInfo& adaptInfo); + + protected: + /// Marking parameter. + double msGamma_ = 0.5; + + /// Marking parameter. + double msGammaC_ = 0.1; + }; + + + /** + * \ingroup Adaption + * + * \brief + * Equidistribution strategy + */ + + template <class Traits> + class ESMarker + : public Marker<Traits> + { + using Super = Marker<Traits>; + using Grid = typename Super::Grid; + using Estimates = typename Super::Estimates; + + public: + /// Constructor. + ESMarker(std::string name, std::string component, Estimates const& est, + std::shared_ptr<Grid> const& grid) + : Super{std::move(name), std::move(component), est, grid} + { + Parameters::get(this->name_ + "->ESTheta", esTheta_); + Parameters::get(this->name_ + "->ESThetaC", esThetaC_); + } + + /// Implementation of Marker::initMarking(). + virtual void initMarking(AdaptInfo& adaptInfo); + + protected: + /// Marking parameter. + double esTheta_ = 0.9; + + /// Marking parameter. + double esThetaC_ = 0.2; + }; + + + /** + * \ingroup Adaption + * + * \brief + * Guaranteed error reduction strategy + */ + + template <class Traits> + class GERSMarker + : public Marker<Traits> + { + using Super = Marker<Traits>; + using Grid = typename Super::Grid; + using Element = typename Super::Element; + using Estimates = typename Super::Estimates; + + public: + /// Constructor. + GERSMarker(std::string name, std::string component, Estimates const& est, + std::shared_ptr<Grid> const& grid) + : Super{std::move(name), std::move(component), est, grid} + { + Parameters::get(this->name_ + "->GERSThetaStar", gersThetaStar_); + Parameters::get(this->name_ + "->GERSNu", gersNu_); + Parameters::get(this->name_ + "->GERSThetaC", gersThetaC_); + } + + /// Implementation of Marker::markGrid(). + virtual Flag markGrid(AdaptInfo& adaptInfo); + + protected: + /// Refinement marking function. + void markElementForRefinement(AdaptInfo& adaptInfo, Element const& elem); + + /// Coarsening marking function. + void markElementForCoarsening(AdaptInfo& adaptInfo, Element const& elem); + + protected: + /// Marking parameter. + double gersSum_ = 0.0; + + /// Marking parameter. + double oldErrSum_ = 0.0; + + /// Marking parameter. + double gersThetaStar_ = 0.6; + + /// Marking parameter. + double gersNu_ = 0.1; + + /// Marking parameter. + double gersThetaC_ = 0.1; + }; + +} + +#include "Marker.inc.hpp" diff --git a/src/amdis/Marker.inc.hpp b/src/amdis/Marker.inc.hpp new file mode 100644 index 0000000000000000000000000000000000000000..7f06e94d711ef5514d9ba1b33242da5394ca03c7 --- /dev/null +++ b/src/amdis/Marker.inc.hpp @@ -0,0 +1,240 @@ +#include <cmath> + +namespace AMDiS { + +template <class Traits> +std::shared_ptr<Marker<Traits> > Marker<Traits>::createMarker(std::string name, std::string component, Estimates const& est, std::shared_ptr<Grid> const& grid) +{ + int strategy = 0; + Parameters::get(name + "->strategy", strategy); + + std::shared_ptr<Marker<Traits> > marker; + + switch (strategy) { + case 0: // no refinement/coarsening + break; + case 1: + msg("Creating global refinement (GR) marker"); + marker = std::make_shared<GRMarker<Traits> >(name, component, est, grid); + break; + case 2: + msg("Creating maximum strategy (MS) marker"); + marker = std::make_shared<MSMarker<Traits> >(name, component, est, grid); + break; + case 3: + msg("Creating equidistribution strategy (ES) marker"); + marker = std::make_shared<ESMarker<Traits> >(name, component, est, grid); + break; + case 4: + msg("Creating guaranteed error reduction strategy (GERS) marker"); + marker = std::make_shared<GERSMarker<Traits> >(name, component, est, grid); + break; + default: + error_exit("invalid strategy"); + } + + return marker; +} + + +template <class Traits> +void Marker<Traits>::initMarking(AdaptInfo& adaptInfo) +{ + elMarkRefine_ = 0; + elMarkCoarsen_ = 0; + estSum_ = std::pow(adaptInfo.getEstSum(component_), p_); + estMax_ = adaptInfo.getEstMax(component_); + refineAllowed_ = adaptInfo.isRefinementAllowed(component_); + coarsenAllowed_ = adaptInfo.isCoarseningAllowed(component_); +} + + +template <class Traits> +void Marker<Traits>::finishMarking(AdaptInfo& adaptInfo) +{ + msg(elMarkRefine_, " elements marked for refinement"); + msg(elMarkCoarsen_, " elements marked for coarsening"); +} + + +template <class Traits> +void Marker<Traits>::markElement(AdaptInfo& adaptInfo, const Element& elem) +{ + const auto& index = grid_->leafIndexSet().index(elem); + double lError = est_[index]; + + if (lError > markRLimit_ && refineAllowed_ + && (maxRefineLevel_ == -1 || elem.level() < maxRefineLevel_)) { + this->mark(elem, 1); + } else if (lError <= markCLimit_ && coarsenAllowed_ + && (minRefineLevel_ == -1 || elem.level() > minRefineLevel_)) { + this->mark(elem, -1); + } +} + + +template <class Traits> +Flag Marker<Traits>::markGrid(AdaptInfo& adaptInfo) +{ + if (!grid_) + error_exit("No grid!"); + + initMarking(adaptInfo); + + if (!coarsenAllowed_ && !refineAllowed_) + return 0; + + for (const auto& elem : Dune::elements(grid_->leafGridView())) + markElement(adaptInfo, elem); + + finishMarking(adaptInfo); + + Flag markFlag; + if (elMarkRefine_) + markFlag = 1; + if (elMarkCoarsen_) + markFlag |= 2; + + return markFlag; +} + + +template <class Traits> +void MSMarker<Traits>::initMarking(AdaptInfo& adaptInfo) +{ + Super::initMarking(adaptInfo); + + double msGammaP = std::pow(msGamma_, this->p_); + double msGammaCP = std::pow(msGammaC_, this->p_); + + this->markRLimit_ = msGammaP * adaptInfo.getEstMax(this->component_); + this->markCLimit_ = msGammaCP * adaptInfo.getEstMax(this->component_); + + msg("start max_est: ", adaptInfo.getEstMax(this->component_), ", mark_limits: ", this->markRLimit_, ", " , this->markCLimit_); +} + + +template <class Traits> +void ESMarker<Traits>::initMarking(AdaptInfo& adaptInfo) +{ + Super::initMarking(adaptInfo); + + double esThetaP = std::pow(esTheta_, this->p_); + double esThetaCP = std::pow(esThetaC_, this->p_); + double epsP = std::pow(adaptInfo.getSpaceTolerance(this->component_), this->p_); + + int nLeaves = (this->grid_->leafGridView()).size(0); +/*#ifdef HAVE_PARALLEL_DOMAIN_AMDIS + Parallel::mpi::globalAdd(nLeaves); +#endif*/ + + this->markRLimit_ = esThetaP * epsP / nLeaves; + this->markCLimit_ = esThetaCP * epsP / nLeaves; + + msg("start mark_limits: ", this->markRLimit_, ", " , this->markCLimit_, "; nt = ", nLeaves); +} + + +template <class Traits> +Flag GERSMarker<Traits>::markGrid(AdaptInfo& adaptInfo) +{ + Super::initMarking(adaptInfo); + + if (!this->coarsenAllowed_ && !this->refineAllowed_) + return 0; + + gersSum_ = 0.0; + + double LTheta = std::pow(1.0 - gersThetaStar_, this->p_); + double epsP = std::pow(adaptInfo.getSpaceTolerance(this->component_), this->p_); + + if (this->estSum_ < oldErrSum_) { + double improv = this->estSum_ / oldErrSum_; + double wanted = 0.8 * epsP / this->estSum_; + double redfac = std::min((1.0 - wanted) / (1.0 - improv), 1.0); + redfac = std::max(redfac, 0.0); + + if (redfac < 1.0) { + LTheta *= redfac; + msg("GERS: use extrapolated theta_star = ", std::pow(LTheta, 1.0 / this->p_)); + } + } + + oldErrSum_ = this->estSum_; + double GERSGamma = 1.0; + + if (this->refineAllowed_) { + if (LTheta > 0) { + do { + gersSum_ = 0.0; + GERSGamma -= gersNu_; + this->markRLimit_ = GERSGamma * this->estMax_; + + for (const auto& elem : Dune::elements(this->grid_->leafGridView())) + markElementForRefinement(adaptInfo, elem); + + } while((GERSGamma > 0) && (gersSum_ < LTheta * this->estSum_)); + } + + msg("GERS refinement with gamma = ", GERSGamma); + } + + if (this->coarsenAllowed_) { + GERSGamma = 0.3; + LTheta = gersThetaC_ * epsP; + + do { + gersSum_ = 0.0; + GERSGamma -= gersNu_; + this->markCLimit_ = GERSGamma * this->estMax_; + + for (const auto& elem : Dune::elements(this->grid_->leafGridView())) + markElementForCoarsening(adaptInfo, elem); + + msg("coarse loop: gamma = ", GERSGamma, ", sum = ", gersSum_, ", limit = ", LTheta); + } while(gersSum_ > LTheta); + + msg("GERS coarsening with gamma = ", GERSGamma); + } + + Super::finishMarking(adaptInfo); + + Flag markFlag; + if (this->elMarkRefine_) + markFlag = 1; + if (this->elMarkCoarsen_) + markFlag |= 2; + + return markFlag; +} + + +template <class Traits> +void GERSMarker<Traits>::markElementForRefinement(AdaptInfo& adaptInfo, const Element& elem) +{ + double lError = this->est_[this->grid_->leafIndexSet().index(elem)]; + + if (lError > this->markRLimit_) { + gersSum_ += lError; + this->mark(elem, 1); + } +} + + +template <class Traits> +void GERSMarker<Traits>::markElementForCoarsening(AdaptInfo& adaptInfo, const Element& elem) +{ + double lError = this->est_[this->grid_->leafIndexSet().index(elem)]; + + if (this->grid_->getMark(elem) <= 0) { + if (lError <= this->markCLimit_) { + gersSum_ += lError; + this->mark(elem, -1); + } else { + this->mark(elem, 0); + } + } +} + + +} // end namespace AMDiS diff --git a/src/amdis/ProblemStat.hpp b/src/amdis/ProblemStat.hpp index 28ebe21718a25a447d4c647f5642be3c8c65534f..9352089e83f137088cde0b6136cc5d3922baf007 100644 --- a/src/amdis/ProblemStat.hpp +++ b/src/amdis/ProblemStat.hpp @@ -19,6 +19,7 @@ #include <amdis/Flag.hpp> #include <amdis/Initfile.hpp> #include <amdis/LinearAlgebra.hpp> +#include <amdis/Marker.hpp> #include <amdis/Mesh.hpp> #include <amdis/ProblemStatBase.hpp> #include <amdis/ProblemStatTraits.hpp> @@ -33,6 +34,7 @@ #include <amdis/io/FileWriterInterface.hpp> +#include <amdis/utility/TreeData.hpp> #include <amdis/utility/TreePath.hpp> namespace AMDiS @@ -52,7 +54,7 @@ namespace AMDiS using Element = typename GridView::template Codim<0>::Entity; using WorldVector = typename Element::Geometry::GlobalCoordinate; - /// Dimension of the mesh + /// Dimension of the grid static constexpr int dim = Grid::dimension; /// Dimension of the world @@ -66,15 +68,15 @@ namespace AMDiS public: /** * \brief Constructor. Takes the name of the problem that is used to - * access values correpsonding to this püroblem in the parameter file. + * access values corresponding to this problem in the parameter file. **/ explicit ProblemStat(std::string name) : StandardProblemIteration(dynamic_cast<ProblemStatBase&>(*this)) , name_(std::move(name)) {} - /// Constructor taking additionally a reference to a mesh that is used - /// instead of the default created mesh, \ref ProblemStat + /// Constructor taking additionally a reference to a grid that is used + /// instead of the default created grid, \ref ProblemStat ProblemStat(std::string name, Grid& grid) : ProblemStat(std::move(name)) { @@ -142,14 +144,12 @@ namespace AMDiS bool createMatrixData = true, bool storeMatrixData = false) override; - /// Implementation of \ref ProblemStatBase::buildAfterCoarse virtual void buildAfterCoarsen(AdaptInfo& adaptInfo, Flag flag, bool asmMatrix = true, bool asmVector = true) override; - /// Writes output files. void writeFiles(AdaptInfo& adaptInfo, bool force = false); @@ -199,7 +199,7 @@ namespace AMDiS /// Return a pointer to the grid, \ref grid std::shared_ptr<Grid> getGrid() { return grid_; } - /// Set the mesh. Stores pointer to passed reference and initializes feSpaces + /// Set the grid. Stores pointer to passed reference and initializes feSpaces /// matrices and vectors, as well as the file-writer. void setGrid(Grid& grid) { @@ -211,12 +211,6 @@ namespace AMDiS } - /// Return the gridView of the leaf-level - auto leafGridView() { return grid_->leafGridView(); } - - /// Return the gridView of levle `level` - auto levelGridView(int level) { return grid_->levelGridView(level); } - /// Return the \ref feSpaces std::shared_ptr<GlobalBasis> const& getGlobalBasis() { return globalBasis_; } @@ -233,7 +227,7 @@ namespace AMDiS { gridName_ = ""; Parameters::get(name_ + "->mesh", gridName_); - test_exit(!gridName_.empty(), "No mesh name specified for '", name_, "->mesh'!"); + test_exit(!gridName_.empty(), "No grid name specified for '", name_, "->mesh'!"); grid_ = MeshCreator<Grid>::create(gridName_); @@ -263,6 +257,16 @@ namespace AMDiS systemMatrix_ = std::make_shared<SystemMatrix>(*globalBasis_, *globalBasis_, "mat"); solution_ = std::make_shared<SystemVector>(*globalBasis_, "solution"); rhs_ = std::make_shared<SystemVector>(*globalBasis_, "rhs"); + + AMDiS::forEachNode_(localView_->tree(), [&,this](auto const& node, auto treePath) + { + std::string i = to_string(treePath); + estimates_[i].resize(globalBasis_->gridView().indexSet().size(0)); + for (std::size_t j = 0; j < estimates_[i].size(); j++) + estimates_[i][j] = 0.0; // TODO: Remove when estimate() is implemented + }); + + rhs_ = std::make_shared<SystemVector>(*globalBasis_, "rhs"); } void createSolver() @@ -276,6 +280,8 @@ namespace AMDiS linearSolver_ = solverCreator->create(name_ + "->solver"); } + void createMarker(); + void createFileWriter(); @@ -311,7 +317,7 @@ namespace AMDiS virtual Flag coarsenMesh(AdaptInfo& adaptInfo) override { return 0; } /// Implementation of \ref ProblemStatBase::markElements. - virtual Flag markElements(AdaptInfo& adaptInfo) override { return 0; } + virtual Flag markElements(AdaptInfo& adaptInfo) override; private: @@ -321,7 +327,10 @@ namespace AMDiS /// Grid of this problem. std::shared_ptr<Grid> grid_; // TODO: generalize to multi-mesh problems - /// Name of the mesh + /// Number of grids + int nGrids = 1; + + /// Name of the grid std::string gridName_ = "none"; /// FE spaces of this problem. @@ -331,6 +340,9 @@ namespace AMDiS /// A FileWriter object std::list<std::shared_ptr<FileWriterInterface>> filewriter_; + /// Pointer to the adaptation markers + std::list<std::shared_ptr<Marker<Traits> > > marker_; + /// An object of the linearSolver Interface std::shared_ptr<LinearSolverType> linearSolver_; @@ -340,6 +352,10 @@ namespace AMDiS /// A block-vector with the solution components std::shared_ptr<SystemVector> solution_; + /// A vector with the local element error estimates + /// for each node in the basis tree, indexed by [to_string(treePath)][element index] + std::map<std::string, std::vector<double> > estimates_; + /// A block-vector (load-vector) corresponding to the right.hand side /// of the equation, filled during assembling std::shared_ptr<SystemVector> rhs_; diff --git a/src/amdis/ProblemStat.inc.hpp b/src/amdis/ProblemStat.inc.hpp index 4499009bdc5a041383647220988da8a43dd196e8..263b5db3d35308019eb2b2eb6146853381c79815 100644 --- a/src/amdis/ProblemStat.inc.hpp +++ b/src/amdis/ProblemStat.inc.hpp @@ -13,6 +13,7 @@ #include <amdis/LocalAssembler.hpp> #include <amdis/GridFunctionOperator.hpp> #include <amdis/common/Loops.hpp> +// #include <amdis/Estimator.hpp> namespace AMDiS { @@ -22,7 +23,7 @@ void ProblemStat<Traits>::initialize( Self* adoptProblem, Flag adoptFlag) { - // create grides + // create grids if (grid_) { warning("grid already created"); } @@ -78,6 +79,7 @@ void ProblemStat<Traits>::initialize( if (adoptProblem && adoptFlag.isSet(INIT_SYSTEM)) { solution_ = adoptProblem->solution_; + estimates_ = adoptProblem->estimates_; rhs_ = adoptProblem->rhs_; systemMatrix_ = adoptProblem->systemMatrix_; } @@ -101,6 +103,13 @@ void ProblemStat<Traits>::initialize( warning("no solver created\n"); } + // create marker + if (initFlag.isSet(INIT_MARKER)) + createMarker(); + + if (adoptProblem && adoptFlag.isSet(INIT_MARKER)) + marker_ = adoptProblem->marker_; + // create file writer if (initFlag.isSet(INIT_FILEWRITER)) @@ -110,6 +119,30 @@ void ProblemStat<Traits>::initialize( } +template <class Traits> +void ProblemStat<Traits>::createMarker() +{ + AMDiS::forEachNode_(localView_->tree(), [&,this](auto const& node, auto treePath) + { + std::string componentName = name_ + "->marker[" + to_string(treePath) + "]"; + + if (!Parameters::get<std::string>(componentName + "->strategy")) + return; + + std::string tp = to_string(treePath); + auto newMarker = Marker<Traits>::createMarker(componentName, tp, estimates_[tp], grid_); + if (newMarker) + marker_.push_back(std::move(newMarker)); + + // If there is more than one marker, and all components are defined + // on the same grid, the maximum marking has to be enabled. + // TODO: needs to be checked! + if (marker_.size() > 1) + marker_.back()->setMaximumMarking(true); + }); +} + + template <class Traits> void ProblemStat<Traits>::createFileWriter() { @@ -280,6 +313,21 @@ solve(AdaptInfo& adaptInfo, bool createMatrixData, bool storeMatrixData) } +template <class Traits> +Flag ProblemStat<Traits>::markElements(AdaptInfo& adaptInfo) +{ + Dune::Timer t; + + Flag markFlag = 0; + for (auto& currentMarker : marker_) + markFlag |= currentMarker->markGrid(adaptInfo); + + msg("markElements needed ", t.elapsed(), " seconds"); + + return markFlag; +} + + template <class Traits> void ProblemStat<Traits>:: buildAfterCoarsen(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool asmVector) @@ -287,7 +335,7 @@ buildAfterCoarsen(AdaptInfo& /*adaptInfo*/, Flag /*flag*/, bool asmMatrix, bool Dune::Timer t; Assembler<Traits> assembler(*globalBasis_, matrixOperators_, rhsOperators_, constraints_); - auto gv = leafGridView(); + auto gv = grid_->leafGridView(); globalBasis_->update(gv); assembler.assemble(*systemMatrix_, *solution_, *rhs_, asmMatrix, asmVector); @@ -305,4 +353,5 @@ writeFiles(AdaptInfo& adaptInfo, bool force) msg("writeFiles needed ", t.elapsed(), " seconds"); } + } // end namespace AMDiS diff --git a/src/amdis/utility/TreePath.hpp b/src/amdis/utility/TreePath.hpp index 9d29ead4fa48046b9b6652b8a6ec233c24c39df7..4949a9281ee4025edd45171809451ffddd1a2603 100644 --- a/src/amdis/utility/TreePath.hpp +++ b/src/amdis/utility/TreePath.hpp @@ -8,8 +8,6 @@ #include <dune/typetree/treepath.hh> #include <dune/typetree/typetraits.hh> -#include <amdis/common/Mpl.hpp> - namespace AMDiS { struct RootTreePath {}; @@ -24,21 +22,26 @@ namespace AMDiS { template <class TP> struct IsPreTreePath - : any_of_t<std::is_same<TP, int>::value, std::is_same<TP,std::size_t>::value> + : std::is_integral<TP> {}; template <int I> - struct IsPreTreePath<int_t<I>> + struct IsPreTreePath<std::integral_constant<int, I>> : std::true_type {}; template <std::size_t I> - struct IsPreTreePath<index_t<I>> + struct IsPreTreePath<std::integral_constant<std::size_t, I>> + : std::true_type + {}; + + template <int... I> + struct IsPreTreePath<std::integer_sequence<int, I...>> : std::true_type {}; template <std::size_t... I> - struct IsPreTreePath<Indices<I...>> + struct IsPreTreePath<std::index_sequence<I...>> : std::true_type {}; @@ -87,16 +90,28 @@ namespace AMDiS template <int I> - auto makeTreePath(int_t<I>) { return Dune::TypeTree::hybridTreePath(index_<std::size_t(I)>); } + auto makeTreePath(std::integral_constant<int,I>) + { + return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}); + } template <int... I> - auto makeTreePath(Ints<I...>) { return Dune::TypeTree::hybridTreePath(index_<std::size_t(I)>...); } + auto makeTreePath(std::integer_sequence<int, I...>) + { + return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, std::size_t(I)>{}...); + } template <std::size_t I> - auto makeTreePath(index_t<I> _i) { return Dune::TypeTree::hybridTreePath(_i); } + auto makeTreePath(std::integral_constant<std::size_t,I> _i) + { + return Dune::TypeTree::hybridTreePath(_i); + } template <std::size_t... I> - auto makeTreePath(Indices<I...>) { return Dune::TypeTree::hybridTreePath(index_<I>...); } + auto makeTreePath(std::index_sequence<I...>) + { + return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...); + } template <class... T> @@ -108,7 +123,7 @@ namespace AMDiS template <std::size_t... I> auto makeTreePath(Dune::TypeTree::TreePath<I...>) { - return Dune::TypeTree::hybridTreePath(index_<I>...); + return Dune::TypeTree::hybridTreePath(std::integral_constant<std::size_t, I>{}...); } template <class TP> @@ -128,7 +143,7 @@ namespace AMDiS void printTreePath(std::ostream& os, TreePath const& tp, std::index_sequence<I...>) { (void)std::initializer_list<int>{ - ((void)(os << treePathIndex(tp, index_<I>) << ","), 0)... + ((void)(os << treePathIndex(tp, std::integral_constant<std::size_t, I>{}) << ","), 0)... }; } }