def test_vtx_mesh(tempdir, dim, simplex): filename = os.path.join(tempdir, "mesh_vtx.bp") mesh = generate_mesh(dim, simplex) with VTXWriter(mesh.comm, filename, mesh) as f: f.write(0.0) mesh.geometry.x[:, 1] += 0.1 f.write(0.1)
def test_vtx_functions_fail(tempdir, dim, simplex): "Test for error when elements differ" mesh = generate_mesh(dim, simplex) v = Function(VectorFunctionSpace(mesh, ("Lagrange", 2))) w = Function(FunctionSpace(mesh, ("Lagrange", 1))) filename = os.path.join(tempdir, "v.bp") with pytest.raises(RuntimeError): VTXWriter(mesh.comm, filename, [v, w])
def test_vtx_different_meshes_function(tempdir, simplex): "Test for error when functions do not share a mesh" mesh = generate_mesh(2, simplex) v = Function(FunctionSpace(mesh, ("Lagrange", 1))) mesh2 = generate_mesh(2, simplex) w = Function(FunctionSpace(mesh2, ("Lagrange", 1))) filename = os.path.join(tempdir, "v.bp") with pytest.raises(RuntimeError): VTXWriter(mesh.comm, filename, [v, w])
def test_second_order_vtx(tempdir): filename = os.path.join(tempdir, "mesh_fides.bp") points = np.array([[0, 0, 0], [1, 0, 0], [0.5, 0, 0]], dtype=np.float64) cells = np.array([[0, 1, 2]], dtype=np.int32) cell = ufl.Cell("interval", geometric_dimension=points.shape[1]) domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 2)) mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain) with VTXWriter(mesh.comm, filename, mesh) as f: f.write(0.0)
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_vtx_functions(tempdir, dim, simplex): "Test saving high order Lagrange functions" mesh = generate_mesh(dim, simplex) V = VectorFunctionSpace(mesh, ("DG", 2)) v = Function(V) bs = V.dofmap.index_map_bs def vel(x): values = np.zeros((dim, x.shape[1])) values[0] = x[1] values[1] = x[0] return values v.interpolate(vel) W = FunctionSpace(mesh, ("DG", 2)) w = Function(W) w.interpolate(lambda x: x[0] + x[1]) filename = os.path.join(tempdir, "v.bp") f = VTXWriter(mesh.comm, filename, [v, w]) # Set two cells to 0 for c in [0, 1]: dofs = np.asarray([V.dofmap.cell_dofs(c) * bs + b for b in range(bs)], dtype=np.int32) v.x.array[dofs] = 0 w.x.array[W.dofmap.cell_dofs(c)] = 1 v.x.scatter_forward() w.x.scatter_forward() # Save twice and update geometry for t in [0.1, 1]: mesh.geometry.x[:, :2] += 0.1 f.write(t) f.close()
def demo_periodic3D(celltype: CellType): # Create mesh and finite element if celltype == CellType.tetrahedron: # Tet setup N = 10 mesh = create_unit_cube(MPI.COMM_WORLD, N, N, N) V = fem.VectorFunctionSpace(mesh, ("CG", 1)) else: # Hex setup N = 10 mesh = create_unit_cube(MPI.COMM_WORLD, N, N, N, CellType.hexahedron) V = fem.VectorFunctionSpace(mesh, ("CG", 2)) def dirichletboundary(x: NDArray[np.float64]) -> NDArray[np.bool_]: return np.logical_or( np.logical_or(np.isclose(x[1], 0), np.isclose(x[1], 1)), np.logical_or(np.isclose(x[2], 0), np.isclose(x[2], 1))) # Create Dirichlet boundary condition zero = PETSc.ScalarType([0, 0, 0]) geometrical_dofs = fem.locate_dofs_geometrical(V, dirichletboundary) bc = fem.dirichletbc(zero, geometrical_dofs, V) bcs = [bc] def PeriodicBoundary(x): return np.isclose(x[0], 1) facets = locate_entities_boundary(mesh, mesh.topology.dim - 1, PeriodicBoundary) arg_sort = np.argsort(facets) mt = meshtags(mesh, mesh.topology.dim - 1, facets[arg_sort], np.full(len(facets), 2, dtype=np.int32)) def periodic_relation(x): out_x = np.zeros(x.shape) out_x[0] = 1 - x[0] out_x[1] = x[1] out_x[2] = x[2] return out_x with Timer("~~Periodic: Compute mpc condition"): mpc = dolfinx_mpc.MultiPointConstraint(V) mpc.create_periodic_constraint_topological(V.sub(0), mt, 2, periodic_relation, bcs, 1) mpc.finalize() # Define variational problem u = TrialFunction(V) v = TestFunction(V) a = inner(grad(u), grad(v)) * dx x = SpatialCoordinate(mesh) dx_ = x[0] - 0.9 dy_ = x[1] - 0.5 dz_ = x[2] - 0.1 f = as_vector((x[0] * sin(5.0 * pi * x[1]) + 1.0 * exp(-(dx_ * dx_ + dy_ * dy_ + dz_ * dz_) / 0.02), 0.1 * dx_ * dz_, 0.1 * dx_ * dy_)) rhs = inner(f, v) * dx petsc_options: Dict[str, Union[str, float, int]] if complex_mode: rtol = 1e-16 petsc_options = {"ksp_type": "preonly", "pc_type": "lu"} else: rtol = 1e-8 petsc_options = { "ksp_type": "cg", "ksp_rtol": rtol, "pc_type": "hypre", "pc_hypre_typ": "boomeramg", "pc_hypre_boomeramg_max_iter": 1, "pc_hypre_boomeramg_cycle_type": "v", "pc_hypre_boomeramg_print_statistics": 1 } problem = LinearProblem(a, rhs, mpc, bcs, petsc_options=petsc_options) u_h = problem.solve() # --------------------VERIFICATION------------------------- print("----Verification----") u_ = fem.Function(V) u_.x.array[:] = 0 org_problem = fem.petsc.LinearProblem(a, rhs, u=u_, bcs=bcs, petsc_options=petsc_options) with Timer("~Periodic: Unconstrained solve"): org_problem.solve() it = org_problem.solver.getIterationNumber() print(f"Unconstrained solver iterations: {it}") # Write solutions to file ext = "tet" if celltype == CellType.tetrahedron else "hex" u_.name = "u_" + ext + "_unconstrained" # NOTE: Workaround as tabulate dof coordinates does not like extra ghosts u_out = fem.Function(V) old_local = u_out.x.map.size_local * u_out.x.bs old_ghosts = u_out.x.map.num_ghosts * u_out.x.bs mpc_local = u_h.x.map.size_local * u_h.x.bs assert (old_local == mpc_local) u_out.x.array[:old_local + old_ghosts] = u_h.x.array[:mpc_local + old_ghosts] u_out.name = "u_" + ext fname = f"results/demo_periodic3d_{ext}.bp" out_periodic = VTXWriter(MPI.COMM_WORLD, fname, u_out) out_periodic.write(0) out_periodic.close() root = 0 with Timer("~Demo: Verification"): dolfinx_mpc.utils.compare_mpc_lhs(org_problem.A, problem.A, mpc, root=root) dolfinx_mpc.utils.compare_mpc_rhs(org_problem.b, problem.b, mpc, root=root) # Gather LHS, RHS and solution on one process A_csr = dolfinx_mpc.utils.gather_PETScMatrix(org_problem.A, root=root) K = dolfinx_mpc.utils.gather_transformation_matrix(mpc, root=root) L_np = dolfinx_mpc.utils.gather_PETScVector(org_problem.b, root=root) u_mpc = dolfinx_mpc.utils.gather_PETScVector(u_h.vector, root=root) if MPI.COMM_WORLD.rank == root: KTAK = K.T * A_csr * K reduced_L = K.T @ L_np # Solve linear system d = scipy.sparse.linalg.spsolve(KTAK, reduced_L) # Back substitution to full solution vector uh_numpy = K @ d assert np.allclose(uh_numpy, u_mpc, rtol=rtol)
def test_vtx_single_function(tempdir, dim, simplex): "Test saving a single first order Lagrange functions" mesh = generate_mesh(dim, simplex) v = Function(FunctionSpace(mesh, ("Lagrange", 1))) filename = os.path.join(tempdir, "v.bp") writer = VTXWriter(mesh.comm, filename, v) writer.write(0) writer.close() filename = os.path.join(tempdir, "v2.bp") writer = VTXWriter(mesh.comm, filename, v._cpp_object) writer.write(0) writer.close()