Esempio n. 1
0
    def __init__(self, p1dg_space, time_dependent_mesh=True):
        """
        :arg p1dg_space: P1DG function space
        """

        assert_function_space(p1dg_space, ['Discontinuous Lagrange', 'DQ'], 1)
        self.is_vector = p1dg_space.value_size > 1
        if self.is_vector:
            p1dg_scalar_space = FunctionSpace(p1dg_space.mesh(), 'DG', 1)
            super(VertexBasedP1DGLimiter, self).__init__(p1dg_scalar_space)
        else:
            super(VertexBasedP1DGLimiter, self).__init__(p1dg_space)
        self.mesh = self.P0.mesh()
        self.is_2d = self.mesh.geometric_dimension() == 2
        self.time_dependent_mesh = time_dependent_mesh
        # for vertical 2d in non-hydrostatic (nh) extension, WPan 2020-02-11
        self.mesh_is_extruded = (p1dg_space.mesh().ufl_cell()
                                 not in (ufl.Cell('triangle'),
                                         ufl.Cell('interval')))

        # NOTE below use non-loopy kernel which seems to run faster, TODO check, WPan 2020-03-27
        # Update min and max loop
        self._min_max_loop = """
            for (int i = 0; i < maxq.dofs; i++) {
                maxq[i] = fmax(maxq[i], q[0]);
                minq[i] = fmin(minq[i], q[0]);
            }
        """

        # Perform limiting loop
        self._limit_kernel = """
Esempio n. 2
0
    def test_facetarea(self):
        "Testing assembly of facet area for embedded meshes"

        # Boundary mesh not running in parallel
        if MPI.num_processes() > 1:
            return

        area = ufl.Cell("interval", geometric_dimension=2).facet_area
        a = area * ds
        b = assemble(a, mesh=self.bottom1)
        self.assertAlmostEqual(b, 2.0)

        area = ufl.Cell("interval", geometric_dimension=3).facet_area
        a = area * ds
        b = assemble(a, mesh=self.bottom3)
        self.assertAlmostEqual(b, 2.0)

        area = ufl.Cell("triangle", geometric_dimension=2).facet_area
        a = area * ds
        b0 = assemble(a, mesh=UnitSquareMesh(self.m, self.m))

        area = ufl.Cell("triangle", geometric_dimension=3).facet_area
        a = area * ds
        b1 = assemble(a, mesh=self.bottom2)
        self.assertAlmostEqual(b0, b1)
Esempio n. 3
0
def cell(dimDomainOrGrid):
    if isinstance(dimDomainOrGrid, ufl.Cell):
        return dimDomainOrGrid
    try:
        dimWorld = int(dimDomainOrGrid.dimWorld)
        dimDomain = int(dimDomainOrGrid.dimGrid)
    except:
        dimDomain = dimDomainOrGrid
        if isinstance(dimDomain, tuple):
            if len(dimDomain) != 2:
                raise Exception(
                    'dimDomain tuple must contain exactly two elements.')
            dimWorld = int(dimDomain[1])
            dimDomain = dimDomain[0]
        else:
            dimWorld = int(dimDomain)
    if dimDomain == 1:
        return ufl.Cell("interval", dimWorld)
    elif dimDomain == 2:
        return ufl.Cell("triangle", dimWorld)
    elif dimDomain == 3:
        return ufl.Cell("tetrahedron", dimWorld)
    elif dimDomain == 4:
        # add 4d cell types to ufl data structures
        _patchufl4d()
        return ufl.Cell("pentachoron", dimWorld)
    else:
        raise NotImplementedError('UFL cell not implemented for dimension ' +
                                  str(dimDomain) + '.')
Esempio n. 4
0
def extension_cell(o):
    '''
    UFL cell corresponding to extension of o[cell] to facets(triangles) 
    in 3d or lines in (2d)
    '''
    # Space
    if hasattr(o, 'ufl_cell'):
        return extension_cell(o.ufl_cell())
    # Foo like
    if hasattr(o, 'ufl_element'):
        return extension_cell(o.ufl_element().cell())
    # Elm
    if hasattr(o, 'cell'):
        return extension_cell(o.cell())

    gdim = o.geometric_dimension()
    assert gdim in (2, 3)
    assert o.topological_dimension() == 1  # Always extend from 1

    # Line in 3d extends to 'cylinder' surface around it
    if gdim == 3:
        return ufl.Cell('triangle', gdim)
    # Line in 2d extends to line in 3d
    else:
        return ufl.Cell('interval', gdim)
Esempio n. 5
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. 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)
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. 8
0
    def _process_args(cls,
                      mesh,
                      family,
                      degree=None,
                      dim=None,
                      vfamily=None,
                      vdegree=None,
                      **kwargs):
        # VectorFunctionSpace dimension defaults to the geometric dimension of the mesh.
        dim = dim or mesh.ufl_cell().geometric_dimension()

        if isinstance(mesh, mesh_t.ExtrudedMesh) and isinstance(
                family, ufl.OuterProductElement):
            element = ufl.OuterProductVectorElement(family, dim=dim)
        elif isinstance(mesh, mesh_t.ExtrudedMesh
                        ) and vfamily is not None and vdegree is not None:
            la = ufl.FiniteElement(family,
                                   domain=mesh._old_mesh.ufl_cell(),
                                   degree=degree)
            lb = ufl.FiniteElement(vfamily,
                                   domain=ufl.Cell("interval", 1),
                                   degree=vdegree)
            element = ufl.OuterProductVectorElement(la, lb, dim=dim)
        else:
            element = ufl.VectorElement(family,
                                        domain=mesh.ufl_cell(),
                                        degree=degree,
                                        dim=dim)
        return (mesh, mesh, element), dict(kwargs, dim=dim)
Esempio n. 9
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. 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 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. 12
0
    def _process_args(cls,
                      mesh,
                      family,
                      degree=None,
                      vfamily=None,
                      vdegree=None,
                      **kwargs):
        # Two choices:
        # 1) pass in mesh, family, degree to generate a simple function space
        # 2) set up the function space using FiniteElement, EnrichedElement,
        #       OuterProductElement and so on
        if isinstance(family, ufl.FiniteElementBase):
            # Second case...
            element = family
        else:
            # First case...
            if isinstance(mesh, mesh_t.ExtrudedMesh
                          ) and vfamily is not None and vdegree is not None:
                # if extruded mesh, make the OPE
                la = ufl.FiniteElement(family,
                                       domain=mesh._old_mesh.ufl_cell(),
                                       degree=degree)
                # if second element was passed in, use in
                lb = ufl.FiniteElement(vfamily,
                                       domain=ufl.Cell("interval", 1),
                                       degree=vdegree)
                # now make the OPE
                element = ufl.OuterProductElement(la, lb)
            else:
                # if not an extruded mesh, just make the element
                element = ufl.FiniteElement(family,
                                            domain=mesh.ufl_cell(),
                                            degree=degree)

        return (mesh, mesh, element), kwargs
Esempio n. 13
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. 14
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. 15
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. 16
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. 17
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)
Esempio n. 18
0
def test_empty_rank_mesh():
    """Construction of mesh where some ranks are empty"""
    comm = MPI.COMM_WORLD
    cell_type = CellType.triangle
    tdim = 2
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", ufl.Cell(cell_type.name), 1))

    def partitioner(comm, nparts, local_graph, num_ghost_nodes, ghosting):
        """Leave cells on the curent rank"""
        dest = np.full(len(cells), comm.rank, dtype=np.int32)
        return graph.create_adjacencylist(dest)

    if comm.rank == 0:
        cells = np.array([[0, 1, 2], [0, 2, 3]], dtype=np.int64)
        cells = graph.create_adjacencylist(cells)
        x = np.array([[0., 0.], [1., 0.], [1., 1.], [0., 1.]])
    else:
        cells = graph.create_adjacencylist(np.empty((0, 3), dtype=np.int64))
        x = np.empty((0, 2), dtype=np.float64)

    mesh = _mesh.create_mesh(comm, cells, x, domain, GhostMode.none,
                             partitioner)

    topology = mesh.topology

    # Check number of vertices
    vmap = topology.index_map(0)
    assert vmap.size_local == x.shape[0]
    assert vmap.num_ghosts == 0

    # Check number of cells
    cmap = topology.index_map(tdim)
    assert cmap.size_local == cells.num_nodes
    assert cmap.num_ghosts == 0

    # Check number of edges
    topology.create_entities(1)
    emap = topology.index_map(1)

    e_to_v = topology.connectivity(1, 0)

    assert emap.num_ghosts == 0
    if comm.rank == 0:
        assert emap.size_local == 5
        assert e_to_v.num_nodes == 5
        assert len(e_to_v.array) == 10
    else:
        assert emap.size_local == 0
        assert len(e_to_v.array) == 0
        assert e_to_v.num_nodes == 0

    # Test creating and getting permutations doesn't throw an error
    mesh.topology.create_entity_permutations()
    mesh.topology.get_cell_permutation_info()
    mesh.topology.get_facet_permutations()
Esempio n. 19
0
def test_second_order_fides(tempdir):
    """Check that fides throws error on second order mesh"""
    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 pytest.raises(RuntimeError):
        FidesWriter(mesh.comm, filename, mesh)
Esempio n. 20
0
def test_custom_partitioner(tempdir, Nx, cell_type):
    mpi_comm = MPI.COMM_WORLD

    Lx = mpi_comm.size
    points = [np.array([0, 0, 0]), np.array([Lx, Lx, Lx])]
    mesh = dolfinx.BoxMesh(mpi_comm, points, [Nx, Nx, Nx], cell_type,
                           GhostMode.shared_facet)

    filename = os.path.join(tempdir, "u1_.xdmf")
    with XDMFFile(mpi_comm, filename, "w") as file:
        file.write_mesh(mesh)

    # Read all geometry data on all processes
    with XDMFFile(MPI.COMM_SELF, filename, "r") as file:
        x_global = file.read_geometry_data()

    # Read topology data
    with XDMFFile(MPI.COMM_WORLD, filename, "r") as file:
        cell_type = file.read_cell_type()
        x = file.read_geometry_data()
        topo = file.read_topology_data()

    num_local_coor = x.shape[0]
    all_sizes = mpi_comm.allgather(num_local_coor)
    all_sizes.insert(0, 0)
    all_ranges = np.cumsum(all_sizes)

    # Testing the premise: coordinates are read contiguously in chunks
    rank = mpi_comm.rank
    assert (np.all(x_global[all_ranges[rank]:all_ranges[rank + 1]] == x))

    cell = ufl.Cell(dolfinx.cpp.mesh.to_string(cell_type[0]))
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, cell_type[1]))

    # Partition mesh in layers, capture geometrical data and topological
    # data from outer scope
    def partitioner(*args):
        midpoints = np.mean(x_global[topo], axis=1)
        dest = np.floor(midpoints[:, 0] % mpi_comm.size)
        return dolfinx.cpp.graph.AdjacencyList_int32(dest)

    ghost_mode = GhostMode.none
    new_mesh = dolfinx.mesh.create_mesh(mpi_comm, topo, x, domain, ghost_mode,
                                        partitioner)
    new_mesh.topology.create_connectivity_all()

    tdim = new_mesh.topology.dim
    assert mesh.topology.index_map(
        tdim).size_global == new_mesh.topology.index_map(tdim).size_global
    num_cells = new_mesh.topology.index_map(tdim).size_local
    cell_midpoints = dolfinx.cpp.mesh.midpoints(new_mesh, tdim,
                                                range(num_cells))
    assert num_cells > 0
    assert np.all(cell_midpoints[:, 0] >= mpi_comm.rank)
    assert np.all(cell_midpoints[:, 0] <= mpi_comm.rank + 1)
Esempio n. 21
0
def test_assemble_empty_rank_mesh():
    """Assembly on mesh where some ranks are empty"""
    comm = MPI.COMM_WORLD
    cell_type = CellType.triangle
    domain = ufl.Mesh(
        ufl.VectorElement("Lagrange", ufl.Cell(cell_type.name), 1))

    def partitioner(comm, nparts, local_graph, num_ghost_nodes, ghosting):
        """Leave cells on the curent rank"""
        dest = np.full(len(cells), comm.rank, dtype=np.int32)
        return graph.create_adjacencylist(dest)

    if comm.rank == 0:
        # Put cells on rank 0
        cells = np.array([[0, 1, 2], [0, 2, 3]], dtype=np.int64)
        cells = graph.create_adjacencylist(cells)
        x = np.array([[0., 0.], [1., 0.], [1., 1.], [0., 1.]])
    else:
        # No cells onm other ranks
        cells = graph.create_adjacencylist(np.empty((0, 3), dtype=np.int64))
        x = np.empty((0, 2), dtype=np.float64)

    mesh = create_mesh(comm, cells, x, domain, GhostMode.none, partitioner)

    V = FunctionSpace(mesh, ("Lagrange", 2))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    f, k, zero = Function(V), Function(V), Function(V)
    f.x.array[:] = 10.0
    k.x.array[:] = 1.0
    zero.x.array[:] = 0.0
    a = form(inner(k * u, v) * dx + inner(zero * u, v) * ds)
    L = form(inner(f, v) * dx + inner(zero, v) * ds)
    M = form(2 * k * dx + k * ds)

    sum = comm.allreduce(assemble_scalar(M), op=MPI.SUM)
    assert sum == pytest.approx(6.0)

    # Assemble
    A = assemble_matrix(a)
    A.assemble()
    b = assemble_vector(L)
    b.ghostUpdate(addv=PETSc.InsertMode.ADD, mode=PETSc.ScatterMode.REVERSE)

    # Solve
    ksp = PETSc.KSP()
    ksp.create(mesh.comm)
    ksp.setOperators(A)
    ksp.setTolerances(rtol=1.0e-9, max_it=50)
    ksp.setFromOptions()
    x = b.copy()
    ksp.solve(b, x)

    assert np.allclose(x.array, 10.0)
Esempio n. 22
0
    def test_cell_volume(self):
        "Testing assembly of volume for embedded meshes"

        # Boundary mesh not running in parallel
        if MPI.num_processes() > 1:
            return

        volume = ufl.Cell("interval", geometric_dimension=2).volume
        a = volume * dx
        b = assemble(a, mesh=self.bottom1)
        self.assertAlmostEqual(b, 1.0 / self.m)

        volume = ufl.Cell("interval", geometric_dimension=3).volume
        a = volume * dx
        b = assemble(a, mesh=self.bottom3)
        self.assertAlmostEqual(b, 1.0 / self.m)

        volume = ufl.Cell("triangle", geometric_dimension=3).volume
        a = volume * dx
        b = assemble(a, mesh=self.bottom2)
        self.assertAlmostEqual(b, 1.0 / (2 * self.m * self.m))
Esempio n. 23
0
def ufl_mesh_from_gmsh(gmsh_cell: int, gdim: int) -> ufl.Mesh:
    """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)
    scalar_element = ufl.FiniteElement("Lagrange",
                                       cell,
                                       degree,
                                       variant="equispaced")
    return ufl.Mesh(ufl.VectorElement(scalar_element))
