Example #1
0
def IntervalMesh(comm,
                 nx: int,
                 points: list,
                 ghost_mode=cpp.mesh.GhostMode.shared_facet,
                 partitioner=cpp.mesh.partition_cells_graph):
    """Create an interval mesh

    Parameters
    ----------
    comm
        MPI communicator
    nx
        Number of cells
    point
        Coordinates of the end points
    ghost_mode

    """
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "interval", 1))
    cmap = fem.create_coordinate_map(comm, domain)
    mesh = cpp.generation.create_interval_mesh(comm, nx, points, cmap,
                                               ghost_mode, partitioner)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Example #2
0
def BoxMesh(comm,
            points: typing.List[numpy.array],
            n: list,
            cell_type=cpp.mesh.CellType.tetrahedron,
            ghost_mode=cpp.mesh.GhostMode.shared_facet,
            partitioner=cpp.mesh.partition_cells_graph):
    """Create box mesh

    Parameters
    ----------
    comm
        MPI communicator
    points
        List of points representing vertices
    n
        List of cells in each direction

    """
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(cell_type), 1))
    cmap = fem.create_coordinate_map(comm, domain)
    mesh = cpp.generation.create_box_mesh(comm, points, n, cmap, ghost_mode,
                                          partitioner)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Example #3
0
def RectangleMesh(comm,
                  points: typing.List[numpy.array],
                  n: list,
                  cell_type=cpp.mesh.CellType.triangle,
                  ghost_mode=cpp.mesh.GhostMode.shared_facet,
                  diagonal: str = "right"):
    """Create rectangle mesh

    Parameters
    ----------
    comm
        MPI communicator
    points
        List of `Points` representing vertices
    n
        List of number of cells in each direction
    diagonal
        Direction of diagonal

    """
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(cell_type), 1))
    cmap = fem.create_coordinate_map(comm, domain)
    mesh = cpp.generation.RectangleMesh.create(comm, points, n, cmap,
                                               ghost_mode, diagonal)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Example #4
0
def test_higher_order_coordinate_map(points, celltype):
    """
    Computes physical coordinates of a cell, based on the coordinate map.
    """
    cells = np.array([range(len(points))])
    mesh = Mesh(MPI.comm_world, celltype, points, cells, [], GhostMode.none)
    V = FunctionSpace(mesh, ("Lagrange", mesh.degree()))

    X = V.element.dof_reference_coordinates()
    coord_dofs = mesh.coordinate_dofs().entity_points()
    x_g = mesh.geometry.points

    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    x_coord_new = np.zeros([len(points), mesh.geometry.dim])

    i = 0
    for node in range(len(points)):
        x_coord_new[i] = x_g[coord_dofs[0, node], :mesh.geometry.dim]
        i += 1

    x = np.zeros(X.shape)
    cmap.push_forward(x, X, x_coord_new)

    assert (np.allclose(x[:, 0], X[:, 0]))
    assert (np.allclose(x[:, 1], 2 * X[:, 1]))

    if mesh.geometry.dim == 3:
        assert (np.allclose(x[:, 2], 3 * X[:, 2]))
Example #5
0
def UnitCubeMesh(comm,
                 nx,
                 ny,
                 nz,
                 cell_type=cpp.mesh.CellType.tetrahedron,
                 ghost_mode=cpp.mesh.GhostMode.none):
    """Create a mesh of a unit cube with coordinate mapping attached

    Parameters
    ----------
    comm
        MPI communicator
    nx
        Number of cells in "x" direction
    ny
        Number of cells in "y" direction
    nz
        Number of cells in "z" direction

    """
    mesh = BoxMesh(
        comm, [numpy.array([0.0, 0.0, 0.0]),
               numpy.array([1.0, 1.0, 1.0])], [nx, ny, nz], cell_type,
        ghost_mode)
    mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)
    return mesh
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)
Example #7
0
def test_higher_order_coordinate_map(points, celltype, order):
    """Computes physical coordinates of a cell, based on the coordinate map."""
    cells = np.array([range(len(points))])
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(celltype), order))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

    V = FunctionSpace(mesh, ("Lagrange", 2))
    X = V.element.dof_reference_coordinates()
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x

    cmap = fem.create_coordinate_map(mesh.mpi_comm(), mesh.ufl_domain())
    x_coord_new = np.zeros([len(points), mesh.geometry.dim])

    i = 0
    for node in range(len(points)):
        x_coord_new[i] = x_g[coord_dofs.links(0)[node], :mesh.geometry.dim]
        i += 1
    x = np.zeros(X.shape)
    cmap.push_forward(x, X, x_coord_new)

    assert (np.allclose(x[:, 0], X[:, 0]))
    assert (np.allclose(x[:, 1], 2 * X[:, 1]))

    if mesh.geometry.dim == 3:
        assert (np.allclose(x[:, 2], 3 * X[:, 2]))
