def postProcess(self, context): ## global Pcount ## Pcount += 1 ## random.seed(1) skeleton = context.getObject() prog = self.makeProgress() self.count = 0 prog.setMessage(self.header) before = skeleton.energyTotal(self.criterion.alpha) while self.iteration.goodToGo(): self.count += 1 # the context acquires the writing permissions inside # coreProcess. self.coreProcess(context) self.updateIteration(prog) if prog.stopped(): break switchboard.notify("skeleton nodes moved", context) if prog.stopped(): self.targets.cleanUp() return after = skeleton.energyTotal(self.criterion.alpha) if before: rate = 100.0*(before-after)/before else: rate = 0.0 diffE = after - before reporter.report("%s deltaE = %10.4e (%6.3f%%)" % (self.outro, diffE, rate)) self.targets.cleanUp() prog.finish()
def okskelmod(self,gtkobj): path = self.skelwidget.get_value() modifier = self.skelmod.get_value() if path and modifier: OOF.Skeleton.Modify(skeleton=path, modifier=modifier) else: reporter.report("Can't modify!!!!")
def reportSomething(self, delta, total, rate, count): if total: reduce = abs(100.0*delta/total) else: reduce = 0.0 reporter.report("Iteration %d: E = %10.4e, deltaE=%10.4e (%6.3f%%), Acceptance Rate = %4.1f%%" % (count, total, delta, reduce, 100.*rate))
def apply(self, oldskeleton, context): prog = progress.getProgress("SplitQuads", progress.DEFINITE) try: skel = oldskeleton.properCopy(skeletonpath=context.path()) elements = self.targets(skel, context, copy=1) done = 0 # No. of quads split. savedE = 0.0 # Saved energy from the merge nel = len(elements) for i in range(nel): element = elements[i] if element.nnodes()==4 and element.active(skel): changes = self.split_how(skel, element) bestchange = self.criterion(changes, skel) if bestchange is not None: done += 1 savedE += bestchange.deltaE(skel, self.criterion.alpha) bestchange.accept(skel) if prog.stopped(): return None prog.setFraction(1.0*(i+1)/nel) prog.setMessage("%d/%d elements" % (i+1, nel)) reporter.report("%d quadrilateral%s split." % (done, 's'*(done!=1))) skel.cleanUp() return skel finally: prog.finish()
def add_prop(self, matname, propname): prop_reg = AllProperties[propname] mat = self[matname] if prop_reg: # Can be None for nonparametrizable properties. mat[propname]=prop_reg else: reporter.report("Nonparametrizable property is not loadable.")
def readData(self, datafile, prog): count = 1 lines = datafile.readlines() nlines = len(lines) data = utils.ReservableList(nlines) # The number of angle components to read is the number of # parameters in the Registration for the selected Orientation # subclass. for reg in orientationmatrix.Orientation.registry: if reg.subclass == self.angle_type: nAngleComps = len(reg.params) break xycol0 = self.xy_column - 1 # UI uses fortran indexing xycol1 = xycol0 + 2 # TODO: Are there 3D EBSD files? acol0 = self.angle_column - 1 # UI uses fortran indexing acol1 = acol0 + nAngleComps # Look for the last non-blank non-comment line in the file, # and examine it to find out what data lines look like. This # information will be used to skip the header lines at the top # of the file. for i in xrange(len(lines)-1, -1, -1): line = lines[i].strip() if line and line[0] != self.comment_character: words = self.separator.split(line) nwords = len(words) lastline = i break # Loop over the lines in reverse, and stop at the first one # that can't be handled. That will be the last header line. for i in xrange(lastline, -1, -1): line = lines[i] if line[0] != self.comment_character: # Skip comments cols = self.separator.split(line) if len(cols) != nwords: break try: angletuple = map(float, cols[acol0:acol1]) position = primitives.Point( *map(float, cols[xycol0:xycol1])) except ValueError: # Ran into the header. Quit reading. break grps = [template.replace('%s', cols[gcol-1]) for (template, gcol) in self.groups] data.append(DataPoint(position, angletuple, grps)) count += 1 # count actual lines, comments and all prog.setMessage("read %d/%d lines" % (count, nlines)) prog.setFraction(float(count)/nlines) npts = len(data) reporter.report( "Read %d lines, found %d data points" % (len(lines), npts)) return data
def statusCB(self, button): # status details button callback meshctxt = self.currentMeshContext() details = meshctxt.status.getDetails() if details: reporter.report("\n*** Mesh Status for %s ***\n%s: %s" % (meshctxt.path(), meshctxt.status.tag, details)) else: reporter.report("\n*** Mesh Status for %s ***\n%s" % (meshctxt.path(), meshctxt.status.tag)) reporter_GUI.raiseMessageWindows()
def queryGroup(menuitem, microstructure, group): mscontext = ooflib.common.microstructure.microStructures[microstructure] ms = mscontext.getObject() mscontext.begin_reading() try: grp = ms.findGroup(group) nop = len(grp) areaOfGroup = nop*ms.areaOfPixels() finally: mscontext.end_reading() reporter.report(">>> ", nop, " pixels, ", "area = ", areaOfGroup)
def _save_prop(menuitem): global materialspage propname = materialspage.current_property_name() if propname: params = filter(lambda x: x.name!="property", menuitem.params) if parameterwidgets.getParameters(ident='PropMenu', title='Save Property', *params): menuitem.callWithDefaults(property=propname) else: reporter.report("No property selected for saving.")
def __call__(self, skel, context, targets, criterion, fixer): prog = progress.findProgress("Rationalize") # Copy the element list from skeleton.element before # rationalizing. This is necessary because rationalizing # modifies the Skeleton's element list. elements = targets(skel, context, copy=1) random.shuffle(elements) executed_action = self.getRegistration().gerund processed = {} count = 0 done = 0 # No. of rationalized elements nel = len(elements) # No. of elements in the list for element in elements: count += 1 # The i-th element being processed ... for progress bar if element not in processed and element.active(skel): # fixer is either self.findAndFix or self.fixAll. They # return a list of ProvisionalChanges objects, from # which we pick the best one. changes = fixer(skel, element) bestchange = criterion(changes, skel) if bestchange is not None: done += bestchange.nRemoved() # Accepting the change converts provisional # elements to actual elements. bestchange.accept(skel) for elephant in bestchange.removed: processed[elephant] = 1 for oldel, newel in bestchange.substitutions: # If an unprocessed element has been replaced, # its replacement still has to be processed. # The element being replaced should *not* be # processed, in any case, since it's no longer # in the skeleton. # If the criterion is "Unconditional" or # "Limited Unconditional", it doesn't add subs to # the list. if oldel not in processed: processed[oldel] = 1 if criterion.addSubstitute(elements, newel): nel += 1 if prog.stopped(): break else: prog.setFraction(1.0*count/nel) prog.setMessage(executed_action + " %d/%d" % (count, nel)) skel.cleanUp() reporter.report("%d elements rationalized : %s." % (done, self.getRegistration().name()))
def queryElem(self, menuitem, position): context = self.getSkeletonContext() if not context: return skeleton = context.getObject() if parallel_enable.enabled(): skeletonIPC.smenu.Skel_Info_Query(targetname="Element", position=position, skeleton=context.path()) if mpitools.Rank() > 0: return elem = skeleton.enclosingElement(position) if not elem: reporter.report("Try to click ON an Element, dude.") else: self.finishQuery(context, elem, "Element", position)
def _info_subproblem(menuitem, subproblem): if parallel_enable.enabled(): ipcsubpmenu.Info(subproblem=subproblem) return subpctxt = ooflib.engine.subproblemcontext.subproblems[subproblem] subpctxt.begin_reading() try: reporter.report( """*** Subproblem Info *** %s %d elements %d nodes area = %s""" % (subpctxt.subptype, subpctxt.nelements(), subpctxt.nnodes(), subpctxt.area())) finally: subpctxt.end_reading()
def _redo(menuitem, skeleton): if parallel_enable.enabled(): from ooflib.engine.IO import skeletonIPC skeletonIPC.smenu.Redo(skeleton=skeleton) context = skeletoncontext.skeletonContexts[skeleton] if context.redoable(): context.begin_writing() try: context.redoModification() finally: context.end_writing() switchboard.notify("redraw") else: reporter.report("Can't redo skeleton modification.")
def queryNode(self, menuitem, position): context = self.getSkeletonContext() if not context: return skeleton = context.getObject() if parallel_enable.enabled(): skeletonIPC.smenu.Skel_Info_Query(targetname="Node", position=position, skeleton=context.path()) if mpitools.Rank() > 0: return node = skeleton.nearestNode(position) if not node: reporter.report("Avoid clicking OUTSIDE of a skeleton.") else: self.finishQuery(context, node, "Node", position)
def newPixelGroup_parallel(menuitem, name, microstructure): if name and microstructure: mscontext = ooflib.common.microstructure.microStructures[microstructure] ms = mscontext.getObject() mscontext.begin_writing() try: if ms: (grp, newness) = ms.getGroup(name) finally: mscontext.end_writing() if newness: switchboard.notify("new pixel group", grp) return grp reporter.report("Failed to create group", name, "in microstructure", microstructure)
def parametrize(self, gtkobj=None): if self.current_property: reg = self.current_property[1] if reg is not None: # Get the associated LabelTree node. ltn = AllProperties.data.reverse_dict[reg] menuitem = ltn.menus[AllProperties.parametrizekey] # Copy parameters out of the PropertyRegistration, not # the menu item. params = [p for p in reg.params if p.name != 'name'] if parameterwidgets.getParameters( title='Parametrize '+self.current_property[0], *params): menuitem.callParamList(params) else: # should never happen reporter.report("Property is not parametrizable.") else: # should never happen reporter.report("No property selected.")
def show(self, messages=[]): debug.mainthreadTest() if self.currentPageName is None: self.installPage(pagenames[0]) self.pageChooser.set_state(self.currentPageName) self.historian.record(pagenames[0]) # don't use self.gtk.show_all(), since there may be page # components that shouldn't yet be shown. self.menubar.show_all() self.pageChooserFrame.show_all() self.pageframe.show() self.mainbox.show() for page in allPages.values(): page.show() self.gtk.show() for m in messages: reporter.report(m)
def _query_elem_group(menuitem, skeleton, group): skelc = whoville.getClass('Skeleton')[skeleton] members = skelc.elementgroups.get_group(group) area = 0.0 homog = 0.0 for element in members: area += element.area() homog += element.homogeneity(skelc.getObject().MS) if len(members): homog /= len(members) plural="s"*(len(members)!=1) strings = ["Group '%s'" % group, "%d element%s" % (len(members), "s"*(len(members)!=1)), "area=%s" % area, "average homogeneity=%g" % homog] matl = skelc.elementgroups.getMaterial(group) if matl is not None: strings.append("material=%s" % matl.name()) reporter.report(", ".join(strings))
def apply(self, oldskeleton, context): try: prog = progress.getProgress("Merge", progress.DEFINITE) skel = oldskeleton.properCopy(skeletonpath=context.path()) elements = self.targets(skel, context, copy=1) random.shuffle(elements) # A dict. keyed by element to prevent considering merging # element which does not exist any more. processed = {} # Merged triangles done = 0 # No. of triangles merged. savedE = 0.0 # Saved energy from the merge nel = len(elements) for i in range(nel): element = elements[i] if element not in processed and \ element.nnodes()==3 and element.active(skel): changes = self.mergeTriangles(element, skel, processed) bestchange = self.criterion(changes, skel) if bestchange is not None: done += 2 savedE += bestchange.deltaE(skel, self.criterion.alpha) bestchange.accept(skel) # Now that these two are merged, we need to indicate # that these are not to be looked at again. for e in bestchange.removed: processed[e] = 1 if prog.stopped(): return None else: prog.setFraction(1.0*(i+1)/nel) prog.setMessage("%d/%d" % (i+1, nel)) reporter.report("Merged %d triangles, saving energy %f" %\ (done, savedE)) skel.cleanUp() return skel finally: prog.finish()
def parallel_deactivateField(menuitem, subproblem, field): debug.fmsg() deactivation = False subpcontext = ooflib.engine.subproblemcontext.subproblems[subproblem] subpcontext.reserve() subpcontext.begin_writing() try: subp = subpcontext.getObject() if subp.is_active_field(field): subp.deactivate_field(field) deactivation = True else: reporter.report( "You must define and activate a Field before you can deactivate it.") finally: subpcontext.end_writing() subpcontext.cancel_reservation() if deactivation: subpcontext.autoenableBCs() switchboard.notify("field activated", subproblem, field.name(), 0) subpcontext.changed()
def parallel_activateField(menuitem, mesh, field): activated = False meshcontext = ooflib.engine.mesh.meshes[mesh] subpcontext = meshcontext.get_default_subproblem() subpcontext.reserve() subpcontext.begin_writing() try: subp = subpcontext.getObject() if subp.is_defined_field(field): subp.activate_field(field) activation = True else: reporter.report( "You must define a Field before you can activate it.") finally: subpcontext.end_writing() subpcontext.cancel_reservation() if activation: subpcontext.autoenableBCs() switchboard.notify("field activated", subpcontext.path(), field.name(), 1) subpcontext.changed()
def _apply(self, oldskeleton, context, prog): skel = oldskeleton.properCopy(skeletonpath=context.path()) elements = self.targets(skel, context, copy=1) random.shuffle(elements) # A dict. keyed by element to prevent considering swapping an # element which does not exist any more. processed = {} done = 0 # No. of elements swapped savedE = 0 # Saved energy from swapping nel = len(elements) for i in range(nel): element = elements[i] if element not in processed and element.active(skel): # Loop over the neighbors, generating candidates for # the result of the swap. changes = self.coreProcess(skel, processed, element) bestchange = self.criterion(changes, skel) if bestchange is not None: done += 2 savedE += bestchange.deltaE(skel, self.criterion.alpha) bestchange.accept(skel) # Newly created elements from swap should not be # looked at again, not to mention the original pair for elephant in bestchange.removed: processed[elephant] = 1 for elephant in bestchange.inserted: processed[elephant] = 1 if prog.stopped(): return None prog.setFraction(1.0*(i+1)/nel) prog.setMessage("%d/%d" % (i+1, nel)) reporter.report("Swapped %d elements, saving energy %g" % (done, savedE)) skel.cleanUp() return skel
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 apply(self, oldskeleton, context): # skel = oldskeleton.properCopy(skeletonpath=context.path()) # vigilante doesn't really need a properCopy! skel = oldskeleton.deputyCopy() skel.activate() suckers = skel.illegalElements() # illegalset holds the elements to be checked. It is # initially set to the illegal elements in the unmodified # skeleton, but new element can be added to it if moving one # node fixes two elements and breaks one. illegalset = set() for el in suckers: illegalset.add(el) random.shuffle(suckers) nguilty = len(suckers) # arbitrary number just to keep us out of an infinite loop max = 222 count = 0 while illegalset and count < max: count += 1 self.smoothIllegalElements(skel, illegalset, suckers) ndone = nguilty - len(illegalset) if illegalset: reporter.warn("Could not remove all illegal elements!") reporter.report("%d illegal element%s removed." % (ndone, "s" * (ndone != 1))) ## TODO: There are cases in which this doesn't work, that ## could be solved by moving a node *towards* the average ## position of its neighbors, but not all the way. Try moving ## problem nodes until their elements become barely legal. skel.cleanUp() skel.checkIllegality() return skel
def apply(self, oldskeleton, context): #skel = oldskeleton.properCopy(skeletonpath=context.path()) # vigilante doesn't really need a properCopy! skel = oldskeleton.deputyCopy() skel.activate() suckers = skel.illegalElements() # a list # illegalset holds the elements to be checked. It is # initially set to the illegal elements in the unmodified # skeleton, but new elements can be added to it if moving one # node fixes two elements and breaks one. # illegalset = set() illegalset = {el for el in suckers} random.shuffle(suckers) nguilty = len(suckers) # arbitrary number just to keep us out of an infinite loop max = 222 count = 0 while illegalset and count < max: count += 1 self.smoothIllegalElements(skel, illegalset, suckers) ndone = nguilty - len(illegalset) if illegalset: reporter.warn("Could not remove all illegal elements!") reporter.report("%d illegal element%s removed." % (ndone, "s" * (ndone != 1))) ## TODO: There are cases in which this doesn't work, that ## could be solved by moving a node *towards* the average ## position of its neighbors, but not all the way. Try moving ## problem nodes until their elements become barely legal. skel.cleanUp() skel.checkIllegality() return skel
def _activateField(menuitem, subproblem, field): activation = False if parallel_enable.enabled(): ipcsubpmenu.Field.Activate(subproblem=subproblem,field=field) else: subpcontext = ooflib.engine.subproblemcontext.subproblems[subproblem] subpcontext.reserve() subpcontext.begin_writing() try: subp = subpcontext.getObject() if subp.is_defined_field(field): subp.activate_field(field) activation = True else: reporter.report( "You must define a Field before you can activate it.") finally: subpcontext.end_writing() subpcontext.cancel_reservation() if activation: subpcontext.autoenableBCs() switchboard.notify("field activated", subproblem, field.name(), 1) subpcontext.changed("Field activated.")
def _activateField(menuitem, subproblem, field): activation = False if parallel_enable.enabled(): ipcsubpmenu.Field.Activate(subproblem=subproblem, field=field) else: subpcontext = ooflib.engine.subproblemcontext.subproblems[subproblem] subpcontext.reserve() subpcontext.begin_writing() try: subp = subpcontext.getObject() if subp.is_defined_field(field): subp.activate_field(field) activation = True else: reporter.report( "You must define a Field before you can activate it.") finally: subpcontext.end_writing() subpcontext.cancel_reservation() if activation: subpcontext.autoenableBCs() switchboard.notify("field activated", subproblem, field.name(), 1) subpcontext.changed("Field activated.")
def parallel_deactivateField(menuitem, mesh, field): deactivated = False meshcontext = ooflib.engine.mesh.meshes[mesh] subpcontext = meshcontext.get_default_subproblem() subpcontext.reserve() subpcontext.begin_writing() try: subp = subpcontext.getObject() if subp.is_active_field(field): subp.deactivate_field(field) deactivation = True else: reporter.report( "You must define and activate a Field before you can deactivate it." ) finally: subpcontext.end_writing() subpcontext.cancel_reservation() if deactivation: subpcontext.autoenableBCs() switchboard.notify("field activated", subpcontext.path(), field.name(), 0) subpcontext.changed()
def _modify(menuitem, skeleton, modifier): # context is actually the Who of the skeleton context = skeletoncontext.skeletonContexts[skeleton] context.reserve() start_nnodes = context.getObject().nnodes() start_nelems = context.getObject().nelements() try: context.begin_writing() try: skel = modifier.apply(context.getObject(), context) # skel is None whenever the modifier fails # or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") return context.pushModification(skel) # parallelized skel.needsHash() finally: context.end_writing() # If the skeleton is modified in postProcess, use # begin/end_writing inside the function call to guarantee # that no dead-locking occurs because of possible switchboard # calls to READ or REDRAW that may make use of # begin/end_reading(). See anneal.py for an example. modifier.postProcess(context) # parallelize for each modifier skel.updateGeometry() # force recalculation of homogeneity, etc end_nnodes = context.getObject().nnodes() end_nelems = context.getObject().nelements() if end_nnodes > start_nnodes: reporter.report(end_nnodes - start_nnodes, "more nodes.") elif end_nnodes < start_nnodes: reporter.report(start_nnodes - end_nnodes, "fewer nodes.") if end_nelems > start_nelems: reporter.report(end_nelems - start_nelems, "more elements.") elif end_nelems < start_nelems: reporter.report(start_nelems - end_nelems, "fewer elements.") finally: context.cancel_reservation() switchboard.notify('redraw') switchboard.notify('Skeleton modified', skeleton, modifier)
def _modify(menuitem, skeleton, modifier): # context is actually the Who of the skeleton context = skeletoncontext.skeletonContexts[skeleton] context.reserve() start_nnodes = context.getObject().nnodes() start_nelems = context.getObject().nelements() try: context.begin_writing() try: skel = modifier.apply(context.getObject(), context) # skel is None whenever the modifier fails # or is interrupted from finishing its task if skel is None: reporter.warn("Modify Process Interrupted") return context.pushModification(skel) # parallelized skel.needsHash() finally: context.end_writing() # If the skeleton is modified in postProcess, use # begin/end_writing inside the function call to guarantee # that no dead-locking occurs because of possible switchboard # calls to READ or REDRAW that may make use of # begin/end_reading(). See anneal.py for an example. modifier.postProcess(context) # parallelize for each modifier end_nnodes = context.getObject().nnodes() end_nelems = context.getObject().nelements() if end_nnodes > start_nnodes: reporter.report(end_nnodes - start_nnodes, "more nodes.") elif end_nnodes < start_nnodes: reporter.report(start_nnodes - end_nnodes, "fewer nodes.") if end_nelems > start_nelems: reporter.report(end_nelems - start_nelems, "more elements.") elif end_nelems < start_nelems: reporter.report(start_nelems - end_nelems, "fewer elements.") finally: context.cancel_reservation() switchboard.notify("redraw") switchboard.notify("Skeleton modified", skeleton, modifier)
def showLayer_gui(self, menuitem): # OOFMenu GUI callback if self.selectedLayer is None: \ reporter.report('No layer is selected!') else: self.menu.Layer.Show(n=self.layerID(self.selectedLayer))
def _postProcess(self, context): if _rank == 0: pBar = progressbar.getProgress() pBar.set_message(self.header) skeleton = context.getObject() before = mpitools.Allreduce_DoubleSum( skeleton.energyTotal(self.criterion.alpha)) if _rank == 0: if self.pbar_type == "continuous": n = self.iteration.iterations self.count = 0 while self.iteration.goodToGo(): self.count += 1 # the context to acquires the writing persmissions # inside coreProcess. mpitools.Barrier() self.coreProcess_parallel(context) self.updateIteration_parallel() if _rank == 0: if pBar.query_stop(): pBar.set_failure() pBar.set_message("Failed") # Sending a break signal mpitools.Isend_Bool(False, range(1, _size)) break else: if self.pbar_type == "continuous": pBar.set_progress(1.0 * self.count / n) # does this ever get displayed? pBar.set_message("%s%d/%d" % (self.header, self.count, n)) # Sending a continue signal mpitools.Isend_Bool(True, range(1, _size)) else: if not mpitools.Recv_Bool(0): break switchboard.notify("skeleton nodes moved", context) if _rank == 0: if pBar.query_stop(): # or pBar.get_success() <0: pBar.set_failure() pBar.set_message("Failed") mpitools.Isend_Bool(False, range(1, _size)) return else: mpitools.Isend_Bool(True, range(1, _size)) else: if not mpitools.Recv_Bool(0): return mpitools.Barrier() after = mpitools.Allreduce_DoubleSum( skeleton.energyTotal(self.criterion.alpha)) # Reporting to the message window if _rank == 0: if before: rate = 100.0 * (before - after) / before else: rate = 0.0 diffE = after - before reporter.report("%s deltaE = %10.4e (%6.3f%%)" % (self.outro, diffE, rate))
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)
def reportNothing(self, count): reporter.report("Iteration %d: No attempts made, no nodes moved!" % count)
def sanity_check(self): # Check basic skeleton connections: the leg bone connected to # the knee bone, etc. diagnosis = self.getObject().sanityCheck() # returns string sane = not diagnosis if not sane: reporter.report(diagnosis) ## Old way, doing more of the check in python. # sane = self.getObject().sanity_check_old() # in cskeleton2.spy # Check that the predefined face boundaries have the right # area and the edge boundaries have the right length. x, y, z = self.getParent().getObject().size() areas = { "Ymax": x * z, "Ymin": x * z, "Zmax": x * y, "Zmin": x * y, "Xmin": y * z, "Xmax": y * z } for bdyname in areas: bdy = self.getBoundary(bdyname) bdyarea = bdy.current_boundary().area() if abs(bdyarea - areas[bdyname]) / areas[bdyname] > 1.e-6: reporter.report( "Area mismatch for boundary '%s'. Expected %g, got %g." % (bdyname, areas[bdyname], bdyarea)) sane = False for bdyname in ( "XmaxYmax", "XmaxYmin", "XmaxZmax", "XmaxZmin", "XminYmax", "XminYmin", "XminZmax", "XminZmin", "YmaxZmax", "YmaxZmin", "YminZmax", "YminZmin", ): if "Z" not in bdyname: length = z elif "X" not in bdyname: length = x elif "Y" not in bdyname: length = y bdy = self.getBoundary(bdyname) bdylength = bdy.current_boundary().length() if abs(bdylength - length) / length > 1.e-6: reporter.report( "Length mismatch for boundary '%s'. Expected %g, got %g." % (bdyname, length, bdylength)) sane = False if sane: reporter.report("*** Skeleton Sanity Check passed. ***") else: reporter.report("*** Skeleton sanity check failed. ***") return sane
def postProcess(self, context): ## This function first creates a mesh with custom-made properties, ## then assigns "temporary" properties to pixels ## and specifies BCs and equations. ## Next, iterates for the solution using the specified solver, ## accepts all node moves and redraws skeleton. ## It repeats these steps until iteration criteria has been met. ## Finally, the (temporary) mesh and the rest of the temporary ## objects are cleaned up. ## create progress bar prog = progress.getProgress("Relax", progress.DEFINITE) ## get skeleton and calculate energy skeleton = context.getObject() before = skeleton.energyTotal(self.alpha) self.count = 0 try: while self.goodToGo(skeleton) and not prog.stopped(): # TODO: Why do we create a new mesh for each # iteration? Can't we update the positions of the # nodes and re-use the mesh? ## femesh is created and properties are assigned mesh = self.create_mesh(context) # mesh context object ## define displacement field self.define_fields(mesh) ## activate the mechanical balance equation self.activate_equations(mesh) mesh.changed("Relaxing") ## constrain the nodes on the boundaries to only slide ## along the edge self.set_boundary_conditions(mesh) # solve linear system. self.coreProcess(mesh, mesh.get_default_subproblem()) if prog.stopped(): break # Update positions of nodes in the Skeleton. If this # creates illegal elements, the iteration will stop. # Illegality is checked by goodToGo(). context.begin_writing() try: self.update_node_positions(skeleton, mesh) finally: context.end_writing() mesh.lockAndDelete() switchboard.notify("skeleton nodes moved", context) switchboard.notify("redraw") self.updateIteration() ## update iteration manager machinery prog.setFraction(1.0*self.count/self.iterations) prog.setMessage("%d/%d iterations" % (self.count, self.iterations)) prog.finish() ## calculate total energy improvement, if any. after = skeleton.energyTotal(self.alpha) if before: rate = 100.0*(before-after)/before else: rate = 0.0 diffE = after - before reporter.report("Relaxation complete: deltaE = %10.4e (%6.3f%%)" % (diffE, rate)) finally: if config.dimension() == 2: del self.topBoundaryCondition del self.leftBoundaryCondition del self.bottomBoundaryCondition del self.rightBoundaryCondition materialmanager.materialmanager.delete_prop(self.stiffness.name()) materialmanager.materialmanager.delete_prop(self.skelRelRate.name()) propertyregistration.AllProperties.delete(self.stiffness.name()) propertyregistration.AllProperties.delete(self.skelRelRate.name()) materialmanager.materialmanager.delete_secret(self.materialName)
def front_end(no_interp=None): global startupfiles global gtk_options global randomseed ## From here on is the serial version. # VTK is started even in text mode to allow off-screen rendering, # interpretation of scripted mouse clicks, etc. from ooflib.SWIG.common.IO import vtkutils vtkutils.initialize_vtk() # When loading modules, use utils.OOFexec so that names are # imported into the oof environment, not the oof.run environment. if not (runtimeflags.text_mode or config.no_gui()): # The gtk import dance described below doesn't work when the program # has been packaged by cx_freeze. # TODO 3.1: is checking frozen required for gtk2? frozen = hasattr(sys, 'frozen') if not frozen: import pygtk pygtk.require("2.0") import gtk msg = gtk.check_version(2, 6, 0) if msg: print msg sys.exit(3) # The GUI initialization modules must be called before any # calls to mainthread.run(), because mainthread.run() is # redefined when mainthreadGUI.py is loaded (by # common/IO/GUI/initialize.py) import ooflib.common.IO.GUI.initialize import ooflib.engine.IO.GUI.initialize import ooflib.image.IO.GUI.initialize import ooflib.orientationmap.GUI.initialize import ooflib.tutorials.initialize if replaydelay is not None: from ooflib.common.IO.GUI import gtklogger gtklogger.set_delay(int(replaydelay)) else: # text mode # Load non-gui initialization modules. import ooflib.common.initialize import ooflib.engine.initialize import ooflib.image.initialize import ooflib.orientationmap.initialize import ooflib.EXTENSIONS.initialize # The random number generator must be seeded *after* the gui has # been started, because libfontconfig is using random numbers. We # want the numbers to be the same in text and gui modes, so that # the test suite gets predictable answers. if debug.debug() or randomseed is not None: if randomseed is None: randomseed = 17 random.seed(randomseed) crandom.rndmseed(randomseed) for module in startupimports: exec('import ' + module) if not (runtimeflags.text_mode or config.no_gui()): reporter.report("Welcome to %s version %s!" % (program_name.upper(), oofversion.version)) if not no_interp: # Default case, run on local thread. from ooflib.common.IO.GUI import oofGUI oofGUI.start(files=startupfiles) # This call never returns. print "This line should never be printed. rank =", _rank else: # TODO 3.1: The gui and no_interp combination is # thinkable, but has problems. You have to run the GUI on # a separate thread, but then exceptions show up as modal # dialog boxes in the GUI, and block the menu items which # raised them, causing a loss of control. Also, the # current threading scheme requires that all gtk activity # happen on the main thread. print "GUI no_interp mode not implemented. Sorry." raise NotImplementedError("GUI no_interp mode") else: # text mode from ooflib.common import quit # Allow exceptions to propagate to the user if in batch mode # or not running an interpreter. Otherwise, exceptions are # caught and reported to the user, but the program keeps # running. if runtimeflags.batch_mode or no_interp: from ooflib.common import worker worker.propagate_exceptions = True threadstate.textMode() lock.disableLocks() # disables Locks, but not SLocks if startupfiles: loadStartUpFiles(startupfiles) if runtimeflags.batch_mode: # Batch mode runs startupfiles and quits immediately. quit.set_quiet() quit.quit() if sys.exc_info()[0] is not None: sys.exit(1) sys.exit(0) # Format the banner for the current line width. if not quit.quiet(): width = utils.screenwidth() wiggles = "//=*=\\\\=*=" nwiggles = (width - 2) / len(wiggles) welcome = "Welcome to %s version %s!" % (program_name.upper(), oofversion.version) nblanks = (width - len(welcome)) / 2 banner = ( wiggles * nwiggles + "//\n\n" + " " * nblanks + welcome + "\n" + string.join( utils.format(banner1 % {'name': program_name.upper()}, width), "\n") + "\n\n" + wiggles * nwiggles + "//\n" + string.join( utils.format(banner2 % {'name': program_name.upper()}, width), "\n")) else: banner = "" if not no_interp: import code # Try to import readline, which allows command line # editing in text mode. If it's not there, don't worry -- # it's possible to live without it. Some systems don't # seem to have it, although it's supposedly available on # all Unix systems. try: import readline except ImportError: pass # Start up the interpreter in the __main__ namespace. # This is the namespace that utils.OOFeval and OOFdefine # use. It's not necessarily *this* namespace. interp = code.InteractiveConsole(sys.modules['__main__'].__dict__) interp.interact(banner)
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)
def canvas_infoCB(self, *args): debug.mainthreadTest() # Visible canvas size in pixel units xmax = self.gfxwindow().oofcanvas.get_width_in_pixels()-1 ymax = self.gfxwindow().oofcanvas.get_height_in_pixels()-1 # Visible MS in physical units ll = self.get_proper_world_coord(0, ymax) ur = self.get_proper_world_coord(xmax, 0) reporter.report("### Canvas Information ###") reporter.report("Width (pixels) : ", xmax) reporter.report("Height (pixels) : ", ymax) reporter.report("Lower-left corner : ", ll) reporter.report("Upper-right corner: ", ur) reporter.report("H-scroll position : ", self.gfxwindow().hScrollPosition()) reporter.report("V-scroll position : ", self.gfxwindow().vScrollPosition()) reporter.report("Pixels per unit : ", self.gfxwindow().oofcanvas.get_pixels_per_unit()) reporter.report("Canvas allocation : ", self.gfxwindow().oofcanvas.get_allocation()) reporter.report("Scroll region : ", self.gfxwindow().oofcanvas.get_scrollregion())
# end if t1 > starttime lasttime = t1 # end loop over output times finally: meshctxt.solver_postcompute() meshctxt.pause_writing() meshctxt.outputSchedule.finish() meshctxt.resume_writing() prog.finish() for subp in subprobctxts: if len(subprobctxts) == 1: head = "--" else: head = "-- Subproblem %s --" % subp.name() subp.solverStats.report(head, reporter.fileobj) reporter.report("Matrices were built", subp.newMatrixCount, "time%s." % ("s" * (subp.newMatrixCount != 1))) #=--=##=--=##=--=##=--=##=--=##=--=##=--=##=--=##=--=##=--=##=--=##=--=# # Solve for the static fields in each subproblem. If the subproblem's # stepper is second order, *also* solve for the first order fields # (those with 1st time derivatives but not second). Do this # self-consistently if there is more than one subproblem. # Static field initialization works via a multiple dispatch # scheme,like this: # The initializeStaticFields function in this file calls each # SubProblem's initializeStaticFields method, which uses its # computeStaticFields method to compute the field values, and then
def front_end(no_interp=None): global startupfiles global gtk_options global randomseed ## From here on is the serial version. # When loading modules, use utils.OOFexec so that names are # imported into the oof environment, not the oof.run environment. if not (runtimeflags.text_mode or config.no_gui()): # The gtk import dance described below doesn't work when the program # has been packaged by cx_freeze. # TODO LATER: is checking frozen required for gtk2? frozen = hasattr(sys, 'frozen') if not frozen: import pygtk pygtk.require("2.0") import gtk msg = gtk.check_version(2, 6, 0) if msg: print msg sys.exit(3) import ooflib.common.IO.GUI.initialize # temporarily disable the engine, tutorials, orientationmap # for 3D development import ooflib.engine.IO.GUI.initialize import ooflib.image.IO.GUI.initialize if config.dimension() == 2: import ooflib.orientationmap.GUI.initialize import ooflib.tutorials.initialize if replaydelay is not None: from ooflib.common.IO.GUI import gtklogger gtklogger.set_delay(int(replaydelay)) else: # text mode import ooflib.common.initialize import ooflib.engine.initialize import ooflib.image.initialize if config.dimension() == 2: import ooflib.orientationmap.initialize import ooflib.EXTENSIONS.initialize # The random number generator must be seeded *after* the gui has # been started, because libfontconfig is using random numbers. We # want the numbers to be the same in text and gui modes, so that # the test suite gets predictable answers. if debug.debug() or randomseed is not None: if randomseed is None: randomseed = 17 random.seed(randomseed) crandom.rndmseed(randomseed) for module in startupimports: exec('import ' + module) if not (runtimeflags.text_mode or config.no_gui()): reporter.report("Welcome to OOF2 version %s!" % oofversion.version) ## The files to be loaded must be loaded *after* the GUI ## starts, but this routine doesn't regain control once it ## starts the GUI. So we have to install the file loader ## (loadStartUpFiles) as an idle callback, which will run on ## the main thread. loadStartUpFiles just issues menu ## commands that load the files, and if it runs on the main ## thread those menu commands will run by Workers on ## subthreads, and won't be run sequentially. So, instead of ## installing loadStartUpFiles as an idle callback, we install ## subthread.execute and have it call loadStartUpFiles, since ## workers on subthreads don't create additional subthreads to ## run their menu items. if startupfiles: # startupfiles won't be run until after the GUI starts. mainthread.run(subthread.execute_immortal, (loadStartUpFiles, (startupfiles, ))) if not no_interp: # Default case, run on local thread. from ooflib.common.IO.GUI import oofGUI oofGUI.start() # This call never returns. print "This line should never be printed. rank =", _rank else: # TODO LATER: The gui and no_interp combination is # thinkable, but has problems. You have to run the GUI on # a separate thread, but then exceptions show up as modal # dialog boxes in the GUI, and block the menu items which # raised them, causing a loss of control. Also, the # current threading scheme requires that all gtk activity # happen on the main thread. print "GUI no_interp mode not implemented. Sorry." raise NotImplementedError("GUI no_interp mode") else: # text mode from ooflib.common import quit # Allow exceptions to propagate to the user if in batch mode # or not running an interpreter. Otherwise, exceptions are # caught and reported to the user, but the program keeps # running. if runtimeflags.batch_mode or no_interp: from ooflib.common import worker worker.propagate_exceptions = True if startupfiles: loadStartUpFiles(startupfiles) if runtimeflags.batch_mode: # Batch mode runs startupfiles and quits immediately. quit.set_quiet() quit.quit() if sys.exc_info()[0] is not None: sys.exit(1) sys.exit(0) # Format the banner for the current line width. if not quit.quiet(): width = utils.screenwidth() wiggles = "//=*=\\\\=*=" nwiggles = (width - 2) / len(wiggles) welcome = "Welcome to OOF2 version %s!" % oofversion.version nblanks = (width - len(welcome)) / 2 banner = wiggles*nwiggles + "//\n\n" \ + " "*nblanks + welcome + "\n" + \ string.join(utils.format(banner1, width),"\n") + \ "\n\n" + wiggles*nwiggles + "//\n" + \ string.join(utils.format(banner2, width), "\n") else: banner = "" if not no_interp: import code # Try to import readline, which allows command line # editing in text mode. If it's not there, don't worry -- # it's possible to live without it. Some systems don't # seem to have it, although it's supposedly available on # all Unix systems. try: import readline except ImportError: pass # Start up the interpreter in the __main__ namespace. # This is the namespace that utils.OOFeval and OOFdefine # use. It's not necessarily *this* namespace. interp = code.InteractiveConsole(sys.modules['__main__'].__dict__) interp.interact(banner)
def camera_infoCB(self, *args): debug.mainthreadTest() camera = self.gfxwindow().oofcanvas.getCamera() reporter.report(camera)
def hideLayer_gui(self, menuitem): # OOFMenu GUI callback. if self.selectedLayer is None: reporter.report('No layer is selected!') else: self.menu.Layer.Hide(n=self.layerID(self.selectedLayer))
def _query_sgmt_group(menuitem, skeleton, group): skelc = whoville.getClass('Skeleton')[skeleton] members = skelc.segmentgroups.get_group(group) plural="s"*(len(members)!=1) reporter.report(">>> ", len(members), " segment"+plural )
def proffudge(menuitem, iterations): from ooflib.common.EXTRA import profiler fudge = profiler.calibrate_profiler(iterations) helpmenu.Debug.Profile.Start.get_arg('fudge').value = fudge reporter.report('fudge =', fudge)
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 canvas_infoCB(self, *args): debug.mainthreadTest() # Visible canvas size in pixel units xmax = self.gfxwindow().oofcanvas.get_width_in_pixels() - 1 ymax = self.gfxwindow().oofcanvas.get_height_in_pixels() - 1 # Visible MS in physical units ll = self.get_proper_world_coord(0, ymax) ur = self.get_proper_world_coord(xmax, 0) reporter.report("### Canvas Information ###") reporter.report("Width (pixels) : ", xmax) reporter.report("Height (pixels) : ", ymax) reporter.report("Lower-left corner : ", ll) reporter.report("Upper-right corner: ", ur) reporter.report("H-scroll position : ", self.gfxwindow().hScrollPosition()) reporter.report("V-scroll position : ", self.gfxwindow().vScrollPosition()) reporter.report("Pixels per unit : ", self.gfxwindow().oofcanvas.get_pixels_per_unit()) reporter.report("Canvas allocation : ", self.gfxwindow().oofcanvas.get_allocation()) reporter.report("Scroll region : ", self.gfxwindow().oofcanvas.get_scrollregion())