Line data Source code
1 : #ifndef BL_AMRMESH_H_
2 : #define BL_AMRMESH_H_
3 : #include <AMReX_Config.H>
4 :
5 : #include <AMReX_Array.H>
6 : #include <AMReX_Vector.H>
7 : #include <AMReX_RealBox.H>
8 : #include <AMReX_IntVect.H>
9 : #include <AMReX_Geometry.H>
10 : #include <AMReX_DistributionMapping.H>
11 : #include <AMReX_BoxArray.H>
12 : #include <AMReX_TagBox.H>
13 :
14 : #ifdef AMREX_USE_BITTREE
15 : #include <Bittree_BittreeAmr.h>
16 : #endif
17 :
18 : namespace amrex {
19 :
20 : struct AmrInfo {
21 : int verbose = 0;
22 : //! Maximum allowed level.
23 : int max_level = 0;
24 : //! Refinement ratios
25 : Vector<IntVect> ref_ratio {{IntVect(2)}};
26 : //! Blocking factor in grid generation (by level).
27 : Vector<IntVect> blocking_factor {{IntVect(8)}};
28 : //! Maximum allowable grid size (by level).
29 : #if defined(AMREX_USE_GPU)
30 : Vector<IntVect> max_grid_size {{IntVect(AMREX_D_PICK(128,128,64))}};
31 : #else
32 : Vector<IntVect> max_grid_size {{IntVect(AMREX_D_PICK(128,128,32))}};
33 : #endif
34 : //! Buffer cells around each tagged cell.
35 : Vector<IntVect> n_error_buf {{IntVect(1)}};
36 : //! Grid efficiency.
37 : Real grid_eff = static_cast<Real>(0.7);
38 : //! Cells required for proper nesting.
39 : int n_proper = 1;
40 : int use_fixed_upto_level = 0;
41 : bool use_fixed_coarse_grids = false;
42 :
43 : /**
44 : * Split the number grids until the number of grids is no less than the
45 : * number of procs. Overridden by refine_grid_layout_dims.
46 : */
47 : bool refine_grid_layout = true;
48 :
49 : /**
50 : * For each specified dimension, chop in that dimension so that
51 : * the number of grids is no less than the number of procs.
52 : */
53 : IntVect refine_grid_layout_dims = IntVect(1);
54 :
55 : bool check_input = true;
56 : bool use_new_chop = false;
57 : bool iterate_on_new_grids = true;
58 : };
59 :
60 : class AmrMesh
61 : : protected AmrInfo
62 : {
63 : public:
64 :
65 : friend std::ostream& operator<< (std::ostream& os, AmrMesh const& amr_mesh);
66 :
67 : AmrMesh ();
68 :
69 : AmrMesh (const RealBox* rb, int max_level_in,
70 : const Vector<int>& n_cell_in, int coord=-1,
71 : Vector<IntVect> refrat = Vector<IntVect>(),
72 : const int* is_per = nullptr);
73 :
74 : AmrMesh (const RealBox& rb, int max_level_in,
75 : const Vector<int>& n_cell_in, int coord,
76 : Vector<IntVect> const& a_refrat,
77 : Array<int,AMREX_SPACEDIM> const& is_per);
78 :
79 : AmrMesh (Geometry const& level_0_geom, AmrInfo const& amr_info);
80 :
81 : AmrMesh (const AmrMesh& rhs) = delete;
82 : AmrMesh& operator= (const AmrMesh& rhs) = delete;
83 :
84 : AmrMesh (AmrMesh&& rhs) = default;
85 : AmrMesh& operator= (AmrMesh&& rhs) = default;
86 :
87 : virtual ~AmrMesh () = default;
88 :
89 660 : [[nodiscard]] int Verbose () const noexcept { return verbose; }
90 :
91 : //! Return the max level
92 39 : [[nodiscard]] int maxLevel () const noexcept { return max_level; }
93 :
94 : //! Return the finest level
95 : [[nodiscard]] int finestLevel () const noexcept { return finest_level; }
96 :
97 : //! Return the refinement ratio for level lev
98 100 : [[nodiscard]] IntVect refRatio (int lev) const noexcept { return ref_ratio[lev]; }
99 :
100 : //! Return the maximum refinement ratio in any direction.
101 : [[nodiscard]] int MaxRefRatio (int lev) const noexcept;
102 :
103 : //! Return refinement ratios between all levels.
104 50 : [[nodiscard]] const Vector<IntVect>& refRatio () const noexcept { return ref_ratio; }
105 :
106 35 : [[nodiscard]] const Vector<Geometry>& Geom () const noexcept { return geom; }
107 : [[nodiscard]] const Vector<DistributionMapping>& DistributionMap () const noexcept { return dmap; }
108 : [[nodiscard]] const Vector<BoxArray>& boxArray () const noexcept { return grids; }
109 :
110 : [[nodiscard]] const Geometry& Geom (int lev) const noexcept { return geom[lev]; }
111 : [[nodiscard]] const DistributionMapping& DistributionMap (int lev) const noexcept { return dmap[lev]; }
112 41 : [[nodiscard]] const BoxArray& boxArray (int lev) const noexcept { return grids[lev]; }
113 :
114 300 : [[nodiscard]] Vector<Geometry> Geom (int a_coarsest_lev, int a_finest_lev) const noexcept {
115 300 : Vector<Geometry> r;
116 300 : r.reserve(a_finest_lev-a_coarsest_lev+1);
117 600 : for (int lev = a_coarsest_lev; lev <= a_finest_lev; ++lev) {
118 300 : r.push_back(geom[lev]);
119 : }
120 300 : return r;
121 : }
122 : [[nodiscard]] Vector<BoxArray> boxArray (int a_coarsest_lev, int a_finest_lev) const noexcept {
123 : Vector<BoxArray> r;
124 : r.reserve(a_finest_lev-a_coarsest_lev+1);
125 : for (int lev = a_coarsest_lev; lev <= a_finest_lev; ++lev) {
126 : r.push_back(grids[lev]);
127 : }
128 : return r;
129 : }
130 300 : [[nodiscard]] Vector<DistributionMapping> DistributionMap (int a_coarsest_lev, int a_finest_lev) const noexcept {
131 300 : Vector<DistributionMapping> r;
132 300 : r.reserve(a_finest_lev-a_coarsest_lev+1);
133 600 : for (int lev = a_coarsest_lev; lev <= a_finest_lev; ++lev) {
134 300 : r.push_back(dmap[lev]);
135 : }
136 300 : return r;
137 : }
138 :
139 : Vector<Geometry>& Geom () noexcept { return geom; }
140 : Geometry& Geom (int lev) noexcept { return geom[lev]; }
141 :
142 : void SetMaxGridSize (int new_mgs) noexcept {
143 : max_grid_size.assign(max_level+1, IntVect{AMREX_D_DECL(new_mgs,new_mgs,new_mgs)});
144 : }
145 : void SetMaxGridSize (const IntVect& new_mgs) noexcept {
146 : max_grid_size.assign(max_level+1, new_mgs);
147 : }
148 : void SetMaxGridSize (const Vector<int>& new_mgs) noexcept {
149 : max_grid_size.resize(max_level+1);
150 : for (int i = 0; i <= max_level; ++i) {
151 : max_grid_size[i] = IntVect{AMREX_D_DECL(new_mgs[i],new_mgs[i],new_mgs[i])};
152 : }
153 : }
154 : void SetMaxGridSize (const Vector<IntVect>& new_mgs) noexcept {
155 : max_grid_size.assign(new_mgs.cbegin(), new_mgs.cbegin()+max_level+1);
156 : }
157 :
158 : void SetBlockingFactor (int new_bf) noexcept {
159 : blocking_factor.assign(max_level+1, IntVect{AMREX_D_DECL(new_bf,new_bf,new_bf)});
160 : }
161 : void SetBlockingFactor (const IntVect& new_bf) noexcept {
162 : blocking_factor.assign(max_level+1, new_bf);
163 : }
164 : void SetBlockingFactor (const Vector<int>& new_bf) noexcept {
165 : blocking_factor.resize(max_level+1);
166 : for (int i = 0; i <= max_level; ++i) {
167 : blocking_factor[i] = IntVect{AMREX_D_DECL(new_bf[i],new_bf[i],new_bf[i])};
168 : }
169 : }
170 : void SetBlockingFactor (const Vector<IntVect>& new_bf) noexcept {
171 : blocking_factor.assign(new_bf.cbegin(), new_bf.cend()+max_level+1);
172 : }
173 :
174 : void SetGridEff (Real eff) noexcept { grid_eff = eff; }
175 : void SetNProper (int n) noexcept { n_proper = n; }
176 :
177 : //! Set ref_ratio would require rebuilding Geometry objects.
178 :
179 : void SetFinestLevel (int new_finest_level) noexcept { finest_level = new_finest_level; }
180 : void SetDistributionMap (int lev, const DistributionMapping& dmap_in) noexcept;
181 : void SetBoxArray (int lev, const BoxArray& ba_in) noexcept;
182 : void SetGeometry (int lev, const Geometry& geom_in) noexcept;
183 :
184 : //! Given domain box, return AMR level. Return -1 if there is no match.
185 : [[nodiscard]] int GetLevel (Box const& domain) const noexcept;
186 :
187 : void ClearDistributionMap (int lev) noexcept;
188 : void ClearBoxArray (int lev) noexcept;
189 :
190 : //! Return the number of buffer cells (as a single integer) in error estimator.
191 : [[nodiscard]] int nErrorBuf (int lev, int direction = 0) const noexcept { return n_error_buf[lev][direction]; }
192 :
193 : //! Return the number of buffer cells (as an IntVect) in error estimator.
194 : [[nodiscard]] const IntVect& nErrorBufVect (int lev) const noexcept { return n_error_buf[lev]; }
195 :
196 : //! Return the minimum allowable grid efficiency.
197 : [[nodiscard]] Real gridEff () const noexcept { return grid_eff; }
198 :
199 : //! Return the number of cells to define proper nesting
200 : [[nodiscard]] int nProper () const noexcept { return n_proper; }
201 :
202 : //! Return the blocking factor at level lev
203 : [[nodiscard]] const IntVect& blockingFactor (int lev) const noexcept { return blocking_factor[lev]; }
204 :
205 : //! Return the largest allowable grid.
206 : [[nodiscard]] const IntVect& maxGridSize (int lev) const noexcept { return max_grid_size[lev]; }
207 :
208 : [[nodiscard]] bool LevelDefined (int lev) const noexcept;
209 :
210 : //! Should we keep the coarser grids fixed (and not regrid those levels) at all?
211 : [[nodiscard]] bool useFixedCoarseGrids () const noexcept { return use_fixed_coarse_grids; }
212 :
213 : //! Up to what level should we keep the coarser grids fixed (and not regrid those levels)?
214 : [[nodiscard]] int useFixedUpToLevel () const noexcept { return use_fixed_upto_level; }
215 :
216 : //! "Try" to chop up grids so that the number of boxes in the BoxArray is greater than the target_size.
217 : void ChopGrids (int lev, BoxArray& ba, int target_size) const;
218 :
219 : //! Make a level 0 grids covering the whole domain. It does NOT install the new grids.
220 : [[nodiscard]] BoxArray MakeBaseGrids () const;
221 :
222 : /**
223 : * \brief Make new grids based on error estimates. This function
224 : * expects that valid BoxArrays exist in this->grids from level
225 : * lbase to level this->finest_level (the current finest level).
226 : * new_grids. On return, the new finest level is stored in
227 : * new_finest, and the new grids are stored in new_grids from Array
228 : * element lbase+1 to new_finest_level (unless fixed grids are
229 : * used). Note that this function adds at most one more level to
230 : * the existing levels, and it may remove all levels above the base
231 : * level. This function does not change the value of
232 : * this->finest_level, nor does it modifies any BoxArrays stored in
233 : * this->grids. It also does not modify new_grids's elements
234 : * outside the range [lbase+1,new_finest_level].
235 : */
236 : void MakeNewGrids (int lbase, Real time, int& new_finest, Vector<BoxArray>& new_grids);
237 :
238 : //! This function makes new grid for all levels (including level 0).
239 : void MakeNewGrids (Real time = 0.0);
240 :
241 : //! This function is called by the second version of MakeNewGrids.
242 : //! Make a new level from scratch using provided BoxArray and DistributionMapping.
243 : //! Only used during initialization.
244 : virtual void MakeNewLevelFromScratch (int /*lev*/, Real /*time*/, const BoxArray& /*ba*/, const DistributionMapping& /*dm*/) {}
245 :
246 : //! Tag cells for refinement. TagBoxArray tags is built on level lev grids.
247 : virtual void ErrorEst (int /*lev*/, TagBoxArray& /*tags*/, Real /*time*/, int /*ngrow*/) {}
248 :
249 : //! Manually tag. Note that tags is built on level lev grids coarsened by bf_lev[lev].
250 0 : virtual void ManualTagsPlacement (int /*lev*/, TagBoxArray& /*tags*/, const Vector<IntVect>& /*bf_lev*/) {}
251 :
252 : //! Apply some user-defined changes the to base grids.
253 : //!
254 : //! This function is only called by MakeNewGrids after computing a box array for the coarsest level
255 : //! and before calling MakeNewLevelFromScratch.
256 : //!
257 : //! For example, use this function if you want to remove covered grids on the coarsest refinement level.
258 0 : virtual void PostProcessBaseGrids(BoxArray& /*box_array*/) const {}
259 :
260 0 : [[nodiscard]] virtual BoxArray GetAreaNotToTag (int /*lev*/) { return BoxArray(); }
261 :
262 : [[nodiscard]] Long CountCells (int lev) const noexcept;
263 :
264 : [[nodiscard]] virtual DistributionMapping MakeDistributionMap (int lev, BoxArray const& ba);
265 :
266 : protected:
267 :
268 : int finest_level; //!< Current finest level.
269 : Vector<Geometry> geom;
270 : Vector<DistributionMapping> dmap;
271 : Vector<BoxArray> grids;
272 :
273 : #ifdef AMREX_USE_BITTREE
274 : bool use_bittree = false;
275 : std::unique_ptr<bittree::BittreeAmr> btmesh;
276 : #endif
277 :
278 : unsigned int num_setdm = 0;
279 : unsigned int num_setba = 0;
280 :
281 : void checkInput();
282 :
283 : void SetIterateToFalse () noexcept { iterate_on_new_grids = false; }
284 : void SetUseNewChop () noexcept { use_new_chop = true; }
285 :
286 : private:
287 : void InitAmrMesh (int max_level_in, const Vector<int>& n_cell_in,
288 : Vector<IntVect> refrat = Vector<IntVect>(),
289 : const RealBox* rb = nullptr, int coord = -1,
290 : const int* is_per = nullptr);
291 :
292 : static void ProjPeriodic (BoxList& blout, const Box& domain,
293 : Array<int,AMREX_SPACEDIM> const& is_per);
294 : };
295 :
296 : std::ostream& operator<< (std::ostream& os, AmrMesh const& amr_mesh);
297 :
298 : }
299 :
300 : #endif
|