Exemple #1
0
def parallel_info_subproblem(menuitem, subproblem):
    subpctxt = ooflib.engine.subproblemcontext.subproblems[subproblem]
    subpctxt.begin_reading()
    reportstring = ""
    nGatherNodes = 0
    nElements = 0
    TotalArea = 0
    try:
        nElements = subpctxt.nelements()
        TotalArea = subpctxt.area()
        reportstring = """*** Subproblem Info ***
%s
%d elements
%d nodes
area = %g\n""" % (subpctxt.getObject(), nElements, subpctxt.nnodes(),
                  TotalArea)
        nGatherNodes = subpctxt.getObject().GatherNumNodes()
    finally:
        subpctxt.end_reading()

    if mpitools.Rank() == 0:
        #Get output from other processes
        for proc in range(mpitools.Size()):
            if proc != 0:
                reportstring += "(From remote process %d:)\n" % proc
                reportstring += mpitools.Recv_String(proc)
                nElements += mpitools.Recv_Int(proc)
                TotalArea += mpitools.Recv_Double(proc)
        reportstring += """***** Totals (union) *****
%d elements
%d unique nodes
Total Area = %g""" % (nElements, nGatherNodes, TotalArea)
        reporter.report(reportstring)
    else:
        mpitools.Send_String(reportstring, 0)
        mpitools.Send_Int(nElements, 0)
        mpitools.Send_Double(TotalArea, 0)
Exemple #2
0
def parallel_move_node(menuitem, origin, destination,
                       allow_illegal,
                       skeletonpath):
    skelcontext = skeletoncontext.skeletonContexts[skeletonpath]
    #skelcontext = self.gfxwindow().topwho('Skeleton')
    if skelcontext:
        skeleton = skelcontext.getObject().deputyCopy()
        skeleton.activate()
        #If one looks at moveNodeGUI.py, origin here is already
        #set to the position of the nearest node.
        node = skeleton.nearestNode(origin)
        nodeindex=node.getIndex()
        distance2=(node.position()-origin)**2
        ###############################################################
        # Get nearest node distances from all processes
        if _rank==0:
            #Get list of squares of distance of node to the click point
            distance2list=[distance2]
            dmin=-1
            dmin_proc_list=[]
            #Get distances from other processes
            for proc in range(_size):
                if proc!=0:
                    distance2list.append(mpitools.Recv_Double(proc))
                if distance2list[proc]>=0:
                    dmin=distance2list[proc]
            #Find closest node among those "nominated" by each process
            for proc in range(_size):
                if distance2list[proc]>=0:
                    if distance2list[proc]<dmin:
                        dmin=distance2list[proc]
            for proc in range(_size):
                if distance2list[proc]==dmin:
                    dmin_proc_list.append(proc)
        else:
            #Backend sends report to front end
            mpitools.Send_Double(distance2,0)

        mpitools.Barrier()
        
        #Tell the processes in dmin_proc_list to try moving their nodes
        #and report back the result. Then really move the node if the
        #move is valid for all of them.
        if _rank==0:
            for proc in range(_size):
                if proc in dmin_proc_list:
                    if proc==0:
                        moveit=1
                    else:
                        mpitools.Send_Int(1,proc)
                else:
                    if proc==0:
                        moveit=0
                    else:
                        mpitools.Send_Int(0,proc)
        else:
            moveit=mpitools.Recv_Int(0)

        mpitools.Barrier()

        #
        ###############################################################
        skelcontext.reserve()
        skelcontext.begin_writing()
        try:
            if moveit:
                skeleton.moveNodeTo(node, destination)
                #TODO 3.1: If the node is shared, the move may be valid in one process
                #but invalid in another.
                if node.illegal():
                    if allow_illegal==1:
                        skeleton.setIllegal()
                    else:
                        node.moveBack()
                elif skeleton.illegal(): # node motion may have rehabilitated
                    skeleton.checkIllegality()
                skelcontext.pushModification(skeleton)
        finally:
            #
            collect_pieces(skeleton)
            #
            skelcontext.end_writing()
            skelcontext.cancel_reservation()
        skeleton.needsHash()
        switchboard.notify('redraw')
