def _ops_callback(menuitem, mesh, time, data, domain, sampling, destination, **kwargs): if parallel_enable.enabled(): menuitem.ipcmenu(mesh=mesh, data=data, domain=domain, sampling=sampling, destination=destination) return operation = menuitem.data() # data is a DataOperation Registration direct = getattr(menuitem.data, 'direct', False) if not (direct or data.allowsArithmetic()): raise ooferror2.ErrUserError("Output '" + data.name + "' can only be used with Direct output") # Set the mesh in the domain, then run the operation. domain.set_mesh(mesh) domain.read_lock() # acquires Mesh's read lock. try: # The domain has all the mesh data, so we don't have to pass that data. meshctxt = ooflib.engine.mesh.meshes[mesh] meshctxt.precompute_all_subproblems() t = meshctxt.getTime(time) # converts '<latest>' to time, if needed meshctxt.restoreCachedData(t) destination.open() try: if sampling.make_samples(domain): printHeaders(destination, operation, data, domain, sampling) # Do the calculation operation(t, data, domain, sampling, destination) else: reporter.warn("Analysis domain is empty! No output produced.") finally: meshctxt.releaseCachedData() destination.close() finally: domain.read_release() # domain holds a reference to the mesh, and since it's a # Parameter value, the command history holds a reference to # domain. We need to clear the mesh reference so that the # mesh can be destroyed when everybody else is done with it. domain.set_mesh(None) sampling.clearSamples()
def solver_precompute(self, solving=False): # Called before time-stepping. This routine precomputes # things that can't possibly be time-dependent. Called by # Mesh.solver_precompute(), which is called by the Solve # menuitem callback before calling evolve(). debug.subthreadTest() if self._precomputing: return if self.solveFlag and self.solver_mode is not None: subprob = self.getObject() subprob.precomputeLock.acquire() self._precomputing = True try: if subprob.precomputeRequired: # Check that materials are well defined, etc. # Being badly defined isn't an error unless we're # actually trying to solve a problem now. If # we're just precomputing to find out if the Solve # button should be sensitized, or something like # that, it's ok to simply bail out without raising # an exception. unsolvable = self.checkSolvability() if unsolvable: if solving: raise ooferror2.ErrUserError(unsolvable) else: return self.precomputeMaterials(lock=False) # Find mapping for symmetrization. # find_equation_mapping calls # CSubProblem::set_equation_mapping, which is a # fairly expensive operation, since it loops over # all nodal equations. from ooflib.engine import conjugate # avoid import loop conjugate.listofconjugatepairs.find_equation_mapping(self) conjugate.check_symmetry(self.path()) subprob.precomputeRequired = False finally: self._precomputing = False subprob.precomputeLock.release()
def get_endpoints(self): dim = config.dimension() cs_obj = self.meshctxt.getCrossSection(self.cross_section) bounds = self.meshctxt.size() errmsg = ("Segment %s, %s is entirely outside the mesh." % (cs_obj.start, cs_obj.end)) # Check that both endpoints aren't out of bounds on the same # side of the bounding box in any dimension. for i in range(dim): if ((cs_obj.start[i] < 0 and cs_obj.end[i] < 0) or (cs_obj.start[i] > bounds[i] and cs_obj.end[i] > bounds[i])): raise ooferror2.ErrUserError(errmsg) # If an endpoint is out of bounds in any dimension, project it # back onto the bounding planes. First, clone the endpoints # so that we aren't modifying the data in the cross section # object. real_start = primitives.Point(*tuple(cs_obj.start)) real_end = primitives.Point(*tuple(cs_obj.end)) for i in range(dim): direction = real_end - real_start otherdims = [(i + j) % dim for j in range(1, dim)] if real_start[i] < 0: # direction[i] can't be zero if real_start[i] < 0 or # else the bounding box check above would have failed. alpha = -real_start[i] / direction[i] for j in otherdims: real_start[j] += alpha * direction[j] real_start[i] = 0 # don't allow roundoff elif real_start[i] > bounds[i]: alpha = (real_start[i] - bounds[i]) / direction[i] for j in otherdims: real_start[j] -= alpha * direction[j] real_start[i] = bounds[i] if real_end[i] < 0: alpha = -real_end[i] / direction[i] for j in otherdims: real_end[j] += alpha * direction[j] real_end[i] = 0 elif real_end[i] > bounds[i]: alpha = (real_end[i] - bounds[i]) / direction[i] for j in otherdims: real_end[j] -= alpha * direction[j] real_end[i] = bounds[i] # Check that the clipped segment isn't infinitesimal. This # can happen if it grazes a corner of the Microstructure. seg = real_end - real_start if seg * seg == 0: raise ooferror2.ErrUserError(errmsg) # Check that the modified points aren't out of bounds, which # can happen if the original points were placed sufficiently # perversely. for i in range(dim): if not (0 <= real_start[i] <= bounds[i] and 0 <= real_end[i] <= bounds[i]): raise ooferror2.ErrUserError(errmsg) return (real_start, real_end)
def resolveQuery(self, skelctxt, indx): face = skelctxt.getObject().getFaceByUid(indx) if face is None: raise ooferror2.ErrUserError("Invalid face id") return face
def resolveQuery(self, skelctxt, indx): seg = skelctxt.getObject().getSegmentByUid(indx) if not seg: raise ooferror2.ErrUserError("Invalid segment id") return seg
def resolveQuery(self, skelctxt, indx): if indx < 0 or indx > skelctxt.getObject().nnodes(): raise ooferror2.ErrUserError("Node index out of range.") return skelctxt.getObject().getNode(indx)
def resolveQuery(self, skelctxt, indx): if indx < 0 or indx > skelctxt.getObject().nelements(): raise ooferror2.ErrUserError("Element index out of range.") el = skelctxt.getObject().getElement(indx) # el.dumpFaceInfo(skelctxt.getObject()); return el