Chombo + EB  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  /* User writes a function with the signature:
364 
365  <PRE>
366  void myfunction(const Box& box, int comps, T& t)
367  {
368  your code here;
369  }
370  </PRE>
371 
372  They can then hand this off to LayoutData::apply. This class
373  then cycles through all the T objects and invokes this function. Function
374  must not be inline. (I'm still trying to figure out a nice way to send
375  in non-static member functions).
376  */
377  virtual void apply(void (*a_Function)(const Box& box, int comps, T& t));
378 
379  ///
380  virtual bool isDefined() const;
381 
382  virtual void clear() ;
383 
384  static int s_verbosity;
385 
386 protected:
387  int m_comps;
390 
391  friend class LevelData<T>;
392 
393  void setVector(const BoxLayoutData<T>& da,
394  const Interval& srcComps,
395  const Interval& destComps);
396 
397  void allocateGhostVector(const DataFactory<T>& factory,
398  const IntVect& ghost = IntVect::Zero);
399 
400  void makeItSo(const Interval& a_srcComps,
401  const BoxLayoutData<T>& a_src,
402  BoxLayoutData<T>& a_dest,
403  const Interval& a_destComps,
404  const Copier& a_copier,
405  const LDOperator<T>& a_op = LDOperator<T>()) const;
406  void makeItSoBegin(
407  const Interval& a_srcComps,
408  const BoxLayoutData<T>& a_src,
409  BoxLayoutData<T>& a_dest,
410  const Interval& a_destComps,
411  const Copier& a_copier,
412  const LDOperator<T>& a_op = LDOperator<T>()) const;
413  void makeItSoLocalCopy(
414  const Interval& a_srcComps,
415  const BoxLayoutData<T>& a_src,
416  BoxLayoutData<T>& a_dest,
417  const Interval& a_destComps,
418  const Copier& a_copier,
419  const LDOperator<T>& a_op = LDOperator<T>()) const;
420  void makeItSoEnd(
421  BoxLayoutData<T>& a_dest,
422  const Interval& a_destComps,
423  const LDOperator<T>& a_op = LDOperator<T>()) const;
424 
425  //========================================================================
426  //
427  // data structures used by makeItSo when we have some
428  // data that needs to be moved (ie. there are entries
429  // in the 'FROM' or 'TO' CopyIterators)
430  //
431  void completePendingSends() const;
432 
433  void allocateBuffers(const BoxLayoutData<T>& a_src,
434  const Interval& a_srcComps,
435  const BoxLayoutData<T>& a_dest,
436  const Interval& a_destComps,
437  const Copier& a_copier,
438  const LDOperator<T>& a_op) const;
439 
441  const Interval& a_srcComps,
442  const LDOperator<T>& a_op) const;
443 
444  void postSendsFromMe() const ;
445 
446  void postReceivesToMe() const ;
447 
449  const Interval& a_destComps,
450  const LDOperator<T>& a_op) const ;
451 
453  const Interval& a_destComps,
454  int ncomp,
455  const DataFactory<T>& factory,
456  const LDOperator<T>& a_op) const;
457 
458  /** \name Parallel messaging members */
459  /*@{*/
460 // mutable void* m_sendbuffer; // pointer member OK here,
461 // // since LevelData<T> has no copy
462 // mutable size_t m_sendcapacity;
463 // mutable void* m_recbuffer; // pointer member OK here,
464 // // since LevelData<T> has no copy
465 // mutable size_t m_reccapacity;
467 #ifdef CH_MPI
468 
469 #ifndef DOXYGEN
470 
471 #endif
472 // mutable std::vector<bufEntry> m_fromMe;
473 // mutable std::vector<bufEntry> m_toMe;
474 
475  mutable Vector<MPI_Request> m_sendRequests, m_receiveRequests;
476  mutable Vector<MPI_Status> m_receiveStatus, m_sendStatus;
477  mutable int numSends, numReceives;
478 #endif
479 
480 };
481 
482 ///
483 /** not actually L-p norms, since it doesn't take into
484  account the dx of the system. A user can take that
485  into account or not.
486 
487  For p != 0, returns pth root of sum of pth powers over all
488  points in all fabs and all components in the interval:
489 
490  ( sum [ |A[i][pt,var]|^p : FArrayBox A[i], point pt in A[i].box(), var in interval ] )^(1/p)
491 
492  To turn into an L-p norm, one needs to multiply this by dx^(SpaceDim/p).
493 
494  For p == 0, returns global max over all points in all fabs and all
495  components in the interval:
496 
497  max [ |A[i][pt,var]| : FArrayBox A[i], point pt in A[i].box(), var in interval ]
498 
499  Some people don't like that this norm is not normalized based on
500  number of points in A. Normalization is your problem.
501  */
503  const Interval& interval,
504  const int& p = 2);
505 
506 //======================================================================
507 template < >
509  int ncomps,
510  const DataIndex& a_datInd) const;
511 
512 template < >
514  int ncomps,
515  const DataIndex& a_datInd) const;
516 
517 #include "NamespaceFooter.H"
518 #include "BoxLayoutDataI.H"
519 
520 #endif //BOXLAYOUTDATA
void unpackReceivesToMe(BoxLayoutData< T > &a_dest, const Interval &a_destComps, const LDOperator< T > &a_op) const
Definition: BoxLayoutDataI.H:365
void postSendsFromMe() const
Definition: BoxLayoutDataI.H:355
void postReceivesToMe() const
Definition: BoxLayoutDataI.H:360
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:337
int m_comps
Definition: BoxLayoutData.H:387
CopierBuffer * m_buff
Definition: BoxLayoutData.H:466
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:145
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:332
Definition: Copier.H:59
void setVector(const BoxLayoutData< T > &da, const Interval &srcComps, const Interval &destComps)
Definition: BoxLayoutDataI.H:47
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:372
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:172
Data on a BoxLayout.
Definition: BoxLayoutData.H:97
static int s_verbosity
Definition: BoxLayoutData.H:384
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:237
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:654
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:465
void makeItSoEnd(BoxLayoutData< T > &a_dest, const Interval &a_destComps, const LDOperator< T > &a_op=LDOperator< T >()) const
Definition: BoxLayoutDataI.H:318
int nComp() const
Definition: BoxLayoutData.H:306
Definition: DataIndex.H:112
Definition: BoxLayoutData.H:100
void writeSendDataFromMeIntoBuffers(const BoxLayoutData< T > &a_src, const Interval &a_srcComps, const LDOperator< T > &a_op) const
Definition: BoxLayoutDataI.H:348
bool m_isdefined
Definition: BoxLayoutData.H:389
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
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:388
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:33
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).