def test_submesh_boundary(d, n, boundary, ghost_mode): if d == 2: mesh = create_unit_square(MPI.COMM_WORLD, n, n, ghost_mode=ghost_mode) else: mesh = create_unit_cube(MPI.COMM_WORLD, n, n, n, ghost_mode=ghost_mode) edim = mesh.topology.dim - 1 entities = locate_entities_boundary(mesh, edim, boundary) submesh, vertex_map, geom_map = create_submesh(mesh, edim, entities) submesh_topology_test(mesh, submesh, vertex_map, edim, entities) submesh_geometry_test(mesh, submesh, geom_map, edim, entities)
def test_save_2d_vector(tempdir, encoding, cell_type): filename = os.path.join(tempdir, "u_2dv.xdmf") mesh = create_unit_square(MPI.COMM_WORLD, 12, 13, cell_type) V = VectorFunctionSpace(mesh, ("Lagrange", 2)) u = Function(V) u.vector.set(1.0 + ( 1j if np.issubdtype(PETSc.ScalarType, np.complexfloating) else 0)) with XDMFFile(mesh.comm, filename, "w", encoding=encoding) as file: file.write_mesh(mesh) file.write_function(u)
def test_assemble_functional_dx(mode): mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) M = form(1.0 * dx(domain=mesh)) value = assemble_scalar(M) value = mesh.comm.allreduce(value, op=MPI.SUM) assert value == pytest.approx(1.0, 1e-12) x = ufl.SpatialCoordinate(mesh) M = form(x[0] * dx(domain=mesh)) value = assemble_scalar(M) value = mesh.comm.allreduce(value, op=MPI.SUM) assert value == pytest.approx(0.5, 1e-12)
def test_submesh(d, n, codim, marker, ghost_mode): if d == 2: mesh = create_unit_square(MPI.COMM_WORLD, n, n, ghost_mode=ghost_mode) else: mesh = create_unit_cube(MPI.COMM_WORLD, n, n, n, ghost_mode=ghost_mode) edim = mesh.topology.dim - codim entities = locate_entities(mesh, edim, marker) submesh, vertex_map, geom_map = create_submesh(mesh, edim, entities) submesh_topology_test(mesh, submesh, vertex_map, edim, entities) submesh_geometry_test(mesh, submesh, geom_map, edim, entities)
def test_interpolation_n2curl_to_bdm(tdim, order): if tdim == 2: mesh = create_unit_square(MPI.COMM_WORLD, 5, 5) else: mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2) V = FunctionSpace(mesh, ("N2curl", order)) V1 = FunctionSpace(mesh, ("BDM", order)) u, v = Function(V), Function(V1) u.interpolate(lambda x: x[:tdim]**order) v.interpolate(u) s = assemble_scalar(form(ufl.inner(u - v, u - v) * ufl.dx)) assert np.isclose(s, 0)
def plot_meshtags(): # MeshTags and using subplots # =========================== mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, cell_type=CellType.quadrilateral) # We continue using the mesh from the previous section, and find all # cells satisfying the condition below def in_circle(x): """True for points inside circle with radius 2""" return np.array((x.T[0] - 0.5)**2 + (x.T[1] - 0.5)**2 < 0.2**2, dtype=np.int32) # Create a dolfinx.MeshTag for all cells. If midpoint is inside the # circle, it gets value 1, otherwise 0. num_cells = mesh.topology.index_map(mesh.topology.dim).size_local midpoints = compute_midpoints(mesh, mesh.topology.dim, list(np.arange(num_cells, dtype=np.int32))) cell_tags = MeshTags(mesh, mesh.topology.dim, np.arange(num_cells), in_circle(midpoints)) cells, types, x = plot.create_vtk_mesh(mesh, mesh.topology.dim) grid = pyvista.UnstructuredGrid(cells, types, x) # As the dolfinx.MeshTag contains a value for every cell in the # geometry, we can attach it directly to the grid grid.cell_data["Marker"] = cell_tags.values grid.set_active_scalars("Marker") # We create a plotter consisting of two windows, and add a plot of the # Meshtags to the first window. subplotter = pyvista.Plotter(shape=(1, 2)) subplotter.subplot(0, 0) subplotter.add_text("Mesh with markers", font_size=14, color="black", position="upper_edge") subplotter.add_mesh(grid, show_edges=True, show_scalar_bar=False) subplotter.view_xy() # We can also visualize subsets of data, by creating a smaller topology, # only consisting of those entities that has value one in the # dolfinx.MeshTag cells, types, x = plot.create_vtk_mesh( mesh, mesh.topology.dim, cell_tags.indices[cell_tags.values == 1]) # We add this grid to the second plotter sub_grid = pyvista.UnstructuredGrid(cells, types, x) subplotter.subplot(0, 1) subplotter.add_text("Subset of mesh", font_size=14, color="black", position="upper_edge") subplotter.add_mesh(sub_grid, show_edges=True, edge_color="black") if pyvista.OFF_SCREEN: subplotter.screenshot("2D_markers.png", transparent_background=transparent, window_size=[2 * figsize, figsize]) else: subplotter.show()
def test_block_size(mesh): meshes = [ create_unit_square(8, 8), create_unit_cube(4, 4, 4), create_unit_square(8, 8, CellType.quadrilateral), create_unit_cube(4, 4, 4, CellType.hexahedron) ] for mesh in meshes: P2 = FiniteElement("Lagrange", mesh.ufl_cell(), 2) V = FunctionSpace(mesh, P2) assert V.dofmap.bs == 1 V = FunctionSpace(mesh, P2 * P2) assert V.dofmap.index_map_bs == 2 for i in range(1, 6): W = FunctionSpace(mesh, MixedElement(i * [P2])) assert W.dofmap.index_map_bs == i V = VectorFunctionSpace(mesh, ("Lagrange", 2)) assert V.dofmap.index_map_bs == mesh.geometry.dim
def test_add_diagonal(): """Test adding entries to diagonal of sparsity pattern""" mesh = create_unit_square(MPI.COMM_WORLD, 10, 10) V = VectorFunctionSpace(mesh, ("Lagrange", 1)) pattern = SparsityPattern(mesh.comm, [V.dofmap.index_map, V.dofmap.index_map], [V.dofmap.index_map_bs, V.dofmap.index_map_bs]) mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim) facets = compute_boundary_facets(mesh.topology) blocks = locate_dofs_topological(V, mesh.topology.dim - 1, facets) pattern.insert_diagonal(blocks) pattern.assemble() assert len(blocks) == pattern.num_nonzeros
def run_symmetry_test(cell_type, element, form_f): if cell_type == CellType.triangle or cell_type == CellType.quadrilateral: mesh = create_unit_square(MPI.COMM_WORLD, 2, 2, cell_type) else: mesh = create_unit_cube(MPI.COMM_WORLD, 2, 2, 2, cell_type) space = FunctionSpace(mesh, element) u = ufl.TrialFunction(space) v = ufl.TestFunction(space) f = form(form_f(u, v)) A = dolfinx.fem.assemble_matrix(f) A.assemble() check_symmetry(A)
def test_complex_assembly(): """Test assembly of complex matrices and vectors""" mesh = create_unit_square(MPI.COMM_WORLD, 10, 10) P2 = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), 2) V = FunctionSpace(mesh, P2) u = ufl.TrialFunction(V) v = ufl.TestFunction(V) g = -2 + 3.0j j = 1.0j a_real = form(inner(u, v) * dx) L1 = form(inner(g, v) * dx) b = assemble_vector(L1) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) bnorm = b.norm(PETSc.NormType.N1) b_norm_ref = abs(-2 + 3.0j) assert bnorm == pytest.approx(b_norm_ref) A = assemble_matrix(a_real) A.assemble() A0_norm = A.norm(PETSc.NormType.FROBENIUS) x = ufl.SpatialCoordinate(mesh) a_imag = form(j * inner(u, v) * dx) f = 1j * ufl.sin(2 * np.pi * x[0]) L0 = form(inner(f, v) * dx) A = assemble_matrix(a_imag) A.assemble() A1_norm = A.norm(PETSc.NormType.FROBENIUS) assert A0_norm == pytest.approx(A1_norm) b = assemble_vector(L0) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) b1_norm = b.norm(PETSc.NormType.N2) a_complex = form((1 + j) * inner(u, v) * dx) f = ufl.sin(2 * np.pi * x[0]) L2 = form(inner(f, v) * dx) A = assemble_matrix(a_complex) A.assemble() A2_norm = A.norm(PETSc.NormType.FROBENIUS) assert A1_norm == pytest.approx(A2_norm / np.sqrt(2)) b = assemble_vector(L2) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) b2_norm = b.norm(PETSc.NormType.N2) assert b2_norm == pytest.approx(b1_norm)
def test_save_and_load_2d_mesh(tempdir, encoding, cell_type): filename = os.path.join(tempdir, "mesh.xdmf") mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, cell_type) mesh.name = "square" with XDMFFile(mesh.comm, filename, "w", encoding=encoding) as file: file.write_mesh(mesh) with XDMFFile(MPI.COMM_WORLD, filename, "r", encoding=encoding) as file: mesh2 = file.read_mesh(name="square") assert mesh2.name == mesh.name assert mesh.topology.index_map(0).size_global == mesh2.topology.index_map(0).size_global assert mesh.topology.index_map(mesh.topology.dim).size_global == mesh2.topology.index_map( mesh.topology.dim).size_global
def test_save_2d_vector(tempdir, cell_type): mesh = create_unit_square(MPI.COMM_WORLD, 16, 16, cell_type=cell_type) u = Function(VectorFunctionSpace(mesh, ("Lagrange", 1))) def f(x): vals = np.zeros((2, x.shape[1])) vals[0] = x[0] vals[1] = 2 * x[0] * x[1] return vals u.interpolate(f) filename = os.path.join(tempdir, "u.pvd") with VTKFile(MPI.COMM_WORLD, filename, "w") as vtk: vtk.write_function(u, 0.) vtk.write_function(u, 1.)
def test_save_vtkx_cell_point(tempdir): """Test writing point-wise data""" mesh = create_unit_square(MPI.COMM_WORLD, 8, 5) P = ufl.FiniteElement("Discontinuous Lagrange", mesh.ufl_cell(), 0) V = FunctionSpace(mesh, P) u = Function(V) u.interpolate(lambda x: 0.5 * x[0]) u.name = "A" filename = os.path.join(tempdir, "v.bp") with pytest.raises(RuntimeError): f = VTXWriter(mesh.comm, filename, [u]) f.write(0) f.close()
def test_sub_refine(): """Test that refinement of a subset of edges works""" mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, diagonal=DiagonalType.left, ghost_mode=GhostMode.none) mesh.topology.create_entities(1) def left_corner_edge(x, tol=1e-16): return logical_and(isclose(x[0], 0), x[1] < 1 / 4 + tol) edges = locate_entities_boundary(mesh, 1, left_corner_edge) if MPI.COMM_WORLD.size == 0: assert edges == 1 mesh2 = refine(mesh, edges, redistribute=False) assert mesh.topology.index_map(2).size_global + 3 == mesh2.topology.index_map(2).size_global
def test_incompatible_spaces(): """Test that error is thrown when function spaces are not compatible""" mesh = create_unit_square(MPI.COMM_WORLD, 13, 7) V = FunctionSpace(mesh, ("Lagrange", 1)) W = FunctionSpace(mesh, ("Nedelec 1st kind H(curl)", 1)) with pytest.raises(RuntimeError): create_discrete_gradient(V._cpp_object, W._cpp_object) with pytest.raises(RuntimeError): create_discrete_gradient(V._cpp_object, V._cpp_object) with pytest.raises(RuntimeError): create_discrete_gradient(W._cpp_object, W._cpp_object) V = FunctionSpace(mesh, ("Lagrange", 2)) with pytest.raises(RuntimeError): create_discrete_gradient(W._cpp_object, V._cpp_object)
def test_complex_assembly_solve(): """Solve a positive definite helmholtz problem and verify solution with the method of manufactured solutions""" degree = 3 mesh = create_unit_square(MPI.COMM_WORLD, 20, 20) P = ufl.FiniteElement("Lagrange", mesh.ufl_cell(), degree) V = FunctionSpace(mesh, P) x = ufl.SpatialCoordinate(mesh) # Define source term A = 1.0 + 2.0 * (2.0 * np.pi)**2 f = (1. + 1j) * A * ufl.cos(2 * np.pi * x[0]) * ufl.cos(2 * np.pi * x[1]) # Variational problem u, v = ufl.TrialFunction(V), ufl.TestFunction(V) C = 1.0 + 1.0j a = form(C * inner(grad(u), grad(v)) * dx + C * inner(u, v) * dx) L = form(inner(f, v) * dx) # Assemble A = assemble_matrix(a) A.assemble() b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) # Create solver solver = PETSc.KSP().create(mesh.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) # Reference Solution def ref_eval(x): return np.cos(2 * np.pi * x[0]) * np.cos(2 * np.pi * x[1]) u_ref = Function(V) u_ref.interpolate(ref_eval) diff = (x - u_ref.vector).norm(PETSc.NormType.N2) assert diff == pytest.approx(0.0, abs=1e-1)
def test_rank0(): """Test evaluation of UFL expression. This test evaluates gradient of P2 function at interpolation points of vector dP1 element. For a donor function f(x, y) = x^2 + 2*y^2 result is compared with the exact gradient grad f(x, y) = [2*x, 4*y]. """ mesh = create_unit_square(MPI.COMM_WORLD, 5, 5) P2 = FunctionSpace(mesh, ("P", 2)) vdP1 = VectorFunctionSpace(mesh, ("DG", 1)) f = Function(P2) def expr1(x): return x[0]**2 + 2.0 * x[1]**2 f.interpolate(expr1) ufl_expr = ufl.grad(f) points = vdP1.element.interpolation_points compiled_expr = Expression(ufl_expr, points) num_cells = mesh.topology.index_map(2).size_local array_evaluated = compiled_expr.eval(np.arange(num_cells, dtype=np.int32)) @numba.njit def scatter(vec, array_evaluated, dofmap): for i in range(num_cells): for j in range(3): for k in range(2): vec[2 * dofmap[i * 3 + j] + k] = array_evaluated[i, 2 * j + k] # Data structure for the result b = Function(vdP1) dofmap = vdP1.dofmap.list.array scatter(b.x.array, array_evaluated, dofmap) b.x.scatter_forward() def grad_expr1(x): return np.vstack((2.0 * x[0], 4.0 * x[1])) b2 = Function(vdP1) b2.interpolate(grad_expr1) assert np.allclose(b2.x.array, b.x.array)
def test_vector_interpolation_spatial(order, dim, affine): if dim == 2: ct = CellType.triangle if affine else CellType.quadrilateral mesh = create_unit_square(MPI.COMM_WORLD, 3, 4, ct) elif dim == 3: ct = CellType.tetrahedron if affine else CellType.hexahedron mesh = create_unit_cube(MPI.COMM_WORLD, 3, 2, 2, ct) V = VectorFunctionSpace(mesh, ("Lagrange", order)) u = Function(V) x = ufl.SpatialCoordinate(mesh) # The expression (x,y,z)^n is contained in space f = ufl.as_vector([x[i]**order for i in range(dim)]) u.interpolate(Expression(f, V.element.interpolation_points)) assert np.isclose( np.abs(assemble_scalar(form(ufl.inner(u - f, u - f) * ufl.dx))), 0)
def test_coefficient(): mesh = create_unit_square(MPI.COMM_WORLD, 13, 13) V = FunctionSpace(mesh, ("Lagrange", 1)) DG0 = FunctionSpace(mesh, ("DG", 0)) vals = Function(DG0) vals.vector.set(2.0) Form = _cpp.fem.Form_float64 if PETSc.ScalarType == np.float64 else _cpp.fem.Form_complex128 integrals = { IntegralType.cell: ([(-1, tabulate_tensor_b_coeff.address)], None) } L = Form([V._cpp_object], integrals, [vals._cpp_object], [], False) b = dolfinx.fem.petsc.assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) bnorm = b.norm(PETSc.NormType.N2) assert (np.isclose(bnorm, 2.0 * 0.0739710713711999))
def test_ghost_mesh_dS_assembly(mode, dS): mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) dS = dS(mesh) a = form(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 test_mpc_assembly(master_point, degree, celltype, get_assemblers): # noqa: F811 _, assemble_vector = get_assemblers # Create mesh and function space mesh = create_unit_square(MPI.COMM_WORLD, 3, 5, celltype) V = fem.FunctionSpace(mesh, ("Lagrange", degree)) # Generate reference vector v = ufl.TestFunction(V) x = ufl.SpatialCoordinate(mesh) f = ufl.sin(2 * ufl.pi * x[0]) * ufl.sin(ufl.pi * x[1]) rhs = ufl.inner(f, v) * ufl.dx linear_form = fem.form(rhs) def l2b(li): return np.array(li, dtype=np.float64).tobytes() s_m_c = { l2b([1, 0]): { l2b([0, 1]): 0.43, l2b([1, 1]): 0.11 }, l2b([0, 0]): { l2b(master_point): 0.69 } } mpc = dolfinx_mpc.MultiPointConstraint(V) mpc.create_general_constraint(s_m_c) mpc.finalize() b = assemble_vector(linear_form, mpc) b.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) # Reduce system with global matrix K after assembly L_org = fem.petsc.assemble_vector(linear_form) L_org.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE) root = 0 comm = mesh.comm with Timer("~TEST: Compare"): dolfinx_mpc.utils.compare_mpc_rhs(L_org, b, mpc, root=root) list_timings(comm, [TimingType.wall])
def test_basic_assembly(mode): mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) f = Function(V) f.x.array[:] = 10.0 a = inner(f * u, v) * dx + inner(u, v) * ds L = inner(f, v) * dx + inner(2.0, v) * ds a, L = form(a), form(L) # Initial assembly A = assemble_matrix(a) A.assemble() assert isinstance(A, PETSc.Mat) b = assemble_vector(L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert isinstance(b, PETSc.Vec) # Second assembly normA = A.norm() A.zeroEntries() A = assemble_matrix(A, a) A.assemble() assert isinstance(A, PETSc.Mat) assert normA == pytest.approx(A.norm()) normb = b.norm() with b.localForm() as b_local: b_local.set(0.0) b = assemble_vector(b, L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert isinstance(b, PETSc.Vec) assert normb == pytest.approx(b.norm()) # Vector re-assembly - no zeroing (but need to zero ghost entries) with b.localForm() as b_local: b_local.array[b.local_size:] = 0.0 assemble_vector(b, L) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) assert 2.0 * normb == pytest.approx(b.norm()) # Matrix re-assembly (no zeroing) assemble_matrix(A, a) A.assemble() assert 2.0 * normA == pytest.approx(A.norm())
def test_overlapping_bcs(): """Test that, when boundaries condition overlap, the last provided boundary condition is applied""" n = 23 mesh = create_unit_square(MPI.COMM_WORLD, n, n) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = form(inner(u, v) * dx) L = form(inner(1, v) * dx) dofs_left = locate_dofs_geometrical(V, lambda x: x[0] < 1.0 / (2.0 * n)) dofs_top = locate_dofs_geometrical(V, lambda x: x[1] > 1.0 - 1.0 / (2.0 * n)) dof_corner = np.array(list(set(dofs_left).intersection(set(dofs_top))), dtype=np.int64) # Check only one dof pair is found globally assert len(set(np.concatenate(MPI.COMM_WORLD.allgather(dof_corner)))) == 1 bcs = [ dirichletbc(PETSc.ScalarType(0), dofs_left, V), dirichletbc(PETSc.ScalarType(123.456), dofs_top, V) ] A, b = create_matrix(a), create_vector(L) assemble_matrix(A, a, bcs=bcs) A.assemble() # Check the diagonal (only on the rank that owns the row) d = A.getDiagonal() if len(dof_corner) > 0 and dof_corner[0] < V.dofmap.index_map.size_local: assert np.isclose(d.array_r[dof_corner[0]], 1.0) with b.localForm() as b_loc: b_loc.set(0) assemble_vector(b, L) apply_lifting(b, [a], [bcs]) b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE) set_bc(b, bcs) b.ghostUpdate(addv=PETSc.InsertMode.INSERT, mode=PETSc.ScatterMode.FORWARD) if len(dof_corner) > 0: with b.localForm() as b_loc: assert b_loc[dof_corner[0]] == 123.456
def plot_scalar(): # Plotting a Function using warp by scalar # ======================================== # We start by creating a unit square mesh and interpolating a function # into a first order Lagrange space mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, cell_type=CellType.quadrilateral) V = FunctionSpace(mesh, ("Lagrange", 1)) u = Function(V, dtype=np.float64) u.interpolate(lambda x: np.sin(np.pi * x[0]) * np.sin(2 * x[1] * np.pi)) # As we want to visualize the function u, we have to create a grid to # attached the dof values to We do this by creating a topology and # geometry based on the function space V cells, types, x = plot.create_vtk_mesh(V) grid = pyvista.UnstructuredGrid(cells, types, x) grid.point_data["u"] = u.x.array # We set the function "u" as the active scalar for the mesh, and warp # the mesh in z-direction by its values grid.set_active_scalars("u") warped = grid.warp_by_scalar() # We create a plotting window consisting of to plots, one of the scalar # values, and one where the mesh is warped by these values subplotter = pyvista.Plotter(shape=(1, 2)) subplotter.subplot(0, 0) subplotter.add_text("Scalar countour field", font_size=14, color="black", position="upper_edge") subplotter.add_mesh(grid, show_edges=True, show_scalar_bar=True) subplotter.view_xy() subplotter.subplot(0, 1) subplotter.add_text("Warped function", position="upper_edge", font_size=14, color="black") sargs = dict(height=0.8, width=0.1, vertical=True, position_x=0.05, position_y=0.05, fmt="%1.2e", title_font_size=40, color="black", label_font_size=25) subplotter.set_position([-3, 2.6, 0.3]) subplotter.set_focus([3, -1, -0.15]) subplotter.set_viewup([0, 0, 1]) subplotter.add_mesh(warped, show_edges=True, scalar_bar_args=sargs) if pyvista.OFF_SCREEN: subplotter.screenshot("2D_function_warp.png", transparent_background=transparent, window_size=[figsize, figsize]) else: subplotter.show()
def test_nonlinear_pde_snes(): """Test Newton solver for a simple nonlinear PDE""" # Create mesh and function space mesh = create_unit_square(MPI.COMM_WORLD, 12, 15) V = FunctionSpace(mesh, ("Lagrange", 1)) u = Function(V) v = TestFunction(V) F = inner(5.0, v) * dx - ufl.sqrt(u * u) * inner( grad(u), grad(v)) * dx - inner(u, v) * dx u_bc = Function(V) u_bc.x.array[:] = 1.0 bc = dirichletbc( u_bc, locate_dofs_geometrical( V, lambda x: np.logical_or(np.isclose(x[0], 0.0), np.isclose(x[0], 1.0)))) # Create nonlinear problem problem = NonlinearPDE_SNESProblem(F, u, bc) u.x.array[:] = 0.9 b = la.create_petsc_vector(V.dofmap.index_map, V.dofmap.index_map_bs) J = create_matrix(problem.a) # Create Newton solver and solve snes = PETSc.SNES().create() snes.setFunction(problem.F, b) snes.setJacobian(problem.J, J) snes.setTolerances(rtol=1.0e-9, max_it=10) snes.getKSP().setType("preonly") snes.getKSP().setTolerances(rtol=1.0e-9) snes.getKSP().getPC().setType("lu") snes.solve(None, u.vector) assert snes.getConvergedReason() > 0 assert snes.getIterationNumber() < 6 # Modify boundary condition and solve again u_bc.x.array[:] = 0.6 snes.solve(None, u.vector) assert snes.getConvergedReason() > 0 assert snes.getIterationNumber() < 6
def test_custom_mesh_loop_ctypes_rank2(): """Test numba assembler for bilinear form""" # Create mesh and function space mesh = create_unit_square(MPI.COMM_WORLD, 64, 64) V = FunctionSpace(mesh, ("Lagrange", 1)) # Extract mesh and dofmap data num_owned_cells = mesh.topology.index_map(mesh.topology.dim).size_local num_cells = num_owned_cells + mesh.topology.index_map( mesh.topology.dim).num_ghosts x_dofs = mesh.geometry.dofmap.array.reshape(num_cells, 3) x = mesh.geometry.x dofmap = V.dofmap.list.array.reshape(num_cells, 3).astype(np.dtype(PETSc.IntType)) # Generated case with general assembler u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = form(inner(u, v) * dx) A0 = assemble_matrix(a) A0.assemble() A0.zeroEntries() start = time.time() dolfinx.fem.assemble_matrix(A0, a) end = time.time() print("Time (C++, pass 2):", end - start) A0.assemble() # Custom case A1 = A0.copy() for i in range(2): A1.zeroEntries() mat = A1.handle start = time.time() assemble_matrix_ctypes(mat, (x_dofs, x), dofmap, num_owned_cells, MatSetValues_ctypes, PETSc.InsertMode.ADD_VALUES) end = time.time() print("Time (numba, pass {}): {}".format(i, end - start)) A1.assemble() assert (A0 - A1).norm() == pytest.approx(0.0, abs=1.0e-9)
def test_vector_element(): # VectorFunctionSpace containing a scalar should work mesh = create_unit_square(MPI.COMM_WORLD, 1, 1, CellType.triangle, GhostMode.shared_facet) U = VectorFunctionSpace(mesh, ("P", 2)) u = ufl.TrialFunction(U) v = ufl.TestFunction(U) a = form(ufl.inner(u, v) * ufl.dx) A = dolfinx.fem.petsc.assemble_matrix(a) A.assemble() with pytest.raises(ValueError): # VectorFunctionSpace containing a vector should throw an error rather than segfaulting U = VectorFunctionSpace(mesh, ("RT", 2)) u = ufl.TrialFunction(U) v = ufl.TestFunction(U) a = form(ufl.inner(u, v) * ufl.dx) A = dolfinx.fem.petsc.assemble_matrix(a) A.assemble()
def test_2D_lagrange_to_curl(order): mesh = create_unit_square(MPI.COMM_WORLD, 3, 4) V = FunctionSpace(mesh, ("N1curl", order)) u = Function(V) W = FunctionSpace(mesh, ("Lagrange", order)) u0 = Function(W) u0.interpolate(lambda x: -x[1]) u1 = Function(W) u1.interpolate(lambda x: x[0]) f = ufl.as_vector((u0, u1)) f_expr = Expression(f, V.element.interpolation_points) u.interpolate(f_expr) x = ufl.SpatialCoordinate(mesh) f_ex = ufl.as_vector((-x[1], x[0])) assert np.isclose( np.abs(assemble_scalar(form(ufl.inner(u - f_ex, u - f_ex) * ufl.dx))), 0)
def test_coefficents_non_constant(): "Test packing coefficients with non-constant values" mesh = create_unit_square(MPI.COMM_WORLD, 3, 5) V = FunctionSpace( mesh, ("Lagrange", 3)) # degree 3 so that interpolation is exact u = Function(V) u.interpolate(lambda x: x[0] * x[1]**2) x = SpatialCoordinate(mesh) v = ufl.TestFunction(V) # -- Volume integral vector F = form((ufl.inner(u, v) - ufl.inner(x[0] * x[1]**2, v)) * dx) b0 = assemble_vector(F) b0.assemble() assert np.linalg.norm(b0.array) == pytest.approx(0.0) # -- Exterior facet integral vector F = form((ufl.inner(u, v) - ufl.inner(x[0] * x[1]**2, v)) * ds) b0 = assemble_vector(F) b0.assemble() assert np.linalg.norm(b0.array) == pytest.approx(0.0) # -- Interior facet integral vector V = FunctionSpace(mesh, ("DG", 3)) # degree 3 so that interpolation is exact u0 = Function(V) u0.interpolate(lambda x: x[1]**2) u1 = Function(V) u1.interpolate(lambda x: x[0]) x = SpatialCoordinate(mesh) v = ufl.TestFunction(V) F = (ufl.inner(u1('+') * u0('-'), ufl.avg(v)) - ufl.inner(x[0] * x[1]**2, ufl.avg(v))) * ufl.dS F = form(F) b0 = assemble_vector(F) b0.assemble() assert np.linalg.norm(b0.array) == pytest.approx(0.0)
def test_basic_assembly_petsc_matrixcsr(mode): mesh = create_unit_square(MPI.COMM_WORLD, 12, 12, ghost_mode=mode) V = FunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = inner(u, v) * dx + inner(u, v) * ds a = form(a) A0 = fem.assemble_matrix(a) A0.finalize() assert isinstance(A0, la.MatrixCSRMetaClass) A1 = fem.petsc.assemble_matrix(a) A1.assemble() assert isinstance(A1, PETSc.Mat) assert np.sqrt(A0.norm_squared()) == pytest.approx(A1.norm()) V = VectorFunctionSpace(mesh, ("Lagrange", 1)) u, v = ufl.TrialFunction(V), ufl.TestFunction(V) a = form(inner(u, v) * dx + inner(u, v) * ds) with pytest.raises(RuntimeError): A0 = fem.assemble_matrix(a)