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 _GENLEVELMGIMPLEM_H_
00029 #define _GENLEVELMGIMPLEM_H_
00030
00031 #include "GenLevelMGF_F.H"
00032
00033
00034 template <class T>
00035 GenLevelMG<T>::GenLevelMG()
00036 {
00037 setDefaultValues();
00038 }
00039
00041
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
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
00079
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
00087 setDefaultValues();
00088
00089 define(a_L, a_refCoarse, a_opin);
00090 }
00091
00092
00093
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
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
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
00140
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
00157
00158
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
00168 if (m_nCoarserLevels != 0)
00169 {
00170
00171
00172
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
00195
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
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
00266 if (m_lCoarsePtr != NULL)
00267 {
00268
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
00278
00279 m_levelopPtr->applyOpH(a_soln,m_resid);
00280 m_levelopPtr->diff(m_resid,a_rhs);
00281 m_levelopPtr->negate(m_resid);
00282
00283
00284 #if FIXIT
00285 assert(m_averageOp.isDefined());
00286
00287 m_averageOp.averageToCoarse(m_crseResid, m_resid);
00288 #endif
00289
00290
00291 m_lCoarsePtr->mgRelax(m_crseCorr, m_crseResid, a_bottomSolveFlag);
00292
00293
00294 crseCorrect(a_soln, m_crseCorr, m_refToCoar);
00295
00296
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
00306
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
00315 for (int iter = 0; iter < m_numBottomGSRB; iter++)
00316 {
00317 m_levelopPtr->smooth(a_soln,a_rhs);
00318 }
00319
00320 m_levelopPtr->bottomSmoother(a_soln,a_rhs);
00321 }
00322 else
00323 {
00324
00325
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
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
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