示例#1
0
    def local_facet_dat(self):
        """Dat indicating which local facet of each adjacent
        cell corresponds to the current facet."""

        return op2.Dat(
            op2.DataSet(self.set, self._rank), self.local_facet_number,
            np.uintc, "%s_%s_local_facet_number" % (self.mesh.name, self.kind))
示例#2
0
    def __init__(self, mesh, element, name=None, real_tensorproduct=False):
        super(FunctionSpace, self).__init__()
        if type(element) is ufl.MixedElement:
            raise ValueError("Can't create FunctionSpace for MixedElement")
        finat_element = create_element(element)
        if isinstance(finat_element, finat.TensorFiniteElement):
            # Retrieve scalar element
            finat_element = finat_element.base_element
        # Used for reconstruction of mixed/component spaces
        self.real_tensorproduct = real_tensorproduct
        sdata = get_shared_data(mesh,
                                finat_element,
                                real_tensorproduct=real_tensorproduct)
        # The function space shape is the number of dofs per node,
        # hence it is not always the value_shape.  Vector and Tensor
        # element modifiers *must* live on the outside!
        if type(element) is ufl.TensorElement:
            # UFL enforces value_shape of the subelement to be empty
            # on a TensorElement.
            self.shape = element.value_shape()
        elif type(element) is ufl.VectorElement:
            # First dimension of the value_shape is the VectorElement
            # shape.
            self.shape = element.value_shape()[:1]
        else:
            self.shape = ()
        self._ufl_function_space = ufl.FunctionSpace(mesh.ufl_mesh(), element)
        self._shared_data = sdata
        self._mesh = mesh

        self.rank = len(self.shape)
        r"""The rank of this :class:`FunctionSpace`.  Spaces where the
        element is scalar-valued (or intrinsically vector-valued) have
        rank zero.  Spaces built on :class:`~ufl.classes.VectorElement` or
        :class:`~ufl.classes.TensorElement` instances have rank equivalent to
        the number of components of their
        :meth:`~ufl.classes.FiniteElementBase.value_shape`."""

        self.value_size = int(numpy.prod(self.shape, dtype=int))
        r"""The total number of degrees of freedom at each function
        space node."""
        self.name = name
        r"""The (optional) descriptive name for this space."""
        self.node_set = sdata.node_set
        r"""A :class:`pyop2.Set` representing the function space nodes."""
        self.dof_dset = op2.DataSet(self.node_set,
                                    self.shape or 1,
                                    name="%s_nodes_dset" % self.name)
        r"""A :class:`pyop2.DataSet` representing the function space
        degrees of freedom."""

        self.comm = self.node_set.comm
        self.finat_element = finat_element
        self.extruded = sdata.extruded
        self.offset = sdata.offset
        self.cell_boundary_masks = sdata.cell_boundary_masks
        self.interior_facet_boundary_masks = sdata.interior_facet_boundary_masks
