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)
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')
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()
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)