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 _BaseIFFABI_H_
00029 #define _BaseIFFABI_H_
00030 #include "MayDay.H"
00031 #include "FaceIterator.H"
00032
00033 template <class T> inline
00034 const EBGraph&
00035 BaseIFFAB<T>::getEBGraph() const
00036 {
00037 return m_ebgraph;
00038 }
00039
00040 template <class T> inline
00041 BaseIFFAB<T>::BaseIFFAB()
00042 {
00043 setDefaultValues();
00044 }
00045
00046 template <class T> inline
00047 BaseIFFAB<T>::~BaseIFFAB()
00048 {
00049 clear();
00050 }
00051
00052 template <class T> inline
00053 BaseIFFAB<T>::BaseIFFAB(const IntVectSet& a_ivsin,
00054 const EBGraph& a_ebgraph,
00055 const int& a_direction,
00056 const int& a_nvarin)
00057 {
00058 setDefaultValues();
00059 define(a_ivsin, a_ebgraph, a_direction, a_nvarin);
00060 }
00061
00062 template <class T> inline
00063 void
00064 BaseIFFAB<T>::define(const IntVectSet& a_ivsin,
00065 const EBGraph& a_ebgraph,
00066 const int& a_direction,
00067 const int& a_nvarin)
00068 {
00069 clear();
00070 m_isDefined = true;
00071 assert(a_nvarin > 0);
00072 assert((a_direction >= 0) && (a_direction < SpaceDim));
00073 const Box& domain = a_ebgraph.getDomain();
00074 m_direction = a_direction;
00075 m_ivs = a_ivsin;
00076 m_ebgraph = a_ebgraph;
00077 m_nComp = a_nvarin;
00078 if(!a_ivsin.isEmpty())
00079 {
00080 Box minbox = a_ivsin.minBox();
00081 m_ivmap.resize(surroundingNodes(minbox,a_direction), 1);
00082 }
00083 m_nFaces = 0;
00084 for(IVSIterator ivsit(a_ivsin); ivsit.ok(); ++ivsit)
00085 {
00086
00087
00088
00089 const IntVect thisIV = ivsit();
00090 Vector<VolIndex> theseVoFs = m_ebgraph.getVoFs(thisIV);
00091 for(SideIterator sit; sit.ok(); ++sit)
00092 {
00093 int iside = sign(sit());
00094 IntVect otherIV = thisIV + iside*BASISV(m_direction);
00095
00096
00097
00098
00099 int numfaces = 0;
00100 if(domain.contains(otherIV))
00101 {
00102 numfaces = (m_ebgraph.numVoFs(thisIV))*(m_ebgraph.numVoFs(otherIV));
00103 #ifndef NDEBUG
00104 Vector<FaceIndex> facesHi = m_ebgraph.getAllFaces(thisIV, m_direction, sit());
00105 Vector<FaceIndex> facesLo = m_ebgraph.getAllFaces(otherIV, m_direction, flip(sit()));
00106 if(facesHi.size() != facesLo.size())
00107 {
00108 MayDay::Error("internally inconsistent geometry");
00109 }
00110 #endif
00111 }
00112 else
00113 {
00114 numfaces = m_ebgraph.numVoFs(thisIV);
00115 }
00116
00117
00118 IntVect ivface;
00119 if(sit() == Side::Lo)
00120 ivface = thisIV;
00121 else
00122 ivface = otherIV;
00123
00124 Vector<int>& vIndex = m_ivmap(ivface, 0);
00125 vIndex.resize(numfaces);
00126
00127
00128 for(int ivof = 0; ivof < theseVoFs.size(); ivof++)
00129 {
00130 Vector<FaceIndex> sideFaces =
00131 m_ebgraph.getFaces(theseVoFs[ivof],m_direction, sit());
00132 for(int iface = 0; iface < sideFaces.size(); iface++)
00133 {
00134 vIndex[iface] = m_nFaces;
00135 m_nFaces++;
00136 }
00137 }
00138 }
00139 }
00140
00141 if(m_nFaces > 0)
00142 {
00143
00144 for (int dir = 0; dir < SpaceDim; ++dir)
00145 {
00146 m_loVect[dir] = 1;
00147 m_hiVect[dir] = 1;
00148 }
00149 m_hiVect[0] = m_nFaces;
00150 m_dataPtr = new T[m_nComp*m_nFaces];
00151 }
00152 else
00153 {
00154 m_loVect = IntVect::Unit;
00155 m_hiVect = IntVect::Zero;
00156 m_dataPtr = NULL;
00157 }
00158 }
00159
00160 template <class T> inline
00161 const IntVectSet&
00162 BaseIFFAB<T>::getIVS() const
00163 {
00164 return m_ivs;
00165 }
00166
00167 template <class T> inline
00168 int
00169 BaseIFFAB<T>::direction() const
00170 {
00171 return m_direction;
00172 }
00173
00174 template <class T> inline
00175 void
00176 BaseIFFAB<T>::setVal(const T& a_value)
00177 {
00178 assert(isDefined());
00179 for(int ivec = 0; ivec < m_nFaces*m_nComp; ivec++)
00180 m_dataPtr[ivec] = a_value;
00181 }
00182
00183 template <class T> inline
00184 void
00185 BaseIFFAB<T>::copy(const Box& a_fromBox,
00186 const Interval& a_dstInterval,
00187 const Box& a_toBox,
00188 const BaseIFFAB<T>& a_src,
00189 const Interval& a_srcInterval)
00190 {
00191 assert(isDefined());
00192 assert(a_src.isDefined());
00193 assert(a_srcInterval.size() == a_dstInterval.size());
00194 assert(a_dstInterval.begin() >= 0);
00195 assert(a_srcInterval.begin() >= 0);
00196 assert(a_dstInterval.end() < m_nComp);
00197 assert(a_srcInterval.end() < a_src.m_nComp);
00198 assert(a_fromBox == a_toBox);
00199
00200 Box intBox = a_toBox;
00201 IntVectSet ivsIntersect = m_ivs;
00202 ivsIntersect &= a_src.m_ivs;
00203 ivsIntersect &= intBox;
00204 int compSize = a_srcInterval.size();
00205 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00206 for(FaceIterator faceit(ivsIntersect, m_ebgraph, m_direction, stopCrit);
00207 faceit.ok(); ++faceit)
00208 {
00209 const FaceIndex& face = faceit();
00210 for(int icomp = 0; icomp < compSize; icomp++)
00211 {
00212 int isrccomp = a_srcInterval.begin() + icomp;
00213 int idstcomp = a_dstInterval.begin() + icomp;
00214 int isrc = a_src.getIndex(face, isrccomp);
00215 int idst = getIndex(face, idstcomp);
00216 m_dataPtr[idst] = a_src.m_dataPtr[isrc];
00217 }
00218 }
00219 }
00220
00221 template <class T> inline
00222 int
00223 BaseIFFAB<T>::getLocalVecIndex(const FaceIndex& a_face) const
00224 {
00225 int retval;
00226 if(!a_face.isBoundary())
00227 {
00228
00229 assert(a_face.cellIndex(Side::Lo) >= 0);
00230 assert(a_face.cellIndex(Side::Hi) >= 0);
00231 int xlen = m_ebgraph.numVoFs(a_face.gridIndex(Side::Lo));
00232 int loCell = a_face.cellIndex(Side::Lo);
00233 int hiCell = a_face.cellIndex(Side::Hi);
00234 retval = loCell + xlen*hiCell;
00235 }
00236 else
00237 {
00238 int loCell = a_face.cellIndex(Side::Lo);
00239 int hiCell = a_face.cellIndex(Side::Hi);
00240
00241 assert(((loCell == -1)&&(hiCell > -1))||
00242 ((hiCell == -1)&&(loCell > -1)));
00243
00244 retval = Max(loCell, hiCell);
00245 }
00246 return retval;
00247 }
00248
00249 template <class T> inline
00250 int
00251 BaseIFFAB<T>::getIndex(const FaceIndex& a_face, const int& a_comp) const
00252 {
00253 assert((a_comp >= 0) && (a_comp < m_nComp));
00254
00255
00256
00257 const Vector<int>& vecOffset = m_ivmap(a_face.gridIndex(Side::Hi), 0);
00258 int ivec = getLocalVecIndex(a_face);
00259
00260
00261
00262 int ioffset = vecOffset[ivec];
00263 assert(ioffset >= 0);
00264 assert(ioffset < m_nFaces);
00265
00266 ioffset += m_nFaces*a_comp;
00267 return ioffset;
00268 }
00269
00270 template <class T> inline
00271 void
00272 BaseIFFAB<T>::clear()
00273 {
00274 m_nComp = 0;
00275 m_nFaces = 0;
00276 m_direction = -1;
00277 m_ivs.makeEmpty();
00278 m_ivmap.clear();
00279 if(m_dataPtr != NULL)
00280 {
00281 delete[] m_dataPtr;
00282 m_dataPtr = NULL;
00283 }
00284 m_isDefined = false;
00285 }
00286
00287 template <class T> inline
00288 bool
00289 BaseIFFAB<T>::isDefined() const
00290 {
00291 return (m_isDefined);
00292 }
00293
00294 template <class T> inline
00295 int
00296 BaseIFFAB<T>::numFaces() const
00297 {
00298 return m_nFaces;
00299 }
00300
00301 template <class T> inline
00302 int
00303 BaseIFFAB<T>::nComp() const
00304 {
00305 return m_nComp;
00306 }
00307
00308 template <class T> inline
00309 T&
00310 BaseIFFAB<T>::operator() (const FaceIndex& a_ndin,
00311 const int& a_comp)
00312 {
00313 assert(isDefined());
00314 assert(a_comp >= 0);
00315 assert(a_comp < m_nComp);
00316 assert((m_ivs.contains(a_ndin.gridIndex(Side::Lo)) ||
00317 m_ivs.contains(a_ndin.gridIndex(Side::Hi))));
00318 assert(a_ndin.direction() == m_direction);
00319 int iloc = getIndex(a_ndin, a_comp);
00320 return(m_dataPtr[iloc]);
00321 }
00322
00323 template <class T> inline
00324 const T&
00325 BaseIFFAB<T>::operator() (const FaceIndex& a_ndin,
00326 const int& a_comp) const
00327 {
00328 assert(isDefined());
00329 assert(a_comp >= 0);
00330 assert(a_comp < m_nComp);
00331 assert((m_ivs.contains(a_ndin.gridIndex(Side::Lo)) ||
00332 m_ivs.contains(a_ndin.gridIndex(Side::Hi))));
00333 assert(a_ndin.direction() == m_direction);
00334 int iloc = getIndex(a_ndin, a_comp);
00335 return(m_dataPtr[iloc]);
00336 }
00337
00338 template <class T> inline
00339 const T*
00340 BaseIFFAB<T>::dataPtr(const int& a_comp) const
00341 {
00342 assert(isDefined());
00343 assert(a_comp >= 0);
00344 assert(a_comp < m_nComp);
00345 return m_dataPtr + a_comp*m_nFaces;
00346 }
00347
00348 template <class T> inline
00349 T*
00350 BaseIFFAB<T>::dataPtr(const int& a_comp)
00351 {
00352 assert(isDefined());
00353 return m_dataPtr + a_comp*m_nFaces;
00354 }
00355
00356 template <class T> inline
00357 const int*
00358 BaseIFFAB<T>::loVect() const
00359 {
00360 return m_loVect.getVect();
00361 }
00362
00363 template <class T> inline
00364 const int*
00365 BaseIFFAB<T>::hiVect() const
00366 {
00367 return m_hiVect.getVect();
00368 }
00369
00370 template <class T> inline
00371 void
00372 BaseIFFAB<T>::setDefaultValues()
00373 {
00374 m_isDefined = false;
00375 m_dataPtr = NULL;
00376 m_nFaces = 0;
00377 m_nComp = 0;
00378 m_direction = -1;
00379 m_loVect = IntVect::Unit;
00380 m_hiVect = IntVect::Zero;
00381 }
00382
00383 template <class T> inline
00384 BaseIFFAB<T>&
00385 BaseIFFAB<T>::operator= (const BaseIFFAB<T>& a_input)
00386 {
00387 MayDay::Error("BaseIFFAB operator = not defined");
00388 return *this;
00389 }
00390
00391 template <class T> inline
00392 BaseIFFAB<T>::BaseIFFAB (const BaseIFFAB<T>& a_input)
00393 {
00394 MayDay::Error("BaseIFFAB copy constructor not defined");
00395 }
00396
00397 template <class T> inline
00398 int BaseIFFAB<T>::size(const Box& a_region,
00399 const Interval& a_comps) const
00400 {
00401 assert(isDefined());
00402
00403 IntVectSet subIVS = m_ivs;
00404 subIVS &= a_region;
00405
00406
00407 int retval = 0;
00408 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00409 for(FaceIterator faceit(subIVS, m_ebgraph, m_direction, stopCrit);
00410 faceit.ok(); ++faceit)
00411 {
00412 retval++;
00413 }
00414
00415 retval *= a_comps.size();
00416
00417 retval *= sizeof(T);
00418 return retval;
00419 }
00420
00421 template <class T> inline
00422 void BaseIFFAB<T>::linearOut(void* a_buf,
00423 const Box& a_region,
00424 const Interval& a_comps) const
00425 {
00426 assert(isDefined());
00427
00428
00429 T* buffer = (T*)a_buf;
00430
00431 IntVectSet subIVS = m_ivs;
00432 subIVS &= a_region;
00433 const BaseIFFAB<T>& thisFAB = *this;
00434
00435 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00436 for(FaceIterator faceit(subIVS, m_ebgraph, m_direction, stopCrit);
00437 faceit.ok(); ++faceit)
00438 {
00439 const FaceIndex& face = faceit();
00440 for(int icomp = a_comps.begin(); icomp <= a_comps.end(); icomp++)
00441 {
00442 const T& thisVal = thisFAB(face, icomp);
00443
00444 *buffer = thisVal;
00445
00446 ++buffer;
00447 }
00448 }
00449 }
00450
00451 template <class T> inline
00452 void BaseIFFAB<T>::linearIn(void* a_buf, const Box& a_region, const Interval& a_comps)
00453 {
00454 assert(isDefined());
00455
00456
00457 T* buffer = (T*)a_buf;
00458
00459 IntVectSet subIVS = m_ivs;
00460 subIVS &= a_region;
00461 BaseIFFAB<T>& thisFAB = *this;
00462
00463 FaceStop::WhichFaces stopCrit = FaceStop::SurroundingWithBoundary;
00464 for(FaceIterator faceit(subIVS, m_ebgraph, m_direction, stopCrit);
00465 faceit.ok(); ++faceit)
00466 {
00467 const FaceIndex& face = faceit();
00468 for(int icomp = a_comps.begin(); icomp <= a_comps.end(); icomp++)
00469 {
00470 T& thisVal = thisFAB(face, icomp);
00471
00472 thisVal = *buffer;
00473
00474 ++buffer;
00475 }
00476 }
00477 }
00478
00479
00480
00481 #endif
00482