diff options
Diffstat (limited to 'Carpet/CarpetRegrid/src/regrid.cc')
-rw-r--r-- | Carpet/CarpetRegrid/src/regrid.cc | 955 |
1 files changed, 108 insertions, 847 deletions
diff --git a/Carpet/CarpetRegrid/src/regrid.cc b/Carpet/CarpetRegrid/src/regrid.cc index 82f6e0954..3c6b8b0a7 100644 --- a/Carpet/CarpetRegrid/src/regrid.cc +++ b/Carpet/CarpetRegrid/src/regrid.cc @@ -1,81 +1,70 @@ #include <assert.h> -#include <math.h> -#include <stdarg.h> -#include <stdlib.h> -#include <string.h> -#include <algorithm> -#include <list> #include <sstream> #include <string> -#include <vector> #include "cctk.h" #include "cctk_Parameters.h" -#include "bbox.hh" -#include "bboxset.hh" -#include "defs.hh" #include "gh.hh" -#include "gf.hh" #include "vect.hh" #include "carpet.hh" #include "regrid.hh" extern "C" { - static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetRegrid/src/regrid.cc,v 1.33 2004/01/15 09:45:58 cott Exp $"; + static const char* rcsid = "$Header: /home/eschnett/C/carpet/Carpet/Carpet/CarpetRegrid/src/regrid.cc,v 1.34 2004/01/25 14:57:30 schnetter Exp $"; CCTK_FILEVERSION(Carpet_CarpetRegrid_regrid_cc); } -#undef AUTOMATIC_BOUNDARIES - - - namespace CarpetRegrid { using namespace std; using namespace Carpet; - int initial_refinement_levels = 0; // Store the initial number of - // levels to refine for correct - // progressive MR. - // Note that this does not need - // to be checkpointed as it is - // reset at the beginning of every - // iteration. - int last_regridded_iteration = -1; // The last iteration where any - // regridding was done. - - int CarpetRegridStartup () - { - RegisterRegridRoutine (CarpetRegridRegrid); - return 0; - } - - - - int CarpetRegridRegrid (const cGH * const cctkGH, - gh<dim>::rexts& bbsss, - gh<dim>::rbnds& obss, - gh<dim>::rprocs& pss) + CCTK_INT CarpetRegrid_Regrid (CCTK_POINTER_TO_CONST const cctkGH_, + CCTK_INT const reflevel, + CCTK_INT const map, + CCTK_INT const size, + CCTK_INT const * const nboundaryzones_, + CCTK_INT const * const is_internal_, + CCTK_INT const * const is_staggered_, + CCTK_INT const * const shiftout_, + CCTK_POINTER const bbsss_, + CCTK_POINTER const obss_, + CCTK_POINTER const pss_) { DECLARE_CCTK_PARAMETERS; + const cGH * const cctkGH = (const cGH *) cctkGH_; + + assert (reflevel>=0 && reflevel<maxreflevels); + assert (map>=0 && map<maps); + + assert (size == 2*dim); + jjvect const nboundaryzones (* (jjvect const *) nboundaryzones_); + jjvect const is_internal (* (jjvect const *) is_internal_); + jjvect const is_staggered (* (jjvect const *) is_staggered_); + jjvect const shiftout (* (jjvect const *) shiftout_); + + gh<dim>::rexts & bbsss = * (gh<dim>::rexts *) bbsss_; + gh<dim>::rbnds & obss = * (gh<dim>::rbnds *) obss_; + gh<dim>::rprocs & pss = * (gh<dim>::rprocs *) pss_; + + gh<dim> const & hh = *vhh.at(map); + + assert (is_meta_mode()); + + + assert (regrid_every == -1 || regrid_every == 0 || regrid_every % maxmglevelfact == 0); // Return if no regridding is desired if (regrid_every == -1) return 0; -#if 0 - // Return if this is not the main hierarchy - if (mglevel != 0) return 0; -#endif - assert (mglevel == -1); - // Return if we want to regrid during initial data only, and this // is not the time for initial data if (regrid_every == 0 && cctkGH->cctk_iteration != 0) return 0; @@ -85,833 +74,105 @@ namespace CarpetRegrid { && cctkGH->cctk_iteration % regrid_every != 0) { return 0; } - - // Find the number of levels that should be active. - int newnumlevels; - - // Is this the first time that we have regridded this iteration? - if (cctkGH->cctk_iteration > last_regridded_iteration) { - last_regridded_iteration = cctkGH->cctk_iteration; - initial_refinement_levels = refinement_levels; + + + + // Steer parameters + if (activate_newlevels_on_regrid != 0) { + if (cctkGH->cctk_iteration >= activate_next) { + const int newnumlevels + = min(refinement_levels + activate_newlevels_on_regrid, + maxreflevels); + assert (newnumlevels>0 && newnumlevels<=maxreflevels); + + *const_cast<CCTK_INT*>(&activate_next) = cctkGH->cctk_iteration + 1; + ostringstream next; + next << activate_next; + CCTK_ParameterSet + ("activate_next", "CarpetRegrid", next.str().c_str()); + + *const_cast<CCTK_INT*>(&refinement_levels) = newnumlevels; + ostringstream param; + param << refinement_levels; + CCTK_ParameterSet + ("refinement_levels", "CarpetRegrid", param.str().c_str()); + + } } - if (cctkGH->cctk_iteration == 0) { - newnumlevels = refinement_levels; - } else { - if (regrid_from_function) { - if (CCTK_IsFunctionAliased("RegridLevel")) { - int tempnewnumlevels = 0; - newnumlevels = 0; - BEGIN_MGLEVEL_LOOP(cctkGH) { - tempnewnumlevels = - RegridLevel(cctkGH, reflevel, refinement_levels,maxreflevels); - newnumlevels = max(tempnewnumlevels, newnumlevels); - } END_MGLEVEL_LOOP; - } else { - CCTK_WARN(1, "No thorn has provided the function " - "\"RegridLevel\". Regridding will not be done."); - } - } else { - // The standard progressive MR number of levels. - newnumlevels = initial_refinement_levels + - activate_newlevels_on_regrid; + if (regrid_from_function) { + if (! CCTK_IsFunctionAliased("RegridLevel")) { + CCTK_WARN (0, "No thorn has provided the function \"RegridLevel\""); } + const int newnumlevels + = RegridLevel (cctkGH, reflevel, refinement_levels, maxreflevels); + assert (newnumlevels>0 && newnumlevels<=maxreflevels); + + *const_cast<CCTK_INT*>(&refinement_levels) = newnumlevels; + ostringstream param; + param << refinement_levels; + CCTK_ParameterSet + ("refinement_levels", "CarpetRegrid", param.str().c_str()); } - - newnumlevels = min(newnumlevels, maxreflevels); - - if ( ( newnumlevels >= 1) && (newnumlevels <= maxreflevels )) { - char numlevelstring[10]; - sprintf(numlevelstring,"%d",newnumlevels); - CCTK_ParameterSet("refinement_levels","carpetregrid",numlevelstring); - } - list<ibbox> bbl; - list<bvect> obl; + + + int do_recompose; if (CCTK_EQUALS(refined_regions, "none")) { - MakeRegions_BaseLevel (cctkGH, bbl, obl); - + do_recompose = BaseLevel + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else if (CCTK_EQUALS(refined_regions, "centre")) { - MakeRegions_RefineCentre (cctkGH, newnumlevels, bbl, obl); - + do_recompose = Centre + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else if (CCTK_EQUALS(refined_regions, "manual-gridpoints")) { - if (refinement_levels > 4) { - CCTK_WARN (0, "Cannot currently specify manual refinement regions for more than 4 refinement levels"); - } - assert (refinement_levels<=4); - vector<ivect> lower(3), upper(3); - lower[0] = ivect (l1ixmin, l1iymin, l1izmin); - upper[0] = ivect (l1ixmax, l1iymax, l1izmax); - lower[1] = ivect (l2ixmin, l2iymin, l2izmin); - upper[1] = ivect (l2ixmax, l2iymax, l2izmax); - lower[2] = ivect (l3ixmin, l3iymin, l3izmin); - upper[2] = ivect (l3ixmax, l3iymax, l3izmax); - MakeRegions_AsSpecified (cctkGH, newnumlevels, lower, upper, - bbl, obl); - + do_recompose = ManualGridpoints + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else if (CCTK_EQUALS(refined_regions, "manual-coordinates")) { - if (refinement_levels > 4) { - CCTK_WARN (0, "Cannot currently specify manual refinement regions for more than 4 refinement levels"); - } - assert (refinement_levels<=4); - vector<rvect> lower(3), upper(3); - lower[0] = rvect (l1xmin, l1ymin, l1zmin); - upper[0] = rvect (l1xmax, l1ymax, l1zmax); - lower[1] = rvect (l2xmin, l2ymin, l2zmin); - upper[1] = rvect (l2xmax, l2ymax, l2zmax); - lower[2] = rvect (l3xmin, l3ymin, l3zmin); - upper[2] = rvect (l3xmax, l3ymax, l3zmax); - MakeRegions_AsSpecified (cctkGH, newnumlevels, lower, upper, - bbl, obl); - + do_recompose = ManualCoordinates + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else if (CCTK_EQUALS(refined_regions, "manual-gridpoint-list")) { - vector<vector<ibbox> > bbss; - if (strcmp(gridpoints, "") != 0) { - istringstream gp_str(gridpoints); - gp_str >> bbss; - } - - vector<vector<vect<vect<bool,2>,dim> > > obss; - if (strcmp(outerbounds, "") !=0 ) { - istringstream ob_str (outerbounds); - ob_str >> obss; - bool good = obss.size() == bbss.size(); - if (good) { - for (int rl=0; rl<(int)obss.size(); ++rl) { - good = good && obss[rl].size() == bbss[rl].size(); - } - } - if (! good) { - cout << "gridpoints: " << bbss << endl; - cout << "outerbounds: " << obss << endl; - CCTK_WARN (0, "The parameters \"outerbounds\" and \"gridpoints\" must have the same structure"); - } - } else { - obss.resize(bbss.size()); - for (int rl=0; rl<(int)obss.size(); ++rl) { - obss[rl].resize(bbss[rl].size()); - for (int c=0; c<(int)obss[rl].size(); ++c) { - obss[rl][c] = vect<vect<bool,2>,dim>(vect<bool,2>(false)); - } - } - } - - MakeRegions_AsSpecified (cctkGH, newnumlevels, bbss, obss, - bbl, obl); - + do_recompose = ManualGridpointList + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else if (CCTK_EQUALS(refined_regions, "manual-coordinate-list")) { - vector<vector<rbbox> > bbss; - if (strcmp(coordinates, "") != 0) { - istringstream co_str(coordinates); - co_str >> bbss; - } - - vector<vector<vect<vect<bool,2>,dim> > > obss; - if (strcmp(outerbounds, "") !=0 ) { - istringstream ob_str (outerbounds); - ob_str >> obss; - bool good = obss.size() == bbss.size(); - if (good) { - for (int rl=0; rl<(int)obss.size(); ++rl) { - good = good && obss[rl].size() == bbss[rl].size(); - } - } - if (! good) { - cout << "coordinates: " << bbss << endl; - cout << "outerbounds: " << obss << endl; - CCTK_WARN (0, "The parameters \"outerbounds\" and \"coordinates\" must have the same structure"); - } - } else { - obss.resize(bbss.size()); - for (int rl=0; rl<(int)obss.size(); ++rl) { - obss[rl].resize(bbss[rl].size()); - for (int c=0; c<(int)obss[rl].size(); ++c) { - obss[rl][c] = vect<vect<bool,2>,dim>(vect<bool,2>(false)); - } - } - } - - MakeRegions_AsSpecified (cctkGH, newnumlevels, bbss, obss, - bbl, obl); - + do_recompose = ManualCoordinateList + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else if (CCTK_EQUALS(refined_regions, "automatic")) { - const int vi = CCTK_VarIndex (errorvar); - assert (vi>=0 && vi<CCTK_NumVars()); - const int gi = CCTK_GroupIndexFromVarI (vi); - assert (gi>=0 && gi<CCTK_NumGroups()); - const int v1 = CCTK_FirstVarIndexI(gi); - assert (v1>=0 && v1<=vi && v1<CCTK_NumVars()); - - assert (CCTK_GroupTypeI(gi) == CCTK_GF); - assert (CCTK_VarTypeI(vi) == CCTK_VARIABLE_REAL); - assert (CCTK_GroupDimI(gi) == dim); - - assert (gi < (int)arrdata.size()); - assert (vi-v1 < (int)arrdata[gi].data.size()); - assert (arrdata[gi].data[vi-v1]); - const gf<CCTK_REAL,dim>& error - = *dynamic_cast<const gf<CCTK_REAL,dim>*>(arrdata[gi].data[vi-v1]); - - MakeRegions_Adaptively (cctkGH, minwidth, minfraction, maxerror, error, - bbl, obl); - + do_recompose = Automatic + (cctkGH, hh, reflevel, map, + size, nboundaryzones, is_internal, is_staggered, shiftout, + bbsss, obss, pss); + } else { assert (0); } -#ifdef AUTOMATIC_BOUNDARIES - assert (obl.size() == 0); -#else - assert (bbl.size() == obl.size()); -#endif - - // transform bbox list into bbox vector - vector<ibbox> bbs; - bbs.reserve (bbl.size()); - for (list<ibbox>::const_iterator it = bbl.begin(); - it != bbl.end(); - ++it) { - bbs.push_back (*it); - } -#ifdef AUTOMATIC_BOUNDARIES - vector<bvect> obs; - obs.resize (bbs.size()); - for (int c=0; c<(int)bbs.size(); ++c) { - ivect extlo = hh->baseextent.lower(); - ivect extup = hh->baseextent.upper(); - ivect str = bbs[c].stride(); - for (int d=0; d<dim; ++d) { - // Decide what is an outer boundary. - // Allow it to be one grid point to the interior. - assert (bbs[c].lower()[d] >= extlo[d]); - obs[c][d][0] = bbs[c].lower()[d] <= extlo[d] + str[d]; - assert (bbs[c].upper()[d] <= extup[d]); - obs[c][d][1] = bbs[c].upper()[d] >= extup[d] - str[d]; - } - } -#else - vector<bvect> obs; - obs.reserve (obl.size()); - for (list<bvect>::const_iterator it = obl.begin(); - it != obl.end(); - ++it) { - obs.push_back (*it); - } -#endif - - - - // TODO: ensure nesting properties - - // make multiprocessor aware - SplitRegions (cctkGH, bbs, obs); - - // make multigrid aware - gh<dim>::cexts bbss; - bbss = hh->make_reflevel_multigrid_boxes(bbs, mglevels); - - // insert into grid hierarchy - bbsss = hh->extents; - obss = hh->outer_boundaries; - if (bbss.size() == 0) { - // remove all finer levels - // TODO: this might not work - bbsss.resize(reflevel+1); - obss.resize(reflevel+1); - } else { - assert (reflevel < (int)bbsss.size()); - if (reflevel+1 == (int)bbsss.size()) { - // add a finer level - bbsss.push_back (bbss); - obss.push_back (obs); - } else { - // change a finer level - bbsss[reflevel+1] = bbss; - obss[reflevel+1] = obs; - } - } - - MakeProcessors (cctkGH, bbsss, pss); - - return 1; // do recompose - } - - - - void MakeRegions_BaseLevel (const cGH* cctkGH, - list<ibbox>& bbl, list<bvect>& obl) - { - assert (bbl.empty()); - assert (obl.empty()); - } - - - - // This is a helpful helper routine. The user can use it to define - // how the hierarchy should be refined. But the result of this - // routine is rather arbitrary. - void MakeRegions_RefineCentre (const cGH* cctkGH, const int reflevels, - list<ibbox>& bbl, list<bvect>& obl) - { - assert (bbl.empty()); - assert (obl.empty()); - - if (reflevel+1 >= reflevels) return; - - ivect rstr = hh->baseextent.stride(); - ivect rlb = hh->baseextent.lower(); - ivect rub = hh->baseextent.upper(); - - for (int rl=0; rl<reflevel+1; ++rl) { - // save old values - const ivect oldrlb = rlb; - const ivect oldrub = rub; - // refined boxes have smaller stride - assert (all(rstr%hh->reffact == 0)); - rstr /= hh->reffact; - // calculate new extent - const ivect quarter = (rub - rlb) / 4 / rstr * rstr; - rlb = oldrlb + quarter; - rub = oldrub - quarter; - assert (all(rlb >= oldrlb && rub <= oldrub)); - } - - bbl.push_back (ibbox(rlb, rub, rstr)); - obl.push_back (bvect(vect<bool,2>(false))); - } - - - - static void - MakeRegions_AsSpecified_OneLevel (const cGH* cctkGH, const int reflevels, - const ivect ilower, - const ivect iupper, - const bvect obound, - list<ibbox>& bbl, list<bvect>& obl) - { - if (reflevel+1 >= reflevels) return; - - const ivect rstr = hh->baseextent.stride(); - const ivect rlb = hh->baseextent.lower(); - const ivect rub = hh->baseextent.upper(); - - const int rl = reflevel+1; - - const int levfac = ipow(hh->reffact, rl); - assert (all (rstr % levfac == 0)); - const ivect str (rstr / levfac); - const ivect lb (ilower); - const ivect ub (iupper); - if (! all(lb>=rlb && ub<=rub)) { - ostringstream buf; - buf << "The refinement region boundaries for refinement level #" << rl << " are not within the main grid. Allowed are the grid point boundaries " << rlb << " - " << rub << "; specified were " << lb << " - " << ub << ends; - CCTK_WARN (0, buf.str().c_str()); - } - if (! all(lb<=ub)) { - CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, - "The refinement region boundaries for refinement level #%d have the upper boundary less than the lower boundary", rl); - } - if (! all(lb%str==0 && ub%str==0)) { - CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, - "The refinement region boundaries for refinement level #%d are not a multiple of the stride for that level", rl); - } - assert (all(lb>=rlb && ub<=rub)); - assert (all(lb<=ub)); - assert (all(lb%str==0 && ub%str==0)); - - bbl.push_back (ibbox(lb, ub, str)); - obl.push_back (obound); - } - - - - void MakeRegions_AsSpecified (const cGH* cctkGH, const int reflevels, - const vector<ivect> lower, - const vector<ivect> upper, - list<ibbox>& bbl, list<bvect>& obl) - { - assert (lower.size() == upper.size()); - - if (reflevel+1 >= reflevels) return; - - const int rl = reflevel+1; - - const ivect ilower = lower[rl-1]; - const ivect iupper = upper[rl-1]; - const bvect obound = bvect(vect<bool,2>(false)); - - MakeRegions_AsSpecified_OneLevel (cctkGH, reflevels, - ilower, iupper, obound, - bbl, obl); - } - - - - static ivect delta2int (const cGH* cctkGH, const rvect & rpos, const int rl) - { - rvect global_lower, global_upper; - for (int d=0; d<dim; ++d) { - const int ierr = CCTK_CoordRange - (cctkGH, &global_lower[d], &global_upper[d], d+1, 0, "cart3d"); - if (ierr<0) { - global_lower[d] = 0; - global_upper[d] = 1; - } - } - const ivect global_extent (hh->baseextent.upper() - hh->baseextent.lower()); - - CCTK_REAL (* const rfloor) (CCTK_REAL const) = floor; - - const rvect scale = rvect(global_extent) / (global_upper - global_lower); - const int levfac = ipow(hh->reffact, rl); - assert (all (hh->baseextent.stride() % levfac == 0)); - const ivect istride = hh->baseextent.stride() / levfac; - - const ivect ipos = ivect(map(rfloor, rpos * scale / rvect(istride) + 0.5)) * istride; - - const rvect apos = rpos * scale; - assert (all(abs(apos - rvect(ipos)) < rvect(istride)*0.01)); - - return ipos; - } - - - - static ivect pos2int (const cGH* cctkGH, const rvect & rpos, const int rl) - { - rvect global_lower, global_upper; - for (int d=0; d<dim; ++d) { - const int ierr = CCTK_CoordRange - (cctkGH, &global_lower[d], &global_upper[d], d+1, 0, "cart3d"); - if (ierr<0) { - global_lower[d] = 0; - global_upper[d] = 1; - } - } - const ivect global_extent (hh->baseextent.upper() - hh->baseextent.lower()); - - CCTK_REAL (* const rfloor) (CCTK_REAL const) = floor; - - const rvect scale = rvect(global_extent) / (global_upper - global_lower); - const int levfac = ipow(hh->reffact, rl); - assert (all (hh->baseextent.stride() % levfac == 0)); - const ivect istride = hh->baseextent.stride() / levfac; - - const ivect ipos = ivect(map(rfloor, (rpos - global_lower) * scale / rvect(istride) + 0.5)) * istride; - - return ipos; - } - - - -#if 0 - void MakeRegions_AsSpecified (const cGH* cctkGH, const int reflevels, - const vector<rvect> lower, - const vector<rvect> upper, - list<ibbox>& bbl, list<bvect>& obl) - { - assert (lower.size() == upper.size()); - - if (reflevel+1 >= reflevels) return; - - rvect global_lower, global_upper; - for (int d=0; d<dim; ++d) { - const int ierr = CCTK_CoordRange - (cctkGH, &global_lower[d], &global_upper[d], d+1, 0, "cart3d"); - if (ierr<0) { - global_lower[d] = 0; - global_upper[d] = 1; - } - } - const ivect global_extent (hh->baseextent.upper() - hh->baseextent.lower()); - - const int rl = reflevel+1; - - const rvect scale = rvect(global_extent) / (global_upper - global_lower); - const rvect rlower = (lower[rl-1] - global_lower) * scale; - const rvect rupper = (upper[rl-1] - global_lower) * scale; -// const ivect ilower = ivect(map((CCTK_REAL(*)(CCTK_REAL))floor, rlower + 0.5)); -// const ivect iupper = ivect(map((CCTK_REAL(*)(CCTK_REAL))floor, rupper + 0.5)); - CCTK_REAL (* const rfloor) (CCTK_REAL const) = floor; - const int levfac = ipow(hh->reffact, rl); - assert (all (hh->baseextent.stride() % levfac == 0)); - const ivect istride = hh->baseextent.stride() / levfac; - const ivect ilower = ivect(map(rfloor, rlower / rvect(istride) + 0.5)) * istride; - const ivect iupper = ivect(map(rfloor, rupper / rvect(istride) + 0.5)) * istride; - const bvect obound = bvect(vect<bool,2>(false)); - - MakeRegions_AsSpecified_OneLevel (cctkGH, reflevels, - ilower, iupper, obound, - bbl, obl); - } -#endif - - - - void MakeRegions_AsSpecified (const cGH* cctkGH, const int reflevels, - const vector<rvect> lower, - const vector<rvect> upper, - list<ibbox>& bbl, list<bvect>& obl) - { - assert (lower.size() == upper.size()); - vector<ivect> ilower, iupper; - ilower.resize (lower.size()); - iupper.resize (upper.size()); - for (int rl=1; rl<lower.size()+1; ++rl) { - ilower[rl-1] = pos2int (cctkGH, lower[rl-1], rl); - iupper[rl-1] = pos2int (cctkGH, upper[rl-1], rl); - } - MakeRegions_AsSpecified (cctkGH, reflevels, ilower, iupper, bbl, obl); - } - - - - void MakeRegions_AsSpecified (const cGH* cctkGH, const int reflevels, - const vector<vector<ibbox> > bbss, - const vector<vector<bvect> > obss, - list<ibbox>& bbl, list<bvect>& obl) - { - if (reflevel+1 >= reflevels) return; - - const int rl = reflevel+1; - assert (rl-1 < (int)bbss.size()); - assert (obss.size() == bbss.size()); - - for (int c=0; c<(int)bbss[rl-1].size(); ++c) { - assert (obss[rl-1].size() == bbss[rl-1].size()); - - const ivect ilower = bbss[rl-1][c].lower(); - const ivect iupper = bbss[rl-1][c].upper(); - const bvect obound = obss[rl-1][c]; - - MakeRegions_AsSpecified_OneLevel (cctkGH, reflevels, - ilower, iupper, obound, - bbl, obl); - - } - } - - - - void MakeRegions_AsSpecified (const cGH* cctkGH, const int reflevels, - const vector<vector<rbbox> > bbss, - const vector<vector<bvect> > obss, - list<ibbox>& bbl, list<bvect>& obl) - { - vector<vector<ibbox> > ibbss; - ibbss.resize (bbss.size()); - for (int rl=1; rl<bbss.size()+1; ++rl) { - ibbss[rl-1].resize (bbss[rl-1].size()); - for (int c=0; c<bbss[rl-1].size(); ++c) { - const ivect ilower = pos2int (cctkGH, bbss[rl-1][c].lower(), rl); - const ivect iupper = pos2int (cctkGH, bbss[rl-1][c].upper(), rl); - const ivect istride = delta2int (cctkGH, bbss[rl-1][c].stride(), rl); - ibbss[rl-1][c] = ibbox (ilower, iupper, istride); - } - } - MakeRegions_AsSpecified (cctkGH, reflevels, ibbss, obss, bbl, obl); - } - - - - static void - MakeRegions_Adaptively_Recombine (list<ibbox>& bbl1, - list<ibbox>& bbl2, - list<ibbox>& bbl, - const ibbox& iface, - const int dir) - { - assert (!iface.empty()); - assert (iface.lower()[dir] == iface.upper()[dir]); - - const int oldnumboxes = bbl.size() + bbl1.size() + bbl2.size(); - int numcombinedboxes = 0; - - int oldnumpoints = 0; - for (list<ibbox>::const_iterator ibb = bbl.begin(); ibb != bbl.end(); ++ibb) { - oldnumpoints += ibb->size(); - } - for (list<ibbox>::const_iterator ibb1 = bbl1.begin(); ibb1 != bbl1.end(); ++ibb1) { - oldnumpoints += ibb1->size(); - } - for (list<ibbox>::const_iterator ibb2 = bbl2.begin(); ibb2 != bbl2.end(); ++ibb2) { - oldnumpoints += ibb2->size(); - } - -#if 0 - // remember old bounding boxes - bboxset<int,dim> oldboxes; - for (list<ibbox>::const_iterator ibb1 = bbl1.begin(); ibb1 != bbl1.end(); ++ibb1) { - oldboxes += *ibb1; - } - for (list<ibbox>::const_iterator ibb2 = bbl2.begin(); ibb2 != bbl2.end(); ++ibb2) { - oldboxes += *ibb2; - } -#endif -#if 0 - cout << endl; - cout << "MakeRegions_Adaptively_Recombine: initial list:" << endl; - cout << bbl << endl; - cout << "MakeRegions_Adaptively_Recombine: initial list 1:" << endl; - cout << bbl1 << endl; - cout << "MakeRegions_Adaptively_Recombine: initial list 2:" << endl; - cout << bbl2 << endl; -#endif - - const ivect lo = iface.lower(); - const ivect up = iface.upper(); - const ivect str = iface.stride(); - - { - // prune boxes on the left - list<ibbox>::iterator ibb1 = bbl1.begin(); - while (ibb1 != bbl1.end()) { - // is this bbox just to the left of the interface? -// const ivect lo1 = ibb1->lower(); - const ivect up1 = ibb1->upper(); - const ivect str1 = ibb1->stride(); - assert (up1[dir]+str1[dir] <= lo[dir]); - assert (all(str1 == str)); - if (up1[dir]+str1[dir] < lo[dir]) { - // no: forget it - bbl.push_back (*ibb1); - ibb1 = bbl1.erase(ibb1); - continue; - } - ++ibb1; - } // while - } - - { - // prune boxes on the right - list<ibbox>::iterator ibb2 = bbl2.begin(); - while (ibb2 != bbl2.end()) { - // is this bbox just to the right of the interface? - const ivect lo2 = ibb2->lower(); -// const ivect up2 = ibb2->upper(); - const ivect str2 = ibb2->stride(); - assert (up[dir] <= lo2[dir]); - assert (all(str2 == str)); - if (up[dir] < lo2[dir]) { - // no: forget it - bbl.push_back (*ibb2); - ibb2 = bbl2.erase(ibb2); - continue; - } - ++ibb2; - } // while - } - - { - // walk all boxes on the left - list<ibbox>::iterator ibb1 = bbl1.begin(); - while (ibb1 != bbl1.end()) { - ivect lo1 = ibb1->lower(); - ivect up1 = ibb1->upper(); - ivect str1 = ibb1->stride(); - assert (up1[dir]+str1[dir] == lo[dir]); - lo1[dir] = lo[dir]; - up1[dir] = up[dir]; - const ibbox iface1 (lo1,up1,str1); - - { - // walk all boxes on the right - list<ibbox>::iterator ibb2 = bbl2.begin(); - while (ibb2 != bbl2.end()) { - ivect lo2 = ibb2->lower(); - ivect up2 = ibb2->upper(); - ivect str2 = ibb2->stride(); - assert (lo2[dir] == up[dir]); - lo2[dir] = lo[dir]; - up2[dir] = up[dir]; - const ibbox iface2 (lo2,up2,str2); - - // check for a match - if (iface1 == iface2) { - const ibbox combined (ibb1->lower(), ibb2->upper(), str); - bbl.push_back (combined); - ibb1 = bbl1.erase(ibb1); - ibb2 = bbl2.erase(ibb2); - ++numcombinedboxes; -// cout << "MRA: Combining along " << "xyz"[dir] << " to " << bbl.back() << " size " << bbl.back().size() << endl; - goto continue_search; - } - - ++ibb2; - } // while - } - - ++ibb1; - continue_search:; - } // while - } - - bbl.splice (bbl.end(), bbl1); - bbl.splice (bbl.end(), bbl2); - - assert (bbl1.empty() && bbl2.empty()); - - const int newnumboxes = bbl.size(); - assert (newnumboxes + numcombinedboxes == oldnumboxes); - - int newnumpoints = 0; - for (list<ibbox>::const_iterator ibb = bbl.begin(); ibb != bbl.end(); ++ibb) { - newnumpoints += ibb->size(); - } - assert (newnumpoints == oldnumpoints); - -#if 0 - // find new bounding boxes - bboxset<int,dim> newboxes; - for (list<ibbox>::const_iterator ibb = bbl.begin(); ibb != bbl.end(); ++ibb) { - newboxes += *ibb; - } - - // Check that they are equal - assert (newboxes.size() <= oldboxes.size()); - assert ((newboxes.size()==0) == (oldboxes.size()==0)); - assert (oldboxes == newboxes); -#endif -#if 0 - cout << "MakeRegions_Adaptively_Recombine: final list:" << endl; - cout << bbl << endl; - cout << endl; -#endif - } - - static void - MakeRegions_Adaptively (const cGH* const cctkGH, - const int minwidth, - const CCTK_REAL minfraction, - const CCTK_REAL maxerror, - const data<CCTK_REAL,dim>& error, - list<ibbox>& bbl, - const ibbox& region) - { - // Just to be sure - assert (! region.empty()); - - // Count grid points that need to be refined - // (this doesn't work yet on multiple processors) - assert (CCTK_nProcs(cctkGH)==1); - int cnt = 0; - for (ibbox::iterator it=region.begin(); it!=region.end(); ++it) { - if (error[*it] > maxerror) ++cnt; - } - const CCTK_REAL fraction = (CCTK_REAL)cnt / region.size(); - const int width = maxval(region.shape() / region.stride()); - - if (cnt == 0) { - // Don't refine - } else if (width < 2*minwidth || fraction >= minfraction) { - // Refine the whole region - const ivect lo(region.lower()); - const ivect up(region.upper()); - const ivect str(region.stride()); - bbl.push_back (ibbox(lo,up+str-str/reffact,str/reffact)); -// cout << "MRA: Refining to " << bbl.back() << " size " << bbl.back().size() << " fraction " << fraction << endl; - } else { - // Split the region and check recursively - const int dir = maxloc(region.shape()); - const ivect lo(region.lower()); - const ivect up(region.upper()); - const ivect str(region.stride()); - ivect lo1(lo), lo2(lo); - ivect up1(up), up2(up); - const int mgstr = ipow(hh->mgfact, mglevels); // honour multigrid factors - const int step = str[dir]*mgstr; - lo2[dir] = ((up[dir]+lo[dir])/2/step)*step; - up1[dir] = lo2[dir]-str[dir]; - const ibbox region1(lo1,up1,str); - const ibbox region2(lo2,up2,str); - assert (region1.is_contained_in(region)); - assert (region2.is_contained_in(region)); - assert ((region1 & region2).empty()); - assert (region1 + region2 == region); - list<ibbox> bbl1, bbl2; - MakeRegions_Adaptively (cctkGH, minwidth, minfraction, maxerror, - error, bbl1, region1); - MakeRegions_Adaptively (cctkGH, minwidth, minfraction, maxerror, - error, bbl2, region2); - // Combine regions if possible - up2 += str-str/reffact; - up2[dir] = lo2[dir]; - const ibbox iface(lo2,up2,str/reffact); - MakeRegions_Adaptively_Recombine (bbl1, bbl2, bbl, iface, dir); - } - - } - - void - MakeRegions_Adaptively (const cGH* const cctkGH, - const int minwidth, - const CCTK_REAL minfraction, - const CCTK_REAL maxerror, - const gf<CCTK_REAL,dim>& error, - list<ibbox>& bbl, list<bvect>& obl) - { - assert (bbl.empty()); - - if (reflevel+1 >= maxreflevels) return; - - assert (component == -1); - - const int rl = reflevel; - - // Arbitrary - const int tl = 0; - const int ml = 0; - -// cout << endl << "MRA: Choosing regions to refine in " << hh->components(rl) << " components" << endl; - - for (int c=0; c<hh->components(rl); ++c) { - const ibbox region = hh->extents[rl][c][ml]; - assert (! region.empty()); - - const data<CCTK_REAL,dim>& errdata = *error(tl,rl,c,ml); - - MakeRegions_Adaptively (cctkGH, minwidth, minfraction, maxerror, - errdata, bbl, region); - } - -// int numpoints = 0; -// for (list<ibbox>::const_iterator ibb = bbl.begin(); ibb != bbl.end(); ++ibb) { -// numpoints += ibb->size(); -// } -// cout << "MRA: Chose " << bbl.size() << " regions with a total size of " << numpoints << " to refine." << endl << endl; - - // Remove grid points outside the outer boundary - vect<bool,dim> obp; - { - DECLARE_CCTK_PARAMETERS; - assert (sizeof outside_boundary_points == dim * sizeof (CCTK_INT)); - obp = outside_boundary_points; - } - for (list<ibbox>::iterator it = bbl.begin(); - it != bbl.end(); - ++it) { - const ivect ub = obp.ifthen (it->upper(), - min (it->upper(), hh->baseextent.upper())); - *it = ibbox(it->lower(), ub, it->stride()); - } - - // Create obl from bbl - for (list<ibbox>::const_iterator it = bbl.begin(); - it != bbl.end(); - ++it) { - obl.push_back (zip ((vect<bool,2> (*) (bool, bool)) &vect<bool,2>::make, - it->lower() == hh->baseextent.lower(), - it->upper() == hh->baseextent.upper())); - } - + return do_recompose; } } // namespace CarpetRegrid |