Esempio n. 24
0
def test_eval_manifold():
    # Simple two-triangle surface in 3d
    vertices = [(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 = [(0, 1, 2), (0, 1, 3)]
    cell = ufl.Cell("triangle", geometric_dimension=3)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 1))
    mesh = create_mesh(MPI.COMM_WORLD, cells, vertices, domain)
    Q = FunctionSpace(mesh, ("Lagrange", 1))
    u = Function(Q)
    u.interpolate(lambda x: x[0] + x[1])
    assert np.isclose(u.eval([0.75, 0.25, 0.5], 0)[0], 1.0)
Esempio n. 25
0
def test_distance_triangle():
    gdim, shape, degree = 2, "triangle", 1
    cell = ufl.Cell(shape, geometric_dimension=gdim)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
    x = [[0., 0., 0.], [0., 1., 0.], [1., 1., 0.]]
    cells = [[0, 1, 2]]
    mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [-1.0, -1.0, 0.0]) == pytest.approx(2.0)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [-1.0, 0.5, 0.0]) == pytest.approx(1.0)
    assert squared_distance(mesh, mesh.topology.dim, [0],
                            [0.5, 0.5, 0.0]) == pytest.approx(0.0)
Esempio n. 26
0
def test_make_2():
    coords = np.array([[0, 0, 2], [1, 0, 2], [1, 1, 2], [0, 1., 2]])
    cells = np.array([[0, 1], [1, 2], [2, 3], [3, 0], [0, 2]])

    mesh = make_line_mesh(coords, cells=cells)
    assert np.linalg.norm(mesh.coordinates() - coords) < 1E-13

    cells = np.array([[0, 1], [1, 2], [2, 3], [0, 3], [0, 2]])
    cells0 = np.array(map(sorted, mesh.cells()))

    assert np.linalg.norm(cells0 - cells) < 1E-13, mesh.cells()

    assert mesh.ufl_cell() == ufl.Cell('interval', 3)
