00001 #ifdef CH_LANG_CC
00002
00003
00004
00005
00006
00007
00008
00009 #endif
00010
00011 #ifndef _BASELEVELBACKWARDEULER_H_
00012 #define _BASELEVELBACKWARDEULER_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 BaseLevelBackwardEuler : public BaseLevelHeatSolver<LevelDataType, FluxDataType, FluxRegisterType>
00045 {
00046
00047 public:
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 BaseLevelBackwardEuler(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 ~BaseLevelBackwardEuler()
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
00146 this->m_ops[a_level]->incr(phit, a_phiOld, 1.0);
00147 this->m_ops[a_level]->incr(rhst, a_src , a_dt);
00148
00149
00150 this->m_ops[a_level]->diagonalScale(phit, true);
00151
00152
00153 if (!a_rhsAlreadyKappaWeighted)
00154 this->m_ops[a_level]->kappaScale(rhst);
00155
00156
00157 this->m_ops[a_level]->incr(rhst, phit, 1.0);
00158
00159
00160
00161 LevelDataType coarseData;
00162 if ((a_crsePhiOldPtr != NULL) && (a_level > 0))
00163 {
00164 this->m_ops[a_level-1]->create(coarseData, *a_crsePhiOldPtr);
00165 this->m_ops[a_level-1]->setToZero(coarseData);
00166
00167 Real newTime = a_oldTime + a_dt;
00168 this->timeInterp(coarseData, *a_crsePhiOldPtr, *a_crsePhiNewPtr,
00169 newTime, a_crseOldTime, a_crseNewTime, a_level-1);
00170
00171 }
00172
00173 this->solveHelm(a_phiNew, coarseData, rhst, a_level, 1.0, a_dt, a_zeroPhi);
00174 this->incrementFlux(a_flux, a_phiNew, a_level, 1.0, a_dt, -1.0, true);
00175
00176
00177
00178
00179 if ((a_fineFluxRegPtr != NULL) && (a_level < this->m_grids.size()-1))
00180 {
00181 Real fluxMult = 1.0;
00182 for (DataIterator dit = this->m_grids[a_level].dataIterator(); dit.ok(); ++dit)
00183 {
00184 FluxDataType& thisFlux = a_flux[dit];
00185 for (int dir=0; dir<SpaceDim; ++dir)
00186 {
00187 a_fineFluxRegPtr->incrementCoarse(thisFlux[dir],
00188 fluxMult, dit(),
00189 intervBase,
00190 intervFlux,
00191 dir);
00192 }
00193 }
00194 }
00195
00196 if ((a_crseFluxRegPtr != NULL) && (a_level > 0))
00197 {
00198 Real fluxMult = 1.0;
00199
00200 for (DataIterator dit = this->m_grids[a_level].dataIterator(); dit.ok(); ++dit)
00201 {
00202 FluxDataType& thisFlux = a_flux[dit];
00203 for (int dir=0; dir<SpaceDim; ++dir)
00204 {
00205 a_crseFluxRegPtr->incrementFine(thisFlux[dir], fluxMult, dit(),
00206 intervBase,
00207 intervFlux,
00208 dir);
00209 }
00210 }
00211 }
00212 }
00213
00214 private:
00215
00216 BaseLevelBackwardEuler& operator=(const BaseLevelBackwardEuler&);
00217 BaseLevelBackwardEuler(const BaseLevelBackwardEuler& a_opin);
00218 BaseLevelBackwardEuler();
00219 };
00220
00221 #include "NamespaceFooter.H"
00222
00223 #endif