.. role:: underline
:class: underline
==========================
WRF Software & Computation
==========================
|
|
WRF Build Mechanism
===================
The WRF build mechanism provides a uniform apparatus for configuring and compiling the WRF model, WRFDA, WRF-Chem, and WRF-Hydro systems, as well as the WRF Preprocessing System (WPS) over a range of platforms, with a variety of options. This section describes the components and functioning of the build mechanism. For instructions on building the WRF modeling system code, `see the Compiling chapter of this Users' Guide <./compiling.html>`_.
|
|
Build Components
----------------
The primary components of the build mechanism are included in the WRF source code, and consist of the following:
|
Scripts
+++++++
The top-level WRF directory contains three user-executable scripts: *configure* (which relies on the Perl script in *arch/Config_new.pl*), *compile*, and *clean*
|
|
Programs
++++++++
A significant number of WRF lines of code are automatically generated at compile time by the *tools/registry* file.
|
|
Makefiles
+++++++++
The primary **Makefile** (input to the UNIX "make" utility) is in the top-level WRF directory. There are also makefiles in most subdirectories, as well. "make" is called recursively over the directory structure when the *compile* script is run by the user.
|
|
Configuration Files
+++++++++++++++++++
The user-invoked *configure* script generates a file called *configure.wrf*. This file contains a compiler, linker, and other build settings, as well as rules and macro definitions used by the "make" utility. It is included by the Makefiles in most of the WRF source distribution (Makefiles in *tools* and *external* directories do not include *configure.wrf*), and is deleted when the code system is cleaned by the user-issued *clean* script. Thus, *configure.wrf* can be modified for temporary changes, such as optimization levels and compiling with debugging. Permanent changes should be made in *arch/configure_new.defaults*. The *configure.wrf* file is composed by the following three files:
* **arch/configure_new.defaults** : contains lists of compiler options for all supported platforms and configurations. Changes made to this file are permanent.
* **arch/preamble_new** : constitutes the generic parts (non-architecture-specific) of the configure.wrf file generated by the *configure* script. *See the file for details.**
* **arch/postamble_new** : similar to *arch/preamble_new*. *See the file for details.*
|
|
Registry
++++++++
The *Registry* directory contains files that control many compile-time aspects of the WRF code. The files are named *Registry.X*, where *X* corresponds to the intended application specified during configuration (for e.g., if a WRF-Chem compile is chosen, the *Registry.EM_CHEM* file will be used, where *X* corresponds to the intended application, specified during configuration). The *configure* script copies the appropriate *Registry.X* file to a generic file named *Registry*, which is the file that *tools/registry* uses as input. Any changes to the the *Registry* file will be lost; permanent changes should be made to *Registry.X*. For a standard WRF-ARW build, the file is typically *Registry.EM_COMMON*. The command "include" is used by the registry program, allowing the file *Registry.EM_COMMON* to be included during a build. This file holds all shared entries for all applications, which helps to reduce the amount of replicated registry information. See the full :ref:`Registry` section for additional details.
|
|
Environment Variables
+++++++++++++++++++++
The following aspects of the configuration and build are controlled by environment variables:
* The non-standard locations of netCDF libraries or the Perl command
* Which dynamic core to compile
* Machine-specific features
* Optional build libraries (such as Grib Edition 2, HDF, and parallel netCDF)
|
In addition to WRF-related environment settings, there may also be settings specific to particular compilers or libraries. For e.g., local installations may require setting a variable like *MPICH_F90* to ensure the correct instance of the Fortran 90 compiler is used by the ``mpif90`` command.
|
|
|
How the WRF Build Works
-----------------------
The two steps in the WRF build process are **configuration** and **compilation**.
.. container:: row m-0 p-0
.. container:: col-md-12 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header-def
.. rubric:: Configuration
.. container:: card-body-def
The *configure* script configures the model to determine information about the user's computing environment prior to compilation.
|
Configuration only takes a few seconds to run through the following processes:
#. Attempts to locate mandatory and optional libraries (e.g., netCDF or HDF) and tools, such as Perl; it checks for these in standard paths, or uses settings from the user's shell environment
#. Calls the UNIX "uname" command to determine the user's platform
#. Calls the Perl script *arch/Config_new.pl*, which traverses the list of known machine configurations and displays a list of available options to the user
#. The selected set of options is then used to create the *configure.wrf* file in the top-level directory.
|
.. note::
The *configure.wrf* file may be edited, but changes could be temporary if the file is later deleted by the user-invoked *clean* script, or overwritten by the next invocation of the *configure* script.
|
|
.. container:: row m-0 p-0
.. container:: col-md-12 pl-0 pr-3 py-3 m-0
.. container:: card px-0 h-100
.. rst-class:: card-header-def
.. rubric:: Compilation
.. container:: card-body-def
The *compile* script is used to compile the WRF code after it has been configured.
|
The *compile* cshell script performs a number of checks, constructs an argument list, copies the appropriate *Registry.X* file to *Registry/Registry*, and then invokes the UNIX "make" command in the top-level directory. The *Makefile* in the top-level directory directs the rest of the build, accomplished as a set of recursive invocations of "make" in the WRF subdirectories. Most makefiles include *configure.wrf* from the top-level directory. The order of a complete build is as follows:
#. *make* in the *external* directory
* *make* in *external/io_{grib1,grib_share,int,netcdf}* for Grib Edition 1, binary, and netCDF implementations of I/O API
* *make* in *external/RSL_LITE* to build the communications layer (DM_PARALLEL only)
* *make* in *external/esmf_time_f90* to build the ESMF time manager library
* *make* in *external/fftpack* to build the FFT library for the global filters
* *make* in other *external* directories, as specified by the "external:" target in the *configure.wrf* file
|
#. *make* in the *tools* directory to build the program that reads the *Registry/Registry* file and auto-generates files in the *inc* directory
#. *make* in the *frame* directory to build the WRF framework specific modules
#. *make* in the *share* directory to build the mediation layer routines, including WRF I/O modules that call the I/O API
#. *make* in the *phys* directory to build the WRF model layer routines for physics
#. *make* in the *dyn_em* directory for mediation-layer and model-layer subroutines
#. *make* in the *main* directory to build the main programs for WRF, with a symbolic link to create executable files (location depending on the build case that was selected as the argument to the compile script; for e.g., for a real-data case, the executables are linked to *test/em_real*)
* Source files (*.F* files, and in some of the *external* directories, *.F90* files) are preprocessed to produce *.f90* files, which are input to the compiler. As part of the preprocessing, Registry-generated files from the *inc* directory may be included.
* *.f90* files are compiled, resulting in the creation of *.o* (object) files that are added to the library *main/libwrflib.a*. Most external directories generate their own library file.
* The linking step produces the *wrf.exe* executable and other executables, depending on the case argument to the "compile" command: *real.exe* (a preprocessor for real-data cases) or *ideal.exe* (a preprocessor for idealized cases), and the *ndown.exe* program, for one-way nesting of real-data cases.
|
The *.o* files and *.f90* files created during the compile are retained until the next invocation of the *clean* script. The *.f90* files provide the true reference for tracking down run time errors that refer to line numbers or for sessions using interactive debugging tools such as "dbx" or "gdb."
|
|
|
.. _Registry:
Registry
========
Much of the WRF code is automatically generated from a user-edited text-based table called the "Registry." The Registry provides a high-level, single-point of control over the fundamental structure of the model data. It contains lists describing state data fields and their attributes:
* dimensionality
* binding to particular solvers
* association with WRF I/O streams
* communication operations
* run time configuration options (namelist elements and their bindings to model control structures).
|
Adding or modifying a state variable to WRF involves modifying a single line of a single file, which is then automatically propagated to scores of locations in the source code the next time the code is compiled.
The WRF Registry has two components: the Registry file (which the user may edit), and the Registry program. The Registry file is located in the *Registry* directory and contains entries that direct auto-generation of WRF code by the Registry program. There are multiple Registry files in this directory, with the filename syntax *Registry.X*, where *X* specifies the type of build selected during configuration.
|
.. csv-table::
:widths: 20, 40
:header: "File Name","Type of WRF Build"
Registry.EM_COMMON,Standard/Basic WRF
Registry.EM_COMMON.var, Minimal subset of Registry.EM_COMMON required for a WRFDA compile
Registry.EM_CHEM","WRF Chemistry (WRF-Chem)"
Registry.wrfvar","WRF Data Assimilation (WRFDA)"
Registry.wrfchemvar","WRF-Chem + WRFDA"
Registry.tladj","WRFPLUS"
|
.. note::
The *Registry.EM_COMMON* file contains variables that are common to all applications. The above *Registry.X* files make use of this file, reducing replicated registry information. Additionally, files in the *Registry* directory named *registry.x* (where *x* represents a specific application) are also included in this manner.
|
The WRF build mechanism copies the appropriate *Registry.X* file to *Registry/Registry* and this file is used to direct the Registry program, which is included in the WRF source code in the *tools* directory. It is built automatically when WRF is compiled from clean code. The executable file is *tools/registry*, which reads the contents of the *Registry/Registry* file and generates files in the *inc* directory. These "include" files are inserted (with cpp "#include" commands) into WRF Fortran source files prior to compilation. The Registry program, itself, is written in C. The source files and makefile are in the *tools* directory. The syntax and semantics for entries in the Registry are described in detail in `WRF Tiger Team Documentation: The Registry `_.
In addition to the WRF model itself, *Registry/Registry* is used to build the accompanying preprocessors, such as real.exe (for real data) or ideal.exe (for ideal simulations), and the ndown.exe program (used for one-way, off-line nesting).
|
.. image:: ../../images/users_guide/wrf_software_registry_mechanics.jpg
:alt: "An image that shows when the user compiles WRF, the Registry Program reads Registry/Registry, producing auto-generated sections of code that are stored in files in the inc directory. These are included into WRF using the CPP preprocessor and the Fortran compiler."
When WRF is compiled, the Registry program reads *Registry/Registry*, producing auto-generated sections of code that are stored in files in the *inc* directory. These are included in WRF, using the CPP preprocessor and the Fortran compiler.
|
The Registry describes every variable that is an input or an output field, or is required for parallel communication, specifically associated with a physics package, or needs to provide a tendency to multiple physics or dynamics routines. The following is defined for each variables:
* Index ordering
* Horizontal and vertical staggering
* Feedback and nesting interpolation requirements
* The associated IO
|
Adding a variable into the model typically only requires the addition of a single line to the *Registry.X* file, regardless of dimensionality. The same is true when defining a new run-time option (i.e., a new namelist entry). As with the model state arrays and variables, the entire model configuration is described in the Registry. Since the Registry modifies code for compile-time options, any change to the Registry (i.e., any file in the *Registry* directory) requires the code to be returned to the original unbuilt status with the ``clean -a`` command, and then reconfigured and recompiled.
|
The Registry file also provides input to generate all communications for distributed memory processing (halo interchanges between patches, support for periodic lateral boundaries, and array transposes for FFTs to be run in the X, Y, or Z directions). The Registry associates various fields with particular physics packages so the memory footprint reflects the actual selection of the options, not a maximal value.
|
|
|
Registry Syntax
---------------
Each entry in the Registry is specific to a single variable, regardless of whether it applies to a model dimension, a new field, new namelist value, or communication. A single entry may be spread across several lines with a backslach (\) at the end of a line to denote the entry is continuing. When adding a new line to the Registry, keep in mind the following:
* It is recommended to copy an entry that is similar to the new entry, and then modify the new entry.
* The Registry is not sensitive to spatial formatting.
* White space separates identifiers in each entry.
* After any change to a registry file, the code must be cleaned, reconfigured, and recompiled.
* If a column has no entry, do not leave it blank. Use the dash character ( - ).
|
|
|
Registry Entries
----------------
The following entry types are used in the WRF Registry (not case-dependent).
.. csv-table::
:widths: 20, 40
"**Dimspec**","Describes dimensions used to define arrays in the model"
"**State**","Describes state variables and arrays in the domain structure"
"**I1**","Describes local variables and arrays in 'solve'"
"**Typedef**","Describes derived types that are subtypes of the domain structure"
"**Rconfig**","Describes a configuration (e.g. namelist) variable or array"
"**Package**","Describes attributes of a package (e.g. physics)"
"**Halo**","Describes halo update interprocessor communications"
"**Period**","Describes communications for periodic boundary updates"
"**Xpose**","Describes communications for parallel matrix transposes"
"**include**","Similar to a CPP #include file"
|
These keywords appear as the first word in each line of the Registry file to define which type of information is being provided. Following are details and examples of the more-likely Registry types.
|
Dimspec
+++++++
The first set of entries in the Registry are specifications of the dimensions for the fields to be defined. To keep the WRF system consistent between build types, a unified *registry.dimspec* file is used (located in the *Registry* directory), and is included in each *Registry.\** file, using the keyword "include." In the example below, three dimensions are defined: *i, j*, and *k*. Issuing the command ``ncdump -h`` on a WRF file, provides three directional dimensions as west_east, south_north, and bottom_top. That information is contained in this example.
.. code-block::
#
dimspec i 1 standard_domain x west_east
dimspec j 3 standard_domain y south_north
dimspec k 2 standard_domain z bottom_top
|
Because WRF uses horizontal and vertical staggering, dimension names are extended with a *_stag* suffix, representing staggered sizes. The list of names in the ** column may either be a single, unique character, or a string with no embedded spaces (e.g., *my_dim*). When this dimension is used later to dimension-ize a state or *i1* variable, it must be surrounded by curly braces (e.g., *{my_dim}*). This ** variable is not case specific.
|
|
State and I1
++++++++++++
A WRF **state** variable is a field that is eligible for input/output (IO) and communications, and exists for the duration of the model forecast. **I1** variables (intermediate level one) are typically considered tendency terms, computed during a single model time-step, and then discarded prior to the next time-step. The space allocation and de-allocation for these I1 variables is automatic (on the stack for the model solver).
Below are the columns used for state and I1 variables (printed in order from left to right in the Registry file).
|
.. csv-table::
:header: "Column Heading","Description","Notes"
"**Table**","either 'state' or 'I1'","string"
"**Type**","type of variable or array","real, double, integer, logical, character, or derived"
"**Sym**","symbolic name inside WRF","string; not case-sensitive"
"**Dims**","dimensionality of the array","string; use hyphen (-) when dimensionless"
"**Use**","denotes association with the solver (dyn_em), or 4D scalar array","string; if not specific, declared 'misc'"
"**NumTLev**","number of time levels","integer for arrays; use hyphen (-) for variables"
"**Stagger**","indicates staggered dimensions","string; X,Y,Z, or hyphen (-) if not staggered"
"**IO**","whether and how it is subject to I/O and nesting","string; use hyphen (-) when no specification"
"**Dname**","metadata name","string; in quotes"
"**Descrip**","metadata description","string; in quotes"
"**Units**","metadata units","string; in quotes"
|
The following is a state variable that is a Fortran type "real." The name of the field inside the WRF model is *u_gc*. It is a three-dimensional array (*igj*), has a single time level, and is staggered in the X and Z directions. This field is input only to the real program (*i1*). On output, the netCDF name is *UU*, with the accompanying description and units provided(the example is broken across two lines for this guide, but represents a single line in the Registry file).
.. code-block::
#