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 specified
assert(strs.size() == dim); // Check number of fluxes
for (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 groups
fluxes[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 different
return 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 parameter
nghostzones = {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 specified
assert(strs.size() == dim); // Check number of fluxes
for (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 groups
fluxes[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 different
return 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 parameter
nghostzones = {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 valid
bool 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 happen
assert(leveldata.level > 0);
// Copy from same level and/or prolongate from next coarser level
auto &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 valid
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_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 level
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);
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 levels
const 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 levels
const 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 level
if (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 level
if (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 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;
// // 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 interior
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";
});
}
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: volume
int 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: volume
int 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);