Skip to content

Commit

Permalink
New EB optimization parameter: eb2.num_coarsen_opt (AMReX-Codes#2872)
Browse files Browse the repository at this point in the history
At the beginning of EB generation, we chop the entire finest domain into
boxes and find out the type of the boxes.  We then collect the completely
covered boxes and cut boxes into two BoxArrays.  This process can be costly
because of the number of calls to the implicit functions.  In this commit,
we have introduced a new ParmParse parameter, eb2.num_coarsen_opt with a
default value of zero.  If for instance it is set to 3, we start the box
type categorization at a resolution that is coarsened by a factor of 2^3.
For the provisional cut boxes, we refine them by a factor of 2, Then we chop
them into small boxes and categorize the new boxes.  This process is
performed recursively until we are at the original finest resolution.

The users should be aware that, if eb2.num_coaren_opt is too big, this could
produce in erroneous results because evaluating the implicit function on
coarse boxes could miss fine structures in the EB.

Thank Robert Marskar for sharing this algorithm.
  • Loading branch information
WeiqunZhang authored Jul 8, 2022
1 parent 557aae8 commit c849dd1
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 68 deletions.
4 changes: 2 additions & 2 deletions Src/Base/AMReX_Box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ AllGatherBoxes (Vector<Box>& bxs, int n_extra_reserve)
if (count_tot == 0) return;

if (count_tot > static_cast<Long>(std::numeric_limits<int>::max())) {
amrex::Abort("AllGatherBoxes: not many boxes");
amrex::Abort("AllGatherBoxes: too many boxes");
}

Vector<Box> recv_buffer;
Expand Down Expand Up @@ -161,7 +161,7 @@ AllGatherBoxes (Vector<Box>& bxs, int n_extra_reserve)
if (count_tot == 0) return;

if (count_tot > static_cast<Long>(std::numeric_limits<int>::max())) {
amrex::Abort("AllGatherBoxes: not many boxes");
amrex::Abort("AllGatherBoxes: too many boxes");
}

Vector<Box> recv_buffer;
Expand Down
13 changes: 9 additions & 4 deletions Src/EB/AMReX_EB2.H
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ public:
IndexSpaceImp (const G& gshop, const Geometry& geom,
int required_coarsening_level, int max_coarsening_level,
int ngrow, bool build_coarse_level_by_coarsening,
bool extend_domain_face);
bool extend_domain_face, int num_coarsen_opt);

IndexSpaceImp (IndexSpaceImp<G> const&) = delete;
IndexSpaceImp (IndexSpaceImp<G> &&) = delete;
Expand Down Expand Up @@ -95,27 +95,32 @@ private:
#include <AMReX_EB2_IndexSpaceI.H>

bool ExtendDomainFace ();
int NumCoarsenOpt ();

template <typename G>
void
Build (const G& gshop, const Geometry& geom,
int required_coarsening_level, int max_coarsening_level,
int ngrow = 4, bool build_coarse_level_by_coarsening = true,
bool extend_domain_face = ExtendDomainFace())
bool extend_domain_face = ExtendDomainFace(),
int num_coarsen_opt = NumCoarsenOpt())
{
BL_PROFILE("EB2::Initialize()");
IndexSpace::push(new IndexSpaceImp<G>(gshop, geom,
required_coarsening_level,
max_coarsening_level,
ngrow, build_coarse_level_by_coarsening,
extend_domain_face));
extend_domain_face,
num_coarsen_opt));
}

void Build (const Geometry& geom,
int required_coarsening_level,
int max_coarsening_level,
int ngrow = 4,
bool build_coarse_level_by_coarsening = true);
bool build_coarse_level_by_coarsening = true,
bool extend_domain_face = ExtendDomainFace(),
int num_coarsen_opt = NumCoarsenOpt());

int maxCoarseningLevel (const Geometry& geom);
int maxCoarseningLevel (IndexSpace const* ebis, const Geometry& geom);
Expand Down
34 changes: 25 additions & 9 deletions Src/EB/AMReX_EB2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ AMREX_EXPORT Vector<std::unique_ptr<IndexSpace> > IndexSpace::m_instance;

AMREX_EXPORT int max_grid_size = 64;
AMREX_EXPORT bool extend_domain_face = true;
AMREX_EXPORT int num_coarsen_opt = 0;

void Initialize ()
{
ParmParse pp("eb2");
pp.queryAdd("max_grid_size", max_grid_size);
pp.queryAdd("extend_domain_face", extend_domain_face);
pp.queryAdd("num_coarsen_opt", num_coarsen_opt);

amrex::ExecOnFinalize(Finalize);
}
Expand All @@ -41,6 +43,11 @@ bool ExtendDomainFace ()
return extend_domain_face;
}

int NumCoarsenOpt ()
{
return num_coarsen_opt;
}

