def test_manifold_point_search():
    # Simple two-triangle surface in 3d
    vertices = np.array([[0.0, 0.0, 1.0], [1.0, 1.0, 1.0], [1.0, 0.0, 0.0],
                         [0.0, 1.0, 0.0]])
    cells = np.array([[0, 1, 2], [0, 1, 3]], dtype=np.int64)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain)
    bb = BoundingBoxTree(mesh, mesh.topology.dim)

    # Find cell colliding with point
    points = np.array([[0.5, 0.25, 0.75], [0.25, 0.5, 0.75]])
    cell_candidates = geometry.compute_collisions(bb, points)
    colliding_cells = geometry.compute_colliding_cells(mesh, cell_candidates,
                                                       points)

    # Extract vertices of cell
    indices = _cpp.mesh.entities_to_geometry(
        mesh, mesh.topology.dim,
        [colliding_cells.links(0)[0],
         colliding_cells.links(1)[0]], False)
    cell_vertices = mesh.geometry.x[indices]

    # Compare vertices with input
    assert np.allclose(cell_vertices, vertices[cells])
示例#2
0
def test_manifold_point_search():
    # Simple two-triangle surface in 3d
    vertices = numpy.array([[0.0, 0.0, 1.0], [1.0, 1.0, 1.0], [1.0, 0.0, 0.0],
                            [0.0, 1.0, 0.0]])
    cells = numpy.array([[0, 1, 2], [0, 1, 3]], dtype=numpy.int64)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "triangle", 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain)
    x = mesh.geometry.x
    tdim = mesh.topology.dim

    bb = BoundingBoxTree(mesh, tdim)

    # Find cell colliding with point
    p = numpy.array([0.5, 0.25, 0.75])
    cell_candidates = geometry.compute_collisions_point(bb, p)
    cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1)

    # Extract vertices of cell
    top_indices = cpp.mesh.entities_to_geometry(mesh, tdim, [cell], False)
    cell_vertices = x[top_indices]

    # Compare vertices with input (should be in cell 0)
    assert numpy.allclose(cell_vertices, vertices[cells[0]])

    # Find cell colliding with point
    p = numpy.array([0.25, 0.5, 0.75])
    cell_candidates = geometry.compute_collisions_point(bb, p)
    cell = cpp.geometry.select_colliding_cells(mesh, cell_candidates, p, 1)

    # Extract vertices of cell
    top_indices = cpp.mesh.entities_to_geometry(mesh, tdim, [cell], False)
    x = mesh.geometry.x
    cell_vertices = x[top_indices]

    # Compare vertices with input (should be in cell 1)
    assert numpy.allclose(cell_vertices, vertices[cells[1]])
示例#3
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 = cells[:, perm_vtk(CellType.quadrilateral, cells.shape[1])]
    cell = ufl.Cell("quadrilateral", geometric_dimension=points.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 2))
    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", 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)
示例#4
0
def mesh_3D_dolfin(theta=0,
                   ct=CellType.tetrahedron,
                   ext="tetrahedron",
                   num_refinements=0,
                   N0=5):
    timer = Timer("Create mesh")

    def find_plane_function(p0, p1, p2):
        """
        Find plane function given three points:
        http://www.nabla.hr/CG-LinesPlanesIn3DA3.htm
        """
        v1 = np.array(p1) - np.array(p0)
        v2 = np.array(p2) - np.array(p0)

        n = np.cross(v1, v2)
        D = -(n[0] * p0[0] + n[1] * p0[1] + n[2] * p0[2])
        return lambda x: np.isclose(0, np.dot(n, x) + D)

    def over_plane(p0, p1, p2):
        """
        Returns function that checks if a point is over a plane defined
        by the points p0, p1 and p2.
        """
        v1 = np.array(p1) - np.array(p0)
        v2 = np.array(p2) - np.array(p0)

        n = np.cross(v1, v2)
        D = -(n[0] * p0[0] + n[1] * p0[1] + n[2] * p0[2])
        return lambda x: n[0] * x[0] + n[1] * x[1] + D > -n[2] * x[2]

    tmp_mesh_name = "tmp_mesh.xdmf"
    r_matrix = rotation_matrix([1 / np.sqrt(2), 1 / np.sqrt(2), 0], -theta)

    if MPI.COMM_WORLD.rank == 0:
        # Create two coarse meshes and merge them
        mesh0 = create_unit_cube(MPI.COMM_SELF, N0, N0, N0, ct)
        mesh0.geometry.x[:, 2] += 1
        mesh1 = create_unit_cube(MPI.COMM_SELF, 2 * N0, 2 * N0, 2 * N0, ct)

        tdim0 = mesh0.topology.dim
        num_cells0 = mesh0.topology.index_map(tdim0).size_local
        cells0 = entities_to_geometry(
            mesh0, tdim0,
            np.arange(num_cells0, dtype=np.int32).reshape((-1, 1)), False)
        tdim1 = mesh1.topology.dim
        num_cells1 = mesh1.topology.index_map(tdim1).size_local
        cells1 = entities_to_geometry(
            mesh1, tdim1,
            np.arange(num_cells1, dtype=np.int32).reshape((-1, 1)), False)
        cells1 += mesh0.geometry.x.shape[0]

        # Concatenate points and cells
        points = np.vstack([mesh0.geometry.x, mesh1.geometry.x])
        cells = np.vstack([cells0, cells1])
        cell = Cell(ext, geometric_dimension=points.shape[1])
        domain = Mesh(VectorElement("Lagrange", cell, 1))
        # Rotate mesh
        points = np.dot(r_matrix, points.T).T

        mesh = create_mesh(MPI.COMM_SELF, cells, points, domain)
        with XDMFFile(MPI.COMM_SELF, tmp_mesh_name, "w") as xdmf:
            xdmf.write_mesh(mesh)

    MPI.COMM_WORLD.barrier()
    with XDMFFile(MPI.COMM_WORLD, tmp_mesh_name, "r") as xdmf:
        mesh = xdmf.read_mesh()

    # Refine coarse mesh
    for i in range(num_refinements):
        mesh.topology.create_entities(mesh.topology.dim - 2)
        mesh = refine(mesh, redistribute=True)

    tdim = mesh.topology.dim
    fdim = tdim - 1
    # Find information about facets to be used in meshtags
    bottom_points = np.dot(
        r_matrix,
        np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]]).T)
    bottom = find_plane_function(bottom_points[:, 0], bottom_points[:, 1],
                                 bottom_points[:, 2])
    bottom_facets = locate_entities_boundary(mesh, fdim, bottom)
    top_points = np.dot(
        r_matrix,
        np.array([[0, 0, 2], [1, 0, 2], [0, 1, 2], [1, 1, 2]]).T)
    top = find_plane_function(top_points[:, 0], top_points[:, 1],
                              top_points[:, 2])
    top_facets = locate_entities_boundary(mesh, fdim, top)

    # Determine interface facets
    if_points = np.dot(
        r_matrix,
        np.array([[0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]).T)
    interface = find_plane_function(if_points[:, 0], if_points[:, 1],
                                    if_points[:, 2])
    i_facets = locate_entities_boundary(mesh, fdim, interface)
    mesh.topology.create_connectivity(fdim, tdim)
    top_interface = []
    bottom_interface = []
    facet_to_cell = mesh.topology.connectivity(fdim, tdim)
    num_cells = mesh.topology.index_map(tdim).size_local

    # Find top and bottom interface facets
    cell_midpoints = compute_midpoints(mesh, tdim, range(num_cells))
    top_cube = over_plane(if_points[:, 0], if_points[:, 1], if_points[:, 2])
    for facet in i_facets:
        i_cells = facet_to_cell.links(facet)
        assert (len(i_cells == 1))
        i_cell = i_cells[0]
        if top_cube(cell_midpoints[i_cell]):
            top_interface.append(facet)
        else:
            bottom_interface.append(facet)

    # Create cell tags
    num_cells = mesh.topology.index_map(tdim).size_local
    cell_midpoints = compute_midpoints(mesh, tdim, range(num_cells))
    top_cube_marker = 2
    indices = []
    values = []
    for cell_index in range(num_cells):
        if top_cube(cell_midpoints[cell_index]):
            indices.append(cell_index)
            values.append(top_cube_marker)
    ct = meshtags(mesh, tdim, np.array(indices, dtype=np.intc),
                  np.array(values, dtype=np.intc))

    # Create meshtags for facet data
    markers = {
        3: top_facets,
        4: bottom_interface,
        9: top_interface,
        5: bottom_facets
    }  # , 6: left_facets, 7: right_facets}
    indices = np.array([], dtype=np.intc)
    values = np.array([], dtype=np.intc)
    for key in markers.keys():
        indices = np.append(indices, markers[key])
        values = np.append(values,
                           np.full(len(markers[key]), key, dtype=np.intc))
    sorted_indices = np.argsort(indices)
    mt = meshtags(mesh, fdim, indices[sorted_indices], values[sorted_indices])
    mt.name = "facet_tags"
    fname = f"meshes/mesh_{ext}_{theta:.2f}.xdmf"

    with XDMFFile(MPI.COMM_WORLD, fname, "w") as o_f:
        o_f.write_mesh(mesh)
        o_f.write_meshtags(ct)
        o_f.write_meshtags(mt)
    timer.stop()
示例#5
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 = 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)
示例#6
0
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)
示例#7
0
# Generate mesh
model.occ.synchronize()
model.mesh.generate(3)

