JN2TPHENEBIY2OE5FRCQ2E6QCL6FPVHJHUCP4UODD6DITRVV2LIQC PITNVXYKFCIZYOBCVUINO7RXD6P66MZKUPCCH5OOEEWVCQM7DPEQC FYLM4H3VFAC5MR4QQH5Q4LQKVEIIMVAE65BSGS6A7EP6CG47RXFQC I4P6OKQG6OD3JX2KV23QLKMG7DSNYMTYUZCIOKNPTHOFHOFLMSNAC ME3INBPCOPZGNA5M5A2FOBA4WOMD7F2UFHVVOQCSMDEN7RLDXUKQC DBWFFDGEHJEA5KWYP56DRILSXCAPB72DY7AGY75QFJ2UJ7ITJ2QQC LHPZHX4FMRYBM7NI22QTP3VZDBYFRSNTY3L6BEEFPPF5KWCFFIHQC YDBJPTC5P4FG5CQ7QAGDNXVPX4BNR3LFG4TEORB7UJ7UGDS6CNGQC BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC 722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC 2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC NZTFEMGJPN53J34S3MVUCL7TTRB4UG7JQM2R563OAHIRM4QPZOWAC M5R6KQLXLGYSVKHVAX5AJKD6NYE6IM5Z6WVTR3BTKPJDNNKF3ARAC UEZKNPXXK5WU6B5LYRKGGYGBZ6T6TAZI26CWTJFUBUW2SJJOMV2AC BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC GQVQJCNQNO2KD7ZMC7RESCUAMUAP7OED6CTA6SYLZKQGXKXZ6T3QC 33IC3UHCEPZLGS5ACS2JXHGT6CRU5LXU6PM6RDHCERPOIELVRVXQC T3TZRPPAIA24I3YL3JFB4XEAYCWU3HJAJUCF7NNIFMP4I5X4SM5QC MF53IYPRC7HEG2LRV347PTVBWENVKHMUYN6FIAEVTTVPIXH4FMGQC WTDXZR735D7JBS4XVLTEXBVFMLSRLZUHZNVHH7ZWVGFGATD6DFNAC BSMJ4V7GV3EOGY4KCSTOJQUOFE2OOCIKQETE4WC2WRNLWBQIBW3QC A7ETPFXEHA2RM4LINSBVMJJ3G62NF7Q5ZQOKJPNJK3YOQ5WS5HKAC PG2P3JQPLWZRLCAJ7JY2B7G7AM5DHOE2CJUKIPWREI3NAUKZF3TAC R6B5YHARRV34JO6W4GAWBOQ4BW5H6VEKXWMVKJKPWC7MUO4ZYZVQC VIK5E6DBUCP5HGDVHDP6SWTHH7ODEUIGKOGSXR7VLVK46LDD4W6QC E3MBKFT4GEFDAGZQQW4OROY5F6FWC46G6MRH54GDYTGO7O5YSRIAC MSBBCXVGD3GRLE5KAI6BKAFRV7SQUWI2SNN43AJAUD3ISRCEXY6QC 24A4OZBZBQ6QXIQ3EOOCQIBTOWRA32TMSQ4CCL3LKIJVJPKZFHVQC KN5Z747NMDBSXQHVGLLYQKCOW5423HDAYDCMIR6RTZZMICMCPN3AC DGEGTDYVGRHEGNFDHCCVTD6AVLRJ2XHDXQPWR5MMR62V5NU2XGIQC JHHVFKSN2L3YMG4JKXUDS6EBBYCDUDO56LNAZMG4QYS2FFPZF3SQC VAF66DTVLDWNG7N2PEQYEH4OH5SPSMFBXKPR2PU67IIM6CVPCJ7AC FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC EHF2P5PKVTMAUL5R5QSZ3DS3VLE7Z6SHJTCZAGRBTQ66Y7HZKNYQC IV3MLV677VWS7GLESBQZ4HRFNW5TBFBIGIBWXTCHAER3FQ7VG3GQC USPPNUMNL5HU5WEOIWJMIFAX6TBZERVAV67XJUJQ6KSNLG55JAGQC 3ROBI6IPLFHSSNMGTZHYWIPCO342OKQLXHNWFJ3KMNQRNYMAMLKAC UZAKARMGORRQG733ZUPJOEGL5FG243I32NCC2SRSFDCZKUQ5A52QC UUGQGVC4WEKN64WAP7F5QPS2UHGQB5ZLMFRIYNWKMIEBDO3QRX4AC WASO7G5FJXRXWNH2U2FLUNEKU6VE63OI3HUYP64BVD4LMD6KE7OQC W4XMGPEHBCV6AAPJBI4SSEMCDB6KKCGRUC2X2F5YLBY22OR3ICPAC X7A7HYGU2NPWCZCG5SYFD4NINYDP6UYWFFE3WP6YNLSDIABG2KJAC RFUF3QUEOYDFA5H5BZJP7HVQ5LMCWCIO7MV32RQBDMVDULGQGO5QC GCJJ35BFUTRWJGWOVVMYNOSXEELH6YYX7FW4XL6QWPUD63TAL5NQC NUNYA5E7NMMUTVAQKVO34GUQI3U2TJTCEIZZT3PAPZ3ZU5LB44BQC UTHNLH3J3VG7BBJPOKGE6DY7Z2QHDLY72TR2VMEDQYP73SIWZGKAC TUDUMVD5MTJJJGVYVOCALOOKOUYNB7LOFJRCYCZDVGN536JAO2OQC groupdata.valid.at(tl) = vector<valid_t>(groupdata.numvars);groupdata.why_valid.at(tl) =vector<why_valid_t>(groupdata.numvars, {"SetupLevel"});for (int vi = 0; vi < groupdata.numvars; ++vi)
groupdata.valid.at(tl).resize(groupdata.numvars);for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).set(valid_t(false),[] { return "SetupLevel"; });
groupdata.valid.at(tl) = vector<valid_t>(groupdata.numvars);groupdata.why_valid.at(tl) =vector<why_valid_t>(groupdata.numvars, {"MakeNewLevelFromCoarse"});
groupdata.valid.at(tl).resize(groupdata.numvars);for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).set(valid_t(false), [] { return "MakeNewLevelFromCoarse"; });
for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi) = valid_t(false);groupdata.why_valid.at(tl).at(vi) = {"MakeNewLevelFromCoarse: coarse grid is 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";});
// Expext coarse grid data to be validfor (int vi = 0; vi < groupdata.numvars; ++vi) {if (!coarsegroupdata.valid.at(tl).at(vi).valid_all()) {valid_t all_valid(true);CCTK_VERROR("MakeNewLevelFromCoarse before prolongation: Grid ""function \"%s\" is invalid on refinement level %d, ""time level %d; expected valid %s, found valid %s",CCTK_FullVarName(coarsegroupdata.firstvarindex + vi),coarseleveldata.level, tl, string(all_valid).c_str(),string(coarsegroupdata.valid.at(tl).at(vi)).c_str());}}
// Expect coarse grid data to be valid
check_valid(coarseleveldata, coarsegroupdata, vi, tl, [&]() {
error_if_invalid(coarseleveldata, coarsegroupdata, vi, tl, make_valid_all(),[] { return "MakeNewLevelFromCoarse before prolongation"; });check_valid(coarseleveldata, coarsegroupdata, vi, tl, [] {
auto &valid = groupdata.valid.at(tl).at(vi);valid.valid_int = coarsegroupdata.valid.at(tl).at(vi).valid_all();valid.valid_outer = false;valid.valid_ghosts = false;groupdata.why_valid.at(tl).at(vi) = {"MakeNewLevelFromCoarse: prolongated"};
groupdata.valid.at(tl).at(vi).set(make_valid_int(), [] {return "MakeNewLevelFromCoarse after prolongation";});
auto valid = vector<valid_t>(groupdata.numvars);auto why_valid = vector<why_valid_t>(groupdata.numvars, {"RemakeLevel"});
auto valid = vector<why_valid_t>(groupdata.numvars, why_valid_t([] { return "RemakeLevel"; }));
const bool cond = coarsegroupdata.valid.at(tl).at(vi).valid_all() &&groupdata.valid.at(tl).at(vi).valid_all();if (!cond)CCTK_VERROR("Found invalid input data: RemakeLevel level %d, ""variable %s%s: need everything defined, have coarse ""%s (%s), have current %s (%s)",leveldata.level,CCTK_FullVarName(groupdata.firstvarindex + vi),string("_p", tl).c_str(),string(coarsegroupdata.valid.at(tl).at(vi)).c_str(),string(coarsegroupdata.why_valid.at(tl).at(vi)).c_str(),string(groupdata.valid.at(tl).at(vi)).c_str(),string(groupdata.why_valid.at(tl).at(vi)).c_str());
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"; });
for (int vi = 0; vi < groupdata.numvars; ++vi) {valid.at(vi).valid_int =coarsegroupdata.valid.at(tl).at(vi).valid_all() &&groupdata.valid.at(tl).at(vi).valid_all();valid.at(vi).valid_outer = false;valid.at(vi).valid_ghosts = false;why_valid.at(vi) = {"RemakeLevel: copied and prolongated"};}
for (int vi = 0; vi < groupdata.numvars; ++vi)valid.at(vi) = why_valid_t(make_valid_int(), [] {return "RemakeLevel after prolongation";});
struct why_valid_t {string why_int, why_outer, why_ghosts;why_valid_t() : why_valid_t("<unknown reason>") {}why_valid_t(const string &why): why_int(why), why_outer(why), why_ghosts(why) {}
inline constexpr valid_t make_valid_int() {valid_t valid;valid.valid_int = true;return valid;}inline constexpr valid_t make_valid_outer() {valid_t valid;valid.valid_outer = true;return valid;}inline constexpr valid_t make_valid_ghosts() {valid_t valid;valid.valid_ghosts = true;return valid;}inline constexpr valid_t make_valid_all() { return ~valid_t(); }
friend ostream &operator<<(ostream &os, const why_valid_t why) {return os << "why_valid_t{int:" << why.why_int << ","<< "outer:" << why.why_outer << ","<< "ghosts:" << why.why_ghosts << "}";}operator string() const {ostringstream buf;buf << *this;return buf.str();}};
class why_valid_t {valid_t valid;function<string()> why_int, why_outer, why_ghosts;public:why_valid_t() : why_valid_t([] { return "<unknown reason>"; }) {}why_valid_t(const function<string()> &why) : why_valid_t(false, why) {}why_valid_t(bool b, const function<string()> &why): why_valid_t(valid_t(b), why) {}why_valid_t(const valid_t &val, const function<string()> &why): valid(val), why_int(why), why_outer(why), why_ghosts(why) {}const valid_t &get() const { return valid; }void set(const valid_t &val, const function<string()> &why) {auto old_valid = valid;valid = val;auto new_valid = valid;if (new_valid.valid_int != old_valid.valid_int)why_int = why;if (new_valid.valid_outer != old_valid.valid_outer)why_outer = why;if (new_valid.valid_ghosts != old_valid.valid_ghosts)why_ghosts = why;}void set_int(bool b, const function<string()> &why) {auto val = valid;val.valid_int = b;set(val, why);}void set_outer(bool b, const function<string()> &why) {auto val = valid;val.valid_outer = b;set(val, why);}void set_ghosts(bool b, const function<string()> &why) {auto val = valid;val.valid_ghosts = b;set(val, why);}void set_and(const valid_t &val, const function<string()> &why) {set(valid & val, why);}void set_or(const valid_t &val, const function<string()> &why) {set(valid | val, why);}friend ostream &operator<<(ostream &os, const why_valid_t why) {return os << why.valid << ","<< "why{int:" << why.why_int() << ","<< "outer:" << why.why_outer() << ","<< "ghosts:" << why.why_ghosts() << "}";}operator string() const {ostringstream buf;buf << *this;return buf.str();}};
if (!groupdata.valid.at(tl).at(vi).valid_int)CCTK_VWARN(CCTK_WARN_ALERT,"Variable %s has invalid data in the interior of level %d",CCTK_FullVarName(groupdata.firstvarindex + vi),leveldata.level);
warn_if_invalid(leveldata, groupdata, vi, tl, make_valid_int(),[] { return "Before reduction"; });
// Ensure grid functions are validvoid error_if_invalid(const GHExt::LevelData &leveldata,const GHExt::CommonGroupData &groupdata, int vi, int tl,const valid_t &required, const function<string()> &msg) {const valid_t &have = groupdata.valid.at(tl).at(vi).get();if (CCTK_BUILTIN_EXPECT((required & ~have).valid_any(), false))CCTK_VERROR("%s: Grid function \"%s\" is invalid on refinement level %d, time ""level %d; required %s, found %s",msg().c_str(), CCTK_FullVarName(groupdata.firstvarindex + vi),leveldata.level, tl, string(required).c_str(),string(groupdata.valid.at(tl).at(vi)).c_str());}void warn_if_invalid(const GHExt::LevelData &leveldata,const GHExt::CommonGroupData &groupdata, int vi, int tl,const valid_t &required, const function<string()> &msg) {const valid_t &have = groupdata.valid.at(tl).at(vi).get();if (CCTK_BUILTIN_EXPECT((required & ~have).valid_any(), false))CCTK_VWARN(CCTK_WARN_ALERT,"%s: Grid function \"%s\" is invalid on refinement level %d, time ""level %d; required %s, found %s",msg().c_str(), CCTK_FullVarName(groupdata.firstvarindex + vi),leveldata.level, tl, string(required).c_str(),string(groupdata.valid.at(tl).at(vi)).c_str());}
leveldata.level, tl, string(valid).c_str());
leveldata.level, tl, string(groupdata.valid.at(tl).at(vi)).c_str());}// Ensure grid functions are validvoid error_if_invalid(const GHExt::CommonGroupData &groupdata, int vi, int tl,const valid_t &required, const function<string()> &msg) {const valid_t &have = groupdata.valid.at(tl).at(vi).get();if (CCTK_BUILTIN_EXPECT((required & ~have).valid_any(), false))CCTK_VERROR("%s: Grid function \"%s\" is invalid on time level %d; ""required %s, found %s",msg().c_str(), CCTK_FullVarName(groupdata.firstvarindex + vi),tl, string(required).c_str(),string(groupdata.valid.at(tl).at(vi)).c_str());}void warn_if_invalid(const GHExt::CommonGroupData &groupdata, int vi, int tl,const valid_t &required, const function<string()> &msg) {const valid_t &have = groupdata.valid.at(tl).at(vi).get();if (CCTK_BUILTIN_EXPECT((required & ~have).valid_any(), false))CCTK_VWARN(CCTK_WARN_ALERT,"%s: Grid function \"%s\" is invalid on time level %d; ""required %s, found %s",msg().c_str(), CCTK_FullVarName(groupdata.firstvarindex + vi),tl, string(required).c_str(),string(groupdata.valid.at(tl).at(vi)).c_str());
const valid_t &have = groupdata.valid.at(rd.tl).at(rd.vi);// "x <= y" for booleans means "x implies y"const bool cond = need.valid_int <= have.valid_int &&need.valid_outer <= have.valid_outer &&need.valid_ghosts <= have.valid_ghosts;if (!cond)CCTK_VERROR("Found invalid input data: iteration %d %s: %s::%s, ""level %d, ""variable %s%s: need %s, have %s",cctkGH->cctk_iteration, attribute->where,attribute->thorn, attribute->routine, leveldata.level,CCTK_FullVarName(groupdata.firstvarindex + rd.vi),string("_p", rd.tl).c_str(), string(need).c_str(),string(have).c_str());check_valid(leveldata, groupdata, rd.vi, rd.tl, [&]() {
error_if_invalid(leveldata, groupdata, rd.vi, rd.tl, need, [&] {ostringstream buf;buf << "CallFunction iteration " << cctkGH->cctk_iteration << " "<< attribute->where << ": " << attribute->thorn<< "::" << attribute->routine << " checking input";return buf.str();});check_valid(leveldata, groupdata, rd.vi, rd.tl, [&] {
const valid_t &have = scalargroupdata.valid.at(rd.tl).at(rd.vi);// "x <= y" for booleans means "x implies y"const bool cond = need.valid_int <= have.valid_int &&need.valid_outer <= have.valid_outer &&need.valid_ghosts <= have.valid_ghosts;if (!cond)CCTK_VERROR("Found invalid input data: iteration %d %s: %s::%s, ""variable %s%s: need %s, have %s",cctkGH->cctk_iteration, attribute->where,attribute->thorn, attribute->routine,CCTK_FullVarName(scalargroupdata.firstvarindex + rd.vi),string("_p", rd.tl).c_str(), string(need).c_str(),string(have).c_str());check_valid(scalargroupdata, rd.vi, rd.tl, [&]() {
error_if_invalid(scalargroupdata, rd.vi, rd.tl, need, [&] {ostringstream buf;buf << "CallFunction iteration " << cctkGH->cctk_iteration << " "<< attribute->where << ": " << attribute->thorn<< "::" << attribute->routine << " checking input";return buf.str();});check_valid(scalargroupdata, rd.vi, rd.tl, [&] {
valid_t &have = groupdata.valid.at(wr.tl).at(wr.vi);have.valid_int &= need.valid_int || !provided.valid_int;have.valid_outer &= need.valid_outer || !provided.valid_outer;have.valid_ghosts &= need.valid_ghosts || !provided.valid_ghosts;
groupdata.valid.at(wr.tl).at(wr.vi).set_and(need | ~provided,[iteration = cctkGH->cctk_iteration, where = attribute->where,thorn = attribute->thorn, routine = attribute->routine] {ostringstream buf;buf << "CallFunction iteration " << iteration << " " << where<< ": " << thorn << "::" << routine<< ": Poison output variables that are not input variables";return buf.str();});
valid_t &have = scalargroupdata.valid.at(wr.tl).at(wr.vi);have.valid_int &= need.valid_int || !provided.valid_int;have.valid_outer &= need.valid_outer || !provided.valid_outer;have.valid_ghosts &= need.valid_ghosts || !provided.valid_ghosts;
scalargroupdata.valid.at(wr.tl).at(wr.vi).set_and(need | ~provided,[iteration = cctkGH->cctk_iteration, where = attribute->where,thorn = attribute->thorn, routine = attribute->routine] {ostringstream buf;buf << "CallFunction iteration " << iteration << " " << where<< ": " << thorn << "::" << routine<< ": Poison output variables that are not input variables";return buf.str();});
valid_t &have = groupdata.valid.at(wr.tl).at(wr.vi);have.valid_int |= provided.valid_int;have.valid_outer |= provided.valid_outer;have.valid_ghosts |= provided.valid_ghosts;
groupdata.valid.at(wr.tl).at(wr.vi).set_or(provided,[iteration = cctkGH->cctk_iteration, where = attribute->where,thorn = attribute->thorn, routine = attribute->routine] {ostringstream buf;buf << "CallFunction iteration " << iteration << " " << where<< ": " << thorn << "::" << routine<< ": Mark output variables as valid";return buf.str();});
valid_t &have = scalargroupdata.valid.at(wr.tl).at(wr.vi);have.valid_int |= provided.valid_int;have.valid_outer |= provided.valid_outer;have.valid_ghosts |= provided.valid_ghosts;
scalargroupdata.valid.at(wr.tl).at(wr.vi).set_or(provided,[iteration = cctkGH->cctk_iteration, where = attribute->where,thorn = attribute->thorn, routine = attribute->routine] {ostringstream buf;buf << "CallFunction iteration " << iteration << " " << where<< ": " << thorn << "::" << routine<< ": Mark output variables as valid";return buf.str();});
valid_t &have = groupdata.valid.at(inv.tl).at(inv.vi);have.valid_int &= !provided.valid_int;have.valid_outer &= !provided.valid_outer;have.valid_ghosts &= !provided.valid_ghosts;
groupdata.valid.at(inv.tl).at(inv.vi).set_and(~provided,[iteration = cctkGH->cctk_iteration, where = attribute->where,thorn = attribute->thorn, routine = attribute->routine] {ostringstream buf;buf << "CallFunction iteration " << iteration << " " << where<< ": " << thorn << "::" << routine<< ": Mark invalid variables as invalid";return buf.str();});
valid_t &have = scalargroupdata.valid.at(inv.tl).at(inv.vi);have.valid_int &= !provided.valid_int;have.valid_outer &= !provided.valid_outer;have.valid_ghosts &= !provided.valid_ghosts;
scalargroupdata.valid.at(inv.tl).at(inv.vi).set_and(~provided,[iteration = cctkGH->cctk_iteration, where = attribute->where,thorn = attribute->thorn, routine = attribute->routine] {ostringstream buf;buf << "CallFunction iteration " << iteration << " " << where<< ": " << thorn << "::" << routine<< ": Mark invalid variables as invalid";return buf.str();});
if (!groupdata.valid.at(tl).at(vi).valid_int) {CCTK_VWARN(CCTK_WARN_ALERT,"Grid function '%s' interior not valid before restrict",CCTK_FullVarName(vi));all_valid = false;}}if (!all_valid) {CCTK_ERROR("Found grid functions that are not valid in the interior");}for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).valid_ghosts = false;for (int vi = 0; vi < groupdata.numvars; ++vi) {
error_if_invalid(leveldata, groupdata, tl, vi, make_valid_int(),[] { return "SyncGroupsByDirI before syncing"; });groupdata.valid.at(tl).at(vi).set_and(~make_valid_ghosts(), [] {return "SyncGroupsByDirI before syncing: Mark ghost zones as ""invalid";});
groupdata.valid.at(tl).at(vi).valid_ghosts =groupdata.valid.at(tl).at(vi).valid_int;
groupdata.valid.at(tl).at(vi).set_ghosts(true, [] {return "SyncGroupsByDirI after syncing: Mark ghost zones as ""valid";});
all_invalid &= !coarsegroupdata.valid.at(tl).at(vi).valid_int &&!coarsegroupdata.valid.at(tl).at(vi).valid_outer &&!coarsegroupdata.valid.at(tl).at(vi).valid_ghosts &&!groupdata.valid.at(tl).at(vi).valid_int;
all_invalid &=!coarsegroupdata.valid.at(tl).at(vi).get().valid_any() &&!groupdata.valid.at(tl).at(vi).get().valid_int;
for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).valid_int = false;groupdata.valid.at(tl).at(vi).valid_outer = false;groupdata.valid.at(tl).at(vi).valid_ghosts = false;}
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";});
if (!coarsegroupdata.valid.at(tl).at(vi).valid_int) {CCTK_VWARN(CCTK_WARN_ALERT,"Prolongation requires valid interior in coarse grid (level = %d), but found it invalid for '%s' on timelevel %d",level - 1, CCTK_FullVarName(vi), tl);some_sources_invalid = true;}if (!coarsegroupdata.valid.at(tl).at(vi).valid_outer) {CCTK_VWARN(CCTK_WARN_ALERT,"Prolongation requires valid boundary in coarse grid (level = %d), but found it invalid for '%s' on timelevel %d",level - 1, CCTK_FullVarName(vi), tl);some_sources_invalid = true;}if (!coarsegroupdata.valid.at(tl).at(vi).valid_ghosts) {CCTK_VWARN(CCTK_WARN_ALERT,"Prolongation requires valid ghosts in coarse grid (level = %d), but found it invalid for '%s' on timelevel %d",level - 1, CCTK_FullVarName(vi), tl);some_sources_invalid = true;}if (!groupdata.valid.at(tl).at(vi).valid_int) {CCTK_VWARN(CCTK_WARN_ALERT,"Prolongation expects valid interior in fine grid (level = %d), but found it invalid for '%s' on timelevel %d",level, CCTK_FullVarName(vi), tl);some_sources_invalid = true;}}if (some_sources_invalid)CCTK_ERROR("Some sources for prolongation were invalid");for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).valid_ghosts = false;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";});
check_valid(coarseleveldata, coarsegroupdata, 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, [] {
groupdata.valid.at(tl).at(vi).valid_ghosts =coarsegroupdata.valid.at(tl).at(vi).valid_int &&coarsegroupdata.valid.at(tl).at(vi).valid_outer &&coarsegroupdata.valid.at(tl).at(vi).valid_ghosts &&groupdata.valid.at(tl).at(vi).valid_int;} // if all_invalid
groupdata.valid.at(tl).at(vi).set_ghosts(true, [] { return "SyncGroupsByDirI after prolongation"; });} // if not all_invalid
assert(finegroupdata.valid.at(tl).at(vi).valid_int);assert(groupdata.valid.at(tl).at(vi).valid_int);
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"; });
assert(flux_finegroupdata.valid.at(tl).at(vi).valid_int);assert(flux_groupdata.valid.at(tl).at(vi).valid_int);
error_if_invalid(fineleveldata, flux_finegroupdata, vi, tl, make_valid_int(), [&] {ostringstream buf;buf << "Reflux: Fine level flux in direction " << d;return buf.str();});error_if_invalid(leveldata, flux_groupdata, vi, tl, make_valid_int(), [&] {ostringstream buf;buf << "Reflux: Coarse level flux in direction " << d;return buf.str();});
all_invalid &= !finegroupdata.valid.at(tl).at(vi).valid_int &&!groupdata.valid.at(tl).at(vi).valid_int;
all_invalid &= !finegroupdata.valid.at(tl).at(vi).get().valid_int &&!groupdata.valid.at(tl).at(vi).get().valid_int;
groupdata.valid.at(tl).at(vi).valid_outer = false;groupdata.valid.at(tl).at(vi).valid_ghosts = false;
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)";});
assert(finegroupdata.valid.at(tl).at(vi).valid_int &&groupdata.valid.at(tl).at(vi).valid_int);
error_if_invalid(fineleveldata, finegroupdata, vi, tl, make_valid_int(),[] { return "Restrict on fine level before restricting"; });
for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).valid_int &=finegroupdata.valid.at(tl).at(vi).valid_int;groupdata.valid.at(tl).at(vi).valid_outer = false;groupdata.valid.at(tl).at(vi).valid_ghosts = false;}
for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).set(make_valid_int(),[] { return "Restrict"; });
void error_if_invalid(const GHExt::LevelData &leveldata,const GHExt::CommonGroupData &groupdata, int vi, int tl,const valid_t &required, const function<string()> &msg);void warn_if_invalid(const GHExt::LevelData &leveldata,const GHExt::CommonGroupData &groupdata, int vi, int tl,const valid_t &required, const function<string()> &msg);