示例#1
0
def boundTsat(pRes,Z,clsEOS,clsIO) :

    if clsIO.Deb["TSAT"] > 0 :
        qDeb = True
        fDeb = clsIO.fDeb
    else :
        qDeb = False

#== Limiting Values ===================================================

    qSat = True

    tMax = 2500.0
    tMin =  200.0

    iMax,trMx,Kmax = ST.twoSidedStabCheck(qSat,pRes,tMax,Z,clsEOS,clsIO)
    iMin,trMn,Kmin = ST.twoSidedStabCheck(qSat,pRes,tMin,Z,clsEOS,clsIO)

    n2SC = 2

    if qDeb :
        sOut = "boundTsat: iMax,iMin,trMn {:2d} {:2d} {:10.3e}\n".format(iMax,iMin,trMn)
        fDeb.write(sOut)

#-- Test limiting values --------------------------------------------

    if iMax > 0 :
        print("Fluid at (Pres,Tres) = ({:10.3f},{:8.3f}) is 2-Phase: No-Psat".format(pRes,tMax))
        iTyp = -1
        logK = NP.zeros(clsEOS.NC)
        return tMin,tMax,logK
      
#----------------------------------------------------------------------
#  Interval Halving
#----------------------------------------------------------------------

    tInt = 0.5*(tMin + tMax)

    while abs(tMax - tMin) > 100.0 :

        iTyp,triV,K = ST.twoSidedStabCheck(qSat,pRes,tInt,Z,clsEOS,clsIO)

        n2SC += 1

        if qDeb :
            sOut = "iTyp,pRes,tMin,tInt,triV,tMax {:2d} {:10.3f} {:10.3f} {:10.3f} {:10.3e}{:10.3f}\n".format(iTyp,pRes,tMin,tInt,triV,tMax)
            fDeb.write(sOut)

        if iTyp > 0 :
            tMin = tInt
            logK = NP.log(K)
        else        :
            tMax = tInt

        tInt = 0.5*(tMin + tMax)

#== Return values =====================================================

    return tMin,tMax,logK
示例#2
0
def boundPsat(tRes,Z,clsEOS,clsIO) :

    if clsIO.Deb["PSAT"] > 0 :
        qDeb = True
        fDeb = clsIO.fDeb
    else :
        qDeb = False

#== Limiting Values ===================================================

    qSat = True

    pMax = 15010.0
    pMin =    10.0

    iMax,trMx,Kmax = ST.twoSidedStabCheck(qSat,pMax,tRes,Z,clsEOS,clsIO)
    iMin,trMn,Kmin = ST.twoSidedStabCheck(qSat,pMin,tRes,Z,clsEOS,clsIO)

    n2SC = 2

    #print("boundPsat: iMax,iMin,trMn {:2d} {:2d} {:10.3e}".format(iMax,iMin,trMn))

#-- Test limiting values --------------------------------------------

    if iMax > 0 :
        print("Fluid at (Pres,Tres) = ({:10.3f},{:8.3f}) is 2-Phase: No-Psat".format(pMax,tRes))
        iTyp = -1
        logK = NP.zeros(clsEOS.NC)
        return iTyp,pMin,pMax,logK
      
#----------------------------------------------------------------------
#  Interval Halving
#----------------------------------------------------------------------

    pInt = 0.5*(pMin + pMax)

    while abs(pMax - pMin) > 100.0 :

        iTyp,triV,K = ST.twoSidedStabCheck(qSat,pInt,tRes,Z,clsEOS,clsIO)

        n2SC += 1

        #print("iTyp,pMin,pInt,triV,pMax {:2d} {:10.3f} {:10.3f} {:10.3e}{:10.3f}".format(iTyp,pMin,pInt,triV,pMax))

        if iTyp > 0 :
            pMin = pInt
            logK = NP.log(K)
        else        :
            pMax = pInt

        pInt = 0.5*(pMin + pMax)

#== Return values =====================================================

    return iTyp,pMin,pMax,logK
示例#3
0
def rescuePsat(qBub,p2PH,p1PH,tRes,Z,clsEOS,clsIO) :

    if clsIO.Deb["PSAT"] > 0 :
        qDeb = True
        fDeb = clsIO.fDeb
    else :
        qDeb = False

