def calcSAT(iExp, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.NC nSam = clsEXP.nSamp nTem = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sName #print("calcSEP: nCom,nSam,nRow ",nCom,nSam,nPrs) typDEP = RX.expDEPvars.get("SAT") typOBS = RX.expOBSvars.get("SAT") iTR = typDEP.index("TEMP") iPS = typOBS.index("PSAT") iZF = typOBS.index("ZFAC") iDO = typOBS.index("DENO") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = dicSAM[nSam].gZI(iC) #====================================================================== # Loop over user defined 'stages' #====================================================================== for iTem in range(nTem): tRes = clsEXP.dDep[iTem][iTR] pSatO = clsEXP.dObs[iTem][iPS] if pSatO > 0.0: pEst = 0.95 * pSatO else: pEst = -1.0 qBub, pSat, Ksat = CS.calcPsat(pEst, tRes, clsEOS, clsSAM, clsIO) iLiq = 0 MPs, VPs, DPs, ZPs, UPs, dmS, dmS = CE.calcProps( iLiq, pSat, tRes, Z, clsEOS) clsEXP.dCal[iTem][iPS] = pSat clsEXP.dCal[iTem][iZF] = ZPs clsEXP.dCal[iTem][iDO] = DPs #====================================================================== # End of Module #====================================================================== return
def calcTopBottom(zTyp, dDep, pDep, tRes, zDep, fRef, clsEOS, clsIO): nCom = clsEOS.nComp qSat = True qBub = None pSat = None #-- Calculate a Pressure & Composition at Bottom Depth -------------- pDep, zDep = calcStepGRD(dDep, pDep, tRes, zDep, fRef, clsEOS, clsIO) #-- Is the new Composition Stable? ---------------------------------- iDep, depT, kDep = CT.twoSidedStabTest(qSat, pDep, tRes, zDep, clsEOS, clsIO) #-- Unstable? Re-Initialise and Calculate New Bottom Composition & Pressure if iDep > 0: if iDep == 1: #-- Liquid-Like Fluid Unstable zDep = kDep / zDep elif iDep == 2: #-- Vapour-Like Fluid Unstable zDep = kDep * zDep else: print("Search at " & zTyp & " Depth Returned Unstable Fluid with iStab = 3") crash = 1.0 / 0.0 zDep = UT.Norm(zDep) pDep, zDep = calcStepGRD(dDep, pDep, tRes, zDep, fRef, clsEOS, clsIO) logK = NP.log(kDep) else: logK = NP.zeros(nCom) #== Now Calculate the Saturation Pressure at this Depth =============== clsWRK = AD.classSample("GRDwrk") clsWRK.setIntComp(nCom, nCom) for iC in range(nCom): clsWRK.sZI(iC, zDep[iC]) qSat, pSat, Ksat = CS.calcPsat(pDep, tRes, qBub, pSat, logK, clsEOS, clsWRK, clsIO) #print("calcTopBottom: dDep,pDep,iDep,qSat,pSat ",dDep,pDep,iDep,qSat,pSat) #== Return Values ===================================================== return pDep, zDep, qSat, pSat
def calcGOCGRD(hAbv, hBel, tRes, hRef, pRef, zRef, fRef, clsEOS, clsIO): if clsIO.Deb["GRD"] > 0: qDeb = True fDeb = clsIO.fDeb else: qDeb = False nCom = clsEOS.NC iNeu = 0 pObs = -1.0 zDep = NP.zeros(nCom) #-- Composition at this Depth clsWRK = RS.classSample("GRDwrk") clsWRK.setNComp(nCom) #-------------------------------------------------------------------- # Simple Interval Halving #-------------------------------------------------------------------- iMid = 1 while hBel - hAbv > 1.0e-01: hMid = 0.5 * (hAbv + hBel) dDep = hMid - hRef pDep, zDep = calcStepGRD(dDep, pRef, tRes, zRef, fRef, clsEOS, clsIO) mDep, vDep, yDep, gDen, uDep, dumS, dumS = CE.calcProps( iNeu, pDep, tRes, zDep, clsEOS) zC1, zC7 = calcMoleFracGRD(zDep, clsEOS) for iC in range(nCom): clsWRK.sZI(iC, zDep[iC]) qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, clsEOS, clsWRK, clsIO) if qDeb: if qBub: iBub = 1 else: iBub = -1 sOut = "GOC search: iMid,hAbv,hMid,hBel,iBub,pSat {:2d} {:10.3f} {:10.3f} {:10.3f} {:2d} {:10.3f}\n" \ .format(iMid,hAbv,hMid,hBel,iBub,pSat) fDeb.write(sOut) if qBub: hBel = hMid else: hAbv = hMid iMid += 1 return
def calcBlack(clsEOS,dicSAM,clsBLK,clsUNI,clsIO) : sim3 = clsBLK.tSim[:3] #== Set Output File Name [rootName.sim] =============================== if sim3 == "CMG" : if not clsIO.qIMX : pathIMX = clsIO.patR + ".imex" fIMX = open(pathIMX,'w') clsIO.setQIMX(True) clsIO.setFIMX(fIMX) else : fIMX = clsIO.fIMX fSim = clsIO.fIMX sCom = "**" elif sim3 == "TEM" : if not clsIO.qMOR : pathMOR = clsIO.patR + ".mor" fMOR = open(pathMOR,'w') clsIO.setQMOR(True) clsIO.setFMOR(fMOR) else : fMOR = clsIO.fMOR fSim = clsIO.fMOR sCom = "--" elif sim3 == "VIP" : if not clsIO.qVIP : pathVIP = clsIO.patR + ".vip" fVIP = open(pathVIP,'w') clsIO.setQVIP(True) clsIO.setFVIP(fVIP) else : fVIP = clsIO.fVIP fSim = clsIO.fVIP sCom = "C " elif sim3 == "ECL" : if not clsIO.q100 : path100 = clsIO.patR + ".e100" f100 = open(path100,'w') clsIO.setQ100(True) clsIO.setF100(f100) else : f100 = clsIO.f100 fSim = clsIO.f100 sCom = "--" #-- Write Header Information to Simulator File ---------------------- WO.outputHeader(fSim,sCom,clsIO) WO.outputEOS(fSim,sCom,clsIO,clsEOS) #== Initialisation ==================================================== print("calcBlack: Entered") qLiq = True ; qVap = False iLiq = 1 ; iVap = -1 iSam = clsBLK.sNum nCom = clsEOS.nComp clsSAM = dicSAM[iSam] Z = NP.zeros(nCom) for iC in range(nCom) : Z[iC] = clsSAM.gZI(iC) sNam = dicSAM[iSam].sNam clsBLK.setSamp(iSam,sNam) #-- Store the name xTyp = clsBLK.xTyp tRes = clsBLK.Tres pSep = clsBLK.pSep tSep = clsBLK.tSep #-- Has User Defined Non-Standard Wiring for the Stage Order? ------- if clsBLK.qLsep : Lsep = clsBLK.Lsep else : Lsep = [] if clsBLK.qVsep : Vsep = clsBLK.Vsep else : Vsep = [] #print("calcBlack: pSep,tSep,Lsep,Vsep ",pSep,tSep,Lsep,Vsep) #-- Brine Density at Standard (Stock Tank) Conditions --------------- pStc = UT.pStand #-- Standard Pressure [psia] tStc = UT.tStand #-- Standard Temperature [degR = 60.0 degF] mFrc = clsBLK.bSalt #-- Mass Fraction of Salt in the Brine dSTW,comW = CW.calcRoweChouDen(mFrc,tStc,pStc,clsUNI) #-- Stock Tank Brine Density clsBLK.setDenSTW(dSTW) #-- Brine Properties at Reference Pressure & Tres (for PVTW keyword) CW.calcPVTW(clsBLK,clsUNI,clsIO) #====================================================================== # Saturation Pressure Stage: Find Psat #====================================================================== clsEOS.eosCoefsNoPT() #-- This experiment at varying temperature so set when needed ------- pMea = -1.0 qBub = None pSat = None logK = NP.empty(nCom) qBub,pSat,Ksat = CS.calcPsat(pMea,tRes,qBub,pSat,logK,clsEOS,clsSAM,clsIO) clsBLK.Psat = pSat Xsat = NP.zeros(nCom) Ysat = NP.zeros(nCom) if qBub : Xsat = NP.copy(Z) Ysat = NP.multiply(Z,Ksat) else : Xsat = NP.divide(Z,Ksat) Ysat = NP.copy(Z) Xsat = UT.Norm(Xsat) ; Ysat = UT.Norm(Ysat) #-- Properties of the Feed and Incipient Phases at Psat ------------- Mx,Vx,Dx,Zx,Ux,Cx,Wx = CE.calcProps(iLiq,pSat,tRes,Xsat,clsEOS) My,Vy,Dy,Zy,Uy,dS,dS = CE.calcProps(iVap,pSat,tRes,Ysat,clsEOS) UgDew = Uy #== Flash the Psat Liquid & Vapour through the Separator Train ======== if qBub : Vsat = Vx else : Vsat = Vy Doo,Dgo,Rs,Bo,Bd,ySTG = \ BO.sepFlash(iLiq,pSep,tSep,Lsep,Vsep,Xsat,Vx,clsEOS,clsIO) Dog,Dgg,Rv,Bg,Bd,ySTG = \ BO.sepFlash(iVap,pSep,tSep,Lsep,Vsep,Ysat,Vy,clsEOS,clsIO) Md,Vd,Dd,Zd,Ud,dS,dS = CE.calcProps(iVap,pSat,tRes,ySTG,clsEOS) Bd = BO.gasFVF(pSat,tRes,Zd) RsSat = Rs #-- Store the Saturated GOR & CGR RvSat = Rv #-- Stock Tank Densities from Saturated Stage depending on Type ----- if qBub : dSTO = Doo dSTG = Dgo else : dSTO = Dog dSTG = Dgg dTab = [] #-- Stores all Saturated data pTab = [] #-- Will store all values of Pres (including those > Psat) dRow = [pSat,Rs,Bo,Ux,Cx,Wx,Rv,Bg,Uy,Bd,Ud] dTab.append(dRow) #== Setup Pressure Nodes in the Tables ================================ pMax = clsBLK.Pmax pMin = clsBLK.Pmin pInc = clsBLK.Pinc pRes = pMax qIns = True #====================================================================== # Build pTab-Array #====================================================================== while pRes >= pMin : if pRes > pSat : #-- Above Psat pTab.append(pRes) else : if qIns : #-- Insert Psat pTab.append(pSat) qIns = False pTab.append(pRes) #-- Below Psat pRes = pRes - pInc #-- Decrement Pressure #-- Total number of stages (pressure nodes) ------------------------- nPrs = len(pTab) #====================================================================== # Depletion Stages #====================================================================== if qBub : vEst = 0.0 else : vEst = 1.0 zTot = 1.0 pRes = pMax qIns = True while pRes >= pMin : #-- Above Psat ------------------------------------------------------ if pRes > pSat : pass else : #-- Psat-Row? ------------------------------------------------------- if qIns : qIns = False #-- This experiment at varying temperature so set when needed ------- V,K,X,Y = CF.calcFlash(pRes,tRes,Z,vEst,clsEOS,clsIO) vEst = V Moil,Vliq,dLiq,Zoil,Uoil,Coil,Viso = CE.calcProps(iLiq,pRes,tRes,X,clsEOS) Mgas,Vvap,dVap,Zgas,Ugas,dumS,dumS = CE.calcProps(iVap,pRes,tRes,Y,clsEOS) zGas = zTot* V zOil = zTot*(1.0-V) Xsep = NP.copy(X) #-- Local copies of (X,Y) to flash thru Seps Ysep = NP.copy(Y) #-- Flash Liquid thru the Separator Train --------------------------- Doo,Dgo,Rs,Bo,Bd,ySTG = \ BO.sepFlash(iLiq,pSep,tSep,Lsep,Vsep,Xsep,Vliq,clsEOS,clsIO) #-- Flash Vapour thru the Separator Train --------------------------- Dog,Dgg,Rv,Bg,Bd,ySTG = \ BO.sepFlash(iVap,pSep,tSep,Lsep,Vsep,Ysep,Vvap,clsEOS,clsIO) #Ud,dumm = CE.calcLBCderv(tRes,dVap,ySTG,clsEOS) #-- Dry Gas Visc at pRes Md,Vd,Dd,Zd,Ud,dS,dS = CE.calcProps(iVap,pRes,tRes,ySTG,clsEOS) Bd = BO.gasFVF(pRes,tRes,Zd) #== Modify the Moles to Next Stage, Depending on Depletion Type ======= Voil = zOil*Vliq Vgas = zGas*Vvap Vtot = Voil + Vgas Vrem = Vtot - Vsat zRem = pRes*Vrem/(Zgas*UT.gasCon*tRes) if xTyp == "CCE" : pass elif xTyp == "CVD" : for iC in range(nCom) : Z[iC] = (zTot*Z[iC] - zRem*Y[iC])/(zTot - zRem) zTot = zTot - zRem elif xTyp == "DLE" : Z = NP.copy(X) zTot = zTot - zGas dRow = [pRes,Rs,Bo,Uoil,Coil,Viso,Rv,Bg,Ugas,Bd,Ud] dTab.append(dRow) #== Decrement Pressure and Continue =================================== pRes = pRes - pInc #== Work Arrays for "Back-Up" Fits ==================================== nSat = len(dTab) X = NP.zeros(nSat) Y = NP.zeros(nSat) #====================================================================== # Slope and Intercept of the (assumed linear) Bo versus Rs #====================================================================== for i in range(nSat) : X[i] = dTab[i][clsBLK.iRs] Y[i] = dTab[i][clsBLK.iBo] slope,inter = UT.linearFit(X,Y) clsBLK.BoS = slope clsBLK.BoI = inter #====================================================================== # Slope and Intercept of the (assumed exp) Muo versus Rs #====================================================================== for i in range(nSat) : X[i] = dTab[i][clsBLK.iRs] Y[i] = log(dTab[i][clsBLK.iUo]) slope,logIn = UT.linearFit(X,Y) inter = exp(logIn) clsBLK.UoS = slope clsBLK.UoI = inter #====================================================================== # Slope and Intercept of the (assumed linear) co.p versus Rs #====================================================================== for i in range(nSat) : X[i] = dTab[i][clsBLK.iRs] Y[i] = dTab[i][clsBLK.iCo]*dTab[i][clsBLK.iPr] slope,inter = UT.linearFit(X,Y) clsBLK.CoS = slope clsBLK.CoI = inter #====================================================================== # Stock Tank Oil and Gas Properties #====================================================================== mSTO,oGrv = BP.initOilProps(dSTO,clsBLK) mSTG,gGrv = BP.initGasProps(dSTG,clsBLK) clsBLK.mSTO = mSTO clsBLK.mSTG = mSTG cCon = (dSTO/mSTO)*(UT.gasCon*UT.tStand/UT.pStand) #-- Singh et al Eqn.(14) clsBLK.Co = cCon #== Output Header ===================================================== WB.outputHeaderBO(fSim,iSam,sNam,clsBLK,clsIO,clsUNI) #====================================================================== # Generate the Saturated Oil and Gas STO Mole Fractions #====================================================================== cTab = [] #-- Table used to store 'calculated' data for iPrs in range(nSat) : Pr = dTab[iPrs][clsBLK.iPr] Rs = dTab[iPrs][clsBLK.iRs] ; Bo = dTab[iPrs][clsBLK.iBo] Rv = dTab[iPrs][clsBLK.iRv] ; Bg = dTab[iPrs][clsBLK.iBg] denO = BP.denOil(dSTO,dSTG,Rs,Bo) denG = BP.denGas(dSTO,dSTG,Rv,Bg) xLiq = cCon/(cCon + Rs) yLiq = cCon/(cCon + 1.0/Rv) Mliq = BP.phaseMw(mSTG,mSTO,xLiq) Mvap = BP.phaseMw(mSTG,mSTO,yLiq) Vliq = Mliq/denO Vvap = Mvap/denG cRow = [xLiq,yLiq,denO,denG,Vliq,Vvap] cTab.append(cRow) #print("Pr,xO,yO,Vl,Vv {:10.3f}{:8.5f}{:8.5f}{:8.4f}{:8.4f}".format(Pr,xLiq,yLiq,Vliq,Vvap)) #====================================================================== # Check the Oil Viscosity versus Pressure trend is physical # It can go wrong for condensates #====================================================================== qMonV = BP.oilViscMono(dTab,clsBLK) qMonC = BP.oilCompMono(dTab,clsBLK) #print("calcBlack: qMonv,qMonC ",qMonV,qMonC) #== Initialise Extension Method ========================================= clsBLK.RT = UT.gasCon*tRes #-- RT nEOS = clsBLK.nEOS clsBLK.EOS1["sOil"] = 0.5 clsBLK.EOS1["sGas"] = 0.5 #======================================================================== # Fit the 2-Component (STO & STG) EoS Parameters to Saturated Data #======================================================================== sOil,sGas = \ BE.regEoSData(dTab,cTab,dicSAM,clsEOS,clsBLK,clsIO) #======================================================================== # Fit the 2-Component (STO & STG) Viscosity Parameters to Saturated Data #======================================================================== rOil,rGas = \ BV.regViscData(dTab,cTab,dicSAM,clsEOS,clsBLK,clsIO) #======================================================================== # Calculate Convergence Pressure: Re-Set Saturated (sOil,sGas) #======================================================================== BO.setEoSVis(0,sOil,sGas,rOil,rGas,clsBLK) pCon = BO.convPressure(dTab,clsBLK) if pCon < pMax : pCon = pMax KoSat,KgSat,mO,mG = BO.extendTable(pSat,pCon,dTab,clsBLK) RsMax,RvMax = BO.calcRsRv(cCon,pCon,pSat,KoSat,KgSat,mO,mG) #== Extended Data ===================================================== eTab = [] uLst = dTab[0][clsBLK.iUo] iRow = 0 for iExt in range(len(pTab)) : if pTab[iExt] > pSat : pRes = pTab[iExt] RTp = clsBLK.RT/pRes Rs,Rv = BO.calcRsRv(cCon,pRes,pSat,KoSat,KgSat,mO,mG) Bo,Uo = BO.calcSatProp(qLiq,RTp,cCon,dSTO,dSTG,Rs ,clsBLK) Co,Vo = BO.calcComp(qLiq,RTp,cCon,dSTO,dSTG,Rs,Bo,Uo,clsBLK) Bg,Ug = BO.calcSatProp(qVap,RTp,cCon,dSTO,dSTG,Rv ,clsBLK) Bd,Ud = BO.calcSatProp(qVap,RTp,cCon,dSTO,dSTG,0.0,clsBLK) #-- For condensates, Uo can go astray ------------------------------- if Uo > uLst : Ux = clsBLK.UoI*exp(Rs*clsBLK.UoS) Uo = Ux uLst = Uo eRow = [pRes,Rs,Bo,Uo,Co,Vo,Rv,Bg,Ug,Bd,Ud] eTab.append(eRow) #======================================================================== # Oil and Gas Output depends on Simulator Type #======================================================================== qDep = clsBLK.qDep if sim3 == "TEM" : BM.outMORE(fSim,dTab,eTab,sOil,sGas,rOil,rGas,qMonV,clsBLK,clsUNI,clsIO) if not qDep : clsIO.qMOR = UT.closeFile(fSim) elif sim3 == "CMG" : BI.outIMEX(fSim,dTab,eTab,sOil,sGas,rOil,rGas,qMonV,clsBLK,clsUNI,clsIO) if not qDep : clsIO.qIMX = UT.closeFile(fSim) elif sim3 == "VIP" : BN.outVIP( fSim,dTab,eTab,sOil,sGas,rOil,rGas,qMonV,clsBLK,clsUNI,clsIO) if not qDep : clsIO.qVIP = UT.closeFile(fSim) else : B1.outE100(fSim,dTab,eTab,sOil,sGas,rOil,rGas,qMonV,clsBLK,clsUNI,clsIO) if not qDep : clsIO.q100 = UT.closeFile(fSim) #======================================================================== # Composition versus Depth Calculation? #======================================================================== if qDep : BG.blackGrad(clsEOS,dicSAM,clsBLK,clsUNI,clsIO) clsIO.q100 = UT.closeFile(fSim) #======================================================================== # End of Routine #======================================================================== print("calcBlack: Finished") return
def calcGRD(iExp, qDif, clsEOS, dicSAM, clsEXP, clsIO): if clsIO.Deb["GRD"] > 0: qDeb = True fDeb = clsIO.fDeb else: qDeb = False qSat = True #-- Various dimensions ---------------------------------------------- nCom = clsEOS.nComp nSam = clsEXP.nSamp nDep = clsEXP.nRow - 1 #-- Extra Row for GOC, if present nRef = clsEXP.nDref nGOC = nDep #-- Pointers into the potential observed data (for calculated data) - typIND = AP.classLIB().INDshrt.get("GRD") typOBS = AP.classLIB().OBSshrt.get("GRD") iHG = typIND.index("HEIG") iPR = typOBS.index("PRES") iPS = typOBS.index("PSAT") iDN = typOBS.index("DENS") iC1 = typOBS.index("ZC1") iCP = typOBS.index("ZC7+") #-- Sample Name ----------------------------------------------------- clsSAM = dicSAM[nSam] sNam = clsSAM.sNam clsWRK = AD.classSample("GRDwrk") clsWRK.setIntComp(nCom, nCom) #-- Load Reference Composition -------------------------------------- zRef = NP.zeros(nCom) for iC in range(nCom): zRef[iC] = clsSAM.gZI(iC) #-- Reference Depth & Pressure -------------------------------------- pRef = clsEXP.Pref hRef = clsEXP.Dref #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #== Saturation Pressure at Reference Depth ============================ pSatO = clsEXP.PsatO if pSatO > 0.0: pObs = 0.95 * pSatO else: pObs = -1.0 qBub = None pSat = None logK = NP.empty(nCom) qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, qBub, pSat, logK, clsEOS, clsSAM, clsIO) if qBub: iRef = 1 #-- Ref-State is BUB else: iRef = -1 #-- DEW iNeu = 0 iLiq = 1 iVap = -1 mSat, vSat, dSat, zSat, uSat, dumS, dumS = CE.calcProps( iNeu, pSat, tRes, zRef, clsEOS) zC1, zC7 = calcMoleFracGRD(zRef, clsEOS) clsEXP.dCal[iPR][nRef] = pRef clsEXP.dCal[iPS][nRef] = pSat clsEXP.dCal[iDN][nRef] = dSat clsEXP.dCal[iC1][nRef] = zC1 clsEXP.dCal[iCP][nRef] = zC7 for iC in range(nCom): clsEXP.zCal[nRef][iC] = zRef[iC] #-- Get Reference (log) Fugacity Coeffs ----------------------------- fRef, dumP = setupCalcGRDCoefsP(iNeu, pRef, tRes, zRef, clsEOS) #-- Dont need Ref dlnPhi/dP #====================================================================== # GOC Search, if appropriate #====================================================================== iTop = 0 iBot = 0 if nRef > 0: hTop = clsEXP.dInd[iHG][0] dTop = hTop - hRef zTyp = "Top" #-- Calculate a Pressure & Composition at Top Depth ----------------- pTop,zTop,qTop,sTop = \ calcTopBottom(zTyp,dTop,pRef,tRes,zRef,fRef,clsEOS,clsIO) if not qTop: iTop = -1 #-- Is DEW point else: hTop = None if nRef < nDep: hBot = clsEXP.dInd[iHG][nDep - 1] dBot = hBot - hRef zTyp = "Bot" #-- Calculate a Pressure & Composition at Bottom Depth -------------- pBot,zBot,qBot,sBot = \ calcTopBottom(zTyp,dBot,pRef,tRes,zRef,fRef,clsEOS,clsIO) if qBot: iBot = 1 #-- Is BUB point else: hBot = None #-------------------------------------------------------------------- # Search for Gas-Oil-Contact? #-------------------------------------------------------------------- if iTop * iBot < 0: if iRef == iTop: hTop = hRef else: hBot = hRef print("Gas-Oil-Contact Detected in Depth Interval") hGOC,pGOC,sGOC,dGOC,zC1,zC7,zDew,zBub = \ calcGOC(hTop,hBot,tRes,hRef,pRef,zRef,fRef,clsEOS,clsIO) else: print("No Gas-Oil-Contact Detected in Depth Interval") hGOC = 0.0 pGOC = 0.0 sGOC = 0.0 dGOC = 0.0 zC1 = 0.0 zC7 = 0.0 zDew = NP.zeros(nCom) zBub = NP.zeros(nCom) clsEXP.dInd[iHG][nGOC] = hGOC clsEXP.dCal[iPR][nGOC] = pGOC clsEXP.dCal[iPS][nGOC] = sGOC clsEXP.dCal[iDN][nGOC] = dGOC clsEXP.dCal[iC1][nGOC] = zC1 clsEXP.dCal[iCP][nGOC] = zC7 for iC in range(nCom): clsEXP.zCal[nGOC][iC] = zDew[iC] #-- Above and Below any Possible GOC -------------------------------- hAbv = None hBel = None #-------------------------------------------------------------------- # Above Reference Depth #-------------------------------------------------------------------- zTyp = "Abv" for iDep in range(nRef - 1, -1, -1): hDep = clsEXP.dInd[iHG][iDep] dDep = hDep - hRef #print("Above: iDep,hDep ",iDep,hDep) pDep,zDep,qDep,sDep = \ calcTopBottom(zTyp,dDep,pRef,tRes,zRef,fRef,clsEOS,clsIO) mDep, vDep, yDep, gDen, uDep, dumS, dumS = CE.calcProps( iNeu, pDep, tRes, zDep, clsEOS) zC1, zC7 = calcMoleFracGRD(zDep, clsEOS) clsEXP.dCal[iPR][iDep] = pDep clsEXP.dCal[iPS][iDep] = sDep clsEXP.dCal[iDN][iDep] = yDep clsEXP.dCal[iC1][iDep] = zC1 clsEXP.dCal[iCP][iDep] = zC7 for iC in range(nCom): clsEXP.zCal[iDep][iC] = zDep[iC] if qDeb: if qBub: isBub = 1 else: isBub = -1 sOut = "Above: iDep,hDep,pDep,pSat,Bub,zC1,zC7+,Dens {:2d} {:10.3f} {:10.3f} {:10.3f} {:2d} {:6.4f} {:6.4f} {:7.3f}\n".format( iDep, hDep, pDep, pSat, isBub, zC1, zC7, yDep) fDeb.write(sOut) WO.writeArrayDebug(fDeb, zDep, "zDep") #-------------------------------------------------------------------- # Below Reference Depth #-------------------------------------------------------------------- zTyp = "Bel" for iDep in range(nRef + 1, nDep): hDep = clsEXP.dInd[iHG][iDep] dDep = hDep - hRef #print("Below: iDep,hDep ",iDep,hDep) pDep,zDep,qDep,sDep = \ calcTopBottom(zTyp,dDep,pRef,tRes,zRef,fRef,clsEOS,clsIO) mDep, vDep, yDep, gDen, uDep, dumS, dumS = CE.calcProps( iNeu, pDep, tRes, zDep, clsEOS) zC1, zC7 = calcMoleFracGRD(zDep, clsEOS) clsEXP.dCal[iPR][iDep] = pDep clsEXP.dCal[iPS][iDep] = sDep clsEXP.dCal[iDN][iDep] = yDep clsEXP.dCal[iC1][iDep] = zC1 clsEXP.dCal[iCP][iDep] = zC7 for iC in range(nCom): clsEXP.zCal[iDep][iC] = zDep[iC] if qDeb: if qBub: isBub = 1 else: isBub = -1 sOut = "Below: iDep,hDep,pDep,pSat,Bub,zC1,zC7+,Dens {:2d} {:10.3f} {:10.3f} {:10.3f} {:2d} {:6.4f} {:6.4f} {:7.3f}\n".format( iDep, hDep, pDep, pSat, isBub, zC1, zC7, yDep) fDeb.write(sOut) WO.writeArrayDebug(fDeb, zDep, "zDep") #====================================================================== # End of Routine #====================================================================== return
def calcGRD(iExp, clsEOS, dicSAM, clsEXP, clsIO): if clsIO.Deb["GRD"] > 0: qDeb = True fDeb = clsIO.fDeb else: qDeb = False #-- Various dimensions ---------------------------------------------- nCom = clsEOS.NC nSam = clsEXP.nSamp nDep = clsEXP.nRow nRef = clsEXP.nDref #-- Pointers into the potential observed data (for calculated data) - typDEP = RX.expDEPvars.get("GRD") typOBS = RX.expOBSvars.get("GRD") iHG = typDEP.index("HEIG") iPR = typOBS.index("PRES") iPS = typOBS.index("PSAT") iDN = typOBS.index("DENS") iC1 = typOBS.index("ZC1") iCP = typOBS.index("ZC7+") #-- Sample Name ----------------------------------------------------- clsSAM = dicSAM[nSam] sNam = clsSAM.sName clsWRK = RS.classSample("GRDwrk") clsWRK.setNComp(nCom) #-- Load Reference Composition -------------------------------------- zRef = NP.zeros(nCom) for iC in range(nCom): zRef[iC] = clsSAM.gZI(iC) #-- Reference Depth & Pressure -------------------------------------- pRef = clsEXP.Pref dRef = clsEXP.Dref #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #== Saturation Pressure at Reference Depth ============================ pSatO = clsEXP.PsatO if pSatO > 0.0: pObs = 0.95 * pSatO else: pObs = -1.0 qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, clsEOS, clsSAM, clsIO) iNeu = 0 iLiq = 1 iVap = -1 mSat, vSat, dSat, zSat, uSat, dumS, dumS = CE.calcProps( iNeu, pSat, tRes, zRef, clsEOS) zC1, zC7 = calcMoleFracGRD(zRef, clsEOS) clsEXP.dCal[nRef][iPR] = pRef clsEXP.dCal[nRef][iPS] = pSat clsEXP.dCal[nRef][iDN] = dSat clsEXP.dCal[nRef][iC1] = zC1 clsEXP.dCal[nRef][iCP] = zC7 #-- Get Fugacity Coeffs and their Pressure-Derivatives -------------- fRef, refP = setupCalcGRDCoefsP(iNeu, pRef, tRes, zRef, clsEOS) #-- Above and Below any Possible GOC -------------------------------- hAbv = None hBel = None #-------------------------------------------------------------------- # Above Reference Depth #-------------------------------------------------------------------- hLst = dRef pSatR = pSat for iDep in range(nRef - 1, -1, -1): hDep = clsEXP.dDep[iDep][iHG] dDep = hDep - dRef pDep, zDep = calcStepGRD(dDep, pRef, tRes, zRef, fRef, clsEOS, clsIO) mDep, vDep, yDep, gDen, uDep, dumS, dumS = CE.calcProps( iNeu, pDep, tRes, zDep, clsEOS) zC1, zC7 = calcMoleFracGRD(zDep, clsEOS) for iC in range(nCom): clsWRK.sZI(iC, zDep[iC]) qSat, pSat, Ksat = CS.calcPsat(pDep, tRes, clsEOS, clsWRK, clsIO) if qSat != qBub: #-- Going Up => Must Have Gone from Bubble -> Dew hAbv = hDep hBel = hLst hLst = hDep qBub = qSat clsEXP.dCal[iDep][iPR] = pDep clsEXP.dCal[iDep][iPS] = pSat clsEXP.dCal[iDep][iDN] = yDep clsEXP.dCal[iDep][iC1] = zC1 clsEXP.dCal[iDep][iCP] = zC7 if qDeb: if qBub: isBub = 1 else: isBub = -1 sOut = "Above: iDep,hDep,pDep,pSat,Bub,zC1,zC7+,Dens {:2d} {:10.3f} {:10.3f} {:10.3f} {:2d} {:6.4f} {:6.4f} {:7.3f}\n".format( iDep, hDep, pDep, pSat, isBub, zC1, zC7, yDep) fDeb.write(sOut) #WO.writeArrayDebug(fDeb,Ksat,"Ksat") #-------------------------------------------------------------------- # Below Reference Depth #-------------------------------------------------------------------- hLst = dRef pSat = pSatR for iDep in range(nRef + 1, nDep): hDep = clsEXP.dDep[iDep][iHG] dDep = hDep - dRef pDep, zDep = calcStepGRD(dDep, pRef, tRes, zRef, fRef, clsEOS, clsIO) mDep, vDep, yDep, gDen, uDep, dumS, dumS = CE.calcProps( iNeu, pDep, tRes, zDep, clsEOS) zC1, zC7 = calcMoleFracGRD(zDep, clsEOS) for iC in range(nCom): clsWRK.sZI(iC, zDep[iC]) qSat, pSat, Ksat = CS.calcPsat(pDep, tRes, clsEOS, clsWRK, clsIO) if qSat != qBub: #-- Going Down => Must Have Gone from Dew -> Bubble hAbv = hLst hBel = hDep hLst = hDep qBub = qSat clsEXP.dCal[iDep][iPR] = pDep clsEXP.dCal[iDep][iPS] = pSat clsEXP.dCal[iDep][iDN] = yDep clsEXP.dCal[iDep][iC1] = zC1 clsEXP.dCal[iDep][iCP] = zC7 if qDeb: if qBub: isBub = 1 else: isBub = -1 sOut = "Below: iDep,hDep,pDep,pSat,Bub,zC1,zC7+,Dens {:2d} {:10.3f} {:10.3f} {:10.3f} {:2d} {:6.4f} {:6.4f} {:7.3f}\n".format( iDep, hDep, pDep, pSat, isBub, zC1, zC7, yDep) fDeb.write(sOut) #WO.writeArrayDebug(fDeb,Ksat,"Ksat") #-------------------------------------------------------------------- # Have we bracketed a GOC? #-------------------------------------------------------------------- #print("hAbv,hBel ",hAbv,hBel) if hAbv != None and hBel != None: calcGOCGRD(hAbv, hBel, tRes, dRef, pRef, zRef, fRef, clsEOS, clsIO) #====================================================================== # End of Routine #====================================================================== return
def calcSWL(iExp, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.NC nSam = clsEXP.nSamp nInj = clsEXP.nSinj nAdd = clsEXP.nRow sNam = dicSAM[nSam].sName #print("calcSEP: nCom,nSam,nRow ",nCom,nSam,nPrs) typDEP = RX.expDEPvars.get("SWL") typOBS = RX.expOBSvars.get("SWL") iMO = typDEP.index("MOLE") iPS = typOBS.index("PSAT") iVS = typOBS.index("VSWL") #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #-- Load Feed Composition ------------------------------------------- clsSAM = dicSAM[nSam] clsINJ = dicSAM[nInj] clsWRK = RS.classSample("SWLwrk") clsWRK.setNComp(nCom) Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) #-- Load Injection Composition -------------------------------------- Y = NP.zeros(nCom) for iC in range(nCom): Y[iC] = clsINJ.gZI(iC) #-- Composition Array to be used ------------------------------------ W = NP.zeros(nCom) mTot = 1.0 mInj = 0.0 #====================================================================== # Loop over user defined 'stages' #====================================================================== for iAdd in range(nAdd): mInj = clsEXP.dDep[iAdd][iMO] mTot = mInj + 1.0 #print("calcSWL: iAdd,mAdd,mInj,mTot ",iAdd,mThs,mInj,mTot) wDiv = 1.0 / mTot for iC in range(nCom): W[iC] = (Z[iC] + mInj * Y[iC]) * wDiv clsWRK.sZI(iC, W[iC]) pSatO = clsEXP.dObs[iAdd][iPS] if pSatO > 0.0: pEst = 0.95 * pSatO else: pEst = -1.0 qBub, pSat, Ksat = CS.calcPsat(pEst, tRes, clsEOS, clsWRK, clsIO) iLiq = 0 MPs, VPs, DPs, ZPs, UPs, dmS, dmS = CE.calcProps( iLiq, pSat, tRes, W, clsEOS) if iAdd == 0: Vref = VPs Vswl = mTot * VPs / Vref clsEXP.dCal[iAdd][iPS] = pSat clsEXP.dCal[iAdd][iVS] = Vswl #====================================================================== # End of Module #====================================================================== return
def calcCCE(iExp, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.NC nSam = clsEXP.nSamp nPrs = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sName typDEP = RX.expDEPvars.get("CCE") typOBS = RX.expOBSvars.get("CCE") iPR = typDEP.index("PRES") iRV = typOBS.index("RELV") iSL = typOBS.index("SLIQ") iZF = typOBS.index("ZFAC") iDO = typOBS.index("DENO") iUG = typOBS.index("VISG") iUO = typOBS.index("VISO") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #-- Saturation Pressure --------------------------------------------- if clsEXP.PsatO > 0.0: pObs = clsEXP.PsatO else: pObs = -1.0 qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, clsEOS, clsSAM, clsIO) clsEXP.setPsatCal(pSat) iNeu = 0 iLiq = 1 iVap = -1 Msat, Vsat, Dsat, Zsat, Usat, dumS, dumS = CE.calcProps( iNeu, pSat, tRes, Z, clsEOS) if qBub: vEst = 0.0 else: vEst = 1.0 #====================================================================== # Loop over user defined pressures #====================================================================== for iPrs in range(nPrs): pRes = clsEXP.dDep[iPrs][iPR] #== 1-Phase or 2-Phase? =============================================== if pRes > pSat: M1P, V1P, D1P, Z1P, U1P, dmS, dmS = CE.calcProps( iNeu, pRes, tRes, Z, clsEOS) #print("calcCCE[Z]: iP,pR,Mw,Vm,Ro,ZF,vS {:2d} {:8.2f} {:7.3f} {:8.4f} {:8.3f} {:8.4f} {:8.4f}".format(iPrs,pRes,M1P,V1P,D1P,Z1P,V1P)) relV = V1P / Vsat if qBub: sLiq = 1.0 else: sLiq = 0.0 Zgas = Z1P Doil = D1P Ugas = U1P Uoil = U1P else: #-- Two-Phase => Flash the Fluid V, K, X, Y = CF.calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO) vEst = V Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iLiq, pRes, tRes, X, clsEOS) Mgas, Vvap, Dgas, Zgas, Ugas, dumS, dumS = CE.calcProps( iVap, pRes, tRes, Y, clsEOS) Voil = (1.0 - V) * Vliq Vgas = V * Vvap Vtot = Voil + Vgas relV = Vtot / Vsat if clsEXP.sLCCE == "TOT": sLiq = Voil / Vtot else: sLiq = Voil / Vsat #== Store the data for this stage ===================================== clsEXP.dCal[iPrs][iRV] = relV clsEXP.dCal[iPrs][iSL] = sLiq clsEXP.dCal[iPrs][iZF] = Zgas clsEXP.dCal[iPrs][iDO] = Doil clsEXP.dCal[iPrs][iUG] = Ugas clsEXP.dCal[iPrs][iUO] = Uoil #====================================================================== # End of Module #====================================================================== return
def calcSEP(iExp, clsEOS, dicSAM, clsEXP, clsIO): if clsIO.Deb["SEP"] > 0: qDeb = True fDeb = clsIO.fDeb else: qDeb = False nCom = clsEOS.NC nSam = clsEXP.nSamp nPrs = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sName #print("calcSEP: nCom,nSam,nRow ",nCom,nSam,nPrs) typDEP = RX.expDEPvars.get("SEP") typOBS = RX.expOBSvars.get("SEP") iPR = typDEP.index("PRES") iTR = typDEP.index("TEMP") iBO = typOBS.index("BO") iRS = typOBS.index("GOR") iDO = typOBS.index("DENO") iGG = typOBS.index("GGRV") Lsep = clsEXP.Lsep Vsep = clsEXP.Vsep #print("calcSEP: Lsep ",Lsep) #print("calcSEP: Vsep ",Vsep) #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) molZ = NP.zeros(nPrs) comZ = NP.zeros((nCom, nPrs)) xSTO = NP.zeros(nCom) ySTG = NP.zeros(nCom) molO = NP.zeros(nPrs) molG = NP.zeros(nPrs) mSTO = 0.0 mSTG = 0.0 #-- First Stage is (pSat,tRes) and all feed goes to Stage-2 --------- molZ[0] = 1.0 molZ[1] = 1.0 for iC in range(nCom): comZ[iC][0] = Z[iC] comZ[iC][1] = Z[iC] #-- 1st-Stage is Assumed to (Psat,tRes) ----------------------------- pObs = clsEXP.dDep[0][iPR] tRes = clsEXP.dDep[0][iTR] #print("calcSEP: pObs,tRes ",pObs,tRes) #-- Saturation Pressure --------------------------------------------- if clsEXP.PsatO > 0.0: pObs = clsEXP.PsatO else: pObs = -1.0 qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, clsEOS, clsSAM, clsIO) #print("CalcSEP: Psat {:10.3f}".format(pSat)) clsEXP.setPsatCal(pSat) iLiq = 1 iVap = -1 Msat, Vsat, Dsat, Zsat, Usat, dumS, dumS = CE.calcProps( iLiq, pSat, tRes, Z, clsEOS) vEst = 0.5 #====================================================================== # Loop over user defined pressures #====================================================================== zGas = 0.0 zOil = 0.0 zTot = 1.0 for iPrs in range(1, nPrs): pRes = clsEXP.dDep[iPrs][iPR] tRes = clsEXP.dDep[iPrs][iTR] #print("iPrs,pRes,tRes {:2d} {:10.3f} {:8.3f}".format(iPrs,pRes,tRes)) #-- 2-Phase Flash --------------------------------------------------- for iC in range(nCom): Z[iC] = comZ[iC][iPrs] #zSum = NP.sum(Z) #Z = NP.divide(Z,zSum) Z = UT.Norm(Z) #print("iSep,Z ",iPrs,Z) V, K, X, Y = CF.calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO) if V < 0.0: V = 0.0 #-- calcFlash sets X=Z & Y=Z if 1-Phase elif V > 1.0: V = 1.0 vEst = V zGas = molZ[iPrs] * V zOil = molZ[iPrs] * (1.0 - V) molG[iPrs] = zGas molO[iPrs] = zOil #print("iSep,molZ,molG,molO {:2d} {:10.5f} {:10.5f} {:10.5f}".format(iPrs,molZ[iPrs],molG[iPrs],molO[iPrs])) #-- Properties of the Liquid and Vapour Output of this stage -------- Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iLiq, pRes, tRes, X, clsEOS) Mgas, Vvap, Dgas, Zgas, Ugas, dumS, dumS = CE.calcProps( iVap, pRes, tRes, Y, clsEOS) #-- Where is Liquid Output Going Next? ------------------------------ kSepL = Lsep[iPrs] if kSepL == 0: if mSTO + zOil > 0.0: for iC in range(nCom): xSTO[iC] = (xSTO[iC] * mSTO + zOil * X[iC]) / (mSTO + zOil) mSTO = mSTO + zOil else: xSTO = BP.copy(X) else: for iC in range(nCom): comZ[iC][kSepL] = (comZ[iC][kSepL] * molZ[kSepL] + X[iC] * zOil) / (molZ[kSepL] + zOil) molZ[kSepL] = molZ[kSepL] + zOil #-- Where is Vapour Output Going Next? ------------------------------ kSepV = Vsep[iPrs] if kSepV == 0: if mSTG + zGas > 0.0: for iC in range(nCom): ySTG[iC] = (ySTG[iC] * mSTG + zGas * Y[iC]) / (mSTG + zGas) mSTG = mSTG + zGas else: ySTG = NP.copy(Y) else: for iC in range(nCom): comZ[iC][kSepV] = (comZ[iC][kSepV] * molZ[kSepV] + Y[iC] * zGas) / (molZ[kSepV] + zGas) molZ[kSepV] = molZ[kSepV] + zGas Voil = zOil * Vliq Vgas = zGas * CO.volMol #-- Temporary storage for Bo & Rs ahead of divide by Vsto below ----- clsEXP.dCal[iPrs][iBO] = Voil clsEXP.dCal[iPrs][iRS] = Vgas clsEXP.dCal[iPrs][iDO] = Doil clsEXP.dCal[iPrs][iGG] = Mgas / CO.molAir #== Stock Tank Oil Volume ============================================= nTot = 0.0 rTot = 0.0 gTot = 0.0 Vsto = clsEXP.dCal[nPrs - 1][iBO] for iPrs in range(1, nPrs): clsEXP.dCal[iPrs][iBO] = clsEXP.dCal[iPrs][iBO] / Vsto #-- Bo clsEXP.dCal[iPrs][iRS] = clsEXP.dCal[iPrs][iRS] / Vsto #-- GOR nTot = nTot + molG[iPrs] rTot = rTot + molG[iPrs] * clsEXP.dCal[iPrs][iRS] gTot = gTot + molG[iPrs] * clsEXP.dCal[iPrs][iGG] #== Saturation Pressure Stage ========================================= if nTot > 0.0: gTot = gTot / nTot else: gTot = 0.0 #print("mSTG,mSTO {:10.5f} {:10.5f}".format(mSTG,mSTO)) clsEXP.dCal[0][iBO] = Vsat / Vsto clsEXP.dCal[0][iRS] = mSTG * CO.volMol / Vsto clsEXP.dCal[0][iDO] = Dsat clsEXP.dCal[0][iGG] = gTot #====================================================================== # End of Module #====================================================================== return
def calcDLE(iExp, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.NC nSam = clsEXP.nSamp nPrs = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sName #print("calcCVD: nCom,nSam,nRow ",nCom,nSam,nPrs) typDEP = RX.expDEPvars.get("DLE") typOBS = RX.expOBSvars.get("DLE") iPR = typDEP.index("PRES") iBO = typOBS.index("BO") iRS = typOBS.index("GOR") iDO = typOBS.index("DENO") iBT = typOBS.index("BT") iBG = typOBS.index("BG") iZF = typOBS.index("ZFAC") iGG = typOBS.index("GGRV") iUO = typOBS.index("VISO") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #-- Saturation Pressure --------------------------------------------- if clsEXP.PsatO > 0.0: pObs = clsEXP.PsatO else: pObs = -1.0 qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, clsEOS, clsSAM, clsIO) clsEXP.setPsatCal(pSat) iLiq = 1 iVap = -1 Msat, Vsat, Dsat, Zsat, Usat, dumS, dumS = CE.calcProps( iLiq, pSat, tRes, Z, clsEOS) if qBub: vEst = 0.0 else: vEst = 1.0 #====================================================================== # Loop over user defined pressures #====================================================================== zMol = 1.0 rTot = 0.0 psTs = CO.pStand / CO.tStand for iPrs in range(nPrs): pRes = clsEXP.dDep[iPrs][iPR] #== 1-Phase or 2-Phase? =============================================== if pRes > pSat: M1P, V1P, D1P, Z1P, U1P, dmS, dmS = CE.calcProps( iLiq, pRes, tRes, Z, clsEOS) if qBub: sLiq = 1.0 else: sLiq = 0.0 Voil = V1P Vrem = 0.0 Doil = D1P Vtot = V1P Bgas = 0.0 Zgas = 0.0 gGrv = 0.0 Uoil = U1P else: V, K, X, Y = CF.calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO) vEst = V Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iLiq, pRes, tRes, X, clsEOS) Mgas, Vvap, Dgas, Zgas, Ugas, dumS, dumS = CE.calcProps( iVap, pRes, tRes, Y, clsEOS) Voil = zMol * (1.0 - V) * Vliq Vgas = zMol * V * Vvap zRem = pRes * Vgas / (Zgas * CO.gasCon * tRes) zMol = zMol - zRem Vrem = zRem * CO.volMol rTot = rTot + Vrem Z = NP.copy(X) Vtot = Voil + Vgas Bgas = psTs * Zgas * tRes / pRes gGrv = Mgas / CO.molAir #-- Temporary Storage Ahead of Stock Tank Corrections --------------- clsEXP.dCal[iPrs][iBO] = Voil clsEXP.dCal[iPrs][iRS] = Vrem clsEXP.dCal[iPrs][iDO] = Doil clsEXP.dCal[iPrs][iBT] = Vtot clsEXP.dCal[iPrs][iBG] = Bgas clsEXP.dCal[iPrs][iZF] = Zgas clsEXP.dCal[iPrs][iGG] = gGrv clsEXP.dCal[iPrs][iUO] = Uoil #== Stock Tank Volume ================================================= Mst, Vst, Dst, Zst, Ust, dmS, dmS = CE.calcProps(iLiq, CO.pStand, CO.tStand, Z, clsEOS) Vsto = zMol * Vst #== "Normalise" via Stock Tank Volume ================================= for iPrs in range(nPrs): rTot = rTot - clsEXP.dCal[iPrs][iRS] clsEXP.dCal[iPrs][iBO] = clsEXP.dCal[iPrs][iBO] / Vsto clsEXP.dCal[iPrs][iRS] = rTot / Vsto clsEXP.dCal[iPrs][iBT] = clsEXP.dCal[iPrs][iBO] + \ clsEXP.dCal[iPrs][iBG]*(clsEXP.dCal[0][iRS] - clsEXP.dCal[iPrs][iRS]) #====================================================================== # End of Module #====================================================================== return
def calcCVD(iExp, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.NC nSam = clsEXP.nSamp nPrs = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sName #print("calcCVD: nCom,nSam,nRow ",nCom,nSam,nPrs) typDEP = RX.expDEPvars.get("CVD") typOBS = RX.expOBSvars.get("CVD") iPR = typDEP.index("PRES") iMR = typOBS.index("MREM") iSL = typOBS.index("SLIQ") iZF = typOBS.index("ZFAC") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #-- Saturation Pressure --------------------------------------------- if clsEXP.PsatO > 0.0: pObs = clsEXP.PsatO else: pObs = -1.0 qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, clsEOS, clsSAM, clsIO) clsEXP.setPsatCal(pSat) iNeu = 0 iLiq = 1 iVap = -1 Msat, Vsat, Dsat, Zsat, Usat, dumS, dumS = CE.calcProps( iNeu, pSat, tRes, Z, clsEOS) if qBub: vEst = 0.0 else: vEst = 1.0 #====================================================================== # Loop over user defined pressures #====================================================================== zMol = 1.0 zTot = 0.0 for iPrs in range(nPrs): pRes = clsEXP.dDep[iPrs][iPR] #== 1-Phase or 2-Phase? =============================================== if pRes > pSat: M1P, V1P, D1P, Z1P, U1P, dmS, dmS = CE.calcProps( iNeu, pRes, tRes, Z, clsEOS) if qBub: sLiq = 1.0 else: sLiq = 0.0 zTot = 0.0 Zgas = Z1P else: V, K, X, Y = CF.calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO) vEst = V Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iLiq, pRes, tRes, X, clsEOS) Mgas, Vvap, Dgas, Zgas, Ugas, dumS, dumS = CE.calcProps( iVap, pRes, tRes, Y, clsEOS) Voil = zMol * (1.0 - V) * Vliq Vgas = zMol * V * Vvap sLiq = Voil / Vsat Vtot = Voil + Vgas Vrem = Vtot - Vsat zRem = pRes * Vrem / (Zgas * CO.gasCon * tRes) for iC in range(nCom): Z[iC] = (zMol * Z[iC] - zRem * Y[iC]) / (zMol - zRem) zMol = zMol - zRem zTot = zTot + zRem #-- Load Data ------------------------------------------------------- clsEXP.dCal[iPrs][iMR] = zTot clsEXP.dCal[iPrs][iSL] = sLiq clsEXP.dCal[iPrs][iZF] = Zgas #====================================================================== # End of Module #====================================================================== return
def calcCCE(iExp, qDif, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.nComp nSam = clsEXP.nSamp nPrs = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sNam #== Independent & Calculated Data ===================================== typIND = AP.classLIB().INDshrt.get("CCE") typCAL = AP.classLIB().CALshrt.get("CCE") iPR = typIND.index("PRES") iRV = typCAL.index("RELV") iSL = typCAL.index("SLIQ") iZF = typCAL.index("ZFAC") iDO = typCAL.index("DENO") iUG = typCAL.index("VISG") iUO = typCAL.index("VISO") iMO = typCAL.index("MWO") iMG = typCAL.index("MWG") iDG = typCAL.index("DENG") iFT = typCAL.index("IFT") iHO = typCAL.index("HO") iHG = typCAL.index("HG") iCO = typCAL.index("CPO") iCG = typCAL.index("CPG") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #-- Saturation Pressure --------------------------------------------- if clsEXP.PsatO > 0.0: pObs = clsEXP.PsatO else: pObs = -1.0 qBub, pSat, logK = clsEXP.getPsatInfo(qDif, nCom) qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, qBub, pSat, logK, clsEOS, clsSAM, clsIO) if not qDif: clsEXP.setPsatInfo(qBub, pSat, NP.log(Ksat)) clsEXP.setPsatCal(pSat) iNeu = 0 iLiq = 1 iVap = -1 Msat, Vsat, Dsat, Zsat, Usat, dumS, dumS = CE.calcProps( iNeu, pSat, tRes, Z, clsEOS) #if qBub : vEst = 0.0 #else : vEst = 1.0 vEst = None #====================================================================== # Loop over user defined pressures #====================================================================== for iPrs in range(nPrs): pRes = clsEXP.dInd[iPR][iPrs] #== 1-Phase or 2-Phase? =============================================== if pRes > pSat: Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iNeu, pRes, tRes, Z, clsEOS) #print("calcCCE[Z]: iP,pR,Mw,Vm,Ro,ZF,vS {:2d} {:8.2f} {:7.3f} {:8.4f} {:8.3f} {:8.4f} {:8.4f}".format(iPrs,pRes,M1P,V1P,D1P,Z1P,V1P)) relV = Vliq / Vsat if qBub: sLiq = 1.0 else: sLiq = 0.0 Mgas = Moil Vvap = Vliq Dgas = Doil Zgas = Zoil Ugas = Uoil IFT = 0.0 #-- Surface Tension [dyne/cm] HO,CPO,uJTO = \ CE.calcEnthSpecHeat(iNeu,pRes,tRes,Z,clsEOS) #-- Enthalpy & Spec Heat HG = HO CPG = CPO uJTG = uJTO #-- Gas = Oil = 1-Phase! #print("P,uJTO,uJTG,IFT {:8.2f} {:10.3e} {:10.3e} {:8.4f}".format(pRes,uJTO,uJTG,IFT)) else: #-- Two-Phase => Flash the Fluid V, K, X, Y = CF.calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO) vEst = V Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iLiq, pRes, tRes, X, clsEOS) Mgas, Vvap, Dgas, Zgas, Ugas, dumS, dumS = CE.calcProps( iVap, pRes, tRes, Y, clsEOS) Voil = (1.0 - V) * Vliq Vgas = V * Vvap Vtot = Voil + Vgas relV = Vtot / Vsat if clsEXP.sLCCE == "TOT": sLiq = Voil / Vtot else: sLiq = Voil / Vsat if sLiq < 0.0: crash = 1.0 / 0.0 IFT = CE.calcIFT(Vliq, Vvap, X, Y, clsEOS) HO,CPO,uJTO = \ CE.calcEnthSpecHeat(iLiq,pRes,tRes,X,clsEOS) #-- Enthalpy & Spec Heat HG,CPG,uJTG = \ CE.calcEnthSpecHeat(iVap,pRes,tRes,Y,clsEOS) #-- Enthalpy & Spec Heat #print("P,uJTO,uJTg {:8.2f} {:10.3e} {:10.3e} {:8.4f}".format(pRes,uJTO,uJTG,IFT)) #== Store the data for this stage ===================================== clsEXP.dCal[iRV][iPrs] = relV clsEXP.dCal[iSL][iPrs] = sLiq clsEXP.dCal[iZF][iPrs] = Zgas clsEXP.dCal[iDO][iPrs] = Doil clsEXP.dCal[iUG][iPrs] = Ugas clsEXP.dCal[iUO][iPrs] = Uoil clsEXP.dCal[iMO][iPrs] = Moil clsEXP.dCal[iMG][iPrs] = Mgas clsEXP.dCal[iDG][iPrs] = Dgas clsEXP.dCal[iFT][iPrs] = IFT clsEXP.dCal[iHO][iPrs] = HO clsEXP.dCal[iHG][iPrs] = HG clsEXP.dCal[iCO][iPrs] = CPO clsEXP.dCal[iCG][iPrs] = CPG #====================================================================== # End of Module #====================================================================== return
def calcSAT(iExp, qDif, clsEOS, dicSAM, clsEXP, clsIO): nCom = clsEOS.nComp nSam = clsEXP.nSamp nTem = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sNam #print("calcSEP: nCom,nSam,nRow ",nCom,nSam,nPrs) typIND = AP.classLIB().INDshrt.get("SAT") typOBS = AP.classLIB().OBSshrt.get("SAT") iTR = typIND.index("TEMP") iPS = typOBS.index("PSAT") iZF = typOBS.index("ZFAC") iDO = typOBS.index("DENO") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = dicSAM[nSam].gZI(iC) #====================================================================== # Loop over user defined 'stages' #====================================================================== for iTem in range(nTem): tRes = clsEXP.dInd[iTR][iTem] pSatO = clsEXP.dObs[iPS][iTem] if pSatO > 0.0: pEst = 0.95 * pSatO else: pEst = -1.0 qBub = None pSat = None logK = NP.empty(nCom) qBub,pSat,Ksat = \ CS.calcPsat(pEst,tRes,qBub,pSat,logK,clsEOS,clsSAM,clsIO) iLiq = 0 MPs, VPs, DPs, ZPs, UPs, dmS, dmS = CE.calcProps( iLiq, pSat, tRes, Z, clsEOS) clsEXP.dCal[iPS][iTem] = pSat clsEXP.dCal[iZF][iTem] = ZPs clsEXP.dCal[iDO][iTem] = DPs #print("calcSAT: tRes,qBub,pSat ",tRes,qBub,pSat) #====================================================================== # End of Module #====================================================================== return
def calcCVD(iExp, qDif, clsEOS, dicSAM, clsEXP, clsIO): if clsIO.Deb["CVD"] > 0: qDeb = True fDeb = clsIO.fDeb else: qDeb = False nCom = clsEOS.nComp nSam = clsEXP.nSamp nPrs = clsEXP.nRow clsSAM = dicSAM[nSam] sNam = clsSAM.sNam if qDeb: sOut = "calcCVD: nCom,nSam,nRow {:2d} {:2d} {:2d}\n".format( nCom, nSam, nPrs) fDeb.write(sOut) #-- Independent & Calculated Data ----------------------------------- typIND = AP.classLIB().INDshrt.get("CVD") typCAL = AP.classLIB().CALshrt.get("CVD") iPR = typIND.index("PRES") iMR = typCAL.index("MREM") iSL = typCAL.index("SLIQ") iZF = typCAL.index("ZFAC") iMO = typCAL.index("MWO") iMG = typCAL.index("MWG") iDO = typCAL.index("DENO") iDG = typCAL.index("DENG") iUO = typCAL.index("VISO") iUG = typCAL.index("VISG") #-- Load Feed Composition ------------------------------------------- Z = NP.zeros(nCom) for iC in range(nCom): Z[iC] = clsSAM.gZI(iC) #-- Reservoir Temperature ------------------------------------------- tRes = clsEXP.Tres #-- Saturation Pressure --------------------------------------------- if clsEXP.PsatO > 0.0: pObs = clsEXP.PsatO else: pObs = -1.0 qBub, pSat, logK = clsEXP.getPsatInfo(qDif, nCom) qBub, pSat, Ksat = CS.calcPsat(pObs, tRes, qBub, pSat, logK, clsEOS, clsSAM, clsIO) if qDeb: sOut = "calcCVD: tRes,qBub,pSat {:8.2f} {:} {:10.3f}\n".format( tRes, qBub, pSat) fDeb.write(sOut) if not qDif: clsEXP.setPsatInfo(qBub, pSat, NP.log(Ksat)) clsEXP.setPsatCal(pSat) iNeu = 0 iLiq = 1 iVap = -1 Msat, Vsat, Dsat, Zsat, Usat, dumS, dumS = CE.calcProps( iNeu, pSat, tRes, Z, clsEOS) #if qBub : vEst = 0.0 #else : vEst = 1.0 vEst = None #====================================================================== # Loop over user defined pressures #====================================================================== zMol = 1.0 zTot = 0.0 for iPrs in range(nPrs): pRes = clsEXP.dInd[iPR][iPrs] #== 1-Phase or 2-Phase? =============================================== if pRes > pSat: Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iNeu, pRes, tRes, Z, clsEOS) if qBub: sLiq = 1.0 else: sLiq = 0.0 zTot = 0.0 Mgas = Moil Dgas = Doil Zgas = Zoil Ugas = Uoil else: V, K, X, Y = CF.calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO) vEst = V Moil, Vliq, Doil, Zoil, Uoil, dumS, dumS = CE.calcProps( iLiq, pRes, tRes, X, clsEOS) Mgas, Vvap, Dgas, Zgas, Ugas, dumS, dumS = CE.calcProps( iVap, pRes, tRes, Y, clsEOS) Voil = zMol * (1.0 - V) * Vliq Vgas = zMol * V * Vvap sLiq = Voil / Vsat Vtot = Voil + Vgas Vrem = Vtot - Vsat zRem = pRes * Vrem / (Zgas * UT.gasCon * tRes) #-- Moles Removed for iC in range(nCom): Z[iC] = (zMol * Z[iC] - zRem * Y[iC]) / (zMol - zRem) zMol = zMol - zRem zTot = zTot + zRem if qDeb: sOut = "calcCVD: zRem {:10.3e}\n".format(zRem) fDeb.write(sOut) #-- Load Data ------------------------------------------------------- clsEXP.dCal[iMR][iPrs] = zTot clsEXP.dCal[iSL][iPrs] = sLiq clsEXP.dCal[iZF][iPrs] = Zgas clsEXP.dCal[iMO][iPrs] = Moil clsEXP.dCal[iMG][iPrs] = Mgas clsEXP.dCal[iDO][iPrs] = Doil clsEXP.dCal[iDG][iPrs] = Dgas clsEXP.dCal[iUO][iPrs] = Uoil clsEXP.dCal[iUG][iPrs] = Ugas #====================================================================== # End of Module #====================================================================== return