def qr_solve_lsq(M, b): Vt = mp.qr_solve(M, b) V = mp.zeros(M.cols,1) for i in range(M.cols): V[i] = Vt[0][i] return V
def __iter__(self): f = self.f x0 = self.constraint(self.x0) norm = self.norm J = self.J fx = self._matrix(f(x0)) fxnorm = norm(fx) cancel = False x0 = self._matrix(x0) while not cancel: # get direction of descent fxn = -fx Jx = J(x0) try: s = self._Axb(Jx, fxn) except: try: s = mp.qr_solve(Jx, fxn)[0] except ZeroDivisionError: cancel = True break except TypeError: cancel = True break # damping step size TODO: better strategy (hard task) l = self._mpfloat('1.0') x1 = x0 + l * s damp_iter = 0 while True: damp_iter += 1 if x1.tolist() == x0.tolist() or damp_iter > self.max_damping: if self.verbose > 1: print("Solver: Found stationary point.") cancel = True break x1 = self._matrix(self.constraint(x1)) fx = self._matrix(f(list(x1))) newnorm = norm(fx) if newnorm <= fxnorm: # new x accepted fxnorm = newnorm x0 = x1 break l /= 2.0 x1 = x0 + l * s yield (x0, fxnorm)
def solve_ss_network(self, T, P): """ calculates the steady state concentrations if all A => B + C reactions are irreversible and the flux from/to the source configuration is 1.0 """ A = np.zeros((len(self.isomers), len(self.isomers))) b = np.zeros(len(self.isomers)) bimolecular = len(self.source) > 1 isomer_spcs = [iso.species[0] for iso in self.isomers] for rxn in self.net_reactions: if rxn.reactants[0] in isomer_spcs: ind = isomer_spcs.index(rxn.reactants[0]) kf = rxn.get_rate_coefficient(T, P) A[ind, ind] -= kf else: ind = None if rxn.products[0] in isomer_spcs: ind2 = isomer_spcs.index(rxn.products[0]) kr = rxn.get_rate_coefficient( T, P) / rxn.get_equilibrium_constant(T) A[ind2, ind2] -= kr else: ind2 = None if ind is not None and ind2 is not None: A[ind, ind2] += kr A[ind2, ind] += kf if bimolecular: if rxn.reactants[0] == self.source: kf = rxn.get_rate_coefficient(T, P) b[ind2] += kf elif rxn.products[0] == self.source: kr = rxn.get_rate_coefficient( T, P) / rxn.get_equilibrium_constant(T) b[ind] += kr if not bimolecular: ind = isomer_spcs.index(self.source[0]) b[ind] = -1.0 # flux at source else: b = -b / b.sum() # 1.0 flux from source if len(b) == 1: return np.array([b[0] / A[0, 0]]) con = np.linalg.cond(A) if np.log10(con) < 15: c = np.linalg.solve(A, b) else: logging.warning( "Matrix Ill-conditioned, attempting to use Arbitrary Precision Arithmetic" ) mp.dps = 30 + int(np.log10(con)) Amp = mp.matrix(A.tolist()) bmp = mp.matrix(b.tolist()) try: c = mp.qr_solve(Amp, bmp) c = np.array(list(c[0])) if any(c <= 0.0): c, rnorm = opt.nnls(A, b) c = c.astype(np.float64) except: # fall back to raw flux analysis rather than solve steady state problem return None if np.isnan(c).any(): return None return c
def lin_solve(mat, vec): if mode == mode_python: return np.linalg.solve(mat, vec) else: return mpmath.qr_solve(mat, vec)[0]
def _action(self, act=1): if QSMODE == MODE_MPMATH: args = {} if act==0: self.typeStr = "mpmath_qr_solve_dps"+getArgDesc(mpmath.qr_solve, args)+" DPS"+str(DPS) self.matrixType = 1 self.indexType = 1 else: self.coeffVec = mpmath.qr_solve(self.sysMat, self.resVec, **args) self.printCalStr() else: if PYTYPE_COEFF_SOLVE_METHOD == "numpy_solve": args = {} if act==0: self.typeStr = "numpy_solve"+getArgDesc(np.linalg.solve, args) self.matrixType = 0 self.indexType = 0 else: self.coeffVec = np.linalg.solve(self.sysMat, self.resVec, **args) self.printCalStr() elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_lstsq": args = {} if act==0: self.typeStr = "numpy_lstsq"+getArgDesc(np.linalg.lstsq, args) self.matrixType = 0 self.indexType = 0 else: self.coeffVec = np.linalg.lstsq(self.sysMat, self.resVec, **args)[0] self.printCalStr() elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_bicg": args = {} if act==0: self.typeStr = "numpy_sparse_bicg"+getArgDesc(sp_sparse_linalg.bicg, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.bicg(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=10*len(self.resVec) elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_bicgstab": args = {} if act==0: self.typeStr = "numpy_sparse_bicgstab"+getArgDesc(sp_sparse_linalg.bicgstab, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.bicgstab(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=10*len(self.resVec) elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_lgmres": args = {} if act==0: self.typeStr = "numpy_sparse_lgmres"+getArgDesc(sp_sparse_linalg.lgmres, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.lgmres(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=1000 elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_minres": args = {} if act==0: self.typeStr = "numpy_sparse_minres"+getArgDesc(sp_sparse_linalg.minres, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.minres(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=5*self.sysMat.shape[0] elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_sparse_qmr": args = {} if act==0: self.typeStr = "numpy_sparse_qmr"+getArgDesc(sp_sparse_linalg.qmr, args) self.matrixType = 0 self.indexType = 1 else: self.coeffVec = self._sparseRet(sp_sparse_linalg.qmr(self.sysMat, self.resVec, **args))#, tol=1e-05, maxiter=10*len(self.resVec) elif PYTYPE_COEFF_SOLVE_METHOD == "numpy_qr": args_qr = {} args_s = {} if act==0: self.typeStr = "numpy_qr"+getArgDesc(np.linalg.qr, args_qr)+",numpy_solve"+getArgDesc(np.linalg.solve, args_s) self.matrixType = 0 self.indexType = 0 else: Q,R = np.linalg.qr(self.sysMat, **args_qr) y = np.dot(Q.T,self.resVec) self.coeffVec = np.linalg.solve(R,y, **args_s) self.printCalStr()
def solve_SS_network(self, T, P): """ calculates the steady state concentrations if all A => B + C reactions are irreversible and the flux from/to the source configuration is 1.0 """ A = np.zeros((len(self.isomers), len(self.isomers))) b = np.zeros(len(self.isomers)) bimolecular = len(self.source) > 1 isomerSpcs = [iso.species[0] for iso in self.isomers] for rxn in self.pathReactions: if rxn.reactants[0] in isomerSpcs: ind = isomerSpcs.index(rxn.reactants[0]) kf = rxn.getRateCoefficient(T, P) A[ind, ind] -= kf else: ind = None if rxn.products[0] in isomerSpcs: ind2 = isomerSpcs.index(rxn.products[0]) kr = rxn.getRateCoefficient(T, P) / rxn.getEquilibriumConstant(T) A[ind2, ind2] -= kr else: ind2 = None if ind and ind2: A[ind, ind2] += kr A[ind2, ind] += kf if bimolecular: if rxn.reactants[0].species == self.source: kf = rxn.getRateCoefficient(T, P) b[ind2] += kf elif rxn.products[0].species == self.source: kr = rxn.getRateCoefficient( T, P) / rxn.getEquilibriumConstant(T) b[ind] += kr if not bimolecular: ind = isomerSpcs.index(self.source[0]) b[ind] = -1.0 #flux at source else: b = -b / b.sum() #1.0 flux from source if len(b) == 1: return np.array([b[0] / A[0, 0]]) con = np.linalg.cond( A ) #this matrix can be very ill-conditioned so we enhance precision accordingly mp.dps = 30 + int(np.log10(con)) Amp = mp.matrix(A.tolist()) bmp = mp.matrix(b.tolist()) c = mp.qr_solve(Amp, bmp) c = np.array(list(c[0])) if any(c <= 0.0): c, rnorm = opt.nnls(A, b) c = c.astype(np.float64) return c
def Bound(U,B,sol,eig,dic,order,condB = "harm pot",condU = 'Inviscid'): lso = len(sol) for s in range(len(sol)): globals() ['C'+str(s)] = Symbol('C'+str(s)) ################################# ### Inviscid solution : ### ### lso=3 --> 1 boundary ### ### lso=6 --> 2 boundaries ### ################################# nn = n.xreplace(dic).doit() U = (U.xreplace(makedic(veigen(eig,sol),order))).xreplace({U0:1}) B = (B.xreplace(makedic(veigen(eig,sol),order))) if (condB == "harm pot"): bchx,bchy,bchz = symbols("bchx,bchy,bchz") bcc =surfcond((bchx*C.i +bchy*C.j + bchz*C.k)*ansatz - gradient(psi),dic).doit() sob = list(linsolve([bcc&C.i,bcc&C.j,bcc&C.k],(bchx,bchy,bchz)))[0] bbc = sob[0]*C.i + sob[1]*C.j + sob[2]*C.k bb = B.xreplace(makedic(veigen(eig,sol),order)) - (bbc*ansatz) Eq_b= surfcond(bb,dic) Eq_bx = Eq_b&C.i; Eq_by = Eq_b&C.j; Eq_bz = Eq_b&C.k if params.Bound_nb ==2: bchx2,bchy2,bchz2 = symbols("bchx2,bchy2,bchz2") bcc2 =surfcond_2((bchx2*C.i +bchy2*C.j +bchz2*C.k)*ansatz - gradient(psi_2b),dic) sob2 = list(linsolve([bcc2&C.i,bcc2&C.j,bcc2&C.k],(bchx2,bchy2,bchz2)))[0] bbc2 = sob2[0]*C.i + sob2[1]*C.j + sob2[2]*C.k bb2 = B.xreplace(makedic(veigen(eig,sol),order)) - (bbc2*ansatz) Eq_b2= surfcond_2(bb2,dic) Eq_b2x = Eq_b2&C.i; Eq_b2y = Eq_b2&C.j; Eq_b2z = Eq_b2&C.k if (condB == "thick"): bchx,bchy,bchz,eta = symbols("bchx,bchy,bchz,eta") kz_t = -sqrt(-kxl**2-kyl**2-I*omega/qRmm) # kz_t = I*1e12 B_mant = (bchx*C.i +bchy*C.j + bchz*C.k)*ansatz.xreplace({kz:kz_t}) eq_ind = (surfcond((diff(B_mant,t)-qRmm*laplacian(B_mant)-diff(B,t) +qRm*laplacian(B) - curl(U.cross(B))).xreplace({kz:kz_t}),dic).xreplace(dic)) eq_E = (qRm*curl(B)-U.cross(B)-qRmm*curl(B_mant)) eq_Et = surfcond(((nn).cross(eq_E)).xreplace({kz:kz_t}),dic) eq_B = surfcond(((B_mant.dot(nn)-B.dot(nn))).xreplace({kz:kz_t}),dic) un = (U.dot(nn)) Eq_n1= surfcond((un).xreplace({kz:kz_t}),dic).xreplace(dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,eq_ind&C.i,eq_ind&C.j,eq_ind&C.k,eq_Et.dot(tx),eq_Et.dot(ty)]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,bchx,bchy,bchz)) U = (U.xreplace(makedic(veigen(eig,sol),order))).xreplace({U0:1}) un = U.dot(nn) Eq_n1= surfcond(un,dic).xreplace(dic) if condU == "Inviscid": if params.Bound_nb ==2: nn2 = n2.xreplace(dic).doit() un2 = U.dot(nn2) Eq_n2= surfcond_2(un2,dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_n2,Eq_bx,Eq_by,Eq_bz,Eq_b2x,Eq_b2y,Eq_b2z]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,C5,Symbol("psi"+str(order)),Symbol("psi"+str(order)+"_2b"))) elif params.Bound_nb ==1: TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_bx,Eq_by,Eq_bz]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,Symbol("psi"+str(order)))) elif condU == 'noslip': if params.Bound_nb ==1: U = (U.xreplace(makedic(veigen(eig,sol),order))) ut1 = U.dot(tx) ut2 = U.dot(ty) Eq_BU1= surfcond(ut1,dic) Eq_BU2 = surfcond(ut2,dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_BU1,Eq_BU2,Eq_bx,Eq_by,Eq_bz]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,Symbol("psi"+str(order)))) elif params.Bound_nb ==2: un1 = U.dot(tx2) un2 = U.dot(ty2) Eq2_BU1= surfcond_2(un1,dic) Eq2_BU2 = surfcond_2(un2,dic) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_n2,Eq_BU1,Eq_BU2,Eq2_BU1,Eq2_BU2,Eq_bx,Eq_by,Eq_bz,Eq_b2x,Eq_b2y,Eq_b2z]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,Symbol("psi"+str(order)),Symbol("psi"+str(order)+"_2b"))) elif condU == 'stressfree': if params.Bound_nb ==1: eu = strain(U)*nn eu1 = eu*tx eu2 = eu*ty Eq_BU1 = surfcond(eu1,dic,realtopo =False) Eq_BU2 = surfcond(eu2,dic,realtopo =False) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_BU1,Eq_BU2,Eq_bx,Eq_by,Eq_bz]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,Symbol("psi"+str(order)))) elif params.Bound_nb ==2: eu = strain(U)*nn2 eu1 = eu*tx2 eu2 = eu*ty2 Eq2_BU1 = surfcond2(eu1,dic,realtopo =False) Eq2_BU2 = surfcond2(eu2,dic,realtopo =False) TEq = [(taylor(eq,order,dic)).xreplace({x:0,y:0,t:0}) for eq in [Eq_n1,Eq_n2,Eq_BU1,Eq_BU2,Eq2_BU1,Eq2_BU2,Eq_bx,Eq_by,Eq_bz,Eq_b2x,Eq_b2y,Eq_b2z]] Mat, res = linear_eq_to_matrix(TEq,(C0,C1,C2,C3,C4,C5,C6,C7,C8,C9,Symbol("psi"+str(order)),Symbol("psi"+str(order)+"_2b"))) Mat = Mat.evalf(mp.mp.dps) res = res.evalf(mp.mp.dps) Mat = mpmathM(Mat) res = mpmathM(res) try: abc = mp.qr_solve(Mat,res)[0] except: abc = mp.lu_solve(Mat,res) mantle =0 #In progress ... solans = zeros(7,1) for l in range(lso): solans = solans + abc[l]*Matrix(eig[l])*(ansatz).xreplace({kz:sol[l]}) solans = solans.xreplace(dic) return(abc,solans,mantle)
coe = lambda x: x.coeff(ex) rmep = (rmec).applyfunc(coe) nwkz = simplify((log(ex).expand(force=True)/I).xreplace({x:0,y:0,t:0,z:1})) Mp = simplify(M.xreplace({kz:nwkz})) rmep = subs_k(rmep,i,Bound_nb) Mp = subs_k(Mp,i,Bound_nb) with mp.workdps(int(mp.mp.dps*2)): Mp = mpmathM(Mp) rmep = mpmathM(rmep) try: soluchap = mp.qr_solve(Mp,rmep)[0] except: soluchap = mp.lu_solve(Mp,rmep) print('QR decomposition failed LU used') sop = Matrix(soluchap)*ex so_part = so_part+sop with mp.workdps(int(mp.mp.dps*2)): so_part = so_part.xreplace({**dico0,**dico1}) Usopart = so_part[0]*C.i + so_part[1]*C.j + so_part[2]*C.k Bsopart = so_part[4]*C.i + so_part[5]*C.j + so_part[6]*C.k psopart = so_part[3] Ubnd = U + e**i*Usopart