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
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
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)
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
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)
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
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
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)
def xtr_nodes(): nset = op2.Set(NUM_NODES * layers) return op2.ExtrudedSet(nset, layers=layers)
def xtr_elements(): eset = op2.Set(NUM_ELE) return op2.ExtrudedSet(eset, layers=layers)
def elements(): s = op2.Set(nelems) return op2.ExtrudedSet(s, layers=layers)
def cell_set(self): return op2.ExtrudedSet(self._base_mesh.cell_set, layers=self.layers)
def cell_set(self): return self.parent.cell_set if self.parent else \ op2.ExtrudedSet(self._old_mesh.cell_set, layers=self._layers)