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
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
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
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]
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
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
def testApplyIS(self): is_in = PETSc.IS().createStride(self.lgmap.getSize()) is_out = self.lgmap.apply(is_in)
# 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:
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)
def Scipy2PETSc(A): A = A.tocsr() return PETSc.Mat().createAIJ(size=A.shape, csr=(A.indptr, A.indices, A.data))
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
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])
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):
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])
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)
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
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
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
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)
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)
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)
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()
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)
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)
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))
#!/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
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
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")
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
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)
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(' ')