--- manual/s_phys_pkgs/text/packages.tex	2004/02/11 18:09:17	1.1
+++ manual/s_phys_pkgs/text/packages.tex	2004/10/12 18:16:03	1.4
@@ -1,7 +1,11 @@
-% $Header: /home/ubuntu/mnt/e9_copy/manual/s_phys_pkgs/text/packages.tex,v 1.1 2004/02/11 18:09:17 edhill Exp $
+% $Header: /home/ubuntu/mnt/e9_copy/manual/s_phys_pkgs/text/packages.tex,v 1.4 2004/10/12 18:16:03 edhill Exp $
 % $Name:  $
 
 \section{Using MITgcm Packages}
+\label{sec:pkg:using}
+\begin{rawhtml}
+<!-- CMIREDIR:package_using: -->
+\end{rawhtml}
 
 The set of packages that will be used within a partiucular model can
 be configured using a combination of both ``compile--time'' and
@@ -63,15 +67,178 @@
 
 For run--time package control, MITgcm uses flags set through a
 \texttt{data.pkg} file.  While some packages (\textit{eg.}
-\texttt{debug}, \texttt{mnc}, \texttt{cost}) may have their own
-conventions, most follow a simple flag naming convention of the
-form:
+\texttt{debug}, \texttt{mnc}, \texttt{exch2}) may have their own usage
+conventions, most follow a simple flag naming convention of the form:
 \begin{verbatim}
   usePackageName=.TRUE.
 \end{verbatim}
 where the \texttt{usePackageName} variable can activate or disable the
-package at runtime.
+package at runtime.  As mentioned previously, packages must be
+included in order to be activated.  Generally, such mistakes will be
+detected and reported as errors by the code.  However, users should
+still be aware of the dependency.
 
 
-%\subsection{Modifying or Creating Packages}
+\section{Package Coding Standards}
+
+The following sections describe how to modify and/or create new MITgcm
+packages.
+
+\subsection{Packages are Not Libraries}
+
+To a beginner, the MITgcm packages may resemble libraries as used in
+myriad software projects.  While future versions are likely to
+implement packages as libraries (perhaps using FORTRAN90/95 syntax)
+the current packages (FORTRAN77) are \textbf{not} based upon any
+concept of libraries.
+
+\subsubsection{File Inclusion Rules}
+
+Instead, packages should be viewed only as directories containing
+``sets of source files'' that are built using some simple mechanisms
+provided by \texttt{genmake2}.  Conceptually, the build process adds
+files as they are found and proceeds according to the following rules:
+\begin{enumerate}
+\item \texttt{genmake2} locates a ``core'' or main set of source files
+  (the \texttt{-standarddirs} option sets these locations and the
+  default value contains the directories \texttt{eesupp} and
+  \texttt{model}).
+  
+\item \texttt{genmake2} then finds additional source files by
+  inspecting the contents of each of the package directories:
+  \begin{enumerate}
+  \item As the new files are found, they are added to a list of source
+    files.
+
+  \item If there is a file name ``collision'' (that is, if one of the
+    files in a package has the same name as one of the files
+    previously encountered) then the file within the newer (more
+    recently visited) package will superseed (or ``hide'') any
+    previous file(s) with the same name.
+    
+  \item Packages are visited (and thus files discovered) {\it in the
+      order that the packages are enabled} within \texttt{genmake2}.
+    Thus, the files in \texttt{PackB} may superseed the files in
+    \texttt{PackA} if \texttt{PackA} is enabled before \texttt{PackB}.
+    Thus, package ordering can be significant!  For this reason,
+    \texttt{genmake2} honors the order in which packages are
+    specified.
+  \end{enumerate}
+\end{enumerate}
+
+These rules were adopted since they provide a relatively simple means
+for rapidly including (or ``hiding'') existing files with modified
+versions.
+
+\subsubsection{Conditional Compilation and \texttt{PACKAGES\_CONFIG.h}}
+
+Given that packages are simply groups of files that may be added or
+removed to form a whole, one may wonder how linking (that is, FORTRAN
+symbol resolution) is handled.  This is the second way that
+\texttt{genmake2} supports the concept of packages.  Basically,
+\texttt{genmake2} creates a \texttt{Makefile} that, in turn, is able
+to create a file called \texttt{PACKAGES\_CONFIG.h} that contains a set
+of C pre-processor (or ``CPP'') directives such as:
+\begin{verbatim}
+   #undef  ALLOW_KPP
+   #undef  ALLOW_LAND
+   ...
+   #define ALLOW_GENERIC_ADVDIFF
+   #define ALLOW_MDSIO
+   ...
+\end{verbatim}
+These CPP symbols are then used throughout the code to conditionally
+isolate variable definitions, function calls, or any other code that
+depends upon the presence or absence of any particular package.
+
+An example illustrating the use of these defines is:
+\begin{verbatim}
+   #ifdef ALLOW_GMREDI
+         IF (useGMRedi) CALL GMREDI_CALC_DIFF(
+        I        bi,bj,iMin,iMax,jMin,jMax,K,
+        I        maskUp,
+        O        KappaRT,KappaRS,
+        I        myThid)
+   #endif
+\end{verbatim}
+which is included from the file
+\filelink{calc\_diffusivity.F}{model-src-calc_diffusivity.F}
+and shows how both the compile--time \texttt{ALLOW\_GMREDI} flag and the
+run--time \texttt{useGMRedi} are nested.
+
+There are some benefits to using the technique described here.  The
+first is that code snippets or subroutines associated with packages
+can be placed or called from almost anywhere else within the code.
+The second benefit is related to memory footprint and performance.
+Since unused code can be removed, there is no performance penalty due
+to unnecessary memory allocation, unused function calls, or extra
+run-time \texttt{IF (...)} conditions.  The major problems with this
+approach are the potentially difficult-to-read and difficult-to-debug
+code caused by an overuse of CPP statements.  So while it can be done,
+developers should exerecise some discipline and avoid unnecesarily
+``smearing'' their package implementation details across numerous
+files.
+
+
+\subsubsection{Package Startup or Boot Sequence}
+
+Calls to package routines within the core code timestepping loop can
+vary.  However, all packages should follow a required "boot" sequence
+outlined here:
+
+{\footnotesize
+\begin{verbatim}
+    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
+
+     6. S/R DO_THE_MODEL_IO
+
+        #ifdef ALLOW_${PKG}
+          if ( use${Pkg} )
+     &       CALL ${PKG}_DIAGS( )
+        #endif
+
+     7. S/R PACKAGES_WRITE_PICKUP()
+
+        #ifdef ALLOW_${PKG}
+          if ( use${Pkg} )
+     &       CALL ${PKG}_WRITE_PICKUP( )
+        #endif\end{verbatim}
+}
+
+
+\subsubsection{Package Startup or Boot Sequence}
 