Exemple #3
0
def parallel_skel_info_query(menuitem, targetname, position, skeleton):
    debug.fmsg()
    skelcontext = skeletoncontext.skeletonContexts[skeleton]        
    skelobj = skelcontext.getObject()
    skelcontext.begin_reading()
    try:
        if targetname=="Node":
            node = skelobj.nearestNode(position)
            nodeindex=-1
            reportstring=""
            distance2=-1
            if node:
                nodeindex=node.getIndex()
                distance2=(node.position()-position)**2
                if node.movable_x() and node.movable_y():
                    nmob = "free"
                elif node.movable_x() and not node.movable_y():
                    nmob = "x only"
                elif not node.movable_x() and node.movable_y():
                    nmob = "y only"
                elif node.pinned():
                    nmob = "pinned"
                else:
                    nmob = "fixed"
                nneighborelements="None"
                if node.neighborElements(skelobj):
                    nneighborelements=string.join(["Element %d" % obj.index
                                                   for obj in node.neighborElements(skelobj)],",")
                reportstring="""
    index=%d
    position=(%g,%g)
    mobility=%s
    neighborelements=%s""" % (nodeindex,
                                node.position().x,node.position().y,
                                nmob,
                                nneighborelements)

            if _rank==0:
                #Get list of squares of distance of node to the click point
                distance2list=[distance2]
                #Get list of reportstring(s) from each process
                reportstringlist=[reportstring]
                dmin=-1
                dmin_proc=-1
                msg="Skeleton Info Query Node IPC/MPI:\n"
                #Get report from other processes
                for proc in range(_size):
                    if proc!=0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append(mpitools.Recv_Double(proc))
                    if distance2list[proc]>=0:
                        dmin=distance2list[proc]
                        dmin_proc=proc
                    #msg+="From process %d:%s\n" % (proc,reportstringlist[proc])
                #Find closest node among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc]>=0:
                        if distance2list[proc]<dmin:
                            dmin=distance2list[proc]
                            dmin_proc=proc
                if dmin_proc!=-1:
                    msg+="The closest node to the point clicked at (%g,%g) is from process %d:%s\n" % \
                    (position.x,position.y,dmin_proc,reportstringlist[dmin_proc])
                reporter.report(msg)
            else:
                #Backend sends report to front end
                mpitools.Send_String(reportstring,0)
                mpitools.Send_Double(distance2,0)
        ################################################################################
        elif targetname=="Segment":
            # Function to calculate the distance squared between a point and
            # a segment (the perpendicular distance or distance from endpoints),
            # taken from skeleton.py.
            def segdistance(pt, segment):
                nodes = segment.nodes()
                p0 = nodes[0].position()
                p1 = nodes[1].position()
                a = pt-p0
                b = p1-p0
                seglength2 = b**2
                f = ((a*b)/seglength2)
                if f < 0:
                    alpha = -f
                    r = pt - p0
                elif f > 1:
                    alpha = f-1
                    r = pt - p1
                else:
                    r = a-f*b
                    alpha = 0
                return (r**2, alpha*alpha*seglength2)

            sgmt = skelobj.nearestSgmt(position)
            reportstring=""
            distance2=(-1,-1)
            if sgmt:
                distance2=segdistance(position,sgmt)
                sindex = `sgmt.getIndex()`
                length = `sgmt.length()`
                homogval = sgmt.homogeneity(skelobj.MS)
                if 0.9999 < homogval < 1.0:
                    homog = "1 - (%e)" % (1.0-homogval)
                else:
                    homog = `homogval`

                reportstring="""
    index=%s
    nodes=%s
    elements=%s
    length=%s
    homogeneity=%s""" % (sindex,
                         string.join(["Node %d at (%g, %g)" % (obj.index,
                                                               obj.position().x,
                                                               obj.position().y)
                                      for obj in sgmt.get_nodes()],","),
                         string.join(["Element %d" % obj.index for obj in sgmt.getElements()],","),
                         length,
                         homogval)

            if _rank==0:
                distance2list=[distance2]
                #Get list of reportstring(s) from each process
                reportstringlist=[reportstring]
                dmin=(-1,-1)
                dmin_proc=-1
                msg="Skeleton Info Query Segment IPC/MPI:\n"
                #Get report from other processes
                for proc in range(_size):
                    if proc!=0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append((mpitools.Recv_Double(proc),mpitools.Recv_Double(proc)))
                    if distance2list[proc][0]>=0:
                        dmin=distance2list[proc]
                        dmin_proc=proc
                #Find closest segment among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc][0]>=0:
                        if distance2list[proc]<dmin:
                            dmin=distance2list[proc]
                            dmin_proc=proc
                if dmin_proc!=-1:
                    msg+="From process %d:" % dmin_proc
                    msg+=reportstringlist[dmin_proc]
                    reporter.report(msg)
                else:
                    reporter.report("No segment found!\n")
            else:
                #Backend sends report to front end
                mpitools.Send_String(reportstring,0)
                mpitools.Send_Double(distance2[0],0)
                mpitools.Send_Double(distance2[1],0)
        ################################################################################
        elif targetname=="Element":
            #This gets the element closest to the clicked point.
            #If the point is not within the microstructure then the point
            #is moved to the boundaries of the microstructure.
            elem = skelobj.enclosingElement(position)
            reportstring=""
            distance2=-1
            if elem:
                distance2=(elem.center()-position)**2
                etype = `elem.type()`[1:-1] # strip quotes
                eindex = `elem.getIndex()`
                earea = "%g" % elem.area()

                if not elem.illegal():
                    domCat = elem.dominantPixel(skelobj.MS)
                    repPix = skelobj.MS.getRepresentativePixel(domCat)
                    pixGrp = pixelgroup.pixelGroupNames(skelobj.MS, repPix)
                    pixgrps = string.join(pixGrp, ", ")
                    ehom = "%f" % elem.homogeneity(skelobj.MS)
                    eshape = "%f" % elem.energyShape()

                    mat = elem.material(skelobj)
                    if mat:
                        matname = mat.name()
                    else:
                        matname = "<No material>"
                else:                           # illegal element
                    pixgrps = "???"
                    ehom = "???"
                    eshape = "???"
                    matname = "???"

                reportstring="""
    index=%s
    type=%s
    nodes=%s
    segments=%s
    area=%s
    dominant pixel=%s
    homogeneity=%s
    shape energy=%s
    material=%s""" % (eindex,
                      etype,
                      string.join(["Node %d at (%g, %g)" % (obj.index,
                                                            obj.position().x,
                                                            obj.position().y)
                                   for obj in elem.nodes],","),
                      string.join(["Segment %d, nodes (%d, %d) (length: %g)" %
                                   (obj.index, obj.nodes()[0].index, obj.nodes()[1].index,
                                    obj.length())
                                   for obj in elem.getSegments(skelobj)],","),
                      earea,
                      pixgrps,
                      ehom,
                      eshape,
                      matname)

            if _rank==0:
                distance2list=[distance2]
                #Get list of reportstring(s) from each process
                reportstringlist=[reportstring]
                dmin=-1
                dmin_proc=-1
                msg="Skeleton Info Query Element IPC/MPI:\n"
                #Get report from other processes
                for proc in range(_size):
                    if proc!=0:
                        reportstringlist.append(mpitools.Recv_String(proc))
                        distance2list.append(mpitools.Recv_Double(proc))
                    if distance2list[proc]>=0:
                        dmin=distance2list[proc]
                        dmin_proc=proc
                #Find closest element among those "nominated" by each process
                for proc in range(_size):
                    if distance2list[proc]>=0:
                        if distance2list[proc]<dmin:
                            dmin=distance2list[proc]
                            dmin_proc=proc
                if dmin_proc!=-1:
                    msg+="From process %d:" % dmin_proc
                    msg+=reportstringlist[dmin_proc]
                    reporter.report(msg)
                else:
                    reporter.report("No enclosing element found!\n")
            else:
                #Backend sends report to front end
                mpitools.Send_String(reportstring,0)
                mpitools.Send_Double(distance2,0)
    finally:
        skelcontext.end_reading()