#== Using interval halfing ============================================

    pSat = 0.5*(p2PH+p1PH)
    qSat = True

    while abs(p1PH-p2PH) > 0.001 :

        iTyp,triV,K = ST.twoSidedStabCheck(qSat,pSat,tRes,Z,clsEOS,clsIO)

        if iTyp == 0 :
            p1PH = pSat
        else         :
            p2PH = pSat
            logK = NP.log(K)

        pSat = 0.5*(p2PH+p1PH)

#== Return arguments ==================================================    
        
    return p2PH,logK
示例#4
0
def searchOnePhase(qBub,pInc,pRes,tRes,Z,clsEOS,clsIO) :

    q1PH = False
    qSat = True

#----------------------------------------------------------------------
#  Increment upward until we find 1-Phase state
#----------------------------------------------------------------------

    while not q1PH :

        iTyp,triV,K = ST.twoSidedStabCheck(qSat,pRes,tRes,Z,clsEOS,clsIO)

        if iTyp == 0 : break
        else         : pRes = pRes + pInc

#== Return value ======================================================

    return pRes
示例#5
0
def searchTwoPhase(qBub,pInc,pRes,tRes,Z,clsEOS,clsIO) :

    iTyp = 0
    qSat = True

#----------------------------------------------------------------------
#  Increment downward (in pressure) until we find 2-Phase state
#----------------------------------------------------------------------

    while iTyp == 0 :

        iTyp,triV,K = ST.twoSidedStabCheck(qSat,pRes,tRes,Z,clsEOS,clsIO)

        if iTyp > 0 : break
        else        : pRes = pRes - pInc

#== Return Information ================================================

    logK = NP.log(K)

    return iTyp,pRes,logK
示例#6
0
def sweepPsatNoData(qBub,tRes,Z,clsEOS,clsIO) :

    iTyp,p2PH,p1PH,logK = boundPsat(tRes,Z,clsEOS,clsIO)

    if clsIO.Deb["PSAT"] > 0 :
        qDeb = True
        fDeb = clsIO.fDeb
    else :
        qDeb = False

    logK = NP.zeros(clsEOS.NC)

    if qBub : iFed =  1     #-- Feed is Likely a Liquid
    else    : iFed = -1     #             Else a Vapour
        
#== Pressure Limits and # Increments ==================================

    pMIN =    10.0
    pMAX = 15010.0
    nINC = 15

#== set pSat = pMIN and calculate Increment ===========================

    pSat =  pMIN
    pINC = (pMAX - pSat)/float(nINC)
    p1PH = -1.0

#======================================================================
#  Increment in pressure until we find 1-Phase State
#======================================================================

    qSat = True

    for iStep in range(nINC+1) :

#== Can we split of another composition at this pressure? =============
        
        iThs,tThs,Kths = ST.twoSidedStabCheck(qSat,pSat,tRes,Z,clsEOS,clsIO)

        if iThs > 0 : i2PH = 2
        else        : i2PH = 1

        if qDeb :
            sOut = "pSat,tRes,i2PH {:10.3f} {:8.3f} {:1d}\n".format(pSat,tRes,i2PH)
            fDeb.write(sOut)
   
        if iThs > 0 :
            iTyp = iThs
            p2PH = pSat
            logK = NP.log(Kths)
        else        :
            p1PH = pSat
            break
            
#== Increment pSat estimator and repeat ===============================
                
        pSat = pSat + pINC

#== Return Information ================================================    

    return iTyp,p2PH,p1PH,logK
示例#7
0
def calcFlash(pRes, tRes, Z, vEst, clsEOS, clsIO):

    if clsIO.Deb['FLASH'] > 0:
        qDeb = True
        fDeb = clsIO.fDeb
    else:
        qDeb = False

    nCom = clsEOS.NC
    #mFLS = 101
    mFLS = 13  #-- SS/GDEM for max-13 steps, then BFGS
    qSat = False

    iLiq = 1
    iVap = -1

    #-- Work arrays to hold residuals/GDEM ------------------------------

    res0 = NP.zeros(nCom)
    res1 = NP.zeros(nCom)
    res2 = NP.zeros(nCom)

    #-- Check if we have an unstable solution at (P,T): get K-Values ----

    iTyp, triV, K = ST.twoSidedStabCheck(qSat, pRes, tRes, Z, clsEOS, clsIO)

    if qDeb:
        sOut = "calcFlash: tRes,pRes,iTyp {:10.3f} {:10.3f} {:2d}\n".format(
            tRes, pRes, iTyp)
        fDeb.write(sOut)
        WO.writeArrayDebug(fDeb, K, "Post-2SidedStab: K")

    if iTyp == 0:
        #print("Fluid at (P,T) = ({:8.1f},{:8.2f}) is Single-Phase".format(pRes,tRes))
        V = -1.0
        K = NP.ones(nCom)
        X = Z
        Y = Z
        return V, K, X, Y

