WNYN6LX3FYXXW3TKGRA7GRLFMIR4YXQMFAWJCB76QAXLY6JR4Q7AC
UEICYVRXRLWSAHYZT2ZSO5D5EUINBHJQI6QWQPVE22HVTBC344GQC
3NWSBBMPHW3XOWLAMWI2AXX5VQDRHYT7CKGHL32RD6AUAUH67SVAC
D4JEUZQOFJSQ2FIQBMQ6P7YQM3AATMOWCNIRMKRIEJX4ZIKENGXQC
B7Y552HZXBV2PD22T7ZXGFJKUYU23A7XDWV4XZK46SGQKX7U45PQC
BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC
722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC
KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC
BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC
MSBBCXVGD3GRLE5KAI6BKAFRV7SQUWI2SNN43AJAUD3ISRCEXY6QC
USPPNUMNL5HU5WEOIWJMIFAX6TBZERVAV67XJUJQ6KSNLG55JAGQC
BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC
IVHURSHY4636OGIF3PNDO5CWOVRLJ75M4LP65J6I2E6KAM4QKF4AC
UUGQGVC4WEKN64WAP7F5QPS2UHGQB5ZLMFRIYNWKMIEBDO3QRX4AC
EJWFGXTWIBKJ62LO6QM62LM7MGTYEHOCZDKA3UVR5UYWQZ2O54DQC
VMCDMDXKME66ESRMB3PYSUZZH2XG2GIQMEOEKRH33WGCEBPXTWUQC
M5R6KQLXLGYSVKHVAX5AJKD6NYE6IM5Z6WVTR3BTKPJDNNKF3ARAC
RF3SDQ3ELEBCGJSFQL2VOSHNN34RAH6KM3LEITEYOHKJMMHHKMFAC
UZAKARMGORRQG733ZUPJOEGL5FG243I32NCC2SRSFDCZKUQ5A52QC
ZARZZPSISIOCXZOWNJQMMQSQPXFSZLDDIDAFY35X2GV37RBB7WUAC
WASO7G5FJXRXWNH2U2FLUNEKU6VE63OI3HUYP64BVD4LMD6KE7OQC
33IC3UHCEPZLGS5ACS2JXHGT6CRU5LXU6PM6RDHCERPOIELVRVXQC
WMCMZILMWKIKL6K5ROISXT23A6XTZQGSBQ3IAWMDOJMK2JERGJKQC
67UXOK4QSZFAPVZXU2MJMD7I2232JCK4QDMIOMVMEQNQUGN7632AC
GQVQJCNQNO2KD7ZMC7RESCUAMUAP7OED6CTA6SYLZKQGXKXZ6T3QC
TOBGHRPKEPSXDN56WGSZNWOMCBVJ4KUSLWYWI56MC2RR3MM3KLZAC
W4XMGPEHBCV6AAPJBI4SSEMCDB6KKCGRUC2X2F5YLBY22OR3ICPAC
FS7Q6TUHBK5WSRDC3TM6KV2BPGWATRBLDHFGEJ72BR3FRDEOC3WAC
X7A7HYGU2NPWCZCG5SYFD4NINYDP6UYWFFE3WP6YNLSDIABG2KJAC
PQB3EKQ6MBCXPTW4HB7SGMSTOTYMB3EFZX2573OFCQI6PSOEKCSQC
T35FSMI7CA2CFZSRLTCZQBT2KDSEPDZD5UAPNNGR4YYAJ67LT4PAC
FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC
2DD222JSYRPHTXKSRXLSOMSCQPZUORNFLLO2P3GMIDELAAMD5MEQC
2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC
HBZVMDSQU5KSMGZXRL67OERWEDNGTSYJVGV4BFDKKSSSHU4X23AAC
73MGOJCJR5RBFRRV4CWYIPB3JSKJEXRBNG63SX3IDR4GJHEL2TWQC
TYKQOTJ6JYOIGGODRZNGSZ6MCGAYJNYM5TXXE5OSVL3DY5NOQO3AC
2DALQONYWEACYEPAPWH3MRRVZSHQ5XTMKRIQWZT7YXKISMDR4HWQC
WE6MDRN5SPK3THM4COLQFE3IUWBCQ5ZYUIAUCBJAZVEMMOVTNBOAC
E3MBKFT4GEFDAGZQQW4OROY5F6FWC46G6MRH54GDYTGO7O5YSRIAC
NUOLOGCKMF5UOBGBYEOX4O7NQ5AEVVLCH6KRBQRJQXIRDNJ2C2ZQC
3BFBGMNXEPJUUTSJDJ222PQATNDNX4GGRJA2PZBPMWFMG2ZRGH2AC
2BSBB53DVGURXHAIBJQI2YO6V42HYBLMF5IULSCYMZQPN4EH7IMQC
P2M2LDDITHKC7HC6RMWQDTS5CT6CCH4LSIN37HQUA3NTC6SFNZOQC
4TMNUWJCT42VYYU2SBGVIXURBRWRH7SSC7PDATP2CUUDTLVVK7IAC
assert(current_level == -1);
for (int level = int(ghext->leveldata.size()) - 2; level >= 0; --level)
Restrict(level);
assert(active_levels);
active_levels->loop_reverse([&](const auto &leveldata) {
if (leveldata.level != int(ghext->leveldata.size()) - 1)
Restrict(leveldata.level);
});
CycleTimelevels(cctkGH);
// Find smallest iteration number. Levels at this iteration will
// be evolved.
rat64 iteration = ghext->leveldata.at(0).iteration;
for (const auto &leveldata : ghext->leveldata)
iteration = min(iteration, leveldata.iteration);
CCTK_Traverse(cctkGH, "CCTK_PRESTEP");
CCTK_Traverse(cctkGH, "CCTK_EVOL");
// Loop over all levels, in batches that combine levels that don't
// subcycle. The level range is [min_level, max_level).
int min_level = 0;
while (min_level < int(ghext->leveldata.size())) {
// Find end of batch
int max_level = min_level + 1;
while (max_level < int(ghext->leveldata.size()) &&
!ghext->leveldata.at(max_level).is_subcycling_level)
++max_level;
// Skip this batch of levels if it is not active at the current
// iteration
if (ghext->leveldata.at(min_level).iteration > iteration)
break;
// Reflux
assert(current_level == -1);
for (int level = int(ghext->leveldata.size()) - 2; level >= 0; --level)
Reflux(level);
active_levels = make_optional<active_levels_t>(min_level, max_level);
// Advance iteration number on this batch of levels
active_levels->loop([&](auto &restrict leveldata) {
leveldata.iteration += leveldata.delta_iteration;
});
InvalidateTimelevels(cctkGH);
Restrict(level);
CCTK_Traverse(cctkGH, "CCTK_POSTRESTRICT");
Reflux(level);
if (!restrict_during_sync) {
// Restrict
for (int level = int(ghext->leveldata.size()) - 2; level >= 0; --level)
Restrict(level);
CCTK_Traverse(cctkGH, "CCTK_POSTRESTRICT");
}
CCTK_Traverse(cctkGH, "CCTK_POSTSTEP");
CCTK_Traverse(cctkGH, "CCTK_CHECKPOINT");
CCTK_Traverse(cctkGH, "CCTK_ANALYSIS");
CCTK_OutputGH(cctkGH);
active_levels = optional<active_levels_t>();
// Loop over all levels
// TODO: parallelize this loop
for (int level = min_level; level < max_level; ++level) {
const auto &restrict leveldata = ghext->leveldata.at(level);
// Loop over all levels
// TODO: parallelize this loop
active_levels->loop([&](const auto &restrict leveldata) {
if (restrict_during_sync) {
if (current_level == -1) {
for (int level = int(ghext->leveldata.size()) - 2; level >= 0; --level)
Restrict(level, groups);
} else {
if (current_level < int(ghext->leveldata.size()) - 1)
Restrict(current_level, groups);
}
}
if (restrict_during_sync)
active_levels->loop_reverse([&](const auto &leveldata) {
if (leveldata.level < int(ghext->leveldata.size()) - 1)
Restrict(leveldata.level, groups);
});
const int min_level = current_level == -1 ? 0 : current_level;
const int max_level =
current_level == -1 ? ghext->leveldata.size() : current_level + 1;
for (int level = min_level; level < max_level; ++level) {
auto &restrict leveldata = ghext->leveldata.at(level);
active_levels->loop([&](auto &restrict leveldata) {
FillPatchSingleLevel(*groupdata.mfab.at(tl), 0.0,
{&*groupdata.mfab.at(tl)}, {0.0}, 0, 0,
groupdata.numvars, ghext->amrcore->Geom(level),
physbc, 0);
FillPatchSingleLevel(
*groupdata.mfab.at(tl), 0.0, {&*groupdata.mfab.at(tl)}, {0.0},
0, 0, groupdata.numvars, ghext->amrcore->Geom(leveldata.level),
physbc, 0);
// Whether CallFunction traverses all levels (-1) or just one specific level
// (>=0)
extern int current_level;
template <typename F> void loop(F f) {
for (int level = min_level; level < max_level; ++level)
assert(ghext->leveldata.at(level).iteration ==
ghext->leveldata.at(min_level).iteration);
for (int level = min_level; level < max_level; ++level)
f(ghext->leveldata.at(level));
}
template <typename F> void loop_reverse(F f) {
for (int level = min_level; level < max_level; ++level)
assert(ghext->leveldata.at(level).iteration ==
ghext->leveldata.at(min_level).iteration);
for (int level = max_level - 1; level >= min_level; --level)
f(ghext->leveldata.at(level));
}
};
// The levels CallFunction should traverse
extern optional<active_levels_t> active_levels;