Пример #1
0
def get_node_set(mesh, nodes_per_entity):
    """Get the :class:`node set <pyop2.Set>`.

    :arg mesh: The mesh to use.
    :arg nodes_per_entity: The number of function space nodes per
        topological entity.
    :returns: A :class:`pyop2.Set` for the function space nodes.
    """
    global_numbering = get_global_numbering(mesh, nodes_per_entity)
    node_classes = mesh.node_classes(nodes_per_entity)
    halo = halo_mod.Halo(mesh._plex, global_numbering)
    node_set = op2.Set(node_classes, halo=halo, comm=mesh.comm)
    extruded = mesh.cell_set._extruded
    if extruded:
        # FIXME! This is a LIE! But these sets should not be extruded
        # anyway, only the code gen in PyOP2 is busted.
        node_set = op2.ExtrudedSet(node_set, layers=2)

    assert global_numbering.getStorageSize() == node_set.total_size
    if not extruded and node_set.total_size >= (1 <<
                                                (IntType.itemsize * 8 - 4)):
        raise RuntimeError(
            "Problems with more than %d nodes per process unsupported",
            (1 << (IntType.itemsize * 8 - 4)))
    return node_set
Пример #2
0
def get_node_set(mesh, nodes_per_entity):
    """Get the :class:`node set <pyop2.Set>`.

    :arg mesh: The mesh to use.
    :arg nodes_per_entity: The number of function space nodes per
        topological entity.
    :returns: A :class:`pyop2.Set` for the function space nodes.
    """
    global_numbering = get_global_numbering(mesh, nodes_per_entity)
    # Use a DM to create the halo SFs
    dm = PETSc.DMShell().create(mesh.comm)
    dm.setPointSF(mesh._plex.getPointSF())
    dm.setDefaultSection(global_numbering)
    node_classes = tuple(numpy.dot(nodes_per_entity, mesh._entity_classes))
    node_set = op2.Set(node_classes, halo=halo_mod.Halo(dm), comm=mesh.comm)
    # Don't need it any more, explicitly destroy.
    dm.destroy()
    extruded = bool(mesh.layers)
    if extruded:
        node_set = op2.ExtrudedSet(node_set, layers=mesh.layers)

    assert global_numbering.getStorageSize() == node_set.total_size
    if not extruded and node_set.total_size >= (1 <<
                                                (IntType.itemsize * 8 - 4)):
        raise RuntimeError(
            "Problems with more than %d nodes per process unsupported",
            (1 << (IntType.itemsize * 8 - 4)))
    return node_set
Пример #3
0
 def test_direct_loop_inc(self, iterset, diterset):
     dat = op2.Dat(diterset)
     xtr_iterset = op2.ExtrudedSet(iterset, layers=10)
     k = 'static void k(double *x) { *x += 1.0; }'
     dat.data[:] = 0
     op2.par_loop(op2.Kernel(k, 'k'),
                  xtr_iterset, dat(op2.INC))
     assert numpy.allclose(dat.data[:], 9.0)
Пример #4
0
    def node_set(self):
        """A :class:`pyop2.Set` containing the nodes of this
        :class:`.FunctionSpace`. One or (for
        :class:`.VectorFunctionSpace`\s) more degrees of freedom are
        stored at each node.
        """

        name = "%s_nodes" % self.name
        if self._halo:
            s = op2.Set(self.dof_classes, name, halo=self._halo)
            if self.extruded:
                return op2.ExtrudedSet(s, layers=self._mesh.layers)
            return s
        else:
            s = op2.Set(self.node_count, name)
            if self.extruded:
                return op2.ExtrudedSet(s, layers=self._mesh.layers)
            return s
Пример #5
0
 def set(self):
     size = self.classes
     halo = None
     if isinstance(self.mesh, ExtrudedMeshTopology):
         if self.kind == "interior":
             base = self.mesh._base_mesh.interior_facets.set
         else:
             base = self.mesh._base_mesh.exterior_facets.set
         return op2.ExtrudedSet(base, layers=self.mesh.layers)
     return op2.Set(size, "%s_%s_facets" % (self.mesh.name, self.kind), halo=halo)
Пример #6
0
def read_triangle(f, layers=None):
    """Read the triangle file with prefix f into OP2 data strctures. Presently
    only .node and .ele files are read, attributes are ignored, and there may
    be bugs. The dat structures are returned as:

        (nodes, coords, elements, elem_node)

    These items have type:

        (Set, Dat, Set, Map)

    The Layers argument allows the reading of data for extruded meshes.
    It is to be used when dealing with extruded meshes.
    """
    # Read nodes
    with open(f + '.node') as h:
        num_nodes = int(h.readline().split(' ')[0])
        node_values = np.zeros((num_nodes, 2), dtype=np.float64)
        for line in h:
            if line[0] == '#':
                continue
            node, x, y = line.split()[:3]
            node_values[int(node) - 1, :] = [float(x), float(y)]

    nodes = op2.Set(num_nodes, "nodes")
    coords = op2.Dat(nodes ** 2, node_values, name="coords")

    # Read elements
    with open(f + '.ele') as h:
        num_tri, nodes_per_tri, num_attrs = [int(col) for col in h.readline().split()]
        map_values = np.zeros((num_tri, nodes_per_tri), dtype=np.int32)
        for line in h:
            if line[0] == '#':
                continue
            vals = [int(v) - 1 for v in line.split()]
            map_values[vals[0], :] = vals[1:nodes_per_tri + 1]

    if layers is not None:
        elements = op2.ExtrudedSet(op2.Set(num_tri, "elements"), layers=layers)
    else:
        elements = op2.Set(num_tri, "elements")
    elem_node = op2.Map(elements, nodes, nodes_per_tri, map_values, "elem_node")

    return nodes, coords, elements, elem_node
Пример #7
0
def get_node_set(mesh, nodes_per_entity):
    """Get the :class:`node set <pyop2.Set>`.

    :arg mesh: The mesh to use.
    :arg nodes_per_entity: The number of function space nodes per
        topological entity.
    :returns: A :class:`pyop2.Set` for the function space nodes.
    """
    global_numbering = get_global_numbering(mesh, nodes_per_entity)
    # Use a DM to create the halo SFs
    dm = PETSc.DMShell().create()
    dm.setPointSF(mesh._plex.getPointSF())
    dm.setDefaultSection(global_numbering)
    node_classes = tuple(numpy.dot(nodes_per_entity, mesh._entity_classes))
    node_set = op2.Set(node_classes, halo=halo_mod.Halo(dm))
    # Don't need it any more, explicitly destroy.
    dm.destroy()
    extruded = bool(mesh.layers)
    if extruded:
        node_set = op2.ExtrudedSet(node_set, layers=mesh.layers)

    assert global_numbering.getStorageSize() == node_set.total_size
    return node_set
Пример #8
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)
Пример #9
0
def xtr_nodes():
    nset = op2.Set(NUM_NODES * layers)
    return op2.ExtrudedSet(nset, layers=layers)
Пример #10
0
def xtr_elements():
    eset = op2.Set(NUM_ELE)
    return op2.ExtrudedSet(eset, layers=layers)
Пример #11
0
def elements():
    s = op2.Set(nelems)
    return op2.ExtrudedSet(s, layers=layers)
Пример #12
0
 def cell_set(self):
     return op2.ExtrudedSet(self._base_mesh.cell_set, layers=self.layers)
Пример #13
0
 def cell_set(self):
     return self.parent.cell_set if self.parent else \
         op2.ExtrudedSet(self._old_mesh.cell_set, layers=self._layers)