Example #8
0
def UnitSquareMesh(comm,
                   nx,
                   ny,
                   cell_type=cpp.mesh.CellType.triangle,
                   ghost_mode=cpp.mesh.GhostMode.none,
                   diagonal="right"):
    """Create a mesh of a unit square with coordinate mapping attached

    Parameters
    ----------
    comm
        MPI communicator
    nx
        Number of cells in "x" direction
    ny
        Number of cells in "y" direction
    diagonal
        Direction of diagonal

    """
    mesh = RectangleMesh(
        comm, [numpy.array([0.0, 0.0, 0.0]),
               numpy.array([1.0, 1.0, 0.0])], [nx, ny], cell_type, ghost_mode,
        diagonal)
    mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)
    return mesh
Example #9
0
    def read_mesh(self,
                  ghost_mode=cpp.mesh.GhostMode.shared_facet,
                  name="mesh",
                  xpath="/Xdmf/Domain"):
        # Read mesh data from file
        cell_type = super().read_cell_type(name, xpath)
        cells = super().read_topology_data(name, xpath)
        x = super().read_geometry_data(name, xpath)

        # Construct the geometry map
        cell = ufl.Cell(cpp.mesh.to_string(cell_type[0]),
                        geometric_dimension=x.shape[1])
        domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, cell_type[1]))
        cmap = fem.create_coordinate_map(self.comm(), domain)

        # Build the mesh
        mesh = cpp.mesh.create_mesh(self.comm(),
                                    cpp.graph.AdjacencyList_int64(cells), cmap,
                                    x, ghost_mode,
                                    cpp.mesh.partition_cells_graph)
        mesh.name = name
        domain._ufl_cargo = mesh
        mesh._ufl_domain = domain

        return mesh
Example #10
0
def test_quadrilateral_dof_positions(space_type):
    """Checks that dofs on shared quadrilateral edges match up"""

    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "quadrilateral", 1))
    if MPI.COMM_WORLD.rank == 0:
        # Create a quadrilateral mesh
        N = 6
        temp_points = np.array([[x / 2, y / 2] for x in range(N)
                                for y in range(N)])

        order = [i for i, j in enumerate(temp_points)]
        shuffle(order)
        points = np.zeros(temp_points.shape)
        for i, j in enumerate(order):
            points[j] = temp_points[i]

        cells = []
        for x in range(N - 1):
            for y in range(N - 1):
                a = N * y + x
                cell = [order[i] for i in [a, a + 1, a + N, a + N + 1]]
                cells.append(cell)

        # On process 0, input mesh data and distribute to other
        # processes
        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    else:
        mesh = create_mesh(MPI.COMM_WORLD, np.ndarray((0, 4)),
                           np.ndarray((0, 2)), domain)

    V = FunctionSpace(mesh, space_type)
    dofmap = V.dofmap

    edges = {}

    # Get coordinates of dofs and edges and check that they are the same
    # for each global dof number
    X = V.element.dof_reference_coordinates()
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x
    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    for cell_n in range(coord_dofs.num_nodes):
        dofs = dofmap.cell_dofs(cell_n)

        x_coord_new = np.zeros([4, 2])
        for v in range(4):
            x_coord_new[v] = x_g[coord_dofs.links(cell_n)[v], :2]
        x = X.copy()
        cmap.push_forward(x, X, x_coord_new)

        edge_dofs_local = []
        for i in range(4):
            edge_dofs_local += list(dofmap.dof_layout.entity_dofs(1, i))
        edge_dofs = [dofs[i] for i in edge_dofs_local]
        for i, j in zip(edge_dofs, x[edge_dofs_local]):
            if i in edges:
                assert np.allclose(j, edges[i])
            else:
                edges[i] = j
