00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _LEVELDATAI_H_
00012 #define _LEVELDATAI_H_
00013
00014 #include <cstdlib>
00015 #include <algorithm>
00016 using std::sort;
00017
00018 #include "parstream.H"
00019 #include "CH_Timer.H"
00020 #include <float.h>
00021 #include "NamespaceHeader.H"
00022
00023
00024
00025
00026 template < > void LevelData<FluxBox>::degenerateLocalOnly( LevelData<FluxBox>& a_to, const SliceSpec& a_ss ) const;
00027
00028
00029 template<class T>
00030 LevelData<T>::LevelData()
00031 {
00032 }
00033
00034
00035
00036 template<class T>
00037 LevelData<T>::~LevelData()
00038 {
00039 CH_TIME("~LevelData");
00040 }
00041
00042
00043
00044 template<class T>
00045 LevelData<T>::LevelData(const DisjointBoxLayout& dp, int comps, const IntVect& ghost,
00046 const DataFactory<T>& a_factory)
00047 : m_disjointBoxLayout(dp), m_ghost(ghost)
00048 {
00049 #ifdef CH_MPI
00050 this->numSends = 0;
00051 this->numReceives = 0;
00052 #endif
00053 this->m_boxLayout = dp;
00054 this->m_comps = comps;
00055 this->m_isdefined = true;
00056
00057 if(m_ghost != IntVect::Zero)
00058 {
00059 m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
00060 }
00061
00062 if (!dp.isClosed())
00063 {
00064 MayDay::Error("non-disjoint DisjointBoxLayout: LevelData<T>::LevelData(const DisjointBoxLayout& dp, int comps)");
00065 }
00066
00067 this->m_threadSafe = a_factory.threadSafe();
00068
00069
00070 Interval interval(0, comps-1);
00071 this->allocateGhostVector(a_factory, ghost);
00072 this->setVector(*this, interval, interval);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082 template<class T>
00083 void LevelData<T>::define(const DisjointBoxLayout& dp, int comps, const IntVect& ghost,
00084 const DataFactory<T> & a_factory)
00085 {
00086 CH_TIME("LevelData<T>::define(dbl,comps,ghost,factory)");
00087
00088 if (this->m_isdefined)
00089 {
00090 m_exchangeCopier.clear();
00091 }
00092
00093 this->m_isdefined = true;
00094 if (!dp.isClosed())
00095 {
00096 MayDay::Error("non-disjoint DisjointBoxLayout: LevelData<T>::define(const DisjointBoxLayout& dp,....)");
00097 }
00098 if (comps<=0)
00099 {
00100 MayDay::Error("LevelData::LevelData(const BoxLayout& dp, int comps) comps<=0");
00101 }
00102 this->m_comps = comps;
00103 this->m_boxLayout = dp;
00104
00105 this->m_threadSafe = a_factory.threadSafe();
00106
00107
00108 m_disjointBoxLayout = dp;
00109 m_ghost = ghost;
00110
00111
00112
00113 bool periodic = m_disjointBoxLayout.physDomain().isPeriodic();
00114 if((m_ghost != IntVect::Zero) && !periodic)
00115 {
00116 m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
00117 }
00118
00119
00120 this->allocateGhostVector(a_factory, ghost);
00121
00122 }
00123
00124
00125
00126 template<class T>
00127 void LevelData<T>::define(const LevelData<T>& da, const DataFactory<T> & a_factory)
00128 {
00129 CH_TIME("LevelData<T>::define(LevelData<T>,factory)");
00130
00131 if (this->m_isdefined)
00132 {
00133 m_exchangeCopier.clear();
00134 }
00135 this->m_isdefined = true;
00136 if (this == &da) return;
00137 m_disjointBoxLayout = da.m_disjointBoxLayout;
00138 this->m_boxLayout = da.m_disjointBoxLayout;
00139 this->m_comps = da.m_comps;
00140 this->m_threadSafe = a_factory.threadSafe();
00141
00142
00143 m_ghost = da.m_ghost;
00144
00145
00146 if(m_ghost != IntVect::Zero)
00147 {
00148 m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
00149 }
00150 this->allocateGhostVector(a_factory, m_ghost);
00151 da.copyTo(*this);
00152 }
00153
00154
00155
00156 template<class T>
00157 void LevelData<T>::define(const LevelData<T>& da, const Interval& comps,
00158 const DataFactory<T>& a_factory)
00159 {
00160 CH_TIME("LevelData<T>::define(LevelData<T>,comps,factory)");
00161
00162 if (this->m_isdefined)
00163 {
00164 m_exchangeCopier.clear();
00165 }
00166 this->m_isdefined = true;
00167 this->m_threadSafe = a_factory.threadSafe();
00168
00169 if (this == &da)
00170 {
00171 MayDay::Error(" LevelData<T>::define(const LevelData<T>& da, const Interval& comps) called with 'this'");
00172 }
00173 CH_assert(comps.size()>0);
00174
00175
00176 CH_assert(comps.begin()>=0);
00177
00178 m_disjointBoxLayout = da.m_disjointBoxLayout;
00179 this->m_boxLayout = da.m_disjointBoxLayout;
00180
00181 this->m_comps = comps.size();
00182
00183 m_ghost = da.m_ghost;
00184
00185 if(m_ghost != IntVect::Zero)
00186 {
00187 m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
00188 }
00189
00190 Interval dest(0, this->m_comps-1);
00191
00192 this->allocateGhostVector(a_factory, m_ghost);
00193
00194 this->setVector(da, comps, dest);
00195
00196 }
00197
00198
00199
00200 template<class T>
00201 void LevelData<T>::copyTo(const Interval& srcComps,
00202 BoxLayoutData<T>& dest,
00203 const Interval& destComps) const
00204 {
00205 CH_TIME("copyTo");
00206 if ((BoxLayoutData<T>*)this == &dest) return;
00207
00208 if (this->boxLayout() == dest.boxLayout())
00209 {
00210 CH_TIME("local copy");
00211
00212 DataIterator it = this->dataIterator();
00213 int nbox = it.size();
00214 #pragma omp parallel for if(this->m_threadSafe)
00215 for (int ibox = 0; ibox < nbox; ibox++)
00216 {
00217 dest[it[ibox]].copy(this->box(it[ibox]),
00218 destComps,
00219 this->box(it[ibox]),
00220 this->operator[](it[ibox]),
00221 srcComps);
00222 }
00223 return;
00224 }
00225
00226 Copier copier(m_disjointBoxLayout, dest.boxLayout());
00227 copyTo(srcComps, dest, destComps, copier);
00228 }
00229
00230 template<class T>
00231 void LevelData<T>::localCopyTo(const Interval& srcComps,
00232 LevelData<T>& dest,
00233 const Interval& destComps) const
00234 { CH_TIME("localCopyTo");
00235 if ((BoxLayoutData<T>*)this == &dest) return;
00236
00237 if(this->disjointBoxLayout() == dest.disjointBoxLayout())
00238 {
00239 DataIterator it = this->dataIterator();
00240 int nbox = it.size();
00241 #pragma omp parallel for if(this->m_threadSafe)
00242 for (int ibox = 0; ibox < nbox; ibox++)
00243 {
00244 Box srcBox = this->box(it[ibox]);
00245 Box dstBox = this->box(it[ibox]);
00246 srcBox.grow(this->ghostVect());
00247 dstBox.grow(dest.ghostVect());
00248 Box minBox = srcBox;
00249 minBox &= dstBox;
00250 dest[it[ibox]].copy(minBox,
00251 destComps,
00252 minBox,
00253 this->operator[](it[ibox]),
00254 srcComps);
00255 }
00256 }
00257 else
00258 {
00259 MayDay::Error("localCopyTo only works with identical DBLs");
00260 }
00261
00262 return;
00263 }
00264
00265 template<class T>
00266 void LevelData<T>::localCopyTo(LevelData<T>& dest) const
00267 {
00268 CH_assert(this->nComp() == dest.nComp());
00269 this->localCopyTo(this->interval(), dest, dest.interval());
00270 }
00271
00272
00273
00274
00275 template<class T>
00276 void LevelData<T>::copyTo(BoxLayoutData<T>& dest) const
00277 {
00278 CH_assert(this->nComp() == dest.nComp());
00279 this->copyTo(this->interval(), dest, dest.interval());
00280 }
00281
00282
00283
00284 template<class T>
00285 void LevelData<T>::copyTo(const Interval& srcComps,
00286 LevelData<T>& dest,
00287 const Interval& destComps) const
00288 {
00289 if (this == &dest)
00290 {
00291 MayDay::Error("src == dest in copyTo function. Perhaps you want exchange ?");
00292 }
00293
00294 if (this->boxLayout() == dest.boxLayout() && dest.ghostVect() == IntVect::Zero)
00295 {
00296
00297 DataIterator it = this->dataIterator();
00298 int nbox = it.size();
00299 #pragma omp parallel for if(this->m_threadSafe)
00300 for (int ibox = 0; ibox < nbox; ibox++)
00301 {
00302 dest[it[ibox]].copy(this->box(it[ibox]),
00303 destComps,
00304 this->box(it[ibox]),
00305 this->operator[](it[ibox]),
00306 srcComps);
00307 }
00308 return;
00309 }
00310
00311 Copier copier(m_disjointBoxLayout, dest.getBoxes(), dest.m_ghost);
00312 copyTo(srcComps, dest, destComps, copier);
00313 }
00314
00315
00316
00317 template<class T>
00318 void LevelData<T>::copyTo(LevelData<T>& dest) const
00319 {
00320 CH_assert(this->nComp() == dest.nComp());
00321 this->copyTo(this->interval(), dest, dest.interval());
00322 }
00323
00324
00325
00326 template<class T>
00327 void LevelData<T>::copyTo(const Interval& srcComps,
00328 BoxLayoutData<T>& dest,
00329 const Interval& destComps,
00330 const Copier& copier,
00331 const LDOperator<T>& a_op) const
00332 {
00333 CH_TIME("copyTo");
00334 #ifdef CH_MPI
00335 {
00336
00337
00338 }
00339 #endif
00340
00341 this->makeItSo(srcComps, *this, dest, destComps, copier, a_op);
00342 }
00343
00344
00345
00346 template<class T>
00347 void LevelData<T>::copyTo(BoxLayoutData<T>& dest,
00348 const Copier& copier,
00349 const LDOperator<T>& a_op) const
00350 {
00351 CH_assert(this->nComp() == dest.nComp());
00352 this->copyTo(this->interval(), dest, dest.interval(), copier, a_op);
00353 }
00354
00355
00356
00357 template<class T>
00358 void LevelData<T>::copyTo(const Interval& srcComps,
00359 LevelData<T>& dest,
00360 const Interval& destComps,
00361 const Copier& copier,
00362 const LDOperator<T>& a_op) const
00363 {
00364 CH_TIME("copyTo");
00365 #ifdef CH_MPI
00366 {
00367
00368
00369 }
00370 #endif
00371 this->makeItSo(srcComps, *this, dest, destComps, copier, a_op);
00372 }
00373
00374
00375
00376 template<class T>
00377 void LevelData<T>::copyTo(LevelData<T>& dest,
00378 const Copier& copier,
00379 const LDOperator<T>& a_op) const
00380 {
00381 CH_assert(this->nComp() == dest.nComp());
00382 this->copyTo(this->interval(), dest, dest.interval(), copier, a_op);
00383 }
00384
00385
00386
00387 template<class T>
00388 void LevelData<T>::exchange(const Interval& comps)
00389 {
00390 CH_TIME("exchange+copier");
00391
00392
00393
00394 if(m_ghost != IntVect::Zero)
00395 {
00396 if(!m_exchangeCopier.isDefined())
00397 {
00398 CH_TIME("defining_copier");
00399 m_exchangeCopier.define(m_disjointBoxLayout, m_disjointBoxLayout, m_ghost, true);
00400 }
00401 {
00402 CH_TIME("actual_exchange");
00403 exchange(comps, m_exchangeCopier);
00404 }
00405 }
00406
00407
00408
00409
00410
00411
00412 }
00413
00414
00415
00416 template<class T>
00417 void LevelData<T>::exchange(void)
00418 {
00419 exchange(this->interval());
00420 }
00421
00422
00423
00424 template<class T>
00425 void LevelData<T>::exchange(const Interval& comps,
00426 const Copier& copier,
00427 const LDOperator<T>& a_op)
00428 {
00429 CH_TIME("exchange");
00430 #ifdef CH_MPI
00431 {
00432
00433
00434 }
00435 #endif
00436 this->makeItSo(comps, *this, *this, comps, copier, a_op);
00437 }
00438
00439
00440
00441 template<class T>
00442 void LevelData<T>::exchange(const Copier& copier)
00443 {
00444 exchange(this->interval(), copier);
00445 }
00446
00447
00448
00449 template<class T>
00450 void LevelData<T>::exchangeNoOverlap(const Copier& copier)
00451 {
00452 CH_TIME("exchangeNoOverlap");
00453 this->makeItSoBegin(this->interval(), *this, *this, this->interval(), copier);
00454 this->makeItSoEnd(*this, this->interval());
00455 this->makeItSoLocalCopy(this->interval(), *this, *this, this->interval(), copier);
00456 }
00457
00458
00459
00460 template<class T>
00461 void LevelData<T>::exchangeBegin(const Copier& copier)
00462 {
00463 CH_TIME("exchangeBegin");
00464 this->makeItSoBegin(this->interval(), *this, *this, this->interval(), copier);
00465 this->makeItSoLocalCopy(this->interval(), *this, *this, this->interval(), copier);
00466 }
00467
00468
00469
00470 template<class T>
00471 void LevelData<T>::exchangeEnd()
00472 {
00473 CH_TIME("exchangeEnd");
00474 this->makeItSoEnd(*this, this->interval());
00475 }
00476
00477
00478
00479 template<class T>
00480 void LevelData<T>::define(const BoxLayout& dp, int comps, const DataFactory<T>& a_factory)
00481 {
00482 MayDay::Error("LevelData<T>::define called with BoxLayout input");
00483 }
00484
00485
00486
00487 template<class T>
00488 void LevelData<T>::define(const BoxLayout& dp)
00489 {
00490 MayDay::Error("LevelData<T>::define called with BoxLayout input");
00491 }
00492
00493
00494
00495 template<class T>
00496 void LevelData<T>::define(const BoxLayoutData<T>& da, const DataFactory<T>& a_factory )
00497 {
00498 MayDay::Error("LevelData<T>::define called with BoxLayout input");
00499 }
00500
00501
00502
00503 template<class T>
00504 void LevelData<T>::define(const BoxLayoutData<T>& da, const Interval& comps,
00505 const DataFactory<T>& a_factory)
00506 {
00507 MayDay::Error("LevelData<T>::define called with BoxLayout input");
00508 }
00509
00510
00511
00512 template<class T>
00513 void LevelData<T>::apply( void (*a_Function)(const Box& box, int comps, T& t) )
00514 {
00515 DataIterator it = this->dataIterator();
00516 int nbox = it.size();
00517 #pragma omp parallel for
00518 for (int ibox = 0; ibox < nbox; ibox++)
00519 {
00520
00521 a_Function(m_disjointBoxLayout.get(it[ibox]), this->m_comps, *(this->m_vector[it[ibox].datInd()]));
00522 }
00523 }
00524
00525
00526
00527 template<class T>
00528 void LevelData<T>::apply( const ApplyFunctor & f )
00529 {
00530 DataIterator it = this->dataIterator();
00531 int nbox = it.size();
00532 #pragma omp parallel for
00533 for (int ibox = 0; ibox < nbox; ibox++)
00534 {
00535
00536 f(m_disjointBoxLayout.get(it[ibox]), this->m_comps, *(this->m_vector[it[ibox].datInd()]));
00537 }
00538 }
00539
00540
00541
00542 template<class T> void
00543 LevelData<T>::degenerate( LevelData<T>& a_to,
00544 const SliceSpec& a_sliceSpec ) const
00545 {
00546 DisjointBoxLayout toDBL;
00547 m_disjointBoxLayout.degenerate( toDBL, a_sliceSpec );
00548 IntVect toGhost;
00549 for ( int i=0;i<CH_SPACEDIM;++i )
00550 {
00551 if ( i != a_sliceSpec.direction )
00552 {
00553 toGhost[i] = m_ghost[i];
00554 } else
00555 {
00556 toGhost[i] = 0;
00557 }
00558 }
00559 a_to.define( toDBL, this->nComp(), toGhost );
00560 copyTo( a_to );
00561 }
00562
00563
00564
00565 template<class T> void
00566 LevelData<T>::degenerateLocalOnly( LevelData<T>& a_to,
00567 const SliceSpec& a_sliceSpec ) const
00568 {
00569 DisjointBoxLayout toDBL;
00570 m_disjointBoxLayout.degenerate( toDBL, a_sliceSpec, true );
00571 IntVect toGhost;
00572 for ( int i=0;i<CH_SPACEDIM;++i )
00573 {
00574 if ( i != a_sliceSpec.direction )
00575 {
00576 toGhost[i] = m_ghost[i];
00577 } else
00578 {
00579 toGhost[i] = 0;
00580 }
00581 }
00582 a_to.define( toDBL, this->nComp(), toGhost );
00583
00584
00585 DataIterator fromDit = this->dataIterator();
00586 DataIterator toDit = a_to.dataIterator();
00587 for (toDit.begin(); toDit.ok(); ++toDit)
00588 {
00589 fromDit.begin();
00590 bool done = false;
00591 while (!done)
00592 {
00593 if (m_disjointBoxLayout[fromDit].contains(toDBL[toDit]))
00594 {
00595
00596 FArrayBox& toFAB = a_to[toDit];
00597 const FArrayBox& fromFAB = this->operator[](fromDit);
00598
00599 Box intersectBox = toFAB.box();
00600 intersectBox &= fromFAB.box();
00601
00602 toFAB.copy(fromFAB, intersectBox);
00603 done = true;
00604 }
00605 else
00606 {
00607 ++fromDit;
00608
00609
00610
00611 if (!fromDit.ok()) done = true;
00612 }
00613 }
00614
00615 }
00616
00617 }
00618
00619
00620 #include "NamespaceFooter.H"
00621 #endif