# Sort mesh nodes according to their index in gmsh (Starts at 1)
x = extract_gmsh_geometry(model, model_name="Sphere")

# Extract cells from gmsh (Only interested in tetrahedrons)
element_types, element_tags, node_tags = model.mesh.getElements(dim=3)
assert len(element_types) == 1
name, dim, order, num_nodes, local_coords, num_first_order_nodes = model.mesh.getElementProperties(
    element_types[0])
cells = node_tags[0].reshape(-1, num_nodes) - 1

mesh = create_mesh(MPI.COMM_SELF, cells, x,
                   ufl_mesh_from_gmsh(element_types[0], x.shape[1]))

with XDMFFile(MPI.COMM_SELF, "mesh_rank_{}.xdmf".format(MPI.COMM_WORLD.rank),
              "w") as file:
    file.write_mesh(mesh)

# Create a distributed (parallel) mesh with affine geometry.
# Generate mesh on rank 0, then build a distributed mesh ::

if MPI.COMM_WORLD.rank == 0:
    # Generate a mesh

    model.add("Sphere minus box")
    model.setCurrent("Sphere minus box")

    sphere_dim_tags = model.occ.addSphere(0, 0, 0, 1)
def mesh_2D_dolfin(celltype: str, theta: float = 0):
    """
    Create two 2D cubes stacked on top of each other,
    and the corresponding mesh markers using dolfin built-in meshes
    """
    def find_line_function(p0, p1):
        """
        Find line y=ax+b for each of the lines in the mesh
        https://mathworld.wolfram.com/Two-PointForm.html
        """
        # Line aligned with y axis
        if np.isclose(p1[0], p0[0]):
            return lambda x: np.isclose(x[0], p0[0])
        return lambda x: np.isclose(
            x[1], p0[1] + (p1[1] - p0[1]) / (p1[0] - p0[0]) * (x[0] - p0[0]))

    def over_line(p0, p1):
        """
        Check if a point is over or under y=ax+b for each of the
        lines in the mesh https://mathworld.wolfram.com/Two-PointForm.html
        """
        return lambda x: x[1] > p0[1] + (p1[1] - p0[1]) / (p1[0] - p0[0]) * (x[
            0] - p0[0])

    # Using built in meshes, stacking cubes on top of each other
    N = 15
    if celltype == "quadrilateral":
        ct = _mesh.CellType.quadrilateral
    elif celltype == "triangle":
        ct = _mesh.CellType.triangle
    else:
        raise ValueError("celltype has to be tri or quad")
    if MPI.COMM_WORLD.rank == 0:
        mesh0 = _mesh.create_unit_square(MPI.COMM_SELF, N, N, ct)
        mesh1 = _mesh.create_unit_square(MPI.COMM_SELF, 2 * N, 2 * N, ct)
        mesh0.geometry.x[:, 1] += 1

        # Stack the two meshes in one mesh
        r_matrix = _utils.rotation_matrix([0, 0, 1], theta)
        points = np.vstack([mesh0.geometry.x, mesh1.geometry.x])
        points = np.dot(r_matrix, points.T)
        points = points[:2, :].T

        # Transform topology info into geometry info
        tdim0 = mesh0.topology.dim
        num_cells0 = mesh0.topology.index_map(tdim0).size_local
        cells0 = _cpp.mesh.entities_to_geometry(
            mesh0, tdim0,
            np.arange(num_cells0, dtype=np.int32).reshape((-1, 1)), False)
        tdim1 = mesh1.topology.dim
        num_cells1 = mesh1.topology.index_map(tdim1).size_local
        cells1 = _cpp.mesh.entities_to_geometry(
            mesh1, tdim1,
            np.arange(num_cells1, dtype=np.int32).reshape((-1, 1)), False)
        cells1 += mesh0.geometry.x.shape[0]

        cells = np.vstack([cells0, cells1])
        cell = ufl.Cell(celltype, geometric_dimension=points.shape[1])
        domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 1))
        mesh = _mesh.create_mesh(MPI.COMM_SELF, cells, points, domain)
        tdim = mesh.topology.dim
        fdim = tdim - 1

        # Find information about facets to be used in meshtags
        bottom_points = np.dot(
            r_matrix,
            np.array([[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0]]).T)
        bottom = find_line_function(bottom_points[:, 0], bottom_points[:, 1])
        bottom_facets = _mesh.locate_entities_boundary(mesh, fdim, bottom)

        top_points = np.dot(
            r_matrix,
            np.array([[0, 1, 0], [1, 1, 0], [1, 2, 0], [0, 2, 0]]).T)
        top = find_line_function(top_points[:, 2], top_points[:, 3])
        top_facets = _mesh.locate_entities_boundary(mesh, fdim, top)

        left_side = find_line_function(top_points[:, 0], top_points[:, 3])
        left_facets = _mesh.locate_entities_boundary(mesh, fdim, left_side)

        right_side = find_line_function(top_points[:, 1], top_points[:, 2])
        right_facets = _mesh.locate_entities_boundary(mesh, fdim, right_side)

        top_cube = over_line(bottom_points[:, 2], bottom_points[:, 3])

        num_cells = mesh.topology.index_map(tdim).size_local
        cell_midpoints = _cpp.mesh.compute_midpoints(mesh, tdim,
                                                     range(num_cells))
        interface = find_line_function(bottom_points[:, 2], bottom_points[:,
                                                                          3])
        i_facets = _mesh.locate_entities_boundary(mesh, fdim, interface)
        bottom_interface = []
        top_interface = []
        mesh.topology.create_connectivity(fdim, tdim)
        facet_to_cell = mesh.topology.connectivity(fdim, tdim)
        for facet in i_facets:
            i_cells = facet_to_cell.links(facet)
            assert (len(i_cells == 1))
            i_cell = i_cells[0]
            if top_cube(cell_midpoints[i_cell]):
                top_interface.append(facet)
            else:
                bottom_interface.append(facet)

        top_cube_marker = 2
        cell_indices = []
        cell_values = []
        for cell_index in range(num_cells):
            if top_cube(cell_midpoints[cell_index]):
                cell_indices.append(cell_index)
                cell_values.append(top_cube_marker)
        ct = _mesh.meshtags(mesh, tdim, np.array(cell_indices, dtype=np.intc),
                            np.array(cell_values, dtype=np.intc))

        # Create meshtags for facet data
        markers: Dict[int, np.ndarray] = {
            3: top_facets,
            4: np.hstack(bottom_interface),
            9: np.hstack(top_interface),
            5: bottom_facets,
            6: left_facets,
            7: right_facets
        }
        all_indices = []
        all_values = []

        for key in markers.keys():
            all_indices.append(markers[key])
            all_values.append(np.full(len(markers[key]), key, dtype=np.intc))
        arg_sort = np.argsort(np.hstack(all_indices))
        mt = _mesh.meshtags(mesh, fdim,
                            np.hstack(all_indices)[arg_sort],
                            np.hstack(all_values)[arg_sort])
        mt.name = "facet_tags"  # type: ignore
        with _io.XDMFFile(MPI.COMM_SELF,
                          f"meshes/mesh_{celltype}_{theta:.2f}.xdmf",
                          "w") as o_f:
            o_f.write_mesh(mesh)
            o_f.write_meshtags(ct)
            o_f.write_meshtags(mt)
    MPI.COMM_WORLD.barrier()
