def evolve(meshctxt, endtime): global linsys_dict starttime = meshctxt.getObject().latestTime() # We're solving a static problem if endtime is the same as the # current time, or if there are no non-static steppers and output # is requested at at single time. staticProblem = (starttime == endtime or (not meshctxt.timeDependent() and meshctxt.outputSchedule.isSingleTime())) # "continuing" is true if we're continuing an earlier time # evolution, in which case we can assume that all Fields have # their correct initial values. "continuing" is never true for # static problems. continuing = (not staticProblem and isinstance(meshctxt.status, meshstatus.Solved)) targettime = endtime if starttime > endtime: raise ooferror2.ErrSetupError( "End time must not precede current time.") meshctxt.solver_precompute(solving=True) meshctxt.setStatus(meshstatus.Solving()) meshctxt.timeDiff = endtime - starttime # used to get next endtime in GUI # Make sure that the starting point has been cached. ## TODO OPT: Is it necessary to call cacheCurrentData here? meshctxt.restoreLatestData() meshctxt.cacheCurrentData() meshctxt.releaseLatestData() meshctxt.outputSchedule.reset(starttime, continuing) prog = ProgressData(starttime, endtime, progress.getProgress("Solving", progress.DEFINITE)) try: # Get an ordered list of subproblems to be solved. First, # create tuples containing a subproblem and its solveOrder. subprobctxts = [(s.solveOrder, s) for s in meshctxt.subproblems() if s.time_stepper is not None and s.solveFlag] subprobctxts.sort() # sort by solveOrder subprobctxts = [s[1] for s in subprobctxts] # strip solveOrder # Initialize statistics. for subp in subprobctxts: subp.resetStats() if not continuing: # Initialize static fields in all subproblems. For static # problems, this computes the actual solution. try: linsys_dict = initializeStaticFields(subprobctxts, starttime, prog) # Initial output comes *after* solving static fields. # For fully static problems, this is the only output. _do_output(meshctxt, starttime) except ooferror2.ErrInterrupted: raise except ooferror2.ErrError, exc: meshctxt.setStatus(meshstatus.Failed(exc.summary())) raise except Exception, exc: meshctxt.setStatus(meshstatus.Failed( ` exc `)) raise
def computeStaticFieldsL(self, linsys, unknowns): # Initialize "static" fields for linear problems. if linsys.n_unknowns_part('K')==0 and linsys.n_unknowns_part('C')==0: return if self.nonlinear_activefields(): raise ooferror2.ErrSetupError( "A nonlinear solver is required for subproblem '%s'." % self.name()) # u2 = fields that have second time derivative terms in the # equations. These correspond to nonempty columns in M. # u1 = fields that have first time derivative terms, but not # second. These correspond to empty columns in M but not C. # u0 = fields that have no time derivative terms. These # correspond to empty columns in both M and C. # u1, u2, and u2dot are set by initial conditions. We're # solving for u0 and u1dot. u2 = self.time_stepper.get_unknowns_part('M', linsys, unknowns) u1 = self.time_stepper.get_unknowns_part('C', linsys, unknowns) u0 = self.time_stepper.get_unknowns_part('K', linsys, unknowns) if len(u0) > 0: # Find u0 by solving # K00 u0 + K01 u1 + K02 u2 = f0 # which is the derivative-free part of the full set of # equations. K00 = self.time_stepper.K_submatrix(linsys, 'K', 'K') # rhs = f0 - K01*u1 - K02*u2, written out to avoid temporaries rhs = self.time_stepper.rhs_ind_part('K', linsys) # f0 copy if len(u1) > 0: K01 = self.time_stepper.K_submatrix(linsys, 'K', 'C') rhs -= K01*u1 if len(u2) > 0: K02 = self.time_stepper.K_submatrix(linsys, 'K', 'M') rhs -= K02*u2 self.matrix_method(self.asymmetricK).solve(K00, rhs, u0) self.time_stepper.set_unknowns_part('K', linsys, u0, unknowns) if len(u1) > 0 and self.time_stepper.derivOrder() > 1: # Find u1dot by solving # C11 u1dot + C12 u2dot + K10 u0 + K11 u1 + K12 u2 + f1 = 0 u1dot = self.time_stepper.get_derivs_part('C', linsys, unknowns) u2dot = self.time_stepper.get_derivs_part('M', linsys, unknowns) # rhs = f1 - C12*u2dot - K10*u0 - K11*u1 - K12*u2 rhs = self.time_stepper.rhs_ind_part('C', linsys) # copy of f1 K11 = self.time_stepper.K_submatrix(linsys, 'C', 'C') rhs -= K11*u1 # -= might avoid a copy if len(u2dot) > 0: C12 = self.time_stepper.C_submatrix(linsys, 'C', 'M') rhs -= C12*u2dot if len(u0) > 0: K10 = self.time_stepper.K_submatrix(linsys, 'C', 'K') rhs -= K10*u0 if len(u2) > 0: K12 = self.time_stepper.K_submatrix(linsys, 'C', 'M') rhs -= K12*u2 C11 = self.time_stepper.C_submatrix(linsys, 'C', 'C') self.matrix_method(self.asymmetricC).solve(C11, rhs, u1dot) self.time_stepper.set_derivs_part('C', linsys, u1dot, unknowns)
if staticProblem: meshctxt.setStatus(meshstatus.Solved()) meshctxt.setCurrentTime(endtime, None) return time = starttime if continuing: delta = meshctxt.solverDelta else: delta = None lasttime = None # Loop over output times for t1 in meshctxt.outputSchedule.times(endtime): if t1 == lasttime: raise ooferror2.ErrSetupError("Time step is zero!") # If t1 <= starttime, there's no evolution to be done, and # any output at t1==starttime has already been done after # static initialization. if t1 - starttime > max(t1, starttime) * 10. * utils.machine_epsilon: if t1 > endtime: t1 = endtime if delta is None: delta = min([ subp.time_stepper.initial_stepsize(t1 - starttime) for subp in subprobctxts ]) try: time, delta, linsys_dict = evolve_to( meshctxt,