Beispiel #1
0
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()
Beispiel #2
0
    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()
Beispiel #3
0
    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)
Beispiel #4
0
 def resolveQuery(self, skelctxt, indx):
     face = skelctxt.getObject().getFaceByUid(indx)
     if face is None:
         raise ooferror2.ErrUserError("Invalid face id")
     return face
Beispiel #5
0
 def resolveQuery(self, skelctxt, indx):
     seg = skelctxt.getObject().getSegmentByUid(indx)
     if not seg:
         raise ooferror2.ErrUserError("Invalid segment id")
     return seg
Beispiel #6
0
 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)
Beispiel #7
0
 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