ASIS:Coding

FORTRAN90 Modules
We aim not to pass information via variables which are 'global' to modules. In other words, we don't want to have a module defining variables which are then accessed through 'use' statements by functional code elsewhere in the model. This would be a maintenance headache and is likely to lead to bugs. Argument passing is much safer.

(If arg lists get very long, we could consider grouping related variables into derived types.)

Global constants
There is 1 occasion when it is good idea to access variables in modules and at all other times they should be hidden & protected using the 'private' keyword:

- Constants - keep them all in one place and available to all. Must be e.g. real, parameter :: pi = 3.142...

The main program can declare the variables that it passes to subroutines.

Use of private/public
It is a good idea to have a structured set of modules in the overall program. A large proliferation leaves a programmer reeling.

The PPM module provided by Vicky shows good modularity. A clear way to use the code is achieved by only exposing the 3 subroutines, ppminitial, ppmthck and ppmfinal.

Using 'public' and 'private' in the module and then using: use ppm, only: ppminitial,ppmthck,ppmfinal is great because it keeps things simple and well designed, protects the program and so makes it easier to maintain, and also tells the programmer higher up in the program where the subroutines are coming from.

Initialisation
Note that is desirable that modules can have some /private/ variables that don't appear in argument lists. These are variables that may be setup during initialisation (and cleaned up in finalise). This way the main program does not need to know anything about them and so it keeps things simple. Not just OK, definitely a good thing for certain--but not all--variables. (Note that with the AMR code the solvers may be called with different grids during a single simulation, so it is important that grid specific variables not be used in this way.)

- any variable which belongs to the module and is operated upon by the initialisation routine should be private, global to the module and therefore is not in the argument list. They are in scope for all routines in the module. Examples could be variables read in from a file, or arrays allocated as some working space for calculations made by the module.

- any vars that are passed to the init routine via an argument list should be:

(A) intent(in) i.e. values from the main program that are just copied as part of init. These copies can be local to the subroutine if that is all that is required, or stored as a module variable, if more than one routine requires the values.

(B) intent(out) i.e. vars from the main program are passed in and altered.