Пример #1
0
def lineSearchEOS(fun0, delX, Grad, pObs, xOil, yOil, vOil, vGas, clsBLK,
                  clsIO):

    nVar = len(delX)

    grd0 = NP.dot(delX, Grad)

    if grd0 > 0.0:
        print("lineSearch: grd0 > 0")
        fun1 = fun0
        res1 = [0.0 for i in range(1)]
        return fun1, res1

    lamB = 1.0  #-- Default first   step-length [Full Newton!]
    lamM = 1.0E-04  #-- Minimum allowed step-length
    lam2 = lamB
    fun2 = fun0

    #== Create Work Array to Hold Current EOS Multipliers =================

    xVec = storeEOScoefs(clsBLK)

    #----------------------------------------------------------------------
    #  Find the Lambda Parameter
    #----------------------------------------------------------------------

    qConv = False

    while not qConv:

        #-- Update variables ------------------------------------------------

        updateEOScoefs(xVec, lamB, delX, clsBLK)

        #--------------------------------------------------------------------
        #  Run the experiments with the Perturbed EoS (cF)
        #--------------------------------------------------------------------

        fun1, res1 = calcResEOSBoth(pObs, xOil, yOil, vOil, vGas, clsBLK,
                                    clsIO)

        #print("lnsrch: fun0,grd0,lamB,fun1 {:10.5f} {:10.5f} {:10.3e} {:10.5f}".format(fun0,grd0,lamB,fun1))

        #== What to do? =======================================================

        if fun1 <= fun0 + 1.0E-04 * lamB * grd0:

            #-- Sufficent improvement: update variables and exit ----------------

            for iVar in range(nVar):
                xVec[iVar] = xVec[iVar] + lamB * delX[iVar]

            restoreEOScoefs(xVec, clsBLK)
            break

        elif lamB < lamM:

            restoreEOScoefs(xVec, clsBLK)
            break

        else:

            lamT = CR.updateLambda(lamB, lam2, fun0, fun1, fun2, grd0)

        lam2 = lamB
        fun2 = fun1
        lamB = max(lamT, 0.1 * lamB)  #-- lamB > 0.1*lamT

#========================================================================
#  End of module
#========================================================================

    return fun1, res1
Пример #2
0
def lineSearchFlash(kBFGS,qAlf,pRes,tRes,Z,fun0,aOld,dAlf,Grad,clsEOS) :

    nCom = clsEOS.nComp

    aNew = NP.zeros(nCom)

#-- Woolfe Conditions -----------------------------------------------

    c1W = 1.0E-04
    c2W = 0.9

#== if grd0 > 0.0, solution will go uphil, replace by SS iteration ====

    grd0 = NP.dot(dAlf,Grad)

    if grd0 >= -1.0E-12 :
        iSS =  1
        dAlf = -Grad            #-- Vector
        aNew =  aOld + dAlf     #-- Vector
        fun1,Grad = flashFuncDervBFGS(aNew,qAlf,pRes,tRes,Z,clsEOS)
        grd1 = NP.dot(Grad,dAlf)
        #print("SS, not BFGS: kBFGS,fun1,grd0,grd1 {:3d} {:10.3e} {:10.3e} {:10.3e}".format(kBFGS,fun1,grd0,grd1))
        return iSS,fun1,aNew,Grad
    else :
        iSS = -1

    #print("LS_Flash: fun0,grd0 {:10.3e} {:10.3e}".format(fun0,grd0))

    lamB = 1.0  ; lamM = 1.0E-04
    lam2 = lamB ; fun2 = fun0

#== Find Step-Length based on reduction in gStar ======================

    while lamB > lamM :

#-- Current step-length ---------------------------------------------

        aNew = aOld + lamB*dAlf     #-- Vector

#-- New GFE, etc ----------------------------------------------------
    
        fun1,Grad = flashFuncDervBFGS(aNew,qAlf,pRes,tRes,Z,clsEOS)

        grd1 = NP.dot(Grad,dAlf)
        fTst = fun1 - fun0 - c1W*lamB*grd0

        #print("lsBFGS: kBFGS,lamB,fTst,grd1 {:3d} {:10.3e} {:10.3e} {:10.3e}".\
        #     format(kBFGS,lamB,fTst,grd1))

#== What to do?  Converged or Back-Tracking? ==========================

        if fTst <= 0.0 and grd1 < c2W*abs(grd0) : break
        else : lamT = CR.updateLambda(lamB,lam2,fun0,fun1,fun2,grd0)

        lam2 = lamB
        fun2 = fun1
        lamB = max(lamT,0.1*lamB)

#== Return information ================================================        

    return iSS,fun1,aNew,Grad