Example #11
0
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 = permute_cell_ordering(
                cells,
                permutation_vtk_to_dolfin(CellType.triangle, cells.shape[1]))
            mesh = Mesh(MPI.comm_world, CellType.triangle, points, cells, [],
                        GhostMode.none)

            def e2(x):
                return x[2] + x[0] * x[1]

            degree = mesh.degree()
            # Interpolate function
            V = FunctionSpace(mesh, ("CG", degree))
            u = Function(V)
            cmap = fem.create_coordinate_map(mesh.ufl_domain())
            mesh.geometry.coord_mapping = cmap
            u.interpolate(e2)

            intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 40}))
            intu = MPI.sum(mesh.mpi_comm(), intu)

            nodes = [0, 9, 8, 3]
            ref = sympy_scipy(points, nodes, L, H)
            assert ref == pytest.approx(intu, rel=1e-6)
Example #12
0
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 = permute_cell_ordering(cells, permutation_vtk_to_dolfin(CellType.quadrilateral, cells.shape[1]))
    mesh = Mesh(MPI.comm_world, CellType.quadrilateral, points, cells,
                [], GhostMode.none)

    def e2(x):
        return x[2] + x[0] * x[1]

    # Interpolate function
    V = FunctionSpace(mesh, ("CG", 3))
    u = Function(V)
    cmap = fem.create_coordinate_map(mesh.ufl_domain())

    mesh.geometry.coord_mapping = cmap

    u.interpolate(e2)

    intu = assemble_scalar(u * dx(mesh))
    intu = MPI.sum(mesh.mpi_comm(), intu)

    nodes = [0, 3, 10, 11]
    ref = sympy_scipy(points, nodes, 2 * L, H)
    assert ref == pytest.approx(intu, rel=1e-6)
Example #13
0
def UnitIntervalMesh(comm, nx, ghost_mode=cpp.mesh.GhostMode.none):
    """Create a mesh on the unit interval with coordinate mapping attached

    Parameters
    ----------
    comm
        MPI communicator
    nx
        Number of cells

    """
    mesh = IntervalMesh(comm, nx, [0.0, 1.0], ghost_mode)
    mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)
    return mesh
Example #14
0
def create_mesh(comm, cells, x, domain,
                ghost_mode=cpp.mesh.GhostMode.shared_facet,
                partitioner=cpp.mesh.partition_cells_graph):
    """Create a mesh from topology and geometry data"""
    cmap = fem.create_coordinate_map(comm, domain)
    try:
        mesh = cpp.mesh.create_mesh(comm, cells, cmap, x, ghost_mode, partitioner)
    except TypeError:
        mesh = cpp.mesh.create_mesh(comm, cpp.graph.AdjacencyList_int64(numpy.cast['int64'](cells)),
                                    cmap, x, ghost_mode, partitioner)

    # Attach UFL data (used when passing a mesh into UFL functions)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Example #15
0
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 = permute_cell_ordering(cells, permutation_vtk_to_dolfin(CellType.triangle, cells.shape[1]))

            mesh = Mesh(MPI.comm_world, CellType.triangle, points, cells,
                        [], GhostMode.none)

            def e2(x):
                return x[2] + x[0] * x[1]
            degree = mesh.degree()
            # Interpolate function
            V = FunctionSpace(mesh, ("CG", degree))
            u = Function(V)
            cmap = fem.create_coordinate_map(mesh.ufl_domain())
            mesh.geometry.coord_mapping = cmap
            u.interpolate(e2)

            intu = assemble_scalar(u * dx(metadata={"quadrature_degree": 50}))
            intu = MPI.sum(mesh.mpi_comm(), intu)
            nodes = [0, 3, 10, 11, 12]
            ref = sympy_scipy(points, nodes, L, H)
            assert ref == pytest.approx(intu, rel=1e-4)
 def perform_test(points, cells):
     mesh = cpp.mesh.Mesh(MPI.comm_world, CellType.tetrahedron, points,
                          np.array(cells), [], cpp.mesh.GhostMode.none)
     mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)
     V = FunctionSpace(mesh, (space_type, order))
     f = Function(V)
     output = []
     for dof in range(len(f.vector[:])):
         f.vector[:] = np.zeros(len(f.vector[:]))
         f.vector[dof] = 1
         points = np.array([[1 / 3, 1 / 3, 1 / 3], [1 / 3, 1 / 3, 1 / 3]])
         cells = np.array([0, 1])
         result = f.eval(points, cells)
         normal = np.array([1., 1., 1.])
         output.append(result.dot(normal))
     return output
