T3TZRPPAIA24I3YL3JFB4XEAYCWU3HJAJUCF7NNIFMP4I5X4SM5QC IVNZPCEYT3E2XEQBDIXHNA6WAZ6WVSAPFVLJTLPC7D7O4UPOU2OAC KK3NMMOX7Z77JZ4D6UDD44VVQOGYRUN4SSFCSHJDELRFZMQE7HXAC NUNYA5E7NMMUTVAQKVO34GUQI3U2TJTCEIZZT3PAPZ3ZU5LB44BQC KOOPA77MHDMNHAKH7YXUD2POVQCT3R2HHDHEFBW3G7MVM7QJQVYAC BJDGFYBMECTJG7BHLNHLSCUCBVYHAY6OGY37FIJP6JDGNDXQNQVAC WV2J4VRLSW42SGIRDLF326LLC7L2ABAMSZ3YKABS532K27U3X3CAC WZPFZTNOJMA2ANRX22OL6QUCU6KUWSZVQJSL46KKBEB37MWRVNNAC WTDXZR735D7JBS4XVLTEXBVFMLSRLZUHZNVHH7ZWVGFGATD6DFNAC M5R6KQLXLGYSVKHVAX5AJKD6NYE6IM5Z6WVTR3BTKPJDNNKF3ARAC 722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC MF53IYPRC7HEG2LRV347PTVBWENVKHMUYN6FIAEVTTVPIXH4FMGQC VIK5E6DBUCP5HGDVHDP6SWTHH7ODEUIGKOGSXR7VLVK46LDD4W6QC E3MBKFT4GEFDAGZQQW4OROY5F6FWC46G6MRH54GDYTGO7O5YSRIAC BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC YIQN7NJTGEVKW7JZHL6CTH6EPCIXCNBYNURIGXPYZAOUX3VAJQMAC FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC OHAARXLBTFOIV5FOTY7IDMOIAE275CKXCE6XQMWV3EC63YCSMIWAC CWFPG3JOFDQGDQEN56PEE6FLJXF665S4BEOKMYX7V5KGXM4ACIHAC BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC BSMJ4V7GV3EOGY4KCSTOJQUOFE2OOCIKQETE4WC2WRNLWBQIBW3QC GECUITHDXKCWB7HBCM7EA5Q56JDDWUVUWHMW2K6OM7UW36DFAZ3QC A7ETPFXEHA2RM4LINSBVMJJ3G62NF7Q5ZQOKJPNJK3YOQ5WS5HKAC EHF2P5PKVTMAUL5R5QSZ3DS3VLE7Z6SHJTCZAGRBTQ66Y7HZKNYQC IV3MLV677VWS7GLESBQZ4HRFNW5TBFBIGIBWXTCHAER3FQ7VG3GQC UEZKNPXXK5WU6B5LYRKGGYGBZ6T6TAZI26CWTJFUBUW2SJJOMV2AC 2A2A26IPPHUXJP36FFK3YPT2PJA36CEADQNNTDEYLMDLVANNCJEQC IL5XPFSWQX3OWZHEUSDP3R2IKVWHHOI6MNNBKU3P6MNBT6MVYJ2QC W4XMGPEHBCV6AAPJBI4SSEMCDB6KKCGRUC2X2F5YLBY22OR3ICPAC RFUF3QUEOYDFA5H5BZJP7HVQ5LMCWCIO7MV32RQBDMVDULGQGO5QC 3ROBI6IPLFHSSNMGTZHYWIPCO342OKQLXHNWFJ3KMNQRNYMAMLKAC UTHNLH3J3VG7BBJPOKGE6DY7Z2QHDLY72TR2VMEDQYP73SIWZGKAC coarsegroupdata.valid.at(tl).at(vi).valid_bnd;groupdata.valid.at(tl).at(vi).valid_bnd = false;
coarsegroupdata.valid.at(tl).at(vi).valid_outer &&coarsegroupdata.valid.at(tl).at(vi).valid_ghosts;groupdata.valid.at(tl).at(vi).valid_outer = false;groupdata.valid.at(tl).at(vi).valid_ghosts = false;
const bool cond = coarsegroupdata.valid.at(tl).at(vi).valid_int &&coarsegroupdata.valid.at(tl).at(vi).valid_bnd &&
const bool cond =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_bnd;valid.at(vi).valid_bnd = false;
groupdata.valid.at(tl).at(vi).valid_outer &&groupdata.valid.at(tl).at(vi).valid_ghosts;valid.at(vi).valid_outer = false;valid.at(vi).valid_ghosts = false;
for (int dir = 0; dir < dim; ++dir) {for (int face = 0; face < 2; ++face) {if (bbox[2 * dir + face]) {
for (int nk = -1; nk <= +1; ++nk) {for (int nj = -1; nj <= +1; ++nj) {for (int ni = -1; ni <= +1; ++ni) {if ((ni != 0 && bbox[0 + (ni == -1 ? 0 : 1)]) ||(nj != 0 && bbox[2 + (nj == -1 ? 0 : 1)]) ||(nk != 0 && bbox[4 + (nk == -1 ? 0 : 1)])) {const array<int, dim> inormal{ni, nj, nk};
array<int, dim> imin, imax;for (int d = 0; d < dim; ++d) {// by default, include interior and outer boundaries and ghostsint ghost_offset = nghostzones[d] - group_nghostzones[d];imin[d] = ghost_offset;imax[d] = lsh[d] + offset[d] - ghost_offset;
array<int, dim> imin, imax;for (int d = 0; d < dim; ++d) {const int ghost_offset = nghostzones[d] - group_nghostzones[d];const int begin_bnd = ghost_offset;const int begin_int = nghostzones[d];const int end_int = lsh[d] + offset[d] - nghostzones[d];const int end_bnd = lsh[d] + offset[d] - ghost_offset;switch (inormal[d]) {case -1: // lower boundaryimin[d] = begin_bnd;imax[d] = begin_int;break;case 0: // interiorimin[d] = begin_int;imax[d] = end_int;break;case +1: // upper boundaryimin[d] = end_int;imax[d] = end_bnd;break;default:assert(0);}
// avoid covering edges and corners multiple timesif (d < dir) {if (bbox[2 * d])imin[d] = nghostzones[d]; // only interiorif (bbox[2 * d + 1])imax[d] = lsh[d] + offset[d] - nghostzones[d]; // only interior
imin[d] = max(tmin[d], imin[d]);imax[d] =min(tmax[d] + (tmax[d] >= lsh[d] ? offset[d] : 0), imax[d]);
loop_box<CI, CJ, CK>(f, imin, imax);
for (int nk = -1; nk <= +1; ++nk) {for (int nj = -1; nj <= +1; ++nj) {for (int ni = -1; ni <= +1; ++ni) {if ((ni != 0 && !bbox[0 + (ni == -1 ? 0 : 1)]) ||(nj != 0 && !bbox[2 + (nj == -1 ? 0 : 1)]) ||(nk != 0 && !bbox[4 + (nk == -1 ? 0 : 1)])) {const array<int, dim> inormal{ni, nj, nk};array<int, dim> imin, imax;for (int d = 0; d < dim; ++d) {const int ghost_offset = nghostzones[d] - group_nghostzones[d];const int begin_bnd = ghost_offset;const int begin_int = nghostzones[d];const int end_int = lsh[d] + offset[d] - nghostzones[d];const int end_bnd = lsh[d] + offset[d] - ghost_offset;switch (inormal[d]) {case -1: // lower boundaryimin[d] = begin_bnd;imax[d] = begin_int;break;case 0: // interiorimin[d] = begin_int;imax[d] = end_int;break;case +1: // upper boundaryimin[d] = end_int;imax[d] = end_bnd;break;default:assert(0);}imin[d] = max(tmin[d], imin[d]);imax[d] =min(tmax[d] + (tmax[d] >= lsh[d] ? offset[d] : 0), imax[d]);}loop_box<CI, CJ, CK>(f, imin, imax, inormal);}
where_t where;if (!valid.valid_int) {if (!valid.valid_bnd)where = where_t::everywhere;elsewhere = where_t::interior;
if (!valid.valid_int && !valid.valid_outer && !valid.valid_ghosts) {grid.loop_idx(where_t::everywhere, groupdata.indextype,groupdata.nghostzones,[&](const Loop::PointDesc &p) { ptr_(p.I) = 0.0 / 0.0; });
if (!valid.valid_bnd)where = where_t::boundary;elseassert(0);
if (!valid.valid_int)grid.loop_idx(where_t::interior, groupdata.indextype,groupdata.nghostzones,[&](const Loop::PointDesc &p) { ptr_(p.I) = 0.0 / 0.0; });if (!valid.valid_outer)grid.loop_idx(where_t::boundary, groupdata.indextype,groupdata.nghostzones,[&](const Loop::PointDesc &p) { ptr_(p.I) = 0.0 / 0.0; });if (!valid.valid_ghosts)grid.loop_idx(where_t::ghosts, groupdata.indextype,groupdata.nghostzones,[&](const Loop::PointDesc &p) { ptr_(p.I) = 0.0 / 0.0; });
where_t where;if (valid.valid_int) {if (valid.valid_bnd)where = where_t::everywhere;elsewhere = where_t::interior;
if (valid.valid_int && valid.valid_outer && valid.valid_ghosts) {grid.loop_idx(where_t::everywhere, groupdata.indextype,groupdata.nghostzones, [&](const Loop::PointDesc &p) {if (CCTK_BUILTIN_EXPECT(CCTK_isnan(ptr_(p.I)), false))found_nan = true;});
if (valid.valid_bnd)where = where_t::boundary;elseassert(0);}grid.loop_idx(where, groupdata.indextype, groupdata.nghostzones,[&](const Loop::PointDesc &p) {if (CCTK_BUILTIN_EXPECT(isnan(ptr_(p.I)), false))
if (valid.valid_int)grid.loop_idx(where_t::interior, groupdata.indextype,groupdata.nghostzones, [&](const Loop::PointDesc &p) {if (CCTK_BUILTIN_EXPECT(CCTK_isnan(ptr_(p.I)), false))found_nan = true;});if (valid.valid_outer)grid.loop_idx(where_t::boundary, groupdata.indextype,groupdata.nghostzones, [&](const Loop::PointDesc &p) {if (CCTK_BUILTIN_EXPECT(CCTK_isnan(ptr_(p.I)), false))found_nan = true;});if (valid.valid_ghosts)grid.loop_idx(where_t::ghosts, groupdata.indextype,groupdata.nghostzones, [&](const Loop::PointDesc &p) {if (CCTK_BUILTIN_EXPECT(CCTK_isnan(ptr_(p.I)), false))
if (where & WH_INTERIOR)valid.valid_int = true;// We treat "ghost" and "boundary" as the sameif (where & (WH_GHOSTS | WH_BOUNDARY))valid.valid_bnd = true;
valid.valid_int = where & WH_INTERIOR;valid.valid_outer = where & WH_BOUNDARY;valid.valid_ghosts = where & WH_GHOSTS;
for (int vi = 0; vi < groupdata.numvars; ++vi)groupdata.valid.at(tl).at(vi).valid_bnd = false;
for (int vi = 0; vi < groupdata.numvars; ++vi) {groupdata.valid.at(tl).at(vi).valid_outer = false;groupdata.valid.at(tl).at(vi).valid_ghosts = false;}