5. Chris's Notes...

           MITgcmUV Packages
           =================

  Optional parts of code are separated from
the MITgcmUV core driver code and organised into
packages. The packaging structure provides a mechanism for
maintaining suites of code, specific to particular
classes of problem, in a way that is cleanly
separated from the generic fluid dynamical engine.

 The MITgcmUV packaging structure is describe
below using generic package names ${pkg}.
A concrete examples of a package is the code
for implementing GM/Redi mixing. This code uses
the package name
*   ${PKG} = GMREDI
*   ${pkg} = gmredi
*   ${Pkg} = gmRedi

Package states
==============

 Packages can be any one of four states, included,
 excluded, enabled, disabled as follows:

 included(excluded) compile time state which
                    includes(excludes) package
                    code and routine calls from
                    compilation/linking etc...

 enabled(disabled)  run-time state which
                    enables(disables) package code
                    execution.

 Every call to a ${pkg}_... routine from outside the package
 should be placed within both a
 #ifdef ALLOW_${PKG} ... block and a
 if ( use${Pkg} ) ... then block.
 Package states are generally not expected to change during
 a model run.

Package structure
=================

o  Each package gets its runtime configuration
   parameters from a file named "data.${pkg}"
   Package runtime config. options are imported
   into a common block held in a header file
   called "${PKG}.h".
   Note: In some packages, the header file "${PKG}.h" is splitted
   into "${PKG}_PARAMS.h" that contains the package parameters and
   ${PKG}_VARS.h" for the field arrays.

o  The core driver part of the model can check
   for runtime enabling or disabling of individual packages
   through logical flags use${Pkg}.
   The information is loaded from a
   global package setup file called "data.pkg".
   The use${Pkg} flags are not used within
   individual packages.

o  Included in "${PKG}.h" is a logical flag
   called ${Pkg}IsOn. The "${PKG}.h" header file can be imported
   by other packages to check dependencies and requirements
   from other packages ( see "Package Boot Sequence" section).
   NOTE: This procedure is not presently implemented,
   ----- neither for kpp nor for gmRedi.

CPP Flags
=========

    1. Within the core driver code flags of the form
       ALLOW_${PKG} are used to include or exclude
       whole packages. The ALLOW_${PKG} flags are included
       from a PACKAGES_CONFIG.h file that is automatically
       generated by genmake2 (see genmake2 section).
       held in-line in the CPP_OPTIONS.h header file.
       e.g.

       Core model code .....

       #include "PACKAGES_CONFIG.h"
       #include "CPP_OPTIONS.h"
         :
         :
         :

       #ifdef ALLOW_${PKG}
         if ( use${Pkg} ) CALL ${PKG}_DO_SOMETHING(...)
       #endif

    2. Within an individual package a header file,
       "${PKG}_OPTIONS.h", is used to set CPP flags
       specific to that package. It also includes
       "PACKAGES_CONFIG.h" and "CPP_OPTIONS.h".

Package Boot Sequence
=====================

    Calls to package routines within the core code timestepping
    loop can vary. However, all packages follow a required
    "boot" sequence outlined here:

    1. S/R PACKAGES_BOOT()
            :
        CALL OPEN_COPY_DATA_FILE( 'data.pkg', 'PACKAGES_BOOT', ... )

    2. S/R PACKAGES_READPARMS()
            :
        #ifdef ALLOW_${PKG}
          if ( use${Pkg} )
     &       CALL ${PKG}_READPARMS( retCode )
        #endif

    3. S/R PACKAGES_INIT_FIXED()
            :
        #ifdef ALLOW_${PKG}
          if ( use${Pkg} )
     &       CALL ${PKG}_INIT_FIXED( retCode )
        #endif

    4. S/R PACKAGES_CHECK()
            :
        #ifdef ALLOW_${PKG}
          if ( use${Pkg} )
     &       CALL ${PKG}_CHECK( retCode )
        #else
          if ( use${Pkg} )
     &       CALL PACKAGES_CHECK_ERROR('${PKG}')
        #endif

    5. S/R PACKAGES_INIT_VARIABLES()
            :
        #ifdef ALLOW_${PKG}
          if ( use${Pkg} )
     &       CALL ${PKG}_INIT_VARIA( )
        #endif