示例#3
0
    def __init__(self, mesh, element, name=None):
        super(FunctionSpace, self).__init__()
        if type(element) is ufl.MixedElement:
            raise ValueError("Can't create FunctionSpace for MixedElement")
        sdata = get_shared_data(mesh, element)
        # The function space shape is the number of dofs per node,
        # hence it is not always the value_shape.  Vector and Tensor
        # element modifiers *must* live on the outside!
        if type(element) in {ufl.TensorElement, ufl.VectorElement}:
            # The number of "free" dofs is given by reference_value_shape,
            # not value_shape due to symmetry specifications
            rvs = element.reference_value_shape()
            # This requires that the sub element is not itself a
            # tensor element (which is checked by the top level
            # constructor of function spaces)
            sub = element.sub_elements()[0].value_shape()
            self.shape = rvs[:len(rvs) - len(sub)]
        else:
            self.shape = ()
        self._ufl_function_space = ufl.FunctionSpace(mesh.ufl_mesh(), element)
        self._shared_data = sdata
        self._mesh = mesh

        self.rank = len(self.shape)
        r"""The rank of this :class:`FunctionSpace`.  Spaces where the
        element is scalar-valued (or intrinsically vector-valued) have
        rank zero.  Spaces built on :class:`~ufl.classes.VectorElement` or
        :class:`~ufl.classes.TensorElement` instances have rank equivalent to
        the number of components of their
        :meth:`~ufl.classes.FiniteElementBase.value_shape`."""

        self.value_size = int(numpy.prod(self.shape, dtype=int))
        r"""The total number of degrees of freedom at each function
        space node."""
        self.name = name
        r"""The (optional) descriptive name for this space."""
        self.node_set = sdata.node_set
        r"""A :class:`pyop2.Set` representing the function space nodes."""
        self.dof_dset = op2.DataSet(self.node_set,
                                    self.shape or 1,
                                    name="%s_nodes_dset" % self.name)
        r"""A :class:`pyop2.DataSet` representing the function space
        degrees of freedom."""

        self.comm = self.node_set.comm
        # Need to create finat element again as sdata does not
        # want to carry finat_element.
        self.finat_element = create_element(element)
        # Used for reconstruction of mixed/component spaces.
        # sdata carries real_tensorproduct.
        self.real_tensorproduct = sdata.real_tensorproduct
        self.extruded = sdata.extruded
        self.offset = sdata.offset
        self.cell_boundary_masks = sdata.cell_boundary_masks
        self.interior_facet_boundary_masks = sdata.interior_facet_boundary_masks
示例#4
0
def matrix_funptr(form):
    from firedrake.tsfc_interface import compile_form
    test, trial = map(operator.methodcaller("function_space"),
                      form.arguments())
    if test != trial:
        raise NotImplementedError("Only for matching test and trial spaces")
    kernel, = compile_form(form, "subspace_form", split=False)

    kinfo = kernel.kinfo

    if kinfo.subdomain_id != "otherwise":
        raise NotImplementedError("Only for full domain integrals")
    if kinfo.integral_type != "cell":
        raise NotImplementedError("Only for cell integrals")

    # OK, now we've validated the kernel, let's build the callback
    args = []

    toset = op2.Set(1, comm=test.comm)
    dofset = op2.DataSet(toset, 1)
    arity = sum(m.arity * s.cdim
                for m, s in zip(test.cell_node_map(), test.dof_dset))
    iterset = test.cell_node_map().iterset
    cell_node_map = op2.Map(iterset,
                            toset,
                            arity,
                            values=numpy.zeros(iterset.total_size * arity,
                                               dtype=IntType))
    mat = DenseMat(dofset)

    arg = mat(op2.INC, (cell_node_map[op2.i[0]], cell_node_map[op2.i[1]]))
    arg.position = 0
    args.append(arg)

    mesh = form.ufl_domains()[kinfo.domain_number]
    arg = mesh.coordinates.dat(op2.READ,
                               mesh.coordinates.cell_node_map()[op2.i[0]])
    arg.position = 1
    args.append(arg)
    for n in kinfo.coefficient_map:
        c = form.coefficients()[n]
        for (i, c_) in enumerate(c.split()):
            map_ = c_.cell_node_map()
            if map_ is not None:
                map_ = map_[op2.i[0]]
            arg = c_.dat(op2.READ, map_)
            arg.position = len(args)
            args.append(arg)

    iterset = op2.Subset(mesh.cell_set, [0])
    mod = JITModule(kinfo.kernel, iterset, *args)
    return mod._fun, kinfo
示例#5
0
def dvnodes(nodes):
    return op2.DataSet(nodes, 2, "dvnodes")
