def __init__(self, mesh: fenics.Mesh, mode: str, file_name: str, function: fenics.Function, function_name: str): self.file = fenics.HDF5File(mesh.mpi_comm(), file_name, mode) self.function = function self.function_name = function_name
def gather_mesh(mesh): """Gather a local copy of a distributed mesh""" # comm = MPI.COMM_WORLD if mesh in gather_mesh_cache: logGATHER('gather_mesh cache hit') return gather_mesh_cache[mesh] comm = mesh.mpi_comm() size = comm.size if size == 1: gather_mesh_cache[mesh] = mesh return (mesh) # sequential: nothing to do dim = mesh.geometry().dim() topology = mesh.topology() logGATHER('topology.global_indices(0)', topology.global_indices(0)) logGATHER('topology.size(0)', topology.size(0)) # # To define a mesh, we need two things: a list of all the # vertices, each with an index and coordinates, and a list of all # cells, each specified by a list of vertices. # vcoord = mesh.coordinates() vcoords = gather_array(vcoord, comm) # vertexes from all processes vindex = topology.global_indices(0) vindexes = gather_array(vindex, comm) # global vertex indexes try: gnv = topology.size_global(0) except AttributeError: gnv = np.max(vindexes) + 1 logGATHER('gnv', gnv) gvcs = np.zeros((gnv, dim), dtype=vcoords.dtype) for v, vc in enumerate(vcoords): # coords indexed by global indices gvcs[vindexes[v], :] = vc logGATHER('gvcs', gvcs) # # We now have in gvcs a list of global vertex coordinates. (The # indices are just 0...len(gvcs)-1.) Now for the cells: # nc = mesh.num_cells() logGATHER('nc', nc) total = comm.allreduce(nc) logGATHER('total', total) cell = np.zeros(nc * (dim + 1), dtype=int) cell[:] = vindex[mesh.cells().flatten()] # vindex to get global indices logGATHER('cell', cell) cells = gather_array(cell, comm) cells = cells.reshape(-1, dim + 1) logGATHER('cells', cells) cindex = topology.global_indices(dim) logGATHER('cindex', cindex) cindexes = gather_array(cindex, comm) logGATHER('cindexes', cindexes) try: gnc = topology.size_global(dim) except AttributeError: gnc = np.max(cindexes) + 1 logGATHER('gnc', gnc) gcells = np.zeros((gnc, dim + 1), dtype=int) for v, cell in enumerate(cells): gcells[cindexes[v], :] = cell logGATHER('gcells', gcells) # # Now use this collected info to construct a mesh # try: scomm = fe.mpi_comm_self() except AttributeError: scomm = MPI.COMM_SELF mesh = Mesh(scomm) # new mesh is sequential logGATHER('scomm', scomm) logGATHER('MPI.COMM_SELF', MPI.COMM_SELF) # if comm.rank == 0: if True: # construct a mesh in all processes editor = MeshEditor() editor.open(mesh, str(cellShapes[dim - 1]), dim, dim) editor.init_vertices_global(len(gvcs), len(gvcs)) editor.init_cells_global(len(gcells), len(gcells)) for v, vc in enumerate(gvcs): editor.add_vertex_global(v, v, vc) for c, cell in enumerate(gcells): logGATHER('c, cell', c, cell) editor.add_cell(c, cell) mesh.order() logGATHER('mesh.mpi_comm()', mesh.mpi_comm()) logGATHER('mesh.mpi_comm().size', mesh.mpi_comm().size) gather_mesh_cache[mesh] = mesh logGATHER('caching gathered mesh') return (mesh)