Block-Structured AMR Software Framework
Loading...
Searching...
No Matches
AMReX_EB2_IndexSpaceI.H
Go to the documentation of this file.
1
9template <typename G>
10IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
11 int required_coarsening_level,
12 int max_coarsening_level,
13 int ngrow, bool build_coarse_level_by_coarsening,
14 bool extend_domain_face, int num_coarsen_opt)
15 : m_gshop(gshop),
16 m_build_coarse_level_by_coarsening(build_coarse_level_by_coarsening),
17 m_extend_domain_face(extend_domain_face),
18 m_num_coarsen_opt(num_coarsen_opt)
19{
20 // build finest level (i.e., level 0) first
21 AMREX_ALWAYS_ASSERT(required_coarsening_level >= 0 && required_coarsening_level <= 30);
22 max_coarsening_level = std::max(required_coarsening_level,max_coarsening_level);
23 max_coarsening_level = std::min(30,max_coarsening_level);
24
25 int ngrow_finest = std::max(ngrow,0);
26 for (int i = 1; i <= required_coarsening_level; ++i) {
27 ngrow_finest *= 2;
28 }
29
30 m_geom.push_back(geom);
31 m_domain.push_back(geom.Domain());
32 m_ngrow.push_back(ngrow_finest);
33 m_gslevel.reserve(max_coarsening_level+1);
34 m_gslevel.emplace_back(this, gshop, geom, EB2::max_grid_size, ngrow_finest, extend_domain_face,
35 num_coarsen_opt);
36
37 for (int ilev = 1; ilev <= max_coarsening_level; ++ilev)
38 {
39 bool coarsenable = m_geom.back().Domain().coarsenable(2,2);
40 if (!coarsenable) {
41 if (ilev <= required_coarsening_level) {
42 amrex::Abort("IndexSpaceImp: domain is not coarsenable at level "+std::to_string(ilev));
43 } else {
44 break;
45 }
46 }
47
48 int ng = (ilev > required_coarsening_level) ? 0 : m_ngrow.back()/2;
49
50 Box cdomain = amrex::coarsen(m_geom.back().Domain(),2);
51 Geometry cgeom = amrex::coarsen(m_geom.back(),2);
52 m_gslevel.emplace_back(this, ilev, EB2::max_grid_size, ng, cgeom, m_gslevel[ilev-1]);
53 if (!m_gslevel.back().isOK()) {
54 m_gslevel.pop_back();
55 if (ilev <= required_coarsening_level) {
56 if (build_coarse_level_by_coarsening) {
57 amrex::Abort("Failed to build required coarse EB level "+std::to_string(ilev));
58 } else {
59 m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face,
60 num_coarsen_opt-ilev);
61 }
62 } else {
63 break;
64 }
65 }
66 m_geom.push_back(cgeom);
67 m_domain.push_back(cdomain);
68 m_ngrow.push_back(ng);
69 }
70}
71
72
73template <typename G>
75 int ngrow,
76 bool extend_domain_face, int num_coarsen_opt)
77 : m_gshop(gshop),
78 m_build_coarse_level_by_coarsening(false),
79 m_extend_domain_face(extend_domain_face),
80 m_num_coarsen_opt(num_coarsen_opt)
81{
82
83 auto nlevels = int(geom.size());
84 m_gslevel.reserve(nlevels);
85
86 for (int ilev = 0; ilev < nlevels; ++ilev)
87 {
88 int ng = ngrow;
89 Geometry cgeom = geom[ilev];
90 Box cdomain = cgeom.Domain();
91 m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face,
92 num_coarsen_opt-ilev);
93 m_geom.push_back(cgeom);
94 m_domain.push_back(cdomain);
95 m_ngrow.push_back(ng);
96 }
97}
98
99template <typename G>
100const Level&
102{
103 auto it = std::ranges::find(m_domain, geom.Domain());
104 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(it != std::end(m_domain),
105 "IndexSpaceImp::getLevel: Geometry not found");
106 int i = std::distance(m_domain.begin(), it);
107 return m_gslevel[i];
108}
109
110template <typename G>
111const Geometry&
113{
114 auto it = std::ranges::find(m_domain, dom);
115 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(it != std::end(m_domain),
116 "IndexSpaceImp::getLevel: domain not found");
117 int i = std::distance(m_domain.begin(), it);
118 return m_geom[i];
119}
120
121template <typename G>
122void
123IndexSpaceImp<G>::addFineLevels (int num_new_fine_levels)
124{
125 if (num_new_fine_levels <= 0) { return; }
126 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(num_new_fine_levels <= 30,
127 "IndexSpaceImp::addFineLevels: num_new_fine_levels too large");
128
129 if (m_num_coarsen_opt > 0) {
130 m_num_coarsen_opt += num_new_fine_levels;
131 }
132
133 int rr_fine = static_cast<int>(1U << num_new_fine_levels);
134 IndexSpaceImp<G> fine_isp(m_gshop, amrex::refine(m_geom[0], rr_fine),
135 num_new_fine_levels-1, num_new_fine_levels-1,
136 m_ngrow[0], m_build_coarse_level_by_coarsening,
137 m_extend_domain_face, m_num_coarsen_opt);
138
139 fine_isp.m_gslevel.reserve(m_domain.size()+num_new_fine_levels);
140 for (int i = 0; i < m_domain.size(); ++i) {
141 fine_isp.m_gslevel.emplace_back(std::move(m_gslevel[i]));
142 }
143 std::swap(fine_isp.m_gslevel, m_gslevel);
144
145 // The new levels were built by fine_isp, which is about to be destroyed.
146 for (auto& lev : m_gslevel) {
147 lev.m_parent = this;
148 }
149
150 m_geom.insert(m_geom.begin(), fine_isp.m_geom.begin(), fine_isp.m_geom.end());
151 m_domain.insert(m_domain.begin(), fine_isp.m_domain.begin(), fine_isp.m_domain.end());
152 m_ngrow.insert(m_ngrow.begin(), fine_isp.m_ngrow.begin(), fine_isp.m_ngrow.end());
153}
154
155template <typename G>
156void
158{
159 if (num_new_coarse_levels <= 0) { return; }
160 AMREX_ALWAYS_ASSERT_WITH_MESSAGE(num_new_coarse_levels <= 30,
161 "IndexSpaceImp::addRegularCoarseLevels: num_new_coarse_levels too large");
162
163 auto nlevs_old = int(m_gslevel.size());
164 int nlevs_new = nlevs_old + num_new_coarse_levels;
165
166 Vector<GShopLevel<G>> new_gslevel;
167 new_gslevel.reserve(nlevs_new);
168
169 Vector<Geometry> new_geom;
170 new_geom.reserve(nlevs_new);
171
172 Vector<Box> new_domain;
173 new_domain.reserve(nlevs_new);
174
175 Vector<int> new_ngrow;
176 new_ngrow.reserve(nlevs_new);
177
178 for (int ilev = 0; ilev < num_new_coarse_levels; ++ilev) {
179 int rr = static_cast<int>(1U << (num_new_coarse_levels-ilev)); // 2^(num_new_coarse_levels-ilev)
180 new_geom.push_back(amrex::coarsen(m_geom[0], rr));
181 new_domain.push_back(new_geom.back().Domain());
182 new_ngrow.push_back(m_ngrow[0]);
183 new_gslevel.push_back(GShopLevel<G>::makeAllRegular(this, new_geom.back()));
184 }
185
186 for (int ilev = 0; ilev < nlevs_old; ++ilev) {
187 new_gslevel.emplace_back(std::move(m_gslevel[ilev]));
188 new_geom.push_back (m_geom [ilev]);
189 new_domain.push_back(m_domain[ilev]);
190 new_ngrow.push_back (m_ngrow [ilev]);
191 }
192
193 std::swap(new_gslevel, m_gslevel);
194 std::swap(new_geom , m_geom);
195 std::swap(new_domain , m_domain);
196 std::swap(new_ngrow , m_ngrow);
197
198 for (int ilev = num_new_coarse_levels-1; ilev >= 0; --ilev) {
199 m_gslevel[ilev].buildCutCellMask(m_gslevel[ilev+1]);
200 }
201}
202
203template <typename G>
204void
205IndexSpaceImp<G>::setShift (int direction, int ncells)
206{
207 auto nlevs = int(m_gslevel.size());
208 for (int ilev = nlevs-1; ilev >= 0; --ilev) {
209 m_gslevel[ilev].setShift(direction, ncells);
210 ncells *= 2;
211 }
212}
213
214template <typename G>
215void
217{
218 for (int face_dir = 0; face_dir < AMREX_SPACEDIM; ++face_dir) {
219 for (int ilev = 0; ilev < int(m_gslevel.size()); ++ilev) {
220 m_gslevel[ilev].buildFCData(m_gshop, face_dir, EB2::max_grid_size);
221 }
222 }
223}
#define AMREX_ALWAYS_ASSERT_WITH_MESSAGE(EX, MSG)
Definition AMReX_BLassert.H:49
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
Definition AMReX_EB2_Level.H:293
Definition AMReX_EB2.H:84
const Level & getLevel(const Geometry &geom) const final
Definition AMReX_EB2_IndexSpaceI.H:101
void addFineLevels(int num_new_fine_levels) final
Definition AMReX_EB2_IndexSpaceI.H:123
void addRegularCoarseLevels(int num_new_coarse_levels) final
Definition AMReX_EB2_IndexSpaceI.H:157
const Geometry & getGeometry(const Box &dom) const final
Definition AMReX_EB2_IndexSpaceI.H:112
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, int num_coarsen_opt)
Definition AMReX_EB2_IndexSpaceI.H:10
void setShift(int direction, int ncells) override
Definition AMReX_EB2_IndexSpaceI.H:205
void buildAllFCData() override
Build face-centered EB data for all three face directions.
Definition AMReX_EB2_IndexSpaceI.H:216
Definition AMReX_EB2_Level.H:43
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:85
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:244
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:29
Long size() const noexcept
Definition AMReX_Vector.H:54
__host__ __device__ BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
Return a copy of b coarsened by the isotropic ratio ref_ratio.
Definition AMReX_Box.H:1469
__host__ __device__ BoxND< dim > refine(const BoxND< dim > &b, int ref_ratio) noexcept
Return a copy of b refined by the isotropic ratio ref_ratio.
Definition AMReX_Box.H:1510
void Abort(const std::string &msg)
Print a fatal-error message to stderr and abort execution.
Definition AMReX.cpp:242
const int[]
Definition AMReX_BLProfiler.cpp:1665