Chombo + EB  3.2
ProblemDomain.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 _PROBLEMDOMAIN_H_
12 #define _PROBLEMDOMAIN_H_
13 
14 #ifndef WRAPPER
15 #include <iostream>
16 
17 #include "Vector.H"
18 #include "IntVect.H"
19 #include "Box.H"
20 #include "Misc.H"
21 #endif
22 
23 #include "SPACE.H"
24 #include "NamespaceHeader.H"
25 
26 /// Class to manage box-shifting used to enforce periodic BC's
27 /** The ShiftIterator class contains a list of shift vectors necessary
28  to enforce periodic boundary conditions (enforced by shifting the
29  Box of each Fab, then copying any overlapping valid cells with
30  ghost cells of the shifted Fab. Depending on the number of periodic
31  directions, the list of shift vectors over which to iterate differs.
32 */
34 {
35 public:
36  /// Basic constructor
37  ShiftIterator();
38 
39  /// Defining Constructor
40  /**
41  Builds a ShiftIterator based on the periodicity in
42  \em a_isPeriodic
43  */
44  ShiftIterator(const bool* a_isPeriodic);
45 
46  /// Defining Constructor
47  /**
48  Builds a ShiftIterator based on the periodicity in
49  \em a_isPeriodic and also allows for multiple wraps
50  */
51  ShiftIterator(const bool* a_isPeriodic, const IntVect& a_numWraps );
52 
53  /// Copy constructor
54  ShiftIterator(const ShiftIterator& a_shiftIt);
55 
56  /// Destructor
58 
59  /// Assignment operator
60  ShiftIterator& operator=(const ShiftIterator& a_src);
61 
62  /// Recompute shift vectors based on periodic directions
63  void computeShifts(const bool* a_isPeriodic);
64 
65  /// Recompute shift vectors based on periodic directions
66  void computeShifts(const bool* a_isPeriodic, const IntVect& a_numWraps);
67 
68 
69  /// Returns the current shift unit vector
70  inline IntVect operator()() const;
71 
72  /// Equivalent to the () operator
73  IntVect i() const
74  {
75  return this->operator()();
76  }
77  /// Increment to the next shift unit vector
78  inline void operator++();
79 
80  /// Equivalent to the ++ operator
81  void incr()
82  {
83  ++(*this);
84  }
85 
86  /// Is the iterator still within its range of shift vectors?
87  inline bool ok() const;
88 
89  ///which periodic image is this
90  unsigned int index() const
91  {
92  return m_index;
93  }
94 
95  const IntVect& operator[](int index) const
96  {
97  return m_shift_vectors[index];
98  }
99  /// Reset to first shift unit vector
100  inline void reset();
101 
102  /// Equivalent to reset()
103  inline void begin();
104 
105  /// Skip the iterator to the end.
106  /**
107  ok() will return false after this method is called.
108  */
109  void end();
110 
111 private:
112 
113  unsigned int m_index;
114 
116 
117 };
118 
119 /// A class to facilitate interaction with physical boundary conditions
120 /**
121 
122  ProblemDomain is a class which facilitates the application of physical
123  boundary conditions, both periodic and non-periodic. This class contains
124  much of the functionality of the Box class, since logically the
125  computational domain is generally a Box.
126 
127  Intersection with a ProblemDomain object will result in only removing
128  regions which are outside the physical domain in non-periodic directions.
129  Regions outside the logical computational domain in periodic directions will
130  be treated as ghost cells which can be filled with an exchange() function
131  or through suitable interpolation from a coarser domain.
132 
133  Since ProblemDomain will contain a Box, it is a dimension dependent class,
134  so SpaceDim must be defined as either 1, 2, or 3 when compiling.
135 
136  Note that this implementation of ProblemDomain is inherently
137  cell-centered.
138 
139 */
140 
142 {
143 public:
144 
145  // Constructors
146 
147  /// The default constructor. The constructed domain box is empty.
148  /**
149  */
150  ProblemDomain ();
151 
152  /// Construct ProblemDomain with \em a_domBox as computational domain
153  /**
154  This constructor defaults to non-periodic domain
155  */
156  ProblemDomain(const Box& a_domBox);
157 
158  /// Construct ProblemDomain with a_domBox as computational domain.
159  /**
160  \em a_isPeriodic is a SpaceDim array of bools; if true, the
161  physical boundary condition is periodic in the coordinate direction.
162  False means a non-periodic BC.
163  */
164  ProblemDomain(const Box& a_domBox, const bool* a_isPeriodic);
165 
166  /// Construct a ProblemDomain.
167  /**
168  It is an error if small is greater than big.
169  Defaults to non-periodic domain.
170  */
171  ProblemDomain (const IntVect& small,
172  const IntVect& big);
173 
174  /// Construct a ProblemDomain.
175  /**
176  It is an error if small is greater than big.
177  \em a_isPeriodic is a SpaceDim array of bools; if true, the
178  physical boundary condition is periodic in the coordinate direction.
179  False means a non-periodic BC.
180  */
181  ProblemDomain (const IntVect& small,
182  const IntVect& big,
183  const bool* a_isPeriodic);
184 
185  /// Construct ProblemDomain with specified lengths.
186  /**
187  It is an error if the lengths are negative.
188  Defaults to non-periodic domain.
189  */
190  ProblemDomain (const IntVect& small,
191  const int* vec_len);
192 
193  /// Construct ProblemDomain with specified lengths.
194  /**
195  It is an error if the lengths are negative.
196  \em a_isPeriodic is a SpaceDim array of bools; if true, the
197  physical boundary condition is periodic in the coordinate direction.
198  False means a non-periodic BC.
199  */
200  ProblemDomain (const IntVect& small,
201  const int* vec_len,
202  const bool* a_isPeriodic);
203 
204  /// The copy constructor.
205  /**
206  */
207  ProblemDomain (const ProblemDomain& a_src);
208 
209  /// Construct ProblemDomain with \em a_domBox as computational domain
210  /**
211  This constructor defaults to non-periodic domain
212  */
213  void define(const Box& a_domBox);
214 
215  /// Construct ProblemDomain with a_domBox as computational domain.
216  /**
217  \em a_isPeriodic is a SpaceDim array of bools; if true, the
218  physical boundary condition is periodic in the coordinate direction.
219  False means a non-periodic BC.
220  */
221  void define(const Box& a_domBox, const bool* a_isPeriodic);
222 
223  /// Construct a ProblemDomain.
224  /**
225  It is an error if small is greater than big.
226  Defaults to non-periodic domain.
227  */
228  void define (const IntVect& small,
229  const IntVect& big);
230 
231  /// Construct a ProblemDomain.
232  /**
233  It is an error if small is greater than big.
234  \em a_isPeriodic is a SpaceDim array of bools; if true, the
235  physical boundary condition is periodic in the coordinate direction.
236  False means a non-periodic BC.
237  */
238  void define (const IntVect& small,
239  const IntVect& big,
240  const bool* a_isPeriodic);
241 
242  /// Construct ProblemDomain with specified lengths.
243  /**
244  It is an error if the lengths are negative.
245  Defaults to non-periodic domain.
246  */
247  void define (const IntVect& small,
248  const int* vec_len);
249 
250  /// Construct ProblemDomain with specified lengths.
251  /**
252  It is an error if the lengths are negative.
253  \em a_isPeriodic is a SpaceDim array of bools; if true, the
254  physical boundary condition is periodic in the coordinate direction.
255  False means a non-periodic BC.
256  */
257  void define (const IntVect& small,
258  const int* vec_len,
259  const bool* a_isPeriodic);
260 
261  /// The copy constructor.
262  /**
263  */
264  void define (const ProblemDomain& a_src);
265 
266  // Accessors
267 
268  /// Returns the logical computational domain
269  /**
270  */
271  const Box& domainBox() const;
272 
273  /// Returns true if BC is periodic in direction a_dir
274  /**
275  */
276  bool isPeriodic(int a_dir) const;
277 
278  /// Returns bool[SpaceDim vector of periodicity info
279  /**
280  */
281  const bool* isPeriodicVect() const
282  {return m_isPeriodic;}
283 
284  /// Returns true if BC is periodic in _any_ direction
285  /**
286  */
287  bool isPeriodic() const;
288 
289  /// Returns the shiftIterator for this ProblemDomain
290  /**
291  The shiftIterator is defined based on the periodicity of this
292  ProblemDomain.
293  */
294  ShiftIterator shiftIterator() const;
295 
296  /// Returns true if this ProblemDomain is empty or undefined.
297  /**
298  */
299  bool isEmpty () const;
300 
301  /// Return the size of the domainBox in the specified coordinate direction.
302  /**
303  */
304  int size (const int& a_idir) const;
305 
306  /// Return the size of the domainBox.
307  /**
308  */
309  IntVect size () const;
310 
311  /// Returns true if argument is contained within this ProblemDomain.
312  /**
313  An empty ProblemDomain does not contain and is not contained by
314  any ProblemDomain, including itself. Note also that in a periodic
315  Direction, any index is valid, since the domain is infinite in that
316  direction.
317  */
318  bool contains (const IntVect& p) const;
319 
320  /// Returns the periodic image of this IntVect inside of the ProblemDomain.
321  /**
322  Return true if the domain contains this IntVect, returning the image
323  in 'p', otherwise returns false
324  */
325  bool image (IntVect& p) const;
326 
327  /// Returns true if argument is contained within this ProblemDomain.
328  /**
329  An empty ProblemDomain does not contain any Box. An entirely periodic
330  domain contains any Box.
331  */
332  bool contains (const Box& b) const;
333 
334  /// Equivalent to \em contains() function.
335  bool contains_box(const Box& b) const
336  {
337  return contains(b);
338  }
339 
340  /// Returns true if this ProblemDomain and the argument intersect.
341  /**
342  It is an error if a_box is not cell-centered.
343  An empty ProblemDomain does not intersect any Box.
344  This will do nothing in periodic directions (since a periodic domain
345  is infinite in the periodic direction. If periodic in all dimensions,
346  this will always return true.
347  */
348  bool intersects (const Box& a_box) const;
349 
350  /// Returns true if this ProblemDomain and the argument intersect.
351  /**
352  It is an error if a_box is not cell-centered.
353  This routine does not perform the check to see if *this or b are
354  empty Boxes. It is the callers responsibility to ensure that
355  this never happens. If you are unsure, the use the .intersects(..)
356  routine. In periodic directions, will always return true.
357 
358  */
359  bool intersectsNotEmpty (const Box& a_box) const;
360 
361  /// Returns true if this argument is adjacent to a periodic boundary
362  /**
363  */
364  bool periodicAdjacent(const Box& a_box) const;
365 
366  ///
367  /**
368  */
369  void insertImages(std::list<Box>& a_list, const Box& a_box) const;
370 
371  /// Returns true if box1 and box2 or any of their periodic images intersect
372  /**
373  (useful for checking disjointness)
374  */
375  bool intersects(const Box& box1, const Box& box2) const;
376 
377  /// Returns true if the two domain are equivalent
378  /**
379  */
380  bool operator== (const ProblemDomain& a_otherDomain) const;
381 
382  /// Returns true if the two domain are not equivalent
383  /**
384  */
385  bool operator!= (const ProblemDomain& a_otherDomain) const;
386 
387  /// Modifies a_box to be the intersection of a_box and \em a_probdomain
388  /**
389  */
390  friend void operator &=(Box& a_box, const ProblemDomain& a_probdomain);
391 
392  /// Returns a Box which is the interesection of a_box and \em a_probdomain
393  /**
394  */
395  friend Box operator & (const Box& a_box, const ProblemDomain& a_probdomain);
396 
397  // Modification Functions
398 
399  /// The assignment operator.
400  /**
401  */
403 
404  /// Sets whether BC is periodic in direction a_dir (true == periodic)
405  /**
406  */
407  void setPeriodic(int a_dir, bool a_isPeriodic);
408 
409  /// Grows (or shrinks) the domain Box by i in all directions
410  /**
411  */
412  inline ProblemDomain& grow (int i);
413 
414  /// Returns a ProblemDomain with a domainBox grown by the given amount
415  /**
416  */
417  friend inline ProblemDomain grow(const ProblemDomain& pd,
418  int i);
419 
420  /// Grow this ProblemDomain
421  /**
422  Modifies this ProblemDomain by growing the domainBox in each
423  direction by the specified amount
424  */
425  inline ProblemDomain& grow(const IntVect& v);
426 
427  /// Returns a grown version of \em pd.
428  /**
429  Returns a ProblemDomain that is the argument ProblemDomain
430  with a DomainBox grown by the given amount.
431  */
432  friend inline ProblemDomain grow (const ProblemDomain& pd,
433  const IntVect& v);
434 
435  /// Grow this ProblemDomain
436  /**
437  Modifies this ProblemDomain by growing it on the low and high end
438  by n_cell cells in direction idir.
439  */
440  inline ProblemDomain& grow(int idir, int n_cell);
441 
442  /// Grow this ProblemDomain on the low side
443  /**
444  Modifies this ProblemDomain by growing it on the low end by n_cell
445  cells in direction idir.
446  */
447  inline ProblemDomain& growLo(int idir, int n_cell=1);
448 
449  /// Grow this ProblemDomain on the high side
450  /** Modifies this ProblemDomain by growing it on the high end by n_Cell
451  cells in direction idir
452  */
453  inline ProblemDomain& growHi(int idir, int n_cell=1);
454 
455  /// Returns a face-centered Box at the low side of \em a_pd
456  /**
457  Returns the edge-centered Box (in direction \em a_dir) defining
458  the low side of the argument ProblemDomain. The output Box will
459  have the given length in the given direction. Directions are
460  zero-based. It is an error if not 0 <= dir < SpaceDim. The neighbor
461  of an Empty ProblemDomain is an Empty Box of the appropriate type.
462  If \em a_dir is a periodic direction, will return an empty Box.
463  */
464  friend Box bdryLo (const ProblemDomain& a_pd,
465  int a_dir,
466  int a_len);
467 
468  /// Returns a face-centered Box at the high side of \em a_pd
469  /**
470  Returns the edge-centered Box (in direction \em a_dir) defining the
471  high side of the argument ProblemDomain. The return Box will have the
472  given length in the given direction. Directions are zero-based.
473  It is an error if not 0 <= dir < SpaceDim. The neighbor of an
474  Empty ProblemDomain is an Empty Box of the appropriate type.
475  If \em a_dir is a periodic direction, will return an empty Box.
476  */
477  friend Box bdryHi (const ProblemDomain& a_pd,
478  int a_dir,
479  int a_len);
480 
481  /// Returns the cell-centered Box adjacent to the low side of \em a_pd.
482  /**
483  Returns the cell centered Box of the given length adjacent to the
484  argument ProblemDomain on the low end along the given coordinate direction.
485  The return Box is identical to the argument ProblemDomain in the other
486  directions. The return ProblemDomain and the argument ProblemDomain
487  have an empty intersection.
488 
489  \b NOTES:
490  - len >= 1.
491  - Box retval = adjCellLo(b,dir,len) is equivalent to the following set of
492  operations:
493  \code
494  Box retval(b);
495 
496  retval.convert(dir,ProblemDomain::CELL);
497 
498  retval.setrange(dir,retval.smallEnd(dir)-len,len);
499  \endcode
500 
501  Directions are zero-based. It is an error if not 0 <= dir <
502  SpaceDim. The neighbor of an Empty ProblemDomain is an Empty Box of the
503  appropriate type. If \em a_dir is a periodic direction, will return
504  an empty Box as well.
505 
506  */
507  friend Box adjCellLo (const ProblemDomain& a_pd,
508  int a_dir,
509  int a_len);
510 
511  /// Returns the cell-centered Box adjacent to the low side of \em a_pd.
512  /**
513  Returns the cell centered Box of the given length adjacent to the
514  argument ProblemDomain on the high end along the given coordinate
515  direction. The return Box is identical to the argument ProblemDomain in
516  the other directions. The return Box and the argument ProblemDomain have
517  an empty intersection.
518 
519  \b NOTES:
520  - len >= 1.
521 
522  - Box retval = adjCellHi(b,dir,len) is equivalent to the
523  following set of operations:
524  \code
525  Box retval(b);
526 
527  retval.convert(dir,ProblemDomain::CELL);
528 
529  retval.setrange(dir,retval.bigEnd(dir)+1,len);
530  \endcode
531 
532  Directions are zero-based. It is an error if not 0 <= dir <
533  SpaceDim. The neighbor of an Empty ProblemDomain is an Empty Box of the
534  appropriate type. If \em a_dir is a periodic direction, will return
535  an empty Box.
536 
537  */
538  friend Box adjCellHi (const ProblemDomain& a_pd,
539  int a_dir,
540  int a_len);
541 
542  // Intersection functions
543 
544  /// Returns the Box intersection of this ProblemDomain and \em a_b
545  /**
546  The intersection of the Empty ProblemDomain and any Box is the Empty
547  Box. This operator does nothing in periodic directions (since
548  a periodic domain is an infinite domain).
549 
550  */
551  Box operator& (const Box& a_b) const;
552 
553  // refinement
554 
555  /// Refine this problem domain.
556  /**
557  Modifies this ProblemDomain by refining it by given (positive) refinement
558  ratio. The Empty ProblemDomain is not modified by this function.
559  */
560  ProblemDomain& refine (int a_refinement_ratio);
561 
562  /// Return a ProblemDomain which is a refinement of \em a_probdomain
563  /**
564  Returns a ProblemDomain that is the argument ProblemDomain refined by
565  given (positive) refinement ratio. The Empty ProblemDomain is not
566  modified by this function.
567  */
568  friend ProblemDomain refine (const ProblemDomain& a_probdomain,
569  int a_refinement_ratio);
570 
571  /// Refine this ProblemDomain
572  /**
573  Modifies this ProblemDomain by refining it by given (positive) refinement
574  ratio. The Empty ProblemDomain is not modified by this function.
575  */
576  ProblemDomain& refine (const IntVect& a_refinement_ratio);
577 
578  /// Refinement function
579  /**
580  Returns a ProblemDomain that is the argument ProblemDomain refined
581  by given (positive) refinement ratio. The Empty ProblemDomain is
582  not modified by this function.
583 
584  */
585  friend ProblemDomain refine (const ProblemDomain& a_probdomain,
586  const IntVect& a_refinement_ratio);
587 
588  // coarsening
589 
590  /// Coarsen this ProblemDomain
591  /**
592  Modifies this ProblemDomain by coarsening it by given (positive)
593  refinement ratio. The Empty ProblemDomain is not modified by
594  this function.
595  */
596 
597  ProblemDomain& coarsen (int a_refinement_ratio);
598 
599  /// Coarsening function
600  /**
601  Returns a ProblemDomain that is the argument ProblemDomain coarsened
602  by given (positive) refinement ratio. The Empty ProblemDomain is not
603  modified by this function.
604  */
605  friend ProblemDomain coarsen (const ProblemDomain& a_probdomain,
606  int a_refinement_ratio);
607 
608  /// Coarsen this ProblemDomain
609  /**
610  Modifies this ProblemDomain by coarsening by given (positive) refinement
611  ratio. The Empty ProblemDomain is not modified by this function.
612  */
613  ProblemDomain& coarsen (const IntVect& refinement_ratio);
614 
615  /// Coarsening function
616  /**
617  Returns a ProblemDomain that is the argument ProblemDomain coarsened
618  by given (positive) refinement ratio. The Empty ProblemDomain is
619  not modified by this function.
620 
621  */
622  friend ProblemDomain coarsen (const ProblemDomain& a_probdomain,
623  const IntVect& a_refinement_ratio);
624 
625  ///
626  void shift(const IntVect& a_shift)
627  {
628  m_domainBox.shift(a_shift);
629  }
630 
631  bool operator<(const ProblemDomain& rhs) const
632  {
633  return m_domainBox < rhs.m_domainBox;
634  }
635  // I/O Functions
636 
637  /// Write an ASCII representation to the ostream.
638  /**
639  */
640  friend std::ostream& operator<< (std::ostream& os,
641  const ProblemDomain& bx);
642 
643  /// Read from istream.
644  /**
645  */
646  friend std::istream& operator>> (std::istream& is,
647  ProblemDomain& bx);
648 
649  void shiftIt(Box& a_box, int shiftIndex) const ;
650  void unshiftIt(Box& a_box, int shiftIndex) const ;
651  /// Gives more detail than printOn.
652  /**
653  Useful for exiting due to an error.
654  */
655  void dumpOn (std::ostream& strm) const;
656 
657 
658 protected:
659  friend class HDF5Handle;
660 
661  /**
662  Periodicity info
663  */
664  bool m_isPeriodic[SpaceDim];
665 
666  /**
667  Domain index extents
668  */
670 
671  /**
672  Shift iterator for this ProblemDomain
673  */
675 };
676 
678 {
679 public:
680  ImageIterator(const ProblemDomain& a_domain)
681  {
682  define(a_domain);
683  }
684 
685  void define(const ProblemDomain& a_domain);
686 
687  void begin(const Box& a_box)
688  {
689  m_counter=-1;
690  m_box = a_box;
691  this->operator++();
692  }
693 
694  void operator++();
695 
696  bool ok()
697  {
698  return m_shifter[m_counter] != IntVect::Zero;
699  }
700 
701  const Box& box() const
702  {
703  return m_current;
704  }
705 
706  const ProblemDomain& domain() const
707  {
708  return m_domain;
709  }
710 
711  void checkDefine(const ProblemDomain& a_domain)
712  {
713  if (!(m_domain == a_domain)) define(a_domain);
714  }
715 
716 protected:
718  Box m_quadrant[D_TERM6(3,*3,*3,*3,*3,*3)];
719  IntVect m_shifter[D_TERM6(3,*3,*3,*3,*3,*3)];
723 };
724 
725 //
726 // Inlines.
727 //
728 #ifndef WRAPPER
729 
730 inline
732  : m_index(100), m_shift_vectors()
733 {
734 }
735 
736 inline
738 {
739  m_index = a_src.m_index;
741 }
742 
743 inline
746 {
747  m_index = a_src.m_index;
749  return *this;
750 }
751 
752 inline
753 IntVect
755 {
756  CH_assert(ok());
757  return m_shift_vectors[m_index];
758 }
759 
760 inline
761 void
763 {
764  m_index++;
765 }
766 
767 inline
768 bool
770 {
771  return (m_index < m_shift_vectors.size());
772 }
773 
774 inline
775 void
777 {
778  m_index = 0;
779 }
780 
781 inline
782 void
784 {
785  m_index = 0;
786 }
787 
788 inline
789 void
791 {
793 }
794 
795 inline
797 {
798  // default is a non-periodic domain
799  for (int dir=0; dir<SpaceDim; dir++)
800  {
801  m_isPeriodic[dir] = false;
802  }
803 
804 }
805 
806 inline
808  : m_domainBox(b.m_domainBox), m_shiftIt(b.m_shiftIt)
809 {
810  for (int dir=0; dir<SpaceDim; dir++)
811  {
812  m_isPeriodic[dir] = b.m_isPeriodic[dir];
813  }
814 }
815 
816 inline void
818 
819 {
821  m_shiftIt = (b.m_shiftIt);
822  for (int dir=0; dir<SpaceDim; dir++)
823  {
824  m_isPeriodic[dir] = b.m_isPeriodic[dir];
825  }
826 }
827 
828 inline
829 bool
830 ProblemDomain::operator== (const ProblemDomain& a_otherDomain) const
831 {
832  bool result = true;
833 
834  if (m_domainBox != a_otherDomain.m_domainBox)
835  {
836  result = false;
837  }
838  else
839  {
840  for (int dir=0; dir<SpaceDim; dir++)
841  {
842  if (m_isPeriodic[dir] != a_otherDomain.m_isPeriodic[dir])
843  {
844  result = false;
845  break;
846  }
847  }
848  }
849 
850  return result;
851 }
852 
853 inline
854 bool
855 ProblemDomain::operator!= (const ProblemDomain& a_otherDomain) const
856 {
857  return !(*this == a_otherDomain);
858 }
859 
860 inline
863 {
865  for (int dir=0; dir<SpaceDim; dir++)
866  {
867  m_isPeriodic[dir] = b.m_isPeriodic[dir];
868  }
869  m_shiftIt = b.m_shiftIt;
870  return *this;
871 }
872 
873 inline void
874 ProblemDomain::shiftIt(Box& a_box, int a_shiftIndex) const
875 {
876  a_box.shift(m_shiftIt[a_shiftIndex]*m_domainBox.size());
877 }
878 
879 inline void
880 ProblemDomain::unshiftIt(Box& a_box, int a_shiftIndex) const
881 {
882  a_box.shift(- m_shiftIt[a_shiftIndex]*m_domainBox.size());
883 }
884 
885 inline
886 const Box&
888 {
889  return m_domainBox;
890 }
891 
892 inline
893 bool
895 {
896  return m_isPeriodic[a_dir];
897 }
898 
899 inline
900 bool
902 {
903  return D_TERM6(m_isPeriodic[0], ||
904  m_isPeriodic[1], ||
905  m_isPeriodic[2], ||
906  m_isPeriodic[3], ||
907  m_isPeriodic[4], ||
908  m_isPeriodic[5]);
909 }
910 
911 inline
914 {
915  m_domainBox.grow(i);
916  return *this;
917 }
918 
919 inline
921 grow(const ProblemDomain& pd, int i)
922 {
923  ProblemDomain newPd(pd);
924  newPd.grow(i);
925  return newPd;
926 }
927 
928 inline
931 {
932  m_domainBox.grow(v);
933  return *this;
934 }
935 
936 inline
938 grow(const ProblemDomain& pd, const IntVect& v)
939 {
940  ProblemDomain newPd(pd);
941  newPd.grow(v);
942  return newPd;
943 }
944 
945 inline
947 ProblemDomain::grow(int idir, int n_cell)
948 {
949  m_domainBox.grow(idir, n_cell);
950  return *this;
951 }
952 
953 inline
955 ProblemDomain::growLo(int idir, int n_cell)
956 {
957  m_domainBox.growLo(idir, n_cell);
958  return *this;
959 }
960 
961 inline
963 ProblemDomain::growHi(int idir, int n_cell)
964 {
965  m_domainBox.growHi(idir, n_cell);
966  return *this;
967 }
968 
969 inline
972 {
973  return m_shiftIt;
974 }
975 
976 inline
977 bool
979 {
980  return (m_domainBox.isEmpty());
981 }
982 
983 inline
984 int
985 ProblemDomain::size (const int& a_idir) const
986 {
987  return (m_domainBox.size(a_idir));
988 }
989 
990 inline
991 IntVect
993 {
994  return (m_domainBox.size());
995 }
996 
997 inline
998 bool
1000 {
1001 
1002  // boy is this ugly!
1003  return ( !isEmpty()
1004  && (D_TERM6((m_isPeriodic[0]
1005  || ( p[0] >= m_domainBox.smallEnd(0)
1006  && p[0] <= m_domainBox.bigEnd (0))),
1007  && (m_isPeriodic[1]
1008  || ( p[1] >= m_domainBox.smallEnd(1)
1009  && p[1] <= m_domainBox.bigEnd (1))),
1010  && (m_isPeriodic[2]
1011  || ( p[2] >= m_domainBox.smallEnd(2)
1012  && p[2] <= m_domainBox.bigEnd (2))),
1013  && (m_isPeriodic[3]
1014  || ( p[3] >= m_domainBox.smallEnd(3)
1015  && p[3] <= m_domainBox.bigEnd (3))),
1016  && (m_isPeriodic[4]
1017  || ( p[4] >= m_domainBox.smallEnd(4)
1018  && p[4] <= m_domainBox.bigEnd (4))),
1019  && (m_isPeriodic[5]
1020  || ( p[5] >= m_domainBox.smallEnd(5)
1021  && p[5] <= m_domainBox.bigEnd (5))))));
1022 }
1023 
1024 inline
1025 bool
1027 {
1028  if (m_domainBox.contains(p)) return true;
1029  if (!contains(p)) return false;
1030 
1031  D_TERM6(
1032  if (m_isPeriodic[0])
1033  {
1034  if (p[0]<m_domainBox.smallEnd(0)) p[0]+= m_domainBox.size(0);
1035  else if (p[0]>m_domainBox.bigEnd(0)) p[0]-= m_domainBox.size(0);
1036  },
1037  if (m_isPeriodic[1])
1038  {
1039  if (p[1]<m_domainBox.smallEnd(1)) p[1]+= m_domainBox.size(1);
1040  else if (p[1]>m_domainBox.bigEnd(1)) p[1]-= m_domainBox.size(1);
1041  },
1042  if (m_isPeriodic[2])
1043  {
1044  if (p[2]<m_domainBox.smallEnd(2)) p[2]+= m_domainBox.size(2);
1045  else if (p[2]>m_domainBox.bigEnd(2)) p[2]-= m_domainBox.size(2);
1046  },
1047  if (m_isPeriodic[3])
1048  {
1049  if (p[3]<m_domainBox.smallEnd(3)) p[3]+= m_domainBox.size(3);
1050  else if (p[3]>m_domainBox.bigEnd(3)) p[3]-= m_domainBox.size(3);
1051  },
1052  if (m_isPeriodic[4])
1053  {
1054  if (p[4]<m_domainBox.smallEnd(4)) p[4]+= m_domainBox.size(4);
1055  else if (p[4]>m_domainBox.bigEnd(4)) p[4]-= m_domainBox.size(4);
1056  },
1057  if (m_isPeriodic[5])
1058  {
1059  if (p[5]<m_domainBox.smallEnd(5)) p[5]+= m_domainBox.size(5);
1060  else if (p[5]>m_domainBox.bigEnd(5)) p[5]-= m_domainBox.size(5);
1061  });
1062 
1063  return true;
1064 }
1065 
1066 inline
1067 bool
1069 {
1070  // boy is this ugly!
1071  if (b.type() == m_domainBox.type())
1072  {
1073  return ( !isEmpty()
1074  && (D_TERM6((m_isPeriodic[0]
1075  || ( b.smallEnd(0) >= m_domainBox.smallEnd(0)
1076  && b.bigEnd (0) <= m_domainBox.bigEnd (0))), &&
1077  (m_isPeriodic[1]
1078  || ( b.smallEnd(1) >= m_domainBox.smallEnd(1)
1079  && b.bigEnd (1) <= m_domainBox.bigEnd (1))), &&
1080  (m_isPeriodic[2]
1081  || ( b.smallEnd(2) >= m_domainBox.smallEnd(2)
1082  && b.bigEnd (2) <= m_domainBox.bigEnd (2))), &&
1083  (m_isPeriodic[3]
1084  || ( b.smallEnd(3) >= m_domainBox.smallEnd(3)
1085  && b.bigEnd (3) <= m_domainBox.bigEnd (3))), &&
1086  (m_isPeriodic[4]
1087  || ( b.smallEnd(4) >= m_domainBox.smallEnd(4)
1088  && b.bigEnd (4) <= m_domainBox.bigEnd (4))), &&
1089  (m_isPeriodic[5]
1090  || ( b.smallEnd(5) >= m_domainBox.smallEnd(5)
1091  && b.bigEnd (5) <= m_domainBox.bigEnd (5))))));
1092  }
1093  else
1094  {
1096 
1097  // Check b's centering and adjust intersectBox as needed
1098  for (int dir = 0; dir < SpaceDim; dir++)
1099  {
1100  if (b.type(dir) != domainBox.type(dir))
1101  {
1102  if (b.type(dir) == IndexType::NODE)
1103  {
1104  domainBox.surroundingNodes(dir);
1105  }
1106  else
1107  {
1108  domainBox.enclosedCells(dir);
1109  }
1110  }
1111  }
1112 
1113  return ( !isEmpty()
1114  && (D_TERM6((m_isPeriodic[0]
1115  || ( b.smallEnd(0) >= domainBox.smallEnd(0)
1116  && b.bigEnd (0) <= domainBox.bigEnd (0))), &&
1117  (m_isPeriodic[1]
1118  || ( b.smallEnd(1) >= domainBox.smallEnd(1)
1119  && b.bigEnd (1) <= domainBox.bigEnd (1))), &&
1120  (m_isPeriodic[2]
1121  || ( b.smallEnd(2) >= domainBox.smallEnd(2)
1122  && b.bigEnd (2) <= domainBox.bigEnd (2))), &&
1123  (m_isPeriodic[3]
1124  || ( b.smallEnd(3) >= domainBox.smallEnd(3)
1125  && b.bigEnd (3) <= domainBox.bigEnd (3))), &&
1126  (m_isPeriodic[4]
1127  || ( b.smallEnd(4) >= domainBox.smallEnd(4)
1128  && b.bigEnd (4) <= domainBox.bigEnd (4))), &&
1129  (m_isPeriodic[5]
1130  || ( b.smallEnd(5) >= domainBox.smallEnd(5)
1131  && b.bigEnd (5) <= domainBox.bigEnd (5))))));
1132  }
1133 }
1134 
1135 /// Returns a face-centered Box at the low side of \em a_pd
1136 /**
1137  Returns the edge-centered Box (in direction \em a_dir) defining
1138  the low side of the argument ProblemDomain. The output Box will
1139  have the given length in the given direction. Directions are
1140  zero-based. It is an error if not 0 <= dir < SpaceDim. The neighbor
1141  of an Empty ProblemDomain is an Empty Box of the appropriate type.
1142  If \em a_dir is a periodic direction, will return an empty Box.
1143  */
1144 Box bdryLo (const ProblemDomain& a_pd,
1145  int a_dir,
1146  int a_len=1);
1147 
1148 /// Returns a face-centered Box at the high side of \em a_pd
1149 /**
1150  Returns the edge-centered Box (in direction \em a_dir) defining the
1151  high side of the argument ProblemDomain. The return Box will have the
1152  given length in the given direction. Directions are zero-based.
1153  It is an error if not 0 <= dir < SpaceDim. The neighbor of an
1154  Empty ProblemDomain is an Empty Box of the appropriate type.
1155  If \em a_dir is a periodic direction, will return an empty Box.
1156  */
1157 Box bdryHi (const ProblemDomain& a_pd,
1158  int a_dir,
1159  int a_len=1);
1160 
1161 /// Returns the cell-centered Box adjacent to the low side of \em a_pd.
1162 /**
1163  Returns the cell centered Box of the given length adjacent to the
1164  argument ProblemDomain on the low end along the given coordinate direction.
1165  The return Box is identical to the argument ProblemDomain in the other
1166  directions. The return ProblemDomain and the argument ProblemDomain
1167  have an empty intersection.
1168 
1169  \b NOTES:
1170  - len >= 1.
1171  - Box retval = adjCellLo(b,dir,len) is equivalent to the following set of
1172  operations:
1173  \code
1174  Box retval(b);
1175 
1176  retval.convert(dir,ProblemDomain::CELL);
1177 
1178  retval.setrange(dir,retval.smallEnd(dir)-len,len);
1179  \endcode
1180 
1181  Directions are zero-based. It is an error if not 0 <= dir <
1182  SpaceDim. The neighbor of an Empty ProblemDomain is an Empty Box of the
1183  appropriate type. If \em a_dir is a periodic direction, will return
1184  an empty Box as well.
1185 
1186  */
1187 Box adjCellLo (const ProblemDomain& a_pd,
1188  int a_dir,
1189  int a_len=1);
1190 
1191 /// Returns the cell-centered Box adjacent to the low side of \em a_pd.
1192 /**
1193  Returns the cell centered Box of the given length adjacent to the
1194  argument ProblemDomain on the high end along the given coordinate
1195  direction. The return Box is identical to the argument ProblemDomain in
1196  the other directions. The return Box and the argument ProblemDomain have
1197  an empty intersection.
1198 
1199  \b NOTES:
1200  - len >= 1.
1201 
1202  - Box retval = adjCellHi(b,dir,len) is equivalent to the
1203  following set of operations:
1204  \code
1205  Box retval(b);
1206 
1207  retval.convert(dir,ProblemDomain::CELL);
1208 
1209  retval.setrange(dir,retval.bigEnd(dir)+1,len);
1210  \endcode
1211 
1212  Directions are zero-based. It is an error if not 0 <= dir <
1213  SpaceDim. The neighbor of an Empty ProblemDomain is an Empty Box of the
1214  appropriate type. If \em a_dir is a periodic direction, will return
1215  an empty Box.
1216 
1217  */
1218 Box adjCellHi (const ProblemDomain& a_pd,
1219  int a_dir,
1220  int a_len=1);
1221 
1222 
1223 #endif /*WRAPPER*/
1224 
1225 #include "NamespaceFooter.H"
1226 #endif
Box m_domainBox
Definition: ProblemDomain.H:669
Definition: Box.H:52
bool contains(const IntVect &p) const
Returns true if argument is contained within this ProblemDomain.
Definition: ProblemDomain.H:999
bool contains_box(const Box &b) const
Equivalent to contains() function.
Definition: ProblemDomain.H:335
IntVect size() const
size functions
Definition: Box.H:1803
#define D_TERM6(a, b, c, d, e, f)
Definition: CHArray.H:40
#define CH_assert(cond)
Definition: CHArray.H:37
Box refine(const Box &b, const IntVect &refinement_ratio)
A class to facilitate interaction with physical boundary conditions.
Definition: ProblemDomain.H:141
ProblemDomain & growLo(int idir, int n_cell=1)
Grow this ProblemDomain on the low side.
Definition: ProblemDomain.H:955
void shift(const IntVect &a_shift)
Definition: ProblemDomain.H:626
friend Box bdryLo(const ProblemDomain &a_pd, int a_dir, int a_len)
Returns a face-centered Box at the low side of a_pd.
const Box & box() const
Definition: ProblemDomain.H:701
IntVect i() const
Equivalent to the () operator.
Definition: ProblemDomain.H:73
IntVect type() const
Definition: Box.H:1789
bool contains(const IntVect &p) const
Definition: Box.H:1871
ProblemDomain & operator=(const ProblemDomain &b)
The assignment operator.
Definition: ProblemDomain.H:862
Box & surroundingNodes()
IntVect size() const
Return the size of the domainBox.
Definition: ProblemDomain.H:992
int isEmpty(const box2d *)
bool m_isPeriodic[SpaceDim]
Definition: ProblemDomain.H:664
IntVect operator()() const
Returns the current shift unit vector.
Definition: ProblemDomain.H:754
ShiftIterator shiftIterator() const
Returns the shiftIterator for this ProblemDomain.
Definition: ProblemDomain.H:971
ProblemDomain m_domain
Definition: ProblemDomain.H:717
const int SpaceDim
Definition: SPACE.H:38
bool ok()
Definition: ProblemDomain.H:696
void incr()
Equivalent to the ++ operator.
Definition: ProblemDomain.H:81
Box & enclosedCells()
const ProblemDomain & domain() const
Definition: ProblemDomain.H:706
IndexTM< T, N > coarsen(const IndexTM< T, N > &a_p, T a_s)
Definition: IndexTMI.H:430
ShiftIterator()
Basic constructor.
Definition: ProblemDomain.H:731
const IntVect & bigEnd() const
Definition: Box.H:1768
bool operator<(const ProblemDomain &rhs) const
Definition: ProblemDomain.H:631
std::ostream & operator<<(std::ostream &a_os, const IndexTM< T, N > &a_iv)
void begin(const Box &a_box)
Definition: ProblemDomain.H:687
Class to manage box-shifting used to enforce periodic BC&#39;s.
Definition: ProblemDomain.H:33
friend Box adjCellLo(const ProblemDomain &a_pd, int a_dir, int a_len)
Returns the cell-centered Box adjacent to the low side of a_pd.
bool isPeriodic() const
Returns true if BC is periodic in any direction.
Definition: ProblemDomain.H:901
void shiftIt(Box &a_box, int shiftIndex) const
Definition: ProblemDomain.H:874
const IntVect & smallEnd() const
{ Accessors}
Definition: Box.H:1754
void computeShifts(const bool *a_isPeriodic)
Recompute shift vectors based on periodic directions.
std::istream & operator>>(std::istream &a_os, IndexTM< T, N > &a_iv)
void begin()
Equivalent to reset()
Definition: ProblemDomain.H:783
bool operator==(const ProblemDomain &a_otherDomain) const
Returns true if the two domain are equivalent.
Definition: ProblemDomain.H:830
bool isEmpty() const
Returns true if this ProblemDomain is empty or undefined.
Definition: ProblemDomain.H:978
unsigned int index() const
which periodic image is this
Definition: ProblemDomain.H:90
ShiftIterator m_shiftIt
Definition: ProblemDomain.H:674
Vector< IntVect > m_shift_vectors
Definition: ProblemDomain.H:115
size_t size() const
Definition: Vector.H:192
int m_counter
Definition: ProblemDomain.H:722
static const IntVect Zero
Definition: IntVect.H:654
void define(const Box &a_domBox)
Construct ProblemDomain with a_domBox as computational domain.
friend Box bdryHi(const ProblemDomain &a_pd, int a_dir, int a_len)
Returns a face-centered Box at the high side of a_pd.
Box adjCellLo(const ProblemDomain &a_pd, int a_dir, int a_len=1)
Returns the cell-centered Box adjacent to the low side of a_pd.
void checkDefine(const ProblemDomain &a_domain)
Definition: ProblemDomain.H:711
bool image(IntVect &p) const
Returns the periodic image of this IntVect inside of the ProblemDomain.
Definition: ProblemDomain.H:1026
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:465
ProblemDomain & growHi(int idir, int n_cell=1)
Grow this ProblemDomain on the high side.
Definition: ProblemDomain.H:963
void unshiftIt(Box &a_box, int shiftIndex) const
Definition: ProblemDomain.H:880
bool ok() const
Is the iterator still within its range of shift vectors?
Definition: ProblemDomain.H:769
ImageIterator(const ProblemDomain &a_domain)
Definition: ProblemDomain.H:680
void operator++()
Increment to the next shift unit vector.
Definition: ProblemDomain.H:762
friend Box adjCellHi(const ProblemDomain &a_pd, int a_dir, int a_len)
Returns the cell-centered Box adjacent to the low side of a_pd.
Handle to a particular group in an HDF file.
Definition: CH_HDF5.H:294
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
Box bdryLo(const ProblemDomain &a_pd, int a_dir, int a_len=1)
Returns a face-centered Box at the low side of a_pd.
ProblemDomain()
The default constructor. The constructed domain box is empty.
Definition: ProblemDomain.H:796
ProblemDomain grow(const ProblemDomain &pd, int i)
Definition: ProblemDomain.H:921
ShiftIterator & operator=(const ShiftIterator &a_src)
Assignment operator.
Definition: ProblemDomain.H:745
void reset()
Reset to first shift unit vector.
Definition: ProblemDomain.H:776
Box & shift(int dir, int nzones)
shift functions
Definition: Box.H:2067
bool operator!=(const ProblemDomain &a_otherDomain) const
Returns true if the two domain are not equivalent.
Definition: ProblemDomain.H:855
Box bdryHi(const ProblemDomain &a_pd, int a_dir, int a_len=1)
Returns a face-centered Box at the high side of a_pd.
Box m_box
Definition: ProblemDomain.H:720
Box & grow(int i)
grow functions
Definition: Box.H:2247
const IntVect & operator[](int index) const
Definition: ProblemDomain.H:95
Box & growLo(int idir, int n_cell=1)
Definition: Box.H:2333
ProblemDomain & grow(int i)
Grows (or shrinks) the domain Box by i in all directions.
Definition: ProblemDomain.H:913
Definition: ProblemDomain.H:677
const Box & domainBox() const
Returns the logical computational domain.
Definition: ProblemDomain.H:887
bool isEmpty() const
{ Comparison Functions}
Definition: Box.H:1846
Box m_current
Definition: ProblemDomain.H:721
Box adjCellHi(const ProblemDomain &a_pd, int a_dir, int a_len=1)
Returns the cell-centered Box adjacent to the low side of a_pd.
~ShiftIterator()
Destructor.
void end()
Skip the iterator to the end.
Definition: ProblemDomain.H:790
unsigned int m_index
Definition: ProblemDomain.H:113
Box & growHi(int idir, int n_cell=1)
Definition: Box.H:2364
const bool * isPeriodicVect() const
Returns bool[SpaceDim vector of periodicity info.
Definition: ProblemDomain.H:281