00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _BASELEVELCRANKNICOLSON_H_
00012 #define _BASELEVELCRANKNICOLSON_H_
00013
00014 #include <iostream>
00015 #include <math.h>
00016 #include "SPACE.H"
00017 #include <stdlib.h>
00018 #include <REAL.H>
00019 #include <Box.H>
00020 #include <DisjointBoxLayout.H>
00021 #include <LevelData.H>
00022 #include <ProblemDomain.H>
00023 #include "AMRTGA.H"
00024 #include "BaseLevelHeatSolver.H"
00025 #include "NamespaceHeader.H"
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 template <class LevelDataType,
00042 class FluxDataType,
00043 class FluxRegisterType>
00044 class BaseLevelCrankNicolson : public BaseLevelHeatSolver<LevelDataType, FluxDataType, FluxRegisterType>
00045 {
00046
00047 public:
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 BaseLevelCrankNicolson(const Vector<DisjointBoxLayout>& a_grids,
00060 const Vector<int>& a_refRat,
00061 const ProblemDomain& a_level0Domain,
00062 RefCountedPtr<AMRLevelOpFactory<LevelDataType> >& a_opFact,
00063 const RefCountedPtr<AMRMultiGrid<LevelDataType> >& a_solver)
00064 :BaseLevelHeatSolver<LevelDataType,FluxDataType,FluxRegisterType>(a_grids, a_refRat, a_level0Domain, a_opFact, a_solver)
00065 {
00066 }
00067
00068
00069 virtual ~BaseLevelCrankNicolson()
00070 {
00071 }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105 void updateSoln(LevelDataType& a_phiNew,
00106 LevelDataType& a_phiOld,
00107 LevelDataType& a_src,
00108 LevelData<FluxDataType>& a_flux,
00109 FluxRegisterType* a_fineFluxRegPtr,
00110 FluxRegisterType* a_crseFluxRegPtr,
00111 const LevelDataType* a_crsePhiOldPtr,
00112 const LevelDataType* a_crsePhiNewPtr,
00113 Real a_oldTime,
00114 Real a_crseOldTime,
00115 Real a_crseNewTime,
00116 Real a_dt,
00117 int a_level,
00118 bool a_zeroPhi = true,
00119 bool a_rhsAlreadyKappaWeighted = false,
00120 int a_fluxStartComponent = 0)
00121 {
00122 CH_assert(!this->m_ops[a_level]->isTimeDependent());
00123 int ncomp = a_phiNew.nComp();
00124 Interval intervBase(0, ncomp-1);
00125 Interval intervFlux(a_fluxStartComponent, a_fluxStartComponent + ncomp-1);
00126
00127 CH_assert(a_level >= 0);
00128 CH_assert(a_level < this->m_grids.size());
00129 CH_assert((a_level == 0) || (a_crsePhiOldPtr != NULL));
00130 CH_assert((a_level == 0) || (a_crsePhiNewPtr != NULL));
00131 CH_assert(a_crseNewTime >= a_crseOldTime);
00132 CH_assert(a_dt >= 0.);
00133
00134 LevelDataType rhst, phit;
00135 this->m_ops[a_level]->create(rhst, a_src);
00136 this->m_ops[a_level]->create(phit, a_phiNew);
00137
00138 this->m_ops[a_level]->setToZero(phit);
00139 this->m_ops[a_level]->setToZero(rhst);
00140 if (a_zeroPhi)
00141 {
00142 this->m_ops[a_level]->setToZero(a_phiNew);
00143 }
00144
00145 LevelDataType coarseData;
00146 if ((a_crsePhiOldPtr != NULL) && (a_level > 0))
00147 {
00148 this->m_ops[a_level-1]->create(coarseData, *a_crsePhiOldPtr);
00149 this->timeInterp(coarseData, *a_crsePhiOldPtr, *a_crsePhiNewPtr,
00150 a_oldTime, a_crseOldTime, a_crseNewTime, a_level-1);
00151 }
00152
00153
00154
00155 this->applyHelm(phit, a_phiOld, &coarseData, a_level, 0.5, a_dt, false);
00156
00157
00158 this->m_ops[a_level]->incr(rhst, a_src , a_dt);
00159
00160
00161 this->m_ops[a_level]->diagonalScale(phit, true);
00162
00163
00164 if (!a_rhsAlreadyKappaWeighted)
00165 this->m_ops[a_level]->kappaScale(rhst);
00166
00167
00168 this->m_ops[a_level]->incr(rhst, phit, 1.0);
00169
00170 this->solveHelm(a_phiNew, coarseData, rhst, a_level, 0.5, a_dt, a_zeroPhi);
00171 this->incrementFlux(a_flux, a_phiNew, a_level, 0.5, a_dt, -1.0, false);
00172
00173
00174
00175
00176 if ((a_fineFluxRegPtr != NULL) && (a_level < this->m_grids.size()-1))
00177 {
00178 Real fluxMult = 1.0;
00179 for (DataIterator dit = this->m_grids[a_level].dataIterator(); dit.ok(); ++dit)
00180 {
00181 FluxDataType& thisFlux = a_flux[dit];
00182 for (int dir=0; dir<SpaceDim; ++dir)
00183 {
00184 a_fineFluxRegPtr->incrementCoarse(thisFlux[dir],
00185 fluxMult, dit(),
00186 intervBase,
00187 intervFlux,
00188 dir);
00189 }
00190 }
00191 }
00192
00193 if ((a_crseFluxRegPtr != NULL) && (a_level > 0))
00194 {
00195 Real fluxMult = 1.0;
00196
00197 for (DataIterator dit = this->m_grids[a_level].dataIterator(); dit.ok(); ++dit)
00198 {
00199 FluxDataType& thisFlux = a_flux[dit];
00200 for (int dir=0; dir<SpaceDim; ++dir)
00201 {
00202 a_crseFluxRegPtr->incrementFine(thisFlux[dir], fluxMult, dit(),
00203 intervBase,
00204 intervFlux,
00205 dir);
00206 }
00207 }
00208 }
00209 }
00210
00211 private:
00212
00213 BaseLevelCrankNicolson& operator=(const BaseLevelCrankNicolson&);
00214 BaseLevelCrankNicolson(const BaseLevelCrankNicolson& a_opin);
00215 BaseLevelCrankNicolson();
00216 };
00217
00218 #include "NamespaceFooter.H"
00219 #endif