Chombo + EB  3.0
Copier.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 _COPIER_H_
12 #define _COPIER_H_
13 
14 #include "DisjointBoxLayout.H"
15 #include "Pool.H"
16 #include "Vector.H"
17 #include "ProblemDomain.H"
18 #include "NamespaceHeader.H"
19 
20 class CopyIterator;
21 
22 // These classes are public because I can't find a nice
23 // way to make a class a friend of all the instantiations
24 // of a template class. These classes are not part of
25 // the public interface for the Array API.
26 //
27 // Later, if MotionItem shows up in the profiler, we
28 // can start using a pool allocation scheme and placement new
29 
31 {
32 public:
36  int procID;
37  // this constructor will probably eventually go away
38  MotionItem(const DataIndex& a_from,
39  const DataIndex& a_to,
40  const Box& a_region);
41  MotionItem(const DataIndex& a_from,
42  const DataIndex& a_to,
43  const Box& a_fromRegion,
44  const Box& a_toRegion);
45  void reverse();
46 
47 };
48 
49 
51 {
52 public:
53 
54  ///null constructor, copy constructor and operator= can be compiler defined.
56  m_recbuffer(NULL), m_reccapacity(0)
57  {}
58 
59  ///
60  virtual ~CopierBuffer();
61 
62  void clear();
63 
64  bool isDefined(int ncomps) const
65  { return ncomps == m_ncomps;}
66 
67  mutable int m_ncomps;
68 
69  mutable void* m_sendbuffer; // pointer member OK here,
70  // since LevelData<T> has no copy
71  mutable size_t m_sendcapacity;
72  mutable void* m_recbuffer; // pointer member OK here,
73  // since LevelData<T> has no copy
74  mutable size_t m_reccapacity;
75 
76 
77 #ifndef DOXYGEN
78 
79  struct bufEntry
80  {
81  void* bufPtr; // pointer into contiguous m_buffer
82  size_t size;
83  const MotionItem* item;
84  unsigned int procID;
85  bool operator < (const bufEntry& rhs) const
86  {
87  if (procID == rhs.procID)
88  {
89  const Box& left = item->toRegion;
90  const Box& right= rhs.item->toRegion;
91  if (left.smallEnd() == right.smallEnd())
92  {
93  return left.bigEnd().lexLT(right.bigEnd());
94  }
95  else
96  {
97  return item->toRegion < rhs.item->toRegion;
98  }
99  }
100  //else
101  return procID < rhs.procID;
102  }
103  };
104 
105 #endif
106  mutable std::vector<bufEntry> m_fromMe;
107  mutable std::vector<bufEntry> m_toMe;
108 
109 
110 protected:
111 
112 };
113 
114 
115 /// A strange but true thing to make copying from one boxlayoutdata to another fast
116 /**
117  class to handle the organization of data from a LevelData to a BoxLayoutData
118  defined over the same index space. The idea behind this object
119  is twofold:
120  A) there is a significant amount of information that can be
121  computed once and reused from one copy to the next for
122  a LevelData and BoxLayoutData that have unchanging BoxLayouts
123  underneath them. In these cases, LevelData::copyTo methods
124  has an optional argument. That way, in cases where the operation
125  is only performed a single time, we do not waste our time building
126  optimizing data, etc.
127  B) when we interface with KeLP, this class maps quite well
128  with the existing KeLP API (class MotionPlan).
129 
130  pains have been taken to not have this class be templated. Thus
131  it does not actually perform the copying itself (which would require
132  knowledge of the template class type). It provides an iterator
133  interface to MotionItems that specify the required work. LevelData
134  provides the copyTo methods.
135 */
136 
137 class Copier
138 {
139 public:
140 
141  ///null constructor, copy constructor and operator= can be compiler defined.
143  {}
144 
145  Copier(const Copier& a_rhs);
146 
147  ///
148  Copier(const DisjointBoxLayout& a_level,
149  const BoxLayout& a_dest,
150  bool a_exchange = false,
151  IntVect a_shift = IntVect::Zero);
152 
153  /// this constructor contains support for periodic BC's
154  Copier(const DisjointBoxLayout& a_level,
155  const BoxLayout& a_dest,
156  const ProblemDomain& a_domain,
157  bool a_exchange = false,
158  IntVect a_shift = IntVect::Zero);
159 
160  /// Copier to copy data into the valid and invalid regions of a_dest from a_level
161  Copier(const DisjointBoxLayout& a_level,
162  const BoxLayout& a_dest,
163  const IntVect& a_destGhost,
164  bool a_exchange = false,
165  IntVect a_shift = IntVect::Zero);
166 
167  /// Copier to copy data into the valid and invalid regions of a_dest from a_level with support for periodic BCs
168  Copier(const DisjointBoxLayout& a_level,
169  const BoxLayout& a_dest,
170  const ProblemDomain& a_domain,
171  const IntVect& a_destGhost,
172  bool a_exchange = false,
173  IntVect a_shift = IntVect::Zero);
174 
175  ///
176  virtual ~Copier();
177 
178  ///
179  virtual void define(const DisjointBoxLayout& a_level,
180  const BoxLayout& a_dest,
181  bool a_exchange = false,
182  IntVect a_shift = IntVect::Zero);
183 
184  /// contains support for periodic BCs
185  virtual void define(const DisjointBoxLayout& a_level,
186  const BoxLayout& a_dest,
187  const ProblemDomain& a_domain,
188  bool a_exchange = false,
189  IntVect a_shift = IntVect::Zero);
190 
191  ///
192  virtual void define(const DisjointBoxLayout& a_level,
193  const BoxLayout& a_dest,
194  const IntVect& a_destGhost,
195  bool a_exchange = false,
196  IntVect a_shift = IntVect::Zero);
197 
198  /// contains support for periodic BCs
199  virtual void define(const BoxLayout& a_level,
200  const BoxLayout& a_dest,
201  const ProblemDomain& a_domain,
202  const IntVect& a_destGhost,
203  bool a_exchange = false,
204  IntVect a_shift = IntVect::Zero);
205 
206  /// alternative version of define for exchange copiers that uses new optimized neighborIterator
207  virtual void exchangeDefine(const DisjointBoxLayout& a_grids,
208  const IntVect& a_ghost);
209 
210  /// performs the computation necessary for moving from ghost+valid cells to valid.
211  /** instead of copying from the valid of a_src to the valid+ghost of a_dest,
212  this routine defines a Copier that moves data from the ghost+valid region
213  of a_src to the valid region of a_dest. This is used by LevelFluxRegister.
214  */
215  void ghostDefine(const DisjointBoxLayout& a_src,
216  const DisjointBoxLayout& a_dest,
217  const ProblemDomain& a_domain,
218  const IntVect& a_srcGhost);
219  ///
220  virtual void clear();
221 
222  ///
223  /**
224  The assignment operator.
225 
226  */
227  Copier& operator= (const Copier& b);
228 
229 
230  ///
231  /**
232  reverse the communication of this Copier.
233  */
234  void reverse();
235 
236  ///
237  /**
238  Under the right algorithmic circumstances, a user might know that they no not
239  need corner cells filled in exchanges, what they really need are just sufficient
240  ghost cells in each CH_SPACEDIM direction for each valid cell. This operation
241  eliminates copy operations that do not contribute to such cells. Under reasonable
242  3D configurations this can eliminate more than half the copy operations.
243  */
244  void trimEdges(const DisjointBoxLayout& a_exchangedLayout, const IntVect& ghost);
245 
246  ///
247  /*
248  OK, if you *really* know what you are doing (!) you can coarsen a Copier in place of
249  building a new Copier on a coarsened DisjointBoxLayout. The trick is when you do have
250  ghost cells and working out on paper for yourself that the coarsening is valid. One
251  common configuration is an exchange Copier with *one* ghost cell. A particular
252  case where coarsen will do the *wrong* thing is an exchange Copier with more than one
253  ghost cell.
254  **/
255  void coarsen(int a_refRatio);
256 
257  int print() const;
258 
259  bool bufferAllocated() const;
260  void setBufferAllocated(bool arg) const;
261 
262  int numLocalCellsToCopy() const;
263  int numFromCellsToCopy() const;
264  int numToCellsToCopy() const;
265 
266  bool isDefined() const
267  { return m_isDefined;}
268 
270 
271 protected:
272 
273  friend class CopyIterator;
274 
278 
279  friend void dumpmemoryatexit();
281  mutable bool buffersAllocated;
282 
283  // keep a refcounted reference around for debugging purposes, we can
284  // decide afterwards if we want to eliminate it.
287 
289 
290  void trimMotion(const DisjointBoxLayout& a_exchangedLayout, const IntVect& a_ghost,
291  const Vector<MotionItem*>& a_oldItems, Vector<MotionItem*>& a_newItems);
292 
293  void sort();
294 
295 
296  // sneaky end-around to problem of getting physDomains in derived classes
297  const ProblemDomain& getPhysDomain(const DisjointBoxLayout& a_level) const;
298 };
299 
300 std::ostream& operator<<(std::ostream& os, const Copier& copier);
301 
302 //===========================================================================
303 // end of public interface for Copier.
304 //===========================================================================
305 
306 
307 inline MotionItem::MotionItem(const DataIndex& a_from,
308  const DataIndex& a_to,
309  const Box& a_region)
310  :fromIndex(a_from), toIndex(a_to), fromRegion(a_region),
311  toRegion(a_region), procID(-1)
312 {
313 }
314 
315 inline MotionItem::MotionItem(const DataIndex& a_from,
316  const DataIndex& a_to,
317  const Box& a_fromRegion,
318  const Box& a_toRegion)
319  :fromIndex(a_from), toIndex(a_to), fromRegion(a_fromRegion),
320  toRegion(a_toRegion), procID(-1)
321 {
322 }
323 
324 inline
326 {
327  Box tmp(fromRegion);
329  toRegion=tmp;
330  DataIndex tmpIndex(fromIndex);
331  fromIndex = toIndex;
332  toIndex = tmpIndex;
333 }
334 
336 {
337 public:
339  {
343  };
344 
345  inline CopyIterator(const Copier& a_copier, local_from_to);
346 
347  inline const MotionItem& operator()() const;
348 
349  inline void operator++();
350 
351  inline bool ok() const;
352 
353  inline void reset();
354 private:
356  unsigned int m_current;
357 };
358 
359 //====== inlined functions====================================
360 
361 inline CopyIterator::CopyIterator(const Copier& a_copier, local_from_to type)
362  :m_current(0)
363 {
364  switch(type)
365  {
366  case LOCAL:
367  m_motionplanPtr = &(a_copier.m_localMotionPlan);
368  break;
369  case FROM:
370  m_motionplanPtr = &(a_copier.m_fromMotionPlan);
371  break;
372  case TO:
373  m_motionplanPtr = &(a_copier.m_toMotionPlan);
374  break;
375  default:
376  MayDay::Error("illegal local_from_to option for CopyIterator");
377  }
378 }
379 
381 {
382  CH_assert(m_current < m_motionplanPtr->size());
383  return *(m_motionplanPtr->operator[](m_current));
384 }
385 
387 {
388  ++m_current;
389 }
390 
391 inline bool CopyIterator::ok() const
392 {
393  return m_current < m_motionplanPtr->size();
394 }
395 
396 inline void CopyIterator::reset()
397 {
398  m_current = 0;
399 }
400 
401 #include "NamespaceFooter.H"
402 #endif
void ghostDefine(const DisjointBoxLayout &a_src, const DisjointBoxLayout &a_dest, const ProblemDomain &a_domain, const IntVect &a_srcGhost)
performs the computation necessary for moving from ghost+valid cells to valid.
int numLocalCellsToCopy() const
void sort()
void reset()
Definition: Copier.H:396
#define CH_assert(cond)
Definition: CHArray.H:37
A class to facilitate interaction with physical boundary conditions.
Definition: ProblemDomain.H:130
CopierBuffer m_buffers
Definition: Copier.H:269
Vector< MotionItem * > m_fromMotionPlan
Definition: Copier.H:276
int m_ncomps
Definition: Copier.H:67
bool bufferAllocated() const
A not-necessarily-disjoint collective of boxes.
Definition: BoxLayout.H:146
void reverse()
A strange but true thing to make copying from one boxlayoutdata to another fast.
Definition: Copier.H:137
std::ostream & operator<<(std::ostream &os, const Copier &copier)
std::vector< bufEntry > m_fromMe
Definition: Copier.H:106
DisjointBoxLayout m_originPlan
Definition: Copier.H:285
Definition: Copier.H:341
bool m_isDefined
Definition: Copier.H:288
const MotionItem & operator()() const
Definition: Copier.H:380
Definition: Copier.H:50
size_t m_sendcapacity
Definition: Copier.H:71
bool isDefined(int ncomps) const
Definition: Copier.H:64
void reverse()
Definition: Copier.H:325
static Pool s_motionItemPool
Definition: Copier.H:280
Definition: Copier.H:342
Definition: Copier.H:30
int procID
Definition: Copier.H:36
DataIndex toIndex
Definition: Copier.H:33
BoxLayout m_dest
Definition: Copier.H:286
Vector< MotionItem * > m_toMotionPlan
Definition: Copier.H:277
size_t m_reccapacity
Definition: Copier.H:74
void * m_recbuffer
Definition: Copier.H:72
MotionItem(const DataIndex &a_from, const DataIndex &a_to, const Box &a_region)
Definition: Copier.H:307
void coarsen(int a_refRatio)
void * m_sendbuffer
Definition: Copier.H:69
int numToCellsToCopy() const
void trimMotion(const DisjointBoxLayout &a_exchangedLayout, const IntVect &a_ghost, const Vector< MotionItem * > &a_oldItems, Vector< MotionItem * > &a_newItems)
bool operator<(const FaceIndex &f1, const FaceIndex &f2)
Definition: FaceIndex.H:204
const IntVect & bigEnd() const
Definition: Box.H:1779
Pool is a class to optimize memory allocation.
Definition: Pool.H:63
bool lexLT(const IntVect &s) const
Definition: IntVect.H:814
bool buffersAllocated
Definition: Copier.H:281
virtual void exchangeDefine(const DisjointBoxLayout &a_grids, const IntVect &a_ghost)
alternative version of define for exchange copiers that uses new optimized neighborIterator ...
A BoxLayout that has a concept of disjointedness.
Definition: DisjointBoxLayout.H:31
CopierBuffer()
null constructor, copy constructor and operator= can be compiler defined.
Definition: Copier.H:55
Vector< MotionItem * > m_localMotionPlan
Definition: Copier.H:275
const ProblemDomain & getPhysDomain(const DisjointBoxLayout &a_level) const
Box toRegion
Definition: Copier.H:35
static void Error(const char *const a_msg=m_nullString, int m_exitCode=CH_DEFAULT_ERROR_CODE)
Print out message to cerr and exit with the specified exit code.
unsigned int m_current
Definition: Copier.H:356
void operator++()
Definition: Copier.H:386
void trimEdges(const DisjointBoxLayout &a_exchangedLayout, const IntVect &ghost)
static const IntVect Zero
Definition: IntVect.H:627
int numFromCellsToCopy() const
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:465
Copier & operator=(const Copier &b)
Definition: DataIndex.H:112
bool ok() const
Definition: Copier.H:391
Copier()
null constructor, copy constructor and operator= can be compiler defined.
Definition: Copier.H:142
void setBufferAllocated(bool arg) const
local_from_to
Definition: Copier.H:338
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
virtual ~CopierBuffer()
size_t size() const
Definition: Vector.H:177
virtual void clear()
virtual ~Copier()
Definition: Copier.H:340
friend void dumpmemoryatexit()
bool isDefined() const
Definition: Copier.H:266
virtual void define(const DisjointBoxLayout &a_level, const BoxLayout &a_dest, bool a_exchange=false, IntVect a_shift=IntVect::Zero)
const Vector< MotionItem * > * m_motionplanPtr
Definition: Copier.H:355
DataIndex fromIndex
Definition: Copier.H:33
int print() const
const IntVect & smallEnd() const
{ Accessors}
Definition: Box.H:1765
int procID()
local process ID
Box fromRegion
Definition: Copier.H:34
CopyIterator(const Copier &a_copier, local_from_to)
Definition: Copier.H:361
std::vector< bufEntry > m_toMe
Definition: Copier.H:107
Definition: Copier.H:335