Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

BaseFabImplem.H

Go to the documentation of this file.
00001 /*   _______              __
00002     / ___/ /  ___  __ _  / /  ___
00003    / /__/ _ \/ _ \/  V \/ _ \/ _ \
00004    \___/_//_/\___/_/_/_/_.__/\___/
00005 */
00006 // CHOMBO Copyright (c) 2000-2004, The Regents of the University of
00007 // California, through Lawrence Berkeley National Laboratory (subject to
00008 // receipt of any required approvals from U.S. Dept. of Energy).  All
00009 // rights reserved.
00010 //
00011 // Redistribution and use in source and binary forms, with or without
00012 // modification, are permitted provided that the following conditions are met:
00013 //
00014 // (1) Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 // (2) Redistributions in binary form must reproduce the above copyright
00017 // notice, this list of conditions and the following disclaimer in the
00018 // documentation and/or other materials provided with the distribution.
00019 // (3) Neither the name of Lawrence Berkeley National Laboratory, U.S.
00020 // Dept. of Energy nor the names of its contributors may be used to endorse
00021 // or promote products derived from this software without specific prior
00022 // written permission.
00023 //
00024 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
00026 // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
00027 // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
00028 // OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00029 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00030 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00031 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00032 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00033 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00034 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00035 //
00036 // You are under no obligation whatsoever to provide any bug fixes,
00037 // patches, or upgrades to the features, functionality or performance of
00038 // the source code ("Enhancements") to anyone; however, if you choose to
00039 // make your Enhancements available either publicly, or directly to
00040 // Lawrence Berkeley National Laboratory, without imposing a separate
00041 // written license agreement for such Enhancements, then you hereby grant
00042 // the following license: a non-exclusive, royalty-free perpetual license
00043 // to install, use, modify, prepare derivative works, incorporate into
00044 // other computer software, distribute, and sublicense such Enhancements or
00045 // derivative works thereof, in binary and source code form.
00046 //
00047 // TRADEMARKS. Product and company names mentioned herein may be the
00048 // trademarks of their respective owners.  Any rights not expressly granted
00049 // herein are reserved.
00050 //
00051 
00052 #ifndef _BASEFABIMPLEM_H_
00053 #define _BASEFABIMPLEM_H_
00054 
00055 #include "BaseFabMacros.H"
00056 
00057 #include "MayDay.H"
00058 
00059 //
00060 // BaseFab<Real> spaecializations
00061 //
00062 
00063 template < > void BaseFab<Real>::define();
00064 
00065 template < > void BaseFab<Real>::undefine();
00066 
00067 template < > void BaseFab<Real>::setVal (Real val);
00068 
00069 template < > void BaseFab<int>::define();
00070 
00071 template < > void BaseFab<int>::undefine();
00072 
00073 //
00074 // Implementation.=====================================
00075 //
00076 
00077 template <class T> inline BaseFab<T>::BaseFab()
00078   :
00079   m_domain(Box()),
00080   m_nvar(0),
00081   m_numpts(0),
00082   m_truesize(0),
00083   m_dptr(0),
00084   m_aliased(false)
00085 {}
00086 
00087 template <class T> inline BaseFab<T>::BaseFab(const Box& a_bx,
00088                                               int        a_n,
00089                                               T*         a_alias)
00090   :
00091   m_domain(a_bx),
00092   m_nvar(a_n),
00093   m_numpts(a_bx.numPts()),
00094   m_dptr(0),
00095   m_aliased(false)
00096 {
00097   if (a_alias != NULL)
00098   {
00099     m_dptr    = a_alias;
00100     m_aliased = true;
00101   }
00102   else
00103   {
00104     define();
00105   }
00106 }
00107 
00108 template <class T> inline BaseFab<T>::BaseFab(const Interval& a_comps,
00109                                               BaseFab<T>&     a_original)
00110   :
00111   m_domain(a_original.m_domain),
00112   m_nvar(a_comps.size()),
00113   m_numpts(a_original.m_numpts),
00114   m_truesize(a_original.m_numpts * m_nvar),
00115   m_dptr(a_original.dataPtr(a_comps.begin())),
00116   m_aliased(true)
00117 {}
00118 
00119 template <class T> inline BaseFab<T>::~BaseFab()
00120 {
00121   undefine();
00122 }
00123 
00124 template <class T> void BaseFab<T>::resize(const Box& a_b,
00125                                            int        a_n,
00126                                            T*         a_alias)
00127 {
00128   // m_nvar   = a_n;
00129   // m_domain = a_b;
00130   // m_numpts = m_domain.numPts();
00131   //
00132   // if (m_dptr == 0)
00133   // {
00134   //   define();
00135   // }
00136   // else if (m_nvar*m_numpts > m_truesize)
00137   // {
00138   //   undefine();
00139   //   define();
00140   // }
00141 
00142   undefine();
00143 
00144   m_nvar   = a_n;
00145   m_domain = a_b;
00146   m_numpts = m_domain.numPts();
00147 
00148   if (a_alias != NULL)
00149   {
00150     m_dptr    = a_alias;
00151     m_aliased = true;
00152   }
00153   else
00154   {
00155     m_aliased = false;
00156     define();
00157   }
00158 }
00159 
00160 template <class T> inline void BaseFab<T>::define(const Interval& a_comps,
00161                                                   BaseFab<T>&     a_original)
00162 {
00163   undefine();
00164 
00165   m_domain   = a_original.m_domain;
00166   m_numpts   = a_original.m_numpts;
00167   m_truesize = a_original.m_numpts*a_comps.size();
00168   m_nvar     = a_comps.size();
00169   m_dptr     = a_original.dataPtr(a_comps.begin());
00170   m_aliased  = true;
00171 
00172   // resize(a_original.m_domain, a_comps.size(),
00173   //        a_original.dataPtr(a_comps.begin()));
00174 }
00175 
00176 template <class T> inline void BaseFab<T>::clear()
00177 {
00178   undefine();
00179 
00180   m_domain = Box();
00181   m_nvar   = 0;
00182   m_numpts = 0;
00183 }
00184 
00185 template <class T> inline int BaseFab<T>::nComp() const
00186 {
00187   return m_nvar;
00188 }
00189 
00190 template <class T> Arena* BaseFab<T>::s_Arena = NULL;
00191 
00192 template <class T> inline const Box& BaseFab<T>::box() const
00193 {
00194   return m_domain;
00195 }
00196 
00197 template <class T> inline const int* BaseFab<T>::size() const
00198 {
00199   return m_domain.size().getVect();
00200 }
00201 
00202 template <class T> inline const IntVect& BaseFab<T>::smallEnd() const
00203 {
00204   return m_domain.smallEnd();
00205 }
00206 
00207 template <class T> inline const IntVect& BaseFab<T>::bigEnd() const
00208 {
00209   return m_domain.bigEnd();
00210 }
00211 
00212 template <class T> inline T& BaseFab<T>::operator () (const IntVect& a_p,
00213                                                       int            a_n)
00214 {
00215  CH_assert(a_n >= 0);
00216  CH_assert(a_n < m_nvar);
00217  CH_assert(!(m_dptr == 0));
00218  CH_assert(m_domain.contains(a_p));
00219 
00220   return m_dptr[m_domain.index(a_p) + a_n * m_numpts];
00221 }
00222 
00223 template <class T> inline T& BaseFab<T>::operator () (const IntVect& a_p)
00224 {
00225  CH_assert(!(m_dptr == 0));
00226  CH_assert(m_domain.contains(a_p));
00227 
00228   return m_dptr[m_domain.index(a_p)];
00229 }
00230 
00231 template <class T> inline const T& BaseFab<T>::operator () (const IntVect& a_p,
00232                                                             int            a_n) const
00233 {
00234  CH_assert(a_n >= 0);
00235  CH_assert(a_n < m_nvar);
00236  CH_assert(!(m_dptr == 0));
00237  CH_assert(m_domain.contains(a_p));
00238 
00239   return m_dptr[m_domain.index(a_p) + a_n * m_numpts];
00240 }
00241 
00242 template <class T> inline const T& BaseFab<T>::operator () (const IntVect& a_p) const
00243 {
00244  CH_assert(!(m_dptr == 0));
00245  CH_assert(m_domain.contains(a_p));
00246 
00247   return m_dptr[m_domain.index(a_p)];
00248 }
00249 
00250 template <class T> inline void BaseFab<T>::getVal(T*             a_data,
00251                                                   const IntVect& a_pos,
00252                                                   int            a_n,
00253                                                   int            a_numcomp) const
00254 {
00255   const int  loc     = m_domain.index(a_pos);
00256   const long size    = m_domain.numPts();
00257 
00258  CH_assert(!(m_dptr == 0));
00259  CH_assert(a_n >= 0 && a_n + a_numcomp <= m_nvar);
00260 
00261   for (int k = 0; k < a_numcomp; k++)
00262   {
00263     a_data[k] = m_dptr[loc+(a_n+k)*size];
00264   }
00265 }
00266 
00267 template <class T> inline void BaseFab<T>::getVal(T*             a_data,
00268                                                   const IntVect& a_pos) const
00269 {
00270   getVal(a_data,a_pos,0,m_nvar);
00271 }
00272 
00273 template <class T> inline const int* BaseFab<T>::loVect() const
00274 {
00275   return m_domain.loVect();
00276 }
00277 
00278 template <class T> inline const int* BaseFab<T>::hiVect() const
00279 {
00280   return m_domain.hiVect();
00281 }
00282 
00283 template <class T> inline const int* BaseFab<T>::nCompPtr() const
00284 {
00285  CH_assert(!(m_dptr == 0));
00286 
00287   return &m_nvar;
00288 }
00289 
00290 template <class T> inline T* BaseFab<T>::dataPtr(int a_n)
00291 {
00292  CH_assert(!(m_dptr == 0));
00293  CH_assert((a_n >= 0) && (a_n < m_nvar));
00294 
00295   return &m_dptr[a_n * m_numpts];
00296 }
00297 
00298 template <class T> inline const T* BaseFab<T>::dataPtr(int a_n) const
00299 {
00300  CH_assert(!(m_dptr == 0));
00301  CH_assert((a_n >= 0) && (a_n < m_nvar));
00302 
00303   return &m_dptr[a_n * m_numpts];
00304 }
00305 
00306 template <class T> inline bool BaseFab<T>::contains(const BaseFab<T>& a_fab) const
00307 {
00308   return box().contains(a_fab.box()) && m_nvar <= a_fab.m_nvar;
00309 }
00310 
00311 template <class T> inline bool BaseFab<T>::contains (const Box& a_bx) const
00312 {
00313   return box().contains(a_bx);
00314 }
00315 
00316 template <class T> inline void BaseFab<T>::setVal(T          a_x,
00317                                                   const Box& a_bx,
00318                                                   int        a_nstart,
00319                                                   int        a_numcomp)
00320 {
00321   performSetVal(a_x,a_bx,a_nstart,a_numcomp);
00322 }
00323 
00324 template <class T> inline void BaseFab<T>::setVal(T          a_x,
00325                                                   const Box& a_bx,
00326                                                   int        a_n)
00327 {
00328   performSetVal(a_x,a_bx,a_n,1);
00329 }
00330 
00331 template <class T> inline void BaseFab<T>::setVal(T   a_x,
00332                                                   int a_n)
00333 {
00334   performSetVal(a_x,m_domain,a_n,1);
00335 }
00336 
00337 template <class T> inline void BaseFab<T>::setVal(T a_x)
00338 {
00339   performSetVal(a_x,box(),0,m_nvar);
00340 }
00341 
00342 template <class T>
00343 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src,
00344                                     const Box&        a_srcbox,
00345                                     int               a_srccomp,
00346                                     const Box&        a_destbox,
00347                                     int               a_destcomp,
00348                                     int               a_numcomp)
00349 {
00350  CH_assert(a_srcbox.sameSize(a_destbox));
00351  CH_assert(a_src.box().contains(a_srcbox));
00352  CH_assert(m_domain.contains(a_destbox));
00353  CH_assert(a_srccomp >= 0 && a_srccomp+a_numcomp <= a_src.nComp());
00354  CH_assert(a_destcomp >= 0 && a_destcomp+a_numcomp <= m_nvar);
00355 
00356   performCopy(a_src,a_srcbox,a_srccomp,a_destbox,a_destcomp,a_numcomp);
00357 
00358   return *this;
00359 }
00360 
00361 template <class T>
00362 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src,
00363                                     int               a_srccomp,
00364                                     int               a_destcomp,
00365                                     int               a_numcomp)
00366 {
00367  CH_assert(a_srccomp  >= 0 && a_srccomp  + a_numcomp <= a_src.m_nvar);
00368  CH_assert(a_destcomp >= 0 && a_destcomp + a_numcomp <= m_nvar);
00369 
00370   Box overlap(m_domain);
00371   overlap &= a_src.m_domain;
00372 
00373   if (!overlap.isEmpty())
00374   {
00375     performCopy(a_src,overlap,a_srccomp,overlap,a_destcomp,a_numcomp);
00376   }
00377 
00378   return *this;
00379 }
00380 
00381 template <class T>
00382 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src,
00383                                     const Box&        a_destbox)
00384 {
00385  CH_assert(m_nvar <= a_src.m_nvar);
00386  CH_assert(m_domain.contains(a_destbox));
00387 
00388   Box overlap(a_destbox);
00389   overlap &= a_src.m_domain;
00390 
00391   if (!overlap.isEmpty())
00392   {
00393     performCopy(a_src,overlap,0,overlap,0,m_nvar);
00394   }
00395 
00396   return *this;
00397 }
00398 
00399 template <class T>
00400 inline BaseFab<T>& BaseFab<T>::copy(const BaseFab<T>& a_src)
00401 {
00402  CH_assert(m_nvar <= a_src.m_nvar);
00403  CH_assert(m_domain.sameType(a_src.m_domain));
00404 
00405   Box overlap(m_domain);
00406   overlap &= a_src.m_domain;
00407 
00408   if (!overlap.isEmpty())
00409   {
00410     performCopy(a_src,overlap,0,overlap,0,m_nvar);
00411   }
00412 
00413   return *this;
00414 }
00415 
00416 template <class T> inline void BaseFab<T>::copy(const Box&        a_RegionFrom,
00417                                                 const Interval&   a_Cdest,
00418                                                 const Box&        a_RegionTo,
00419                                                 const BaseFab<T>& a_src,
00420                                                 const Interval&   a_Csrc)
00421 {
00422   if ((this == &a_src) && (a_RegionFrom == a_RegionTo))
00423   {
00424     return;
00425   }
00426 
00427  CH_assert(a_Cdest.size() == a_Csrc.size());
00428 
00429   copy(a_src, a_RegionFrom, a_Csrc.begin(), a_RegionTo,
00430        a_Cdest.begin(), a_Cdest.size());
00431 }
00432 
00433 template <class T> inline BaseFab<T>& BaseFab<T>::shift(const IntVect& a_v)
00434 {
00435   m_domain += a_v;
00436 
00437   return *this;
00438 }
00439 
00440 template <class T> inline BaseFab<T>& BaseFab<T>::shift(int a_idir,
00441                                                         int a_ncells)
00442 {
00443   m_domain.shift(a_idir,a_ncells);
00444 
00445   return *this;
00446 }
00447 
00448 template <class T> inline BaseFab<T> & BaseFab<T>::shiftHalf(int a_idir,
00449                                                              int a_numHalfs)
00450 {
00451   m_domain.shiftHalf(a_idir,a_numHalfs);
00452 
00453   return *this;
00454 }
00455 
00456 template <class T> inline BaseFab<T> & BaseFab<T>::shiftHalf(const IntVect& a_v)
00457 {
00458   m_domain.shiftHalf(a_v);
00459 
00460   return *this;
00461 }
00462 
00463 template <class T> inline int BaseFab<T>::size(const Box&      a_box,
00464                                                const Interval& a_comps) const
00465 {
00466   return a_box.numPts() * sizeof(T) * a_comps.size();
00467 }
00468 
00469 template <class T> inline void BaseFab<T>::linearOut(void*           a_buf,
00470                                                      const Box&      a_R,
00471                                                      const Interval& a_comps) const
00472 {
00473   T* buffer = (T*)a_buf;
00474 
00475   ForAllThisBNN(T,a_R,a_comps.begin(),a_comps.size())
00476   {
00477     *buffer = thisR;
00478     ++buffer;
00479   } EndFor;
00480 }
00481 
00482 template <class T> inline void BaseFab<T>::linearIn(void*           a_buf,
00483                                                     const Box&      a_R,
00484                                                     const Interval& a_comps)
00485 {
00486   T* buffer = (T*)a_buf;
00487 
00488   ForAllThisBNN(T,a_R,a_comps.begin(),a_comps.size())
00489   {
00490     thisR = *buffer;
00491     ++buffer;
00492   } EndFor;
00493 }
00494 
00495 template <class T> inline void BaseFab<T>::define()
00496 {
00497  CH_assert(m_nvar > 0);
00498  CH_assert(m_dptr == 0);
00499  CH_assert(m_numpts > 0);
00500  CH_assert(!m_aliased);
00501   //CH_assert(!(The_FAB_Arena == 0));// not a sufficient test !!!
00502 
00503 #ifdef CH_USE_MEMORY_TRACKING
00504   if (s_Arena == NULL)
00505   {
00506     s_Arena = new BArena(name().c_str());
00507   }
00508 #else
00509   if (s_Arena == NULL)
00510   {
00511     s_Arena = new BArena("");
00512   }
00513 #endif
00514 
00515   if (s_Arena == NULL)
00516   {
00517     MayDay::Error("malloc in basefab failed");
00518   }
00519 
00520   m_truesize = m_nvar * m_numpts;
00521   m_dptr     = static_cast<T*>(s_Arena->alloc(m_truesize * sizeof(T)));
00522 
00523 #ifdef CH_USE_MEMORY_TRACKING
00524   s_Arena->bytes += m_truesize * sizeof(T) + sizeof(BaseFab<T>);
00525   if (s_Arena->bytes > s_Arena->peak)
00526   {
00527     s_Arena->peak = s_Arena->bytes;
00528   }
00529 #endif
00530 
00531   //
00532   // Now call T::T() on the raw memo'ry so we have valid Ts.
00533   //
00534   T* ptr = m_dptr;
00535 
00536   for (int i = 0; i < m_truesize; i++, ptr++)
00537   {
00538     new (ptr) T;
00539   }
00540 }
00541 
00542 template <class T> inline void BaseFab<T>::undefine()
00543 {
00544   //CH_assert(!(The_FAB_Arena == 0));
00545   //
00546   // Call T::~T() on the to-be-destroyed memory.
00547   //
00548   if (m_aliased)
00549   {
00550     m_dptr = 0;
00551     return;
00552   }
00553 
00554   if (m_dptr == 0)
00555   {
00556     return;
00557   }
00558 
00559   T* ptr = m_dptr;
00560 
00561   for (int i = 0; i < m_truesize; i++, ptr++)
00562   {
00563     ptr->~T();
00564   }
00565 
00566   s_Arena->free(m_dptr);
00567 
00568 #ifdef CH_USE_MEMORY_TRACKING
00569   s_Arena->bytes -= m_truesize * sizeof(T) + sizeof(BaseFab<T>);
00570 #endif
00571 
00572   m_dptr = 0;
00573 }
00574 
00575 template <class T> inline std::string BaseFab<T>::name()
00576 {
00577   std::string rtn = (typeid(T)).name();
00578 
00579   return rtn;
00580 }
00581 
00582 template <class T>
00583 inline void BaseFab<T>::performCopy(const BaseFab<T>& a_src,
00584                                     const Box&        a_srcbox,
00585                                     int               a_srccomp,
00586                                     const Box&        a_destbox,
00587                                     int               a_destcomp,
00588                                     int               a_numcomp)
00589 {
00590  CH_assert(a_src.box().contains(a_srcbox));
00591  CH_assert(box().contains(a_destbox));
00592  CH_assert(a_destbox.sameSize(a_srcbox));
00593  CH_assert(a_srccomp  >= 0 && a_srccomp  + a_numcomp <= a_src.nComp());
00594  CH_assert(a_destcomp >= 0 && a_destcomp + a_numcomp <= nComp());
00595 
00596   ForAllThisBNNXCBN(T, a_destbox, a_destcomp, a_numcomp, a_src, a_srcbox, a_srccomp)
00597   {
00598     thisR = a_srcR;
00599   } EndForTX
00600 }
00601 
00602 template <class T> inline void BaseFab<T>::performSetVal(T          a_x,
00603                                                          const Box& a_bx,
00604                                                          int        a_nstart,
00605                                                          int        a_numcomp)
00606 {
00607  CH_assert(m_domain.contains(a_bx));
00608  CH_assert(a_nstart >= 0 && a_nstart + a_numcomp <= m_nvar);
00609 
00610   if (a_bx == m_domain)
00611   {
00612     T* data = &m_dptr[a_nstart * m_numpts];
00613 
00614     for (long i = 0, N = a_numcomp * m_numpts; i < N; i++)
00615     {
00616       *data++ = a_x;
00617     }
00618   }
00619   else
00620     {
00621       ForAllThisBNN(T,a_bx,a_nstart,a_numcomp)
00622       {
00623         thisR = a_x;
00624       } EndFor
00625     }
00626 }
00627 
00628 #endif

Generated on Wed Oct 5 13:52:08 2005 for Chombo&AMRSelfGravity by  doxygen 1.4.1