Example #17
0
def test_dof_positions(cell_type, space_type):
    """Checks that dofs on shared triangle edges match up"""
    mesh = randomly_ordered_mesh(cell_type)

    if cell_type == "triangle":
        entities_per_cell = [3, 3, 1]
    elif cell_type == "quadrilateral":
        entities_per_cell = [4, 4, 1]
    elif cell_type == "tetrahedron":
        entities_per_cell = [4, 6, 4, 1]
    elif cell_type == "hexahedron":
        entities_per_cell = [8, 12, 6, 1]

    # Get coordinates of dofs and edges and check that they are the same
    # for each global dof number
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x
    tdim = mesh.topology.dim
    cmap = fem.create_coordinate_map(mesh.mpi_comm(), mesh.ufl_domain())

    mesh.topology.create_entity_permutations()
    perms = mesh.topology.get_cell_permutation_info()

    V = FunctionSpace(mesh, space_type)
    entities = {i: {} for i in range(1, tdim)}
    for cell in range(coord_dofs.num_nodes):
        # Push coordinates forward
        X = V.element.interpolation_points
        V.element.apply_dof_transformation(X, perms[cell], tdim)
        x = X.copy()
        xg = x_g[coord_dofs.links(cell), :tdim]
        cmap.push_forward(x, X, xg)

        dofs = V.dofmap.cell_dofs(cell)

        for entity_dim in range(1, tdim):
            entity_dofs_local = []
            for i in range(entities_per_cell[entity_dim]):
                entity_dofs_local += list(
                    V.dofmap.dof_layout.entity_dofs(entity_dim, i))
            entity_dofs = [dofs[i] for i in entity_dofs_local]
            for i, j in zip(entity_dofs, x[entity_dofs_local]):
                if i in entities[entity_dim]:
                    assert np.allclose(j, entities[entity_dim][i])
                else:
                    entities[entity_dim][i] = j
Example #18
0
def Mesh(comm,
         cell_type,
         x,
         cells,
         ghosts,
         degree=1,
         ghost_mode=cpp.mesh.GhostMode.none):
    """Crete a mesh from topology and geometry data"""
    cell = ufl.Cell(cpp.mesh.to_string(cell_type),
                    geometric_dimension=x.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
    cmap = fem.create_coordinate_map(domain)

    mesh = cpp.mesh.Mesh(comm, cell_type, x, cells, cmap, ghosts, ghost_mode)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Example #19
0
def xtest_read_write_p2_function(tempdir):
    mesh = cpp.generation.UnitDiscMesh.create(MPI.comm_world, 3,
                                              cpp.mesh.GhostMode.none)
    gdim = mesh.geometry.dim
    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    mesh.geometry.coord_mapping = cmap
    Q = FunctionSpace(mesh, ("Lagrange", 2))

    F = Function(Q)
    if has_petsc_complex:

        def expr_eval(x):
            return x[0] + 1.0j * x[0]

        F.interpolate(expr_eval)
    else:

        def expr_eval(x):
            return x[0]

        F.interpolate(expr_eval)

    filename = os.path.join(tempdir, "tri6_function.xdmf")
    with XDMFFile(mesh.mpi_comm(), filename,
                  encoding=XDMFFile.Encoding.HDF5) as xdmf:
        xdmf.write(F)

    Q = VectorFunctionSpace(mesh, ("Lagrange", 1))
    F = Function(Q)
    if has_petsc_complex:

        def expr_eval(x):
            return x[:gdim] + 1.0j * x[:gdim]

        F.interpolate(expr_eval)
    else:

        def expr_eval(x):
            return x[:gdim]

        F.interpolate(expr_eval)
    filename = os.path.join(tempdir, "tri6_vector_function.xdmf")
    with XDMFFile(mesh.mpi_comm(), filename,
                  encoding=XDMFFile.Encoding.HDF5) as xdmf:
        xdmf.write(F)
Example #20
0
    def read_mesh(self, name="mesh", xpath="/Xdmf/Domain"):
        # Read mesh data from file
        cell_type, x, cells = super().read_mesh_data(name, xpath)

        # Construct the geometry map
        cell = ufl.Cell(cpp.mesh.to_string(cell_type[0]),
                        geometric_dimension=x.shape[1])
        domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, cell_type[1]))
        cmap = fem.create_coordinate_map(domain)

        # Build the mesh
        mesh = cpp.mesh.create(self.comm(), cpp.graph.AdjacencyList64(cells),
                               cmap, x, cpp.mesh.GhostMode.none)
        mesh.name = name
        domain._ufl_cargo = mesh
        mesh._ufl_domain = domain

        return mesh
