Version 13 (modified by kanani, 6 years ago) (diff) |
---|
PALM coding rules
(0) Why to follow some standards?
Because everyone has her/his own programming style, sort of a dialect, making it difficult for other developers to understand, extend, debug, or optimize the code. So what do we do? We learn and apply the coding standard to make PALM more easily readable for all current and future developers. Let's all work on that together. We are aware that the PALM core doesn't completely comply with the following rules yet, but we are working on that.
Formulated rules are based on the specifications given for the ocean dynamics model [add-new-link-to NEMO].
Other work that influenced the development of this standard are [add-link Community Climate System Model], [add-link Software Developer's Guide], [add-link Report on Column Physics Standards], and [add-link European Standards For Writing and Documenting Exchangeable FORTRAN 90 Code].
(1) General hints & requirements
(1.1) Language
- FORTRAN-2003 standard (all FORTRAN compilers can handle this, FORTRAN-2008 standard not yet supported by all compilers)
- Use English language only
- Use ASCII characters only
- Use SI units as physical units
- Line-length limit 132 characters (absolute limit for most compilers)
- NO use of tab characters (only exception: Makefile), because depending on the text editor, the code indentations might be corrupted.
AVOID | USE INSTEAD |
COMMON blocks | ... |
(1.2) Implementing new features to PALM
(will follow)
- module structure (attach a template or link to template in repo)
- available interfaces in the PALM core
(2) Documenting & commenting
Documentation consists of putting information both internally and externally of the source code. Comments should give a good idea of what the code does and where to look for any special activity. PALM supports the use of Doxygen, a tool for generating documentation and flow charts from annotated source code. This requires some special formatting, as described below.
(2.1) External documentation
You are in the middle of it. We have an extensive online documentation wiki embedded into a [link-to trac] project management system, directly connected to the svn repository, allowing to [link-to-browser browse the PALM code] @ all its former and of course current revision in a web-based environment.
Your carefully developed code can only be used, if there is a documentation that tells the PALM user how to use and steer the feature. All pages can be accessed from the main [link-to Documentation] page (see index on the left). There are pages for model/code description, and user-manual pages that explain about model steering, data analysis and debugging. Have a look at and discuss with us where your documentation material fits in best.
(2.2) Internal documentation
File header section (see Fig. 4)
- Doxygen command for FORTRAN file name (!> starts a doxygen command line)
- PALM license section (you may have to add other licenses if allowedly implementing code from other models)
- Revision comments (see [link-to svn branches and trunk committing])
- Doxygen command for listing authors of the module
- Module description (give a brief description of about the modules purpose)
- Another set of doxygen commands for listing todos, notes and know bugs
Description of variables (one variable per declaration statement!)
- Short description for each declared variable, comments should be aligned per declaration block
- At minimum, 2 whitespace before !<
- !< character introduces doxygen comment
LOGICAL :: conserve_water_content = .TRUE. !< open or closed bottom surface for the soil model LOGICAL :: constant_roughness = .FALSE. !< use fixed/dynamic roughness lengths for water surfaces REAL(wp) :: c_surface = 20000.0_wp !< Surface (skin) heat capacity (J m-2 K-1) REAL(wp) :: deep_soil_temperature = 9999999.9_wp !< Deep soil temperature (K)
- If comment reaches over 132 characters (hard limit), break comment into (max.) 2 lines
LOGICAL :: conserve_water_content = .TRUE. !< open or closed bottom surface for the soil model !< in the land-surface model
Commenting of code blocks
- Carefully comment each block of code
- Comments always start with
! !--
- Comment text always starts at same position as the indented code to be described, and break text into several lines if > 132 characters are reached
DO j = nys, nyn ! !-- Tendency terms for u-velocity component. Please note, in case of !-- non-cyclic boundary conditions the grid point i=0 is excluded from !-- the prognostic equations for the u-component. IF ( i >= nxlu ) THEN tend(:,j,i) = 0.0_wp IF ( timestep_scheme(1:5) == 'runge' ) THEN
- Avoid superfluous comments like
! !-- Loop over all grid indices DO i = nxl, nxr DO j = nys, nyn
(3) Naming conventions
(3.1) Use of lower & upper case letters
- Upper case: FORTRAN keywords and intrinsic functions or routines, e.g.
- SUBROUTINE, MODULE, etc.
- INTEGER, REAL, PARAMETER, etc.
- DO, ENDDO, IF, ELSE, etc.
- READ, WRITE, CALL, etc.
- MPI_ALLTOALL (MPI functions), NF90_CREATE (NetCDF functions), etc.
- Lower case: Everything else!
(3.2) Names for routines and variables
Use clear, unambiguous naming in lower-case letters, with individual words separated by underscore.
- MODULE/SUBROUTINE: name is constructed (if applicable) as verb followed by object, e.g.
land_surface_model or read_restart_data - MODULE/SUBROUTINE files: <filename>.f90 --> MODULE <filename> ... END MODULE <filename> (simplification of Make process)
- Functions: names provide information about the value it is expected to return, e.g.
solar_zenith_angle( ) - Variables & constants: names are readable, memorable and descriptive
- LOGICAL (boolean) variables: give names that imply
TRUE or FALSE
PROHIBITED:
- Names that may clash with the operating system or language intrinsic, e.g.
read( ) or access( ) - One-letter variable names (only allowed for basic flow variables like velocities (u, v, w), humidity (q) or turbulent kinetic energy (e), as well as loop or other counters (e.g. i, j, k))
(4) Formatting & sorting
Line length limit: 132 characters (hard limit)
(4.1) Indentation, spaces & line breaks
General module/subroutine structure (see Fig. 1)
- 0 whitespace in front of pre-processor directives
- 1 whitespace before MODULE, CONTAINS, SUBROUTINE (= first indentation level)
- +3 whitespaces for all following indentation levels
(only exception: ONLY list in USE statements +4 whitespaces)
- 1 whitespace between individual strings, and between strings and symbols/numbers
- 1 whitespace before and after all operators (+, -, *, =, /)
(exception: 0 whitespace for (exponent operator, e.g. u2) and operators within expressions for array indices, e.g. u(i+1)) - 1 whitespace after ,
(only exception: 0 whitespace between array dimensions, e.g. (i,j,k)) - 1 whitespace before ::
(at minimum, see Sect. Alignment) - 2 whitespace after : and ::
- 1 blank line between enclosed/unrelated blocks of instructions, assignments, clauses, statements, etc.
- 2 blank lines in front of each SUBROUTINE within a MODULE
Whitespaces between brackets (see Fig. 1)
- 0 whitespace between string and (
- 1 whitespace after ( and before )
(only exception: 0 whitespace for brackets containing array indices)
Whitespaces in DO loops, IF blocks, CASE structures
(see Fig. 2)
- In general: 1 whitespace everywhere and 3 whitespace for each indentation level
- But: 2 whitespace
- between DO and loop index
- after IF ( ) --> see CALL, THEN
- in front of and after logical operators (e.g. .OR., see list of allowed operators)
(4.2) Alignment
(see Fig. 3)
- Block-wise alignment of continuation line mark &
- Alignment of ONLY lists
- At least block-wise alignment for same type/group of declaration statement
- Alignment of message_string values
- Alignment of expressions between brackets (e.g. in IF ( ) THEN or in argument list of subroutine calls)
- Alignment of related code, e.g. in complex equations or setting of initial values for variables (missing in png)
(4.3) Alphabetical sorting
- Members in ONLY lists of USE statements (see e.g. Fig. 3)
- Parameters in NAMELISTS (see e.g. initialization_parameters NAMELIST in parin.f90)
- Declaration types (first CHARACTERs, then INTEGERs, etc., see Fig. 3)
- Variables in declaration statements (see Fig. 3)
(5) Coding
(5.1) Variable & parameter declarations
- clear structure in declaration part (USE, IMPLICIT NONE, declarations, SAVE, PRIVATE, PUBLIC list_of_public_variables)
- for long lists form groups
- one declaration line per variable
(5.2) Allowed operators
- Use /=, <, <=, ==, >, >=, etc. as relational operators instead of .GE., .LT., etc.
- Use .AND., .OR., .NOT. as logical operators
(5.3) Preprocessor directives
PALM works with the C Pre-Processor (CPP), available on any UNIX platform, and covered my most FORTRAN compilers. Only few pre-processor directives are used in PALM, and activated by the %cpp_options variable in the .palm.config.<configuration_identifier> file.
Table or link to other page
flag | description |
parallel | .... |
Use this syntax (starting at first character of a line): {{{#if defined(parallel)
some code
#endif}}}
(instead of .OR.), && (instead of .AND.), e.g. |
#if ! defined(__parallel) && (__netcdf)
(5.4) Code structure
(move somewhere else)
- one module per file (only exception: modules.f90)
- clarify program entities, i.e. use SUBROUTINE <name> ... END SUBROUTINE <name>, same holds for INTERFACE, MODULE, PROGRAM
(5.5) Error messages
- Use message routine (explain parameters here...)
- I/O error conditions via IOSTAT (is this fail-safe for different compilers?)
(5.6) Code optimization
???
(6) Final steps
Good practice
- no warning/error message should remain during compile (also try debug options)
Clean up
- PRINT/WRITE statements for debugging
- Check that all parameters are used
- place & character for line continuation at position 80 (minimum), max at position 120
(Note: FORTRAN-2003 defines a limit of 39 continuation lines)
Attachments (5)
- rules_indent_loops.png (23.7 KB) - added by kanani 6 years ago.
- rules_align.png (137.0 KB) - added by kanani 6 years ago.
- rules_indent_general.png (75.4 KB) - added by kanani 6 years ago.
- rules_header.png (90.5 KB) - added by kanani 6 years ago.
- european_standards-1.pdf (99.2 KB) - added by kanani 6 years ago.
Download all attachments as: .zip