00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _BINFABIMPLEM_H_
00029 #define _BINFABIMPLEM_H_
00030
00031 #include "BoxIterator.H"
00032 #include "List.H"
00033
00034
00035
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
00091
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
00103
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
00115
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 }
00125 }
00126 }
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
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
00169 template <class T>
00170 void
00171 BinFab<T>::addItemsDestructive(List<T>& a_List)
00172 {
00173 if (a_List.length() > 0)
00174 {
00175
00176
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))
00187 {
00188 this->operator()(binLoc,comp).append(thisItem);
00189 a_List.remove(lit);
00190 }
00191 else
00192 {
00193
00194
00195 ++lit;
00196 }
00197 }
00198 }
00199 }
00200
00202
00205
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
00214
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))
00224 {
00225 this->operator()(binLoc,comp).append(thisItem);
00226
00227
00228
00229
00230
00231
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
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
00270
00271
00272 Box ibox = a_box;
00273 if (ibox.isEmpty())
00274 {
00275 ibox = this->box();
00276 }
00277
00278
00279
00280 Interval comps = a_comps;
00281 if (comps.size() == 0)
00282 {
00283 comps = this->interval();
00284 }
00285
00286
00287
00288
00289
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
00302 template <class T>
00303 const int*
00304 BinFab<T>::size() const
00305 {
00306 return BaseFab<List<T> >::size();
00307 }
00308
00309
00310 template <class T>
00311 int
00312 BinFab<T>::size(const Box& box, const Interval& comps) const
00313 {
00314 int totalSize = 0;
00315
00316
00317
00318 int sizeOfT ;
00319 {
00320 T tmp ;
00321 sizeOfT = tmp.size() ;
00322 }
00323
00324
00325 BoxIterator bit(box);
00326 for (int comp=comps.begin(); comp<=comps.end(); ++comp)
00327 {
00328 for (bit.begin(); bit.ok(); ++bit)
00329 {
00330 const List<T>& thisList = this->operator()(bit(), comp);
00331 totalSize += thisList.length();
00332 }
00333 }
00334
00335
00336 totalSize *= sizeOfT;
00337
00338
00339
00340
00341
00342
00343 int numBins = box.numPts() * comps.size();
00344 totalSize += numBins * sizeof(int);
00345
00346 return totalSize;
00347 }
00348
00349 template <class T>
00350 void BinFab<T>::linearOut(void* buf, const Box& R, const Interval& comps) const
00351 {
00352 char* buf_ch = (char*)buf;
00353
00354
00355 BoxIterator bit(R);
00356 for (int comp=comps.begin(); comp<= comps.end(); ++comp)
00357 {
00358 for (bit.begin(); bit.ok(); ++bit)
00359 {
00360 const List<T>& thisList = this->operator()(bit(), comp);
00361 int *intBuffer = (int*)buf_ch;
00362
00363 *intBuffer = thisList.length();
00364 buf_ch += sizeof(int);
00365
00366
00367 ListIterator<T> lit(thisList);
00368 for (lit.rewind(); lit; ++lit)
00369 {
00370 thisList[lit].linearOut(buf_ch);
00371 buf_ch += thisList[lit].size();
00372 }
00373 }
00374 }
00375 }
00376
00377 template <class T>
00378 void BinFab<T>::linearIn(void* buf, const Box& R, const Interval& comps)
00379 {
00380
00381 char *buf_ch = (char*)buf;
00382
00383 BoxIterator bit(R);
00384 for (int comp = comps.begin(); comp <= comps.end(); ++comp)
00385 {
00386 for (bit.begin(); bit.ok(); ++bit)
00387 {
00388 List<T>& thisList = this->operator()(bit(), comp);
00389
00390
00391 thisList.clear();
00392
00393 int numItems = *((int*)buf_ch);
00394
00395 buf_ch += sizeof(int);
00396
00397 if (numItems > 100000)
00398 {
00399 pout() << " [error: numItems=" << numItems << "] ";
00400 numItems = 1;
00401 }
00402
00403 for (int n = 0; n < numItems; ++n)
00404 {
00405 T thisBinItem;
00406
00407 thisBinItem.linearIn( buf_ch );
00408 thisList.append(thisBinItem);
00409 buf_ch += thisBinItem.size();
00410 }
00411 }
00412 }
00413 }
00414
00415 template <class T>
00416 IntVect BinFab<T>::locateBin(const T& a_binItem) const
00417 {
00418 IntVect binLoc;
00419 RealVect thisPos = a_binItem.position();
00420
00421 thisPos -= m_origin;
00422 thisPos /= m_mesh_spacing;
00423
00424 for (int d=0; d<SpaceDim; ++d)
00425 {
00426
00427 if (m_probdomain.isPeriodic(d))
00428 {
00429 binLoc[d] = (int)floor(thisPos[d]) % m_probdomain.domainBox().size(d);
00430 }
00431 else
00432 {
00433 binLoc[d] = (int) floor(thisPos[d]);
00434
00435 if (thisPos[d] < 0) --binLoc[d];
00436 }
00437 }
00438
00439 return binLoc;
00440 }
00441
00442 #endif