Chombo + EB + MF  3.2
LevelData.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 _LEVELDATA_H_
12 #define _LEVELDATA_H_
13 
14 #include "IntVect.H"
15 #include "BoxLayoutData.H"
16 #include "DisjointBoxLayout.H"
17 #include "Copier.H"
18 #include "SPMD.H"
19 #include "NamespaceHeader.H"
20 
21 ///Data over a disjoint union of rectangles
22 
23 /**
24  LevelData is-a BoxLayoutData. It is built from a DisjointBoxLayout
25  instead though, thus making the data in a DisjointBoxLayout uniquely
26  defined for all spatial indices defined by the underlying
27  DisjointBoxLayout. It carries within it an inherent concept of
28  ghost cells (which the user can choose to be empty).
29 
30  Since LevelData is-a BoxLayoutData, all the methods
31  required of the template class T for BoxLayoutData are also
32  required for LevelData. LevelData does not have any extra requirements.
33 */
34 
35 template <class T>
36 void aliasLevelData(LevelData<T>& a_alias,
37  LevelData<T>* a_original,
38  const Interval& a_interval);
39 
40 template<class T> class LevelData : public BoxLayoutData<T>
41 {
42 public:
43 
44  ///
45  LevelData();
46 
47  ///
48  LevelData(const DisjointBoxLayout& dp, int comps,
49  const IntVect& ghost = IntVect::Zero,
50  const DataFactory<T>& a_factory = DefaultDataFactory<T>());
51 
52  ///
53  virtual ~LevelData();
54 
55  ///
56  virtual void define(const DisjointBoxLayout& dp, int comps,
57  const IntVect& ghost = IntVect::Zero,
58  const DataFactory<T>& a_factory = DefaultDataFactory<T>());
59 
60  ///
61  /**
62  copy definer. this LevelData thrown away and da's LevelData copied
63  */
64  virtual void define(const LevelData<T>& da,
65  const DataFactory<T>& a_factory = DefaultDataFactory<T>());
66 
67  ///
68  /**
69  Copy definer. 'this' LevelData thrown away and da's LevelData copied.
70  This LevelData is now defined for the range [0, comps.size()] and filled
71  with the data in da from [comps.begin(), comps.end()]
72  */
73  virtual void define(const LevelData<T>& da, const Interval& comps,
74  const DataFactory<T>& a_factory = DefaultDataFactory<T>());
75 
76  ///
77  virtual void copyTo(const Interval& srcComps,
78  BoxLayoutData<T>& dest,
79  const Interval& destComps) const;
80 
81 
82  ///only works if source and dest have the same disjointboxlayout
83  virtual void localCopyTo(const Interval& srcComps,
84  LevelData<T> & dest,
85  const Interval& destComps) const;
86 
87  /// assumes source and dest have same interval
88  virtual void localCopyTo(LevelData<T> & dest) const;
89 
90 
91  /// Simplest case -- assumes source and dest have same interval
92  virtual void copyTo(BoxLayoutData<T>& dest) const;
93 
94  /*
95  ///
96  virtual void copyTo(const Interval& srcComps,
97  BoxLayoutData<T>& dest,
98  const Interval& destComps,
99  const Copier& copier) const;
100 
101  /// Simplest case -- assumes source and dest have same interval
102  virtual void copyTo(BoxLayoutData<T>& dest,
103  const Copier& copier) const;
104  */
105  ////////////////////////////// FM MOD START //////////////////////////
106  ///
107  /** same as copyTo that takes a BoxLayoutData, except that it fills the
108  ghost cells of 'dest' with data from 'this' also. USer passes in
109  a prebuilt Copier object*/
110  virtual void copyTo(const Interval& srcComps,
111  BoxLayoutData<T>& dest,
112  const Interval& destComps,
113  const Copier& copier,
114  const LDOperator<T>& a_op = LDOperator<T>()) const;
115 
116  /// Simplest case -- assumes source and dest have same interval
117  virtual void copyTo(BoxLayoutData<T>& dest,
118  const Copier& copier,
119  const LDOperator<T>& a_op = LDOperator<T>()) const;
120 
121  ////////////////////////////// FM MOD. END ////////////////////////////
122  ///
123  /** same as copyTo that takes a BoxLayoutData, except that it fills the
124  ghost cells of 'dest' with data from 'this' also. */
125  virtual void copyTo(const Interval& srcComps,
126  LevelData<T>& dest,
127  const Interval& destComps) const;
128 
129  /// Simplest case -- assumes source and dest have same interval
130  virtual void copyTo(LevelData<T>& dest) const;
131 
132  ///
133  /** same as copyTo that takes a BoxLayoutData, except that it fills the
134  ghost cells of 'dest' with data from 'this' also. USer passes in
135  a prebuilt Copier object*/
136  virtual void copyTo(const Interval& srcComps,
137  LevelData<T>& dest,
138  const Interval& destComps,
139  const Copier& copier,
140  const LDOperator<T>& a_op = LDOperator<T>()) const;
141 
142  /// Simplest case -- assumes source and dest have same interval
143  virtual void copyTo(LevelData<T>& dest,
144  const Copier& copier,
145  const LDOperator<T>& a_op = LDOperator<T>()) const;
146 
147  /// Simplest case -- do all components
148  virtual void exchange(void);
149 
150  /// Simplest case -- do all components. Accepts a pre-built copier.
151  virtual void exchange(const Copier& copier);
152 
153  /// Accepts an arbitrary component range
154  virtual void exchange(const Interval& comps);
155 
156  /// The most general case -- can accept an arbitrary component range,
157  /// a pre-built Copier object, and an arbitrary accumulation operator.
158  virtual void exchange(const Interval& comps,
159  const Copier& copier,
160  const LDOperator<T>& a_op = LDOperator<T>());
161 
162  /// asynchronous exchange start. load and fire off messages.
163  virtual void exchangeBegin(const Copier& copier);
164  /// finish asynchronous exchange
165  virtual void exchangeEnd();
166 
167  virtual void exchangeNoOverlap(const Copier& copier);
168 
169  ///
170  const IntVect& ghostVect() const
171  {
172  return m_ghost;
173  }
174 
175  /**
176  \name overidden virtual functions
177 
178  These functions will invoke error messages when invoked.
179  C++ will ensure that constructors are not called for the
180  base class by a user, but a 'define' function has no such protection,
181  hence the need to prevent such usage. A runtime error is not
182  a perfect solution...(strong construction gets around this *sigh*).
183  classes that derive from LevelData will have to turn its valid
184  defines into runtime errors also and make its own defines. Thus
185  taking over the job of the compiler.
186  */
187  /*@{*/
188  virtual void define(const BoxLayout& dp, int comps,
189  const DataFactory<T>& factory);
190 
191  ///
192  virtual void define(const BoxLayoutData<T>& da,
193  const DataFactory<T>& factory = DefaultDataFactory<T>());
194 
195  ///
196  virtual void define(const BoxLayoutData<T>& da, const Interval& comps,
197  const DataFactory<T>& factory = DefaultDataFactory<T>());
198 
199  virtual void define(const BoxLayout& deadFunction);
200  /*@}*/
201 
202  ///
204  {
205  return m_disjointBoxLayout;
206  }
207 
208  ///
210  {
211  return m_disjointBoxLayout;
212  }
213 
214  ///
215  /** User writes a function with the signature:
216 
217  \code
218  void myfunction(const Box& box, int n_comps, T& t)
219  {
220  your code here;
221  }
222  \endcode
223 
224  They can then hand this off to LayoutData::apply, which invokes this
225  function for every T. The argument "box" is the Box (as known to the
226  DisjointBoxLayout here) associated with that T and the argument "n_comps"
227  is the number of components in this LevelData.
228 
229  Your function must not be inline.
230 
231  For example:
232  \code
233  LevelData<FArrayBox> data(layout, 3, IntVect::Unit);
234  struct val
235  {
236  static void set1(const Box& box, int n_comps, const FArrayBox& fab)
237  {
238  fab.setVal( box.smallEnd(0), box, 0, n_comps );
239  }
240  };
241 
242  data.apply(val::set1);
243  \endcode
244 */
245  virtual void apply( void (*a_Function)(const Box&, int, T&) );
246 
247  /** For use with apply( const ApplyFunctor& ) */
249  {
250  virtual ~ApplyFunctor()
251  {
252  }
253 
254  virtual void operator()( const Box&, int, T& ) const = 0;
255  };
256 
257 /** Like the other apply(), but here the argument is an instance of a class
258  derived from LevelData::ApplyFunctor, and which implements ApplyFunctor's
259  pure virtual void operator()(const Box& box, int n_comps, T& t) const.
260 
261  Going with an instance of such a class is more convenient if you want
262  the thing you pass to apply() to have state.
263 
264  For example:
265  \code
266  class MyFunctor : public LevelData<FArrayBox>::ApplyFunctor
267  {
268  public:
269  MyFunctor( Real x ) : m_x(x)
270  {
271  ...
272  }
273  virtual void operator()(const Box& box, int n_comps, FArrayBox& fab) const
274  {
275  fab.setVal( m_x, box, 0, n_comps );
276  }
277  private:
278  const Real m_x;
279  }
280 
281  LevelData<FArrayBox> data(layout, 3, IntVect::Unit);
282  data.apply( MyFunctor(3.14, 0) );
283 
284  \endcode
285 
286 */
287  virtual void apply( const ApplyFunctor& );
288 
289  void degenerate( LevelData<T>& a_to, const SliceSpec& a_ss ) const;
290 
291  /// version of degenerate which does strictly local copying
292  /** this means that it maintains source ghost cell values in the
293  destination*/
294  void degenerateLocalOnly( LevelData<T>& a_to, const SliceSpec& a_ss ) const;
295 
296 protected:
298 
300 
301  friend void aliasLevelData<T>(LevelData<T>& a_alias,
302  LevelData<T>* a_original,
303  const Interval& a_interval);
304 
306 };
307 
308 /// LevelData aliasing function
309 /**
310  @param a_alias aliased LevelData<T> object. original data in a_alias is destroyed and new aliasing role assumed.
311  @param a_original pointer to LevelData<T> that will be aliased.
312  @param a_interval range of components of each T in a_original that will be created in the a_alias argument.
313 
314 \code
315 
316 LevelData<FArrayBox> original(dbl, 4, 2*IntVect::Unit);
317 Interval subcomps(2, 3);
318 LevelData<FArrayBox> alias;
319 aliasLevelData<FArrayBox>(alias, &original, subcomps);
320 // component 0 of every FArrayBox in alias references the same data as
321 // component 2 in original
322 \endcode
323 
324 The template class T must have an 'alias' constructor
325 
326 \code
327 class A
328  {
329 public:
330  A(const Interval& subcomps, A& original);// alias constructor
331  ...
332  };
333 
334  \endcode
335  */
336 template <class T>
337 void aliasLevelData(LevelData<T>& a_alias, LevelData<T>* a_original,
338  const Interval& a_interval)
339 {
340  AliasDataFactory<T> factory(a_original, a_interval);
341  a_alias.define(a_original->disjointBoxLayout(), a_interval.size(), a_original->ghostVect(), factory);
342 }
343 
344 // ====== inlined function definitions ================
345 
346 // As with the BoxLayoutData implementation file. This file
347 // just gives the interface and the inline implmentations
348 // are given in LevelDataI.H
349 
350 #include "NamespaceFooter.H"
351 #include "LevelDataI.H"
352 
353 #endif
virtual void operator()(const Box &, int, T &) const =0
virtual void localCopyTo(const Interval &srcComps, LevelData< T > &dest, const Interval &destComps) const
only works if source and dest have the same disjointboxlayout
Definition: LevelDataI.H:240
LevelData()
Definition: LevelDataI.H:30
void degenerate(LevelData< T > &a_to, const SliceSpec &a_ss) const
Definition: LevelDataI.H:581
DisjointBoxLayout m_disjointBoxLayout
Definition: LevelData.H:297
Definition: LevelData.H:248
A not-necessarily-disjoint collective of boxes.
Definition: BoxLayout.H:145
A strange but true thing to make copying from one boxlayoutdata to another fast.
Definition: Copier.H:152
Definition: SliceSpec.H:41
IntVect m_ghost
Definition: LevelData.H:299
Copier m_exchangeCopier
Definition: LevelData.H:305
void aliasLevelData(LevelData< T > &a_alias, LevelData< T > *a_original, const Interval &a_interval)
Data over a disjoint union of rectangles.
Definition: LevelData.H:337
int size() const
Definition: Interval.H:75
virtual void exchange(void)
Simplest case – do all components.
Definition: LevelDataI.H:451
virtual void exchangeBegin(const Copier &copier)
asynchronous exchange start. load and fire off messages.
Definition: LevelDataI.H:499
Factory object to data members of a BoxLayoutData container.
Definition: BoxLayoutData.H:70
virtual void copyTo(const Interval &srcComps, BoxLayoutData< T > &dest, const Interval &destComps) const
Definition: LevelDataI.H:202
virtual void apply(void(*a_Function)(const Box &, int, T &))
Structure for passing component ranges in code.
Definition: Interval.H:23
new code
Definition: BoxLayoutData.H:170
void degenerateLocalOnly(LevelData< T > &a_to, const SliceSpec &a_ss) const
version of degenerate which does strictly local copying
Definition: LevelDataI.H:604
Data on a BoxLayout.
Definition: BoxLayoutData.H:97
virtual void define(const DisjointBoxLayout &dp, int comps, const IntVect &ghost=IntVect::Zero, const DataFactory< T > &a_factory=DefaultDataFactory< T >())
Definition: LevelDataI.H:80
const DisjointBoxLayout & disjointBoxLayout() const
Definition: LevelData.H:209
const DisjointBoxLayout & getBoxes() const
Definition: LevelData.H:203
A BoxLayout that has a concept of disjointedness.
Definition: DisjointBoxLayout.H:30
virtual ~ApplyFunctor()
Definition: LevelData.H:250
static const IntVect Zero
Definition: IntVect.H:658
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:469
Definition: BoxLayoutData.H:100
virtual ~LevelData()
Definition: LevelDataI.H:37
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
Factory object to data members of a BoxLayoutData container.
Definition: BoxLayoutData.H:30
Definition: BoxLayoutData.H:173
virtual void exchangeEnd()
finish asynchronous exchange
Definition: LevelDataI.H:509
virtual void exchangeNoOverlap(const Copier &copier)
Definition: LevelDataI.H:488
const IntVect & ghostVect() const
Definition: LevelData.H:170