From 5a671fa59487d5d76df29531b609bc5e85c6c7a3 Mon Sep 17 00:00:00 2001 From: Arne Morten Kvarving Date: Wed, 15 Jul 2020 10:23:03 +0200 Subject: [PATCH] added: allow specifying a function for beta t holds the adaptive step number. this allows for flexible specification of how much to refine at each step. --- src/SIM/AdaptiveSetup.C | 43 +++++++++++++++++++++++++++-------------- src/SIM/AdaptiveSetup.h | 4 +++- 2 files changed, 32 insertions(+), 15 deletions(-) diff --git a/src/SIM/AdaptiveSetup.C b/src/SIM/AdaptiveSetup.C index 8d814ffe..24e968f0 100644 --- a/src/SIM/AdaptiveSetup.C +++ b/src/SIM/AdaptiveSetup.C @@ -16,6 +16,7 @@ #include "SIMenums.h" #include "ASMbase.h" #include "ASMunstruct.h" +#include "Functions.h" #include "IntegrandBase.h" #include "Utilities.h" #include "IFEM.h" @@ -33,6 +34,7 @@ AdaptiveSetup::AdaptiveSetup (SIMoutput& sim, bool sa) : model(sim), alone(sa) // Default grid adaptation parameters linIndep = false; beta = 10.0; + betaFunc = nullptr; errTol = 1.0; rCond = 1.0; condLimit = 1.0e12; @@ -52,6 +54,12 @@ AdaptiveSetup::AdaptiveSetup (SIMoutput& sim, bool sa) : model(sim), alone(sa) } +AdaptiveSetup::~AdaptiveSetup() +{ + delete betaFunc; +} + + bool AdaptiveSetup::parse (const TiXmlElement* elem) { if (strcasecmp(elem->Value(),"adaptive")) @@ -114,7 +122,13 @@ bool AdaptiveSetup::parse (const TiXmlElement* elem) } else if ((value = utl::getValue(child,"use_sub_norm"))) adNorm = atoi(value); else if ((value = utl::getValue(child,"beta"))) { - beta = atof(value); + std::string functype; + utl::getAttribute(child,"functype",functype); + if (functype == "expression") { + IFEM::cout << "\tRefinement function: "; + betaFunc = utl::parseTimeFunc(value,functype,1.0); + } else + beta = atof(value); std::string type; utl::getAttribute(child,"type",type,true); if (type.compare("threshold") == 0 || type.compare("threashold") == 0) @@ -133,7 +147,8 @@ bool AdaptiveSetup::parse (const TiXmlElement* elem) threshold = SYMMETRIZED; utl::getAttribute(child,"eps",symmEps); } - IFEM::cout <<"\tRefinement percentage: "<< beta <<" type="<< threshold; + IFEM::cout <<"\tRefinement percentage: "<< (betaFunc ? (*betaFunc)(1) : beta) + <<" type="<< threshold; if (threshold == SYMMETRIZED) IFEM::cout <<" (eps = "<< symmEps <<")"; IFEM::cout << std::endl; @@ -283,7 +298,7 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep, } prm.options.reserve(8); - prm.options.push_back(beta); + prm.options.push_back(betaFunc ? (*betaFunc)(iStep-1) : beta); prm.options.push_back(knot_mult); prm.options.push_back(scheme); prm.options.push_back(linIndep); @@ -301,7 +316,7 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep, return -2; } - IFEM::cout <<"\nRefining by increasing solution space by "<< beta + IFEM::cout <<"\nRefining by increasing solution space by "<< prm.options[0] <<" percent."<< std::endl; prm.errors.resize(thePatch->getNoRefineElms()); dynamic_cast(thePatch)->remapErrors(prm.errors,refIn,true); @@ -370,19 +385,19 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep, double limit, sumErr = 0.0, curErr = 0.0; switch (threshold) { case MAXIMUM: // beta percent of max error (less than 100%) - limit = error.front().first * beta*0.01; + limit = error.front().first * prm.options[0]*0.01; break; case AVERAGE: // beta percent of avg error (typical 100%) for (const DblIdx& e : error) sumErr += e.first; - limit = (sumErr/error.size()) * beta*0.01; + limit = (sumErr/error.size()) * prm.options[0]*0.01; break; case MINIMUM: // beta percent of min error (more than 100%) - limit = error.back().first * beta*0.01; + limit = error.back().first * prm.options[0]*0.01; break; case DORFEL: limit = error.back().first; for (const DblIdx& e : error) sumErr += e.first; - sumErr *= beta*0.01; + sumErr *= prm.options[0]*0.01; for (const DblIdx& e : error) if (curErr < sumErr) curErr += e.first; @@ -397,7 +412,7 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep, } if (threshold == NONE || threshold == SYMMETRIZED) - refineSize = ceil(error.size()*beta/100.0); + refineSize = ceil(error.size()*prm.options[0]/100.0); else refineSize = std::upper_bound(error.begin(), error.end(), DblIdx(limit,0), std::greater_equal()) - error.begin(); @@ -433,22 +448,22 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep, switch (threshold) { case NONE: - IFEM::cout << beta <<"% of all "<< str; + IFEM::cout << prm.options[0] <<"% of all "<< str; break; case SYMMETRIZED: IFEM::cout << 100.0*refineSize/error.size() <<"% of all "<< str; break; case MAXIMUM: - IFEM::cout << beta <<"% of max error ("<< limit <<")"; + IFEM::cout << prm.options[0] <<"% of max error ("<< limit <<")"; break; case AVERAGE: - IFEM::cout << beta <<"% of average error ("<< limit <<")"; + IFEM::cout << prm.options[0] <<"% of average error ("<< limit <<")"; break; case MINIMUM: - IFEM::cout << beta <<"% of min error ("<< limit <<")"; + IFEM::cout << prm.options[0] <<"% of min error ("<< limit <<")"; break; case DORFEL: - IFEM::cout << beta <<"% of total error ("<< limit <<")"; + IFEM::cout << prm.options[0] <<"% of total error ("<< limit <<")"; break; default: break; diff --git a/src/SIM/AdaptiveSetup.h b/src/SIM/AdaptiveSetup.h index 4aeb8d20..548d57a5 100644 --- a/src/SIM/AdaptiveSetup.h +++ b/src/SIM/AdaptiveSetup.h @@ -16,6 +16,7 @@ #include "MatVec.h" +class ScalarFunc; class SIMoutput; class TiXmlElement; namespace LR { struct RefineData; } @@ -39,7 +40,7 @@ public: //! \param[in] sa If \e true, this is a stand-alone driver explicit AdaptiveSetup(SIMoutput& sim, bool sa = true); //! \brief Empty destructor. - virtual ~AdaptiveSetup() {} + virtual ~AdaptiveSetup(); //! \brief Sets the norm group/index of the norm to base mesh adaptation on. void setAdaptationNorm(size_t g, size_t i = 0) { adaptor = g; adNorm = i; } @@ -96,6 +97,7 @@ private: bool alone; //!< If \e false, this class is wrapped by SIMSolver bool linIndep; //!< Test mesh for linear independence after refinement double beta; //!< Refinement percentage in each step + ScalarFunc* betaFunc;//!< Beta as a function double errTol; //!< Global error stop tolerance double condLimit; //!< Upper limit on condition number int maxStep; //!< Maximum number of adaptive refinements