00001 #include "mixedhybridcompositionalsimple.h"
00002 #include "numericmethods.h"
00003 #include "hdf5orthowriter.h"
00004 #include "hdf5orthowriter.h"
00005 #include "solvergpu_agm.h"
00006 #include <fstream>
00007
00008 MixedHybridCompositionalSimple::MixedHybridCompositionalSimple(OrthoMesh &mesh,Function3D &fInitP,Function3D &fPrescribedVelocities, Function3D &fPrescribedPression, const VecDouble &K, const VecDouble &vPor,Function1D &fMobT,Function1D &fRelMobilities,double grav, double dt, FlashCompositional &flash,LinearSolver &solver,int debugLevel,bool bCheckNoBC )
00009 :MixedHybridCompositional(mesh,fInitP,fPrescribedVelocities, fPrescribedPression, K, vPor,fMobT,fRelMobilities,grav, dt,flash,solver,debugLevel, bCheckNoBC)
00010 {
00011 m_vGravTerm.reinit(m_mesh.numCells());
00012 m_vMobT.reinit(m_mesh.numCells());
00013 v1.reinit(m_mesh.numCells());
00014 v2.reinit(m_mesh.numCells());
00015 m_solAnt = m_sol;
00016
00017 }
00018
00019
00020
00021
00022
00023
00024 void MixedHybridCompositionalSimple::iterate(TransportBase &trans)
00025 {
00026 m_solAnt=m_sol;
00027 this->assemblySystem(m_A,m_B,m_dt,m_sol,m_vK,m_vPor,m_flash,m_fMobT,m_fFracFlux,m_grav);
00028
00029 m_solver.solve(m_A,m_sol,m_B);
00030
00031
00032
00033
00034
00035
00036
00037
00038 this->getNormalVelocitiesFromPressure(m_Vq,m_mesh,m_bc,m_vK,m_sol,m_vMobT,m_vGravTerm);
00039
00040 }
00041
00042
00043
00044
00045
00046 double MixedHybridCompositionalSimple::assemblySystem(SparseMatrix<double> &A,VecDouble &B, double dt, const VecDouble &vP, const VecDouble &vK, const VecDouble &vPor, FlashCompositional &flash, GeneralFunctionInterface &fMobT, GeneralFunctionInterface &fRelMobilities,double grav)
00047 {
00048 assert(flash.numPhases()==2);
00049 assert((flash.numPhases() -1) == fRelMobilities.getImageDim());
00050 assert(fMobT.getDomainDim() == flash.numPhases()-1);
00051 assert(fMobT.getImageDim() == 1);
00052 assert(fRelMobilities.getDomainDim() == flash.numPhases()-1);
00053 assert(grav >= 0);
00054
00055 static VecDouble phasesVol(flash.numPhases());
00056 static VecDouble phasesDensities(flash.numPhases());
00057 static VecDouble phasesViscosities(flash.numPhases());
00058 double maxStE=0.0;
00059
00060
00061
00062
00063 static VecDouble vS(flash.numPhases()-1);
00064
00065
00066
00067 static FlashData data(flash.numPhases(),flash.numComponents());
00068
00069
00070
00071 OrthoMesh::Cell_It cell = m_mesh.begin_cell();
00072 Index nCells = m_mesh.numCells();
00073 double cellVol=cell->volume();
00074
00075 A=0.0;
00076 B=0.0;
00077
00078
00079 double BetaG_dt;
00080 double St;
00081 for (Index cellIndex=0;cellIndex < nCells; cellIndex++,cell++)
00082 {
00083
00084 flash.flash(cellIndex,data);
00085 double P=vP(cellIndex);
00086
00087 flash.getPhasesVolume(P,data,phasesVol);
00088 St=phasesVol.l1_norm();
00089
00090 v2(cellIndex)=St;
00091
00092 if (fabs(1-St) > maxStE) maxStE = fabs(1-St);
00093
00094 BetaG_dt=vPor(cellIndex)*m_flash.getFluidCompressibility(P,data)/(dt);
00095 if (BetaG_dt < -0.0)
00096 {
00097 printf("Error BetaG_dt = %g\n",BetaG_dt);
00098 data.print();
00099 abort();
00100 }
00101 A.add(cellIndex,cellIndex,BetaG_dt*cellVol);
00102 v1(cellIndex)=-BetaG_dt*cellVol;
00103
00104
00105 B(cellIndex)+=(BetaG_dt*vP(cellIndex)+vPor(cellIndex)*(St-1.0)/dt)*cellVol;
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116 for (unsigned k=0;k<vS.size();k++)
00117 vS(k) = phasesVol(k)/St;
00118 m_vMobT(cellIndex)=fMobT(vS);
00119
00120
00121
00122 const VecDouble& compMass=flash.getComponentsMolarMass();
00123 data.getPhasesDensities(phasesDensities,compMass,phasesVol);
00124
00125 double dMob = fRelMobilities(vS,0);
00126 double mobAcum=dMob;
00127 double dGravTerm;
00128 dGravTerm=dMob*phasesDensities(0);
00129 for (unsigned k=1;k<vS.size();k++)
00130 {
00131 dMob = fRelMobilities(vS,k);
00132 dGravTerm+=dMob*phasesDensities(k);
00133 mobAcum+=dMob;
00134 }
00135 dGravTerm+=(1.0-mobAcum)*phasesDensities(vS.size());
00136
00137
00138
00139
00140 m_vGravTerm(cellIndex)=-dGravTerm*grav;
00141
00142 assert(mobAcum<=1.0);
00143 }
00144 MixedHybridBase::assemblySystem(A,B,m_mesh,m_bc,vK,m_vMobT,m_vGravTerm);
00145
00146 HDF5OrthoWriter::getHDF5OrthoWriter().setVariable("St_Error",maxStE);
00147 return maxStE;
00148 }
00149
00150
00151 void MixedHybridCompositionalSimple::testSolution(OrthoMesh::Cell_It &cell, double dt, VecDouble& Bg,const VecDouble &por,const VecDouble &K,const VecDouble &P,const VecDouble &vPprev,const VecDouble &vMobT,const VecDouble &St)
00152 {
00153 double U = cell->index_up();
00154 double D = cell->index_down();
00155 double L = cell->index_left();
00156 double R = cell->index_right();
00157 double F = cell->index_front();
00158 double B = cell->index_back();
00159 double I = cell->index();
00160
00161 double Kr = 2*vMobT(R)*K(R)*vMobT(I)*K(I)/(vMobT(R)*K(R) + vMobT(I)*K(I));
00162 double Kl = 2*vMobT(L)*K(L)*vMobT(I)*K(I)/(vMobT(L)*K(L) + vMobT(I)*K(I));
00163 double Ku = 2*vMobT(U)*K(U)*vMobT(I)*K(I)/(vMobT(U)*K(U) + vMobT(I)*K(I));
00164 double Kd = 2*vMobT(D)*K(D)*vMobT(I)*K(I)/(vMobT(D)*K(D) + vMobT(I)*K(I));
00165 double Kf = 2*vMobT(F)*K(F)*vMobT(I)*K(I)/(vMobT(F)*K(F) + vMobT(I)*K(I));
00166 double Kb = 2*vMobT(B)*K(B)*vMobT(I)*K(I)/(vMobT(B)*K(B) + vMobT(I)*K(I));
00167 Point3D DX = m_mesh.getDX();
00168 double Pant = vPprev(I);
00169 double result;
00170 result= por(I)*Bg(I)*P(I)/dt +
00171 (Kr*(P(I)-P(R)) + Kl*(P(I)-P(L)))/(DX(0)*DX(0)) +
00172 (Ku*(P(I)-P(U)) + Kd*(P(I)-P(D)))/(DX(1)*DX(1)) +
00173 (Kf*(P(I)-P(F)) + Kb*(P(I)-P(B)))/(DX(2)*DX(2))
00174 -
00175 (por(I)*Bg(I)*Pant/dt + por(I)*(St(I)-1.0)/dt);
00176
00177 printf("Residual = %g\n", result);
00178
00179
00180
00181 }
00182
00183
00184 void MixedHybridCompositionalSimple::assemblyInitialSystem(SparseMatrix<double> &A,VecDouble &B, HybridFaceBC &bc,const VecDouble &vP, const VecDouble &vK, FlashCompositional &flash, GeneralFunctionInterface &fMobT, GeneralFunctionInterface &fRelMobilities,double grav)
00185 {
00186 assert(flash.numPhases()==2);
00187 assert((flash.numPhases() -1) == fRelMobilities.getImageDim());
00188 assert(fMobT.getDomainDim() == flash.numPhases()-1);
00189 assert(fMobT.getImageDim() == 1);
00190 assert(fRelMobilities.getDomainDim() == flash.numPhases()-1);
00191 assert(grav >= 0);
00192
00193 VecDouble phasesVol(flash.numPhases());
00194 VecDouble phasesDensities(flash.numPhases());
00195 VecDouble phasesViscosities(flash.numPhases());
00196
00197
00198
00199
00200
00201 static VecDouble vS(flash.numPhases()-1);
00202
00203
00204
00205 FlashData data(flash.numPhases(),flash.numComponents());
00206
00207
00208
00209 OrthoMesh::Cell_It cell = m_mesh.begin_cell();
00210 Index nCells = m_mesh.numCells();
00211
00212
00213 A=0.0;
00214 B=0.0;
00215
00216 for (Index cellIndex=0;cellIndex < nCells; cellIndex++,cell++)
00217 {
00218
00219 flash.flash(cellIndex,data);
00220 double P=vP(cellIndex);
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 flash.getPhasesVolume(P,data,phasesVol);
00234 double St=NumericMethods::vectorSum(phasesVol);
00235 for (unsigned k=0;k<vS.size();k++)
00236 vS(k) = phasesVol(k)/St;
00237 m_vMobT(cellIndex)=fMobT(vS);
00238
00239
00240
00241 const VecDouble& compMass=flash.getComponentsMolarMass();
00242 data.getPhasesDensities(phasesDensities,compMass,phasesVol);
00243
00244 double dMob = fRelMobilities(vS,0);
00245 double mobAcum=dMob;
00246 double dGravTerm;
00247 dGravTerm=dMob*phasesDensities(0);
00248 for (unsigned k=1;k<vS.size();k++)
00249 {
00250 dMob = fRelMobilities(vS,k);
00251 dGravTerm+=dMob*phasesDensities(k);
00252 mobAcum+=dMob;
00253 }
00254 dGravTerm+=(1.0-mobAcum)*phasesDensities(vS.size());
00255
00256
00257
00258
00259 m_vGravTerm(cellIndex)=-dGravTerm*grav;
00260
00261 assert(mobAcum<=1.0);
00262 }
00263
00264
00265 MixedHybridBase::assemblySystem(A,B,m_mesh,bc,vK,m_vMobT,m_vGravTerm);
00266 }
00267
00268
00269 void MixedHybridCompositionalSimple::findInitialPressure(double referencePressure,double tol)
00270 {
00271
00272 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00273 VecDouble PAnt = m_sol;
00274 VecDouble vv(m_mesh.numVertices());
00275 m_flash.execute();
00276 this->assemblyInitialSystem(m_A,m_B,m_bc,m_sol,m_vK,m_flash,m_fMobT,m_fFracFlux,0.0);
00277 m_solver.solve(m_A,m_sol,m_B);
00278 m_flash.execute();
00279 this->assemblyInitialSystem(m_A,m_B,m_bc,m_sol,m_vK,m_flash,m_fMobT,m_fFracFlux,m_grav);
00280 m_solver.solve(m_A,m_sol,m_B);
00281 double error;
00282 m_mesh.projectCentralValuesAtVertices(m_sol,vv);
00283 hdf5.writeScalarField(vv,"P0");
00284 printf("Find Initial Pressure");
00285 while((error=NumericMethods::vectorMaxRelDiff(PAnt,m_sol)) > tol)
00286 {
00287 printf("Error %g\n",error);
00288 m_flash.execute();
00289 this->assemblyInitialSystem(m_A,m_B,m_bc,m_sol,m_vK,m_flash,m_fMobT,m_fFracFlux,m_grav);
00290 PAnt=m_sol;
00291 m_solver.solveAgain(m_A,m_sol,m_B);
00292 hdf5.writeScalarField(vv,"P0");
00293 }
00294 printf("Error %g\n",error);
00295
00296 }
00297
00298
00299 void MixedHybridCompositionalSimple::printOutput()
00300 {
00301 MixedHybridCompositional::printOutput();
00302
00303 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00304
00305 VecDouble Vv(m_mesh.numVertices());
00306
00307
00308 if (_debugLevel >= 3)
00309 {
00310 Matrix M(m_mesh.numVertices(),3);
00311 m_mesh.projectVelocitiesInFacesToVertices(M,m_Vq);
00312 M.copyColumn(Vv,2);
00313 hdf5.writeScalarField(Vv,"VelZ");
00314 }
00315
00316 m_mesh.projectCentralValuesAtVertices(v2,Vv);
00317 hdf5.writeScalarField(Vv,"St");
00318
00319 }
00320
00321
00322 void MixedHybridCompositionalSimple::rollback()
00323 {
00324 printf("ROLLLLLLLLLLLLLLLLLL\n");
00325 m_sol=m_solAnt;
00326 }