Ejemplo n.º 1
0
    tol = 1.0E-8       # tolerance
    iter = 0            # iteration counter
    maxiter = 10        # max no of iterations allowed
    SolutionTime = 0
    while epsu > tol  and iter < maxiter:
        iter += 1
        uu = Function(W)
        AA, bb = assemble_system(maxwell+ns+CoupleTerm, Lmaxwell + Lns, bc)


        VelPres = Velocitydim[xx-1][0] +Pressuredim[xx-1][0]


        A,b,x = Direct.RemoveRowCol(AA,bb,VelPres)

        ksp = PETSc.KSP().create()
        pc = PETSc.PC().create()
        ksp.setOperators(A)

        ksp.setFromOptions()

        print '\n\n\nSolving with:', ksp.getType()


        tic()

        ksp.solve(b, x)

        time = toc()
        print time
        SolutionTime = SolutionTime +time
Ejemplo n.º 2
0
def test_manufactured_poisson(degree, filename, datadir):
    """ Manufactured Poisson problem, solving u = x[1]**p, where p is the
    degree of the Lagrange function space.

    """

    with XDMFFile(MPI.COMM_WORLD, os.path.join(datadir, filename), "r", encoding=XDMFFile.Encoding.ASCII) as xdmf:
        mesh = xdmf.read_mesh(name="Grid")

    V = FunctionSpace(mesh, ("Lagrange", degree))
    u, v = TrialFunction(V), TestFunction(V)
    a = inner(grad(u), grad(v)) * dx

    # Get quadrature degree for bilinear form integrand (ignores effect
    # of non-affine map)
    a = inner(grad(u), grad(v)) * dx(metadata={"quadrature_degree": -1})
    a.integrals()[0].metadata()["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(a)

    # Source term
    x = SpatialCoordinate(mesh)
    u_exact = x[1]**degree
    f = - div(grad(u_exact))

    # Set quadrature degree for linear form integrand (ignores effect of
    # non-affine map)
    L = inner(f, v) * dx(metadata={"quadrature_degree": -1})
    L.integrals()[0].metadata()["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(L)

    t0 = time.time()
    L = fem.Form(L)
    t1 = time.time()
    print("Linear form compile time:", t1 - t0)

    u_bc = Function(V)
    u_bc.interpolate(lambda x: x[1]**degree)

    # Create Dirichlet boundary condition
    mesh.topology.create_connectivity_all()
    facetdim = mesh.topology.dim - 1
    bndry_facets = np.where(np.array(cpp.mesh.compute_boundary_facets(mesh.topology)) == 1)[0]
    bdofs = locate_dofs_topological(V, facetdim, bndry_facets)
    assert(len(bdofs) < V.dim)
    bc = DirichletBC(u_bc, bdofs)

    t0 = time.time()
    b = assemble_vector(L)
    apply_lifting(b, [a], [[bc]])
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)
    set_bc(b, [bc])
    t1 = time.time()
    print("Vector assembly time:", t1 - t0)

    t0 = time.time()
    a = fem.Form(a)
    t1 = time.time()
    print("Bilinear form compile time:", t1 - t0)

    t0 = time.time()
    A = assemble_matrix(a, [bc])
    A.assemble()
    t1 = time.time()
    print("Matrix assembly time:", t1 - t0)

    # Create LU linear solver
    solver = PETSc.KSP().create(MPI.COMM_WORLD)
    solver.setType(PETSc.KSP.Type.PREONLY)
    solver.getPC().setType(PETSc.PC.Type.LU)
    solver.setOperators(A)
    # Solve
    t0 = time.time()
    uh = Function(V)
    solver.solve(b, uh.vector)
    uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)

    t1 = time.time()
    print("Linear solver time:", t1 - t0)

    M = (u_exact - uh)**2 * dx
    t0 = time.time()
    M = fem.Form(M)
    t1 = time.time()
    print("Error functional compile time:", t1 - t0)

    t0 = time.time()
    error = mesh.mpi_comm().allreduce(assemble_scalar(M), op=MPI.SUM)

    t1 = time.time()

    print("Error assembly time:", t1 - t0)
    assert np.absolute(error) < 1.0e-14
Ejemplo n.º 3
0
def solve(A, b, u, params, Fspace, SolveType, IterType, OuterTol, InnerTol,
          HiptmairMatrices, Hiptmairtol, KSPlinearfluids, Fp, kspF):

    if SolveType == "Direct":
        ksp = PETSc.KSP()
        ksp.create(comm=PETSc.COMM_WORLD)
        pc = ksp.getPC()
        ksp.setType('preonly')
        pc.setType('lu')
        OptDB = PETSc.Options()
        OptDB['pc_factor_mat_solver_package'] = "mumps"
        OptDB['pc_factor_mat_ordering_type'] = "rcm"
        ksp.setFromOptions()
        scale = b.norm()
        b = b / scale
        ksp.setOperators(A, A)
        del A
        ksp.solve(b, u)
        # Mits +=dodim
        u = u * scale
        MO.PrintStr("Number iterations = " + str(ksp.its), 60, "+", "\n\n",
                    "\n\n")
        return u, ksp.its, 0
    elif SolveType == "Direct-class":
        ksp = PETSc.KSP()
        ksp.create(comm=PETSc.COMM_WORLD)
        pc = ksp.getPC()
        ksp.setType('gmres')
        pc.setType('none')
        ksp.setFromOptions()
        scale = b.norm()
        b = b / scale
        ksp.setOperators(A, A)
        del A
        ksp.solve(b, u)
        # Mits +=dodim
        u = u * scale
        MO.PrintStr("Number iterations = " + str(ksp.its), 60, "+", "\n\n",
                    "\n\n")
        return u, ksp.its, 0

    else:

        # u = b.duplicate()
        if IterType == "Full":
            ksp = PETSc.KSP()
            ksp.create(comm=PETSc.COMM_WORLD)
            pc = ksp.getPC()
            ksp.setType('fgmres')
            pc.setType('python')
            pc.setType(PETSc.PC.Type.PYTHON)
            OptDB = PETSc.Options()
            OptDB['ksp_gmres_restart'] = 200
            # FSpace = [Velocity,Magnetic,Pressure,Lagrange]
            reshist = {}

            def monitor(ksp, its, fgnorm):
                reshist[its] = fgnorm
                print its, "    OUTER:", fgnorm

            # ksp.setMonitor(monitor)
            ksp.max_it = 500
            W = Fspace
            FFSS = [W.sub(0), W.sub(1), W.sub(2), W.sub(3)]
            pc.setPythonContext(
                MHDprec.InnerOuterMAGNETICinverse(
                    FFSS, kspF, KSPlinearfluids[0], KSPlinearfluids[1], Fp,
                    HiptmairMatrices[3], HiptmairMatrices[4],
                    HiptmairMatrices[2], HiptmairMatrices[0],
                    HiptmairMatrices[1], HiptmairMatrices[6], Hiptmairtol))
            #OptDB = PETSc.Options()

            # OptDB['pc_factor_mat_solver_package']  = "mumps"
            # OptDB['pc_factor_mat_ordering_type']  = "rcm"
            # ksp.setFromOptions()
            scale = b.norm()
            b = b / scale
            ksp.setOperators(A, A)
            del A
            ksp.solve(b, u)
            # Mits +=dodim
            u = u * scale
            MO.PrintStr("Number iterations = " + str(ksp.its), 60, "+", "\n\n",
                        "\n\n")
            return u, ksp.its, 0

        IS = MO.IndexSet(Fspace, '2by2')
        M_is = IS[1]
        NS_is = IS[0]
        kspNS = PETSc.KSP().create()
        kspM = PETSc.KSP().create()
        kspNS.setTolerances(OuterTol)

        kspNS.setOperators(A[0])
        kspM.setOperators(A[1])
        # print P.symmetric
        if IterType == "MD":
            kspNS.setType('gmres')
            kspNS.max_it = 500

            pcNS = kspNS.getPC()
            pcNS.setType(PETSc.PC.Type.PYTHON)
            pcNS.setPythonContext(
                NSpreconditioner.NSPCD(
                    MixedFunctionSpace([Fspace.sub(0),
                                        Fspace.sub(1)]), kspF,
                    KSPlinearfluids[0], KSPlinearfluids[1], Fp))
        elif IterType == "CD":
            kspNS.setType('minres')
            pcNS = kspNS.getPC()
            pcNS.setType(PETSc.PC.Type.PYTHON)
            Q = KSPlinearfluids[1].getOperators()[0]
            Q = 1. / params[2] * Q
            KSPlinearfluids[1].setOperators(Q, Q)
            pcNS.setPythonContext(
                StokesPrecond.MHDApprox(
                    MixedFunctionSpace([Fspace.sub(0),
                                        Fspace.sub(1)]), kspF,
                    KSPlinearfluids[1]))
        reshist = {}

        def monitor(ksp, its, fgnorm):
            reshist[its] = fgnorm
            print fgnorm

        # kspNS.setMonitor(monitor)

        uNS = u.getSubVector(NS_is)
        bNS = b.getSubVector(NS_is)
        # print kspNS.view()
        scale = bNS.norm()
        bNS = bNS / scale
        print bNS.norm()
        kspNS.solve(bNS, uNS)
        uNS = uNS * scale
        NSits = kspNS.its
        kspNS.destroy()
        # for line in reshist.values():
        #     print line
        kspM.setFromOptions()
        kspM.setType(kspM.Type.MINRES)
        kspM.setTolerances(InnerTol)
        pcM = kspM.getPC()
        pcM.setType(PETSc.PC.Type.PYTHON)
        pcM.setPythonContext(
            MP.Hiptmair(MixedFunctionSpace([Fspace.sub(2),
                                            Fspace.sub(3)]),
                        HiptmairMatrices[3], HiptmairMatrices[4],
                        HiptmairMatrices[2], HiptmairMatrices[0],
                        HiptmairMatrices[1], HiptmairMatrices[6], Hiptmairtol))

        uM = u.getSubVector(M_is)
        bM = b.getSubVector(M_is)
        scale = bM.norm()
        bM = bM / scale
        print bM.norm()
        kspM.solve(bM, uM)
        uM = uM * scale
        Mits = kspM.its
        kspM.destroy()
        u = IO.arrayToVec(np.concatenate([uNS.array, uM.array]))

        MO.PrintStr("Number of M iterations = " + str(Mits), 60, "+", "\n\n",
                    "\n\n")
        MO.PrintStr("Number of NS/S iterations = " + str(NSits), 60, "+",
                    "\n\n", "\n\n")
        return u, NSits, Mits
Ejemplo n.º 4
0
from __future__ import print_function
from petsc4py import PETSc
import numpy as np
import DMPFOR
from six.moves import range



global_nx =3
global_ny =2
dof=4

da = PETSc.DA().create(dim=2,
dof=dof,
sizes=[global_nx, global_ny], 
#periodic_type = PETSc.DA.PeriodicType.GHOSTED_XYZ,
#stencil_type=self.STENCIL,
#stencil_width=2,
comm=PETSc.COMM_WORLD)


gVec = da.createGlobalVector()
lVec = da.createLocalVector()




ranges = da.getRanges()

