Code layout#
BOUT++ is organised into classes and groups of functions which operate on them: It’s not purely object-oriented, but takes advantage of many of C++’s object-oriented features.
Fig. 21 shows the most important parts of BOUT++ and how they fit together.
Fig. 21 Overview of BOUT++ control flow during initialisation (red), and running (blue)#
The initialisation process is shown in red: basic information is first
read from the grid file (e.g. size of the grid, topology etc.), then
the user-supplied initialisation code is called. This code can read
other variables from the grid, and makes at least one call to
PhysicsModel::bout_solve() to specify a variable to be evolved. The
main thing bout_solve does is to add
these variables to the solver.
The process of running a timestep is shown in blue in
Fig. 21: The main loop calls the solver, which in turn
calls PVODE. To evolve the system PVODE makes calls to the RHS
function inside solver. This moves data between PVODE and BOUT++, and
calls the user-supplied PhysicsModel::rhs() code to calculate
time-derivatives. Much of the work calculating time-derivatives
involves differential operators.
Calculation of the RHS function, and handling of
data in BOUT++ involves many different
components. Fig. 22 shows (most) of the classes and
functions involved, and the relationships between them. Some thought
was put into how this should be organised, but it has also changed
over time, so some parts could be cleaner.
Fig. 22 Relationship between important classes and functions used in calculating the RHS function#
Directories#
The source code for the core of BOUT++ is divided into include files
(which can be used in physics models) in bout++/include/bout, and
source code and low-level includes in bout++/src. Many parts of
the code are defined by their interface, and can have multiple
different implementations. An example is the time-integration solvers:
many different implementations are available, some of which use
external libraries, but all have the same interface and can be used
interchangeably. This is reflected in the directory structure inside
bout++/src. A common pattern is to store individual
implementations of an interface in a subdirectory called impls.
include/bout/foo.hxx
src/.../foo.cxx
src/.../impls/one/one.hxx
src/.../impls/one/one.cxx
where foo.hxx defines the interface, foo.cxx implements common
functions used in several implementations. Individual implementations
are stored in their own subdirectories of impls. Components which
follow this pattern include invert/laplace and invert/parderiv
inversions, mesh, and solver.
The layout of the src/ directory is as follows:
src/bout++.cxx: Main file which initialises, runs and finalises BOUT++. The two most important public functions areBoutInitialise()andBoutFinalise()for starting/stopping the library.src/fieldImplementations of “fields” (the scalars
Field2D,Field3D,FieldPerp, and vectorsVector2D,Vector3D), as well as basic operations (arithmetic, Algebraic operators, and vector calculus), and initialisation.
src/invertImplementations of different inverse operators, including Fourier transforms (via an interface to FFTW, see
bout::fft::rfft()andbout::fft::irfft()).
src/invert/laplaceImplementations of some inverse generalised Laplacian operator variations, where some directions may be constant. See Laplacian inversion for more details.
src/invert/parderivInversion of parallel derivatives, intended for use in preconditioners. See
InvertPar
src/invert/pardivInversion of parallel divergence, intended for use in Nonlocal heat flux models.
src/meshImplementations of low-level numerical routines. This includes things like the inter-process communications, boundary conditions, derivative operators, interpolation, the coordinate system (including Parallel Transforms), and the Mesh itself.
src/physicsThis contains some specialised physics operators and routines, such as gyro-averaging and Nonlocal heat flux models.
src/solverImplementations of time integration solvers
src/sysGeneral purpose utilities used throughout the library, such as
BoutException, wrappers for C libraries likePETScandHYPRE, screen and file input and output.