Ejemplo n.º 1
0
def test_prism_hcurl(space, degree, horiz_expected, vert_expected):
    W0_h = FIAT.Lagrange(UFCTriangle(), degree)
    W1_h = FIAT.supported_elements[space](UFCTriangle(), degree)

    W0_v = FIAT.DiscontinuousLagrange(UFCInterval(), degree - 1)
    W0 = FIAT.Hcurl(FIAT.TensorProductElement(W0_h, W0_v))

    W1_v = FIAT.Lagrange(UFCInterval(), degree)
    W1 = FIAT.Hcurl(FIAT.TensorProductElement(W1_h, W1_v))

    elem = FIAT.EnrichedElement(W0, W1)
    assert horiz_expected == entity_support_dofs(elem, (2, 0))
    assert vert_expected == entity_support_dofs(elem, (1, 1))
Ejemplo n.º 2
0
def test_quad_rtcf():
    W0_h = FIAT.Lagrange(UFCInterval(), 1)
    W1_h = FIAT.DiscontinuousLagrange(UFCInterval(), 0)

    W0_v = FIAT.DiscontinuousLagrange(UFCInterval(), 0)
    W0 = FIAT.Hdiv(FIAT.TensorProductElement(W0_h, W0_v))

    W1_v = FIAT.Lagrange(UFCInterval(), 1)
    W1 = FIAT.Hdiv(FIAT.TensorProductElement(W1_h, W1_v))

    elem = FIAT.EnrichedElement(W0, W1)
    assert {0: [0, 1, 2], 1: [0, 1, 3]} == entity_support_dofs(elem, (1, 0))
    assert {0: [0, 2, 3], 1: [1, 2, 3]} == entity_support_dofs(elem, (0, 1))
Ejemplo n.º 3
0
def test_quad_rtcf():
    W0_h = FIAT.Lagrange(UFCInterval(), 1)
    W1_h = FIAT.DiscontinuousLagrange(UFCInterval(), 0)

    W0_v = FIAT.DiscontinuousLagrange(UFCInterval(), 0)
    W0 = FIAT.Hdiv(FIAT.TensorProductElement(W0_h, W0_v))

    W1_v = FIAT.Lagrange(UFCInterval(), 1)
    W1 = FIAT.Hdiv(FIAT.TensorProductElement(W1_h, W1_v))

    elem = FIAT.EnrichedElement(W0, W1)
    assert {0: [0, 1, 2], 1: [0, 1, 3]} == entity_support_dofs(elem, (1, 0))
    assert {0: [0, 2, 3], 1: [1, 2, 3]} == entity_support_dofs(elem, (0, 1))
Ejemplo n.º 4
0
def test_prism_hcurl(space, degree, horiz_expected, vert_expected):
    W0_h = FIAT.Lagrange(UFCTriangle(), degree)
    W1_h = FIAT.supported_elements[space](UFCTriangle(), degree)

    W0_v = FIAT.DiscontinuousLagrange(UFCInterval(), degree - 1)
    W0 = FIAT.Hcurl(FIAT.TensorProductElement(W0_h, W0_v))

    W1_v = FIAT.Lagrange(UFCInterval(), degree)
    W1 = FIAT.Hcurl(FIAT.TensorProductElement(W1_h, W1_v))

    elem = FIAT.EnrichedElement(W0, W1)
    assert horiz_expected == entity_support_dofs(elem, (2, 0))
    assert vert_expected == entity_support_dofs(elem, (1, 1))
