BoxList::BoxList(const Box& bx, const IntVect& tilesize) : btype(bx.ixType()) { int ntiles = 1; IntVect nt; for (int d=0; d<BL_SPACEDIM; d++) { nt[d] = (bx.length(d)+tilesize[d]-1)/tilesize[d]; ntiles *= nt[d]; } IntVect small, big, ijk; // note that the initial values are all zero. ijk[0] = -1; for (int t=0; t<ntiles; ++t) { for (int d=0; d<BL_SPACEDIM; d++) { if (ijk[d]<nt[d]-1) { ijk[d]++; break; } else { ijk[d] = 0; } } for (int d=0; d<BL_SPACEDIM; d++) { small[d] = ijk[d]*tilesize[d]; big[d] = std::min(small[d]+tilesize[d]-1, bx.length(d)-1); } Box tbx(small, big, btype); tbx.shift(bx.smallEnd()); push_back(tbx); } }
void FabArrayBase::buildTileArray (const IntVect& tileSize, TileArray& ta) const { // Note that we store Tiles always as cell-centered boxes, even if the boxarray is nodal. for (int i = 0; i < indexMap.size(); ++i) { const int K = indexMap[i]; const Box& bx = boxarray.getCellCenteredBox(K); IntVect nt_in_fab, tsize, nleft; int ntiles = 1; for (int d=0; d<BL_SPACEDIM; d++) { int ncells = bx.length(d); nt_in_fab[d] = std::max(ncells/tileSize[d], 1); tsize [d] = ncells/nt_in_fab[d]; nleft [d] = ncells - nt_in_fab[d]*tsize[d]; ntiles *= nt_in_fab[d]; } IntVect small, big, ijk; // note that the initial values are all zero. ijk[0] = -1; for (int t = 0; t < ntiles; ++t) { ta.indexMap.push_back(K); ta.localIndexMap.push_back(i); for (int d=0; d<BL_SPACEDIM; d++) { if (ijk[d]<nt_in_fab[d]-1) { ijk[d]++; break; } else { ijk[d] = 0; } } for (int d=0; d<BL_SPACEDIM; d++) { if (ijk[d] < nleft[d]) { small[d] = ijk[d]*(tsize[d]+1); big[d] = small[d] + tsize[d]; } else { small[d] = ijk[d]*tsize[d] + nleft[d]; big[d] = small[d] + tsize[d] - 1; } } Box tbx(small, big, IndexType::TheCellType()); tbx.shift(bx.smallEnd()); ta.tileArray.push_back(tbx); } } }
void FabArrayBase::buildTileArray (const IntVect& tileSize, TileArray& ta) const { // Note that we store Tiles always as cell-centered boxes, even if the boxarray is nodal. const int N = indexMap.size(); if (tileSize == IntVect::TheZeroVector()) { for (int i = 0; i < N; ++i) { if (isOwner(i)) { const int K = indexMap[i]; const Box& bx = boxarray.getCellCenteredBox(K); ta.indexMap.push_back(K); ta.localIndexMap.push_back(i); ta.tileArray.push_back(bx); } } } else { #if defined(BL_USE_TEAM) && !defined(__INTEL_COMPILER) std::vector<int> local_idxs(N); std::iota(std::begin(local_idxs), std::end(local_idxs), 0); #else std::vector<int> local_idxs; for (int i = 0; i < N; ++i) local_idxs.push_back(i); #endif #if defined(BL_USE_TEAM) const int nworkers = ParallelDescriptor::TeamSize(); if (nworkers > 1) { // reorder it so that each worker will be more likely to work on their own fabs std::stable_sort(local_idxs.begin(), local_idxs.end(), [this](int i, int j) { return this->distributionMap[this->indexMap[i]] < this->distributionMap[this->indexMap[j]]; }); } #endif for (std::vector<int>::const_iterator it = local_idxs.begin(); it != local_idxs.end(); ++it) { const int i = *it; // local index const int K = indexMap[i]; // global index const Box& bx = boxarray.getCellCenteredBox(K); IntVect nt_in_fab, tsize, nleft; int ntiles = 1; for (int d=0; d<BL_SPACEDIM; d++) { int ncells = bx.length(d); nt_in_fab[d] = std::max(ncells/tileSize[d], 1); tsize [d] = ncells/nt_in_fab[d]; nleft [d] = ncells - nt_in_fab[d]*tsize[d]; ntiles *= nt_in_fab[d]; } IntVect small, big, ijk; // note that the initial values are all zero. ijk[0] = -1; for (int t = 0; t < ntiles; ++t) { ta.indexMap.push_back(K); ta.localIndexMap.push_back(i); for (int d=0; d<BL_SPACEDIM; d++) { if (ijk[d]<nt_in_fab[d]-1) { ijk[d]++; break; } else { ijk[d] = 0; } } for (int d=0; d<BL_SPACEDIM; d++) { if (ijk[d] < nleft[d]) { small[d] = ijk[d]*(tsize[d]+1); big[d] = small[d] + tsize[d]; } else { small[d] = ijk[d]*tsize[d] + nleft[d]; big[d] = small[d] + tsize[d] - 1; } } Box tbx(small, big, IndexType::TheCellType()); tbx.shift(bx.smallEnd()); ta.tileArray.push_back(tbx); } } } }