Chombo + EB  3.2
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 // LevelData<FluxBox> specializations
25 
26 template < > void LevelData<FluxBox>::degenerateLocalOnly( LevelData<FluxBox>& a_to, const SliceSpec& a_ss ) const;
27 
28 //-----------------------------------------------------------------------
29 template<class T>
31 {
32 }
33 //-----------------------------------------------------------------------
34 
35 //-----------------------------------------------------------------------
36 template<class T>
38 {
39  CH_TIME("~LevelData");
40 }
41 //-----------------------------------------------------------------------
42 
43 //-----------------------------------------------------------------------
44 template<class T>
45 LevelData<T>::LevelData(const DisjointBoxLayout& dp, int comps, const IntVect& ghost,
46  const DataFactory<T>& a_factory)
47  : m_disjointBoxLayout(dp), m_ghost(ghost)
48 {
49 #ifdef CH_MPI
50  this->numSends = 0;
51  this->numReceives = 0;
52 #endif
53  this->m_boxLayout = dp;
54  this->m_comps = comps;
55  this->m_isdefined = true;
56  //no need for exchange copier if no ghost
57  if(m_ghost != IntVect::Zero)
58  {
60  }
61 
62  if (!dp.isClosed())
63  {
64  MayDay::Error("non-disjoint DisjointBoxLayout: LevelData<T>::LevelData(const DisjointBoxLayout& dp, int comps)");
65  }
66 
67  this->m_threadSafe = a_factory.threadSafe();
68  //this->m_threadSafe = false;
69 
70  Interval interval(0, comps-1);
71  this->allocateGhostVector(a_factory, ghost);
72  this->setVector(*this, interval, interval); // Does nothing.
73 }
74 //-----------------------------------------------------------------------
75 
76 // Since I need to thwart the user from invoking the
77 // 'define' methods that use a general BoxLayout, I cannot
78 // get at said functions myself now. Ha! So, I have to recode
79 // them here.
80 
81 //-----------------------------------------------------------------------
82 template<class T>
83 void LevelData<T>::define(const DisjointBoxLayout& dp, int comps, const IntVect& ghost,
84  const DataFactory<T> & a_factory)
85 {
86  CH_TIME("LevelData<T>::define(dbl,comps,ghost,factory)");
87  // clear exchange copier if it's already been defined
88  if (this->m_isdefined)
89  {
90  m_exchangeCopier.clear();
91  }
92 
93  this->m_isdefined = true;
94  if (!dp.isClosed())
95  {
96  MayDay::Error("non-disjoint DisjointBoxLayout: LevelData<T>::define(const DisjointBoxLayout& dp,....)");
97  }
98  if (comps<=0)
99  {
100  MayDay::Error("LevelData::LevelData(const BoxLayout& dp, int comps) comps<=0");
101  }
102  this->m_comps = comps;
103  this->m_boxLayout = dp;
104 
105  this->m_threadSafe = a_factory.threadSafe();
106  //this->m_threadSafe = false;
107 
108  m_disjointBoxLayout = dp;
109  m_ghost = ghost;
110  //no need for exchange copier if no ghost
111  //do not do this if it is periodic because bad things can happen
112  //with large number of ghost cells.
113  bool periodic = m_disjointBoxLayout.physDomain().isPeriodic();
114  if((m_ghost != IntVect::Zero) && !periodic)
115  {
116  m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
117  }
118 
119  // Interval interval(0, comps-1);
120  this->allocateGhostVector(a_factory, ghost);
121  // this->setVector(*this, interval, interval);
122 }
123 //-----------------------------------------------------------------------
124 
125 //-----------------------------------------------------------------------
126 template<class T>
127 void LevelData<T>::define(const LevelData<T>& da, const DataFactory<T> & a_factory)
128 {
129  CH_TIME("LevelData<T>::define(LevelData<T>,factory)");
130  // clear exchange copier if it's already been defined
131  if (this->m_isdefined)
132  {
133  m_exchangeCopier.clear();
134  }
135  this->m_isdefined = true;
136  if (this == &da) return;
137  m_disjointBoxLayout = da.m_disjointBoxLayout;
138  this->m_boxLayout = da.m_disjointBoxLayout;
139  this->m_comps = da.m_comps;
140  this->m_threadSafe = a_factory.threadSafe();
141  //this->m_threadSafe = false;
142 
143  m_ghost = da.m_ghost;
144 
145  //no need for exchange copier if no ghost
146  if(m_ghost != IntVect::Zero)
147  {
148  m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
149  }
150  this->allocateGhostVector(a_factory, m_ghost);
151  da.copyTo(*this);
152 }
153 //-----------------------------------------------------------------------
154 
155 //-----------------------------------------------------------------------
156 template<class T>
157 void LevelData<T>::define(const LevelData<T>& da, const Interval& comps,
158  const DataFactory<T>& a_factory)
159 {
160  CH_TIME("LevelData<T>::define(LevelData<T>,comps,factory)");
161  // clear exchange copier if it's already been defined
162  if (this->m_isdefined)
163  {
164  m_exchangeCopier.clear();
165  }
166  this->m_isdefined = true;
167  this->m_threadSafe = a_factory.threadSafe();
168  //this->m_threadSafe = false;
169  if (this == &da)
170  {
171  MayDay::Error(" LevelData<T>::define(const LevelData<T>& da, const Interval& comps) called with 'this'");
172  }
173  CH_assert(comps.size()>0);
174  // this line doesn't make any sense!
175  //CH_assert(comps.end()<=this->m_comps);
176  CH_assert(comps.begin()>=0);
177 
178  m_disjointBoxLayout = da.m_disjointBoxLayout;
179  this->m_boxLayout = da.m_disjointBoxLayout;
180 
181  this->m_comps = comps.size();
182 
183  m_ghost = da.m_ghost;
184  //no need for exchange copier if no ghost
185  if(m_ghost != IntVect::Zero)
186  {
187  m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
188  }
189 
190  Interval dest(0, this->m_comps-1);
191 
192  this->allocateGhostVector(a_factory, m_ghost);
193 
194  this->setVector(da, comps, dest);
195 
196 }
197 //-----------------------------------------------------------------------
198 //-----------------------------------------------------------------------
199 
200 template<class T>
201 void LevelData<T>::copyTo(const Interval& srcComps,
202  BoxLayoutData<T>& dest,
203  const Interval& destComps) const
204 {
205  CH_TIME("copyTo");
206  if ((BoxLayoutData<T>*)this == &dest) return;
207 
208  if (this->boxLayout() == dest.boxLayout())
209  {
210  CH_TIME("local copy");
211  // parallel direct copy here, no communication issues
212  DataIterator it = this->dataIterator();
213  int nbox = it.size();
214 #pragma omp parallel for if(this->m_threadSafe)
215  for (int ibox = 0; ibox < nbox; ibox++)
216  {
217  dest[it[ibox]].copy(this->box(it[ibox]),
218  destComps,
219  this->box(it[ibox]),
220  this->operator[](it[ibox]),
221  srcComps);
222  }
223  return;
224  }
225 
226  Copier copier(m_disjointBoxLayout, dest.boxLayout());
227  copyTo(srcComps, dest, destComps, copier);
228 }
229 
230 template<class T>
231 void LevelData<T>::localCopyTo(const Interval& srcComps,
232  LevelData<T>& dest,
233  const Interval& destComps) const
234 { CH_TIME("localCopyTo");
235  if ((BoxLayoutData<T>*)this == &dest) return;
236 
237  if(this->disjointBoxLayout() == dest.disjointBoxLayout())
238  {
239  DataIterator it = this->dataIterator();
240  int nbox = it.size();
241 #pragma omp parallel for if(this->m_threadSafe)
242  for (int ibox = 0; ibox < nbox; ibox++)
243  {
244  Box srcBox = this->box(it[ibox]);
245  Box dstBox = this->box(it[ibox]);
246  srcBox.grow(this->ghostVect());
247  dstBox.grow(dest.ghostVect());
248  Box minBox = srcBox;
249  minBox &= dstBox;
250  dest[it[ibox]].copy(minBox,
251  destComps,
252  minBox,
253  this->operator[](it[ibox]),
254  srcComps);
255  }
256  }
257  else
258  {
259  MayDay::Error("localCopyTo only works with identical DBLs");
260  }
261 
262  return;
263 }
264 
265 template<class T>
267 {
268  CH_assert(this->nComp() == dest.nComp());
269  this->localCopyTo(this->interval(), dest, dest.interval());
270 }
271 
272 //-----------------------------------------------------------------------
273 
274 //-----------------------------------------------------------------------
275 template<class T>
277 {
278  CH_assert(this->nComp() == dest.nComp());
279  this->copyTo(this->interval(), dest, dest.interval());
280 }
281 //-----------------------------------------------------------------------
282 
283 //-----------------------------------------------------------------------
284 template<class T>
285 void LevelData<T>::copyTo(const Interval& srcComps,
286  LevelData<T>& dest,
287  const Interval& destComps) const
288 {
289  if (this == &dest)
290  {
291  MayDay::Error("src == dest in copyTo function. Perhaps you want exchange ?");
292  }
293 
294  if (this->boxLayout() == dest.boxLayout() && dest.ghostVect() == IntVect::Zero)
295  {
296  // parallel direct copy here, no communication issues
297  DataIterator it = this->dataIterator();
298  int nbox = it.size();
299 #pragma omp parallel for if(this->m_threadSafe)
300  for (int ibox = 0; ibox < nbox; ibox++)
301  {
302  dest[it[ibox]].copy(this->box(it[ibox]),
303  destComps,
304  this->box(it[ibox]),
305  this->operator[](it[ibox]),
306  srcComps);
307  }
308  return;
309  }
310 
311  Copier copier(m_disjointBoxLayout, dest.getBoxes(), dest.m_ghost);
312  copyTo(srcComps, dest, destComps, copier);
313 }
314 //-----------------------------------------------------------------------
315 
316 //-----------------------------------------------------------------------
317 template<class T>
319 {
320  CH_assert(this->nComp() == dest.nComp());
321  this->copyTo(this->interval(), dest, dest.interval());
322 }
323 //-----------------------------------------------------------------------
324 
325 //-----------------------------------------------------------------------
326 template<class T>
327 void LevelData<T>::copyTo(const Interval& srcComps,
328  BoxLayoutData<T>& dest,
329  const Interval& destComps,
330  const Copier& copier,
331  const LDOperator<T>& a_op) const
332 {
333  CH_TIME("copyTo");
334 #ifdef CH_MPI
335  {
336 // CH_TIME("MPI_Barrier copyTo");
337 // MPI_Barrier(Chombo_MPI::comm);
338  }
339 #endif
340 
341  this->makeItSo(srcComps, *this, dest, destComps, copier, a_op);
342 }
343 //-----------------------------------------------------------------------
344 
345 //-----------------------------------------------------------------------
346 template<class T>
348  const Copier& copier,
349  const LDOperator<T>& a_op) const
350 {
351  CH_assert(this->nComp() == dest.nComp());
352  this->copyTo(this->interval(), dest, dest.interval(), copier, a_op);
353 }
354 //-----------------------------------------------------------------------
355 
356 //-----------------------------------------------------------------------
357 template<class T>
358 void LevelData<T>::copyTo(const Interval& srcComps,
359  LevelData<T>& dest,
360  const Interval& destComps,
361  const Copier& copier,
362  const LDOperator<T>& a_op) const
363 {
364  CH_TIME("copyTo");
365 #ifdef CH_MPI
366  {
367 // CH_TIME("MPI_Barrier copyTo");
368 // MPI_Barrier(Chombo_MPI::comm);
369  }
370 #endif
371  this->makeItSo(srcComps, *this, dest, destComps, copier, a_op);
372 }
373 //-----------------------------------------------------------------------
374 
375 //-----------------------------------------------------------------------
376 template<class T>
378  const Copier& copier,
379  const LDOperator<T>& a_op) const
380 {
381  CH_assert(this->nComp() == dest.nComp());
382  this->copyTo(this->interval(), dest, dest.interval(), copier, a_op);
383 }
384 //-----------------------------------------------------------------------
385 
386 //-----------------------------------------------------------------------
387 template<class T>
389 {
390  CH_TIME("exchange+copier");
391  // later on we can code this part as a direct algorithm
392  // by copying and pasting the code from the Copier::define code
393  // for now, just do the easy to debug approach.
394  if(m_ghost != IntVect::Zero)//no need for exchange copier if no ghost
395  {
396  if(!m_exchangeCopier.isDefined())
397  {
398  CH_TIME("defining_copier");
399  m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
400  }
401  {
402  CH_TIME("actual_exchange");
403  exchange(comps, m_exchangeCopier);
404  }
405  }
406 
407  // if there aren't any ghost cells, there isn't really anything
408  // to do here (also, if m_ghost == Zero, m_exchangeCopier
409  // wasn't defined!
410  //if (m_ghost != IntVect::Zero)
411  //this->makeItSo(comps, *this, *this, comps, m_exchangeCopier);
412 }
413 //-----------------------------------------------------------------------
414 
415 //-----------------------------------------------------------------------
416 template<class T>
418 {
419  exchange(this->interval());
420 }
421 //-----------------------------------------------------------------------
422 
423 //-----------------------------------------------------------------------
424 template<class T>
426  const Copier& copier,
427  const LDOperator<T>& a_op)
428 {
429  CH_TIME("exchange");
430 #ifdef CH_MPI
431  {
432 // CH_TIME("MPI_Barrier exchange");
433 // MPI_Barrier(Chombo_MPI::comm);
434  }
435 #endif
436  this->makeItSo(comps, *this, *this, comps, copier, a_op);
437 }
438 //-----------------------------------------------------------------------
439 
440 //-----------------------------------------------------------------------
441 template<class T>
442 void LevelData<T>::exchange(const Copier& copier)
443 {
444  exchange(this->interval(), copier);
445 }
446 //-----------------------------------------------------------------------
447 
448 //-----------------------------------------------------------------------
449 template<class T>
451 {
452  CH_TIME("exchangeNoOverlap");
453  this->makeItSoBegin(this->interval(), *this, *this, this->interval(), copier);
454  this->makeItSoEnd(*this, this->interval());
455  this->makeItSoLocalCopy(this->interval(), *this, *this, this->interval(), copier);
456 }
457 //-----------------------------------------------------------------------
458 
459 //-----------------------------------------------------------------------
460 template<class T>
462 {
463  CH_TIME("exchangeBegin");
464  this->makeItSoBegin(this->interval(), *this, *this, this->interval(), copier);
465  this->makeItSoLocalCopy(this->interval(), *this, *this, this->interval(), copier);
466 }
467 //-----------------------------------------------------------------------
468 
469 //-----------------------------------------------------------------------
470 template<class T>
472 {
473  CH_TIME("exchangeEnd");
474  this->makeItSoEnd(*this, this->interval());
475 }
476 //-----------------------------------------------------------------------
477 
478 //-----------------------------------------------------------------------
479 template<class T>
480 void LevelData<T>::define(const BoxLayout& dp, int comps, const DataFactory<T>& a_factory)
481 {
482  MayDay::Error("LevelData<T>::define called with BoxLayout input");
483 }
484 //-----------------------------------------------------------------------
485 
486 //-----------------------------------------------------------------------
487 template<class T>
489 {
490  MayDay::Error("LevelData<T>::define called with BoxLayout input");
491 }
492 //-----------------------------------------------------------------------
493 
494 //-----------------------------------------------------------------------
495 template<class T>
496 void LevelData<T>::define(const BoxLayoutData<T>& da, const DataFactory<T>& a_factory )
497 {
498  MayDay::Error("LevelData<T>::define called with BoxLayout input");
499 }
500 //-----------------------------------------------------------------------
501 
502 //-----------------------------------------------------------------------
503 template<class T>
504 void LevelData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
505  const DataFactory<T>& a_factory)
506 {
507  MayDay::Error("LevelData<T>::define called with BoxLayout input");
508 }
509 //-----------------------------------------------------------------------
510 
511 //-----------------------------------------------------------------------
512 template<class T>
513 void LevelData<T>::apply( void (*a_Function)(const Box& box, int comps, T& t) )
514 {
515  DataIterator it = this->dataIterator();
516  int nbox = it.size();
517 #pragma omp parallel for
518  for (int ibox = 0; ibox < nbox; ibox++)
519  {
520 
521  a_Function(m_disjointBoxLayout.get(it[ibox]), this->m_comps, *(this->m_vector[it[ibox].datInd()]));
522  }
523 }
524 //-----------------------------------------------------------------------
525 
526 //-----------------------------------------------------------------------
527 template<class T>
529 {
530  DataIterator it = this->dataIterator();
531  int nbox = it.size();
532 #pragma omp parallel for
533  for (int ibox = 0; ibox < nbox; ibox++)
534  {
535  // unsigned int index = this->m_boxLayout.lindex(it());
536  f(m_disjointBoxLayout.get(it[ibox]), this->m_comps, *(this->m_vector[it[ibox].datInd()]));
537  }
538 }
539 //-----------------------------------------------------------------------
540 
541 //-----------------------------------------------------------------------
542 template<class T> void
544  const SliceSpec& a_sliceSpec ) const
545 {
546  DisjointBoxLayout toDBL;
547  m_disjointBoxLayout.degenerate( toDBL, a_sliceSpec );
548  IntVect toGhost;
549  for ( int i=0;i<CH_SPACEDIM;++i )
550  {
551  if ( i != a_sliceSpec.direction )
552  {
553  toGhost[i] = m_ghost[i];
554  } else
555  {
556  toGhost[i] = 0;
557  }
558  }
559  a_to.define( toDBL, this->nComp(), toGhost );
560  copyTo( a_to );
561 }
562 //-----------------------------------------------------------------------
563 
564 //-----------------------------------------------------------------------
565 template<class T> void
567  const SliceSpec& a_sliceSpec ) const
568 {
569  DisjointBoxLayout toDBL;
570  m_disjointBoxLayout.degenerate( toDBL, a_sliceSpec, true );
571  IntVect toGhost;
572  for ( int i=0;i<CH_SPACEDIM;++i )
573  {
574  if ( i != a_sliceSpec.direction )
575  {
576  toGhost[i] = m_ghost[i];
577  } else
578  {
579  toGhost[i] = 0;
580  }
581  }
582  a_to.define( toDBL, this->nComp(), toGhost );
583 
584  // manage copyTo ourselves to maintain locality
585  DataIterator fromDit = this->dataIterator();
586  DataIterator toDit = a_to.dataIterator();
587  for (toDit.begin(); toDit.ok(); ++toDit)
588  {
589  fromDit.begin();
590  bool done = false;
591  while (!done)
592  {
593  if (m_disjointBoxLayout[fromDit].contains(toDBL[toDit]))
594  {
595  // boxes intersect, do copy
596  FArrayBox& toFAB = a_to[toDit];
597  const FArrayBox& fromFAB = this->operator[](fromDit);
598  // note that we're including ghost cells here
599  Box intersectBox = toFAB.box();
600  intersectBox &= fromFAB.box();
601  // now do copy
602  toFAB.copy(fromFAB, intersectBox);
603  done = true;
604  } // end if we found an intersection
605  else
606  {
607  ++fromDit;
608  // probably want to check for lexigraphical sorting done-ness
609 
610  // are we done looping through fromBoxes?
611  if (!fromDit.ok()) done = true;
612  } // end if we didn't find a match
613  } // end while loop over fromBoxes
614 
615  } // end loop over toBoxes
616 
617 }
618 //-----------------------------------------------------------------------
619 
620 #include "NamespaceFooter.H"
621 #endif
int m_comps
Definition: BoxLayoutData.H:387
#define CH_SPACEDIM
Definition: SPACE.H:51
#define CH_assert(cond)
Definition: CHArray.H:37
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:231
LevelData()
Definition: LevelDataI.H:30
void degenerate(LevelData< T > &a_to, const SliceSpec &a_ss) const
Definition: LevelDataI.H:543
DisjointBoxLayout m_disjointBoxLayout
Definition: LevelData.H:297
Definition: LevelData.H:248
A not-necessarily-disjoint collective of boxes.
Definition: BoxLayout.H:145
int nComp() const
Definition: BoxLayoutData.H:306
A strange but true thing to make copying from one boxlayoutdata to another fast.
Definition: Copier.H:145
int size() const
Definition: DataIterator.H:218
Definition: SliceSpec.H:41
IntVect m_ghost
Definition: LevelData.H:299
void begin()
initialize this iterator to the first Box in its Layout
Definition: LayoutIterator.H:122
void setVector(const BoxLayoutData< T > &da, const Interval &srcComps, const Interval &destComps)
Definition: BoxLayoutDataI.H:46
Definition: DataIterator.H:190
Copier m_exchangeCopier
Definition: LevelData.H:305
int size() const
Definition: Interval.H:75
BoxLayout m_boxLayout
Definition: LayoutData.H:118
virtual void exchange(void)
Simplest case – do all components.
Definition: LevelDataI.H:417
Definition: EBInterface.H:45
virtual void exchangeBegin(const Copier &copier)
asynchronous exchange start. load and fire off messages.
Definition: LevelDataI.H:461
Box minBox(const Box &b1, const Box &b2)
virtual void copyTo(const Interval &srcComps, BoxLayoutData< T > &dest, const Interval &destComps) const
Definition: LevelDataI.H:201
virtual void apply(void(*a_Function)(const Box &, int, T &))
#define CH_TIME(name)
Definition: CH_Timer.H:82
Structure for passing component ranges in code.
Definition: Interval.H:23
void allocateGhostVector(const DataFactory< T > &factory, const IntVect &ghost=IntVect::Zero)
Definition: BoxLayoutDataI.H:171
void degenerateLocalOnly(LevelData< T > &a_to, const SliceSpec &a_ss) const
version of degenerate which does strictly local copying
Definition: LevelDataI.H:566
Interval interval() const
Definition: BoxLayoutData.H:312
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:83
BaseFab< T > & copy(const BaseFab< T > &a_src, const Box &a_srcbox, int a_srccomp, const Box &a_destbox, int a_destcomp, int a_numcomp)
Definition: BaseFabImplem.H:381
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
bool isClosed() const
Definition: BoxLayout.H:729
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.
int begin() const
Definition: Interval.H:97
const BoxLayout & boxLayout() const
Definition: LayoutData.H:107
static const IntVect Zero
Definition: IntVect.H:654
A Rectangular Domain on an Integer Lattice.
Definition: Box.H:465
bool m_isdefined
Definition: BoxLayoutData.H:389
virtual ~LevelData()
Definition: LevelDataI.H:37
An integer Vector in SpaceDim-dimensional space.
Definition: CHArray.H:42
Definition: FArrayBox.H:45
DataIterator dataIterator() const
Definition: LayoutDataI.H:78
void degenerate(DisjointBoxLayout &a_to, const SliceSpec &a_ss, bool a_maintainProcAssign=false) const
Factory object to data members of a BoxLayoutData container.
Definition: BoxLayoutData.H:30
Box & grow(int i)
grow functions
Definition: Box.H:2247
virtual bool ok() const
return true if this iterator is still in its Layout
Definition: LayoutIterator.H:117
virtual bool threadSafe() const
Definition: BoxLayoutData.H:49
Definition: BoxLayoutData.H:173
bool m_threadSafe
Definition: BoxLayoutData.H:388
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:471
int direction
Definition: SliceSpec.H:48
virtual void exchangeNoOverlap(const Copier &copier)
Definition: LevelDataI.H:450
const IntVect & ghostVect() const
Definition: LevelData.H:170
const Box & box() const
Definition: BaseFabImplem.H:226