Example #1
0
    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)
Example #2
0
  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)
Example #3
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)
Example #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)