nx_start = ranges[0][0]
nx_end = ranges[0][1]
Ejemplo n.º 5
0
def Maxwell(V, Q, F, b0, r0, params, mesh, HiptmairMatrices, Hiptmairtol):
    parameters['reorder_dofs_serial'] = False

    W = V*Q
    W = FunctionSpace(mesh, MixedElement([V, Q]))

    IS = MO.IndexSet(W)

    (b, r) = TrialFunctions(W)
    (c, s) = TestFunctions(W)
    if params[0] == 0.0:
        a11 = params[1]*inner(curl(b), curl(c))*dx
    else:
        a11 = params[1]*params[0]*inner(curl(b), curl(c))*dx
    a21 = inner(b, grad(s))*dx
    a12 = inner(c, grad(r))*dx
    # print F
    L = inner(c, F)*dx
    a = a11+a12+a21

    def boundary(x, on_boundary):
        return on_boundary
    # class b0(Expression):
    #     def __init__(self):
    #         self.p = 1
    #     def eval_cell(self, values, x, ufc_cell):
    #         values[0] = 0.0
    #         values[1] = 1.0
    #     def value_shape(self):
    #         return (2,)

    bcb = DirichletBC(W.sub(0), b0, boundary)
    bcr = DirichletBC(W.sub(1), r0, boundary)
    bc = [bcb, bcr]

    A, b = assemble_system(a, L, bc)
    A, b = CP.Assemble(A, b)
    u = b.duplicate()

    ksp = PETSc.KSP()
    ksp.create(comm=PETSc.COMM_WORLD)
    pc = ksp.getPC()
    ksp.setType('preonly')
    pc.setType('lu')
    OptDB = PETSc.Options()
    OptDB['pc_factor_mat_solver_package']  = "pastix"
    OptDB['pc_factor_mat_ordering_type']  = "rcm"
    ksp.setFromOptions()

    # ksp = PETSc.KSP().create()
    # ksp.setTolerances(1e-8)
    # ksp.max_it = 200
    # pc = ksp.getPC()
    # pc.setType(PETSc.PC.Type.PYTHON)
    # ksp.setType('minres')
    # pc.setPythonContext(MP.Hiptmair(W, HiptmairMatrices[3], HiptmairMatrices[4], HiptmairMatrices[
    #                     2], HiptmairMatrices[0], HiptmairMatrices[1], HiptmairMatrices[6], Hiptmairtol))
    scale = b.norm()
    b = b/scale
    ksp.setOperators(A, A)
    del A
    start_time = time.time()
    ksp.solve(b, u)
    print("{:40}").format("Maxwell solve, time: "), " ==>  ", ("{:4f}").format(time.time() - start_time), ("{:9}").format(
        "   Its: "), ("{:4}").format(ksp.its),  ("{:9}").format("   time: "), ("{:4}").format(time.strftime('%X %x %Z')[0:5])
    u = u*scale

    b_k = Function(FunctionSpace(mesh, V))
    r_k = Function(FunctionSpace(mesh, Q))
    b_k.vector()[:] = u.getSubVector(IS[0]).array
    r_k.vector()[:] = u.getSubVector(IS[1]).array

    return b_k, r_k
Ejemplo n.º 6
0
    def Solve(self, A, b, reuse_factorisation=False):
        """Solves the linear system of equations"""

        if not issparse(A):
            raise ValueError("Linear system is not of sparse type")

        if A.shape == (0, 0) and b.shape[0] == 0:
            warn("Empty linear system!!! Nothing to solve!!!")
            return np.copy(b)

        self.reuse_factorisation = reuse_factorisation
        if self.solver_type != "direct" and self.reuse_factorisation is True:
            warn(
                "Re-using factorisation for non-direct solvers is not possible. The pre-conditioner is going to be reused instead"
            )

        # DECIDE IF THE SOLVER TYPE IS APPROPRIATE FOR THE PROBLEM
        if self.switcher_message is False and self.dont_switch_solver is False:
            # PREFER PARDISO OR MUMPS OVER AMG IF AVAILABLE
            if self.has_pardiso:
                self.solver_type = "direct"
                self.solver_subtype = "pardiso"
            elif self.has_mumps:
                self.solver_type = "direct"
                self.solver_subtype = "mumps"
            elif b.shape[0] > 100000 and self.has_amg_solver:
                self.solver_type = "amg"
                self.solver_subtype = "gmres"
                print(
                    'Large system of equations. Switching to algebraic multigrid solver'
                )
                self.switcher_message = True
            # elif mesh.points.shape[0]*MainData.nvar > 50000 and MainData.C < 4:
            # self.solver_type = "direct"
            # self.solver_subtype = "MUMPS"
            # print 'Large system of equations. Switching to MUMPS solver'
            elif b.shape[
                    0] > 70000 and self.geometric_discretisation == "hex" and self.has_amg_solver:
                self.solver_type = "amg"
                self.solver_subtype = "gmres"
                print(
                    'Large system of equations. Switching to algebraic multigrid solver'
                )
                self.switcher_message = True
            else:
                self.solver_type = "direct"
                self.solver_subtype = "umfpack"

        if self.solver_type == 'direct':
            # CALL DIRECT SOLVER
            if self.solver_subtype == 'umfpack' and self.has_umfpack:
                if A.dtype != np.float64:
                    A = A.astype(np.float64)

                t_solve = time()
                if self.solver_context_manager is None:
                    if self.reuse_factorisation is False:
                        sol = spsolve(A,
                                      b,
                                      permc_spec='MMD_AT_PLUS_A',
                                      use_umfpack=True)
                        # from scikits import umfpack
                        # sol = umfpack.spsolve(A, b)

                        # SuperLU
                        # from scipy.sparse.linalg import splu
                        # lu = splu(A.tocsc())
                        # sol = lu.solve(b)
                    else:
                        from scikits import umfpack
                        lu = umfpack.splu(A)
                        sol = lu.solve(b)
                        self.solver_context_manager = lu
                else:
                    sol = self.solver_context_manager.solve(b)

                # print("UmfPack solver time is {}".format(time() - t_solve))

            elif self.solver_subtype == 'mumps' and self.has_mumps:

                from mumps.mumps_context import MUMPSContext
                t_solve = time()
                A = A.tocoo()
                # False means non-symmetric - Do not change it to True. True means symmetric pos def
                # which is not the case for electromechanics
                if self.solver_context_manager is None:
                    context = MUMPSContext(
                        (A.shape[0], A.row, A.col, A.data, False),
                        verbose=False)
                    context.analyze()
                    context.factorize()
                    sol = context.solve(rhs=b)

                    if self.reuse_factorisation:
                        self.solver_context_manager = context
                else:
                    sol = self.solver_context_manager.solve(rhs=b)

                print("MUMPS solver time is {}".format(time() - t_solve))

                return sol

            elif self.solver_subtype == "pardiso" and self.has_pardiso:
                # NOTE THAT THIS PARDISO SOLVER AUTOMATICALLY SAVES THE RIGHT FACTORISATION
                import pypardiso
                from pypardiso.scipy_aliases import pypardiso_solver as ps
                A = A.tocsr()
                t_solve = time()
                sol = pypardiso.spsolve(A, b)
                if self.reuse_factorisation is False:
                    ps.remove_stored_factorization()
                    ps.free_memory()
                print("Pardiso solver time is {}".format(time() - t_solve))

            else:
                # FOR 'super_lu'
                if A.dtype != np.float64:
                    A = A.astype(np.float64)
                A = A.tocsc()

                if self.solver_context_manager is None:
                    if self.reuse_factorisation is False:
                        sol = spsolve(A,
                                      b,
                                      permc_spec='MMD_AT_PLUS_A',
                                      use_umfpack=True)
                    else:
                        lu = splu(A)
                        sol = lu.solve(b)
                        self.solver_context_manager = lu
                else:
                    sol = self.solver_context_manager.solve(b)

        elif self.solver_type == "iterative":
            t_solve = time()
            # CALL ITERATIVE SOLVER
            if self.solver_subtype == "gmres":
                sol = gmres(A, b, tol=self.iterative_solver_tolerance)[0]
            if self.solver_subtype == "lgmres":
                sol = lgmres(A, b, tol=self.iterative_solver_tolerance)[0]
            elif self.solver_subtype == "bicgstab":
                sol = bicgstab(A, b, tol=self.iterative_solver_tolerance)[0]
            else:
                sol = cg(A, b, tol=self.iterative_solver_tolerance)[0]

            # PRECONDITIONED ITERATIVE SOLVER - CHECK
            # P = spilu(A.tocsc(), drop_tol=1e-5)
            # M_x = lambda x: P.solve(x)
            # m = A.shape[1]
            # n = A.shape[0]
            # M = LinearOperator((n * m, n * m), M_x)
            # sol = cg(A, b, tol=self.iterative_solver_tolerance, M=M)[0]
            print("Iterative solver time is {}".format(time() - t_solve))

        elif self.solver_type == "amg":
            if self.has_amg_solver is False:
                raise ImportError(
                    'Algebraic multigrid solver was not found. Please install it using "pip install pyamg"'
                )
            from pyamg import ruge_stuben_solver, rootnode_solver, smoothed_aggregation_solver

            if A.dtype != b.dtype:
                # DOWN-CAST
                b = b.astype(A.dtype)

            if not isspmatrix_csr(A):
                A = A.tocsr()

            t_solve = time()

            if self.iterative_solver_tolerance > 1e-9:
                self.iterative_solver_tolerance = 1e-10

            # AMG METHOD
            amg_func = None
            if self.preconditioner_type == "smoothed_aggregation":
                # THIS IS TYPICALLY FASTER BUT THE TOLERANCE NEED TO BE SMALLER, TYPICALLY 1e-10
                amg_func = smoothed_aggregation_solver
            elif self.preconditioner_type == "ruge_stuben":
                amg_func = ruge_stuben_solver
            elif self.preconditioner_type == "rootnode":
                amg_func = rootnode_solver
            else:
                amg_func = rootnode_solver

            ml = amg_func(A)
            # ml = amg_func(A, smooth=('energy', {'degree':2}), strength='evolution' )
            # ml = amg_func(A, max_levels=3, diagonal_dominance=True)
            # ml = amg_func(A, coarse_solver=spsolve)
            # ml = amg_func(A, coarse_solver='cholesky')

            if self.solver_context_manager is None:
                # M = ml.aspreconditioner(cycle='V')
                M = ml.aspreconditioner()
                if self.reuse_factorisation:
                    self.solver_context_manager = M
            else:
                M = self.solver_context_manager

            # EXPLICIT CALL TO KYROLOV SOLVERS WITH AMG PRECONDITIONER
            # sol, info = bicgstab(A, b, M=M, tol=self.iterative_solver_tolerance)
            # sol, info = cg(A, b, M=M, tol=self.iterative_solver_tolerance)
            # sol, info = gmres(A, b, M=M, tol=self.iterative_solver_tolerance)

            # IMPLICIT CALL TO KYROLOV SOLVERS WITH AMG PRECONDITIONER
            residuals = []
            sol = ml.solve(b,
                           tol=self.iterative_solver_tolerance,
                           accel=self.solver_subtype,
                           residuals=residuals)

            print("AMG solver time is {}".format(time() - t_solve))

        elif self.solver_type == "petsc" and self.has_petsc:
            if self.solver_subtype != "gmres" and self.solver_subtype != "minres" and self.solver_subtype != "cg":
                self.solver_subtype == "cg"
            if self.iterative_solver_tolerance < 1e-9:
                self.iterative_solver_tolerance = 1e-7

            from petsc4py import PETSc
            t_solve = time()
            pA = PETSc.Mat().createAIJ(size=A.shape,
                                       csr=(A.indptr, A.indices, A.data))
            pb = PETSc.Vec().createWithArray(b)

            ksp = PETSc.KSP()
            ksp.create(PETSc.COMM_WORLD)
            # ksp.create()
            ksp.setType(self.solver_subtype)
            ksp.setTolerances(atol=self.iterative_solver_tolerance,
                              rtol=self.iterative_solver_tolerance)
            # ILU
            ksp.getPC().setType('icc')

            # CREATE INITIAL GUESS
            psol = PETSc.Vec().createWithArray(np.ones(b.shape[0]))
            # SOLVE
            ksp.setOperators(pA)
            ksp.setFromOptions()
            ksp.solve(pb, psol)
            sol = psol.getArray()

            # print('Converged in', ksp.getIterationNumber(), 'iterations.')
            print("Petsc linear iterative solver time is {}".format(time() -
                                                                    t_solve))

        else:
            warn(
                "{} solver is not available. Default solver is going to be used"
                .format(self.solver_type))
            # FOR 'super_lu'
            if A.dtype != np.float64:
                A = A.astype(np.float64)
            A = A.tocsc()

            if self.solver_context_manager is None:
                if self.reuse_factorisation is False:
                    sol = spsolve(A,
                                  b,
                                  permc_spec='MMD_AT_PLUS_A',
                                  use_umfpack=True)
                else:
                    lu = splu(A)
                    sol = lu.solve(b)
                    self.solver_context_manager = lu
            else:
                sol = self.solver_context_manager.solve(b)

        return sol