Example #21
0
def test_higher_order_tetra_coordinate_map(order):
    """
    Computes physical coordinates of a cell, based on the coordinate map.
    """
    celltype = CellType.tetrahedron
    points = np.array([[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3],
                       [0, 4 / 3, 1], [0, 2 / 3, 2], [2 / 3, 0, 1],
                       [1 / 3, 0, 2], [2 / 3, 2 / 3, 0], [1 / 3, 4 / 3, 0],
                       [0, 0, 1], [0, 0, 2], [0, 2 / 3, 0], [0, 4 / 3, 0],
                       [1 / 3, 0, 0], [2 / 3, 0, 0], [1 / 3, 2 / 3, 1],
                       [0, 2 / 3, 1], [1 / 3, 0, 1], [1 / 3, 2 / 3, 0]])

    if order == 1:
        points = np.array(
            [points[0, :], points[1, :], points[2, :], points[3, :]])
    elif order == 2:
        points = np.array([
            points[0, :], points[1, :], points[2, :], points[3, :],
            [0, 1, 3 / 2], [1 / 2, 0, 3 / 2], [1 / 2, 1, 0], [0, 0, 3 / 2],
            [0, 1, 0], [1 / 2, 0, 0]
        ])
    cells = np.array([range(len(points))])
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(celltype), order))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    V = FunctionSpace(mesh, ("Lagrange", order))
    X = V.element.dof_reference_coordinates()
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x

    cmap = fem.create_coordinate_map(mesh.mpi_comm(), mesh.ufl_domain())
    x_coord_new = np.zeros([len(points), mesh.geometry.dim])

    i = 0
    for node in range(len(points)):
        x_coord_new[i] = x_g[coord_dofs.links(0)[node], :mesh.geometry.dim]
        i += 1

    x = np.zeros(X.shape)
    cmap.push_forward(x, X, x_coord_new)
    assert (np.allclose(x[:, 0], X[:, 0]))
    assert (np.allclose(x[:, 1], 2 * X[:, 1]))
    assert (np.allclose(x[:, 2], 3 * X[:, 2]))
Example #22
0
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 = permute_cell_ordering(
        cells, permutation_vtk_to_dolfin(CellType.quadrilateral,
                                         cells.shape[1]))

    mesh = Mesh(MPI.comm_world, CellType.quadrilateral, points, cells, [],
                GhostMode.none)

    def e2(x):
        return x[2] + x[0] * x[1]

    # Interpolate function
    V = FunctionSpace(mesh, ("CG", 2))
    u = Function(V)
    cmap = fem.create_coordinate_map(mesh.ufl_domain())

    mesh.geometry.coord_mapping = cmap

    u.interpolate(e2)

    intu = assemble_scalar(u * dx(mesh))
    intu = MPI.sum(mesh.mpi_comm(), intu)

    nodes = [0, 3, 7]
    ref = sympy_scipy(points, nodes, L, H)
    assert ref == pytest.approx(intu, rel=1e-6)