Esempio n. 27
0
def test_third_order_tri():
    #  *---*---*---*   3--11--10--2
    #  | \         |   | \        |
    #  *   *   *   *   8   7  15  13
    #  |     \     |   |    \     |
    #  *  *    *   *   9  14  6   12
    #  |         \ |   |        \ |
    #  *---*---*---*   0--4---5---1
    for H in (1.0, 2.0):
        for Z in (0.0, 0.5):
            L = 1
            points = np.array([
                [0, 0, 0],
                [L, 0, 0],
                [L, H, Z],
                [0, H, Z],  # 0, 1, 2, 3
                [L / 3, 0, 0],
                [2 * L / 3, 0, 0],  # 4, 5
                [2 * L / 3, H / 3, 0],
                [L / 3, 2 * H / 3, 0],  # 6, 7
                [0, 2 * H / 3, 0],
                [0, H / 3, 0],  # 8, 9
                [2 * L / 3, H, Z],
                [L / 3, H, Z],  # 10, 11
                [L, H / 3, 0],
                [L, 2 * H / 3, 0],  # 12, 13
                [L / 3, H / 3, 0],  # 14
                [2 * L / 3, 2 * H / 3, 0]
            ])  # 15
            cells = np.array([[0, 1, 3, 4, 5, 6, 7, 8, 9, 14],
                              [1, 2, 3, 12, 13, 10, 11, 7, 6, 15]])
            cells = cells[:, perm_vtk(CellType.triangle, cells.shape[1])]

            cell = ufl.Cell("triangle", geometric_dimension=points.shape[1])
            domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, 3))
            mesh = create_mesh(MPI.COMM_WORLD, cells, points, domain)

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

            # Interpolate function
            V = FunctionSpace(mesh, ("Lagrange", 3))
            u = Function(V)
            u.interpolate(e2)

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

            nodes = [0, 9, 8, 3]
            ref = sympy_scipy(points, nodes, L, H)
            assert ref == pytest.approx(intu, rel=1e-6)
