VMCDMDXKME66ESRMB3PYSUZZH2XG2GIQMEOEKRH33WGCEBPXTWUQC TYKQOTJ6JYOIGGODRZNGSZ6MCGAYJNYM5TXXE5OSVL3DY5NOQO3AC 2DALQONYWEACYEPAPWH3MRRVZSHQ5XTMKRIQWZT7YXKISMDR4HWQC T3ARO5SWCVNUDSQHQYD3QLIJ3JLSFFNOWXPC2VTDOERWSFOFV47QC 3I2VE3RJ4E4WZZSUGJKOMHP2FKOAZA6SLVMVYE3B54SZCYXGIU4QC M5R6KQLXLGYSVKHVAX5AJKD6NYE6IM5Z6WVTR3BTKPJDNNKF3ARAC 722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC IEFVL4X5BPCLUX5D24ESP7FTFSX2HMCD2GOIFCMSWNUYEHQEJOIAC KG47IF4CPCUT3BHS34WDRHTH5HYMBTY4OSTB3X7APR2E5ZJ32IYQC YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC MSBBCXVGD3GRLE5KAI6BKAFRV7SQUWI2SNN43AJAUD3ISRCEXY6QC GQVQJCNQNO2KD7ZMC7RESCUAMUAP7OED6CTA6SYLZKQGXKXZ6T3QC 33IC3UHCEPZLGS5ACS2JXHGT6CRU5LXU6PM6RDHCERPOIELVRVXQC TVBD244E7Q7WV44CRBTFST535NUP3JAZH6OLL4IKDR3OWEXSU7HAC BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC 24A4OZBZBQ6QXIQ3EOOCQIBTOWRA32TMSQ4CCL3LKIJVJPKZFHVQC 5IAXY3XZJTRMMVT2OVIJ6OXQJI6OJPTPCHHA4IVLVMHANCCC5NKAC JN2TPHENEBIY2OE5FRCQ2E6QCL6FPVHJHUCP4UODD6DITRVV2LIQC LHPZHX4FMRYBM7NI22QTP3VZDBYFRSNTY3L6BEEFPPF5KWCFFIHQC T3TZRPPAIA24I3YL3JFB4XEAYCWU3HJAJUCF7NNIFMP4I5X4SM5QC BVO33OXTG3QDBJ5YLBBVMUDHZGVFE777UOGZKVAHQK6MSDVR5RRAC VIK5E6DBUCP5HGDVHDP6SWTHH7ODEUIGKOGSXR7VLVK46LDD4W6QC BSMJ4V7GV3EOGY4KCSTOJQUOFE2OOCIKQETE4WC2WRNLWBQIBW3QC WNIZUZ26W6RAWU2D4XTX5KU5D63VGG74RXB2W4N4M2VDQNE6T6UQC XZE3LDQF3QWMWBGQJROJZW2R2LQWBAWLFJVS2Z52RMEW4TPI75JQC 7O7ZM5ZQVDPNESV7VJFZRXUINZSKPLOM44AWZEKOCZODHEL6Y36QC LSOYKV2LJ6WOBTNCW43WXV47RIQEBNZFEJJZM5QA7XDZF4D2PANQC FS7Q6TUHBK5WSRDC3TM6KV2BPGWATRBLDHFGEJ72BR3FRDEOC3WAC PG2P3JQPLWZRLCAJ7JY2B7G7AM5DHOE2CJUKIPWREI3NAUKZF3TAC R6B5YHARRV34JO6W4GAWBOQ4BW5H6VEKXWMVKJKPWC7MUO4ZYZVQC E3MBKFT4GEFDAGZQQW4OROY5F6FWC46G6MRH54GDYTGO7O5YSRIAC A7ETPFXEHA2RM4LINSBVMJJ3G62NF7Q5ZQOKJPNJK3YOQ5WS5HKAC U77PE56ICORZNQW33NXGSEMW7GDHCSSZ4EXB6OHBJSHEG6WHYSSQC FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC GKKJ75HX2ERLVBZVE2CUB6T3J2SUT7R3UKEKTEYNOG43ZKX6X5MQC ORAAQXS3UNKXYDJBCTHNEIDJIZDHWMM5EVCZKVMFRKQK2NIQNJGAC UUGQGVC4WEKN64WAP7F5QPS2UHGQB5ZLMFRIYNWKMIEBDO3QRX4AC BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC A245RNFHKVWQGWN3R7TQNYSNUZJ3K4EM3FZNSY5Y7KOEPDGJGUKQC 3ROBI6IPLFHSSNMGTZHYWIPCO342OKQLXHNWFJ3KMNQRNYMAMLKAC UEZKNPXXK5WU6B5LYRKGGYGBZ6T6TAZI26CWTJFUBUW2SJJOMV2AC PQB3EKQ6MBCXPTW4HB7SGMSTOTYMB3EFZX2573OFCQI6PSOEKCSQC 2DD222JSYRPHTXKSRXLSOMSCQPZUORNFLLO2P3GMIDELAAMD5MEQC RTNZAS3UPI6GG3KY4Z5WVXJ4R2YF5427BB6WAV3GHRS5W7XPOSUQC UZAKARMGORRQG733ZUPJOEGL5FG243I32NCC2SRSFDCZKUQ5A52QC WASO7G5FJXRXWNH2U2FLUNEKU6VE63OI3HUYP64BVD4LMD6KE7OQC HBZVMDSQU5KSMGZXRL67OERWEDNGTSYJVGV4BFDKKSSSHU4X23AAC GCJJ35BFUTRWJGWOVVMYNOSXEELH6YYX7FW4XL6QWPUD63TAL5NQC 2XYZZL42IEZHGDJA6NDKGSQKGJP24LOTLFJ6RNHOKWHHSUYIHGKQC NUNYA5E7NMMUTVAQKVO34GUQI3U2TJTCEIZZT3PAPZ3ZU5LB44BQC YDBJPTC5P4FG5CQ7QAGDNXVPX4BNR3LFG4TEORB7UJ7UGDS6CNGQC 2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC WE6MDRN5SPK3THM4COLQFE3IUWBCQ5ZYUIAUCBJAZVEMMOVTNBOAC USPPNUMNL5HU5WEOIWJMIFAX6TBZERVAV67XJUJQ6KSNLG55JAGQC TOBGHRPKEPSXDN56WGSZNWOMCBVJ4KUSLWYWI56MC2RR3MM3KLZAC UTHNLH3J3VG7BBJPOKGE6DY7Z2QHDLY72TR2VMEDQYP73SIWZGKAC bool get_group_checkpoint_flag(const int gi) {int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);char buf[100];int iret = Util_TableGetString(tags, sizeof buf, buf, "checkpoint");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {return true;} else if (iret >= 0) {string str(buf);for (auto &c : str)c = tolower(c);if (str == "yes")return true;if (str == "no")return false;assert(0);} else {assert(0);}}bool get_group_restrict_flag(const int gi) {int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);char buf[100];int iret = Util_TableGetString(tags, sizeof buf, buf, "restrict");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {return true;} else if (iret >= 0) {string str(buf);for (auto &c : str)c = tolower(c);if (str == "yes")return true;if (str == "no")return false;assert(0);} else {assert(0);}}
array<int, dim> get_group_indextype(const int gi) {assert(gi >= 0);const int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);array<CCTK_INT, dim> index;int iret = Util_TableGetIntArray(tags, dim, index.data(), "index");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {index = {1, 1, 1}; // default: cell-centred} else if (iret >= 0) {assert(iret == dim);} else {assert(0);}array<int, dim> indextype;for (int d = 0; d < dim; ++d)indextype[d] = index[d];return indextype;}array<int, dim> get_group_fluxes(const int gi) {assert(gi >= 0);const int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);vector<char> fluxes_buf(1000);const int iret =Util_TableGetString(tags, fluxes_buf.size(), fluxes_buf.data(), "fluxes");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {fluxes_buf[0] = '\0'; // default: empty (no fluxes)} else if (iret >= 0) {// do nothing} else {assert(0);}const string str(fluxes_buf.data());vector<string> strs;size_t end = 0;while (end < str.size()) {size_t begin = str.find_first_not_of(' ', end);if (begin == string::npos)break;end = str.find(' ', begin);strs.push_back(str.substr(begin, end - begin));}array<int, dim> fluxes;fluxes.fill(-1);if (strs.empty())return fluxes; // No fluxes specifiedassert(strs.size() == dim); // Check number of fluxesfor (int d = 0; d < dim; ++d) {auto str1 = strs[d];if (str1.find(':') == string::npos) {const char *impl = CCTK_GroupImplementationI(gi);str1 = string(impl) + "::" + str1;}int gi1 = CCTK_GroupIndex(str1.c_str());assert(gi1 >= 0); // Check fluxes are valid groupsfluxes[d] = gi1;}for (int d = 0; d < dim; ++d)for (int d1 = d + 1; d1 < dim; ++d1)assert(fluxes[d] != fluxes[d1]); // Check groups are all differentreturn fluxes;}array<int, dim> get_group_nghostzones(const int gi) {DECLARE_CCTK_PARAMETERS;assert(gi >= 0);const int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);array<CCTK_INT, dim> nghostzones;int iret =Util_TableGetIntArray(tags, dim, nghostzones.data(), "nghostzones");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {// default: use driver parameternghostzones = {ghost_size, ghost_size, ghost_size};} else if (iret >= 0) {assert(iret == dim);} else {assert(0);}return nghostzones;}////////////////////////////////////////////////////////////////////////////////
}}array<int, dim> get_group_indextype(const int gi) {assert(gi >= 0);const int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);array<CCTK_INT, dim> index;int iret = Util_TableGetIntArray(tags, dim, index.data(), "index");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {index = {1, 1, 1}; // default: cell-centred} else if (iret >= 0) {assert(iret == dim);} else {assert(0);
array<int, dim> get_group_fluxes(const int gi) {assert(gi >= 0);const int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);vector<char> fluxes_buf(1000);const int iret =Util_TableGetString(tags, fluxes_buf.size(), fluxes_buf.data(), "fluxes");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {fluxes_buf[0] = '\0'; // default: empty (no fluxes)} else if (iret >= 0) {// do nothing} else {assert(0);}const string str(fluxes_buf.data());vector<string> strs;size_t end = 0;while (end < str.size()) {size_t begin = str.find_first_not_of(' ', end);if (begin == string::npos)break;end = str.find(' ', begin);strs.push_back(str.substr(begin, end - begin));}array<int, dim> fluxes;fluxes.fill(-1);if (strs.empty())return fluxes; // No fluxes specifiedassert(strs.size() == dim); // Check number of fluxesfor (int d = 0; d < dim; ++d) {auto str1 = strs[d];if (str1.find(':') == string::npos) {const char *impl = CCTK_GroupImplementationI(gi);str1 = string(impl) + "::" + str1;}int gi1 = CCTK_GroupIndex(str1.c_str());assert(gi1 >= 0); // Check fluxes are valid groupsfluxes[d] = gi1;}for (int d = 0; d < dim; ++d)for (int d1 = d + 1; d1 < dim; ++d1)assert(fluxes[d] != fluxes[d1]); // Check groups are all differentreturn fluxes;}array<int, dim> get_group_nghostzones(const int gi) {
void SetupLevel(int level, const BoxArray &ba, const DistributionMapping &dm,const function<string()> &why) {
assert(gi >= 0);const int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);array<CCTK_INT, dim> nghostzones;int iret =Util_TableGetIntArray(tags, dim, nghostzones.data(), "nghostzones");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {// default: use driver parameternghostzones = {ghost_size, ghost_size, ghost_size};} else if (iret >= 0) {assert(iret == dim);} else {assert(0);}return nghostzones;}void SetupLevel(int level, const BoxArray &ba, const DistributionMapping &dm) {DECLARE_CCTK_PARAMETERS;
// If there is more than one time level, then we don't prolongate// the oldest.int ntls = groupdata.mfab.size();int prolongate_tl = ntls > 1 ? ntls - 1 : ntls;
const int ntls = groupdata.mfab.size();// We only prolongate the state vector. And if there is more than// one time level, then we don't prolongate the oldest.const int prolongate_tl =groupdata.do_checkpoint ? (ntls > 1 ? ntls - 1 : ntls) : 0;
groupdata.valid.at(tl).at(vi).set(valid_t(false), [] { return "MakeNewLevelFromCoarse"; });}for (int tl = 0; tl < prolongate_tl; ++tl) {// Only interpolate if coarse grid data are validbool all_invalid = true;for (int vi = 0; vi < groupdata.numvars; ++vi)all_invalid &= !coarsegroupdata.valid.at(tl).at(vi).get().valid_any();if (all_invalid) {for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).set(valid_t(false), [] {return "MakeNewLevelFromCoarse: coarse grid is invalid";});} else {
groupdata.valid.at(tl).at(vi).set(valid_t(false), [] {return "MakeNewLevelFromCoarse: not prolongated because variable is ""not evolved";});if (tl < prolongate_tl) {
const BoxArray &gba = convert(ba,IndexType(groupdata.indextype[0] ? IndexType::CELL : IndexType::NODE,groupdata.indextype[1] ? IndexType::CELL : IndexType::NODE,groupdata.indextype[2] ? IndexType::CELL : IndexType::NODE));// If there is more than one time level, then we don't// prolongate the oldest.int ntls = groupdata.mfab.size();int prolongate_tl = ntls > 1 ? ntls - 1 : ntls;// This must not happenassert(leveldata.level > 0);// Copy from same level and/or prolongate from next coarser levelauto &coarseleveldata = ghext->leveldata.at(level - 1);
const BoxArray &gba = convert(ba,IndexType(groupdata.indextype[0] ? IndexType::CELL : IndexType::NODE,groupdata.indextype[1] ? IndexType::CELL : IndexType::NODE,groupdata.indextype[2] ? IndexType::CELL : IndexType::NODE));const int ntls = groupdata.mfab.size();// We only prolongate the state vector. And if there is more than// one time level, then we don't prolongate the oldest.const int prolongate_tl =groupdata.do_checkpoint ? (ntls > 1 ? ntls - 1 : ntls) : 0;
// Only interpolate if coarse grid data are validbool all_invalid = true;for (int vi = 0; vi < groupdata.numvars; ++vi)all_invalid &=!coarsegroupdata.valid.at(tl).at(vi).get().valid_any() &&!groupdata.valid.at(tl).at(vi).get().valid_any();if (all_invalid) {// do nothing} else {for (int vi = 0; vi < groupdata.numvars; ++vi) {error_if_invalid(coarseleveldata, coarsegroupdata, vi, tl,make_valid_all(),[] { return "RemakeLevel before prolongation"; });error_if_invalid(leveldata, groupdata, vi, tl, make_valid_all(),[] { return "RemakeLevel before prolongation"; });check_valid(coarseleveldata, coarsegroupdata, vi, tl,[] { return "RemakeLevel before prolongation"; });// We cannot call this function since it would try to// traverse the old grid function with the new grid// structure.// TODO: Use explicit loop instead (see above)// check_valid(leveldata, groupdata, vi, tl);}
for (int vi = 0; vi < groupdata.numvars; ++vi) {error_if_invalid(coarseleveldata, coarsegroupdata, vi, tl,make_valid_all(),[] { return "RemakeLevel before prolongation"; });error_if_invalid(leveldata, groupdata, vi, tl, make_valid_all(),[] { return "RemakeLevel before prolongation"; });check_valid(coarseleveldata, coarsegroupdata, vi, tl,[] { return "RemakeLevel before prolongation"; });// We cannot call this function since it would try to// traverse the old grid function with the new grid// structure.// TODO: Use explicit loop instead (see above)// check_valid(leveldata, groupdata, vi, tl);}
FillPatchTwoLevels(*mfab, 0.0, {&*coarsegroupdata.mfab.at(tl)}, {0.0},{&*groupdata.mfab.at(tl)}, {0.0}, 0, 0,groupdata.numvars, ghext->amrcore->Geom(level - 1),ghext->amrcore->Geom(level), cphysbc, 0, fphysbc,0, reffact, interpolator, bcs, 0);
// Copy from same level and/or prolongate from next coarser levelFillPatchTwoLevels(*mfab, 0.0, {&*coarsegroupdata.mfab.at(tl)}, {0.0},{&*groupdata.mfab.at(tl)}, {0.0}, 0, 0,groupdata.numvars, ghext->amrcore->Geom(level - 1),ghext->amrcore->Geom(level), cphysbc, 0, fphysbc, 0,reffact, interpolator, bcs, 0);
for (int vi = 0; vi < groupdata.numvars; ++vi)valid.at(vi) = why_valid_t(make_valid_int(), [] {return "RemakeLevel after prolongation";});}
for (int vi = 0; vi < groupdata.numvars; ++vi)valid.at(vi) = why_valid_t(make_valid_int(), [] {return "RemakeLevel after prolongation";});
// Should we really do this? Cactus's extension handling mechanism// becomes inconsistent once extensions have been unregistered.int iret = CCTK_UnregisterGHExtension("CarpetX");assert(iret == 0);
if (false) {// Should we really do this? Cactus's extension handling mechanism// becomes inconsistent once extensions have been unregistered.int iret = CCTK_UnregisterGHExtension("CarpetX");assert(iret == 0);}
}namespace {bool get_group_checkpoint_flag(const int gi) {int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);char buf[100];int iret = Util_TableGetString(tags, sizeof buf, buf, "checkpoint");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {return true;} else if (iret >= 0) {string str(buf);for (auto &c : str)c = tolower(c);if (str == "yes")return true;if (str == "no")return false;assert(0);} else {assert(0);}
assert(current_level == -1);for (auto &restrict leveldata : ghext->leveldata) {const int num_groups = CCTK_NumGroups();for (int gi = 0; gi < num_groups; ++gi) {cGroup group;int ierr = CCTK_GroupData(gi, &group);assert(!ierr);
const int num_groups = CCTK_NumGroups();for (int gi = 0; gi < num_groups; ++gi) {cGroup group;int ierr = CCTK_GroupData(gi, &group);assert(!ierr);
auto &restrict groupdata = *leveldata.groupdata.at(gi);const bool checkpoint = get_group_checkpoint_flag(groupdata.groupindex);if (!checkpoint) {// Invalidate all time levelsconst int ntls = groupdata.mfab.size();for (int tl = 0; tl < ntls; ++tl) {for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).set(valid_t(), [] {return "InvalidateTimelevels (invalidate all ""non-checkpointed variables)";});poison_invalid(leveldata, groupdata, vi, tl);
assert(current_level == -1);for (auto &restrict leveldata : ghext->leveldata) {auto &restrict groupdata = *leveldata.groupdata.at(gi);if (!groupdata.do_checkpoint) {// Invalidate all time levelsconst int ntls = groupdata.mfab.size();for (int tl = 0; tl < ntls; ++tl) {for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).set(valid_t(), [] {return "InvalidateTimelevels (invalidate all ""non-checkpointed variables)";});poison_invalid(leveldata, groupdata, vi, tl);}
assert(current_level == -1);for (auto &restrict leveldata : ghext->leveldata) {const int num_groups = CCTK_NumGroups();for (int gi = 0; gi < num_groups; ++gi) {cGroup group;int ierr = CCTK_GroupData(gi, &group);assert(!ierr);
const int num_groups = CCTK_NumGroups();for (int gi = 0; gi < num_groups; ++gi) {cGroup group;int ierr = CCTK_GroupData(gi, &group);assert(!ierr);
auto &restrict groupdata = *leveldata.groupdata.at(gi);const int ntls = groupdata.mfab.size();// Rotate time levels and invalidate current time levelif (ntls > 1) {rotate(groupdata.mfab.begin(), groupdata.mfab.end() - 1,groupdata.mfab.end());rotate(groupdata.valid.begin(), groupdata.valid.end() - 1,groupdata.valid.end());for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(0).at(vi).set(valid_t(), [] {return "CycletimeLevels (invalidate current time level)";});for (int vi = 0; vi < groupdata.numvars; ++vi)poison_invalid(leveldata, groupdata, vi, 0);
assert(current_level == -1);for (auto &restrict leveldata : ghext->leveldata) {auto &restrict groupdata = *leveldata.groupdata.at(gi);const int ntls = groupdata.mfab.size();// Rotate time levels and invalidate current time levelif (ntls > 1) {rotate(groupdata.mfab.begin(), groupdata.mfab.end() - 1,groupdata.mfab.end());rotate(groupdata.valid.begin(), groupdata.valid.end() - 1,groupdata.valid.end());for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(0).at(vi).set(valid_t(), [] {return "CycletimeLevels (invalidate current time level)";});poison_invalid(leveldata, groupdata, vi, 0);}}for (int tl = 0; tl < ntls; ++tl)for (int vi = 0; vi < groupdata.numvars; ++vi)check_valid(leveldata, groupdata, vi, tl,[&]() { return "CycleTimelevels"; });
// Only prolongate valid grid functionsbool all_invalid = true;for (int vi = 0; vi < groupdata.numvars; ++vi)all_invalid &=!coarsegroupdata.valid.at(tl).at(vi).get().valid_any() &&!groupdata.valid.at(tl).at(vi).get().valid_int;
// // Only prolongate valid grid functions// bool all_invalid = true;// for (int vi = 0; vi < groupdata.numvars; ++vi)// all_invalid &=// !coarsegroupdata.valid.at(tl).at(vi).get().valid_any() &&// !groupdata.valid.at(tl).at(vi).get().valid_int;// if (all_invalid) {
if (all_invalid) {
// for (int vi = 0; vi < groupdata.numvars; ++vi)// groupdata.valid.at(tl).at(vi).set(valid_t(), [] {// return "SyncGroupsByDirI skipping prolongation: Mark as "// "invalid because neither coarse grid nor fine grid "// "interior are valid";// });
} else {
for (int vi = 0; vi < groupdata.numvars; ++vi) {error_if_invalid(coarseleveldata, coarsegroupdata, vi, tl,make_valid_all(), [] {return "SyncGroupsByDirI on coarse level ""before prolongation";});error_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(), [] {return "SyncGroupsByDirI on fine level before prolongation";});poison_invalid(leveldata, groupdata, vi, tl);check_valid(coarseleveldata, coarsegroupdata, vi, tl, [] {return "SyncGroupsByDirI on coarse level before prolongation";});check_valid(leveldata, groupdata, vi, tl, [] {return "SyncGroupsByDirI on fine level before prolongation";});groupdata.valid.at(tl).at(vi).set_ghosts(false, [] {return "SyncGroupsByDirI before prolongation: Mark ghosts as ""invalid";});}FillPatchTwoLevels(*groupdata.mfab.at(tl), 0.0, {&*coarsegroupdata.mfab.at(tl)},{0.0}, {&*groupdata.mfab.at(tl)}, {0.0}, 0, 0, groupdata.numvars,ghext->amrcore->Geom(level - 1), ghext->amrcore->Geom(level),cphysbc, 0, fphysbc, 0, reffact, interpolator, bcs, 0);for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).set_ghosts(true, [] { return "SyncGroupsByDirI after prolongation"; });}} // if not all_invalid} // for tl
for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).set_ghosts(false, [] {return "SyncGroupsByDirI before prolongation: Mark ghosts as ""invalid";});poison_invalid(leveldata, groupdata, vi, tl);error_if_invalid(coarseleveldata, coarsegroupdata, vi, tl,make_valid_all(), [] {return "SyncGroupsByDirI on coarse level ""before prolongation";});error_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(), [] {return "SyncGroupsByDirI on fine level before prolongation";});check_valid(coarseleveldata, coarsegroupdata, vi, tl, [] {return "SyncGroupsByDirI on coarse level before prolongation";});check_valid(leveldata, groupdata, vi, tl, [] {return "SyncGroupsByDirI on fine level before prolongation";});}FillPatchTwoLevels(*groupdata.mfab.at(tl), 0.0, {&*coarsegroupdata.mfab.at(tl)},{0.0}, {&*groupdata.mfab.at(tl)}, {0.0}, 0, 0,groupdata.numvars, ghext->amrcore->Geom(level - 1),ghext->amrcore->Geom(level), cphysbc, 0, fphysbc, 0, reffact,interpolator, bcs, 0);for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).set_ghosts(true, [] { return "SyncGroupsByDirI after prolongation"; });} // if not all_invalid} // for tl}
// }
error_if_invalid(fineleveldata, finegroupdata, vi, tl, make_valid_int(),[] { return "Reflux: Fine level data"; });error_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(),[] { return "Reflux: Coarse level data"; });
error_if_invalid(fineleveldata, finegroupdata, vi, tl, make_valid_int(),[] { return "Reflux before refluxing: Fine level data"; });error_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(), [] {return "Reflux before refluxing: Coarse level data";});
namespace {bool get_group_restrict_flag(const int gi) {int tags = CCTK_GroupTagsTableI(gi);assert(tags >= 0);char buf[100];int iret = Util_TableGetString(tags, sizeof buf, buf, "restrict");if (iret == UTIL_ERROR_TABLE_NO_SUCH_KEY) {return true;} else if (iret >= 0) {string str(buf);for (auto &c : str)c = tolower(c);if (str == "yes")return true;if (str == "no")return false;assert(0);} else {assert(0);}}} // namespace
auto &groupdata = *leveldata.groupdata.at(gi);const auto &finegroupdata = *fineleveldata.groupdata.at(gi);// If there is more than one time level, then we don't restrict the// oldest.
// If there is more than one time level, then we don't restrict the oldest.
// Only restrict valid grid functions. Restriction only uses the// interior.bool all_invalid = true;for (int vi = 0; vi < groupdata.numvars; ++vi)all_invalid &= !finegroupdata.valid.at(tl).at(vi).get().valid_int &&!groupdata.valid.at(tl).at(vi).get().valid_int;if (all_invalid) {for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).set_and(make_valid_int(), [] {return "Restrict on fine level skipping restricting (both fine and ""coarse level data are invalid)";});}
for (int vi = 0; vi < groupdata.numvars; ++vi) {
} else {for (int vi = 0; vi < groupdata.numvars; ++vi) {
// Restriction only uses the interiorerror_if_invalid(fineleveldata, finegroupdata, vi, tl, make_valid_int(),[] { return "Restrict on fine level before restricting"; });poison_invalid(fineleveldata, finegroupdata, vi, tl);check_valid(fineleveldata, finegroupdata, vi, tl,[] { return "Restrict on fine level before restricting"; });error_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(), [] {return "Restrict on coarse level before restricting";});poison_invalid(leveldata, groupdata, vi, tl);check_valid(leveldata, groupdata, vi, tl, [] {return "Restrict on coarse level before restricting";});}
error_if_invalid(fineleveldata, finegroupdata, vi, tl, make_valid_int(),[] { return "Restrict on fine level before restricting"; });poison_invalid(fineleveldata, finegroupdata, vi, tl);check_valid(fineleveldata, finegroupdata, vi, tl, [] {return "Restrict on fine level before restricting";});error_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(), [] {return "Restrict on coarse level before restricting";});poison_invalid(leveldata, groupdata, vi, tl);check_valid(leveldata, groupdata, vi, tl, [] {return "Restrict on coarse level before restricting";});}
// rank: 0: vertex, 1: edge, 2: face, 3: volumeint rank = 0;for (int d = 0; d < dim; ++d)rank += groupdata.indextype[d];switch (rank) {case 0:average_down_nodal(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl),reffact);break;case 1:average_down_edges(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl),reffact);break;case 2:average_down_faces(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl),reffact);break;case 3:average_down(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl), 0,groupdata.numvars, reffact);break;default:assert(0);}for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).set(make_valid_int(),[] { return "Restrict"; });
// rank: 0: vertex, 1: edge, 2: face, 3: volumeint rank = 0;for (int d = 0; d < dim; ++d)rank += groupdata.indextype[d];switch (rank) {case 0:average_down_nodal(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl),reffact);break;case 1:average_down_edges(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl),reffact);break;case 2:average_down_faces(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl),reffact);break;case 3:average_down(*finegroupdata.mfab.at(tl), *groupdata.mfab.at(tl), 0,groupdata.numvars, reffact);break;default:assert(0);