示例#9
0
def randomly_ordered_mesh(cell_type):
    """Create a randomly ordered mesh to use in the test."""
    random.seed(6)

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

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

        if cell_type == "triangle":
            # 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])

        elif cell_type == "quadrilateral":
            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)

        elif cell_type == "tetrahedron":
            cells = []
            for x in range(N - 1):
                for y in range(N - 1):
                    for z in range(N - 1):
                        a = N**2 * z + N * y + x
                        for c in [
                            [a + N, a + N**2 + 1, a, a + 1],
                            [a + N, a + N**2 + 1, a + 1, a + N + 1],
                            [a + N, a + N**2 + 1, a + N + 1, a + N**2 + N + 1],
                            [
                                a + N, a + N**2 + 1, a + N**2 + N + 1,
                                a + N**2 + N
                            ], [a + N, a + N**2 + 1, a + N**2 + N, a + N**2],
                            [a + N, a + N**2 + 1, a + N**2, a]
                        ]:
                            cell = [order[i] for i in c]
                            cells.append(cell)

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

        # On process 0, input mesh data and distribute to other
        # processes
        return create_mesh(MPI.COMM_WORLD, cells, points, domain)
    else:
        if cell_type == "triangle":
            return create_mesh(MPI.COMM_WORLD, np.ndarray((0, 3)),
                               np.ndarray((0, 2)), domain)
        elif cell_type == "quadrilateral":
            return create_mesh(MPI.COMM_WORLD, np.ndarray((0, 4)),
                               np.ndarray((0, 2)), domain)
        elif cell_type == "tetrahedron":
            return create_mesh(MPI.COMM_WORLD, np.ndarray((0, 4)),
                               np.ndarray((0, 3)), domain)
        elif cell_type == "hexahedron":
            return create_mesh(MPI.COMM_WORLD, np.ndarray((0, 8)),
                               np.ndarray((0, 3)), domain)
示例#10
0
def gmsh_model_to_mesh(model, cell_data=False, facet_data=False, gdim=None, exportMesh=False, fileName="mesh.msh"):
    """
    Given a GMSH model, create a DOLFIN-X mesh and MeshTags. Can theoretically export to msh file
        model: The GMSH model
        cell_data: Boolean, True of a mesh tag for cell data should be returned
                   (Default: False)
        facet_data: Boolean, True if a mesh tag for facet data should be
                    returned (Default: False)
        gdim: Geometrical dimension of problem (Default: 3)
    """

    if gdim is None:
        gdim = 3

    if MPI.COMM_WORLD.rank == 0:
        # Get mesh geometry
        x = extract_gmsh_geometry(model)

        # Get mesh topology for each element
        topologies = extract_gmsh_topology_and_markers(model)

        # Get information about each cell type from the msh files
        num_cell_types = len(topologies.keys())
        cell_information = {}
        cell_dimensions = numpy.zeros(num_cell_types, dtype=numpy.int32)
        for i, element in enumerate(topologies.keys()):
            properties = model.mesh.getElementProperties(element)
            name, dim, order, num_nodes, local_coords, _ = properties
            cell_information[i] = {
                "id": element,
                "dim": dim,
                "num_nodes": num_nodes
            }
            cell_dimensions[i] = dim

        # Sort elements by ascending dimension
        perm_sort = numpy.argsort(cell_dimensions)

        # Broadcast cell type data and geometric dimension
        cell_id = cell_information[perm_sort[-1]]["id"]
        tdim = cell_information[perm_sort[-1]]["dim"]
        num_nodes = cell_information[perm_sort[-1]]["num_nodes"]
        cell_id, num_nodes = MPI.COMM_WORLD.bcast([cell_id, num_nodes], root=0)

        # Check for facet data and broadcast if found
        if facet_data:
            if tdim - 1 in cell_dimensions:
                num_facet_nodes = MPI.COMM_WORLD.bcast(
                    cell_information[perm_sort[-2]]["num_nodes"], root=0)
                gmsh_facet_id = cell_information[perm_sort[-2]]["id"]
                marked_facets = numpy.asarray(
                    topologies[gmsh_facet_id]["topology"], dtype=numpy.int64)
                facet_values = numpy.asarray(
                    topologies[gmsh_facet_id]["cell_data"], dtype=numpy.int32)
            else:
                raise ValueError("No facet data found in file.")

        cells = numpy.asarray(topologies[cell_id]["topology"],
                              dtype=numpy.int64)
        cell_values = numpy.asarray(topologies[cell_id]["cell_data"],
                                    dtype=numpy.int32)

    else:
        cell_id, num_nodes = MPI.COMM_WORLD.bcast([None, None], root=0)
        cells, x = numpy.empty([0, num_nodes],
                               dtype=numpy.int32), numpy.empty([0, gdim])
        cell_values = numpy.empty((0, ), dtype=numpy.int32)
        if facet_data:
            num_facet_nodes = MPI.COMM_WORLD.bcast(None, root=0)
            marked_facets = numpy.empty((0, num_facet_nodes),
                                        dtype=numpy.int32)
            facet_values = numpy.empty((0, ), dtype=numpy.int32)

    # Create distributed mesh
    ufl_domain = ufl_mesh_from_gmsh(cell_id, gdim)
    gmsh_cell_perm = perm_gmsh(to_type(str(ufl_domain.ufl_cell())), num_nodes)
    cells = cells[:, gmsh_cell_perm]
    mesh = create_mesh(MPI.COMM_WORLD, cells, x[:, :gdim], ufl_domain)
    # Create MeshTags for cells
    if cell_data:
        local_entities, local_values = distribute_entity_data(
            mesh, mesh.topology.dim, cells, cell_values)
        mesh.topology.create_connectivity(mesh.topology.dim, 0)
        adj = AdjacencyList_int32(local_entities)
        ct = create_meshtags(mesh, mesh.topology.dim, adj,
                             numpy.int32(local_values))
        ct.name = "cells"

    # Create MeshTags for facets
    if facet_data:
        # Permute facets from MSH to Dolfin-X ordering
        # FIXME: This does not work for prism meshes
        facet_type = cell_entity_type(to_type(str(ufl_domain.ufl_cell())),
                                      mesh.topology.dim - 1, 0)
        gmsh_facet_perm = perm_gmsh(facet_type, num_facet_nodes)
        marked_facets = marked_facets[:, gmsh_facet_perm]

        local_entities, local_values = distribute_entity_data(
            mesh, mesh.topology.dim - 1, marked_facets, facet_values)
        mesh.topology.create_connectivity(mesh.topology.dim - 1,
                                          mesh.topology.dim)
        adj = AdjacencyList_int32(local_entities)
        ft = create_meshtags(mesh, mesh.topology.dim - 1, adj,
                             numpy.int32(local_values))
        ft.name = "facets"

    if exportMesh:
        gmsh.write(fileName)

    if cell_data and facet_data:
        return mesh, ct, ft
    elif cell_data and not facet_data:
        return mesh, ct
    elif not cell_data and facet_data:
        return mesh, ft
    else:
        return mesh
示例#11
0
def test_gmsh_input_3d(order, cell_type):
    try:
        import gmsh
    except ImportError:
        pytest.skip()
    if cell_type == CellType.hexahedron and order > 2:
        pytest.xfail(
            "GMSH permutation for order > 2 hexahedra not implemented in DOLFINX."
        )

    res = 0.2

    gmsh.initialize()
    if cell_type == CellType.hexahedron:
        gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2)
        gmsh.option.setNumber("Mesh.RecombineAll", 2)
    gmsh.option.setNumber("Mesh.CharacteristicLengthMin", res)
    gmsh.option.setNumber("Mesh.CharacteristicLengthMax", res)

    circle = gmsh.model.occ.addDisk(0, 0, 0, 1, 1)

    if cell_type == CellType.hexahedron:
        gmsh.model.occ.extrude([(2, circle)],
                               0,
                               0,
                               1,
                               numElements=[5],
                               recombine=True)
    else:
        gmsh.model.occ.extrude([(2, circle)], 0, 0, 1, numElements=[5])
    gmsh.model.occ.synchronize()

    gmsh.model.mesh.generate(3)
    gmsh.model.mesh.setOrder(order)

    idx, points, _ = gmsh.model.mesh.getNodes()
    points = points.reshape(-1, 3)
    idx -= 1
    srt = np.argsort(idx)
    assert np.all(idx[srt] == np.arange(len(idx)))
    x = points[srt]

    element_types, element_tags, node_tags = gmsh.model.mesh.getElements(dim=3)
    name, dim, order, num_nodes, local_coords, num_first_order_nodes = gmsh.model.mesh.getElementProperties(
        element_types[0])

    cells = node_tags[0].reshape(-1, num_nodes) - 1
    if cell_type == CellType.tetrahedron:
        gmsh_cell_id = MPI.COMM_WORLD.bcast(gmsh.model.mesh.getElementType(
            "tetrahedron", order),
                                            root=0)
    elif cell_type == CellType.hexahedron:
        gmsh_cell_id = MPI.COMM_WORLD.bcast(gmsh.model.mesh.getElementType(
            "hexahedron", order),
                                            root=0)
    gmsh.finalize()

    # Permute the mesh topology from GMSH ordering to DOLFIN-X ordering
    domain = ufl_mesh_from_gmsh(gmsh_cell_id, 3)
    cells = cells[:, perm_gmsh(cell_type, cells.shape[1])]

    mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain)

    volume = assemble_scalar(1 * dx(mesh))

    assert mesh.mpi_comm().allreduce(volume, op=MPI.SUM) == pytest.approx(
        np.pi, rel=10**(-1 - order))
