Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
  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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
  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)