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

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

    """
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "interval", 1))
    cmap = fem.create_coordinate_map(comm, domain)
    mesh = cpp.generation.create_interval_mesh(comm, nx, points, cmap,
                                               ghost_mode, partitioner)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Esempio n. 2
0
def create_boundary_mesh(mesh, comm, orient=False):
    """
    Create a mesh consisting of all exterior facets of a mesh
    Input:
      mesh   - The mesh
      comm   - The MPI communicator
      orient - Boolean flag for reorientation of facets to have
               consistent outwards-pointing normal (default: True)
    Output:
      bmesh - The boundary mesh
      bmesh_to_geometry - Map from cells of the boundary mesh
                          to the geometry of the original mesh
    """
    ext_facets = cpp.mesh.exterior_facet_indices(mesh)
    boundary_geometry = cpp.mesh.entities_to_geometry(mesh,
                                                      mesh.topology.dim - 1,
                                                      ext_facets, orient)
    facet_type = cpp.mesh.to_string(
        cpp.mesh.cell_entity_type(mesh.topology.cell_type,
                                  mesh.topology.dim - 1))
    facet_cell = ufl.Cell(facet_type, geometric_dimension=mesh.geometry.dim)
    degree = mesh.ufl_domain().ufl_coordinate_element().degree()
    ufl_domain = ufl.Mesh(ufl.VectorElement("Lagrange", facet_cell, degree))
    bmesh = create_mesh(comm, boundary_geometry, mesh.geometry.x, ufl_domain)
    return bmesh, boundary_geometry
Esempio n. 3
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)
    mesh.topology.create_connectivity_all()
    assert cpp.mesh.volume_entities(mesh, [0], mesh.topology.dim) == 1.0
Esempio n. 4
0
def test_cmap_hex(degree, compile_args):
    """Test hexahedron cell"""
    # Assuming FIAT Tensor Product layout of cell.

    cell = ufl.hexahedron
    e = ufl.VectorElement("Lagrange", cell, degree)
    mesh = ufl.Mesh(e)
    compiled_cmap, module = ffcx.codegeneration.jit.compile_coordinate_maps(
        [mesh], cffi_extra_compile_args=compile_args)

    assert compiled_cmap[0].is_affine == 0
    assert compiled_cmap[0].geometric_dimension == 3
    assert compiled_cmap[0].topological_dimension == 3

    # Reference coordinates X to basis
    phi = np.zeros((degree + 1)**3, dtype=np.float64)
    phi_ptr = module.ffi.cast("double *", module.ffi.from_buffer(phi))
    X = np.array([[0.5, 0.5, 0.5]], dtype=np.float64)
    X_ptr = module.ffi.cast("double *", module.ffi.from_buffer(X))
    compiled_cmap[0].evaluate_basis_derivatives(phi_ptr, 0, X.shape[0], X_ptr)
    assert np.isclose(sum(phi), 1.0)

    num_entity_dofs = compiled_cmap[0].create_scalar_dofmap().num_entity_dofs

    assert num_entity_dofs[0] == 1

    if degree == 1:
        assert num_entity_dofs[1] == 0
        assert num_entity_dofs[2] == 0
        assert num_entity_dofs[3] == 0
    elif degree == 2:
        assert num_entity_dofs[1] == 1
        assert num_entity_dofs[2] == 1
        assert num_entity_dofs[3] == 1
Esempio n. 5
0
def test_cmap_triangle(degree, compile_args):
    """Test triangle cell."""
    cell = ufl.triangle
    element = ufl.VectorElement("Lagrange", cell, degree)
    mesh = ufl.Mesh(element)
    compiled_cmap, module = ffcx.codegeneration.jit.compile_coordinate_maps(
        [mesh], cffi_extra_compile_args=compile_args, cache_dir=".")

    assert compiled_cmap[0].is_affine == (1 if (degree == 1) else 0)
    assert compiled_cmap[0].geometric_dimension == 2
    assert compiled_cmap[0].topological_dimension == 2

    # Reference coordinates X to basis
    phi = np.zeros(((degree + 2) * (degree + 1)) // 2, dtype=np.float64)
    phi_ptr = module.ffi.cast("double *", module.ffi.from_buffer(phi))
    X = np.array([[1 / 3, 1 / 3]], dtype=np.float64)
    X_ptr = module.ffi.cast("double *", module.ffi.from_buffer(X))
    compiled_cmap[0].evaluate_basis_derivatives(phi_ptr, 0, X.shape[0], X_ptr)
    assert np.isclose(sum(phi), 1.0)

    num_entity_dofs = compiled_cmap[0].create_scalar_dofmap().num_entity_dofs

    assert num_entity_dofs[0] == 1
    assert num_entity_dofs[2] == 0
    assert num_entity_dofs[3] == 0

    if degree == 1:
        assert num_entity_dofs[1] == 0
    elif degree == 2:
        assert num_entity_dofs[1] == 1
Esempio n. 6
0
def test_assemble_manifold():
    """Test assembly of poisson problem on a mesh with topological dimension 1
    but embedded in 2D (gdim=2).
    """
    points = numpy.array([[0.0, 0.0], [0.2, 0.0], [0.4, 0.0], [0.6, 0.0],
                          [0.8, 0.0], [1.0, 0.0]],
                         dtype=numpy.float64)
    cells = numpy.array([[0, 1], [1, 2], [2, 3], [3, 4], [4, 5]],
                        dtype=numpy.int32)
    cell = ufl.Cell("interval", geometric_dimension=points.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    assert mesh.geometry.dim == 2
    assert mesh.topology.dim == 1

    U = dolfinx.FunctionSpace(mesh, ("P", 1))

    u, v = ufl.TrialFunction(U), ufl.TestFunction(U)
    w = dolfinx.Function(U)

    a = ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx(mesh)
    L = ufl.inner(1.0, v) * ufl.dx(mesh)

    bcdofs = dolfinx.fem.locate_dofs_geometrical(
        U, lambda x: numpy.isclose(x[0], 0.0))
    bcs = [dolfinx.DirichletBC(w, bcdofs)]
    A = dolfinx.fem.assemble_matrix(a, bcs)
    A.assemble()

    b = dolfinx.fem.assemble_vector(L)
    dolfinx.fem.apply_lifting(b, [a], [bcs])
    dolfinx.fem.set_bc(b, bcs)

    assert numpy.isclose(b.norm(), 0.41231)
    assert numpy.isclose(A.norm(), 25.0199)
Esempio n. 7
0
def test_collision_2nd_order_triangle():
    points = np.array([[0, 0], [1, 0], [0, 1], [0.65, 0.65], [0, 0.5], [0.5, 0]])
    cells = np.array([[0, 1, 2, 3, 4, 5]])
    cell = ufl.Cell("triangle", geometric_dimension=2)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 2))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

    # Sample points along an interior line of the domain. The last point
    # is outside the simplex made by the vertices.
    sample_points = np.array([[0.1, 0.3, 0], [0.2, 0.5, 0], [0.6, 0.6, 0]])

    # Create boundingboxtree
    tree = geometry.BoundingBoxTree(mesh, mesh.geometry.dim)
    for point in sample_points:
        colliding_cell = geometry.compute_colliding_cells(tree, mesh, point, 1)
        assert(len(colliding_cell) == 1)

    # Check if there is a point on the linear approximation of the
    # curved facet
    def line_through_points(p0, p1):
        return lambda x: (p1[1] - p0[1]) / (p1[0] - p0[0]) * (x - p0[0]) + p0[1]
    line_func = line_through_points(points[2], points[3])
    point = np.array([0.2, line_func(0.2), 0])
    # Point inside 2nd order geometry, outside linear approximation
    # Usefull for debugging on a later stage
    # point = np.array([0.25, 0.89320760, 0])
    distance = cpp.geometry.squared_distance(mesh, mesh.topology.dim - 1, 2, point)
    assert np.isclose(distance, 0)
Esempio n. 8
0
def test_triangle_mesh(order):
    points = []
    points += [[i / order, 0] for i in range(order + 1)]
    for j in range(1, order):
        points += [[i / order + 0.1, j / order] for i in range(order + 1 - j)]
    points += [[0, 1]]

    def coord_to_vertex(x, y):
        return y * (2 * order + 3 - y) // 2 + x

    # Define a cell using dolfin ordering
    cell = [coord_to_vertex(i, j) for i, j in [(0, 0), (order, 0), (0, order)]]
    if order > 1:
        for i in range(1, order):
            cell.append(coord_to_vertex(order - i, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(0, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(i, 0))

        for j in range(1, order):
            for i in range(1, order - j):
                cell.append(coord_to_vertex(i, j))

    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange",
                          ufl.Cell("triangle", geometric_dimension=2), order))

    check_cell_volume(points, cell, domain, 0.5)
Esempio n. 9
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.dim)]
            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)
Esempio n. 10
0
    def read_mesh(self,
                  ghost_mode=cpp.mesh.GhostMode.shared_facet,
                  name="mesh",
                  xpath="/Xdmf/Domain"):
        # Read mesh data from file
        cell_shape, cell_degree = super().read_cell_type(name, xpath)
        cells = super().read_topology_data(name, xpath)
        x = super().read_geometry_data(name, xpath)

        # Construct the geometry map
        cell = ufl.Cell(cpp.mesh.to_string(cell_shape),
                        geometric_dimension=x.shape[1])
        domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, cell_degree))

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

        return mesh
Esempio n. 11
0
def test_cmap_hex(degree, compile_args):
    """Test hexahedron cell"""

    cell = ufl.hexahedron
    e = ufl.VectorElement("Lagrange", cell, degree)
    mesh = ufl.Mesh(e)
    compiled_cmap, module = ffcx.codegeneration.jit.compile_coordinate_maps(
        [mesh], cffi_extra_compile_args=compile_args)

    assert compiled_cmap[0].is_affine == 0
    assert compiled_cmap[0].geometric_dimension == 3
    assert compiled_cmap[0].topological_dimension == 3

    num_entity_dofs = compiled_cmap[0].create_scalar_dofmap().num_entity_dofs

    assert num_entity_dofs[0] == 1

    if degree == 1:
        assert num_entity_dofs[1] == 0
        assert num_entity_dofs[2] == 0
        assert num_entity_dofs[3] == 0
    elif degree == 2:
        assert num_entity_dofs[1] == 1
        assert num_entity_dofs[2] == 1
        assert num_entity_dofs[3] == 1
def test_quadrilateral_mesh(order):
    random.seed(13)

    points = []
    points += [[i / order, 0] for i in range(order + 1)]
    for j in range(1, order):
        points += [[i / order + 0.1, j / order] for i in range(order + 1)]
    points += [[j / order, 1] for j in range(order + 1)]

    def coord_to_vertex(x, y):
        return (order + 1) * y + x

    # Define a cell using DOLFINx ordering
    cell = [coord_to_vertex(i, j)
            for i, j in [(0, 0), (order, 0), (0, order), (order, order)]]
    if order > 1:
        for i in range(1, order):
            cell.append(coord_to_vertex(i, 0))
        for i in range(1, order):
            cell.append(coord_to_vertex(0, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(order, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(i, order))

        for j in range(1, order):
            for i in range(1, order):
                cell.append(coord_to_vertex(i, j))

    domain = ufl.Mesh(ufl.VectorElement(
        "Q", ufl.Cell("quadrilateral", geometric_dimension=2), order))

    check_cell_volume(points, cell, domain, 1)
Esempio n. 13
0
def ufl_domain(self):
    """Returns the ufl domain corresponding to the mesh."""
    # Cache object to avoid recreating it a lot
    if not hasattr(self, "_ufl_domain"):
        self._ufl_domain = ufl.Mesh(
            self.ufl_coordinate_element(), ufl_id=self.ufl_id(), cargo=self)
    return self._ufl_domain
Esempio n. 14
0
def BoxMesh(comm,
            points: typing.List[numpy.array],
            n: list,
            cell_type=cpp.mesh.CellType.tetrahedron,
            ghost_mode=cpp.mesh.GhostMode.shared_facet,
            partitioner=cpp.mesh.partition_cells_graph):
    """Create box mesh

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

    """
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(cell_type), 1))
    mesh = cpp.generation.create_box_mesh(comm, points, n, cell_type,
                                          ghost_mode, partitioner)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Esempio n. 15
0
def create_box(
    comm: _MPI.Comm,
    points: typing.List[np.array],
    n: list,
    cell_type=CellType.tetrahedron,
    ghost_mode=GhostMode.shared_facet,
    partitioner=_cpp.mesh.create_cell_partitioner()
) -> Mesh:
    """Create box mesh

    Args:
        comm: MPI communicator
        points: Coordinates of the 'lower-left' and 'upper-right'
            corners of the box
        n: List of cells in each direction
        cell_type: The cell type
        ghost_mode: The ghost mode used in the mesh partitioning
        partitioner: Function that computes the parallel distribution of
            cells across MPI ranks

    Returns:
        A mesh of a box domain

    """
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell_type.name, 1))
    mesh = _cpp.mesh.create_box(comm, points, n, cell_type, ghost_mode,
                                partitioner)
    return Mesh.from_cpp(mesh, domain)
Esempio n. 16
0
def one_cell_mesh(cell_type):
    if cell_type == CellType.interval:
        points = np.array([[-1.], [2.]])
    if cell_type == CellType.triangle:
        points = np.array([[-1., -1.], [2., 0.], [0., 0.5]])
    elif cell_type == CellType.tetrahedron:
        points = np.array([[-1., -1., -1.], [2., 0., 0.], [0., 0.5, 0.], [0., 0., 1.]])
    elif cell_type == CellType.quadrilateral:
        points = np.array([[-1., 0.], [1., 0.], [-1., 1.5], [1., 1.5]])
    elif cell_type == CellType.hexahedron:
        points = np.array([[-1., -0.5, 0.], [1., -0.5, 0.], [-1., 1.5, 0.],
                           [1., 1.5, 0.], [0., -0.5, 1.], [1., -0.5, 1.],
                           [-1., 1.5, 1.], [1., 1.5, 1.]])
    num_points = len(points)

    # Randomly number the points and create the mesh
    order = list(range(num_points))
    random.shuffle(order)
    ordered_points = np.zeros(points.shape)
    for i, j in enumerate(order):
        ordered_points[j] = points[i]
    cells = np.array([order])

    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cpp.mesh.to_string(cell_type), 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, ordered_points, domain)

    mesh.topology.create_connectivity_all()
    return mesh
Esempio n. 17
0
def create_interval(
    comm: _MPI.Comm,
    nx: int,
    points: list,
    ghost_mode=GhostMode.shared_facet,
    partitioner=_cpp.mesh.create_cell_partitioner()
) -> Mesh:
    """Create an interval mesh

    Args:
        comm: MPI communicator
        nx: Number of cells
        points: Coordinates of the end points
        ghost_mode: Ghost mode used in the mesh partitioning. Options
            are `GhostMode.none' and `GhostMode.shared_facet`.
        partitioner: Partitioning function to use for determining the
            parallel distribution of cells across MPI ranks

    Returns:
        An interval mesh

    """
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", "interval", 1))
    mesh = _cpp.mesh.create_interval(comm, nx, points, ghost_mode, partitioner)
    return Mesh.from_cpp(mesh, domain)
Esempio n. 18
0
def create_rectangle(comm: _MPI.Comm,
                     points: typing.List[np.array],
                     n: list,
                     cell_type=CellType.triangle,
                     ghost_mode=GhostMode.shared_facet,
                     partitioner=_cpp.mesh.create_cell_partitioner(),
                     diagonal: DiagonalType = DiagonalType.right) -> Mesh:
    """Create rectangle mesh

    Args:
        comm: MPI communicator
        points: Coordinates of the lower-left and upper-right corners of the
            rectangle
        n: Number of cells in each direction
        cell_type: Mesh cell type
        ghost_mode: Ghost mode used in the mesh partitioning
        partitioner: Function that computes the parallel distribution of
            cells across MPI ranks
        diagonal: Direction of diagonal of triangular meshes. The
            options are ``left``, ``right``, ``crossed``, ``left/right``,
            ``right/left``.

    Returns:
        A mesh of a rectangle

    """
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell_type.name, 1))
    mesh = _cpp.mesh.create_rectangle(comm, points, n, cell_type, ghost_mode,
                                      partitioner, diagonal)
    return Mesh.from_cpp(mesh, domain)
Esempio n. 19
0
def test_higher_order_coordinate_map(points, celltype, order):
    """Computes physical coordinates of a cell, based on the coordinate map."""
    print(celltype)
    cells = np.array([range(len(points))])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cpp.mesh.to_string(celltype), order))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

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

    x_coord_new = np.zeros([len(points), mesh.geometry.dim])

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

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

    if mesh.geometry.dim == 3:
        assert np.allclose(x[:, 2], 3 * X[:, 2])
Esempio n. 20
0
def test_custom_quadrature(compile_args):
    ve = ufl.VectorElement("P", "triangle", 1)
    mesh = ufl.Mesh(ve)

    e = ufl.FiniteElement("P", mesh.ufl_cell(), 2)
    V = ufl.FunctionSpace(mesh, e)
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    points = [[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [0.5, 0.5], [0.0, 0.5], [0.5, 0.0]]
    weights = [1 / 12] * 6
    a = u * v * ufl.dx(metadata={"quadrature_rule": "custom",
                                 "quadrature_points": points, "quadrature_weights": weights})

    forms = [a]
    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(forms, cffi_extra_compile_args=compile_args)

    ffi = cffi.FFI()
    form = compiled_forms[0][0]
    default_integral = form.create_cell_integral(-1)

    A = np.zeros((6, 6), dtype=np.float64)
    w = np.array([], dtype=np.float64)
    c = np.array([], dtype=np.float64)

    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)
    default_integral.tabulate_tensor(
        ffi.cast("double *", A.ctypes.data),
        ffi.cast("double *", w.ctypes.data),
        ffi.cast("double *", c.ctypes.data),
        ffi.cast("double *", coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    # Check that A is diagonal
    assert np.count_nonzero(A - np.diag(np.diagonal(A))) == 0
Esempio n. 21
0
def RectangleMesh(comm,
                  points: typing.List[numpy.array],
                  n: list,
                  cell_type=cpp.mesh.CellType.triangle,
                  ghost_mode=cpp.mesh.GhostMode.shared_facet,
                  diagonal: str = "right"):
    """Create rectangle mesh

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

    """
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", cpp.mesh.to_string(cell_type), 1))
    cmap = fem.create_coordinate_map(comm, domain)
    mesh = cpp.generation.RectangleMesh.create(comm, points, n, cmap,
                                               ghost_mode, diagonal)
    domain._ufl_cargo = mesh
    mesh._ufl_domain = domain
    return mesh
Esempio n. 22
0
def create_submesh(mesh, dim, entities):
    submesh, vertex_map, geom_map = _cpp.mesh.create_submesh(mesh, dim, entities)
    submesh_ufl_cell = ufl.Cell(submesh.topology.cell_name(),
                                geometric_dimension=submesh.geometry.dim)
    # FIXME Don't hard code degree (and maybe Lagrange?)
    submesh_domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell=submesh_ufl_cell, degree=1))
    return (Mesh.from_cpp(submesh, submesh_domain), vertex_map, geom_map)
Esempio n. 23
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.dim)]
            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)
Esempio n. 24
0
def test_quadrilateral_dof_positions(space_type):
    """Checks that dofs on shared quadrilateral edges match up"""

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

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

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

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

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

    edges = {}

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

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

        edge_dofs_local = []
        for i in range(4):
            edge_dofs_local += list(dofmap.dof_layout.entity_dofs(1, i))
        edge_dofs = [dofs[i] for i in edge_dofs_local]
        for i, j in zip(edge_dofs, x[edge_dofs_local]):
            if i in edges:
                assert np.allclose(j, edges[i])
            else:
                edges[i] = j
Esempio n. 25
0
def test_tetrahedron_mesh(order):
    points = []
    points += [[i / order, j / order, 0] for j in range(order + 1)
               for i in range(order + 1 - j)]
    for k in range(1, order):
        points += [[i / order, j / order + 0.1, k / order]
                   for j in range(order + 1 - k)
                   for i in range(order + 1 - k - j)]

    points += [[0, 0, 1]]

    def coord_to_vertex(x, y, z):
        return z * (3 * order**2 - 3 * order * z + 12 * order + z**2 - 6 * z +
                    11) // 6 + y * (2 * (order - z) + 3 - y) // 2 + x

    # Define a cell using dolfin ordering
    cell = [
        coord_to_vertex(x, y, z)
        for x, y, z in [(0, 0, 0), (order, 0, 0), (0, order, 0), (0, 0, order)]
    ]

    if order > 1:
        for i in range(1, order):
            cell.append(coord_to_vertex(0, order - i, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(order - i, 0, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(order - i, i, 0))
        for i in range(1, order):
            cell.append(coord_to_vertex(0, 0, i))
        for i in range(1, order):
            cell.append(coord_to_vertex(0, i, 0))
        for i in range(1, order):
            cell.append(coord_to_vertex(i, 0, 0))

        for j in range(1, order):
            for i in range(1, order - j):
                cell.append(coord_to_vertex(order - i - j, i, j))
        for j in range(1, order):
            for i in range(1, order - j):
                cell.append(coord_to_vertex(0, i, j))
        for j in range(1, order):
            for i in range(1, order - j):
                cell.append(coord_to_vertex(i, 0, j))
        for j in range(1, order):
            for i in range(1, order - j):
                cell.append(coord_to_vertex(i, j, 0))

        for k in range(1, order):
            for j in range(1, order - k):
                for i in range(1, order - j - k):
                    cell.append(coord_to_vertex(i, j, k))

    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange",
                          ufl.Cell("tetrahedron", geometric_dimension=3),
                          order))

    check_cell_volume(points, cell, domain, 1 / 6)
Esempio n. 26
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)
Esempio n. 27
0
def ufl_mesh_from_gmsh(gmsh_cell: int, gdim: int):
    """
    Create a UFL mesh from a Gmsh cell identifier and the geometric dimension.
    See: # http://gmsh.info//doc/texinfo/gmsh.html#MSH-file-format
    """
    shape, degree = _gmsh_to_cells[gmsh_cell]
    cell = ufl.Cell(shape, geometric_dimension=gdim)
    return ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
Esempio n. 28
0
def ufl_domain(mesh):
    """Returns the ufl domain corresponding to the mesh."""
    # Cache object to avoid recreating it a lot
    if not hasattr(mesh, "_ufl_domain"):
        mesh._ufl_domain = ufl.Mesh(mesh.ufl_coordinate_element(),
                                    ufl_id=mesh.ufl_id(),
                                    cargo=mesh)
    return mesh._ufl_domain
Esempio n. 29
0
def create_quad_mesh(offset):
    """Creates a mesh of a single square element if offset = 0, or a
    trapezium element if |offset| > 0."""
    x = np.array([[0, 0], [1, 0], [0, 0.5 + offset], [1, 0.5 - offset]])
    cells = np.array([[0, 1, 2, 3]])
    ufl_mesh = ufl.Mesh(ufl.VectorElement("Lagrange", "quadrilateral", 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, x, ufl_mesh)
    return mesh
Esempio n. 30
0
def test_second_order_vtx(tempdir):
    filename = os.path.join(tempdir, "mesh_fides.bp")
    points = np.array([[0, 0, 0], [1, 0, 0], [0.5, 0, 0]], dtype=np.float64)
    cells = np.array([[0, 1, 2]], dtype=np.int32)
    cell = ufl.Cell("interval", geometric_dimension=points.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 2))
    mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)
    with VTXWriter(mesh.comm, filename, mesh) as f:
        f.write(0.0)