def iteration(self, k, t0, dt, **kw): """Perform one PFASST iteration.""" rank = self.mpi.rank state = self.state levels = self.levels T = levels[0] # finest/top level B = levels[-1] # coarsest/bottom level state.set(iteration=k, cycle=0) T.call_hooks("pre-iteration", **kw) # post receive requests for F in levels[:-1]: F.post_receive((F.level + 1) * 100 + k) # down for F, G in self.fine_to_coarse: state.increment_cycle() for s in range(F.sweeps): F.sdc.sweep(t0, dt, F, **kw) F.send((F.level + 1) * 100 + k, blocking=False) restrict_time_space(t0, dt, F, G, **kw) # bottom state.increment_cycle() B.receive((B.level + 1) * 100 + k, blocking=True) for s in range(B.sweeps): B.sdc.sweep(t0, dt, B, **kw) B.send((B.level + 1) * 100 + k, blocking=True) # up for F, G in self.coarse_to_fine: state.increment_cycle() interpolate_time_space(t0, F, G, **kw) F.receive((F.level + 1) * 100 + k, **kw) if rank > 0: interpolate(F.q0, G.q0, F, G, **kw) if F.level != 0: for s in range(F.sweeps): F.sdc.sweep(t0, dt, F, **kw) # done state.set(cycle=0) T.call_hooks("post-iteration", **kw)
def predictor(self, t0, dt, **kwargs): """Perform the PFASST predictor.""" B = self.levels[-1] rank = self.mpi.rank ntime = self.mpi.ntime B.q0[...] = B.qSDC[0] self.state.cycle = -1 self.state.iteration = -1 self.state.predictor = True B.call_hooks('pre-predictor', **kwargs) pred_iters = optdb.predictor_iterations or 1 for k in range(1, rank+pred_iters+1): self.state.iteration = k # get new initial value (skip on first iteration) if k > 1 and rank > 0: B.receive(k-1, blocking=True) # coarse sdc sweep B.call_hooks('pre-sweep', **kwargs) B.bSDC[0] = B.q0 for s in range(B.sweeps): B.sdc.sweep(B.bSDC, t0, dt, B.qSDC, B.fSDC, B.feval, **kwargs) B.qend[...] = B.qSDC[-1] B.call_hooks('post-sweep', **kwargs) # send result forward if rank < ntime-1: B.send(k, blocking=True) self.state.iteration = -1 B.call_hooks('post-predictor', **kwargs) # interpolate coarest to finest and set initial conditions for F, G in self.coarse_to_fine: interpolate_time_space(F.qSDC, G.qSDC, F, G, **kwargs) eval_at_sdc_nodes(t0, dt, F.qSDC, F.fSDC, F, **kwargs) for F in self.levels: F.q0[...] = F.qSDC[0] for F in self.levels: F.call_hooks('predictor', **kwargs)
def predictor(self, t0, dt, **kw): """Perform the PFASST predictor.""" B = self.levels[-1] rank = self.mpi.rank state = self.state self.state.set(cycle=-1, iteration=-1, predictor=True) B.call_hooks("pre-predictor", **kw) B.q0[...] = B.qSDC[0] # predictor loop for k in range(1, rank + 2): state.set(iteration=k) if k > 1: B.receive(k - 1, blocking=True) for s in range(B.sweeps): B.sdc.sweep(t0, dt, B, **kw) B.send(k, blocking=True) state.set(iteration=-1) B.call_hooks("post-predictor", **kw) # interpolate for F, G in self.coarse_to_fine: # XXX: sweep in middle levels? interpolate_time_space(t0, F, G, **kw) # done for F in self.levels: F.call_hooks("end-predictor", **kw) state.set(predictor=False)
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)