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