def test_map_vtk_to_dolfin(vtk, dolfin, cell_type): p = perm_vtk(cell_type, len(vtk)) cell_p = np.array(vtk)[p] assert (cell_p == dolfin).all() p = np.argsort(perm_vtk(cell_type, len(vtk))) cell_p = np.array(dolfin)[p] assert (cell_p == vtk).all()
def xtest_read_write_p2_mesh(tempdir, encoding): pygmsh = pytest.importorskip("pygmsh") if MPI.COMM_WORLD.rank == 0: geom = pygmsh.opencascade.Geometry() geom.add_ball([0.0, 0.0, 0.0], 1.0, char_length=0.4) pygmsh_mesh = pygmsh.generate_mesh( geom, mesh_file_type="vtk", extra_gmsh_arguments=["-order", "2"]) cells, x = pygmsh_mesh.cells[-1].data, pygmsh_mesh.points pygmsh_cell = pygmsh_mesh.cells[-1].type cell_type, gdim, num_nodes = MPI.COMM_WORLD.bcast( [pygmsh_cell, x.shape[1], cells.shape[1]], root=0) else: cell_type, gdim, num_nodes = MPI.COMM_WORLD.bcast([None, None, None], root=0) cells, x = np.empty([0, num_nodes]), np.empty([0, gdim]) domain = ufl_mesh_from_gmsh(cell_type, gdim) cell_type = cpp.mesh.to_type(str(domain.ufl_cell())) cells = cells[:, perm_vtk(cell_type, cells.shape[1])] mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain) filename = os.path.join(tempdir, "tet10_mesh.xdmf") with XDMFFile(mesh.mpi_comm(), filename, "w", encoding=encoding) as xdmf: xdmf.write_mesh(mesh) with XDMFFile(mesh.mpi_comm(), filename, "r", encoding=encoding) as xdmf: mesh2 = xdmf.read_mesh() assert mesh.topology.index_map(0).size_global == mesh2.topology.index_map( 0).size_global dim = mesh.topology.dim assert mesh.topology.index_map( dim).size_global == mesh2.topology.index_map(dim).size_global
def test_fourth_order_quad(L, H, Z): """Test by comparing integration of z+x*y against sympy/scipy integration of a quad element. Z>0 implies curved element. *---------* 20-21-22-23-24-41--42--43--44 | | | | | | | 15 16 17 18 19 37 38 39 40 | | | | | | | 10 11 12 13 14 33 34 35 36 | | | | | | | 5 6 7 8 9 29 30 31 32 | | | | | *---------* 0--1--2--3--4--25--26--27--28 """ points = np.array([[0, 0, 0], [L / 4, 0, 0], [L / 2, 0, 0], # 0 1 2 [3 * L / 4, 0, 0], [L, 0, 0], # 3 4 [0, H / 4, -Z / 3], [L / 4, H / 4, -Z / 3], [L / 2, H / 4, -Z / 3], # 5 6 7 [3 * L / 4, H / 4, -Z / 3], [L, H / 4, -Z / 3], # 8 9 [0, H / 2, 0], [L / 4, H / 2, 0], [L / 2, H / 2, 0], # 10 11 12 [3 * L / 4, H / 2, 0], [L, H / 2, 0], # 13 14 [0, (3 / 4) * H, 0], [L / 4, (3 / 4) * H, 0], # 15 16 [L / 2, (3 / 4) * H, 0], [3 * L / 4, (3 / 4) * H, 0], # 17 18 [L, (3 / 4) * H, 0], [0, H, Z], [L / 4, H, Z], # 19 20 21 [L / 2, H, Z], [3 * L / 4, H, Z], [L, H, Z], # 22 23 24 [(5 / 4) * L, 0, 0], [(6 / 4) * L, 0, 0], # 25 26 [(7 / 4) * L, 0, 0], [2 * L, 0, 0], # 27 28 [(5 / 4) * L, H / 4, -Z / 3], [(6 / 4) * L, H / 4, -Z / 3], # 29 30 [(7 / 4) * L, H / 4, -Z / 3], [2 * L, H / 4, -Z / 3], # 31 32 [(5 / 4) * L, H / 2, 0], [(6 / 4) * L, H / 2, 0], # 33 34 [(7 / 4) * L, H / 2, 0], [2 * L, H / 2, 0], # 35 36 [(5 / 4) * L, 3 / 4 * H, 0], # 37 [(6 / 4) * L, 3 / 4 * H, 0], # 38 [(7 / 4) * L, 3 / 4 * H, 0], [2 * L, 3 / 4 * H, 0], # 39 40 [(5 / 4) * L, H, Z], [(6 / 4) * L, H, Z], # 41 42 [(7 / 4) * L, H, Z], [2 * L, H, Z]]) # 43 44 # VTK ordering cells = np.array([[0, 4, 24, 20, 1, 2, 3, 9, 14, 19, 21, 22, 23, 5, 10, 15, 6, 7, 8, 11, 12, 13, 16, 17, 18], [4, 28, 44, 24, 25, 26, 27, 32, 36, 40, 41, 42, 43, 9, 14, 19, 29, 30, 31, 33, 34, 35, 37, 38, 39]]) cells = cells[:, perm_vtk(CellType.quadrilateral, cells.shape[1])] cell = ufl.Cell("quadrilateral", geometric_dimension=points.shape[1]) domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 4)) mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain) def e2(x): return x[2] + x[0] * x[1] V = FunctionSpace(mesh, ("CG", 4)) u = Function(V) u.interpolate(e2) intu = assemble_scalar(u * dx(mesh)) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 5, 10, 15, 20] ref = sympy_scipy(points, nodes, 2 * L, H) assert ref == pytest.approx(intu, rel=1e-5)
def xtest_third_order_tri(): # *---*---*---* 3--11--10--2 # | \ | | \ | # * * * * 8 7 15 13 # | \ | | \ | # * * * * 9 14 6 12 # | \ | | \ | # *---*---*---* 0--4---5---1 for H in (1.0, 2.0): for Z in (0.0, 0.5): L = 1 points = np.array([ [0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z], # 0, 1, 2, 3 [L / 3, 0, 0], [2 * L / 3, 0, 0], # 4, 5 [2 * L / 3, H / 3, 0], [L / 3, 2 * H / 3, 0], # 6, 7 [0, 2 * H / 3, 0], [0, H / 3, 0], # 8, 9 [2 * L / 3, H, Z], [L / 3, H, Z], # 10, 11 [L, H / 3, 0], [L, 2 * H / 3, 0], # 12, 13 [L / 3, H / 3, 0], # 14 [2 * L / 3, 2 * H / 3, 0] ]) # 15 cells = np.array([[0, 1, 3, 4, 5, 6, 7, 8, 9, 14], [1, 2, 3, 12, 13, 10, 11, 7, 6, 15]]) cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])] mesh = Mesh(MPI.COMM_WORLD, CellType.triangle, points, cells, [], degree=3) def e2(x): return x[2] + x[0] * x[1] degree = mesh.geometry.dofmap_layout().degree() # Interpolate function V = FunctionSpace(mesh, ("CG", degree)) u = Function(V) u.interpolate(e2) intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 40})) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 9, 8, 3] ref = sympy_scipy(points, nodes, L, H) assert ref == pytest.approx(intu, rel=1e-6)
def test_third_order_tri(): # *---*---*---* 3--11--10--2 # | \ | | \ | # * * * * 8 7 15 13 # | \ | | \ | # * * * * 9 14 6 12 # | \ | | \ | # *---*---*---* 0--4---5---1 for H in (1.0, 2.0): for Z in (0.0, 0.5): L = 1 points = np.array([ [0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z], # 0, 1, 2, 3 [L / 3, 0, 0], [2 * L / 3, 0, 0], # 4, 5 [2 * L / 3, H / 3, 0], [L / 3, 2 * H / 3, 0], # 6, 7 [0, 2 * H / 3, 0], [0, H / 3, 0], # 8, 9 [2 * L / 3, H, Z], [L / 3, H, Z], # 10, 11 [L, H / 3, 0], [L, 2 * H / 3, 0], # 12, 13 [L / 3, H / 3, 0], # 14 [2 * L / 3, 2 * H / 3, 0] ]) # 15 cells = np.array([[0, 1, 3, 4, 5, 6, 7, 8, 9, 14], [1, 2, 3, 12, 13, 10, 11, 7, 6, 15]]) cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])] cell = ufl.Cell("triangle", geometric_dimension=points.shape[1]) domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 3)) mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain) def e2(x): return x[2] + x[0] * x[1] # Interpolate function V = FunctionSpace(mesh, ("Lagrange", 3)) u = Function(V) u.interpolate(e2) intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 40})) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 9, 8, 3] ref = sympy_scipy(points, nodes, L, H) assert ref == pytest.approx(intu, rel=1e-6)
def test_third_order_quad(L, H, Z): """Test by comparing integration of z+x*y against sympy/scipy integration of a quad element. Z>0 implies curved element. *---------* 3--8--9--2-22-23-17 | | | | | | | 11 14 15 7 26 27 21 | | | | | | | 10 12 13 6 24 25 20 | | | | | *---------* 0--4--5--1-18-19-16 """ points = np.array([[0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z], # 0 1 2 3 [L / 3, 0, 0], [2 * L / 3, 0, 0], # 4 5 [L, H / 3, 0], [L, 2 * H / 3, 0], # 6 7 [L / 3, H, Z], [2 * L / 3, H, Z], # 8 9 [0, H / 3, 0], [0, 2 * H / 3, 0], # 10 11 [L / 3, H / 3, 0], [2 * L / 3, H / 3, 0], # 12 13 [L / 3, 2 * H / 3, 0], [2 * L / 3, 2 * H / 3, 0], # 14 15 [2 * L, 0, 0], [2 * L, H, Z], # 16 17 [4 * L / 3, 0, 0], [5 * L / 3, 0, 0], # 18 19 [2 * L, H / 3, 0], [2 * L, 2 * H / 3, 0], # 20 21 [4 * L / 3, H, Z], [5 * L / 3, H, Z], # 22 23 [4 * L / 3, H / 3, 0], [5 * L / 3, H / 3, 0], # 24 25 [4 * L / 3, 2 * H / 3, 0], [5 * L / 3, 2 * H / 3, 0]]) # 26 27 # Change to multiple cells when matthews dof-maps work for quads cells = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [1, 16, 17, 2, 18, 19, 20, 21, 22, 23, 6, 7, 24, 25, 26, 27]]) cells = cells[:, perm_vtk(CellType.quadrilateral, cells.shape[1])] cell = ufl.Cell("quadrilateral", geometric_dimension=points.shape[1]) domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 3)) mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain) def e2(x): return x[2] + x[0] * x[1] # Interpolate function V = FunctionSpace(mesh, ("CG", 3)) u = Function(V) u.interpolate(e2) intu = assemble_scalar(u * dx(mesh)) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 3, 10, 11] ref = sympy_scipy(points, nodes, 2 * L, H) assert ref == pytest.approx(intu, rel=1e-6)
def test_fourth_order_tri(): L = 1 # *--*--*--*--* 3-21-20-19--2 # | \ | | \ | # * * * * * 10 9 24 23 18 # | \ | | \ | # * * * * * 11 15 8 22 17 # | \ | | \ | # * * * * * 12 13 14 7 16 # | \ | | \ | # *--*--*--*--* 0--4--5--6--1 for H in (1.0, 2.0): for Z in (0.0, 0.5): points = np.array( [[0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z], # 0, 1, 2, 3 [L / 4, 0, 0], [L / 2, 0, 0], [3 * L / 4, 0, 0], # 4, 5, 6 [3 / 4 * L, H / 4, Z / 2], [L / 2, H / 2, 0], # 7, 8 [L / 4, 3 * H / 4, 0], [0, 3 * H / 4, 0], # 9, 10 [0, H / 2, 0], [0, H / 4, Z / 2], # 11, 12 [L / 4, H / 4, Z / 2], [L / 2, H / 4, Z / 2], [L / 4, H / 2, 0], # 13, 14, 15 [L, H / 4, Z / 2], [L, H / 2, 0], [L, 3 * H / 4, 0], # 16, 17, 18 [3 * L / 4, H, Z], [L / 2, H, Z], [L / 4, H, Z], # 19, 20, 21 [3 * L / 4, H / 2, 0], [3 * L / 4, 3 * H / 4, 0], # 22, 23 [L / 2, 3 * H / 4, 0]] # 24 ) cells = np.array([[0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], [1, 2, 3, 16, 17, 18, 19, 20, 21, 9, 8, 7, 22, 23, 24]]) cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])] cell = ufl.Cell("triangle", geometric_dimension=points.shape[1]) domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 4)) mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain) def e2(x): return x[2] + x[0] * x[1] # Interpolate function V = FunctionSpace(mesh, ("Lagrange", 4)) u = Function(V) u.interpolate(e2) intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 50})) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 3, 10, 11, 12] ref = sympy_scipy(points, nodes, L, H) assert ref == pytest.approx(intu, rel=1e-4)
def test_gmsh_input_quad(order): pygmsh = pytest.importorskip("pygmsh") # Parameterize test if gmsh gets wider support R = 1 res = 0.2 if order == 2 else 0.2 algorithm = 2 if order == 2 else 5 element = "quad{0:d}".format(int((order + 1)**2)) geo = pygmsh.opencascade.Geometry() geo.add_raw_code("Mesh.ElementOrder={0:d};".format(order)) geo.add_ball([0, 0, 0], R, char_length=res) geo.add_raw_code("Recombine Surface {1};") geo.add_raw_code("Mesh.Algorithm = {0:d};".format(algorithm)) msh = pygmsh.generate_mesh(geo, verbose=True, dim=2) if order > 2: # Quads order > 3 have a gmsh specific ordering, and has to be # re-mapped msh_to_dolfin = np.array( [0, 3, 11, 10, 1, 2, 6, 7, 4, 9, 12, 15, 5, 8, 13, 14]) cells = np.zeros(msh.cells_dict[element].shape) for i in range(len(cells)): for j in range(len(msh_to_dolfin)): cells[i, j] = msh.cells_dict[element][i, msh_to_dolfin[j]] else: # XDMF does not support higher order quads cells = msh.cells_dict[ element][:, perm_vtk(CellType.quadrilateral, msh.cells_dict[element]. shape[1])] mesh = Mesh(MPI.COMM_WORLD, CellType.quadrilateral, msh.points, cells, [], degree=order) surface = assemble_scalar(1 * dx(mesh)) assert mesh.mpi_comm().allreduce(surface, op=MPI.SUM) == pytest.approx( 4 * np.pi * R * R, rel=1e-5)
def test_second_order_tri(): # Test second order mesh by computing volume of two cells # *-----*-----* 3----6-----2 # | \ | | \ | # | \ | | \ | # * * * 7 8 5 # | \ | | \ | # | \ | | \ | # *-----*-----* 0----4-----1 for H in (1.0, 2.0): for Z in (0.0, 0.5): L = 1 points = np.array([[0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z], [L / 2, 0, 0], [L, H / 2, 0], [L / 2, H, Z], [0, H / 2, 0], [L / 2, H / 2, 0]]) cells = np.array([[0, 1, 3, 4, 8, 7], [1, 2, 3, 5, 6, 8]]) cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])] mesh = Mesh(MPI.COMM_WORLD, CellType.triangle, points, cells, [], degree=2) def e2(x): return x[2] + x[0] * x[1] # Interpolate function V = FunctionSpace(mesh, ("CG", 2)) u = Function(V) u.interpolate(e2) intu = assemble_scalar( u * dx(mesh, metadata={"quadrature_degree": 20})) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 3, 7] ref = sympy_scipy(points, nodes, L, H) assert ref == pytest.approx(intu, rel=1e-6)
def test_quadrilateral_mesh_vtk(order): random.seed(13) points = [] points += [[i / order, 0] for i in range(order + 1)] for j in range(1, order): points += [[i / order + 0.1, j / order] for i in range(order + 1)] points += [[j / order, 1] for j in range(order + 1)] def coord_to_vertex(x, y): return (order + 1) * y + x # Make the cell, following https://blog.kitware.com/modeling-arbitrary-order-lagrange-finite-elements-in-the-visualization-toolkit/ # noqa: E501 cell = [ coord_to_vertex(i, j) for i, j in [(0, 0), (order, 0), (order, order), (0, order)] ] if order > 1: for i in range(1, order): cell.append(coord_to_vertex(i, 0)) for i in range(1, order): cell.append(coord_to_vertex(order, i)) for i in range(1, order): cell.append(coord_to_vertex(i, order)) for i in range(1, order): cell.append(coord_to_vertex(0, i)) for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(i, j)) cell = np.array(cell)[perm_vtk(CellType.quadrilateral, len(cell))] domain = ufl.Mesh( ufl.VectorElement("Q", ufl.Cell("quadrilateral", geometric_dimension=2), order)) check_cell_volume(points, cell, domain, 1)
def test_second_order_quad(L, H, Z): """ Test by comparing integration of z+x*y against sympy/scipy integration of a quad element. Z>0 implies curved element. *-----* 3--6--2 | | | | | | 7 8 5 | | | | *-----* 0--4--1 """ points = np.array([[0, 0, 0], [L, 0, 0], [L, H, Z], [0, H, Z], [L / 2, 0, 0], [L, H / 2, 0], [L / 2, H, Z], [0, H / 2, 0], [L / 2, H / 2, 0], [2 * L, 0, 0], [2 * L, H, Z]]) cells = np.array([[0, 1, 2, 3, 4, 5, 6, 7, 8]]) cells = cells[:, perm_vtk(CellType.quadrilateral, cells.shape[1])] mesh = Mesh(MPI.COMM_WORLD, CellType.quadrilateral, points, cells, [], degree=2) def e2(x): return x[2] + x[0] * x[1] # Interpolate function V = FunctionSpace(mesh, ("CG", 2)) u = Function(V) u.interpolate(e2) intu = assemble_scalar(u * dx(mesh)) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) nodes = [0, 3, 7] ref = sympy_scipy(points, nodes, L, H) assert ref == pytest.approx(intu, rel=1e-6)
def test_triangle_mesh_vtk(order): points = [] points += [[i / order, 0] for i in range(order + 1)] for j in range(1, order): points += [[i / order + 0.1, j / order] for i in range(order + 1 - j)] points += [[0, 1]] def coord_to_vertex(x, y): return y * (2 * order + 3 - y) // 2 + x # Make the cell, following https://blog.kitware.com/modeling-arbitrary-order-lagrange-finite-elements-in-the-visualization-toolkit/ # noqa: E501 cell = [coord_to_vertex(i, j) for i, j in [(0, 0), (order, 0), (0, order)]] if order > 1: for i in range(1, order): cell.append(coord_to_vertex(i, 0)) for i in range(1, order): cell.append(coord_to_vertex(order - i, i)) for i in range(1, order): cell.append(coord_to_vertex(0, order - i)) if order == 3: cell.append(coord_to_vertex(1, 1)) elif order > 3: cell.append(coord_to_vertex(1, 1)) cell.append(coord_to_vertex(order - 2, 1)) cell.append(coord_to_vertex(1, order - 2)) if order > 4: raise NotImplementedError cell = np.array(cell)[perm_vtk(CellType.triangle, len(cell))] domain = ufl.Mesh( ufl.VectorElement("Lagrange", ufl.Cell("triangle", geometric_dimension=2), order)) check_cell_volume(points, cell, domain, 0.5)
def test_nth_order_triangle(order): num_nodes = (order + 1) * (order + 2) / 2 cells = np.array([range(int(num_nodes))]) cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])] if order == 1: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000]]) elif order == 2: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.50000, 0.00000, 0.00000], [0.50000, 0.50000, -0.25000], [0.00000, 0.50000, -0.25000]]) elif order == 3: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.33333, 0.00000, 0.00000], [0.66667, 0.00000, 0.00000], [0.66667, 0.33333, -0.11111], [0.33333, 0.66667, 0.11111], [0.00000, 0.66667, 0.11111], [0.00000, 0.33333, -0.11111], [0.33333, 0.33333, -0.11111]]) elif order == 4: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.25000, 0.00000, 0.00000], [0.50000, 0.00000, 0.00000], [0.75000, 0.00000, 0.00000], [0.75000, 0.25000, -0.06250], [0.50000, 0.50000, 0.06250], [0.25000, 0.75000, -0.06250], [0.00000, 0.75000, -0.06250], [0.00000, 0.50000, 0.06250], [0.00000, 0.25000, -0.06250], [0.25000, 0.25000, -0.06250], [0.50000, 0.25000, -0.06250], [0.25000, 0.50000, 0.06250]]) elif order == 5: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.20000, 0.00000, 0.00000], [0.40000, 0.00000, 0.00000], [0.60000, 0.00000, 0.00000], [0.80000, 0.00000, 0.00000], [0.80000, 0.20000, -0.04000], [0.60000, 0.40000, 0.04000], [0.40000, 0.60000, -0.04000], [0.20000, 0.80000, 0.04000], [0.00000, 0.80000, 0.04000], [0.00000, 0.60000, -0.04000], [0.00000, 0.40000, 0.04000], [0.00000, 0.20000, -0.04000], [0.20000, 0.20000, -0.04000], [0.60000, 0.20000, -0.04000], [0.20000, 0.60000, -0.04000], [0.40000, 0.20000, -0.04000], [0.40000, 0.40000, 0.04000], [0.20000, 0.40000, 0.04000]]) elif order == 6: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.16667, 0.00000, 0.00000], [0.33333, 0.00000, 0.00000], [0.50000, 0.00000, 0.00000], [0.66667, 0.00000, 0.00000], [0.83333, 0.00000, 0.00000], [0.83333, 0.16667, -0.00463], [0.66667, 0.33333, 0.00463], [0.50000, 0.50000, -0.00463], [0.33333, 0.66667, 0.00463], [0.16667, 0.83333, -0.00463], [0.00000, 0.83333, -0.00463], [0.00000, 0.66667, 0.00463], [0.00000, 0.50000, -0.00463], [0.00000, 0.33333, 0.00463], [0.00000, 0.16667, -0.00463], [0.16667, 0.16667, -0.00463], [0.66667, 0.16667, -0.00463], [0.16667, 0.66667, 0.00463], [0.33333, 0.16667, -0.00463], [0.50000, 0.16667, -0.00463], [0.50000, 0.33333, 0.00463], [0.33333, 0.50000, -0.00463], [0.16667, 0.50000, -0.00463], [0.16667, 0.33333, 0.00463], [0.33333, 0.33333, 0.00463]]) elif order == 7: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.14286, 0.00000, 0.00000], [0.28571, 0.00000, 0.00000], [0.42857, 0.00000, 0.00000], [0.57143, 0.00000, 0.00000], [0.71429, 0.00000, 0.00000], [0.85714, 0.00000, 0.00000], [0.85714, 0.14286, -0.02041], [0.71429, 0.28571, 0.02041], [0.57143, 0.42857, -0.02041], [0.42857, 0.57143, 0.02041], [0.28571, 0.71429, -0.02041], [0.14286, 0.85714, 0.02041], [0.00000, 0.85714, 0.02041], [0.00000, 0.71429, -0.02041], [0.00000, 0.57143, 0.02041], [0.00000, 0.42857, -0.02041], [0.00000, 0.28571, 0.02041], [0.00000, 0.14286, -0.02041], [0.14286, 0.14286, -0.02041], [0.71429, 0.14286, -0.02041], [0.14286, 0.71429, -0.02041], [0.28571, 0.14286, -0.02041], [0.42857, 0.14286, -0.02041], [0.57143, 0.14286, -0.02041], [0.57143, 0.28571, 0.02041], [0.42857, 0.42857, -0.02041], [0.28571, 0.57143, 0.02041], [0.14286, 0.57143, 0.02041], [0.14286, 0.42857, -0.02041], [0.14286, 0.28571, 0.02041], [0.28571, 0.28571, 0.02041], [0.42857, 0.28571, 0.02041], [0.28571, 0.42857, -0.02041]]) # Higher order tests are too slow elif order == 8: points = np.array([[0.00000, 0.00000, 0.00000], [1.00000, 0.00000, 0.00000], [0.00000, 1.00000, 0.00000], [0.12500, 0.00000, 0.00000], [0.25000, 0.00000, 0.00000], [0.37500, 0.00000, 0.00000], [0.50000, 0.00000, 0.00000], [0.62500, 0.00000, 0.00000], [0.75000, 0.00000, 0.00000], [0.87500, 0.00000, 0.00000], [0.87500, 0.12500, -0.00195], [0.75000, 0.25000, 0.00195], [0.62500, 0.37500, -0.00195], [0.50000, 0.50000, 0.00195], [0.37500, 0.62500, -0.00195], [0.25000, 0.75000, 0.00195], [0.12500, 0.87500, -0.00195], [0.00000, 0.87500, -0.00195], [0.00000, 0.75000, 0.00195], [0.00000, 0.62500, -0.00195], [0.00000, 0.50000, 0.00195], [0.00000, 0.37500, -0.00195], [0.00000, 0.25000, 0.00195], [0.00000, 0.12500, -0.00195], [0.12500, 0.12500, -0.00195], [0.75000, 0.12500, -0.00195], [0.12500, 0.75000, 0.00195], [0.25000, 0.12500, -0.00195], [0.37500, 0.12500, -0.00195], [0.50000, 0.12500, -0.00195], [0.62500, 0.12500, -0.00195], [0.62500, 0.25000, 0.00195], [0.50000, 0.37500, -0.00195], [0.37500, 0.50000, 0.00195], [0.25000, 0.62500, -0.00195], [0.12500, 0.62500, -0.00195], [0.12500, 0.50000, 0.00195], [0.12500, 0.37500, -0.00195], [0.12500, 0.25000, 0.00195], [0.25000, 0.25000, 0.00195], [0.50000, 0.25000, 0.00195], [0.25000, 0.50000, 0.00195], [0.37500, 0.25000, 0.00195], [0.37500, 0.37500, -0.00195], [0.25000, 0.37500, -0.00195]]) cell = ufl.Cell("triangle", geometric_dimension=points.shape[1]) domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, order)) mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain) # Find nodes corresponding to y axis nodes = [] for j in range(points.shape[0]): if np.isclose(points[j][0], 0): nodes.append(j) def e2(x): return x[2] + x[0] * x[1] # For solution to be in functionspace V = FunctionSpace(mesh, ("CG", max(2, order))) u = Function(V) u.interpolate(e2) quad_order = 30 intu = assemble_scalar(u * dx(metadata={"quadrature_degree": quad_order})) intu = mesh.mpi_comm().allreduce(intu, op=MPI.SUM) ref = scipy_one_cell(points, nodes) assert ref == pytest.approx(intu, rel=3e-3)
def test_hexahedron_mesh_vtk(order): if order > 2: pytest.xfail( "VTK permutation for order > 2 hexahedra not implemented in DOLFINX." ) random.seed(13) points = [] points += [[i / order, j / order, 0] for j in range(order + 1) for i in range(order + 1)] for k in range(1, order): points += [[i / order, j / order + 0.1, k / order] for j in range(order + 1) for i in range(order + 1)] points += [[i / order, j / order, 1] for j in range(order + 1) for i in range(order + 1)] def coord_to_vertex(x, y, z): return (order + 1)**2 * z + (order + 1) * y + x # Make the cell, following https://blog.kitware.com/modeling-arbitrary-order-lagrange-finite-elements-in-the-visualization-toolkit/ # noqa: E501 cell = [ coord_to_vertex(x, y, z) for x, y, z in [(0, 0, 0), (order, 0, 0), ( order, order, 0), (0, order, 0), (0, 0, order), (order, 0, order), (order, order, order), (0, order, order)] ] if order > 1: for i in range(1, order): cell.append(coord_to_vertex(i, 0, 0)) for i in range(1, order): cell.append(coord_to_vertex(order, i, 0)) for i in range(1, order): cell.append(coord_to_vertex(i, order, 0)) for i in range(1, order): cell.append(coord_to_vertex(0, i, 0)) for i in range(1, order): cell.append(coord_to_vertex(i, 0, order)) for i in range(1, order): cell.append(coord_to_vertex(order, i, order)) for i in range(1, order): cell.append(coord_to_vertex(i, order, order)) for i in range(1, order): cell.append(coord_to_vertex(0, i, order)) for i in range(1, order): cell.append(coord_to_vertex(0, 0, i)) for i in range(1, order): cell.append(coord_to_vertex(order, 0, i)) for i in range(1, order): cell.append(coord_to_vertex(order, order, i)) for i in range(1, order): cell.append(coord_to_vertex(0, order, i)) # The ordering of faces does not match documentation. # See https://gitlab.kitware.com/vtk/vtk/uploads/a0dc0173a41d3cf6b03a9266c0e23688/image.png # The edge flip in this like however has been fixed in VTK so we follow the main documentation link for edges for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(0, i, j)) for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(order, i, j)) for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(i, 0, j)) for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(i, order, j)) for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(i, j, 0)) for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(i, j, order)) for k in range(1, order): for j in range(1, order): for i in range(1, order): cell.append(coord_to_vertex(i, j, k)) cell = np.array(cell)[perm_vtk(CellType.hexahedron, len(cell))] domain = ufl.Mesh( ufl.VectorElement("Q", ufl.Cell("hexahedron", geometric_dimension=3), order)) check_cell_volume(points, cell, domain, 1)
def test_tetrahedron_mesh_vtk(order): if order > 3: pytest.xfail( "VTK permutation for order > 3 tetrahedra not implemented in DOLFINX." ) points = [] points += [[i / order, j / order, 0] for j in range(order + 1) for i in range(order + 1 - j)] for k in range(1, order): points += [[i / order, j / order + 0.1, k / order] for j in range(order + 1 - k) for i in range(order + 1 - k - j)] points += [[0, 0, 1]] def coord_to_vertex(x, y, z): return z * (3 * order**2 - 3 * order * z + 12 * order + z**2 - 6 * z + 11) // 6 + y * (2 * (order - z) + 3 - y) // 2 + x # Make the cell, following https://blog.kitware.com/modeling-arbitrary-order-lagrange-finite-elements-in-the-visualization-toolkit/ # noqa: E501 cell = [ coord_to_vertex(x, y, z) for x, y, z in [(0, 0, 0), (order, 0, 0), (0, order, 0), (0, 0, order)] ] if order > 1: for i in range(1, order): cell.append(coord_to_vertex(i, 0, 0)) for i in range(1, order): cell.append(coord_to_vertex(order - i, i, 0)) for i in range(1, order): cell.append(coord_to_vertex(0, order - i, 0)) for i in range(1, order): cell.append(coord_to_vertex(0, 0, i)) for i in range(1, order): cell.append(coord_to_vertex(order - i, 0, i)) for i in range(1, order): cell.append(coord_to_vertex(0, order - i, i)) if order == 3: # The ordering of faces does not match documentation. # See https://gitlab.kitware.com/vtk/vtk/uploads/a0dc0173a41d3cf6b03a9266c0e23688/image.png cell.append(coord_to_vertex(1, 0, 1)) cell.append(coord_to_vertex(1, 1, 1)) cell.append(coord_to_vertex(0, 1, 1)) cell.append(coord_to_vertex(1, 1, 0)) elif order == 4: # The ordering of faces does not match documentation. # See https://gitlab.kitware.com/vtk/vtk/uploads/a0dc0173a41d3cf6b03a9266c0e23688/image.png cell.append(coord_to_vertex(1, 0, 1)) cell.append(coord_to_vertex(2, 0, 1)) cell.append(coord_to_vertex(1, 0, 2)) cell.append(coord_to_vertex(1, 2, 1)) cell.append(coord_to_vertex(1, 1, 2)) cell.append(coord_to_vertex(2, 1, 1)) cell.append(coord_to_vertex(0, 1, 1)) cell.append(coord_to_vertex(0, 1, 2)) cell.append(coord_to_vertex(0, 2, 1)) cell.append(coord_to_vertex(1, 1, 0)) cell.append(coord_to_vertex(1, 2, 0)) cell.append(coord_to_vertex(2, 1, 0)) cell.append(coord_to_vertex(1, 1, 1)) elif order > 4: raise NotImplementedError if False: for j in range(1, order): for i in range(1, order - j): cell.append(coord_to_vertex(i, 0, j)) for j in range(1, order): for i in range(1, order - j): cell.append(coord_to_vertex(0, i, j)) for j in range(1, order): for i in range(1, order - j): cell.append(coord_to_vertex(i, j, 0)) for j in range(1, order): for i in range(1, order - j): cell.append(coord_to_vertex(order - i - j, i, j)) for k in range(1, order): for j in range(1, order - k): for i in range(1, order - j - k): cell.append(coord_to_vertex(i, j, k)) cell = np.array(cell)[perm_vtk(CellType.tetrahedron, len(cell))] domain = ufl.Mesh( ufl.VectorElement("Lagrange", ufl.Cell("tetrahedron", geometric_dimension=3), order)) check_cell_volume(points, cell, domain, 1 / 6)