Ejemplo n.º 7
0
 def testApplyIS(self):
     is_in = PETSc.IS().createStride(self.lgmap.getSize())
     is_out = self.lgmap.apply(is_in)
Ejemplo n.º 8
0

# load libraries
from numpy import *
import matplotlib.pyplot as plt
import h5py as h5
from petsc4py import PETSc
from slepc4py import SLEPc
from mpi4py import MPI

# load functions for stability analysis
import parfemstab as pfs
from parfemstab import Print,PrintRed,PrintGreen

# Set MUMPS as the linear solver
opts = PETSc.Options()

# Parallel info
comm = MPI.COMM_WORLD
rank = comm.Get_rank()

# Get the directory where ff++ data is
di = opts.getString('dir')

# Build FreeFEMdisc from .dat files
Print('Loading discretization files ... ')
if rank == 0:
    try:
        ffdisc = ff.FreeFEMdisc(di+'/ffdata.h5')
        Print('data loaded from .h5 file ... ')
    except IOError:
Ejemplo n.º 9
0
    def amg_solve(N, method):
        # Elasticity parameters
        E = 1.0e9
        nu = 0.3
        mu = E / (2.0 * (1.0 + nu))
        lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))

        # Stress computation
        def sigma(v):
            return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(
                grad(v))) * Identity(2)

        # Define problem
        mesh = UnitSquareMesh(MPI.COMM_WORLD, N, N)
        V = VectorFunctionSpace(mesh, 'Lagrange', 1)
        bc0 = Function(V)
        with bc0.vector.localForm() as bc_local:
            bc_local.set(0.0)

        def boundary(x):
            return np.full(x.shape[1], True)

        facetdim = mesh.topology.dim - 1
        bndry_facets = locate_entities_boundary(mesh, facetdim, boundary)

        bdofs = locate_dofs_topological(V.sub(0), V, facetdim, bndry_facets)
        bc = DirichletBC(bc0, bdofs, V.sub(0))
        u = TrialFunction(V)
        v = TestFunction(V)

        # Forms
        a, L = inner(sigma(u), grad(v)) * dx, dot(ufl.as_vector(
            (1.0, 1.0)), v) * dx

        # Assemble linear algebra objects
        A = assemble_matrix(a, [bc])
        A.assemble()
        b = assemble_vector(L)
        apply_lifting(b, [a], [[bc]])
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)
        set_bc(b, [bc])

        # Create solution function
        u = Function(V)

        # Create near null space basis and orthonormalize
        null_space = build_nullspace(V, u.vector)

        # Attached near-null space to matrix
        A.set_near_nullspace(null_space)

        # Test that basis is orthonormal
        assert null_space.is_orthonormal()

        # Create PETSC smoothed aggregation AMG preconditioner, and
        # create CG solver
        solver = PETSc.KSP().create(mesh.mpi_comm)
        solver.setType("cg")

        # Set matrix operator
        solver.setOperators(A)

        # Compute solution and return number of iterations
        return solver.solve(b, u.vector)
Ejemplo n.º 10
0
def Scipy2PETSc(A):
    A = A.tocsr()
    return PETSc.Mat().createAIJ(size=A.shape, csr=(A.indptr, A.indices, A.data))
Ejemplo n.º 11
0
def test_krylov_samg_solver_elasticity():
    "Test PETScKrylovSolver with smoothed aggregation AMG"

    def build_nullspace(V, x):
        """Function to build null space for 2D elasticity"""

        # Create list of vectors for null space
        nullspace_basis = [x.copy() for i in range(3)]

        with ExitStack() as stack:
            vec_local = [
                stack.enter_context(x.localForm()) for x in nullspace_basis
            ]
            basis = [np.asarray(x) for x in vec_local]

            # Build null space basis
            dofs = [V.sub(i).dofmap.list.array for i in range(2)]
            for i in range(2):
                basis[i][dofs[i]] = 1.0
            x = V.tabulate_dof_coordinates()
            basis[2][dofs[0]] = -x[dofs[0], 1]
            basis[2][dofs[1]] = x[dofs[1], 0]

        null_space = VectorSpaceBasis(nullspace_basis)
        null_space.orthonormalize()
        return null_space

    def amg_solve(N, method):
        # Elasticity parameters
        E = 1.0e9
        nu = 0.3
        mu = E / (2.0 * (1.0 + nu))
        lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu))

        # Stress computation
        def sigma(v):
            return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym(
                grad(v))) * Identity(2)

        # Define problem
        mesh = UnitSquareMesh(MPI.COMM_WORLD, N, N)
        V = VectorFunctionSpace(mesh, 'Lagrange', 1)
        bc0 = Function(V)
        with bc0.vector.localForm() as bc_local:
            bc_local.set(0.0)

        def boundary(x):
            return np.full(x.shape[1], True)

        facetdim = mesh.topology.dim - 1
        bndry_facets = locate_entities_boundary(mesh, facetdim, boundary)

        bdofs = locate_dofs_topological(V.sub(0), V, facetdim, bndry_facets)
        bc = DirichletBC(bc0, bdofs, V.sub(0))
        u = TrialFunction(V)
        v = TestFunction(V)

        # Forms
        a, L = inner(sigma(u), grad(v)) * dx, dot(ufl.as_vector(
            (1.0, 1.0)), v) * dx

        # Assemble linear algebra objects
        A = assemble_matrix(a, [bc])
        A.assemble()
        b = assemble_vector(L)
        apply_lifting(b, [a], [[bc]])
        b.ghostUpdate(addv=PETSc.InsertMode.ADD,
                      mode=PETSc.ScatterMode.REVERSE)
        set_bc(b, [bc])

        # Create solution function
        u = Function(V)

        # Create near null space basis and orthonormalize
        null_space = build_nullspace(V, u.vector)

        # Attached near-null space to matrix
        A.set_near_nullspace(null_space)

        # Test that basis is orthonormal
        assert null_space.is_orthonormal()

        # Create PETSC smoothed aggregation AMG preconditioner, and
        # create CG solver
        solver = PETSc.KSP().create(mesh.mpi_comm)
        solver.setType("cg")

        # Set matrix operator
        solver.setOperators(A)

        # Compute solution and return number of iterations
        return solver.solve(b, u.vector)

    # Set some multigrid smoother paramete rs
    opts = PETSc.Options()
    opts["mg_levels_ksp_type"] = "chebyshev"
    opts["mg_levels_pc_type"] = "jacobi"

    # Improve estimate of eigenvalues for Chebyshev smoothing
    opts["mg_levels_esteig_ksp_type"] = "cg"
    opts["mg_levels_ksp_chebyshev_esteig_steps"] = 50

    # Build list of smoothed aggregation preconditioners
    methods = ["petsc_amg"]
    # if "ml_amg" in PETScPreconditioner.preconditioners():
    #    methods.append("ml_amg")

    # Test iteration count with increasing mesh size for each
    # preconditioner
    for method in methods:
        for N in [8, 16, 32, 64]:
            print("Testing method '{}' with {} x {} mesh".format(method, N, N))
            niter = amg_solve(N, method)
            assert niter < 18
Ejemplo n.º 12
0
 def __init__(self, global_max):
     from petsc4py import PETSc
     self._local_max = global_max
     self._global_max = global_max
     self._reduce_vec = PETSc.Vec().createWithArray([0])
Ejemplo n.º 13
0
import numpy as np; np.set_printoptions(linewidth=np.nan)
from mpi4py import MPI
import petsc4py; petsc4py.init(sys.argv)
from petsc4py import PETSc
import cProfile

stype = PETSc.DMDA.StencilType.BOX
ssize = 1

bx = PETSc.DMDA.BoundaryType.PERIODIC
by = PETSc.DMDA.BoundaryType.PERIODIC
bz = PETSc.DMDA.BoundaryType.PERIODIC

comm = PETSc.COMM_WORLD

OptDB = PETSc.Options()  # get PETSc option DB
m = OptDB.getInt('m', PETSc.DECIDE)
n = OptDB.getInt('n', PETSc.DECIDE)
p = OptDB.getInt('p', PETSc.DECIDE)

dm = PETSc.DMDA().create(dim=3, sizes=(6, 8, 5), proc_sizes=(m, n, p),
                         boundary_type=(bx, by, bz), stencil_type=stype,
                         stencil_width=ssize, dof=1, comm=comm,
                         setup=False)
dm.setFromOptions()
dm.setUp()

data = dm.createGlobalVector()


def initialise(dm, field):
Ejemplo n.º 14
0
import sys
import slepc4py
from scipy.sparse import csr_matrix
from scipy.spatial.distance import cosine
slepc4py.init(sys.argv)
import numpy as np
from petsc4py import PETSc
from slepc4py import SLEPc
import pickle

ascii_viewer = PETSc.Viewer().createBinary(sys.argv[-2], "r")
U = PETSc.Mat().load(ascii_viewer)

ascii_viewer = PETSc.Viewer().createBinary(sys.argv[-1], "r")
U_cpp = PETSc.Mat().load(ascii_viewer)

indptr, indices, data = U.getValuesCSR()
m1 = csr_matrix((data, indices, indptr)).todense()
indptr, indices, data = U_cpp.getValuesCSR()
m2 = csr_matrix((data, indices, indptr)).todense()

m, n = m1.shape
assert m1.shape == m2.shape
vectors1 = []
vectors2 = []
for i in range(n):
    c1i = [j for sub in m1[:, i].tolist() for j in sub]
    c2i = [j for sub in m2[:, i].tolist() for j in sub]
    vectors1.append(c1i)
    vectors2.append(c2i)
    #print(vectors1[-1])
Ejemplo n.º 15
0
 def setUp(self):
     self.idx = self._mk_idx(PETSc.COMM_WORLD)
     self.iset = PETSc.IS().createGeneral(self.idx, comm=PETSc.COMM_WORLD)
     self.lgmap = PETSc.LGMap().create(self.iset)