示例#6
0
def residual_funptr(form, state):
    from firedrake.tsfc_interface import compile_form
    test, = map(operator.methodcaller("function_space"), form.arguments())

    if state.function_space() != test:
        raise NotImplementedError(
            "State and test space must be dual to one-another")

    if state is not None:
        interface = make_builder(dont_split=(state, ))
    else:
        interface = None

    kernel, = compile_form(form,
                           "subspace_form",
                           split=False,
                           interface=interface)

    kinfo = kernel.kinfo

    if kinfo.subdomain_id != "otherwise":
        raise NotImplementedError("Only for full domain integrals")
    if kinfo.integral_type != "cell":
        raise NotImplementedError("Only for cell integrals")
    args = []

    toset = op2.Set(1, comm=test.comm)
    dofset = op2.DataSet(toset, 1)
    arity = sum(m.arity * s.cdim
                for m, s in zip(test.cell_node_map(), test.dof_dset))
    iterset = test.cell_node_map().iterset
    cell_node_map = op2.Map(iterset,
                            toset,
                            arity,
                            values=numpy.zeros(iterset.total_size * arity,
                                               dtype=IntType))
    dat = DenseDat(dofset)

    statedat = DenseDat(dofset)
    statearg = statedat(op2.READ, cell_node_map[op2.i[0]])

    arg = dat(op2.INC, cell_node_map[op2.i[0]])
    arg.position = 0
    args.append(arg)

    mesh = form.ufl_domains()[kinfo.domain_number]
    arg = mesh.coordinates.dat(op2.READ,
                               mesh.coordinates.cell_node_map()[op2.i[0]])
    arg.position = 1
    args.append(arg)
    for n in kinfo.coefficient_map:
        c = form.coefficients()[n]
        if c is state:
            statearg.position = len(args)
            args.append(statearg)
            continue
        for (i, c_) in enumerate(c.split()):
            map_ = c_.cell_node_map()
            if map_ is not None:
                map_ = map_[op2.i[0]]
            arg = c_.dat(op2.READ, map_)
            arg.position = len(args)
            args.append(arg)

    iterset = op2.Subset(mesh.cell_set, [0])
    mod = JITModule(kinfo.kernel, iterset, *args)
    return mod._fun, kinfo
示例#7
0
def dindset2(indset):
    return op2.DataSet(indset, 2, "dindset2")
示例#8
0
def diterset(iterset):
    return op2.DataSet(iterset, 1, "diterset")
示例#9
0
def delems2(elems):
    return op2.DataSet(elems, 2, "delems2")
示例#10
0
 def dset(cls, set):
     return op2.DataSet(set, 1, 'set')
示例#11
0
def dele2(ele):
    return op2.DataSet(ele, 2, 'dele2')
示例#12
0
def dele(ele):
    return op2.DataSet(ele, 1, 'dele')
示例#13
0
def dnode2(node):
    return op2.DataSet(node, 2, 'dnode2')
示例#14
0
def dnode(node):
    return op2.DataSet(node, 1, 'dnode')
示例#15
0
 def dtoset(cls, toset):
     return op2.DataSet(toset, 1, 'dtoset')
示例#16
0
def xtr_dvnodes(xtr_nodes):
    return op2.DataSet(xtr_nodes, 3, "xtr_dvnodes")
