Something like this?
/*=========================================================================== BrusierRestrict
The way this routine should work:
Pass in the values of the fine level and the course level, Pass in the grid hierarchy and a grid function or set of grid functions Call the half-weighted restriction operator(s) for said grid functions(s) For any coarse grid points adjacent to inner boundary points, replace these points with injected/"straight copy" data from the fine grid
Note: currently calling ref_restric_all, but I don't really want to restrict "all" grid functions. Just some of them...
Much of this routine was "lifted" from LSUDevelopment/Refluxing/src/correct.cc ===========================================================================*/ namespace variables {
char const * restrict const soln[] = { "BruiserConstraints::phi", "BruiserConstraints::wx", "BruiserConstraints::wy", "BruiserConstraints::wz", NULL };
char const * restrict const rhs[] = { "BruiserConstraints::rhsphi", "BruiserConstraints::rhswx", "BruiserConstraints::rhswy", "BruiserConstraints::rhswz", NULL };
char const * restrict const none[] = { NULL };
} // namespace variables
static void get_varinds (cGH const * restrict const cctkGH, char const * restrict const * restrict const names, vector<int>& gis, vector<int>& vis) { int nvars = 0; while (names[nvars]) ++nvars; assert (gis.empty()); assert (vis.empty()); gis.reserve(nvars); vis.reserve(nvars); }
void BruiserRestrict(CCTK_ARGUMENTS) {
DECLARE_CCTK_PARAMETERS;
CCTK_VInfo(CCTK_THORNSTRING,"reflevel = %d, mglevel = %d", reflevel,mglevel);
CCTK_WARN(0,"BruiserRestrict: No clue what to do here. Aborting."); /* Something like... */ vector<int> gis, vis; get_varinds (cctkGH, variables::soln, gis, vis); CCTK_INT const nvars = gis.size(); int const tl = 0; CCTK_REAL time = 0.0;
int const coarse_vi = CCTK_VarIndex ("Brusier::phi"); // What about other variables: wx, wy, and wz? int const coarse_gi = CCTK_GroupIndexFromVarI (coarse_vi); assert (coarse_gi >= 0); int const coarse_v0 = CCTK_FirstVarIndexI (coarse_gi); assert (coarse_v0 >= 0);
int const fine_vi = CCTK_VarIndex ("Brusier::phi");
for (comm_state state; not state.done(); state.step()) { for (int m=0; m<maps; ++m) { ggf *const gv = arrdata.AT(coarse_gi).AT(m).data. AT(coarse_vi - coarse_v0); // This subtraction does what? gv->ref_restrict_all (state, tl, reflevel, mglevel, time); } } // for state }
Yes:
void BruiserRestrict(CCTK_ARGUMENTS) {
DECLARE_CCTK_PARAMETERS;
CCTK_VInfo(CCTK_THORNSTRING,"reflevel = %d, mglevel = %d", reflevel, mglevel);
int const nvars = 4; int gis[nvars], v0s[nvars]; vis[nvars];
gis[0] = CCTK_GroupIndex("Bruiser::phigroup"); assert(gis[0] >= 0); v0s[0] = CCTK_FirstVarIndexI(gis[0]); assert(v0s[0] >= 0); vis[0] = CCTK_VarIndex("Bruiser::phi") - v0s[0]; assert(vis[0] >= 0);
gis[1] = ...; v0s[1] = ...; vis[1] = ...; // etc.
int const tl = 0; CCTK_REAL const time = cctk_time;
for (comm_state state; not state.done(); state.step()) { for (int m=0; m<maps; ++m) { for (int n=0; n<nvars; ++n) { ggf *const gv = arrdata.AT(gis[n]).AT(m).data.AT(vis[n]); gv->ref_restrict_all (state, tl, reflevel, mglevel, time); } } } // for state }
-erik
How about this? I came up with this last night, and it _seems_ to work..
ŠAnd another question: Does the "base grid" count as reflevel = 0? OrŠmore specifically, if not, how do we restrict on to the "non-refined" grid?
//definitions from control.cc
#define SWITCH_TO_LEVEL(cctkGH, rl) \ do { \ bool switch_to_level_ = true; \ assert (is_level_mode()); \ int const rl_ = (rl); \ BEGIN_GLOBAL_MODE (cctkGH) { \ ENTER_LEVEL_MODE (cctkGH, rl_) {
#define END_SWITCH_TO_LEVEL \ } LEAVE_LEVEL_MODE; \ } END_GLOBAL_MODE; \ assert (switch_to_level_); \ switch_to_level_ = false; \ } while (false)
/*========================================================================= == BrusierRestrictGroup. Restricts a whole group of variables
Should Call the half-weighted restriction operator(s) for said grid functions(s) For any coarse grid points adjacent to inner boundary points, replace these points with injected/"straight copy" data from the fine grid
Note that ref_restrict_all assumes you're on the *coarser* level. =========================================================================== */ void BruiserRestrictGroup(CCTK_ARGUMENTS, const char *groupname) {
DECLARE_CCTK_PARAMETERS;
if (bruiser_verbosity >= 5) CCTK_VInfo(CCTK_THORNSTRING,"BruiserRestrictGroup:reflevel = %d, mglevel = %d, groupname = "%s"" ,reflevel,mglevel,groupname);
CCTK_INT group_index = CCTK_GroupIndex(groupname); if (group_index < 0) CCTK_VWarn(CCTK_WARN_ALERT, __LINE__, __FILE__, CCTK_THORNSTRING, "BruiserRestrictGroup: Bad group name: "%s"",groupname);
CCTK_INT numvars = CCTK_NumVarsInGroupI(group_index); CCTK_INT first_varindex = CCTK_FirstVarIndexI(group_index); if (first_varindex < 0) CCTK_VWarn(CCTK_WARN_ALERT, __LINE__, __FILE__, CCTK_THORNSTRING, "BruiserRestrictGroup: Bad first_varindex = %d",first_varindex);
CCTK_REAL time = 0.0; // ? Does this need to be changed for non-initial times? int const tl = 0; // ?
if (0 == reflevel) CCTK_VWarn(CCTK_WARN_ALERT, __LINE__, __FILE__, CCTK_THORNSTRING, "BruiserRestrictGroup: reflevel = %d, already on base grid",reflevel);
CCTK_INT const finer_level = reflevel; // Save this info for consistency check
SWITCH_TO_LEVEL (cctkGH, reflevel-1) { // Drop to coarser level for (CCTK_INT vi = 0; vi < numvars; vi++) { // Loop over variables in group
if (bruiser_verbosity >= 5) CCTK_VInfo(CCTK_THORNSTRING," BruiserRestrictGroup: Restricting "%s"", CCTK_FullName(first_varindex + vi));
for (comm_state state; not state.done(); state.step()) { for (int m=0; m<maps; ++m) { ggf *const gv = arrdata.AT(group_index).AT(m).data.AT(vi);
gv->ref_restrict_all (state, tl, reflevel, mglevel, time);
// TODO: injection at inner (excision) boundary } } // for state
} // End of loop over variables in group } END_SWITCH_TO_LEVEL; assert ( finer_level == reflevel ); // Does this make sure we're back on the finer level?
} // End of BruiserRestrictGroup
On Tue, Apr 10, 2012 at 12:39 PM, Scott Hawley scott.hawley@belmont.edu wrote:
How about this? I came up with this last night, and it _seems_ to work..
The variable "time" may need to be set to cctk_time. Since restriction does not perform time interpolation, the only bad effect if you don't do so could be that Carpet aborts with an error message complaining about an inconsistent time. Or maybe this variable is ignored for restriction.
The loop over comm_state should be the outermost loop. For each such loop, Carpet communicates, and it is most efficient to pack as many communications together as possible. Hence the vi loop should be inside the comm_state loop. This is purely for efficiency; the code is correct as is.
Yes, your last assert statement does what you assume it does.
ŠAnd another question: Does the "base grid" count as reflevel = 0? OrŠmore specifically, if not, how do we restrict on to the "non-refined" grid?
Yes, the base grid has reflevel 0. Restricting means to restrict TO a particular level, so you do want to restrict (to) level 0, but restricting (to) the finest grid is a no-op (since there are no finer grids).
-erik
Thank you so much!
On 4/10/12 4:06 PM, "Erik Schnetter" schnetter@cct.lsu.edu wrote:
On Tue, Apr 10, 2012 at 12:39 PM, Scott Hawley scott.hawley@belmont.edu wrote:
How about this? I came up with this last night, and it _seems_ to work..
The variable "time" may need to be set to cctk_time. Since restriction does not perform time interpolation, the only bad effect if you don't do so could be that Carpet aborts with an error message complaining about an inconsistent time. Or maybe this variable is ignored for restriction.
The loop over comm_state should be the outermost loop. For each such loop, Carpet communicates, and it is most efficient to pack as many communications together as possible. Hence the vi loop should be inside the comm_state loop. This is purely for efficiency; the code is correct as is.
Yes, your last assert statement does what you assume it does.
ŠAnd another question: Does the "base grid" count as reflevel = 0? OrŠmore specifically, if not, how do we restrict on to the "non-refined" grid?
Yes, the base grid has reflevel 0. Restricting means to restrict TO a particular level, so you do want to restrict (to) level 0, but restricting (to) the finest grid is a no-op (since there are no finer grids).
-erik
-- Erik Schnetter schnetter@cct.lsu.edu http://www.perimeterinstitute.ca/personal/eschnetter/
users@lists.einsteintoolkit.org