Ejemplo n.º 16
0
def solver_FE_MAT_PETSc(I, a, L, Nx, C, T):
    """
	This solver uses matrix to solve with a Forward Euler scheme,
	using u = A*u_1, that is just a simple matrix-vector product.
	"""

    x = np.linspace(0, L, Nx + 1)
    dx = x[1] - x[0]
    dt = C * dx**2 / a
    Nt = int(round(T / float(dt)))
    t = np.linspace(0, T, Nt + 1)
    t0 = time.clock()

    A = PETSc.Mat().createAIJ([Nx + 1, Nx + 1], nnz=3)
    [Istart, Iend] = A.getOwnershipRange()
    for i in range(Istart, Iend):  # filling the non-zero entires
        A.setValue(i, i, 1. - 2 * C)
        A.setValue(i - 1, i, C)
        A.setValue(i, i - 1, C)
    if Istart == 0:
        A.setValue(0, 0, 1)
        A.setValue(0, 1, 0)
    if Iend == Nx + 1:
        A.setValue(Nx, Nx, 1)
        A.setValue(Nx, Nx - 1, 0)

    # Get the left and right hand side vectors with properties
    # from the matrix T, e.g. type and sizes.
    u, u_1 = A.getVecs()

    # Initialize first time step from the numpy array I
    u_1.setValues(range(Istart, Iend), I[Istart:Iend])

    # Assemble the vectors and matrix. This partition each part
    # on its correct process/rank
    A.assemble()
    u.assemble()
    u_1.assemble()

    # This is for outputting to file, to be read from another program.
    # Is more difficult if in parallel.
    if PETSc.Options().getBool('toFile', default=False):
        if PETSc.COMM_WORLD.getSize() > 1:
            if PETSc.COMM_WORLD.getRank() == 0:
                print 'Warning: not writing to file (using parallel)'
        else:
            W = PETSc.Viewer().createASCII('test3.txt', format=1)
            u_1.view(W)

    for n in range(0, Nt):
        # Solve for next step. This should be done without
        # matrix multiplication (solving the system directly).
        A.mult(u_1, u)

        # Copy new solution to the old vector
        u, u_1 = u_1, u

        # Set boundary condition
        u_1.setValue(0, 0)
        u_1.setValue(Nx, 0)

        if PETSc.Options().getBool('toFile', default=False):
            u_1.view(W)

    return u_1, time.clock() - t0
Ejemplo n.º 17
0
def test_manufactured_poisson_dg(degree, filename, datadir):
    """ Manufactured Poisson problem, solving u = x[component]**n, where n is the
    degree of the Lagrange function space.

    """
    with XDMFFile(MPI.comm_world, os.path.join(datadir, filename)) as xdmf:
        if MPI.size(MPI.comm_world) == 1:  # Serial
            mesh = xdmf.read_mesh(GhostMode.none)
        else:
            mesh = xdmf.read_mesh(GhostMode.shared_facet)

    V = FunctionSpace(mesh, ("DG", degree))
    u, v = TrialFunction(V), TestFunction(V)

    # Exact solution
    x = SpatialCoordinate(mesh)
    u_exact = x[1] ** degree

    # Coefficient
    k = Function(V)
    k.vector.set(2.0)
    k.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD)

    # Source term
    f = - div(k * grad(u_exact))

    # Mesh normals and element size
    n = FacetNormal(mesh)
    h = CellDiameter(mesh)
    h_avg = (h("+") + h("-")) / 2.0

    # Penalty parameter
    alpha = 32

    dx_ = dx(metadata={"quadrature_degree": -1})
    ds_ = ds(metadata={"quadrature_degree": -1})
    dS_ = dS(metadata={"quadrature_degree": -1})

    a = inner(k * grad(u), grad(v)) * dx_ \
        - k("+") * inner(avg(grad(u)), jump(v, n)) * dS_ \
        - k("+") * inner(jump(u, n), avg(grad(v))) * dS_ \
        + k("+") * (alpha / h_avg) * inner(jump(u, n), jump(v, n)) * dS_ \
        - inner(k * grad(u), v * n) * ds_ \
        - inner(u * n, k * grad(v)) * ds_ \
        + (alpha / h) * inner(k * u, v) * ds_
    L = inner(f, v) * dx_ - inner(k * u_exact * n, grad(v)) * ds_ \
        + (alpha / h) * inner(k * u_exact, v) * ds_

    for integral in a.integrals():
        integral.metadata()["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(a)
    for integral in L.integrals():
        integral.metadata()["quadrature_degree"] = ufl.algorithms.estimate_total_polynomial_degree(L)

    b = assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    A = assemble_matrix(a, [])
    A.assemble()

    # Create LU linear solver
    solver = PETSc.KSP().create(MPI.comm_world)
    solver.setType(PETSc.KSP.Type.PREONLY)
    solver.getPC().setType(PETSc.PC.Type.LU)
    solver.setOperators(A)

    # Solve
    uh = Function(V)
    solver.solve(b, uh.vector)
    uh.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                          mode=PETSc.ScatterMode.FORWARD)

    error = assemble_scalar((u_exact - uh)**2 * dx)
    error = MPI.sum(mesh.mpi_comm(), error)

    assert np.absolute(error) < 1.0e-14
Ejemplo n.º 18
0
def Stokes(V, Q, F, u0, pN, params, mesh):
    parameters['reorder_dofs_serial'] = False

    W = FunctionSpace(mesh, MixedElement([V, Q]))

    IS = MO.IndexSet(W)

    (u, p) = TrialFunctions(W)
    (v, q) = TestFunctions(W)
    n = FacetNormal(mesh)

    # dx = Measure('dx', domain=mesh, subdomain_data=domains)
    # ds = Measure('ds', domain=mesh, subdomain_data=boundaries)

    a11 = params[2]*inner(grad(v), grad(u))*dx
    a12 = -div(v)*p*dx
    a21 = -div(u)*q*dx
    a = a11+a12+a21

    L = inner(v, F)*dx  # - inner(pN*n,v)*ds(2)

    pp = params[2]*inner(grad(v), grad(u))*dx + (1./params[2])*p*q*dx
    def boundary(x, on_boundary):
        return on_boundary
    # bcu = DirichletBC(W.sub(0), u0, boundaries, 1)
    bcu = DirichletBC(W.sub(0), u0, boundary)
    # bcu = [bcu1, bcu2]
    A, b = assemble_system(a, L, bcu)
    A, b = CP.Assemble(A, b)
    C = A.getSubMatrix(IS[1], IS[1])
    u = b.duplicate()
    P, Pb = assemble_system(pp, L, bcu)
    P, Pb = CP.Assemble(P, Pb)

    ksp = PETSc.KSP()
    ksp.create(comm=PETSc.COMM_WORLD)
    pc = ksp.getPC()
    ksp.setType('preonly')
    pc.setType('lu')
    OptDB = PETSc.Options()
    # if __version__ != '1.6.0':
    OptDB['pc_factor_mat_solver_package']  = "pastix"
    OptDB['pc_factor_mat_ordering_type']  = "rcm"
    ksp.setFromOptions()
    ksp.setOperators(A,A)

    # ksp = PETSc.KSP().create()
    # ksp.setTolerances(1e-8)
    # ksp.max_it = 200
    # pc = ksp.getPC()
    # pc.setType(PETSc.PC.Type.PYTHON)
    # ksp.setType('minres')
    # pc.setPythonContext(StokesPrecond.Approx(W, 1))
    # ksp.setOperators(A, P)

    scale = b.norm()
    b = b/scale
    del A
    start_time = time.time()
    ksp.solve(b, u)
    # Mits +=dodim
    u = u*scale
    print("{:40}").format("Stokes solve, time: "), " ==>  ", ("{:4f}").format(time.time() - start_time), ("{:9}").format(
        "   Its: "), ("{:4}").format(ksp.its),  ("{:9}").format("   time: "), ("{:4}").format(time.strftime('%X %x %Z')[0:5])
    u_k = Function(FunctionSpace(mesh, V))
    p_k = Function(FunctionSpace(mesh, Q))
    u_k.vector()[:] = u.getSubVector(IS[0]).array
    p_k.vector()[:] = u.getSubVector(IS[1]).array
    ones = Function(FunctionSpace(mesh, Q))
    ones.vector()[:] = (0*ones.vector().array()+1)
    p_k.vector()[:] += -assemble(p_k*dx)/assemble(ones*dx)
    return u_k, p_k
