def __init__(self, num_procs, controller_params, description): """ Initialization routine for PFASST controller Args: num_procs: number of parallel time steps (still serial, though), can be 1 controller_params: parameter set for the controller and the steps description: all the parameters to set up the rest (levels, problems, transfer, ...) """ # call parent's initialization routine super(allinclusive_multigrid_nonMPI, self).__init__(controller_params) self.MS = [stepclass.step(description)] # try to initialize via dill.copy (much faster for many time-steps) try: for p in range(num_procs - 1): self.MS.append(dill.copy(self.MS[0])) # if this fails (e.g. due to un-picklable data in the steps), initialize seperately except dill.PicklingError and TypeError: self.logger.warning( 'Need to initialize steps separately due to pickling error') for p in range(num_procs - 1): self.MS.append(stepclass.step(description)) if self.params.dump_setup: self.dump_setup(step=self.MS[0], controller_params=controller_params, description=description) if num_procs > 1 and len(self.MS[0].levels) > 1: for S in self.MS: for L in S.levels: if not L.sweep.coll.right_is_node: raise ControllerError( "For PFASST to work, we assume uend^k = u_M^k") if all(len(S.levels) == len(self.MS[0].levels) for S in self.MS): self.nlevels = len(self.MS[0].levels) else: raise ControllerError( 'all steps need to have the same number of levels') if self.nlevels == 0: raise ControllerError('need at least one level') self.nsweeps = [] for nl in range(self.nlevels): if all(S.levels[nl].params.nsweeps == self.MS[0].levels[nl].params.nsweeps for S in self.MS): self.nsweeps.append(self.MS[0].levels[nl].params.nsweeps) if self.nlevels > 1 and self.nsweeps[-1] > 1: raise ControllerError( 'this controller cannot do multiple sweeps on coarsest level')
def __init__(self, num_procs, controller_params, description): """ Initialization routine for PFASST controller Args: num_procs: number of parallel time steps (still serial, though), can be 1 controller_params: parameter set for the controller and the steps description: all the parameters to set up the rest (levels, problems, transfer, ...) """ # call parent's initialization routine super(allinclusive_multigrid_nonMPI, self).__init__(controller_params) self.MS = [] # simply append step after step and generate the hierarchies for p in range(num_procs): self.MS.append(stepclass.step(description)) if self.params.dump_setup: self.dump_setup(step=self.MS[0], controller_params=controller_params, description=description) assert not (len(self.MS) > 1 and len(self.MS[0].levels) == 1), "ERROR: multigrid cannot do MSSDC" if num_procs > 1 and len(self.MS[0].levels) > 1: for S in self.MS: for L in S.levels: assert L.sweep.coll.right_is_node, "For PFASST to work, we assume uend^k = u_M^k"
def test_caninstantiate(self): for type in classes: self.swparams['collocation_class'] = type self.description['sweeper_params'] = self.swparams S = stepclass.step(description=self.description) assert isinstance( S.levels[0].sweep, imex ), "sweeper in generated level is not an object of type imex"
def __init__(self, num_procs, controller_params, description): """ Initialization routine for PFASST controller Args: num_procs: number of parallel time steps (still serial, though), can be 1 controller_params: parameter set for the controller and the step class description: all the parameters to set up the rest (levels, problems, transfer, ...) """ # call parent's initialization routine super(allinclusive_classic_nonMPI, self).__init__(controller_params) self.logger.warning('classic controller is about to become deprecated, use multigrid controller instead') self.MS = [stepclass.step(description)] # try to initialize via dill.copy (much faster for many time-steps) try: for p in range(num_procs - 1): self.MS.append(dill.copy(self.MS[0])) # if this fails (e.g. due to un-picklable data in the steps), initialize seperately except dill.PicklingError and TypeError: self.logger.warning('Need to initialize steps separately due to pickling error') for p in range(num_procs - 1): self.MS.append(stepclass.step(description)) assert not (len(self.MS) > 1 and len(self.MS[0].levels) == 1), "ERROR: classic cannot do MSSDC" if self.params.dump_setup: self.dump_setup(step=self.MS[0], controller_params=controller_params, description=description) num_levels = len(self.MS[0].levels) if num_procs > 1 and num_levels > 1: for S in self.MS: for L in S.levels: if not L.sweep.coll.right_is_node or L.sweep.params.do_coll_update: raise ControllerError("For PFASST to work, we assume uend^k = u_M^k in this controller") for nl in range(len(self.MS[0].levels)): if self.MS[0].levels[nl].params.nsweeps > 1: raise ControllerError('classic controller cannot do multiple sweeps')
def setupLevelStepProblem(self): self.description['sweeper_params'] = self.swparams step = stepclass.step(description=self.description) level = step.levels[0] level.status.time = 0.0 u0 = step.levels[0].prob.u_exact(step.time) step.init_step(u0) nnodes = step.levels[0].sweep.coll.num_nodes problem = level.prob return step, level, problem, nnodes
def test_canregisterlevel(self): for type in classes: self.swparams['collocation_class'] = type self.description['sweeper_params'] = self.swparams step = stepclass.step(description=self.description) L = step.levels[0] with self.assertRaises(Exception): L.sweep.predict() with self.assertRaises(Exception): L.update_nodes() with self.assertRaises(Exception): L.compute_end_point()
def __init__(self, num_procs, controller_params, description): """ Initialization routine for PFASST controller Args: num_procs: number of parallel time steps (still serial, though), can be 1 controller_params: parameter set for the controller and the step class description: all the parameters to set up the rest (levels, problems, transfer, ...) """ # call parent's initialization routine super(allinclusive_classic_nonMPI, self).__init__(controller_params) self.logger.warning('classic controller is about to become deprecated, use multigrid controller instead') self.MS = [] # simply append step after step and generate the hierarchies for p in range(num_procs): self.MS.append(stepclass.step(description)) assert not (len(self.MS) > 1 and len(self.MS[0].levels) == 1), "ERROR: classic cannot do MSSDC" if self.params.dump_setup: self.dump_setup(step=self.MS[0], controller_params=controller_params, description=description) num_levels = len(self.MS[0].levels) if num_procs > 1 and num_levels > 1: for S in self.MS: for L in S.levels: if not L.sweep.coll.right_is_node or L.sweep.params.do_coll_update: raise ControllerError("For PFASST to work, we assume uend^k = u_M^k in this controller") for nl in range(len(self.MS[0].levels)): if self.MS[0].levels[nl].params.nsweeps > 1: raise ControllerError('classic controller cannot do multiple sweeps')
# the following are not used in the computation pparams['lambda_s'] = np.array([0.0]) pparams['lambda_f'] = np.array([0.0]) pparams['u0'] = 1.0 swparams = {} # swparams['collocation_class'] = collclass.CollGaussLobatto # swparams['collocation_class'] = collclass.CollGaussLegendre swparams['collocation_class'] = collclass.CollGaussRadau_Right swparams['num_nodes'] = mvals[i] do_coll_update = True # # ...this is functionality copied from test_imexsweeper. Ideally, it should be available in one place. # step = stepclass.step(params={}) L = lvl.level(problem_class=swfw_scalar, problem_params=pparams, dtype_u=mesh, dtype_f=rhs_imex_mesh, sweeper_class=imex, sweeper_params=swparams, level_params={}, hook_class=hookclass.hooks, id="stability") step.register_level(L) step.status.dt = 1.0 # Needs to be 1.0, change dt through lambdas step.status.time = 0.0 u0 = step.levels[0].prob.u_exact(step.status.time) step.init_step(u0) nnodes = step.levels[0].sweep.coll.num_nodes