Skip to content

Commit c849dd1

Browse files
authored
New EB optimization parameter: eb2.num_coarsen_opt (AMReX-Codes#2872)
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.
1 parent 557aae8 commit c849dd1

File tree

11 files changed

+121
-68
lines changed

11 files changed

+121
-68
lines changed

Src/Base/AMReX_Box.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ AllGatherBoxes (Vector<Box>& bxs, int n_extra_reserve)
126126
if (count_tot == 0) return;
127127

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

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

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

167167
Vector<Box> recv_buffer;

Src/EB/AMReX_EB2.H

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public:
6666
IndexSpaceImp (const G& gshop, const Geometry& geom,
6767
int required_coarsening_level, int max_coarsening_level,
6868
int ngrow, bool build_coarse_level_by_coarsening,
69-
bool extend_domain_face);
69+
bool extend_domain_face, int num_coarsen_opt);
7070

7171
IndexSpaceImp (IndexSpaceImp<G> const&) = delete;
7272
IndexSpaceImp (IndexSpaceImp<G> &&) = delete;
@@ -95,27 +95,32 @@ private:
9595
#include <AMReX_EB2_IndexSpaceI.H>
9696

9797
bool ExtendDomainFace ();
98+
int NumCoarsenOpt ();
9899

99100
template <typename G>
100101
void
101102
Build (const G& gshop, const Geometry& geom,
102103
int required_coarsening_level, int max_coarsening_level,
103104
int ngrow = 4, bool build_coarse_level_by_coarsening = true,
104-
bool extend_domain_face = ExtendDomainFace())
105+
bool extend_domain_face = ExtendDomainFace(),
106+
int num_coarsen_opt = NumCoarsenOpt())
105107
{
106108
BL_PROFILE("EB2::Initialize()");
107109
IndexSpace::push(new IndexSpaceImp<G>(gshop, geom,
108110
required_coarsening_level,
109111
max_coarsening_level,
110112
ngrow, build_coarse_level_by_coarsening,
111-
extend_domain_face));
113+
extend_domain_face,
114+
num_coarsen_opt));
112115
}
113116

114117
void Build (const Geometry& geom,
115118
int required_coarsening_level,
116119
int max_coarsening_level,
117120
int ngrow = 4,
118-
bool build_coarse_level_by_coarsening = true);
121+
bool build_coarse_level_by_coarsening = true,
122+
bool extend_domain_face = ExtendDomainFace(),
123+
int num_coarsen_opt = NumCoarsenOpt());
119124

120125
int maxCoarseningLevel (const Geometry& geom);
121126
int maxCoarseningLevel (IndexSpace const* ebis, const Geometry& geom);

Src/EB/AMReX_EB2.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@ AMREX_EXPORT Vector<std::unique_ptr<IndexSpace> > IndexSpace::m_instance;
2121

2222
AMREX_EXPORT int max_grid_size = 64;
2323
AMREX_EXPORT bool extend_domain_face = true;
24+
AMREX_EXPORT int num_coarsen_opt = 0;
2425

2526
void Initialize ()
2627
{
2728
ParmParse pp("eb2");
2829
pp.queryAdd("max_grid_size", max_grid_size);
2930
pp.queryAdd("extend_domain_face", extend_domain_face);
31+
pp.queryAdd("num_coarsen_opt", num_coarsen_opt);
3032

3133
amrex::ExecOnFinalize(Finalize);
3234
}
@@ -41,6 +43,11 @@ bool ExtendDomainFace ()
4143
return extend_domain_face;
4244
}
4345

