00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _BASEIFFABI_H_
00012 #define _BASEIFFABI_H_
00013 #include "MayDay.H"
00014 #include "FaceIterator.H"
00015 #include <typeinfo>
00016 #include "NamespaceHeader.H"
00017
00018 template <class T>
00019 bool BaseIFFAB<T>::s_doSurroundingNodeSemantic = false;
00020
00021
00022 template <class T>
00023 void
00024 BaseIFFAB<T>::setSurroundingNodeSemantic(bool a_useSurr)
00025 {
00026 s_doSurroundingNodeSemantic = a_useSurr;
00027 }
00028
00029
00030
00031 template <class T>
00032 bool
00033 BaseIFFAB<T>::useThisFace(const Box& a_toBox,
00034 const FaceIndex& a_face) const
00035 {
00036 return ((a_toBox.contains(a_face.gridIndex(Side::Lo))) ||
00037 (a_toBox.contains(a_face.gridIndex(Side::Hi))));
00038 }
00039
00040
00041
00042
00043
00044
00045
00046 template <class T>
00047 void
00048 BaseIFFAB<T>::getBoxAndIVS(Box& a_intBox,
00049 IntVectSet& a_ivsIntersect,
00050 const Box& a_toBox) const
00051 {
00052 Box grownBox = a_toBox;
00053 if (s_doSurroundingNodeSemantic)
00054 {
00055 grownBox.grow(m_direction, 1);
00056 }
00057 a_intBox = grownBox;
00058 a_ivsIntersect = m_ivs;
00059 a_ivsIntersect &= a_intBox;
00060 }
00061
00062 template <class T>
00063 bool BaseIFFAB<T>::s_verbose = false;
00064
00065 template <class T> inline void
00066 BaseIFFAB<T>::setVerbose(bool a_verbose)
00067 {
00068 s_verbose = a_verbose;
00069 }
00070
00071 template <class T> inline
00072 const EBGraph&
00073 BaseIFFAB<T>::getEBGraph() const
00074 {
00075 return m_ebgraph;
00076 }
00077
00078 template <class T> inline
00079 BaseIFFAB<T>::BaseIFFAB()
00080 {
00081 setDefaultValues();
00082 }
00083
00084 template <class T> inline
00085 BaseIFFAB<T>::~BaseIFFAB()
00086 {
00087 clear();
00088 }
00089
00090 template <class T> inline
00091 BaseIFFAB<T>::BaseIFFAB(const IntVectSet& a_ivsin,
00092 const EBGraph& a_ebgraph,
00093 const int& a_direction,
00094 const int& a_nvarin)
00095 {
00096 setDefaultValues();
00097 define(a_ivsin, a_ebgraph, a_direction, a_nvarin);
00098 }
00099
00100 template <class T> Arena* BaseIFFAB<T>::s_Arena = NULL;
00101
00102
00103 template <class T> inline
00104 void
00105 BaseIFFAB<T>::define(const IntVectSet& a_ivsin,
00106 const EBGraph& a_ebgraph,
00107 const int& a_direction,
00108 const int& a_nvarin)
00109 {
00110 clear();
00111 m_isDefined = true;
00112 CH_assert(a_nvarin > 0);
00113 CH_assert((a_direction >= 0) && (a_direction < SpaceDim));
00114 const ProblemDomain& domain = a_ebgraph.getDomain();
00115 m_direction = a_direction;
00116 m_ivs = a_ivsin;
00117 m_ebgraph = a_ebgraph;
00118 m_nComp = a_nvarin;
00119 Box minbox = a_ivsin.minBox();
00120 BaseFab<int> faceLocFab;
00121 BaseFab<bool> doneThat;
00122 if (!a_ivsin.isEmpty())
00123 {
00124 m_fab.resize( surroundingNodes(minbox,a_direction), 1);
00125 faceLocFab.resize(surroundingNodes(minbox,a_direction), 1);
00126 doneThat.resize( surroundingNodes(minbox,a_direction), 1);
00127 faceLocFab.setVal(-1);
00128 m_fab.setVal(NULL);
00129 doneThat.setVal(false);
00130 }
00131
00132
00133 m_nFaces = 0;
00134 int nVoFs = 0;
00135 for (IVSIterator ivsit(m_ivs); ivsit.ok(); ++ivsit)
00136 {
00137 const IntVect& iv = ivsit();
00138 IntVect ivLo = iv-BASISV(m_direction);
00139 IntVect ivHi = iv+BASISV(m_direction);
00140
00141 int numVoFsHere = m_ebgraph.numVoFs(iv);
00142
00143 nVoFs += numVoFsHere;
00144
00145 if (!doneThat(iv, 0))
00146 {
00147 doneThat(iv, 0) = true;
00148
00149 bool onLoBoundary = false;
00150 if (!domain.isPeriodic(m_direction))
00151 {
00152 onLoBoundary = iv[m_direction] == domain.domainBox().smallEnd(m_direction);
00153 }
00154 int numFacesLoSide = numVoFsHere;
00155 if (!onLoBoundary)
00156 {
00157 int numVoFsLo = m_ebgraph.numVoFs(ivLo);
00158 numFacesLoSide = numVoFsHere*numVoFsLo;
00159 }
00160
00161 faceLocFab(iv, 0) = m_nFaces;
00162 m_nFaces += numFacesLoSide;
00163 }
00164 if (!doneThat(ivHi, 0))
00165 {
00166 doneThat(ivHi, 0) = true;
00167
00168 bool onHiBoundary = false;
00169 if (!domain.isPeriodic(m_direction))
00170 {
00171 onHiBoundary = iv[m_direction] == domain.domainBox().bigEnd(m_direction);
00172 }
00173 int numFacesHiSide = numVoFsHere;
00174 if (!onHiBoundary)
00175 {
00176 int numVoFsHi = m_ebgraph.numVoFs(ivHi);
00177 numFacesHiSide = numVoFsHere*numVoFsHi;
00178 }
00179
00180 faceLocFab(ivHi, 0) = m_nFaces;
00181 m_nFaces += numFacesHiSide;
00182 }
00183 }
00184
00185 if (m_nFaces > 0)
00186 {
00187
00188
00189 #ifdef CH_USE_MEMORY_TRACKING
00190
00191
00192
00193
00194 #else
00195
00196
00197
00198
00199 #endif
00200
00201
00202
00203
00204
00205
00206 m_truesize = m_nFaces*m_nComp;
00207
00208
00209
00210 m_data.resize(m_truesize);
00211
00212
00213 #ifdef CH_USE_MEMORY_TRACKING
00214
00215
00216
00217
00218
00219 #endif
00220 doneThat.setVal(false);
00221 }
00222 if (m_nFaces==0) return;
00223
00224 T* startLoc = &m_data[0];
00225 for (IVSIterator ivsit(m_ivs); ivsit.ok(); ++ivsit)
00226 {
00227 const IntVect& iv = ivsit();
00228 if (!doneThat(iv, 0))
00229 {
00230 doneThat(iv, 0) = true;
00231 int iface = faceLocFab(iv, 0);
00232 if (iface >= 0)
00233 {
00234 m_fab(iv, 0) = startLoc + iface;
00235 }
00236 }
00237 IntVect ivHi = iv+BASISV(m_direction);
00238 if (!doneThat(ivHi, 0))
00239 {
00240 doneThat(ivHi, 0) = true;
00241 int iface = faceLocFab(ivHi, 0);
00242 if (iface >= 0)
00243 {
00244 m_fab(ivHi, 0) = startLoc + iface;
00245 }
00246 }
00247 }
00248 }
00249
00250 template <class T> inline
00251 const IntVectSet&
00252 BaseIFFAB<T>::getIVS() const
00253 {
00254 return m_ivs;
00255 }
00256
00257 template <class T> inline
00258 int
00259 BaseIFFAB<T>::direction() const
00260 {
00261 return m_direction;
00262 }
00263
00264 template <class T> inline
00265 void
00266 BaseIFFAB<T>::setVal(const T& a_value)
00267 {
00268 CH_assert(isDefined());
00269 for (int ivec = 0; ivec < m_nFaces*m_nComp; ivec++)
00270 {
00271 m_data[ivec] = a_value;
00272 }
00273 }
00274
00275 template <class T> inline
00276 void
00277 BaseIFFAB<T>::setVal(int ivar, const T& a_value)
00278 {
00279 CH_assert(isDefined());
00280 CH_assert(ivar >= 0);
00281 CH_assert(ivar < m_nComp);
00282
00283 for (int ivec = ivar; ivec < m_nFaces*m_nComp; ivec += m_nComp)
00284 {
00285 m_data[ivec] = a_value;
00286 }
00287 }
00288
00289 template <class T> inline
00290 void
00291 BaseIFFAB<T>::copy(const Box& a_fromBox,
00292 const Interval& a_dstInterval,
00293 const Box& a_toBox,
00294 const BaseIFFAB<T>& a_src,
00295 const Interval& a_srcInterval)
00296 {
00297 CH_assert(isDefined());
00298 CH_assert(a_src.isDefined());
00299 CH_assert(a_srcInterval.size() == a_dstInterval.size());
00300 CH_assert(a_dstInterval.begin() >= 0);
00301 CH_assert(a_srcInterval.begin() >= 0);
00302 CH_assert(a_dstInterval.end() < m_nComp);
00303 CH_assert(a_srcInterval.end() < a_src.m_nComp);
00304
00305 if ((!m_ivs.isEmpty()) && (!a_src.m_ivs.isEmpty()))
00306 {
00307 CH_assert( (a_fromBox == a_toBox) || m_ebgraph.getDomain().isPeriodic() );
00308
00309 Box intBox;
00310 IntVectSet ivsIntersect;
00311
00312
00313 getBoxAndIVS(intBox, ivsIntersect, a_toBox);
00314
00315 ivsIntersect &= a_src.m_ivs;
00316 int compSize = a_srcInterval.size();
00317
00318 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00319 FaceIterator faceit(ivsIntersect, m_ebgraph, m_direction, stopCrit);
00320 for (faceit.reset(); faceit.ok(); ++faceit)
00321 {
00322 const FaceIndex& face = faceit();
00323
00324
00325 if (useThisFace(a_toBox, face))
00326 {
00327 for (int icomp = 0; icomp < compSize; icomp++)
00328 {
00329 int isrccomp = a_srcInterval.begin() + icomp;
00330 int idstcomp = a_dstInterval.begin() + icomp;
00331 (*this)(face, idstcomp) = a_src(face, isrccomp);
00332 }
00333 }
00334 }
00335 }
00336 }
00337
00338 template <class T> inline
00339 T*
00340 BaseIFFAB<T>::getIndex(const FaceIndex& a_face, const int& a_comp) const
00341 {
00342
00343
00344 T* dataPtr = (T*)(m_fab(a_face.gridIndex(Side::Hi), 0));
00345 int faceLoc = getLocalVecIndex(a_face);
00346 dataPtr += faceLoc;
00347 dataPtr += m_nFaces*a_comp;
00348 return dataPtr;
00349 }
00350
00351 template <class T> inline
00352 int
00353 BaseIFFAB<T>::getLocalVecIndex(const FaceIndex& a_face) const
00354 {
00355 int retval;
00356 if (!a_face.isBoundary())
00357 {
00358
00359 CH_assert(a_face.cellIndex(Side::Lo) >= 0);
00360 CH_assert(a_face.cellIndex(Side::Hi) >= 0);
00361 int xlen = m_ebgraph.numVoFs(a_face.gridIndex(Side::Lo));
00362 int loCell = a_face.cellIndex(Side::Lo);
00363 int hiCell = a_face.cellIndex(Side::Hi);
00364 retval = loCell + xlen*hiCell;
00365 }
00366 else
00367 {
00368 int loCell = a_face.cellIndex(Side::Lo);
00369 int hiCell = a_face.cellIndex(Side::Hi);
00370
00371 CH_assert(((loCell == -1)&&(hiCell > -1))||
00372 ((hiCell == -1)&&(loCell > -1)));
00373
00374 retval = Max(loCell, hiCell);
00375 }
00376 return retval;
00377 }
00378
00379 template <class T> inline
00380 void
00381 BaseIFFAB<T>::clear()
00382 {
00383 m_nComp = 0;
00384 m_nFaces = 0;
00385 m_direction = -1;
00386 m_ivs.makeEmpty();
00387 m_fab.clear();
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 m_isDefined = false;
00399 }
00400
00401 template <class T> inline
00402 bool
00403 BaseIFFAB<T>::isDefined() const
00404 {
00405 return (m_isDefined);
00406 }
00407
00408 template <class T> inline
00409 int
00410 BaseIFFAB<T>::numFaces() const
00411 {
00412 return m_nFaces;
00413 }
00414
00415 template <class T> inline
00416 int
00417 BaseIFFAB<T>::nComp() const
00418 {
00419 return m_nComp;
00420 }
00421
00422 template <class T> inline
00423 T&
00424 BaseIFFAB<T>::operator() (const FaceIndex& a_ndin,
00425 const int& a_comp)
00426 {
00427 CH_assert(isDefined());
00428 CH_assert(a_comp >= 0);
00429 CH_assert(a_comp < m_nComp);
00430 CH_assert((m_ivs.contains(a_ndin.gridIndex(Side::Lo)) ||
00431 m_ivs.contains(a_ndin.gridIndex(Side::Hi))));
00432 CH_assert(a_ndin.direction() == m_direction);
00433
00434 T* dataPtr = getIndex(a_ndin, a_comp);
00435 return(*dataPtr);
00436 }
00437
00438 template <class T> inline
00439 const T&
00440 BaseIFFAB<T>::operator() (const FaceIndex& a_ndin,
00441 const int& a_comp) const
00442 {
00443 CH_assert(isDefined());
00444 CH_assert(a_comp >= 0);
00445 CH_assert(a_comp < m_nComp);
00446 CH_assert((m_ivs.contains(a_ndin.gridIndex(Side::Lo)) ||
00447 m_ivs.contains(a_ndin.gridIndex(Side::Hi))));
00448 CH_assert(a_ndin.direction() == m_direction);
00449
00450 T* dataPtr = getIndex(a_ndin, a_comp);
00451 return(*dataPtr);
00452 }
00453
00454 template <class T> inline
00455 T*
00456 BaseIFFAB<T>::dataPtr(const int& a_comp)
00457 {
00458 CH_assert(a_comp >= 0);
00459 CH_assert(a_comp <= m_nComp);
00460 static T* dummy = NULL;
00461 if (m_nFaces==0) return dummy;
00462
00463 return &(m_data[0]) + a_comp*m_nFaces;
00464
00465 }
00466
00467 template <class T> inline
00468 const T*
00469 BaseIFFAB<T>::dataPtr(const int& a_comp) const
00470 {
00471 CH_assert(a_comp >= 0);
00472 CH_assert(a_comp <= m_nComp);
00473 static T* dummy = NULL;
00474 if (m_nFaces==0) return dummy;
00475
00476 return &(m_data[0]) + a_comp*m_nFaces;
00477 }
00478
00479 template <class T> inline
00480 void
00481 BaseIFFAB<T>::setDefaultValues()
00482 {
00483 m_isDefined = false;
00484
00485 m_data.resize(0);
00486 m_nFaces = 0;
00487 m_nComp = 0;
00488 m_direction = -1;
00489 }
00490
00491 template <class T> inline
00492 int BaseIFFAB<T>::size(const Box& a_region,
00493 const Interval& a_comps) const
00494 {
00495 CH_assert(isDefined());
00496
00497 Box intBox;
00498 IntVectSet subIVS;
00499
00500
00501 getBoxAndIVS(intBox, subIVS, a_region);
00502
00503 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00504 FaceIterator faceit(subIVS, m_ebgraph, m_direction, stopCrit);
00505 Vector<FaceIndex> faces = faceit.getVector();
00506
00507
00508 int facesize = linearListSize(faces);
00509
00510
00511 int datasize = 0;
00512 for (int iface = 0; iface < faces.size(); iface++)
00513 {
00514
00515
00516 if (useThisFace(a_region, faces[iface]))
00517 {
00518 for (int icomp = a_comps.begin(); icomp <= a_comps.end(); icomp++)
00519 {
00520 const T& dataPt = (*this)(faces[iface], icomp);
00521 int pointsize = CH_XD::linearSize(dataPt);
00522 datasize += pointsize;
00523 }
00524 }
00525 }
00526
00527 int retval = facesize + datasize;
00528
00529 if (s_verbose)
00530 {
00531 pout() << "###############" << std::endl;
00532 pout() << "BaseIFFAB size() for region " << m_ebgraph.getRegion() << std::endl;
00533 pout() << " a_comps = (" << a_comps.begin() << "," << a_comps.end() << "),"
00534 << " a_region = " << a_region << " subIVS = ";
00535
00536 pout() << "m_ivs = ";
00537
00538 pout() << "size = " << retval << std::endl;
00539 pout() << "###############" << std::endl;
00540 }
00541
00542 return retval;
00543 }
00544
00545 template <class T> inline
00546 void BaseIFFAB<T>::linearOut(void* a_buf,
00547 const Box& a_region,
00548 const Interval& a_comps) const
00549 {
00550 CH_assert(isDefined());
00551 Box intBox;
00552 IntVectSet subIVS;
00553
00554
00555 getBoxAndIVS(intBox, subIVS, a_region);
00556
00557 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00558 FaceIterator faceit(subIVS, m_ebgraph, m_direction, stopCrit);
00559 Vector<FaceIndex> faces = faceit.getVector();
00560
00561
00562 unsigned char* charbuffer = (unsigned char *) a_buf;
00563 linearListOut(charbuffer, faces);
00564 charbuffer += linearListSize(faces);
00565
00566
00567 const BaseIFFAB<T>& thisFAB = *this;
00568 for (int iface = 0; iface < faces.size(); iface++)
00569 {
00570
00571
00572 if (useThisFace(a_region, faces[iface]))
00573 {
00574 const FaceIndex& face = faces[iface];
00575 for (int icomp = a_comps.begin(); icomp <= a_comps.end(); icomp++)
00576 {
00577
00578 const T& dataPt = thisFAB(face, icomp);
00579 CH_XD::linearOut(charbuffer, dataPt);
00580
00581 charbuffer += CH_XD::linearSize(dataPt);
00582 }
00583 }
00584 }
00585 }
00586
00587 template <class T> inline
00588 void BaseIFFAB<T>::linearIn(void* a_buf, const Box& a_region, const Interval& a_comps)
00589 {
00590 CH_assert(isDefined());
00591
00592
00593 Box intBox;
00594 IntVectSet subIVS;
00595
00596
00597 getBoxAndIVS(intBox, subIVS, a_region);
00598
00599 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00600 FaceIterator faceit(subIVS, m_ebgraph, m_direction, stopCrit);
00601 Vector<FaceIndex> faces = faceit.getVector();
00602
00603 unsigned char* charbuffer = (unsigned char *) a_buf;
00604 linearListIn(faces, charbuffer);
00605 charbuffer += linearListSize(faces);
00606
00607 for (int iface = 0; iface < faces.size(); iface++)
00608 {
00609
00610
00611 if (useThisFace(a_region, faces[iface]))
00612 {
00613 const FaceIndex& face = faces[iface];
00614 for (int icomp = a_comps.begin(); icomp <= a_comps.end(); icomp++)
00615 {
00616
00617 T& dataPt = (*this)(face, icomp);
00618 CH_XD::linearIn(dataPt, charbuffer) ;
00619
00620 charbuffer += CH_XD::linearSize(dataPt);
00621 }
00622 }
00623 }
00624 }
00625
00626
00627
00628 #include "NamespaceFooter.H"
00629 #endif