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