Package Output
==============
     6. S/R DO_THE_MODEL_IO

        #ifdef ALLOW_${PKG}
          if ( use${Pkg} )
     &       CALL ${PKG}_OUTPUT( )
        #endif

     7. S/R PACKAGES_WRITE_PICKUP()

        #ifdef ALLOW_${PKG}
          if ( use${Pkg} )
     &       CALL ${PKG}_WRITE_PICKUP( )
        #endif

Description
===========

      - ${PKG}_READPARMS()
    is responsible for reading
    in the package parameters file data.${pkg}, and storing
    the package parameters in "${PKG}.h" (or in "${PKG}_PARAMS.h").
    -> called from INITIALISE_FIXED in PACKAGES_READPARMS

     - ${PKG}_INIT_FIXED()
    is responsible for completing the internal setup of a package.
    -> called from INITIALISE_FIXED in PACKAGES_INIT_FIXED
    note: 1) some pkg use instead:
             CALL ${PKG}_INITIALISE  ( or the old form CALL ${PKG}_INIT )
          2) for simple pkg setup, this part is done inside ${PKG}_READPARMS

     - ${PKG}_CHECK()
    is responsible for validating
    basic package setup and inter-package dependencies.
    ${PKG}_CHECK can import other package parameters it may
    need to check. This is done through header files "${PKG}.h".
    It is assumed that parameters owned by other packages
    will not be reset during ${PKG}_CHECK().
    -> called from INITIALISE_FIXED in PACKAGES_CHECK

     - ${PKG}_INIT_VARIA()
    is responsible for fill-in all package variables with an initial value.
    Contains eventually a call to ${PKG}_READ_PICKUP that will read
    from a pickup file the package variables required to restart the model.
    This routine is called after the core model state has been completely
    initialised but before the core model timestepping starts.
    -> called from INITIALISE_VARIA in PACKAGES_INIT_VARIABLES
    note: the name ${PKG}_INIT_VARIA is not yet standard and some pkg
     use for e.g. ${PKG}_INI_VARS, ${PKG}_INIT_VARIABLES, or the old
     form ${PKG}_INIT

     - ${PKG}_OUTPUT( )
     is responsible for writing time-average fields to output files
     (but the cumulating step is done within the package main S/R).
     Can also contain other diagnostics (.e.g. CALL ${PKG}_MONITOR)
     and write snap-shot fields that are hold in common blocks. Other
     temporary fields are directly dump to file where they are available.
     NOTE: 1) the S/R old name ${PKG}_DIAGS is used in some packages
              but is beeing replaced by ${PKG}_OUTPUT
              to avoid confusion with pkg/diagnostics functionality.
           2) the output part is not yet in a standard form and might still
              evolve a lot.
    -> called within DO_THE_MODEL_IO

     - ${PKG}_WRITE_PICKUP()
     is responsible for writing a package pickup file when necessary for
     a restart. (found also the old name: ${PKG}_WRITE_CHECKPOINT )
    -> called from FORWARD_STEP and THE_MODEL_MAIN in PACKAGES_WRITE_PICKUP

Summary
=======

- CPP options:
  -----------------------
  * ALLOW_${PKG}         include/exclude package for compilation

- FORTRAN logical:
  -----------------------
  * use${Pkg}            enable package for execution at runtime
                         -> declared in PARAMS.h
  * ${Pkg}IsOn           for package cross-dependency check
                         -> declared in ${PKG}.h
                         N.B.: Not presently used!

- header files
  -----------------------
  * ${PKG}_OPTIONS.h     has further package-specific CPP options
  * ${PKG}.h             package-specific common block variables, fields
   or  ${PKG}_PARAMS.h   package-specific common block parameters
   and ${PKG}_VARS.h     package-specific common block fields

- FORTRAN source files
  -----------------------
  * ${pkg}_readparms.F    reads parameters from file data.${pkg}
  * ${pkg}_init_fixed.F   complete the package setup
  * ${pkg}_check.F        checks package dependencies and consistencies
  * ${pkg}_init_varia.F   initialises package-related fields
  * ${pkg}_... .F         package source code
  * ${pkg}_output.F       write output to file.
  * ${pkg}_write_pickup.F write a package pickup file to restart the model

  New: Subroutine in one package (pkgA) that only contains code which
       is connected to a 2nd package (pkgB) (e.g.: gmredi_diagnostics_init.F)
       will be named: pkgA_pkgB_something.F

- parameter file
  -----------------------
  * data.${pkg}          parameter file