Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Compound Members | File Members

BinFabImplem.H

Go to the documentation of this file.
00001 /*   _______              __
00002     / ___/ /  ___  __ _  / /  ___
00003    / /__/ _ \/ _ \/  ' \/ _ \/ _ \
00004    \___/_//_/\___/_/_/_/_.__/\___/
00005 */
00006 //
00007 // This software is copyright (C) by the Lawrence Berkeley
00008 // National Laboratory.  Permission is granted to reproduce
00009 // this software for non-commercial purposes provided that
00010 // this notice is left intact.
00011 //
00012 // It is acknowledged that the U.S. Government has rights to
00013 // this software under Contract DE-AC03-765F00098 between
00014 // the U.S.  Department of Energy and the University of
00015 // California.
00016 //
00017 // This software is provided as a professional and academic
00018 // contribution for joint exchange. Thus it is experimental,
00019 // is provided ``as is'', with no warranties of any kind
00020 // whatsoever, no support, no promise of updates, or printed
00021 // documentation. By using this software, you acknowledge
00022 // that the Lawrence Berkeley National Laboratory and
00023 // Regents of the University of California shall have no
00024 // liability with respect to the infringement of other
00025 // copyrights by any part of this software.
00026 //
00027 
00028 #ifndef _BINFABIMPLEM_H_
00029 #define _BINFABIMPLEM_H_
00030 
00031 #include "BoxIterator.H"
00032 #include "List.H"
00033 
00034 //
00035 // Implementation.=====================================
00036 //
00037 
00038 template <class T>
00039 BinFab<T>::BinFab()
00040   : BaseFab<List<T> >(),
00041     m_origin(D_DECL(1.0e8, 1.0e8, 1.0e8)),
00042     m_mesh_spacing(D_DECL(0,0,0))
00043 {
00044 }
00045 
00046 template <class T>
00047 BinFab<T>::BinFab(const Box&           a_domain,
00048                   const RealVect&      a_mesh_spacing,
00049                   const RealVect&      a_origin,
00050                   const ProblemDomain& a_probdomain)
00051 {
00052   define(a_domain, a_mesh_spacing, a_origin, a_probdomain);
00053 }
00054 
00055 template <class T>
00056 BinFab<T>::BinFab(const BinFab& a_binfab)
00057 {
00058   define(a_binfab.domain, a_binfab.m_mesh_spacing, a_binfab.m_origin,
00059          a_binfab.m_probdomain);
00060 
00061   copy(a_binfab);
00062 }
00063 
00064 template <class T>
00065 BinFab<T>::~BinFab()
00066 {
00067   this->undefine();
00068 }
00069 
00070 template <class T>
00071 void BinFab<T>::define(const Box&           a_domain,
00072                        const RealVect&      a_mesh_spacing,
00073                        const RealVect&      a_origin,
00074                        const ProblemDomain& a_probdomain)
00075 {
00076   this->domain = a_domain;
00077   this->nvar = 1;
00078   this->numpts = this->domain.numPts();
00079 
00080   BaseFab<List<T> >::define();
00081 
00082   m_mesh_spacing = a_mesh_spacing;
00083   m_origin = a_origin;
00084   m_probdomain = a_probdomain;
00085 }
00086 
00087 template <class T>
00088 void BinFab<T>::reBin()
00089 {
00090   // loop through each bin and determine if each binItem is
00091   // in the correct bin.
00092   BoxIterator bit(this->domain);
00093   int comp = 0;
00094 
00095   for (bit.begin(); bit.ok(); ++bit)
00096     {
00097       const IntVect thisIV = bit();
00098       List<T>& thisList = this->operator()(thisIV,comp);
00099 
00100       if (thisList.length() > 0)
00101         {
00102           // now index through the List and figure out which bin this
00103           // particle should be in
00104           ListIterator<T> thisLit(thisList);
00105           IntVect binLoc;
00106 
00107           for (thisLit.rewind(); thisLit; ++thisLit)
00108             {
00109               T& thisItem = thisList[thisLit];
00110               binLoc = locateBin(thisItem);
00111 
00112               if (binLoc != thisIV)
00113                 {
00114                   // binItem needs to be moved.
00115                   // note that if binItem moves outside of domain, it is lost
00116                   if (this->domain.contains(binLoc))
00117                     this->operator()(binLoc,comp).append(thisItem);
00118 #ifndef NDEBUG
00119                   else
00120                     cerr << "warning: BinFab::reBin() lost an item at " << binLoc << endl;
00121 #endif
00122                   thisList.remove(thisLit);
00123                 }
00124             } // end loop over items in this List of binItems
00125         } // end if this list has items
00126     } // end loop over bins
00127 }
00128 
00130 template <class T>
00131 void BinFab<T>::addItem(const T& a_item)
00132 {
00133     int comp = 0;
00134     IntVect binLoc = locateBin(a_item);
00135 
00136     if (this->domain.contains(binLoc))
00137       {
00138         this->operator()(binLoc,comp).append(a_item);
00139       }
00140 }
00141 
00143 template <class T>
00144 void
00145 BinFab<T>::addItems(const List<T>& a_List)
00146 {
00147   if (a_List.length() > 0)
00148     {
00149       // loop through items in List, and add to appropriate locations
00150       ListIterator<T> lit(a_List);
00151       int comp = 0;
00152       IntVect binLoc;
00153 
00154       for (lit.rewind(); lit; ++lit)
00155         {
00156           const T& thisItem =  a_List[lit];
00157           binLoc = locateBin(thisItem);
00158 
00159           if (this->domain.contains(binLoc))
00160           {
00161             this->operator()(binLoc,comp).append(thisItem);
00162           }
00163         }
00164     }
00165 }
00166 
00168 //  [NOTE: this is mostly the same as the previous version, except for the inner loop]
00169 template <class T>
00170 void
00171 BinFab<T>::addItemsDestructive(List<T>& a_List)
00172 {
00173  if (a_List.length() > 0)
00174     {
00175       // loop through items in List, add to appropriate bins,
00176       // and remove from List
00177       ListIterator<T> lit(a_List);
00178       int comp = 0;
00179       IntVect binLoc;
00180 
00181       for (lit.rewind(); lit; )
00182         {
00183           const T& thisItem =  a_List[lit];
00184           binLoc = locateBin(thisItem);
00185 
00186           if (this->domain.contains(binLoc))  //[NOTE: BaseFab domain, not problem domain]
00187             {
00188               this->operator()(binLoc,comp).append(thisItem);
00189               a_List.remove(lit);
00190             }
00191           else
00192             {
00193               // removing a list element has the side-effect of moving the
00194               // iterator forward, so only increment explicitly if not removed
00195               ++lit;
00196             }
00197         }
00198     }
00199 }
00200 
00202 
00205 //  [NOTE: this is mostly the same as the previous version, except for the inner loop]
00206 template <class T>
00207 void
00208 BinFab<T>::addItemsDestructive(List<T>& a_List ,const Box& a_valid ,bool a_in)
00209 {
00210   assert( a_valid.cellCentered() );
00211   if (a_List.length() > 0) 
00212     {
00213       // loop through items in List, add to appropriate bins, 
00214       // and remove from List
00215       ListIterator<T> lit(a_List);
00216       int comp = 0;
00217       IntVect binLoc;
00218 
00219       for (lit.rewind(); lit; )
00220         {
00221           const T& thisItem =  a_List[lit];
00222           binLoc = locateBin(thisItem);
00223           if (this->domain.contains(binLoc))  //[NOTE: BaseFab domain, not problem domain]
00224             {
00225               this->operator()(binLoc,comp).append(thisItem);
00226               // If the a_in flag is true, then delete the particle from the
00227               // List if it is in the valid Box; if the a_in flag is false,
00228               // delete the particle if it is NOT in the Box.
00229               // Removing a list element has the side-effect of moving the
00230               // iterator forward, so explicitly increment the iterator only
00231               // if the particle was not removed.
00232               if( a_valid.contains(binLoc) )
00233                 {
00234                   if( a_in ) a_List.remove(lit);
00235                   else     ++lit ;
00236                 }
00237               else
00238                 {
00239                   if( a_in ) ++lit;
00240                   else     a_List.remove(lit);
00241                 }
00242             }
00243           else
00244             {
00245               // not added or removed, so increment the iterator
00246               ++lit;
00247             }
00248         }
00249     }  
00250 }
00251 
00252 template <class T>
00253 void BinFab<T>::clear()
00254 {
00255   this->undefine();
00256 
00257   this->domain = Box();
00258   this->nvar = 0;
00259   this->numpts = 0;
00260   m_origin = RealVect(D_DECL(1.0e8, 1.0e8, 1.0e8));
00261   m_mesh_spacing = RealVect(D_DECL(1.0e8, 1.0e8, 1.0e8));
00262 }
00263 
00264 template <class T>
00265 int BinFab<T>::numItems(const Box& a_box, const Interval& a_comps) const
00266 {
00267   int totalSize = 0;
00268 
00269   // default is an empty box, so use this BinFab's box instead
00270   // [NOTE: this leaves the caller no way to ask for an empty box;
00271   //       it must avoid calling this routine in that case. Sorry.]
00272   Box ibox = a_box;
00273   if (ibox.isEmpty())
00274     {
00275       ibox = this->box();
00276     }
00277 
00278   // default is an empty interval, so use all comps
00279   //[NOTE: see above NOTE]
00280   Interval comps = a_comps;
00281   if (comps.size() == 0)
00282     {
00283       comps = this->interval();
00284     }
00285 
00286   // iterate over all bins and components in the BinFab
00287   // [NOTE: making the "c" loop be inner would have better cache
00288   //       efficiency for large #s of comps, but would take more
00289   //       instructions and that will dominate for small ncomps.
00290   for (int c = comps.begin(); c <= comps.end(); ++c)
00291     {
00292       for (BoxIterator bi(ibox); bi.ok(); ++bi)
00293         {
00294           totalSize += this->operator()(bi(),c).length();
00295         }
00296     }
00297 
00298   return totalSize;
00299 }
00300 
00301 template <class T>
00302 int
00303 BinFab<T>::size(const Box& box, const Interval& comps) const
00304 {
00305   int totalSize = 0;
00306 
00307   // First extract the size of the binItem.
00308   // Assumes all the items are the same size.
00309   int sizeOfT ;
00310   {
00311     T tmp ;
00312     sizeOfT = tmp.size() ;
00313   }
00314 
00315   // Count the number of items in the fab
00316   BoxIterator bit(box);
00317   for (int comp=comps.begin(); comp<=comps.end(); ++comp)
00318     {
00319       for (bit.begin(); bit.ok(); ++bit)
00320         {
00321           const List<T>& thisList = this->operator()(bit(), comp);
00322           totalSize += thisList.length();
00323         }
00324     }
00325 
00326   // totalSize now has total number of binItems.  now compute total size
00327   totalSize *= sizeOfT;
00328 
00329   // will also need to add an integer for each list to determine how
00330   // many binItems are in each list. (is this the right thing to do?)
00331   // alternate approach would be to simply unpack a List<T> on the other
00332   // end and then do an addItems call with that list.  that will probably
00333   // be slower, though.
00334   int numBins = box.numPts() * comps.size();
00335   totalSize += numBins * sizeof(int);
00336 
00337   return totalSize;
00338 }
00339 
00340 template <class T>
00341 void BinFab<T>::linearOut(void* buf, const Box& R, const Interval& comps) const
00342 {
00343   char* buf_ch = (char*)buf;
00344   // all we do in this function is loop over the box (and components),
00345   // and call linearOut on the individual items...
00346   BoxIterator bit(R);
00347   for (int comp=comps.begin(); comp<= comps.end(); ++comp)
00348     {
00349       for (bit.begin(); bit.ok(); ++bit)
00350         {
00351           const List<T>& thisList = this->operator()(bit(), comp);
00352           int *intBuffer = (int*)buf_ch;
00353 
00354           *intBuffer = thisList.length();
00355           buf_ch += sizeof(int);
00356 
00357           // now loop over the items in the list.
00358           ListIterator<T> lit(thisList);
00359           for (lit.rewind(); lit; ++lit)
00360             {
00361               thisList[lit].linearOut(buf_ch);
00362               buf_ch += thisList[lit].size();
00363             }
00364         }
00365     }
00366 }
00367 
00368 template <class T>
00369 void BinFab<T>::linearIn(void* buf, const Box& R, const Interval& comps)
00370 {
00371   // should be just the inverse of linearOut
00372   char *buf_ch = (char*)buf;
00373 
00374   BoxIterator bit(R);
00375   for (int comp = comps.begin(); comp <= comps.end(); ++comp)
00376     {
00377       for (bit.begin(); bit.ok(); ++bit)
00378         {
00379           List<T>& thisList = this->operator()(bit(), comp);
00380           int numItems = *((int*)buf_ch);
00381 
00382           buf_ch += sizeof(int);
00383 
00384           if (numItems > 100000)
00385             {
00386               cout << " [error: numItems=" << numItems << "] ";
00387               numItems = 1;
00388             }
00389 
00390           for (int n = 0; n < numItems; ++n)
00391             {
00392               T thisBinItem;
00393 
00394               thisBinItem.linearIn( buf_ch );
00395               thisList.append(thisBinItem);
00396               buf_ch += thisBinItem.size();
00397             }
00398         }
00399     }
00400 }
00401 
00402 template <class T>
00403 IntVect BinFab<T>::locateBin(const T& a_binItem) const
00404 {
00405   IntVect binLoc;
00406   RealVect thisPos = a_binItem.position();
00407 
00408   thisPos -= m_origin;
00409   thisPos /= m_mesh_spacing;
00410 
00411   for (int d=0; d<SpaceDim; ++d)
00412     {
00413       // handle periodic domain
00414       if (m_probdomain.isPeriodic(d))
00415         {
00416           binLoc[d] = (int) thisPos[d] % m_probdomain.domainBox().size(d);
00417         }
00418       else
00419         {
00420           binLoc[d] = (int) thisPos[d];
00421           // need to shift by one if negative
00422           if (thisPos[d] < 0) --binLoc[d];
00423         }
00424     }
00425 
00426   return binLoc;
00427 }
00428 
00429 #endif

Generated on Wed Jun 2 13:53:32 2004 for Chombo&INSwithParticles by doxygen 1.3.2