GQVQJCNQNO2KD7ZMC7RESCUAMUAP7OED6CTA6SYLZKQGXKXZ6T3QC 24A4OZBZBQ6QXIQ3EOOCQIBTOWRA32TMSQ4CCL3LKIJVJPKZFHVQC LSOYKV2LJ6WOBTNCW43WXV47RIQEBNZFEJJZM5QA7XDZF4D2PANQC E3MBKFT4GEFDAGZQQW4OROY5F6FWC46G6MRH54GDYTGO7O5YSRIAC 3KQ5ZQE45TNGATMW4R4NHXVBULGOXHF7JYC53BZL2LNDQ2V7C2CAC 722HZ7UFINNE3YKSYKP2NHZ5XEG5QQLQHSKC7PREJZR3EX6RDYUAC TVBD244E7Q7WV44CRBTFST535NUP3JAZH6OLL4IKDR3OWEXSU7HAC 33IC3UHCEPZLGS5ACS2JXHGT6CRU5LXU6PM6RDHCERPOIELVRVXQC KCIWCVZOHG44WBOLKI2XK33WPHPRI5FWCETF4AOGTPZISKCW3CLQC FEMASUBNU32NSG4DNXZX54CGCA57PVRGYO46L3A6F2EJ4BCSJ3SAC BPRNUTY7MHK7LK4EY5MY5OFFG3ABOL7LWXD574L35M74YSQPULFAC BSMJ4V7GV3EOGY4KCSTOJQUOFE2OOCIKQETE4WC2WRNLWBQIBW3QC 5XGIB7XMEZNBLA5ZLQTXRTC3AZ5CTRGMXWBPVMWXG4DPHKWDF4ZAC QN2UTSQP4IMCMVXZNR24J22N24ASGXF6EWXQ2P3VWVQERUPFAFDQC WASO7G5FJXRXWNH2U2FLUNEKU6VE63OI3HUYP64BVD4LMD6KE7OQC MSBBCXVGD3GRLE5KAI6BKAFRV7SQUWI2SNN43AJAUD3ISRCEXY6QC TOBGHRPKEPSXDN56WGSZNWOMCBVJ4KUSLWYWI56MC2RR3MM3KLZAC BVR7DVINVPQG7PA6Z7QYVYNQ43YZL7XCC6AOMSMWMGAAB2Q43STAC UUGQGVC4WEKN64WAP7F5QPS2UHGQB5ZLMFRIYNWKMIEBDO3QRX4AC WE6MDRN5SPK3THM4COLQFE3IUWBCQ5ZYUIAUCBJAZVEMMOVTNBOAC UTHNLH3J3VG7BBJPOKGE6DY7Z2QHDLY72TR2VMEDQYP73SIWZGKAC 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 specifiedassert(strs.size() == dim); // Check number of fluxesfor (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 groupsfluxes[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 differentreturn fluxes;}
}if (level > 0) {array<int, dim> fluxes = get_group_fluxes(groupdata.groupindex);const bool have_fluxes = fluxes[0] >= 0;if (have_fluxes) {assert((groupdata.indextype == array<int, dim>{1, 1, 1}));groupdata.freg = make_unique<FluxRegister>(gba, dm, ghext->amrcore->refRatio(level - 1), level,groupdata.numvars);groupdata.fluxes = fluxes;} else {groupdata.fluxes.fill(-1);}}}// Check flux register consistencyfor (int gi = 0; gi < numgroups; ++gi) {const auto &groupdata = leveldata.groupdata.at(gi);if (groupdata.freg) {for (int d = 0; d < dim; ++d) {assert(groupdata.fluxes[d] != groupdata.groupindex);const auto &flux_groupdata =leveldata.groupdata.at(groupdata.fluxes[d]);array<int, dim> flux_indextype{1, 1, 1};flux_indextype[d] = 0;assert(flux_groupdata.indextype == flux_indextype);assert(flux_groupdata.numvars == groupdata.numvars);}
}void Reflux(int level) {DECLARE_CCTK_PARAMETERS;if (!do_reflux)return;CCTK_VINFO("Refluxing level %d", level);#warning "TODO"bool didprint = false;static Timer timer("Reflux");Interval interval(timer);auto &leveldata = ghext->leveldata.at(level);const auto &fineleveldata = ghext->leveldata.at(level + 1);for (int gi = 0; gi < int(leveldata.groupdata.size()); ++gi) {const int tl = 0;auto &groupdata = leveldata.groupdata.at(gi);const auto &finegroupdata = fineleveldata.groupdata.at(gi);// If the group has associated fluxesif (finegroupdata.freg) {if (!didprint) {CCTK_VINFO(" found flux registers");didprint = true;}// Check coarse and fine data and fluxes are validfor (int vi = 0; vi < finegroupdata.numvars; ++vi) {assert(finegroupdata.valid.at(tl).at(vi).valid_int &&finegroupdata.valid.at(tl).at(vi).valid_bnd);assert(groupdata.valid.at(tl).at(vi).valid_int &&groupdata.valid.at(tl).at(vi).valid_bnd);}for (int d = 0; d < dim; ++d) {int flux_gi = finegroupdata.fluxes[d];const auto &flux_finegroupdata = fineleveldata.groupdata.at(flux_gi);const auto &flux_groupdata = leveldata.groupdata.at(flux_gi);for (int vi = 0; vi < finegroupdata.numvars; ++vi) {assert(flux_finegroupdata.valid.at(tl).at(vi).valid_int &&flux_finegroupdata.valid.at(tl).at(vi).valid_bnd);assert(flux_groupdata.valid.at(tl).at(vi).valid_int &&flux_groupdata.valid.at(tl).at(vi).valid_bnd);}}#warning "TODO"const Geometry &geom0 = ghext->amrcore->Geom(level);const CCTK_REAL *restrict gdx = geom0.CellSize();CCTK_REAL dt = 0.25 * pow(0.5, 2) * gdx[0];CCTK_REAL dx = 1.0 * pow(0.5, level) * gdx[0];for (int d = 0; d < dim; ++d) {int flux_gi = finegroupdata.fluxes[d];const auto &flux_finegroupdata = fineleveldata.groupdata.at(flux_gi);const auto &flux_groupdata = leveldata.groupdata.at(flux_gi);finegroupdata.freg->CrseInit(*flux_groupdata.mfab.at(tl), d, 0, 0,flux_groupdata.numvars, -dt * dx * dx);finegroupdata.freg->FineAdd(*flux_finegroupdata.mfab.at(tl), d, 0, 0,flux_finegroupdata.numvars,dt * (0.5 * dx) * (0.5 * dx));}const Geometry &geom = ghext->amrcore->Geom(level);finegroupdata.freg->Reflux(*groupdata.mfab.at(tl), 1.0, 0, 0,groupdata.numvars, geom);}}