def set_initial_conditions(self, u0, t0, dt, **kwargs): """Set initial conditions.""" levels = self.levels T = levels[0] try: levels[0].q0[...] = u0 except ValueError: raise ValueError, 'initial condition shape mismatch' # set initial condtion and evaluate at finest level T.qSDC[0] = T.q0 T.feval.evaluate(T.q0, t0, T.fSDC[:,0]) # spread to remaining nodes at finest level for n in range(1, T.sdc.nnodes): T.qSDC[n] = T.qSDC[0] T.fSDC[:,n] = T.fSDC[:,0] # restrict finest level to coarser levels for F, G in self.fine_to_coarse: restrict_time_space(F.qSDC, G.qSDC, F, G, **kwargs) restrict_space_sum_time(F.bSDC, G.bSDC, F, G, **kwargs) eval_at_sdc_nodes(t0, dt, G.qSDC, G.fSDC, G, **kwargs) G.bSDC[1:] += fas(dt, F.fSDC, G.fSDC, F, G, **kwargs)
def iteration(self, k, t0, dt, cycles, **kwargs): """Perform one PFASST iteration.""" levels = self.levels nlevels = len(levels) rank = self.mpi.rank ntime = self.mpi.ntime T = levels[0] # finest/top level B = levels[nlevels-1] # coarsest/bottom level self.state.cycle = 0 T.call_hooks('pre-iteration', **kwargs) # post receive requests if rank > 0: for iF in range(len(self.levels)-1): F = self.levels[iF] F.post_receive((F.level+1)*100+k) #### cycle for down, up in cycles: #### down for iF in down: self.state.cycle += 1 finest = iF == 0 coarsest = iF == nlevels - 1 F = levels[iF] if not coarsest: G = levels[iF+1] # get new initial value on coarsest level if coarsest: if rank > 0: F.receive((F.level+1)*100+k, blocking=coarsest) # sdc sweep F.call_hooks('pre-sweep', **kwargs) F.bSDC[0] = F.q0 for s in range(F.sweeps): F.sdc.sweep(F.bSDC, t0, dt, F.qSDC, F.fSDC, F.feval, **kwargs) F.qend[...] = F.qSDC[-1] F.call_hooks('post-sweep', **kwargs) # send new value forward if rank < ntime-1: F.send((F.level+1)*100+k, blocking=coarsest) # restrict if not coarsest: G.call_hooks('pre-restrict', **kwargs) restrict_time_space(F.qSDC, G.qSDC, F, G, **kwargs) restrict_space_sum_time(F.bSDC, G.bSDC, F, G, **kwargs) eval_at_sdc_nodes(t0, dt, G.qSDC, G.fSDC, G, **kwargs) G.bSDC[1:,:] += fas(dt, F.fSDC, G.fSDC, F, G, **kwargs) G.call_hooks('post-restrict', **kwargs) #### up for iF in up: self.state.cycle += 1 finest = iF == 0 F = levels[iF] G = levels[iF+1] # interpolate G.call_hooks('pre-interpolate', **kwargs) interpolate_time_space(F.qSDC, G.qSDC, F, G, **kwargs) eval_at_sdc_nodes(t0, dt, F.qSDC, F.fSDC, F, **kwargs) G.call_hooks('post-interpolate', **kwargs) # get new initial value if rank > 0: F.receive((F.level+1)*100+k) interpolate(F.q0, G.q0, F, G, **kwargs) # sdc sweep if not finest: F.call_hooks('pre-sweep', **kwargs) F.bSDC[0] = F.q0 for s in range(F.sweeps): F.sdc.sweep(F.bSDC, t0, dt, F.qSDC, F.fSDC, F.feval, **kwargs) F.qend[...] = F.qSDC[-1] F.call_hooks('post-sweep', **kwargs) #### done self.state.cycle = 0 T.call_hooks('post-iteration', **kwargs)