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
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