Ejemplo n.º 5
0
def get_bt_masks(mesh, key, fiat_element):
    """Get masks for top and bottom dofs.

    :arg mesh: The mesh to use.
    :arg key: Canonicalised entity_dofs (see :func:`entity_dofs_key`).
    :arg fiat_element: The FIAT element.
    :returns: A dict mapping ``"topological"`` and ``"geometric"``
        keys to bottom and top dofs (extruded) or ``None``.
    """
    if not bool(mesh.layers):
        return None
    bt_masks = {}
    # Compute the top and bottom masks to identify boundary dofs
    #
    # Sorting the keys of the closure entity dofs, the whole cell
    # comes last [-1], before that the horizontal facet [-2], before
    # that vertical facets [-3]. We need the horizontal facets here.
    closure_dofs = fiat_element.entity_closure_dofs()
    horiz_facet_dim = sorted(closure_dofs.keys())[-2]
    b_mask = closure_dofs[horiz_facet_dim][0]
    t_mask = closure_dofs[horiz_facet_dim][1]
    bt_masks["topological"] = (b_mask, t_mask)  # conversion to tuple
    # Geometric facet dofs
    facet_dofs = entity_support_dofs(fiat_element, horiz_facet_dim)
    bt_masks["geometric"] = (facet_dofs[0], facet_dofs[1])
    return bt_masks
Ejemplo n.º 6
0
def test_discontinuous_element():
    elem = FIAT.DiscontinuousElement(FIAT.Lagrange(UFCTriangle(), 3))
    assert entity_support_dofs(elem, 1) == {
        0: [1, 2, 3, 4],
        1: [0, 2, 5, 6],
        2: [0, 1, 7, 8]
    }
Ejemplo n.º 7
0
def get_bt_masks(mesh, key, fiat_element):
    """Get masks for top and bottom dofs.

    :arg mesh: The mesh to use.
    :arg key: Canonicalised entity_dofs (see :func:`entity_dofs_key`).
    :arg fiat_element: The FIAT element.
    :returns: A dict mapping ``"topological"`` and ``"geometric"``
        keys to bottom and top dofs (extruded) or ``None``.
    """
    if not bool(mesh.layers):
        return None
    bt_masks = {}
    # Compute the top and bottom masks to identify boundary dofs
    #
    # Sorting the keys of the closure entity dofs, the whole cell
    # comes last [-1], before that the horizontal facet [-2], before
    # that vertical facets [-3]. We need the horizontal facets here.
    closure_dofs = fiat_element.entity_closure_dofs()
    horiz_facet_dim = sorted(closure_dofs.keys())[-2]
    b_mask = closure_dofs[horiz_facet_dim][0]
    t_mask = closure_dofs[horiz_facet_dim][1]
    bt_masks["topological"] = (b_mask, t_mask)  # conversion to tuple
    # Geometric facet dofs
    facet_dofs = entity_support_dofs(fiat_element, horiz_facet_dim)
    bt_masks["geometric"] = (facet_dofs[0], facet_dofs[1])
    return bt_masks
def test_hex(hex_mesh, args, kwargs, horiz_expected, vert_expected):
    V = FunctionSpace(hex_mesh, *args, **kwargs)
    assert horiz_expected == entity_support_dofs(V.fiat_element, (2, 0))
    assert vert_expected == entity_support_dofs(V.fiat_element, (1, 1))
