Exemple #1
0
def norm(x):
    # -----------------------------------------------------------------------------
    """
    Args:
      x: Vector.

    Returns:
      Norm of the vector.
    """

    return sqrt(vec_vec(x, x))  # end of function
Exemple #2
0
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
Exemple #3
0
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
Exemple #4
0
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
Exemple #5
0
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
Exemple #6
0
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
Exemple #7
0
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