// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == TU Dresden == // == == // == Institut für Wissenschaftliches Rechnen == // == Zellescher Weg 12-14 == // == 01069 Dresden == // == germany == // == == // ============================================================================ // == == // == https://gforge.zih.tu-dresden.de/projects/amdis/ == // == == // ============================================================================ /** \file Marker.h */ #ifndef AMDIS_MARKER_H #define AMDIS_MARKER_H #include "Element.h" #include "ElInfo.h" #include "Flag.h" #include "Mesh.h" #include "AdaptInfo.h" #include "Traverse.h" #include "MatrixVector.h" namespace AMDiS { /** * \ingroup Adaption * * \brief * Base class for all scalar markers. */ class Marker { public: /// Constructor. Marker() {} /// Constructor. Marker(std::string name_, int row_) : name(name_), row(row_), maximumMarking(false), p(2), info(10), maxRefineLevel(-1) { GET_PARAMETER(0, name + "->p", "%f", &p); GET_PARAMETER(0, name + "->info", "%d", &info); GET_PARAMETER(0, name + "->max refinement level", "%d", &maxRefineLevel); } /// destructor virtual ~Marker() {} /** \brief * 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. */ inline void setMark(Element *el, char newMark) { char oldMark = el->getMark(); if (!maximumMarking || (newMark > oldMark)) { el->setMark(newMark); if (oldMark > 0) { elMarkRefine--; } else { if (oldMark < 0) elMarkCoarsen--; } if (newMark > 0) { elMarkRefine++; } else { if (newMark < 0) elMarkCoarsen++; } } } /// Can be used by sub classes. Called before traversal. virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh); /// Can be used by sub classes. Called after traversal. virtual void finishMarking(AdaptInfo *adaptInfo); /// Marks one element. virtual void markElement(AdaptInfo *adaptInfo, ElInfo *elInfo); /// Marking of the mesh. virtual Flag markMesh(AdaptInfo *adaptInfo, Mesh *mesh); /// Sets \ref maximumMarking. inline void setMaximumMarking(bool maxMark) { maximumMarking = maxMark; } inline int getElMarkRefine() { return elMarkRefine; } inline int getElMarkCoarsen() { return elMarkCoarsen; } // Returns \ref name of the Marker inline std::string getName() const { return name; } /// Creates a scalr marker depending on the strategy set in parameters. static Marker *createMarker(std::string name, int row_); protected: /// Name of the scalar marker. std::string name; /** \brief * Equal to -1 for scalar problems. Component number if marker is * part of a vector valued marker. */ int row; /// estimation sum double estSum; /// estmation maximum double estMax; /** \brief * If true, elements are marked only if the new value is bigger than * the current marking. */ bool maximumMarking; /** \brief * Lower limit for error estimation, from which an element is marked for * refinement */ double markRLimit; /** \brief * Upper limit for error estimation, from which an element is marked for * coarsening */ double markCLimit; /// power in estimator norm double p; /// Info level. int info; /// Counter for elements marked for refinement int elMarkRefine; /// Counter for elements marked for coarsening int elMarkCoarsen; /// Maximal depth for element refinement. int maxRefineLevel; }; /** * \ingroup Adaption * * \brief * Global refinement. */ class GRMarker : public Marker { public: /// Constructor. GRMarker(std::string name_, int row_) : Marker(name_, row_) {} /// Implementation of Marker::markElement(). virtual void markElement(AdaptInfo *adaptInfo, ElInfo *elInfo) { Element *el = elInfo->getElement(); if (adaptInfo->isRefinementAllowed(row == -1 ? 0 : row)) setMark(el, adaptInfo->getRefineBisections(row == -1 ? 0 : row)); } }; /** * \ingroup Adaption * * \brief * Maximum strategy. */ class MSMarker : public Marker { public: /// Constructor. MSMarker(std::string name_, int row_) : Marker(name_, row_), MSGamma(0.5), MSGammaC(0.1) { GET_PARAMETER(0, name + "->MSGamma", "%f", &MSGamma); GET_PARAMETER(0, name + "->MSGammaC", "%f", &MSGammaC); } /// Implementation of MarkScal::initMarking(). virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh) { Marker::initMarking(adaptInfo, mesh); double MSGammaP = pow(MSGamma, p); double MSGammaCP = pow(MSGammaC, p); markRLimit = MSGammaP * adaptInfo->getEstMax(row == -1 ? 0 : row); markCLimit = MSGammaCP * adaptInfo->getEstMax(row == -1 ? 0 : row); } protected: /// Marking parameter. double MSGamma; /// Marking parameter. double MSGammaC; }; /** * \ingroup Adaption * * \brief * Equidistribution strategy */ class ESMarker : public Marker { public: /// Constructor. ESMarker(std::string name_, int row_) : Marker(name_, row_), ESTheta(0.9), ESThetaC(0.2) { GET_PARAMETER(0, name + "->ESTheta", "%f", &ESTheta); GET_PARAMETER(0, name + "->ESThetaC", "%f", &ESThetaC); } /// Implementation of MarkScal::initMarking(). virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh); protected: /// Marking parameter. double ESTheta; /// Marking parameter. double ESThetaC; }; /** * \ingroup Adaption * * \brief * Guaranteed error reduction strategy */ class GERSMarker : public Marker { public: /// Constructor. GERSMarker(std::string name_, int row_) : Marker(name_, row_), oldErrSum(0.0), GERSThetaStar(0.6), GERSNu(0.1), GERSThetaC(0.1) { GET_PARAMETER(0, name + "->GERSThetaStar", "%f", &GERSThetaStar); GET_PARAMETER(0, name + "->GERSNu", "%f", &GERSNu); GET_PARAMETER(0, name + "->GERSThetaC", "%f", &GERSThetaC); } /// Implementation of Marker::markMesh(). virtual Flag markMesh(AdaptInfo *adaptInfo, Mesh *mesh); protected: /// Refinement marking function. void markElementForRefinement(AdaptInfo *adaptInfo, ElInfo *elInfo); /// Coarsening marking function. void markElementForCoarsening(AdaptInfo *adaptInfo, ElInfo *elInfo); protected: /// Marking parameter. double GERSSum; /// Marking parameter. double oldErrSum; /// Marking parameter. double GERSThetaStar; /// Marking parameter. double GERSNu; /// Marking parameter. double GERSThetaC; }; } #endif