void
IndexSpace::push (IndexSpace* ispace)
{
Expand Down Expand Up @@ -74,7 +81,8 @@ const IndexSpace* TopIndexSpaceIfPresent() noexcept {

void
Build (const Geometry& geom, int required_coarsening_level,
int max_coarsening_level, int ngrow, bool build_coarse_level_by_coarsening)
int max_coarsening_level, int ngrow, bool build_coarse_level_by_coarsening,
bool a_extend_domain_face, int a_num_coarsen_opt)
{
ParmParse pp("eb2");
std::string geom_type;
Expand All @@ -85,7 +93,8 @@ Build (const Geometry& geom, int required_coarsening_level,
EB2::AllRegularIF rif;
EB2::GeometryShop<EB2::AllRegularIF> gshop(rif);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "box")
{
Expand All @@ -102,7 +111,8 @@ Build (const Geometry& geom, int required_coarsening_level,

EB2::GeometryShop<EB2::BoxIF> gshop(bf);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "cylinder")
{
Expand All @@ -127,7 +137,8 @@ Build (const Geometry& geom, int required_coarsening_level,

EB2::GeometryShop<EB2::CylinderIF> gshop(cf);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "plane")
{
Expand All @@ -141,7 +152,8 @@ Build (const Geometry& geom, int required_coarsening_level,

EB2::GeometryShop<EB2::PlaneIF> gshop(pf);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "sphere")
{
Expand All @@ -158,7 +170,8 @@ Build (const Geometry& geom, int required_coarsening_level,

EB2::GeometryShop<EB2::SphereIF> gshop(sf);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "torus")
{
Expand All @@ -177,7 +190,8 @@ Build (const Geometry& geom, int required_coarsening_level,

EB2::GeometryShop<EB2::TorusIF> gshop(sf);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "parser")
{
Expand All @@ -188,7 +202,8 @@ Build (const Geometry& geom, int required_coarsening_level,
EB2::ParserIF pif(parser.compile<3>());
EB2::GeometryShop<EB2::ParserIF,Parser> gshop(pif,parser);
EB2::Build(gshop, geom, required_coarsening_level,
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
a_extend_domain_face, a_num_coarsen_opt);
}
else if (geom_type == "stl")
{
Expand All @@ -206,7 +221,8 @@ Build (const Geometry& geom, int required_coarsening_level,
geom, required_coarsening_level,
max_coarsening_level, ngrow,
build_coarse_level_by_coarsening,
extend_domain_face));
a_extend_domain_face,
a_num_coarsen_opt));
}
else
{
Expand Down
8 changes: 5 additions & 3 deletions Src/EB/AMReX_EB2_IndexSpaceI.H
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
int required_coarsening_level,
int max_coarsening_level,
int ngrow, bool build_coarse_level_by_coarsening,
bool extend_domain_face)
bool extend_domain_face, int num_coarsen_opt)
{
// build finest level (i.e., level 0) first
AMREX_ALWAYS_ASSERT(required_coarsening_level >= 0 && required_coarsening_level <= 30);
Expand All @@ -20,7 +20,8 @@ IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
m_domain.push_back(geom.Domain());
m_ngrow.push_back(ngrow_finest);
m_gslevel.reserve(max_coarsening_level+1);
m_gslevel.emplace_back(this, gshop, geom, EB2::max_grid_size, ngrow_finest, extend_domain_face);
m_gslevel.emplace_back(this, gshop, geom, EB2::max_grid_size, ngrow_finest, extend_domain_face,
num_coarsen_opt);

for (int ilev = 1; ilev <= max_coarsening_level; ++ilev)
{
Expand All @@ -44,7 +45,8 @@ IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
if (build_coarse_level_by_coarsening) {
amrex::Abort("Failed to build required coarse EB level "+std::to_string(ilev));
} else {
m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face);
m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face,
num_coarsen_opt-ilev);
}
} else {
break;
Expand Down
2 changes: 1 addition & 1 deletion Src/EB/AMReX_EB2_IndexSpace_STL.H
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public:
const Geometry& geom, int required_coarsening_level,
int max_coarsening_level, int ngrow,
bool build_coarse_level_by_coarsening,
bool extend_domain_face);
bool extend_domain_face, int num_coarsen_opt);

IndexSpaceSTL (IndexSpaceSTL const&) = delete;
IndexSpaceSTL (IndexSpaceSTL &&) = delete;
Expand Down
6 changes: 3 additions & 3 deletions Src/EB/AMReX_EB2_IndexSpace_STL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ IndexSpaceSTL::IndexSpaceSTL (const std::string& stl_file, Real stl_scale,
const Geometry& geom, int required_coarsening_level,
int max_coarsening_level, int ngrow,
bool build_coarse_level_by_coarsening,
bool extend_domain_face)
bool extend_domain_face, int num_coarsen_opt)
{
Gpu::LaunchSafeGuard lsg(true); // Always use GPU

Expand All @@ -29,7 +29,7 @@ IndexSpaceSTL::IndexSpaceSTL (const std::string& stl_file, Real stl_scale,
m_ngrow.push_back(ngrow_finest);
m_stllevel.reserve(max_coarsening_level+1);
m_stllevel.emplace_back(this, stl_tools, geom, EB2::max_grid_size, ngrow_finest,
extend_domain_face);
extend_domain_face, num_coarsen_opt);

for (int ilev = 1; ilev <= max_coarsening_level; ++ilev)
{
Expand All @@ -54,7 +54,7 @@ IndexSpaceSTL::IndexSpaceSTL (const std::string& stl_file, Real stl_scale,
amrex::Abort("Failed to build required coarse EB level "+std::to_string(ilev));
} else {
m_stllevel.emplace_back(this, stl_tools, cgeom, EB2::max_grid_size, ng,
extend_domain_face);
extend_domain_face, num_coarsen_opt-ilev);
}
} else {
break;
Expand Down
Loading

0 comments on commit c849dd1

Please sign in to comment.