def solveMatrix(self, matrix, rhs, solution): succ = self.solver.solve(matrix, rhs, solution) if succ != cmatrixmethods.SUCCESS: if succ == cmatrixmethods.NUMERICAL: raise ooferror2.ErrPyProgrammingError( "The provided data did not satisfy the prerequisites.") elif succ == cmatrixmethods.INVALID_INPUT: raise ooferror2.ErrPyProgrammingError( "The inputs are invalid, or the algorithm has been improperly called." ) return (1, 0)
def solveMatrix(self, matrix, rhs, solution): if _check_symmetry: import sys if (matrix.nrows() != matrix.ncols() or not matrix.is_symmetric(1.e-12)): # can be very slow raise ooferror2.ErrPyProgrammingError( "%dx%d CG matrix is not symmetric!" % (matrix.nrows(), matrix.ncols())) succ = self.solver.solve(matrix, rhs, solution) if succ != cmatrixmethods.SUCCESS: if succ == cmatrixmethods.NOCONVERG: raise ooferror2.ErrPyProgrammingError( "Iterative procedure did not converge") return self.solver.iterations(), self.solver.error()
def solveMatrix(self, matrix, rhs, solution): succ = self.solver.solve(matrix, rhs, solution) if succ != cmatrixmethods.SUCCESS: if succ == cmatrixmethods.NOCONVERG: raise ooferror2.ErrPyProgrammingError( "Iterative procedure did not converge") return self.solver.iterations(), self.solver.error()
def solveMatrix(self, matrix, rhs, solution): if _check_symmetry: import sys if (matrix.nrows()!=matrix.ncols() or not matrix.is_symmetric(1.e-12)): # can be very slow raise ooferror2.ErrPyProgrammingError( "%dx%d CG matrix is not symmetric!" % (matrix.nrows(), matrix.ncols())) # debug.fmsg("matrix=\n%s" % matrix) # debug.fmsg("rhs=", rhs) pc = self.preconditioner.create_preconditioner(matrix) return cmatrixmethods.solveCG( matrix, rhs, pc, self.max_iterations, self.tolerance, solution)
def retrieve_analysis(self, name): # switchboard "retrieve analysis" analysis = namedanalysis.getNamedBulkAnalysis(name) self.suppressRetrievalLoop = True try: self.op_obj.set(analysis.operation, interactive=False) if analysis.data.isScalarOutput(): self.scalar_output_button.set_active(1) # sets output_obj elif analysis.data.isAggregateOutput(): self.aggregate_output_button.set_active(1) # sets output_obj else: raise ooferror2.ErrPyProgrammingError("Unclassifiable output?") self.output_obj.set_value(analysis.data) self.domain_obj.set(analysis.domain, interactive=False) self.sample_obj.set(analysis.sampling, interactive=False) finally: self.suppressRetrievalLoop = False gtklogger.checkpoint("retrieved named analysis") # If this call was triggered by the namedAnalysisChooser, # setting the chooser's value is redundant but harmless. If # the call was triggered by a script, setting the chooser's # value is required. self.setNamedAnalysisChooser()
def realelement_shares(self, skeleton, mesh, index, fe_node, curnodeindex, elemdict, materialfunc): # Be safe with indices. if self.meshindex is None: # Zero is nontrivial index. self.meshindex = index else: if index != self.meshindex: raise ooferror2.ErrPyProgrammingError( "Index mismatch in element construction.") nnewnodes = 0 ncn = len(self.nodes) # Corner nodes. # elemdict is a dictionary of MasterElements, keyed by number # of sides. elementtype = elemdict[self.nnodes()] nodes = [] # real nodes for this element for i in range(len(self.nodes)): # i.e. for each edge... c0 = self.nodes[i] nodes.append(fe_node[c0]) # Corner nodes already exist. c1 = self.nodes[(i+1)%ncn] cset = skeletonnode.canonical_order(c0, c1) # Look up this edge in the dictionary. If it's there, # then nodes have been created on the edge already, and we # should reuse them. try: xtranodes = mesh.getEdgeNodes(cset) # The nodes were created by the neighboring element. # Since elements traverse their edges counterclockwise # when creating nodes, the preexisting nodes are in # the wrong order for the current element. xtranodes.reverse() except KeyError: newindexinc=0 newindex=0 protocount=0 protodiclength=len(elementtype.protodic[i]) if c0.index<c1.index: newindexinc=1 newindex=skeleton.maxnnodes+100*c0.index else: # Do this to distinguish the protonode on either # side of a corner node that has a smaller index # than either corner nodes of the collinear # segments extending from that corner node. newindexinc=-1 newindex=skeleton.maxnnodes+100*c1.index+50+protodiclength-1 # The edge wasn't in the dictionary. It's a new edge. xtranodes = [] # Loop over all protonodes on the current # edge of the new element for newproto in elementtype.protodic[i]: masterxy = primitives.Point(newproto.mastercoord()[0], newproto.mastercoord()[1]) realxy = self.frommaster(masterxy, 0) newnode = _makenewnode_shares( mesh, newproto, coord.Coord(realxy.x, realxy.y), c0,c1,newindex,protocount, protodiclength,skeleton.maxnnodes) newindex+=newindexinc protocount+=1 nnewnodes = nnewnodes + 1 xtranodes.append(newnode) mesh.addEdgeNodes(cset, xtranodes) #Should this be 'join'ed instead, for speed? nodes = nodes + xtranodes # Interior nodes at the end. for newproto in elementtype.protodic['interior']: masterxy = primitives.Point(newproto.mastercoord()[0], newproto.mastercoord()[1]) realxy = self.frommaster(masterxy, 0) newnode = _makenewnode(mesh, newproto, coord.Coord(realxy.x, realxy.y)) nnewnodes = nnewnodes + 1 nodes.append(newnode) mesh.addInternalNodes(self, newnode) # Having constructed the list of nodes, call the real # element's constructor. realel = elementtype.build(self, materialfunc(self, skeleton), nodes) # Long-lost cousin of Kal-El and Jor-El. mesh.addElement(realel) # Add to mesh. # Tell the element about its exterior edges. for edge in self.exterior_edges: realel.set_exterior(fe_node[edge[0]], fe_node[edge[1]]) return nnewnodes
def realelement(self, skeletoncontext, mesh, index, fe_node, seg_dict, elemdict, materialfunc): # Create a real element corresponding to this skeleton # element. The elemdict argument is a dictionary (keyed by the # number of sides of the element) of MasterElement objects, # which contain the information needed to construct the real # elements. "index" is the SkeletonElement's position in the # Skeleton's list, and "fe_node" is a dictionary of real nodes # in the FEMesh, indexed by their corresponding SkeletonNode # objects. The lists give the nodes in the order in which # they were added to the element. # Be safe with indices. if self.meshindex is None: # Zero is nontrivial index. self.meshindex = index else: if index != self.meshindex: raise ooferror2.ErrPyProgrammingError( "Index mismatch in element construction.") nnewnodes = 0 ncn = len(self.nodes) # Corner nodes. # elemdict is a dictionary of MasterElements, keyed by number # of sides. elementtype = elemdict[self.nnodes()] nodes = [] # real nodes for this element for i in range(len(self.nodes)): # i.e. for each edge... c0 = self.nodes[i] nodes.append(fe_node[c0]) # Corner nodes already exist. c1 = self.nodes[(i+1)%ncn] cset = skeletonnode.canonical_order(c0, c1) # Look up this edge in the dictionary. If it's there, # then nodes have been created on the edge already, and we # should reuse them. try: xtranodes = mesh.getEdgeNodes(cset) # The nodes were created by the neighboring element. # Since elements traverse their edges counterclockwise # when creating nodes, the preexisting nodes are in # the wrong order for the current element. xtranodes.reverse() except KeyError: # The edge wasn't in the dictionary. It's a new edge. xtranodes = [] # Loop over all protonodes on the current # edge of the new element for newproto in elementtype.protodic[i]: masterxy = primitives.Point(newproto.mastercoord()[0], newproto.mastercoord()[1]) realxy = self.frommaster(masterxy, 0) newnode = _makenewnode(mesh, newproto, coord.Coord(realxy.x, realxy.y)) nnewnodes = nnewnodes + 1 xtranodes.append(newnode) #Interface branch try: #If the segment represented by cset is a member of an #interface, then new edge nodes (xtranodes) will #not be shared by another element. test=seg_dict[cset] except KeyError: mesh.addEdgeNodes(cset, xtranodes) nodes = nodes + xtranodes # Interior nodes at the end. for newproto in elementtype.protodic['interior']: masterxy = primitives.Point(newproto.mastercoord()[0], newproto.mastercoord()[1]) realxy = self.frommaster(masterxy, 0) newnode = _makenewnode(mesh, newproto, coord.Coord(realxy.x, realxy.y)) nnewnodes = nnewnodes + 1 nodes.append(newnode) mesh.addInternalNodes(self, newnode) # Having constructed the list of nodes, call the real # element's constructor. materialfunc returns the element's # material. In normal operation, materialfunc is # SkeletonElement.realmaterial. realel = elementtype.build(self, materialfunc(self, skeletoncontext), nodes) mesh.addElement(realel) # Add to mesh. # Tell the element about its exterior edges. for edge in self.exterior_edges: realel.set_exterior(fe_node[edge[0]], fe_node[edge[1]]) return nnewnodes
def new_child(self,index): raise ooferror2.ErrPyProgrammingError( "Attempt to clone element parent class.")
def refinement(self, skeleton, newSkeleton, context, prog): maxdelta = max(newSkeleton.MS.sizeOfPixels()) maxdelta2 = (self.min_distance * maxdelta)**2 markedEdges = SnapEdgeMarkings(newSkeleton, skeleton, maxdelta2) self.newEdgeNodes = {} # allows sharing of new edge nodes # Primary marking (bisections only!) self.targets(skeleton, context, 1, markedEdges, self.criterion) # Additional marking #self.degree.markExtras(skeleton, markedEdges) # Refine elements and segments segmentdict = {} # which segments have been handled n = len(skeleton.elements) elements = skeleton.elements for ii in range(n): #print ii, n oldElement = elements[ii] oldnnodes = oldElement.nnodes() # For 2D: # Get list of number of subdivisions on each edge ("marks") (numinitmarks,marks,cats,edgenodes) = \ markedEdges.getSnapMarks(oldElement) # Find the canonical order for the marks. (The order is # ambiguous due to the arbitrary choice of the starting # edge. Finding the canonical order allows the refinement # rule to be found in the rule table.) rotation is the # offset into the elements node list required to match the # refinement rule to the element's marked edges. # signature is the canonical ordering of the marks. #rotation, signature = findSignature(marks) signature_info = findSignature(marks) if config.dimension() == 2: signature = signature_info[1] elif config.dimension() == 3: signature = signature_info #print numinitmarks, signature # Create new elements # TODO: It's annoying that we have a separate # "unrefinedelement" method. It would be cleaner if this # were called automatically using the signature. We # should do this when we move things to C. if numinitmarks > 0: newElements = self.rules[signature].apply( oldElement, signature_info, cats, edgenodes, newSkeleton, maxdelta2) if debug.debug(): for el in newElements: if el.illegal(): debug.fmsg("oldElement=", oldElement) debug.fmsg( [n.position() for n in oldElement.nodes]) debug.fmsg("newElement=", el) debug.fmsg([n.position() for n in el.nodes]) debug.fmsg("signature=", signature) debug.fmsg("rule=", self.rules[signature]) raise ooferror2.ErrPyProgrammingError( "Illegal element created by SnapRefine") else: newElements = snaprefinemethod.unrefinedelement( oldElement, signature_info, newSkeleton) # If the old element's homogeneity is 1, it's safe to say that # new elements' homogeneities are 1. if oldElement.homogeneity(skeleton.MS, False) == 1.0: for el in newElements: el.copyHomogeneity(oldElement) # The calls to Skeleton.newElement() made by the # refinement rules have created new SkeletonSegments in # newSkeleton, but have not set the parentage of those # segments. We have to fix that here. for newElement in newElements: for segment in newElement.getSegments(newSkeleton): # Only look at each segment once. if segment not in segmentdict: segmentdict[segment] = 1 pseg = findParentSegment(skeleton, newElement, segment, edgenodes) if pseg: pseg.add_child(segment) segment.add_parent(pseg) if prog.stopped(): return None prog.setFraction(1.0 * (ii + 1) / n) prog.setMessage("%d/%d elements" % (ii + 1, n)) newSkeleton.cleanUp() #print "end of refinement" return newSkeleton