Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

GenAMRLevelMGImplem.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 _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   // put reasonable value into refinement ratio
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     // nCoarserLevels = log2(reftoCoarse) - 1
00105     // bug fixed by petermc, 15 Apr 2002
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   // residual,lofphi has no ghost cells, corr and phi have 1 ghost cell
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   // ParmParse pp("amrlevelmg");
00158   // m_arrayViewVerbose = pp.contains("verbose");
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   // operator on this level including interpolated bc's from Level-1
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   // now reflux to enforce flux-matching from finer levels...
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   // operator on this level including interpolated bc's from Level-1
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   // now reflux to enforce flux-matching from finer levels...
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   // Interpolate corrections from next coarser level to the correction
00298   // field at this level.
00299   if (m_level > 0)
00300   {
00301     // Initialize correction at the next coarser level.
00302     // this uses the two-level only operator (Lnf)
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   // Finish resid calc,
00310   // initialize the correction to the correction,
00311   // and apply smoother.
00312   m_levelopPtr->diff(m_resid,m_lofPhi);
00313 
00314   m_levelopPtr->setToZero(m_dcorr);
00315   smooth(m_dcorr,m_resid);
00316 
00317   // Increment correction.
00318   // Increment saved value of phi with corr, and overwrite phi.
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   // Apply smoother.
00344   smooth(m_corr,m_resid);
00345 
00346   // Update phi.
00347   m_levelopPtr->sum(phi,m_corr);
00348 
00349   // Compute residual for the next coarser level.
00350   // Form residual on next coarser level.
00351   if (m_level > 0)
00352   {
00353     // Initialize correction at the next coarser level.
00354     // this has to be done before applyOpI
00355     // int reftoCoarse = m_parent->m_refRatio[m_level-1];
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     // petermc, 18 Apr 2002, replaced this with applyOpH
00362     // because coarser level is zero anyway.
00363     // m_levelopPtr->applyOpIcfHphys(m_corr, &nextCoarser.m_corr, m_lofPhi);
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     // overwrite residual on Level-1 with
00375     // coarsened residual from this level
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 // returns normType norm of mfab
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   // create temps so inputs do not get changed
00409   T mfab;
00410   mfab.define(a_mfinput, a_mfinput.interval());
00411 
00412   // compute the bloody norm
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     // this function does the wacky boxlib-type norm
00449     normTot[comp] = norm(mfab, thisInterval, a_normType);
00450 #endif
00451 
00452     // so we normalize it for sanity's sake
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   } // end loop over components
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   // no bottom solve here
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   // finelevfr.setToZero(); called in initFRCoarse
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   // looping through every box in this grid
00553   // and fill fluxregisters with coarse flux
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   // flux register stuff
00597   // looping through every box in finer grid
00598   // and increment fluxregisters with fine flux
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

Generated on Wed Apr 16 14:31:04 2003 for EBChombo by doxygen1.2.16