#include #include #include #include #include #include "cctk.h" #include "cctk_Parameters.h" #include "gh.hh" #include "carpet.hh" #include "regrid.hh" namespace CarpetRegrid { using namespace std; using namespace Carpet; int ManualCoordinateList (cGH const * const cctkGH, gh const & hh, gh::mexts & bbsss, gh::rbnds & obss, gh::rprocs & pss) { DECLARE_CCTK_PARAMETERS; int ierr; assert (refinement_levels >= 1); // do nothing if the levels already exist if (reflevel == refinement_levels && !tracking) return 0; assert (bbsss.size() >= 1); vector > bbss = bbsss.at(0); jjvect nboundaryzones, is_internal, is_staggered, shiftout; ierr = GetBoundarySpecification (2*dim, &nboundaryzones[0][0], &is_internal[0][0], &is_staggered[0][0], &shiftout[0][0]); assert (!ierr); rvect physical_min, physical_max; rvect interior_min, interior_max; rvect exterior_min, exterior_max; rvect base_spacing; ierr = GetDomainSpecification (dim, &physical_min[0], &physical_max[0], &interior_min[0], &interior_max[0], &exterior_min[0], &exterior_max[0], &base_spacing[0]); assert (!ierr); bbss.resize (refinement_levels); obss.resize (refinement_levels); pss.resize (refinement_levels); vector > newbbss; if (strcmp(coordinates, "") != 0) { istringstream gp_str(coordinates); try { gp_str >> newbbss; } catch (input_error) { CCTK_WARN (0, "Could not parse parameter \"coordinates\""); } if (newbbss.size() >= spacereffacts.size()) { CCTK_WARN (0, "Parameter \"coordinates\" defines too many refinement levels; at most Carpet::max_refinement_levels - 1 may be defined"); } } if ((int)newbbss.size() < refinement_levels-1) { CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "The parameter \"coordinates\" must contain at least \"refinement_levels-1\" (here: %d) levels", int(refinement_levels-1)); } // Remove superfluous boxes newbbss.resize (refinement_levels-1); vector > newobss; if (smart_outer_boundaries) { // TODO: // assert (domain_from_coordbase); newobss.resize(newbbss.size()); for (int rl=0; rl<(int)newobss.size(); ++rl) { ivect const spacereffact = spacereffacts.at(rl+1); assert (mglevel==0); rvect const spacing = base_spacing * ipow((CCTK_REAL)mgfact, basemglevel) / rvect(spacereffact); ierr = ConvertFromPhysicalBoundary (dim, &physical_min[0], &physical_max[0], &interior_min[0], &interior_max[0], &exterior_min[0], &exterior_max[0], &spacing[0]); assert (!ierr); newobss.at(rl).resize(newbbss.at(rl).size()); for (int c=0; c<(int)newobss.at(rl).size(); ++c) { rvect lo = newbbss.at(rl).at(c).lower(); rvect up = newbbss.at(rl).at(c).upper(); rvect str = newbbss.at(rl).at(c).stride(); bbvect ob = newobss.at(rl).at(c); for (int d=0; d> newobss; } catch (input_error) { CCTK_WARN (0, "Could not parse parameter \"outerbounds\""); } if (newobss.size() >= spacereffacts.size()) { CCTK_WARN (0, "Parameter \"outerbounds\" defines too many refinement levels; at most Carpet::max_refinement_levels - 1 may be defined"); } bool good = newobss.size() == newbbss.size(); if (good) { for (int rl=0; rl<(int)newobss.size(); ++rl) { good = good and newobss.at(rl).size() == newbbss.at(rl).size(); } } if (! good) { cout << "coordinates: " << newbbss << endl; cout << "outerbounds: " << newobss << endl; CCTK_WARN (0, "The parameters \"outerbounds\" and \"coordinates\" must have the same structure"); } } else { newobss.resize(newbbss.size()); for (int rl=0; rl<(int)newobss.size(); ++rl) { newobss.at(rl).resize(newbbss.at(rl).size()); for (int c=0; c<(int)newobss.at(rl).size(); ++c) { newobss.at(rl).at(c) = bbvect(false); } } } } // if ! smart_outer_boundaries for (int rl=1; rl bbs; gh::cbnds obs; bbs.reserve (newbbss.at(rl-1).size()); obs.reserve (newbbss.at(rl-1).size()); for (int c=0; c<(int)newbbss.at(rl-1).size(); ++c) { rbbox const & ext = newbbss.at(rl-1).at(c); bbvect const & ob = newobss.at(rl-1).at(c); // TODO: // assert (domain_from_coordbase); ivect const spacereffact = spacereffacts.at(rl); rvect const spacing = base_spacing * ipow((CCTK_REAL)mgfact, basemglevel) / rvect(spacereffact); if (! all(abs(ext.stride() - spacing) < spacing * (CCTK_REAL) 1.0e-10)) { assert (dim==3); CCTK_VWarn (0, __LINE__, __FILE__, CCTK_THORNSTRING, "The grid spacing on refinement level %d is incorrect. I expected [%g,%g,%g], but I found [%g,%g,%g].", int(rl), double(spacing[0]), double(spacing[1]), double(spacing[2]), double(ext.stride()[0]), double(ext.stride()[1]), double(ext.stride()[2])); } assert (all(abs(ext.stride() - spacing) < spacing * (CCTK_REAL) 1.0e-10)); rvect offset = rvect(0); if (c < num_offsets) { if (rl >= offset_firstlevel) { assert (dim==3); offset = rvect(offsetx[c], offsety[c], offsetz[c]); } } ManualCoordinates_OneLevel (cctkGH, hh, rl, refinement_levels, ext.lower() + offset, ext.upper() + offset, ob, bbs, obs); } if (merge_overlapping_components) { // Check if one or more of our components touch again: // Loop over all pairs of components for (int c=0; c<(int)bbs.size(); ++c) { for (int cc=0; cc