00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _AMRTGA_H_
00012 #define _AMRTGA_H_
00013
00014 #include <cmath>
00015 #include <cstdlib>
00016 #include <cstdio>
00017 #include <iostream>
00018 #include <iomanip>
00019 #include <fstream>
00020 #include <string>
00021 #include "AMRMultiGrid.H"
00022 #include "NamespaceHeader.H"
00023
00024
00025
00026
00027
00028
00029
00030 template <class T>
00031 class TGAHelmOp : public AMRLevelOp<T>
00032 {
00033 public:
00034
00035
00036
00037 TGAHelmOp()
00038 :m_isTimeDependent(false),
00039 m_phonyIdentityCoef(NULL)
00040 {
00041 }
00042
00043
00044
00045
00046
00047 explicit TGAHelmOp(bool a_isTimeDependent)
00048 :m_isTimeDependent(a_isTimeDependent),
00049 m_phonyIdentityCoef(NULL)
00050 {
00051 }
00052
00053
00054 virtual ~TGAHelmOp()
00055 {
00056 }
00057
00058
00059
00060
00061 virtual void setAlphaAndBeta(const Real& a_alpha,
00062 const Real& a_beta) = 0;
00063
00064
00065
00066
00067
00068
00069
00070
00071 virtual void diagonalScale(T& a_rhs, bool a_kappaWeighted)
00072 {
00073 MayDay::Error("Two argument version of diagonalScale called but not implemented!");
00074 }
00075
00076
00077 virtual void kappaScale(T& a_rhs)
00078 {
00079
00080 }
00081
00082
00083
00084
00085
00086 virtual void diagonalScale(T& a_rhs)
00087 {
00088 diagonalScale(a_rhs, true);
00089 }
00090
00091
00092
00093
00094 virtual void divideByIdentityCoef(T& a_rhs) = 0;
00095
00096
00097
00098
00099
00100 virtual void applyOpNoBoundary(T& a_ans, const T& a_phi) = 0;
00101
00102
00103
00104
00105 virtual void setTime(Real a_time)
00106 {
00107 ;
00108 }
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118 virtual void setTime(Real a_oldTime, Real a_mu, Real a_dt)
00119 {
00120 setTime(a_oldTime + a_mu * a_dt);
00121 }
00122
00123
00124 bool isTimeDependent() const
00125 {
00126 return m_isTimeDependent;
00127 }
00128
00129
00130 virtual T& identityCoef()
00131 {
00132 MayDay::Error("Access to identity coefficient not allowed for this operator");
00133
00134
00135 return *m_phonyIdentityCoef;
00136 }
00137
00138 private:
00139
00140
00141 TGAHelmOp(const TGAHelmOp&);
00142 TGAHelmOp& operator=(const TGAHelmOp&);
00143
00144
00145
00146 bool m_isTimeDependent;
00147
00148
00149
00150 T* m_phonyIdentityCoef;
00151 };
00152
00153
00154
00155
00156
00157
00158 template <class T, class TFlux>
00159 class LevelTGAHelmOp : public TGAHelmOp< T >
00160 {
00161 public:
00162
00163
00164
00165 LevelTGAHelmOp()
00166 :TGAHelmOp<T>::TGAHelmOp(false)
00167 {
00168 }
00169
00170
00171
00172
00173
00174 LevelTGAHelmOp(bool a_isTimeIndependent)
00175 :TGAHelmOp<T>::TGAHelmOp(a_isTimeIndependent)
00176 {
00177 }
00178
00179
00180 virtual ~LevelTGAHelmOp()
00181 {
00182 }
00183
00184
00185
00186
00187 virtual void fillGrad(const T& a_phi) = 0;
00188
00189
00190 virtual void getFlux(TFlux& a_flux,
00191 const T& a_data,
00192 const Box& a_grid,
00193 const DataIndex& a_dit,
00194 Real a_scale) = 0;
00195
00196 };
00197
00198
00199
00200
00201
00202
00203 template <class T>
00204 class AMRTGA
00205 {
00206 public:
00207
00208
00209 TGAHelmOp<T>* newOp(const ProblemDomain& a_indexSpace,
00210 const AMRLevelOpFactory<T>& a_opFact)
00211 {
00212 AMRLevelOpFactory<T>& opFact = (AMRLevelOpFactory<T>&) a_opFact;
00213 TGAHelmOp<T>* retval = (TGAHelmOp<T>*) opFact.AMRnewOp(a_indexSpace);
00214 return retval;
00215 }
00216
00217
00218 ~AMRTGA();
00219
00220
00221
00222
00223 AMRTGA(const RefCountedPtr<AMRMultiGrid<T> > & a_solver,
00224 const AMRLevelOpFactory<T>& a_factory,
00225 const ProblemDomain& a_level0Domain,
00226 const Vector<int>& a_refRat,
00227 int a_numLevels = -1,
00228 int a_verbosity = 0);
00229
00230
00231
00232
00233
00234
00235
00236 void oneStep(Vector<T*>& a_phiNew,
00237 Vector<T*>& a_phiOld,
00238 Vector<T*>& a_source,
00239 const Real& a_dt,
00240 int a_lbase,
00241 int a_lmax,
00242 Real a_timeOld = 0);
00243
00244
00245 void resetAlphaAndBeta(const Real& a_alpha,
00246 const Real& a_beta);
00247
00248 void setTime(Real time);
00249
00250 protected:
00251 void solveHelm(Vector<T*>& a_ans,
00252 Vector<T*>& a_rhs,
00253 int a_lbase,
00254 int a_lmax,
00255 Real a_mu,
00256 Real a_dt);
00257
00258 void applyHelm(Vector<T*>& a_ans,
00259 Vector<T*>& a_source,
00260 int a_lbase,
00261 int a_lmax,
00262 Real a_mu,
00263 Real a_dt,
00264 bool a_homogeneousBC);
00265
00266 void setMu();
00267
00268 void createData(Vector<T* >& a_source,
00269 int a_lbase,
00270 int a_lmax);
00271
00272 private:
00273
00274
00275 Vector<TGAHelmOp<T> * > m_ops;
00276 ProblemDomain m_level0Domain;
00277 Vector<int> m_refRat;
00278 RefCountedPtr<AMRMultiGrid<T> > m_solver;
00279 Real m_mu1, m_mu2, m_mu3, m_mu4;
00280 int m_verbosity, m_numLevels;
00281 bool m_dataCreated;
00282 Vector<T*> m_rhst;
00283 Vector<T*> m_srct;
00284
00285
00286 AMRTGA(const AMRTGA<T>& a_opin)
00287 {
00288 MayDay::Error("invalid operator");
00289 }
00290
00291 void operator=(const AMRTGA<T>& a_opin)
00292 {
00293 MayDay::Error("invalid operator");
00294 }
00295
00296
00297 AMRTGA()
00298 {
00299 MayDay::Error("invalid operator");
00300 }
00301 };
00302
00303
00304 template <class T>
00305 void AMRTGA<T>::
00306 resetAlphaAndBeta(const Real& a_alpha,
00307 const Real& a_beta)
00308 {
00309 Vector<MGLevelOp<T>* > ops = m_solver->getAllOperators();
00310 for (int iop = 0; iop < ops.size(); iop++)
00311 {
00312
00313 TGAHelmOp<T>* helmop = (TGAHelmOp<T>*) ops[iop];
00314 helmop->setAlphaAndBeta(a_alpha, a_beta);
00315 }
00316 }
00317
00318
00319 template <class T>
00320 void AMRTGA<T>::
00321 setTime(Real a_time)
00322 {
00323 Vector<MGLevelOp<T>* > ops = m_solver->getAllOperators();
00324 for (int iop = 0; iop < ops.size(); iop++)
00325 {
00326
00327 TGAHelmOp<T>* helmop = (TGAHelmOp<T>*) ops[iop];
00328 helmop->setTime(a_time);
00329 }
00330 }
00331
00332
00333 template <class T>
00334 AMRTGA<T>::
00335 AMRTGA(const RefCountedPtr<AMRMultiGrid<T> >& a_solver,
00336 const AMRLevelOpFactory<T> & a_opFact,
00337 const ProblemDomain& a_level0Domain,
00338 const Vector<int>& a_refRat,
00339 int a_numLevels,
00340 int a_verbosity)
00341 {
00342
00343 m_verbosity = a_verbosity;
00344 m_level0Domain = a_level0Domain;
00345 m_refRat = a_refRat;
00346 m_solver = a_solver;
00347 m_numLevels = a_numLevels;
00348 if (m_numLevels < 0)
00349 {
00350 m_numLevels = a_refRat.size();
00351 }
00352
00353 m_ops.resize(m_numLevels);
00354 Vector< AMRLevelOp<T> * >& amrops = m_solver->getAMROperators();
00355 for (int ilev = 0; ilev < m_numLevels; ilev++)
00356 {
00357 m_ops[ilev] = dynamic_cast<TGAHelmOp<T>* >(amrops[ilev]);
00358 if (m_ops[ilev]==NULL)
00359 {
00360 MayDay::Error("dynamic cast failed---is that operator really a TGAHelmOp?");
00361 }
00362 }
00363
00364 setMu();
00365 m_dataCreated = false;
00366 }
00367 template <class T>
00368 void AMRTGA<T>::
00369 setMu()
00370 {
00371 Real tgaEpsilon = 1.e-12;
00372 #ifdef CH_USE_FLOAT
00373 tgaEpsilon = sqrt(tgaEpsilon);
00374 #endif
00375 Real a = 2.0 - sqrt(2.0) - tgaEpsilon;
00376 m_mu1 = (a - sqrt( a*a - 4.0*a + 2.0))/2.0 ;
00377 m_mu2 = (a + sqrt( a*a - 4.0*a + 2.0))/2.0 ;
00378 m_mu3 = (1.0 - a);
00379 m_mu4 = 0.5 - a;
00380 if (m_verbosity > 4)
00381 {
00382 pout() << " AMRTGA:: epsilon = " << tgaEpsilon << std::endl;
00383 }
00384 }
00385
00386 template <class T>
00387 void AMRTGA<T>::
00388 createData(Vector<T* >& a_source,
00389 int a_lbase,
00390 int a_lmax)
00391 {
00392 m_dataCreated = true;
00393 m_rhst.resize(a_source.size(), NULL);
00394 m_srct.resize(a_source.size(), NULL);
00395 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00396 {
00397 m_rhst[ilev] = new T();
00398 m_srct[ilev] = new T();
00399 m_ops[ilev]->create(*m_rhst[ilev], *a_source[ilev]);
00400 m_ops[ilev]->create(*m_srct[ilev], *a_source[ilev]);
00401 }
00402 }
00403
00404 template <class T>
00405 AMRTGA<T>::~AMRTGA()
00406 {
00407 for (int ilev = 0; ilev < m_rhst.size(); ilev++)
00408 {
00409 if (m_rhst[ilev] != NULL)
00410 {
00411 delete m_rhst[ilev];
00412 delete m_srct[ilev];
00413 m_rhst[ilev] = NULL;
00414 m_srct[ilev] = NULL;
00415 }
00416 }
00417 }
00418 template <class T>
00419 void AMRTGA<T>::
00420 oneStep(Vector<T* >& a_phiNew,
00421 Vector<T* >& a_phiOld,
00422 Vector<T* >& a_source,
00423 const Real& a_dt,
00424 int a_lbase,
00425 int a_lmax,
00426 Real a_told)
00427 {
00428 if (!m_dataCreated)
00429 {
00430 createData(a_source, a_lbase, a_lmax);
00431 }
00432
00433 if (m_verbosity > 3)
00434 {
00435 pout() << " AMRTGA:: starting mu4 operation" << std::endl;
00436 }
00437
00438 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00439 {
00440 m_ops[ilev]->setToZero(*m_srct[ilev]);
00441 m_ops[ilev]->incr(*m_srct[ilev], *a_source[ilev], 1.0);
00442
00443
00444 m_ops[ilev]->divideByIdentityCoef(*m_srct[ilev]);
00445 }
00446
00447
00448
00449 applyHelm(m_rhst, m_srct, a_lbase, a_lmax, m_mu4, a_dt, true);
00450
00451 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00452 {
00453
00454 m_ops[ilev]->scale( *m_rhst[ilev], a_dt);
00455 }
00456
00457 if (m_verbosity > 3)
00458 {
00459 pout() << " AMRTGA:: starting mu3 operation" << std::endl;
00460 }
00461
00462
00463 setTime(a_told);
00464
00465
00466 applyHelm(a_phiNew, a_phiOld, a_lbase, a_lmax, m_mu3, a_dt, false);
00467
00468 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00469 {
00470
00471 m_ops[ilev]->incr(*m_rhst[ilev], *a_phiNew[ilev], 1.0);
00472 }
00473
00474 if (m_verbosity > 2)
00475 {
00476 pout() << " AMRTGA:: starting mu2 operation" << std::endl;
00477 }
00478
00479 setTime(a_told + a_dt*(m_mu2 + m_mu3));
00480
00481 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00482 {
00483 m_ops[ilev]->assignLocal(*a_phiNew[ilev], *a_phiOld[ilev]);
00484 }
00485 solveHelm(a_phiNew, m_rhst, a_lbase, a_lmax, m_mu2, a_dt);
00486 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00487 {
00488
00489 m_ops[ilev]->assignLocal(*m_rhst[ilev], *a_phiNew[ilev]);
00490 }
00491
00492
00493 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00494 {
00495 m_ops[ilev]->diagonalScale(*m_rhst[ilev]);
00496 }
00497
00498 if (m_verbosity > 2)
00499 {
00500 pout() << " AMRTGA:: starting mu1 operation" << std::endl;
00501 }
00502
00503 setTime(a_told + a_dt);
00504
00505 for (int ilev = a_lbase; ilev <= a_lmax; ilev++)
00506 {
00507 m_ops[ilev]->assignLocal(*a_phiNew[ilev], *a_phiOld[ilev]);
00508 }
00509 solveHelm(a_phiNew, m_rhst, a_lbase, a_lmax, m_mu1, a_dt);
00510 }
00511
00512 template <class T>
00513 void AMRTGA<T>::
00514 applyHelm(Vector<T*>& a_ans,
00515 Vector<T*>& a_phi,
00516 int a_lbase,
00517 int a_lmax,
00518 Real a_mu,
00519 Real a_dt,
00520 bool a_homogeneousBC)
00521 {
00522 Real factor = a_mu*a_dt;
00523
00524 resetAlphaAndBeta(1.0, factor);
00525
00526 m_solver->computeAMROperator(a_ans,
00527 a_phi,
00528 a_lmax,
00529 a_lbase,
00530 a_homogeneousBC);
00531
00532
00533
00534
00535
00536 }
00537
00538 template <class T>
00539 void AMRTGA<T>::
00540 solveHelm(Vector<T*>& a_ans,
00541 Vector<T*>& a_rhs,
00542 int a_lbase,
00543 int a_lmax,
00544 Real a_mu,
00545 Real a_dt)
00546 {
00547 Real factor = -a_mu*a_dt;
00548
00549 resetAlphaAndBeta(1.0, factor);
00550
00551 m_solver->solveNoInit(a_ans,
00552 a_rhs,
00553 a_lmax,
00554 a_lbase,
00555 false);
00556 if (m_solver->m_exitStatus==1 && m_verbosity>3)
00557 {
00558 pout() << "AMRTGA:: WARNING: solver exitStatus == 1" << std::endl;
00559 }
00560 }
00561
00562 #include "NamespaceFooter.H"
00563 #endif