Esempio n. 28
0
def test_distance_tetrahedron():
    gdim = 3
    shape = "tetrahedron"
    degree = 1
    cell = ufl.Cell(shape, geometric_dimension=gdim)
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
    x = numpy.array([[0., 0., 0.], [0., 1., 0.], [0., 1., 1.], [1, 1., 1]])
    cells = numpy.array([[0, 1, 2, 3]], dtype=numpy.int32)
    mesh = create_mesh(MPI.COMM_WORLD, cells, x, domain)
    assert cpp.geometry.squared_distance(mesh, mesh.topology.dim, 0,
                                         numpy.array([-1.0, -1.0, -1.0])) == pytest.approx(3.0)
    assert cpp.geometry.squared_distance(mesh, mesh.topology.dim, 0,
                                         numpy.array([-1.0, 0.5, 0.5])) == pytest.approx(1.0)
    assert cpp.geometry.squared_distance(mesh, mesh.topology.dim, 0, numpy.array([0.5, 0.5, 0.5])) == pytest.approx(0.0)
Esempio n. 29
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)
Esempio n. 30
0
def Mesh(comm,
         cell_type,
         x,
         cells,
         ghosts,
         degree=1,
         ghost_mode=cpp.mesh.GhostMode.none):
    """Create a mesh from topology and geometry data

    Note: this function is deprecated in favour of mesh.create
    """
    cell = ufl.Cell(cpp.mesh.to_string(cell_type),
                    geometric_dimension=x.shape[1])
    domain = ufl.Mesh(ufl.VectorElement("Lagrange", cell, degree))
    return create_mesh(comm, cells, x, domain, ghost_mode)