示例#12
0
def build_piston(n, length, radius, write_file=False, fname=""):
    """
    Build a hex cylinder mesh using gmsh
    """
    gmsh.initialize()
    gmsh.option.setNumber("General.Terminal", 0)
    model = gmsh.model()

    if MPI.COMM_WORLD.rank == 0:
        model.add("Piston")
        model.setCurrent("Piston")

        h = length / n

        gmsh.option.setNumber("Mesh.RecombineAll", 2)
        gmsh.option.setNumber("Mesh.RecombinationAlgorithm", 2)
        gmsh.option.setNumber("Mesh.CharacteristicLengthMin", 0.98 * h)
        gmsh.option.setNumber("Mesh.CharacteristicLengthMax", 1.02 * h)

        circle = model.occ.addDisk(0, 0, 0, radius, radius)
        model.occ.rotate([(2, circle)], 0., 0., 0., 0., 1., 0., np.pi / 2)
        model.occ.extrude([(2, circle)],
                          length,
                          0,
                          0,
                          numElements=[n],
                          recombine=True)

        model.occ.synchronize()
        model.mesh.generate(3)

        # sort mesh according to their index in gmsh
        x = extract_gmsh_geometry(model, model.getCurrent())

        # extract cells from gmsh
        element_types, element_tags, node_tags = model.mesh.getElements(dim=3)
        name, dim, order, num_nodes, local_coords, num_first_order_nodes = \
            model.mesh.getElementProperties(element_types[0])

        # broadcast cell type data and geometric dimension
        gmsh_cell_id = MPI.COMM_WORLD.bcast(element_types[0], root=0)

        # get mesh data for dim (0, tdim)
        cells = node_tags[0].reshape(-1, num_nodes) - 1

        num_nodes = MPI.COMM_WORLD.bcast(cells.shape[1], root=0)
        gmsh.finalize()
    else:
        gmsh_cell_id = MPI.COMM_WORLD.bcast(None, root=0)
        num_nodes = MPI.COMM_WORLD.bcast(None, root=0)
        cells, x = np.empty([0, num_nodes]), np.empty([0, 3])

    # permute the mesh topology from GMSH ordering to DOLFIN-X ordering
    domain = ufl_mesh_from_gmsh(gmsh_cell_id, 3)
    gmsh_hex = perm_gmsh(cpp.mesh.CellType.hexahedron, 8)
    cells = cells[:, gmsh_hex]

    mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain)
    mesh.name = "piston_hex"

    if write_file:
        with XDMFFile(MPI.COMM_WORLD, "{}.xdmf".format(fname), "w") as file:
            file.write_mesh(mesh)

    return mesh
    gmsh_facet_id = gmsh.model.mesh.getElementType("line", 2)
    marked_facets = topologies[gmsh_facet_id]["topology"].astype(np.int64)
    facet_values = topologies[gmsh_facet_id]["cell_data"].astype(np.int32)
else:
    # Create dolfinx mesh on other processes
    gmsh_cell_id = MPI.COMM_WORLD.bcast(None, root=0)
    num_nodes = MPI.COMM_WORLD.bcast(None, root=0)
    cells, x = np.empty([0, num_nodes]), np.empty([0, 3])
    marked_facets = np.empty((0, 3), dtype=np.int64)
    facet_values = np.empty((0,), dtype=np.int32)

# Permute the topology from GMSH to DOLFINx ordering
domain = ufl_mesh_from_gmsh(gmsh_cell_id, 2)
gmsh_tri6 = perm_gmsh(cpp.mesh.CellType.triangle, cells.shape[1])
cells = cells[:, gmsh_tri6]
mesh = create_mesh(MPI.COMM_WORLD, cells, x[:, :2], domain)

# Permute also entities which are tagged
gmsh_line3 = perm_gmsh(cpp.mesh.CellType.interval, 3)
marked_facets = marked_facets[:, gmsh_line3]

local_entities, local_values = extract_local_entities(
    mesh, 1, marked_facets, facet_values)
mesh.topology.create_connectivity(1, 0)
mt = create_meshtags(mesh, 1,
                     cpp.graph.AdjacencyList_int32(local_entities),
                     np.int32(local_values))

n = FacetNormal(mesh)
ds = Measure("ds", subdomain_data=mt)
示例#14
0
def gmsh_model_to_mesh(model, gdim):
    """
    Given a GMSH model, create a DOLFINx mesh and MeshTags.

    Parameters
    ----------
    model : gmsh.model
        The GMSH model.
    gdim: int
        Geometrical dimension of problem.

    Author
    ----------
    J. S. Dokken, http://jsdokken.com/converted_files/tutorial_gmsh.html
    """

    assert MPI.COMM_WORLD.size == 1, "This function has been simplified to the case of serial computations"

    # Get mesh geometry
    x = extract_gmsh_geometry(model)

    # Get mesh topology for each element
    topologies = extract_gmsh_topology_and_markers(model)

    # Get information about each cell type from the msh files
    num_cell_types = len(topologies.keys())
    cell_information = {}
    cell_dimensions = np.zeros(num_cell_types, dtype=np.int32)
    for i, element in enumerate(topologies.keys()):
        properties = model.mesh.getElementProperties(element)
        name, dim, order, num_nodes, coords, _ = properties
        cell_information[i] = {
            "id": element,
            "dim": dim,
            "num_nodes": num_nodes
        }
        cell_dimensions[i] = dim

    # Sort elements by ascending dimension
    perm_sort = np.argsort(cell_dimensions)

    # Get cell type data and geometric dimension
    cell_id = cell_information[perm_sort[-1]]["id"]
    tdim = cell_information[perm_sort[-1]]["dim"]
    num_nodes = cell_information[perm_sort[-1]]["num_nodes"]
    cells = np.asarray(topologies[cell_id]["topology"], dtype=np.int64)
    cell_values = np.asarray(topologies[cell_id]["cell_data"], dtype=np.int32)

    # Look up facet data
    assert tdim - 1 in cell_dimensions
    num_facet_nodes = cell_information[perm_sort[-2]]["num_nodes"]
    gmsh_facet_id = cell_information[perm_sort[-2]]["id"]
    marked_facets = np.asarray(topologies[gmsh_facet_id]["topology"],
                               dtype=np.int64)
    facet_values = np.asarray(topologies[gmsh_facet_id]["cell_data"],
                              dtype=np.int32)

    # Create distributed mesh
    ufl_domain = ufl_mesh_from_gmsh(cell_id, gdim)
    gmsh_cell_perm = perm_gmsh(to_type(str(ufl_domain.ufl_cell())), num_nodes)
    cells = cells[:, gmsh_cell_perm]
    mesh = create_mesh(MPI.COMM_WORLD, cells, x[:, :gdim], ufl_domain)

    # Create MeshTags for cells
    entities, values = distribute_entity_data(mesh, mesh.topology.dim, cells,
                                              cell_values)
    mesh.topology.create_connectivity(mesh.topology.dim, 0)
    adj = AdjacencyList_int32(entities)
    ct = meshtags_from_entities(mesh, mesh.topology.dim, adj, np.int32(values))
    ct.name = "Cell tags"

    # Create MeshTags for facets
    facet_type = cell_entity_type(to_type(str(ufl_domain.ufl_cell())),
                                  mesh.topology.dim - 1, 0)
    gmsh_facet_perm = perm_gmsh(facet_type, num_facet_nodes)
    marked_facets = marked_facets[:, gmsh_facet_perm]

    entities, values = distribute_entity_data(mesh, mesh.topology.dim - 1,
                                              marked_facets, facet_values)
    mesh.topology.create_connectivity(mesh.topology.dim - 1, mesh.topology.dim)
    adj = AdjacencyList_int32(entities)
    ft = meshtags_from_entities(mesh, mesh.topology.dim - 1, adj,
                                np.int32(values))
    ft.name = "Facet tags"

    return mesh, ct, ft
