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.
This commit is contained in:
parent
4faf645010
commit
5a671fa594
@ -16,6 +16,7 @@
|
|||||||
#include "SIMenums.h"
|
#include "SIMenums.h"
|
||||||
#include "ASMbase.h"
|
#include "ASMbase.h"
|
||||||
#include "ASMunstruct.h"
|
#include "ASMunstruct.h"
|
||||||
|
#include "Functions.h"
|
||||||
#include "IntegrandBase.h"
|
#include "IntegrandBase.h"
|
||||||
#include "Utilities.h"
|
#include "Utilities.h"
|
||||||
#include "IFEM.h"
|
#include "IFEM.h"
|
||||||
@ -33,6 +34,7 @@ AdaptiveSetup::AdaptiveSetup (SIMoutput& sim, bool sa) : model(sim), alone(sa)
|
|||||||
// Default grid adaptation parameters
|
// Default grid adaptation parameters
|
||||||
linIndep = false;
|
linIndep = false;
|
||||||
beta = 10.0;
|
beta = 10.0;
|
||||||
|
betaFunc = nullptr;
|
||||||
errTol = 1.0;
|
errTol = 1.0;
|
||||||
rCond = 1.0;
|
rCond = 1.0;
|
||||||
condLimit = 1.0e12;
|
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)
|
bool AdaptiveSetup::parse (const TiXmlElement* elem)
|
||||||
{
|
{
|
||||||
if (strcasecmp(elem->Value(),"adaptive"))
|
if (strcasecmp(elem->Value(),"adaptive"))
|
||||||
@ -114,6 +122,12 @@ bool AdaptiveSetup::parse (const TiXmlElement* elem)
|
|||||||
} else if ((value = utl::getValue(child,"use_sub_norm")))
|
} else if ((value = utl::getValue(child,"use_sub_norm")))
|
||||||
adNorm = atoi(value);
|
adNorm = atoi(value);
|
||||||
else if ((value = utl::getValue(child,"beta"))) {
|
else if ((value = utl::getValue(child,"beta"))) {
|
||||||
|
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);
|
beta = atof(value);
|
||||||
std::string type;
|
std::string type;
|
||||||
utl::getAttribute(child,"type",type,true);
|
utl::getAttribute(child,"type",type,true);
|
||||||
@ -133,7 +147,8 @@ bool AdaptiveSetup::parse (const TiXmlElement* elem)
|
|||||||
threshold = SYMMETRIZED;
|
threshold = SYMMETRIZED;
|
||||||
utl::getAttribute(child,"eps",symmEps);
|
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)
|
if (threshold == SYMMETRIZED)
|
||||||
IFEM::cout <<" (eps = "<< symmEps <<")";
|
IFEM::cout <<" (eps = "<< symmEps <<")";
|
||||||
IFEM::cout << std::endl;
|
IFEM::cout << std::endl;
|
||||||
@ -283,7 +298,7 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
prm.options.reserve(8);
|
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(knot_mult);
|
||||||
prm.options.push_back(scheme);
|
prm.options.push_back(scheme);
|
||||||
prm.options.push_back(linIndep);
|
prm.options.push_back(linIndep);
|
||||||
@ -301,7 +316,7 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep,
|
|||||||
return -2;
|
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;
|
<<" percent."<< std::endl;
|
||||||
prm.errors.resize(thePatch->getNoRefineElms());
|
prm.errors.resize(thePatch->getNoRefineElms());
|
||||||
dynamic_cast<ASMunstruct*>(thePatch)->remapErrors(prm.errors,refIn,true);
|
dynamic_cast<ASMunstruct*>(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;
|
double limit, sumErr = 0.0, curErr = 0.0;
|
||||||
switch (threshold) {
|
switch (threshold) {
|
||||||
case MAXIMUM: // beta percent of max error (less than 100%)
|
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;
|
break;
|
||||||
case AVERAGE: // beta percent of avg error (typical 100%)
|
case AVERAGE: // beta percent of avg error (typical 100%)
|
||||||
for (const DblIdx& e : error) sumErr += e.first;
|
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;
|
break;
|
||||||
case MINIMUM: // beta percent of min error (more than 100%)
|
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;
|
break;
|
||||||
case DORFEL:
|
case DORFEL:
|
||||||
limit = error.back().first;
|
limit = error.back().first;
|
||||||
for (const DblIdx& e : error) sumErr += e.first;
|
for (const DblIdx& e : error) sumErr += e.first;
|
||||||
sumErr *= beta*0.01;
|
sumErr *= prm.options[0]*0.01;
|
||||||
for (const DblIdx& e : error)
|
for (const DblIdx& e : error)
|
||||||
if (curErr < sumErr)
|
if (curErr < sumErr)
|
||||||
curErr += e.first;
|
curErr += e.first;
|
||||||
@ -397,7 +412,7 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (threshold == NONE || threshold == SYMMETRIZED)
|
if (threshold == NONE || threshold == SYMMETRIZED)
|
||||||
refineSize = ceil(error.size()*beta/100.0);
|
refineSize = ceil(error.size()*prm.options[0]/100.0);
|
||||||
else
|
else
|
||||||
refineSize = std::upper_bound(error.begin(), error.end(), DblIdx(limit,0),
|
refineSize = std::upper_bound(error.begin(), error.end(), DblIdx(limit,0),
|
||||||
std::greater_equal<DblIdx>()) - error.begin();
|
std::greater_equal<DblIdx>()) - error.begin();
|
||||||
@ -433,22 +448,22 @@ int AdaptiveSetup::calcRefinement (LR::RefineData& prm, int iStep,
|
|||||||
|
|
||||||
switch (threshold) {
|
switch (threshold) {
|
||||||
case NONE:
|
case NONE:
|
||||||
IFEM::cout << beta <<"% of all "<< str;
|
IFEM::cout << prm.options[0] <<"% of all "<< str;
|
||||||
break;
|
break;
|
||||||
case SYMMETRIZED:
|
case SYMMETRIZED:
|
||||||
IFEM::cout << 100.0*refineSize/error.size() <<"% of all "<< str;
|
IFEM::cout << 100.0*refineSize/error.size() <<"% of all "<< str;
|
||||||
break;
|
break;
|
||||||
case MAXIMUM:
|
case MAXIMUM:
|
||||||
IFEM::cout << beta <<"% of max error ("<< limit <<")";
|
IFEM::cout << prm.options[0] <<"% of max error ("<< limit <<")";
|
||||||
break;
|
break;
|
||||||
case AVERAGE:
|
case AVERAGE:
|
||||||
IFEM::cout << beta <<"% of average error ("<< limit <<")";
|
IFEM::cout << prm.options[0] <<"% of average error ("<< limit <<")";
|
||||||
break;
|
break;
|
||||||
case MINIMUM:
|
case MINIMUM:
|
||||||
IFEM::cout << beta <<"% of min error ("<< limit <<")";
|
IFEM::cout << prm.options[0] <<"% of min error ("<< limit <<")";
|
||||||
break;
|
break;
|
||||||
case DORFEL:
|
case DORFEL:
|
||||||
IFEM::cout << beta <<"% of total error ("<< limit <<")";
|
IFEM::cout << prm.options[0] <<"% of total error ("<< limit <<")";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "MatVec.h"
|
#include "MatVec.h"
|
||||||
|
|
||||||
|
class ScalarFunc;
|
||||||
class SIMoutput;
|
class SIMoutput;
|
||||||
class TiXmlElement;
|
class TiXmlElement;
|
||||||
namespace LR { struct RefineData; }
|
namespace LR { struct RefineData; }
|
||||||
@ -39,7 +40,7 @@ public:
|
|||||||
//! \param[in] sa If \e true, this is a stand-alone driver
|
//! \param[in] sa If \e true, this is a stand-alone driver
|
||||||
explicit AdaptiveSetup(SIMoutput& sim, bool sa = true);
|
explicit AdaptiveSetup(SIMoutput& sim, bool sa = true);
|
||||||
//! \brief Empty destructor.
|
//! \brief Empty destructor.
|
||||||
virtual ~AdaptiveSetup() {}
|
virtual ~AdaptiveSetup();
|
||||||
|
|
||||||
//! \brief Sets the norm group/index of the norm to base mesh adaptation on.
|
//! \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; }
|
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 alone; //!< If \e false, this class is wrapped by SIMSolver
|
||||||
bool linIndep; //!< Test mesh for linear independence after refinement
|
bool linIndep; //!< Test mesh for linear independence after refinement
|
||||||
double beta; //!< Refinement percentage in each step
|
double beta; //!< Refinement percentage in each step
|
||||||
|
ScalarFunc* betaFunc;//!< Beta as a function
|
||||||
double errTol; //!< Global error stop tolerance
|
double errTol; //!< Global error stop tolerance
|
||||||
double condLimit; //!< Upper limit on condition number
|
double condLimit; //!< Upper limit on condition number
|
||||||
int maxStep; //!< Maximum number of adaptive refinements
|
int maxStep; //!< Maximum number of adaptive refinements
|
||||||
|
Loading…
Reference in New Issue
Block a user