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

GenLevelMGImplem.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 _GENLEVELMGIMPLEM_H_
00029 #define _GENLEVELMGIMPLEM_H_
00030 
00031 #include "GenLevelMGF_F.H"
00032 
00033 // default constructor
00034 template <class T>
00035 GenLevelMG<T>::GenLevelMG()
00036 {
00037   setDefaultValues();
00038 }
00039 
00041 // this calls the levelmg big define function
00042 template <class T>
00043 GenLevelMG<T>::GenLevelMG(const DisjointBoxLayout&     a_ba,
00044                           const DisjointBoxLayout*     a_baseBaPtr,
00045                           Real                         a_dxLevel,
00046                           int                          a_refRatio,
00047                           const Box&                   a_domain,
00048                           int                          a_nCoarserLevels,
00049                           const GenLevelMGOp<T>* const a_opin,
00050                           int                          a_ncomp)
00051 {
00052   setDefaultValues();
00053 
00054   ProblemDomain physdomain(a_domain);
00055   define(a_ba,a_baseBaPtr, a_dxLevel, a_refRatio, physdomain,
00056          a_nCoarserLevels, a_opin, a_ncomp);
00057 }
00058 
00060 // this calls the levelmg big define function
00061 template <class T>
00062 GenLevelMG<T>::GenLevelMG(const DisjointBoxLayout&     a_ba,
00063                           const DisjointBoxLayout*     a_baseBaPtr,
00064                           Real                         a_dxLevel,
00065                           int                          a_refRatio,
00066                           const ProblemDomain&         a_domain,
00067                           int                          a_nCoarserLevels,
00068                           const GenLevelMGOp<T>* const a_opin,
00069                           int                          a_ncomp)
00070 {
00071   setDefaultValues();
00072 
00073   define(a_ba,a_baseBaPtr, a_dxLevel, a_refRatio, a_domain,
00074          a_nCoarserLevels, a_opin, a_ncomp);
00075 }
00076 
00077 // --------------------------------------------------------------
00078 // constructor for coarsened version of levelMG
00079 // refcoarse is the ratio from coarsened thing to this thing
00080 // --------------------------------------------------------------
00081 template <class T>
00082 GenLevelMG<T>::GenLevelMG(const GenLevelMG&      a_L,
00083                           int                    a_refCoarse,
00084                           const GenLevelMGOp<T>* a_opin)
00085 {
00086   // set pointers to NULL so define does not try to delete them
00087   setDefaultValues();
00088 
00089   define(a_L, a_refCoarse, a_opin);
00090 }
00091 
00092 // ------------------------------------------------------------
00093 // destructor
00094 // ------------------------------------------------------------
00095 template <class T>
00096 GenLevelMG<T>::~GenLevelMG()
00097 {
00098   clearMemory();
00099 }
00100 
00101 template <class T>
00102 bool GenLevelMG<T>::isDefined() const
00103 {
00104   return m_isDefined;
00105 }
00106 
00107 // corresponding define function
00108 template <class T>
00109 void GenLevelMG<T>::define(const DisjointBoxLayout&     a_ba,
00110                            const DisjointBoxLayout*     a_baseBaPtr,
00111                            Real                         a_dxLevel,
00112                            int                          a_refRatio,
00113                            const  Box&                  a_domain,
00114                            int                          a_nCoarserLevels,
00115                            const GenLevelMGOp<T>* const a_opin,
00116                            int                          a_ncomp)
00117 {
00118   ProblemDomain physdomain(a_domain);
00119   define(a_ba, a_baseBaPtr, a_dxLevel, a_refRatio, a_domain,
00120          a_nCoarserLevels, a_opin, a_ncomp);
00121 }
00122 
00123 // corresponding define function
00124 template <class T>
00125 void GenLevelMG<T>::define(const DisjointBoxLayout&     a_ba,
00126                            const DisjointBoxLayout*     a_baseBaPtr,
00127                            Real                         a_dxLevel,
00128                            int                          a_refRatio,
00129                            const  ProblemDomain&        a_domain,
00130                            int                          a_nCoarserLevels,
00131                            const GenLevelMGOp<T>* const a_opin,
00132                            int                          a_ncomp)
00133 {
00134   assert(a_opin != NULL);
00135   assert(a_nCoarserLevels >= 0);
00136   assert(!a_domain.isEmpty());
00137   assert(a_ba.checkPeriodic(a_domain));
00138 
00139   // either there are no coarser levels
00140   // or we have a legitimate ref ratio
00141   assert((a_refRatio > 0) || (a_baseBaPtr == NULL));
00142   assert(a_dxLevel > 0);
00143 
00144   clearMemory();
00145 
00146   m_ba = a_ba;
00147   m_baseBaPtr = a_baseBaPtr;
00148 
00149   m_dxLevel = a_dxLevel;
00150   m_domain  = a_domain;
00151 
00152   m_nCoarserLevels = a_nCoarserLevels;
00153 
00154   m_isDefined = true;
00155   m_levelopPtr = a_opin->newOp();
00156   // no need to do inhomgeneous CFInterp here
00157   // all levelmg operations (smooth, etc) use
00158   // only homogeneous cf interpolation
00159 #if FIXIT
00160   bool homogeneousOnly = true;
00161   m_levelopPtr->define(m_ba,  m_baseBaPtr,
00162                        m_dxLevel,  a_refRatio,
00163                        m_domain, homogeneousOnly, a_ncomp);
00164 #endif
00165 
00166   m_levelopPtr->defineData(m_resid);
00167   // recursively define MG hierarchy
00168   if (m_nCoarserLevels != 0)
00169   {
00170     // this constructor is called at the finest mg level.
00171     // this means that it might need an averaging operator
00172     // but it does not need an interpolation operator
00173     m_refToCoar = 2;
00174     if (m_baCoarsened.isClosed())
00175     {
00176       m_baCoarsened = DisjointBoxLayout();
00177     }
00178     coarsen(m_baCoarsened, m_ba, m_refToCoar);
00179 #if FIXIT      
00180     m_crseCorr.define(m_baCoarsened,a_ncomp,IntVect::TheUnitVector());
00181     m_crseResid.define(m_baCoarsened,a_ncomp,IntVect::TheZeroVector());
00182     m_averageOp.define(m_ba, m_baCoarsened, a_ncomp, m_refToCoar);
00183 #endif
00184 
00185     m_lCoarsePtr = new GenLevelMG<T>(*this, m_refToCoar, a_opin);
00186     if (m_lCoarsePtr == NULL)
00187     {
00188       MayDay::Error("Out of Memory in GenLevelMG::define");
00189     }
00190   }
00191 }
00192 
00193 // --------------------------------------------------------------
00194 // constructor for coarsened version of levelMG
00195 // refcoarse is the ratio from coarsened thing to this thing
00196 // --------------------------------------------------------------
00197 template <class T>
00198 void GenLevelMG<T>::define(const GenLevelMG&            a_L,
00199                            int                          a_refCoarse,
00200                            const GenLevelMGOp<T>* const a_opin)
00201 {
00202   assert(a_refCoarse == 2);
00203   assert(a_opin != NULL);
00204 
00205   clearMemory();
00206 
00207   m_isDefined = true;
00208 
00209   m_ba = a_L.m_baCoarsened;
00210 
00211   Real dxcoarse = a_refCoarse*a_L.m_dxLevel;
00212   int ncomp = a_L.m_resid.nComp();
00213 
00214   ProblemDomain dprobc = coarsen(a_L.m_domain, a_refCoarse);
00215   m_nCoarserLevels = a_L.m_nCoarserLevels - 1;
00216 
00217   assert(m_nCoarserLevels >= 0);
00218 
00219   m_baseBaPtr = a_L.m_baseBaPtr;
00220   m_dxLevel = dxcoarse;
00221   m_domain = dprobc;
00222   m_resid.define(m_ba, ncomp, IntVect::TheZeroVector());
00223   m_levelopPtr = a_L.m_levelopPtr->newOp();
00224 
00225 #if FIXIT
00226   m_levelopPtr->define(a_L.m_levelopPtr, a_refCoarse);
00227 #endif
00228 
00229   // recursively define MG hierarchy
00230   if (m_nCoarserLevels != 0)
00231   {
00232     m_refToCoar = 2;
00233     coarsen(m_baCoarsened, m_ba, m_refToCoar);
00234 #if FIXIT
00235     m_crseCorr.define(m_baCoarsened,ncomp,IntVect::TheUnitVector());
00236     m_crseResid.define(m_baCoarsened,ncomp,IntVect::TheZeroVector());
00237     m_averageOp.define(m_ba, m_baCoarsened, ncomp, m_refToCoar);
00238 #endif
00239 
00240     m_lCoarsePtr = new GenLevelMG(*this, m_refToCoar, a_opin);
00241     if (m_lCoarsePtr == NULL)
00242     {
00243       MayDay::Error("Out of Memory in GenLevelMG::define");
00244     }
00245   }
00246   else
00247   {
00248     m_lCoarsePtr = NULL;
00249   }
00250 }
00251 
00252 template <class T>
00253 void GenLevelMG<T>::mgRelax(T&       a_soln,
00254                             const T& a_rhs,
00255                             bool     a_bottomSolveFlag)
00256 {
00257   assert(isDefined());
00258 
00259   int ncomp = a_rhs.nComp();
00260 
00261   assert(a_soln.nComp() == ncomp);
00262   assert(ncomp == m_resid.nComp());
00263   assert(a_soln.ghostVect() >= IntVect::TheUnitVector());
00264 
00265   // now, either coarsen or call bottom solver
00266   if (m_lCoarsePtr != NULL)
00267   {
00268     // first, smooth on this level
00269     for (int iter = 0; iter < m_numSmoothDown; iter++)
00270     {
00271       m_levelopPtr->smooth(a_soln,a_rhs);
00272     }
00273 
00274     GenLevelMGOp<T>& crseLevelop = *(m_lCoarsePtr->m_levelopPtr);
00275     crseLevelop.setToZero(m_crseCorr);
00276 
00277     // define residual on this grid
00278     // using homogeneous cf bcs
00279     m_levelopPtr->applyOpH(a_soln,m_resid);
00280     m_levelopPtr->diff(m_resid,a_rhs);
00281     m_levelopPtr->negate(m_resid);
00282 
00283     // coarsen residual and physical boundary condition
00284 #if FIXIT
00285     assert(m_averageOp.isDefined());
00286 
00287     m_averageOp.averageToCoarse(m_crseResid, m_resid);
00288 #endif
00289 
00290     // relax recursively on coarsened level
00291     m_lCoarsePtr->mgRelax(m_crseCorr, m_crseResid, a_bottomSolveFlag);
00292 
00293     // interpolate correction back up and modify solution
00294     crseCorrect(a_soln, m_crseCorr, m_refToCoar);
00295 
00296     // smooth again on this level
00297     for (int iter = 0; iter < m_numSmoothUp; iter++)
00298     {
00299       m_levelopPtr->smooth(a_soln,a_rhs);
00300     }
00301 
00302   }
00303   else if (m_domain.domainBox().numPts() == 1)
00304   {
00305     // grid is 1x1, just need to smooth
00306     // first, smooth on this level
00307     for (int iter = 0; iter < m_numBottomGSRB; iter++)
00308     {
00309       m_levelopPtr->smooth(a_soln,a_rhs);
00310     }
00311   }
00312   else if (a_bottomSolveFlag)
00313   {
00314     // first, smooth on this level
00315     for (int iter = 0; iter < m_numBottomGSRB; iter++)
00316     {
00317       m_levelopPtr->smooth(a_soln,a_rhs);
00318     }
00319     // use bottom smoother
00320     m_levelopPtr->bottomSmoother(a_soln,a_rhs);
00321   }
00322   else
00323   {
00324     // smooth on this level
00325     // do numSmoothDown iterations
00326     for (int iter = 0; iter < m_numSmoothDown; iter++)
00327     {
00328       m_levelopPtr->smooth(a_soln,a_rhs);
00329     }
00330   }
00331 }
00332 
00333 template <class T>
00334 void GenLevelMG<T>::setnumBottomGSRB(int a_numBottomGSRB)
00335 {
00336   m_numBottomGSRB = a_numBottomGSRB;
00337 }
00338 
00339 template <class T>
00340 void GenLevelMG<T>::setnumSmoothUp(int a_numSmoothUp)
00341 {
00342   m_numSmoothUp = a_numSmoothUp;
00343 }
00344 
00345 template <class T>
00346 void GenLevelMG<T>::setnumSmoothDown(int a_numSmoothDown)
00347 {
00348   m_numSmoothDown = a_numSmoothDown;
00349 }
00350 
00351 template <class T>
00352 GenLevelMGOp<T>* GenLevelMG<T>::levelOpPtr()
00353 {
00354   return m_levelopPtr;
00355 }
00356 
00357 template <class T>
00358 GenLevelMG<T>* GenLevelMG<T>::lCoarsePtr()
00359 {
00360   return m_lCoarsePtr;
00361 }
00362 
00363 template <class T>
00364 void GenLevelMG<T>::setDefaultValues()
00365 {
00366   // set defaults
00367   m_numBottomGSRB = 16;
00368   m_numSmoothUp = 4;
00369   m_numSmoothDown = 4;
00370 
00371   m_lCoarsePtr = NULL;
00372   m_levelopPtr = NULL;
00373 
00374   m_dxLevel = -1;
00375 
00376   m_isDefined = false;
00377 }
00378 
00379 template <class T>
00380 void GenLevelMG<T>::clearMemory()
00381 {
00382   if (m_lCoarsePtr != NULL)
00383   {
00384     delete m_lCoarsePtr;
00385     m_lCoarsePtr = NULL;
00386   }
00387 
00388   if (m_levelopPtr != NULL)
00389   {
00390     delete m_levelopPtr;
00391     m_levelopPtr = NULL;
00392   }
00393 
00394   m_isDefined = false;
00395 }
00396 
00397 template <class T>
00398 void GenLevelMG<T>::crseCorrect(T&       a_fine,
00399                                 const T& a_crse,
00400                                 int      a_refRat)
00401 {
00402 #if FIXIT
00403   DataIterator crseIt = a_crse.dataIterator();
00404   const DisjointBoxLayout& crseBoxes = a_crse.getBoxes();
00405   const DisjointBoxLayout& fineBoxes = a_fine.getBoxes();
00406 
00407   for (crseIt.reset(); crseIt.ok(); ++crseIt)
00408   {
00409     const Box& crseBox = crseBoxes[crseIt()];
00410 
00411     const T& crseFab = a_crse[crseIt()];
00412     T& fineFab = a_fine[crseIt()];
00413 
00414     Box fineBox = fineBoxes[crseIt()];
00415 
00416     fineBox.coarsen(a_refRat);
00417     fineBox &= crseBox;
00418 
00419     // c set refinement box
00420     Box nrefbox(IntVect::TheZeroVector(),
00421                 (a_refRat-1)*IntVect::TheUnitVector());
00422 
00423     if (!fineBox.isEmpty())
00424     {
00425       FORT_GENINTERPMG(CHF_FRA(fineFab),
00426                        CHF_FRA(crseFab),
00427                        CHF_BOX(fineBox),
00428                        CHF_CONST_INT(a_refRat),
00429                        CHF_BOX(nrefbox));
00430      }
00431   }
00432 #endif
00433 }
00434 
00435 #endif

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