def J(self, x): """Assemble Jacobian matrix.""" if self._J is None: self._J = fem.assemble_matrix(self.a, [self.bc]) else: self._J.zeroEntries() self._J = fem.assemble_matrix(self._J, self.a, [self.bc]) self._J.assemble() return self._J
def test_ghost_mesh_assembly(mode, dx, ds): mesh = UnitSquareMesh(MPI.comm_world, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = TrialFunction(V), TestFunction(V) dx = dx(mesh) ds = ds(mesh) f = Function(V) with f.vector.localForm() as f_local: f_local.set(10.0) a = inner(f * u, v) * dx + inner(u, v) * ds L = inner(f, v) * dx + inner(2.0, v) * ds # Initial assembly A = fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) b = fem.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert isinstance(b, PETSc.Vec) # Check that the norms are the same for all three modes normA = A.norm() assert normA == pytest.approx(0.6713621455570528, rel=1.e-6, abs=1.e-12) normb = b.norm() assert normb == pytest.approx(1.582294032953906, rel=1.e-6, abs=1.e-12)
def test_krylov_solver_lu(): mesh = UnitSquareMesh(MPI.comm_world, 12, 12) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = TrialFunction(V), TestFunction(V) a = inner(u, v) * dx L = inner(1.0, v) * dx A = assemble_matrix(a) A.assemble() b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) norm = 13.0 solver = PETScKrylovSolver(mesh.mpi_comm()) solver.set_options_prefix("test_lu_") PETScOptions.set("test_lu_ksp_type", "preonly") PETScOptions.set("test_lu_pc_type", "lu") solver.set_from_options() x = A.createVecRight() solver.set_operator(A) solver.solve(x, b) # *Tight* tolerance for LU solves assert round(x.norm(PETSc.NormType.N2) - norm, 12) == 0
def test_nullspace_check(mesh, degree): V = VectorFunctionSpace(mesh, ('Lagrange', degree)) u, v = TrialFunction(V), TestFunction(V) mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh) E, nu = 2.0e2, 0.3 mu = E / (2.0 * (1.0 + nu)) lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)) def sigma(w, gdim): return 2.0 * mu * ufl.sym(grad(w)) + lmbda * ufl.tr( grad(w)) * ufl.Identity(gdim) a = inner(sigma(u, mesh.geometry.dim), grad(v)) * dx # Assemble matrix and create compatible vector A = assemble_matrix(a) A.assemble() # Create null space basis and test null_space = build_elastic_nullspace(V) assert null_space.in_nullspace(A, tol=1.0e-8) null_space.orthonormalize() assert null_space.in_nullspace(A, tol=1.0e-8) # Create incorrect null space basis and test null_space = build_broken_elastic_nullspace(V) assert not null_space.in_nullspace(A, tol=1.0e-8) null_space.orthonormalize() assert not null_space.in_nullspace(A, tol=1.0e-8)
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, only_boundary): return [only_boundary] * x.shape(0) bc = DirichletBC(V.sub(0), bc0, boundary) 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 = PETScKrylovSolver("cg", method) # Set matrix operator solver.set_operator(A) # Compute solution and return number of iterations return solver.solve(u.vector(), b)
def test_krylov_solver_lu(): mesh = UnitSquareMesh(MPI.comm_world, 12, 12) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = TrialFunction(V), TestFunction(V) a = inner(u, v) * dx L = inner(1.0, v) * dx A = assemble_matrix(a) A.assemble() b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) norm = 13.0 solver = PETSc.KSP().create(mesh.mpi_comm()) solver.setOptionsPrefix("test_lu_") opts = PETSc.Options("test_lu_") opts["ksp_type"] = "preonly" opts["pc_type"] = "lu" solver.setFromOptions() x = A.createVecRight() solver.setOperators(A) solver.solve(b, x) # *Tight* tolerance for LU solves assert x.norm(PETSc.NormType.N2) == pytest.approx(norm, abs=1.0e-12)
def J(self, x): """Assemble Jacobian matrix.""" if self._J is None: self._J = fem.assemble_matrix([[self.a]], [self.bc], dolfin.cpp.fem.BlockType.monolithic) else: self._J = fem.assemble(self._J, self.a, [self.bc]) return self._J
def test_ghost_mesh_dS_assembly(mode, dS): mesh = UnitSquareMesh(MPI.comm_world, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = TrialFunction(V), TestFunction(V) dS = dS(mesh) a = inner(avg(u), avg(v)) * dS # Initial assembly A = fem.assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) # Check that the norms are the same for all three modes normA = A.norm() print(normA) assert normA == pytest.approx(2.1834054713561906, rel=1.e-6, abs=1.e-12)
def _solve_varproblem(*args, **kwargs): "Solve variational problem a == L or F == 0" # Extract arguments eq, u, bcs, J, tol, M, form_compiler_parameters, petsc_options \ = _extract_args(*args, **kwargs) # Solve linear variational problem if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form): a = fem.Form(eq.lhs, form_compiler_parameters=form_compiler_parameters) L = fem.Form(eq.rhs, form_compiler_parameters=form_compiler_parameters) b = fem.assemble_vector(L._cpp_object) fem.apply_lifting(b, [a._cpp_object], [bcs]) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) fem.set_bc(b, bcs) A = fem.assemble_matrix(a._cpp_object, bcs) A.assemble() comm = L._cpp_object.mesh().mpi_comm() ksp = PETSc.KSP().create(comm) ksp.setOperators(A) ksp.setOptionsPrefix("dolfin_solve_") opts = PETSc.Options() opts.prefixPush("dolfin_solve_") for k, v in petsc_options.items(): opts[k] = v opts.prefixPop() ksp.setFromOptions() ksp.solve(b, u.vector) ksp.view() # Solve nonlinear variational problem else: raise RuntimeError("Not implemented")
def _solve_varproblem(*args, **kwargs): "Solve variational problem a == L or F == 0" # Extract arguments eq, u, bcs, J, tol, M, form_compiler_parameters, petsc_options \ = _extract_args(*args, **kwargs) # Solve linear variational problem if isinstance(eq.lhs, ufl.Form) and isinstance(eq.rhs, ufl.Form): a = fem.Form(eq.lhs, form_compiler_parameters=form_compiler_parameters) L = fem.Form(eq.rhs, form_compiler_parameters=form_compiler_parameters) b = fem.assemble(L._cpp_object) fem.apply_lifting(b, [a._cpp_object], [bcs]) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) fem.set_bc(b, bcs) A = cpp.fem.create_matrix(a._cpp_object) A.zeroEntries() A = fem.assemble_matrix(a._cpp_object, bcs) A.assemble() comm = L._cpp_object.mesh().mpi_comm() solver = cpp.la.PETScKrylovSolver(comm) solver.set_options_prefix("dolfin_solve_") for k, v in petsc_options.items(): cpp.la.PETScOptions.set("dolfin_solve_" + k, v) solver.set_from_options() solver.set_operator(A) solver.solve(u.vector(), b) # Solve nonlinear variational problem else: raise RuntimeError("Not implemented")
# Define variational problem u = TrialFunction(V) v = TestFunction(V) a = inner(sigma(u), grad(v)) * dx L = inner(f, v) * dx u0 = Function(V) with u0.vector.localForm() as bc_local: bc_local.set(0.0) # Set up boundary condition on inner surface bc = DirichletBC(V, u0, boundary) # Assemble system, applying boundary conditions and preserving symmetry) 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 (required for smoothed aggregation AMG). null_space = build_nullspace(V) # Attach near nullspace to matrix A.setNearNullSpace(null_space)
def project(v, V=None, bcs=[], mesh=None, funct=None): """Return projection of given expression *v* onto the finite element space *V*. *Arguments* v a :py:class:`Function <dolfin.functions.function.Function>` or an :py:class:`Expression <dolfin.functions.expression.Expression>` bcs Optional argument :py:class:`list of DirichletBC <dolfin.fem.bcs.DirichletBC>` V Optional argument :py:class:`FunctionSpace <dolfin.functions.functionspace.FunctionSpace>` mesh Optional argument :py:class:`mesh <dolfin.cpp.Mesh>`. funct Target function where result is stored. *Example of usage* .. code-block:: python v = Expression("sin(pi*x[0])") V = FunctionSpace(mesh, "Lagrange", 1) Pv = project(v, V) This is useful for post-processing functions or expressions which are not readily handled by visualization tools (such as for example discontinuous functions). """ # Try figuring out a function space if not specified if V is None: # Create function space based on Expression element if trying # to project an Expression if isinstance(v, function.Expression): if mesh is not None and isinstance(mesh, cpp.mesh.Mesh): V = function.FunctionSpace(mesh, v.ufl_element()) # else: # cpp.dolfin_error("projection.py", # "perform projection", # "Expected a mesh when projecting an Expression") else: # Otherwise try extracting function space from expression V = _extract_function_space(v, mesh) # Check arguments # Ensure we have a mesh and attach to measure if mesh is None: mesh = V.mesh dx = ufl.dx(mesh) # Define variational problem for projection w = function.TestFunction(V) Pv = function.TrialFunction(V) a = ufl.inner(Pv, w) * dx L = ufl.inner(v, w) * dx # Assemble linear system A = fem.assemble_matrix(a, bcs) A.assemble() b = fem.assemble_vector(L) fem.apply_lifting(b, [a], [bcs]) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) fem.set_bc(b, bcs) # Solve linear system for projection if funct is None: funct = function.Function(V) la.solve(A, funct.vector, b) return funct
def J(self, snes, x, J, P): """Assemble Jacobian matrix.""" J.zeroEntries() fem.assemble_matrix(J, self.a, [self.bc]) J.assemble()