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 _GENAMRLEVELMGIMPLEM_H
00029 #define _GENAMRLEVELMGIMPLEM_H
00030
00031 #include "SPMD.H"
00032 #include "LayoutIterator.H"
00033
00034 #include "GenAMRSolver.H"
00035
00037 template <class T>
00038 GenAMRLevelMG<T>::GenAMRLevelMG()
00039 {
00040 setDefaultValues();
00041 }
00042
00044 template <class T>
00045 GenAMRLevelMG<T>::GenAMRLevelMG(const GenAMRSolver<T>* const a_parent,
00046 int a_level,
00047 const GenAMRLevelMGOp<T>* const a_opin,
00048 int a_ncomp)
00049 {
00050 setDefaultValues();
00051
00052 define(a_parent, a_level, a_opin, a_ncomp);
00053 }
00054
00056 template <class T>
00057 GenAMRLevelMG<T>::~GenAMRLevelMG()
00058 {
00059 clearMemory();
00060 }
00061
00063 template <class T>
00064 bool GenAMRLevelMG<T>::isDefined() const
00065 {
00066 return m_isDefined;
00067 }
00068
00070 template <class T>
00071 void GenAMRLevelMG<T>::define(const GenAMRSolver<T>* const a_parent,
00072 int a_level,
00073 const GenAMRLevelMGOp<T>* const a_opin,
00074 int a_ncomp)
00075 {
00076 clearMemory();
00077
00078 assert(a_parent != NULL);
00079 assert(a_parent->isDefined());
00080 assert(a_level >= 0);
00081 assert(a_level <= a_parent->m_finestLevel);
00082
00083 m_isDefined = true;
00084 m_parent = a_parent;
00085 m_level = a_level;
00086
00087 int nCoarserLevels;
00088 const DisjointBoxLayout& grids = a_parent->m_gridsLevel[a_level];
00089 const DisjointBoxLayout* baseBAPtr = NULL;
00090
00091
00092 int reftoCoarse = 2;
00093
00094 const ProblemDomain& domain = a_parent->m_domainLevel[a_level];
00095
00096 if (m_level > 0)
00097 {
00098 const DisjointBoxLayout& baseGrids = a_parent->m_gridsLevel[a_level-1];
00099
00100 baseBAPtr = &baseGrids;
00101 reftoCoarse = a_parent->m_refRatio[a_level-1];
00102 m_levfluxreg.define(grids, baseGrids, domain, reftoCoarse, a_ncomp);
00103
00104
00105
00106 nCoarserLevels = -1;
00107
00108 for (int interRatio = reftoCoarse; interRatio >= 2; interRatio /= 2)
00109 {
00110 nCoarserLevels++;
00111 }
00112 }
00113 else
00114 {
00115 nCoarserLevels = 0;
00116 }
00117
00118 Real dx = a_parent->m_dxLevel[a_level];
00119
00120 m_levelMG.define(grids, baseBAPtr, dx,
00121 reftoCoarse, domain,
00122 nCoarserLevels, a_opin,
00123 a_ncomp);
00124
00125 m_mginterp.define(grids, a_ncomp, reftoCoarse, domain);
00126
00127 if (m_level > 0)
00128 {
00129 coarsen(m_coarsenedGrids, grids, reftoCoarse);
00130 #if FIXIT
00131 m_resC.define(m_coarsenedGrids, a_ncomp,IntVect::TheZeroVector());
00132 m_residualCopier.define(m_coarsenedGrids, a_parent->m_gridsLevel[a_level-1]);
00133 m_averageOp.define(grids, m_coarsenedGrids, a_ncomp, reftoCoarse);
00134 #endif
00135 }
00136 if (m_level < a_parent->m_finestLevel)
00137 {
00138 m_fineExchangeCopier.define( a_parent->m_gridsLevel[a_level+1],
00139 a_parent->m_gridsLevel[a_level+1],
00140 IntVect::TheUnitVector());
00141 }
00142
00143 m_levelopPtr = a_opin->newOp();
00144 #if FIXIT
00145 m_levelopPtr->define(grids, baseBAPtr, dx, reftoCoarse,
00146 domain, false, a_ncomp);
00147 #endif
00148
00149
00150 m_levelopPtr->defineData(m_lofPhi);
00151 m_levelopPtr->defineData(m_resid);
00152
00153 m_levelopPtr->defineOpData(m_corr);
00154 m_levelopPtr->defineOpData(m_dcorr);
00155 m_levelopPtr->defineOpData(m_phiSave);
00156
00157
00158
00159 }
00160
00161 template <class T>
00162 void GenAMRLevelMG<T>::setnumSmoothUp(int a_numSmoothUp)
00163 {
00164 assert(isDefined());
00165
00166 m_levelMG.setnumSmoothUp(a_numSmoothUp);
00167 }
00168
00169 template <class T>
00170 void GenAMRLevelMG<T>::setnumSmoothDown(int a_numSmoothDown)
00171 {
00172 assert(isDefined());
00173
00174 m_levelMG.setnumSmoothDown(a_numSmoothDown);
00175 }
00176
00178 template <class T>
00179 void GenAMRLevelMG<T>::applyAMROperator(Vector<T* >& a_phiLevel,
00180 T& a_LOfPhi)
00181 {
00182 assert(isDefined());
00183
00184 T* crsePhi = NULL;
00185
00186
00187 if (m_level > 0)
00188 {
00189 crsePhi = a_phiLevel[m_level-1];
00190 }
00191
00192 m_levelopPtr->setToZero(a_LOfPhi);
00193
00194 T& phi = *a_phiLevel[m_level];
00195 m_levelopPtr->applyOpI(phi, crsePhi, a_LOfPhi);
00196
00197
00198 if (m_level < m_parent->m_finestLevel)
00199 {
00200 reflux(a_phiLevel, a_LOfPhi);
00201 }
00202 }
00203
00205 template <class T>
00206 void GenAMRLevelMG<T>::applyAMROperatorHphys(Vector<T* >& a_phiLevel,
00207 T& a_LOfPhi)
00208 {
00209 assert(isDefined());
00210
00211 m_levelopPtr->setToZero(a_LOfPhi);
00212
00213 T* crsePhi = NULL;
00214
00215
00216 if (m_level > 0)
00217 {
00218 crsePhi = a_phiLevel[m_level-1];
00219 }
00220
00221 T& phi = *a_phiLevel[m_level];
00222 m_levelopPtr->applyOpIcfHphys(phi, crsePhi, a_LOfPhi);
00223
00224
00225 if (m_level < m_parent->m_finestLevel)
00226 {
00227 reflux(a_phiLevel, a_LOfPhi);
00228 }
00229 }
00230
00235 template <class T>
00236 void GenAMRLevelMG<T>::computeAMRResidual(Vector<T* >& a_phiLevel,
00237 const Vector<T* >& a_rhsLevel)
00238 {
00239 assert(isDefined());
00240
00241 T& rhs = *a_rhsLevel[m_level];
00242
00243 applyAMROperator(a_phiLevel,m_resid);
00244 m_levelopPtr->negDiff(m_resid,rhs);
00245 }
00246
00251 template <class T>
00252 void GenAMRLevelMG<T>::computeAMRResidual(T& a_resid,
00253 Vector<T* >& a_phiLevel,
00254 const Vector<T* >& a_rhsLevel)
00255 {
00256 assert(isDefined());
00257
00258 T& rhs = *a_rhsLevel[m_level];
00259
00260 applyAMROperator(a_phiLevel, a_resid);
00261 m_levelopPtr->diff(a_resid,rhs);
00262 m_levelopPtr->negate(a_resid);
00263 }
00264
00269 template <class T>
00270 void GenAMRLevelMG<T>::computeAMRResidualHphys(Vector<T* >& a_phiLevel,
00271 const Vector<T* >& a_rhsLevel)
00272 {
00273 assert(isDefined());
00274
00275 T& rhs = *a_rhsLevel[m_level];
00276
00277 applyAMROperatorHphys(a_phiLevel, m_resid);
00278 m_levelopPtr->diff(m_resid,rhs);
00279 m_levelopPtr->negate(m_resid);
00280 }
00281
00286 template <class T>
00287 void GenAMRLevelMG<T>::upSweep(Vector<T *>& a_phiLevel,
00288 const Vector<T *>& a_rhsLevel)
00289 {
00290 assert(isDefined());
00291
00292 T& phi = *a_phiLevel[m_level];
00293 const T& rhs = *a_rhsLevel[m_level];
00294
00295 assert(phi.nComp() == rhs.nComp());
00296
00297
00298
00299 if (m_level > 0)
00300 {
00301
00302
00303 GenAMRLevelMG& nextCoarser = *m_parent->m_amrmgLevel[m_level-1];
00304 m_mginterp.interpToFine(m_corr, nextCoarser.m_corr);
00305
00306 m_levelopPtr->applyOpIcfHphys(m_corr, &nextCoarser.m_corr, m_lofPhi);
00307 }
00308
00309
00310
00311
00312 m_levelopPtr->diff(m_resid,m_lofPhi);
00313
00314 m_levelopPtr->setToZero(m_dcorr);
00315 smooth(m_dcorr,m_resid);
00316
00317
00318
00319 m_levelopPtr->sum(m_corr,m_dcorr);
00320 m_levelopPtr->sum(m_phiSave,m_corr);
00321
00322 m_levelopPtr->copy(phi,m_phiSave);
00323 }
00324
00329 template <class T>
00330 void GenAMRLevelMG<T>::downSweep(Vector<T* >& a_phiLevel,
00331 const Vector<T* >& a_rhsLevel)
00332 {
00333 assert(isDefined());
00334
00335 T & phi = *a_phiLevel[m_level];
00336 T & rhs = *a_rhsLevel[m_level];
00337
00338 assert(phi.nComp() == rhs.nComp());
00339
00340 m_levelopPtr->setToZero(m_corr);
00341 m_levelopPtr->copy(m_phiSave,phi);
00342
00343
00344 smooth(m_corr,m_resid);
00345
00346
00347 m_levelopPtr->sum(phi,m_corr);
00348
00349
00350
00351 if (m_level > 0)
00352 {
00353
00354
00355
00356 GenAMRLevelMG& nextCoarser = *m_parent->m_amrmgLevel[m_level-1];
00357 GenAMRLevelMGOp<T>& coarLevelop = *(nextCoarser.m_levelopPtr);
00358
00359 coarLevelop.setToZero(nextCoarser.m_corr);
00360
00361
00362
00363
00364 m_levelopPtr->applyOpH(m_corr,m_lofPhi);
00365 m_levelopPtr->diff(m_lofPhi,m_resid);
00366 m_levelopPtr->negate(m_lofPhi);
00367
00368 #if FIXIT
00369 m_averageOp.averageToCoarse(m_resC, m_lofPhi);
00370 #endif
00371
00372 nextCoarser.computeAMRResidualHphys(a_phiLevel, a_rhsLevel);
00373
00374
00375
00376 m_resC.copyTo(m_resC.interval(),
00377 nextCoarser.m_resid,
00378 nextCoarser.m_resid.interval(), m_residualCopier);
00379 }
00380 }
00381
00383 template <class T>
00384 Vector<Real> GenAMRLevelMG<T>::computeResidualNorm(int a_normType) const
00385 {
00386 assert(isDefined());
00387
00388 Vector<Real> normPeterson(m_resid.nComp(),0.0);
00389 normPeterson = computeNorm(m_resid, a_normType);
00390
00391 return normPeterson;
00392 }
00393
00394 template <class T>
00395 GenAMRLevelMGOp<T>* GenAMRLevelMG<T>::levelOpPtr() const
00396 {
00397 return m_levelopPtr;
00398 }
00399
00400
00401 template <class T>
00402 Vector<Real> GenAMRLevelMG<T>::computeNorm(const T& a_mfinput,
00403 int a_normType) const
00404 {
00405 assert(isDefined());
00406 assert((a_normType >= 0) && (a_normType <= 2));
00407
00408
00409 T mfab;
00410 mfab.define(a_mfinput, a_mfinput.interval());
00411
00412
00413 int ncomp = mfab.nComp();
00414
00415 Vector<Real> normTot(ncomp,0.0);
00416
00417 if (m_level < m_parent->m_finestLevel)
00418 {
00419 #if FIXIT
00420 const DisjointBoxLayout& fineGrids = m_parent->m_gridsLevel[m_level+1];
00421 int nrefFine = m_parent->m_refRatio[m_level];
00422
00423 DataIterator dit = mfab.dataIterator();
00424 for (dit.ok(); dit.ok(); ++dit)
00425 {
00426 LayoutIterator litFine = fineGrids.layoutIterator();
00427
00428 for (litFine.reset(); litFine.ok(); ++litFine)
00429 {
00430 Box overlayBox = mfab[dit()].box();
00431 Box coarsenedGrid = coarsen(fineGrids[litFine()], nrefFine);
00432
00433 overlayBox &= coarsenedGrid;
00434
00435 if (!overlayBox.isEmpty())
00436 {
00437 mfab[dit()].setVal(0.0,overlayBox,0, ncomp);
00438 }
00439 }
00440 }
00441 #endif
00442 }
00443
00444 for (int comp = 0; comp < mfab.nComp(); comp++)
00445 {
00446 #if FIXIT
00447 Interval thisInterval(comp,comp);
00448
00449 normTot[comp] = norm(mfab, thisInterval, a_normType);
00450 #endif
00451
00452
00453 if (a_normType != 0)
00454 {
00455 Real dx = m_parent->m_dxLevel[m_level];
00456 Real expon = SpaceDim/a_normType;
00457 Real normfac = pow(dx, expon);
00458 normTot[comp] *= normfac;
00459 }
00460 }
00461
00462 return normTot;
00463 }
00464
00466 template <class T>
00467 void GenAMRLevelMG<T>::smooth(T& a_soln,
00468 const T& a_rhs)
00469 {
00470 assert(isDefined());
00471 assert(a_soln.ghostVect() >= IntVect::TheUnitVector());
00472 assert(a_soln.getBoxes() == m_parent->m_gridsLevel[m_level]);
00473 assert(a_rhs.getBoxes() == m_parent->m_gridsLevel[m_level]);
00474
00475
00476 m_levelMG.mgRelax(a_soln, a_rhs, false);
00477 }
00478
00479 template <class T>
00480 void GenAMRLevelMG<T>::clearMemory()
00481 {
00482 if (m_levelopPtr != NULL)
00483 {
00484 delete m_levelopPtr;
00485 }
00486 m_levelopPtr = NULL;
00487 }
00488
00489 template <class T>
00490 void GenAMRLevelMG<T>::setDefaultValues()
00491 {
00492 m_isDefined = false;
00493 m_parent = NULL;
00494 m_level = -1;
00495 m_isDefined = false;
00496 m_arrayViewVerbose = false;
00497 m_levelopPtr = NULL;
00498 }
00499
00507 template <class T>
00508 void GenAMRLevelMG<T>::reflux(Vector<T *>& a_phiLevel,
00509 T& a_LOfPhi)
00510 {
00511 assert(isDefined());
00512 assert(m_level < m_parent->m_finestLevel);
00513
00514 GenAMRLevelMG& higher = *(m_parent->m_amrmgLevel[m_level + 1]);
00515
00516 assert(higher.isDefined());
00517
00518 #if FIXIT
00519 LevelFluxRegister& finelevfr = higher.m_levfluxreg;
00520 #endif
00521
00522
00523 initFRCoarse(a_phiLevel);
00524
00525 incrementFRFine(a_phiLevel);
00526 Real dxlevel = m_parent->m_dxLevel[m_level];
00527
00528 assert(dxlevel > 0);
00529
00530 #if FIXIT
00531 Real scale = 1.0/dxlevel;
00532 finelevfr.reflux(a_LOfPhi, scale);
00533 #endif
00534 }
00535
00537
00540 template <class T>
00541 void GenAMRLevelMG<T>::initFRCoarse(Vector<T *>& a_phiLevel)
00542 {
00543 assert(isDefined());
00544 assert(m_level < m_parent->m_finestLevel);
00545
00546 GenAMRLevelMG& higher = *(m_parent->m_amrmgLevel[m_level + 1]);
00547
00548 assert(higher.isDefined());
00549
00550 LevelFluxRegister& finelevfr = higher.m_levfluxreg;
00551
00552
00553
00554 finelevfr.setToZero();
00555
00556 #if FIXIT
00557 Interval interv(0,a_phiLevel[m_level]->nComp()-1);
00558 T& phic = *a_phiLevel[m_level];
00559
00560 DataIterator dit = phic.dataIterator();
00561 for (dit.reset(); dit.ok(); ++dit)
00562 {
00563 const T& coarfab = phic[dit()];
00564
00565 for (int idir = 0; idir < SpaceDim; idir++)
00566 {
00567 T coarflux;
00568 m_levelopPtr->getFlux(coarflux, coarfab, dit(), idir);
00569
00570 Real scale = 1.0;
00571 finelevfr.incrementCoarse(coarflux,
00572 scale,dit(),
00573 interv,interv,idir);
00574 }
00575 }
00576 #endif
00577 }
00578
00582 template <class T>
00583 void GenAMRLevelMG<T>::incrementFRFine(Vector<T *>& a_phiLevel)
00584 {
00585 assert(isDefined());
00586 assert(m_level < m_parent->m_finestLevel);
00587
00588 GenAMRLevelMG& higher = *(m_parent->m_amrmgLevel[m_level+1]);
00589
00590 assert(higher.isDefined());
00591
00592 #if FIXIT
00593 LevelFluxRegister& finelevfr = higher.m_levfluxreg;
00594 #endif
00595
00596
00597
00598
00599 #if FIXIT
00600 T& phif = *a_phiLevel[m_level + 1];
00601 T& phic = *a_phiLevel[m_level];
00602 Interval interv = phif.interval();
00603
00606 higher.m_levelopPtr->CFInterp(phif, phic);
00607 phif.exchange(phif.interval(), m_fineExchangeCopier);
00608
00609 DataIterator ditf = phif.dataIterator();
00610 for (ditf.reset(); ditf.ok(); ++ditf)
00611 {
00612 const T& phifFab = phif[ditf()];
00613
00614 for (int idir = 0; idir < SpaceDim; idir++)
00615 {
00616 SideIterator sit;
00617 for (sit.begin(); sit.ok(); sit.next())
00618 {
00619 Side::LoHiSide hiorlo = sit();
00620 Box fabbox;
00621
00622 if (sit() == Side::Lo)
00623 {
00624 fabbox = adjCellLo(phifFab.box(),idir, 2);
00625 fabbox.shift(idir, 2);
00626 }
00627 else
00628 {
00629 fabbox = adjCellHi(phifFab.box(),idir, 2);
00630 fabbox.shift(idir, -2);
00631 }
00632
00633 assert(!fabbox.isEmpty());
00634
00635 T phifab(fabbox, phif.nComp());
00636 phifab.copy(phifFab);
00637
00638 T fineflux;
00639 higher.m_levelopPtr->getFlux(fineflux, phifab, ditf(), idir);
00640
00641 Real scale = 1.0;
00642 finelevfr.incrementFine(fineflux, scale, ditf(),
00643 interv, interv, idir, hiorlo);
00644 }
00645 }
00646 }
00647 #endif
00648 }
00649
00650 template <class T>
00651 void GenAMRLevelMG<T>::setArrayViewVerbose(bool a_verbosity)
00652 {
00653 m_arrayViewVerbose = a_verbosity;
00654 }
00655
00656 #endif