Developers:Preprocessing
From OctopusWiki
Octupus uses the C preprocessor to extend the capabilities of Fortran 90. The reason for using a C preprocessor and not a Fortran one is that it is quite standard and all machines have one.
Contents |
Global definitions
Each octopus source code file in src/ should include the header global.h and use the global_m module.
Datatypes
To be able to change at compile time the size of the real type, the macro FLOAT is defined, this must be used instead of any fortran native real type. To define literals of this type the macro CNST should be used. The most common values are also defined in the global_m module: M_ONE, M_TWO, ... , M_TEN, M_HALF, M_THIRD , M_FOURTH, M_TWO_THIRD, M_Pi, etc.
For example:
FLOAT :: a, b a = M_FIVE b = CNST(27.211383)
For complex values, use the macro CMPLX.
If you need types of a given precision, you can use REAL_SINGLE and REAL_DOUBLE, which are always defined as 4 bytes and 8 bytes values respectively.
Constants
| MAX_DIM | Maximun number of dimensions that the code can use. |
Shortcuts
There are also some macros defined that works as shortcuts:
| NP | gr%m%np |
| NP_PART | gr%m%np_part |
| NDIM | gr%sb%dim |
| LAP | f_der%der_discr%lapl |
Remember that altough this are macros, these values are known at runtime, so you can't you use it to define static arrays.
Poor men's templates
To avoid writing the same piece of code for complex and real functions, we have a series of macros that allows us to write generic functions (or templates) that can be defined for different datatypes at compile time.
"X" is a preprocessor function defined both in file "complex.F90" and in file "real.F90". In the former case it transforms the argument into "z" + the argument, and in the second case it transforms the argument into "d" + the argument. So that line would go into:
call zHpsi(h, gr, st%zpsi(:,:, p, ik) , h_psi, ik)
in the first case, and into
call dHpsi(h, gr, st%dpsi(:,:, p, ik) , h_psi, ik)
in the second case.