46+
int NumCoarsenOpt ()
47+
{
48+
return num_coarsen_opt;
49+
}
50+
4451
void
4552
IndexSpace::push (IndexSpace* ispace)
4653
{
@@ -74,7 +81,8 @@ const IndexSpace* TopIndexSpaceIfPresent() noexcept {
7481

7582
void
7683
Build (const Geometry& geom, int required_coarsening_level,
77-
int max_coarsening_level, int ngrow, bool build_coarse_level_by_coarsening)
84+
int max_coarsening_level, int ngrow, bool build_coarse_level_by_coarsening,
85+
bool a_extend_domain_face, int a_num_coarsen_opt)
7886
{
7987
ParmParse pp("eb2");
8088
std::string geom_type;
@@ -85,7 +93,8 @@ Build (const Geometry& geom, int required_coarsening_level,
8593
EB2::AllRegularIF rif;
8694
EB2::GeometryShop<EB2::AllRegularIF> gshop(rif);
8795
EB2::Build(gshop, geom, required_coarsening_level,
88-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
96+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
97+
a_extend_domain_face, a_num_coarsen_opt);
8998
}
9099
else if (geom_type == "box")
91100
{
@@ -102,7 +111,8 @@ Build (const Geometry& geom, int required_coarsening_level,
102111

103112
EB2::GeometryShop<EB2::BoxIF> gshop(bf);
104113
EB2::Build(gshop, geom, required_coarsening_level,
105-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
114+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
115+
a_extend_domain_face, a_num_coarsen_opt);
106116
}
107117
else if (geom_type == "cylinder")
108118
{
@@ -127,7 +137,8 @@ Build (const Geometry& geom, int required_coarsening_level,
127137

128138
EB2::GeometryShop<EB2::CylinderIF> gshop(cf);
129139
EB2::Build(gshop, geom, required_coarsening_level,
130-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
140+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
141+
a_extend_domain_face, a_num_coarsen_opt);
131142
}
132143
else if (geom_type == "plane")
133144
{
@@ -141,7 +152,8 @@ Build (const Geometry& geom, int required_coarsening_level,
141152

142153
EB2::GeometryShop<EB2::PlaneIF> gshop(pf);
143154
EB2::Build(gshop, geom, required_coarsening_level,
144-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
155+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
156+
a_extend_domain_face, a_num_coarsen_opt);
145157
}
146158
else if (geom_type == "sphere")
147159
{
@@ -158,7 +170,8 @@ Build (const Geometry& geom, int required_coarsening_level,
158170

159171
EB2::GeometryShop<EB2::SphereIF> gshop(sf);
160172
EB2::Build(gshop, geom, required_coarsening_level,
161-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
173+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
174+
a_extend_domain_face, a_num_coarsen_opt);
162175
}
163176
else if (geom_type == "torus")
164177
{
@@ -177,7 +190,8 @@ Build (const Geometry& geom, int required_coarsening_level,
177190

178191
EB2::GeometryShop<EB2::TorusIF> gshop(sf);
179192
EB2::Build(gshop, geom, required_coarsening_level,
180-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
193+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
194+
a_extend_domain_face, a_num_coarsen_opt);
181195
}
182196
else if (geom_type == "parser")
183197
{
@@ -188,7 +202,8 @@ Build (const Geometry& geom, int required_coarsening_level,
188202
EB2::ParserIF pif(parser.compile<3>());
189203
EB2::GeometryShop<EB2::ParserIF,Parser> gshop(pif,parser);
190204
EB2::Build(gshop, geom, required_coarsening_level,
191-
max_coarsening_level, ngrow, build_coarse_level_by_coarsening);
205+
max_coarsening_level, ngrow, build_coarse_level_by_coarsening,
206+
a_extend_domain_face, a_num_coarsen_opt);
192207
}
193208
else if (geom_type == "stl")
194209
{
@@ -206,7 +221,8 @@ Build (const Geometry& geom, int required_coarsening_level,
206221
geom, required_coarsening_level,
207222
max_coarsening_level, ngrow,
208223
build_coarse_level_by_coarsening,
209-
extend_domain_face));
224+
a_extend_domain_face,
225+
a_num_coarsen_opt));
210226
}
211227
else
212228
{

Src/EB/AMReX_EB2_IndexSpaceI.H

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
44
int required_coarsening_level,
55
int max_coarsening_level,
66
int ngrow, bool build_coarse_level_by_coarsening,
7-
bool extend_domain_face)
7+
bool extend_domain_face, int num_coarsen_opt)
88
{
99
// build finest level (i.e., level 0) first
1010
AMREX_ALWAYS_ASSERT(required_coarsening_level >= 0 && required_coarsening_level <= 30);
@@ -20,7 +20,8 @@ IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
2020
m_domain.push_back(geom.Domain());
2121
m_ngrow.push_back(ngrow_finest);
2222
m_gslevel.reserve(max_coarsening_level+1);
23-
m_gslevel.emplace_back(this, gshop, geom, EB2::max_grid_size, ngrow_finest, extend_domain_face);
23+
m_gslevel.emplace_back(this, gshop, geom, EB2::max_grid_size, ngrow_finest, extend_domain_face,
24+
num_coarsen_opt);
2425

2526
for (int ilev = 1; ilev <= max_coarsening_level; ++ilev)
2627
{
@@ -44,7 +45,8 @@ IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
4445
if (build_coarse_level_by_coarsening) {
4546
amrex::Abort("Failed to build required coarse EB level "+std::to_string(ilev));
4647
} else {
47-
m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face);
48+
m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face,
49+
num_coarsen_opt-ilev);
4850
}
4951
} else {
5052
break;

Src/EB/AMReX_EB2_IndexSpace_STL.H

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public:
1919
const Geometry& geom, int required_coarsening_level,
2020
int max_coarsening_level, int ngrow,
2121
bool build_coarse_level_by_coarsening,
22-
bool extend_domain_face);
22+
bool extend_domain_face, int num_coarsen_opt);
2323

2424
IndexSpaceSTL (IndexSpaceSTL const&) = delete;
2525
IndexSpaceSTL (IndexSpaceSTL &&) = delete;

Src/EB/AMReX_EB2_IndexSpace_STL.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ IndexSpaceSTL::IndexSpaceSTL (const std::string& stl_file, Real stl_scale,
77
const Geometry& geom, int required_coarsening_level,
88
int max_coarsening_level, int ngrow,
99
bool build_coarse_level_by_coarsening,
10-
bool extend_domain_face)
10+
bool extend_domain_face, int num_coarsen_opt)
1111
{
1212
Gpu::LaunchSafeGuard lsg(true); // Always use GPU
1313

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

3434
for (int ilev = 1; ilev <= max_coarsening_level; ++ilev)
3535
{
@@ -54,7 +54,7 @@ IndexSpaceSTL::IndexSpaceSTL (const std::string& stl_file, Real stl_scale,
5454
amrex::Abort("Failed to build required coarse EB level "+std::to_string(ilev));
5555
} else {
5656
m_stllevel.emplace_back(this, stl_tools, cgeom, EB2::max_grid_size, ng,
57-
extend_domain_face);
57+
extend_domain_face, num_coarsen_opt-ilev);
5858
}
5959
} else {
6060
break;

0 commit comments

Comments
 (0)