Overview

The LIBPFASST library evolves systems of ODEs in time:

\[u'(t) = f(u(t), t).\]

LIBPFASST comes with builtin sub-steppers for fully explicit, fully implicit, and implicit-explicit (IMEX) systems.

The user provides:

  1. Function evaluation routines: \(F(U, t)\). These functions may depend on the PFASST level, which allows for multi-order and/or multi-physics operators.
  2. For implicit or IMEX schemes, a backward Euler solver: \(U - dt F(U) = RHS\).
  3. Spatial interpolation and restriction routines: \(R(U)\) and \(P(U)\).
  4. Solution encapsulation routines to tell LIBPFASST how to manipulate solutions. This enables LIBPFASST to interoperate nicely with other libraries that have particular ways of storing solutions (eg, BoxLib, PEPC, or PETSc). In particular, this allows LIBPFASST to work with spatially distributed solutions.

User interactions with LIBPFASST are typically marshaled through the type(pf_pfasst_t) class. This class acts as the overall controller of the algorithm. Implementing a ODE/PDE solver in LIBPFASST generally consists of the following steps:

  1. Create an type(pf_pfasst_t) controller.
  2. Create an type(pf_encap_t) encapsulation object. This may be level dependent.
  3. Create an type(pf_comm_t) communicator object. This allows LIBPFASST to use MPI or pthreads parallelization (independent of any spatial parallelization).
  4. Create an type(pf_sweeper_t) SDC sweeper. Builtin sweepers include: explicit, implicit, or imex. Custom sweepers can also be built. This can also be level dependent.
  5. Add levels to the type(pf_pfasst_t) controller. This includes telling LIBPFASST how many degrees-of-freedom are on each level, how many SDC nodes should be used on each level and their type, which interpolation and restriction routines to use, which encapsulation object to use etc.
  6. Add any desired hooks to the controller and set any controller options.
  7. Call the communicator’s and controller’s setup routines.
  8. Run.
  9. Tidy up.