// ============================================================================ // == == // == AMDiS - Adaptive multidimensional simulations == // == == // ============================================================================ // == == // == crystal growth group == // == == // == Stiftung caesar == // == Ludwig-Erhard-Allee 2 == // == 53175 Bonn == // == germany == // == == // ============================================================================ // == == // == http://www.caesar.de/cg/AMDiS == // == == // ============================================================================ /** \file AdaptInfo.h */ #ifndef AMDIS_ADAPTINFO_H #define AMDIS_ADAPTINFO_H #include "MemoryManager.h" #include "MatrixVector.h" #include "Parameters.h" #include "Serializable.h" namespace AMDiS { // =========================================================================== // ===== class AdaptInfo ===================================================== // =========================================================================== /** * \ingroup Adaption * * \brief * Holds adapt parameters and infos about the problem. Base class * for AdaptInfoScal and AdaptInfoVec. */ class AdaptInfo : public Serializable { protected: /** \brief * Stores adapt infos for a scalar problem or for one component of a * vector valued problem. */ class ScalContent { public: /** \brief * Constructor. */ ScalContent(::std::string prefix) : est_sum(0.0), est_t_sum(0.0), est_max(0.0), est_t_max(0.0), spaceTolerance(1.0), timeTolerance(1.0), timeErrLow(1.0), coarsenAllowed(0), refinementAllowed(1), refineBisections(1), coarseBisections(1) { double totalTol = 1.0; double relSpaceErr = 1.0; double relTimeErr = 0.5; double timeTheta1 = 1.0; double timeTheta2 = 0.3; GET_PARAMETER(0, prefix + "->tolerance", "%f", &totalTol); GET_PARAMETER(0, prefix + "->rel space error", "%f", &relSpaceErr); GET_PARAMETER(0, prefix + "->rel time error", "%f", &relTimeErr); GET_PARAMETER(0, prefix + "->time theta 1", "%f", &timeTheta1); GET_PARAMETER(0, prefix + "->time theta 2", "%f", &timeTheta2); GET_PARAMETER(0, prefix + "->coarsen allowed", "%d", &coarsenAllowed); GET_PARAMETER(0, prefix + "->refinement allowed", "%d", &refinementAllowed); GET_PARAMETER(0, prefix + "->refine bisections", "%d", &refineBisections); GET_PARAMETER(0, prefix + "->coarsen bisections", "%d", &coarseBisections); spaceTolerance = totalTol * relSpaceErr; timeTolerance = totalTol * relTimeErr * timeTheta1; timeErrLow = totalTol * relTimeErr * timeTheta2; }; /** \brief * Sum of all error estimates */ double est_sum; /** \brief * Sum of all time error estimates */ double est_t_sum; /** \brief * maximal local error estimate. */ double est_max; /** \brief * Maximum of all time error estimates */ double est_t_max; /** \brief * Tolerance for the (absolute or relative) error */ double spaceTolerance; /** \brief * Time tolerance. */ double timeTolerance; /** \brief * Lower bound for the time error. */ double timeErrLow; /** \brief * true if coarsening is allowed, false otherwise. */ int coarsenAllowed; /** \brief * true if refinement is allowed, false otherwise. */ int refinementAllowed; /** \brief * parameter to tell the marking strategy how many bisections should be * performed when an element is marked for refinement; usually the value is * 1 or DIM */ int refineBisections; /** \brief * parameter to tell the marking strategy how many bisections should * be undone when an element is marked for coarsening; usually the value is * 1 or DIM */ int coarseBisections; }; public: /** \brief * Constructor. */ AdaptInfo(::std::string name_, int size = 1) : name(name_), spaceIteration(-1), maxSpaceIteration(-1), timestepIteration(0), maxTimestepIteration(30), timeIteration(0), maxTimeIteration(30), time(0.0), startTime(0.0), endTime(1.0), timestep(0.0), minTimestep(0.0), maxTimestep(1.0), timestepNumber(0), solverIterations(0), maxSolverIterations(0), solverTolerance(1e-8), solverResidual(0.0), scalContents(size) { GET_PARAMETER(0, name_ + "->start time", "%f", &startTime); time = startTime; GET_PARAMETER(0, name_ + "->timestep", "%f", ×tep); GET_PARAMETER(0, name_ + "->end time", "%f", &endTime); GET_PARAMETER(0, name_ + "->max iteration", "%d", &maxSpaceIteration); GET_PARAMETER(0, name_ + "->max timestep iteration", "%d", &maxTimestepIteration); GET_PARAMETER(0, name_ + "->max time iteration", "%d", &maxTimeIteration); GET_PARAMETER(0, name_ + "->min timestep", "%f", &minTimestep); GET_PARAMETER(0, name_ + "->max timestep", "%f", &maxTimestep); if (size == 1) { scalContents[0] = new ScalContent(name); } else { char number[5]; for (int i = 0; i < size; i++) { sprintf(number, "[%d]", i); scalContents[i] = new ScalContent(name + ::std::string(number)); } } }; /** \brief * Destructor. */ virtual ~AdaptInfo() { int i; for(i = 0; i < scalContents.getSize(); i++) { delete scalContents[i]; } }; inline void reset() { spaceIteration = -1; timestepIteration = 0; timeIteration = 0; time = 0.0; timestep = 0.0; timestepNumber = 0; solverIterations = 0; solverResidual = 0.0; }; /** \brief * Returns whether space tolerance is reached. */ virtual bool spaceToleranceReached() { int i, size = scalContents.getSize(); for(i = 0; i < size; i++) { if(!(scalContents[i]->est_sum < scalContents[i]->spaceTolerance)) { return false; } } return true; }; /** \brief * Returns whether space tolerance of component i is reached. */ virtual bool spaceToleranceReached(int i) { if(!(scalContents[i]->est_sum < scalContents[i]->spaceTolerance)) { return false; } else { return true; } }; /** \brief * Returns whether time tolerance is reached. */ virtual bool timeToleranceReached() { //if(timestep <= minTimestep) return true; int i, size = scalContents.getSize(); for(i = 0; i < size; i++) { if(!(scalContents[i]->est_t_sum < scalContents[i]->timeTolerance)) { return false; } } return true; }; /** \brief * Returns whether time tolerance of component i is reached. */ virtual bool timeToleranceReached(int i) { if(!(scalContents[i]->est_t_sum < scalContents[i]->timeTolerance)) { return false; } else { return true; } }; /** \brief * Returns whether time error is under its lower bound. */ virtual bool timeErrorLow() { int size = scalContents.getSize(); for (int i = 0; i < size; i++) { if (!(scalContents[i]->est_t_sum < scalContents[i]->timeErrLow)) { return false; } } return true; }; /** \brief * Returns \ref spaceIteration. */ inline int getSpaceIteration() { return spaceIteration; }; /** \brief * Sets \ref spaceIteration. */ inline void setSpaceIteration(int it) { spaceIteration = it; }; /** \brief * Returns \ref maxSpaceIteration. */ inline int getMaxSpaceIteration() { return maxSpaceIteration; }; /** \brief * Sets \ref maxSpaceIteration. */ inline void setMaxSpaceIteration(int it) { maxSpaceIteration = it; }; /** \brief * Increments \ref spaceIteration by 1; */ inline void incSpaceIteration() { spaceIteration++; }; /** \brief * Sets \ref timestepIteration. */ inline void setTimestepIteration(int it) { timestepIteration = it; }; /** \brief * Returns \ref timestepIteration. */ inline int getTimestepIteration() { return timestepIteration; }; /** \brief * Increments \ref timestepIteration by 1; */ inline void incTimestepIteration() { timestepIteration++; }; /** \brief * Returns \ref maxTimestepIteration. */ inline int getMaxTimestepIteration() { return maxTimestepIteration; }; /** \brief * Sets \ref maxTimestepIteration. */ inline void setMaxTimestepIteration(int it) { maxTimestepIteration = it; }; /** \brief * Sets \ref timeIteration. */ inline void setTimeIteration(int it) { timeIteration = it; }; /** \brief * Returns \ref timeIteration. */ inline int getTimeIteration() { return timeIteration; }; /** \brief * Increments \ref timesIteration by 1; */ inline void incTimeIteration() { timeIteration++; }; /** \brief * Returns \ref maxTimeIteration. */ inline int getMaxTimeIteration() { return maxTimeIteration; }; /** \brief * Sets \ref maxTimeIteration. */ inline void setMaxTimeIteration(int it) { maxTimeIteration = it; }; /** \brief * Returns \ref timestepNumber. */ inline int getTimestepNumber() { return timestepNumber; }; /** \brief * Increments \ref timestepNumber by 1; */ inline void incTimestepNumber() { timestepNumber++; }; /** \brief * Sets \ref est_sum. */ inline void setEstSum(double e, int index) { scalContents[index]->est_sum = e; }; /** \brief * Sets \ref est_max. */ inline void setEstMax(double e, int index) { scalContents[index]->est_max = e; }; /** \brief * Sets \ref est_max. */ inline void setTimeEstMax(double e, int index) { scalContents[index]->est_t_max = e; }; /** \brief * Sets \ref est_t_sum. */ inline void setTimeEstSum(double e, int index) { scalContents[index]->est_t_sum = e; }; /** \brief * Returns \ref est_sum. */ inline double getEstSum(int index) { return scalContents[index]->est_sum; }; /** \brief * Returns \ref est_t_sum. */ inline double getEstTSum(int index) { return scalContents[index]->est_t_sum; }; /** \brief * Returns \ref est_max. */ inline double getEstMax(int index) { return scalContents[index]->est_max; }; /** \brief * Returns \ref est_max. */ inline double getTimeEstMax(int index) { return scalContents[index]->est_t_max; }; /** \brief * Returns \ref est_t_sum. */ inline double getTimeEstSum(int index) { return scalContents[index]->est_t_sum; }; /** \brief * Returns \ref spaceTolerance. */ inline double getSpaceTolerance(int index) { return scalContents[index]->spaceTolerance; }; /** \brief * Sets \ref spaceTolerance. */ inline void setSpaceTolerance(int index, double tol) { scalContents[index]->spaceTolerance = tol; }; /** \brief * Returns \ref timeTolerance. */ inline double getTimeTolerance(int index) { return scalContents[index]->timeTolerance; }; /** \brief * Sets \ref time */ inline double setTime(double t) { time = t; if (time > endTime) time = endTime; if (time < startTime) time = startTime; return time; }; /** \brief * Gets \ref time */ inline double getTime() { return time; }; /** \brief * Gets \ref &time */ inline double *getTimePtr() { return &time; }; /** \brief * Sets \ref timestep */ inline double setTimestep(double t) { timestep = t; if (timestep > maxTimestep) timestep = maxTimestep; if (timestep < minTimestep) timestep = minTimestep; if (time + timestep > endTime) timestep = endTime - time; return timestep; }; /** \brief * Gets \ref timestep */ inline double getTimestep() { return timestep; }; /** \brief * Sets \ref minTimestep */ inline void setMinTimestep(double t) { minTimestep = t; }; /** \brief * Gets \ref minTimestep */ inline double getMinTimestep() { return minTimestep; }; /** \brief * Sets \ref maxTimestep */ inline void setMaxTimestep(double t) { maxTimestep = t; }; /** \brief * Gets \ref maxTimestep */ inline double getMaxTimestep() { return maxTimestep; }; /** \brief * Gets \ref ×tep */ inline double *getTimestepPtr() { return ×tep; }; /** \brief * Sets \ref startTime = time */ inline void setStartTime(double time) { startTime = time; }; /** \brief * Sets \ref endTime = time */ inline void setEndTime(double time) { endTime = time; }; /** \brief * Returns \ref startTime */ inline double getStartTime() { return startTime; }; /** \brief * Returns \ref endTime */ inline double getEndTime() { return endTime; }; /** \brief * Returns \ref timeErrLow. */ inline double getTimeErrLow(int index) { return scalContents[index]->timeErrLow; }; /** \brief * Returns whether coarsening is allowed or not. */ inline bool isCoarseningAllowed(int index) { return (scalContents[index]->coarsenAllowed == 1); }; /** \brief * Returns whether coarsening is allowed or not. */ inline bool isRefinementAllowed(int index) { return (scalContents[index]->refinementAllowed == 1); }; /** \brief * */ inline void allowRefinement(bool allow, int index) { scalContents[index]->refinementAllowed = allow; }; /** \brief * */ inline void allowCoarsening(bool allow, int index) { scalContents[index]->coarsenAllowed = allow; }; /** \brief * Returns \ref refineBisections */ inline const int getRefineBisections(int index) const { return scalContents[index]->refineBisections; }; /** \brief * Returns \ref coarseBisections */ inline const int getCoarseBisections(int index) const { return scalContents[index]->coarseBisections; }; inline int getSize() { return scalContents.getSize(); }; inline void setSolverIterations(int it) { solverIterations = it; }; inline int getSolverIterations() { return solverIterations; }; inline void setMaxSolverIterations(int it) { maxSolverIterations = it; }; inline int getMaxSolverIterations() { return maxSolverIterations; }; inline void setSolverTolerance(double tol) { solverTolerance = tol; }; inline double getSolverTolerance() { return solverTolerance; }; inline void setSolverResidual(double res) { solverResidual = res; }; inline double getSolverResidual() { return solverResidual; }; /** \brief * Creates new scalContents with the given size. */ void setScalContents(int newSize); // ===== Serialiazable implementation ===== void serialize(::std::ostream& out); void deserialize(::std::istream& in); protected: /** \brief * Name. */ ::std::string name; /** \brief * Current space iteration */ int spaceIteration; /** \brief * maximal allowed number of iterations of the adaptive procedure; if * maxIteration <= 0, no iteration bound is used */ int maxSpaceIteration; /** \brief * Current timestep iteration */ int timestepIteration; /** \brief * Maximal number of iterations for choosing a timestep */ int maxTimestepIteration; /** \brief * Current time iteration */ int timeIteration; /** \brief * Maximal number of time iterations */ int maxTimeIteration; /** \brief * Actual time, end of time interval for current time step */ double time; /** \brief * Initial time */ double startTime; /** \brief * Final time */ double endTime; /** \brief * Current time step size */ double timestep; /** \brief * Minimal step size */ double minTimestep; /** \brief * Maximal step size */ double maxTimestep; /** \brief * Number of current time step */ int timestepNumber; /** \brief * number of iterations needed of linear or nonlinear solver */ int solverIterations; /** \brief * maximal number of iterations needed of linear or nonlinear solver */ int maxSolverIterations; double solverTolerance; double solverResidual; /** \brief * Scalar adapt infos. */ Vector scalContents; }; } #endif // AMDIS_ADAPTINFO_H