def norm(x): # ----------------------------------------------------------------------------- """ Args: x: Vector. Returns: Norm of the vector. """ return sqrt(vec_vec(x, x)) # end of function
def cgs(a, phi, b, tol, verbose=False, max_iter=-1): # ----------------------------------------------------------------------------- """ Args: a: ...... Object of the type "Matrix", holding the system matrix. phi: .... Object of the type "Unknown" to be solved. b: ...... Three-dimensional array holding the source term. tol: .... Absolute solver tolerance verbose: Logical variable setting if solver will be verbose (print info on Python console) or not. max_iter: Maxiumum number of iterations. Returns: x: Three-dimensional array with solution. """ if verbose is True: write.at(__name__) # Helping variable x = phi.val # Intitilize arrays p = zeros(x.shape) p_hat = Unknown("vec_p_hat", phi.pos, x.shape, -1, per=phi.per, verbose=False) q = zeros(x.shape) r = zeros(x.shape) r_tilda = zeros(x.shape) u = zeros(x.shape) u_hat = Unknown("vec_u_hat", phi.pos, x.shape, -1, per=phi.per, verbose=False) v_hat = zeros(x.shape) # r = b - A * x r[:, :, :] = b[:, :, :] - mat_vec_bnd(a, phi) # Chose r~ r_tilda[:, :, :] = r[:, :, :] # --------------- # Iteration loop # --------------- if max_iter == -1: max_iter = prod(phi.val.shape) for i in range(1, max_iter): if verbose is True: print(" iteration: %3d:" % (i), end="") # rho = r~ * r rho = vec_vec(r_tilda, r) # If rho == 0 method fails if abs(rho) < TINY * TINY: if verbose is True == True: write.at(__name__) print(" Fails becuase rho = %12.5e" % rho) return x if i == 1: # u = r u[:, :, :] = r[:, :, :] # p = u p[:, :, :] = u[:, :, :] else: # beta = rho / rho_old beta = rho / rho_old # u = r + beta q u[:, :, :] = r[:, :, :] + beta * q[:, :, :] # p = u + beta (q + beta p) p[:, :, :] = u[:, :, :] + beta * (q[:, :, :] + beta * p[:, :, :]) # Solve M p_hat = p p_hat.val[:, :, :] = p[:, :, :] / a.C[:, :, :] # v^ = A * p^ v_hat[:, :, :] = mat_vec_bnd(a, p_hat) # alfa = rho / (r~ * v^) alfa = rho / vec_vec(r_tilda, v_hat) # q = u - alfa v^ q[:, :, :] = u[:, :, :] - alfa * v_hat[:, :, :] # Solve M u^ = u + q u_hat.val[:, :, :] = (u[:, :, :] + q[:, :, :]) / a.C[:, :, :] # x = x + alfa u^ x[:, :, :] += alfa * u_hat.val[:, :, :] # q^ = A u^ q_hat = mat_vec_bnd(a, u_hat) # r = r - alfa q^ r[:, :, :] -= alfa * q_hat[:, :, :] # Compute residual res = norm(r) if verbose is True: print("%12.5e" % res) # If tolerance has been reached, get out of here if res < tol: return x # Prepare for next iteration rho_old = rho return x # end of function
def bicgstab(a, phi, b, tol, ver): # ----------------------------------------------------------------------------- """ Args: a: System matrix in PyNS format (which ssentially means storing a bundle of non-zero diagonals in compas directions) phi: Unknown to be solved (from "create_unknown" function) b: Three-dimensional matrix holding the source term. tol: Absolute solver tolerance ver: Logical variable setting if solver will be verbatim (print info on Python console) or not. Returns: x: Three-dimensional matrix with solution. Note: One should also consider implementing periodic boundary conditions in this version of the solver. """ if ver: print("Solver: BiCGStab") # Helping variables x = phi.val n = prod(x.shape) # Intitilize arrays p = zeros(x.shape) p_hat = zeros(x.shape) r = zeros(x.shape) r_tilda = zeros(x.shape) s = zeros(x.shape) s_hat = zeros(x.shape) v = zeros(x.shape) # r = b - A * x r[:,:,:] = b[:,:,:] - mat_vec_bnd(a, phi) # Chose r~ r_tilda[:,:,:] = r[:,:,:] # --------------- # Iteration loop # --------------- for i in range(1,n): if ver: print(" iteration: %3d:" % (i), end = "" ) # rho = r~ * r rho = vec_vec(r_tilda, r) # If rho == 0 method fails if abs(rho) < TINY * TINY: print("bicgstab fails becuase rho = %12.5e" % rho) return x if i == 1: # p = r p[:,:,:] = r[:,:,:] else: # beta = (rho / rho_old)(alfa/omega) beta = rho / rho_old * alfa / omega # p = r + beta (p - omega v) p[:,:,:] = r[:,:,:] + beta * (p[:,:,:] - omega * v[:,:,:]) # Solve M p_hat = p p_hat[:,:,:] = p[:,:,:] / a.P[:,:,:] # v = A * p^ v[:,:,:] = mat_vec(a, p_hat) # alfa = rho / (r~ * v) alfa = rho / vec_vec(r_tilda, v) # s = r - alfa v s[:,:,:] = r[:,:,:] - alfa * v[:,:,:] # Check norm of s, if small enough set x = x + alfa p_hat and stop res = norm(s) if res < tol: if ver: print("%12.5e" %res) x[:,:,:] += alfa * p_hat[:,:,:] return x # Solve M s^ = s s_hat[:,:,:] = s[:,:,:] / a.P[:,:,:] # t = A s^ t = mat_vec(a, s_hat) # omega = (t * s) / (t * t) omega = vec_vec(t, s) / vec_vec(t, t) # x = x + alfa p^ + omega * s^ x[:,:,:] += alfa * p_hat[:,:,:] + omega * s_hat[:,:,:] # r = s - omega q^ r[:,:,:] = s[:,:,:] - omega * t[:,:,:] # Compute residual res = norm(r) if ver: print("%12.5e" %res) # If tolerance has been reached, get out of here if res < tol: return x # Prepare for next iteration rho_old = rho return x # end of function
def cgs(a, phi, b, tol, ver): # ----------------------------------------------------------------------------- """ Args: a: System matrix in PyNS format (which ssentially means storing a bundle of non-zero diagonals in compas directions) phi: Unknown to be solved (from "create_unknown" function) b: Three-dimensional matrix holding the source term. tol: Absolute solver tolerance ver: Logical variable setting if solver will be verbatim (print info on Python console) or not. Returns: x: Three-dimensional matrix with solution. Note: One should also consider implementing periodic boundary conditions in this version of the solver. """ if ver: print("Solver: CGS") # Helping variables x = phi.val n = prod(x.shape) # Intitilize arrays p = zeros(x.shape) p_hat = zeros(x.shape) q = zeros(x.shape) r = zeros(x.shape) r_tilda = zeros(x.shape) u = zeros(x.shape) u_hat = zeros(x.shape) v_hat = zeros(x.shape) # r = b - A * x r[:, :, :] = b[:, :, :] - mat_vec_bnd(a, phi) # Chose r~ r_tilda[:, :, :] = r[:, :, :] # --------------- # Iteration loop # --------------- for i in range(1, n): if ver: print(" iteration: %3d:" % (i), end="") # rho = r~ * r rho = vec_vec(r_tilda, r) # If rho == 0 method fails if abs(rho) < TINY * TINY: print("cgs fails becuase rho = %12.5e" % rho) return x if i == 1: # u = r u[:, :, :] = r[:, :, :] # p = u p[:, :, :] = u[:, :, :] else: # beta = rho / rho_old beta = rho / rho_old # u = r + beta q u[:, :, :] = r[:, :, :] + beta * q[:, :, :] # p = u + beta (q + beta p) p[:, :, :] = u[:, :, :] + beta * (q[:, :, :] + beta * p[:, :, :]) # Solve M p_hat = p p_hat[:, :, :] = p[:, :, :] / a.P[:, :, :] # v^ = A * p^ v_hat[:, :, :] = mat_vec(a, p_hat) # alfa = rho / (r~ * v^) alfa = rho / vec_vec(r_tilda, v_hat) # q = u - alfa v^ q[:, :, :] = u[:, :, :] - alfa * v_hat[:, :, :] # Solve M u^ = u + q u_hat[:, :, :] = (u[:, :, :] + q[:, :, :]) / a.P[:, :, :] # x = x + alfa u^ x[:, :, :] += alfa * u_hat[:, :, :] # q^ = A u^ q_hat = mat_vec(a, u_hat) # r = r - alfa q^ r[:, :, :] -= alfa * q_hat[:, :, :] # Compute residual res = norm(r) if ver: print("%12.5e" % res) # If tolerance has been reached, get out of here if res < tol: return x # Prepare for next iteration rho_old = rho return x # end of function
def bicgstab(a, phi, b, tol, verbose=False, max_iter=-1): # ----------------------------------------------------------------------------- """ Args: a: ...... Object of the type "Matrix", holding the system matrix. phi: .... Object of the type "Unknown" to be solved. b: ...... Three-dimensional array holding the source term. tol: .... Absolute solver tolerance verbose: Logical variable setting if solver will be verbose (print info on Python console) or not. max_iter: Maxiumum number of iterations. Returns: x: Three-dimensional array with solution. """ if verbose is True: write.at(__name__) # Helping variable x = phi.val # Intitilize arrays p = zeros(x.shape) p_hat = Unknown("vec_p_hat", phi.pos, x.shape, -1, per=phi.per, verbose=False) r = zeros(x.shape) r_tilda = zeros(x.shape) s = zeros(x.shape) s_hat = Unknown("vec_s_hat", phi.pos, x.shape, -1, per=phi.per, verbose=False) v = zeros(x.shape) # r = b - A * x r[:, :, :] = b[:, :, :] - mat_vec_bnd(a, phi) # Chose r~ r_tilda[:, :, :] = r[:, :, :] # --------------- # Iteration loop # --------------- if max_iter == -1: max_iter = prod(phi.val.shape) for i in range(1, max_iter): if verbose is True: print(" iteration: %3d:" % (i), end="") # rho = r~ * r rho = vec_vec(r_tilda, r) # If rho == 0 method fails if abs(rho) < TINY * TINY: write.at(__name__) print(" Fails becuase rho = %12.5e" % rho) return x if i == 1: # p = r p[:, :, :] = r[:, :, :] else: # beta = (rho / rho_old)(alfa/omega) beta = rho / rho_old * alfa / omega # p = r + beta (p - omega v) p[:, :, :] = r[:, :, :] + beta * (p[:, :, :] - omega * v[:, :, :]) # Solve M p_hat = p p_hat.val[:, :, :] = p[:, :, :] / a.C[:, :, :] # v = A * p^ v[:, :, :] = mat_vec_bnd(a, p_hat) # alfa = rho / (r~ * v) alfa = rho / vec_vec(r_tilda, v) # s = r - alfa v s[:, :, :] = r[:, :, :] - alfa * v[:, :, :] # Check norm of s, if small enough set x = x + alfa p_hat and stop res = norm(s) if res < tol: if verbose is True == True: write.at(__name__) print(" Fails becuase rho = %12.5e" % rho) x[:, :, :] += alfa * p_hat.val[:, :, :] return x # Solve M s^ = s s_hat.val[:, :, :] = s[:, :, :] / a.C[:, :, :] # t = A s^ t = mat_vec_bnd(a, s_hat) # omega = (t * s) / (t * t) omega = vec_vec(t, s) / vec_vec(t, t) # x = x + alfa p^ + omega * s^ x[:, :, :] += alfa * p_hat.val[:, :, :] + omega * s_hat.val[:, :, :] # r = s - omega q^ r[:, :, :] = s[:, :, :] - omega * t[:, :, :] # Compute residual res = norm(r) if verbose is True: print("%12.5e" % res) # If tolerance has been reached, get out of here if res < tol: return x # Prepare for next iteration rho_old = rho return x # end of function
def cg(a, phi, b, tol, ver): # ----------------------------------------------------------------------------- """ Args: a: System matrix in PyNS format (which ssentially means storing a bundle of non-zero diagonals in compas directions) phi: Unknown to be solved (from "create_unknown" function) b: Three-dimensional matrix holding the source term. tol: Absolute solver tolerance ver: Logical variable setting if solver will be verbatim (print info on Python console) or not. Returns: x: Three-dimensional matrix with solution. Note: One should also consider implementing periodic boundary conditions in this version of the solver. """ if ver: print("Solver: CG") # Helping variables x = phi.val n = prod(x.shape) # Intitilize arrays p = zeros(x.shape) q = zeros(x.shape) r = zeros(x.shape) z = zeros(x.shape) # r = b - A * x r[:, :, :] = b[:, :, :] - mat_vec_bnd(a, phi) # --------------- # Iteration loop # --------------- for i in range(1, n): if ver: print(" iteration: %3d:" % (i), end="") # Solve M z = r z[:, :, :] = r[:, :, :] / a.P[:, :, :] # rho = r * z rho = vec_vec(r, z) if i == 1: # p = z p[:, :, :] = z[:, :, :] else: # beta = rho / rho_old beta = rho / rho_old # p = z + beta p p[:, :, :] = z[:, :, :] + beta * p[:, :, :] # q = A * p q[:, :, :] = mat_vec(a, p) # alfa = rho / (p * q) alfa = rho / vec_vec(p, q) # x = x + alfa p x[:, :, :] += alfa * p[:, :, :] # r = r - alfa q r[:, :, :] -= alfa * q[:, :, :] # Compute residual res = norm(r) if ver: print("%12.5e" % res) # If tolerance has been reached, get out of here if res < tol: return x # Prepare for next iteration rho_old = rho return x # end of function
def cg(a, phi, b, tol, verbose=False, max_iter=-1): # ----------------------------------------------------------------------------- """ Args: a: ...... Object of the type "Matrix", holding the system matrix. phi: .... Object of the type "Unknown" to be solved. b: ...... Three-dimensional array holding the source term. tol: .... Absolute solver tolerance verbose: Logical variable setting if solver will be verbose (print info on Python console) or not. max_iter: Maxiumum number of iterations. Returns: x: Three-dimensional array with solution. """ if verbose is True: write.at(__name__) # Helping variable x = phi.val # Intitilize arrays p = Unknown("vec_p", phi.pos, x.shape, -1, per=phi.per, verbose=False) q = zeros(x.shape) r = zeros(x.shape) z = zeros(x.shape) # r = b - A * x r[:, :, :] = b[:, :, :] - mat_vec_bnd(a, phi) # --------------- # Iteration loop # --------------- if max_iter == -1: max_iter = prod(phi.val.shape) for i in range(1, max_iter): if verbose is True: print(" iteration: %3d:" % (i), end="") # Solve M z = r z[:, :, :] = r[:, :, :] / a.C[:, :, :] # rho = r * z rho = vec_vec(r, z) if i == 1: # p = z p.val[:, :, :] = z[:, :, :] else: # beta = rho / rho_old beta = rho / rho_old # p = z + beta p p.val[:, :, :] = z[:, :, :] + beta * p.val[:, :, :] # q = A * p q[:, :, :] = mat_vec_bnd(a, p) # alfa = rho / (p * q) alfa = rho / vec_vec(p.val, q) # x = x + alfa p x[:, :, :] += alfa * p.val[:, :, :] # r = r - alfa q r[:, :, :] -= alfa * q[:, :, :] # Compute residual res = norm(r) if verbose is True: print("%12.5e" % res) # If tolerance has been reached, get out of here if res < tol: return x # Prepare for next iteration rho_old = rho return x # end of function