Block-Structured AMR Software Framework
 
Loading...
Searching...
No Matches
AMReX_EB2_IndexSpaceI.H
Go to the documentation of this file.
1
2template <typename G>
3IndexSpaceImp<G>::IndexSpaceImp (const G& gshop, const Geometry& geom,
4 int required_coarsening_level,
5 int max_coarsening_level,
6 int ngrow, bool build_coarse_level_by_coarsening,
7 bool extend_domain_face, int num_coarsen_opt)
8 : m_gshop(gshop),
9 m_build_coarse_level_by_coarsening(build_coarse_level_by_coarsening),
10 m_extend_domain_face(extend_domain_face),
11 m_num_coarsen_opt(num_coarsen_opt)
12{
13 // build finest level (i.e., level 0) first
14 AMREX_ALWAYS_ASSERT(required_coarsening_level >= 0 && required_coarsening_level <= 30);
15 max_coarsening_level = std::max(required_coarsening_level,max_coarsening_level);
16 max_coarsening_level = std::min(30,max_coarsening_level);
17
18 int ngrow_finest = std::max(ngrow,0);
19 for (int i = 1; i <= required_coarsening_level; ++i) {
20 ngrow_finest *= 2;
21 }
22
23 m_geom.push_back(geom);
24 m_domain.push_back(geom.Domain());
25 m_ngrow.push_back(ngrow_finest);
26 m_gslevel.reserve(max_coarsening_level+1);
27 m_gslevel.emplace_back(this, gshop, geom, EB2::max_grid_size, ngrow_finest, extend_domain_face,
29
30 for (int ilev = 1; ilev <= max_coarsening_level; ++ilev)
31 {
32 bool coarsenable = m_geom.back().Domain().coarsenable(2,2);
33 if (!coarsenable) {
34 if (ilev <= required_coarsening_level) {
35 amrex::Abort("IndexSpaceImp: domain is not coarsenable at level "+std::to_string(ilev));
36 } else {
37 break;
38 }
39 }
40
41 int ng = (ilev > required_coarsening_level) ? 0 : m_ngrow.back()/2;
42
43 Box cdomain = amrex::coarsen(m_geom.back().Domain(),2);
44 Geometry cgeom = amrex::coarsen(m_geom.back(),2);
45 m_gslevel.emplace_back(this, ilev, EB2::max_grid_size, ng, cgeom, m_gslevel[ilev-1]);
46 if (!m_gslevel.back().isOK()) {
47 m_gslevel.pop_back();
48 if (ilev <= required_coarsening_level) {
49 if (build_coarse_level_by_coarsening) {
50 amrex::Abort("Failed to build required coarse EB level "+std::to_string(ilev));
51 } else {
52 m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face,
53 num_coarsen_opt-ilev);
54 }
55 } else {
56 break;
57 }
58 }
59 m_geom.push_back(cgeom);
60 m_domain.push_back(cdomain);
61 m_ngrow.push_back(ng);
62 }
63}
64
65
66template <typename G>
68 int ngrow,
70 : m_gshop(gshop),
71 m_build_coarse_level_by_coarsening(false),
72 m_extend_domain_face(extend_domain_face),
73 m_num_coarsen_opt(num_coarsen_opt)
74{
75
76 auto nlevels = int(geom.size());
77 m_gslevel.reserve(nlevels);
78
79 for (int ilev = 0; ilev < nlevels; ++ilev)
80 {
81 int ng = ngrow;
82 Geometry cgeom = geom[ilev];
83 Box cdomain = cgeom.Domain();
84 m_gslevel.emplace_back(this, gshop, cgeom, EB2::max_grid_size, ng, extend_domain_face,
85 num_coarsen_opt-ilev);
86 m_geom.push_back(cgeom);
87 m_domain.push_back(cdomain);
88 m_ngrow.push_back(ng);
89 }
90}
91
92template <typename G>
93const Level&
95{
96 auto it = std::find(std::begin(m_domain), std::end(m_domain), geom.Domain());
97 int i = std::distance(m_domain.begin(), it);
98 return m_gslevel[i];
99}
100
101template <typename G>
102const Geometry&
104{
105 auto it = std::find(std::begin(m_domain), std::end(m_domain), dom);
106 int i = std::distance(m_domain.begin(), it);
107 return m_geom[i];
108}
109
110template <typename G>
111void
112IndexSpaceImp<G>::addFineLevels (int num_new_fine_levels)
113{
114 if (num_new_fine_levels <= 0) { return; }
115
116 if (m_num_coarsen_opt > 0) {
117 m_num_coarsen_opt += num_new_fine_levels;
118 }
119
120 IndexSpaceImp<G> fine_isp(m_gshop, amrex::refine(m_geom[0], 1<<num_new_fine_levels),
121 num_new_fine_levels-1, num_new_fine_levels-1,
122 m_ngrow[0], m_build_coarse_level_by_coarsening,
123 m_extend_domain_face, m_num_coarsen_opt);
124
125 fine_isp.m_gslevel.reserve(m_domain.size()+num_new_fine_levels);
126 for (int i = 0; i < m_domain.size(); ++i) {
127 fine_isp.m_gslevel.emplace_back(std::move(m_gslevel[i]));
128 }
129 std::swap(fine_isp.m_gslevel, m_gslevel);
130
131 m_geom.insert(m_geom.begin(), fine_isp.m_geom.begin(), fine_isp.m_geom.end());
132 m_domain.insert(m_domain.begin(), fine_isp.m_domain.begin(), fine_isp.m_domain.end());
133 m_ngrow.insert(m_ngrow.begin(), fine_isp.m_ngrow.begin(), fine_isp.m_ngrow.end());
134}
135
136template <typename G>
137void
139{
140 if (num_new_coarse_levels <= 0) { return; }
141
142 auto nlevs_old = int(m_gslevel.size());
143 int nlevs_new = nlevs_old + num_new_coarse_levels;
144
145 Vector<GShopLevel<G>> new_gslevel;
146 new_gslevel.reserve(nlevs_new);
147
148 Vector<Geometry> new_geom;
149 new_geom.reserve(nlevs_new);
150
151 Vector<Box> new_domain;
152 new_domain.reserve(nlevs_new);
153
154 Vector<int> new_ngrow;
155 new_ngrow.reserve(nlevs_new);
156
157 for (int ilev = 0; ilev < num_new_coarse_levels; ++ilev) {
158 int rr = 1 << (num_new_coarse_levels-ilev); // 2^(num_new_coarse_levels-ilev)
159 new_geom.push_back(amrex::coarsen(m_geom[0], rr));
160 new_domain.push_back(new_geom.back().Domain());
161 new_ngrow.push_back(m_ngrow[0]);
162 new_gslevel.push_back(GShopLevel<G>::makeAllRegular(this, new_geom.back()));
163 }
164
165 for (int ilev = 0; ilev < nlevs_old; ++ilev) {
166 new_gslevel.emplace_back(std::move(m_gslevel[ilev]));
167 new_geom.push_back (m_geom [ilev]);
168 new_domain.push_back(m_domain[ilev]);
169 new_ngrow.push_back (m_ngrow [ilev]);
170 }
171
172 std::swap(new_gslevel, m_gslevel);
173 std::swap(new_geom , m_geom);
174 std::swap(new_domain , m_domain);
175 std::swap(new_ngrow , m_ngrow);
176
177 for (int ilev = num_new_coarse_levels-1; ilev >= 0; --ilev) {
178 m_gslevel[ilev].buildCutCellMask(m_gslevel[ilev+1]);
179 }
180}
181
182template <typename G>
183void
184IndexSpaceImp<G>::setShift (int direction, int ncells)
185{
186 auto nlevs = int(m_gslevel.size());
187 for (int ilev = nlevs-1; ilev >= 0; --ilev) {
188 m_gslevel[ilev].setShift(direction, ncells);
189 ncells *= 2;
190 }
191}
#define AMREX_ALWAYS_ASSERT(EX)
Definition AMReX_BLassert.H:50
Definition AMReX_EB2_Level.H:118
Definition AMReX_EB2.H:75
const Level & getLevel(const Geometry &geom) const final
Definition AMReX_EB2_IndexSpaceI.H:94
Vector< GShopLevel< G > > m_gslevel
Definition AMReX_EB2.H:113
Vector< int > m_ngrow
Definition AMReX_EB2.H:116
void addFineLevels(int num_new_fine_levels) final
Definition AMReX_EB2_IndexSpaceI.H:112
Vector< Geometry > m_geom
Definition AMReX_EB2.H:114
void addRegularCoarseLevels(int num_new_coarse_levels) final
Definition AMReX_EB2_IndexSpaceI.H:138
Vector< Box > m_domain
Definition AMReX_EB2.H:115
const Geometry & getGeometry(const Box &dom) const final
Definition AMReX_EB2_IndexSpaceI.H:103
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:3
void setShift(int direction, int ncells) override
Definition AMReX_EB2_IndexSpaceI.H:184
Definition AMReX_EB2_Level.H:33
Rectangular problem domain geometry.
Definition AMReX_Geometry.H:73
const Box & Domain() const noexcept
Returns our rectangular domain.
Definition AMReX_Geometry.H:210
This class is a thin wrapper around std::vector. Unlike vector, Vector::operator[] provides bound che...
Definition AMReX_Vector.H:28
Long size() const noexcept
Definition AMReX_Vector.H:53
int max_grid_size
Definition AMReX_EB2.cpp:23
int num_coarsen_opt
Definition AMReX_EB2.cpp:25
bool extend_domain_face
Definition AMReX_EB2.cpp:24
__host__ __device__ BoxND< dim > coarsen(const BoxND< dim > &b, int ref_ratio) noexcept
Coarsen BoxND by given (positive) refinement ratio. NOTE: if type(dir) = CELL centered: lo <- lo/rati...
Definition AMReX_Box.H:1322
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition AMReX.cpp:230
__host__ __device__ BoxND< dim > refine(const BoxND< dim > &b, int ref_ratio) noexcept
Definition AMReX_Box.H:1360