示例#17
0
    def test_extruded_assemble_mat_rhs_solve(self, backend, xtr_mat,
                                             xtr_coords, xtr_elements,
                                             xtr_elem_node, extrusion_kernel,
                                             xtr_nodes, vol_comp, xtr_dnodes,
                                             vol_comp_rhs, xtr_b):
        coords_dim = 3
        coords_xtr_dim = 3  # dimension
        # BIG TRICK HERE:
        # We need the +1 in order to include the entire column of vertices.
        # Extrusion is meant to iterate over the 3D cells which are layer - 1 in number.
        # The +1 correction helps in the case of iteration over vertices which need
        # one extra layer.
        iterset = op2.Set(NUM_NODES, "verts1")
        iterset = op2.ExtrudedSet(iterset, layers=(layers + 1))
        vnodes = op2.DataSet(iterset, coords_dim)

        d_nodes_xtr = op2.DataSet(xtr_nodes, coords_xtr_dim)
        d_lnodes_xtr = op2.DataSet(xtr_nodes, 1)

        # Create an op2.Dat with the base mesh coordinates
        coords_vec = numpy.zeros(vnodes.total_size * coords_dim)
        length = len(xtr_coords.flatten())
        coords_vec[0:length] = xtr_coords.flatten()
        coords = op2.Dat(vnodes, coords_vec, numpy.float64, "dat1")

        # Create an op2.Dat with slots for the extruded coordinates
        coords_new = numpy.array([0.] * layers * NUM_NODES * coords_xtr_dim,
                                 dtype=numpy.float64)
        coords_xtr = op2.Dat(d_nodes_xtr, coords_new, numpy.float64, "dat_xtr")

        # Creat an op2.Dat to hold the layer number
        layer_vec = numpy.tile(numpy.arange(0, layers), NUM_NODES)
        layer = op2.Dat(d_lnodes_xtr, layer_vec, numpy.int32, "dat_layer")

        # Map a map for the bottom of the mesh.
        vertex_to_coords = [i for i in range(0, NUM_NODES)]
        v2coords_offset = numpy.array([0], numpy.int32)
        map_2d = op2.Map(iterset, iterset, 1, vertex_to_coords, "v2coords",
                         v2coords_offset)

        # Create Map for extruded vertices
        vertex_to_xtr_coords = [layers * i for i in range(0, NUM_NODES)]
        v2xtr_coords_offset = numpy.array([1], numpy.int32)
        map_xtr = op2.Map(iterset, xtr_nodes, 1, vertex_to_xtr_coords,
                          "v2xtr_coords", v2xtr_coords_offset)

        # Create Map for layer number
        v2xtr_layer_offset = numpy.array([1], numpy.int32)
        layer_xtr = op2.Map(iterset, xtr_nodes, 1, vertex_to_xtr_coords,
                            "v2xtr_layer", v2xtr_layer_offset)

        op2.par_loop(extrusion_kernel, iterset,
                     coords_xtr(op2.INC, map_xtr, flatten=True),
                     coords(op2.READ, map_2d, flatten=True),
                     layer(op2.READ, layer_xtr))

        # Assemble the main matrix.
        op2.par_loop(
            vol_comp, xtr_elements,
            xtr_mat(op2.INC,
                    (xtr_elem_node[op2.i[0]], xtr_elem_node[op2.i[1]])),
            coords_xtr(op2.READ, xtr_elem_node))

        eps = 1.e-5
        xtr_mat.assemble()
        assert_allclose(sum(sum(xtr_mat.values)), 36.0, eps)

        # Assemble the RHS
        xtr_f_vals = numpy.array([1] * NUM_NODES * layers, dtype=numpy.int32)
        xtr_f = op2.Dat(d_lnodes_xtr, xtr_f_vals, numpy.int32, "xtr_f")

        op2.par_loop(vol_comp_rhs, xtr_elements,
                     xtr_b(op2.INC, xtr_elem_node[op2.i[0]], flatten=True),
                     coords_xtr(op2.READ, xtr_elem_node, flatten=True),
                     xtr_f(op2.READ, xtr_elem_node))

        assert_allclose(sum(xtr_b.data), 6.0, eps)

        x_vals = numpy.zeros(NUM_NODES * layers, dtype=valuetype)
        xtr_x = op2.Dat(d_lnodes_xtr, x_vals, valuetype, "xtr_x")

        op2.solve(xtr_mat, xtr_x, xtr_b)

        assert_allclose(sum(xtr_x.data), 7.3333333, eps)
示例#18
0
 def dset2(cls, set):
     return op2.DataSet(set, 2, 'set2')
示例#19
0
def delems(elems):
    return op2.DataSet(elems, 1, "delems")
示例#20
0
def dnode_set1(node_set1):
    return op2.DataSet(node_set1, 1, "dnodes1")
示例#21
0
 def ds2(cls, s2):
     return op2.DataSet(s2, 1)
示例#22
0
def dnode_set2(node_set1):
    return op2.DataSet(node_set1, 2, "dnodes2")
示例#23
0
def dindset(indset):
    return op2.DataSet(indset, 1, "dindset")
示例#24
0
def dedge_set1(edge_set1):
    return op2.DataSet(edge_set1, 1, "dedges1")
