Coding Standard for CCM4

This document defines a set of specifications, rules, and recommendations for the coding of CCM4. The purpose is to provide a framework that enables users to easily understand or modify the code, or to port it to new computational environments. In addition, it is hoped that adherence to these guidelines will facilitate the exchange and incorporation of new packages and parameterizations into the model.  Other works which influenced the development of this document are "Report on Column Physics Standards" (http://nsipp.gsfc.nasa.gov/infra/) and "European Standards For Writing and Documenting Exchangeable Fortran 90 Code" (http://nsipp.gsfc.nasa.gov/infra/eurorules.html).

 Style Rules

integer :: i,j,k ! Spatial indices
Continuation lines are acceptable on multi-dimensional array declarations which take up many columns. For example:
real(r8), dimension(plond,plev), intent(in) :: &
array1, &! array1 is blah blah blah
array2   ! array2 is blah blah blah
Note that the f90 standard defines a limit of 39 continuation lines.
a = b + c*d + blahblahblah/xxxxxxxxxx + &
    h*g + e*f
call sub76 (x, y, z, w, a, &
            b, c, d, e)

subroutine sub76 (x, y, z, w, a, &
                  b, c, d, e)

call linemsbc (u3(i1,1,1,j,n3m1), v3(i1,1,1,j,n3m1), t3(i1,1,1,j,n3m1), &
               q3(i1,1,1,j,n3m1), qfcst(i1,1,m,j), xxx)
subroutine linemsbc (u, v, t, &
                     q, qfcst, xxx)
!
! Describe what is going on
!
Key features of this style are 1) it starts with a "!" in column 1; 2) The text starts in column 3; and 3) the text is offset above and below by a blank comment line. The blank comments could just as well be completely blank lines (i.e. no "!") if the developer prefers.
file 1:
subroutine driver
use mod1
real :: x, y
...
call sub1(x,y)
call sub2(y)
return
end subroutine
file 2:
module mod1
private
real :: var, var2
public sub1, sub2

contains
subroutine sub1(a,b)
...
return
end subroutine

subroutine sub2(a)
...
return
end subroutine

end module

The number, type, and dimensionality of the arguments passed to sub1 and sub2 are automatically checked by the compiler.
The final reason to store multiple routines and their data in a single module is that the scope of the data defined in the module can be limited to only the routines which are also in the module. This is accomplished with the "private" clause.
If none of the above conditions hold, it is not acceptable to simply glue together a bunch of functions or subroutines in a single file.
Content Rules
!-----------------------------------------------------------------------
!
! Purpose:
! <Say what the routine does>
!
! Method:
! <Describe the algorithm(s) used in the routine.>
! <Also include any applicable external references.>
!
! Author: <Who is primarily responsible for the code>
!
!-----------------------------------------------------------------------
Inclusion of the "Method" portion is not required when not applicable, such as a module which contains data but no subroutines. Note also that the "Author" portion is expected to be filled in by hand, *not* automatically by the cvs variable "$Author".
subroutine sub1 (x, y, z)
implicit none
real(r8), intent(in) :: x
real(r8), intent(out) :: y
real(r8), intent(inout) :: z

y = x
z = z + x

return
end

Package Coding Rules

The term "package" in the following rules refers to a routine or group of routines which takes a well-defined set of input and produces a well-defined set of output. A package can be large, such as a dynamics package, which computes large scale advection for a single timestep. Or it could be relatively small, such as a parameterization to compute the effects of gravity wave drag.

subroutine sub
logical first/.true./
if (first) then
   first = .false.
   <set time-invariant values>
end if
integer, parameter :: r8 = selected_real_kind(12)
integer, parameter :: i8 = selected_int_kind(13)
Thus, any variable declared real(r8) will be of sufficient size to maintain 12 decimal digits in their mantissa. Likewise, integer variables declared integer(i8) will be able to represent an integer of at least 13 decimal digits. Note that the names r8 and i8 defined above are meant to reflect the size in bytes of variables which are subsequently defined with that "kind" value.
real(r8) :: arr(1)
where "arr" is an input argument into which the user wishes to index beyond 1. Use of the (*) construct in array dimensioning to circumvent this problem is forbidden because it effectively disables array bounds checking.
The preferable mechanism for dynamic memory allocation is automatic arrays, as opposed to ALLOCATABLE or POINTER arrays for which memory must be explicitly allocated and deallocated. An example of an automatic array is:
subroutine sub(n)
real :: a(n)
...
return
end
The same routine using an allocatable array would look like:
subroutine sub(n)
real, allocatable :: a(:)
allocate(a(n))
...
deallocate(a)
return
end