def test_prism_hdiv(prism_mesh, space, degree, horiz_expected, vert_expected):
    W0_h = FiniteElement(space, "triangle", degree)
    W1_h = FiniteElement("DG", "triangle", degree - 1)

    W0_v = FiniteElement("DG", "interval", degree - 1)
    W0 = HDiv(OuterProductElement(W0_h, W0_v))

    W1_v = FiniteElement("CG", "interval", degree)
    W1 = HDiv(OuterProductElement(W1_h, W1_v))

    V = FunctionSpace(prism_mesh, W0+W1)
    assert horiz_expected == horiz_facet_support_dofs(V.fiat_element)
    assert vert_expected == vert_facet_support_dofs(V.fiat_element)
Example #2
0
def test_prism_hcurl(prism_mesh, space, degree, horiz_expected, vert_expected):
    W0_h = FiniteElement("CG", "triangle", degree)
    W1_h = FiniteElement(space, "triangle", degree)

    W0_v = FiniteElement("DG", "interval", degree - 1)
    W0 = HCurl(OuterProductElement(W0_h, W0_v))

    W1_v = FiniteElement("CG", "interval", degree)
    W1 = HCurl(OuterProductElement(W1_h, W1_v))

    V = FunctionSpace(prism_mesh, W0 + W1)
    assert horiz_expected == horiz_facet_support_dofs(V.fiat_element)
    assert vert_expected == vert_facet_support_dofs(V.fiat_element)
Example #3
0
    def exterior_facet_boundary_node_map(self, method):
        '''The :class:`pyop2.Map` from exterior facets to the nodes on
        those facets. Note that this differs from
        :meth:`exterior_facet_node_map` in that only surface nodes
        are referenced, not all nodes in cells touching the surface.

        :arg method: The method for determining boundary nodes. See
            :class:`~.bcs.DirichletBC`.
        '''

        el = self.fiat_element

        dim = self._mesh.facet_dimension()

        if method == "topological":
            boundary_dofs = el.entity_closure_dofs()[dim]
        elif method == "geometric":
            if self.extruded:
                # This function is only called on extruded meshes when
                # asking for the nodes that live on the "vertical"
                # exterior facets.  Hence we don't need to worry about
                # horiz_facet_support_dofs as well.
                boundary_dofs = vert_facet_support_dofs(el)
            else:
                boundary_dofs = facet_support_dofs(el)

        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)

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

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

        local_facet_nodes = np.array(
            [dofs for e, dofs in boundary_dofs.iteritems()])

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

        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", ("l_nodes[facet[0]][n]",))))
                          ])

        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=np.uintc)
        op2.par_loop(kernel, facet_set,
                     fs_dat(op2.READ),
                     facet_dat(op2.WRITE),
                     local_facet_dat(op2.READ))

        if isinstance(self._mesh, mesh_t.ExtrudedMesh):
            offset = self.offset[boundary_dofs[0]]
        else:
            offset = None
        return op2.Map(facet_set, self.node_set,
                       nodes_per_facet,
                       facet_dat.data_ro_with_halos,
                       name="exterior_facet_boundary_node",
                       offset=offset)
Example #4
0
    def exterior_facet_boundary_node_map(self, method):
        '''The :class:`pyop2.Map` from exterior facets to the nodes on
        those facets. Note that this differs from
        :meth:`exterior_facet_node_map` in that only surface nodes
        are referenced, not all nodes in cells touching the surface.

        :arg method: The method for determining boundary nodes. See
            :class:`~.bcs.DirichletBC`.
        '''

        el = self.fiat_element

        dim = self._mesh.facet_dimension()

        if method == "topological":
            boundary_dofs = el.entity_closure_dofs()[dim]
        elif method == "geometric":
            if self.extruded:
                # This function is only called on extruded meshes when
                # asking for the nodes that live on the "vertical"
                # exterior facets.  Hence we don't need to worry about
                # horiz_facet_support_dofs as well.
                boundary_dofs = vert_facet_support_dofs(el)
            else:
                boundary_dofs = facet_support_dofs(el)

        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)

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

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

        local_facet_nodes = np.array(
            [dofs for e, dofs in boundary_dofs.iteritems()])

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

        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", ("l_nodes[facet[0]][n]", ))))
        ])

        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=np.uintc)
        op2.par_loop(kernel, facet_set, fs_dat(op2.READ), facet_dat(op2.WRITE),
                     local_facet_dat(op2.READ))

        if isinstance(self._mesh.topology, mesh_t.ExtrudedMeshTopology):
            offset = self.offset[boundary_dofs[0]]
        else:
            offset = None
        return op2.Map(facet_set,
                       self.node_set,
                       nodes_per_facet,
                       facet_dat.data_ro_with_halos,
                       name="exterior_facet_boundary_node",
                       offset=offset)
def test_prism(prism_mesh, args, kwargs, horiz_expected, vert_expected):
    V = FunctionSpace(prism_mesh, *args, **kwargs)
    assert horiz_expected == horiz_facet_support_dofs(V.fiat_element)
    assert vert_expected == vert_facet_support_dofs(V.fiat_element)
Example #6
0
def test_quad(quad_mesh, args, kwargs, horiz_expected, vert_expected):
    V = FunctionSpace(quad_mesh, *args, **kwargs)
    assert horiz_expected == horiz_facet_support_dofs(V.fiat_element)
    assert vert_expected == vert_facet_support_dofs(V.fiat_element)