for (int component = 0; component < ncomps; ++component) {
const Box &box = mfab.box(component); // interior
Box refined_box(box);
refined_box.refine(2);
const vector<pair<int, Box> > child_boxes =
fine_boxarray.intersections(refined_box);
vector<int> children;
children.reserve(child_boxes.size());
for (const auto &ib : child_boxes) {
const int fine_component = ib.first;
children.push_back(fine_comp0 + fine_component);
}
segment_types.push_back(DB_BLOCKCENT);
segment_data.push_back(move(children));
}
} else {
// no finer level, hence no children
const int ncomps = ncomps_level.at(level);
for (int component = 0; component < ncomps; ++component) {
segment_types.push_back(DB_BLOCKCENT);
segment_data.emplace_back();
}
}
}
vector<int> &segment_lengths = num_children;
vector<const int *> segment_data_ptrs;
segment_lengths.reserve(segment_data.size());
segment_data_ptrs.reserve(segment_data.size());
for (const auto &data : segment_data) {
segment_lengths.push_back(data.size());
segment_data_ptrs.push_back(data.data());
}
ierr = DBPutGroupelmap(metafile.get(), childmaps_name.c_str(),
ncomps_total, segment_types.data(),
segment_lengths.data(), nullptr,
segment_data_ptrs.data(), nullptr, 0, nullptr);
assert(!ierr);
}
// Create Mrgtree
{
const int max_mgrtree_children = 2;
const DB::ptr<DBmrgtree> mrgtree = DB::make(
DBMakeMrgtree(DB_MULTIMESH, 0, max_mgrtree_children, nullptr));
assert(mrgtree);
// Describe AMR configuration
const int max_amr_decomp_children = 2;
ierr = DBAddRegion(mrgtree.get(), "amr_decomp", 0,
max_amr_decomp_children, nullptr, 0, nullptr,
nullptr, nullptr, nullptr);
assert(!ierr);
ierr = DBSetCwr(mrgtree.get(), "amr_decomp");
assert(ierr >= 0);
// Describe AMR levels
{
ierr = DBAddRegion(mrgtree.get(), "levels", 0, nlevels, nullptr, 0,
nullptr, nullptr, nullptr, nullptr);
assert(!ierr);
ierr = DBSetCwr(mrgtree.get(), "levels");
assert(ierr >= 0);
const vector<string> region_names{"@level%d@n"};
vector<const char *> region_name_ptrs;
region_name_ptrs.reserve(region_names.size());
for (const string &name : region_names)
region_name_ptrs.push_back(name.c_str());
vector<int> segment_ids;
vector<int> segment_types;
segment_ids.reserve(nlevels);
segment_types.reserve(nlevels);
for (int l = 0; l < nlevels; ++l) {
segment_ids.push_back(l);
segment_types.push_back(DB_BLOCKCENT);
}
ierr = DBAddRegionArray(
mrgtree.get(), nlevels, region_name_ptrs.data(), 0,
levelmaps_name.c_str(), 1, segment_ids.data(),
ncomps_level.data(), segment_types.data(), nullptr);
assert(!ierr);
ierr = DBSetCwr(mrgtree.get(), "..");
assert(ierr >= 0);
}
// Describe AMR children
{
ierr = DBAddRegion(mrgtree.get(), "patches", 0, ncomps_total,
nullptr, 0, nullptr, nullptr, nullptr, nullptr);
assert(ierr >= 0);
ierr = DBSetCwr(mrgtree.get(), "patches");
assert(ierr >= 0);
const vector<string> region_names{"@patch%d@n"};
vector<const char *> region_name_ptrs;
region_name_ptrs.reserve(region_names.size());
for (const string &name : region_names)
region_name_ptrs.push_back(name.c_str());
vector<int> segment_types;
vector<int> segment_ids;
segment_types.reserve(ncomps_total);
segment_ids.reserve(ncomps_total);
for (int c = 0; c < ncomps_total; ++c) {
segment_ids.push_back(c);
segment_types.push_back(DB_BLOCKCENT);
}
ierr = DBAddRegionArray(
mrgtree.get(), ncomps_total, region_name_ptrs.data(), 0,
childmaps_name.c_str(), 1, segment_ids.data(),
num_children.data(), segment_types.data(), nullptr);
ierr = DBSetCwr(mrgtree.get(), "..");
assert(ierr >= 0);
}
{
const vector<string> mrgv_onames{
multimeshname + "_wmrgtree_lvlRatios",
multimeshname + "_wmrgtree_ijkExts",
multimeshname + "_wmrgtree_xyzExts", "rank"};
vector<const char *> mrgv_oname_ptrs;
mrgv_oname_ptrs.reserve(mrgv_onames.size() + 1);
for (const string &name : mrgv_onames)
mrgv_oname_ptrs.push_back(name.c_str());
mrgv_oname_ptrs.push_back(nullptr);
const DB::ptr<DBoptlist> optlist = DB::make(DBMakeOptlist(10));
assert(optlist);
ierr = DBAddOption(optlist.get(), DBOPT_MRGV_ONAMES,
mrgv_oname_ptrs.data());
assert(!ierr);
ierr = DBPutMrgtree(metafile.get(), "mrgTree", "amr_mesh",
mrgtree.get(), optlist.get());
assert(!ierr);
}
}
// Write refinement ratios
{
const string levelrationame = multimeshname + "_wmrgtree_lvlRatios";
const vector<string> compnames{"iRatio", "jRatio", "kRatio"};
vector<const char *> compname_ptrs;
compname_ptrs.reserve(compnames.size());
for (const string &name : compnames)
compname_ptrs.push_back(name.c_str());
const vector<string> regionnames{"@level%d@n"};
vector<const char *> regionname_ptrs;
regionname_ptrs.reserve(regionnames.size());
for (const string &name : regionnames)
regionname_ptrs.push_back(name.c_str());
array<vector<int>, ndims> data;
for (int d = 0; d < ndims; ++d) {
data[d].reserve(1);
data[d].push_back(2);
}
array<const void *, ndims> data_ptrs;
for (int d = 0; d < ndims; ++d)
data_ptrs[d] = data[d].data();
ierr = DBPutMrgvar(metafile.get(), levelrationame.c_str(), "mrgTree",
ndims, compname_ptrs.data(), nlevels,
regionname_ptrs.data(), DB_INT, data_ptrs.data(),
nullptr);
assert(!ierr);
}
typedef array<array<int, ndims>, 2> iextent_t;
typedef array<array<double, ndims>, 2> extent_t;
vector<iextent_t> iextents;
vector<extent_t> extents;
iextents.reserve(ncomps_total);
extents.reserve(ncomps_total);
for (const auto &leveldata : ghext->leveldata) {
const auto &groupdata = *leveldata.groupdata.at(gi);
const int tl = 0;
const MultiFab &mfab = *groupdata.mfab[tl];
const Geometry &geom = ghext->amrcore->Geom(leveldata.level);
const double *const x0 = geom.ProbLo();
const double *const dx = geom.CellSize();
const int nfabs = mfab.size();
for (int c = 0; c < nfabs; ++c) {
const Box &fabbox = mfab.fabbox(c); // exterior
iextent_t iextent;
extent_t extent;
for (int d = 0; d < ndims; ++d) {
iextent[0][d] = fabbox.smallEnd(d);
iextent[1][d] = fabbox.bigEnd(d);
extent[0][d] = x0[d] + fabbox.smallEnd(d) * dx[d];
extent[1][d] = x0[d] + fabbox.bigEnd(d) * dx[d];
}
iextents.push_back(iextent);
extents.push_back(extent);
}
}
// Write extents
{
const string iextentsname = multimeshname + "_wmrgtree_ijkExts";
const string extentsname = multimeshname + "_wmrgtree_xyzExts";
const vector<string> icompnames{"iMin", "iMax", "jMin",
"jMax", "kMin", "kMax"};
const vector<string> compnames{"xMin", "xMax", "yMin",
"yMax", "zMin", "zMax"};
vector<const char *> icompname_ptrs;
icompname_ptrs.reserve(icompnames.size());
for (const string &name : icompnames)
icompname_ptrs.push_back(name.c_str());
vector<const char *> compname_ptrs;
compname_ptrs.reserve(compnames.size());
for (const string &name : compnames)
compname_ptrs.push_back(name.c_str());
const vector<string> regionnames{"@patch%d@n"};
vector<const char *> regionname_ptrs;
regionname_ptrs.reserve(regionnames.size());
for (const string &name : regionnames)
regionname_ptrs.push_back(name.c_str());
array<array<vector<int>, 2>, ndims> idata;
array<array<vector<double>, 2>, ndims> data;
for (int d = 0; d < ndims; ++d) {
for (int f = 0; f < 2; ++f) {
idata[d][f].reserve(ncomps_total);
data[d][f].reserve(ncomps_total);
}
}
for (int c = 0; c < ncomps_total; ++c) {
for (int d = 0; d < ndims; ++d) {
for (int f = 0; f < 2; ++f) {
idata[d][f].push_back(iextents[c][f][d]);
data[d][f].push_back(extents[c][f][d]);
}
}
}
array<array<const void *, 2>, ndims> idata_ptrs;
array<array<const void *, 2>, ndims> data_ptrs;
for (int d = 0; d < ndims; ++d) {
for (int f = 0; f < 2; ++f) {
idata_ptrs[d][f] = idata[d][f].data();
data_ptrs[d][f] = data[d][f].data();
}
}
ierr = DBPutMrgvar(metafile.get(), iextentsname.c_str(), "mrgTree",
ndims, icompname_ptrs.data(), nlevels,
regionname_ptrs.data(), DB_INT, idata_ptrs.data(),
nullptr);
assert(!ierr);
ierr =
DBPutMrgvar(metafile.get(), extentsname.c_str(), "mrgTree", ndims,
compname_ptrs.data(), nlevels, regionname_ptrs.data(),
DB_INT, data_ptrs.data(), nullptr);
assert(!ierr);
// Write rank
const int rank = ndims;
const int *const rank_ptr = &rank;
ierr = DBPutMrgvar(metafile.get(), "rank", "mrgTree", 1, nullptr,
ncomps_total, regionname_ptrs.data(), DB_INT,
&rank_ptr, nullptr);
assert(!ierr);
}
// Write multimesh