File AdaptCriteria.cu
File List > src > AdaptCriteria.cu
Go to the documentation of this file
#include "AdaptCriteria.h"
// Adaptation criteria functions
template <class T> int AdaptCriteria(Param XParam, Forcing<float> XForcing, Model<T> XModel)
{
int success = 0;
if (XParam.AdaptCrit.compare("Threshold") == 0)
{
success = Thresholdcriteria(XParam, T(std::stod(XParam.Adapt_arg1)), XModel.OutputVarMap[XParam.Adapt_arg2], XModel.blocks, XModel.adapt.refine, XModel.adapt.coarsen);
}
if (XParam.AdaptCrit.compare("Inrange") == 0)
{
success = inrangecriteria(XParam, T(std::stod(XParam.Adapt_arg1)), T(std::stod(XParam.Adapt_arg2)), XModel.OutputVarMap[XParam.Adapt_arg3], XModel.blocks, XModel.adapt.refine, XModel.adapt.coarsen);
}
if (XParam.AdaptCrit.compare("Targetlevel") == 0)
{
for (int ig = 0; ig < XForcing.targetadapt.size(); ig++)
{
targetlevelcriteria(XParam, XForcing.targetadapt[ig], XModel.blocks, XModel.adapt.refine, XModel.adapt.coarsen);
}
}
return success;
}
template int AdaptCriteria<float>(Param XParam, Forcing<float> XForcing, Model<float> XModel);
template int AdaptCriteria<double>(Param XParam, Forcing<float> XForcing, Model<double> XModel);
template <class T> int Thresholdcriteria(Param XParam,T threshold, T* z, BlockP<T> XBlock, bool* refine, bool* coarsen)
{
// Threshold criteria is a general form of wet dry criteria where esp is the threshold and h is the parameter tested
// Below is written as a wet dry analogy where wet is vlaue above threshold and dry is below
int success = 0;
//int i;
//Coarsen dry blocks and refine wet ones
//CPU version
// To start we assume all values are below the threshold
bool iswet = false;
for (int ibl = 0; ibl < XParam.nblk; ibl++)
{
int ib = XBlock.active[ibl];
refine[ib] = false; // only refine if all are wet
coarsen[ib] = true; // always try to coarsen
iswet = false;
for (int iy = 0; iy < XParam.blkwidth; iy++)
{
for (int ix = 0; ix < XParam.blkwidth; ix++)
{
int i = memloc(XParam, ix, iy, ib);
//(ix + XParam.halowidth) + (iy + XParam.halowidth) * XParam.blkmemwidth + ib * XParam.blksize;
if (z[i] > threshold)
{
iswet = true;
}
}
}
refine[ib] = iswet;
coarsen[ib] = !iswet;
//printf("ib=%d; refibe[ib]=%s\n", ib, iswet ? "true" : "false");
}
return success;
}
template int Thresholdcriteria<float>(Param XParam, float threshold, float* z, BlockP<float> XBlock, bool* refine, bool* coarsen);
template int Thresholdcriteria<double>(Param XParam, double threshold, double* z, BlockP<double> XBlock, bool* refine, bool* coarsen);
template<class T>
int inrangecriteria(Param XParam, T zmin, T zmax, T* z, BlockP<T> XBlock, bool* refine, bool* coarsen)
{
// First use a simple refining criteria: zb>zmin && zb<zmax refine otherwise corasen
int success = 0;
//int i;
// To start
bool isinrange = false;
for (int ibl = 0; ibl < XParam.nblk; ibl++)
{
int ib = XBlock.active[ibl];
refine[ib] = false; // only refine if zb is in range
coarsen[ib] = true; // always try to coarsen otherwise
isinrange = false;
for (int iy = 0; iy < XParam.blkwidth; iy++)
{
for (int ix = 0; ix < XParam.blkwidth; ix++)
{
int i = (ix + XParam.halowidth) + (iy + XParam.halowidth) * XParam.blkmemwidth + ib * XParam.blksize;
if (z[i] >= zmin && z[i] <= zmax)
{
isinrange = true;
}
}
}
refine[ib] = isinrange;
coarsen[ib] = !isinrange;
//printf("ib=%d; refibe[ib]=%s\n", ib, iswet ? "true" : "false");
}
return success;
}
template int inrangecriteria<float>(Param XParam, float zmin, float zmax, float* z, BlockP<float> XBlock, bool* refine, bool* coarsen);
template int inrangecriteria<double>(Param XParam, double zmin, double zmax, double* z, BlockP<double> XBlock, bool* refine, bool* coarsen);
template<class T>
int targetlevelcriteria(Param XParam, StaticForcingP<int> targetlevelmap, BlockP<T> XBlock, bool* refine, bool* coarsen)
{
int targetlevel;
bool uplevel, samelevel;
T delta, x, y;
int success = 0;
for (int ibl = 0; ibl < XParam.nblk; ibl++)
{
int ib = XBlock.active[ibl];
delta = T(calcres(XParam.dx, XBlock.level[ib]));
uplevel = false;
samelevel = false;
refine[ib] = false; // only refine if all are wet
coarsen[ib] = true; // always try to coarsen
for (int iy = 0; iy < XParam.blkwidth; iy++)
{
for (int ix = 0; ix < XParam.blkwidth; ix++)
{
//
int n = memloc(XParam, ix, iy, ib);
x = T(XParam.xo) + XBlock.xo[ib] + T(ix) * delta;
y = T(XParam.yo) + XBlock.yo[ib] + T(iy) * delta;
targetlevel = int(round(interp2BUQ(x, y, targetlevelmap)));
if (targetlevel > XBlock.level[ib])
{
//printf("x=%f; y=%f; target=%d; level=%d", x, y, targetlevel, XBlock.level[ib]);
uplevel = true;
}
if (targetlevel == XBlock.level[ib])
{
samelevel = true;
}
}
}
if (uplevel)
{
refine[ib] = true; // only refine if all are wet
coarsen[ib] = false;
}
else if (samelevel)
{
coarsen[ib] = false;
}
}
return success;
}
template int targetlevelcriteria<float>(Param XParam, StaticForcingP<int> targetlevelmap, BlockP<float> XBlock, bool* refine, bool* coarsen);
template int targetlevelcriteria<double>(Param XParam, StaticForcingP<int> targetlevelmap, BlockP<double> XBlock, bool* refine, bool* coarsen);