Ejemplo n.º 9
0
    def exterior_facet_boundary_node_map(self, V, method):
        """Return the :class:`pyop2.Map` from exterior facets to nodes
        on the boundary.

        :arg V: The function space.
        :arg method:  The method for determining boundary nodes.  See
           :class:`~.DirichletBC` for details.
        """
        try:
            return self.map_caches["boundary_node"][method]
        except KeyError:
            pass
        el = V.fiat_element

        dim = self.mesh.facet_dimension()

        if method == "topological":
            boundary_dofs = el.entity_closure_dofs()[dim]
        elif method == "geometric":
            # This function is only called on extruded meshes when
            # asking for the nodes that live on the "vertical"
            # exterior facets.
            boundary_dofs = entity_support_dofs(el, dim)

        nodes_per_facet = \
            len(boundary_dofs[0])

        # HACK ALERT
        # The facet set does not have a halo associated with it, since
        # we only construct halos for DoF sets.  Fortunately, this
        # loop is direct and we already have all the correct
        # information available locally.  So We fake a set of the
        # correct size and carry out a direct loop
        facet_set = op2.Set(self.mesh.exterior_facets.set.total_size,
                            comm=self.mesh.comm)

        fs_dat = op2.Dat(facet_set**el.space_dimension(),
                         data=V.exterior_facet_node_map().values_with_halo.view())

        facet_dat = op2.Dat(facet_set**nodes_per_facet,
                            dtype=numpy.int32)

        # Ensure these come out in sorted order.
        local_facet_nodes = numpy.array(
            [boundary_dofs[e] for e in sorted(boundary_dofs.keys())])

        # Helper function to turn the inner index of an array into c
        # array literals.
        c_array = lambda xs: "{"+", ".join(map(str, xs))+"}"

        # AST for: l_nodes[facet[0]][n]
        rank_ast = ast.Symbol("l_nodes", rank=(ast.Symbol("facet", rank=(0,)), "n"))

        body = ast.Block([ast.Decl("int",
                                   ast.Symbol("l_nodes", (len(el.get_reference_element().topology[dim]),
                                                          nodes_per_facet)),
                                   init=ast.ArrayInit(c_array(map(c_array, local_facet_nodes))),
                                   qualifiers=["const"]),
                          ast.For(ast.Decl("int", "n", 0),
                                  ast.Less("n", nodes_per_facet),
                                  ast.Incr("n", 1),
                                  ast.Assign(ast.Symbol("facet_nodes", ("n",)),
                                             ast.Symbol("cell_nodes", (rank_ast, ))))
                          ])

        kernel = op2.Kernel(ast.FunDecl("void", "create_bc_node_map",
                                        [ast.Decl("int*", "cell_nodes"),
                                         ast.Decl("int*", "facet_nodes"),
                                         ast.Decl("unsigned int*", "facet")],
                                        body),
                            "create_bc_node_map")

        local_facet_dat = op2.Dat(facet_set ** self.mesh.exterior_facets._rank,
                                  self.mesh.exterior_facets.local_facet_dat.data_ro_with_halos,
                                  dtype=numpy.uintc)
        op2.par_loop(kernel, facet_set,
                     fs_dat(op2.READ),
                     facet_dat(op2.WRITE),
                     local_facet_dat(op2.READ))

        if self.extruded:
            offset = self.offset[boundary_dofs[0]]
        else:
            offset = None
        val = op2.Map(facet_set, self.node_set,
                      nodes_per_facet,
                      facet_dat.data_ro_with_halos,
                      name="exterior_facet_boundary_node",
                      offset=offset)
        self.map_caches["boundary_node"][method] = val
        return val
Ejemplo n.º 10
0
def test_quad(base, extr, horiz_expected, vert_expected):
    elem_A = FIAT.supported_elements[base[0]](UFCInterval(), base[1])
    elem_B = FIAT.supported_elements[extr[0]](UFCInterval(), extr[1])
    elem = FIAT.TensorProductElement(elem_A, elem_B)
    assert horiz_expected == entity_support_dofs(elem, (1, 0))
    assert vert_expected == entity_support_dofs(elem, (0, 1))