示例#15
0
# Generating a mesh on each process rank
# ======================================
#
# Generate a mesh on each rank with pygmsh, and create a DOLFIN-X mesh
# on each rank

# Interface needs updating for (py)msh API change
sys.exit(0)

geom = pygmsh.opencascade.Geometry()
geom.add_ball([0.0, 0.0, 0.0], 1.0, char_length=0.2)
pygmsh_mesh = pygmsh.generate_mesh(geom)
cells, x = pygmsh_mesh.cells[-1].data, pygmsh_mesh.points
pygmsh_cell = pygmsh_mesh.cells[-1].type
mesh = create_mesh(MPI.COMM_SELF, cells, x,
                   ufl_mesh_from_gmsh(pygmsh_cell, x.shape[1]))

with XDMFFile(MPI.COMM_SELF, "mesh_rank_{}.xdmf".format(MPI.COMM_WORLD.rank),
              "w") as file:
    file.write_mesh(mesh)

# Create a distributed (parallel) mesh with affine geometry
# =========================================================
#
# Generate mesh on rank 0, then build a distributed mesh

if MPI.COMM_WORLD.rank == 0:
    # Generate a mesh
    geom = pygmsh.opencascade.Geometry()
    ball = geom.add_ball([0.0, 0.0, 0.0], 1.0, char_length=0.2)
    box = geom.add_box([0.0, 0.0, 0.0], [1.0, 1.0, 1.0])
示例#16
0
def test_hexahedron_dof_ordering(space_type):
    """Checks that dofs on shared hexahedron edges match up"""

    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "hexahedron", 1))
    if MPI.COMM_WORLD.rank == 0:
        N = 5
        temp_points = np.array([[x / 2, y / 2, z / 2] for x in range(N) for y in range(N) for z 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):
                for z in range(N - 1):
                    a = N ** 2 * z + N * y + x
                    cell = [order[i] for i in [a, a + 1, a + N, a + N + 1,
                                               a + N ** 2, a + 1 + N ** 2, a + N + N ** 2,
                                               a + N + 1 + N ** 2]]
                    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, 8)), np.ndarray((0, 3)), domain)

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

    edges = {}
    faces = {}

    # 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([8, 3])
        for v in range(8):
            x_coord_new[v] = x_g[coord_dofs.links(cell_n)[v]]
        x = X.copy()
        cmap.push_forward(x, X, x_coord_new)

        edge_dofs_local = []
        for i in range(12):
            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

        face_dofs_local = []
        for i in range(6):
            face_dofs_local += list(dofmap.dof_layout.entity_dofs(2, i))
        face_dofs = [dofs[i] for i in face_dofs_local]
        for i, j in zip(face_dofs, x[face_dofs_local]):
            if i in faces:
                assert np.allclose(j, faces[i])
            else:
                faces[i] = j
示例#17
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
示例#18
0
def xtest_quadrilateral_integral(space_type, space_order):
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "quadrilateral", 1))
    temp_points = np.array([[-1., -1.], [0., 0.], [1., 0.], [-1., 1.],
                            [0., 1.], [2., 2.]])

    for repeat in range(10):
        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]

        connections = {0: [1, 2], 1: [0, 3], 2: [0, 3], 3: [1, 2]}

        cells = []
        for cell in [[0, 1, 3, 4], [1, 2, 4, 5]]:
            # Randomly number the cell
            start = choice(range(4))
            cell_order = [start]
            for i in range(2):
                diff = choice([
                    i for i in connections[start] if i not in cell_order
                ]) - cell_order[0]
                cell_order += [c + diff for c in cell_order]
            cells.append([order[cell[i]] for i in cell_order])

        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
        V = FunctionSpace(mesh, (space_type, space_order))
        Vvec = VectorFunctionSpace(mesh, ("P", 1))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        for d in dofs:
            v = Function(V)
            v.vector[:] = [
                1 if i == d else 0 for i in range(v.vector.local_size)
            ]
            if space_type in ["RTCF"]:
                # Hdiv
                def normal(x):
                    values = np.zeros((2, x.shape[1]))
                    values[0] = [1 for i in values[0]]
                    return values

                n = Function(Vvec)
                n.interpolate(normal)
                form = ufl.inner(ufl.jump(v), n) * ufl.dS
            elif space_type in ["RTCE"]:
                # Hcurl
                def tangent(x):
                    values = np.zeros((2, x.shape[1]))
                    values[1] = [1 for i in values[1]]
                    return values

                t = Function(Vvec)
                t.interpolate(tangent)
                form = ufl.inner(ufl.jump(v), t) * ufl.dS
            else:
                form = ufl.jump(v) * ufl.dS

            value = fem.assemble_scalar(form)
            assert np.isclose(value, 0)
示例#19
0
def random_evaluation_mesh(cell_type):
    random.seed(6)

    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell_type, 1))
    if cell_type == "triangle":
        temp_points = np.array([[-1., -1.], [0., 0.], [1., 0.], [0., 1.]])
        temp_cells = [[0, 1, 3], [1, 2, 3]]
    elif cell_type == "quadrilateral":
        temp_points = np.array([[-1., -1.], [0., 0.], [1., 0.], [-1., 1.],
                                [0., 1.], [2., 2.]])
        temp_cells = [[0, 1, 3, 4], [1, 2, 4, 5]]
    elif cell_type == "tetrahedron":
        temp_points = np.array([[-1., 0., -1.], [0., 0., 0.], [1., 0., 1.],
                                [0., 1., 0.], [0., 0., 1.]])
        temp_cells = [[0, 1, 3, 4], [1, 2, 3, 4]]
    elif cell_type == "hexahedron":
        temp_points = np.array([[-1., 0., -1.], [0., 0., 0.], [1., 0., 1.],
                                [-1., 1., 1.], [0., 1., 0.], [1., 1., 1.],
                                [-1., 0., 0.], [0., 0., 1.], [1., 0., 2.],
                                [-1., 1., 2.], [0., 1., 1.], [1., 1., 2.]])
        temp_cells = [[0, 1, 3, 4, 6, 7, 9, 10], [1, 2, 4, 5, 7, 8, 10, 11]]

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

    cells = []
    for cell in temp_cells:
        # Randomly number the cell
        if cell_type == "triangle":
            cell_order = list(range(3))
            random.shuffle(cell_order)
        elif cell_type == "quadrilateral":
            connections = {0: [1, 2], 1: [0, 3], 2: [0, 3], 3: [1, 2]}
            start = random.choice(range(4))
            cell_order = [start]
            for i in range(2):
                diff = random.choice([
                    i for i in connections[start] if i not in cell_order
                ]) - cell_order[0]
                cell_order += [c + diff for c in cell_order]
        elif cell_type == "tetrahedron":
            cell_order = list(range(4))
            random.shuffle(cell_order)
        elif cell_type == "hexahedron":
            connections = {
                0: [1, 2, 4],
                1: [0, 3, 5],
                2: [0, 3, 6],
                3: [1, 2, 7],
                4: [0, 5, 6],
                5: [1, 4, 7],
                6: [2, 4, 7],
                7: [3, 5, 6]
            }
            start = random.choice(range(8))
            cell_order = [start]
            for i in range(3):
                diff = random.choice([
                    i for i in connections[start] if i not in cell_order
                ]) - cell_order[0]
                cell_order += [c + diff for c in cell_order]

        cells.append([order[cell[i]] for i in cell_order])
    return create_mesh(MPI.COMM_WORLD, cells, points, domain)
