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