Exemple #4
0
def parallel_mesh_info_query(menuitem, targetname, position, mesh):
    debug.fmsg()
    meshcontext = ooflib.engine.mesh.meshes[mesh]
    skelobj = meshcontext.getSkeleton()
    femesh = meshcontext.getObject()

    if targetname == "Node":
        fnode = femesh.closestNode(position.x, position.y)
        reportstring = ""
        distance2 = -1
        if fnode:
            distance2 = (fnode.position() - position)**2
            reportstring = """
    index=%d
    type=%s
    position=(%g,%g)
    displaced_position=(%g,%g)
    fields=%s\n""" % (fnode.index(), fnode.classname(), fnode.position().x,
                      fnode.position().y, fnode.displaced_position(femesh).x,
                      fnode.displaced_position(femesh).y, ', '.join(
                          fnode.fieldNames()))
            #Get the subproblems defined on the mesh that contains the node,
            #get the active fields in each subproblem, and find the values
            #of the fields at the node.
            reportsubpfields = ["    subproblems and field values:"]
            for subpctxt in meshcontext.subproblems():
                subp = subpctxt.getObject()
                if subp.containsNode(fnode):
                    reportsubpfields.append(8 * " " + subpctxt.name())
                    for field in subpctxt.all_compound_fields():
                        if subp.is_active_field(field):
                            reportsubpfields.append(12 * " " + ` field `)
                            #The hasField check is redundant because of containsNode above.
                            if fnode.hasField(field):
                                for i in range(field.ndof()):
                                    reportsubpfields.append(16 * " " + (
                                        "%g" % field.value(fnode, i)))
            reportstring += string.join(reportsubpfields, "\n")

        if _rank == 0:
            #Get list of squares of distance of node to the click point
            distance2list = [distance2]
            #Get list of reportstring(s) from each process
            reportstringlist = [reportstring]
            dmin = -1
            dmin_proc = -1
            msg = "Mesh Info Query Node IPC/MPI:\n"
            #Get report from other processes
            for proc in range(_size):
                if proc != 0:
                    reportstringlist.append(mpitools.Recv_String(proc))
                    distance2list.append(mpitools.Recv_Double(proc))
                if distance2list[proc] >= 0:
                    dmin = distance2list[proc]
                    dmin_proc = proc
            #Find closest node among those "nominated" by each process
            for proc in range(_size):
                if distance2list[proc] >= 0:
                    if distance2list[proc] < dmin:
                        dmin = distance2list[proc]
                        dmin_proc = proc
            if dmin_proc != -1:
                msg+="The closest node to the point clicked at (%g,%g) is from process %d:%s\n" % \
                (position.x,position.y,dmin_proc,reportstringlist[dmin_proc])
            reporter.report(msg)
        else:
            #Backend sends report to front end
            mpitools.Send_String(reportstring, 0)
            mpitools.Send_Double(distance2, 0)
    ################################################################################
    elif targetname == "Element":
        selem = skelobj.enclosingElement(position)
        reportstring = ""
        distance2 = -1
        if selem:
            felem = femesh.getElement(selem.meshindex)
            if felem:
                distance2 = (selem.center() - position)**2

                mat = felem.material()
                if mat:
                    matname = mat.name()
                else:
                    matname = "<No material>"

                reportstring = """
    index=%s
    type=%d
    nodes=%s
    material=%s\n""" % (felem.masterelement().name(), felem.get_index(),
                        string.join([
                            "%s %d at (%g, %g)" %
                            (obj.classname(), obj.index(), obj.position().x,
                             obj.position().y)
                            for obj in felem.node_iterator()
                        ], ","), matname)
                #Get the subproblems defined on the mesh,
                #get the active fields in each subproblem, and find the values
                #of the fields at the position inside the element.
                reportsubpfields = ["    subproblems and field values:"]
                for subpctxt in meshcontext.subproblems():
                    subp = subpctxt.getObject()
                    reportsubpfields.append(8 * " " + subpctxt.name())
                    for field in subpctxt.all_compound_fields():
                        if subp.is_active_field(field):
                            reportsubpfields.append(12 * " " + ` field `)
                            masterpos = felem.to_master(position)
                            o = felem.outputField(field, masterpos)
                            valuelist = o.valuePtr().value_list()
                            for val in valuelist:
                                reportsubpfields.append(16 * " " + ` val `)
                reportstring += string.join(reportsubpfields, "\n")

        if _rank == 0:
            distance2list = [distance2]
            #Get list of reportstring(s) from each process
            reportstringlist = [reportstring]
            dmin = -1
            dmin_proc = -1
            msg = "Mesh Info Query Element IPC/MPI:\n"
            #Get report from other processes
            for proc in range(_size):
                if proc != 0:
                    reportstringlist.append(mpitools.Recv_String(proc))
                    distance2list.append(mpitools.Recv_Double(proc))
                if distance2list[proc] >= 0:
                    dmin = distance2list[proc]
                    dmin_proc = proc
            #Find closest element among those "nominated" by each process
            for proc in range(_size):
                if distance2list[proc] >= 0:
                    if distance2list[proc] < dmin:
                        dmin = distance2list[proc]
                        dmin_proc = proc
            if dmin_proc != -1:
                msg += "From process %d:" % dmin_proc
                msg += reportstringlist[dmin_proc]
                reporter.report(msg)
            else:
                reporter.report("No enclosing element found!\n")
        else:
            #Backend sends report to front end
            mpitools.Send_String(reportstring, 0)
            mpitools.Send_Double(distance2, 0)