Ejemplo n.º 11
0
    def exterior_facet_boundary_node_map(self, V, method):
        """Return the :class:`pyop2.Map` from exterior facets to nodes
        on the boundary.

        :arg V: The function space.
        :arg method:  The method for determining boundary nodes.  See
           :class:`~.DirichletBC` for details.
        """
        try:
            return self.map_caches["boundary_node"][method]
        except KeyError:
            pass
        el = V.fiat_element

        dim = self.mesh.facet_dimension()

        if method == "topological":
            boundary_dofs = el.entity_closure_dofs()[dim]
        elif method == "geometric":
            # This function is only called on extruded meshes when
            # asking for the nodes that live on the "vertical"
            # exterior facets.
            boundary_dofs = entity_support_dofs(el, dim)

        nodes_per_facet = \
            len(boundary_dofs[0])

        # HACK ALERT
        # The facet set does not have a halo associated with it, since
        # we only construct halos for DoF sets.  Fortunately, this
        # loop is direct and we already have all the correct
        # information available locally.  So We fake a set of the
        # correct size and carry out a direct loop
        facet_set = op2.Set(self.mesh.exterior_facets.set.total_size,
                            comm=self.mesh.comm)

        fs_dat = op2.Dat(
            facet_set**el.space_dimension(),
            data=V.exterior_facet_node_map().values_with_halo.view())

        facet_dat = op2.Dat(facet_set**nodes_per_facet, dtype=numpy.int32)

        # Ensure these come out in sorted order.
        local_facet_nodes = numpy.array(
            [boundary_dofs[e] for e in sorted(boundary_dofs.keys())])

        # Helper function to turn the inner index of an array into c
        # array literals.
        c_array = lambda xs: "{" + ", ".join(map(str, xs)) + "}"

        # AST for: l_nodes[facet[0]][n]
        rank_ast = ast.Symbol("l_nodes",
                              rank=(ast.Symbol("facet", rank=(0, )), "n"))

        body = ast.Block([
            ast.Decl("int",
                     ast.Symbol("l_nodes",
                                (len(el.get_reference_element().topology[dim]),
                                 nodes_per_facet)),
                     init=ast.ArrayInit(
                         c_array(map(c_array, local_facet_nodes))),
                     qualifiers=["const"]),
            ast.For(
                ast.Decl("int", "n", 0), ast.Less("n", nodes_per_facet),
                ast.Incr("n", 1),
                ast.Assign(ast.Symbol("facet_nodes", ("n", )),
                           ast.Symbol("cell_nodes", (rank_ast, ))))
        ])

        kernel = op2.Kernel(
            ast.FunDecl("void", "create_bc_node_map", [
                ast.Decl("int*", "cell_nodes"),
                ast.Decl("int*", "facet_nodes"),
                ast.Decl("unsigned int*", "facet")
            ], body), "create_bc_node_map")

        local_facet_dat = op2.Dat(
            facet_set**self.mesh.exterior_facets._rank,
            self.mesh.exterior_facets.local_facet_dat.data_ro_with_halos,
            dtype=numpy.uintc)
        op2.par_loop(kernel, facet_set, fs_dat(op2.READ), facet_dat(op2.WRITE),
                     local_facet_dat(op2.READ))

        if self.extruded:
            offset = self.offset[boundary_dofs[0]]
        else:
            offset = None
        val = op2.Map(facet_set,
                      self.node_set,
                      nodes_per_facet,
                      facet_dat.data_ro_with_halos,
                      name="exterior_facet_boundary_node",
                      offset=offset)
        self.map_caches["boundary_node"][method] = val
        return val
Ejemplo n.º 12
0
def test_prism(base, extr, horiz_expected, vert_expected):
    elem_A = FIAT.supported_elements[base[0]](UFCTriangle(), base[1])
    elem_B = FIAT.supported_elements[extr[0]](UFCInterval(), extr[1])
    elem = FIAT.TensorProductElement(elem_A, elem_B)
    assert horiz_expected == entity_support_dofs(elem, (2, 0))
    assert vert_expected == entity_support_dofs(elem, (1, 1))
Ejemplo n.º 13
0
def test_discontinuous_element():
    elem = FIAT.DiscontinuousElement(FIAT.Lagrange(UFCTriangle(), 3))
    assert entity_support_dofs(elem, 1) == {0: [1, 2, 3, 4],
                                            1: [0, 2, 5, 6],
                                            2: [0, 1, 7, 8]}
Ejemplo n.º 14
0
def test_hex(hex_mesh, args, kwargs, horiz_expected, vert_expected):
    V = FunctionSpace(hex_mesh, *args, **kwargs)
    assert horiz_expected == entity_support_dofs(V.fiat_element, (2, 0))
    assert vert_expected == entity_support_dofs(V.fiat_element, (1, 1))