Chombo + EB + MF  3.2
BoxLayoutData.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 _BOXLAYOUTDATA_H_
12 #define _BOXLAYOUTDATA_H_
13 
14 #include "LayoutData.H"
15 #include "Interval.H"
16 #include "FArrayBox.H"
17 #include "DisjointBoxLayout.H"
18 #include "Copier.H"
19 #include "SPMD.H"
20 #include "memtrack.H"
21 #include "NamespaceHeader.H"
22 
23 //--Forward declarations
24 
25 class FluxBox;
26 
27 extern int LinearizationTest;
28 
29 /// Factory object to data members of a BoxLayoutData container
30 template <class T> class DataFactory
31 {
32 public:
33 
34  virtual ~DataFactory()
35  {
36  }
37 
38  /// factory function. creates a new 'T' object
39  /** creates a new 'T' object and returns a pointer to it.
40  */
41  virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const=0;
42 
43  virtual bool callDelete() const
44  {
45  return true;
46  }
47 
48  //return true if copy and construction are thread safe
49  virtual bool threadSafe() const
50  {
51  return true;
52  }
53 };
54 
55 /// Factory object to data members of a BoxLayoutData container
56 /**
57  creates new T object by invoking operator new
58 
59  \code
60  template <class T>
61  T* DefaultDataFactory<T>::create(const Box& box,
62  int ncomps,
63  const DataIndex& a_datInd) const
64  {
65  return new T(box, ncomps);
66  }
67  \endcode
68  */
69 
70 template <class T> class DefaultDataFactory : public DataFactory<T>
71 {
72 public:
73  /// factory function. creates a new 'T' object
74  /** creates a new 'T' object and returns a pointer to it. Responsiblitly
75  for calling operator 'delete' on this pointer is passed to the user. */
76  virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
77 
78 };
79 
80 class FABAliasDataFactory : public DataFactory<FArrayBox>
81 {
82 public:
84  {}
85 
86  FABAliasDataFactory(const LayoutData<Real*>& aliases);
87  void define(const LayoutData<Real*>& aliases);
88  /// factory function. creates a new 'T' object using an aliased dataPtr for T
89  /** creates a new 'T' object and returns a pointer to it. Responsiblitly
90  for calling operator 'delete' on this pointer is passed to the user. */
91  virtual FArrayBox* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
92 
93 protected:
95 };
96 
97 template<class T> class BoxLayoutData;
98 
99 template <class T>
100 class AliasDataFactory : public DataFactory<T>
101 {
102 public:
104  {}
105 
106  AliasDataFactory(BoxLayoutData<T>* a_original, const Interval& interval);
107  void define(BoxLayoutData<T>* a_original, const Interval& interval);
108  /** creates a new 'T' object and returns a pointer to it. Responsiblitly
109  for calling operator 'delete' on this pointer is passed to the user. */
110  virtual T* create(const Box& box, int ncomps, const DataIndex& a_datInd) const;
111 
112  //return true if copy and construction are thread safe
113  virtual bool threadSafe() const
114  {
115  return m_origPointer->threadSafe();
116  }
117 protected:
120 };
121 
122 //--For aliasing a LevelData<FArrayBox> to a LevelData<FluxBox>
123 
124 class FABAliasFlBxDataFactory : public DataFactory<FArrayBox>
125 {
126 public:
128  {}
129 
131  const Interval& a_interval,
132  const int a_dir);
133  void define(BoxLayoutData<FluxBox>* a_original,
134  const Interval& a_interval,
135  const int a_dir);
136  /** creates a new 'T' object and returns a pointer to it. Responsiblitly
137  for calling operator 'delete' on this pointer is passed to the user. */
138  virtual FArrayBox* create(const Box& a_box,
139  int a_ncomps,
140  const DataIndex& a_datInd) const;
141 protected:
144  int m_dir;
145 };
146 
147 //new code
148 //--For aliasing a LevelData<FArrayBox> to a LevelData<FluxBox>
149 
150 class FaceFabDataFactory : public DataFactory<FArrayBox>
151 {
152 public:
154  {}
155 
156  FaceFabDataFactory(const int a_dir);
157 
158  void define(const int a_dir);
159 
160  /** creates a new 'T' object and returns a pointer to it. Responsiblitly
161  for calling operator 'delete' on this pointer is passed to the user. */
162  virtual FArrayBox* create(const Box & a_box ,
163  int a_ncomps,
164  const DataIndex& a_datInd) const;
165 protected:
166  int m_dir;
167 };
168 
169 ///new code
170 template<class T> class LevelData;
171 
172 template <class T>
174 {
175 public:
176  // to keep the compiler happy
177  virtual ~LDOperator()
178  {
179  }
180  virtual int size(const T& arg, const Box& b, const Interval& comps) const
181  {
182  return arg.size(b, comps);
183  }
184  virtual void linearOut(const T& arg, void* buf, const Box& R,
185  const Interval& comps) const
186  {
187  arg.linearOut(buf, R, comps);
188  }
189  virtual void linearIn(T& arg, void* buf, const Box& R,
190  const Interval& comps)const
191  {
192  arg.linearIn(buf, R, comps);
193  }
194 
195  ///this boolean only has to do with whether the op(...) function is thread safe
196  /**
197  If you want to declare a class more generally thread-unsafe, use the data factory
198  threadSafe interface.
199  */
200  virtual bool threadSafe() const
201  {
202  return true;
203  }
204  virtual void op(T& dest,
205  const Box& RegionFrom,
206  const Interval& Cdest,
207  const Box& RegionTo,
208  const T& src,
209  const Interval& Csrc) const
210  {
211  if (LinearizationTest == 0)
212  {
213  dest.copy(RegionFrom, Cdest,RegionTo, src, Csrc);
214  }
215  else
216  {
217  int sizeSource = size(src, RegionFrom, Csrc);
218  int sizeDest = size(dest, RegionTo, Cdest);
219 
220  if (T::preAllocatable() == 0 || T::preAllocatable() == 1)
221  {
222  if (sizeSource != sizeDest)
223  {
224  MayDay::Abort("LinearizationTest failure: dest and source have different sizes");
225  }
226  }
227  Vector<char> buffer(sizeSource);
228  void* b = (void*)&(buffer[0]);
229  linearOut(src, b, RegionFrom, Csrc);
230  linearIn(dest, b, RegionTo, Cdest);
231  }
232  }
233 };
234 
235 /// Data on a BoxLayout
236 /**
237 
238  A collection of Box-oriented objects. The arrangement
239  of Boxes is given by the underlying BoxLayout object.
240  BoxLayoutData attempt to prevent users from manipulating
241  the template class T to become out of sync with the
242  boxes in the BoxLayout. Caveat emptor.
243 
244  All access to the data in a BoxLayoutData is forced to be
245  data-parallel, by use of the DataIterator.
246 
247  class T must provide the following methods:
248  - <PRE> T() </PRE>
249  - <PRE> T(const Box& box, int comps) </PRE>
250  - <PRE> define(const Box& box, int comps) </PRE>
251  - <PRE> void copy(const Box& Rfrom, const Interval& Cd, const Box& Rto, const T& source, const Interval Cs)
252  Cs and Cd must have same length, but can be displaced;
253  Rfrom and Rto must be the same size, but can be translated. </PRE>
254  - <PRE> static int preAllocatable()
255  returns 0 if the size(...) function is strictly a function of Box and
256  Interval, and does not depend on the current state of the T object.
257  return 1 if size(..) is symmetric, in that sender and receiver T object
258  can size their message buffers, but a static object cannot.
259  returns 2 if the object is truly dynamic. the message size is subject to
260  unique object data. </PRE>
261  - <PRE> int size(const Box& R, const Interval& comps) </PRE>
262  - <PRE> void linearOut(void* buf, const Box& R, const Interval& comps)
263  writes the T object into the byte stream buf, already allocated. </PRE>
264  - <PRE> void linearIn(void* buf, const Box& R, const Interval& comps)
265  reads in the T object from the byte stream buf. </PRE>
266 
267  In sequential codes, many of these functions will not be called, but in the
268  general parallel case, they all will be.
269 */
270 
271 template<class T>
272 class BoxLayoutData : public LayoutData<T>
273 {
274 public:
275  ///
276  BoxLayoutData();
277 
278  virtual ~BoxLayoutData();
279  ///
280  BoxLayoutData(const BoxLayout& boxes, int comps,
281  const DataFactory<T>& factory = DefaultDataFactory<T>());
282 
283  ///
284  virtual void define(const BoxLayout& boxes, int comps,
285  const DataFactory<T>& factory = DefaultDataFactory<T>());
286 
287  ///
288  virtual void define(const BoxLayoutData<T>& da,
289  const DataFactory<T>& factory = DefaultDataFactory<T>());
290 
291  ///
292  /** Define this BoxLayoutData to be the subset of the
293  data in da defined by the Interval comps.
294  */
295  virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
296  const DataFactory<T>& factory = DefaultDataFactory<T>());
297 
298  /// overridden and throws an error.
299  virtual void define(const BoxLayout& boxes);
300 
301  virtual bool threadSafe() const
302  {
303  return m_threadSafe;
304  }
305  ///
306  int nComp() const
307  {
308  return m_comps;
309  }
310 
311  ///
313  {
314  Interval outint(0, m_comps-1);
315  return(outint);
316  }
317 
318  /// General data copying operation.
319  /**
320  @param a_destGrids BoxLayout for the destination data holder
321  @param a_dest return argument. upon completion contains a Vector of T objects
322  for each Box in a_destGrids that overlaps this->boxLayout()
323  @param a_interval range of components to source
324  @param a_domain ProblemDomain that this grid and a_destGrids reside on.
325  @param factory optional data factory for template classes that have non-trivial construction
326  */
327  void generalCopyTo(const BoxLayout& a_destGrids,
328  LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
329  const Interval& a_interval,
330  const ProblemDomain& a_domain,
331  const DataFactory<T>& factory = DefaultDataFactory<T>()) const ;
332 
333  ///
334  void generalCopyTo(const BoxLayout& a_destGrids,
335  LayoutData<Vector<RefCountedPtr<T> > >& a_dest,
336  const Interval& a_interval,
337  const ProblemDomain& a_domain,
338  const Copier& a_copier,
339  const DataFactory<T>& factory = DefaultDataFactory<T>()) const ;
340 
341  ///
342  /**
343  Special version of generalCopyTo that performs increment-on-intersection of
344  the destination instead of replacement
345  */
346  void addTo(const Interval& a_srcComps,
347  BoxLayoutData<T>& a_dest,
348  const Interval& a_destComps,
349  const ProblemDomain& a_domain) const;
350  ///
351  /**
352  Special version of generalCopyTo that performs increment-on-intersection of
353  the destination instead of replacement. This version lets the user send in a
354  pre-built Copier.
355  */
356  void addTo(const Interval& a_srcComps,
357  BoxLayoutData<T>& a_dest,
358  const Interval& a_destComps,
359  const ProblemDomain& a_domain,
360  const Copier& a_copier) const;
361 
362 
363  /**
364  Special version of generalCopyTo that performs increment-on-intersection of
365  the destination instead of replacement. This version of addTo allows for split-phase
366  communication, where you call addToBegin on the source, then addToEnd on
367  the destination. This version *requires* the user to use a prebuilt Copier and ensure
368  it's lifetime lives past the call to addToEnd (I have my buffers in the Copier)
369  */
370  void addToBegin(const Interval& a_srcComps,
371  BoxLayoutData<T>& a_dest,
372  const Interval& a_destComps,
373  const Copier& a_copier) const;
374 
375  /// you call this on the destination BoxLayoutData, not the source.
376  void addToEnd(const Interval& a_destComps);
377 
378  ///
379  /* User writes a function with the signature:
380 
381  <PRE>
382  void myfunction(const Box& box, int comps, T& t)
383  {
384  your code here;
385  }
386  </PRE>
387 
388  They can then hand this off to LayoutData::apply. This class
389  then cycles through all the T objects and invokes this function. Function
390  must not be inline. (I'm still trying to figure out a nice way to send
391  in non-static member functions).
392  */
393  virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
394 
395  ///
396  virtual bool isDefined() const;
397 
398  virtual void clear() ;
399 
400  int s_verbosity = 0;
401 
402 protected:
403  int m_comps;
406 
407  friend class LevelData<T>;
408 
409  void setVector(const BoxLayoutData<T>& da,
410  const Interval& srcComps,
411  const Interval& destComps);
412 
413  void allocateGhostVector(const DataFactory<T>& factory,
414  const IntVect& ghost = IntVect::Zero);
415 
416  void makeItSo(const Interval& a_srcComps,
417  const BoxLayoutData<T>& a_src,
418  BoxLayoutData<T>& a_dest,
419  const Interval& a_destComps,
420  const Copier& a_copier,
421  const LDOperator<T>& a_op = LDOperator<T>()) const;
422  void makeItSoBegin(
423  const Interval& a_srcComps,
424  const BoxLayoutData<T>& a_src,
425  BoxLayoutData<T>& a_dest,
426  const Interval& a_destComps,
427  const Copier& a_copier,
428  const LDOperator<T>& a_op = LDOperator<T>()) const;
429  void makeItSoLocalCopy(
430  const Interval& a_srcComps,
431  const BoxLayoutData<T>& a_src,
432  BoxLayoutData<T>& a_dest,
433  const Interval& a_destComps,
434  const Copier& a_copier,
435  const LDOperator<T>& a_op = LDOperator<T>()) const;
436  void makeItSoEnd(
437  const Interval& a_destComps,
438  const LDOperator<T>& a_op = LDOperator<T>());
439 
440  //========================================================================
441  //
442  // data structures used by makeItSo when we have some
443  // data that needs to be moved (ie. there are entries
444  // in the 'FROM' or 'TO' CopyIterators)
445  //
446  void completePendingSends() const;
447 
448  void allocateBuffers(const BoxLayoutData<T>& a_src,
449  const Interval& a_srcComps,
450  const BoxLayoutData<T>& a_dest,
451  const Interval& a_destComps,
452  const Copier& a_copier,
453  const LDOperator<T>& a_op) const;
454 
456  const Interval& a_srcComps,
457  const LDOperator<T>& a_op) const;
458 
459  void postSendsFromMe() const ;
460 
461  void postReceivesToMe() const ;
462 
463  void unpackReceivesToMe(
464  const Interval& a_destComps,
465  const LDOperator<T>& a_op) ;
466 
468  const Interval& a_destComps,
469  int ncomp,
470  const DataFactory<T>& factory,
471  const LDOperator<T>& a_op) const;
472 
473  /** \name Parallel messaging members */
474  /*@{*/
475 // mutable void* m_sendbuffer; // pointer member OK here,
476 // // since LevelData<T> has no copy
477 // mutable size_t m_sendcapacity;
478 // mutable void* m_recbuffer; // pointer member OK here,
479 // // since LevelData<T> has no copy
480 // mutable size_t m_reccapacity;
482 #ifdef CH_MPI
483 
484 #ifndef DOXYGEN
485 
486 #endif
487  // objects moved into Copier
488 // mutable std::vector<bufEntry> m_fromMe;
489 // mutable std::vector<bufEntry> m_toMe;
490 
491  // mutable Vector<MPI_Request> m_sendRequests, m_receiveRequests;
492  // mutable Vector<MPI_Status> m_receiveStatus, m_sendStatus;
493  // mutable int numSends, numReceives;
494 #endif
495 
496 };
497 
498 ///
499 /** not actually L-p norms, since it doesn't take into
500  account the dx of the system. A user can take that
501  into account or not.
502 
503  For p != 0, returns pth root of sum of pth powers over all
504  points in all fabs and all components in the interval:
505 
506  ( sum [ |A[i][pt,var]|^p : FArrayBox A[i], point pt in A[i].box(), var in interval ] )^(1/p)
507 
508  To turn into an L-p norm, one needs to multiply this by dx^(SpaceDim/p).
509 
510  For p == 0, returns global max over all points in all fabs and all
511  components in the interval:
512 
513  max [ |A[i][pt,var]| : FArrayBox A[i], point pt in A[i].box(), var in interval ]
514 
515  Some people don't like that this norm is not normalized based on
516  number of points in A. Normalization is your problem.
517  */
519  const Interval& interval,
520  const int& p = 2);
521 
522 //======================================================================
523 template < >
525  int ncomps,
526  const DataIndex& a_datInd) const;
527 
528 template < >
530  int ncomps,
531  const DataIndex& a_datInd) const;
532 
533 #include "NamespaceFooter.H"
534 #include "BoxLayoutDataI.H"
535 
536 #endif //BOXLAYOUTDATA
void postSendsFromMe() const
Definition: BoxLayoutDataI.H:372
void postReceivesToMe() const
Definition: BoxLayoutDataI.H:377
void allocateBuffers(const BoxLayoutData< T > &a_src, const Interval &a_srcComps, const BoxLayoutData< T > &a_dest, const Interval &a_destComps, const Copier &a_copier, const LDOperator< T > &a_op) const
Definition: BoxLayoutDataI.H:354
int m_comps
Definition: BoxLayoutData.H:403
CopierBuffer * m_buff
Definition: BoxLayoutData.H:481
A reference-counting handle class.
Definition: RefCountedPtr.H:173
Interval interval() const
Definition: BoxLayoutData.H:312
Interval m_interval
Definition: BoxLayoutData.H:119
A class to facilitate interaction with physical boundary conditions.
Definition: ProblemDomain.H:141
LayoutData< Real * > aliasPtrs
Definition: BoxLayoutData.H:94
virtual void linearIn(T &arg, void *buf, const Box &R, const Interval &comps) const
Definition: BoxLayoutData.H:189
virtual bool threadSafe() const
this boolean only has to do with whether the op(...) function is thread safe
Definition: BoxLayoutData.H:200
void makeItSoLocalCopy(const Interval &a_srcComps, const BoxLayoutData< T > &a_src, BoxLayoutData< T > &a_dest, const Interval &a_destComps, const Copier &a_copier, const LDOperator< T > &a_op=LDOperator< T >()) const
Definition: BoxLayoutDataI.H:291
A not-necessarily-disjoint collective of boxes.
Definition: BoxLayout.H:145
Data that maintains a one-to-one mapping of T to the boxes in a BoxLayout.
Definition: BoxLayout.H:26
Real norm(const BoxLayoutData< FArrayBox > &A, const Interval &interval, const int &p=2)
A strange but true thing to make copying from one boxlayoutdata to another fast.
Definition: Copier.H:152
void unpackReceivesToMe(const Interval &a_destComps, const LDOperator< T > &a_op)
Definition: BoxLayoutDataI.H:382
void makeItSoBegin(const Interval &a_srcComps, const BoxLayoutData< T > &a_src, BoxLayoutData< T > &a_dest, const Interval &a_destComps, const Copier &a_copier, const LDOperator< T > &a_op=LDOperator< T >()) const
Definition: BoxLayoutDataI.H:250
void completePendingSends() const
Definition: BoxLayoutDataI.H:349
Definition: Copier.H:61
void setVector(const BoxLayoutData< T > &da, const Interval &srcComps, const Interval &destComps)
Definition: BoxLayoutDataI.H:45
virtual ~DataFactory()
Definition: BoxLayoutData.H:34
virtual bool callDelete() const
Definition: BoxLayoutData.H:43
virtual void op(T &dest, const Box &RegionFrom, const Interval &Cdest, const Box &RegionTo, const T &src, const Interval &Csrc) const
Definition: BoxLayoutData.H:204
virtual ~FABAliasFlBxDataFactory()
Definition: BoxLayoutData.H:127
Definition: EBInterface.H:45
Definition: BoxLayoutData.H:150
int LinearizationTest
Factory object to data members of a BoxLayoutData container.
Definition: BoxLayoutData.H:70
A FArrayBox-like container for face-centered fluxes.
Definition: FluxBox.H:22
virtual ~FaceFabDataFactory()
Definition: BoxLayoutData.H:153
void const char const int const int const int const Real const Real * A
Definition: Lapack.H:83
virtual int size(const T &arg, const Box &b, const Interval &comps) const
Definition: BoxLayoutData.H:180
Structure for passing component ranges in code.
Definition: Interval.H:23
void unpackReceivesToMe_append(LayoutData< Vector< RefCountedPtr< T > > > &a_dest, const Interval &a_destComps, int ncomp, const DataFactory< T > &factory, const LDOperator< T > &a_op) const
Definition: BoxLayoutDataI.H:389
int m_dir
Definition: BoxLayoutData.H:166
new code
Definition: BoxLayoutData.H:170
void allocateGhostVector(const DataFactory< T > &factory, const IntVect &ghost=IntVect::Zero)
Definition: BoxLayoutDataI.H:167
Data on a BoxLayout.
Definition: BoxLayoutData.H:97
void linearOut(void *const a_outBuf, const T &inputT)
Definition: SPMDI.H:33
double Real
Definition: REAL.H:33
BoxLayoutData< FluxBox > * m_origPointer
Definition: BoxLayoutData.H:142
Definition: BoxLayoutData.H:80
virtual ~LDOperator()
Definition: BoxLayoutData.H:177
Definition: BoxLayoutData.H:124
void makeItSo(const Interval &a_srcComps, const BoxLayoutData< T > &a_src, BoxLayoutData< T > &a_dest, const Interval &a_destComps, const Copier &a_copier, const LDOperator< T > &a_op=LDOperator< T >()) const
Definition: BoxLayoutDataI.H:232
virtual ~AliasDataFactory()
Definition: BoxLayoutData.H:103
virtual ~FABAliasDataFactory()
Definition: BoxLayoutData.H:83
virtual bool threadSafe() const
Definition: BoxLayoutData.H:113
virtual bool threadSafe() const
Definition: BoxLayoutData.H:49
static const IntVect Zero
Definition: IntVect.H:658
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:469
int nComp() const
Definition: BoxLayoutData.H:306
Definition: DataIndex.H:114
Definition: BoxLayoutData.H:100
void writeSendDataFromMeIntoBuffers(const BoxLayoutData< T > &a_src, const Interval &a_srcComps, const LDOperator< T > &a_op) const
Definition: BoxLayoutDataI.H:365
bool m_isdefined
Definition: BoxLayoutData.H:405
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
Definition: FArrayBox.H:45
virtual T * create(const Box &box, int ncomps, const DataIndex &a_datInd) const =0
factory function. creates a new &#39;T&#39; object
Factory object to data members of a BoxLayoutData container.
Definition: BoxLayoutData.H:30
void makeItSoEnd(const Interval &a_destComps, const LDOperator< T > &a_op=LDOperator< T >())
Definition: BoxLayoutDataI.H:335
int m_dir
Definition: BoxLayoutData.H:144
virtual bool threadSafe() const
Definition: BoxLayoutData.H:301
virtual void linearOut(const T &arg, void *buf, const Box &R, const Interval &comps) const
Definition: BoxLayoutData.H:184
Definition: BoxLayoutData.H:173
BoxLayoutData< T > * m_origPointer
Definition: BoxLayoutData.H:118
bool m_threadSafe
Definition: BoxLayoutData.H:404
virtual T * create(const Box &box, int ncomps, const DataIndex &a_datInd) const
factory function. creates a new &#39;T&#39; object
Definition: BoxLayoutDataI.H:31
void linearIn(T &a_outputT, const void *const inBuf)
Definition: SPMDI.H:27
Interval m_interval
Definition: BoxLayoutData.H:143
static void Abort(const char *const a_msg=m_nullString)
Print out message to cerr and exit via abort() (if serial) or MPI_Abort() (if parallel).