Example #23
0
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 = permute_cell_ordering(
                cells,
                permutation_vtk_to_dolfin(CellType.triangle, cells.shape[1]))
            mesh = Mesh(MPI.comm_world, CellType.triangle, points, cells, [],
                        GhostMode.none)

            def e2(x):
                return x[2] + x[0] * x[1]

            degree = mesh.degree()
            # Interpolate function
            V = FunctionSpace(mesh, ("CG", degree))
            u = Function(V)
            cmap = fem.create_coordinate_map(mesh.ufl_domain())

            mesh.geometry.coord_mapping = cmap
            u.interpolate(e2)

            intu = assemble_scalar(
                u * dx(mesh, metadata={"quadrature_degree": 20}))
            intu = MPI.sum(mesh.mpi_comm(), intu)

            nodes = [0, 3, 7]
            ref = sympy_scipy(points, nodes, L, H)
            assert ref == pytest.approx(intu, rel=1e-6)
Example #24
0
def test_higher_order_tetra_coordinate_map(order):
    """
    Computes physical coordinates of a cell, based on the coordinate map.
    """
    celltype = CellType.tetrahedron
    points = np.array([[0, 0, 0], [1, 0, 0], [0, 2, 0], [0, 0, 3],
                       [0, 4 / 3, 1], [0, 2 / 3, 2], [2 / 3, 0, 1],
                       [1 / 3, 0, 2], [2 / 3, 2 / 3, 0], [1 / 3, 4 / 3, 0],
                       [0, 0, 1], [0, 0, 2], [0, 2 / 3, 0], [0, 4 / 3, 0],
                       [1 / 3, 0, 0], [2 / 3, 0, 0], [1 / 3, 2 / 3, 1],
                       [0, 2 / 3, 1], [1 / 3, 0, 1], [1 / 3, 2 / 3, 0]])

    if order == 1:
        points = np.array(
            [points[0, :], points[1, :], points[2, :], points[3, :]])
    elif order == 2:
        points = np.array([
            points[0, :], points[1, :], points[2, :], points[3, :],
            [0, 1, 3 / 2], [1 / 2, 0, 3 / 2], [1 / 2, 1, 0], [0, 0, 3 / 2],
            [0, 1, 0], [1 / 2, 0, 0]
        ])
    cells = np.array([range(len(points))])
    mesh = Mesh(MPI.comm_world, celltype, points, cells, [], GhostMode.none)
    V = FunctionSpace(mesh, ("Lagrange", order))
    X = V.element.dof_reference_coordinates()
    coord_dofs = mesh.coordinate_dofs().entity_points()
    x_g = mesh.geometry.points

    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    x_coord_new = np.zeros([len(points), mesh.geometry.dim])

    i = 0
    for node in range(len(points)):
        x_coord_new[i] = x_g[coord_dofs[0, node], :mesh.geometry.dim]
        i += 1

    x = np.zeros(X.shape)
    cmap.push_forward(x, X, x_coord_new)
    assert (np.allclose(x[:, 0], X[:, 0]))
    assert (np.allclose(x[:, 1], 2 * X[:, 1]))
    assert (np.allclose(x[:, 2], 3 * X[:, 2]))
Example #25
0
def test_read_write_p2_mesh(tempdir, encoding):
    cell = ufl.Cell("triangle", geometric_dimension=2)
    element = ufl.VectorElement("Lagrange", cell, 2)
    domain = ufl.Mesh(element)
    cmap = fem.create_coordinate_map(domain)

    mesh = cpp.generation.UnitDiscMesh.create(MPI.COMM_WORLD, 3, cmap,
                                              cpp.mesh.GhostMode.none)

    filename = os.path.join(tempdir, "tri6_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 unit_cell(cell_type, random_order=True):
    if cell_type == CellType.interval:
        points = np.array([[0.], [1.]])
    if cell_type == CellType.triangle:
        # Define equilateral triangle with area 1
        root = 3**0.25  # 4th root of 3
        points = np.array([[0., 0.], [2 / root, 0.], [1 / root, root]])
    elif cell_type == CellType.tetrahedron:
        # Define regular tetrahedron with volume 1
        s = 2**0.5 * 3**(1 / 3)  # side length
        points = np.array([[0., 0., 0.], [s, 0., 0.],
                           [s / 2, s * np.sqrt(3) / 2, 0.],
                           [s / 2, s / 2 / np.sqrt(3), s * np.sqrt(2 / 3)]])
    elif cell_type == CellType.quadrilateral:
        # Define unit quadrilateral (area 1)
        points = np.array([[0., 0.], [1., 0.], [0., 1.], [1., 1.]])
    elif cell_type == CellType.hexahedron:
        # Define unit hexahedron (volume 1)
        points = np.array([[0., 0., 0.], [1., 0., 0.], [0., 1., 0.],
                           [1., 1., 0.], [0., 0., 1.], [1., 0., 1.],
                           [0., 1., 1.], [1., 1., 1.]])
    num_points = len(points)

    # Randomly number the points and create the mesh
    order = list(range(num_points))
    if random_order:
        shuffle(order)
    ordered_points = np.zeros(points.shape)
    for i, j in enumerate(order):
        ordered_points[j] = points[i]
    cells = np.array([order])
    mesh = Mesh(MPI.comm_world, cell_type, ordered_points, cells, [],
                cpp.mesh.GhostMode.none)
    mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)
    mesh.create_connectivity_all()
    return mesh