示例#20
0
def xtest_tetrahedron_integral(space_type, space_order):
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "tetrahedron", 1))
    temp_points = np.array([[-1., 0., -1.], [0., 0., 0.], [1., 0., 1.],
                            [0., 1., 0.], [0., 0., 1.]])

    for repeat in range(10):
        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 cell in [[0, 1, 3, 4], [1, 2, 3, 4]]:
            # Randomly number the cell
            cell_order = list(range(4))
            shuffle(cell_order)
            cells.append([order[cell[i]] for i in cell_order])

        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
        V = FunctionSpace(mesh, (space_type, space_order))
        Vvec = VectorFunctionSpace(mesh, ("P", 1))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        for d in dofs:
            v = Function(V)
            v.vector[:] = [
                1 if i == d else 0 for i in range(v.vector.local_size)
            ]
            if space_type in ["RT", "BDM"]:
                # Hdiv
                def normal(x):
                    values = np.zeros((3, x.shape[1]))
                    values[0] = [1 for i in values[0]]
                    return values

                n = Function(Vvec)
                n.interpolate(normal)
                form = ufl.inner(ufl.jump(v), n) * ufl.dS
            elif space_type in ["N1curl", "N2curl"]:
                # Hcurl
                def tangent1(x):
                    values = np.zeros((3, x.shape[1]))
                    values[1] = [1 for i in values[1]]
                    return values

                def tangent2(x):
                    values = np.zeros((3, x.shape[1]))
                    values[2] = [1 for i in values[2]]
                    return values

                t1 = Function(Vvec)
                t1.interpolate(tangent1)
                t2 = Function(Vvec)
                t2.interpolate(tangent1)
                form = ufl.inner(ufl.jump(v), t1) * ufl.dS
                form += ufl.inner(ufl.jump(v), t2) * ufl.dS
            else:
                form = ufl.jump(v) * ufl.dS

            value = fem.assemble_scalar(form)
            assert np.isclose(value, 0)
示例#21
0
def test_volume_quadrilateralR3(coordinates):
    x = numpy.array(coordinates, dtype=numpy.float64)
    cells = numpy.array([[0, 1, 2, 3]], dtype=numpy.int32)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "quadrilateral", 1))
    mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
    assert cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0
示例#22
0
def test_hexahedron_evaluation(space_type, space_order):

    if space_type == "NCF" and space_order >= 3:
        print("Eval in this space not supported yet")
        return
    if space_type == "NCE" and space_order >= 2:
        print("Eval in this space not supported yet")
        return

    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "hexahedron", 1))
    temp_points = np.array([[-1., 0., -1.], [0., 0., 0.], [1., 0., 1.],
                            [-1., 1., 1.], [0., 1., 0.], [1., 1., 1.],
                            [-1., 0., 0.], [0., 0., 1.], [1., 0., 2.],
                            [-1., 1., 2.], [0., 1., 1.], [1., 1., 2.]])

    for repeat in range(10):
        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]

        connections = {
            0: [1, 2, 4],
            1: [0, 3, 5],
            2: [0, 3, 6],
            3: [1, 2, 7],
            4: [0, 5, 6],
            5: [1, 4, 7],
            6: [2, 4, 7],
            7: [3, 5, 6]
        }

        cells = []
        for cell in [[0, 1, 3, 4, 6, 7, 9, 10], [1, 2, 4, 5, 7, 8, 10, 11]]:
            # Randomly number the cell
            start = choice(range(8))
            cell_order = [start]
            for i in range(3):
                diff = choice([
                    i for i in connections[start] if i not in cell_order
                ]) - cell_order[0]
                cell_order += [c + diff for c in cell_order]
            cells.append([order[cell[i]] for i in cell_order])

        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
        V = FunctionSpace(mesh, (space_type, space_order))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        N = 6
        eval_points = np.array([[0., i / N, j / N] for i in range(N + 1)
                                for j in range(N + 1)])
        for d in dofs:
            v = Function(V)
            v.vector[:] = [1 if i == d else 0 for i in range(V.dim)]
            values0 = v.eval(eval_points, [0 for i in eval_points])
            values1 = v.eval(eval_points, [1 for i in eval_points])
            if len(eval_points) == 1:
                values0 = [values0]
                values1 = [values1]
            if space_type == "NCF":
                # Hdiv
                for i, j in zip(values0, values1):
                    assert np.isclose(i[0], j[0])
            elif space_type == "NCE":
                # Hcurl
                for i, j in zip(values0, values1):
                    assert np.allclose(i[1:], j[1:])
            else:
                assert np.allclose(values0, values1)
def mesh_3D_dolfin(theta: float = 0,
                   ct: _mesh.CellType = _mesh.CellType.tetrahedron,
                   ext: str = "tetrahedron",
                   res: float = 0.1):
    timer = _common.Timer("~~Contact: Create mesh")

    def find_plane_function(p0, p1, p2):
        """
        Find plane function given three points:
        http://www.nabla.hr/CG-LinesPlanesIn3DA3.htm
        """
        v1 = np.array(p1) - np.array(p0)
        v2 = np.array(p2) - np.array(p0)

        n = np.cross(v1, v2)
        D = -(n[0] * p0[0] + n[1] * p0[1] + n[2] * p0[2])
        return lambda x: np.isclose(0, np.dot(n, x) + D)

    def over_plane(p0, p1, p2):
        """
        Returns function that checks if a point is over a plane defined
        by the points p0, p1 and p2.
        """
        v1 = np.array(p1) - np.array(p0)
        v2 = np.array(p2) - np.array(p0)

        n = np.cross(v1, v2)
        D = -(n[0] * p0[0] + n[1] * p0[1] + n[2] * p0[2])
        return lambda x: n[0] * x[0] + n[1] * x[1] + D > -n[2] * x[2]

    N = int(1 / res)
    if MPI.COMM_WORLD.rank == 0:
        mesh0 = _mesh.create_unit_cube(MPI.COMM_SELF, N, N, N, ct)
        mesh1 = _mesh.create_unit_cube(MPI.COMM_SELF, 2 * N, 2 * N, 2 * N, ct)
        mesh0.geometry.x[:, 2] += 1

        # Stack the two meshes in one mesh
        r_matrix = _utils.rotation_matrix([1 / np.sqrt(2), 1 / np.sqrt(2), 0],
                                          -theta)
        points = np.vstack([mesh0.geometry.x, mesh1.geometry.x])
        points = np.dot(r_matrix, points.T).T

        # Transform topology info into geometry info
        tdim0 = mesh0.topology.dim
        num_cells0 = mesh0.topology.index_map(tdim0).size_local
        cells0 = _cpp.mesh.entities_to_geometry(
            mesh0, tdim0,
            np.arange(num_cells0, dtype=np.int32).reshape((-1, 1)), False)
        tdim1 = mesh1.topology.dim
        num_cells1 = mesh1.topology.index_map(tdim1).size_local
        cells1 = _cpp.mesh.entities_to_geometry(
            mesh1, tdim1,
            np.arange(num_cells1, dtype=np.int32).reshape((-1, 1)), False)
        cells1 += mesh0.geometry.x.shape[0]

        cells = np.vstack([cells0, cells1])
        cell = ufl.Cell(ext, geometric_dimension=points.shape[1])
        domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 1))
        mesh = _mesh.create_mesh(MPI.COMM_SELF, cells, points, domain)
        tdim = mesh.topology.dim
        fdim = tdim - 1
        # Find information about facets to be used in meshtags
        bottom_points = np.dot(
            r_matrix,
            np.array([[0, 0, 0], [1, 0, 0], [0, 1, 0], [1, 1, 0]]).T)
        bottom = find_plane_function(bottom_points[:, 0], bottom_points[:, 1],
                                     bottom_points[:, 2])
        bottom_facets = _mesh.locate_entities_boundary(mesh, fdim, bottom)

        top_points = np.dot(
            r_matrix,
            np.array([[0, 0, 2], [1, 0, 2], [0, 1, 2], [1, 1, 2]]).T)
        top = find_plane_function(top_points[:, 0], top_points[:, 1],
                                  top_points[:, 2])
        top_facets = _mesh.locate_entities_boundary(mesh, fdim, top)

        # left_side = find_line_function(top_points[:, 0], top_points[:, 3])
        # left_facets = _mesh.locate_entities_boundary(
        #     mesh, fdim, left_side)

        # right_side = find_line_function(top_points[:, 1], top_points[:, 2])
        # right_facets = _mesh.locate_entities_boundary(
        #     mesh, fdim, right_side)
        if_points = np.dot(
            r_matrix,
            np.array([[0, 0, 1], [1, 0, 1], [0, 1, 1], [1, 1, 1]]).T)

        interface = find_plane_function(if_points[:, 0], if_points[:, 1],
                                        if_points[:, 2])
        i_facets = _mesh.locate_entities_boundary(mesh, fdim, interface)
        mesh.topology.create_connectivity(fdim, tdim)
        top_interface = []
        bottom_interface = []
        facet_to_cell = mesh.topology.connectivity(fdim, tdim)
        num_cells = mesh.topology.index_map(tdim).size_local
        cell_midpoints = _cpp.mesh.compute_midpoints(mesh, tdim,
                                                     range(num_cells))
        top_cube = over_plane(if_points[:, 0], if_points[:, 1], if_points[:,
                                                                          2])
        for facet in i_facets:
            i_cells = facet_to_cell.links(facet)
            assert (len(i_cells == 1))
            i_cell = i_cells[0]
            if top_cube(cell_midpoints[i_cell]):
                top_interface.append(facet)
            else:
                bottom_interface.append(facet)

        num_cells = mesh.topology.index_map(tdim).size_local
        cell_midpoints = _cpp.mesh.compute_midpoints(mesh, tdim,
                                                     range(num_cells))
        top_cube_marker = 2
        indices = []
        values = []
        for cell_index in range(num_cells):
            if top_cube(cell_midpoints[cell_index]):
                indices.append(cell_index)
                values.append(top_cube_marker)
        ct = _mesh.meshtags(mesh, tdim, np.array(indices, dtype=np.int32),
                            np.array(values, dtype=np.int32))

        # Create meshtags for facet data
        markers: Dict[int, np.ndarray] = {
            3: top_facets,
            4: np.hstack(bottom_interface),
            9: np.hstack(top_interface),
            5: bottom_facets
        }  # , 6: left_facets, 7: right_facets}
        all_indices = []
        all_values = []

        for key in markers.keys():
            all_indices.append(np.asarray(markers[key], dtype=np.int32))
            all_values.append(np.full(len(markers[key]), key, dtype=np.int32))
        arg_sort = np.argsort(np.hstack(all_indices))
        sorted_vals = np.asarray(np.hstack(all_values)[arg_sort],
                                 dtype=np.int32)
        sorted_indices = np.asarray(np.hstack(all_indices)[arg_sort],
                                    dtype=np.int32)
        mt = _mesh.meshtags(mesh, fdim, sorted_indices, sorted_vals)
        mt.name = "facet_tags"  # type: ignore
        fname = f"meshes/mesh_{ext}_{theta:.2f}.xdmf"

        with _io.XDMFFile(MPI.COMM_SELF, fname, "w") as o_f:
            o_f.write_mesh(mesh)
            o_f.write_meshtags(ct)
            o_f.write_meshtags(mt)
    timer.stop()