Ejemplo n.º 19
0
def test_assembly_solve_block():
    """Solve a two-field nonlinear diffusion like problem with block matrix
    approaches and test that solution is the same.
    """
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 12, 11)
    p = 1
    P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), p)
    V0 = dolfinx.function.FunctionSpace(mesh, P)
    V1 = V0.clone()

    def bc_val_0(x):
        return x[0]**2 + x[1]**2

    def bc_val_1(x):
        return numpy.sin(x[0]) * numpy.cos(x[1])

    def initial_guess_u(x):
        return numpy.sin(x[0]) * numpy.sin(x[1])

    def initial_guess_p(x):
        return -x[0]**2 - x[1]**3

    def boundary(x):
        return numpy.logical_or(x[0] < 1.0e-6, x[0] > 1.0 - 1.0e-6)

    facetdim = mesh.topology.dim - 1
    bndry_facets = locate_entities_boundary(mesh, facetdim, boundary)

    u_bc0 = dolfinx.function.Function(V0)
    u_bc0.interpolate(bc_val_0)
    u_bc1 = dolfinx.function.Function(V1)
    u_bc1.interpolate(bc_val_1)

    bdofs0 = dolfinx.fem.locate_dofs_topological(V0, facetdim, bndry_facets)
    bdofs1 = dolfinx.fem.locate_dofs_topological(V1, facetdim, bndry_facets)

    bcs = [
        dolfinx.fem.dirichletbc.DirichletBC(u_bc0, bdofs0),
        dolfinx.fem.dirichletbc.DirichletBC(u_bc1, bdofs1)
    ]

    # Block and Nest variational problem
    u, p = dolfinx.function.Function(V0), dolfinx.function.Function(V1)
    du, dp = ufl.TrialFunction(V0), ufl.TrialFunction(V1)
    v, q = ufl.TestFunction(V0), ufl.TestFunction(V1)

    f = 1.0
    g = -3.0

    F = [
        inner((u**2 + 1) * ufl.grad(u), ufl.grad(v)) * dx - inner(f, v) * dx,
        inner((p**2 + 1) * ufl.grad(p), ufl.grad(q)) * dx - inner(g, q) * dx
    ]

    J = [[derivative(F[0], u, du),
          derivative(F[0], p, dp)],
         [derivative(F[1], u, du),
          derivative(F[1], p, dp)]]

    # -- Blocked version
    Jmat0 = dolfinx.fem.create_matrix_block(J)
    Fvec0 = dolfinx.fem.create_vector_block(F)

    snes = PETSc.SNES().create(MPI.COMM_WORLD)
    snes.setTolerances(rtol=1.0e-15, max_it=10)

    snes.getKSP().setType("preonly")
    snes.getKSP().getPC().setType("lu")
    snes.getKSP().getPC().setFactorSolverType("superlu_dist")

    problem = NonlinearPDE_SNESProblem(F, J, [u, p], bcs)
    snes.setFunction(problem.F_block, Fvec0)
    snes.setJacobian(problem.J_block, J=Jmat0, P=None)

    u.interpolate(initial_guess_u)
    p.interpolate(initial_guess_p)

    x0 = dolfinx.fem.create_vector_block(F)
    dolfinx.cpp.la.scatter_local_vectors(
        x0, [u.vector.array_r, p.vector.array_r],
        [u.function_space.dofmap.index_map, p.function_space.dofmap.index_map])
    x0.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                   mode=PETSc.ScatterMode.FORWARD)

    snes.solve(None, x0)

    assert snes.getKSP().getConvergedReason() > 0
    assert snes.getConvergedReason() > 0

    J0norm = Jmat0.norm()
    F0norm = Fvec0.norm()
    x0norm = x0.norm()

    # -- Nested (MatNest)
    Jmat1 = dolfinx.fem.create_matrix_nest(J)
    Fvec1 = dolfinx.fem.create_vector_nest(F)

    snes = PETSc.SNES().create(MPI.COMM_WORLD)
    snes.setTolerances(rtol=1.0e-15, max_it=10)

    nested_IS = Jmat1.getNestISs()

    snes.getKSP().setType("fgmres")
    snes.getKSP().setTolerances(rtol=1e-12)
    snes.getKSP().getPC().setType("fieldsplit")
    snes.getKSP().getPC().setFieldSplitIS(["u", nested_IS[0][0]],
                                          ["p", nested_IS[1][1]])

    ksp_u, ksp_p = snes.getKSP().getPC().getFieldSplitSubKSP()
    ksp_u.setType("preonly")
    ksp_u.getPC().setType('lu')
    ksp_u.getPC().setFactorSolverType('superlu_dist')
    ksp_p.setType("preonly")
    ksp_p.getPC().setType('lu')
    ksp_p.getPC().setFactorSolverType('superlu_dist')

    problem = NonlinearPDE_SNESProblem(F, J, [u, p], bcs)
    snes.setFunction(problem.F_nest, Fvec1)
    snes.setJacobian(problem.J_nest, J=Jmat1, P=None)

    u.interpolate(initial_guess_u)
    p.interpolate(initial_guess_p)

    x1 = dolfinx.fem.create_vector_nest(F)
    for x1_soln_pair in zip(x1.getNestSubVecs(), (u, p)):
        x1_sub, soln_sub = x1_soln_pair
        soln_sub.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                    mode=PETSc.ScatterMode.FORWARD)
        soln_sub.vector.copy(result=x1_sub)
        x1_sub.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                           mode=PETSc.ScatterMode.FORWARD)

    snes.solve(None, x1)

    assert snes.getKSP().getConvergedReason() > 0
    assert snes.getConvergedReason() > 0
    assert x1.getType() == "nest"
    assert Jmat1.getType() == "nest"
    assert Fvec1.getType() == "nest"

    J1norm = nest_matrix_norm(Jmat1)
    F1norm = Fvec1.norm()
    x1norm = x1.norm()

    assert J1norm == pytest.approx(J0norm, 1.0e-12)
    assert F1norm == pytest.approx(F0norm, 1.0e-12)
    assert x1norm == pytest.approx(x0norm, 1.0e-12)

    # -- Monolithic version
    E = P * P
    W = dolfinx.function.FunctionSpace(mesh, E)
    U = dolfinx.function.Function(W)
    dU = ufl.TrialFunction(W)
    u0, u1 = ufl.split(U)
    v0, v1 = ufl.TestFunctions(W)

    F = inner((u0**2 + 1) * ufl.grad(u0), ufl.grad(v0)) * dx \
        + inner((u1**2 + 1) * ufl.grad(u1), ufl.grad(v1)) * dx \
        - inner(f, v0) * ufl.dx - inner(g, v1) * dx
    J = derivative(F, U, dU)

    u0_bc = dolfinx.function.Function(V0)
    u0_bc.interpolate(bc_val_0)
    u1_bc = dolfinx.function.Function(V1)
    u1_bc.interpolate(bc_val_1)

    bdofsW0_V0 = dolfinx.fem.locate_dofs_topological((W.sub(0), V0), facetdim,
                                                     bndry_facets)
    bdofsW1_V1 = dolfinx.fem.locate_dofs_topological((W.sub(1), V1), facetdim,
                                                     bndry_facets)

    bcs = [
        dolfinx.fem.dirichletbc.DirichletBC(u0_bc, bdofsW0_V0, W.sub(0)),
        dolfinx.fem.dirichletbc.DirichletBC(u1_bc, bdofsW1_V1, W.sub(1))
    ]

    Jmat2 = dolfinx.fem.create_matrix(J)
    Fvec2 = dolfinx.fem.create_vector(F)

    snes = PETSc.SNES().create(MPI.COMM_WORLD)
    snes.setTolerances(rtol=1.0e-15, max_it=10)

    snes.getKSP().setType("preonly")
    snes.getKSP().getPC().setType("lu")
    snes.getKSP().getPC().setFactorSolverType("superlu_dist")

    problem = NonlinearPDE_SNESProblem(F, J, U, bcs)
    snes.setFunction(problem.F_mono, Fvec2)
    snes.setJacobian(problem.J_mono, J=Jmat2, P=None)

    U.interpolate(lambda x: numpy.row_stack(
        (initial_guess_u(x), initial_guess_p(x))))

    x2 = dolfinx.fem.create_vector(F)
    x2.array = U.vector.array_r

    snes.solve(None, x2)

    assert snes.getKSP().getConvergedReason() > 0
    assert snes.getConvergedReason() > 0

    J2norm = Jmat2.norm()
    F2norm = Fvec2.norm()
    x2norm = x2.norm()

    assert J2norm == pytest.approx(J0norm, 1.0e-12)
    assert F2norm == pytest.approx(F0norm, 1.0e-12)
    assert x2norm == pytest.approx(x0norm, 1.0e-12)
Ejemplo n.º 20
0
                         body_force=solid_body_force)

    sol_real = Function(struct.get_function_space())
    sol_imag = Function(struct.get_function_space())

    # get solution vectors
    #filenames = []
    #for f in os.listdir(solution_dir):
    #    if f.endswith('.dat'):
    #        filenames.append(f)

    #filenames = sorted(filenames)

    pp = Point(solution_point[0], solution_point[1], solution_point[2])
    point_file = open(output_file, 'w')
    u_binary = PETSc.Vec()
    u_binary.create(PETSc.COMM_WORLD)

    create_dir(output_dir)

    real_file = File(output_dir + 'solution_real.pvd')
    imag_file = File(output_dir + 'solution_imag.pvd')

    #for i, f in enumerate(filenames):
    for i in range(solution_n):
        #print('Reading {}...'.format(f))
        #viewer = PETSc.Viewer().createBinary(solution_dir+f,'r')
        print('Reading solution {}...'.format(i))
        viewer = PETSc.Viewer().createBinary(
            solution_dir + solution_prefix + '{}.dat'.format(i), 'r')
        u_binary.load(viewer)
Ejemplo n.º 21
0
def test_assembly_solve_taylor_hood(mesh):
    """Assemble Stokes problem with Taylor-Hood elements and solve."""
    gdim = mesh.geometry.dim
    P2 = dolfinx.function.VectorFunctionSpace(mesh, ("Lagrange", 2))
    P1 = dolfinx.function.FunctionSpace(mesh, ("Lagrange", 1))

    def boundary0(x):
        """Define boundary x = 0"""
        return x[0] < 10 * numpy.finfo(float).eps

    def boundary1(x):
        """Define boundary x = 1"""
        return x[0] > (1.0 - 10 * numpy.finfo(float).eps)

    def initial_guess_u(x):
        u_init = numpy.row_stack((numpy.sin(x[0]) * numpy.sin(x[1]),
                                  numpy.cos(x[0]) * numpy.cos(x[1])))
        if gdim == 3:
            u_init = numpy.row_stack((u_init, numpy.cos(x[2])))
        return u_init

    def initial_guess_p(x):
        return -x[0]**2 - x[1]**3

    u_bc_0 = dolfinx.Function(P2)
    u_bc_0.interpolate(
        lambda x: numpy.row_stack(tuple(x[j] + float(j) for j in range(gdim))))

    u_bc_1 = dolfinx.Function(P2)
    u_bc_1.interpolate(
        lambda x: numpy.row_stack(tuple(numpy.sin(x[j]) for j in range(gdim))))

    facetdim = mesh.topology.dim - 1
    bndry_facets0 = locate_entities_boundary(mesh, facetdim, boundary0)
    bndry_facets1 = locate_entities_boundary(mesh, facetdim, boundary1)

    bdofs0 = dolfinx.fem.locate_dofs_topological(P2, facetdim, bndry_facets0)
    bdofs1 = dolfinx.fem.locate_dofs_topological(P2, facetdim, bndry_facets1)

    bcs = [
        dolfinx.DirichletBC(u_bc_0, bdofs0),
        dolfinx.DirichletBC(u_bc_1, bdofs1)
    ]

    u, p = dolfinx.Function(P2), dolfinx.Function(P1)
    du, dp = ufl.TrialFunction(P2), ufl.TrialFunction(P1)
    v, q = ufl.TestFunction(P2), ufl.TestFunction(P1)

    F = [
        inner(ufl.grad(u), ufl.grad(v)) * dx + inner(p, ufl.div(v)) * dx,
        inner(ufl.div(u), q) * dx
    ]
    J = [[derivative(F[0], u, du),
          derivative(F[0], p, dp)],
         [derivative(F[1], u, du),
          derivative(F[1], p, dp)]]
    P = [[J[0][0], None], [None, inner(dp, q) * dx]]

    # -- Blocked and monolithic

    Jmat0 = dolfinx.fem.create_matrix_block(J)
    Pmat0 = dolfinx.fem.create_matrix_block(P)
    Fvec0 = dolfinx.fem.create_vector_block(F)

    snes = PETSc.SNES().create(MPI.COMM_WORLD)
    snes.setTolerances(rtol=1.0e-15, max_it=10)

    snes.getKSP().setType("minres")
    snes.getKSP().getPC().setType("lu")
    snes.getKSP().getPC().setFactorSolverType("superlu_dist")

    problem = NonlinearPDE_SNESProblem(F, J, [u, p], bcs, P=P)
    snes.setFunction(problem.F_block, Fvec0)
    snes.setJacobian(problem.J_block, J=Jmat0, P=Pmat0)

    u.interpolate(initial_guess_u)
    p.interpolate(initial_guess_p)

    x0 = dolfinx.fem.create_vector_block(F)
    with u.vector.localForm() as _u, p.vector.localForm() as _p:
        dolfinx.cpp.la.scatter_local_vectors(x0, [_u.array_r, _p.array_r], [
            u.function_space.dofmap.index_map,
            p.function_space.dofmap.index_map
        ])
    x0.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                   mode=PETSc.ScatterMode.FORWARD)

    snes.solve(None, x0)

    assert snes.getConvergedReason() > 0

    # -- Blocked and nested

    Jmat1 = dolfinx.fem.create_matrix_nest(J)
    Pmat1 = dolfinx.fem.create_matrix_nest(P)
    Fvec1 = dolfinx.fem.create_vector_nest(F)

    snes = PETSc.SNES().create(MPI.COMM_WORLD)
    snes.setTolerances(rtol=1.0e-15, max_it=10)

    nested_IS = Jmat1.getNestISs()

    snes.getKSP().setType("minres")
    snes.getKSP().setTolerances(rtol=1e-12)
    snes.getKSP().getPC().setType("fieldsplit")
    snes.getKSP().getPC().setFieldSplitIS(["u", nested_IS[0][0]],
                                          ["p", nested_IS[1][1]])

    ksp_u, ksp_p = snes.getKSP().getPC().getFieldSplitSubKSP()
    ksp_u.setType("preonly")
    ksp_u.getPC().setType('lu')
    ksp_u.getPC().setFactorSolverType('superlu_dist')
    ksp_p.setType("preonly")
    ksp_p.getPC().setType('lu')
    ksp_p.getPC().setFactorSolverType('superlu_dist')

    problem = NonlinearPDE_SNESProblem(F, J, [u, p], bcs, P=P)
    snes.setFunction(problem.F_nest, Fvec1)
    snes.setJacobian(problem.J_nest, J=Jmat1, P=Pmat1)

    u.interpolate(initial_guess_u)
    p.interpolate(initial_guess_p)

    x1 = dolfinx.fem.create_vector_nest(F)
    for x1_soln_pair in zip(x1.getNestSubVecs(), (u, p)):
        x1_sub, soln_sub = x1_soln_pair
        soln_sub.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                                    mode=PETSc.ScatterMode.FORWARD)
        soln_sub.vector.copy(result=x1_sub)
        x1_sub.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                           mode=PETSc.ScatterMode.FORWARD)

    x1.set(0.0)
    snes.solve(None, x1)

    assert snes.getConvergedReason() > 0
    assert nest_matrix_norm(Jmat1) == pytest.approx(Jmat0.norm(), 1.0e-12)
    assert Fvec1.norm() == pytest.approx(Fvec0.norm(), 1.0e-12)
    assert x1.norm() == pytest.approx(x0.norm(), 1.0e-12)

    # -- Monolithic

    P2_el = ufl.VectorElement("Lagrange", mesh.ufl_cell(), 2)
    P1_el = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 1)
    TH = P2_el * P1_el
    W = dolfinx.FunctionSpace(mesh, TH)
    U = dolfinx.Function(W)
    dU = ufl.TrialFunction(W)
    u, p = ufl.split(U)
    du, dp = ufl.split(dU)
    v, q = ufl.TestFunctions(W)

    F = inner(ufl.grad(u), ufl.grad(v)) * dx + inner(p, ufl.div(v)) * dx \
        + inner(ufl.div(u), q) * dx
    J = derivative(F, U, dU)
    P = inner(ufl.grad(du), ufl.grad(v)) * dx + inner(dp, q) * dx

    bdofsW0_P2_0 = dolfinx.fem.locate_dofs_topological((W.sub(0), P2),
                                                       facetdim, bndry_facets0)
    bdofsW0_P2_1 = dolfinx.fem.locate_dofs_topological((W.sub(0), P2),
                                                       facetdim, bndry_facets1)

    bcs = [
        dolfinx.DirichletBC(u_bc_0, bdofsW0_P2_0, W.sub(0)),
        dolfinx.DirichletBC(u_bc_1, bdofsW0_P2_1, W.sub(0))
    ]

    Jmat2 = dolfinx.fem.create_matrix(J)
    Pmat2 = dolfinx.fem.create_matrix(P)
    Fvec2 = dolfinx.fem.create_vector(F)

    snes = PETSc.SNES().create(MPI.COMM_WORLD)
    snes.setTolerances(rtol=1.0e-15, max_it=10)

    snes.getKSP().setType("minres")
    snes.getKSP().getPC().setType("lu")
    snes.getKSP().getPC().setFactorSolverType("superlu_dist")

    problem = NonlinearPDE_SNESProblem(F, J, U, bcs, P=P)
    snes.setFunction(problem.F_mono, Fvec2)
    snes.setJacobian(problem.J_mono, J=Jmat2, P=Pmat2)

    U.interpolate(lambda x: numpy.row_stack(
        (initial_guess_u(x), initial_guess_p(x))))

    x2 = dolfinx.fem.create_vector(F)
    x2.array = U.vector.array_r

    snes.solve(None, x2)

    assert snes.getConvergedReason() > 0
    assert Jmat2.norm() == pytest.approx(Jmat0.norm(), 1.0e-12)
    assert Fvec2.norm() == pytest.approx(Fvec0.norm(), 1.0e-12)
    assert x2.norm() == pytest.approx(x0.norm(), 1.0e-12)
