00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _BASEFABIMPLEM_H_
00012 #define _BASEFABIMPLEM_H_
00013
00014 #include "BaseFabMacros.H"
00015 #include "CH_Timer.H"
00016 #include "SliceSpec.H"
00017 #include "MayDay.H"
00018 #include "parstream.H"
00019 #include "NamespaceHeader.H"
00020
00021
00022
00023
00024
00025 template < > void BaseFab<Real>::define();
00026
00027 template < > void BaseFab<Real>::undefine();
00028
00029 template < > void BaseFab<Real>::setVal (Real val);
00030
00031 template < > void BaseFab<int>::define();
00032
00033 template < > void BaseFab<int>::undefine();
00034
00035 template < > int BaseFab<int>::test();
00036
00037 template <class T> int BaseFab<T>::testBoxAndComp()
00038 {
00039 MayDay::Warning("pretty minimal test");
00040 Box b(IntVect::Zero, IntVect::Unit);
00041 BaseFab<T> blerg;
00042 blerg.define(b, 1);
00043
00044 if (blerg.nComp() != 1)
00045 {
00046 pout() << "ncomp busted" << endl;
00047 return -2;
00048 }
00049 if (blerg.box() != b)
00050 {
00051 pout() << "box return busted" << endl;
00052 return -2;
00053 }
00054 for (int idir = 0; idir < SpaceDim; idir++)
00055 {
00056 if (blerg.size()[idir] != 2)
00057 {
00058 pout() << "size busted" <<endl;
00059 return -3;
00060 }
00061 }
00062
00063 if (blerg.smallEnd() != IntVect::Zero)
00064 {
00065 pout() << "smallend busted" <<endl;
00066 return -4;
00067 }
00068 if (blerg.bigEnd() != IntVect::Unit)
00069 {
00070 pout() << "bigend busted" <<endl;
00071 return -5;
00072 }
00073 return 0;
00074 }
00075 template <class T> int BaseFab<T>::test()
00076 {
00077 int retval = testBoxAndComp();
00078 return retval;
00079 }
00080
00081
00082
00083
00084
00085 template <class T> inline BaseFab<T>::BaseFab()
00086 :
00087 m_domain(Box()),
00088 m_nvar(0),
00089 m_numpts(0),
00090 m_truesize(0),
00091 m_dptr(0),
00092 m_aliased(false)
00093 {
00094 }
00095
00096 template <class T> inline BaseFab<T>::BaseFab(const Box& a_bx,
00097 int a_n,
00098 T* a_alias)
00099 :
00100 m_domain(a_bx),
00101 m_nvar(a_n),
00102 m_numpts(a_bx.numPts()),
00103 m_truesize(a_bx.numPts() * a_n),
00104 m_dptr(0),
00105 m_aliased(false)
00106 {
00107 if (a_alias != NULL)
00108 {
00109 m_dptr = a_alias;
00110 m_aliased = true;
00111 }
00112 else
00113 {
00114 define();
00115 }
00116 }
00117
00118 template <class T> inline BaseFab<T>::BaseFab(const Interval& a_comps,
00119 BaseFab<T>& a_original)
00120 :
00121 m_domain(a_original.m_domain),
00122 m_nvar(a_comps.size()),
00123 m_numpts(a_original.m_numpts),
00124 m_truesize(a_original.m_numpts * m_nvar),
00125 m_dptr(a_original.dataPtr(a_comps.begin())),
00126 m_aliased(true)
00127 {
00128 }
00129
00130 template <class T> inline BaseFab<T>::~BaseFab()
00131 {
00132 undefine();
00133 }
00134
00135 template <class T> void BaseFab<T>::resize(const Box& a_b,
00136 int a_n,
00137 T* a_alias)
00138 {
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153 undefine();
00154
00155 m_nvar = a_n;
00156 m_domain = a_b;
00157 m_numpts = m_domain.numPts();
00158
00159 if (a_alias != NULL)
00160 {
00161 m_dptr = a_alias;
00162 m_aliased = true;
00163 }
00164 else
00165 {
00166 m_aliased = false;
00167 define();
00168 }
00169 }
00170
00171 template <class T> inline void BaseFab<T>::define(const Interval& a_comps,
00172 BaseFab<T>& a_original)
00173 {
00174 undefine();
00175
00176 m_domain = a_original.m_domain;
00177 m_numpts = a_original.m_numpts;
00178 m_truesize = a_original.m_numpts*a_comps.size();
00179 m_nvar = a_comps.size();
00180 m_dptr = a_original.dataPtr(a_comps.begin());
00181 m_aliased = true;
00182
00183
00184 }
00185
00186 template <class T> inline void BaseFab<T>::clear()
00187 {
00188 undefine();
00189
00190 m_domain = Box();
00191 m_nvar = 0;
00192 m_numpts = 0;
00193 }
00194
00195 template <class T> inline int BaseFab<T>::nComp() const
00196 {
00197 return m_nvar;
00198 }
00199
00200 template <class T> Arena* BaseFab<T>::s_Arena = NULL;
00201
00202 template <class T> inline const Box& BaseFab<T>::box() const
00203 {
00204 return m_domain;
00205 }
00206
00207 template <class T> inline IntVect BaseFab<T>::size() const
00208 {
00209 return m_domain.size();
00210 }
00211
00212 template <class T> inline const IntVect& BaseFab<T>::smallEnd() const
00213 {
00214 return m_domain.smallEnd();
00215 }
00216
00217 template <class T> inline const IntVect& BaseFab<T>::bigEnd() const
00218 {
00219 return m_domain.bigEnd();
00220 }
00221
00222 template <class T> inline T& BaseFab<T>::operator () (const IntVect& a_p,
00223 int a_n)
00224 {
00225 CH_assert(a_n >= 0);
00226 CH_assert(a_n < m_nvar);
00227 CH_assert(!(m_dptr == 0));
00228 CH_assert(m_domain.contains(a_p));
00229
00230 long int ind1 = m_domain.index(a_p);
00231 long int ind2 = a_n * m_numpts;
00232 long int ind = ind1 + ind2;
00233
00234 return m_dptr[ind];
00235 }
00236
00237 template <class T> inline T& BaseFab<T>::operator () (const IntVect& a_p)
00238 {
00239 CH_assert(!(m_dptr == 0));
00240 CH_assert(m_domain.contains(a_p));
00241
00242 return m_dptr[m_domain.index(a_p)];
00243 }
00244
00245 template <class T> inline const T& BaseFab<T>::operator () (const IntVect& a_p,
00246 int a_n) const
00247 {
00248 CH_assert(a_n >= 0);
00249 CH_assert(a_n < m_nvar);
00250 CH_assert(!(m_dptr == 0));
00251 CH_assert(m_domain.contains(a_p));
00252
00253 return m_dptr[m_domain.index(a_p) + a_n * m_numpts];
00254 }
00255
00256 template <class T> inline const T& BaseFab<T>::operator () (const IntVect& a_p) const
00257 {
00258 CH_assert(!(m_dptr == 0));
00259 CH_assert(m_domain.contains(a_p));
00260
00261 return m_dptr[m_domain.index(a_p)];
00262 }
00263
00264 template <class T> inline void BaseFab<T>::getVal(T* a_data,
00265 const IntVect& a_pos,
00266 int a_n,
00267 int a_numcomp) const
00268 {
00269 const int loc = m_domain.index(a_pos);
00270 const long size = m_domain.numPts();
00271
00272 CH_assert(!(m_dptr == 0));
00273 CH_assert(a_n >= 0 && a_n + a_numcomp <= m_nvar);
00274
00275 for (int k = 0; k < a_numcomp; k++)
00276 {
00277 a_data[k] = m_dptr[loc+(a_n+k)*size];
00278 }
00279 }
00280
00281 template <class T> inline void BaseFab<T>::getVal(T* a_data,
00282 const IntVect& a_pos) const
00283 {
00284 getVal(a_data,a_pos,0,m_nvar);
00285 }
00286
00287 template <class T> inline const int* BaseFab<T>::loVect() const
00288 {
00289 return m_domain.loVect();
00290 }
00291
00292 template <class T> inline const int* BaseFab<T>::hiVect() const
00293 {
00294 return m_domain.hiVect();
00295 }
00296
00297 template <class T> inline const int* BaseFab<T>::nCompPtr() const
00298 {
00299 CH_assert(!(m_dptr == 0));
00300
00301 return &m_nvar;
00302 }
00303
00304 template <class T> inline T* BaseFab<T>::dataPtr(int a_n)
00305 {
00306 CH_assert(!(m_dptr == 0));
00307 CH_assert((a_n >= 0) && (a_n < m_nvar));
00308
00309 return &m_dptr[a_n * m_numpts];
00310 }
00311
00312 template <class T> inline const T* BaseFab<T>::dataPtr(int a_n) const
00313 {
00314 CH_assert(!(m_dptr == 0));
00315 CH_assert((a_n >= 0) && (a_n < m_nvar));
00316
00317 return &m_dptr[a_n * m_numpts];
00318 }
00319
00320 template <class T> inline bool BaseFab<T>::contains(const BaseFab<T>& a_fab) const
00321 {
00322 return box().contains(a_fab.box()) && m_nvar <= a_fab.m_nvar;
00323 }
00324
00325 template <class T> inline bool BaseFab<T>::contains (const Box& a_bx) const
00326 {
00327 return box().contains(a_bx);
00328 }
00329
00330 template <class T> inline void BaseFab<T>::setVal(T a_x,
00331 const Box& a_bx,
00332 int a_nstart,
00333 int a_numcomp)
00334 {
00335 performSetVal(a_x,a_bx,a_nstart,a_numcomp);
00336 }
00337
00338 template <class T> inline void BaseFab<T>::setVal(T a_x,
00339 const Box& a_bx,
00340 int a_n)
00341 {
00342 performSetVal(a_x,a_bx,a_n,1);
00343 }
00344
00345 template <class T> inline void BaseFab<T>::setVal(T a_x,
00346 int a_n)
00347 {
00348 performSetVal(a_x,m_domain,a_n,1);
00349 }
00350
00351 template <class T> inline void BaseFab<T>::setVal(T a_x)
00352 {
00353 performSetVal(a_x,box(),0,m_nvar);
00354 }
00355
00356 template <class T>
00357 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src,
00358 const Box& a_srcbox,
00359 int a_srccomp,
00360 const Box& a_destbox,
00361 int a_destcomp,
00362 int a_numcomp)
00363 {
00364 CH_assert(a_srcbox.sameSize(a_destbox));
00365 CH_assert(a_src.box().contains(a_srcbox));
00366 CH_assert(m_domain.contains(a_destbox));
00367 CH_assert(a_srccomp >= 0 && a_srccomp+a_numcomp <= a_src.nComp());
00368 CH_assert(a_destcomp >= 0 && a_destcomp+a_numcomp <= m_nvar);
00369
00370 performCopy(a_src,a_srcbox,a_srccomp,a_destbox,a_destcomp,a_numcomp);
00371
00372 return *this;
00373 }
00374
00375 template <class T>
00376 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src,
00377 int a_srccomp,
00378 int a_destcomp,
00379 int a_numcomp)
00380 {
00381 CH_assert(a_srccomp >= 0 && a_srccomp + a_numcomp <= a_src.m_nvar);
00382 CH_assert(a_destcomp >= 0 && a_destcomp + a_numcomp <= m_nvar);
00383
00384 Box overlap(m_domain);
00385 overlap &= a_src.m_domain;
00386
00387 if (!overlap.isEmpty())
00388 {
00389 performCopy(a_src,overlap,a_srccomp,overlap,a_destcomp,a_numcomp);
00390 }
00391
00392 return *this;
00393 }
00394
00395 template <class T>
00396 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src,
00397 const Box& a_destbox)
00398 {
00399 CH_assert(m_nvar <= a_src.m_nvar);
00400 CH_assert(m_domain.contains(a_destbox));
00401
00402 Box overlap(a_destbox);
00403 overlap &= a_src.m_domain;
00404
00405 if (!overlap.isEmpty())
00406 {
00407 performCopy(a_src,overlap,0,overlap,0,m_nvar);
00408 }
00409
00410 return *this;
00411 }
00412
00413 template <class T>
00414 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src)
00415 {
00416 CH_assert(m_nvar <= a_src.m_nvar);
00417 CH_assert(m_domain.sameType(a_src.m_domain));
00418
00419 Box overlap(m_domain);
00420 overlap &= a_src.m_domain;
00421
00422 if (!overlap.isEmpty())
00423 {
00424 performCopy(a_src,overlap,0,overlap,0,m_nvar);
00425 }
00426
00427 return *this;
00428 }
00429
00430 template <class T> inline void BaseFab<T>::copy(const Box& a_RegionFrom,
00431 const Interval& a_Cdest,
00432 const Box& a_RegionTo,
00433 const BaseFab<T>& a_src,
00434 const Interval& a_Csrc)
00435 {
00436 if ((this == &a_src) && (a_RegionFrom == a_RegionTo) && (a_Cdest == a_Csrc) )
00437 {
00438 return;
00439 }
00440
00441 CH_assert(a_Cdest.size() == a_Csrc.size());
00442
00443 copy(a_src, a_RegionFrom, a_Csrc.begin(), a_RegionTo,
00444 a_Cdest.begin(), a_Cdest.size());
00445 }
00446
00447 template <class T> inline BaseFab<T>& BaseFab<T>::shift(const IntVect& a_v)
00448 {
00449 m_domain += a_v;
00450
00451 return *this;
00452 }
00453
00454 template <class T> inline BaseFab<T>& BaseFab<T>::shift(int a_idir,
00455 int a_ncells)
00456 {
00457 m_domain.shift(a_idir,a_ncells);
00458
00459 return *this;
00460 }
00461
00462 template <class T> inline BaseFab<T> & BaseFab<T>::shiftHalf(int a_idir,
00463 int a_numHalfs)
00464 {
00465 m_domain.shiftHalf(a_idir,a_numHalfs);
00466
00467 return *this;
00468 }
00469
00470 template <class T> inline BaseFab<T> & BaseFab<T>::shiftHalf(const IntVect& a_v)
00471 {
00472 m_domain.shiftHalf(a_v);
00473
00474 return *this;
00475 }
00476
00477 template <class T> inline int BaseFab<T>::size(const Box& a_box,
00478 const Interval& a_comps) const
00479 {
00480 return a_box.numPts() * sizeof(T) * a_comps.size();
00481 }
00482
00483 template <class T> inline void BaseFab<T>::linearOut(void* a_buf,
00484 const Box& a_R,
00485 const Interval& a_comps) const
00486 {
00487 linearOut2(a_buf, a_R, a_comps);
00488 }
00489 template <class T> inline void* BaseFab<T>::linearOut2(void* a_buf,
00490 const Box& a_R,
00491 const Interval& a_comps) const
00492 {
00493 T* buffer = (T*)a_buf;
00494
00495 ForAllThisCBNN(T,a_R,a_comps.begin(),a_comps.size())
00496 {
00497 *buffer = thisR;
00498 ++buffer;
00499 } EndFor;
00500 return (void*)buffer;
00501 }
00502
00503 template <class T> inline void BaseFab<T>::linearIn(void* a_buf,
00504 const Box& a_R,
00505 const Interval& a_comps)
00506 {
00507
00508 linearIn2(a_buf, a_R, a_comps);
00509 }
00510
00511 template <class T> inline void* BaseFab<T>::linearIn2(void* a_buf,
00512 const Box& a_R,
00513 const Interval& a_comps)
00514 {
00515 T* buffer = (T*)a_buf;
00516
00517 ForAllThisBNN(T,a_R,a_comps.begin(),a_comps.size())
00518 {
00519 thisR = *buffer;
00520 ++buffer;
00521 } EndFor;
00522
00523 return (void*) buffer;
00524 }
00525
00526 template <class T> inline void BaseFab<T>::define()
00527 {
00528 CH_assert(m_nvar > 0);
00529 CH_assert(m_dptr == 0);
00530
00531 CH_assert(!m_aliased);
00532
00533
00534 #ifdef CH_USE_MEMORY_TRACKING
00535 if (s_Arena == NULL)
00536 {
00537 s_Arena = new BArena(name().c_str());
00538 }
00539 #else
00540 if (s_Arena == NULL)
00541 {
00542 s_Arena = new BArena("");
00543 }
00544 #endif
00545
00546 if (s_Arena == NULL)
00547 {
00548 MayDay::Error("malloc in basefab failed");
00549 }
00550
00551 m_truesize = m_nvar * m_numpts;
00552 m_dptr = static_cast<T*>(s_Arena->alloc(m_truesize * sizeof(T)));
00553
00554 #ifdef CH_USE_MEMORY_TRACKING
00555 s_Arena->bytes += m_truesize * sizeof(T) + sizeof(BaseFab<T>);
00556 CH_assert(s_Arena->bytes > 0);
00557 if (s_Arena->bytes > s_Arena->peak)
00558 {
00559 s_Arena->peak = s_Arena->bytes;
00560 }
00561 #endif
00562
00563
00564
00565
00566 T* ptr = m_dptr;
00567
00568 for (long int i = 0; i < m_truesize; i++, ptr++)
00569 {
00570 new (ptr) T;
00571 }
00572 }
00573
00574 template <class T> inline void BaseFab<T>::undefine()
00575 {
00576
00577
00578
00579
00580 if (m_aliased)
00581 {
00582 m_dptr = 0;
00583 return;
00584 }
00585
00586 if (m_dptr == 0)
00587 {
00588 return;
00589 }
00590
00591 T* ptr = m_dptr;
00592
00593 for (long int i = 0; i < m_truesize; i++, ptr++)
00594 {
00595 ptr->~T();
00596 }
00597
00598 s_Arena->free(m_dptr);
00599
00600 #ifdef CH_USE_MEMORY_TRACKING
00601 s_Arena->bytes -= m_truesize * sizeof(T) + sizeof(BaseFab<T>);
00602 CH_assert(s_Arena->bytes >= 0);
00603 #endif
00604
00605 m_dptr = 0;
00606 }
00607
00608 template <class T> inline std::string BaseFab<T>::name()
00609 {
00610 std::string rtn = (typeid(T)).name();
00611
00612 return rtn;
00613 }
00614
00615 template <class T>
00616 inline void BaseFab<T>::performCopy(const BaseFab<T>& a_src,
00617 const Box& a_srcbox,
00618 int a_srccomp,
00619 const Box& a_destbox,
00620 int a_destcomp,
00621 int a_numcomp)
00622 {
00623 CH_assert(a_src.box().contains(a_srcbox));
00624 CH_assert(box().contains(a_destbox));
00625 CH_assert(a_destbox.sameSize(a_srcbox));
00626 CH_assert(a_srccomp >= 0 && a_srccomp + a_numcomp <= a_src.nComp());
00627 CH_assert(a_destcomp >= 0 && a_destcomp + a_numcomp <= nComp());
00628
00629 ForAllThisBNNXCBN(T, a_destbox, a_destcomp, a_numcomp, a_src, a_srcbox, a_srccomp)
00630 {
00631 thisR = a_srcR;
00632 } EndForTX
00633 }
00634
00635 template <class T> inline void BaseFab<T>::performSetVal(T a_x,
00636 const Box& a_bx,
00637 int a_nstart,
00638 int a_numcomp)
00639 {
00640 CH_assert(m_domain.contains(a_bx));
00641 CH_assert(a_nstart >= 0 && a_nstart + a_numcomp <= m_nvar);
00642
00643 if (a_bx == m_domain)
00644 {
00645 T* data = &m_dptr[a_nstart * m_numpts];
00646
00647 for (long i = 0, N = a_numcomp * m_numpts; i < N; i++)
00648 {
00649 *data++ = a_x;
00650 }
00651 }
00652 else
00653 {
00654 ForAllThisBNN(T,a_bx,a_nstart,a_numcomp)
00655 {
00656 thisR = a_x;
00657 } EndFor
00658 }
00659 }
00660
00661 template <class T>
00662 bool BaseFab<T>::isAliased() const
00663 {
00664 return m_aliased;
00665 }
00666
00667 template <class T> void
00668 BaseFab<T>::degenerate( BaseFab<T>& a_slice,
00669 const SliceSpec& a_sliceSpec ) const
00670 {
00671 bool outofbounds;
00672 Box degenerateBox;
00673 this->box().degenerate( degenerateBox, a_sliceSpec, &outofbounds );
00674 if ( outofbounds )
00675 {
00676 MayDay::Error( "Tried to slice out-of-bounds." );
00677 }
00678 a_slice.define( degenerateBox, this->nComp() );
00679 a_slice.copy( *this, degenerateBox );
00680 }
00681
00682
00683 #include "NamespaceFooter.H"
00684 #endif