Skip to content

Commit

Permalink
Make sure ChopGrids does not violate refinement ratio. (#4078)
Browse files Browse the repository at this point in the history
When using ChopGrids on fine level BoxArrays, we must make sure the box
sizes are multiples of refinement ratios.
  • Loading branch information
WeiqunZhang authored Aug 14, 2024
1 parent 5dedac0 commit b7083f0
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 5 deletions.
18 changes: 17 additions & 1 deletion Src/AmrCore/AMReX_AmrMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ AmrMesh::ChopGrids (int lev, BoxArray& ba, int target_size) const
IntVect chunk = max_grid_size[lev];
chunk.min(Geom(lev).Domain().length());

// Note that ba already satisfies the max_grid_size requirement and it's
// coarsenable if it's a fine level BoxArray.

while (ba.size() < target_size)
{
IntVect chunk_prev = chunk;
Expand All @@ -485,11 +488,24 @@ AmrMesh::ChopGrids (int lev, BoxArray& ba, int target_size) const
int idim = chunk_dir[idx].second;
if (refine_grid_layout_dims[idim]) {
int new_chunk_size = chunk[idim] / 2;
int rr = (lev > 0) ? ref_ratio[lev-1][idim] : 1;
if (rr > 1) {
new_chunk_size = (new_chunk_size/rr) * rr;
}
if (new_chunk_size != 0 &&
new_chunk_size%blocking_factor[lev][idim] == 0)
{
chunk[idim] = new_chunk_size;
ba.maxSize(chunk);
if (rr == 1) {
ba.maxSize(chunk);
} else {
IntVect bf(1);
bf[idim] = rr;
// Note that only idim-direction will be chopped by
// minmaxSize because the sizes in other directions
// are already smaller than chunk.
ba.minmaxSize(bf, chunk);
}
break;
}
}
Expand Down
5 changes: 5 additions & 0 deletions Src/Base/AMReX_BoxArray.H
Original file line number Diff line number Diff line change
Expand Up @@ -615,6 +615,11 @@ public:

BoxArray& maxSize (const IntVect& block_size);

//! Forces each Box in BoxArray to have sizes >= min_size and <=
//! max_size. It's the caller's responsibility to make sure both the
//! BoxArray and max_size are coarsenable by min_size.
BoxArray& minmaxSize (const IntVect& min_size, const IntVect& max_size);

//! Refine each Box in the BoxArray to the specified ratio.
BoxArray& refine (int refinement_ratio);

Expand Down
22 changes: 18 additions & 4 deletions Src/Base/AMReX_BoxArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -555,12 +555,26 @@ BoxArray::maxSize (const IntVect& block_size)
blst.maxSize(block_size);
const int N = static_cast<int>(blst.size());
if (size() != N) { // If size doesn't change, do nothing.
BoxList bak = (m_simplified_list) ? *m_simplified_list : BoxList();
auto bak = m_simplified_list;
define(std::move(blst));
if (bak.isNotEmpty()) {
m_simplified_list = std::make_shared<BoxList>(std::move(bak));
}
m_simplified_list = bak;
}
return *this;
}

BoxArray&
BoxArray::minmaxSize (const IntVect& min_size, const IntVect& max_size)
{
AMREX_ASSERT(this->coarsenable(min_size) &&
(max_size/min_size)*min_size == max_size);
std::shared_ptr<BoxList> bak;
if (m_bat.is_simple() && crseRatio() == IntVect::TheUnitVector()) {
bak = m_simplified_list;
}
this->coarsen(min_size);
this->maxSize(max_size/min_size);
this->refine(min_size);
m_simplified_list = bak;
return *this;
}

Expand Down

0 comments on commit b7083f0

Please sign in to comment.