Ejemplo n.º 22
0
    def __init__(self, cfgfile):
        '''
        Constructor
        '''

        #        stencil = 1
        stencil = 2

        # load run config file
        cfg = Config(cfgfile)

        # set some PETSc options
        OptDB = PETSc.Options()

        #        OptDB.setValue('snes_lag_preconditioner', 5)

        OptDB.setValue('snes_atol', cfg['solver']['petsc_residual'])
        OptDB.setValue('snes_rtol', 1E-16)
        OptDB.setValue('snes_stol', 1E-18)
        OptDB.setValue('snes_max_it', 20)

        OptDB.setValue('ksp_rtol', cfg['solver']['petsc_residual'])
        OptDB.setValue('ksp_max_it', 100)

        OptDB.setValue('snes_monitor', '')
        OptDB.setValue('ksp_monitor', '')

        # timestep setup
        self.ht = cfg['grid']['ht']  # timestep size
        self.nt = cfg['grid']['nt']  # number of timesteps
        self.nsave = cfg['io']['nsave']  # save only every nsave'th timestep

        # grid setup
        nx = cfg['grid']['nx']  # number of points in x
        ny = cfg['grid']['ny']  # number of points in y
        Lx = cfg['grid']['Lx']  # spatial domain in x
        x1 = cfg['grid']['x1']  #
        x2 = cfg['grid']['x2']  #

        Ly = cfg['grid']['Ly']  # spatial domain in y
        y1 = cfg['grid']['y1']  #
        y2 = cfg['grid']['y2']  #

        self.nx = nx
        self.ny = ny

        if x1 != x2:
            Lx = x2 - x1
        else:
            x1 = 0.0
            x2 = Lx

        if y1 != y2:
            Ly = y2 - y1
        else:
            y1 = 0.0
            y2 = Ly

        self.hx = Lx / nx  # gridstep size in x
        self.hy = Ly / ny  # gridstep size in y

        # friction, viscosity and resistivity
        mu = cfg['initial_data']['mu']  # friction
        nu = cfg['initial_data']['nu']  # viscosity
        eta = cfg['initial_data']['eta']  # resistivity

        if PETSc.COMM_WORLD.getRank() == 0:
            print()
            print("nt = %i" % (self.nt))
            print("nx = %i" % (self.nx))
            print("ny = %i" % (self.ny))
            print()
            print("ht = %e" % (self.ht))
            print("hx = %e" % (self.hx))
            print("hy = %e" % (self.hy))
            print()
            print("Lx   = %e" % (Lx))
            print("Ly   = %e" % (Ly))
            print()
            print("mu   = %e" % (mu))
            print("nu   = %e" % (nu))
            print("eta  = %e" % (eta))
            print()

        self.time = PETSc.Vec().createMPI(1,
                                          PETSc.DECIDE,
                                          comm=PETSc.COMM_WORLD)
        self.time.setName('t')

        if PETSc.COMM_WORLD.getRank() == 0:
            self.time.setValue(0, 0.0)

        # create DA with single dof
        self.da1 = PETSc.DA().create(dim=2,
                                     dof=1,
                                     sizes=[nx, ny],
                                     proc_sizes=[PETSc.DECIDE, PETSc.DECIDE],
                                     boundary_type=('periodic', 'periodic'),
                                     stencil_width=stencil,
                                     stencil_type='box')

        # create DA (dof = 4 for Bx, By, Vx, Vy)
        self.da4 = PETSc.DA().create(dim=2,
                                     dof=4,
                                     sizes=[nx, ny],
                                     proc_sizes=[PETSc.DECIDE, PETSc.DECIDE],
                                     boundary_type=('periodic', 'periodic'),
                                     stencil_width=stencil,
                                     stencil_type='box')

        # create DA (dof = 5 for Bx, By, Vx, Vy, P)
        self.da5 = PETSc.DA().create(dim=2,
                                     dof=5,
                                     sizes=[nx, ny],
                                     proc_sizes=[PETSc.DECIDE, PETSc.DECIDE],
                                     boundary_type=('periodic', 'periodic'),
                                     stencil_width=stencil,
                                     stencil_type='box')

        # create DA for x grid
        self.dax = PETSc.DA().create(dim=1,
                                     dof=1,
                                     sizes=[nx],
                                     proc_sizes=[PETSc.DECIDE],
                                     boundary_type=('periodic'))

        # create DA for y grid
        self.day = PETSc.DA().create(dim=1,
                                     dof=1,
                                     sizes=[ny],
                                     proc_sizes=[PETSc.DECIDE],
                                     boundary_type=('periodic'))

        # initialise grid
        self.da1.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2)

        self.da4.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2)

        self.da5.setUniformCoordinates(xmin=x1, xmax=x2, ymin=y1, ymax=y2)

        self.dax.setUniformCoordinates(xmin=x1, xmax=x2)

        self.day.setUniformCoordinates(xmin=y1, xmax=y2)

        # create solution and RHS vector
        self.f = self.da5.createGlobalVec()
        self.x = self.da5.createGlobalVec()
        self.b = self.da5.createGlobalVec()

        # create global RK4 vectors
        self.Y = self.da5.createGlobalVec()
        self.X0 = self.da5.createGlobalVec()
        self.X1 = self.da5.createGlobalVec()
        self.X2 = self.da5.createGlobalVec()
        self.X3 = self.da5.createGlobalVec()
        self.X4 = self.da5.createGlobalVec()

        # create local RK4 vectors
        self.localX0 = self.da5.createLocalVec()
        self.localX1 = self.da5.createLocalVec()
        self.localX2 = self.da5.createLocalVec()
        self.localX3 = self.da5.createLocalVec()
        self.localX4 = self.da5.createLocalVec()
        #        self.localP  = self.da1.createLocalVec()

        # create vectors for magnetic and velocity field
        self.Bx = self.da1.createGlobalVec()
        self.By = self.da1.createGlobalVec()
        self.Vx = self.da1.createGlobalVec()
        self.Vy = self.da1.createGlobalVec()
        self.P = self.da1.createGlobalVec()

        self.xcoords = self.da1.createGlobalVec()
        self.ycoords = self.da1.createGlobalVec()

        # create local vectors for initialisation of pressure
        self.localBx = self.da1.createLocalVec()
        self.localBy = self.da1.createLocalVec()
        self.localVx = self.da1.createLocalVec()
        self.localVy = self.da1.createLocalVec()

        # set variable names
        self.Bx.setName('Bx')
        self.By.setName('By')
        self.Vx.setName('Vx')
        self.Vy.setName('Vy')
        self.P.setName('P')

        # create Matrix object
        self.petsc_matrix = PETScMatrix(self.da1, self.da5, nx, ny, self.ht,
                                        self.hx, self.hy, mu, nu, eta)
        self.petsc_jacobian = PETScJacobian(self.da1, self.da5, nx, ny,
                                            self.ht, self.hx, self.hy, mu, nu,
                                            eta)
        self.petsc_function = PETScFunction(self.da1, self.da5, nx, ny,
                                            self.ht, self.hx, self.hy, mu, nu,
                                            eta)

        #        self.petsc_jacobian_4d = PETSc_MHD_NL_Jacobian_Matrix.PETScJacobian(self.da1, self.da5, nx, ny, self.ht, self.hx, self.hy)

        # initialise matrix
        self.A = self.da5.createMat()
        self.A.setOption(self.A.Option.NEW_NONZERO_ALLOCATION_ERR, False)
        self.A.setUp()

        # create jacobian
        self.J = self.da5.createMat()
        self.J.setOption(self.J.Option.NEW_NONZERO_ALLOCATION_ERR, False)
        self.J.setUp()

        # create nonlinear solver
        self.snes = PETSc.SNES().create()
        self.snes.setFunction(self.petsc_function.snes_mult, self.f)
        self.snes.setJacobian(self.updateJacobian, self.J)
        self.snes.setFromOptions()
        self.snes.getKSP().setType('preonly')
        #        self.snes.getKSP().setType('gmres')
        self.snes.getKSP().getPC().setType('lu')
        #        self.snes.getKSP().getPC().setFactorSolverPackage('superlu_dist')
        self.snes.getKSP().getPC().setFactorSolverPackage('mumps')

        self.ksp = None

        # set initial data
        (xs, xe), (ys, ye) = self.da1.getRanges()

        #        coords = self.da1.getCoordinatesLocal()

        xc_arr = self.da1.getVecArray(self.xcoords)
        yc_arr = self.da1.getVecArray(self.ycoords)

        for i in range(xs, xe):
            for j in range(ys, ye):
                xc_arr[i, j] = x1 + i * self.hx
                yc_arr[i, j] = y1 + j * self.hy

        Bx_arr = self.da1.getVecArray(self.Bx)
        By_arr = self.da1.getVecArray(self.By)
        Vx_arr = self.da1.getVecArray(self.Vx)
        Vy_arr = self.da1.getVecArray(self.Vy)

        xc_arr = self.da1.getVecArray(self.xcoords)
        yc_arr = self.da1.getVecArray(self.ycoords)

        if cfg['initial_data']['magnetic_python'] != None:
            init_data = __import__(
                "runs." + cfg['initial_data']['magnetic_python'], globals(),
                locals(), ['magnetic_x', 'magnetic_y'], 0)

            for i in range(xs, xe):
                for j in range(ys, ye):
                    Bx_arr[i, j] = init_data.magnetic_x(
                        xc_arr[i, j], yc_arr[i, j] + 0.5 * self.hy, Lx, Ly)
                    By_arr[i, j] = init_data.magnetic_y(
                        xc_arr[i, j] + 0.5 * self.hx, yc_arr[i, j], Lx, Ly)

        else:
            Bx_arr[xs:xe, ys:ye] = cfg['initial_data']['magnetic']
            By_arr[xs:xe, ys:ye] = cfg['initial_data']['magnetic']

        if cfg['initial_data']['velocity_python'] != None:
            init_data = __import__(
                "runs." + cfg['initial_data']['velocity_python'], globals(),
                locals(), ['velocity_x', 'velocity_y'], 0)

            for i in range(xs, xe):
                for j in range(ys, ye):
                    Vx_arr[i, j] = init_data.velocity_x(
                        xc_arr[i, j], yc_arr[i, j] + 0.5 * self.hy, Lx, Ly)
                    Vy_arr[i, j] = init_data.velocity_y(
                        xc_arr[i, j] + 0.5 * self.hx, yc_arr[i, j], Lx, Ly)

        else:
            Vx_arr[xs:xe, ys:ye] = cfg['initial_data']['velocity']
            Vy_arr[xs:xe, ys:ye] = cfg['initial_data']['velocity']

        if cfg['initial_data']['pressure_python'] != None:
            init_data = __import__(
                "runs." + cfg['initial_data']['pressure_python'], globals(),
                locals(), ['pressure', ''], 0)

        x_arr = self.da5.getVecArray(self.x)
        x_arr[xs:xe, ys:ye, 0] = Vx_arr[xs:xe, ys:ye]
        x_arr[xs:xe, ys:ye, 1] = Vy_arr[xs:xe, ys:ye]
        x_arr[xs:xe, ys:ye, 2] = Bx_arr[xs:xe, ys:ye]
        x_arr[xs:xe, ys:ye, 3] = By_arr[xs:xe, ys:ye]

        self.da1.globalToLocal(self.Bx, self.localBx)
        self.da1.globalToLocal(self.By, self.localBy)
        self.da1.globalToLocal(self.Vx, self.localVx)
        self.da1.globalToLocal(self.Vy, self.localVy)

        Bx_arr = self.da1.getVecArray(self.localBx)
        By_arr = self.da1.getVecArray(self.localBy)
        Vx_arr = self.da1.getVecArray(self.localVx)
        Vy_arr = self.da1.getVecArray(self.localVy)
        P_arr = self.da1.getVecArray(self.P)

        for i in range(xs, xe):
            for j in range(ys, ye):
                P_arr[i, j] = init_data.pressure(xc_arr[i, j] + 0.5 * self.hx,
                                                 yc_arr[i, j] + 0.5 * self.hy,
                                                 Lx, Ly)


