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 writeMORE(ZMFvD, clsEOS, dicSAM, clsCMP, clsIO, clsUNI): #-- Initialisation -------------------------------------------------- sCom = "--" nCom = clsEOS.nComp dVec = NP.zeros(nCom) #-- Open the MORE File, if not already open ------------------------ if not clsIO.qMOR: pathMOR = clsIO.patR + ".mor" fMOR = open(pathMOR, 'w') clsIO.setQMOR(True) clsIO.setFMOR(fMOR) else: fMOR = clsIO.fMOR #== Headers =========================================================== print("Writing Compositional Description for Tempest-MORE") fSim = clsIO.fMOR sInp = clsIO.fInp.name OutU = clsCMP.OutU if OutU[:3] == "MET": sUni = "METRIC" else: sUni = "FIELD " #-- Write Header Information to Simulator File ---------------------- WO.outputHeader(fSim, sCom, clsIO) WO.outputEOS(fSim, sCom, clsIO, clsEOS) #-- Header ---------------------------------------------------------- # 123456789012345678901234567890123456789012345678901234567890 sHead = "--==========================================================\n" fSim.write(sHead) sLabl = "-- Tempest-MORE EOS Model generated by PVTfree Program\n" fSim.write(sLabl) sLabl = "-- From dataset " + sInp + "\n" fSim.write(sLabl) sLabl = "-- User specified " + sUni + " Units\n" fSim.write(sLabl) fSim.write(sHead) fSim.write("\n") #---------------------------------------------------------------------- # MORE-Specific Data #---------------------------------------------------------------------- sLabl = "-- Component Names (CNAM) are specified in the INPU section\n" fSim.write(sLabl) fSim.write("\n") sOut = "CNAM " for iC in range(nCom): sOut = sOut + clsEOS.gNM(iC) + " " sOut = sOut + "WATR\n" fSim.write(sOut) fSim.write("\n") #-- Composition ----------------------------------------------------- sOut = "-- Compositions\n" fSim.write(sOut) fSim.write("\n") nSam = len(dicSAM) for iSam in range(nSam): clsSAM = dicSAM[iSam] sNam = clsSAM.sNam sCom = "" sKey = "SCMP " + sNam + "\n" for iC in range(nCom): dVec[iC] = clsSAM.gZI(iC) writeVectorD(fSim, sCom, sKey, 6, "{:10.7f}", dVec) #-- Fluid Section Header -------------------------------------------- fSim.write(sHead) sLabl = "FLUI EOS\n" fSim.write(sLabl) fSim.write(sHead) fSim.write("\n") sLabl = "-- Equation of State\n" fSim.write(sLabl) fSim.write("\n") sEoS = clsEOS.EOS sOut = "EQUA " + sEoS + "\n" fSim.write(sOut) fSim.write("\n") #-- Reservoir Temperature ------------------------------------------- tRes = clsCMP.Tres if OutU[:3] == "MET": sUni = ": [degC]" tRes = clsUNI.I2X(tRes, "degC") else: sUni = ": [degF]" tRes = clsUNI.I2X(tRes, "degF") sTr = "{:10.3f}\n".format(tRes) sLabl = "-- Reservoir Temperature " + sUni + "\n" fSim.write(sLabl) fSim.write("\n") sOut = "TEMP " + sTr fSim.write(sOut) fSim.write("\n") #-- Main Properties Table ------------------------------------------- sLabl = "-- Main Fluid Properties\n" fSim.write(sLabl) fSim.write("\n") sOut = "PROP CNam Mw Tc Pc AcF Zc SG Para\n" fSim.write(sOut) if OutU[:3] == "MET": sOut = "-- Kelv bara\n" else: sOut = "-- degR psia\n" fSim.write(sOut) for iC in range(nCom): sN = clsEOS.gNM(iC) sNm = sN.ljust(8, ' ') Mw = clsEOS.gPP("MW", iC) sMw = "{:10.3f} ".format(Mw) Tc = clsEOS.gPP("TC", iC) Pc = clsEOS.gPP("PC", iC) if OutU[:3] == "MET": Tc = clsUNI.I2X(Tc, "kelv") Pc = clsUNI.I2X(Pc, "bara") sPc = "{:10.4f}".format(Pc) else: sPc = "{:10.3f} ".format(Pc) sTc = "{:10.3f} ".format(Tc) AF = clsEOS.gPP("AF", iC) sAF = "{:10.5f} ".format(AF) Zc = clsEOS.gPP("ZC", iC) sZc = "{:10.5f} ".format(Zc) SG = clsEOS.gPP("SG", iC) sSG = "{:10.5f} ".format(SG) PA = clsEOS.gPP("PA", iC) sPA = "{:10.3f} ".format(PA) sOut = " " + sNm + sMw + sTc + sPc + sAF + sZc + sSG + sPA + "\n" fSim.write(sOut) fSim.write("/\n") fSim.write("\n") #-- Omega-A & Omega-B Multiplers ----------------------------------- sCom = "-- Omega-A Multipliers " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MA", iC) writeVectorD(fSim, sCom, "OMGA MULT\n", 6, "{:11.9f}", dVec) sCom = "-- Omega-B Multipliers " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MB", iC) writeVectorD(fSim, sCom, "OMGB MULT\n", 6, "{:11.9f}", dVec) #-- Volume Shift Parameters ----------------------------------------- sCom = "-- Volume Shifts " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("SS", iC) writeVectorD(fSim, sCom, "VOLU\n", 6, "{:11.8f}", dVec) #-- BIPs ------------------------------------------------------------ fSim.write("-- Binary Iteraction Parameters (Lower Triangle)\n") fSim.write("\n") fSim.write("INTE\n") sCom = "" for iC in range(1, nCom): bVec = NP.zeros(iC) for jC in range(iC): bVec[jC] = clsEOS.gIJ(iC, jC) writeVectorD(fSim, sCom, "ROW", 7, "{:9.6f}", bVec) fSim.write("/\n") fSim.write("\n") #-- Brine Density at Standard (Stock Tank) Conditions --------------- mFrc = clsCMP.bSalt #-- Mass Fraction of Salt in the Brine dSTW, comW = CW.calcRoweChouDen(mFrc, UT.tStand, UT.pStand, clsUNI) #-- Stock Tank Brine Density clsCMP.setDenSTW(dSTW) clsCMP.setDenSTO(-1.0) #-- In EoS Mode, E300 calculates STO Density clsCMP.setDenSTG(-1.0) #-- Ditto #== Brine Properties at Reference Pressure & Tres (for PVTW keyword) == if clsCMP.setBr: CW.calcPVTW(clsCMP, clsUNI, clsIO) #== Write DENSITY and PVTW keywords =================================== WB.outputECLDensity(OutU, fSim, clsCMP, clsUNI) WB.outputECLPVTW(OutU, fSim, clsCMP, clsUNI) #== Close the file ==================================================== clsIO.qMOR = UT.closeFile(fSim) #== No return value =================================================== return
def writeE300(ZMFvD, clsEOS, dicSAM, clsCMP, clsIO, clsUNI): #-- Open the E300 File, if not already open ------------------------ if not clsIO.q300: path300 = clsIO.patR + ".e300" f300 = open(path300, 'w') clsIO.setQ300(True) clsIO.setF300(f300) else: f300 = clsIO.f300 sCom = "--" #== Headers =========================================================== print("Writing Compositional Description for E300") fSim = clsIO.f300 sInp = clsIO.fInp.name OutU = clsCMP.OutU if OutU[:3] == "MET": sUni = "METRIC" else: sUni = "FIELD " #-- Write Header Information to Simulator File ---------------------- WO.outputHeader(fSim, sCom, clsIO) WO.outputEOS(fSim, sCom, clsIO, clsEOS) #-- Header ---------------------------------------------------------- # 123456789012345678901234567890123456789012345678901234567890 sHead = "--==========================================================\n" fSim.write(sHead) sLabl = "-- E300 EOS Model generated by PVTfree Program\n" fSim.write(sLabl) sLabl = "-- From dataset " + sInp + "\n" fSim.write(sLabl) sLabl = "-- User specified " + sUni + " Units\n" fSim.write(sLabl) fSim.write(sHead) fSim.write("\n") #-- Number of Components -------------------------------------------- nCom = clsEOS.nComp sLabl = "-- Number of Components\n" fSim.write(sLabl) fSim.write("\n") sLabl = "NCOMPS\n" fSim.write(sLabl) sLabl = " {:2d} /\n".format(nCom) fSim.write(sLabl) fSim.write("\n") #-- Equation of State ----------------------------------------------- EOS = clsEOS.EOS if EOS == "SRK": sExt = "Soave-Redlich-Kwong (SRK)" else: sExt = "Peng-Robinson (PR)" sLabl = "-- Equation of State: " + sExt + "\n" fSim.write(sLabl) fSim.write("\n") sLabl = "EOS\n" fSim.write(sLabl) sLabl = " " + str(EOS) + " /\n" fSim.write(sLabl) fSim.write("\n") if EOS == "PR": sLabl = "-- Modified Form of the Peng-Robinson EOS\n" fSim.write(sLabl) fSim.write("\n") sLabl = "PRCORR\n" fSim.write(sLabl) fSim.write("\n") #== Component Properties ============================================== sVec = ["" for i in range(nCom)] dVec = NP.zeros(nCom) #-- Component Names ------------------------------------------------- sCom = "-- Component Names " + "\n" for iC in range(nCom): sVec[iC] = clsEOS.gNM(iC) writeVectorS(fSim, sCom, "CNAMES\n", 7, 8, sVec) #-- Mole Weights ---------------------------------------------------- if OutU[:3] == "MET": sUni = ": [kg/kgmol]" else: sUni = ": [lb/lbmol]" sCom = "-- Molecular Weights " + sUni + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MW", iC) writeVectorD(fSim, sCom, "MW\n", 7, "{:8.3f}", dVec) #-- Critical Temperatures ------------------------------------------- if OutU[:3] == "MET": sUni = ": [Kelvin]" for iC in range(nCom): dVec[iC] = clsUNI.I2X(clsEOS.gPP("TC", iC), "kelv") else: sUni = ": [degrees Rankine]" for iC in range(nCom): dVec[iC] = clsEOS.gPP("TC", iC) sCom = "-- Critical Temperatures " + sUni + "\n" writeVectorD(fSim, sCom, "TCRIT\n", 7, "{:8.3f}", dVec) #-- Critical Pressures ---------------------------------------------- if OutU[:3] == "MET": sUni = ": [barsa]" sFor = "{:8.4f}" for iC in range(nCom): dVec[iC] = clsUNI.I2X(clsEOS.gPP("PC", iC), "bara") else: sUni = ": [psia]" sFor = "{:8.3f}" for iC in range(nCom): dVec[iC] = clsEOS.gPP("PC", iC) sCom = "-- Critical Pressures " + sUni + "\n" writeVectorD(fSim, sCom, "PCRIT\n", 7, sFor, dVec) #-- Critical Volumes ------------------------------------------------ if OutU[:3] == "MET": sUni = ": [m3/kgmol]" sFor = "{:8.3f}" for iC in range(nCom): dVec[iC] = clsUNI.I2X(clsEOS.gPP("VC", iC), "m3/kgmol") else: sUni = ": [ft3/lbmol]" sFor = "{:8.4f}" for iC in range(nCom): dVec[iC] = clsEOS.gPP("VC", iC) sCom = "-- Critical Volumes " + sUni + "\n" writeVectorD(fSim, sCom, "VCRIT\n", 7, sFor, dVec) #-- Critical Z-Factors ---------------------------------------------- sCom = "-- Critical Z-Factors " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("ZC", iC) writeVectorD(fSim, sCom, "ZCRIT\n", 7, "{:8.6f}", dVec) #-- Acentric Factors ------------------------------------------------ sCom = "-- Acentric Factors " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("AF", iC) writeVectorD(fSim, sCom, "ACF\n", 7, "{:8.6f}", dVec) #-- Omega-A's ------------------------------------------------------- sCom = "-- Omega-A Values " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MA", iC) * clsEOS.OA writeVectorD(fSim, sCom, "OMEGAA\n", 6, "{:11.9f}", dVec) #-- Omega-B's ------------------------------------------------------- sCom = "-- Omega-B Values " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MB", iC) * clsEOS.OB writeVectorD(fSim, sCom, "OMEGAB\n", 6, "{:11.9f}", dVec) #-- Parachors ------------------------------------------------------- sCom = "-- Parachors " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("PA", iC) writeVectorD(fSim, sCom, "PARACHOR\n", 7, "{:8.3f}", dVec) #-- Volume Shifts --------------------------------------------------- sCom = "-- Volume Shifts " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("SS", iC) writeVectorD(fSim, sCom, "SSHIFT\n", 7, "{:9.6f}", dVec) #== Binary Interation Coefficients ==================================== fSim.write("-- Binary Iteraction Parameters\n") fSim.write("\n") fSim.write("BIC\n") sCom = "" for iC in range(1, nCom): bVec = NP.zeros(iC) for jC in range(iC): bVec[jC] = clsEOS.gIJ(iC, jC) writeVectorD(fSim, sCom, "", 7, "{:9.6f}", bVec) fSim.write("/\n") fSim.write("\n") #-- Reservoir Temperature ------------------------------------------- tRes = clsCMP.Tres if OutU[:3] == "MET": sUni = ": [degC]" tRes = clsUNI.I2X(tRes, "degC") else: sUni = ": [degF]" tRes = clsUNI.I2X(tRes, "degF") sLabl = "-- Reservoir Temperature " + sUni + "\n" fSim.write(sLabl) fSim.write("\n") fSim.write("RTEMP\n") sLabl = " {:7.3f}".format(tRes) + " /\n" fSim.write(sLabl) fSim.write("\n") #== Composition (versus Depth? ========================================= if clsCMP.qDep: dGOC = clsCMP.dGOC if OutU[:3] == "MET": dUni = "m" zUni = "-- Depth/[m] Composition\n" else: dUni = "ft" zUni = "-- Depth/[ft] Composition\n" dGOC = clsUNI.I2X(dGOC, dUni) sGOC = "{:10.3f} ".format(dGOC) fSim.write("-- Composition versus Depth\n") fSim.write("-- Note: d(GOC) = " + sGOC + dUni + "\n") fSim.write("\n") fSim.write("ZMFVD\n") fSim.write(zUni) writeZMFVD(ZMFvD, dUni, fSim, "ECL", nCom, clsUNI) else: sCom = "-- Composition\n" for iC in range(nCom): dVec[iC] = dicSAM[0].gZI(iC) writeVectorD(fSim, sCom, "ZI\n", 6, "{:10.7f}", dVec) #== Brine Density at Standard (Stock Tank) Conditions ================= mFrc = clsCMP.bSalt #-- Mass Fraction of Salt in the Brine dSTW, comW = CW.calcRoweChouDen(mFrc, UT.tStand, UT.pStand, clsUNI) #-- Stock Tank Brine Density clsCMP.setDenSTW(dSTW) clsCMP.setDenSTO(-1.0) #-- In EoS Mode, E300 calculates STO Density clsCMP.setDenSTG(-1.0) #-- Ditto WB.outputECLDensity(OutU, fSim, clsCMP, clsUNI) #-- Brine Properties at Reference Pressure & Tres (for PVTW keyword) if clsCMP.setBr: CW.calcPVTW(clsCMP, clsUNI, clsIO) #== Write DENSITY and PVTW keywords =================================== WB.outputECLPVTW(OutU, fSim, clsCMP, clsUNI) #== Close the file ==================================================== clsIO.q300 = UT.closeFile(fSim) #== No return value =================================================== return
def writeVIP(ZMFvD, clsEOS, dicSAM, clsCMP, clsIO, clsUNI): #-- Initialisation -------------------------------------------------- sCom = "C " nCom = clsEOS.nComp dVec = NP.zeros(nCom) #-- Open the VIP File, if not already open ------------------------- if not clsIO.qVIP: pathVIP = clsIO.patR + ".vip" fVIP = open(pathVIP, 'w') clsIO.setQVIP(True) clsIO.setFVIP(fVIP) else: fVIP = clsIO.fVIP #== Headers =========================================================== print("Writing Compositional Description for VIP/Nexus") fSim = clsIO.fVIP sInp = clsIO.fInp.name OutU = clsCMP.OutU if OutU[:3] == "MET": sUni = "METRIC" else: sUni = "FIELD " #-- Write Header Information to Simulator File ---------------------- WO.outputHeader(fSim, sCom, clsIO) WO.outputEOS(fSim, sCom, clsIO, clsEOS) #-- Header ---------------------------------------------------------- # 123456789012345678901234567890123456789012345678901234567890 sHead = "C ==========================================================\n" fSim.write(sHead) sLabl = "C VIP/Nexus EOS Model generated by PVTfree Program\n" fSim.write(sLabl) sLabl = "C From dataset " + sInp + "\n" fSim.write(sLabl) sLabl = "C User specified " + sUni + " Units\n" fSim.write(sLabl) fSim.write(sHead) fSim.write("\n") #-- Equation of State ----------------------------------------------- sLabl = "C Equation of State: Peng-Robinson (PR) or Soave-Redlich-Kwong (SRK)\n" fSim.write(sLabl) fSim.write("\n") sEoS = clsEOS.EOS sOut = "EOS " + sEoS + " 1 \n" fSim.write(sOut) fSim.write("\n") #-- Components ------------------------------------------------------ sLabl = "C Component Names\n" fSim.write(sLabl) fSim.write("\n") fSim.write("COMPONENTS\n") sOut = " " for iC in range(nCom): sNam = clsEOS.gNM(iC) sOut = sOut + sNam + " " sOut = sOut + "\n" fSim.write(sOut) fSim.write("\n") #-- Main Properties Table ------------------------------------------- sLabl = "C Main Fluid Properties\n" fSim.write(sLabl) fSim.write("\n") if OutU[:3] == "MET": sOut = "PROPERTIES C KPA\n" else: sOut = "PROPERTIES F PSIA\n" fSim.write(sOut) # 12345678901 sOut = "COMP MW TC PC ZC ACENTRIC OMEGAA OMEGAB VSHIFT PCHOR\n" fSim.write(sOut) for iC in range(nCom): sN = clsEOS.gNM(iC) sNm = sN.ljust(9, ' ') Mw = clsEOS.gPP("MW", iC) sMw = "{:10.3f} ".format(Mw) Tc = clsEOS.gPP("TC", iC) Pc = clsEOS.gPP("PC", iC) if OutU[:3] == "MET": Tc = clsUNI.I2X(Tc, "degc") Pc = clsUNI.I2X(Pc, "kpa") else: Tc = clsUNI.I2X(Tc, "degf") sTc = "{:10.3f} ".format(Tc) sPc = "{:10.3f} ".format(Pc) Zc = clsEOS.gPP("ZC", iC) sZc = "{:10.5f} ".format(Zc) AF = clsEOS.gPP("AF", iC) sAF = "{:10.5f} ".format(AF) MA = clsEOS.gPP("MA", iC) sOA = "{:10.7f} ".format(MA * clsEOS.OA) MB = clsEOS.gPP("MB", iC) sOB = "{:10.7f} ".format(MB * clsEOS.OB) SS = clsEOS.gPP("SS", iC) sSS = "{:10.7f} ".format(SS) PA = clsEOS.gPP("PA", iC) sPA = "{:10.3f} ".format(PA) sOut = sNm + sMw + sTc + sPc + sZc + sAF + sOA + sOB + sSS + sPA + "\n" fSim.write(sOut) fSim.write("\n") #-- BInary Interaction Parameters ----------------------------------- sLabl = "C Binary Interaction Parameters\n" fSim.write(sLabl) fSim.write("\n") for iC in range(1, nCom): sCom = clsEOS.gNM(iC) sOut = "DJK " + sCom + "\n" fSim.write(sOut) for jC in range(iC): sCom = clsEOS.gNM(jC) sNam = sCom.ljust(8, ' ') dVal = clsEOS.gIJ(iC, jC) sVal = " {:10.5f}\n".format(dVal) sOut = sNam + sVal fSim.write(sOut) fSim.write("\n") #-- End of EOS Section ---------------------------------------------- sOut = "C End of EOS Section\n" fSim.write(sOut) fSim.write("\n") fSim.write(sHead) fSim.write("ENDEOS\n") fSim.write(sHead) fSim.write("\n") #== Water Properties ================================================== if clsCMP.setBr: fSim.write("C\n") fSim.write("C Water Properties\n") fSim.write("C\n") fSim.write("\n") CW.calcPVTW(clsCMP, clsUNI, clsIO) #-- Brine Properties pRefW = clsCMP.pRefW #-- Ref Pres dSTW = clsCMP.dSTW #-- Stock Tank Density bRefW = clsCMP.bRefW #-- Ref Bw cRefW = clsCMP.cRefW #-- Ref Comp uRefW = clsCMP.uRefW #-- Ref Visc vRefW = clsCMP.vRefW #-- Viscosibility if OutU[:3] == "MET": pRefW = clsUNI.I2X(pRefW, "kpa") dSTW = clsUNI.I2X(dSTW, "kg/m3") cRefW = clsUNI.I2X(cRefW, "1/kpa") vRefW = clsUNI.I2X(vRefW, "1/kpa") vRefW = uRefW * vRefW #-- d[Visc]/dp = Visc*Viscosibility sPref = "{:10.3f} ".format(pRefW) sDsur = "{:10.3f} ".format(dSTW) sBref = "{:10.5f} ".format(bRefW) sCref = "{:10.3e} ".format(cRefW) sUref = "{:10.5f} ".format(uRefW) sVref = "{:10.3e} ".format(vRefW) #-- Write Water Properties ------------------------------------------ fSim.write( "PVTW IPVTW PBASEW DWB BWI CW VW VWP\n" ) sOut = " 1 " + sPref + sDsur + sBref + sCref + sUref + sVref + "\n" fSim.write(sOut) fSim.write("\n") #== Close the file ==================================================== clsIO.qVIP = UT.closeFile(fSim) #== No return values ================================================== return
def writeGEM(ZMFvD, clsEOS, dicSAM, clsCMP, clsIO, clsUNI): #-- Initialisation -------------------------------------------------- sCom = "**" nCom = clsEOS.nComp dVec = NP.zeros(nCom) #-- Open the GEM File, if not already open ------------------------- if not clsIO.qGEM: pathGEM = clsIO.patR + ".gem" fGEM = open(pathGEM, 'w') clsIO.setQGEM(True) clsIO.setFGEM(fGEM) else: fGEM = clsIO.fGEM #== Headers =========================================================== print("Writing Compositional Description for GEM") fSim = clsIO.fGEM sInp = clsIO.fInp.name OutU = clsCMP.OutU if OutU[:3] == "MET": sUni = "METRIC" else: sUni = "FIELD " #-- Write Header Information to Simulator File ---------------------- WO.outputHeader(fSim, sCom, clsIO) WO.outputEOS(fSim, sCom, clsIO, clsEOS) #-- Header ---------------------------------------------------------- # 123456789012345678901234567890123456789012345678901234567890 sHead = "**==========================================================\n" fSim.write(sHead) sLabl = "** CMG-GEM EOS Model generated by PVTfree Program\n" fSim.write(sLabl) sLabl = "** From dataset " + sInp + "\n" fSim.write(sLabl) sLabl = "** User specified " + sUni + " Units\n" fSim.write(sLabl) fSim.write(sHead) fSim.write("\n") #-- Equation of State ----------------------------------------------- sLabl = "** Equation of State: Peng-Robinson (PR) or Soave-Redlich-Kwong (SRK)\n" fSim.write(sLabl) fSim.write("\n") sEoS = clsEOS.EOS sOut = "*MODEL *" + sEoS + "\n" fSim.write(sOut) fSim.write("\n") #-- Number of Components -------------------------------------------- sLabl = "** Number of Components; All assumed to be USER components\n" fSim.write(sLabl) fSim.write("\n") sOut = "*NC " + str(nCom) + " " + str(nCom) + "\n" fSim.write(sOut) fSim.write("\n") #-- Component Names ------------------------------------------------- sLabl = "** Component Names\n" fSim.write(sLabl) fSim.write("\n") sOut = "*COMPNAME " for iC in range(nCom): sNam = clsEOS.gNM(iC) sOut = sOut + "'" + sNam + "' " sOut = sOut + "\n" fSim.write(sOut) fSim.write("\n") fSim.write("*EOSSET 1\n") fSim.write("\n") #-- Mole Weights ---------------------------------------------------- sCom = "** Molecular Weights : [gm/gmol]\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MW", iC) writeVectorD(fSim, sCom, "*MW", 7, "{:8.3f}", dVec) #-- Specific Gravity ------------------------------------------------ sCom = "** Specific Gravity\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("SG", iC) writeVectorD(fSim, sCom, "*SG", 7, "{:8.6f}", dVec) #-- Boiling Point Temperature --------------------------------------- for iC in range(nCom): dVec[iC] = clsEOS.gPP("TB", iC) if OutU[:3] == "MET": sUni = ": [degC]" for iC in range(nCom): dVec[iC] = clsUNI.I2X(dVec[iC], "degc") else: sUni = ": [degF]" for iC in range(nCom): dVec[iC] = clsUNI.I2X(dVec[iC], "degf") sCom = "** Boiling Point Temperature " + sUni + "\n" writeVectorD(fSim, sCom, "*TB", 7, "{:8.3f}", dVec) #-- Critical Temperatures ------------------------------------------- for iC in range(nCom): dVec[iC] = clsUNI.I2X(clsEOS.gPP("TC", iC), "kelv") sCom = "** Critical Temperatures : [Kelvin]" + "\n" writeVectorD(fSim, sCom, "*TCRIT", 7, "{:8.3f}", dVec) #-- Critical Pressures ---------------------------------------------- for iC in range(nCom): dVec[iC] = clsUNI.I2X(clsEOS.gPP("PC", iC), "atm") sCom = "** Critical Pressures : [atm]\n" writeVectorD(fSim, sCom, "*PCRIT", 7, "{:8.4f}", dVec) #-- Critical Volumes ------------------------------------------------ for iC in range(nCom): dVec[iC] = clsUNI.I2X(clsEOS.gPP("VC", iC), "m3/kgmol") sCom = "** Critical Volumes : [m3/kgmol]\n" writeVectorD(fSim, sCom, "*VCRIT", 7, "{:8.3f}", dVec) #-- Critical Z-Factors ---------------------------------------------- sCom = "** Critical Z-Factors " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("ZC", iC) writeVectorD(fSim, sCom, "*ZCRIT", 7, "{:8.6f}", dVec) #-- Acentric Factors ------------------------------------------------ sCom = "** Acentric Factors " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("AF", iC) writeVectorD(fSim, sCom, "*AC", 7, "{:8.6f}", dVec) #-- Parachors ------------------------------------------------------- sCom = "** Parachors " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("PA", iC) writeVectorD(fSim, sCom, "*PCHOR", 7, "{:8.3f}", dVec) #-- Omega-A's ------------------------------------------------------- sCom = "** Omega-A Values " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MA", iC) * clsEOS.OA writeVectorD(fSim, sCom, "*OMEGA", 6, "{:11.9f}", dVec) #-- Omega-B's ------------------------------------------------------- sCom = "** Omega-B Values " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("MB", iC) * clsEOS.OB writeVectorD(fSim, sCom, "*OMEGB", 6, "{:11.9f}", dVec) #-- Volume Shifts --------------------------------------------------- sCom = "** Volume Shifts " + "\n" for iC in range(nCom): dVec[iC] = clsEOS.gPP("SS", iC) writeVectorD(fSim, sCom, "*VSHIFT", 7, "{:9.6f}", dVec) #-- Binary Interaction Parameters ----------------------------------- sCom = "** Binary Interaction Parameters\n" fSim.write(sCom) fSim.write("\n") sOut = "*BIN " for iC in range(1, nCom): for jC in range(iC): dVal = clsEOS.gIJ(iC, jC) sVal = "{:9.6f} ".format(dVal) sOut = sOut + sVal sOut = sOut + "\n" fSim.write(sOut) sOut = " " fSim.write("\n") #-- Reservoir Temperature ------------------------------------------- tRes = clsCMP.Tres if OutU[:3] == "MET": sUni = ": [degC]" tRes = clsUNI.I2X(tRes, "degC") else: sUni = ": [degF]" tRes = clsUNI.I2X(tRes, "degF") sTr = "{:10.3f}\n".format(tRes) sLabl = "** Reservoir Temperature " + sUni + "\n" fSim.write(sLabl) fSim.write("\n") sOut = "*TRES " + sTr fSim.write(sOut) fSim.write("\n") #== Brine Density at Standard (Stock Tank) Conditions ================= if clsCMP.setBr: CW.calcPVTW(clsCMP, clsUNI, clsIO) #-- Brine Properties dSTW = clsCMP.dSTW #-- Aqueous Phase Properties ---------------------------------------- sLabl = "** Aqueous Phase Properties\n" fSim.write(sLabl) fSim.write("\n") pRefW = clsCMP.pRefW #-- Ref Pres bRefW = clsCMP.bRefW #-- Bw = Vres/Vsur = RhoSur/RhoRes cRefW = clsCMP.cRefW #-- Compressibility bSalt = clsCMP.bSalt dRes = dSTW / bRefW #-- Reservoir Density if OutU[:3] == "MET": dSTW = clsUNI.I2X(dSTW, "kg/m3") dRes = clsUNI.I2X(dRes, "kg/m3") pRefW = clsUNI.I2X(pRefW, "kpa") cRefW = clsUNI.I2X(cRefW, "1/kpa") sDsur = "{:10.3f}\n".format(dSTW) sDres = "{:10.3f}\n".format(dRes) sPref = "{:10.3f}\n".format(pRefW) sCref = "{:10.3e}\n".format(cRefW) sSalt = "{:10.5f}\n".format(bSalt) fSim.write("*DENW " + sDsur) fSim.write("*DENWS " + sDres) fSim.write("*CW " + sCref) fSim.write("*REFPW " + sPref) fSim.write("\n") fSim.write("*AQUEOUS-VISCOSITY *KESTIN\n") fSim.write("*SALINITY *WTFRAC " + sSalt) fSim.write("\n") #== Close the file ==================================================== clsIO.qGEM = UT.closeFile(fSim) #== No return value =================================================== return
def readDef(clsIO, dicSAM, clsUNI): iERR = 0 iCnt = 0 fInP = clsIO.fInP fOut = clsIO.fOut macEPS = calcMacEPS() #-- Compute Machine Epsilon #--------------------------------------------------------------------- # Parse Input File Line by Line #--------------------------------------------------------------------- for curL in fInP: iCnt += 1 #-- Current Line in curL; split into List tokS tokS = curL.split() nTok = len(tokS) #-- Blank or Comment? ----------------------------------------------- if nTok == 0: #-- Blank line pass else: if tokS[0][:2] == "--": pass elif tokS[0][:4].upper() == "ENDD": break elif tokS[0][:3].upper() == "DEB": iERR = RE.readDebug(clsIO) elif tokS[0].upper() == "EOS": #-- Equation of State ----------------------------------------------- EOS = tokS[1].upper() clsEOS = classEoS(EOS) print("Equation of State Specified as ", EOS) sCom = "--" WO.outputHeader(fOut, sCom, clsIO) WO.outputEOS(fOut, sCom, clsIO, clsEOS) elif tokS[0].upper() == "NCOMP": nComp = int(tokS[1]) clsEOS.NC = nComp clsEOS.setNComp(nComp) #-- Dimension the Arrays elif tokS[0].upper() == "NSAMP": nSamp = int(tokS[1]) clsEOS.NS = nSamp elif tokS[0].upper() == "PROPS": curL = next(fInP) #-- Property Names curL = next(fInP) #-- Property Units for iC in range(nComp): curL = next(fInP) tokS = curL.split() nTok = len(tokS) if nTok != 17: print("DEFINE PROPS: Expecting 17 Columns, Only ", nTok, " Read") iERR = -1 break sN = tokS[0] Mw = float(tokS[1]) Tc = float(tokS[2]) Pc = float(tokS[3]) Vc = float(tokS[4]) Zc = float(tokS[5]) AF = float(tokS[6]) Tb = float(tokS[7]) SG = float(tokS[8]) PA = float(tokS[9]) SS = float(tokS[10]) MA = float(tokS[11]) MB = float(tokS[12]) CA = float(tokS[13]) CB = float(tokS[14]) CC = float(tokS[15]) CD = float(tokS[16]) clsEOS.sPP("CN", iC, sN) clsEOS.sPP("MW", iC, Mw) clsEOS.sPP("TC", iC, Tc) clsEOS.sPP("PC", iC, Pc) clsEOS.sPP("VC", iC, Vc) clsEOS.sPP("ZC", iC, Zc) clsEOS.sPP("AF", iC, AF) clsEOS.sPP("TB", iC, Tb) clsEOS.sPP("SG", iC, SG) clsEOS.sPP("PA", iC, PA) clsEOS.sPP("SS", iC, SS) clsEOS.sPP("MA", iC, MA) clsEOS.sPP("MB", iC, MB) clsEOS.sPP("CA", iC, CA) clsEOS.sPP("CB", iC, CB) clsEOS.sPP("CC", iC, CC) clsEOS.sPP("CD", iC, CD) elif tokS[0].upper() == "BIP": curL = next(fInP) #-- Component Names for iC in range(nComp): curL = next(fInP) tokS = curL.split() nTok = len(tokS) if nTok != nComp + 1: print("DEFINE BIP: Expecting ", nComp + 1, " Columns, Only ", nTok, " Read") iERR = -1 break iTok = 1 while iTok < nTok: KIJ = float(tokS[iTok]) clsEOS.sIJ(iC, iTok - 1, KIJ) iTok += 1 elif tokS[0].upper() == "SAMPLES": curL = next(fInP) #-- Sample Names tokS = curL.split() nTok = len(tokS) for iSamp in range(nSamp): sName = tokS[iSamp + 1] csSAM = RS.classSample(sName) dicSAM[iSamp] = csSAM dicSAM[iSamp].setNComp(nComp) for iC in range(nComp): curL = next(fInP) tokS = curL.split() if nTok != nSamp + 1: print("DEFINE SAMPLES: Expecting ", nSamp + 1, " Columns, Only ", nTok, " Read") iERR = -1 break for iSamp in range(nSamp): ZI = float(tokS[iSamp + 1]) if ZI < macEPS: ZI = 1.0E-20 #-- Protect against Z = 0 dicSAM[iSamp].sZI(iC, ZI) else: pass #======================================================================== # Has any slop crept into the sample definitions? #======================================================================== for iSamp in range(nSamp): sumT = 0.0 for iC in range(nComp): sumT = sumT + dicSAM[iSamp].gZI(iC) sumT = 1.0 / sumT for iC in range(nComp): zI = sumT * dicSAM[iSamp].gZI(iC) dicSAM[iSamp].sZI(iC, zI) #== Back-calculate the C7+ Properties ================================= backCalcPlusFracProps(clsEOS, dicSAM) #======================================================================== # Do we need to sort the components? Most to Least Volatility #======================================================================== clsEOS, dicSAM = CR.sortComponents(clsEOS, dicSAM) #======================================================================== # Output the data #======================================================================== sTit = "Initialisation from a saved DEFINE" WO.outputProps(clsIO, clsEOS, dicSAM, sTit) #======================================================================== # Write Fluid Description to the SAV file #======================================================================== WO.outputSave(sTit, clsEOS, dicSAM, clsIO) #====================================================================== # Generate (Approximate) Phase Plots #====================================================================== CP.allSamplesPhasePlot(clsEOS, dicSAM, clsIO) #== Return values ===================================================== return iERR, clsEOS, dicSAM
def readInit(clsIO, dicSAM, clsUNI): iERR = 0 iCnt = 0 nSplt = 0 fInP = clsIO.fInP fOut = clsIO.fOut #---------------------------------------------------------------------- # Parse Input File Line by Line #---------------------------------------------------------------------- for curL in fInP: iCnt += 1 #-- Current Line in curL; split into List tokS ---------------------- tokS = curL.split() nTok = len(tokS) #== Process Options =================================================== if nTok == 0: pass #-- Blank Line elif tokS[0][:2] == "-- ": pass #-- Comment elif tokS[0][:4].upper() == "ENDI": break #-- ENDINIT k/w => Exit #-- EOS K/W Read => Create the clsEOS to hold data ------------------ elif tokS[0].upper() == "EOS": EOS = tokS[1].upper() clsEOS = classEoS(EOS) print("Equation of State Specified as ", EOS) sCom = "--" WO.outputHeader(fOut, sCom, clsIO) WO.outputEOS(fOut, sCom, clsIO, clsEOS) #-- SPLIT k/w ------------------------------------------------------- elif tokS[0][:3].upper() == "SPL": nSplt = int(tokS[1]) #print("SPLIT: nSplt ",nSplt) if nSplt < 2 or nSplt > 5: print("SPLIT: nSplt ", nSplt, " Out of Range, 2 =< Nsplt =< 5 - Error") iERR = -1 break else: clsEOS.setNPseu(nSplt) print("Plus Fraction will be split into ", nSplt, " Pseudo-Components") #-- SAMPLES k/w ----------------------------------------------------- elif tokS[0][:4].upper() == "SAMP": if nSplt == 0: nSplt = 1 clsEOS.setNPseu(nSplt) iERR, dicSAM = RS.readSamp(clsIO, tokS, clsEOS, dicSAM, clsUNI) if iERR < 0: break #-- DEBUG k/w ------------------------------------------------------- elif tokS[0][:3].upper() == "DEB": iERR = RE.readDebug(clsIO) if iERR < 0: break #== Return values ===================================================== return iERR, clsEOS, dicSAM
def runRegression(mIter, clsIO, clsEOS0, dicSAM0, dicEXP0, dicREG, qExp, clsUNI): #== Set Output File Name [rootName.reg] =============================== if not clsIO.qReg: pathReg = clsIO.patR + ".reg" fReg = open(pathReg, 'w') clsIO.setQREG(True) clsIO.setFREG(fReg) else: fReg = clsIO.fReg sCom = "--" WO.outputHeader(fReg, sCom, clsIO) WO.outputEOS(fReg, sCom, clsIO, clsEOS0) #== Number of Variables =============================================== nVar = len(dicREG) #-- Initial (normalised) variables ---------------------------------- xVec = NP.ones(nVar) #-------------------------------------------------------------------- # Run the experiments with the initial EoS and set of sample info #-------------------------------------------------------------------- runRegExps(clsIO, clsEOS0, dicSAM0, dicEXP0, qExp) #== Initial residuals vector ========================================== qWrt = True fReg.write("\n") fReg.write( "============================================================\n") fReg.write(" Regression Output: Initial Residuals\n") fReg.write( "============================================================\n") fReg.write("\n") ssq0, regI = calcResSSQ(qWrt, dicEXP0, qExp, clsIO) nReg = len(regI) #-- Number of items in Residual Vector iTer = 0 #print("iVar,ssqI {:2d}{:10.5f}".format(iTer,ssq0)) #== Take a (deep) copy of the EoS class and Samples dictionary ======== clsEOS1 = deepcopy(clsEOS0) dicSAM1 = deepcopy(dicSAM0) dicEXP1 = deepcopy(dicEXP0) #======================================================================== # Main Loop #======================================================================== qConv = False nIter = 1 while not qConv: #====================================================================== # Build Jacobian by perturbing each variable in turn #====================================================================== jacO = calcJaco(clsIO, dicREG, clsEOS0, clsEOS1, dicSAM0, dicSAM1, dicEXP1, qExp, xVec, regI) #====================================================================== # Calculate the Gradient and Hessian #====================================================================== Grad = NP.dot(jacO, regI) Hess = NP.dot(jacO, jacO.T) #-- Note Transpose! #====================================================================== # Calculate the update vector delX #====================================================================== delX = rotDisc(nIter, Grad, Hess, dicREG, dicSAM1, clsEOS1, clsIO) #writeVector("Grad ",Grad) #writeVector("xVec[B]",xVec) #writeVector("delX ",delX) #====================================================================== # Check if Variables Bounded? #====================================================================== delX, Grad = checkBounds(nIter, clsEOS0, dicREG, dicSAM0, xVec, delX, Grad, Hess, clsIO) #====================================================================== # Line Search #====================================================================== ssq1, xVec, regI = lineSearch(clsIO, dicREG, dicSAM0, dicSAM1, clsEOS0, clsEOS1, dicEXP1, qExp, ssq0, xVec, delX, Grad) #writeVector("xVec[A]",xVec) #====================================================================== # Progress in SSQ? #====================================================================== if abs((ssq1 - ssq0) / ssq1) < 1.0E-04: print("Regression converged!") qConv = True else: ssq0 = ssq1 nIter += 1 if nIter > mIter: print("Regression - Reached Max-Iterations = ", mIter) break #== Plot Before/After Results ========================================= qReg = True GP.regPlots(clsIO, dicEXP0, dicEXP1, dicSAM1, qReg, clsUNI) #====================================================================== # (Deep) copy the working EoS/Samples back to the main EoS/Samples #====================================================================== clsEOS0 = deepcopy(clsEOS1) dicSAM0 = deepcopy(dicSAM1) dicEXP0 = deepcopy(dicEXP1) #====================================================================== # Write Final Set of Residuals #====================================================================== fReg.write("\n") fReg.write( "============================================================\n") fReg.write(" Regression Output: Final Residuals\n") fReg.write( "============================================================\n") fReg.write("\n") ssq0, regI = calcResSSQ(qWrt, dicEXP0, qExp, clsIO) #====================================================================== # Write New EoS & Experiments to Print File #====================================================================== iERR, sTyp = regVarType(dicREG) if sTyp == "REG": sExt = "Regular EOS Variables" elif sTyp == "PLS": sExt = "Plus Fraction Variables" elif sTyp == "LBC": sExt = "LBC Viscosity Variables" sTit = "Regression Using " + sExt WO.outputProps(clsIO, clsEOS0, dicSAM0, sTit) #-- Only Print the Regession "Active" Experiments [qExp] ------------ nExp = len(dicEXP0) qSav = [True for i in range(nExp)] for iExp in range(nExp): qSav[iExp] = qExp[iExp] clsEXP0 = dicEXP0[iExp] clsEXP0.IsAct = qExp[iExp] #-- Print the Experiments ------------------------------------------- WO.outputExps(clsIO, dicEXP0, dicSAM0, clsUNI) #-- Restore the IsAct Flag ------------------------------------------ for iExp in range(nExp): clsEXP0 = dicEXP0[iExp] clsEXP0.IsAct = qSav[iExp] sTit = "Regression Using " + sTyp + " Variable Types" WO.outputSave(sTit, clsEOS0, dicSAM0, clsIO) return clsEOS0, dicSAM0, dicEXP0