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 valid
for (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 valid
void 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 valid
void 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);