#                P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) \
#                           + 0.5 * (0.25 * (Bx_arr[i,j] + Bx_arr[i+1,j])**2 + 0.25 * (By_arr[i,j] + By_arr[i,j+1])**2)
#                P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) \
#                           + 0.5 * (0.25 * (Vx_arr[i,j] + Vx_arr[i+1,j])**2 + 0.25 * (Vy_arr[i,j] + Vy_arr[i,j+1])**2)
#                P_arr[i,j] = init_data.pressure(coords[i,j][0] + 0.5 * self.hx, coords[i,j][1] + 0.5 * self.hy, Lx, Ly) \
#                           + 0.5 * (0.25 * (Vx_arr[i,j] + Vx_arr[i+1,j])**2 + 0.25 * (Vy_arr[i,j] + Vy_arr[i,j+1])**2) \
#                           - 1.0 * (0.25 * (Bx_arr[i,j] + Bx_arr[i+1,j])**2 + 0.25 * (By_arr[i,j] + By_arr[i,j+1])**2)

# copy distribution function to solution vector
        x_arr = self.da5.getVecArray(self.x)
        x_arr[xs:xe, ys:ye, 4] = P_arr[xs:xe, ys:ye]

        # update solution history
        self.petsc_matrix.update_history(self.x)
        self.petsc_jacobian.update_history(self.x)
        self.petsc_function.update_history(self.x)

        # create HDF5 output file
        self.hdf5_viewer = PETSc.ViewerHDF5().create(
            cfg['io']['hdf5_output'],
            mode=PETSc.Viewer.Mode.WRITE,
            comm=PETSc.COMM_WORLD)

        self.hdf5_viewer.pushGroup("/")

        # write grid data to hdf5 file
        coords_x = self.dax.getCoordinates()
        coords_y = self.day.getCoordinates()

        coords_x.setName('x')
        coords_y.setName('y')

        self.hdf5_viewer(coords_x)
        self.hdf5_viewer(coords_y)

        # write initial data to hdf5 file
        self.hdf5_viewer.setTimestep(0)
        self.save_hdf5_vectors()
Ejemplo n.º 23
0
        finally:
            fh.close()


import petsc4py, sys

petsc4py.init(sys.argv)

from petsc4py import PETSc

execfile('petsc-mat.py')
execfile('petsc-cg.py')

x, b = A.getVecs()

ksp = PETSc.KSP().create()
ksp.setType('cg')
ksp.getPC().setType('none')
ksp.setOperators(A)
ksp.setFromOptions()

ksp.max_it = 100
ksp.rtol = 1e-5
ksp.atol = 0
x.set(0)
b.set(1)
ksp.solve(b, x)
print("iterations: %d residual norm: %g" % (ksp.its, ksp.norm))

x.set(0)
b.set(1)
Ejemplo n.º 24
0
                fa[i] = self.lambda0**2 * x[i] * (1 - x[i]**self.nu)

    def evalSolution(self, t, x):
        lam1 = self.lambda0 / 2.0 * ((self.nu / 2.0 + 1)**0.5 +
                                     (self.nu / 2.0 + 1)**(-0.5))
        sig1 = lam1 - np.sqrt(lam1**2 - self.lambda0**2)
        xa = self.da.getVecArray(x)
        for i in range(self.xs, self.xe):
            xa[i] = (1 + (2**(self.nu / 2.0) - 1) *
                     np.exp(-self.nu / 2.0 * sig1 *
                            (-50 +
                             (i + 1) * self.dx + 2 * lam1 * t)))**(-2.0 /
                                                                   self.nu)


da = PETSc.DMDA().create([2049], dof=1, stencil_width=1)

OptDB = PETSc.Options()
ode = Fisher_split(da=da)

x = ode.gvec.duplicate()
f = ode.gvec.duplicate()

ts = PETSc.TS().create(comm=MPI.COMM_WORLD)
ts.setType(ts.Type.ARKIMEXARS443
           )  # Rosenbrock-W. ARKIMEX is a nonlinearly implicit alternative.
# ts.setRKType('3bs')

ts.setIFunction(ode.formFunction, ode.gvec)
ts.setIJacobian(ode.formJacobian, ode.mat)
ts.setRHSFunction(ode.formRHS, ode.rhs)
Ejemplo n.º 25
0
def main():
    # import petsc4py


    n = 4
    dx = 1.0/(n - 1)
    dy = dx
    comm= PETSc.COMM_WORLD
    da = PETSc.DMDA().create([n, n], dof=1, stencil_width=1, comm=comm)
    dar = da.refine()
    print(dar.getSizes())
    exit()

    rank = PETSc.COMM_WORLD.getRank()
    # comm=

    x = da.createGlobalVec()
    xa = da.getVecArray(x)
    (xs, xe), (ys, ye) = da.getRanges()
    print(xs,xe,ys,ye, xa.shape)
    for i in range(xs, xe):
        for j in range(ys, ye):
            xa[i, j, 0] = np.sin(2 * np.pi * (i ) * dx) * np.sin(2 * np.pi * (j ) * dy)
            xa[i, j, 1] = 0.1 * np.sin(2 * np.pi * (i ) * dx) * np.sin(2 * np.pi * (j ) * dy)
    print('x=', rank, x.getArray())
    # print('x:', x.getSizes(), da.getRanges())
    # print()

    y = da.createGlobalVec()
    ya = da.getVecArray(y)
    (xs, xe), (ys, ye) = da.getRanges()
    for i in range(xs, xe):
        for j in range(ys, ye):
            ya[i, j, 0] = -2 * (2.0 * np.pi) ** 2 * np.sin(2 * np.pi * (i ) * dx) * np.sin(2 * np.pi * (j ) * dy)
            ya[i, j, 1] = -0.2 * (2.0 * np.pi) ** 2 * np.sin(2 * np.pi * (i) * dx) * np.sin(2 * np.pi * (j) * dy)
    #
    # z = da.createGlobalVec()
    # za = da.getVecArray(z)
    # (xs, xe), (ys, ye) = da.getRanges()
    # for i in range(xs, xe):
    #     for j in range(ys, ye):
    #         za[i, j] = 4 * (2.0 * np.pi) ** 4 * np.sin(2 * np.pi * (i + 1) * dx) * np.sin(2 * np.pi * (j + 1) * dy)


    # z = y.copy()
    # print('z=', z.getArray())
    # ya = da.getVecArray(y)
    # ya[0,0] = 10.0
    # print(y.getArray()[0], z.getArray()[0])

    A = da.createMatrix()
    A.setType('aij')  # sparse
    A.setFromOptions()
    A.setPreallocationNNZ((5,5))
    A.setUp()

    A.zeroEntries()
    row = PETSc.Mat.Stencil()
    col = PETSc.Mat.Stencil()
    mx, my = da.getSizes()
    (xs, xe), (ys, ye) = da.getRanges()
    for j in range(ys, ye):
        for i in range(xs, xe):
            if (i == 0 or j == 0 or i == mx - 1 or j == my - 1):
                row.index = (i, j)
                row.field = 0
                A.setValueStencil(row, row, 1.0)
                row.field = 1
                A.setValueStencil(row, row, 1.0)
                # pass
            else:
                # u = x[i, j] # center
                diag = -2.0 / dx ** 2 - 2.0 / dy ** 2
                for index, value in [
                    ((i, j - 1), 1.0 / dy ** 2),
                    ((i - 1, j), 1.0 / dx ** 2),
                    ((i, j), diag),
                    ((i + 1, j), 1.0 / dx ** 2),
                    ((i, j + 1), 1.0 / dy ** 2),
                ]:
                    row.index = (i, j)
                    row.field = 0
                    col.index = index
                    col.field = 0
                    A.setValueStencil(row, col, value)
                    row.field = 1
                    col.field = 1
                    A.setValueStencil(row, col, value)

    A.assemble()
    A.view()
    exit()

    Id = da.createMatrix()
    Id.setType('aij')  # sparse
    Id.setFromOptions()
    Id.setPreallocationNNZ((5, 5))
    Id.setUp()

    Id.zeroEntries()
    row = PETSc.Mat.Stencil()
    col = PETSc.Mat.Stencil()
    mx, my = da.getSizes()
    (xs, xe), (ys, ye) = da.getRanges()
    for j in range(ys, ye):
        for i in range(xs, xe):
            row.index = (i, j)
            row.field = 0
            col.index = (i, j)
            col.field = 0
            Id.setValueStencil(row, row, 1.0)
            row.field = 1
            col.field = 1
            Id.setValueStencil(row, col, 1.0)
    Id.assemble()

    # (xs, xe), (ys, ye) = da.getRanges()
    # print(A.getValues(range(n*n), range(n*n)))

    res = da.createGlobalVec()
    A.mult(x, res)
    print('1st turn', rank, res.getArray())
    print((res-y).norm(PETSc.NormType.NORM_INFINITY))

    ksp = PETSc.KSP().create()
    ksp.setOperators(A)
    ksp.setType('cg')
    pc = ksp.getPC()
    pc.setType('mg')
    ksp.setFromOptions()

    x1 = da.createGlobalVec()
    ksp.solve(res, x1)
    print((x1 - x).norm(PETSc.NormType.NORM_INFINITY))

    x2 = da.createGlobalVec()
    Id.mult(x1, x2)
    print((x2 - x1).norm(PETSc.NormType.NORM_INFINITY))