示例#24
0
def xtest_hexahedron_integral(space_type, space_order):
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "hexahedron", 1))
    temp_points = np.array([[-1., 0., -1.], [0., 0., 0.], [1., 0., 1.],
                            [-1., 1., 1.], [0., 1., 0.], [1., 1., 1.],
                            [-1., 0., 0.], [0., 0., 1.], [1., 0., 2.],
                            [-1., 1., 2.], [0., 1., 1.], [1., 1., 2.]])

    for repeat in range(10):
        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]

        connections = {
            0: [1, 2, 4],
            1: [0, 3, 5],
            2: [0, 3, 6],
            3: [1, 2, 7],
            4: [0, 5, 6],
            5: [1, 4, 7],
            6: [2, 4, 7],
            7: [3, 5, 6]
        }

        cells = []
        for cell in [[0, 1, 3, 4, 6, 7, 9, 10], [1, 2, 4, 5, 7, 8, 10, 11]]:
            # Randomly number the cell
            start = choice(range(8))
            cell_order = [start]
            for i in range(3):
                diff = choice([
                    i for i in connections[start] if i not in cell_order
                ]) - cell_order[0]
                cell_order += [c + diff for c in cell_order]
            cells.append([order[cell[i]] for i in cell_order])

        mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
        V = FunctionSpace(mesh, (space_type, space_order))
        Vvec = VectorFunctionSpace(mesh, ("P", 1))
        dofs = [i for i in V.dofmap.cell_dofs(0) if i in V.dofmap.cell_dofs(1)]

        for d in dofs:
            v = Function(V)
            v.vector[:] = [1 if i == d else 0 for i in range(V.dim)]
            if space_type in ["NCF"]:
                # Hdiv
                def normal(x):
                    values = np.zeros((3, x.shape[1]))
                    values[0] = [1 for i in values[0]]
                    return values

                n = Function(Vvec)
                n.interpolate(normal)
                form = ufl.inner(ufl.jump(v), n) * ufl.dS
            elif space_type in ["NCE"]:
                # Hcurl
                def tangent1(x):
                    values = np.zeros((3, x.shape[1]))
                    values[1] = [1 for i in values[1]]
                    return values

                def tangent2(x):
                    values = np.zeros((3, x.shape[1]))
                    values[2] = [1 for i in values[2]]
                    return values

                t1 = Function(Vvec)
                t1.interpolate(tangent1)
                t2 = Function(Vvec)
                t2.interpolate(tangent1)
                form = ufl.inner(ufl.jump(v), t1) * ufl.dS
                form += ufl.inner(ufl.jump(v), t2) * ufl.dS
            else:
                form = ufl.jump(v) * ufl.dS

            value = fem.assemble_scalar(form)
            assert np.isclose(value, 0)
示例#25
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 = 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)
示例#26
0
def test_curl(space_type, order):
    """Test that curl is consistent for different cell permutations of a tetrahedron."""

    tdim = cpp.mesh.cell_dim(CellType.tetrahedron)
    points = unit_cell_points(CellType.tetrahedron)

    spaces = []
    results = []
    cell = list(range(len(points)))
    random.seed(2)

    # Assemble vector on 5 randomly numbered cells
    for i in range(5):
        random.shuffle(cell)

        domain = ufl.Mesh(
            ufl.VectorElement("Lagrange",
                              cpp.mesh.to_string(CellType.tetrahedron), 1))
        mesh = create_mesh(MPI.COMM_WORLD, [cell], points, domain)

        V = FunctionSpace(mesh, (space_type, order))
        v = ufl.TestFunction(V)

        f = ufl.as_vector(tuple(1 if i == 0 else 0 for i in range(tdim)))
        form = ufl.inner(f, ufl.curl(v)) * ufl.dx
        result = fem.assemble_vector(form)
        spaces.append(V)
        results.append(result.array)

    # Set data for first space
    V0 = spaces[0]
    c10_0 = V.mesh.topology.connectivity(1, 0)

    # Check that all DOFs on edges agree

    # Loop over cell edges
    for i, edge in enumerate(V0.mesh.topology.connectivity(tdim, 1).links(0)):

        # Get the edge vertices
        vertices0 = c10_0.links(edge)  # Need to map back

        # Get assembled values on edge
        values0 = sorted([
            result[V0.dofmap.cell_dofs(0)[a]]
            for a in V0.dofmap.dof_layout.entity_dofs(1, i)
        ])

        for V, result in zip(spaces[1:], results[1:]):
            # Get edge->vertex connectivity
            c10 = V.mesh.topology.connectivity(1, 0)

            # Loop over cell edges
            for j, e in enumerate(
                    V.mesh.topology.connectivity(tdim, 1).links(0)):
                if sorted(c10.links(e)) == sorted(
                        vertices0):  # need to map back c.links(e)
                    values = sorted([
                        result[V.dofmap.cell_dofs(0)[a]]
                        for a in V.dofmap.dof_layout.entity_dofs(1, j)
                    ])
                    assert np.allclose(values0, values)
                    break
            else:
                continue
            break
示例#27
0
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:
        random.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])

    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(cell_type), 1))
    mesh = create_mesh(MPI.COMM_WORLD, ordered_cells, ordered_points, domain)
    if return_order:
        return mesh, order
    return mesh
