XU5HOJREK4XY4NBCJINLZPKQNKSYOLUDTWR47REFSNQKDOSNDXLQC
VMCDMDXKME66ESRMB3PYSUZZH2XG2GIQMEOEKRH33WGCEBPXTWUQC
3HPNY5XHNPWR6RVX4LYEVDFJQWSB2CMS7J6XPAKATQ2UPFTXD33QC
JB7UTBIB3ETLK2BWVYETURQSQNXLQA36IIZSPVHK6KTO6BEFP23AC
2DKSL6DKZAIYQUJGDULORCKU5K4Z5Z3W4RIKQYDSLKMCNQNDZFBAC
722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC
DHFIRBK6SZI7R5QBVGMX2M5ADXIVQWNLCVBE6MKVPGHZ4USEC3VQC
BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC
33IC3UHCEPZLGS5ACS2JXHGT6CRU5LXU6PM6RDHCERPOIELVRVXQC
BVO33OXTG3QDBJ5YLBBVMUDHZGVFE777UOGZKVAHQK6MSDVR5RRAC
24A4OZBZBQ6QXIQ3EOOCQIBTOWRA32TMSQ4CCL3LKIJVJPKZFHVQC
5IAXY3XZJTRMMVT2OVIJ6OXQJI6OJPTPCHHA4IVLVMHANCCC5NKAC
VIK5E6DBUCP5HGDVHDP6SWTHH7ODEUIGKOGSXR7VLVK46LDD4W6QC
KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC
YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC
TVBD244E7Q7WV44CRBTFST535NUP3JAZH6OLL4IKDR3OWEXSU7HAC
GQVQJCNQNO2KD7ZMC7RESCUAMUAP7OED6CTA6SYLZKQGXKXZ6T3QC
MSBBCXVGD3GRLE5KAI6BKAFRV7SQUWI2SNN43AJAUD3ISRCEXY6QC
J3SP5HQRWGMM6EM4ZIWPNUIY5HYFRJA4SH2X4OWGESSK7AWA3RNQC
BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC
JN2TPHENEBIY2OE5FRCQ2E6QCL6FPVHJHUCP4UODD6DITRVV2LIQC
UEZKNPXXK5WU6B5LYRKGGYGBZ6T6TAZI26CWTJFUBUW2SJJOMV2AC
IV3MLV677VWS7GLESBQZ4HRFNW5TBFBIGIBWXTCHAER3FQ7VG3GQC
2XYZZL42IEZHGDJA6NDKGSQKGJP24LOTLFJ6RNHOKWHHSUYIHGKQC
BSMJ4V7GV3EOGY4KCSTOJQUOFE2OOCIKQETE4WC2WRNLWBQIBW3QC
BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC
TUDUMVD5MTJJJGVYVOCALOOKOUYNB7LOFJRCYCZDVGN536JAO2OQC
NUNYA5E7NMMUTVAQKVO34GUQI3U2TJTCEIZZT3PAPZ3ZU5LB44BQC
BOOLEAN reflection_z "Reflection symmetry at the lower z boundary"
{
} "no"
BOOLEAN reflection_upper_x "Reflection symmetry at the upper x boundary"
{
} "no"
BOOLEAN reflection_upper_y "Reflection symmetry at the upper y boundary"
{
} "no"
BOOLEAN reflection_upper_z "Reflection symmetry at the upper z boundary"
{
} "no"
vector<array<int, dim> > get_group_parities(const int gi) {
DECLARE_CCTK_PARAMETERS;
assert(gi >= 0);
const int tags = CCTK_GroupTagsTableI(gi);
assert(tags >= 0);
const int nelems = Util_TableGetIntArray(tags, 0, nullptr, "parities");
if (nelems == UTIL_ERROR_TABLE_NO_SUCH_KEY) {
// unset (will use index type)
return {};
} else if (nelems >= 0) {
// do nothing
} else {
assert(0);
}
vector<CCTK_INT> parities1(nelems);
const int iret =
Util_TableGetIntArray(tags, nelems, parities1.data(), "parities");
assert(iret == nelems);
assert(nelems % dim == 0);
vector<array<int, dim> > parities(nelems / dim);
for (size_t n = 0; n < parities.size(); ++n)
for (int d = 0; d < dim; ++d)
parities.at(n)[d] = parities1.at(dim * n + d);
return parities;
}
groupdata.parities = get_group_parities(gi);
if (groupdata.parities.empty()) {
array<int, dim> parity;
for (int d = 0; d < dim; ++d)
parity[d] = groupdata.indextype[d] == 0 ? +1 : -1;
groupdata.parities.resize(groupdata.numvars, parity);
}
assert(int(groupdata.parities.size()) == groupdata.numvars);
for (int vi = 0; vi < groupdata.numvars; ++vi)
for (int d = 0; d < dim; ++d)
assert(abs(groupdata.parities.at(vi)[d]) == 1);
const array<array<bool, 3>, 2> is_periodic{{
{{
periodic || periodic_x,
periodic || periodic_y,
periodic || periodic_z,
}},
{{
periodic || periodic_x,
periodic || periodic_y,
periodic || periodic_z,
}},
}};
const array<array<bool, 3>, 2> is_reflect{{
{{
!!reflection_x,
!!reflection_y,
!!reflection_z,
}},
{{
!!reflection_upper_x,
!!reflection_upper_y,
!!reflection_upper_z,
}},
}};
const auto makebc{[&](const int vi, const int dir, const int face) {
assert(dir >= 0 && dir < dim);
assert(face >= 0 && face < 2);
if (is_periodic[face][dir])
return BCType::int_dir;
if (is_reflect[face][dir])
return groupdata.parities.at(vi)[dir] > 0 ? BCType::reflect_even
: BCType::reflect_odd;
return BCType::ext_dir;
}};
Vector<BCRec> bcs(groupdata.numvars);
for (int vi = 0; vi < groupdata.numvars; ++vi)
bcs.at(vi) = BCRec(makebc(vi, 0, 0), makebc(vi, 1, 0), makebc(vi, 2, 0),
makebc(vi, 0, 1), makebc(vi, 1, 1), makebc(vi, 2, 1));
const auto apply_physbc{[](const Box &, const FArrayBox &, int, int,
const Geometry &, CCTK_REAL, const Vector<BCRec> &,
int, int) {}};
CarpetXPhysBCFunct physbc(ghext->amrcore->Geom(leveldata.level), bcs,
apply_physbcs);
return {move(physbc), move(bcs)};
}
// boundary conditions
const BCRec bcrec(
periodic || periodic_x ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_y ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_z ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_x ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_y ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_z ? BCType::int_dir : BCType::ext_dir);
const Vector<BCRec> bcs(groupdata.numvars, bcrec);
auto physbc_bcs = get_boundaries(leveldata, groupdata);
CarpetXPhysBCFunct &physbc = get<0>(physbc_bcs);
const Vector<BCRec> &bcs = get<1>(physbc_bcs);
// boundary conditions
const BCRec bcrec(
periodic || periodic_x ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_y ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_z ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_x ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_y ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_z ? BCType::int_dir : BCType::ext_dir);
const Vector<BCRec> bcs(groupdata.numvars, bcrec);
auto physbc_bcs = get_boundaries(leveldata, groupdata);
CarpetXPhysBCFunct &physbc = get<0>(physbc_bcs);
const Vector<BCRec> &bcs = get<1>(physbc_bcs);
typedef void apply_physbcs_t(const Box &, const FArrayBox &, int, int,
const Geometry &, CCTK_REAL, const Vector<BCRec> &,
int, int);
typedef PhysBCFunct<apply_physbcs_t *> CarpetXPhysBCFunct;
tuple<CarpetXPhysBCFunct, Vector<BCRec> >
get_boundaries(const GHExt::LevelData &leveldata,
const GHExt::LevelData::GroupData &groupdata);
groupdata.mfab.at(tl)->FillBoundary(
ghext->amrcore->Geom(leveldata.level).periodicity());
FillPatchSingleLevel(
*groupdata.mfab.at(tl), 0.0, {&*groupdata.mfab.at(tl)}, {0.0}, 0,
0, groupdata.numvars, ghext->amrcore->Geom(level), physbc, 0);
// boundary conditions
const BCRec bcrec(
periodic || periodic_x ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_y ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_z ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_x ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_y ? BCType::int_dir : BCType::ext_dir,
periodic || periodic_z ? BCType::int_dir : BCType::ext_dir);
const Vector<BCRec> bcs(groupdata.numvars, bcrec);
// // 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) {
// 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 {