def spread_q0(self, q0, t0, dt, **kw): """Spread q0 to all nodes and restrict throughout.""" levels = self.levels T = levels[0] try: T.q0[...] = q0 except ValueError: raise ValueError, "initial condition shape mismatch" # set initial condtion T.qSDC[0] = T.q0 # evaluate at first node and spread T.sdc.evaluate(t0, T.qSDC, T.fSDC, 0, T.feval, **kw) for n in range(1, T.sdc.nnodes): T.qSDC[n] = T.qSDC[0] for p in range(T.fSDC.shape[0]): T.fSDC[p, n] = T.fSDC[p, 0] # evaluate forcing terms for F in self.levels: if F.forcing: for m in range(len(F.sdc.nodes)): t = t0 + dt * F.sdc.nodes[m] F.feval.forcing(t, F.gSDC[m], **kw) if T.forcing: T.fSDC[0] += T.gSDC # restrict and compute fas corrections for F, G in self.fine_to_coarse: restrict_time_space(t0, dt, F, G, **kw)
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, **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 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)