示例#28
0
def gmsh_to_dolfin(gmsh_model,
                   tdim: int,
                   comm=MPI.COMM_WORLD,
                   prune_y=False,
                   prune_z=False):
    """Converts a gmsh model object into `dolfinx.Mesh` and `dolfinx.MeshTags`
    for physical tags.

    Parameters
    ----------
    gmsh_model
    tdim
        Topological dimension of the mesh
    comm: optional
    ghost_mode: optional
    prune_y: optional
        Prune y-components. Used to embed a flat geometries into lower dimension.
    prune_z: optional
        Prune z-components. Used to embed a flat geometries into lower dimension.

    Note
    ----
    User must call `geo.synchronize()` and `mesh.generate()` before passing the model into
    this method.
    """

    rank = comm.rank

    logger = logging.getLogger("dolfiny")

    if rank == 0:
        # Map from internal gmsh cell type number to gmsh cell name
        # see https://gitlab.onelab.info/gmsh/gmsh/blob/master/Common/GmshDefines.h#L75
        gmsh_cellname = {
            1: 'line',
            2: 'triangle',
            3: "quad",
            4: 'tetra',
            5: "hexahedron",
            8: 'line3',
            9: 'triangle6',
            10: "quad9",
            11: 'tetra10',
            12: 'hexahedron27',
            15: 'vertex',
            21: 'triangle10',
            26: 'line4',
            29: 'tetra20',
            36: 'quad16',
            #  92: 'hexahedron64',
        }

        gmsh_dolfin = {
            "vertex": (CellType.point, 0),
            "line": (CellType.interval, 1),
            "line3": (CellType.interval, 2),
            "line4": (CellType.interval, 3),
            "triangle": (CellType.triangle, 1),
            "triangle6": (CellType.triangle, 2),
            "triangle10": (CellType.triangle, 3),
            "quad": (CellType.quadrilateral, 1),
            "quad9": (CellType.quadrilateral, 2),
            "quad16": (CellType.quadrilateral, 3),
            "tetra": (CellType.tetrahedron, 1),
            "tetra10": (CellType.tetrahedron, 2),
            "tetra20": (CellType.tetrahedron, 3),
            "hexahedron": (CellType.hexahedron, 1),
            "hexahedron27": (CellType.hexahedron, 2),
            #  "hexahedron64": (CellType.hexahedron, 3),
        }

        # Number of nodes for gmsh cell type
        nodes = {
            'vertex': 1,
            'line': 2,
            'line3': 3,
            'line4': 4,
            'triangle': 3,
            'triangle6': 6,
            'triangle10': 10,
            'tetra': 4,
            'tetra10': 10,
            'tetra20': 20,
            'quad': 4,
            'quad9': 9,
            'quad16': 16,
            'hexahedron': 8,
            'hexahedron27': 27,
            #  'hexahedron64': 64,
        }

        # node_tags, coord, param_coords = gmsh_model.mesh.getNodes()

        # FIXME: This silences the RuntimeWarning (ctypes / PEP3118 format string) caused by Gmsh/numpy
        import warnings
        with warnings.catch_warnings():
            warnings.simplefilter("ignore", RuntimeWarning)
            node_tags, coord, param_coords = gmsh_model.mesh.getNodes()

        # Fetch elements for the mesh
        cell_types, cell_tags, cell_node_tags = gmsh_model.mesh.getElements(
            dim=tdim)

        unused_nodes = numpy.setdiff1d(node_tags, cell_node_tags)
        unused_nodes_indices = []

        # FIXME: This would be expensive for many unused nodes case
        for unused_node in unused_nodes:
            unused_nodes_indices.append(
                numpy.where(node_tags == unused_node)[0])

        unused_nodes_indices = numpy.asarray(unused_nodes_indices)

        # Every node has 3 components in gmsh
        dim = 3
        points = numpy.reshape(coord, (-1, dim))

        # Delete unreferenced nodes
        points = numpy.delete(points, unused_nodes_indices, axis=0)
        node_tags = numpy.delete(node_tags, unused_nodes_indices)

        # Prepare a map from node tag to index in coords array
        nmap = numpy.argsort(node_tags - 1)
        cells = {}

        if len(cell_types) > 1:
            raise RuntimeError("Mixed topology meshes not supported.")

        try:
            cellname = gmsh_cellname[cell_types[0]]
        except KeyError:
            raise RuntimeError(
                f"Gmsh cell code {cell_types[0]:d} not supported.")

        try:
            num_nodes = nodes[cellname]
        except KeyError:
            raise RuntimeError(
                f"Cannot determine number of nodes for Gmsh cell type \"{cellname:s}\"."
            )

        logger.info(f"Processing mesh of gmsh cell name \"{cellname:s}\"")

        # Shift 1-based numbering and apply node map
        cells[cellname] = nmap[cell_node_tags[0] - 1]
        cells[cellname] = numpy.reshape(cells[cellname], (-1, num_nodes))

        if prune_z:
            if not numpy.allclose(points[:, 2], 0.0):
                raise RuntimeError("Non-zero z-component would be pruned.")

            points = points[:, :-1]

        if prune_y:
            if not numpy.allclose(points[:, 1], 0.0):
                raise RuntimeError("Non-zero y-component would be pruned.")

            if prune_z:
                # In the case we already pruned z-component
                points = points[:, 0]
            else:
                points = points[:, [0, 2]]

        try:
            dolfin_cell_type, order = gmsh_dolfin[cellname]
        except KeyError:
            raise RuntimeError(
                f"Cannot determine dolfin cell type for Gmsh cell type \"{cellname:s}\"."
            )

        perm = cpp.io.perm_gmsh(dolfin_cell_type, num_nodes)
        logger.info(f"Mesh will be permuted with {perm}")
        cells = cells[cellname][:, perm]

        logger.info(
            f"Constructing mesh for tdim: {tdim:d}, gdim: {points.shape[1]:d}")
        logger.info(f"Number of elements: {cells.shape[0]:d}")

        cells_shape, pts_shape, cellname = comm.bcast(
            [cells.shape, points.shape, cellname], root=0)
    else:
        cells_shape, pts_shape, cellname = comm.bcast([None, None, None],
                                                      root=0)
        cells = numpy.empty((0, cells_shape[1]))
        points = numpy.empty((0, pts_shape[1]))

    mesh = create_mesh(comm, cells, points,
                       ufl_mesh_from_gmsh(cellname, pts_shape[1]))
    mts = {}

    # Get physical groups (dimension, tag)
    pgdim_pgtags = comm.bcast(
        gmsh_model.getPhysicalGroups() if rank == 0 else None, root=0)

    for pgdim, pgtag in pgdim_pgtags:

        # For the current physical tag there could be multiple entities
        # e.g. user tagged bottom and up boundary part with one physical tag
        entity_tags = comm.bcast(gmsh_model.getEntitiesForPhysicalGroup(
            pgdim, pgtag) if rank == 0 else None,
                                 root=0)
        pg_tag_name = comm.bcast(
            gmsh_model.getPhysicalName(pgdim, pgtag) if rank == 0 else None,
            root=0)

        if pg_tag_name == "":
            pg_tag_name = f"tag_{pgtag:d}"

        if rank == 0:

            _mt_cells = []
            _mt_values = []

            for i, entity_tag in enumerate(entity_tags):
                pgcell_types, pgcell_tags, pgnode_tags = gmsh_model.mesh.getElements(
                    pgdim, entity_tag)

                assert (len(pgcell_types) == 1)
                pgcellname = gmsh_cellname[pgcell_types[0]]
                pgnum_nodes = nodes[pgcellname]

                # Shift 1-based numbering and apply node map
                pgnode_tags[0] = nmap[pgnode_tags[0] - 1]
                _mt_cells.append(pgnode_tags[0].reshape(-1, pgnum_nodes))
                _mt_values.append(
                    numpy.full(_mt_cells[-1].shape[0],
                               pgtag,
                               dtype=numpy.int32))

            # Stack all topology and value data. This prepares data
            # for one MVC per (dim, physical tag) instead of multiple MVCs
            _mt_values = numpy.hstack(_mt_values)
            _mt_cells = numpy.vstack(_mt_cells)

            # Fetch the permutation needed for physical group
            pgdolfin_cell_type, pgorder = gmsh_dolfin[pgcellname]
            pgpermutation = cpp.io.perm_gmsh(pgdolfin_cell_type, pgnum_nodes)

            _mt_cells[:, :] = _mt_cells[:, pgpermutation]

            logger.info(f"Constructing MVC for tdim: {pgdim:d}")
            logger.info(f"Number of data values: {_mt_values.shape[0]:d}")

            mt_cells_shape, pgdim = comm.bcast([_mt_cells.shape, pgdim],
                                               root=0)
        else:
            mt_cells_shape, pgdim = comm.bcast([None, None], root=0)
            _mt_cells = numpy.empty((0, mt_cells_shape[1]))
            _mt_values = numpy.empty((0, ))

        local_entities, local_values = extract_local_entities(
            mesh, pgdim, _mt_cells, _mt_values)

        mesh.topology.create_connectivity(pgdim, 0)

        mt = create_meshtags(mesh, pgdim,
                             cpp.graph.AdjacencyList_int32(local_entities),
                             numpy.int32(local_values))
        mt.name = pg_tag_name

        mts[pg_tag_name] = mt

    return mesh, mts
示例#29
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 = 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)
示例#30
0
def test_volume_quadrilateralR3(x):
    cells = [[0, 1, 2, 3]]
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "quadrilateral", 1))
    mesh = create_mesh(MPI.COMM_SELF, cells, x, domain)
    assert _cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0