Chombo + EB + MF  3.2
BRMeshRefine.H
Go to the documentation of this file.
1 #ifdef CH_LANG_CC
2 /*
3  * _______ __
4  * / ___/ / ___ __ _ / / ___
5  * / /__/ _ \/ _ \/ V \/ _ \/ _ \
6  * \___/_//_/\___/_/_/_/_.__/\___/
7  * Please refer to Copyright.txt, in Chombo's root directory.
8  */
9 #endif
10 
11 #ifndef _BRMESHREFINE_H_
12 #define _BRMESHREFINE_H_
13 
14 #include <climits>
15 
16 #include "Vector.H"
17 #include "Box.H"
18 #include "IntVectSet.H"
19 #include "REAL.H"
20 #include "MeshRefine.H"
21 #include "Interval.H"
22 #include <list>
23 #include "NamespaceHeader.H"
24 
25 // Constants:
26 
27 // Minimum acceptable ratio of tagged cells to total cells for
28 // the Berger-Rigoutsos algorithm in \func{makeBoxes}.
29 // Used as default for \var{FillRatio} optional argument.
30 #ifndef _BR_MIN_BOX_FILL_RATIO_
31 #define _BR_MIN_BOX_FILL_RATIO_ ( 0.75 )
32 #endif
33 
34 /// Class which manages Berger-Rigoutsos grid generation
35 /**
36  This class manages grid generation from sets of tagged cells using the
37  Berger-Rigoutsos algorithm in the context of the MeshRefine class
38  from which it is derived
39 
40  There are two ways grids can be defined based on tagged cells.
41  one takes a single IntVectSet of tags defined on the BaseLevel
42  mesh and uses that set of tags for every level to be refined;
43  the other takes a Vector<IntVectSet> of tags defined on all the
44  mesh levels to be refined and uses those.
45 
46  <b> Long Description: </b>
47 
48  Create new meshes based on tagged cells on a range of levels of a mesh
49  hierarchy. Each level of tagged cells is used to generate a new mesh at
50  the next finer level. The finest level in the output mesh will be one
51  level higher than the top of the range of levels given as input. As a
52  special case, use the same tags (appropriately refined) for all levels.
53 
54  \b Usage:
55 
56  Call the regrid functions after computing error estimates and tagging cells.
57  To add a new mesh level, set TopLevel to the index of the finest level
58  in the existing mesh and define tags on the finest level. To keep the
59  existing number of mesh levels, set TopLevel to one less than the
60  index of the finest level and don't define any tags on the finest level.
61  If a single IntVectSet of tags is passed (instead of a
62  Vector<IntVectSet>) then the same tags (properly refined) will be used
63  for all the new meshes up to level TopLevel+1. In any case, the
64  meshes at levels BaseLevel and below are not modified. The output
65  argument newmeshes will be reallocated to the necessary size before
66  being used. When this function returns, the elements of the
67  newmeshes vector corresponding to the unchanged levels will be
68  filled in with copies of the levels from the old mesh vector. The
69  variable tags is modified in an undefined way, so its contents
70  should not be relied upon. The variable BlockFactor specifies the
71  amount by which each box will be coarsenable. Every grid box will
72  have an integral multiple of BlockFactor cells in each dimension and
73  also lower index values that are integral multiples. As a side effect,
74  the minimum box size will be BlockFactor.
75 
76  Expensive validations are done only when debugging is enabled
77  (i.e. the DEBUG make variable is "TRUE").
78 
79  <b> Usage Notes: </b>
80 
81  All the input vectors should be defined with max index >= TopLevel.
82  They should have values for indices [BaseLevel:TopLevel].
83  (except for OldMeshes, which must be defined for all indices). The
84  new mesh vector newmeshes will be redefined up to index
85  TopLevel+1. RefRatios should be defined such that
86  RefRatios[L] is the value to use to refine the level L mesh to
87  produce the level L+1 mesh. The tags vector is modified in an
88  undefined manner. The output variable newmeshes may not be
89  completely defined if an exception occurs.
90  The BlockFactor can be used to force a minimum box size.
91 */
92 class BRMeshRefine : public MeshRefine
93 {
94 public:
95  /// Default constructor -- leaves object in an unusable state
96  BRMeshRefine();
97 
98  /// Full constructor -- leaves object in usable state
99  BRMeshRefine(/// Level 0 domain
100  const Box& a_baseDomain,
101  /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1
102  const Vector<int>& a_refRatios,
103  /// Measure of how efficiently tagged cells will be covered
104  const Real a_fillRatio,
105  /// Amount by which grids are guaranteed to be coarsenable
106  const int a_blockFactor,
107  /// Proper nesting buffer amount
108  const int a_bufferSize,
109  /// Maximum grid length in any direction -- 0 means no limit.
110  const int a_maxSize);
111 
112  /// Full constructor -- leaves object in usable state
113  BRMeshRefine(/// Level 0 domain
114  const ProblemDomain& a_baseDomain,
115  /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1
116  const Vector<int>& a_refRatios,
117  /// Measure of how efficiently tagged cells will be covered
118  const Real a_fillRatio,
119  /// Amount by which grids are guaranteed to be coarsenable
120  const int a_blockFactor,
121  /// Proper nesting buffer amount
122  const int a_bufferSize,
123  /// Maximum grid length in any direction -- 0 means no limit.
124  const int a_maxSize);
125 
126  /// Destructor
127  virtual ~BRMeshRefine();
128 
129  /// Define function -- size of RefRatios will define maximum number of levels
130  void define(/// Level 0 domain
131  const Box& a_baseDomain,
132  /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1
133  const Vector<int>& a_refRatios,
134  /// Measure of how efficiently tagged cells will be covered
135  const Real a_fillRatio,
136  /// Amount by which grids are guaranteed to be coarsenable
137  const int a_blockFactor,
138  /// Proper nesting buffer amount
139  const int a_bufferSize,
140  /// Maximum grid length in any direction -- 0 means no limit
141  const int a_maxSize);
142 
143  /// Define function -- size of RefRatios will define maximum number of levels
144  void define(/// level 0 domain
145  const ProblemDomain& a_baseDomain,
146  /// Refinement ratios -- refRatio[0] is btwn levels 0 and 1
147  const Vector<int>& a_refRatios,
148  /// Measure of how efficiently tagged cells will be covered
149  const Real a_fillRatio,
150  /// Amount by which grids are guaranteed to be coarsenable
151  const int a_blockFactor,
152  /// Proper nesting buffer amount
153  const int a_bufferSize,
154  /// Maximum grid length in any direction -- 0 means no limit
155  const int a_maxSize);
156 
157  /// Constructs a set of boxes which covers a set of tagged cells
158  /** Constructs a set of boxes which covers a set of tagged cells
159  by using the Berger-Rigoutsos algorithm. Everything should
160  be on the same level, and blocking factor is not applied.
161  Boxes will be on the same refinement level as the tags.
162  This would normally be a protected function, but it can be useful
163  to call it on it's own, so it has been left public.
164  */
165  void
166  makeBoxes(/// Output: refined boxes at each new level
167  Vector<Box>& a_mesh,
168  /// Input: set of tagged cells to cover
169  const IntVectSet& a_tags,
170  /// Input: proper nesting domain in which mesh boxes must live
171  const IntVectSet& a_pnd,
172  /// Input: physical domain
173  const ProblemDomain& a_domain,
174  /// Input: largest number of cells in any dimension for any box
175  const int a_maxSize,
176  const int a_totalBufferSize) const;
177 
178 
179 
180  /**
181  Function which actually implement Berger-Rigoutsos chopping.
182  */
183  void
184  makeBoxes(/// Output: refined boxes at each new level
185  std::list<Box>& a_mesh,
186  /// Input: set of tagged cells to cover
187  IntVectSet& a_tags,
188  /// Input: proper nesting domain in which mesh boxes must live
189  const IntVectSet& a_pnd,
190  /// Input: physical domain
191  const ProblemDomain& a_domain,
192  /// Input: largest number of cells in any dimension for any box
193  const int a_maxSize,
194  /// Input: depth of this recursion in the algorithm
195  const int a_depth,
196  const int a_totalBufferSize
197  ) const;
198 
199 protected:
200 
201  /**
202  */
203  void
204  splitBox(std::list<Box> & a_boxes ,
205  const std::list<Box>::iterator& a_boxindex,
206  const int a_dimension ,const int a_maxboxsize ) const;
207 
208  void
209  splitBox(std::list<Box> & a_boxes ,
210  const std::list<Box>::iterator& a_boxindex,
211  const int a_maxboxsize ) const;
212 
213  ///
215  makeTrace( const IntVectSet& a_Ivs ,int a_dir ) const;
216 
217  ///
218  void
219  makeTraces( const IntVectSet& a_Ivs ,Vector<int>* a_traces ) const;
220  ///
221  int
222  findSplit( const Vector<int>& a_trace ) const;
223 
224  int
225  findSplit( const Vector<int>& a_trace, const int a_maxSize ) const;
226 
227  ///
228  int
229  findMaxInflectionPoint( const Vector<int>& a_trace ,int& a_maxVal ) const;
230  int
231  findMaxInflectionPoint( const Vector<int>& a_trace ,int& a_maxVal, const int a_maxSize ) const;
232 
233  ///
234  void
235  splitTags( const IntVectSet& a_tags,
236  const int a_split_dir ,const int a_split_indx,
237  IntVectSet& a_tags_lo ,IntVectSet& a_tags_hi ) const;
238 
239  void splitTagsInPlace(const int a_split_dir, const int a_split_indx,
240  IntVectSet& a_tags_inout_lo,
241  IntVectSet& a_tags_hi) const;
242 
243  void splitTagsInBestDimension(IntVectSet& a_tags_inout_lo,
244  IntVectSet& a_tags_hi,
245  const int a_maxSize) const;
246  ///
247  void
248  breakBoxes(Vector<Box>& a_vboxin, const int& a_maxSize,
249  const int& a_idir) const;
250 
251  ///
252  int
253  maxloc( const int* a_V ,const int a_Size ) const;
254 
255  void makeBoxesParallel(std::list<Box>& a_mesh,
256  IntVectSet& a_tags,
257  const IntVectSet& a_pnd,
258  const ProblemDomain& a_domain,
259  const int a_maxSize,
260  const int a_depth,
261  const int a_totalBufferSize,
262  const int a_minSize,
263  const Interval& a_procInterval
264  ) const;
265 
266  void sendBoxesParallel( const std::list<Box>& a_mesh,
267  int tag) const;
268 
269  void receiveBoxesParallel(const Interval& a_from,
270  const Interval& a_to,
271  std::list<Box>& a_mesh,
272  int tag) const;
273 
274  int longsideRefineDirs(const Box& a_bx, int& a_dir) const;
275 
276  mutable Vector<int> m_messageBuffer; // used for messaging in parallel
277 };
278 
279 /// Splits domain into vector of disjoint boxes with max size maxsize
280 /**
281  Blocking factor is default to one.
282  If you make minimum size > 1, then domain must
283  be coarsenable and refineable by blockfactor
284  (refine(coarsen(domain,blockfactor), minsize) == domain)
285  or an error is thrown. This would be defined in
286  MeshRefine.H, except that it needs to use a BRMeshRefine object.
287  Here a_refineDirs[d] is 1 if refining in dimension d, and 0 if not.
288 */
289 extern void domainSplit(const ProblemDomain& a_domain, Vector<Box>& a_vbox,
290  int a_maxSize, int a_blockfactor=1,
291  IntVect a_refineDirs=IntVect::Unit);
292 
293 ///
294 /**
295  Splits domain into a vector of disjoint boxes with
296  maximum size maxsize.
297  blocking factor is default to one.
298  If you make minimum size > 1, then domain must
299  be coarsenable and refineable by blockfactor
300  (refine(coarsen(domain,blockfactor), minsize) == domain)
301  or an error is thrown. This would be defined in
302  MeshRefine.H, except that it needs to use a BRMeshRefine object.
303  Here a_refineDirs[d] is 1 if refining in dimension d, and 0 if not.
304 */
305 extern void domainSplit(const Box& a_domain, Vector<Box>& a_vbox,
306  int a_maxSize, int a_blockfactor=1,
307  IntVect a_refineDirs=IntVect::Unit);
308 
309 ///
310 /**
311  Recursive function to enforce max size of boxes in a given direction.
312  Does not call Meshrefine.
313  */
314 extern void
315 breakBoxes(Vector<Box>& a_vboxin, const int& a_maxSize, const int& a_idir);
316 
317 #include "NamespaceFooter.H"
318 #endif
void define(const Box &a_baseDomain, const Vector< int > &a_refRatios, const Real a_fillRatio, const int a_blockFactor, const int a_bufferSize, const int a_maxSize)
Define function – size of RefRatios will define maximum number of levels.
An irregular domain on an integer lattice.
Definition: IntVectSet.H:44
void splitTagsInBestDimension(IntVectSet &a_tags_inout_lo, IntVectSet &a_tags_hi, const int a_maxSize) const
A class to facilitate interaction with physical boundary conditions.
Definition: ProblemDomain.H:141
Class which manages Berger-Rigoutsos grid generation.
Definition: BRMeshRefine.H:92
void sendBoxesParallel(const std::list< Box > &a_mesh, int tag) const
void breakBoxes(Vector< Box > &a_vboxin, const int &a_maxSize, const int &a_idir) const
void splitTagsInPlace(const int a_split_dir, const int a_split_indx, IntVectSet &a_tags_inout_lo, IntVectSet &a_tags_hi) const
int longsideRefineDirs(const Box &a_bx, int &a_dir) const
void splitTags(const IntVectSet &a_tags, const int a_split_dir, const int a_split_indx, IntVectSet &a_tags_lo, IntVectSet &a_tags_hi) const
virtual ~BRMeshRefine()
Destructor.
void domainSplit(const ProblemDomain &a_domain, Vector< Box > &a_vbox, int a_maxSize, int a_blockfactor=1, IntVect a_refineDirs=IntVect::Unit)
Splits domain into vector of disjoint boxes with max size maxsize.
int maxloc(const int *a_V, const int a_Size) const
Structure for passing component ranges in code.
Definition: Interval.H:23
void splitBox(std::list< Box > &a_boxes, const std::list< Box >::iterator &a_boxindex, const int a_dimension, const int a_maxboxsize) const
static const IntVect Unit
Definition: IntVect.H:663
void makeBoxesParallel(std::list< Box > &a_mesh, IntVectSet &a_tags, const IntVectSet &a_pnd, const ProblemDomain &a_domain, const int a_maxSize, const int a_depth, const int a_totalBufferSize, const int a_minSize, const Interval &a_procInterval) const
double Real
Definition: REAL.H:33
BRMeshRefine()
Default constructor – leaves object in an unusable state.
void makeBoxes(Vector< Box > &a_mesh, const IntVectSet &a_tags, const IntVectSet &a_pnd, const ProblemDomain &a_domain, const int a_maxSize, const int a_totalBufferSize) const
Constructs a set of boxes which covers a set of tagged cells.
int findSplit(const Vector< int > &a_trace) const
void makeTraces(const IntVectSet &a_Ivs, Vector< int > *a_traces) const
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:469
int findMaxInflectionPoint(const Vector< int > &a_trace, int &a_maxVal) const
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
Vector< int > m_messageBuffer
Definition: BRMeshRefine.H:276
Vector< int > makeTrace(const IntVectSet &a_Ivs, int a_dir) const
Class which manages grid generation.
Definition: MeshRefine.H:26
void receiveBoxesParallel(const Interval &a_from, const Interval &a_to, std::list< Box > &a_mesh, int tag) const