示例#25
0
def matrix_funptr(form, state):
    from firedrake.tsfc_interface import compile_form
    test, trial = map(operator.methodcaller("function_space"),
                      form.arguments())
    if test != trial:
        raise NotImplementedError("Only for matching test and trial spaces")

    if state is not None:
        interface = make_builder(dont_split=(state, ))
    else:
        interface = None

    kernels = compile_form(form,
                           "subspace_form",
                           split=False,
                           interface=interface)

    cell_kernels = []
    int_facet_kernels = []
    for kernel in kernels:
        kinfo = kernel.kinfo

        if kinfo.subdomain_id != "otherwise":
            raise NotImplementedError("Only for full domain integrals")
        if kinfo.integral_type not in {"cell", "interior_facet"}:
            raise NotImplementedError(
                "Only for cell or interior facet integrals")

        # OK, now we've validated the kernel, let's build the callback
        args = []

        if kinfo.integral_type == "cell":
            get_map = operator.methodcaller("cell_node_map")
            kernels = cell_kernels
        elif kinfo.integral_type == "interior_facet":
            get_map = operator.methodcaller("interior_facet_node_map")
            kernels = int_facet_kernels
        else:
            get_map = None

        toset = op2.Set(1, comm=test.comm)
        dofset = op2.DataSet(toset, 1)
        arity = sum(m.arity * s.cdim
                    for m, s in zip(get_map(test), test.dof_dset))
        iterset = get_map(test).iterset
        entity_node_map = op2.Map(iterset,
                                  toset,
                                  arity,
                                  values=numpy.zeros(iterset.total_size *
                                                     arity,
                                                     dtype=IntType))
        mat = LocalMat(dofset)

        arg = mat(op2.INC, (entity_node_map, entity_node_map))
        arg.position = 0
        args.append(arg)
        statedat = LocalDat(dofset)
        state_entity_node_map = op2.Map(iterset,
                                        toset,
                                        arity,
                                        values=numpy.zeros(iterset.total_size *
                                                           arity,
                                                           dtype=IntType))
        statearg = statedat(op2.READ, state_entity_node_map)

        mesh = form.ufl_domains()[kinfo.domain_number]
        arg = mesh.coordinates.dat(op2.READ, get_map(mesh.coordinates))
        arg.position = 1
        args.append(arg)
        if kinfo.oriented:
            c = form.ufl_domain().cell_orientations()
            arg = c.dat(op2.READ, get_map(c))
            arg.position = len(args)
            args.append(arg)
        if kinfo.needs_cell_sizes:
            c = form.ufl_domain().cell_sizes
            arg = c.dat(op2.READ, get_map(c))
            arg.position = len(args)
            args.append(arg)
        for n in kinfo.coefficient_map:
            c = form.coefficients()[n]
            if c is state:
                statearg.position = len(args)
                args.append(statearg)
                continue
            for (i, c_) in enumerate(c.split()):
                map_ = get_map(c_)
                arg = c_.dat(op2.READ, map_)
                arg.position = len(args)
                args.append(arg)

        if kinfo.integral_type == "interior_facet":
            arg = test.ufl_domain().interior_facets.local_facet_dat(op2.READ)
            arg.position = len(args)
            args.append(arg)
        iterset = op2.Subset(iterset, [0])
        mod = seq.JITModule(kinfo.kernel, iterset, *args)
        kernels.append(CompiledKernel(mod._fun, kinfo))
    return cell_kernels, int_facet_kernels
示例#26
0
def delem_set1(elem_set1):
    return op2.DataSet(elem_set1, 1, "delems1")
示例#27
0
def dnodes(nodes):
    return op2.DataSet(nodes, 1, "dnodes")
示例#28
0
def delems_set2(elem_set1):
    return op2.DataSet(elem_set1, 2, "delems2")
示例#29
0
def delements(elements):
    return op2.DataSet(elements, 1, "delements")
示例#30
0
def xtr_dnodes(xtr_nodes):
    return op2.DataSet(xtr_nodes, 1, "xtr_dnodes")