Ejemplo n.º 26
0
#!/usr/bin/python
import sys, petsc4py
petsc4py.init(sys.argv)
from petsc4py import PETSc

if __name__ == "__main__":
    field = PETSc.Shell().create().setURL("./field.py:Field")
    viz = PETSc.Shell().create().setURL("./viz1.py:Viz")
    field.call("init")
    viz.compose("mesh", field.query("mesh"))
    viz.compose("rho", field.query("rho"))
    viz.call("viewRho")
    del viz
    del field
Ejemplo n.º 27
0
def solver_FE_MATfree_PETSc(I, a, L, Nx, C, T):
    """
	This solves the system using a Forward Euler scheme, but
	without using a explisit matrix. This calls advance-function
	to do the calculations at each time step. This saves memory (no
	need to store a matrix in the memory) and time (dont use any
	time setting up a matrix).
	
	For now we can call to advancer-functions (could be extended
	using Cython and f2py for speed):
	- advance_FE_looper: a plain scalar looper.
	- advance_FE_fastnumpy: a vectorized looper using Numpy. Note that
		in this function there is no hardcopying in the conversion
		between PETSc arrays and Numpy arrays, as they share the same
		memory location. This saves time during the calculations.
	"""

    x = np.linspace(0, L, Nx + 1)
    dx = x[1] - x[0]
    dt = C * dx**2 / a
    Nt = int(round(T / float(dt)))
    t = np.linspace(0, T, Nt + 1)
    t0 = time.clock()

    # COMMENT
    da = PETSc.DA().create(sizes=[Nx + 1],
                           boundary_type=2,
                           stencil_type=0,
                           stencil_width=1)
    da.setUniformCoordinates(0, L)  # We never really use this in here
    u = da.createGlobalVector()
    u_1 = da.createGlobalVector()
    #A = da.createMatrix(); A.setType('aij')  # type is seqaij as default, must change this

    # Initialize init time step
    [Istart, Iend] = u_1.getOwnershipRange()
    u_1.setValues(range(Istart, Iend), I[Istart:Iend])

    local_vec = da.createLocalVector()
    local_vec_new = da.createLocalVector()

    # Assemble the vectors and the matrix. This distribute the objects out over the procs.
    #A.assemble();
    u.assemble()
    u_1.assemble()

    # This can be cut out, this is for plotting in external
    # programs
    if PETSc.Options().getBool('toFile', default=False):
        if PETSc.COMM_WORLD.getSize() > 1:
            if PETSc.COMM_WORLD.getRank() == 0:
                print 'Warning: NOT writing to file (using parallel)'
                PETSc.Options().setValue('toFile', False)
        else:
            W = PETSc.Viewer().createASCII('test3.txt', format=1)
            u_1.view(W)

    for n in range(0, Nt):
        da.globalToLocal(u_1, local_vec)

        if PETSc.Options().getString('advance_method',
                                     default='fastnumpy') == 'looper':
            local_vec_new = advance_FE_looper(local_vec, C, da)
        else:
            local_vec_new = advance_FE_fastnumpy(local_vec, C, da)

        da.localToGlobal(local_vec_new, u_1)

        if PETSc.Options().getBool('draw', default=False):
            U = da.createNaturalVector()
            da.globalToNatural(u_1, U)
            petsc_viz(U, 0.001)

    return u_1, time.clock() - t0
Ejemplo n.º 28
0
import freefem as ff

# load libraries
from numpy import *
import matplotlib.pyplot as plt
import h5py as h5
from petsc4py import PETSc
from slepc4py import SLEPc
from mpi4py import MPI

# load functions for stability analysis
import parfemstab as pfs
from parfemstab import Print, PrintRed, PrintGreen

# Set MUMPS as the linear solver
opts = PETSc.Options()

opts.setValue('ksp_type', 'preonly')
opts.setValue('pc_type', 'lu')
opts.setValue('pc_factor_mat_solver_package', 'mumps')

# Parallel info
comm = MPI.COMM_WORLD
rank = comm.Get_rank()

# Get the directory where ff++ data is
di = opts.getString('dir')
PrintRed('Running tests in ' + di + '\n')

PrintRed("Testing time stepping routines ... \n")
Ejemplo n.º 29
0
def solver_BE_PETSc(I, a, L, Nx, C, T):
    """
	This solve our system using an implicit Backward Euler scheme. There is no
	limitation on C, as in the explicit scheme (where C <= 0.5).
	
	We solve the system A*u = u_1 using a sparse A matrix.
	"""

    x = np.linspace(0, L, Nx + 1)
    dx = x[1] - x[0]
    dt = C * dx**2 / a
    Nt = int(round(T / float(dt)))
    t = np.linspace(0, T, Nt + 1)
    t0 = time.clock()

    A = PETSc.Mat().createAIJ([Nx + 1, Nx + 1], nnz=3)
    [Istart, Iend] = A.getOwnershipRange()
    for i in range(Istart,
                   Iend):  # filling the diagonal and off-diagonal entries
        A.setValue(i, i, 1. + 2 * C)
        A.setValue(i - 1, i, -C)
        A.setValue(i, i - 1, -C)
    # For boundary conditions
    A.setValue(0, 0, 1)
    A.setValue(0, 1, 0)
    A.setValue(Nx, Nx, 1)
    A.setValue(Nx, Nx - 1, 0)

    # Create the to vectors, we need two of them (new and old). We're also
    # making a temporary RHS-array b
    u, u_1 = A.getVecs()

    [Istart, Iend] = u_1.getOwnershipRange()
    u_1.setValues(range(Istart, Iend), I[Istart:Iend])

    # Assemble the matrix and vectors. This distribute the data on to the
    # different processors (among other things).
    A.assemble()
    u.assemble()
    u_1.assemble()

    if PETSc.Options().getBool('toFile', default=False):
        if PETSc.COMM_WORLD.getSize() > 1:
            if PETSc.COMM_WORLD.getRank() == 0:
                print 'Warning: not writing to file (using parallel)'
        else:
            print 'Writing to file'
            W = PETSc.Viewer().createASCII('test3.txt', format=1)
            u_1.view(W)
    """
	Setting up the KSP solver, the heart of PETSc. We use setFromOptions.
	
	The command line option for the KSP solver is -ksp_type <method> -pc_type <method>
	List of preconditioners (-pc_type):
	http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/PC/PCType.html#PCType
	List of solvers (-ksp_type):
	http://www.mcs.anl.gov/petsc/petsc-current/docs/manualpages/KSP/KSPType.html#KSPType
	
	As an example: to use a direct solver method using LU, run the program using:
		-ksp_type preonly -pc_type lu
	To run with a Conjugate Gradient iterativ solver (nice for positive-definite and
	symmetric matrices often seen in Finite Difference systems) with incomplete
	Cholesky preconditioning, run with:
		-ksp_type cg -pc_type icc
	
	The solvers and preconditioners are also listed at (along with external packages):
	http://www.mcs.anl.gov/petsc/petsc-current/docs/linearsolvertable.html
	"""

    ksp = PETSc.KSP()
    ksp.create()
    # Setting a CG iterative solver as default, then one can override
    # this with command line options:
    ksp.setType('cg')  # KSP solver
    ksp.getPC().setType('none')  # Preconditioner

    ksp.setFromOptions()
    ksp.setOperators(A)  # Set which matrix to solve the problem with

    for t in range(Nt):
        # Solve for next step using the solver set up above using
        # command-line options.
        ksp.solve(u_1, u)

        # Swap
        u, u_1 = u_1, u

        if PETSc.Options().getBool('toFile', default=False):
            u.view(W)

        if PETSc.Options().getBool('draw', default=False):
            petsc_viz_withoutDA(u, sleeper=0.01)

    return u_1, time.clock() - t0
Ejemplo n.º 30
0
import sys, petsc4py
petsc4py.init(sys.argv)

from petsc4py import PETSc
import Bratu3D as Bratu3D

OptDB = PETSc.Options()

N = OptDB.getInt('N', 16)
lambda_ = OptDB.getReal('lambda', 6.0)
do_plot = OptDB.getBool('plot', False)

da = PETSc.DMDA().create([N, N, N], stencil_width=1)
#app = App(da, lambda_)

snes = PETSc.SNES().create()
F = da.createGlobalVec()
snes.setFunction(Bratu3D.formFunction, F,
                 args=(da, lambda_))
J = da.createMat()
snes.setJacobian(Bratu3D.formJacobian, J,
                 args=(da, lambda_))

snes.setFromOptions()

X = da.createGlobalVec()
Bratu3D.formInitGuess(X, da, lambda_)
snes.solve(None, X)

U = da.createNaturalVec()
da.globalToNatural(X, U)
Ejemplo n.º 31
0
PETSc.Sys.Print(' ')

# set Preconditioner
if ksp.pc.getType()=='none':
	ksp.setOperators(G)
	PETSc.Sys.Print(' Using a %s solver with no preconditioner'%(ksp.getType()))
else:
	PETSc.Sys.Print('********************************************')
	PETSc.Sys.Print('********************************************')
	PETSc.Sys.Print(' ')
	PETSc.Sys.Print('  There is no preconditioner for that case  ')
	PETSc.Sys.Print('  Please write one, that would be cool :-)  ')
	PETSc.Sys.Print(' ')
	PETSc.Sys.Print('********************************************')
	PETSc.Sys.Print('********************************************')
	PETSc._finalize()
	sys.exit(1)

# Print Stuff
PETSc.Sys.Print(' Tolerances asked:  %e %e %d %d'%(rtol, atol, it1, it2))

# Solve!
ksp.solve(d, m)
PETSc.Sys.Print(' ')
PETSc.Sys.Print(' Converged in %d iterations '%(ksp.getIterationNumber()))
PETSc.Sys.Print(' Tolerance Asked: %e %e %d %d'%(ksp.getTolerances()))
PETSc.Sys.Print(' Converged Reason: %d'%(ksp.getConvergedReason()))
PETSc.Sys.Print(' ')
ksp.view()
PETSc.Sys.Print(' ')