Index: param.ccl =================================================================== --- param.ccl (revision 33) +++ param.ccl (working copy) @@ -32,6 +32,20 @@ { } "no" +CCTK_REAL refluxing_fraction "Fraction of refluxing that should be applied" STEERABLE=always +{ + *:* :: "0 = no refluxing, 1 = full refluxing" +} 1.0 + +BOOLEAN halftime_refluxing "Apply some refluxing at half time already (THIS DOES NOT WORK, BECAUSE POSTRESTRICT IS NOT CALLED ON THE FINEST LEVEL)" STEERABLE=always +{ +} "no" + +CCTK_REAL halftime_refluxing_fraction "Fraction of refluxing that should be applied at half time" STEERABLE=always +{ + *:* :: "0 = no refluxing, 1 = full refluxing, 2 = over-refluxing" +} 1.0 + STRING debug_variables "List of intermediate variables to output for debugging" STEERABLE=always { "" :: "" Index: src/correct.cc =================================================================== --- src/correct.cc (revision 33) +++ src/correct.cc (working copy) @@ -418,9 +418,79 @@ +// Reset the fine grid flux register (on the next finer level) +static +void flux_register_fine_reset (cGH const * restrict const cctkGH) +{ + assert (is_level_mode()); + + SWITCH_TO_LEVEL (cctkGH, reflevel+1) { + BEGIN_LOCAL_MAP_LOOP (cctkGH, CCTK_GF) { + BEGIN_LOCAL_COMPONENT_LOOP (cctkGH, CCTK_GF) { + DECLARE_CCTK_ARGUMENTS; + + ivect const& lsh = ivect::ref(cctk_lsh); + int const np = prod(lsh); + + vector flux_register_fine_ptrs = + get_varptrs (cctkGH, reflevel, variables::flux_register_fine); + int const nvars = flux_register_fine_ptrs.size(); + + for (int n=0; n flux_register_coarse_ptrs = + get_varptrs (cctkGH, reflevel, variables::flux_register_coarse); + int const nvars = flux_register_coarse_ptrs.size(); + + for (int n=0; n flux_register_fine_ptrs = - get_varptrs (cctkGH, reflevel, variables::flux_register_fine); - int const nvars = flux_register_fine_ptrs.size(); - - for (int n=0; n=0 and reflevel>=0 and Carpet::map==-1 and component==-1); + + // We reflux on level L by taking a correction from level L+1 into + // account. (This corresponds to restriction, where level L is + // "corrected" from level L+1.) + + // In this case, we apply (part of) the refluxing at half-time + // already. At half-time we are called on the fine level L+1, so we + // have to switch to the corresponding coarse level L first. + + // If there is no coarser level; do nothing + if (reflevel == 0) return; + + // If the next coarser level is aligned; do nothing + assert (maxtimereflevelfact % timereffacts.AT(reflevel-1) == 0); + int const iter_step = maxtimereflevelfact / timereffacts.AT(reflevel-1); + if (cctkGH->cctk_iteration % iter_step == 0) return; + + SWITCH_TO_LEVEL(cctkGH, reflevel-1) { + + if (verbose or veryverbose) { + CCTK_VInfo (CCTK_THORNSTRING, + "Half-time refluxing at iteration %d on level %d of %d", + cctkGH->cctk_iteration, reflevel, reflevels); + } + + reflux (cctkGH, true); + } END_SWITCH_TO_LEVEL; -} - - - -// Reset the coarse grid flux register (on this level) -static -void flux_register_coarse_reset (cGH const * restrict const cctkGH) -{ - assert (is_level_mode()); - - BEGIN_LOCAL_MAP_LOOP (cctkGH, CCTK_GF) { - BEGIN_LOCAL_COMPONENT_LOOP (cctkGH, CCTK_GF) { - DECLARE_CCTK_ARGUMENTS; - - ivect const& lsh = ivect::ref(cctk_lsh); - int const np = prod(lsh); - - vector flux_register_coarse_ptrs = - get_varptrs (cctkGH, reflevel, variables::flux_register_coarse); - int const nvars = flux_register_coarse_ptrs.size(); - - for (int n=0; n=0 and reflevel>=0 and Carpet::map==-1 and component==-1); + if (halftime_refluxing) { + HalfTime_CorrectState (CCTK_PASS_CTOC); + } + // We reflux on level L by taking a correction from level L+1 into // account. (This corresponds to restriction, where level L is // "corrected" from level L+1.) @@ -733,9 +785,6 @@ } reflux (cctkGH); - - flux_register_fine_reset (cctkGH); - flux_register_coarse_reset (cctkGH); }