def test_mesh_topology_lifetime(): """Check that lifetime of Mesh.topology is bound to underlying mesh object""" mesh = UnitSquareMesh(MPI.comm_world, 4, 4) rc = sys.getrefcount(mesh) topology = mesh.topology assert sys.getrefcount(mesh) == rc + 1 del topology assert sys.getrefcount(mesh) == rc
def __init__(self): self.mesh = UnitSquareMesh(40, 40, "left/right") self.V = FunctionSpace(self.mesh, "Lagrange", 1) self.bc = DirichletBC(self.V, 0.0, "on_boundary") u = TrialFunction(self.V) v = TestFunction(self.V) self.a = assemble(dot(grad(u), grad(v)) * dx) self.m = assemble(u * v * dx)
def test_save_2d_vector(tempdir, encoding): filename = os.path.join(tempdir, "u_2dv.xdmf") mesh = UnitSquareMesh(MPI.comm_world, 16, 16) V = VectorFunctionSpace(mesh, ("Lagrange", 2)) u = Function(V) u.vector().set(1.0 + (1j if has_petsc_complex else 0)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(u)
def test_compute_closest_entity_2d(): reference = (1, 1.0) p = Point(-1.0, 0.01) mesh = UnitSquareMesh(MPI.comm_world, 16, 16) tree = BoundingBoxTree(mesh, mesh.topology.dim) entity, distance = tree.compute_closest_entity(p, mesh) assert entity == reference[0] assert round(distance - reference[1], 7) == 0
def mesh(): mesh = UnitSquareMesh(3, 3) assert MPI.size(mesh.mpi_comm()) in (1, 2, 3, 4) # 1 processor -> test serial case # 2 and 3 processors -> test case where submesh in contained only on one processor # 4 processors -> test case where submesh is shared by two processors, # resulting in shared facets and vertices return mesh
def test_save_2d_mesh(tempfile, file_options): mesh = UnitSquareMesh(MPI.comm_world, 32, 32) VTKFile(tempfile + "mesh.pvd", "ascii").write(mesh) f = VTKFile(tempfile + "mesh.pvd", "ascii") f.write(mesh, 0.) f.write(mesh, 1.) for file_option in file_options: VTKFile(tempfile + "mesh.pvd", file_option).write(mesh)
def __init__(self): mesh = UnitSquareMesh(200, 200) self.V = FunctionSpace(mesh, 'Lagrange', 2) test, trial = TestFunction(self.V), TrialFunction(self.V) M = assemble(inner(test, trial) * dx) #self.M = assemble(inner(test, trial)*dx) self.solverM = KrylovSolver("cg", "amg") self.solverM.set_operator(M)
def test_is_zero_simple_vector_expressions(): mesh = UnitSquareMesh(4, 4) V = FunctionSpace(mesh, 'CG', 1) v = TestFunction(V) u = TrialFunction(V) check_is_zero(dot(as_vector([Zero(), u]), as_vector([Zero(), v])), 1) check_is_zero(dot(as_vector([Zero(), u]), as_vector([v, Zero()])), 0)
def test_mg_solver_laplace(): # Create meshes and function spaces meshes = [UnitSquareMesh(N, N) for N in [16, 32, 64]] V = [FunctionSpace(mesh, "Lagrange", 1) for mesh in meshes] # Create variational problem on fine grid u, v = TrialFunction(V[-1]), TestFunction(V[-1]) a = dot(grad(u), grad(v)) * dx L = v * dx bc0 = Function(V[-1]) bc = DirichletBC(V[-1], bc0, "on_boundary") A, b = assemble_system(a, L, bc) # Create collection of PETSc DM objects dm_collection = PETScDMCollection(V) # Create PETSc Krylov solver and set operator solver = PETScKrylovSolver() solver.set_operator(A) # Set PETSc solver type PETScOptions.set("ksp_type", "richardson") PETScOptions.set("pc_type", "mg") # Set PETSc MG type and levels PETScOptions.set("pc_mg_levels", len(V)) PETScOptions.set("pc_mg_galerkin") # Set smoother PETScOptions.set("mg_levels_ksp_type", "chebyshev") PETScOptions.set("mg_levels_pc_type", "jacobi") # Set tolerance and monitor residual PETScOptions.set("ksp_monitor_true_residual") PETScOptions.set("ksp_atol", 1.0e-12) PETScOptions.set("ksp_rtol", 1.0e-12) solver.set_from_options() # Get fine grid DM and attach fine grid DM to solver solver.set_dm(dm_collection.get_dm(-1)) solver.set_dm_active(False) # Solve x = PETScVector() solver.solve(x, b) # Check multigrid solution against LU solver solution solver = LUSolver(A) # noqa x_lu = PETScVector() solver.solve(x_lu, b) assert round((x - x_lu).norm("l2"), 10) == 0 # Clear all PETSc options from petsc4py import PETSc opts = PETSc.Options() for key in opts.getAll(): opts.delValue(key)
def test_append_and_load_mesh_functions(tempdir, encoding, data_type): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") dtype_str, dtype = data_type meshes = [ UnitSquareMesh(MPI.comm_world, 12, 12), UnitCubeMesh(MPI.comm_world, 2, 2, 2) ] for mesh in meshes: dim = mesh.topology.dim vf = MeshFunction(dtype_str, mesh, 0, 0) vf.rename("vertices") ff = MeshFunction(dtype_str, mesh, mesh.topology.dim - 1, 0) ff.rename("facets") cf = MeshFunction(dtype_str, mesh, mesh.topology.dim, 0) cf.rename("cells") if (MPI.size(mesh.mpi_comm()) == 1): for vertex in Vertices(mesh): vf[vertex] = dtype(vertex.index()) for facet in Facets(mesh): ff[facet] = dtype(facet.index()) for cell in Cells(mesh): cf[cell] = dtype(cell.index()) else: for vertex in Vertices(mesh): vf[vertex] = dtype(vertex.global_index()) for facet in Facets(mesh): ff[facet] = dtype(facet.global_index()) for cell in Cells(mesh): cf[cell] = dtype(cell.global_index()) filename = os.path.join(tempdir, "appended_mf_%dD.xdmf" % dim) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as xdmf: xdmf.write(mesh) xdmf.write(vf) xdmf.write(ff) xdmf.write(cf) with XDMFFile(mesh.mpi_comm(), filename) as xdmf: read_function = getattr(xdmf, "read_mf_" + dtype_str) vf_in = read_function(mesh, "vertices") ff_in = read_function(mesh, "facets") cf_in = read_function(mesh, "cells") diff = 0 for vertex in Vertices(mesh): diff += (vf_in[vertex] - vf[vertex]) for facet in Facets(mesh): diff += (ff_in[facet] - ff[facet]) for cell in Cells(mesh): diff += (cf_in[cell] - cf[cell]) assert diff == 0
def amg_solve(N, method): # Elasticity parameters E = 1.0e9 nu = 0.3 mu = E / (2.0 * (1.0 + nu)) lmbda = E * nu / ((1.0 + nu) * (1.0 - 2.0 * nu)) # Stress computation def sigma(v): return 2.0 * mu * sym(grad(v)) + lmbda * tr(sym( grad(v))) * Identity(2) # Define problem mesh = UnitSquareMesh(MPI.comm_world, N, N) V = VectorFunctionSpace(mesh, 'Lagrange', 1) bc0 = Function(V) with bc0.vector.localForm() as bc_local: bc_local.set(0.0) def boundary(x, 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_distance_triangle(): mesh = UnitSquareMesh(MPI.comm_self, 1, 1) cell = Cell(mesh, 1) assert round( cell.distance(Point(-1.0, -1.0)._cpp_object) - numpy.sqrt(2), 7) == 0 assert round(cell.distance(Point(-1.0, 0.5)._cpp_object) - 1, 7) == 0 assert round(cell.distance(Point(0.5, 0.5)._cpp_object) - 0.0, 7) == 0
def cmscr1d_img_pb(img: np.array, alpha0: float, alpha1: float, alpha2: float, alpha3: float, beta: float, deriv='mesh') \ -> (np.array, np.array, float, float, bool): """Computes the L2-H1 mass conserving flow with source for a 1D image sequence with spatio-temporal and convective regularisation with periodic spatial boundary. Args: img (np.array): 1D image sequence of shape (m, n), where m is the number of time steps and n is the number of pixels. alpha0 (float): The spatial regularisation parameter for v. alpha1 (float): The temporal regularisation parameter for v. alpha2 (float): The spatial regularisation parameter for k. alpha3 (float): The temporal regularisation parameter for k. beta (float): The convective regularisation parameter. deriv (str): Specifies how to approximate pertial derivatives. When set to 'mesh' it uses FEniCS built in function. Returns: v (np.array): A velocity array of shape (m, n). k (np.array): A source array of shape (m, n). res (float): The residual. fun (float): The function value. converged (bool): True if Newton's method converged. """ # Check for valid arguments. valid = {'mesh'} if deriv not in valid: raise ValueError("Argument 'deriv' must be one of %r." % valid) # Create mesh. m, n = img.shape mesh = UnitSquareMesh(m - 1, n - 1) # Define function space. V = dh.create_function_space(mesh, 'periodic') W = dh.create_vector_function_space(mesh, 'periodic') # Convert array to function. f = Function(V) f.vector()[:] = dh.img2funvec_pb(img) # Compute partial derivatives. ft, fx = f.dx(0), f.dx(1) # Compute velocity. v, k, res, fun, converged = cmscr1d_weak_solution(W, f, ft, fx, alpha0, alpha1, alpha2, alpha3, beta) # Convert back to array and return. v = dh.funvec2img(v.vector().get_local(), m, n) k = dh.funvec2img(k.vector().get_local(), m, n) return v, k, res, fun, converged
def test_distance_triangle(): mesh = UnitSquareMesh(MPI.comm_self, 1, 1) cell = Cell(mesh, 1) assert round( cell.distance(numpy.array([-1.0, -1.0, 0.0])) - numpy.sqrt(2), 7) == 0 assert round(cell.distance(numpy.array([-1.0, 0.5, 0.0])) - 1, 7) == 0 assert round(cell.distance(numpy.array([0.5, 0.5, 0.0])) - 0.0, 7) == 0
def test_computed_norms_against_references(): # Reference values for norm of solution vector reference = { ("16x16 unit tri square", 1): 9.547454087328376, ("16x16 unit tri square", 2): 18.42366670418269, ("16x16 unit tri square", 3): 27.29583104732836, ("16x16 unit tri square", 4): 36.16867128121694, ("4x4x4 unit tet cube", 1): 12.23389289626038, ("4x4x4 unit tet cube", 2): 28.96491629163837, ("4x4x4 unit tet cube", 3): 49.97350551329799, ("4x4x4 unit tet cube", 4): 74.49938266409099, ("16x16 unit quad square", 1): 9.550848071820747, ("16x16 unit quad square", 2): 18.423668706176354, ("16x16 unit quad square", 3): 27.295831017251672, ("16x16 unit quad square", 4): 36.168671281610855, ("4x4x4 unit hex cube", 1): 12.151954087339782, ("4x4x4 unit hex cube", 2): 28.965646690046885, ("4x4x4 unit hex cube", 3): 49.97349423895635, ("4x4x4 unit hex cube", 4): 74.49938136593539 } # Mesh files and degrees to check meshes = [(UnitSquareMesh(MPI.comm_world, 16, 16), "16x16 unit tri square"), (UnitCubeMesh(MPI.comm_world, 4, 4, 4), "4x4x4 unit tet cube")] # (UnitSquareMesh(MPI.comm_world, 16, 16, CellType.Type.quadrilateral), "16x16 unit quad square"), # (UnitCubeMesh(MPI.comm_world, 4, 4, 4, CellType.Type.hexahedron), "4x4x4 unit hex cube")] degrees = [1, 2] # For MUMPS, increase estimated require memory increase. Typically # required for high order elements on small meshes in 3D PETScOptions.set("mat_mumps_icntl_14", 40) # Iterate over test cases and collect results results = [] for mesh in meshes: for degree in degrees: gc_barrier() norm = compute_norm(mesh[0], degree) results.append((mesh[1], degree, norm)) # Change option back to default PETScOptions.set("mat_mumps_icntl_14", 20) # Check results errors = check_results(results, reference, tol) # Print errors for debugging if they fail if errors: print_errors(errors) # Print results for use as reference if any(e[-1] is None for e in errors): # e[-1] is diff print_reference(results) # A passing test should have no errors assert len(errors) == 0 # See stdout for detailed norms and diffs.
def test_save_2d_scalar(tempdir, encoding): filename = os.path.join(tempdir, "u2.xdmf") mesh = UnitSquareMesh(MPI.comm_world, 16, 16) # FIXME: This randomly hangs in parallel V = FunctionSpace(mesh, ("Lagrange", 2)) u = Function(V) u.vector.set(1.0 + (1j if has_petsc_complex else 0)) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(u)
def _test_eigen_solver_sparse(callback_type): from rbnics.backends.dolfin import EigenSolver # Define mesh mesh = UnitSquareMesh(10, 10) # Define function space V_element = VectorElement("Lagrange", mesh.ufl_cell(), 2) Q_element = FiniteElement("Lagrange", mesh.ufl_cell(), 1) W_element = MixedElement(V_element, Q_element) W = FunctionSpace(mesh, W_element) # Create boundaries class Wall(SubDomain): def inside(self, x, on_boundary): return on_boundary and (x[1] < 0 + DOLFIN_EPS or x[1] > 1 - DOLFIN_EPS) boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1) boundaries.set_all(0) wall = Wall() wall.mark(boundaries, 1) # Define variational problem vq = TestFunction(W) (v, q) = split(vq) up = TrialFunction(W) (u, p) = split(up) lhs = inner(grad(u), grad(v)) * dx - div(v) * p * dx - div(u) * q * dx rhs = -inner(p, q) * dx # Define boundary condition bc = [DirichletBC(W.sub(0), Constant((0., 0.)), boundaries, 1)] # Define eigensolver depending on callback type assert callback_type in ("form callbacks", "tensor callbacks") if callback_type == "form callbacks": solver = EigenSolver(W, lhs, rhs, bc) elif callback_type == "tensor callbacks": LHS = assemble(lhs) RHS = assemble(rhs) solver = EigenSolver(W, LHS, RHS, bc) # Solve the eigenproblem solver.set_parameters({ "linear_solver": "mumps", "problem_type": "gen_non_hermitian", "spectrum": "target real", "spectral_transform": "shift-and-invert", "spectral_shift": 1.e-5 }) solver.solve(1) r, c = solver.get_eigenvalue(0) assert abs(c) < 1.e-10 assert r > 0., "r = " + str(r) + " is not positive" print("Sparse inf-sup constant: ", sqrt(r)) return (sqrt(r), solver.condensed_A, solver.condensed_B)
def test_mesh_point_2d(): "Test mesh-point intersection in 2D" point = Point(0.1, 0.2) mesh = UnitSquareMesh(16, 16) intersection = intersect(mesh, point) assert intersection.intersected_cells() == [98]
def test_normal(): "Test that the normal() method is wrapped" mesh = UnitSquareMesh(4, 4) for facet in facets(mesh): n = facet.normal() nx, ny, nz = n.x(), n.y(), n.z() assert isinstance(nx, float) assert isinstance(ny, float) assert isinstance(nz, float)
def test_vector_p2_2d(): meshc = UnitSquareMesh(MPI.comm_world, 5, 4) meshf = UnitSquareMesh(MPI.comm_world, 5, 8) Vc = VectorFunctionSpace(meshc, "CG", 2) Vf = VectorFunctionSpace(meshf, "CG", 2) u = Expression(("x[0] + 2*x[1]*x[0]", "4*x[0]*x[1]"), degree=2) uc = interpolate(u, Vc) uf = interpolate(u, Vf) mat = PETScDMCollection.create_transfer_matrix(Vc, Vf).mat() Vuc = Function(Vf) mat.mult(uc.vector().vec(), Vuc.vector().vec()) diff = Vuc.vector() diff.vec().axpy(-1, uf.vector().vec()) assert diff.norm(Norm.l2) < 1.0e-12
def testFacetArea(): references = [(UnitIntervalMesh(MPI.comm_world, 1), 2, 2), (UnitSquareMesh( MPI.comm_world, 1, 1), 4, 4), (UnitCubeMesh(MPI.comm_world, 1, 1, 1), 6, 3)] for mesh, surface, ref_int in references: c0 = ufl.FacetArea(mesh) c1 = dolfin.FacetArea(mesh) assert (c0) assert (c1)
def test_save_and_load_2d_mesh(tempdir, encoding): filename = os.path.join(tempdir, "mesh_2D.xdmf") mesh = UnitSquareMesh(MPI.comm_world, 32, 32) with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(mesh) with XDMFFile(MPI.comm_world, filename) as file: mesh2 = file.read_mesh(cpp.mesh.GhostMode.none) assert mesh.num_entities_global(0) == mesh2.num_entities_global(0) dim = mesh.topology.dim assert mesh.num_entities_global(dim) == mesh2.num_entities_global(dim)
def mesh_generator(n): mesh = UnitSquareMesh(n, n, "left/right") dim = mesh.topology().dim() domains = MeshFunction("size_t", mesh, dim) domains.set_all(0) dx = Measure("dx", subdomain_data=domains) boundaries = MeshFunction("size_t", mesh, dim - 1) boundaries.set_all(0) ds = Measure("ds", subdomain_data=boundaries) return mesh, dx, ds
def test_normal(): "Test that the normal() method is wrapped" mesh = UnitSquareMesh(MPI.comm_world, 4, 4) mesh.init(1) for facet in Facets(mesh): n = facet.normal() nx, ny, nz = n[0], n[1], n[2] assert isinstance(nx, float) assert isinstance(ny, float) assert isinstance(nz, float)
def test_save_2d_tensor(tempdir, encoding): if invalid_config(encoding): pytest.skip("XDMF unsupported in current configuration") filename = os.path.join(tempdir, "tensor.xdmf") mesh = UnitSquareMesh(MPI.comm_world, 16, 16) u = Function(TensorFunctionSpace(mesh, "Lagrange", 2)) u.vector()[:] = 1.0 with XDMFFile(mesh.mpi_comm(), filename, encoding=encoding) as file: file.write(u)
def test_save_2d_tensor(tempfile, file_options): mesh = UnitSquareMesh(MPI.comm_world, 16, 16) u = Function(TensorFunctionSpace(mesh, ("Lagrange", 2))) u.vector()[:] = 1.0 VTKFile(tempfile + "u.pvd", "ascii").write(u) f = VTKFile(tempfile + "u.pvd", "ascii") f.write(u, 0.) f.write(u, 1.) for file_option in file_options: VTKFile(tempfile + "u.pvd", file_option).write(u)
def test_ghost_2d(mode): N = 8 num_cells = N * N * 2 mesh = UnitSquareMesh(MPI.comm_world, N, N, ghost_mode=mode) if MPI.size(mesh.mpi_comm()) > 1: assert MPI.sum(mesh.mpi_comm(), mesh.num_cells()) > num_cells assert mesh.num_entities_global(0) == 81 assert mesh.num_entities_global(2) == num_cells
def test_mesh_point_2d(self): "Test mesh-point intersection in 2D" point = Point(0.1, 0.2) mesh = UnitSquareMesh(16, 16) intersection = intersect(mesh, point) if MPI.size(mesh.mpi_comm()) == 1: self.assertEqual(intersection.intersected_cells(), [98])
def test_form_splitter_matrices(shape): mesh = UnitSquareMesh(dolfin.MPI.comm_self, 3, 3) Vu = FunctionSpace(mesh, 'DG', 2) Vp = FunctionSpace(mesh, 'DG', 1) def define_eq(u, v, p, q): "A simple Stokes-like coupled weak form" eq = Constant(2) * dot(u, v) * dx eq += dot(grad(p), v) * dx eq -= dot(Constant([1, 1]), v) * dx eq += dot(grad(q), u) * dx eq -= dot(Constant(0.3), q) * dx return eq if shape == (2, 2): eu = MixedElement([Vu.ufl_element(), Vu.ufl_element()]) ew = MixedElement([eu, Vp.ufl_element()]) W = FunctionSpace(mesh, ew) u, p = TrialFunctions(W) v, q = TestFunctions(W) u = as_vector([u[0], u[1]]) v = as_vector([v[0], v[1]]) elif shape == (3, 3): ew = MixedElement( [Vu.ufl_element(), Vu.ufl_element(), Vp.ufl_element()]) W = FunctionSpace(mesh, ew) u0, u1, p = TrialFunctions(W) v0, v1, q = TestFunctions(W) u = as_vector([u0, u1]) v = as_vector([v0, v1]) eq = define_eq(u, v, p, q) # Define coupled problem eq = define_eq(u, v, p, q) # Split the weak form into a saddle point block matrix system mat, vec = split_form_into_matrix(eq, W, W) # Check shape and that appropriate elements are none assert mat.shape == shape assert mat[-1, -1] is None for i in range(shape[0] - 1): for j in range(shape[1] - 1): if i != j: assert mat[i, j] is None # Check that the split matrices are identical with the # coupled matrix when reassembled into a single matrix compare_split_matrices(eq, mat, vec, W, W)
def setUp(self): mesh = UnitSquareMesh(5, 5, 'crossed') self.V = FunctionSpace(mesh, 'Lagrange', 2) u = interpolate(Expression('1 + 7*(pow(pow(x[0] - 0.5,2) +' + \ ' pow(x[1] - 0.5,2),0.5) > 0.2)'), self.V) test = TestFunction(self.V) trial = TrialFunction(self.V) m = test * trial * dx self.M = assemble(m) k = inner(u * nabla_grad(test), nabla_grad(trial)) * dx self.K = assemble(k)