diff --git a/doc/DevelopersGuide/CCPP_VARIABLES_FV3.pdf b/doc/DevelopersGuide/CCPP_VARIABLES_FV3.pdf new file mode 100644 index 00000000..6bd695f2 Binary files /dev/null and b/doc/DevelopersGuide/CCPP_VARIABLES_FV3.pdf differ diff --git a/doc/DevelopersGuide/CCPP_VARIABLES_SCM.pdf b/doc/DevelopersGuide/CCPP_VARIABLES_SCM.pdf new file mode 100644 index 00000000..80af10e0 Binary files /dev/null and b/doc/DevelopersGuide/CCPP_VARIABLES_SCM.pdf differ diff --git a/doc/UsersGuide/SCM/Makefile b/doc/DevelopersGuide/Makefile similarity index 100% rename from doc/UsersGuide/SCM/Makefile rename to doc/DevelopersGuide/Makefile diff --git a/doc/UsersGuide/SCM/acknow.tex b/doc/DevelopersGuide/acknow.tex similarity index 55% rename from doc/UsersGuide/SCM/acknow.tex rename to doc/DevelopersGuide/acknow.tex index 68304270..1dba3834 100644 --- a/doc/UsersGuide/SCM/acknow.tex +++ b/doc/DevelopersGuide/acknow.tex @@ -8,11 +8,11 @@ \textcolor{darkgray}{\LARGE Acknowledgement} \vspace*{1cm}\par -If significant help was provided via the HWRF helpdesk for work resulting in a publication, please acknowledge the Developmental Testbed Center Hurricane Team.\\ +If significant help was provided via the GMTB helpdesk for work resulting in a publication, please acknowledge the Developmental Testbed Center GMTB Team.\\ \vspace*{1cm}\par For referencing this document please use:\\ \vspace*{1cm}\par -Biswas, M. K., L. Carson, K. Newman, L. Bernardet, C. Holt, 2016: Community HWRF Users' Guide V3.8a, NOAA Technical Memorandum OAR GSD-47, 149 pp., http://doi.org/10.7289/V5/TM-OAR-GSD-47. +Heinzeller, D., L. Bernardet, L. Carson, and G. Firl, 2018. Common Community Physics Package (CCPP) v1.0 Developers' Guide. 15pp. Available at https://dtcenter.org/gmtb/users/ccpp/docs/CCPP-DevGuide-v1.pdf \end{flushleft} \end{titlepage} diff --git a/doc/DevelopersGuide/chap_appendix.tex b/doc/DevelopersGuide/chap_appendix.tex new file mode 100644 index 00000000..861284b6 --- /dev/null +++ b/doc/DevelopersGuide/chap_appendix.tex @@ -0,0 +1,2 @@ +\chapter{Appendix}\label{appendix} + diff --git a/doc/DevelopersGuide/chap_hostmodel.tex b/doc/DevelopersGuide/chap_hostmodel.tex new file mode 100644 index 00000000..9cb745ed --- /dev/null +++ b/doc/DevelopersGuide/chap_hostmodel.tex @@ -0,0 +1,285 @@ +\chapter{Integrating CCPP with a host model} +\label{chap_hostmodel} +\setlength{\parskip}{12pt} +%\label{section: addhostmodel} +This chapter describes the process of connecting a host model with the pool of CCPP physics schemes through the CCPP framework. This work can be split into several distinct steps outlined in the following sections. + +\section{Checking variable requirements on host model side} +The first step consists of making sure that the necessary variables for running the CCPP physics schemes are provided by the host model. A list of all variables required for the current pool of physics can be found in \execout{ccpp-framework/doc/DevelopersGuide/CCPP\_VARIABLES\_XYZ.pdf} (\execout{XYZ}: SCM, FV3). In case a required variable is not provided by the host model, there are several options: +\begin{itemize} +\item If a particular variable is only required by schemes in the pool that will not get used, these schemes can be commented out in the ccpp prebuild config (see Sect.~\ref{sec_addscheme}). +\item If a variable can be calculated from existing variables in the model, an interstitial scheme (usually called \execsub{scheme\_name\_pre}) can be created that calculates the missing variable. However, the memory for this variable must be allocated on the host model side (i.\,e. the variable must be defined but not initialized in the host model). Another interstitial scheme (usually called \execsub{scheme\_name\_post}) might be required to update variables used by the host model with the results from the new scheme. At present, adding interstitial schemes should be done in cooperation with the GMTB Help Desk (\url{gmtb-help@ucar.edu}). +\item In some cases, the declaration and calculation of the missing variable can be placed entirely inside the host model. Please consult with the GMTB Help Desk. +\end{itemize} + +At present, only two types of variable definitions are supported by the CCPP framework: +\begin{itemize} +\item Standard Fortran variables (\execout{character}, \execout{integer}, \execout{logical}, \execout{real}) defined in a module or in the main program. For \execout{character} variables, a fixed length is required. All others can have a \execout{kind} attribute of a kind type defined by the host model. +\item Derived data types defined in a module or the main program. +\end{itemize} +With the CCPP, it is possible to refer to components of derived types or to slices of arrays in the metadata table (see Listing~\ref{lst_metadata_table_hostmodel} in the following section for an example). + +\section{Adding metadata variable tables for the host model} +In order to establish the link between host model variables and physics scheme variables, the host model must provide metadata tables similar to those presented in Sect.~\ref{sec_writescheme}. The host model can have multiple metadata tables or just one, but for each variable required by the pool of CCPP physics schemes, one and only one entry must exist on the host model side. The connection between a variable in the host model and in the physics scheme is made through its \execout{standard\_name}. + +The following requirements must be met when defining variables in the host model metadata tables: +\begin{itemize} +\item The \execout{standard\_name} must match that of the target variable in the physics scheme. +\item The type, kind, shape and size of the variable (as defined in the host model Fortran code) must match that of the target variable. +\item The attributes \execout{units}, \execout{rank}, \execout{type} and \execout{kind} in the host model metadata table must match those in the physics scheme table. +\item The attributes \execout{optional} and \execout{intent} must be set to \execout{F} and \execout{none}, respectively. +\item The \execout{local\_name} of the variable must be set to the name the host model cap (see Sect.~\ref{sec_hostmodel_cap}) uses to refer to the variable. +\item The name of the metadata table must match the name of the module or program in which the variable is defined, or the name of the derived data type if the variable is a component of this type. +\item For metadata tables describing module variables, the table must be placed inside the module. +\item For metadata tables describing components of derived data types, the table must be placed immediately before the type definition. +\end{itemize} +Listing~\ref{lst_metadata_table_hostmodel} provides examples for host model metadata tables. +\begin{sidewaysfigure} +\begin{lstlisting}[language=Fortran, + %basicstyle=\scriptsize\fontfamily{qcr}\fontshape{n}\fontseries{l}\selectfont + basicstyle=\scriptsize\ttfamily, + label=lst_metadata_table_hostmodel, + caption=Example metadata table for a host model] + module example_vardefs + + implicit none + +!> \section arg_table_example_vardefs +!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | +!! |------------|---------------|-----------|-------|------|-----------|--------|--------|----------| +!! | ex_int | example_int | ex. int | none | 0 | integer | | none | F | +!! | ex_real1 | example_real1 | ex. real | m | 2 | real | kind=8 | none | F | +!! | errmsg | error_message | err. msg. | none | 0 | character | len=64 | none | F | +!! | errflg | error_flag | err. flg. | flag | 0 | logical | | none | F | +!! + + integer, parameter :: r15 = selected_real_kind(15) + integer :: ex_int + real(kind=8), dimension(:,:) :: ex_real1 + character(len=64) :: errmsg + logical :: errflg + +! Derived data types + +!> \section arg_table_example_ddt +!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | +!! |------------|---------------|-----------|-------|------|-----------|--------|--------|----------| +!! | ext%l | example_flag | ex. flag | flag | 0 | logical | | none | F | +!! | ext%r | example_real3 | ex. real | kg | 2 | real | r15 | none | F | +!! | ext%r(:,1) | example_slice | ex. slice | kg | 1 | real | r15 | none | F | +!! + type example_ddt + logical :: l + real, dimension(:,:) :: r + end type example_ddt + + type(example_ddt) :: ext + + end module example_vardefs +\end{lstlisting} +\end{sidewaysfigure} + +\section{Writing a host model cap for the CCPP} +\label{sec_hostmodel_cap} +The purpose of the host model cap is to abstract away the communication between the host model and the CCPP physics schemes. While CCPP calls can be placed directly inside the host model code, it is recommended to separate the cap in its own module for clarity and simplicity. The host model cap is responsible for: +\begin{description} +\item[\textbf{Allocating memory for variables needed by physics.}] This is only required if the variables are not allocated by the host model, for example for interstitial variables used exclusively for communication between the physics schemes. +\item[\textbf{Allocating the \execout{cdata} structure.}] The \execout{cdata} structure handles the data exchange between the host model and the physics schemes and must be defined in the host model cap or another suitable location in the host model. The \execout{cdata} variable must be persistent in memory. Note that \execout{cdata} is not restricted to being a scalar but can be a multi-dimensional array, depending on the needs of the host model. For example, a model that uses a 1-dimensional array of blocks for better cache-reuse may require \execout{cdata} to be a 1-dimensional array of the same size. Another example of a multi-dimensional array of \execout{cdata} is in the GMTB SCM, which uses a 1-dimensional \execout{cdata} array for $N$ independent columns. +\item[\textbf{Calling the suite initialization subroutine.}] The suite initialization subroutine takes two arguments, the name of the runtime suite definition file (of type \execout{character}) and the name of the \execout{cdata} variable that must be allocated at this point. +\item[\textbf{Populating the \execout{cdata} structure.}] Each variable required by the physics schemes must be added to the \execout{cdata} structure on the host model side. This is an automated task and accomplished by inserting a preprocessor directive +\begin{lstlisting}[language=Fortran] +#include ccpp_modules.inc +\end{lstlisting} +at the top of the cap (before \execout{implicit none}) to load the required modules (e.\,g. module \execout{example\_vardefs} in listing~\ref{lst_metadata_table_hostmodel}), and a second preprocessor directive +\begin{lstlisting}[language=Fortran] +#include ccpp_fields.inc +\end{lstlisting} +after the \execout{cdata} variable and the variables required by the physics schemes are allocated. + +\emph{Note.} The current implementations of CCPP in SCM and FV3 require a few manual additions of variables to the \execout{cdata} structure to complete the CCPP suite initialization step. These are special cases that will be addressed in the future. +\item[\textbf{Providing interfaces to call CCPP for the host model.}] The cap must provide functions or subroutines that can be called at the appropriate places in the host model (dycore) time integration loop and that internally call \execout{ccpp\_run} and handle any errors returned. +\end{description} +Listing~\ref{lst_host_cap_template} contains a simple template of a host model cap for CCPP, which can also be found in \execout{ccpp-framework/doc/DevelopersGuide/host\_cap\_template.F90}. +\begin{figure} +\lstinputlisting[language=Fortran, + %basicstyle=\scriptsize\fontfamily{qcr}\fontshape{n}\fontseries{l}\selectfont + basicstyle=\scriptsize\ttfamily, + label=lst_host_cap_template, + caption=Fortran template for a CCPP host model cap]{./host_cap_template.F90} +\end{figure} + +\section{Configuring and running the CCPP prebuild script} +\label{sec_ccpp_prebuild_config} +The CCPP prebuild script \execout{ccpp-framework/scripts/ccpp\_prebuild.py} is the central piece of code that connects the host model with the CCPP physics schemes (see Figure~\ref{fig_ccpp_design_with_ccpp_prebuild}). This script must be run before compiling the CCPP physics library, the CCPP framework and the host model cap. The CCPP prebuild script automates several tasks based on the information collected from the metadata tables on the host model side and from the individual physics schemes: +\begin{itemize} +\item Compiles a list of variables required to run all schemes in the CCPP physics pool. +\item Compiles a list of variables provided by the host model. +\item Matches these variables by their \execout{standard\_name}, checks for missing variables and mismatches of their attributes (e.\,g., units, rank, type, kind) and processes information on optional variables (see also Sect.~\ref{sec_writescheme}). +\item Creates Fortran code (\execout{ccpp\_modules.inc}, \execout{ccpp\_fields.inc}) that stores pointers to the host model variables in the \execout{cdata} structure. +\item Auto-generates the caps for the physics schemes. +\item Populates makefiles with schemes and caps. +\end{itemize} +\begin{figure}[h] +\centerline{\includegraphics[width=0.95\textwidth]{./images/ccpp_design_with_ccpp_prebuild.pdf}} +\caption{Role and position of the CCPP prebuild script and the \execout{cdata} structure in the software architecture of an atmospheric modeling system.}\label{fig_ccpp_design_with_ccpp_prebuild} +\end{figure} + +In order to connect CCPP with a host model \execsub{XYZ}, a Python-based configuration file for this model must be created in the directory \execout{ccpp-framework/scripts} by, for example, copying an existing configuration file in this directory, for example +\begin{lstlisting}[language=bash] +cp ccpp_prebuild_config_FV3.py ccpp_prebuild_config_XYZ.py +\end{lstlisting} +and add \execout{HOST\_MODEL=XYZ} to section \execout{User definitions} in \execout{ccpp\_prebuild.py}. + +The configuration in \execout{ccpp\_prebuild\_config\_XYZ.py} depends largely on (a) the directory structure of the host model itself, (b) where the \execout{ccpp-framework} and the \execout{ccpp-physics} directories are located relative to the directory structure of the host model, and (c) from which directory the \execout{ccpp\_prebuild.py} script is executed before/during the build process (this is referred to as \execout{basedir} in \execout{ccpp\_prebuild\_config\_XYZ.py}). + +Here, it is assumed that both \execout{ccpp-framework} and \execout{ccpp-physics} are located in the top-level directory of the host model, and that \execout{ccpp\_prebuild.py} is executed from the same top-level directory (recommended setup). The following variables need to be configured in \execout{ccpp\_prebuild\_config\_XYZ.py}, here shown for the example of SCM: +\begin{lstlisting}[language=python] +# Add all files with metadata tables on the host model side, +# relative to basedir = top-level directory of host model +VARIABLE_DEFINITION_FILES = [ + 'scm/src/gmtb_scm_type_defs.f90', + 'scm/src/gmtb_scm_physical_constants.f90' + ] + +# Add all physics scheme files relative to basedir +SCHEME_FILES = [ + 'ccpp-physics/GFS_layer/GFS_initialize_scm.F90', + 'ccpp-physics/physics/GFS_DCNV_generic.f90', + ... + 'ccpp-physics/physics/sfc_sice.f', + ] + +# Auto-generated makefile snippet that contains all schemes +SCHEMES_MAKEFILE = 'ccpp-physics/CCPP_SCHEMES.mk' + +# CCPP host cap in which to insert the ccpp_field_add statements; +# determines the directory to place ccpp_{modules,fields}.inc +TARGET_FILES = [ + 'scm/src/gmtb_scm.f90', + ] + +# Auto-generated makefile snippet that contains all caps +CAPS_MAKEFILE = 'ccpp-physics/CCPP_CAPS.mk' + +# Directory where to put all auto-generated physics caps +CAPS_DIR = 'ccpp-physics/physics' + +# Optional arguments - only required for schemes that use +# optional arguments. ccpp_prebuild.py will throw an exception +# if it encounters a scheme subroutine with optional arguments +# if no entry is made here. Possible values are: 'all', 'none', +# or a list of standard_names: [ 'var1', 'var3' ]. +OPTIONAL_ARGUMENTS = { + #'subroutine_name_1' : 'all', + #'subroutine_name_2' : 'none', + #'subroutine_name_3' : [ 'var1', 'var2'], + } + +# HTML document containing the model-defined CCPP variables +HTML_VARTABLE_FILE = 'ccpp-physics/CCPP_VARIABLES.html' + +# LaTeX document containing the provided vs requested CCPP variables +LATEX_VARTABLE_FILE = 'ccpp-framework/doc/DevelopersGuide/CCPP_VARIABLES.tex' + +########################################### +# Template code to generate include files # +########################################### + +# Name of the CCPP data structure in the host model cap; +# in the case of SCM, this is a vector with loop index i +CCPP_DATA_STRUCTURE = 'cdata(i)' + +# Modules to load for auto-generated ccpp_field_add code +# in the host model cap (e.g. error handling) +MODULE_USE_TEMPLATE_HOST_CAP = \ +''' +use ccpp_errors, only: ccpp_error +''' + +# Modules to load for auto-generated ccpp_field_get code +# in the physics scheme cap (e.g. derived data types) +MODULE_USE_TEMPLATE_SCHEME_CAP = \ +''' + use machine, only: kind_phys + use GFS_typedefs, only: GFS_statein_type, ... +''' +\end{lstlisting} + +Once the configuration in \execout{ccpp\_prebuild\_config\_XYZ.py} is complete, run +\begin{lstlisting}[language=bash] +./ccpp-framework/scripts/ccpp_prebuild.py [--debug] +\end{lstlisting} +from the top-level directory. Without the debugging flag, the output should look similar to +\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] +INFO: Logging level set to INFO +INFO: Parsing metadata tables for variables provided by host model ... +INFO: Parsed variable definition tables in module gmtb_scm_type_defs +INFO: Parsed variable definition tables in module gmtb_scm_physical_constants +INFO: Metadata table for model SCM written to ccpp-physics/CCPP_VARIABLES.html +INFO: Parsing metadata tables in physics scheme files ... +INFO: Parsed tables in scheme GFS_initialize_scm +INFO: Parsed tables in scheme GFS_DCNV_generic_pre +... +INFO: Parsed tables in scheme sfc_sice +INFO: Checking optional arguments in physics schemes ... +INFO: Metadata table for model SCM written to ccpp-framework/doc/DevelopersGuide/CCPP_VARIABLES.tex +INFO: Comparing metadata for requested and provided variables ... +INFO: Generating module use statements ... +INFO: Generated module use statements for 3 module(s) +INFO: Generating ccpp_field_add statements ... +INFO: Generated ccpp_field_add statements for 394 variable(s) +INFO: Generating include files for host model cap scm/src/gmtb_scm.f90 ... +INFO: Generated module-use include file scm/src/ccpp_modules.inc +INFO: Generated fields-add include file scm/src/ccpp_fields.inc +INFO: Generating schemes makefile snippet ... +INFO: Added 38 schemes to makefile ccpp-physics/CCPP_SCHEMES.mk +INFO: Generating caps makefile snippet ... +INFO: Added 66 auto-generated caps to makefile ccpp-physics/CCPP_CAPS.mk +INFO: CCPP prebuild step completed successfully. +\end{lstlisting} + +\section{Building the CCPP physics library and software framework} +\label{sec_ccpp_build} +\subsection{Preface -- word of caution} +As of now, the CCPP physics library and software framework are built as part of the host model (SCM, FV3GFS). The SCM uses a cmake build system for both the CCPP physics library and the CCPP software framework, while FV3GFS employs a traditional make build system for the CCPP physics library and a cmake build system for the CCPP software framework. Accordingly, \execout{CMakeLists.txt} files in the \execout{ccpp-physics} directory tree refer to an SCM build, while \execout{makefile} files refer to an FV3GFS build. Work is underway to provide a universal build system based on cmake that can be used with all host models + +It should be noted that the current build systems do not make full use of the makefile snippets auto-generated by \execout{ccpp\_prebuild.py} (c.\,f. previous section). The SCM uses hardcoded lists of physics schemes and auto-generated physics scheme caps, while FV3GFS makes use of the auto-generated list of physics scheme caps but uses a hardcoded list of physics scheme files. This is also due to the fact that script \execout{ccpp\_prebuild.py} at the moment only produces traditional \execout{makefile} snippets (e.\,g. \execout{CCPP\_SCHEMES.mk} and \execout{CCPP\_CAPS.mk}). Work is underway to create include files suitable for cmake for both schemes and caps, and to integrate these into the build system. +\subsection{Build steps}\label{sec_ccpp_build_steps} +The instructions laid out below to build the CCPP physics library and CCPP software framework independently of the host model make use of the cmake build system, which is also used with the GMTB single column model SCM. Several steps are required in the following order: +\begin{description} +\item[\textbf{Recommended directory structure.}] As mentioned in Section~\ref{sec_ccpp_prebuild_config}, we recommend placing the two directories (repositories) \execout{ccpp-framework} and \execout{ccpp-physics} in the top-level directory of the host model, and to adapt the CCPP prebuild config such that it can be run from the top-level directory. +\item[\textbf{Set environment variables.}] In general, the CCPP requires the \execout{CC} and \execout{FC} variables to point to the correct compilers. If threading (OpenMP) will be used inside the CCPP physics or the host model calling the CCPP physics (see below), OpenMP-capable compilers must be used here. The setup scripts for SCM in \execout{scm/etc} provide useful examples for the correct environment settings (note that setting \execout{NETCDF} is not required for CCPP, but may be required for the host model). +\item[\textbf{Configure and run \exec{ccpp\_prebuild.py}.}] This step is described in detail in Sect.~\ref{sec_ccpp_prebuild_config}. +\item[\textbf{Build CCPP framework.}] The following steps outline a suggested way to build the CCPP framework: +\begin{lstlisting}[language=bash] +cd ccpp-framework +mkdir build && cd build +cmake -DCMAKE_INSTALL_PREFIX=$PWD .. +# add -DOPENMP=1 before .. for OpenMP build +# add -DCMAKE_BUILD_TYPE=Debug before .. for debug build +make install +# add VERBOSE=1 after install for verbose output +\end{lstlisting} +\item[\textbf{Update environment variables.}] The previous install step creates directories \execout{include} and \execout{lib} inside the build directory. These directories and the newly built library \execout{libccpp.so} need to be added to the environment variables \execout{FFLAGS} and \execout{LDFLAGS}, respectively (example for bash, assuming the current directory is still the above build directory): +\begin{lstlisting}[language=bash] +export FFLAGS="-I$PWD/include -I$PWD/src $FFLAGS" +export LDFLAGS="-L$PWD/lib -lccpp" +\end{lstlisting} +\item[\textbf{Build CCPP physics library.}] Starting from the build directory \execout{ccpp-framework/build}: +\begin{lstlisting}[language=bash] +cd ../.. # back to top-level directory +cd ccpp-physics +mkdir build && cd build +cmake .. +# add -DOPENMP=1 before .. for OpenMP build +make +# add VERBOSE=1 after install for verbose output +\end{lstlisting} +\end{description} +\subsection{Optional: Integration with host model build system} +Following the steps outlined Section~\ref{sec_ccpp_build_steps}, the include files and the library \execout{libccpp.so} that the host model needs to be compiled/linked against to call the CCPP physics through the CCPP framework are located in \execout{ccpp-framework/build/include} and \execout{ccpp-framework/build/lib}. Note that there is no need to link the host model to the CCPP physics library in \execout{ccpp-physics/build}, as long as it is in the search path of the dynamic loader of the OS (for example by adding the directory \execout{ccpp-physics/build} to the \execout{LD\_LIBRARY\_PATH} environment variable). This is because the CCPP physics library is loaded dynamically by the CCPP framework using the library name specified in the runtime suite definition file (see the GMTB Single Column Model Technical Guide v1.0, Chapter 6.1.3, (\url{https://dtcenter.org/gmtb/users/ccpp/docs/}) for further information) + +Thus, setting the environment variables \execout{FFLAGS} and \execout{LDFLAGS} as in Sect.~\ref{sec_ccpp_build_steps} should be sufficient to compile the host model with its newly created host model cap (Sect.~\ref{sec_hostmodel_cap}) and connect to the CCPP library and framework. + +For a complete integration of the CCPP infrastructure and physics library build systems in the host model build system, users are referred to the existing implementations in the GMTB SCM. + diff --git a/doc/DevelopersGuide/chap_intro.tex b/doc/DevelopersGuide/chap_intro.tex new file mode 100644 index 00000000..51b86ce0 --- /dev/null +++ b/doc/DevelopersGuide/chap_intro.tex @@ -0,0 +1,12 @@ +\chapter{Introduction}\label{chap_introduction} +\setlength{\parskip}{12pt} + +The Common Community Physics Package (CCPP) is designed to facilitate the implementation of physics innovations in state-of-the-art atmospheric models, the use of various models to develop physics, and the acceleration of transition of physics innovations to operational NOAA models. The CCPP consists of two separate software packages, the pool of CCPP-compliant physics schemes (\execout{ccpp-physics}) and the framework (driver) that connects the physics schemes with a host model (\execout{ccpp-framework}). + +The connection between the host model and the physics schemes through the CCPP framework is realized with caps on both sides as illustrated in Fig.~\ref{fig_ccpp_design_with_ccpp_prebuild} in Chapter~\ref{chap_hostmodel}. While the caps to the individual physics schemes are auto-generated, the cap that connects the framework (Physics Driver) to the host model must be created manually. For more information about the CCPP design and implementation, please see the CCPP Design Overview at {\url{https://dtcenter.org/gmtb/users/ccpp/docs/}}. + +This document serves two purposes, namely to describe the technical work of writing a CCPP-compliant physics scheme and adding it to the pool of CCPP physics schemes (Chapter~\ref{chap_schemes}), and to explain in detail the process of connecting an atmospheric model (host model) with the CCPP (Chapter~\ref{chap_hostmodel}). For further information and an example for integrating CCPP with a host model, the reader is referred to the GMTB Single Column Model (SCM) User and Technical Guide v1.0 available at {\url{https://dtcenter.org/gmtb/users/ccpp/docs}}. + +At the time of writing, the CCPP is supported for use with the GMTB Single Column Model (SCM). Support for use of CCPP with the experimental version of NCEP's Global Forecast System (GFS) that employs the Finite-Volume Cubed-Sphere dynamical core (FV3GFS) is expected in future releases. + +The GMTB welcomes contributions to CCPP, whether those are bug fixes, improvements to existing parameterizations, or new parameterizations. There are two aspects of adding innovations to the CCPP: technical and programmatic. This Developer's Guide explains how to make parameterizations technically compliant with the CCPP. Acceptance in the master branch of the CCPP repositories, and elevation of a parameterization to supported status, depends on a set of scientific and technical criteria that are under development as part of the incipient CCPP Governance. Contributions can be made in form of git pull requests to the development repositories but before initiating a major development for the CCPP please contact GMTB at \url{gmtb-help@ucar.edu} to create an integration and transition plan. For further information, see the Developer's Corner for CCPP at \url{https://dtcenter.org/gmtb/users/ccpp/developers/index.php}. Note that while the pool of CCPP physics and the CCPP framework are managed by the Global Model Test Bed (GMTB) and governed jointly with partners, the code governance for the host models lies with their respective organizations. Therefore, inclusion of CCPP within those models should be brought up to their governing bodies. \ No newline at end of file diff --git a/doc/DevelopersGuide/chap_schemes.tex b/doc/DevelopersGuide/chap_schemes.tex new file mode 100644 index 00000000..8d957647 --- /dev/null +++ b/doc/DevelopersGuide/chap_schemes.tex @@ -0,0 +1,117 @@ +\chapter{CCPP-compliant physics schemes} +\label{chap_schemes} +\setlength{\parskip}{12pt} + +\section{Writing a CCPP-compliant physics scheme} +\label{sec_writescheme} +The rules for writing a CCPP-compliant scheme are summarized in the following. Listing~\ref{lst_scheme_template} contains a Fortran template for a CCPP-compliant scheme, which can also be found in \execout{ccpp-framework/doc/DevelopersGuide/scheme\_template.F90}. + +General rules: +\begin{itemize} +\item Scheme must be in its own module (module name $=$ scheme name) and must have three entry points (subroutines) starting with the name of the module: module \execout{scheme\_template} $\rightarrow$ subroutines \execout{scheme\_template\_\{init,finalize,run\}}. Note: at present, the \execout{\_init} and \execout{\_finalize} routines can not be used, and are simply placeholders (c.\,f. listing~\ref{lst_scheme_template}) +\item Empty schemes (e.\,g. \execout{scheme\_template\_init} in listing~\ref{lst_scheme_template}) need no argument table. +\item Schemes in use require an argument table as below, the order of arguments in the table must be the same as in the argument list of the subroutine. +\item An argument table must precede the subroutine, and must start with +\begin{lstlisting}[language=Fortran] +!> \section arg_table_subroutine_name Argument Table +\end{lstlisting} +and end with a line containing only +\begin{lstlisting}[language=Fortran] +!! +\end{lstlisting} +\item All external information required by the scheme must be passed in via the argument list, i.e. no external modules (except if defined in the Fortran standards 95--2003). +\item If the width of an argument table exceeds 250 characters, wrap the argument table in CPP preprocessor directives: +\begin{lstlisting}[language=Fortran] +#if 0 +!> \section arg_table_scheme_template_run Argument Table +... +!! +#endif +\end{lstlisting} +\item Module names, scheme names and subroutine names are case sensitive. +\item For better readability, it is suggested to align the columns in the metadata table. +\end{itemize} + +Input/output variable (argument) rules: +\begin{itemize} +\item Variables available for CCPP physics schemes are identified by their unique \execout{standard\_name}. While an effort is made to comply with existing \execout{standard\_name} definitions of the CF conventions (\url{http://cfconventions.org}), additional names are introduced by CCPP (see below for further information). +\item A \execout{standard\_name} cannot be assigned to more than one local variable (\execout{local\_name}). +\item All information (units, rank) must match the specifications on the host model side. +\end{itemize} + +Coding rules: +\begin{itemize} +\item Code must comply to modern Fortran standards (Fortran 90/95/2003) +\item Use labeled \execout{end} statements for modules, subroutines and functions, example:\\ +\execout{module scheme\_template} $\rightarrow$ \execout{end module scheme\_template}. +\item Use \execout{implicit none}. +\item All \execout{intent(out)} variables must be initialized properly inside the subroutine. +\item No permanent state inside the module, i.\,e. no variables carrying the \execout{save} attribute. +\item No \execout{goto} statements. +\item Errors are handled by the host model using the two mandatory arguments \execout{errmsg} and \execout{errflg}. In the event of an error, assign a meaningful error message to \execout{errmsg} and set \execout{errflg} to a value other than 0. +\item Schemes are not allowed to abort/stop the program. +\item Schemes are not allowed to perform I/O operations (except for reading lookup tables or other information needed to initialize the scheme) +\item Line lengths of 120 characters are suggested for better readibility (exception: CCPP metadata argument tables). +\end{itemize} +Parallel programming rules: +\begin{itemize} +\item If OpenMP is used, the number of allowed threads must be provided by the + host model as an \execout{intent(in)} argument in the argument list. +\item If MPI is used, it is restricted to global communications: {barrier}, {broadcast}, {gather}, {scatter}, {reduce}; the MPI communicator must be provided by the host model as an \execout{intent(in)} argument in the argument list. +\item If Fortran coarrays are used, consult with the GMTB helpdesk at (\url{gmtb-help@ucar.edu}). +\end{itemize} +Scientific Documentation rules: +\begin{itemize} +\item Scientific documentation is not technically needed for a parameterization to work with the CCPP. However, inclusion of inline scientific documentation is highly recommended and necessary before a parameterization is submitted for inclusion in the CCPP. +\item Scientific documentation for CCPP parameterizations should be inline within the Fortran code using markups according to the Doxygen software. Reviewing the documentation for CCPP v1.0 parameterizations is a good way of getting started in writing documentation for a new scheme. +\item The CCPP Scientific Documentation can be converted to html format (see \url{https://dtcenter.org/gmtb/users/ccpp/docs/sci_doc/}. +\item For precise instructions on creating the scientific documentation, contact the GMTB helpdesk at \url{gmtb-help@ucar.edu}. +\end{itemize} +\begin{sidewaysfigure} +\lstinputlisting[language=Fortran, + %basicstyle=\scriptsize\fontfamily{qcr}\fontshape{n}\fontseries{l}\selectfont + basicstyle=\scriptsize\ttfamily, + label=lst_scheme_template, + caption=Fortran template for a CCPP-compliant scheme, + firstline=78]{./scheme_template.F90} +\end{sidewaysfigure} + +\section{Adding a new scheme to the CCPP pool} +\label{sec_addscheme} +This section describes briefly how to add a new scheme to the CCPP pool and use it with a host model that already supports the CCPP. +\begin{enumerate} +\item Identify the required variables for your target host model: for a list of variables available for host model \execsub{XYZ} (currently \execout{SCM} and \execout{FV3}), see \execout{ccpp-framework/doc/DevelopersGuide/CCPP\_VARIABLES\_XYZ.pdf}. Contact the GMTB helpdesk at \url{gmtb-help@ucar.edu} if you need additional variables that you believe should be provided by the host model or as part of a pre-/post-scheme (interstitial scheme) instead of being calculated from existing variables inside your scheme. +\item Identify if your new scheme requires additional interstitial code that must be run before/after the scheme and that cannot be part of the scheme itself, for example because of dependencies on other schemes and/or the order the scheme is run in the suite definition file. As of now, interstitial schemes should be created in cooperation with the GMTB helpdesk. +\item Follow the guidelines outlined in the previous section to make your scheme CCPP-compliant. Make sure to use an uppercase suffix \execout{.F90} to enable CPP preprocessing. +\item Locate the CCPP prebuild configuration files for the target host model, for example: +\begin{lstlisting}[language=Python] +ccpp-framework/scripts/ccpp_prebuild_config_FV3.py # for GFDL FV3 +ccpp-framework/scripts/ccpp_prebuild_config_SCM.py # FOR GMTB SCM +\end{lstlisting} +\item Add the new scheme to the list of schemes using the same path as the existing schemes: +\begin{samepage} +\begin{lstlisting}[language=Python] +SCHEME_FILES = [ + ... + '../some_relative_path/existing_scheme.F90', + '../some_relative_path/new_scheme.F90', + ... + ] +\end{lstlisting} +\end{samepage} +\item If the new scheme uses optional arguments, add information on which ones to use further down in the configuration file. See existing entries and documentation in the configuration file for the possible options: +\begin{lstlisting}[language=Python] +OPTIONAL_ARGUMENTS = { + 'SCHEME_NAME' : { + 'SCHEME_NAME_run' : [ + # list of all optional arguments in use for this model, by standard_name + ], + # instead of list [...], can also say 'all' or 'none' + }, + } +\end{lstlisting} +\item Place new scheme in the same location as existing schemes in the CCPP directory structure, e.\,g. \execout{../some\_relative\_path/new\_scheme.F90}. +\item Edit the runtime suite definition file (see, for example, GMTB Single Column Model Technical Guide v1.0, chapter 6.1.3, \url{https://dtcenter.org/gmtb/users/ccpp/docs}) and add the new scheme at the place it should be run. +\item Done! +\end{enumerate} +\textbf{Note:} Making a scheme CCPP-compliant is a necessary step for acceptance of the scheme in the pool of supported CCPP physics schemes, but does not guarantee it. Acceptance is subject to approval by a Governance committee and depends on scientific innovation, demonstrated added value, and compliance with the above rules. The criteria for acceptance of innovations into the CCPP is under development. For further information, please contact the GMTB helpdesk at \url{gmtb-help@ucar.edu}. diff --git a/doc/DevelopersGuide/host_cap_template.F90 b/doc/DevelopersGuide/host_cap_template.F90 new file mode 100644 index 00000000..e0564f92 --- /dev/null +++ b/doc/DevelopersGuide/host_cap_template.F90 @@ -0,0 +1,67 @@ +module example_ccpp_host_cap + + use ccpp_types, only: ccpp_t + use ccpp, only: ccpp_init, ccpp_finalize + use ccpp_fcall, only: ccpp_run + use ccpp_fields, only: ccpp_field_add + use iso_c_binding, only: c_loc + +! Include auto-generated list of modules for ccpp +#include "ccpp_modules.inc" + + implicit none + +! CCPP data structure + type(ccpp_t), save, target :: cdata + + public :: physics_init, physics_run, physics_finalize + +contains + + subroutine physics_init(ccpp_suite_name) + character(len=*), intent(in) :: ccpp_suite_name + integer :: ierr + ierr = 0 + + call ccpp_init(ccpp_suite_name, cdata, ierr) + if (ierr/=0) then + write(*,'(a)') "An error occurred in ccpp_init" + stop + end if + +! Include auto-generated list of calls to ccpp_field_add +#include "ccpp_fields.inc" + + end subroutine physics_init + + subroutine physics_run(step) + ! the step (currently called IPD step) to run as + ! defined in the runtime suite definition file + integer, intent(in) :: step + integer :: ierr + ierr = 0 + + call ccpp_run(cdata%suite%ipds(step), cdata, ierr) + ! future versions: call ccpp_run(cdata, step=step, ierr=ierr) + if (ierr/=0) then + ! errmsg is known because of #include ccpp_modules.inc + write(*,'(a,i0,a)') "An error occurred in physics step ", step, & + "; error message: '" // trim(errmsg) // "'" + stop + end if + + end subroutine physics_run + + subroutine physics_finalize() + integer :: ierr + ierr = 0 + + call ccpp_finalize(cdata, ierr) + if (ierr/=0) then + write(*,'(a)') "An error occurred in ccpp_finalize" + stop + end if + + end subroutine physics_finalize + +end module example_ccpp_host_cap diff --git a/doc/DevelopersGuide/images/ccpp_design_with_ccpp_prebuild.pdf b/doc/DevelopersGuide/images/ccpp_design_with_ccpp_prebuild.pdf new file mode 100644 index 00000000..a36d5e24 Binary files /dev/null and b/doc/DevelopersGuide/images/ccpp_design_with_ccpp_prebuild.pdf differ diff --git a/doc/UsersGuide/SCM/images/dtc_logo.png b/doc/DevelopersGuide/images/dtc_logo.png similarity index 100% rename from doc/UsersGuide/SCM/images/dtc_logo.png rename to doc/DevelopersGuide/images/dtc_logo.png diff --git a/doc/DevelopersGuide/main.tex b/doc/DevelopersGuide/main.tex new file mode 100644 index 00000000..8df6d911 --- /dev/null +++ b/doc/DevelopersGuide/main.tex @@ -0,0 +1,39 @@ +\documentclass[12pt,letterpaper,oneside]{scrbook} + +\usepackage{import} +\import{../common/}{gmtb.sty} + +\makeindex + +\hypersetup{ + pdfauthor={Dom Heinzeller / Ligia Bernardet / Laurie Carson / Grant Firl}, + pdftitle={Common Community Physics Package (CCPP)}, +} + +\begin{document} + +\frontmatter +\import{./}{title.tex} + +\clearpage +\thispagestyle{empty} +\import{./}{acknow.tex} + +\tableofcontents + +\import{./}{preface.tex} + +\mainmatter + +\import{./}{chap_intro.tex} +\import{./}{chap_schemes.tex} +\import{./}{chap_hostmodel.tex} + +\appendix + +\renewcommand{\thechapter}{\Alph{chapter}} +%\import{./}{chap_appendix.tex} + +\backmatter + +\end{document} diff --git a/doc/UsersGuide/SCM/preface.tex b/doc/DevelopersGuide/preface.tex similarity index 100% rename from doc/UsersGuide/SCM/preface.tex rename to doc/DevelopersGuide/preface.tex diff --git a/doc/DevelopersGuide/scheme_template.F90 b/doc/DevelopersGuide/scheme_template.F90 new file mode 100644 index 00000000..73d7022e --- /dev/null +++ b/doc/DevelopersGuide/scheme_template.F90 @@ -0,0 +1,125 @@ +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! CCPP-compliant physics scheme template +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +! +! General rules: +! +! - scheme must be in its own module (module name = scheme name) and must +! have three entry points (subroutines) starting with the name of the module: +! module scheme_template -> subroutines scheme_template_{init,finalize,run} +! +! - empty schemes (e.g., scheme_template_init below) do not need an argument table +! +! - schemes in use require an argument table as below; order of arguments in the +! table must be the same as in the argument list of the subroutine +! +! - all external information required by the scheme must be passed in via the +! argument list, i.e. NO 'use EXTERNAL_MODULE' statements +! +! - if width of argument tables exceeds 250 characters, wrap the table (but only +! the table) in CPP preprocessor directives #if 0 YOUR_TABLE #endif +! +! - for readibility, it is suggested to align the columns in the metadata table +! +! Input/output variable (argument) rules: +! +! - for a list of variables available for the specific host model, see table +! "TABLE_NAME_NUMBER_MISSING" [howto keep up to date?] in the CCPP developer's guide +! +! - a standard_name cannot be assigned to more than one local variable (local_name) +! +! - all information (units, rank, index ordering) must match the specifications +! on the host model side, but subslices can be used/added in the host model: +! HOST MODEL: real, dimension(:,:,:,:) :: hydrometeors +! +! +! Coding rules: +! +! - code must comply to modern Fortran standards (Fortran 90/95/2003) +! +! - use labeled 'end' statements for modules, subroutines and functions +! module scheme_template -> end module scheme_template +! +! - use implicit none +! +! - all intent(out) variables must be initialized properly inside the subroutine +! +! - NO permanent state inside the module, i.e. no variables carrying the 'save' attribute +! +! - NO 'goto' statements +! +! - errors are handled by the host model using the two mandatory arguments +! errmsg and errflg; in the event of an error, assign a meaningful error +! message to errmsg and set errflg to a value other than 0 +! +! - schemes are NOT allowed to abort/stop the program +! +! - schemes are NOT allowed to perform I/O operations (except for reading +! lookup tables / other information needed to initialize the scheme) +! +! - line lengths of 120 characters are suggested for better readibility +! (exception: CCPP metadata argument tables) +! +! Parallel programming rules: +! +! - if OpenMP is used, the number of allowed threads must be provided by the +! host model as an intent(in) argument in the argument list +! +! - if MPI is used, it is restricted to global communications: barrier, broadcast, +! gather, scatter, reduction; the MPI communicator must be provided by the +! host model as an intent(in) argument in the argument list +! - do NOT use MPI_COMM_WORLD +! - do NOT use any point-to-point communication +! +! - if Fortran coarrays are used, consult with the CCPP development team +! +!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + + module scheme_template + + contains + + subroutine scheme_template_init () + end subroutine scheme_template_init + + subroutine scheme_template_finalize() + end subroutine scheme_template_finalize + +!> \section arg_table_scheme_template_run Argument Table +!! | local_name | standard_name | long_name | units | rank | type | kind | intent | optional | +!! |------------|---------------|--------------------|-------|------|-----------|-------|--------|----------| +!! | errmsg | error_message | CCPP error message | none | 0 | character | len=* | out | F | +!! | errflg | error_flag | CCPP error flag | flag | 0 | integer | | out | F | +!! + subroutine scheme_template_run (errmsg, errflg) + + implicit none + + !--- arguments + ! add your arguments here + character(len=*), intent(out) :: errmsg + integer, intent(out) :: errflg + + !--- local variables + ! add your local variables here + + continue + + !--- initialize CCPP error handling variables + errmsg = '' + errflg = 0 + + !--- initialize intent(out) variables + ! initialize all intent(out) variables here + + !--- actual code + ! add your code here + + ! in case of errors, set errflg to a value != 0, + ! create a meaningfull error message and return + + return + + end subroutine scheme_template_run + + end module scheme_template diff --git a/doc/UsersGuide/SCM/title.tex b/doc/DevelopersGuide/title.tex similarity index 58% rename from doc/UsersGuide/SCM/title.tex rename to doc/DevelopersGuide/title.tex index 1826951b..59719469 100644 --- a/doc/UsersGuide/SCM/title.tex +++ b/doc/DevelopersGuide/title.tex @@ -5,20 +5,20 @@ \noindent \begin{center} -\textcolor{darkgray}{\bigsf Common Community Physics Package (CCPP) with Global Model Test Bed Single-Column Model\\} -\vspace*{1em}\par +\textcolor{darkgray}{\bigsf Common Community Physics Package\\[0.5ex] (CCPP)} +\vspace*{1em} -\textcolor{darkgray}{\bigst Quick Start Users' Guide \\v1.0} -\vspace*{1em}\par +\textcolor{darkgray}{\bigst Developers' Guide\\[0.5ex] v1.0} +\vspace*{1em} -\large{March 2018}\\[4em] +\large{April 2018}\\[4em] -Grant Firl, Laurie Carson\\ -\textit{\small{National Center for Atmospheric Research and Developmental Testbed Center}}\\[4em] - -Ligia Bernardet, Dominikus Heinzeller\\ +Dom Heinzeller, Ligia Bernardet\\ \textit{\small{CIRES/CU at NOAA/ESRL Global Systems Division and Developmental Testbed Center}}\\[4em] +Laurie Carson, Grant Firl\\ +\textit{\small{National Center for Atmospheric Research and Developmental Testbed Center}}\\[4em] + \vspace{4em} \includegraphics[width=0.4\textwidth]{images/dtc_logo.png}\\[2em] @@ -26,7 +26,3 @@ \end{center} \end{titlepage} \pagebreak{} - - - - diff --git a/doc/UsersGuide/SCM/chap_install.tex b/doc/UsersGuide/SCM/chap_install.tex deleted file mode 100644 index 0e16aa1d..00000000 --- a/doc/UsersGuide/SCM/chap_install.tex +++ /dev/null @@ -1,137 +0,0 @@ -\chapter{Software Installation} -\label{chapter: softwareinstall} -\setlength{\parskip}{12pt} -\label{section: softwareinstall} - - -\section{Overview} -The following components are included in this release: - -\begin{itemize} - \item CCPP physics - \item CCPP framework - \item GMTB Single Column Model -\end{itemize} - - -This chapter provides instructions for obtaining and compiling -the GMTB SCM. The SCM code calls CCPP-compliant -physics schemes through the CCPP framework code. As such, it requires the -CCPP framework code and physics code, both of which are included as -subdirectories within the SCM code. This package can be considered a simple example -for an atmospheric model to interact with physics through the CCPP. - -\section{Obtaining Code} - -The source code bundle for the CCPP and SCM is provided using github.com. This release repository contains the tested and supported version for general use. - -\begin{enumerate} - - \item Download a compressed file or clone the source using\\ - - \exec{git clone \url{https://[username]@github.com/NCAR/gmtb-scm-release}}\\ - - and enter your github password when prompted.\\ - - \item Change directory into the project.\\ - - \exec{cd gmtb-scm} - -\end{enumerate} - -The CCPP framework can be found in the ccpp-framework subdirectory at this level. The CCPP physics parameterizations can be found in the ccpp-physics subdirectory. - -If you would like to contribute as a developer to this project, please see the Developers Guide at:\\ - -\url{https://dtcenter.org/gmtb/users/ccpp/developers/index.php} - - -\section{System Requirements, Libraries, and Tools} -\label{section: systemrequirements} - -The source code for the SCM and CCPP component is in the form -of programs written in FORTRAN, FORTRAN 90, and C. In addition, the I/O relies on the netCDF -libraries. Beyond the standard scripts, the build system relies -on use of the Python scripting language, along with cmake, GNU make and date. - -The basic requirements for building and running the CCPP and SCM bundle are -listed below: - -\begin{itemize} - \item FORTRAN 90+ compiler - \item C compiler - \item cmake - \item netCDF v3.6+ - \begin{itemize} - \item if netCDF v4.1+ is used, HDF5 and SZIP libs may also be required -\end{itemize} - \item Python -\end{itemize} - - -Because these tools and libraries are typically the purview of -system administrators to install and maintain, they are considered -part of the basic system requirements. - - -There are several utility libraries provided in the SCM bundle, as external packages. These -are built during the compilation phase, and include - - -\begin{itemize} - \item bacio - \item sp - \item w3 - \item w3nco -\end{itemize} - - - -\subsection{Compilers} -The CCPP and SCM have been tested on a variety of -computing platforms. Currently the CCPP system is actively supported -on Linux and MacOS computing platforms using the Intel, PGI or GNU Fortran -compilers. Unforeseen build issues may occur when using older -compiler versions. Typically the best results come from using the -most recent version of a compiler. The "Known Issues" section of the -community website (\url{https://dtcenter.org/gmtb/users/ccpp/support/CCPP_KnownIssues.php}) provides notes regarding compiler support and known issues. - - - -\section{Compiling SCM with CCPP} - -The first step in compiling the CCPP and SCM is to match the physics variables, and build the physics caps needed to use them. Following this step, the top level build system will use \exec{cmake} to query system parameters and \exec{make} to compile the components. A platform-specific script is provided to load modules and set the user environment for common platforms. If you are not using one of these platforms, you will need to set up the same environment on your platform. - -\begin{enumerate} - \item Run the CCPP prebuild script to match required physics variables with those available from the dycore (SCM) and to generate physics caps and makefile segments.\\ - \exec{cd ccpp-framework/scripts} \\ - \exec{./ccpp\_prebuild.py}\\ - - \item Change directory to the top-level SCM directory.\\ - \exec{cd ../../gmtb-scm} \\ - \item Run the machine setup script if necessary. This script loads compiler modules (Fortran 2003-compliant Intel), netCDF module, etc. and sets compiler environment variables. \\ -For t/csh shell, \\ - \exec{source Theia\_setup.csh} or\\ - \exec{source Cheyenne\_setup.csh}\\ - -For bourne/bash shells,\\ - \exec{source Theia\_setup.sh} or\\ - \exec{source Cheyenne\_setup.sh}\\ - - \item Make a build directory and change into it. \\ - \exec{mkdir bin \&\& cd bin}\\ - - \item Invoke cmake on the source code to build. \\ - \exec{cmake ../src}\\ - \item Compile. \\ - \exec{make}\\ - -\end{enumerate} - -The resulting executable may be found at: - -\exec{./bin/gmtb-scm} - -If you encounter errors, please capture a log file from all of the steps, and contact the helpdesk at: \exec{gmtb-help@ucar.edu} - - diff --git a/doc/UsersGuide/SCM/chap_intro.tex b/doc/UsersGuide/SCM/chap_intro.tex deleted file mode 100644 index 6d225882..00000000 --- a/doc/UsersGuide/SCM/chap_intro.tex +++ /dev/null @@ -1,9 +0,0 @@ -\chapter{Introduction} -\setlength{\parskip}{12pt} -\section{CCPP Overview} - -The Common Community Physics Package (CCPP) is a library of physical parameterizations for atmospheric numerical models. It is distributed with a driver that enables its use with any host application. In this release, the CCPP has been bundled with the Global Model Test Bed Single Column Model (SCM) and contains all the physical parameterizations used in the operational NOAA Global Forecast System (GFS) implemented operationally in July 2017. - -This Quick Start Users' Guide provides basic instructions for using the CCPP with the GMTB SCM. Please refer to the release web page for further documentation and user notes. - -\url{https://dtcenter.org/gmtb/users/ccpp/index.php} \ No newline at end of file diff --git a/doc/UsersGuide/SCM/chap_run.tex b/doc/UsersGuide/SCM/chap_run.tex deleted file mode 100644 index 88356852..00000000 --- a/doc/UsersGuide/SCM/chap_run.tex +++ /dev/null @@ -1,63 +0,0 @@ -\chapter{Running SCM} -\label{chapter: runningscm} -\setlength{\parskip}{12pt} -\label{section: runningscm} - -\section{A sample test case} - -The CCPP uses a runtime, dynamically loaded physics library from which physical parameterizations can be selected at runtime. To utilize a given library (of CCPP-compliant!) physics parameterizations, first append the path to the physics suite libraries that you need -within the CCPP. For example, for the library that contains the CCPP-compliant parameterizations of the GFS that went operational in July 2017, -called gmtb-gfsphysics, use: -\begin{itemize} - \item for sh, bash - - \exec{export LD\_LIBRARY\_PATH=\$\{LD\_LIBRARY\_PATH\}:/path/to/build/directory/ccpp-physics}\\ - - \item for csh - - if appending: \\ - \exec{setenv LD\_LIBRARY\_PATH \$\{LD\_LIBRARY\_PATH\}:/path/to/build/directory/ccpp-physics} - - if setting: \\ - \exec{setenv LD\_LIBRARY\_PATH path/to/build/directory/ccpp-physics} -\end{itemize} - - -\section{Run the SCM with the supplied case} -The test case provided with this version of the SCM is TWP-ICE, the Tropical Warm Pool-International Cloud Experiment. The SCM will go through the time steps, applying forcing and calling the physics defined in the suite definition file. -There is a single command line argument required, which is the name of the case configuration file. For the provided case, that name is \exec{twpice}. - - \exec{./gmtb\_scm twpice} - -A netcdf output file is generated in the location specified in the case -configuration file. Any standard NetCDF file viewing or analysis tools may be used to -examine the output file (ncdump, ncview, NCL, etc). For the twpice case, it is located in: - -\exec{gmtb-scm/output\_twpice/output.nc} - -Additional details may be found in the SCM technical documention, including setting physics parameters, examining the output files, etc. - -\url{https://dtcenter.org/gmtb/users/ccpp/index.php} - - -\section{Setting up the physics suite} -A physics suite is defined using a Suite Definition File (SDF) located in -src/ccpp/examples. The SDF file is in XML format and contains the following information: a) suite name, b) number of suite -"parts" (suite parts exist so that an atmosphere "cap" can execute code between -calls to the physics driver), c) number of subcycles for each scheme (if -physics schemes require smaller time steps than the dynamics), and d) the scheme -names. Scheme names found in the SDF must correspond to schemes -located within the physics directory. - -Using a SDF in the SCM framework involves specifying its name in the case -configuration file to be used. For example, for the twpice case -(case\_config/twpice.nml), the variable 'physics suite' is set to the -suite name for using the GFS Physics with this case. - -NOTE: As mentioned in the 'Running' section above, since the schemes - are in their own libraries, you must specify the path to the compiled scheme - libraries that are being used in the suite by appending the LD\_LIBRARY\_PATH - (or DYLD\_LIBRARY\_PATH for Mac OS). Without this step, the scheme libraries will - not be found at runtime. - - diff --git a/doc/UsersGuide/SCM/main.tex b/doc/UsersGuide/SCM/main.tex deleted file mode 100644 index 6cd368d6..00000000 --- a/doc/UsersGuide/SCM/main.tex +++ /dev/null @@ -1,24 +0,0 @@ -\documentclass[12pt,letterpaper,oneside]{scrbook} - -\usepackage{import} -\usepackage{gmtb} - -\makeindex - -\begin{document} - -\frontmatter -\import{./}{title.tex} - -\tableofcontents - -\import{./}{preface.tex} - -\mainmatter - -\import{./}{chap_intro.tex} -\import{./}{chap_install.tex} -\import{./}{chap_run.tex} -\backmatter - -\end{document} diff --git a/doc/UsersGuide/SCM/gmtb.sty b/doc/common/gmtb.sty similarity index 62% rename from doc/UsersGuide/SCM/gmtb.sty rename to doc/common/gmtb.sty index 1d01bec9..b7b9539b 100644 --- a/doc/UsersGuide/SCM/gmtb.sty +++ b/doc/common/gmtb.sty @@ -3,13 +3,15 @@ \usepackage[english]{babel} \usepackage[T1]{fontenc} \usepackage{textcomp} +\usepackage{pstricks} \usepackage{color} +\usepackage{colortbl} \usepackage[automark,nouppercase]{scrpage2} %\usepackage{bera} \usepackage{baskervald} %\usepackage{helvet} %\usepackage{avant} -%\usepackage{lmodern} +\usepackage{lmodern} \usepackage{comment} \usepackage{vwcol} \usepackage{multicol} @@ -32,6 +34,8 @@ \usepackage{tikz} \usetikzlibrary{calc} \usepackage{hyperref} +\usepackage{rotating} +\usepackage{xfrac} % Colours \definecolor{white}{rgb}{1.0,1.0,1.0} @@ -44,16 +48,17 @@ \hypersetup{ pdfauthor={}, - pdftitle={GMTB CCPP Users Guide}, + pdftitle={}, pdfsubject={}, pdfkeywords={}, bookmarksnumbered=true, % Either of these.. I prefer the 2nd as this means % the colour of the text in the document overrides % whatever has been defined as urlcolor. - %colorlinks=true, - %urlcolor=black, - colorlinks=false, + colorlinks=true, + urlcolor=blue, + linkcolor=blue, + %colorlinks=false, pdfborder={0 0 0} } @@ -61,8 +66,8 @@ %\KOMAoptions{pagestyle=plain} % Define a font for the title, subtitles -\DeclareFixedFont{\bigsf}{T1}{phv}{b}{n}{1.2cm} -\DeclareFixedFont{\bigst}{T1}{phv}{b}{n}{1.0cm} +\DeclareFixedFont{\bigsf}{T1}{phv}{b}{n}{0.8cm} +\DeclareFixedFont{\bigst}{T1}{phv}{b}{n}{0.6cm} % Define a background stripe for the title page %\backgroundsetup{ % scale=1, @@ -84,18 +89,40 @@ %\pagestyle{plain} +%Formatting for code listings +\lstset{ + %basicstyle=\footnotesize\fontfamily{qcr}\fontshape{n}\fontseries{l}\selectfont, + basicstyle=\footnotesize\ttfamily, + %basicstyle=\footnotesize\fontfamily{txtt}, + stepnumber=1, + showstringspaces=false, + tabsize=1, + breaklines=true, + breakatwhitespace=false, + keywordstyle=\bfseries\color{green!40!black}, + commentstyle=\color{purple!40!black}, + identifierstyle=\color{blue}, + stringstyle=\color{orange}, + } + % Commands for writing code \newcommand{\exec}[1]{% What to type and execute -{\small\fontfamily{qcr}\fontshape{n}\fontseries{bx}\selectfont{#1}}} +{\small\ttfamily\fontshape{n}\fontseries{bx}\selectfont{#1}}} +%{\small\fontfamily{txtt}\fontshape{n}\fontseries{b}\selectfont{#1}}} +%{\small\fontfamily{qcr}\fontshape{n}\fontseries{bx}\selectfont{#1}}} \newcommand{\execout}[1]{% Output on a terminal -{\small\fontfamily{qcr}\fontshape{n}\fontseries{l}\selectfont{#1}}} +{\small\ttfamily\fontshape{n}\fontseries{m}\selectfont{#1}}} +%{\small\fontfamily{txtt}\fontshape{n}\fontseries{l}\selectfont{#1}}} +%{\small\fontfamily{qcr}\fontshape{n}\fontseries{l}\selectfont{#1}}} \newcommand{\execsub}[1]{% Variable that needs subsituting -{\small\fontfamily{qcr}\fontshape{sl}\fontseries{m}\selectfont{#1}}} +{\small\ttfamily\fontshape{sl}\fontseries{m}\selectfont{#1}}} +%{\small\fontfamily{txtt}\fontshape{sl}\fontseries{m}\selectfont{#1}}} +%{\small\fontfamily{qcr}\fontshape{sl}\fontseries{m}\selectfont{#1}}} -\newcommand{\vf}[1]{% Variable in a file -{\fontfamily{cmss}\fontshape{sl}\fontseries{m}\selectfont{#1}}} +%\newcommand{\vf}[1]{% Variable in a file +%{\fontfamily{cmss}\fontshape{sl}\fontseries{m}\selectfont{#1}}} % Create macro's for table font/style \newcolumntype{+}{>{\global\let\currentrowstyle\relax}} @@ -110,6 +137,8 @@ % Shorthand degree symbol \newcommand{\dgr}{$^{\circ}$} -% Change the default font to be Sans Serif + +% Change the default font to be Sans Serif %\renewcommand{\familydefault}{\sfdefault} + \sloppy diff --git a/schemes/check/CMakeLists.txt b/schemes/check/CMakeLists.txt index 4667e58b..4a5d4b34 100644 --- a/schemes/check/CMakeLists.txt +++ b/schemes/check/CMakeLists.txt @@ -61,6 +61,19 @@ add_custom_command( ) list(APPEND SOURCES ${CMAKE_CURRENT_BINARY_DIR}/check_test_cap.f90) +#------------------------------------------------------------------------------ +# The Fortran compiler/linker flag inserted by cmake to create shared libraries +# with the Intel compiler is deprecated (-i_dynamic), correct here. +# CMAKE_Fortran_COMPILER_ID = {"Intel", "PGI", "GNU", "Clang", "MSVC", ...} +if ("${CMAKE_Fortran_COMPILER_ID}" STREQUAL "Intel") + string(REPLACE "-i_dynamic" "-shared-intel" + CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS + "${CMAKE_SHARED_LIBRARY_CREATE_Fortran_FLAGS}") + string(REPLACE "-i_dynamic" "-shared-intel" + CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS + "${CMAKE_SHARED_LIBRARY_LINK_Fortran_FLAGS}") +endif() + # Guard for undefined/empty CMAKE_Fortran_FLAGS set(CMAKE_Fortran_FLAGS " ${CMAKE_Fortran_FLAGS}") diff --git a/scripts/ccpp_prebuild.py b/scripts/ccpp_prebuild.py index d1508d68..7372328c 100755 --- a/scripts/ccpp_prebuild.py +++ b/scripts/ccpp_prebuild.py @@ -16,7 +16,7 @@ from common import encode_container, execute from metadata_parser import merge_metadata_dicts, parse_scheme_tables, parse_variable_tables from mkcap import Cap, CapsMakefile, SchemesMakefile -from mkdoc import metadata_to_html +from mkdoc import metadata_to_html, metadata_to_latex #set up the command line argument parser parser = argparse.ArgumentParser() @@ -58,6 +58,7 @@ fields_include_file = ccpp_prebuild_config.FIELDS_INCLUDE_FILE html_vartable_file = ccpp_prebuild_config.HTML_VARTABLE_FILE +latex_vartable_file = ccpp_prebuild_config.LATEX_VARTABLE_FILE ############################################################################### # Template code to generate include files (imported) # @@ -328,7 +329,7 @@ def generate_scheme_caps(metadata, arguments): return (success, scheme_caps) def generate_schemes_makefile(schemes): - logging.info('Generating schemes makefile fragment ...') + logging.info('Generating schemes makefile snippet ...') success = True makefile = SchemesMakefile() makefile.filename = schemes_makefile @@ -344,7 +345,7 @@ def generate_schemes_makefile(schemes): return success def generate_caps_makefile(caps): - logging.info('Generating caps makefile fragment ...') + logging.info('Generating caps makefile snippet ...') success = True makefile = CapsMakefile() makefile.filename = caps_makefile @@ -371,7 +372,7 @@ def main(): if not success: raise Exception('Call to gather_variable_definitions failed.') - # Create table with all variables provided by the model + # Create an HTML table with all variables provided by the model success = metadata_to_html(metadata_define, HOST_MODEL, html_vartable_file) if not success: raise Exception('Call to metadata_to_html failed.') @@ -386,6 +387,11 @@ def main(): if not success: raise Exception('Call to check_optional_arguments failed.') + # Create a LaTeX table with all variables requested by the pool of physics and/or provided by the host model + success = metadata_to_latex(metadata_define, metadata_request, HOST_MODEL, latex_vartable_file) + if not success: + raise Exception('Call to metadata_to_latex failed.') + # Check requested against defined arguments to generate metadata (list/dict of variables for CCPP) (success, modules, metadata) = compare_metadata(metadata_define, metadata_request) if not success: @@ -421,5 +427,7 @@ def main(): if not success: raise Exception('Call to generate_caps_makefile failed.') + logging.info('CCPP prebuild step completed successfully.') + if __name__ == '__main__': main() diff --git a/scripts/ccpp_prebuild_config_FV3.py b/scripts/ccpp_prebuild_config_FV3.py index 93d91e75..e9702e74 100755 --- a/scripts/ccpp_prebuild_config_FV3.py +++ b/scripts/ccpp_prebuild_config_FV3.py @@ -7,13 +7,14 @@ # Definitions # ############################################################################### -# Relative to basedir defined in ccpp_prebuild.py +# Add all files with metadata tables on the host model side, +# relative to basedir = top-level directory of host model VARIABLE_DEFINITION_FILES = [ 'FV3/gfsphysics/GFS_layer/GFS_typedefs.F90', 'FV3/gfsphysics/physics/physcons.f90', ] -# Location of scheme_files relative to basedir defined in ccpp_prebuild.py +# Add all physics scheme files relative to basedir SCHEME_FILES = [ 'FV3/gfsphysics/physics/GFS_DCNV_generic.f90', 'FV3/gfsphysics/physics/GFS_MP_generic_post.f90', @@ -56,21 +57,26 @@ 'FV3/gfsphysics/physics/sfc_sice.f', ] -# Relative to basedir defined in ccpp_prebuild.py +# Auto-generated makefile snippet that contains all schemes SCHEMES_MAKEFILE = 'FV3/gfsphysics/CCPP_SCHEMES.mk' -# Relative to basedir defined in ccpp_prebuild.py +# CCPP host cap in which to insert the ccpp_field_add statements; +# determines the directory to place ccpp_{modules,fields}.inc TARGET_FILES = [ 'FV3/gfsphysics/IPD_layer/IPD_CCPP_Driver.F90', ] -# Relative to basedir +# Auto-generated makefile snippet that contains all caps CAPS_MAKEFILE = 'FV3/gfsphysics/CCPP_CAPS.mk' + +# Directory where to put all auto-generated physics caps CAPS_DIR = 'FV3/gfsphysics/physics' -# Optional arguments - only required for schemes that use optional arguments. This script will throw -# an exception if it encounters a scheme subroutine with optional arguments if no entry is made in -# the following dictionary. Valid values are 'all', 'none' or a list of arguments: [ 'var1', 'var3' ]. +# Optional arguments - only required for schemes that use +# optional arguments. ccpp_prebuild.py will throw an exception +# if it encounters a scheme subroutine with optional arguments +# if no entry is made here. Possible values are: 'all', 'none', +# or a list of standard_names: [ 'var1', 'var3' ]. OPTIONAL_ARGUMENTS = { 'rrtmg_sw' : { 'rrtmg_sw_run' : [ @@ -104,28 +110,38 @@ #'subroutine_name_2' : [ 'var1', 'var3'], } -# No path needed - will be created in directory of target files defined above +# Names of Fortran include files in the host model cap (do not change); +# both files will be written to the directory of each target file MODULE_INCLUDE_FILE = 'ccpp_modules.inc' FIELDS_INCLUDE_FILE = 'ccpp_fields.inc' -# HTML document containing the model-defined CCPP variables, relateive to basedir -HTML_VARTABLE_FILE = 'FV3/gfsphysics/CCPP_VARIABLES.html' +# HTML document containing the model-defined CCPP variables +HTML_VARTABLE_FILE = 'FV3/gfsphysics/CCPP_VARIABLES_FV3.html' + +# LaTeX document containing the provided vs requested CCPP variables +LATEX_VARTABLE_FILE = 'ccpp-framework/doc/DevelopersGuide/CCPP_VARIABLES_FV3.tex' ############################################################################### # Template code to generate include files # ############################################################################### -# Modules to load for auto-generated ccpp_field_add code (e.g. error handling) +# Name of the CCPP data structure in the host model cap; +# in the case of FV3, this is a 2-dimensional array with +# the number of blocks as the first and the number of +# OpenMP threads as the second dimension; nb is the loop +# index for the current block, nt for the current thread +CCPP_DATA_STRUCTURE = 'cdata_block(nb,nt)' + +# Modules to load for auto-generated ccpp_field_add code +# in the host model cap (e.g. error handling) MODULE_USE_TEMPLATE_HOST_CAP = \ ''' use ccpp_errors, only: ccpp_error ''' -# Name of the CCPP data structure in the host model cap -CCPP_DATA_STRUCTURE = 'cdata_block(nb,nt)' - -# Modules to load for auto-generated ccpp_field_add code (e.g. error handling) +# Modules to load for auto-generated ccpp_field_get code +# in the physics scheme cap (e.g. derived data types) MODULE_USE_TEMPLATE_SCHEME_CAP = \ ''' use machine, only: kind_phys diff --git a/scripts/ccpp_prebuild_config_SCM.py b/scripts/ccpp_prebuild_config_SCM.py index 6cebaee7..3e26ce5a 100755 --- a/scripts/ccpp_prebuild_config_SCM.py +++ b/scripts/ccpp_prebuild_config_SCM.py @@ -7,69 +7,75 @@ # Definitions # ############################################################################### -# Relative to basedir defined in ccpp_prebuild.py +# Add all files with metadata tables on the host model side, +# relative to basedir = top-level directory of host model VARIABLE_DEFINITION_FILES = [ - '../../scm/src/gmtb_scm_type_defs.f90', - '../../scm/src/gmtb_scm_physical_constants.f90' + 'scm/src/gmtb_scm_type_defs.f90', + 'scm/src/gmtb_scm_physical_constants.f90' ] -# Location of scheme_files relative to basedir defined in ccpp_prebuild.py +# Add all physics scheme files relative to basedir SCHEME_FILES = [ - '../../ccpp-physics/GFS_layer/GFS_initialize_scm.F90', - '../../ccpp-physics/physics/GFS_DCNV_generic.f90', - '../../ccpp-physics/physics/GFS_MP_generic_post.f90', - '../../ccpp-physics/physics/GFS_MP_generic_pre.f90', - '../../ccpp-physics/physics/GFS_PBL_generic.f90', - '../../ccpp-physics/physics/GFS_SCNV_generic.f90', - '../../ccpp-physics/physics/GFS_calpreciptype.f90', - '../../ccpp-physics/physics/GFS_phys_time_vary.f90', - '../../ccpp-physics/physics/GFS_rad_time_vary.f90', - '../../ccpp-physics/physics/GFS_rrtmg_post.F90', - '../../ccpp-physics/physics/GFS_rrtmg_pre.F90', - '../../ccpp-physics/physics/GFS_suite_interstitial.ccpp.f90', - '../../ccpp-physics/physics/GFS_surface_generic.f90', - '../../ccpp-physics/physics/GFS_surface_loop_control.f', - '../../ccpp-physics/physics/GFS_zhao_carr_pre.f90', - '../../ccpp-physics/physics/cnvc90.f', - '../../ccpp-physics/physics/dcyc2.f', - '../../ccpp-physics/physics/get_prs_fv3.f90', - '../../ccpp-physics/physics/gscond.f', - '../../ccpp-physics/physics/gwdc.f', - '../../ccpp-physics/physics/gwdps.f', - '../../ccpp-physics/physics/mfdeepcnv.f', - '../../ccpp-physics/physics/mfshalcnv.f', - '../../ccpp-physics/physics/moninedmf.f', - '../../ccpp-physics/physics/ozphys.f', - '../../ccpp-physics/physics/precpd.f', - '../../ccpp-physics/physics/radlw_main.f', - '../../ccpp-physics/physics/radsw_main.f', - '../../ccpp-physics/physics/rayleigh_damp.f', - '../../ccpp-physics/physics/rrtmg_lw_post.F90', - '../../ccpp-physics/physics/rrtmg_lw_pre.F90', - '../../ccpp-physics/physics/rrtmg_sw_post.F90', - '../../ccpp-physics/physics/rrtmg_sw_pre.F90', - '../../ccpp-physics/physics/sfc_diag.f', - '../../ccpp-physics/physics/sfc_diff.f', - '../../ccpp-physics/physics/sfc_drv.f', - '../../ccpp-physics/physics/sfc_nst.f', - '../../ccpp-physics/physics/sfc_sice.f', + 'ccpp-physics/GFS_layer/GFS_initialize_scm.F90', + 'ccpp-physics/physics/GFS_DCNV_generic.f90', + 'ccpp-physics/physics/GFS_MP_generic_post.f90', + 'ccpp-physics/physics/GFS_MP_generic_pre.f90', + 'ccpp-physics/physics/GFS_PBL_generic.f90', + 'ccpp-physics/physics/GFS_SCNV_generic.f90', + 'ccpp-physics/physics/GFS_calpreciptype.f90', + 'ccpp-physics/physics/GFS_phys_time_vary.f90', + 'ccpp-physics/physics/GFS_rad_time_vary.f90', + 'ccpp-physics/physics/GFS_rrtmg_post.F90', + 'ccpp-physics/physics/GFS_rrtmg_pre.F90', + 'ccpp-physics/physics/GFS_suite_interstitial.ccpp.f90', + 'ccpp-physics/physics/GFS_surface_generic.f90', + 'ccpp-physics/physics/GFS_surface_loop_control.f', + 'ccpp-physics/physics/GFS_zhao_carr_pre.f90', + 'ccpp-physics/physics/cnvc90.f', + 'ccpp-physics/physics/dcyc2.f', + 'ccpp-physics/physics/get_prs_fv3.f90', + 'ccpp-physics/physics/gscond.f', + 'ccpp-physics/physics/gwdc.f', + 'ccpp-physics/physics/gwdps.f', + 'ccpp-physics/physics/mfdeepcnv.f', + 'ccpp-physics/physics/mfshalcnv.f', + 'ccpp-physics/physics/moninedmf.f', + 'ccpp-physics/physics/ozphys.f', + 'ccpp-physics/physics/precpd.f', + 'ccpp-physics/physics/radlw_main.f', + 'ccpp-physics/physics/radsw_main.f', + 'ccpp-physics/physics/rayleigh_damp.f', + 'ccpp-physics/physics/rrtmg_lw_post.F90', + 'ccpp-physics/physics/rrtmg_lw_pre.F90', + 'ccpp-physics/physics/rrtmg_sw_post.F90', + 'ccpp-physics/physics/rrtmg_sw_pre.F90', + 'ccpp-physics/physics/sfc_diag.f', + 'ccpp-physics/physics/sfc_diff.f', + 'ccpp-physics/physics/sfc_drv.f', + 'ccpp-physics/physics/sfc_nst.f', + 'ccpp-physics/physics/sfc_sice.f', ] -# Relative to basedir defined in ccpp_prebuild.py -SCHEMES_MAKEFILE = '../../ccpp-physics/CCPP_SCHEMES.mk' +# Auto-generated makefile snippet that contains all schemes +SCHEMES_MAKEFILE = 'ccpp-physics/CCPP_SCHEMES.mk' -# Relative to basedir defined in ccpp_prebuild.py +# CCPP host cap in which to insert the ccpp_field_add statements; +# determines the directory to place ccpp_{modules,fields}.inc TARGET_FILES = [ - '../../scm/src/gmtb_scm.f90', + 'scm/src/gmtb_scm.f90', ] -# Relative to basedir defined in ccpp_prebuild.py -CAPS_MAKEFILE = '../../ccpp-physics/CCPP_CAPS.mk' -CAPS_DIR = '../../ccpp-physics/physics' +# Auto-generated makefile snippet that contains all caps +CAPS_MAKEFILE = 'ccpp-physics/CCPP_CAPS.mk' -# Optional arguments - only required for schemes that use optional arguments. This script will throw -# an exception if it encounters a scheme subroutine with optional arguments if no entry is made in -# the following dictionary. Valid values are 'all', 'none' or a list of arguments: [ 'var1', 'var3' ]. +# Directory where to put all auto-generated physics caps +CAPS_DIR = 'ccpp-physics/physics' + +# Optional arguments - only required for schemes that use +# optional arguments. ccpp_prebuild.py will throw an exception +# if it encounters a scheme subroutine with optional arguments +# if no entry is made here. Possible values are: 'all', 'none', +# or a list of standard_names: [ 'var1', 'var3' ]. OPTIONAL_ARGUMENTS = { 'rrtmg_sw' : { 'rrtmg_sw_run' : [ @@ -103,28 +109,35 @@ #'subroutine_name_2' : [ 'var1', 'var3'], } -# No path needed - will be created in directory of target files defined above +# Names of Fortran include files in the host model cap (do not change); +# both files will be written to the directory of each target file MODULE_INCLUDE_FILE = 'ccpp_modules.inc' FIELDS_INCLUDE_FILE = 'ccpp_fields.inc' -# HTML document containing the model-defined CCPP variables, relateive to basedir -HTML_VARTABLE_FILE = '../../ccpp-physics/CCPP_VARIABLES.html' +# HTML document containing the model-defined CCPP variables +HTML_VARTABLE_FILE = 'ccpp-physics/CCPP_VARIABLES_SCM.html' + +# LaTeX document containing the provided vs requested CCPP variables +LATEX_VARTABLE_FILE = 'ccpp-framework/doc/DevelopersGuide/CCPP_VARIABLES_SCM.tex' ############################################################################### # Template code to generate include files # ############################################################################### -# Modules to load for auto-generated ccpp_field_add code (e.g. error handling) +# Name of the CCPP data structure in the host model cap; +# in the case of SCM, this is a vector with loop index i +CCPP_DATA_STRUCTURE = 'cdata(i)' + +# Modules to load for auto-generated ccpp_field_add code +# in the host model cap (e.g. error handling) MODULE_USE_TEMPLATE_HOST_CAP = \ ''' use ccpp_errors, only: ccpp_error ''' -# Name of the CCPP data structure in the host model cap -CCPP_DATA_STRUCTURE = 'cdata(i)' - -# Modules to load for auto-generated ccpp_field_add code (e.g. error handling) +# Modules to load for auto-generated ccpp_field_get code +# in the physics scheme cap (e.g. derived data types) MODULE_USE_TEMPLATE_SCHEME_CAP = \ ''' use machine, only: kind_phys diff --git a/scripts/common.py b/scripts/common.py index 03b4f95e..cc8dad20 100755 --- a/scripts/common.py +++ b/scripts/common.py @@ -66,5 +66,11 @@ def decode_container(container): if not len(items) in [1, 2, 3]: raise Exception("decode_container not implemented for {0} items".format(len(items))) for i in xrange(len(items)): - items[i] = items[i][items[i].find('_')+1:] - return items + items[i] = items[i][:items[i].find('_')] + ' ' + items[i][items[i].find('_')+1:] + return ' '.join(items) + +def escape_tex(text): + return text.replace( + '%', '\%').replace( + '_', '\_') + diff --git a/scripts/mkdoc.py b/scripts/mkdoc.py index d5ea539e..171de59e 100755 --- a/scripts/mkdoc.py +++ b/scripts/mkdoc.py @@ -5,7 +5,7 @@ import logging -from common import decode_container +from common import decode_container, escape_tex #################### Main program routine def main(): @@ -25,6 +25,7 @@ def metadata_to_html(metadata, model, filename): shading = { 0 : 'darkgray', 1 : 'lightgray' } success = True + # Header html = ''' CCPP variables provided by model {model} @@ -59,12 +60,115 @@ def metadata_to_html(metadata, model, filename): {v.local_name} '''.format(v=var, rank=var.rank.count(':'), container = decode_container(var.container), bgcolor=shading[count]) html += line + + # Footer + html += ''' + + +''' + with open(filename, 'w') as f: f.write(html) logging.info('Metadata table for model {0} written to {1}'.format(model, filename)) return success + +def metadata_to_latex(metadata_define, metadata_request, model, filename): + """Create a metadata table for each variable provided and/or requested""" + + # Set debug to true if logging level is debug + #debug = logging.getLogger().getEffectiveLevel() == logging.DEBUG + + shading = { 0 : 'darkgray', 1 : 'lightgray' } + success = True + + var_names = sorted(list(set(metadata_define.keys() + metadata_request.keys()))) + + latex = '''\\documentclass[12pt,letterpaper,oneside]{{scrbook}} + +\\usepackage{{import}} +\\import{{../common/}}{{gmtb.sty}} +\\renewcommand{{\\thesection}}{{\\arabic{{section}}}} +\\renewcommand{{\\thesubsection}}{{\\arabic{{section}}.\\arabic{{subsection}}}} + +\\begin{{document}} + +\\section{{CCPP variables provided by model {model} vs requested by pool of physics}}\\label{{sec_ccpp_variables}} +\\subsection{{List of variables}} +\\begin{{longtable}}{{l}}'''.format(model=model) + + for var_name in var_names: + if var_name in metadata_define.keys(): + var = metadata_define[var_name][0] + else: + var = metadata_request[var_name][0] + line = ''' +\hyperlink{{{standard_name_ref}}}{{\\blue\\underline{{\\execout{{{standard_name}}}}}}} \\\\'''.format(standard_name=escape_tex(var.standard_name), standard_name_ref=var.standard_name) + latex += line + + latex += ''' +\\end{longtable}\\pagebreak +\\subsection{Description of variables} +{{\\small\\begin{description} +''' + + for var_name in var_names: + if var_name in metadata_define.keys(): + var = metadata_define[var_name][0] + target = escape_tex(decode_container(var.container)) + local_name = escape_tex(var.local_name) + else: + var = metadata_request[var_name][0] + target = 'MISSING' + local_name = 'MISSING' + if var_name in metadata_request.keys(): + requested_list = [ escape_tex(decode_container(v.container)) for v in metadata_request[var_name] ] + # for the purpose of the table, just output the name of the subroutine + for i in xrange(len(requested_list)): + entry = requested_list[i] + requested_list[i] = entry[entry.find('SUBROUTINE')+len('SUBROUTINE')+1:] + requested = '\\newline '.join(sorted(requested_list)) + else: + requested = 'NOT REQUESTED' + + # Create output + text = ''' +\\begin{{samepage}}\\item{{ +\hypertarget{{{standard_name_ref}}}{{\\blue\\exec{{{standard_name}}}}}}}\\\\ \\nopagebreak +\\begin{{tabular}}{{ll}} +\\execout{{long\_name }} & \\execout{{{long_name} }} \\\\ +\\execout{{units }} & \\execout{{{units} }} \\\\ +\\execout{{rank }} & \\execout{{{rank} }} \\\\ +\\execout{{type }} & \\execout{{{type} }} \\\\ +\\execout{{kind }} & \\execout{{{kind} }} \\\\ +\\execout{{source }} & \\execout{{{target} }} \\\\ +\\execout{{local\_name}} & \\execout{{{local_name} }} \\\\ +\\execout{{requested }} & \\execout{{\\vtop{{{requested}}}}} \\\\ +\\end{{tabular}} +\\vspace{{4pt}} +\\end{{samepage}}'''.format(standard_name=escape_tex(var.standard_name), standard_name_ref=var.standard_name, + long_name=escape_tex(var.long_name), + units=escape_tex(var.units), + rank=var.rank.count(':'), + type=escape_tex(var.type), + kind=escape_tex(var.kind), + target=target, + local_name=local_name, + requested=requested) + latex += text + # Footer + latex += ''' +\\end{description}}} +\\end{document} +''' + + with open(filename, 'w') as f: + f.write(latex) + + logging.info('Metadata table for model {0} written to {1}'.format(model, filename)) + return success + ############################################################################### if __name__ == "__main__": main() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 306ad35d..deba4a5d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -49,8 +49,6 @@ endif() #------------------------------------------------------------------------------ # Set a default build type if none was specified if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) - #message(STATUS "Setting build type to 'Debug' as none was specified.") - #set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE) message(STATUS "Setting build type to 'Release' as none was specified.") set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)