Example #1
0
  def evaluate(self, t0, qSDC, fSDC, node, feval, **kwargs):

    nnodes = fSDC.shape[1]

    f1eval = hasattr(feval, 'f1_evaluate')
    f2eval = hasattr(feval, 'f2_evaluate')

    if node == 'all':

      for m in range(nnodes):

        self.pf.state.node = m
        self.level.call_hooks('pre-feval', **kwargs)

        if f1eval and f2eval:
          feval.f1_evaluate(qSDC[m], t0, fSDC[0, m], **kwargs)
          feval.f2_evaluate(qSDC[m], t0, fSDC[1, m], **kwargs)
        elif f1eval:
          feval.f1_evaluate(qSDC[m], t0, fSDC[0, m], **kwargs)
        else:
          feval.f2_evaluate(qSDC[m], t0, fSDC[0, m], **kwargs)

        self.level.call_hooks('post-feval', **kwargs)

    else:

      self.pf.state.node = node
      self.level.call_hooks('pre-feval', **kwargs)

      if f1eval and f2eval:
        feval.f1_evaluate(qSDC[node], t0, fSDC[0, node], **kwargs)
        feval.f2_evaluate(qSDC[node], t0, fSDC[1, node], **kwargs)
      elif f1eval:
        feval.f1_evaluate(qSDC[node], t0, fSDC[0, node], **kwargs)
      else:
        feval.f2_evaluate(qSDC[node], t0, fSDC[0, node], **kwargs)

      self.level.call_hooks('post-feval', **kwargs)
Example #2
0
  def sweep(self, b, t0, dt, qSDC, fSDC, feval, **kwargs):
    r"""Perform one SDC sweep with new initial conditions and add FAS
    corrections.

    :param b:    right hand side (numpy array of size ``(nnodes,nqvar)``)
    :param t0:   initial time
    :param dt:   time step
    :param qSDC: solution (numpy array of size ``(nnodes,nqvar)``)
    :param fSDC: function (numpy array of size ``(nnodes,nfvar)``)
    :param feval: implicit/explicit function evaluator (instance
            of :py:class:`pfasst.feval.FEval`)

    Note that *qSDC* and *fSDC* are over-written.

    The sweep performed uses forward/fackward Euler time-stepping:

    XXX

    .. math::

      \begin{multline}
        U^{k+1}_{m+1} = U^k_m + \Delta t_m
            \bigl[ f_I(t_{m+1}, U^{k+1}_{m+1}) +
                 f_E(t_{m}, U^{k+1}_{m}) \bigr] \\
        + \vec{S}^{m,m+1}_E \, f_E(\vec{t}, \vec{U}^{k})
        + \vec{S}^{m,m+1}_I \, f_I(\vec{t}, \vec{U}^{k}).
      \end{multline}

    """

    exp = self.smat_exp
    imp = self.smat_imp

    pieces = fSDC.shape[0]
    nnodes = fSDC.shape[1]
    shape  = fSDC.shape[2:]
    size   = feval.size

    fSDCf = fSDC.reshape((pieces, nnodes, size)) # flatten so we can use np.dot
    rhs   = dt * (np.dot(exp, fSDCf[0]) + np.dot(imp, fSDCf[1]))
    rhs   = rhs.reshape((nnodes-1,)+shape)       # unflatten

    # add b
    if b is not None:
      rhs += b[1:]

    # set initial condition and eval
    qSDC[0] = b[0]

    feval.f1_evaluate(qSDC[0], t0, fSDC[0,0], **kwargs)
    feval.f2_evaluate(qSDC[0], t0, fSDC[1,0], **kwargs)

    # sub time-stepping
    t = t0
    dtsdc = dt * self.dsdc

    for m in range(self.nnodes-1):
      t += dtsdc[m]

      y = qSDC[m] + dtsdc[m]*fSDC[0,m] + rhs[m]

      feval.f2_solve(y, qSDC[m+1], t, dtsdc[m], fSDC[1,m+1], **kwargs)
      feval.f1_evaluate(qSDC[m+1], t, fSDC[0,m+1], **kwargs)