// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == crystal growth group == // == == // == Stiftung caesar == // == Ludwig-Erhard-Allee 2 == // == 53175 Bonn == // == germany == // == == // ============================================================================ // == == // == http://www.caesar.de/cg/AMDiS == // == == // ============================================================================ /** \file Marker.h */ #ifndef AMDIS_MARKER_H #define AMDIS_MARKER_H #include "MemoryManager.h" #include "Element.h" #include "ElInfo.h" #include "Flag.h" #include "Mesh.h" #include "AdaptInfo.h" #include "Traverse.h" #include "MatrixVector.h" namespace AMDiS { // =========================================================================== // ===== class Marker ======================================================== // =========================================================================== /** * \ingroup Adaption * * \brief * Base class for all scalar markers. */ class Marker { public: /** \brief * Constructor. */ Marker() {}; /** \brief * Constructor. */ Marker(std::string name_, int row_) : name(name_), row(row_), maximumMarking(false), p(2), info(10) { GET_PARAMETER(0, name + "->p", "%f", &p); GET_PARAMETER(0, name + "->info", "%d", &info); }; /** \brief * 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++; } } }; /** \brief * Can be used by sub classes. Called before traversal. */ virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh); /** \brief * Can be used by sub classes. Called after traversal. */ virtual void finishMarking(AdaptInfo *adaptInfo); /** \brief * Marks one element. */ virtual void markElement(AdaptInfo *adaptInfo, ElInfo *elInfo); /** \brief * Marking of the mesh. */ virtual Flag markMesh(AdaptInfo *adaptInfo, Mesh *mesh); /** \brief * Sets \ref maximumMarking. */ inline void setMaximumMarking(bool maxMark) { maximumMarking = maxMark; }; inline int getElMarkRefine() { return elMarkRefine; }; inline int getElMarkCoarsen() { return elMarkCoarsen; }; /** \brief * Creates a scalr marker depending on the strategy set in parameters. */ static Marker *createMarker(std::string name, int row_); protected: /** \brief * 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; /** \brief * estimation sum */ double estSum; /** \brief * 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; /** \brief * power in estimator norm */ double p; /** \brief * Info level. */ int info; /** \brief * Counter for elements marked for refinement */ int elMarkRefine; /** \brief * Counter for elements marked for coarsening */ int elMarkCoarsen; }; // =========================================================================== // ===== class GRMarker ====================================================== // =========================================================================== /** * \ingroup Adaption * * \brief * Global refinement. */ class GRMarker : public Marker { public: MEMORY_MANAGED(GRMarker); /** \brief * Constructor. */ GRMarker(std::string name_, int row_) : Marker(name_, row_) {}; /** \brief * 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)); }; }; // =========================================================================== // ===== class MSMarker ====================================================== // =========================================================================== /** * \ingroup Adaption * * \brief * Maximum strategy. */ class MSMarker : public Marker { public: MEMORY_MANAGED(MSMarker); /** \brief * 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); }; /** \brief * 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: /** \brief * Marking parameter. */ double MSGamma; /** \brief * Marking parameter. */ double MSGammaC; }; // =========================================================================== // ===== class ESMarker ====================================================== // =========================================================================== /** * \ingroup Adaption * * \brief * Equidistribution strategy */ class ESMarker : public Marker { public: MEMORY_MANAGED(ESMarker); /** \brief * 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); }; /** \brief * Implementation of MarkScal::initMarking(). */ virtual void initMarking(AdaptInfo *adaptInfo, Mesh *mesh); protected: /** \brief * Marking parameter. */ double ESTheta; /** \brief * Marking parameter. */ double ESThetaC; }; // =========================================================================== // ===== class GERSMarker ==================================================== // =========================================================================== /** * \ingroup Adaption * * \brief * Guaranteed error reduction strategy */ class GERSMarker : public Marker { public: MEMORY_MANAGED(GERSMarker); /** \brief * 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); }; /** \brief * Implementation of Marker::markMesh(). */ virtual Flag markMesh(AdaptInfo *adaptInfo, Mesh *mesh); protected: /** \brief * Refinement marking function. */ void markElementForRefinement(AdaptInfo *adaptInfo, ElInfo *elInfo); /** \brief * Coarsening marking function. */ void markElementForCoarsening(AdaptInfo *adaptInfo, ElInfo *elInfo); protected: /** \brief * Marking parameter. */ double GERSSum; /** \brief * Marking parameter. */ double oldErrSum; /** \brief * Marking parameter. */ double GERSThetaStar; /** \brief * Marking parameter. */ double GERSNu; /** \brief * Marking parameter. */ double GERSThetaC; }; } #endif