Skip to content
Alistair Adcroft edited this page Jan 16, 2016 · 25 revisions

MOM6 code style guide

Code style is typically a personal choice. When styles clash

White space

  • No tabs
  • No trailing white space
  • Indents should be consistent (same amount used in contiguous blocks)
  • Preferred indent is 2 spaces
    • "preferred" might understate the reaction invoked by other indent amounts! 😉
  • No white space between a function name and the opening parenthesis
  • White space after all language token
    • if(a==0) is legal fortran but bad style. Use if (a==0) instead.
    • if (a == 0) is even better, since == is a language token.

Local variables

  • Local variable declarations appear after all the dummy argument declarations. We typically use ! Local variables to delineate between the argument and local variable declarations.
  • Local variables should preferably be descriptive multi-character names meaningful in their context, e.g. del_rho_int (delta rho at interface).
  • If using a highly abbreviated or short name, the declaration MUST be commented.
  • Multi-word names should use snake_case (e.g. delta_rho).
    • snake_case admittedly used more characters than camelCase but unfortunately doxygen interprets the Fortran standard too literally and throws away any attempts to use CamelCase. We briefly adopted CamelCase for new cod but are systematically replacing it as we doxygen-ize existing code.

Loop indices

Soft case convention

  • i,j,k are used for cell-center, layer-center references, e.g. h(i,j,k), T(i+1,j,k).
  • I,J are used for staggered, cell-edge references, e.g. u(I,j,k), v(i,J,k), q(I,J,k), u(I-1,j,k). We use a north-east staggering convention so the I means i+1/2 and I-1 means i-1/2.
  • K is used for the interface (between layer) references, e.g. del_t(i,j,K) = T(i,j,K+1) - T(i,j,K). The vertical staggering is such that interface K=1 is above layer k=1 so that K means k-1/2 and K+1 means k+1/2.

Global / module data

  • Absolutely NO!
  • There are a few exceptions which are strictly for debugging non-shared memory applications. Do not use these as an excuse for adding module data.

Data flow

  • All needed data is passed via arguments to subroutines and functions, or as the returned value of a function.
  • All arguments must have declared intent, with the exception of pointers: i.e. intent(in), intent(out), intent(inout).
  • Opaque types are preferred, i.e. referencing members of types defined in other modules is discouraged.
Clone this wiki locally