Exemplo n.º 1
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)
Exemplo n.º 2
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)