Example #27
0
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 = permute_cell_ordering(
        cells, permutation_vtk_to_dolfin(CellType.quadrilateral,
                                         cells.shape[1]))
    mesh = Mesh(MPI.comm_world, CellType.quadrilateral, points, cells, [],
                GhostMode.none)

    def e2(x):
        return x[2] + x[0] * x[1]

    V = FunctionSpace(mesh, ("CG", 4))
    u = Function(V)
    cmap = fem.create_coordinate_map(mesh.ufl_domain())

    mesh.geometry.coord_mapping = cmap

    u.interpolate(e2)

    intu = assemble_scalar(u * dx(mesh))
    intu = MPI.sum(mesh.mpi_comm(), intu)

    nodes = [0, 5, 10, 15, 20]
    ref = sympy_scipy(points, nodes, 2 * L, H)
    assert ref == pytest.approx(intu, rel=1e-5)
Example #28
0
def test_nth_order_triangle(order):
    num_nodes = (order + 1) * (order + 2) / 2
    cells = np.array([range(int(num_nodes))])
    cells = permute_cell_ordering(
        cells, permutation_vtk_to_dolfin(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]])

    mesh = Mesh(MPI.comm_world, CellType.triangle, points, cells, [],
                GhostMode.none)

    # 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)
    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    mesh.geometry.coord_mapping = cmap
    u.interpolate(e2)

    quad_order = 30
    intu = assemble_scalar(u * dx(metadata={"quadrature_degree": quad_order}))
    intu = MPI.sum(mesh.mpi_comm(), intu)

    ref = scipy_one_cell(points, nodes)
    assert ref == pytest.approx(intu, rel=3e-3)
