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