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 CH_BINFABIMPLEM_H
00029 #define CH_BINFABIMPLEM_H
00030 
00031 #include "BoxIterator.H"
00032 #include "List.H"
00033 
00034 
00035 //
00036 // Implementation.=====================================
00037 //
00038 
00039 template <class T>
00040 BinFab<T>::BinFab()
00041   : BaseFab<List<T> >(),
00042   m_origin(D_DECL(1.0e8, 1.0e8, 1.0e8)),
00043   m_mesh_spacing(D_DECL(0,0,0))
00044 {
00045 }
00046 
00047 template <class T>
00048 BinFab<T>::BinFab(const Box& a_domain, 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   copy(a_binfab);
00061 }
00062 
00063 
00064 template <class T>
00065 BinFab<T>::~BinFab()
00066 {
00067   undefine();
00068 }
00069 
00070 template <class T>
00071 void
00072 BinFab<T>::define(const Box& a_domain, const RealVect& a_mesh_spacing,
00073                   const RealVect& a_origin, const ProblemDomain& a_probdomain)
00074 {
00075   domain = a_domain;
00076   nvar = 1;
00077   numpts = domain.numPts();
00078   
00079   BaseFab<List<T> >::define();
00080   
00081   m_mesh_spacing = a_mesh_spacing;
00082   m_origin = a_origin;
00083   m_probdomain = a_probdomain;
00084 }
00085 
00086 
00087 template <class T>
00088 void
00089 BinFab<T>::reBin()
00090 {
00091   // loop through each bin and determine if each binItem is 
00092   // in the correct bin.
00093   BoxIterator bit(domain);
00094   int comp = 0;
00095   
00096   for (bit.begin(); bit.ok(); ++bit) 
00097     {
00098       const IntVect thisIV = bit();      
00099       List<T>& thisList = operator()(thisIV,comp);
00100 
00101       if (thisList.length() > 0) 
00102         {
00103           // now index through the List and figure out which bin this
00104           // particle should be in
00105           ListIterator<T> thisLit(thisList);
00106           
00107           IntVect binLoc;
00108           //RealVect thisPos;
00109           
00110           for (thisLit.rewind(); thisLit; ++thisLit)
00111             {
00112               T& thisItem = thisList[thisLit];
00113 
00114 #if 0 
00115               // moved bin-location stuff into separate function
00116               thisPos = thisItem.position();
00117               thisPos -= m_origin;
00118               thisPos /= m_mesh_spacing;
00119               D_TERM( binLoc[0] = (int) thisPos[0]; ,
00120                       binLoc[1] = (int) thisPos[1]; ,
00121                       binLoc[2] = (int) thisPos[2]; );
00122 #endif
00123 
00124               binLoc = locateBin(thisItem);
00125               
00126               if (binLoc != thisIV) 
00127                 {
00128                   // binItem needs to be moved.
00129                   // note that if binItem moves outside of domain, it is lost
00130                   
00131                   if (domain.contains(binLoc)) 
00132                     operator()(binLoc,comp).append(thisItem);
00133                   
00134                   thisList.remove(thisLit);
00135                 }
00136             
00137               
00138             } // end loop over items in this List of binItems
00139         } // end if this list has items
00140       
00141     } // end loop over bins
00142 }
00143 
00144 template <class T>
00145 void
00146 BinFab<T>::addItem(const T& a_item)
00147 {
00148     int comp = 0 ;
00149     IntVect binLoc = locateBin(a_item) ;
00150     if (domain.contains(binLoc))
00151         operator()(binLoc,comp).append(a_item) ;
00152 }
00153 
00154 template <class T>
00155 void
00156 BinFab<T>::addItems(const List<T>& a_List)
00157 {
00158   // loop through items in List, and add to appropriate locations
00159   ListIterator<T> lit(a_List);
00160 
00161   int comp = 0;
00162   IntVect binLoc;
00163   //RealVect thisPos;
00164 
00165   if (a_List.length() > 0) 
00166     {
00167       for (lit.rewind(); lit; ++lit)
00168         {
00169 
00170           // want to put bin-location stuff in a separate function
00171           const T& thisItem =  a_List[lit];
00172 #if 0          
00173           // want to put bin-location stuff in a separate function
00174           thisPos = thisItem.position();
00175           thisPos -= m_origin;
00176           thisPos /= m_mesh_spacing;
00177           
00178           D_TERM( binLoc[0] = (int) thisPos[0]; ,
00179                   binLoc[1] = (int) thisPos[1]; ,
00180                   binLoc[2] = (int) thisPos[2]; );
00181 #endif
00182           binLoc = locateBin(thisItem);
00183           
00184           if (domain.contains(binLoc))
00185             operator()(binLoc,comp).append(thisItem);
00186         }
00187     }
00188 }
00189 
00190 template <class T>
00191 void
00192 BinFab<T>::addItemsDestructive(List<T>& a_List)
00193 {
00194   // loop through items in List, add to appropriate bins, 
00195   // and remove from List
00196   ListIterator<T> lit(a_List);
00197   int comp = 0;
00198   IntVect binLoc;
00199 
00200   if (a_List.length() > 0) 
00201     {
00202       for (lit.rewind(); lit; )
00203         {
00204           const T& thisItem =  a_List[lit];
00205           binLoc = locateBin(thisItem);
00206           if (domain.contains(binLoc))  //BaseFab domain, not problem domain
00207             {
00208               //cout << "Removing " << thisItem << " (binloc " << binLoc << ")" << endl ;
00209               operator()(binLoc,comp).append(thisItem);
00210               a_List.remove(lit);
00211             }
00212           else
00213             {
00214               // move the iterator only if we didn't delete the current element
00215               ++lit ;
00216             }
00217         }
00218     }
00219 }
00220 
00221 template <class T>
00222 void
00223 BinFab<T>::clear()
00224 {
00225   undefine();
00226   
00227   domain = Box();
00228   nvar = 0;
00229   numpts = 0;
00230   m_origin = RealVect(D_DECL(1.0e8, 1.0e8, 1.0e8));
00231   m_mesh_spacing = RealVect(D_DECL(1.0e8, 1.0e8, 1.0e8));
00232 
00233 }
00234 
00235 template <class T>
00236 int
00237 BinFab<T>::size(const Box& box, const Interval& comps) const
00238 {
00239   int totalSize=0;
00240   BoxIterator bit(box);
00241 
00242   // first extract the size of the binItem:
00243   bit.begin();
00244   const List<T>& thisList = operator()(bit(), comps.begin());
00245   int sizeOfT = thisList.firstElement().size();
00246 
00247   for (int comp=comps.begin(); comp<= comps.end(); comp++) 
00248     {
00249       for (bit.begin(); bit.ok(); ++bit) 
00250         {
00251           const List<T>& thisList = operator()(bit(), comp);
00252           totalSize += thisList.length();
00253         }
00254     }
00255 
00256   // totalSize now has total number of binItems.  now compute total size
00257   totalSize *= sizeOfT;
00258 
00259   // will also need to add an integer for each list to determine how 
00260   // many binItems are in each list. (is this the right thing to do?)
00261   // alternate approach would be to simply unpack a List<T> on the other
00262   // end and then do an addItems call with that list.  that will probably
00263   // be slower, though.
00264   int numBins = box.numPts();
00265   totalSize += numBins*sizeof(int);
00266 
00267   return totalSize;
00268 
00269 }
00270 
00271 template <class T> 
00272 void
00273 BinFab<T>::linearOut(void* buf, const Box& R, const Interval& comps) const
00274 {
00275   // all we do in this function is loop over the box (and components),
00276   // and call linearOut on the individual items...
00277   BoxIterator bit(R);
00278   for (int comp=comps.begin(); comp<= comps.end(); ++comp)
00279     {
00280       for (bit.begin(); bit.ok(); ++bit) 
00281         {
00282           const List<T>& thisList = operator()(bit(), comp);
00283           int* intBuffer = (int*)buf;
00284           *intBuffer = thisList.length();
00285 
00286           // now loop over the items in the list.
00287           ListIterator<T> lit(thisList);
00288           for (lit.rewind(); lit; ++lit)
00289             {
00290               thisList[lit].linearOut(buf);
00291             }
00292         }
00293     }
00294 }
00295 
00296 template <class T>
00297 void
00298 BinFab<T>::linearIn(void* buf, const Box& R, const Interval& comps)
00299 {
00300   // should be just the inverse of linearOut
00301   BoxIterator bit(R);
00302   for (int comp= comps.begin(); comp<= comps.end(); ++comp)
00303     {
00304       for (bit.begin(); bit.ok(); ++bit) 
00305         {
00306           List<T>& thisList = operator()(bit(), comp);
00307           int* intBuffer = (int*)buf;
00308           int numItems = *intBuffer;
00309           for (int n=0; n<numItems; ++n)
00310             {
00311               T thisBinItem;
00312               thisBinItem.linearIn(buf);
00313               thisList.append(thisBinItem);
00314             }
00315         }
00316     }
00317 
00318 }
00319 
00320 template <class T>
00321 IntVect
00322 BinFab<T>::locateBin(const T& a_binItem) const
00323 {
00324   IntVect binLoc;
00325   RealVect thisPos = a_binItem.position();
00326   thisPos -= m_origin;
00327   thisPos /= m_mesh_spacing;
00328 
00329   for( int d=0 ; d<SpaceDim ; ++d ){
00330     // handle periodic domain
00331     if( m_probdomain.isPeriodic(d) ){
00332       binLoc[d] = (int) thisPos[d] % m_probdomain.domainBox().size(d) ;
00333     }else{
00334       binLoc[d] = (int) thisPos[d] ;
00335     }
00336   }
00337   return binLoc;
00338 }
00339 
00340   
00341 
00342 #endif 

Generated on Wed Apr 16 14:26:48 2003 for Chombo by doxygen1.2.16