00001 #include "flashsimpleblackoil.h"
00002 #include "hdf5orthowriter.h"
00003 #include "arrayofvecdouble.h"
00004
00005
00006 #define Rl 0.05
00007 #define Cbl 2.31e-5
00008
00009 FlashSimpleBlackOil::FlashSimpleBlackOil(OrthoMesh &mesh)
00010 :FlashCompositional(2,2),m_mesh(mesh),m(2)
00011 {
00012 compMass.reinit(2);
00013 compMass=1;
00014 }
00015
00016
00017
00018 void FlashSimpleBlackOil::flash(double P, const VecDouble &compTotalMoles, FlashData &data)
00019 {
00020 assert(compTotalMoles.size()==2);
00021 assert(compTotalMoles(0)>=0.0);
00022 assert(compTotalMoles(1)>=0.0);
00023 assert(data.getNPhases()==2);
00024 assert(data.getNComponents()==2);
00025
00026 data.allocateOwnMemory();
00027
00028
00029 double no=compTotalMoles(OIL);
00030 double ng=compTotalMoles(GAS);
00031
00032
00033 double ngo = Rl*P*no;
00034
00035
00036 data.setMoles(OIL,OIL,compTotalMoles(OIL));
00037 data.setMoles(GAS,OIL,0.0);
00038
00039
00040 if (ngo > ng)
00041 {
00042
00043 data.setMoles(OIL,GAS,ng);
00044 data.setMoles(GAS,GAS,0.0);
00045 }
00046 else
00047 {
00048 data.setMoles(OIL,GAS,ngo);
00049 data.setMoles(GAS,GAS,ng-ngo);
00050 }
00051
00052 }
00053
00054
00055
00056
00057
00058 const VecDouble& FlashSimpleBlackOil::getComponentsMolarMass() const
00059 {
00060 return compMass;
00061 }
00062
00063
00064
00065 double FlashSimpleBlackOil::getFluidCompressibility(double P, FlashData &data)
00066 {
00067 double ngg = data.getMoles(GAS,GAS);
00068 if (ngg != 0.0)
00069 {
00070 double ng=data.getMoles(GAS,GAS)+data.getMoles(OIL,GAS);
00071 double no=data.getMoles(OIL,OIL);
00072 return -(-(0.3*no + 0.06*ng)/pow(6+0.06*P,2.0) + 0.0001*no);
00073 }
00074 else
00075 {
00076 double no=data.getMoles(OIL,OIL);
00077 double pb=data.getMoles(OIL,GAS)/(Rl*no);
00078 return -(-(1+0.0001*pb)*Cbl*no/pow(1+Cbl*(P-pb),2));
00079 }
00080
00081
00082 }
00083
00084 void FlashSimpleBlackOil::getPhasesVolume(double P, const FlashData &data, VecDouble &phasesVol)
00085 {
00086 assert(data.getMoles(GAS,OIL)==0.0);
00087 assert(data.getNPhases()==2);
00088 assert(data.getNComponents()==2);
00089
00090
00091 double ngg = data.getMoles(GAS,GAS);
00092 double noo = data.getMoles(OIL,OIL);
00093
00094 if (ngg !=0.0)
00095 {
00096 phasesVol(GAS)=ngg/(6+0.06*P);
00097 phasesVol(OIL)=(1+1.e-4*P)*noo;
00098 }
00099 else
00100 {
00101
00102 phasesVol(GAS)=0.0;
00103
00104
00105 double pb = data.getMoles(OIL,GAS)/(Rl*noo);
00106 phasesVol(OIL)=(1+1.e-4*pb)*noo/(1+Cbl*(P-pb));
00107 }
00108 }
00109
00110
00111
00117 void FlashSimpleBlackOil::getPhasesViscosities(double P,const FlashData &data,VecDouble &visc)
00118 {
00119 assert(visc.size() == 2);
00120 visc(OIL)=1.10366e-12;
00121 visc(GAS)=9.19289e-14;
00122 return;
00123
00124
00125
00126 visc(GAS)=0.012+3e-5*P;
00127
00128 if (data.getMoles(GAS,GAS) != 0.0)
00129 {
00130 visc(OIL)=0.8-0.0001*P;
00131 }
00132 else
00133 {
00134 double pb= getBubblePressure(data);
00135 visc(OIL)=(0.8-0.0001*pb)*(1.0 + 0.0000678 * (P-pb));
00136 }
00137
00138
00139 visc*=1.6786775231481482e-12;
00140 }
00141
00142
00143 double FlashSimpleBlackOil::getBubblePressure(const FlashData &data)
00144 {
00145 assert(data.getMoles(GAS,OIL)==0.0);
00146 assert(data.getMoles(GAS,GAS)==0.0);
00147 return data.getMoles(OIL,GAS)/(Rl*data.getMoles(OIL,OIL));
00148 }
00149
00150
00151
00152 FlashSimpleBlackOil::~FlashSimpleBlackOil()
00153 {
00154
00155 }
00156
00157 void FlashSimpleBlackOil::flash(Index cell, FlashData &data)
00158 {
00159
00160 getTransportModule().getSolutionAtCells().getVecValues(cell,&m);
00161 flash(getDynamicModule().getPressureAtCells()(cell),m,data);
00162 }
00163
00164
00165 void FlashSimpleBlackOil::getTotalVolumeDerivatives(double P,FlashData &data,VecDouble &dv_dm)
00166 {
00167 assert(dv_dm.size() == 2);
00168
00169 double ngg = data.getMoles(GAS,GAS);
00170 double no = data.getMoles(OIL,OIL);
00171
00172 if (ngg != 0.0 )
00173 {
00174
00175
00176 dv_dm(OIL)=-0.05*P/(0.06*P + 6) + P/10000.0 + 1;
00177 dv_dm(GAS)=1.0/(0.06*P+6);
00178 }
00179 else
00180 {
00181 double ng=data.getMoles(OIL,GAS);
00182 dv_dm(OIL)=(((2.31e-5 *P + 1)*no + -9.24e-4 * ng)*no -9.24e-7*ng*ng)/
00183 pow((2.31e-5*P+1)*no-ng*4.62e-4,2);
00184 dv_dm(GAS)=(4.62e-8*P + 0.002462)*no*no/pow( (2.31e-5*P + 1)*no - 4.62e-4*ng, 2);
00185 }
00186
00187
00188 }
00189
00190
00191 void FlashSimpleBlackOil::printOutput()
00192 {
00193 HDF5OrthoWriter &hdf5 = HDF5OrthoWriter::getHDF5OrthoWriter();
00194 unsigned nCells = m_mesh.numCells();
00195 VecDouble vc(nCells);
00196 VecDouble vcSatC(nCells);
00197 FlashData data(numPhases(),numComponents());
00198 VecDouble vv(m_mesh.numVertices());
00199 VecDouble phasesVol(2);
00200 for (unsigned i=0;i<nCells;i++)
00201 {
00202 flash(i,data);
00203
00204 getPhasesVolume(getDynamicModule().getPressureAtCells()(i),data,phasesVol);
00205 vcSatC(i)=phasesVol(1)/(phasesVol(0)+phasesVol(1));
00206 }
00207
00208
00209
00210
00211 m_mesh.projectCentralValuesAtVertices(vcSatC,vv);
00212 hdf5.writeScalarField(vv,"SatC");
00213
00214 }