Block-Structured AMR Software Framework
AMReX_EB2_IndexSpaceI.H
Go to the documentation of this file.
1 
2 template <typename G>
3 IndexSpaceImp<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,
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 
66 template <typename G>
67 const Level&
69 {
70  auto it = std::find(std::begin(m_domain), std::end(m_domain), geom.Domain());
71  int i = std::distance(m_domain.begin(), it);
72  return m_gslevel[i];
73 }
74 
75 template <typename G>
76 const Geometry&
78 {
79  auto it = std::find(std::begin(m_domain), std::end(m_domain), dom);
80  int i = std::distance(m_domain.begin(), it);
81  return m_geom[i];
82 }
83 
84 template <typename G>
85 void
86 IndexSpaceImp<G>::addFineLevels (int num_new_fine_levels)
87 {
88  if (num_new_fine_levels <= 0) { return; }
89 
90  if (m_num_coarsen_opt > 0) {
91  m_num_coarsen_opt += num_new_fine_levels;
92  }
93 
94  IndexSpaceImp<G> fine_isp(m_gshop, amrex::refine(m_geom[0], 1<<num_new_fine_levels),
95  num_new_fine_levels-1, num_new_fine_levels-1,
96  m_ngrow[0], m_build_coarse_level_by_coarsening,
97  m_extend_domain_face, m_num_coarsen_opt);
98 
99  fine_isp.m_gslevel.reserve(m_domain.size()+num_new_fine_levels);
100  for (int i = 0; i < m_domain.size(); ++i) {
101  fine_isp.m_gslevel.emplace_back(std::move(m_gslevel[i]));
102  }
103  std::swap(fine_isp.m_gslevel, m_gslevel);
104 
105  m_geom.insert(m_geom.begin(), fine_isp.m_geom.begin(), fine_isp.m_geom.end());
106  m_domain.insert(m_domain.begin(), fine_isp.m_domain.begin(), fine_isp.m_domain.end());
107  m_ngrow.insert(m_ngrow.begin(), fine_isp.m_ngrow.begin(), fine_isp.m_ngrow.end());
108 }
109 
110 template <typename G>
111 void
112 IndexSpaceImp<G>::addRegularCoarseLevels (int num_new_coarse_levels)
113 {
114  if (num_new_coarse_levels <= 0) { return; }
115 
116  auto nlevs_old = int(m_gslevel.size());
117  int nlevs_new = nlevs_old + num_new_coarse_levels;
118 
119  Vector<GShopLevel<G>> new_gslevel;
120  new_gslevel.reserve(nlevs_new);
121 
122  Vector<Geometry> new_geom;
123  new_geom.reserve(nlevs_new);
124 
125  Vector<Box> new_domain;
126  new_domain.reserve(nlevs_new);
127 
128  Vector<int> new_ngrow;
129  new_ngrow.reserve(nlevs_new);
130 
131  for (int ilev = 0; ilev < num_new_coarse_levels; ++ilev) {
132  int rr = 1 << (num_new_coarse_levels-ilev); // 2^(num_new_coarse_levels-ilev)
133  new_geom.push_back(amrex::coarsen(m_geom[0], rr));
134  new_domain.push_back(new_geom.back().Domain());
135  new_ngrow.push_back(m_ngrow[0]);
136  new_gslevel.push_back(GShopLevel<G>::makeAllRegular(this, new_geom.back()));
137  }
138 
139  for (int ilev = 0; ilev < nlevs_old; ++ilev) {
140  new_gslevel.emplace_back(std::move(m_gslevel[ilev]));
141  new_geom.push_back (m_geom [ilev]);
142  new_domain.push_back(m_domain[ilev]);
143  new_ngrow.push_back (m_ngrow [ilev]);
144  }
145 
146  std::swap(new_gslevel, m_gslevel);
147  std::swap(new_geom , m_geom);
148  std::swap(new_domain , m_domain);
149  std::swap(new_ngrow , m_ngrow);
150 
151  for (int ilev = num_new_coarse_levels-1; ilev >= 0; --ilev) {
152  m_gslevel[ilev].buildCutCellMask(m_gslevel[ilev+1]);
153  }
154 }
#define AMREX_ALWAYS_ASSERT(EX)
Definition: AMReX_BLassert.H:50
Definition: AMReX_EB2_Level.H:115
Definition: AMReX_EB2.H:71
const Level & getLevel(const Geometry &geom) const final
Definition: AMReX_EB2_IndexSpaceI.H:68
Vector< GShopLevel< G > > m_gslevel
Definition: AMReX_EB2.H:103
Vector< int > m_ngrow
Definition: AMReX_EB2.H:106
void addFineLevels(int num_new_fine_levels) final
Definition: AMReX_EB2_IndexSpaceI.H:86
Vector< Geometry > m_geom
Definition: AMReX_EB2.H:104
void addRegularCoarseLevels(int num_new_coarse_levels) final
Definition: AMReX_EB2_IndexSpaceI.H:112
Vector< Box > m_domain
Definition: AMReX_EB2.H:105
const Geometry & getGeometry(const Box &dom) const final
Definition: AMReX_EB2_IndexSpaceI.H:77
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:27
AMREX_EXPORT int max_grid_size
Definition: AMReX_EB2.cpp:23
AMREX_EXPORT bool extend_domain_face
Definition: AMReX_EB2.cpp:24
AMREX_EXPORT int num_coarsen_opt
Definition: AMReX_EB2.cpp:25
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE void swap(T &a, T &b) noexcept
Definition: AMReX_algoim_K.H:113
@ min
Definition: AMReX_ParallelReduce.H:18
@ max
Definition: AMReX_ParallelReduce.H:17
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 end(BoxND< dim > const &box) noexcept
Definition: AMReX_Box.H:1890
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE BoxND< dim > refine(const BoxND< dim > &b, int ref_ratio) noexcept
Definition: AMReX_Box.H:1342
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE Dim3 begin(BoxND< dim > const &box) noexcept
Definition: AMReX_Box.H:1881
AMREX_GPU_HOST_DEVICE AMREX_FORCE_INLINE 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:1304
void Abort(const std::string &msg)
Print out message to cerr and exit via abort().
Definition: AMReX.cpp:221
const int[]
Definition: AMReX_BLProfiler.cpp:1664