def two_unit_cells(cell_type,
                   agree=False,
                   random_order=True,
                   return_order=False):
    if cell_type == CellType.interval:
        points = np.array([[0.], [1.], [-1.]])
        if agree:
            cells = [[0, 1], [2, 0]]
        else:
            cells = [[0, 1], [0, 2]]
    if cell_type == CellType.triangle:
        # Define equilateral triangles with area 1
        root = 3**0.25  # 4th root of 3
        points = np.array([[0., 0.], [2 / root, 0.], [1 / root, root],
                           [1 / root, -root]])
        if agree:
            cells = [[0, 1, 2], [0, 3, 1]]
        else:
            cells = [[0, 1, 2], [1, 0, 3]]
    elif cell_type == CellType.tetrahedron:
        # Define regular tetrahedra with volume 1
        s = 2**0.5 * 3**(1 / 3)  # side length
        points = np.array([[0., 0., 0.], [s, 0., 0.],
                           [s / 2, s * np.sqrt(3) / 2, 0.],
                           [s / 2, s / 2 / np.sqrt(3), s * np.sqrt(2 / 3)],
                           [s / 2, s / 2 / np.sqrt(3), -s * np.sqrt(2 / 3)]])
        if agree:
            cells = [[0, 1, 2, 3], [0, 1, 4, 2]]
        else:
            cells = [[0, 1, 2, 3], [0, 2, 1, 4]]
    elif cell_type == CellType.quadrilateral:
        # Define unit quadrilaterals (area 1)
        points = np.array([[0., 0.], [1., 0.], [0., 1.], [1., 1.], [0., -1.],
                           [1., -1.]])
        if agree:
            cells = [[0, 1, 2, 3], [4, 5, 0, 1]]
        else:
            cells = [[0, 1, 2, 3], [5, 1, 4, 0]]
    elif cell_type == CellType.hexahedron:
        # Define unit hexahedra (volume 1)
        points = np.array([[0., 0., 0.], [1., 0., 0.], [0., 1., 0.],
                           [1., 1., 0.], [0., 0., 1.], [1., 0., 1.],
                           [0., 1., 1.], [1., 1., 1.], [0., 0., -1.],
                           [1., 0., -1.], [0., 1., -1.], [1., 1., -1.]])
        if agree:
            cells = [[0, 1, 2, 3, 4, 5, 6, 7], [8, 9, 10, 11, 0, 1, 2, 3]]
        else:
            cells = [[0, 1, 2, 3, 4, 5, 6, 7], [9, 11, 8, 10, 1, 3, 0, 2]]
    num_points = len(points)

    # Randomly number the points and create the mesh
    order = list(range(num_points))
    if random_order:
        shuffle(order)
    ordered_points = np.zeros(points.shape)
    for i, j in enumerate(order):
        ordered_points[j] = points[i]
    ordered_cells = np.array([[order[i] for i in c] for c in cells])
    mesh = Mesh(MPI.comm_world, cell_type, ordered_points, ordered_cells, [],
                cpp.mesh.GhostMode.none)
    mesh.geometry.coord_mapping = fem.create_coordinate_map(mesh)
    mesh.create_connectivity_all()
    if return_order:
        return mesh, order
    return mesh
Example #30
0
def test_triangle_dof_ordering(space_type):
    """Checks that dofs on shared triangle edges match up"""

    # Create a mesh
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1))
    if MPI.COMM_WORLD.rank == 0:
        N = 6
        # Create a grid of points [0, 0.5, ..., 9.5]**2, then order them
        # in a random order
        temp_points = np.array([[x / 2, y / 2] for x in range(N) for y in range(N)])
        order = [i for i, j in enumerate(temp_points)]
        shuffle(order)
        points = np.zeros(temp_points.shape)
        for i, j in enumerate(order):
            points[j] = temp_points[i]

        # Make triangle cells using the randomly ordered points
        cells = []
        for x in range(N - 1):
            for y in range(N - 1):
                a = N * y + x
                # Adds two triangle cells:
                # a+N -- a+N+1
                #  |   / |
                #  |  /  |
                #  | /   |
                #  a --- a+1
                for cell in [[a, a + 1, a + N + 1], [a, a + N + 1, a + N]]:
                    cells.append([order[i] for i in cell])

        # On process 0, input mesh data and distribute to other
        # processes
        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    else:
        mesh = create_mesh(MPI.COMM_WORLD, np.ndarray((0, 3)), np.ndarray((0, 2)), domain)

    V = FunctionSpace(mesh, space_type)
    dofmap = V.dofmap

    edges = {}

    # Get coordinates of dofs and edges and check that they are the same
    # for each global dof number
    X = V.element.dof_reference_coordinates()
    coord_dofs = mesh.geometry.dofmap
    x_g = mesh.geometry.x
    cmap = fem.create_coordinate_map(mesh.ufl_domain())
    for cell_n in range(coord_dofs.num_nodes):
        dofs = dofmap.cell_dofs(cell_n)

        x_coord_new = np.zeros([3, 2])
        for v in range(3):
            x_coord_new[v] = x_g[coord_dofs.links(cell_n)[v], :2]
        x = X.copy()
        cmap.push_forward(x, X, x_coord_new)

        edge_dofs_local = []
        for i in range(3):
            edge_dofs_local += list(dofmap.dof_layout.entity_dofs(1, i))
        edge_dofs = [dofs[i] for i in edge_dofs_local]
        for i, j in zip(edge_dofs, x[edge_dofs_local]):
            if i in edges:
                assert np.allclose(j, edges[i])
            else:
                edges[i] = j