Beispiel #1
0
def collect_pieces(skel):
    global _rank
    global _size
    # Gather minimal info for element polygons (to display Skeleton at #0)
    # Only the #0 will store the gathered information.
    # no. of nodes & no. of elements
    nnodes = mpitools.Allgather_Int(skel.nnodes())
    #RCL: Use maxnnodes as base offset for the indices of non-corner mesh nodes
    skel.maxnnodes = max(nnodes)
    nelems = mpitools.Allgather_Int(skel.nelements())
    myCoords = list(
        reduce(
        lambda x,y: x+y, [(skel.nodePosition(nd)[0],
                           skel.nodePosition(nd)[1])
                          for nd in skel.node_iterator()]
        ))

    coordSizes = [i*2 for i in nnodes]
    allCoords = mpitools.Allgather_DoubleVec(myCoords,
                                             size_known=coordSizes)
    # allCoords = [[(x0,y0),(x1,y1), ...], [...], ...]
    allCoords = [ [(allCoords[i][2*j],allCoords[i][2*j+1])
                   for j in range(nnodes[i])]
                  for i in range(_size) ]
    # element connectivity signature
    myEConSigs = [el.nnodes() for el in skel.element_iterator()]
    allEConSigs = mpitools.Allgather_IntVec(myEConSigs, size_known=nelems)
    # element connectivity
    myECons = [ [skel.node_index_dict[nd.getIndex()] for nd in el.nodes]
                for el in skel.element_iterator()]
    myECons = reduce(lambda x,y: x+y, myECons)
    conSizes = [reduce(lambda x,y: x+y, aECS) for aECS in allEConSigs]
    temp = mpitools.Allgather_IntVec(myECons, size_known=conSizes)

    def listrize(list, signature):
        nsig = len(signature)
        count = 0
        output = [[] for i in range(nsig)]
        for i in range(nsig):
            for j in range(signature[i]):
                output[i].append(list[count])
                count += 1
        return output

    allECons = [listrize(temp[i], allEConSigs[i]) for i in range(_size)]
    if _rank == 0:
        skel.all_skeletons = {"nodes": allCoords,
                              "elements": allECons}
Beispiel #2
0
def collect_pieces(femesh):

    # Build dictionary (instead of using the mesh assigned indices (via index() or get_index())
    #  which are unique but may have gaps)
    nodedict = {}
    i = 0
    for node in femesh.node_iterator():
        nodedict[node.index()] = i
        i += 1

    global _rank
    global _size
    # Gather minimal info for element polygons (to display mesh Skeleton at #0)
    # Only the #0 will store the reconstituted information.

    #RCL: Collect number of nodes from each process into an array.
    # One gets this for nnodes: [nnodes0, nnodes1, ...]
    nnodes = mpitools.Allgather_Int(femesh.nnodes())

    #RCL: Same for the elements.
    # One gets this for nelems: [nelems0, nelems1, ...]
    nelems = mpitools.Allgather_Int(femesh.nelements())
    myCoords = reduce(lambda x, y: x + y,
                      [[nd.position().x, nd.position().y]
                       for nd in femesh.node_iterator()])

    coordSizes = [i * 2 for i in nnodes]
    #RCL: Collect (x,y) coordinates of nodes from each process
    # coordSizes contains the array of number of coordinates (counting x and y separately) from each process
    # The return value is a 2-D array, indexed first by the process number(?)
    # One gets this for allCoords: [[x0,y0,x1,y1,...], [x0',y0',x1',y1',...], ...]
    allCoords = mpitools.Allgather_DoubleVec(myCoords, size_known=coordSizes)

    #RCL: One gets the following format after the list comprehension operations
    # allCoords = [[(x0,y0),(x1,y1), ...], [...], ...]
    allCoords = [[(allCoords[i][2 * j], allCoords[i][2 * j + 1])
                  for j in range(nnodes[i])] for i in range(_size)]

    # element connectivity signature
    myEConSigs = [len(el.perimeter()) for el in femesh.element_iterator()]
    #RCL: One gets this for allEConSigs: [[elnnodes0,elnnodes1,...],[elnnodes0',elnnodes1',...],...]
    allEConSigs = mpitools.Allgather_IntVec(myEConSigs, size_known=nelems)

    # element connectivity
    #RCL: nodedict must be a map to the 0-based indices of the nodes
    myECons = [[nodedict[nd.index()] for nd in el.node_iterator()]
               for el in femesh.element_iterator()]
    myECons = reduce(lambda x, y: x + y, myECons)

    #RCL: conSizes looks like [[elnnodes0+elnnodes1+...],[elnnodes0'+elnnodes1'+...],...]
    conSizes = [reduce(lambda x, y: x + y, aECS) for aECS in allEConSigs]

    #RCL: temp looks like
    # [[el0_nodeindex1,el0_nodeindex2,...el1_nodeindex1,el1_nodeindex2,...],[el0'_nodeindex1,el0'_nodeindex2,...,el1'_nodeindex1,el1'_nodeindex2,...],...]
    temp = mpitools.Allgather_IntVec(myECons, size_known=conSizes)

    #RCL: The connectivity information could still be shrunk, but its hard...
    # If we store the nodes for each element, duplicate nodes results. Storage becomes ~4*(number of (double x and double y))

    def listrize(list, signature):
        #RCL: nsig is the number of elements if allEConsigs[i] is passed as signature
        nsig = len(signature)
        count = 0
        output = [[] for i in range(nsig)]
        for i in range(nsig):
            for j in range(signature[i]):
                output[i].append(list[count])
                count += 1
        return output

    #RCL: allECons looks like [[[nodeindex1,nodeindex2,...],[nodeindex1',nodeindex2',...],...], [], ...]
    allECons = [listrize(temp[i], allEConSigs[i]) for i in range(_size)]
    if _rank == 0:
        femesh.all_meshskeletons = {"nodes": allCoords, "elements": allECons}