Chombo + EB  3.0
LevelDataI.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 _LEVELDATAI_H_
12 #define _LEVELDATAI_H_
13 
14 #include <cstdlib>
15 #include <algorithm>
16 using std::sort;
17 
18 #include "parstream.H"
19 #include "CH_Timer.H"
20 #include <float.h>
21 #include "NamespaceHeader.H"
22 
23 //-----------------------------------------------------------------------
24 template<class T>
26 {
27 }
28 //-----------------------------------------------------------------------
29 
30 //-----------------------------------------------------------------------
31 template<class T>
33 {
34  CH_TIME("~LevelData");
35 }
36 //-----------------------------------------------------------------------
37 
38 //-----------------------------------------------------------------------
39 template<class T>
40 LevelData<T>::LevelData(const DisjointBoxLayout& dp, int comps, const IntVect& ghost,
41  const DataFactory<T>& a_factory)
42  : m_disjointBoxLayout(dp), m_ghost(ghost)
43 {
44 #ifdef CH_MPI
45  this->numSends = 0;
46  this->numReceives = 0;
47 #endif
48  this->m_boxLayout = dp;
49  this->m_comps = comps;
50  this->m_isdefined = true;
51 
52  if (!dp.isClosed())
53  {
54  MayDay::Error("non-disjoint DisjointBoxLayout: LevelData<T>::LevelData(const DisjointBoxLayout& dp, int comps)");
55  }
56 
57  Interval interval(0, comps-1);
58  this->allocateGhostVector(a_factory, ghost);
59  this->setVector(*this, interval, interval); // Does nothing.
60 }
61 //-----------------------------------------------------------------------
62 
63 // Since I need to thwart the user from invoking the
64 // 'define' methods that use a general BoxLayout, I cannot
65 // get at said functions myself now. Ha! So, I have to recode
66 // them here.
67 
68 //-----------------------------------------------------------------------
69 template<class T>
70 void LevelData<T>::define(const DisjointBoxLayout& dp, int comps, const IntVect& ghost,
71  const DataFactory<T> & a_factory)
72 {
73  CH_TIME("LevelData<T>::define(dbl,comps,ghost,factory)");
74  // clear exchange copier if it's already been defined
75  if (this->m_isdefined)
76  {
78  }
79 
80  this->m_isdefined = true;
81  if (!dp.isClosed())
82  {
83  MayDay::Error("non-disjoint DisjointBoxLayout: LevelData<T>::define(const DisjointBoxLayout& dp,....)");
84  }
85  if (comps<=0)
86  {
87  MayDay::Error("LevelData::LevelData(const BoxLayout& dp, int comps) comps<=0");
88  }
89  this->m_comps = comps;
90  this->m_boxLayout = dp;
91 
93  m_ghost = ghost;
94 
95  // Interval interval(0, comps-1);
96  this->allocateGhostVector(a_factory, ghost);
97  // this->setVector(*this, interval, interval);
98 }
99 //-----------------------------------------------------------------------
100 
101 //-----------------------------------------------------------------------
102 template<class T>
103 void LevelData<T>::define(const LevelData<T>& da, const DataFactory<T> & a_factory)
104 {
105  CH_TIME("LevelData<T>::define(LevelData<T>,factory)");
106  // clear exchange copier if it's already been defined
107  if (this->m_isdefined)
108  {
110  }
111  this->m_isdefined = true;
112  if (this == &da) return;
114  this->m_boxLayout = da.m_disjointBoxLayout;
115  this->m_comps = da.m_comps;
116  m_ghost = da.m_ghost;
117 
118  Interval srcAnddest(0, this->m_comps-1);
119 
120  this->allocateGhostVector(a_factory, m_ghost);
121  da.copyTo(*this);
122 }
123 //-----------------------------------------------------------------------
124 
125 //-----------------------------------------------------------------------
126 template<class T>
127 void LevelData<T>::define(const LevelData<T>& da, const Interval& comps,
128  const DataFactory<T>& a_factory)
129 {
130  CH_TIME("LevelData<T>::define(LevelData<T>,comps,factory)");
131  // clear exchange copier if it's already been defined
132  if (this->m_isdefined)
133  {
135  }
136  this->m_isdefined = true;
137  if (this == &da)
138  {
139  MayDay::Error(" LevelData<T>::define(const LevelData<T>& da, const Interval& comps) called with 'this'");
140  }
141  CH_assert(comps.size()>0);
142  // this line doesn't make any sense!
143  //CH_assert(comps.end()<=this->m_comps);
144  CH_assert(comps.begin()>=0);
145 
147  this->m_boxLayout = da.m_disjointBoxLayout;
148 
149  this->m_comps = comps.size();
150 
151  m_ghost = da.m_ghost;
152 
153  Interval dest(0, this->m_comps-1);
154 
155  this->allocateGhostVector(a_factory, m_ghost);
156 
157  this->setVector(da, comps, dest);
158 
159 }
160 //-----------------------------------------------------------------------
161 
162 //-----------------------------------------------------------------------
163 template<class T>
164 void LevelData<T>::copyTo(const Interval& srcComps,
165  BoxLayoutData<T>& dest,
166  const Interval& destComps) const
167 {
168  if ((BoxLayoutData<T>*)this == &dest) return;
169 
170  if (this->boxLayout() == dest.boxLayout())
171  {
172  // parallel direct copy here, no communication issues
173  for (DataIterator it(this->dataIterator()); it.ok(); ++it)
174  {
175  dest[it()].copy(this->box(it()),
176  destComps,
177  this->box(it()),
178  this->operator[](it()),
179  srcComps);
180  }
181  return;
182  }
183 
184  Copier copier(m_disjointBoxLayout, dest.boxLayout());
185  copyTo(srcComps, dest, destComps, copier);
186 }
187 //-----------------------------------------------------------------------
188 
189 //-----------------------------------------------------------------------
190 template<class T>
192 {
193  CH_assert(this->nComp() == dest.nComp());
194  this->copyTo(this->interval(), dest, dest.interval());
195 }
196 //-----------------------------------------------------------------------
197 
198 //-----------------------------------------------------------------------
199 template<class T>
200 void LevelData<T>::copyTo(const Interval& srcComps,
201  LevelData<T>& dest,
202  const Interval& destComps) const
203 {
204  if (this == &dest)
205  {
206  MayDay::Error("src == dest in copyTo function. Perhaps you want exchange ?");
207  }
208 
209  if (this->boxLayout() == dest.boxLayout() && dest.ghostVect() == IntVect::Zero)
210  {
211  // parallel direct copy here, no communication issues
212  for (DataIterator it(this->dataIterator()); it.ok(); ++it)
213  {
214  dest[it()].copy(this->box(it()),
215  destComps,
216  this->box(it()),
217  this->operator[](it()),
218  srcComps);
219  }
220  return;
221  }
222 
223  Copier copier(m_disjointBoxLayout, dest.getBoxes(), dest.m_ghost);
224  copyTo(srcComps, dest, destComps, copier);
225 }
226 //-----------------------------------------------------------------------
227 
228 //-----------------------------------------------------------------------
229 template<class T>
231 {
232  CH_assert(this->nComp() == dest.nComp());
233  this->copyTo(this->interval(), dest, dest.interval());
234 }
235 //-----------------------------------------------------------------------
236 
237 //-----------------------------------------------------------------------
238 template<class T>
239 void LevelData<T>::copyTo(const Interval& srcComps,
240  BoxLayoutData<T>& dest,
241  const Interval& destComps,
242  const Copier& copier,
243  const LDOperator<T>& a_op) const
244 {
245  CH_TIME("copyTo");
246 #ifdef CH_MPI
247  {
248 // CH_TIME("MPI_Barrier copyTo");
249 // MPI_Barrier(Chombo_MPI::comm);
250  }
251 #endif
252 
253  this->makeItSo(srcComps, *this, dest, destComps, copier, a_op);
254 }
255 //-----------------------------------------------------------------------
256 
257 //-----------------------------------------------------------------------
258 template<class T>
260  const Copier& copier,
261  const LDOperator<T>& a_op) const
262 {
263  CH_assert(this->nComp() == dest.nComp());
264  this->copyTo(this->interval(), dest, dest.interval(), copier, a_op);
265 }
266 //-----------------------------------------------------------------------
267 
268 
269 //-----------------------------------------------------------------------
270 template<class T>
271 void LevelData<T>::copyTo(const Interval& srcComps,
272  LevelData<T>& dest,
273  const Interval& destComps,
274  const Copier& copier,
275  const LDOperator<T>& a_op) const
276 {
277  CH_TIME("copyTo");
278 #ifdef CH_MPI
279  {
280 // CH_TIME("MPI_Barrier copyTo");
281 // MPI_Barrier(Chombo_MPI::comm);
282  }
283 #endif
284  this->makeItSo(srcComps, *this, dest, destComps, copier, a_op);
285 }
286 //-----------------------------------------------------------------------
287 
288 //-----------------------------------------------------------------------
289 template<class T>
291  const Copier& copier,
292  const LDOperator<T>& a_op) const
293 {
294  CH_assert(this->nComp() == dest.nComp());
295  this->copyTo(this->interval(), dest, dest.interval(), copier, a_op);
296 }
297 //-----------------------------------------------------------------------
298 
299 
300 //-----------------------------------------------------------------------
301 template<class T>
303 {
304  CH_TIME("exchange+copier");
305  // later on we can code this part as a direct algorithm
306  // by copying and pasting the code from the Copier::define code
307  // for now, just do the easy to debug approach.
309  {
311  }
312  exchange(comps, m_exchangeCopier);
313 
314  // if there aren't any ghost cells, there isn't really anything
315  // to do here (also, if m_ghost == Zero, m_exchangeCopier
316  // wasn't defined!
317  //if (m_ghost != IntVect::Zero)
318  //this->makeItSo(comps, *this, *this, comps, m_exchangeCopier);
319 }
320 //-----------------------------------------------------------------------
321 
322 //-----------------------------------------------------------------------
323 template<class T>
325 {
326  exchange(this->interval());
327 }
328 //-----------------------------------------------------------------------
329 
330 //-----------------------------------------------------------------------
331 template<class T>
333  const Copier& copier)
334 {
335  CH_TIME("exchange");
336 #ifdef CH_MPI
337  {
338 // CH_TIME("MPI_Barrier exchange");
339 // MPI_Barrier(Chombo_MPI::comm);
340  }
341 #endif
342  this->makeItSo(comps, *this, *this, comps, copier);
343 }
344 //-----------------------------------------------------------------------
345 
346 //-----------------------------------------------------------------------
347 template<class T>
348 void LevelData<T>::exchange(const Copier& copier)
349 {
350  exchange(this->interval(), copier);
351 }
352 //-----------------------------------------------------------------------
353 
354 //-----------------------------------------------------------------------
355 template<class T>
357 {
358  CH_TIME("exchangeNoOverlap");
359  this->makeItSoBegin(this->interval(), *this, *this, this->interval(), copier);
360  this->makeItSoEnd(*this, this->interval());
361  this->makeItSoLocalCopy(this->interval(), *this, *this, this->interval(), copier);
362 }
363 //-----------------------------------------------------------------------
364 
365 
366 //-----------------------------------------------------------------------
367 template<class T>
369 {
370  CH_TIME("exchangeBegin");
371  this->makeItSoBegin(this->interval(), *this, *this, this->interval(), copier);
372  this->makeItSoLocalCopy(this->interval(), *this, *this, this->interval(), copier);
373 }
374 //-----------------------------------------------------------------------
375 
376 //-----------------------------------------------------------------------
377 template<class T>
379 {
380  CH_TIME("exchangeEnd");
381  this->makeItSoEnd(*this, this->interval());
382 }
383 //-----------------------------------------------------------------------
384 
385 
386 //-----------------------------------------------------------------------
387 template<class T>
388 void LevelData<T>::define(const BoxLayout& dp, int comps, const DataFactory<T>& a_factory)
389 {
390  MayDay::Error("LevelData<T>::define called with BoxLayout input");
391 }
392 //-----------------------------------------------------------------------
393 
394 //-----------------------------------------------------------------------
395 template<class T>
397 {
398  MayDay::Error("LevelData<T>::define called with BoxLayout input");
399 }
400 //-----------------------------------------------------------------------
401 
402 //-----------------------------------------------------------------------
403 template<class T>
404 void LevelData<T>::define(const BoxLayoutData<T>& da, const DataFactory<T>& a_factory )
405 {
406  MayDay::Error("LevelData<T>::define called with BoxLayout input");
407 }
408 //-----------------------------------------------------------------------
409 
410 //-----------------------------------------------------------------------
411 template<class T>
412 void LevelData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
413  const DataFactory<T>& a_factory)
414 {
415  MayDay::Error("LevelData<T>::define called with BoxLayout input");
416 }
417 //-----------------------------------------------------------------------
418 
419 
420 //-----------------------------------------------------------------------
421 template<class T>
422 void LevelData<T>::apply( void (*a_Function)(const Box& box, int comps, T& t) )
423 {
424  for (DataIterator it(this->dataIterator()); it.ok(); ++it)
425  {
426  a_Function(m_disjointBoxLayout.get(it()), this->m_comps, *(this->m_vector[it().datInd()]));
427  }
428 }
429 //-----------------------------------------------------------------------
430 
431 //-----------------------------------------------------------------------
432 template<class T>
433 void LevelData<T>::apply( const ApplyFunctor & f )
434 {
435  for (DataIterator it(this->dataIterator()); it.ok(); ++it)
436  {
437  // unsigned int index = this->m_boxLayout.lindex(it());
438  f(m_disjointBoxLayout.get(it()), this->m_comps, *(this->m_vector[it().datInd()]));
439  }
440 }
441 //-----------------------------------------------------------------------
442 
443 //-----------------------------------------------------------------------
444 template<class T> void
446  const SliceSpec& a_sliceSpec ) const
447 {
448  DisjointBoxLayout toDBL;
449  m_disjointBoxLayout.degenerate( toDBL, a_sliceSpec );
450  IntVect toGhost;
451  for ( int i=0;i<CH_SPACEDIM;++i )
452  {
453  if ( i != a_sliceSpec.direction )
454  {
455  toGhost[i] = m_ghost[i];
456  } else
457  {
458  toGhost[i] = 0;
459  }
460  }
461  a_to.define( toDBL, this->nComp(), toGhost );
462  copyTo( a_to );
463 }
464 //-----------------------------------------------------------------------
465 
466 #include "NamespaceFooter.H"
467 #endif
int m_comps
Definition: BoxLayoutData.H:341
bool isDefined() const
Definition: Copier.H:266
Interval interval() const
Definition: BoxLayoutData.H:264
void degenerate(DisjointBoxLayout &a_to, const SliceSpec &a_ss) const
#define CH_SPACEDIM
Definition: SPACE.H:52
#define CH_assert(cond)
Definition: CHArray.H:37
Vector< T * > m_vector
Definition: LayoutData.H:122
void degenerate(LevelData< T > &a_to, const SliceSpec &a_ss) const
Definition: LevelDataI.H:445
LevelData()
Definition: LevelDataI.H:25
DisjointBoxLayout m_disjointBoxLayout
Definition: LevelData.H:280
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
int size() const
Definition: Interval.H:64
A strange but true thing to make copying from one boxlayoutdata to another fast.
Definition: Copier.H:137
int begin() const
Definition: Interval.H:86
Definition: SliceSpec.H:42
IntVect m_ghost
Definition: LevelData.H:282
const BoxLayout & boxLayout() const
Definition: LayoutData.H:108
DataIterator dataIterator() const
Definition: LayoutDataI.H:79
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 setVector(const BoxLayoutData< T > &da, const Interval &srcComps, const Interval &destComps)
Definition: BoxLayoutDataI.H:46
Box box(const DataIndex &a_index) const
Definition: LayoutDataI.H:67
virtual bool ok() const
return true if this iterator is still in its Layout
Definition: LayoutIterator.H:110
Definition: DataIterator.H:140
Copier m_exchangeCopier
Definition: LevelData.H:288
BoxLayout m_boxLayout
Definition: LayoutData.H:116
virtual void exchange(void)
Simplest case – do all components.
Definition: LevelDataI.H:324
Definition: EBInterface.H:45
virtual void exchangeBegin(const Copier &copier)
asynchronous exchange start. load and fire off messages.
Definition: LevelDataI.H:368
virtual void apply(void(*a_Function)(const Box &, int, T &))
#define CH_TIME(name)
Definition: CH_Timer.H:59
Structure for passing component ranges in code.
Definition: Interval.H:23
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
virtual void define(const DisjointBoxLayout &dp, int comps, const IntVect &ghost=IntVect::Zero, const DataFactory< T > &a_factory=DefaultDataFactory< T >())
Definition: LevelDataI.H:70
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 void copyTo(const Interval &srcComps, BoxLayoutData< T > &dest, const Interval &destComps) const
Definition: LevelDataI.H:164
A BoxLayout that has a concept of disjointedness.
Definition: DisjointBoxLayout.H:31
Box get(const LayoutIndex &it) const
Definition: BoxLayout.H:681
const DisjointBoxLayout & getBoxes() const
Definition: LevelData.H:190
const IntVect & ghostVect() const
Definition: LevelData.H:157
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.
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
bool m_isdefined
Definition: BoxLayoutData.H:342
virtual ~LevelData()
Definition: LevelDataI.H:32
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
virtual void clear()
Factory object to data members of a BoxLayoutData container.
Definition: BoxLayoutData.H:30
bool isClosed() const
Definition: BoxLayout.H:696
Definition: BoxLayoutData.H:139
virtual void define(const DisjointBoxLayout &a_level, const BoxLayout &a_dest, bool a_exchange=false, IntVect a_shift=IntVect::Zero)
virtual void exchangeEnd()
finish asynchronous exchange
Definition: LevelDataI.H:378
int direction
Definition: SliceSpec.H:48
virtual void exchangeNoOverlap(const Copier &copier)
Definition: LevelDataI.H:356