3. Introduction to RNPL
RNPL is a programming language designed to ease the solving of hyperbolic partial differential equations with the help of a computer. The main strength of RNPL is that it automatically takes care of many of the required routines, allowing the user to focus on the mathematical aspects of PDE solving. RNPL outputs .sdf (scientific data format) files, which can be viewed with programs such as DV (for 2D and 3D data sets) and XVS (for 1D data sets). RNPL, DV and XVS currently only run on Unix/Linux systems, and can be downloaded here. Before compilation, a number of prerequisites must be installed, including xforms, which on Ubuntu distributions can be obtained straight from the repository. RNPL, DV and XVS require Fortran and C compilers, and before installation the corresponding environment variables must be set to point to the versions of the compilers that the user has. Also, by default RNPL, XVS and DV require the lg2c library during installation. This is a deprecated library, and it can simply be removed from the list of required libraries as it may be hard to find a copy of it. The performance of the programs will not be impacted by this.
RNPL folder structure: In general, any folder containing an RNPL program folder will contain the following files: a source file (denoted by _rnpl), a make file, any number of include files (usually denoted by .inc) and several input data files (usually denoted by id0, id1, etc). When the make command is issued, RNPL will create two fortran files (residuals.f and updates.f) which compute the residuals and update the grid functions respectively, which it will then compile. RNPL will also create various other files for memory management routines, initialization, etc. When the run command is issued, RNPL will attempt to run the binary files it has created with the data from the input files.
RNPL objects: RNPL works with five types of objects: parameters (which are numbers), coordinate systems, grids, grid functions ans operators. A coordinate system is just a definition of the coordinate type that is being used and of the coordinate names, and is usually a declaration of the form:
rect coordinates t, x, y, z
Note: The first coordinate is always assumed to be the temporal one!
Grids: A grid declaration is a definition of the grid type that is being used, together with the coordinate bounds and indices. It usually takes the form:
uniform rect[x,y,z] grid g1 [1:Nx][1:Ny][1:Nz] {xmin:xmax}{ymin:ymax}{zmin:zmax}
This syntax specifies that the grid is called g1, that it is rectangular, consists of Nx × Ny × Nz points and corresponds to coordinate interval [ xmin ; xmax ] × [ ymin ; ymax ] × [ zmin ; zmax ] .
Grid functions: Grid functions are discrete functions defined on the points of a grid which correspond to the continuous variables that enter the equations we want to solve. A standard grid function declaration looks like:
float phi on g1 at 0,1 {out_gf = 1}
This expression defines grid function phi on grid g1. The statement {out_gf = 1} indicates that RNPL should save output corresponding to phi, and the statement 0,1 indicates that phi is defined at the current time level ( 0 ) and at the first future time level ( 1 ).
Operators: RNPL operators are generally used to implement the finite difference operators into RNPL code, although they can be also used to implement other functions such as averaging or introducing a dissipative term. For instance, the operator D0X, corresponding to Dx, is declared as:
operator D0X(f,x) := (<0>f[1][0][0] - <0>f[-1][0][0]) / (2*dx)
One can also declare a forward time-averaging operator as:
operator AVE(f,t) := (<1>f[0][0][0] + <0>f[0][0][0]) / 2
Argument f is just a placeholder, and it can be defined as any letter, not necessarily f. RNPL syntax requires the operator's declaration to contain a coordinate separated from the argument by a comma, even if the operator is not a derivative. The time levels of the argument are called with <> brackets placed before the argument, and the spatial levels are called with [ ] brackets placed after the argument. RNPL allows the definition of an operator in terms of other operators, though care should be used in such cases not to call spatial levels that are outside the grid.
Auxiliary functions: Sometimes, solving PDEs requires using auxiliary functions (that are already known on the entire space-time) in addition to the functions that are being solved for. For example, the wave equation on an arbitrary space-time contains 10 metric components, the metric determinant and a source function, to a total of 12 auxiliary functions. As RNPL does not currently allow the declaration of functions (apart from grid functions), there are two ways of incorporating auxiliary functions into RNPL code: either declaring them as grid functions, or performing the residuals and updates computations directly in an external .inc file. Declaring the auxiliary functions as grid functions is the more straightforward approach, but it has the disadvantage of using a significant amount of memory at high resolutions, as it uses Nx × Ny × Nz × n points for each auxiliary grid function.
Initialization: The initialization statements are performed in the _rnpl source file, and are denoted by initialize statements, followed by an auto initialize statement. Note: It is extremely important to get the initialization working correctly, as improper usage will cause rnpl to set all initial values to 0, which can lead to infinities if the auxiliary variables are being divided by (as is the case with gtt in the wave equation example). It is generally good practice to check all auxiliary variables using DV to make sure that they are not 0 at the initial time level.
1D Wave Equation: Here is a simple example of solving a one-dimensional wave equation with RNPL. Note: As mentioned in the hyperlinked page, when running simulations, do not forget to clear the initial data .sdf files before each new batch run!
For more information on RNPL see The RNPL User's Guide by Robert Marsa and Matthew Choptuik.
Some of the material presented on this web page is based upon work supported in part by the Princeton Applied and Computational Mathematics Program and by the National Science Foundation under Grant No. 0745779.