#-- Will work with log(K) -------------------------------------------

    logK = NP.log(K)

    #======================================================================
    #  Main Iterative Loop
    #======================================================================

    iFLS = 0
    iCut = 0
    icSS = 0

    qPro = False
    qCon = False
    qTrv = False

    V = vEst

    while iFLS < mFLS:

        iFLS += 1
        icSS += 1

        #== Call the RR-Solver ================================================

        V, X, Y = solveRR(Z, K, V)

        #== Calculate the 2-Phase Gibbs Free Energy (GFE) and dG/d(Liq Moles) =

        gfe2, dGdL = calcGFE2(pRes, tRes, V, X, Y, clsEOS)

        #== If last step was GDEM, ensure GFE has been reduced and V bounded ==

        qUPD = True

        if qPro:  #-- Last step was promoted, check required!

            if V >= 0.0 and V <= 1.0:  #-- 0 < V < 1: Flash Physical
                if gfe2 > lstG: qCut = True  #-- but GFE has increased
                else: qCut = False  #-- OK
            else: qCut = True  #-- Negative Flash Teritory

            qPro = False

            #----------------------------------------------------------------------
            #  Cut Step [-ve Flash or GFE increased) or Just Take SS
            #  In Newton (or Newton-Like) Scheme, Would Do Line Seach Here
            #  but would need dG/dlnKi and we only have dG/dnLi
            #  As SS+GDEM, Just Half the Proposed Step, But Only 3 Times (1/8th step)
            #  Why 4?  Seems to Work!!
            #----------------------------------------------------------------------

            if qCut:
                iCut += 1
                if iCut < 4:
                    #print("Promotion Step Halved: iCut ",iCut)
                    iFLS -= 1
                    icSS -= 1
                    dlnK = 0.5 * dlnK
                    logK = logK - dlnK
                    K = NP.exp(logK)
                else:
                    logK = logK - dlnK  #-- Remove the last of the Update
                    logK = logK + res0  #-- And make conventional SS
                    K = NP.exp(logK)

                qUPD = False

#== Updates, Tolerance, Triviality Test, if allowed ===================

        if qUPD:

            res2 = res1  #-- Store previous two steps for GDEM
            res1 = res0
            res0 = dGdL  #-- dG/dnLi = dlnKi

            tolR = NP.dot(res0, res0)  #-- W&B Eqn.(4.30)
            triV = NP.dot(logK, logK)  #-- W&B Eqn.(4.51)

            if tolR < 1.0E-11:  #-- 1E-13 hard to achieve!
                qCon = True
                break

            if triV < 1.0E-04:
                qTrv = True
                break

#-- GDEM or Regular-SS step? ----------------------------------------

            lstG = gfe2  #-- Store 'last' GFE in case GDEM makes increase

            if icSS % CO.mGDEM2 > 0:
                qPro = False
                logK = logK + res0  #-- W&B Eqn.(4.48)
                K = NP.exp(logK)
            else:
                qPro, logK, K, dlnK = GDEM2(tolR, triV, res0, res1, res2, logK,
                                            clsIO)
                icSS = 0
                iCut = 0

#== End of Main Loop ==================================================

        if qDeb:
            sOut = "calcFlash: I,gfe2,tolR,triV,V {:2d},{:10.3e},{:10.3e},{:10.3e},{:10.3e}\n".format(
                iFLS, gfe2, tolR, triV, V)
            fDeb.write(sOut)

#== K-Values, Vapour Fraction and Liquid/Vapour Mole Fractions ========

    K = NP.exp(logK)  #-- K-Values

    V, X, Y = solveRR(Z, K, V)  #-- Solve RR for V,X & Y

    #======================================================================
    #  Not Converged and not trivial, try to finish off with BFGS
    #======================================================================

    if not qCon and not qTrv:
        V, K, X, Y = calcFlashBFGS(pRes, tRes, Z, V, X, Y, clsEOS)

#======================================================================
#  End of Routine: Return Values
#======================================================================

    return V, K, X, Y