Hedstrom Guide
Hedstrom Guide
Katherine S. Hedström
Arctic Region Supercomputing Center
University of Alaska Fairbanks
Katherine S. Hedström
Arctic Region Supercomputing Center
University of Alaska Fairbanks
Nov 2009
This study was funded by the Alaska Outer Continental Shelf Region of the Minerals Manage-
ment Service, U.S. Department of the Interior, Anchorage, Alaska, through Contract M07PC13368
with Rutgers University, Institute of Marine and Coastal Sciences.
The opinions, findings, conclusions, or recommendations expressed in this report or product are
those of the authors and do not necessarily reflect the views of the U.S. Department of the Interior,
nor does mention of trade names or commercial products constitute endorsement or recommenda-
tion for use by the Federal Government.
This document was prepared with LATEX xfig, and inkscape.
Acknowledgments
The ROMS model is descended from the SPEM and SCRUM models, but has been entirely
rewritten by Sasha Shchepetkin, Hernan Arango and John Warner, with many, many other con-
tributors. I am indebted to every one of them for their hard work.
Bill Hibler first came up with the viscous-plastic rheology we are using. Paul Budgell has
rewritten the dynamic sea-ice model, improving the solution procedure and making the water-
stress term implicit in time, then changing it again to use the elastic-viscous-plastic rheology of
Hunke and Dukowicz. I am very grateful that he is allowing us to use his version of the code. The
sea-ice thermodynamics is derived from Sirpa Häkkinen’s implementation of the Mellor-Kantha
scheme. She was kind enough to allow Paul and I to start with her code.
Thanks to the internet community for providing great tools like Perl, patch, cpp, svn, and
gmake to aid in software development (and to make it more fun).
This work was supported in part by a grant of HPC resources from the Arctic Region Super-
computing Center and the DoD High Performance Computing Modernization Program.
Development and testing of the ROMS model has been funded by many, including the USGS
Coastal and Marine Program, the Office of Naval Research, the National Ocean Partnership Pro-
gram...
2 Getting started 3
2.1 myroms.org . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.2 Prerequisites . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.3 Acquiring the ROMS code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
2.4 Compiling ROMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4.1 Environment Variables for make . . . . . . . . . . . . . . . . . . . . . . . . . 4
2.4.2 Providing the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.4.3 Build scripts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.5 Running ROMS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.6 Warnings and bugs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1
4.13.1 Gradient boundary condition . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.13.2 Wall boundary condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.13.3 Clamped boundary condition . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.13.4 Flather boundary condition . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.13.5 Chapman boundary condition . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
4.13.6 Radiation boundary condition . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
4.13.7 Mixed radiation-nudging boundary condition . . . . . . . . . . . . . . . . . . 36
2
7.2 Upwelling/Downwelling Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.1 cppdefs.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
7.2.2 Model domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.2.3 ana_grid . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
7.2.4 Initial conditions and the equation of state . . . . . . . . . . . . . . . . . . . 90
7.2.5 Boundary conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.2.6 Model forcing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.2.7 ocean.in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
7.2.8 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
7.3 Northeast Pacific example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.3.1 nep5.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
7.3.2 NEP5 code chunks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110
7.3.3 Model domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
7.3.4 Initial and boundary conditions . . . . . . . . . . . . . . . . . . . . . . . . . . 113
7.3.5 Forcing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
7.3.6 ocean.in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
7.3.7 Output . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
3
G Makefiles 133
G.1 Introduction to Portable make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133
G.1.1 Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
G.1.2 Implicit Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
G.1.3 Dependencies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
G.2 gnu make . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
G.2.1 Make rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
G.2.2 Assignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136
G.2.3 Include and a Few Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
G.2.4 Conditionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 138
G.3 Multiple Source Directories the ROMS Way . . . . . . . . . . . . . . . . . . . . . . . 139
G.3.1 Directory Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 139
G.3.2 Conditionally Including Components . . . . . . . . . . . . . . . . . . . . . . . 139
G.3.3 User-defined make Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 140
G.3.4 Library Module.mk . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
G.3.5 Main Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
G.3.6 Top Level Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143
G.4 Final warnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146
H sfmakedepend 147
I Subversion 149
I.1 Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
I.2 Checking out the code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
I.3 Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
I.4 Code changes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
I.5 Conflicts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150
I.5.1 Merging conflicts by hand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
I.5.2 Copying a file onto your working file . . . . . . . . . . . . . . . . . . . . . . . 152
I.5.3 Punting: Using svn revert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 152
4
List of Figures
1 Placement of variables on an Arakawa C grid . . . . . . . . . . . . . . . . . . . . . . 13
2 Placement of variables on staggered vertical grid . . . . . . . . . . . . . . . . . . . . 13
3 Masked region within the domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
4 Diagrams of the time stepping and mode coupling used in various ROMS versions. (a)
Rutgers University ROMS (from myroms.org), (b) ROMS AGRIF, (c) UCLA ROMS,
described in [73], (d) non-hydrostatic ROMS ([35]). In all, the curved arrows update
the 3-D fields; those with “pillars” are leapfrog in nature with the pillar representing
the r.h.s. terms. Straight arrows indicate exchange between the barotropic and
baroclinic modes. The shape functions for the fast time steps show just one option
out of many possibilities. The grey function has weights to produce an estimate at
time n + 1, while the light red function has weights to produce an estimate at time
n + 12 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
5 The split time stepping used in the model. . . . . . . . . . . . . . . . . . . . . . . . . 19
6 Weights for the barotropic time stepping. The upper panel shows the primary
weights, centered at time n + 1, while the lower panel shows the secondary weights
weights, centered at time n + 21 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
7 Diagram of the different locations where ice melting and freezing can occur. . . . . . 40
8 Diagram of internal ice temperatures and fluxes. The hashed layer is the snow. . . . 40
9 ROMS directory structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
10 ROMS main structure. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
11 Flow chart of the model main program. . . . . . . . . . . . . . . . . . . . . . . . . . 50
12 The whole grid. Note that there are Lm by Mm interior computational points. The
points on the thick outer line and those outside it are provided by the boundary
conditions. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
13 A tiled grid with some ROMS tile variables. . . . . . . . . . . . . . . . . . . . . . . . 68
14 A choice of numbering schemes: (a) each tile is numbered the same, and (b) each
tile retains the numbering of the parent domain. . . . . . . . . . . . . . . . . . . . . 69
15 Some ROMS variables for tiles, for both a periodic and non-periodic case. Shown
are the variables in the i-direction, the j-direction is similar. . . . . . . . . . . . . . . 70
16 A tiled grid with out-of-date halo regions shown in grey and the interior points
color-coded by tile: (a) before an exchange and (b) after an exchange. . . . . . . . . 71
17 The upwelling/downwelling bathymetry. . . . . . . . . . . . . . . . . . . . . . . . . . 100
18 Surface velocities after one day, showing the flow to the left of the wind (southern
hemisphere). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
19 Constant ξ slices of the u, v, T and w fields at day 1. . . . . . . . . . . . . . . . . . . 102
20 Constant ξ slices of the u, v, T , and w fields at day 5. . . . . . . . . . . . . . . . . . . 103
21 Bathymetry of the Northeast Pacific domain (NEP5). . . . . . . . . . . . . . . . . . 104
22 Surface elevation after 200 days showing tides. This is from a snapshot in a history
file—the averages files have been detided. . . . . . . . . . . . . . . . . . . . . . . . . 114
23 Ice concentration averaged over the month of April, 1959. . . . . . . . . . . . . . . . 115
24 Vertical slice if temperature, averaged over the month of April, 1959. The slice is
across the Bering Sea shelf, showing the transition from vertically mixed at the coast,
a two layer system at mid-shelf, then a thermocline over the shelf-break. . . . . . . . 116
25 The σ-surfaces for the North Atlantic with (a) θ = 0.0001 and b = 0, (b) θ = 8 and
b = 0, (c) θ = 8 and b = 1. (d) The actual values used in this domain were θ = 5
and b = 0.4. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
5
List of Tables
1 The variables used in the description of the ocean model . . . . . . . . . . . . . . . . 9
2 The variables used in the vertical boundary conditions for the ocean model . . . . . 9
3 The time stepping schemes used in the various ROMS versions. α ≡ ωδt is the
Courant number and ω = ck is the frequency for a wave component with wavenumber
k. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
4 Variables used in the ice momentum equations . . . . . . . . . . . . . . . . . . . . . 39
5 Variables used in the ice thermodynamics . . . . . . . . . . . . . . . . . . . . . . . . 41
6 Ocean surface variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
7 Frazil ice variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
8 Variables used in computing the incoming radiation and latent and sensible heat . . 128
6
1 Introduction
This user’s manual for the Regional Ocean Modeling System (ROMS) describes the model equations
and algorithms, as well as additional user configurations necessary for specific applications. This
manual also describes the sea-ice model that we are using (Budgell [5]).
The principle attributes of the model are as follows:
General
Horizontal
• Orthogonal-curvilinear coordinates.
• Arakawa C grid.
• Closed basin, periodic, prescribed, radiation, and gradient open boundary conditions.
• Masking of land areas.
Vertical
• σ (terrain-following) coordinate.
• Free surface.
• Tridiagonal solve with implicit treatment of vertical viscosity and diffusivity.
Ice
Mixing options
Implementation
1
• Dimensional in meter, kilogram, second (MKS) units.
• Fortran 90.
• Runs under UNIX, requires the C preprocessor, gnu make, and Perl.
• All input and output is done in NetCDF [68] (Network Common Data Format),
requires the NetCDF library.
• Options include serial, parallel with MPI, and parallel with OpenMP.
The above list hasn’t changed so very much in the past ten to fifteen years, but many of the
numerical details have changed a great deal. Examples include consistent temporal averaging of
the barotropic mode to guarantee both exact conservation and constancy preservation properties for
tracers; redefined barotropic pressure-gradient terms to account for local variations in the density
field; vertical interpolation performed using conservative parabolic splines; and higher-order, quasi-
monotone advection algorithms.
ROMS now comes with a full suite of advanced data assimilation routines; these options are
beyond the scope of this document.
Chapter 2 has some information on getting started with ROMS. Chapters 3 and 4 describe the
model physics and numerical techniques and contain information from Shchepetkin and McWilliams
[75] and Haidvogel et al. [24]. Chapter 5 describes the ice equations and Chapter 6 lists the model
subroutines and functions. As distributed, ROMS is ready to run with a number of example
problems. The process of configuring ROMS for a particular application and running it is described
in Chapter 7, including a discussion of a few example applications. Chapter 8 describes Hernan
Arango’s plotting programs cnt, ccnt, sec, and csec.
2
2 Getting started
2.1 myroms.org
Starting off with ROMS is not the easiest thing to do, and it just seems to be getting more complex
as time goes by. There are some resources, however, beginning with the electronic home for ROMS
users at www.myroms.org. Go to register, which gives you access to the subversion server for the
code and to the discussion forum for all things ROMS. There is also a wiki, a bug tracking system,
and even a developer blog.
The wiki contains parts of this manual, but the nature of wikis is that they can be more fluid,
with more authors, than a static document such as this. Dave Robertson ([email protected])
is the one to talk to if you would like to contribute to the wiki.
2.2 Prerequisites
As mentioned in Chapter 1, ROMS has some external requirements. These are:
• A Fortran 90 compiler.
• The NetCDF library compiled with the above compiler, including the Fortran 90 interface.
• svn, the subversion revision control software. See Appendix I and the ROMS wiki.
• Gnu make version 3.81 or higher. Appendix G contains more than you ever wanted to know
about this software.
• A C preprocessor—the one from gnu with the -traditional flag works well. See Appendix F.
• Matlab is optional, but it is a common tool for pre- and post-processing of ROMS files.
Make sure you’ve got the right environment before attempting to download or compile ROMS.
• §2.4 describes how to pick the cases and set up the build environment.
• §6.7 lists all the ROMS options that can be added to your case.
• §6.5 lists the fields which can be provided to ROMS via analytic expressions.
• §7.1.12 lists the input parameters ROMS reads from a text file at run time.
• Chapters 6 and 7 are meant to be informative for the simple and not-so-simple cases. If that
isn’t the case, please let me know.
3
• You may be best served by going to the ROMS wiki which includes sections called Getting
Started and Tutorials.
• Don’t be afraid to use the forum. It has everything from employment opportunities to debug-
ging help. Posting there can get you help from one of several people, improving your odds of
success over private emails. Registered users get an email once a day about new postings, so
you might have to wait a day (or more) for a reply.
• There have been ROMS meetings and classes in which a tutorial session is included as part
of the program.
• There are various resources from these online—I’ve heard good things about the tutorials
from Manu Di Lorenzo.
ROMS_APPLICATION Set the cpp option defining the particular application. This is used
for setting up options inside the code specific to this application and also determines
the name of the .h header file for it. This can be either a predefined case, such as
BENCHMARK, or one of your own, such as NEP5.
MY_HEADER_DIR Sets the path to the user’s header file, if any. It can be left empty for the
standard cases, where benchmark.h and the like are found in ROMS/Include, which
is already in the search path. In the case of NEP5, this is set to Apps/NEP where
nep5.h resides.
MY_ANALYTICAL_DIR Sets the path to the user’s analytic files described in §6.5, if any.
This can be User/Functionals or some other location. I tend to place both the header
file and the functionals in the same directory, one directory per application.
MY_CPP_FLAGS Set tunable cpp options. Sometimes it is desirable to activate one or more
cpp options to run different variants of the same application without modifying its header
file. If this is the case, specify each option here using the -D syntax. Notice that you need
to use the shell’s quoting syntax (either single or double quotes) to enclose the definition
if you are using one of the build scripts below.
Compiler-specific Options These flags are used by the files inside the Compilers directory.
USE_DEBUG Set this to on to turn off optimization and turn on the -g flag for
debugging.
USE_MPI Set this if running an MPI parallel job.
USE_OpenMP Set this if running an OpenMP parallel job.
USE_MPIF90 I’m frankly not sure about this one. I suppose if you have both mpich
and some other MPI for a given compiler/system pair, this could be used to
switch between them.
4
USE_LARGE Some systems support both 32-bit and 64-bit options. Select this to get
64-bit addressing, usually used for programs need more than 2 GB of memory.
NETCDF_INCDIR The location of the netcdf.mod and typesizes.mod files.
NETCDF_LIBDIR The location of the NetCDF library.
USE_NETCDF4 Set this if linking against the NetCDF4 library, which needs the
HDF5 library and therefore:
HDF5_LIBDIR The location of the HDF5 library.
FORT A shorthand name for the compiler to be used when selecting which system-compiler file
is to be included from the Compilers directory. See section §G.2.3 and §2.4.2.
Local File Options BINDIR Directory in which to place the binary executable. The default is
“.”, the current (top) directory.
SCRATCH_DIR Put the .f90 and the temporary binary files in a build directory to
avoid clutter. The default is Build under the top directory. It can also point to
differing places if you want to keep these files for multiple projects at the same
time, each in their own directory.
• Where is it?
5
2.4.3 Build scripts
If you have more than one application (or more than one compiler), you will get tired of editing
the makefile. One option is to have a makefile for each configuration, then type:
make -f makefile.circle_pgi
for instance. Another option of keeping track of the user-defined choices in a build script. The
advantage is that updates to the build scripts are less frequent than updates to the makefile.
There are now two of these scripts in the ROMS/Bin directory: build.sh (which is surprisingly
a csh script) and build.bash. The build scripts use environment variables to provide values for
the list above, overwriting those found in the ROMS makefile. Just as in the multiple makefile
option, you will need as many copies of the build script as you have applications. The scope of
these variables is local to the build script, allowing you to compile different applications at the
same time from the same sources as long as each $(SCRATCH_DIR) is unique.
Both scripts have the same options:
-j [N] Compile in parallel using N cpus, omit argument for all available CPUs.
Note that the default is to compile serially and to issue a “make clean” before compiling. It is
left as an exercise for the user if they prefer different default behavior.
There are also a few variables which are not recognized by the ROMS makefile, but are used
locally inside the build script. These are:
MY_ROMS_SRC Set the path to the user’s local current ROMS source code. This is used so
that the script can be run from any directory, not necessarily only from the top ROMS
directory.
cd $PBS_O_WORKDIR
mpirun -np 32 ./oceanM ocean_benchmark3.in
6
aprun -np 32 ./oceanM ocean_benchmark3.in
• The code must be run through the C preprocessor before it is compiled. This can occasionally
be dangerous, especially with the newer ANSI C versions of cpp. Potential problems are listed
in Appendix F. The gnu cpp with the -traditional flag is known to work well.
• The vertical σ-coordinate was chosen as being a sensible way to handle variations in the water
depth as seen in the coastal oceans. Changes to the code have allowed us to expand the well-
behaved range of depths and the range of values for THETA_S, plus there are some new
vertical coordinate options. I used to give guidelines on “reasonable” values for THETA_S,
but I no longer know what’s reasonable.
• σ-coordinates have long had a bad reputation because errors in the pressure gradient terms
can lead to spurious currents. These errors are must less troublesome than in the past due to
code improvements and can also be controlled with some smoothing of the bathymetry. This
in turn changes the shape of the basin and leads to its own set of problems, such as altered
sill depths. Also, the currents will react to the change in shelf slope—you are now solving
a different problem. You may want to explore a matlab tool for minimally smoothing the
bathymetry found at: http://www.liga.ens.fr/∼dutour/Bathymetry/index.html.
• There remain bugs in ROMS. If you find any, please report them on the forum and/or the
bug tracking system at myroms.org.
7
3 Ocean Model Formulation
∂u ∂φ ∂ ∂u
+ ~v · ∇u − f v = − − u0 w0 − ν + Fu + Du (1)
∂t ∂x ∂z ∂z
∂v ∂φ ∂ ∂v
+ ~v · ∇v + f u = − − v 0 w0 − ν + Fv + Dv (2)
∂t ∂y ∂z ∂z
∂φ −ρg
= (3)
∂z ρo
∂C ∂ ∂C
+ ~v · ∇C = − C 0 w0 − νθ + FC + DC . (5)
∂t ∂z ∂z
The variables are shown in Table 3.1. An overbar represents a time average and a prime represents
a fluctuation about the mean. These equations are closed by parameterizing the Reynolds stresses
and turbulent tracer fluxes as:
∂u ∂v ∂C
u0 w0 = −KM ; v 0 w0 = −KM ; C 0 w0 = −KC . (7)
∂z ∂z ∂z
Equations (1) and (2) express the momentum balance in the x- and y-directions, respectively.
The time evolution of all scalar concentration fields, including those for T (x, y, z, t) and S(x, y, z, t),
are governed by the advective-diffusive equation (5). The equation of state is given by equation
(6). In the Boussinesq approximation, density variations are neglected in the momentum equations
except in their contribution to the buoyancy force in the vertical momentum equation (3). Under
the hydrostatic approximation, it is further assumed that the vertical pressure gradient balances
the buoyancy force. Lastly, equation (4) expresses the continuity equation for an incompressible
fluid. For the moment, the effects of forcing and horizontal dissipation will be represented by the
schematic terms F and D, respectively. The horizontal and vertical mixing will be described more
fully in §4.10.1.
8
Variable Description
C(x, y, z, t) scalar quantity, i.e. temperature, salinity, nutrient concentration
Du , Dv , DC optional horizontal diffusive terms
Fu , Fv , FC forcing/source terms
f (x, y) Coriolis parameter
g acceleration of gravity
h(x, y) depth of sea floor below mean sea level
Hz (x, y, z) vertical grid spacing
ν, νθ molecular viscosity and diffusivity
KM , KC vertical eddy viscosity and diffusivity
P total pressure P ≈ −ρo gz
φ(x, y, z, t) dynamic pressure φ = (P/ρo )
ρo + ρ(x, y, z, t) total in situ density
S(x, y, z, t) salinity
t time
T (x, y, z, t) potential temperature
u, v, w the (x, y, z) components of vector velocity ~v
x, y horizontal coordinates
z vertical coordinate
ζ(x, y, t) the surface elevation
Variable Description
QC surface concentration flux
τsx , τsy surface wind stress
τbx , τby bottom stress
Table 2: The variables used in the vertical boundary conditions for the ocean model
The surface boundary condition variables are defined in Table 3.2. Since QT is a strong function
of the surface temperature, we usually choose to compute QT using the surface temperature and
the atmospheric fields in an atmospheric bulk flux parameterization. This bulk flux routine also
computes the wind stress from the winds.
On the variable bottom, z = −h(x, y), the horizontal velocity has a prescribed bottom stress
which is a choice between linear, quadratic, or logarithmic terms. The vertical concentration flux
9
may also be prescribed at the bottom, although it is usually set to zero.
10
∂v ∂φ gρ ∂z ∂ζ 1 ∂ Km ∂v
+ f u + ~v · ∇v = − − −g + + Fv + Dv (9)
∂t ∂y ρo ∂y ∂y Hz ∂σ Hz ∂σ
∂C 1 ∂ KC ∂C
+ ~v · ∇C = + FT + DT (10)
∂t Hz ∂σ Hz ∂σ
ρ = ρ(T, S, P ) (11)
∂φ −gHz ρ
= (12)
∂σ ρo
∂Hz ∂(Hz u) ∂(Hz v) ∂(Hz Ω)
+ + + =0 (13)
∂t ∂x ∂y ∂σ
where
~v = (u, v, Ω)
∂ ∂ ∂
~v · ∇ = u +v +Ω .
∂x ∂y ∂σ
The vertical velocity in σ coordinates is
1 z+h ∂ζ ∂z ∂z
Ω(x, y, σ, t) = w− −u −v
Hz ζ +h ∂t ∂x ∂y
and
∂z ∂z ∂z
w= +u +v + ΩHz .
∂t ∂x ∂y
In the stretched coordinate system, the vertical boundary conditions become:
Km ∂u
top (σ= 0) = τsx (x, y, t)
Hz ∂σ
Km ∂v
= τsy (x, y, t)
Hz ∂σ
KC ∂C QC
Hz ∂σ = ρo cP
Ω=0
Km ∂u
and bottom (σ = −1) = τbx (x, y, t)
Hz ∂σ
Km ∂v
= τby (x, y, t)
Hz ∂σ
KC ∂C
Hz ∂s =0
Ω = 0.
Note the simplification of the boundary conditions on vertical velocity that arises from the σ
coordinate transformation.
11
coordinate transformation in the horizontal. Let the new coordinates be ξ(x, y) and η(x, y), where
the relationship of horizontal arc length to the differential distance is given by:
1
(ds)ξ = dξ (14)
m
1
(ds)η = dη (15)
n
Here, m(ξ, η) and n(ξ, η) are the scale factors which relate the differential distances (∆ξ, ∆η) to
the actual (physical) arc lengths. Appendix C contains the curvilinear version of several common
vector quantities.
Denoting the velocity components in the new coordinate system by
~v · ξˆ = u (16)
and
~v · η̂ = v (17)
the equations of motion (8)-(13) can be re-written (see, e.g., Arakawa and Lamb [2]) as:
!
∂ Hz u ∂ Hz u2 ∂ Hz uv
∂ Hz uΩ
+ + +
∂t mn ∂ξ n ∂η m
∂σ mn
f ∂ 1 ∂ 1
− +v −u Hz v =
mn ∂ξ n ∂η m
Hz ∂φ gρ ∂z ∂ζ 1 ∂ Km ∂u Hz
− + +g + + (Fu + Du ) (18)
n ∂ξ ρo ∂ξ ∂ξ mn ∂σ Hz ∂σ mn
!
∂ Hz v ∂ Hz uv ∂ Hz v 2
∂ Hz vΩ
+ + +
∂t mn ∂ξ n ∂η ∂σ mmn
f ∂ 1 ∂ 1
+ +v −u Hz u =
mn ∂ξ n ∂η m
Hz ∂φ gρ ∂z ∂ζ 1 ∂ Km Hz
− + +g + ∂v∂σ + (Fv + Dv ) (19)
m ∂η ρo ∂η ∂η mn ∂σ Hz mn
∂ Hz C ∂ Hz uC ∂ Hz vC ∂ Hz ΩC
+ + + =
∂t mn ∂ξ n ∂η m ∂σ mn
1 ∂ KC ∂C Hz
+ (FC + DC ) (20)
mn ∂s Hz ∂σ mn
ρ = ρ(T, S, P ) (21)
∂φ gHz ρ
=− (22)
∂σ ρo
∂ Hz ∂ Hz u ∂ Hz v ∂ Hz Ω
+ + + = 0. (23)
∂t mn ∂ξ n ∂η m ∂σ mn
All boundary conditions remain unchanged.
12
4 Numerical Solution Technique
4.1 Vertical and horizontal discretization
4.1.1 Horizontal grid
∆ξ -
6
vi,j+1 6
6 ?
vi,j
The vertical discretization also uses a second-order finite-difference approximation. Just as we use
a staggered horizontal grid, the model was found to be more well-behaved with a staggered vertical
grid. The vertical grid is shown in Fig. 2.
wN
v ρN
wN−1
v ρN−1
v
w2
v ρ2
w1
v ρ1
w0
13
A B C
D E F
G H I J
K L
– u points
M N
– v points
– ρ points
– ψ points
4.2.1 Velocity
At the end of every time step, the values of many variables within the masked region are set to zero
by multiplying by the mask for either the u, v or ρ points. This is appropriate for the v points E
and L in Fig. 3, since the flow in and out of the land should be zero. It is likewise appropriate for
the u point at I, but is not necessarily correct for point G. The only term in the u equation that
∂ ∂u
requires the u value at point G is the horizontal viscosity, which has a term of the form ∂η ν ∂η .
Since point G is used in this term by both points A and M, it is not sufficient to replace its value
with that of the image point for A. Instead, the term ∂u ∂η is computed and the values at points D
and K are replaced with the values appropriate for either free-slip or no-slip boundary conditions.
∂ ∂v
Likewise, the term ∂ξ ν ∂ξ in the v equation must be corrected at the mask boundaries.
This is accomplished by having a fourth mask array defined at the ψ points, in which the values
are set to be no-slip in metrics. For no-slip boundaries, we count on the values inside the land
(point G) having been zeroed out. For point D, the image point at G should contain minus the
value of u at point A. The desired value of ∂u∂η is therefore 2uA while instead we have simply uA .
In order to achieve the correct result, we multiply by a mask which contains the value 2 at point
D. It also contains a 2 at point K so that ∂u∂η there will acquire the desired value of −2uM . The
corner point F is set to have a value of 1.
14
masks, such as point H in Fig. 3, are set to zero after every time step. This point would be used by
the horizontal diffusion term for points B, J, and N. This is corrected by setting the first derivative
terms at points E, I, and L to zero, to be consistent with a no-flux boundary condition. Note
that the equation of state must be able to handle T = S = 0 since this is the value inside masked
regions.
• In the case of wetting and drying, a critical depth, Dcrit , is supplied by the user.
• The total water depth (D = h + ζ) is compared to Dcrit . If the water level is less than this
depth, no flux is allowed out of that cell. Water can always flow in and resubmerge the cell.
• The wetting and drying only happens during the 2-D computations; the 3-D computations
see a depth of Dcrit in the “dry” areas.
• The ice component now checks for dry cells when computing the ice rheology.
2. Compute ρ and ρ∗ for use in the depth-integrated time steps, from the density either at time
n or time n + 21 .
3. Depth integrate the 3-D momentum right-hand side terms at time n + 21 for use in the depth-
integrated time steps (or extrapolate to obtain an estimate of those terms).
4. Take all the depth-integrated steps. Store weighted time-means of the u, v fields centered at
both time n + 12 and time n + 1 (plus ζ at time n + 1). The latter requires this time stepping
to extend past time n + 1, using M ∗ steps rather than just M .
5. Use the weighted time-means from depth-integrated fields to complete the corrector step for
the 3-D fields to time n + 1.
Great care is taken to avoid the introduction of a mode-splitting instability due to the use of shorter
time steps for the depth-integrated computations.
The mode coupling has evolved through the various ROMS versions, as shown in Fig. 4 (from
[74]). The time stepping schemes are also listed in Table 4.3 and described in detail in [73] and
[75]; the relevant ones are described in Appendix A.
15
Figure 4: Diagrams of the time stepping and mode coupling used in various ROMS versions. (a)
Rutgers University ROMS (from myroms.org), (b) ROMS AGRIF, (c) UCLA ROMS, described
in [73], (d) non-hydrostatic ROMS ([35]). In all, the curved arrows update the 3-D fields; those
with “pillars” are leapfrog in nature with the pillar representing the r.h.s. terms. Straight arrows
indicate exchange between the barotropic and baroclinic modes. The shape functions for the fast
time steps show just one option out of many possibilities. The grey function has weights to produce
an estimate at time n + 1, while the light red function has weights to produce an estimate at time
n + 12 .
16
SCRUM 3.0 Rutgers AGRIF UCLA Non-hydrostatic
Reference [28] [25] [61] [73] [35]
Barotropic LF-TR LF-AM3 with LF-AM3 with Gen. FB Gen. FB
mode √ FB feedback FB feedback1 (AB3-AM4) (AB3-AM4)
2-D αmax , iter. 2, (2)2 1.85, (2) 1.85, (2) 1.78, (1) 1.78, (1)
3-D momenta AB3 AB3 LF-AM3 LF-AM3 AB3 (mod)
Tracers AB3 LF-TR LF-AM3 LF-AM3 AB3 (mod)
Internal AB3 Gen. FB LF-AM3, LF-AM3, Gen. FB
waves (AB3-TR) FB feedback FB feedback (AB3-AM4)
αmax , advect. 0.72 0.72 1.587 1.587 0.78
αmax , Cor. 0.72 0.72 1.587 1.587 0.78
αmax , int. w. 0.72, (1) 1.14, (1,2) 1.85, (2) 1.85, (2) 1.78, (1)
Table 3: The time stepping schemes used in the various ROMS versions. α ≡ ωδt is the Courant
number and ω = ck is the frequency for a wave component with wavenumber k.
∂C
+ ∇ · (uC) = 0. (25)
∂t
The continuity equation:
(∇ · u) = 0 (26)
can be used to get from one tracer equation to the other. As a consequence of eq. (24), if the tracer is
spatially uniform, it will remain so regardless of the velocity field (constancy preservation). On the
other hand, as a consequence of (25), the volume integral of the tracer concentration is conserved
in the absence of internal sources and fluxes through the boundary. Both properties are valuable
and should be retained when constructing numerical ocean models.
The semi-discrete form of the tracer equation (20) is:
ξ ξ! η η!
∂ Hz C uHz C vHz C σ Hz Ω 1 ∂ Km ∂C
+δξ +δη +δσ C = +DC +FC (27)
∂t mn nξ mη mn mn ∂σ ∆z ∂σ
Here δξ , δη and δσ denote simple centered finite-difference approximations to ∂/∂ξ, ∂/∂η and ∂/∂σ
with the differences taken over the distances ∆ξ, ∆η and ∆σ, respectively. ∆z is the vertical
ξ η σ
distance from one ρ point to another. ( ) , ( ) and ( ) represent averages taken over the
distances ∆ξ, ∆η and ∆σ.
The finite volume version of the same equation is no different, except that a quantity C is
defined as the volume-averaged concentration over the grid box ∆V :
mn Hz C
Z
C= δξ δη δσ (28)
Hz ∆V mn
ξ ξ
uHz C
The quantity nξ
is the flux through an interface between adjacent grid boxes.
17
This method of averaging was chosen because it internally conserves first moments in the model
domain, although it is still possible to exchange mass and energy through the open boundaries.
The method is similar to that used in Arakawa and Lamb [2]; though their scheme also conserves
enstrophy. Instead, we will focus on (nearly) retaining constancy preservation while coupling the
barotropic (depth-integrated) equations and the baroclinic equations.
The time step in eq. (27) is assumed to be from time n to time n + 1, with the other terms being
evaluated at time n + 12 for second-order accuracy. Setting C to 1 everywhere reduces eq. (27) to:
ξ! η!
∂ Hz uHz vHz Hz Ω
+ δξ + δη + δσ =0 (29)
∂t mn nξ mη mn
If this equation holds true for the step from time n to time n + 1, then our constancy preservation
will hold.
In a hydrostatic model such as ROMS, the discrete continuity equation is needed to compute
Hz
vertical velocity rather than grid-box volume mn (the latter is controlled by changes in ζ in the
Hz Ω
barotropic mode computations). Here, mn is the finite-volume flux across the moving grid-box
interface, vertically on the w grid.
The vertical integral of the continuity eq. (23), using the vertical boundary conditions on Ω, is:
ξ! η!
∂ ζ uD vD
+ δξ + δη =0 (30)
∂t mn nξ mη
where ζ is the surface elevation, D = h + ζ is the total depth, and u, v are the depth-integrated
horizontal velocities. This equation and the corresponding 2-D momentum equations are time
stepped on a shorter time step than eq. (27) and the other 3-D equations. Due to the details in
the mode coupling, it is only possible to maintain constancy preservation to the accuracy of the
barotropic time steps.
is the total depth of the water column. The vertical integral of equation (18) is:
∂ Du ∂ Duu ∂ Duv Df v
+ + −
∂t mn ∂ξ n ∂η m mn
!
∂ 1 ∂ 1 D ∂φ2 ∂ζ
− vv − uv D=− +g
∂ξ n ∂η m n ∂ξ ∂ξ
D 1 ξ
+ F u + Dhu + τs − τbξ (33)
mn mn
where φ2 includes the ∂z∂ξ term, D hu is the horizontal viscosity, and the vertical viscosity only
contributes through the upper and lower boundary conditions. The corresponding vertical integral
18
of equation (19) is:
∂ Dv ∂ Duv ∂ Dvv Df u
+ + +
∂t mn ∂ξ n ∂η m mn
!
∂ 1 ∂ 1 D ∂φ2 ∂ζ
+ uv − uu D=− +g
∂ξ n ∂η m m ∂η ∂η
D 1
τsη − τbη . (34)
+ F v + Dhv +
mn mn
We also need the vertical integral of equation (23), shown above as eq. (30). √
The presence of a free surface introduces waves which propagate at a speed of gh. These
waves usually impose a more severe time-step limit than any of the internal processes. We have
therefore chosen to solve the full equations by means of a split time step. In other words, the depth
integrated equations (33), (34), and (30) are integrated using a short time step and the values of
u and v are used to replace those found by integrating the full equations on a longer time step. A
diagram of the barotropic time stepping is shown in Fig. 5.
Barotropic steps
Some of the terms in equations (33) and (34) are updated on the short time step while others
are not. The contributions from the slow terms are computed once per long time step and stored.
If we call these terms Ruslow and Rvslow , equations (33) and (34) become:
∂ Du ∂ Du u ∂ Du v Df v
+ + −
∂t mn ∂ξ n ∂η m mn
∂ 1 ∂ 1 gD ∂ζ D 1 ξ
− vv − uv D = Ruslow − + Du − τ (35)
∂ξ n ∂η m n ∂ξ mn mn b
∂ Dv ∂ Du v ∂ Dv v Df u
+ + +
∂t mn ∂ξ n ∂η m mn
∂ 1 ∂ 1 gD ∂ζ D 1 η
+ uv − uu D = Rvslow − + Dv − τ . (36)
∂ξ n ∂η m m ∂η mn mn b
When time stepping the model, we compute the right-hand-sides for equations (18) and (19) as
well as the right-hand-sides for equations (35) and (36). The vertical integral of the 3-D right-
hand-sides are obtained and then the 2-D right-hand-sides are subtracted. The resulting fields are
the slow forcings Ruslow and Rvslow . This was found to be the easiest way to retain the baroclinic
contributions of the non-linear terms such as uu − u u.
The model is time stepped from time n to time n+1 by using short time steps on equations (35),
(36) and (30). Equation (30) is time stepped first, so that an estimate of the new D is available for
19
the time rate of change terms in equations (35) and (36). A third-order predictor-corrector time
stepping is used. In practice, we actually time step all the way to time (n + dtfast × M ? ), while
maintaining weighted averages of the values of u, v and ζ. The averages are used to replace the
values at time n + 1 in both the baroclinic and barotropic modes, and for recomputing the vertical
grid spacing Hz . Fig. 6 shows one option for how these weights might look.
P ?
The primary weights, am , are used to compute hζin+1 ≡ M m
m=1 am ζ . There is a related set of
1 ?
secondary weights bm , used as hhuiin+ 2 ≡ M m
P
m=1 bm u . In order to maintain constancy preservation,
this relation must hold:
" n+ 1 n+ 1 n+ 1 n+ 1 #
Du Du Dv Dv
2 2 2 2
hζin+1
i,j = hζini,j − (mn)i,j ∆t − + − (37)
n i+ 12 ,j n i− 12 ,j m i,j+ 21 m i,j− 12
Shchepetkin and McWilliams ([73]) introduce a range of possible weights, but the ones used here
have a shape function: p q
τ τ τ
A(τ ) = A0 1− −r (38)
τ0 τ0 τ0
where p, q are parameters and A0 , τ0 , and r are chosen to satisfy normalization, consistency, and
second-order accuracy conditions,
Z τ?
In = τ n A(τ )dτ = 1, n = 0, 1, 2 (39)
0
using Newton iterations. τ ? is the upper limit of τ with A(τ ) ≥ 0. In practice we initially set
(p + 2)(p + q + 2)
A0 = 1, r = 0 and τ= ,
(p + 1)(p + q + 1)
M ? M?
X X m
am ≡ 1, am ≡ 1, (40)
m=1 m=1
M
and adjust r iteratively to satisfy the n = 2 condition of (39). We are using values of p = 2, q = 4,
and r = 0.284. This form allows some negative weights for small m, allowing M ? to be less than
1.5M .
ROMS also supports an older cosine weighting option, which isn’t recommended since it is only
first-order accurate.
gD ∂ζ gD ∂ζ
− + +F (41)
n ∂ξ n ∂ξ
where the term in square brackets is the mode coupling term and is held fixed over all the barotropic
steps and
Z ζ
1 ∂P
F =− dz (42)
ρ0 n −h ∂ξ
is the vertically integrated pressure gradient. The latter is a function of the bathymetry, free surface
gradient, and the free surface itself, as well as the vertical distribution of density.
20
Figure 6: Weights for the barotropic time stepping. The upper panel shows the primary weights,
centered at time n + 1, while the lower panel shows the secondary weights weights, centered at time
n + 12 .
21
The disadvantage of this approach is that after the barotropic time stepping is complete and
the new free surface is substituted into the full baroclinic pressure gradient, its vertical integral will
no longer be equal to the sum of the new surface slope term and the original coupling term based
on the old free surface. This is one form of mode-splitting error which can lead to trouble because
the vertically integrated pressure gradient is not in balance with the barotropic mass flux.
Instead, let us define the following:
Z ζ Z ζ (Z ζ )
1 ? 1 0
ρ= ρdz, ρ = 1 2 ρdz dz (43)
D −h 2D −h z
which implies that ρ and ρ? are actually independent of ζ as long as the density profile ρ = ρ(σ)
does not change. The vertically integrated pressure gradient becomes:
( ! )
1 g ∂ ρ? D2 ∂h 1 g ∂ζ D ∂ρ? ∂h
− − ρD =− D ρ? + + (ρ? − ρ) (45)
ρ0 n ∂ξ 2 ∂ξ ρ0 n ∂ξ 2 ∂ξ ∂ξ
In the case of uniform density ρ0 , we obtain ρ? ≡ ρ ≡ ρ0 , but we otherwise have two new terms.
The accuracy of these terms depends on an accurate vertical integration of the density, as described
in Shchepetkin and McWilliams (2005, [73]).
22
where we have introduced the advective fluxes:
Hz uC
Fξ = (47)
n
η Hz vC
F = (48)
m
Hz ΩC
Fσ = . (49)
mn
ξ ξ
ξ Hz uC
F = (50)
nξ
η η
Hz vC
Fη = (51)
mη
σ σ
Hz ΩC
Fσ = . (52)
mn
This scheme is known to have some unfortunate properties in the presence of strong gradients,
such as large over- and under-shoots of tracers, leading to the need for large amounts of horizontal
smoothing. ROMS provides alternative advection schemes with better behavior in many situations,
but retains this one for comparison purposes.
The barotropic advection is centered fourth-order unless you specifically pick centered second-order
as your horizontal advection scheme. To get fourth-order, create gradient terms:
ξ
∂C
ξ
G = (53)
∂ξ
η
∂C
Gη = (54)
∂η
σ
∂C
Gσ = . (55)
∂σ
ξ !
ξHz ξ 1 ∂Gξ
F = ξ u C − (56)
n 3 ∂ξ
η
Hz 1 ∂Gη
η η
F = η v C − (57)
m 3 ∂η
σ
Hz 1 ∂Gσ
σ
Fσ = Ω C − . (58)
mn 3 ∂σ
23
4.8.3 Fourth-order Akima
An alternate fourth-order algorithm is that by Akima:
!
∂C ∂C ∂C ∂C
ξ
G =2 + (59)
∂ξ i ∂ξ i+1 ∂ξ i ∂ξ i+1
!
∂C ∂C ∂C ∂C
η
G =2 + (60)
∂η j ∂η j+1 ∂η j ∂η j+1
∂C ∂C ∂C ∂C
σ
G =2 + (61)
∂σ k ∂σ k−1 ∂σ k ∂σ k−1
(62)
With the fluxes as in 56–58.
24
while for the v-velocity we have:
!" #
∂2v Hz u ∂2 Hz u
ξ
F = v−γ 2 −γ 2 (70)
∂ξ n ∂η n
!" #
∂2v Hz v ∂ 2 Hz v
η
F = v−γ 2 −γ 2 (71)
∂η m ∂η m
Hz w 1 9 9 1
σ
F = − vi,j,k−1 + vi,j,k + vi,j,k+1 − vi,j,k+2 (72)
mn 16 16 16 16
In all these terms, the second derivatives are evaluated at an upstream location.
∂ Hz u ∂ Hz v ∂ Hz Ω ∂ Du ∂ Dv
+ + − − = 0. (73)
∂ξ n ∂η m ∂σ mn ∂ξ n ∂η m
Solving for Hz Ω/mn and using the semi-discrete notation of §4.4 we obtain:
Z " ξ! η! ξ! η !#
Hz Ω uD vD uHz vHz
= δξ + δη − δξ − δη dσ. (74)
mn nξ mη nξ mη
The integral is actually computed as a sum from the bottom upwards and also as a sum from the
top downwards. The value used is a linear combination of the two, weighted so that the surface
down value is used near the surface while the other is used near the bottom.
The density is obtained from temperature and salinity via an equation of state. ROMS provides
a choice of a nonlinear equation of state ρ = ρ(T, S, z) or a linear equation of state ρ = ρ(T ). The
nonlinear equation of state has been modified and now corresponds to the UNESCO equation
of state as derived by Jackett and McDougall [34]. It computes in situ density as a function of
potential temperature, salinity and pressure.
Warning: although we have used it quite extensively, McDougall (personal communication)
claims that the single-variable (ρ = ρ(T )) equation of state is not dynamically appropriate as is.
He has worked out the extra source and sink terms required, arising from vertical motions and the
compressibility of water. They are quite complicated and we have not implemented them to see if
they alter the flow.
25
" ! ! !
mn ∂ Hz σξξ ∂ Hz σξη ∂ σξs
F u ≡ ξb · (∇ · ~σ ) = + + + (75)
Hz ∂ξ n ∂η m ∂s mn
#
∂ 1 ∂ 1 1 ∂Hz
Hz σξη − Hz σηη − σss (76)
∂η m ∂ξ n n ∂ξ
" ! ! !
v mn ∂ Hz σηξ ∂ Hz σηη ∂ σηs
F ≡ ηb · (∇ · ~σ ) = + + + (77)
Hz ∂ξ n ∂η m ∂s mn
#
∂ 1 ∂ 1 1 ∂Hz
Hz σηξ − Hz σξξ − σss (78)
∂ξ n ∂η m m ∂η
where
∂u ∂ 1
eξξ = m + mnv , (85)
∂ξ ∂η m
∂v ∂ 1
eηη = n + mnu , (86)
∂η ∂ξ n
1 ∂ (ωHz ) m ∂Hz n ∂Hz
ess = + u + v , (87)
Hz ∂s Hz ∂ξ Hz ∂η
m ∂ (nv) n ∂ (mu)
2 eξη = + , (88)
n ∂ξ m ∂η
1 ∂ (mu) ∂ω
2 eξs = + mHz , (89)
mHz ∂s ∂ξ
1 ∂ (nv) ∂ω
2 eηs = + n Hz . (90)
nHz ∂s ∂η
Here, AM (ξ, η) and KM (ξ, η, s) are the spatially varying horizontal and vertical viscosity coef-
ficients, respectively, and ν is another (very small, often neglected) horizontal viscosity coefficient.
Notice that because of the generalized terrain-following vertical coordinates of ROMS, we need
to transform the horizontal partial derivatives from constant ”z-”surfaces to constant ”s-”surfaces.
And the vertical metric or level thickness is the Jacobian of the transformation, Hz = ∂z ∂s . Also in
ωHz 3
these models, the ”vertical” velocity is computed as mn and has units of m /s.
26
4.10.2 Transverse stress tensor
Assuming transverse isotropy, as in Sadourny and Maynard (1997) [69] and Griffies and Hallberg
(2000) [23], the deviatoric stress tensor can be split into vertical and horizontal sub-tensors. The
horizontal (or transverse) sub-tensor is symmetric, it has a null trace, and it possesses axial sym-
metry in the local vertical direction. Then, transverse stress tensor can be derived from eq. (76)
and (76), yielding
!
∂ Hz F uξ ∂ Hz F uη
u 2
Hz F = n m + m2 n (91)
∂ξ n ∂η m
!
∂ Hz F vξ ∂ Hz F vη
v 2
Hz F = n m + m2 n (92)
∂ξ n ∂η m
where
1 m ∂ (nu) n ∂ (mv)
F uξ = AM − , (93)
n n ∂ξ m ∂η
1 n ∂ (mu) m ∂ (nv)
F uη = AM + , (94)
m m ∂η n ∂ξ
1 m ∂ (nv) n ∂ (mu)
F vξ = AM + , (95)
n n ∂ξ m ∂η
1 n ∂ (mv) m ∂ (nu)
F vη = AM − . (96)
m m ∂η n ∂ξ
Notice the flux form of eq. (91) and (92) and the symmetry between the F uξ and F vη terms
which are defined at density points on a C-grid. Similarly, the F uη and F vξ terms are symmetric
and defined at vorticity points. These staggering positions are optimal for the discretization of the
tensor; it has no computational modes and satisfies first-moment conservation.
The biharmonic friction operator can be computed by applying twice the tensor operator eq.
(91) and (92), but with the squared root of the biharmonic viscosity coefficient (Griffies and Hall-
berg, 2000 [23]). For simplicity and momentum balance, the thickness Hz appears only when
computing the second harmonic operator as in Griffies and Hallberg (2000).
! ! !
u ∂ Hz Ruξ ∂ Hz Ruη ∂
Hz R = n m 2
+m n 2
+ Rus (97)
∂ξ n ∂η m ∂s
! ! !
v ∂ Hz Rvξ ∂ Hz Rvη ∂
Hz R = n m 2
+m n 2
+ Rvs (98)
∂ξ n ∂η m ∂s
where
27
1 1 ∂ (nu) ∂z 1 ∂ (nu) 1 ∂ (mv) ∂z 1 ∂ (mv)
Ruξ = AM m −m − n −n , (99)
n n ∂ξ ∂ξ Hz ∂s m ∂η ∂η Hz ∂s
1 1 ∂ (mu) ∂z 1 ∂ (mu) 1 ∂ (nv) ∂z 1 ∂ (nv)
Ruη = AM n −n + m −m , (100)
m m ∂η ∂η Hz ∂s n ∂ξ ∂ξ Hz ∂s
∂z 1 ∂z 1 ∂ (nu) ∂ (nu) 1 ∂z 1 ∂ (mv) ∂ (mv)
Rus =m AM m −m − n −n + (101)
∂ξ n ∂ξ Hz ∂s ∂ξ m ∂η Hz ∂s ∂η
∂z 1 ∂z 1 ∂ (mu) ∂ (mu) 1 ∂z 1 ∂ (nv) ∂ (nv)
n AM n −n + m −m , (102)
∂η m ∂η Hz ∂s ∂η n ∂ξ Hz ∂s ∂ξ
Notice that transverse stress tensor remains invariant under coordinate transformation. The
rotated tensor (97) and (98) retains the same properties as the unrotated tensor (91) and (92). The
additional terms that arise from the slopes of s-surfaces along geopotentials are discretized using a
modified version of the triad approach of Griffies et al. (1998) [22].
4.10.4 Biharmonic
Biharmonic mixing has less of a physical justification and is used for damping of numerical noise
at the 2∆x scale. The biharmonic operator is ∇4 = ∇2 ∇2 ; the corresponding term is computed
using a temporary variable Y :
mn ∂ ν4 Hz m ∂ψ ∂ ν4 Hz n ∂ψ
Y = + (107)
Hz ∂ξ n ∂ξ ∂η m ∂η
and is
∂ Hz m ∂Y ∂ Hz n ∂Y
− + (108)
∂ξ n ∂ξ ∂η m ∂η
where ψ is any of u, v, T , and S. Note that u and v are treated as independent scalar quantities
rather than as a vector. The complete Laplacian operator on a vector quantity ~u contains additional
terms, including v terms in the u equation and vice versa. These extra terms were found to be
small in a test problem and have been left out of the model.
28
4.11.1 Mellor-Yamada
One of the more popular closure schemes is that of Mellor and Yamada [56], [57]. They actually
present a hierarchy of closures of increasing complexity. ROMS provides only the “Level 2.5”
closure with the Galperin et al. [20] modifications as described in Allen et al. [1]. This closure
scheme adds two prognostic equations, one for the turbulent kinetic energy ( 12 q 2 ) and one for the
turbulent kinetic energy times a length scale (q 2 l).
The turbulent kinetic energy equation is:
! " !#
D q2 ∂ ∂ q2
− Kq = P s + P b − ξd (109)
Dt 2 ∂z ∂z 2
where Ps is the shear production, Pb is the buoyant production and ξd is the dissipation of turbulent
kinetic energy. These terms are given by
" 2 2 #
∂u ∂v
Ps = Km + , (110)
∂z ∂z
Pb = Ks N 2 , (111)
q3
ξd = (112)
B1 l
where B1 is a constant. One can also add a traditional horizontal Laplacian or biharmonic diffusion
(Dq ) to the turbulent kinetic energy equation. The form of this equation in the model coordinates
becomes
! ! ! ! !
∂ Hz q 2 ∂ Hz uq 2 ∂ Hz vq 2 ∂ Hz Ωq 2 ∂ Kq ∂q 2
+ + + − =
∂t mn ∂ξ n ∂η m ∂s mn ∂s mnHz ∂s
" 2 2 #
2Hz Km ∂u ∂v 2Hz Ks 2 2Hz q 3 Hz
+ + N − + Dq . (113)
mn ∂z ∂z mn mnB1 l mn
The equation is timestepped much like the model tracer equations, including an implicit solve for
the vertical operations and an option for using the third-order upwind advection.
There is also an equation for the turbulent length scale l:
" #
D 2 ∂ ∂lq 2 q3
lq − Kl = lE1 (Ps + Pb ) − W̃ (114)
Dt ∂z ∂z B1
29
where W̃ is the wall proximity function:
l 2
W̃ = 1 + E2 (115)
kL
1 1
L−1 = + (116)
ζ −z H +z
The form of this equation in the model coordinates becomes
! ! ! ! !
∂ Hz q 2 l ∂ Hz uq 2 l ∂ Hz vq 2 l ∂ Hz Ωq 2 l ∂ Kq ∂q 2 l
+ + + − =
∂t mn ∂ξ n ∂η m ∂s mn ∂s mnHz ∂s
Hz Hz q 3 Hz
lE1 (Ps + Pb ) − W̃ + Dql . (117)
mn mnB1 mn
The constants are set to (A1 , A2 , B1 , B2 , C1 , E1 , E2 ) = (0.92, 0.74, 16.6, 10.1, 0.08, 1.8, 1.33). The
quantities q 2 and q 2 l are both constrained to be no smaller than 10−8 while l is set to be no larger
than 0.53q/N .
Surface boundary layer The Large, McWilliams and Doney scheme (LMD) matches separate
parameterizations for vertical mixing of the surface boundary layer and the ocean interior. A
formulation based on boundary layer similarity theory is applied in the water column above a
calculated boundary layer depth hsbl . This parameterization is then matched at the interior with
schemes to account for local shear, internal wave and double diffusive mixing effects.
Viscosity and diffusivities at model levels above a calculated surface boundary layer depth
(hsbl ) are expressed as the product of the length scale hsbl , a turbulent velocity scale wx and a
non-dimensional shape function.
νx = hsbl wx (σ)Gx (σ) (125)
where σ is a non-dimensional coordinate ranging from 0 to 1 indicating depth within the surface
boundary layer. The x subscript stands for one of momentum, temperature and salinity.
30
Surface Boundary layer depth The boundary layer depth hsbl is calculated as the minimum
of the Ekman depth, estimated as,
he = 0.7u∗ /f (126)
q
(where u∗ is the friction velocity u∗ = τx2 + τy2 /ρ ), the Monin-Obukhov depth:
31
for momentum and,
− 1.0 ≤ ζ < 0 (133)
for scalars. The non dimensional flux profiles in this regime are,
φm = (1 − 16ζ)1/4 (134)
1/2
φs = (1 − 16ζ) (135)
In more unstable conditions φx is chosen to match the Businger-Dyer forms and with the free
convective limit. Here the flux profiles are
The shape function The non-dimensional shape function G(σ) is a third order polynomial
with coefficients chosen to match the interior viscosity at the bottom of the boundary layer and
Monin-Obukhov similarity theory approaching the surface. This function is defined as a 3rd order
polynomial.
G(σ) = ao + a1 σ + a2 σ 2 + a3 σ 3 (138)
with the coefficients specified to match surface boundary conditions and to smoothly blend with
the interior,
ao = 0 (139)
a1 = 1 (140)
νx (hsbl ) ∂x νx (h) νx (h)∂σ wx (1)
a2 = −2 + 3 + + (141)
hwx (1) wx (1) hwx2 (1)
νx (hsbl ) ∂x νx (h) νx (h)∂σ wx (1)
a3 = 1 − 2 − − (142)
hwx (1) wx (1) hwx2 (1)
where νx (h) is the viscosity calculated by the interior parameterization at the boundary layer depth.
Countergradient flux term The second term of the LMD scheme’s surface boundary layer
formulation is the non-local transport term γ which can play a significant role in mixing during
surface cooling events. This is a redistribution term included in the tracer equation separate from
the diffusion term and is written as
∂
− Kγ. (143)
∂z
LMD base their formulation for non-local scalar transport on a parameterization for pure free
convection from Mailhôt and Benoit [48]. They extend this parameterization to cover any unstable
surface forcing conditions to give
wT0 + wTR
γ T = Cs (144)
wT (σ)h
for temperature and
wS0
γ S = Cs (145)
wS (σ)h
for salinity (other scalar quantities with surface fluxes can be treated similarly). LMD argue that
although there is evidence of non-local transport of momentum as well, the form the term would
take is unclear so they simply specify γm = 0.
32
The interior scheme The interior scheme of Large, McWilliams and Doney estimates the viscos-
ity coefficient by adding the effects of several generating mechanisms: shear mixing, double-diffusive
mixing and internal wave generated mixing.
Shear generated mixing The shear mixing term is calculated using a gradient Richardson
number formulation, with viscosity estimated as:
ν0 Rig < 0,
νxs = ν [1 − (Rig /Ri0
0 )2 ]3 0 < Rig < Ri0 , (147)
0 Rig > Ri0 .
Double diffusive processes The second component of the interior mixing parameteriza-
tion represents double diffusive mixing. From limited sources of laboratory and field data LMD
parameterize the salt fingering case (Rρ > 1.0)
1 × 10−4 [1 − ( (R0ρ −1 )2 )3 for 1.0 < Rρ < Rρ0 = 1.9,
Rρ −1
νsd (Rρ ) = (148)
0 otherwise.
νθd (Rρ ) = 0.7νsd (149)
For diffusive convection (0 < Rρ < 1.0) LMD suggest several formulations from the literature
and choose the one with the most significant impact on mixing (Fedorov [12]).
Internal wave generated mixing Internal wave generated mixing serves as the background
mixing in the LMD scheme. It is specified as a constant for both scalars and momentum. Eddy
diffusivity is estimated based on the data of Ledwell et al. [43]. While Peters et al. [62] suggest
eddy viscosity should be 7 to 10 times larger than diffusivity for gradient Richardson numbers
below approximately 0.7. Therefore LMD use
w
νm = 1.0 × 10−4 m2 s−1 (152)
−5 2 −1
νsw = 1.0 × 10 m s (153)
33
where φ represents one of u, v, or C, and K is the corresponding vertical viscous or diffusive
coefficient. This is timestepped using a semi-implicit Crank-Nicholson scheme with a weighting of
0.5 on the old timestep and 0.5 on the new timestep. Specifically, the equation of motion for φ can
be written as:
∂(Hz φ) ∂ K ∂φ
= mnRφ + (155)
∂t ∂σ Hz ∂σ
where Rφ represents all of the forcing terms other than the vertical viscosity or diffusion. Since we
want the diffusion term to be evaluated partly at the current timestep n and partly at the next
timestep n + 1, we introduce the parameter λ and rewrite equation (155) as:
!
∂(Hz φ) ∂ K ∂φn ∂ K ∂φn+1
= mnRφ + (1 − λ) +λ . (156)
∂t ∂σ Hz ∂σ ∂σ Hz ∂σ
where k is used as the vertical level index. This can be reorganized so that all the terms involving
φn+1 are on the left and all the other terms are on the right. The equation for φn+1k will contain
n+1 n−1
terms involving the neighbors above and below (φk+1 and φk+1 ) which leads to a set of coupled
equations with boundary conditions for the top and bottom. The general form of these equations
is:
Ak φn+1 n+1
k+1 + Bk φk + Ck φn+1
k−1 = Dk (158)
where the boundary conditions are written into the coefficients for the end points. In this case the
coefficients become:
A(1) = 0 (159)
λ∆t Kk−1
A(2 : N) = − (160)
∆σ 2 Hzn+1
k−1
n+1 λ∆t K1
B(1) = Hz1 + (161)
∆σ 2 Hzn+1
1
λ∆t K k λ∆t Kk−1
B(2 : Nm) = Hzn+1 + n+1 + (162)
k 2
∆σ Hzk ∆σ 2 Hzn+1
k−1
λ∆t KNm
B(N) = Hzn+1 + (163)
N
∆σ 2 Hzn+1
Nm
λ∆t Kk
C(1 : Nm) = − (164)
∆σ 2 Hzn+1
k
C(N) = 0 (165)
∆t(1 − λ) K1 n ∆t
D(1) = Hzn1 φn1 + ∆t mnRφ1 + 2 n
(φ2 − φn1 ) − τb (166)
∆σ Hz1 ∆σ
D(2 : Nm) = Hznk φnk + ∆t mnRφk + (167)
" #
∆t(1 − λ) Kk n Kk−1
2 n
(φk+1 − φnk ) − n (φnk − φnk−1 ) (168)
∆σ Hzk Hzk−1
∆t(1 − λ) KNm n ∆t
D(N) = HznN φnN + ∆t mnRφN − 2 n
(φN − φnNm ) + τs (169)
∆σ HzNm ∆σ
34
This is a standard tridiagonal system for which the solution procedure can be found in any standard
reference, such as Press et al. [65].
This boundary condition is extremely simple and consists of setting the gradient of a field to zero
at the edge. The outside value is set equal to the closest interior value.
ROMS now assumes a wall condition if no other boundary condition is chosen. This is a zero
gradient condition for tracers and the surface elevation and zero flow for the normal velocity. For
tangential velocities, the wall is treated as either no-slip or free-slip, depending on the value of
gamma2 chosen by the user.
φ = φext (170)
For the normal component of the barotropic velocity, one option is to radiate out deviations from
exterior values at the speed of the external gravity waves (Flather, [14]):
u = uext − gD (ζ − ζ ext )
p
(171)
The exterior values are often used to provide tidal boundary contitions to the barotropic mode.
However, there are times when only the tidal elevation is known. A reduced physics option is
available for estimating uext in that case.
The time derivative here can be handled either explicitly or implicitly. The model uses an implicit
timestep, with the term ∂ζ
∂ξ being evaluated at the new timestep.
35
4.13.6 Radiation boundary condition
In realistic domains, open boundary conditions can be extremely difficult to get right. There are
situations in which incoming flow and outgoing flow happen along the same boundary or even at
different depths at the same horizontal location. Orlanski [59] proposed a radiation scheme in which
a local normal phase velocity is computed and used to radiate things out (if it is indeed going out).
This works well for a wave propagating normal to the boundary, but has problems when waves
approach the boundary at an angle. Raymond and Kuo [67] have modified the scheme to account
for propagation in all three directions. In ROMS, only the two horizontal directions are accounted
for (with the recommended RADIATION_2D option):
∂φ ∂φ ∂φ
= − φξ + φη ) (173)
∂t ∂ξ ∂η
where
F ∂φ
∂ξ
φξ = (174)
∂φ 2 ∂φ 2
∂ξ + ∂η
F ∂φ
∂η
φη = (175)
∂φ 2 ∂φ 2
∂ξ + ∂η
∂φ
F =− (176)
∂t
These terms are evaluated at the closest interior point in a manner consistent with the time stepping
scheme used. The phase velocities are limited so that the local CFL condition is satisfied. They are
then applied to the boundary point using equation (173), again using a consistent time stepping
scheme. Raymond and Kuo give the form used for centered differencing and a leapfrog time step
while ROMS uses one-sided differences.
The radiation approach is appropriate for waves leaving the domain. A check is made to see
which way the phase velocity is headed. If it is entering the domain, a zero gradient condition is
applied unless the next option is also specified.
36
5 Ice Model Formulation
The sea-ice component of ROMS is a combination of the elastic-viscous-plastic (EVP) rheology
(Hunke and Dukowicz [33], Hunke [32]) and simple one-layer ice and snow thermodynamics with a
molecular sublayer under the ice (Mellor and Kantha [55]). It is tightly coupled, having the same
grid (Arakawa-C) and timestep as the ocean and sharing the same parallel coding structure for use
with MPI or OpenMP (Budgell [5]).
5.1 Dynamics
The momentum equations describe the change in ice/snow velocity due to the combined effects of
the Coriolis force, surface ocean tilt, air and water stress, and internal ice stress: (177) and (178):
∂u ∂ζw
M = Mfv − Mg + τax + τwx + Fx (177)
∂t ∂x
∂v ∂ζw
M = −M f u − M g + τay + τwy + Fy . (178)
∂t ∂y
In this model, we neglect the nonlinear advection terms as well as the curvilinear terms in the
internal ice stress. Nonlinear formulas are used for both the ocean-ice and air-ice surface stress:
~10 |V
~τa = ρa Ca |V ~10 (179)
1
Ca = Cd [1 − cos(2π min(hi + .1, .5)] (180)
2
~τw = ρw Cw |~vw − ~v |(~vw − ~v ). (181)
The force due to the internal ice stress is given by the divergence of the stress tensor σ. The rheology
is given by the stress-strain relation of the medium. We would like to emulate the viscous-plastic
rheology of Hibler (1979) [29]:
P
σij = 2η ˙ij + (ζ − η)˙kk δij − δij (182)
2
!
1 ∂ui ∂uj
˙ij ≡ + (183)
2 ∂xj ∂xi
ζ
.η= (186)
e2
We would also like to have an explicit model that can be solved efficiently on parallel computers.
The EVP rheology has a tunable coefficient E (the Young’s modulus) which can be chosen to make
the elastic term small compared to the other terms. We rearrange the VP rheology:
1 η−ζ P
σij + σkk δij + δij = ˙ij (187)
2η 4ηζ 4ζ
then add the elastic term:
1 ∂σij 1 η−ζ P
+ σij + σkk δij + δij = ˙ij (188)
E ∂t 2η 4ηζ 4ζ
37
Much like the ocean model, the ice model has a split timestep. The internal ice stress term is
updated on a shorter timestep so as to allow the elastic wave velocity to be resolved.
Once the new ice velocities are computed, the ice tracers can be advected using the MPDATA
scheme [77]. The tracers in this case are the ice thickness, ice concentration, snow thickness, internal
ice temperature, and surface melt ponds. The continuity equations describing the evolution of these
parameters (equations (189)–(191)) also include thermodynamic terms (Sh , Ss and SA ), which will
be described in §5.2:
∂Ahi ∂(uAhi ) ∂(vAhi )
=− − + Sh + Dh (189)
∂t ∂x ∂y
∂Ahs ∂(uAhs ) ∂(vAhs )
=− − + Ss + Ds (190)
∂t ∂x ∂y
∂A ∂(uA) ∂(vA)
=− − + SA + DA 0 ≤ A ≤ 1. (191)
∂t ∂x ∂y
The first two equations represent the conservation of ice and snow. Equation 191 is discussed in
some detail in MK89, but represents the advection of ice blocks in which no ridging occurs as long
as there is any open water. An optional ridging term can be added (Gray and Killworth [21]):
∂A ∂(uA) ∂(vA)
=− − − Aα(A) ∇ · ~v H(−∇ · ~v ) + SA + DA 0 ≤ A ≤ 1. (192)
∂t ∂x ∂y
where α(A) is an arbitrary function such that α(0) = 0, α(1) = 1, and 0 ≤ α(A) ≤ 1. The ridging
term leads to an increase in hi under convergent flow as would be produced by ridging. The function
α(A) should be chosen so that it is near zero until the ice concentration is large enough that ridging
is expected to occur, then should increase smoothly to one.
The symbols used in these equations along with the values for the constants are listed in Table
4.
Note that Hibler’s hI variable is equivalent to our Ahi combination - his hI is the average
thickness over the whole gridbox while our hi is the average thickness over the ice-covered fraction
of the gridbox.
5.2 Thermodynamics
The thermodynamics is based on calculating how much ice grows and melts on each of the surface,
bottom, and sides of the ice floes, as well as frazil ice formation (Mellor and Kantha [55]). Once
the ice tracers are advected, the ice concentration and thickness are timestepped according to the
terms on the right:
(189) and (191) is:
DAhi ρo
= [A(Wio − Wai ) + (1 − A)Wao + Wf r ] (193)
Dt ρi
DA ρo A
= [Φ(1 − A)Wao + (1 − A)Wf r ] 0 ≤ A ≤ 1. (194)
Dt ρi hi
The term Ahi is the “effective thickness”, a measure of the ice volume. Its evolution equation
is simply quantifying the change in the amount of ice. The ice concentration equation is more
interesting in that it provides the partitioning between ice melt/growth on the sides vs. on the top
and bottom. The parameter Φ controls this and has differing values for ice melt and retreat. In
principle, most of the ice growth is assumed to happen at the base of the ice while rather more of
the melt happens on the sides of the ice due to warming of the water in the leads.
The heat fluxes through the ice are based on a simple one layer Semtner [70] type model
with snow on top. The temperature is assumed to be linear within the snow and within the ice.
38
Variable Value Description
A(x, y, t) ice concentration
α(A) ridging function
Ca nonlinear air drag coefficient
Cd 2.2 × 10−3 air drag coefficient
Cw 10 × 10−3 water drag coefficient
(Dh , Ds , DA ) diffusion terms
δij Kronecker delta function
E Young’s modulus
e 2 eccentricity of the elliptical yield curve
ij (x, y, t) strain rate tensor
η(x, y, t) nonlinear shear viscosity
f (x, y) Coriolis parameter
(Fx , Fy ) internal ice stress
g 9.8 m s−2 acceleration of gravity
H Heaviside function
hi (x, y, t) ice thickness of ice-covered fraction
ho 1m ice cutoff thickness
hs (x, y, t) snow thickness on ice-covered fraction
M (x, y, t) ice mass (density times thickness)
P (x, y, t) ice pressure or strength
(P ∗ , C) (2.75 × 104 , 20) ice strength parameters
(Sh , Ss , SA ) thermodynamic terms
σij (x, y, t) stress tensor
~τa air stress
~τw water stress
(u, v) the (x, y) components of ice velocity ~v
~
(V10 , ~vw ) 10 meter air and surface water velocities
(ρa , ρw ) (1.3 kg m−3 , 1025 kg m−3 ) air and water densities
ζ(x, y, t) nonlinear bulk viscosity
ζw (x, y, t) height of the ocean surface
39
The ice contains brine pockets for a total ice salinity of 5. The surface ocean temperature and
salinity is half a dz below the surface. The water right below the surface is assumed to be at
the freezing temperature; a logarithmic boundary layer is computed having the temperature and
salinity matched at freezing.
Here, the W variables are the freeze or melt rates as shown in Fig. 7 and Table 5. The frazil
ice growth Wf r will be discussed further in §5.2.2—note that it contributes to changes in A as well
as to changes in hi . The other term that contributes to A is Wao . This term includes a factor Φ
which Mellor and Kantha set to different values depending on whether ice is melting or freezing:
6
Wai
Wao
6 6
?
Wro
Wf r Wio
Figure 7: Diagram of the different locations where ice melting and freezing can occur.
Figure 8 shows the locations of the ice and snow temperatures and the heat fluxes. The tem-
perature profile is assumed to be linear between adjacent temperature points. The interior of the
ice contains “brine pockets”, leading to a prognostic equation for the temperature T1 .
The surface flux to the air is:
Qai = −H ↓ −LE ↓ −s LW↓ −(1 − αs )SW↓ +s σ(T3 + 273)4 (198)
The formulas for sensible heat, latent heat, and incoming longwave and shortwave radiations are
the same as in Parkinson and Washington [60] and are shown in Appendix E. The sensible heat is
11111111111111111
00000000000000000
00000000000000000
11111111111111111
Qai
T3 Qao
11111
00000
00000
11111
00000000000000000
11111111111111111 00000
11111
hs Qs
T2
Qi2 FT
hi T1
Qio
T0
FT
Figure 8: Diagram of internal ice temperatures and fluxes. The hashed layer is the snow.
40
Variable Value Description
αw 0.10 shortwave albedo of water
αi 0.60 shortwave albedo of wet ice
αi 0.65 shortwave albedo of dry ice
αs 0.72 shortwave albedo of wet snow
αs 0.85 shortwave albedo of dry snow
Ck snow correction factor
Cpi 2093 J kg−1 K−1 specific heat of ice
Cpo 3990 J kg−1 K−1 specific heat of water
w 0.97 longwave emissivity of water
i 0.97 longwave emissivity of ice
s 0.99 longwave emissivity of snow
E(T, r) enthalpy of the ice/brine system
FT ↑ heat flux from the ocean into the ice
H↓ sensible heat
iw fraction of the solar heating transmitted
through a lead into the water below
ki 2.04 W m−1 K− 1 thermal conductivity of ice
ks 0.31 W m−1 K− 1 thermal conductivity of snow
Li 302 MJ m−3 latent heat of fusion of ice
Ls 110 MJ m−3 latent heat of fusion of snow
LE ↓ latent heat
LW↓ incoming longwave radiation
m −0.054◦ C/PSU coefficient in linear Tf (S) = mS equation
Φ contribution to A equation from freezing water
Qai heat flux out of the snow/ice surface
Qao heat flux out of the ocean surface
Qi2 heat flux up out of the ice
Qio heat flux up into the ice
Qs heat flux up through the snow
r brine fraction in ice
ρi 910 m3 /kg density of ice
Si 5 PSU salinity of the ice
SW↓ incoming shortwave radiation
σ 5.67 × 10−8 W m−2 K−4 Stefan-Boltzmann constant
T0 temperature of the bottom of the ice
T1 temperature of the interior of the ice
T2 temperature at the upper surface of the ice
T3 temperature at the upper surface of the snow
Tf freezing temperature
Tmelt_i mSi melting temperature of ice
Tmelt_s 0◦ C melting temperature of snow
Wai melt rate on the upper ice/snow surface
Wao freeze rate at the air/water interface
Wf r rate of frazil ice growth
Wio freeze rate at the ice/water interface
Wro Wai rate of run-off of surface melt water
41
a function of T3 , as is the heat flux through the snow Qs . Setting Qai = Qs , we can solve for T3
by setting T3n+1 = T3n + ∆T3 and linearizing in ∆T3 . The temperature T3 is found by an iterative
solution of the surface heat flux balance (using the previous value of T1 in equation 206). As in
Parkinson and Washington, if T3 is found to be above the melting temperature, it is set to Tmelt
and the extra energy goes into melting the snow or ice:
Qai − Qi2
Wai = (199)
ρo L3
L3 ≡ [E(T3 , 1) − E(T1 , R1 )] (200)
Note that L3 = (1 − r)Li plus a small sensible heat correction. We are not storing water on
the surface in melt pools, so everything melted at the surface is assumed to flow into the ocean
(Wro = Wai ).
Inside the ice there are brine pockets in which there is salt water at the in situ freezing tem-
perature. It is assumed that the ice has a uniform overall salinity of Si and that the freezing
temperature is a linear function of salinity. The brine fraction r is given by
Si m
r=
T1
∂E Si mLi
=− + Cpi (202)
∂T T12
2ki
QI2 = (T1 − T2 ) (204)
hi
These can be set equal to each other to solve for T2
T3 + Ck T1
T2 = (205)
1 + Ck
where
2ki hs
Ck ≡ .
hi ks
Substituting into (204), we get:
2ki (T1 − T3 )
Qs = QI2 = (206)
hi (1 + Ck )
Note that in the absence of snow, Ck becomes zero and we recover the formula for the no-snow
case in which T3 = T2 .
At the bottom of the ice, we have
2ki
QI0 = (T0 − T1 ) (207)
hi
42
Variable Value Definition
b 3.0 factor
Ė evaporation
k 0.4 von Karman’s constant
ν 1.8 × 10−6 m2 s−1 kinematic viscosity of seawater
Ṗ precipitation
Pr 13.0 molecular Prandtl number
Prt 0.85 turbulent Prandtl number
S0 surface salinity
τio stress on the ocean from the ice
τao stress on the ocean from the wind
T internal ocean temperature
−1/2
uτ friction velocity |τio |1/2 ρo
z0 roughness parameter
The difference between QI0 and QI2 goes into the enthalpy of the ice:
∂E
ρi hi + ~v · ∇E = QI0 − QI2 (208)
∂t
We can use the chain rule to obtain an equation for timestepping T1 :
∂E ∂T1
ρi hi + ~v · ∇T1 = QI0 − QI2 (209)
∂T ∂t
where
2ki (T1 − T3 )
QI0 − QI2 = (T0 − T1 ) −
hi 1 + Ck
2ki T3 − (2 + Ck )T1
= (T0 +
hi 1 + Ck
43
Variable Value Definition
Cpi 1994 J kg−1 K−1 specific heat of ice
Cpw 3987 J kg−1 K−1 specific heat of water
γ mi /mw2 fraction of water that froze
L 3.16e5 J kg−1 latent heat of fusion
mi mass of ice formed
mw1 mass of water before freezing
mw2 mass of water after freezing
m −0.0543 constant in freezing equation
n 7.59 × 10−4 constant in freezing equation
S1 salinity before freezing
S2 salinity after freezing
T1 temperature before freezing
T2 temperature after freezing
Once we have a the value for FT , we can use it to find the ice growth rates:
1
Wio = (Qio − FT ) (215)
ρo Lo
1
Wao = (Qao − FT ) (216)
ρo Lo
(217)
where
Lo ≡ [E(T0 , 1) − E(T1 , r1 )] (218)
The ocean model receives the following heat and salt fluxes:
The variables are defined in Table 7. Defining γ = mi /mw2 and dropping terms of order γ 2 leads
to:
" !#
L Cpi
T2 = T1 + γ + T1 1 − (225)
Cpw Cpw
S2 = S1 (1 + γ). (226)
44
We also want the final temperature and salinity to be on the freezing line, which we approximate
as:
Tf = mS + nz. (227)
We can then solve for γ:
−T1 + mS1 + nz
γ=
Cpi
. (228)
LCpw + T1 1 − Cpw − mS1
The ocean is checked at each depth k and at each timestep for supercooling. If the water is below
freezing, the temperature and salinity are adjusted as in equations (225) and (226) and the ice
above is thickened by the amount:
ρw
∆h = γk ∆zk . (229)
ρi
45
6 Details of the Code
6.1 Directory structure
The directory structure is as shown in Fig. 9, with the ability to run the ocean alone or coupled to
atmospheric and/or wave models. If running just the ocean, the model can be run forward in time
(the nonlinear model) or as an adjoint, tangent linear, or representer model for data assimilation
purposes. This document describes the uncoupled forward model only, specifically the version used
for the Northeast Pacific domain containing sea ice and other changes from the main trunk code.
Details are subject to change without notice - check your own source code for specific details as
they apply to you.
The directories shown here are:
Apps This directory contains a subdirectory for each of my personal applications. The sub-
directory contains files used by that application: the ROMS header file for setting cpp
definitions, the analytic formulations for fields computed in the model rather than read
from files (bottom heat flux of zero, for instance), and ASCII input files read by ROMS
on startup to set things such as forcing file names and model time-step. Some of these
applications are:
Bering This is a 4 km grid of the Bering Sea, aligned with the Northeast Pacific grid
but at three times the resolution.
Bering_10k This is a 10 km grid of the Bering Sea, a subset of the Northeast Pacific
domain, with the same extent as the 4 km grid above.
CGOA This is a 3 km grid of the Gulf of Alaska. It is a subset of the Northeast Pacific
grid, but at four times the resolution.
Circle This is a circular domain wave propagation problem with an analytic solution
used as a test problem ([39]).
NEP This is the Northeast Pacific domain covering the waters off the west coast of
the US, from California to the Bering Sea. It is a rectangular domain at about
11 km resolution when viewed in a conformal conic projection with standard
latitudes of 40 and 60 N.
Paul Budgell’s applications are also here. The application-specific files included in the
main trunk ROMS are elsewhere.
Data Directories under here contain example forcing, grid, and initial condition NetCDF files.
There is also a directory containing the headers of these files in the format produced by
ncdump (CDL).
Lib The ARPACK and MCT libraries are needed by the data assimilation codes and by the
coupled models, respectively.
Master The ROMS main program is here, in various forms for the forward model, coupled models
and others. See §6.2.
ROMS These files are for the ocean model, as opposed to other components of the coupled system.
46
Bering/
Apps/ Bering_10k/
Atmosphere/ CGOA/ Adjoint/
Compilers/ Circle/ Bin/
Data/ NEP/ Drivers/
Libs/ External/
makefile Functionals/
Master/ Include/
ROMS/ License_ROMS.txt
User/ Modules/
Waves/ Nonlinear/ Biology/
Obsolete/ Sediment/
Programs/
Representer/
SeaIce/
Tangent/
Utility/
Version
Adjoint This is the adjoint of the forward model, for data assimilation.
Bin Various shell and Perl scripts for use with the model. Note that the .sh files are
actually csh scripts, not sh scripts—if it were up to me, I’d rename them all to
.csh.
Drivers The main program includes one of these files, depending on how you are running
the model. The forward model is in nl_ocean.h.
External ROMS reads an ASCII file on startup. Here are examples for various applica-
tions, also examples of the optional files for extra components such as a sediment
model.
Functionals The file analytical.F can include one or more code bits for the analytic
specification of for instance the initial conditions. Here are examples for the
supported model test problems.
Include Each application has a header file with C preprocessor options for that applica-
tion. For instance, the UPWELLING case has the include file upwelling.h
containing C preprocessor options for its periodic channel domain. The full list
of available options is in cppdefs.h.
License_ROMS.txt The open source license under which ROMS is copyrighted.
Modules The ROMS data structures are now in Fortran 90 module files, located here.
Nonlinear The routines used by the nonlinear forward model are here, implementing the
physics described in §4.
Biology The files for the ecosystem parts of the forward model are here.
47
mpi_init initialize_parallel <loop>
ROMS_initialize wclock_on get_data
ROMS_run inp_par main3d or main2d
ROMS_finalize mod_arrays
mpi_finalize initial
get_data
if (trouble) wrt_rst
wclock_off
close_io
Sediment The files for the sediment parts of the forward model are here.
Obsolete Long unused versions of the boundary conditions are stored here.
Programs Not all computer architectures or compilers are the same. The types.F pro-
gram checks your compiler for the sizes of the Fortran floating point types.
Representer This is the representer of the forward model, for data assimilation.
SeaIce The sea ice model described in §5 is here.
Tangent This is the tangent linear of the forward model, for data assimilation.
Utility Here are utility functions used by the various ROMS routines, many dealing with
I/O.
Version A file containing the time and date of this svn revision, also the svn URL.
User Some might choose to use this directory rather than the Apps directory. It serves the
same purpose but is arranged by file type rather than by application.
6.2.2 ocean_control.F
This is again a shell which includes one of many other files to do the actual work. In this case, the
worker files all contain ROMS_initialize, ROMS_run and ROMS_finalize and live in the
ROMS/Drivers directory. The driver file we will be looking at is nl_ocean.h.
6.2.3 ROMS_initialize
This is called at the beginning of the run and therefore starts off by finding out how many parallel
processes are running and which one this is, then calls the following ROMS routines:
48
initialize_parallel is in the mod_parallel module and sets up a few variables, including some
for the built-in profiling.
mod_arrays allocates and initializes the dynamically sized arrays in ROMS based on the grid
sizes read in by inp_par.
initial reads in the initial conditions from a NetCDF file or computes them analytically. Likewise
for the grid, plus it sets up the vertical grid spacing to be used and many other details.
get_data reads in the first record of time-varying forcing fields, boundary conditions, etc.
6.2.4 ROMS_run
This loops over all the steps from the starting iteration to the ending iteration in its argument list.
The loop consists of calls to:
get_data reads in the second and subsequent records of time-varying forcing fields, boundary
conditions, etc.
main3d or main2d solves the full equations described in §4 (main3d) or the depth-integrated
version only (main2d).
6.2.5 ROMS_finalize
This is called at the end of the run, whether it was otherwise successful or not. The routines called
are:
wrt_rst if the run had an error code set, it will write out a restart record of the current model
fields in case they are useful in diagnosing the trouble.
wclock_off ends the built-in timers and causes them to print out a report.
close_io closes all open files so as to flush the buffers and put NetCDF files into a finished state.
6.2.6 main3d
This solves the full three-dimensional equations described in §4. It has siblings main2d for solving
the depth-integrated equations and main3d_offline for reading files from a prior simulation and
using them to advect the biological tracers or the Lagrangian floats. The full version is shown in Fig.
11. Note that many subroutines are optional and only get called if the appropriate C preprocessor
switches have been set. The subroutines are described as follows:
ini_zeta checks for wet/dry cells if needed and initializes all the time levels of zeta.
ini_fields initializes the 2-D velocities to match the vertical integral of the 3-D velocities, making
all the time levels match.
Hz u Hz v
set_massflux computes horizontal mass fluxes, n and m .
49
set_data -
ana_vmix -
first step only: rhs3d
lmd_vmix
ini_zeta my25_prestep
bvf_mix
ini_fields gls_prestep
hmixing
set_massflux <loop>
omega
rho_eos step2d
wvelocity
diag step2d
set_zeta
radiation_stress step3d_uv
set_diags
cawdir_eval omega
set_filter
ccsm_flux my25_corstep
set_avg
bulk_flux gls_corstep
set_avg2
ncep_flux biology
output
bblm sediment
exit if last
set_vbc step3d_t
step done
set_tides ice_frazil
seaice step_floats
diag computes some global sums, prints them, and checks them to see if they are sensible. If
not, it stops the model run.
radiation_stress computes the radiation stresses due to wave-current interactions ([53] and [54]).
cawdir_eval computes a 24-hour mean albedo at the marine surface. Not in the trunk code.
ccsm_flux computes the surface fluxes from the atmosphere based on a marine boundary layer.
This version comes from CCSM and is reputed to do better outside of the tropics. Not
in the trunk code.
bulk_flux computes the surface fluxes from the atmosphere based on a marine boundary layer.
This version comes from COARE version 3.0 ([11], [82] and [58]).
ncep_flux computes the surface fluxes from the NCEP atmospheric model. Not in the trunk
code.
bblm compute the bottom stresses from one of three bottom boundary layer models.
set_vbc computes the surface and bottom fluxes and stresses that aren’t computed elsewhere—set
vertical boundary conditions.
set_tides computes the tidal boundary conditions from the tidal constituents.
seaice runs the sea ice model described in §5. It changes the surface boundary conditions for
the ocean and therefore gets called before the call to output or anything else that would
be needing the surface boundary conditions. Not in the trunk code.
50
ana_vmix is called if there’s an analytic profile for the vertical mixing coefficient.
lmd_vmix is called when using the K-profile parameterization of vertical mixing ([41] and [40]).
hmixing computes time-dependent horizontal mixing coefficients ([76], [31], [88] and [23]).
wvelocity computes the physical vertical velocity for the model output.
set_zeta sets the surface elevation to the time-mean over the last baroclinic time-step.
set_filter accumulates a weighted sum using a Lanczos filter for detiding the most important of
the output fields. Not in the trunk code.
set_avg2 accumulates the time-averaged surface fields for the second averages output. Not in the
trunk code.
my25_prestep computes the predictor step for turbulent kinetic energy prognostic variables, tke
and gls.
gls_prestep computes the predictor step for turbulent kinetic energy prognostic variables, tke
and gls.
step2d computes the depth-integrated time-step. It is called in a loop over all the short time-
steps, first as a predictor step, then as a corrector step.
my25_corstep performs the corrector step for turbulent kinetic energy and length scale prog-
nostic variables, tke and gls ([57] and [20]).
my25_corstep performs the corrector step for turbulent kinetic energy and length scale prog-
nostic variables, tke and gls ([85]).
biology computes the changes to the biological tracers due to biological activity using one of
several options for the ecosystem model.
ice_frazil computes the frazil ice growth, if any. Not in the trunk code.
51
6.3 Initialization
checkdefs Reports on which C preprocessor variables have been #defined and checks their con-
sistency.
get_grid Reads in the curvilinear coordinate arrays as well as f and h from a grid NetCDF file.
set_scoord Sets and initializes relevant variables associated with the vertical transformation to
nondimensional σ-coordinate described in Appendix B.
metrics Computes the metric term combinations which do not depend on the surface elevation
and therefore remain constant in time.
get_state Reads initial fields from disk—either restart or from some other source which has been
converted to the appropriate format of NetCDF file.
grid_coords Convert initial float and station locations to fractional grid coordinates.
6.4 Modules
Now that we are using Fortran 90, the method of choice for managing data structures is modules.
The ROMS/Modules directory contains all of the ROMS modules that contain globally used
variables. The complete list is:
mod_arrays.F This actually has no data structures, but has the routine that calls the allocate
and initialize routines for all the others.
mod_average.F If AVERAGES is defined, this will provide the storage for the running means
of the fields you are averaging.
52
mod_average2.F If AVERAGES2 is defined, this will provide the storage for the surface run-
ning means of the fields you are averaging.
mod_bbl.F If BBL_MODEL is defined, this will provide the storage for the bottom boundary
fields.
mod_biology.F If BIOLOGY is defined, this will provide the storage for the biology interaction
parameters.
mod_boundary.F This contains the storage for the open boundary conditions. If they aren’t
provided analytically, this will also provide the storage for fields read from a file that need
to be time-interpolated.
mod_clima.F If one of CLIMATOLOGY or several other options is defined, this will provide
the storage for the climatology fields.
mod_coupling.F If SOLVE3D is defined, this will provide the storage for the fields used in
coupling the 2-D and 3-D components of the simulation.
mod_diags.F If DIAGNOSTICS is defined, this will provide the storage for the various ten-
dency terms.
mod_eclight.F If both BIOLOGY and ECOSIM are defined, this will set up the spectral
irradiance variables.
mod_eoscoef.F If NONLIN_EOS is defined, this will provide the polynomial expansion coef-
ficients for the nonlinear equation of state for sea water.
mod_filter.F If FILTERED is defined, this will provide the storage for the weighted means
used in detiding the averages.
mod_floats.F If FLOATS is defined, this will provide the storage for the float tracking variables.
mod_forces.F This provides the storage for the surface and bottom forcing fields.
mod_grid.F This provides the storage for the model grid fields.
mod_ice.F If ICE_MODEL is defined, this will provide storage for the ice fields.
mod_iounits.F This contains a number of variables used by the I/O, including file names and
file IDs.
mod_kinds.F This contains the integers associated with the various integer and real Fortran
types. If you find more systems supporting 128-bit reals, let us know.
mod_mixing.F This contains the arrays for the various optional horizontal and vertical mixing
parameterizations.
mod_ncparam.F This contains all sorts of parameters relating to the NetCDF I/O files, includ-
ing that read from the varinfo.dat file. The parameters MV and NV are set here, giving
the maximum number of variables that can be read [this is a change from the trunk code].
53
mod_nesting.F If NESTING is defined, this module defines generic structures used for nesting,
composed, and mosaic grids. Not yet functional.
mod_netcdf.F This brings in netcdf.mod and defines a few type variables based upon it.
mod_ocean.F This contains the 2-D and 3-D fields of the primitive ocean variables and optionally
the sediment variables.
mod_parallel.F This sets up some global variables such as Master, which is true for the master
thread or process. It also initializes the internal ROMS profiling arrays.
mod_param.F This contains the sizes of each grid used, plus things like how many tidal con-
stituents are being used. Many of these are read from the input files during initialization,
not known at compile time.
mod_scalars.F This contains a large number of scalars, i.e. values which don’t have spatial
dependence. Some are fixed constants such as itemp referring to the temperature tracer.
Others could have a different value on each grid.
mod_stepping.F This contains the time-stepping variables used to point to the relevant time
level.
mod_storage.F If PROPAGATOR is defined, this module defines the work space for the
Generalized Stability Theory (GST) Analysis package (ARPACK).
mod_strings.F This contains strings such as a title for the run, the list of cpp options defined,
and the names of the sections of code being profiled.
mod_tides.F If SSH_TIDES and/or UV_TIDES is defined, this will provide the storage for
the tidal constituents.
6.5 Functionals
The Functionals directory contains analytical.F which conditionally includes code bits for com-
puting analytic values for a wide variety of fields. Many are alternates for reading from NetCDF
files, especially for idealized problems.
54
ana_fsobc Computes analytic open boundary conditions for the free surface.
ana_specir Sets surface solar downwelling spectral irradiance at just beneath the sea surface.
ana_spinning Sets time-variable rotation force as the sum of Coriolis and Centripetal accelera-
tions. This is used in polar coordinate applications (annulus grid).
ana_sst Computes analytic sea surface temperature and dQdSST which are used in the surface
heat flux correction.
55
ana_tair Computes analytic air temperature.
ana_tobc Computes analytic open boundary conditions for all tracers (active, passive, biology,
and sediment).
def_* Creates the ROMS NetCDF file of the appropriate type, including dimensions,
attributes, and variables.
def_info Adds some standard scalar variables to any NetCDF file.
get_srflux Reads shortwave radiation flux
wrt_* Writes to the ROMS NetCDF file of the appropriate type.
Momentum terms The default horizontal advection is 3rd-order upstream bias for 3D momen-
tum and 4th-order centered for 2D momentum. The default vertical advection is 4th-order
centered for 3D momentum. If this is the case, no flags for momentum advection need to
be activated except for UV_ADV.
The 3rd-order upstream split advection (UV_U3ADV_SPLIT) can be used to correct
for the spurious mixing of the advection operator in terrain-following coordinates. If this
is the case, the advection operator is split in advective and viscosity components and
several internal flags are activated in globaldefs.h. Notice that horizontal and vertical
advection of momentum is 4th-order centered plus biharmonic viscosity to correct for
spurious mixing.
56
UV_C4ADVECTION Define for 4rd-order centered advection.
UV_SADVECTION Define for splines vertical advection (for shallow, vertically well-
resolved domains).
UV_VIS2 Define to compute the horizontal Laplacian viscosity.
UV_VIS4 Define to compute the horizontal biharmonic viscosity.
UV_SMAGORINSKY Define for Smagorinsky-like viscosity.
UV_LOGDRAG Define for logarithmic bottom friction.
UV_LDRAG Define for linear bottom friction.
UV_QDRAG Define for quadratic bottom friction.
RDRG_GRID Define for spatially variable bottom drag.
DRAG_LIMITER Define for bottom drag limiter.
UV_PSOURCE Define for point sources/sinks.
Q_PSOURCE Define for mass point sources/sinks.
57
QCORRECTION Define to use the net heat flux correction.
SCORRECTION Define to use freshwater flux correction.
SOLAR_SOURCE Define to use solar radiation source term.
SRELAXATION Define to use salinity relaxation as a freshwater flux.
TS_PSOURCE Define for point sources/sinks.
Pressure gradient options If no option is selected, the pressure gradient term is computed
using standard density Jacobian algorithm. Notice that there are two quartic pressure
Jacobian options. They differ on how the WENO reconciliation step is done and in the
monotonicity constraining algorithms.
Atmospheric boundary layer There are three ways to provide longwave radiation in the at-
mospheric boundary layer: (1) Compute the net longwave radiation internally using the
Berliand (1952) equation (LONGWAVE) as function of air temperature, sea surface
temperature, relative humidity, and cloud fraction; (2) provide (read) longwave down-
welling radiation only and then add outgoing longwave radiation (LONGWAVE_OUT)
as a function of the model sea surface temperature; (3) provide net longwave radiation
(default).
The shortwave radiation can be computed using the global albedo equation with a cloud
correction. Alternatively, input shortwave radiation data computed from averaged data
(with snapshots greater or equal than 24 hours) can be modulated by the local diurnal
cycle which is a function longitude, latitude and day-of-year.
58
General model configuration
Analytic fields
59
ANA_M3CLIMA Define for an analytic 3D momentum climatology.
ANA_M3OBC Define for analytic 3D momentum boundary conditions.
ANA_MASK Define for an analytic mask.
ANA_PAIR Define for an analytic surface air pressure.
ANA_PASSIVE Define for analytic initial conditions for inert tracers.
ANA_PERTURB Define for analytic perturbation of initial conditions.
ANA_PSOURCE Define for analytic point sources.
ANA_RAIN Define for analytic rain fall rate.
ANA_SEDIMENT Define for analytic sediment initial fields.
ANA_SMFLUX Define for an analytic kinematic surface momentum stress.
ANA_SPFLUX Define for analytic surface passive tracers fluxes.
ANA_SPINNING Define for an analytic time-varying rotation force.
ANA_SRFLUX Define for an analytic kinematic surface shortwave radiation.
ANA_SSFLUX Define for an analytic kinematic surface freshwater flux.
ANA_SSH Define for an analytic sea surface height.
ANA_SSS Define for an analytic sea surface salinity.
ANA_SST Define for an analytic SST and ∂Q/∂SST.
ANA_STFLUX Define for an analytic kinematic surface heat flux.
ANA_TAIR Define for analytic surface air temperature.
ANA_TCLIMA Define for an analytic tracer climatology.
ANA_TOBC Define for analytic tracer open boundary conditions.
ANA_VMIX Define for analytic vertical mixing coefficients.
ANA_WIND Define for analytic surface winds.
ANA_WWAVE Define for an analytic wind induced wave field.
Vertical mixing
60
CANUTO_A Define for Canuto A-stability function formulation.
CANUTO_B Define for Canuto B-stability function formulation.
CHARNOK Define for Charnok surface roughness from wind stress.
CRAIG_BANNER Define for Craig and Banner wave breaking surface flux.
KANTHA_CLAYSON Define for Kantha and Clayson stability function.
K_C2ADVECTION Define for 2th-order centered advection.
K_C4ADVECTION Define for 4th-order centered advection.
N2S2_HORAVG Define for horizontal smoothing of buoyancy/shear.
ZOS_HSIG Define for surface roughness from wave amplitude.
TKE_WAVEDISS Define for wave breaking surface flux from wave amplitude.
LMD_MIXING Define to activate Large/McWilliams/Doney interior closure.
LMD_BKPP Define to add a bottom boundary layer from a local K-Profile
Parameterization (KPP).
LMD_CONVEC Define to add convective mixing due to shear instabilities.
LMD_DDMIX Define to add double-diffusive mixing.
LMD_NONLOCAL Define to add convective nonlocal transport.
LMD_RIMIX Define to add diffusivity due to shear instabilities.
LMD_SHAPIRO Define to Shapiro filtering boundary layer depths.
LMD_SKPP Define to add a surface boundary layer from a local K-Profile
Parameterization (KPP).
MY25_MIXING Define to activate Mellor/Yamada Level-2.5 closure.
KANTHA_CLAYSON Define for Kantha and Clayson stability function.
K_C2ADVECTION Define for 2th-order centered advection.
K_C4ADVECTION Define for 4th-order centered advection.
N2S2_HORAVG Define for horizontal smoothing of buoyancy/shear.
PP_MIXING Define to activate Pacanowski/Philander closure.
RI_HORAVG Define for horizontal Richardson number smoothing.
RI_VERAVG Define for vertical Richardson number smoothing.
Bottom boundary layer The Options MB_Z0BL and MB_Z0RIP should be activated con-
currently.
61
SSW_CALC_UB Define to compute bottom orbital velocity internally.
SSW_LOGINT Define for logarithmic interpolation of (Ur,Vr).
SSW_FORM_DRAG_COR Define to activate form drag coefficient.
SSW_Z0BIO Define for biogenic bedform roughness for ripples.
SSW_Z0BL Define for bedload roughness for ripples.
SSW_Z0RIP Define for bedform roughness for ripples.
Sea ice
Boundary conditions
Detailed eastern open boundary conditions Other sides have similar. If none of these are
defined, it is assumed to be a closed wall.
62
EAST_M3RADIATION Define for a radiation condition on the 3-D momentum.
EAST_M3NUDGING Define for an active passive nudging term on the 3-D momen-
tum.
EAST_M3CLAMPED Define for clamped 3-D momentum.
EAST_KGRADIENT Define for a gradient condition on the TKE fields.
EAST_KRADIATION Define for a radiation condition on the TKE fields.
EAST_TGRADIENT Define for a gradient condition on the tracers.
EAST_TRADIATION Define for a radiation condition on the tracers.
EAST_TNUDGING Define for an active passive nudging term on the tracers.
EAST_TCLAMPED Define for clamped tracers.
EAST_VOLCONS Define for Eastern edge mass conservation enforcement.
Tides The tidal data is processed in terms of tidal constituents, classified by period. The tidal
forcing is computed for the full horizontal grid. If requested, the tidal forcing is added to
the processed open boundary data.
Both tidal elevation and tidal currents are required to force the model properly. However,
if only the tidal elevation is available, the tidal currents at the open boundary can be esti-
mated by reduced physics. Only the pressure gradient, Coriolis, and surface and bottom
stresses terms are considered at the open boundary. See u2dbc_im.F or v2dbc_im.F
for details. Notice that there is an additional option (FSOBC_REDUCED) for the
computation of the pressure gradient term in both Flather or reduced physics conditions
(*_M2FLATHER, *_M2REDUCED).
Climatology
Ecosystem models
63
BIO_SEDIMENT Define to restore fallen material to the nutrient pool.
CARBON Define to add carbon constituents.
DENITRIFICATION Define to add denitrification processes.
OXYGEN Define to add oxygen dynamics.
OCMIP_OXYGEN_SC Define if Schmidt number from Keeling et al. ([36]).
RIVER_BIOLOGY Define for river biology point-sources.
TALK_NONCONSERV Define for nonconservative computation of alkalinity.
BEST_NPZ Define for Gibson et al. (personal communication) Bering Sea model.
STATIONARY Define for extra output.
BENTHIC Define for benthic components.
ICE_BIO Define for ice algae.
JELLY Define for jellyfish.
CLIM_ICE_1D Define if 1-D with ice.
BIO_UMAINE Define for Chai et al. ([7]) model.
BIO_GOANPZ Define for Hinckley et al. ([30]) Gulf of Alaska model.
NPZD_FRANKS Define for NPZD model of Franks et al. ([18]).
NPZD_IRON Define for NPZD model with iron limitation.
NPZD_POWELL Define for NPZD model of Powell et al. ([64]).
IRON_LIMIT Define for iron limitation on phytoplankton growth.
IRON_RELAX Define for nudging to iron over the shelf.
ECOSIM Define for bio-optical EcoSim model.
NEMURO Define for Nemuro ecosystem model ([38]). Need to choose a zooplankton
grazing option (HOLLING_GRAZING or IVLEV_EXPLICIT). The de-
fault implicit IVLEV algorithm does not work yet.
BIO_SEDIMENT Define to restore fallen material to the nutrient pool.
HOLLING_GRAZING Define for Holling-type s-shaped curve grazing (im-
plicit).
IVLEV_EXPLICIT Define for Ivlev explicit grazing algorithm.
Nearshore options
NetCDF input/output
64
DEFLATE Define to set compression of NetCDF-4/HDF5 format files.
NETCDF4 Define to create NetCDF-4/HDF5 format files.
PARALLEL_IO Define to create NetCDF-4/HDF5 format files with MPI-I/O.
NO_READ_GHOST Define to not include ghost points during read/scatter.
NO_WRITE_GRID Define to omit writing grid arrays.
PERFECT_RESTART Define to include perfect restart variables.
READ_WATER Define to only read water points.
WRITE_WATER Define to only write water points.
RST_SINGLE Define to write single precision restart fields.
OUT_DOUBLE Define to write double precision output fields.
INLINE_2DIO Define to read/write 3D fields level by level.
NBT Number of biological tracers. This will depend on the ecosystem model used.
65
• MPI and OpenMP share the same basic structure.
First, some cpp options. If we’re compiling for MPI, the option -DMPI gets added to the
argument list for cpp. Then, in globaldefs.h, we have:
The rest of the code uses DISTRIBUTE to identify distributed memory jobs. The OpenMP case
is more straightforward, with -D_OPENMP getting passed to cpp and _OPENMP being the
tag to check within ROMS.
The whole horizontal ROMS grid is shown in Fig. 12. The computations are done over the
cells inside the darker line; the cells are numbered 1 to Lm in the ξ-direction and 1 to Mm in the
η-direction. Those looking ahead to running in parallel would be wise to include factors of two in
their choice of Lm and Mm. ROMS will run in parallel with any values of Lm and Mm, but the
computations might not be load-balanced.
The number of tiles is set in the input file as NtileI and NtileJ. For an MPI job, the product
of the two must equal the number of MPI processes. For an OpenMP job, the number of threads
must be a multiple of the number of tiles. For instance, for NtileI= 4 and NtileJ= 6, you must
have 24 MPI processes while 2, 3, 4, 6, 8, 12 and 24 are all valid numbers of OpenMP threads.
Also, a serial run could have 24 tiles and would just compute them sequentially.
Once the input file has been read, we can compute the tile sizes:
ChunkSizeI = (Lm+NtileI-1)/NtileI
ChunkSizeJ = (Mm+NtileJ-1)/NtileJ
MarginI = (NtileI*ChunkSizeI-Lm)/2
MarginJ = (NtileJ*ChunkSizeJ-Mm)/2
66
M d × d × d × d × d × d × d × d
Mm d × d × d × d × d × d × d × d
Mm
d × d × d × d × d × d × d × d
..
.
6 2 d × d × d × d × d × d × d × d
η 2
1 d × d × d × d × d × d × d × d
j=0 d × d × d × d × d × d × d × d
i=0 1 1 2 2 3 3 ··· Lm Lm L L
-
ξ
× – u points
– v points
d – ρ points
Figure 12: The whole grid. Note that there are Lm by Mm interior computational points. The
points on the thick outer line and those outside it are provided by the boundary conditions.
67
ChunkSizeI
3 6 7
2 4 5
1 2 3 ChunkSizeJ
Jtile = 0 tile = 0 1
MarginJ
Itile = 0 1
Some internal ROMS numbers are shown in Fig. 13 and are in the BOUNDS structure in
mod_param.F. MarginI and MarginJ are zero if the numbers work out perfectly, i.e. Lm/NtileI
and Mm/NtileJ are integers. The tile numbers match the MPI process numbers.
In picking a numbering scheme for indices within a tile, there are two common choices, as shown
in Fig. 14. Each tile can be numbered from 1 to ChunksizeI or it can retain the numbering it
would have in the whole grid. We have chosen this second option for ease when debugging features
such as river inputs which apply to specific locations on the grid. It is simple to do using Fortran
90 dynamic memory allocation.
With the tile sizes known, we can assign beginning and ending indices for each tile. Some of
the details depend on whether or not the domain is periodic in that direction, as shown in Fig. 15.
For MPI jobs, the ghost points need to be updated between interior point computations. The
routines mp_exchange2d, mp_exchange3d and mp_exchange4d can be used to update the
halo points of up to four arrays at a time. Each of these routines call tile_neighbors to figure
out which tiles are neighboring and whether or not there really is a neighboring tile on each side.
The mp_exchangexd routines then call:
mpi_irecv
mpi_send
mpi_wait
The exchanges happen first in the east-west direction, then in the north-south direction, saving
the need for diagonal exchanges. A figure with interior points colored by tile and grey halo points
needing an update is shown in Fig. 16(a). The updated halo points are shown in Fig. 16(b).
68
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
(a)
1 2 3 4 5 1 2 3 4 5 1 2 3 4 5
(b)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Figure 14: A choice of numbering schemes: (a) each tile is numbered the same, and (b) each tile
retains the numbering of the parent domain.
What isn’t obvious from this is that the argument TILE means different things depending on if
we’re using OpenMP or MPI:
#ifdef DISTRIBUTE
# define TILE MyRank
#else
# define TILE tile
#endif
#ifdef DISTRIBUTE
NtileX(1:Ngrids)=1
#else
NtileX(1:Ngrids)=NtileI(1:Ngrids)
#endif
In other words, for MPI, TILE becomes the process number and the loop is only executed once.
In looking at a typical routine that’s called from main3d, the routine is usually quite short,
calling a _tile version of itself in which the actual work happens:
69
Non−periodic
Periodic
70
(a)
(b)
Figure 16: A tiled grid with out-of-date halo regions shown in grey and the interior points color-
coded by tile: (a) before an exchange and (b) after an exchange.
71
They are then initialized in calls to the routines in get_bounds.F. If a tile is on the “western”
edge (Itile= 0), then UBi is set to LOWER_BOUND_I.
Imin=LOWER_BOUND_I
:
IF ((Itile.eq.-1).or.(Itile.eq.0)) THEN
LBi=Imin
ELSE
LBi=Istr-Nghost
END IF
#ifdef EW_PERIODIC
# define LOWER_BOUND_I -GHOST_POINTS
#else
# define LOWER_BOUND_I 0
#endif
In the case of set_data, we are simply passing array indices for the tiled arrays. To access the
tiled arrays from within set_data_tile, we need to use the relevant modules and then refer to
the array with its full name:
USE mod_forces
:
CALL set_2dfld_tile (ng, tile, iNLM, idCfra, &
& LBi, UBi, LBj, UBj, &
& FORCES(ng)%cloudG, &
& FORCES(ng)%cloud, &
& update)
In other cases, the parent routine would have the use, then would pass the relevant array to the
_tile routine:
USE mod_grid
:
CALL prsgrd_tile (ng, tile, &
:
& GRID(ng) % Hz, &
:
SUBROUTINE prsgrd_tile (ng, tile, &
:
& Hz, z_r, z_w, &
:
real(r8), intent(in) :: Hz(LBi:,LBj:,:)
This allows the _tile routine to use Hz with the same syntax as the pre-parallel, pre-module code
once had.
6.9.4 Input/output
In ROMS, the distributed memory I/O is all happening on the master process (0) unless you
specifically ask it to use MPI-I/O, which requires both the NETCDF4 and PARALLEL_IO
cpp flags to be defined. If you do this, you will be reading and writing HDF5 files and will need
72
to update your pre- and post-processing tools accordingly. I have tentatively tried the parallel I/O
and found it to be exceedingly slow—I’ve been told since that this is the fault of the NetCDF-4
layer sitting on top of HDF5—HDF5 alone should be fast.
In the case of having all the I/O pass through the master process, we can still read and write
classic NetCDF-3 files. Care must be taken though, in the event of an error. ROMS has been
cleaned up so that the master process will broadcast its return state to the other processes and
they can all die gracefully together when there is a problem.
An example of a routine which reads from disk is get_grid, called from initial. Each MPI
process calls get_grid:
If any one of the processes has trouble, it will enter into the exit_flag which is then shared by all.
To read in an array variable, all processes in get_grid uses nf_fread2d and friends:
Within nf_fread2d, we get to a call to the NetCDF library from just the master process:
IF (InpThread) THEN
status=nf90_get_var(ncid, ncvarid, wrk, start, total)
:
END IF
# ifdef DISTRIBUTE
CALL mp_bcasti (ng, model, status)
# endif
IF (status.ne.nf90_noerr) THEN
exit_flag=2
ioerror=status
nf_fread2d=status
RETURN
END IF
At this point, the master process has the entire 2-D array stored in wrk. This then needs to be
divvied out to the various tiles to their copy of the array in question (stored in the A argument to
nf_fread2d):
73
# ifdef DISTRIBUTE
CALL mp_scatter2d (ng, model, LBi, UBi, LBj, UBj, &
& Nghost, MyType, Amin, Amax, &
# if defined READ_WATER && defined MASKING
& NWpts, SCALARS(ng)%IJwater(:,wtype), &
# endif
& Npts, wrk, A)
74
7 Configuring ROMS for a Specific Application
This chapter describes the parts of ROMS for which the user is responsible when configuring it
for a given application. Section 7.1 describes the process in a generic fashion while §7.2 and §7.3
step through the application of ROMS to upwelling/downwelling and wind-driven Northeast Pacific
problems, respectively. As distributed, ROMS is ready to run quite a few examples, where the C
preprocessor flags determine which is to be executed. Some of these examples are described in
Haidvogel and Beckmann [26], some are listed here:
BASIN This is a rectangular, flat-bottomed basin with double-gyre wind forcing. When run, it
produces a western boundary current flowing into a central “Gulf Stream” which goes un-
stable and generates eddies. The goal is to run adiabatically to study the homogenization
of potential vorticity. It earned its nickname of Big Bad Basin by taking a long time to
run and causing difficulties for the spectral versions of SPEM.
GRAV_ADJ The gravitational adjustment problem takes place in a long narrow domain which
is initialized with dense water at one end and light water at the other. At time zero, the
water is released and it generates two propagating fronts as the light water rushes to fill
the top and the dense water rushes to fill the bottom. This configuration was used to test
various advection schemes.
OVERFLOW This configuration is similar to the GRAV_ADJ problem, but is initialized with
dense water in the shallow part of a domain with a sloping bottom.
SEAMOUNT The seamount test was used to test the pressure gradient errors. It has an idealized
seamount in a periodic channel. See Beckmann and Haidvogel [4] and McCalpin [51] for
more information.
UPWELLING The upwelling/downwelling example was contributed by Anthony Macks and Ja-
son Middleton [47] and consists of a periodic channel with shelves on each side. There
is along-channel wind forcing and the Coriolis term leads to upwelling on one side and
downwelling on the other side. If you run it for several days without vertical mixing, you
end up with dense water over light water.
Some NetCDF input files for the ROMS examples can be found under Data/ROMS in the ROMS
distribution. The ASCII input files are under ROMS/External.
75
7.1.2 Case-specific Include File
Each application has its own include file, included by cppdefs.h. The name of this file is the name of
your application (WIKI_TEST here) turned into lower case, with ’.h’ appended (wiki_test.h).
The location of this file is set by MY_HEADER_DIR, pointing to User/Include or some
other location of your choosing.
The complete list of options to be set prior to compilation are listed in §6.7. Place those you
need in the wiki_test.h file. These include algorithm choices (e.g. advection and turbulence
closure schemes), boundary conditions, output options (averages, diagnostics, stations, floats), and
application modules (biology, sediments). Each line should be of the form:
#define SOME_VAR
Note that any undefined variable need not be mentioned.
Also note that if you copy a predefined application from ROMS/Include as a template for
your application, you must rename it. If you don’t change the name, ROMS will use the one in
ROMS/Include and your file will be ignored during the build procedure.
7.1.3 Functionals
Some of the cpp Options have names beginning with ANA_. For each one of these, you will be
expected to provide an analytic expression for the field in question in the corresponding include file.
These files are listed in §6.5 and their location is determined by MY_ANALYTICAL_DIR.
You may chose to copy those from User/Functionals to some new directory and place your version
of the assignments within
#ifdef WIKI_TEST
! Set weird and wonderful winds
:
#endif
This makes it easy to search for later, if nothing else.
7.1.4 checkdefs.F
For each new cpp variable other than your application name, it is recommended that you also add
the appropriate code to checkdefs.F, such as:
#ifdef SLEET
IF (Master) WRITE(stdout,20) ’SLEET’, &
& ’Sleet falling on the ice option.’
is=lenstr(Coptions)+1
Coptions(is:is+7)=’ SLEET,’
#endif /* ICE */
Note that the number “7” on the Coptions line must be set according to the length of the string
you are adding. In this case 7 is for “ SLEET,”, including the comma and the space. Again, you
do not need to do this for your application name (WIKI_TEST here), since checkdefs will print
whatever is in MyAppCPP.
76
Lm Number of finite-difference points in ξ.
Mm Number of finite-difference points in η.
N Number of finite-difference points in the vertical.
NAT Number of active tracers.
The number of biological tracers is set in the biology.in file. There are no constraints on these
except Lm ≥ 2, Mm ≥ 2, N ≥ 2 and NAT ≥ 1. Lm and Mm should be at least 3 if the domain
is periodic in that direction.
7.1.6 x, y grid
The subroutine get_grid or ana_grid is called by initial to set the grid arrays, the bathymetry,
and the Coriolis parameter. Most of the simple test problems have their grid information specified
in ana_grid.h in the directory ROMS/Functionals. More realistic problems require a NetCDF
grid file, produced by the grid generation programs described in Wilkin and Hedstrom [89], by the
Matlab SeaGrid, or by some other method. The variables which are read by get_grid are:
xl, el, spherical, f, h, pm, pn, x_rho, y_rho, lon_rho, lat_rho, angle.
dndx, dmde.
7.1.7 ξ, η grid
Before providing initial conditions and boundary conditions, the user must understand the model
grid. The fields are laid out on an Arakawa C grid as in Fig. 1. The overall grid is shown in Fig. 12.
The thick outer line shows the position of the model boundary. The points inside this boundary
are those which are advanced in time using the model physics. The points on the boundary and
those on the outside must be supplied by the boundary conditions.
The three-dimensional model fields are carried in four-dimensional arrays, where the fourth
array index refers to one of two or three time levels. The tracers have a fifth array index telling
which tracer is being referred to. For instance, itemp = 1 refers to potential temperature while
isalt = 2 refers to salinity. The integers i, j, and k are used throughout the model to index the
three spatial dimensions:
77
7.1.9 Equation of state
The equation of state is defined in the subroutine rho_eos. Two versions are provided in ROMS:
a nonlinear ρ = ρ(T, S, z) from Jackett and McDougall [34] and a linear ρ(T, S). The linear form is
or
ρ = R0 + Tcoef · (T − T 0),
depending on whether or not SALINITY is defined. Specify which equation of state you would
like to use with the NONLIN_EOS C preprocessor flag in your application include file. The
linear coefficients R0, T0, Tcoef, S0, and Scoef are set in ocean.in. Note that we are computing
in situ density from potential temperature and salinity. Some of the vertical mixing schemes require
potential density and some other fields, which are computed by rho_eos as well.
78
and southern boundaries. Set the climatologies in ana_tclima.h or in a file read by get_data,
set TCLM_NUDGING in wiki_test.h and also set the array Tnudgcof in ana_nudgcoef.h.
(c) Tides
There is also more than one way to force with tides. One way is to provide boundary conditions
with enough temporal resolution to resolve the tides. Another is to provide ROMS with the tidal
constituents at all grid points and to have ROMS reconstruct the tidal currents (UV_TIDES)
and/or elevations (SSH_TIDES) for any given time. An example of such a tidal forcing file is in
Data/ROMS/Forcing/test_head_frc.nc.
The non-trunk code with ice, etc. includes the TIDES_ASTRO option to add on the long-
period tides from Foreman ([15] and [16]). There is also an option to include the tidal potential
forcing term (POT_TIDES), requiring the tidal potential to be included in the tides forcing file.
(d) Rivers
Point sources can be used to provide river inflow to the model. These too can be specified in a
forcing file if not provided via ana_psource.
7.1.12 ocean.in
ROMS expects to read a number of variables from an ASCII file as described in §2.5. Example input
files are in ROMS/External with names like ocean_grav_adj.in, where “grav_adj” refers to
the name of the application. Lines beginning with “!” are comments and will be ignored by ROMS
on reading them.
The input is organized as key/value pairs, separated by one or two equals signs. It is possible
for ROMS to run on more than one grid simultaneously, with the number of grids being set at
compile time via the build script and/or the makefile. If there is one equals sign (=), ROMS
will use the corresponding value for all grids. If there are two (==), ROMS will read a value for
each grid. Thus far, our domains have used just one grid since the inter-grid coupling has not been
released.
ROMS will ignore the parameters not needed by the current simulation, e.g., the GLS param-
eters will not be read if you are not using that mixing scheme. However, I believe all the example
files contain all possible parameters (except the ice branch ones). The input parameters are in
groups, as follows:
Header
Grid-dimension parameters
79
Domain-decomposition parameters
Time-stepping parameters
NTIMES Number of time-steps to evolve the 3-D equations in the current run. This is
actually the total number, including any previous segments of the same run. For
instance, if you already did a three-month run and wish to continue for another
three months, set NTIMES to the number of steps needed for six months.
DT Time-step in seconds for the 3-D equations.
NDTFAST Number of time-steps for the 2-D equations to be executed each dt.
Input/Output parameters
ROMS has several possible output files. The output files can include a restart file, a
history file, an averages file, and a station file, for instance. The restart file often contains
only two records with the older record being overwritten during the next write. The
history file can contain a subset of the restart fields, for instance just the surface elevation
and the surface temperature. The averages file contains time-averages of the model fields,
for instance daily or monthly means, depending on NAVG. The station file contains
timeseries for specified points, possibly quite frequently since each record is small. For
some, machinery is in place to write multiple files, numbering them _0001, _0002, etc.
NRREC Record number of the restart file to read as the initial conditions. Set to 0 at
the beginning of the run, -1 to read the latest record.
LcycleRST Logical, true to cycle between two records of the restart file.
NRST Number of time-steps between writing of restart fields.
NSTA Number of time-steps between writing fields into the stations file.
NFLT Number of time-steps between writing fields into the floats file.
NINFO Number of time-steps between calling diag to write some global information
and check for NaN values.
LDEFOUT True for creating new output files for stations, history, floats, etc. If false,
output is appended to these files.
80
NHIS Number of time-steps between writing history records.
NDEFHIS Number of time-steps between starting new history files.
NTSAVG Starting time-step for the accumulation of output time-averaged data. For
instance, you might want to average over the last day of a thirty-day run.
NAVG Number of time-steps between writing time-averaged data into the averages file.
NDEFAVG Number of time-steps between starting new averages files.
NTSDIA Starting time-step for the accumulation of output diagnostics data. For in-
stance, you might want to write diagnostics for the last day of a thirty-day run.
NDIA Number of time-steps between writing diagnostics data into the diagnostics file.
NDEFDIA Number of time-steps between starting new diagnostics files.
Ritz_tol Relative accuracy of the Ritz values computed in the GST analysis.
TNU2 Constant mixing coefficient for the horizontal Laplacian diffusion of each tracer.
A value is expected for each of the NAT+NPT tracers.
TNU4 Constant mixing coefficient for the horizontal biharmonic diffusion of each tracer.
A value is expected for each of the NAT+NPT tracers.
AKT_BAK Background vertical mixing coefficient for the tracers (NAT+NPT val-
ues).
81
AKV_BAK Background vertical mixing coefficient for momentum.
82
Wetting and drying parameter
Various parameters
Time parameters
TNUDG Time scale (days) of nudging towards tracer climatology at the interior and at
the boundaries. A value is expected for each active tracer.
ZNUDG Time scale (days) of nudging towards free surface climatology at the interior
and at the boundaries.
M2NUDG Time scale (days) of nudging towards 2-D momentum climatology at the
interior and at the boundaries.
M3NUDG Time scale (days) of nudging towards 3-D momentum climatology at the
interior and at the boundaries.
83
R0 Background density value used in the linear equation of state.
T0 Background potential temperature constant.
S0 Background salinity constant.
TCOEF Thermal expansion coefficient in the linear equation of state.
SCOEF Saline contraction coefficient in the linear equation of state.
Slipperiness parameter
gamma2 Slipperiness variable, either 1.0 (free slip) or −1.0 (no slip).
SO_decay Stochastic optimals time decorrelation scale (days) assumed for red noise
processes.
84
Hout(idOvel) 3-D Ω vertical velocity.
Hout(idUbar) 2-D u-velocity component.
Hout(idVbar) 2-D v-velocity component.
Hout(idFsur) Free-surface.
Hout(idBath) Time-dependent bathymetry.
85
Hout(idWlen) Wave length.
Hout(idWdir) Wave direction.
Ice fields
86
Hout(idWio) Ice-ocean ice melt/growth rate.
Hout(idWro) Surface water runoff rate.
Sediment tracers
User parameters
NetCDF-4/HDF5 parameters
87
ASCII input file names
The bottom of the sample files contain comments describing some of these in greater detail.
7.2.1 cppdefs.h
The C preprocessor variable UPWELLING is used for the upwelling configuration of the model.
The makefile will direct cppdefs.h to include the file upwelling.h:
#define UV_ADV
#define UV_COR
#define UV_LDRAG
#define UV_VIS2
#undef MIX_GEO_UV
#define MIX_S_UV
#define TS_U3HADVECTION
#define TS_C4VADVECTION
#undef TS_MPDATA
#define DJ_GRADPS
#define TS_DIF2
#undef TS_DIF4
#undef MIX_GEO_TS
#define MIX_S_TS
88
#define SALINITY
#define SOLVE3D
#define SPLINES
#define AVERAGES
#define DIAGNOSTICS_TS
#define DIAGNOSTICS_UV
#define EW_PERIODIC
#define ANA_GRID
#define ANA_INITIAL
#define ANA_SMFLUX
#define ANA_STFLUX
#define ANA_SSFLUX
#define ANA_BTFLUX
#define ANA_BSFLUX
#ifdef BIO_FENNEL
# define CARBON
# define DENITRIFICATION
# define BIO_SEDIMENT
# define DIAGNOSTICS_BIO
#endif
#ifdef BIO_UMAINE
# define OXYGEN
# undef CARBON
#endif
#ifdef PERFECT_RESTART
89
# undef AVERAGES
# undef DIAGNOSTICS_BIO
# undef DIAGNOSTICS_TS
# undef DIAGNOSTICS_UV
# define OUT_DOUBLE
#endif
Here we have declared that we want a periodic channel (EW_PERIODIC) but no masking. There
is salinity but we’re using a linear equation of state. The momentum equations have advection,
Coriolis force and pressure gradients. There is both horizontal viscosity and diffusion, but they are
along constant σ-surfaces and if you check the input file, you find that the horizontal diffusion is
set to zero.
There are ifdefs for various biology cases, none of which have been defined. Likewise, we are
using the default of ANA_VMIX as distributed. We are asking for many other analytic functions
too, including the grid. We are asking for diagnostic output with the DIAGNOSTICS_TS and
DIAGNOSTICS_UV.
7.2.3 ana_grid
For this geometry one has a choice of using one of the external grid-generation programs or of using
ana_grid to create the grid analytically. The code in ana_grid.h was modified to produce a
bathymetry with a shelf on both walls of the channel when UPWELLING is defined. The fluid
depth ranges from 27 m on the shelves to 150 m in the center of the channel. The horizontal grid
spacing is uniform at 1 km and the Coriolis parameter f is set to a constant value suitable for
Sydney, Australia.
R0 == 1027.0d0 ! kg/m3
T0 == 14.0d0 ! Celsius
S0 == 35.0d0 ! PSU
TCOEF == 1.7d-4 ! 1/Celsius
SCOEF == 0.0d0 ! 1/PSU
90
Since density does not depend on salinity, we have a choice of how to handle the second tracer.
The salinity is set to a uniform value of S0, though it could be left out entirely if we undefine
SALINITY and set NAT to 1.
7.2.7 ocean.in
The model has been set up to run for five days with an internal time-step of 300 s and an external
time-step of 10 s.
NTIMES == 1440
DT == 300.0d0
NDTFAST == 30
We will write history, averages, and diagnostics records every 1/4 day, restart records once a day.
NRREC == 0
LcycleRST == T
NRST == 288
LDEFOUT == T
NHIS == 72
NDEFHIS == 0
NTSAVG == 1
NAVG == 72
NDEFAVG == 0
NTSDIA == 1
NDIA == 72
NDEFDIA == 0
The value of the linear bottom friction coefficient rdrg is set to 3.0 × 10−4 and the channel walls
are set to be free-slip:
91
Vtransform == 1 ! transformation equation
Vstretching == 1 ! stretching function
THETA_S == 3.0d0 ! surface stretching parameter
THETA_B == 0.0d0 ! bottom stretching parameter
TCLINE == 50.0d0 ! critical depth (m)
7.2.8 Output
The model writes some information to standard out, after setting ninfo to 72:
Process Information:
92
to standard output.
T ldefout Switch to create a new output NetCDF file(s).
72 nHIS Number of timesteps between the writing fields
into history file.
1 ntsAVG Starting timestep for the accumulation of output
time-averaged data.
72 nAVG Number of timesteps between the writing of
time-averaged data into averages file.
1 ntsDIA Starting timestep for the accumulation of output
time-averaged diagnostics data.
72 nDIA Number of timesteps between the writing of
time-averaged data into diagnostics file.
0.0000E+00 tnu2(01) Horizontal, harmonic mixing coefficient (m2/s)
for tracer 01: temp
0.0000E+00 tnu2(02) Horizontal, harmonic mixing coefficient (m2/s)
for tracer 02: salt
5.0000E+00 visc2 Horizontal, harmonic mixing coefficient (m2/s)
for momentum.
1.0000E-06 Akt_bak(01) Background vertical mixing coefficient (m2/s)
for tracer 01: temp
1.0000E-06 Akt_bak(02) Background vertical mixing coefficient (m2/s)
for tracer 02: salt
1.0000E-05 Akv_bak Background vertical mixing coefficient (m2/s)
for momentum.
3.0000E-04 rdrg Linear bottom drag coefficient (m/s).
3.0000E-03 rdrg2 Quadratic bottom drag coefficient.
2.0000E-02 Zob Bottom roughness (m).
1 Vtransform S-coordinate transformation equation.
1 Vstretching S-coordinate stretching function.
3.0000E+00 theta_s S-coordinate surface control parameter.
0.0000E+00 theta_b S-coordinate bottom control parameter.
50.000 Tcline S-coordinate surface/bottom layer width (m) used
in vertical coordinate stretching.
1025.000 rho0 Mean density (kg/m3) for Boussinesq approximation.
0.000 dstart Time-stamp assigned to model initialization (days).
0.00 time_ref Reference time for units attribute (yyyymmdd.dd)
0.0000E+00 Tnudg(01) Nudging/relaxation time scale (days)
for tracer 01: temp
0.0000E+00 Tnudg(02) Nudging/relaxation time scale (days)
for tracer 02: salt
0.0000E+00 Znudg Nudging/relaxation time scale (days)
for free-surface.
0.0000E+00 M2nudg Nudging/relaxation time scale (days)
for 2D momentum.
0.0000E+00 M3nudg Nudging/relaxation time scale (days)
for 3D momentum.
0.0000E+00 obcfac Factor between passive and active
open boundary conditions.
14.000 T0 Background potential temperature (C) constant.
35.000 S0 Background salinity (PSU) constant.
93
1027.000 R0 Background density (kg/m3) used in linear Equation
of State.
1.7000E-04 Tcoef Thermal expansion coefficient (1/Celsius).
0.0000E+00 Scoef Saline contraction coefficient (1/PSU).
1.000 gamma2 Slipperiness variable: free-slip (1.0) or
no-slip (-1.0).
T Hout(idFsur) Write out free-surface.
T Hout(idUbar) Write out 2D U-momentum component.
T Hout(idVbar) Write out 2D V-momentum component.
T Hout(idUvel) Write out 3D U-momentum component.
T Hout(idVvel) Write out 3D V-momentum component.
T Hout(idWvel) Write out W-momentum component.
T Hout(idOvel) Write out omega vertical velocity.
T Hout(idTvar) Write out tracer 01: temp
T Hout(idTvar) Write out tracer 02: salt
Output/Input Files:
Number of tracers: 2
0 1 41 1 80 52480
94
ANA_SSFLUX Analytical kinematic surface salinity flux.
ANA_STFLUX Analytical kinematic surface temperature flux.
ANA_VMIX Analytical vertical mixing coefficients.
ASSUMED_SHAPE Using assumed-shape arrays.
AVERAGES Writing out time-averaged fields.
DIAGNOSTICS_TS Computing and writing tracer diagnostic terms.
DIAGNOSTICS_UV Computing and writing momentum diagnostic terms.
DJ_GRADPS Parabolic Splines density Jacobian (Shchepetkin, 2002).
DOUBLE_PRECISION Double precision arithmetic.
EW_PERIODIC East-West periodic boundaries.
MIX_S_TS Mixing of tracers along constant S-surfaces.
MIX_S_UV Mixing of momentum along constant S-surfaces.
NONLINEAR Nonlinear Model.
!NONLIN_EOS Linear Equation of State for seawater.
POWER_LAW Power-law shape time-averaging barotropic filter.
PROFILE Time profiling activated .
!RST_SINGLE Double precision fields in restart NetCDF file.
SALINITY Using salinity.
SOLVE3D Solving 3D Primitive Equations.
SPLINES Conservative parabolic spline reconstruction.
TS_U3HADVECTION Third-order upstream horizontal advection of tracers.
TS_C4VADVECTION Fourth-order centered vertical advection of tracers.
TS_DIF2 Harmonic mixing of tracers.
UV_ADV Advection of momentum.
UV_COR Coriolis term.
UV_U3HADVECTION Third-order upstream horizontal advection of 3D momentum.
UV_C4VADVECTION Fourth-order centered vertical advection of momentum.
UV_LDRAG Linear bottom stress.
UV_VIS2 Harmonic mixing of momentum.
VAR_RHO_2D Variable density barotropic mode.
95
4 -0.7500000 -0.4682798 -18.900 -48.121 -77.341
3 -0.8125000 -0.5668375 -20.475 -55.846 -91.216
2 -0.8750000 -0.6853816 -22.050 -64.818 -107.586
1 -0.9375000 -0.8280918 -23.625 -75.298 -126.971
0 -1.0000000 -1.0000000 -25.200 -87.600 -150.000
96
41 0.0217382098544504 0.0010909315881854 0.9890102622088882 0.9996336754069628
42 0.0109897377911118 0.0003663245930371 1.0000000000000000 0.9999999999999998
97
WRT_AVG - wrote averaged fields into time record = 0000003
WRT_DIAGS - wrote diagnostics fields into time record = 0000003
288 1 00:00:00 5.382882E-04 6.579497E+02 6.579503E+02 3.884376E+11
WRT_HIS - wrote history fields (Index=1,1) into time record = 0000005
WRT_AVG - wrote averaged fields into time record = 0000004
WRT_DIAGS - wrote diagnostics fields into time record = 0000004
WRT_RST - wrote re-start fields (Index=1,1) into time record = 0000001
:
1440 5 00:00:00 2.476731E-02 6.579533E+02 6.579781E+02
3.884376E+11
WRT_HIS - wrote history fields (Index=1,1) into time record
= 0000021
WRT_AVG - wrote averaged fields into time record =
0000020
WRT_DIAGS - wrote diagnostics fields into time record =
0000020
WRT_RST - wrote re-start fields (Index=1,1) into time record
= 0000001
98
number of time records written in RESTART file = 00000002
number of time records written in AVERAGE file = 00000020
ROMS/Functionals/ana_btflux.h
ROMS/Functionals/ana_grid.h
ROMS/Functionals/ana_initial.h
ROMS/Functionals/ana_smflux.h
ROMS/Functionals/ana_stflux.h
ROMS/Functionals/ana_vmix.h
Note that it ends by printing out a profile of where the time was used—the ratios will vary depending
on the application.
NetCDF history and restart files are also created, containing the model fields at the requested
times. We have asked it to save restart records every day. In this case, the restart file has been told
to “cycle”, or to write over the second last record. The restart file at the end of the run contains
the fields at day 4 and day 5. The history file contains records for 0, 1/4, 1/2, 3/4, and 1 day, etc.,
while the averages and diagnostics files are at 1/8, 3/8, 5/8, and 7/8 day, etc.. Plots can be made
from any one of these files, using the plotting software described in §8. Selected frames from such
plots are shown in Fig. 17 to 20.
7.3.1 nep5.h
The C preprocessor variable NEP5 has been chosen to label our Northeast Pacific domain, using
the fifth generation grid file. The header include file then becomes nep5.h:
/*
** Options for Northeast Pacific (NEP5) simulation
*/
#undef NETCDF4
#undef PARALLEL_IO
#undef OFFLINE_FLOATS
/* general */
#define CURVGRID
#define MASKING
#define NONLIN_EOS
#define SOLVE3D
#define SALINITY
#ifdef SOLVE3D
99
Figure 17: The upwelling/downwelling bathymetry.
100
Figure 18: Surface velocities after one day, showing the flow to the left of the wind (southern
hemisphere).
101
Figure 19: Constant ξ slices of the u, v, T and w fields at day 1.
102
Figure 20: Constant ξ slices of the u, v, T , and w fields at day 5.
103
Figure 21: Bathymetry of the Northeast Pacific domain (NEP5).
104
# undef SPLINES
#endif
#define FLOATS
#define STATIONS
#undef WET_DRY
#undef T_PASSIVE
#ifdef T_PASSIVE
# define ANA_PASSIVE
#endif
/* ice */
#ifdef SOLVE3D
# define ICE_MODEL
# ifdef ICE_MODEL
# define ICE_THERMO
# define ICE_MK
# undef ICE_ALB_EC92
# undef ICE_SMOOTH
# define ICE_MOMENTUM
# define ICE_MOM_BULK
# define ICE_EVP
# define ICE_ADVECT
# define ICE_SMOLAR
# define ICE_UPWIND
# define ICE_BULK_FLUXES
# define ANA_AIOBC
# define ANA_HIOBC
# define ANA_HSNOBC
# endif
#endif
/* output stuff */
#define NO_WRITE_GRID
#undef OUT_DOUBLE
#define RST_SINGLE
#define AVERAGES
#undef AVERAGES2
#ifdef SOLVE3D
# undef AVERAGES_DETIDE
# define AVERAGES_AKT
# define AVERAGES_AKS
# define AVERAGES_AKV
# define AVERAGES_FLUXES
# undef AVERAGES_QUADRATIC
# undef DIAGNOSTICS_TS
#endif
#undef DIAGNOSTICS_UV
105
/* advection, dissipation, pressure grad, etc. */
#ifdef SOLVE3D
# define DJ_GRADPS
#endif
#define UV_ADV
#define UV_COR
#define UV_SADVECTION
#ifdef SOLVE3D
# define TS_U3HADVECTION
# define TS_C4VADVECTION
# undef TS_MPDATA
#endif
#define UV_VIS2
#define UV_SMAGORINSKY
#define VISC_3DCOEF
#define MIX_S_UV
#define VISC_GRID
#define SPONGE
#ifdef SOLVE3D
# define TS_DIF2
# define MIX_GEO_TS
# define DIFF_GRID
#endif
/* vertical mixing */
#ifdef SOLVE3D
# define SOLAR_SOURCE
# define LMD_MIXING
# ifdef LMD_MIXING
# define LMD_RIMIX
# define LMD_CONVEC
# define LMD_SKPP
# undef LMD_BKPP
# define LMD_NONLOCAL
# define LMD_SHAPIRO
# undef LMD_DDMIX
# endif
# undef GLS_MIXING
# undef MY25_MIXING
106
# if defined GLS_MIXING || defined MY25_MIXING
# define KANTHA_CLAYSON
# define N2S2_HORAVG
# endif
#endif
/* surface forcing */
#ifdef SOLVE3D
# define CORE_FORCING
# define BULK_FLUXES
# define CCSM_FLUXES
# if defined BULK_FLUXES || defined CCSM_FLUXES
# define LONGWAVE_OUT
# define DIURNAL_SRFLUX
# define EMINUSP
# undef ANA_SRFLUX
# undef ALBEDO
# undef LONGWAVE
# endif
#endif
#ifdef SOLVE3D
# define SRELAXATION
# undef QCORRECTION
#endif
/* tides */
#define LTIDES
#ifdef LTIDES
# define FILTERED
# define SSH_TIDES
# define UV_TIDES
# define ADD_FSOBC
# define ADD_M2OBC
# undef RAMP_TIDES
# define TIDES_ASTRO
107
# define POT_TIDES
# define UV_LDRAG
# define RDRG_GRID
# define DRAG_LIMITER
# undef UV_QDRAG
#else
# define UV_QDRAG
#endif
#define EASTERN_WALL
#define NORTHERN_WALL
#undef WESTERN_WALL
#undef SOUTHERN_WALL
#define RADIATION_2D
#ifndef NORTHERN_WALL
# define NORTH_FSCHAPMAN
# define NORTH_M2FLATHER
# ifdef SOLVE3D
# define NORTH_M3RADIATION
# define NORTH_M3NUDGING
# define NORTH_TRADIATION
# define NORTH_TNUDGING
# define NORTH_MIGRADIENT
# endif
#endif
#ifndef WESTERN_WALL
# define WEST_FSCHAPMAN
# define WEST_M2FLATHER
# ifdef SOLVE3D
# define WEST_M3RADIATION
# define WEST_M3NUDGING
# define WEST_TRADIATION
# define WEST_TNUDGING
# define WEST_MIGRADIENT
# endif
#endif
#ifndef SOUTHERN_WALL
# define SOUTH_FSCHAPMAN
# define SOUTH_M2FLATHER
# ifdef SOLVE3D
# define SOUTH_M3RADIATION
# define SOUTH_M3NUDGING
# define SOUTH_TRADIATION
108
# define SOUTH_TNUDGING
# define SOUTH_MIGRADIENT
# endif
#endif
#ifndef EASTERN_WALL
# define EAST_FSCHAPMAN
# define EAST_M2FLATHER
# ifdef SOLVE3D
# define EAST_M3RADIATION
# define EAST_M3NUDGING
# define EAST_TRADIATION
# define EAST_TNUDGING
# define EAST_MIGRADIENT
# endif
#endif
/* roms quirks */
#ifdef SOLVE3D
# define ANA_BSFLUX
# define ANA_BTFLUX
#else
# define ANA_SMFLUX
#endif
/*
** Biological model options.
*/
#define NEMURO
#define LIMIT_BIO_AKT
#undef BIO_GOANPZ /* Sarah Hinckley’s 11 box model */
#undef BEST_NPZ /* Georgina Gibsons BEST NPZ model */
109
# define IRON_RELAX
# undef IRON_RSIN
# define BIO_SEDIMENT
# define HOLLING_GRAZING
# undef IVLEV_EXPLICIT
# undef ANA_BIOSWRAD
# undef DIAGNOSTICS_BIO
# undef BIO_SEDIMENT
#endif
Here, we have declared that we want two open sides and two closed walls. For each open side,
we’re using a Chapman/Flather combination on the 2D flow and a radiation/nudging combination
on the 3D flow. We’ve got masking, salinity, and the non-linear equation of state. We want Lapla-
cian viscosity on σ-surfaces, diffusion along constant z-surfaces and the full non-linear, curvilinear
momentum equations. Sea ice is turned on, as is the NEMURO ecosystem (for some runs at
least).
Notice that comments are allowed in this file as long as they are in the C/C++ syntax. Also,
conditionals are fine—some parts are only wanted when SOLVE3D is on. There is evidence of
options having been tried and rejected, such as the quadratic bottom drag in the presence of tides.
The “Eastern” side is actually open to the North, up in the Arctic, but it is set to be a closed
boundary. Instead, there is an imposed flow through Bering Strait by using UV_PSOURCE and
ANA_PSOURCE.
110
END DO
# endif
# endif
# if defined NEP5
cff = 800000._r8/Nsrc
DO is=1,Nsrc
Qbar(is)=cff
END DO
# else
ana_psource.h: No values provided for Qbar.
# endif
The total transport is set to 0.8 Sv and is divided among the Nsrc sources.
Doing a search for NEP5 shows up a few other instances. One is in output.F, forcing more
digits in the averages file names for handling one file per record, one record per day for fifty years:
#ifdef NEP5
20 FORMAT (a,’_’,i5.5,’.nc’)
#else
20 FORMAT (a,’_’,i4.4,’.nc’)
#endif
Also in output.F is code to ask for a new stations file for each run rather than appending to the
old one:
#ifdef NEP5
CALL def_station (ng, .true.)
#else
CALL def_station (ng, ldefout(ng))
#endif
A better fix (someday) would be to allow the station files to be numbered just like the averages
files. Why not set ldefout to be true? It is shared by many outputs, including the floats, and you
can only restart floats with ldefout set to false.
One feature which got turned on after the two decade “run 35” is SRELAXATION, in which
I’m nudging the sea surface salinity to a value from a forcing file. If you check the nudging code, you
will find that the timescale for nudging is the same as that used for the open boundary conditions.
That isn’t quite what I want, so there’s this change to set_vbc.F:
There is also a kludge in step_floats.F for a yet-untested float reuse strategy. Having a handy tag
like NEP5 allows me to search for these little hacks later. The file Apps/NEP/ana_hmixcoef.h
tried to sneak by without any NEP5, but the location means that it will be used to set up the
sponge layers for this domain:
111
! Northeast Pacific sponge areas
!
Iwrk = 10
# if defined UV_VIS2
DO i=IstrR,IendR
DO j=JstrR,MIN(Iwrk,JendR)
cff = 250.*0.5_r8*(1.0_r8+COS(pi*REAL(j,r8)/REAL(Iwrk,r8)))
visc2_r(i,j) = max(cff, visc2_r(i,j))
visc2_p(i,j) = max(cff, visc2_p(i,j))
END DO
END DO
DO i=IstrR,MIN(Iwrk,IendR)
DO j=MAX(JstrR,i),JendR
cff = 250.*0.5_r8*(1.0_r8+COS(pi*REAL(i,r8)/REAL(Iwrk,r8)))
visc2_r(i,j) = max(cff, visc2_r(i,j))
visc2_p(i,j) = max(cff, visc2_p(i,j))
END DO
END DO
:
# if defined TS_DIF2
DO itrc=1,NT(ng)
DO j=JstrR,MIN(Iwrk,JendR)
cff = 100. * (1.0_r8+COS(pi*REAL(j,r8)/REAL(Iwrk,r8)))
DO i=IstrR,IendR
diff2(i,j,itrc)=max(cff, diff2(i,j,itrc))
END DO
END DO
DO i=IstrR,MIN(Iwrk,IendR)
DO j=MAX(JstrR,i),JendR
cff = 100. * (1.0_r8+COS(pi*REAL(i,r8)/REAL(Iwrk,r8)))
diff2(i,j,itrc) = max(cff, diff2(i,j,itrc))
END DO
END DO
The vertical structure is the same as we’ve been using for a good long time now, though the
minimum depth keeps creeping shallower:
112
7.3.4 Initial and boundary conditions
The best fields we know of at the moment are known as SODA, a reanalysis from 1958 through
2005 by Carton et al. ([6]). There are Matlab scripts to create initial and boundary conditions
from the SODA files.
7.3.5 Forcing
We are using the CORE forcing files ([42]) and computing the momentum, heat and salt fluxes
from the atmospheric conditions and the model’s surface temperature. There are two options,
one provided by bulk_flux.F and the other provided by ccsm_flux.F. We are opting to use
the second. With minimal fussing, the CORE files can be used as is, on their native grid, then
interpolated by ROMS internally to the domain at hand.
7.3.6 ocean.in
We use an internal time-step of 200 s and an external time-step of 10 s. The horizontal viscosity
and diffusion is:
plus the sponge layers as shown above along the SE and SW boundaries.
7.3.7 Output
The model writes voluminous information to standard out, as shown for the UPWELLING case.
It also writes out NetCDF files for restart, history, daily averages, stations and floats. Plots can be
made from any of these files; some examples are shown in Fig. 22–24 .
113
Figure 22: Surface elevation after 200 days showing tides. This is from a snapshot in a history
file—the averages files have been detided.
114
Figure 23: Ice concentration averaged over the month of April, 1959.
115
Figure 24: Vertical slice if temperature, averaged over the month of April, 1959. The slice is across
the Bering Sea shelf, showing the transition from vertically mixed at the coast, a two layer system
at mid-shelf, then a thermocline over the shelf-break.
116
8 Plotting Programs for Postprocessing
Hernan Arango has provided ROMS with some Fortran programs for creating plots from the
NetCDF history and restart files. Some example plots are shown in §7. Other plotting options are
available via Matlab, Python and NCL. Here we describe only the Fortran programs available
via svn from myroms.org.
There are four plotting programs:
cnt creates black-and-white plots of the horizontal fields, including constant depth plots of
the 3-D fields.
ccnt creates color plots of the horizontal fields, including constant depth plots of the 3-D fields.
sec creates black-and-white plots of vertical slices through the 3-D fields. It includes on option
of finding equal-spaced points along a straight line through the curvilinear grid.
csec creates color plots of vertical slices through the 3-D fields. It includes on option of finding
equal-spaced points along a straight line through the curvilinear grid.
All of these program come with example input files. For instance, the input file for ccnt is called
ccnt.in and is as follows:
1996 -1 : year and starting year-day (use yearday<0, for no time label)
ROMS 3.2
Coarse Arctic ocean with Budgell ice dynamics
ice thermodynamics
117
10.0 LGRID : Desired longitude/latitude grid spacing (degrees)
4 IPROJ : map projection (see below).
-60.0 PLON : projection Pole longitude (west values are negative).
90.0 PLAT : projection Pole latitude (south values are negative).
0.0 ROTA : projection rotation angle (clockwise; degrees).
0 LMSK : flag to color mask land: [0] no, [1] yes
-1 NPAGE : number of plots per page (currently 1, 2, or 4)
T READGRD: logical switch to read in positions from grid NetCDF file.
F PLTLOGO: logical switch draw Logo.
T WRTHDR : logical switch to write out the plot header titles.
T WRTBLAB: logical switch to write out the plot bottom title.
T WRTRANG: logical switch to write out data range values and CI.
c
c=======================================================================
c Copyright (c) 1996 Rutgers University ===
c=======================================================================
c
118
*** IPROJ: Map Projections option. Some of the values for the
projection Pole and rotation angle are suggested.
Check the NCAR manual for details.
*** NPAGE: Number of plots per page. Set this parameter to a negative
value (-1, -2, or -4) to activate preservation of the plot
aspect ratio.
As you can see, there are comments describing what needs to be done. Please see the variable ID
file for the complete list of fields which can be plotted—this list changes as Hernan adds the ability
to plot new fields. Also, check your default.cnt file for other vector and contour parameters. The
palette file includes two number systems, one in the scale from 0 to 255 and the other from 0 to 1.
The ROMS plotting uses the first while the SEOM plotting uses the second.
119
A Model Time-stepping Schemes
Numerical time stepping uses a discrete approximation to:
∂φ(t)
= F(t) (230)
∂t
where φ represents one of u, v, C, or ζ, and F(t) represents all the right-hand-side terms. In
ROMS, the goal is to find time-stepping schemes which are accurate where they are valid and
damping on unresolved signals ([75]). Also, the preference is for time-stepping schemes requiring
only one set of the right-hand-side terms so that different time-stepping schemes can be used for
different terms in the equations. Finally, as mentioned in Table 4.3, not all versions of ROMS use
the same time-stepping algorithm. We list some time-stepping schemes here which are used or have
been used by the ROMS/SCRUM family of models, plus a few to help explain some of the more
esoteric ones.
A.1 Euler
The simplest approximation is the Euler time step:
φ(t + ∆t) − φ(t)
= F(t) (231)
∆t
where you predict the next φ value based only on the current fields. This method is accurate to
first order in ∆t; however, it is unconditionally unstable with respect to advection.
A.2 Leapfrog
The leapfrog time step is accurate to O(∆t2 ):
φ(t + ∆t) − φ(t − ∆t)
= F(t). (232)
2∆t
This time step is more accurate, but it is unconditionally unstable with respect to diffusion. Also,
the even and odd time steps tend to diverge in a computational mode. This computational mode
can be damped by taking correction steps. SCRUM’s time step on the depth-integrated equations
was a leapfrog step with a trapezoidal correction (LF-TR) on every step, which uses a leapfrog step
to obtain an initial guess of φ(t + ∆t). We will call the right-hand-side terms calculated from this
initial guess F ∗ (t + ∆t):
φ(t + ∆t) − φ(t) 1
= [F(t) + F ∗ (t + ∆t)] . (233)
∆t 2
This leapfrog-trapezoidal time step is stable with respect to diffusion and it strongly damps the
computational mode. However, the right-hand-side terms are computed twice per time step.
120
where
F(t) = φ0
∆t2 000
F(t − ∆t) = φ0 − ∆tφ00 + φ + ···
2
F(t − 2∆t) = φ0 − 2∆tφ00 + 2∆t2 φ000 + · · ·
A.4 Forward-Backward
In equation 230 above, we assume that multiple equations for any number of variables are time
stepped synchronously. For coupled equations, we can actually do better by time stepping asyn-
chronously. Consider these equations:
∂ζ
= F(u)
∂t (236)
∂u
= G(ζ)
∂t
If we time step them alternately, we can always be using the newest information:
This scheme is second-order accurate and is stable for longer time steps than many other schemes.
It is however unstable for advection terms.
1h i
ζ n+1 = ζ n + F(un+1,? ) + F(un ) ∆t
2 (239)
1h i
un+1 n
=u + G(ζ n+1 ) + (1 − )G(ζ n+1,? ) + G(ζ n ) ∆t
2
Setting β = = 0 in the above, it becomes a standard second order Runge-Kutta scheme, which is
unstable for a non-dissipative system. Adding the β and terms adds Forward-Backward feedback
to this algorithm, and allows us to improve both its accuracy and stability. The choice of β = 1/3
and = 2/3 leads to a stable third-order scheme with αmax = 2.14093 ([75]).
121
A.6 LF-TR and LF-AM3 with FB Feedback
Another possibility is a leapfrog predictor:
Keeping γ = 1/12 maintains third-order accuracy. The most accurate choices for β and are
β = 17/120 and = 11/20, which yields a fourth-order scheme with low numerical dispersion and
diffusion and αmax = 1.851640 ([75]).
122
B The vertical σ-coordinate
Following Song and Haidvogel [79] but modified by Shchepetkin and McWilliams [73], the vertical
coordinate has been chosen to be:
z = ζ(1 + σ) + hc σ + (h − hc )C(σ), −1 ≤ σ ≤ 0 (243)
where hc is either the minimum depth or a shallower depth above which we wish to have more
resolution. C(σ) is defined as:
sinh(θσ) tanh[θ(σ + 21 )] − tanh( 12 θ)
C(σ) = (1 − b) +b (244)
sinh θ 2 tanh( 21 θ)
where θ and b are surface and bottom control parameters. Their ranges are 0 < θ ≤ 20 and
0 ≤ b ≤ 1, respectively. Equation (243) leads to z = ζ for σ = 0 and z = h for σ = −1.
Some features of this coordinate system:
• It is a generalization of the traditional σ-coordinate system. Letting θ go to zero and using
L’Hopital’s rule, we get:
z = (ζ + h)(1 + σ) − h (245)
which is the classic σ-coordinate.
• It is infinitely differentiable in σ.
• The larger the value of θ, the more resolution is kept above hc .
• For b = 0, the resolution all goes to the surface as θ is increased.
• For b = 1, the resolution goes to both the surface and the bottom equally as θ is increased.
• Some problems turn out to be sensitive to the value of θ used.
Figure 25 shows the σ-surfaces for several values of θ and b for one of our domains. It was produced
by a Matlab tool written by Hernan Arango which is available from our web site (see §2.1).
We find it convenient to define:
∂z ∂C(σ)
Hz ≡ = (ζ + h) + (h − hc ) . (246)
∂σ ∂σ
The derivative of C(σ) can be computed analytically:
∂C(σ) cosh(θσ) coth( 12 θ)
= (1 − b) θ+b θ. (247)
∂σ sinh θ 2 cosh2 [θ(σ + 12 )]
However, we choose to compute Hz discretely as ∆z/∆σ since this leads to the vertical sum of Hz
being exactly the total water depth D.
Note that though we have used this form of σ-coordinate, ROMS is written in such a way as to
work with a variety of vertical mappings. There is one feature which is critical, however. If the free
surface is at rest, ζ = 0, you get one solution for the level depths z (0) (k). In the case of nonzero ζ,
the displacements must be proportional to ζ and to the original distance from the bottom:
!
z (0) (k)
z(k) = z (0) (k) + ζ 1 + (248)
h
or
ζ
(0)
∆z(k) = ∆z (k) 1 + (249)
h
This ensures that the vertical mass fluxes generated by a purely barotropic motion will vanish at
every interface.
123
Figure 25: The σ-surfaces for the North Atlantic with (a) θ = 0.0001 and b = 0, (b) θ = 8 and
b = 0, (c) θ = 8 and b = 1. (d) The actual values used in this domain were θ = 5 and b = 0.4.
124
C Horizontal curvilinear coordinates
The requirement for a boundary-following coordinate system and for a laterally variable grid res-
olution can both be met (for suitably smooth domains) by introducing an appropriate orthogonal
coordinate transformation in the horizontal. Let the new coordinates be ξ(x, y) and η(x, y) where
the relationship of horizontal arc length to the differential distance is given by:
1
(ds)ξ = dξ (250)
m
1
(ds)η = dη (251)
n
Here, m(ξ, η) and n(ξ, η) are the scale factors which relate the differential distances (∆ξ, ∆η) to
the actual (physical) arc lengths.
It is helpful to write the equations in vector notation and to use the formulas for div, grad, and
curl in curvilinear coordinates (see Batchelor, Appendix 2, [3]):
ˆ ∂φ ∂φ
∇φ = ξm + η̂n (252)
∂ξ ∂η
∂ a ∂ b
∇ · ~a = mn + (253)
∂ξ n ∂η m
ξ̂1 ξ̂2
m n k̂
∇ × ~a = mn ∂ ∂ ∂ (254)
∂ξ ∂η ∂z
a b
m n c
∂ m ∂φ ∂ n ∂φ
∇2 φ = ∇ · ∇φ = mn + (255)
∂ξ n ∂ξ ∂η m ∂η
where φ is a scalar and ~a is a vector with components a, b, and c.
125
D Viscosity and Diffusion
D.1 Horizontal viscosity
The horizontal viscosity and diffusion coefficients are scalars which are read in from ocean.in.
Several factors to consider when choosing these values are:
spindown time The spindown time on wavenumber k is k21ν2 for the Laplacian operator and k41ν4
for the biharmonic operator. The smallest wavenumber corresponds to the length 2∆x
π
and is k = ∆x , leading to
∆x2 ∆x4
∆t < tdamp = or (256)
π 2 ν2 π 4 ν4
This time should be short enough to damp out the numerical noise which is being gen-
erated but long enough on the larger scales to retain the features you are interested in.
This time should also be resolved by the model timestep.
boundary layer thickness The western boundary layer has a thickness proportional to
1 1
ν2 ν4
3 5
∆x < LBL = and (257)
β β
for the Laplacian and biharmonic viscosity, respectively. We have found that the model
typically requires the boundary layer to be resolved with at least one grid cell. This leads
to coarse grids requiring large values of ν.
126
E Radiant heat fluxes
As was seen in §5.2, the model thermodynamics requires fluxes of latent and sensible heat and long-
wave and shortwave radiation. We follow the lead of Parkinson and Washington [60] in computing
these terms.
The declination is
δ = 23.44◦ × cos [(172 − day of year) × 2π/365] (260)
and the hour angle is
HA = (12 hours − solar time) × π/12. (261)
The correction for cloudiness is given by
LW ↓ = (1 + 0.275c) F ↓ . (264)
The vapor pressures are used to compute specific humidities according to:
e
q10m = (268)
p − (1 − )e
es
qs = (269)
p − (1 − )es
127
Variable Value Description
(a, b) (9.5, 7.66) vapor pressure constants over ice
(a, b) (7.5, 35.86) vapor pressure constants over water
c cloud cover fraction
CE 1.75 × 10−3 transfer coefficient for latent heat
CH 1.75 × 10−3 transfer coefficient for sensible heat
cp 1004 J kg−1 K−1 specific heat of dry air
δ declination
e vapor pressure in pascals
es saturation vapor pressure
0.622 ratio of molecular weight of water to dry air
HA hour angle
L 2.5 × 106 J kg−1 latent heat of vaporization
L 2.834 × 106 J kg−1 latent heat of sublimation
φ latitude
Qo incoming radiation for cloudless skies
qs surface specific humidity
q10m 10 meter specific humidity
ρa air density
S 1353 W m−2 solar constant
σ 5.67 × 10−8 W m−2 K−4 Stefan-Boltzmann constant
Ta air temperature
Td dew point temperature
Tsfc surface temperature of the water/ice/snow
Vwg geostrophic wind speed
Z solar zenith angle
Table 8: Variables used in computing the incoming radiation and latent and sensible heat
Note that these need to be computed independently for the ice-covered and ice-free portions of each
gridbox since the empirical factors a and b and the factor L differ depending on the surface type.
128
F The C preprocessor
The C preprocessor, cpp, is a standalone program which comes with most C compilers. On older
UNIX systems it was not in the default path, but in /lib or in /usr/lib. Most modern systems have
some version of gcc which comes with a quite capable cpp. Just be sure to give it the -traditional
flag.
This Appendix describes the C preprocessor as used in ROMS with the Fortran language. A
more complete description is given by Kernighan and Ritchie [37]. More practical advice on using
cpp is given by Hazard [27].
include ’file.h’
with the contents of file.h; file.h is assumed to be in the current directory. The C preprocessor
has an equivalent include statement:
#include "file.h"
We are using the C preprocessor style of include because many of the ROMS include files are not
pure Fortran and must be processed by cpp.
where “name” would be replaced with “replacement text” throughout the rest of the file. This was
used in SCRUM as a reasonably portable way to get 64-bit precision:
The statement function is preferable because it allows the compiler to do type checking and because
you don’t have to be as careful about using enough parentheses.
The third form of macro has no replacement text at all:
#define MASKING
In this case, MASKING will evaluate to true in the conditional tests described below.
129
F.3 Conditional inclusion
It is possible to control which parts of the code are seen by the Fortran compiler by the use of
cpp’s conditional inclusion. For example, the statements
#ifdef MASKING
# include "mask.h"
#endif /* MASKING */
:
# ifdef MASKING
c
c Apply Land/Sea mask: slipperiness.
c
do j=1,M
do i=2,Lm
Uflux(i,j)=Uflux(i,j)*pmask(i,j)
enddo
enddo
# endif /* MASKING */
will not be in the Fortran source code if MASKING has not been defined. Likewise, #ifndef
tests for a macro being undefined:
#ifndef RMDOCINC
c rmask Mask at RHO-points (0=Land, 1=Sea).
c pmask Slipperiness mask at PSI-points (0=Land, 1=Sea,
c 1-gamma2=boundary).
c umask Mask at U-points (0=Land, 1=Sea).
c vmask Mask at V-points (0=Land, 1=Sea).
c
c=======================================================================
#endif
There are also #else and #elif (else if) statements, although #elif is newer and is not sup-
ported by all versions of cpp. An example using #else and #elif is shown:
#ifdef SOLITON
real(r8) :: g = 1.0_r8 ! non-dimensional
# elif defined WBC_1 || defined WBC_2 || defined WBC_3
real(r8) :: g = 9.8_r8 ! m/s2
# elif defined CIRCLE
real(r8) :: g = 3.92e-2_r8 ! m/s2
#else
real(r8) :: g = 9.81_r8 ! m/s2
#endif
Actually, #ifdef is a restricted version of the more general test
#if expression
where “expression” is a constant integer value. Zero evaluates to false and everything else is
considered true. Compound expressions may be built using the C logical operators:
&& logical and
|| logical or
! logical not
130
These symbols would be used as in the following example:
F.4 C comments
The C preprocessor will also delete C language comments starting with /* and ending with */ as
in:
#endif /* MASKING */
#define NEP5
#if defined NEP5 || defined BERING
:
# ifdef MASKING
:
# endif
#endif
#define NEP5 1
#if NEP5 || BERING
:
# if MASKING
:
# endif
#endif
Both styles work and you should be aware that there’s more than one way to do it.
1. Apostrophes in Fortran comments. cpp does not know that it is in a comment and some
versions will complain about unmatched apostrophes in the following:
131
2. C++ comments. Some of the newer versions of cpp will remove C++ comments which go from
’//’ to the end of the line. Some perfectly reasonable Fortran lines contain two consecutive
slashes, such as:
3. Macro replacement. One feature of cpp is that you can define macros and have it perform
replacements. The code:
becomes
and you run the risk of creating lines which are longer than 72 characters in length.
Also, make sure that your macros will not be found anywhere else in the code. I used to
use #define DOUBLE for double precision until it was pointed out to me that DOUBLE
PRECISION is perfectly valid Fortran. Since a string that is simply “defined” becomes 1,
the macro processor would turn this into 1 PRECISION.
132
G Makefiles
One of the software development tools which comes with the UNIX operating system is called
make. Make has many uses, but is most commonly used to keep track of how a large program
should be compiled. ROMS now requires the gnu version of make, sometimes known as gmake
(Mecklenburg [52]). This appendix describes generic make, the gnu enhancements to make, as
well as describing the makefile structure used in ROMS. This material first appeared in the ARSC
HPC Newsletter in several segments and has been updated and restructured here.
main.o: main.f
<TAB> f77 -c -O main.f
init.o: init.f
<TAB> f77 -c -O init.f
plot.o: plot.f
<TAB> f77 -c -O0 plot.f
clean:
<TAB> rm *.o core
The default thing to build is model, the first target. The syntax is:
target: dependencies
<TAB> command
<TAB> command
The target model depends on the object files, main.o and friends. They have to exist and be
up to date before model’s link command can be run. If the target is out of date according to
the timestamp on the file, then the commands will be run. Note that the tab is required on the
command lines.
The other targets tell make how to create the object files and that they in turn have dependen-
cies. To compile model, simply type “make”. Make will look for the file makefile, read it, and
do whatever is necessary to make model up to date. If you edit init.f, that file will be newer than
init.o. Make would see that init.o is out of date and run the “f77 -c -O init.f” command. Now
init.o is newer than model, so the link command “f77 -o model main.o init.o plot.o” must be
executed.
To clean up, type “make clean” and the clean target will be brought up to date. The clean
target has no dependencies. What happens in that case is that the command (“rm *.o core”) will
always be executed.
The original version of this Makefile turned off optimization on plot.f due to a compiler bug,
but hopefully you won’t ever have to worry about that.
133
G.1.1 Macros
Make supports a simple string substitution macro. Set it with:
$(MY_MACRO)
The convention is to put the macros near the top of your Makefile and to use upper case. Also,
use separate macros for the name of your compiler and the flags it needs:
F90 = f90
F90FLAGS = -O3
LIBDIR = /usr/local/lib
LIBS = -L$(LIBDIR) -lmylib
#
# IBM version
#
F90 = xlf90_r
F90FLAGS = -O3 -qstrict
LDFLAGS = -bmaxdata:0x40000000
main.o: main.f
$(F90) -c $(F90FLAGS) main.f
init.o: init.f
$(F90) -c $(F90FLAGS) init.f
plot.o: plot.f
$(F90) -c $(F90FLAGS) plot.f
clean:
rm *.o core
Now when we change computers, we only have to change the compiler name in one place.
Likewise, if we want to try a different optimization level, we only specify that in one place.
Notice that you can use comments by starting the line with a #.
model: $(OBJS)
$(FC) $(LDFLAGS) -o model $(OBJS)
134
as your whole Makefile. Make will automatically invoke its default Fortran compiler, possibly
f77 or g77, with whatever default compile options it happens to have (FFLAGS). One built in
rule often looks like:
.c.o:
$(CC) $(CFLAGS) -c $<
which says to compile .c files to .o files using the compiler CC and options CFLAGS. We can
write our own suffix rules in this same style. The only thing to watch for is that make by default
has a limited set of file extentions that it knows about. Let’s write our Makefile using a suffix
rule:
#
# Cray version
#
F90 = f90
F90FLAGS = -O3
LDFLAGS =
.f.o:
$(F90) $(F90FLAGS) -c $<
clean:
rm *.o core
G.1.3 Dependencies
There may be additional dependencies beyond the source->object ones. In our little example,
all our source files include a file called commons.h. If commons.h gets modified to add a new
variable, everything must be recompiled. Make won’t know that unless you tell it:
# include dependencies
main.o: commons.h
init.o: commons.h
plot.o: commons.h
Fortran 90 introduces module dependencies as well. See §H for how we automatically generate this
dependency information.
The most common newbie mistake is to forget that the commands after a target have to start
with a tab.
135
G.2.1 Make rules
The core of make hasn’t changed in decades, but concentrating on gmake allows one to make use
of its nifty little extras designed by real programmers to help with real projects. The first change
that matters to my Makefiles is the change from suffix rules to pattern rules. I’ve always found
the .SUFFIXES list to be odd, especially since .f90 is not in the default list. Good riddance to
all of that! For a concrete example, the old way to provide a rule for going from file.f90 to file.o
is:
%.o: %.f90
<TAB> $(FC) -c $(FFLAGS) $<
In fact, going to a uniform make means that we can figure out what symbols are defined and use
their standard values—in this case, $(FC) and $(FFLAGS) are the built-in default names for the
compiler and its options. If you have any questions about this, you can always run make with the
-p (or --print-data-base) option. This prints out all the rules make knows about, such as:
# default
COMPILE.f = $(FC) $(FFLAGS) $(TARGET_ARCH) -c
Printing the rules database will show variables that make is picking up from the environment,
from the Makefile, and from its built-in rules—and which of these sources is providing each value.
G.2.2 Assignments
In the old days, I only used one kind of assignment: = (equals sign). Gmake has several kinds of
assignment (other makes might as well, but I no longer have to know or care). An example of the
power of gnu make is shown by an example from my Cray X1 Makefile. There is a routine which
runs much more quickly if a short function in another file is inlined. The way to accomplish this is
through the -O inlinefrom=file directive to the compiler. I can’t add this option to FFLAGS,
since the inlined routine won’t compile with this directive—there is only the one file that needs it.
I had:
FFLAGS = -O 3,aggress -e I -e m
FFLAGS2 = -O 3,aggress -O inlinefrom=lmd_wscale.f90 -e I -e m
lmd_skpp.o:
<TAB> $(FC) -c $(FFLAGS2) $*.f90
The first change I can make to this using other assignments is:
FFLAGS := -O 3,aggress -e I -e m
FFLAGS2 := $(FFLAGS) -O inlinefrom=lmd_wscale.f90
The := assignment means to evaluate the right hand side immediately. In this case, there is no
reason not to, as long as the second assigment follows the first one (since it’s using the value of
$(FFLAGS)). For the plain equals, make doesn’t evaluate the right-hand side until its second
pass through the Makefile. However, gnu make supports an assignment which avoids the need
for FFLAGS2 entirely:
136
lmd_skpp.o: FFLAGS += -O inlinefrom=lmd_wscale.f90
What this means is that for the target lmd_skpp.o only, append the inlining directive to FFLAGS.
I think this is pretty cool!
One last kind of assignment is to set the value only if there is no value from somewhere else
(the environment, for instance):
FC ?= mpxlf90_r
include file
and we use it liberally to keep the project information neat. We can also include a file with the
system/compiler information in it, assuming we have some way of deciding which file to include.
We can use uname -s to find out which operating system we’re using. We also need to know which
compiler we’re using.
One user-defined variable is called FORT, the name of the Fortran compiler. This value is
combined with the result of “uname -s” to provide a machine and compiler combination. For
instance, ftn on Linux is the Cray cross-compiler. This would link to a different copy of the
NetCDF library and use different compiler flags than the Intel compiler which might be on the
same system.
We pick one include file at compile time, here picking Linux-ftn.mk, containing the Cray cross-
compiler information. The value Linux comes from the uname command, the ftn comes from the
user, and the two are concatenated. The sed command will turn the slash in UNICOS/mp into
a dash; the native Cray include file is UNICOS-mp-ftn.mk. Strip is a built-in function to strip
away any extra white space.
Another tricky system is CYGWIN, which puts a version number in the uname output, such
as CYGWIN_NT-5.1. Gnu make has quite a few built-in functions, one of which allows us to
do string substitution:
OS := $(patsubst CYGWIN_%,CYGWIN,$(OS))
In make, the % symbol is a sort of wild card, much like * in the shell. Here, we match CYGWIN
followed by an underscore and anything else, replacing the whole with simply CYGWIN. Another
example of a built-in function is the substitution we do in:
where we build our list of objects from the list of sources. There are quite a few other functions,
plus the user can define their own. From the book[52]:
137
GNU make supports both built-in and user-defined functions. A function invocation
looks much like a variable reference, but includes one or more parameters separated
by commas. Most built-in functions expand to some value that is then assigned to a
variable or passed to a subshell. A user-defined function is stored in a variable or macro
and expects one or more parameters to be passed by the caller.
G.2.4 Conditionals
We used to have way too many Makefiles, a separate one for each of the serial/MPI/OpenMP
versions on each system (if supported). For instance, the name of the IBM compiler changes when
using MPI; the options change for OpenMP. The compiler options also change when using 64-bit
addressing or for debugging. A better way to organize this is to have the user select 64-bit or not,
MPI or not, etc., then use conditionals. The complete list of user definable make variables is given
in §2.4.1.
Gnu make supports two kinds of if test, ifdef and ifeq (plus the negative versions ifndef, ifneq).
The example from the book is:
ifdef COMSPEC
# We are running Windows
else
# We are not on Windows
endif
ifdef USE_DEBUG
FFLAGS += -g -qfullpath
else
FFLAGS += -O3 -qstrict
endif
ifeq ($(USE_MPI),on)
# Do MPI things
endif
or
The user has to set values for the USE_MPI, USE_DEBUG, and USE_LARGE switches in
the Makefile or the build script before the compiler-dependent piece is included:
USE_MPI ?= on
USE_DEBUG ?=
USE_LARGE ?=
The Makefile uses the conditional assign “?=” in case a build script is used to set them in the
environment. Be sure to leave the switches meant to be off set to an empty string—the string “off”
will test true on an ifdef test.
138
G.3 Multiple Source Directories the ROMS Way
There’s more than one way to divide your sources into separate directories. The choices we have
made include nonrecursive make and putting the temporary files in their own $(SCRATCH_DIR)
directory. These include the .f90 files which have been through the C preprocessor, object files,
module files, and libraries.
sources :=
libraries :=
That’s simple enough, but the list of directories to search for these sources will depend on the options
chosen by the user, not just in the make options (§2.4.1), but inside the ROMS_HEADER file
as well. How does this happen? Once make knows how to find the ROMS_HEADER, it is
used by cpp to generate an include file telling make about these other options.
MAKE_MACROS := Compilers/make_macros.mk
MACROS := $(shell cpp -P $(ROMS_CPPFLAGS) Compilers/make_macros.h > \
$(MAKE_MACROS); $(CLEAN) $(MAKE_MACROS))
#ifdef SWAN_COUPLING
USE_SWAN := on
#else
USE_SWAN :=
#endif
USE_SWAN := on
or
USE_SWAN :=
This file can then be included by the makefile and the variable USE_SWAN will have the correct
state for this particular compilation. We can now use it and all the similar flags to build a list of
directories.
We initialize two lists:
modules :=
includes := ROMS/Include
139
Add the adjoint bits:
ifdef USE_ADJOINT
modules += ROMS/Adjoint
endif
ifdef USE_ADJOINT
includes += ROMS/Adjoint
endif
modules += ROMS/Nonlinear \
ROMS/Functionals \
ROMS/Utility \
ROMS/Modules
includes += ROMS/Nonlinear \
ROMS/Utility \
ROMS/Drivers
ifdef USE_SWAN
modules += Waves/SWAN/Src
includes += Waves/SWAN/Src
endif
modules += Master
includes += Master Compilers
Now that our lists are complete, let’s put them to use:
1. vpath is a standard make feature for providing a list of directories for make to search for
files of different types. Here we are saying that *.F files can be found in the directories
provided in the $(modules) list, and so on for the others.
2. For each directory in the $(modules) list, make will include the file Module.mk that is
found there. More on these later.
3. For each directory in the $(includes) list, add that directory to the list searched by cpp
with the −I flag.
140
#--------------------------------------------------------------------------
# Make functions for putting the temporary files in $(SCRATCH_DIR)
#--------------------------------------------------------------------------
$2: $3
$$(CPP) $$(CPPFLAGS) $$(MY_CPP_FLAGS) $$< > $$@
$$(CLEAN) $$@
endef
# $(compile-rules)
define compile-rules
$(foreach f, $(local_src), \
$(call one-compile-rule,$(call source-to-object,$f), \
$(call f90-source,$f),$f))
endef
1. We define a function to convert the path from the source directory to the Build directory,
called source-dir-to-binary-dir. Note that the Build directory is called $(SCRATCH_DIR)
here. All it does is strip off the leading directory with the the built-in function notdir, then
paste on the Build directory.
2. Next comes source-to-object, which calls the function above to return the object filename
when given the source filename. It assumes that all sources have a .F extension.
141
3. A similar function is f90-source, which returns the name of the intermediate source which
is created by cpp from our .F file.
4. The Module.mk fragment in each library source directory invokes make-library, which
takes the library name and the list of sources as its arguments. The function adds its library
to the global list of libraries and provides rules for building itself. The double dollar signs
are to delay the variable substitution. Note that we call source-dir-to-binary-dir instead
of source-to-object—this is a work-around for a make bug.
5. The next, one-compile-rule, takes three arguments: the .o filename, the .f90 filename, and
the .F filename. From these, it produces the make rules for running cpp and the compiler.
A note on directories: make uses vpath to find the source file where it resides. It would be
possible to compile from the top directory and put the .o file in Build with the appropriate
arguments, but I don’t know how to get the .mod file into Build short of a mv command.
Likewise, if we compile in the top directory, we need to know the compiler option to tell it
to look in Build for the .mod files it uses. Doing a cd to Build before compiling is just
simpler.
6. The last, compile-rules, is given a list of sources, then calls one-compile-rule once per
source file.
Again, you can invoke make -p to see how make internally transforms all this into actual
targets and rules.
local_sub := ROMS/Nonlinear
local_lib := libNLM.a
$(eval $(compile-rules))
First, we provide the name of the current directory and the library to be built from the resident
sources. Next, we use the wildcard function to search the subdirectory for these sources. Note
that every .F file found will be compiled. If you have half-baked files that you don’t want used,
make sure they have a different extension.
Each subdirectory is resetting the local_src variable. That’s OK because we’re saving the
values in the global sources variable inside the make-library function, which also adds the local
library to the libraries list. The compile-rules function uses this local_src variable to generate
the rules for compiling each file, placing the resulting files in the Build directory.
142
local_sub := Master
local_src := $(wildcard $(local_sub)/*.F)
sources += $(local_src)
ifdef LD_WINDOWS
$(BIN): $(libraries) $(local_objs)
$(LD) $(FFLAGS) $(local_objs) -o $@ $(libraries) $(LIBS_WIN32) $(LDFLAGS)
else
$(BIN): $(libraries) $(local_objs)
$(LD) $(FFLAGS) $(LDFLAGS) $(local_objs) -o $@ $(libraries) $(LIBS)
endif
$(eval $(compile-rules))
Instead of a rule for building a library, we have a rule for building a binary $(BIN). In this case,
the name of the ROMS binary is defined elsewhere. The binary depends on the libraries getting
compiled first, as well as the local sources. During the link, the $(libraries) are compiled from the
sources in the other directories, while $(LIBS) are exteral libraries such as NetCDF.
#ifdef X86_64
! special stuff
#endif
CPPFLAGS += -D’ROOT_DIR="$(ROOTDIR)"’
ifdef ROMS_APPLICATION
CPPFLAGS += $(ROMS_CPPFLAGS)
CPPFLAGS += -DNestedGrids=$(NestedGrids)
MDEPFLAGS += -DROMS_HEADER="$(HEADER)"
endif
143
2. For mod_strings.F, there is a special case:
3. The very first makefile I showed had a set list of files to remove on make clean. We now
build a list, called clean_list:
In other words, we want to clean up the Build directory unless it happens to be the top level
directory, in which case we only want to remove specific files there.
4. “all” is the first target that gets seen by make, making it the default target. In this case,
we know there is only the one binary, whose name we know—the book[52] shows what to do
with more than one binary. Both “all” and “clean” are phony targets in that no files of those
names get generated—make has the .PHONY designation for such targets. Also, the clean
target doesn’t require any compiler information, so the compiler include doesn’t happen if
the target is “clean”:
5. We’ll be creating different executable names, depending on which options we’ve picked:
BIN := $(BINDIR)/oceanS
ifdef USE_DEBUG
BIN := $(BINDIR)/oceanG
else
144
ifdef USE_MPI
BIN := $(BINDIR)/oceanM
endif
ifdef USE_OpenMP
BIN := $(BINDIR)/oceanO
endif
endif
6. The NetCDF library gets included during the final link stage. However, we are now using
the Fortran 90 version of it which requires its module information as well. We just copy the
.mod files into the Build directory:
NETCDF_MODFILE := netcdf.mod
TYPESIZES_MODFILE := typesizes.mod
$(SCRATCH_DIR)/$(NETCDF_MODFILE): | $(SCRATCH_DIR)
cp -f $(NETCDF_INCDIR)/$(NETCDF_MODFILE) $(SCRATCH_DIR)
$(SCRATCH_DIR)/$(TYPESIZES_MODFILE): | $(SCRATCH_DIR)
cp -f $(NETCDF_INCDIR)/$(TYPESIZES_MODFILE) $(SCRATCH_DIR)
Old versions of NetCDF do not have the typesizes.mod file, in which case it has to be
removed from the following dependency list:
$(SCRATCH_DIR)/MakeDepend: makefile \
$(SCRATCH_DIR)/$(NETCDF_MODFILE) \
$(SCRATCH_DIR)/$(TYPESIZES_MODFILE) \
| $(SCRATCH_DIR)
7. Then there is MakeDepend itself. This file is created by the Perl script sfmakedepend.
MakeDepend gets created by “make depend” and included on make’s second pass through
the makefile:
depend: $(SCRATCH_DIR)
$(SFMAKEDEPEND) $(MDEPFLAGS) $(sources) > $(SCRATCH_DIR)/MakeDepend
The dash before the include tells make to ignore errors so that make depend will succeed
before the file exists. The MakeDepend file will contain the include and module dependen-
cies for each source file, such as:
Note that the .h files are included by cpp, so that both the .f90 and .o files become out of
date when an include file is modified. Without the module dependencies, make would try to
build the sources in the wrong order and the compiler would fail with a complaint about not
finding mod_param.mod, for instance.
145
G.4 Final warnings
The cost of this nifty make stuff is:
1. We’re a little closer to the gnu make bugs here, and we need a newer version of gnu make
than before (version 3.81, 3.80 if you’re lucky). Hence this stuff at the top of the makefile:
2. The Makefile dependencies get just a little trickier every change we make. Note that F90
has potentially both include and module use dependencies. The book example uses the C
compiler to produce its own dependencies for each source file into a corresponding .d file to
be included by make. Our Fortran compilers are not so smart. For these hairy compiles, it’s
critical to have accurate dependency information unless we’re willing to make clean between
compiles.
146
H sfmakedepend
The other Perl script I use with Fortran modifies the Makefile to include dependency information,
much like the X11 program makedepend. I originally wrote fmakedepend which was used with
traditional Fortran include statements. I later wrote a variant of it for use with the C preprocessor,
called sfmakedepend. The latest version of sfmakedepend does the job of both programs and
also searches for the dependencies introduced by Fortran 90 modules. It is used by the Makefiles
described in §G.
It recursively searches for Fortran style includes, for instance if file.f has the statement:
include ’commons.h’
the line
file.o: commons.h
will be added to the bottom of the Makefile. This tells make that file.o depends on commons.h
as well as file.f, and to recompile file.f whenever commons.h is modified. It likewise searches
source files for C style includes such as
#include "commons.h"
and adds the corresponding dependencies to the Makefile. It has several options, including -s,
required for Fortran compilers which will not invoke the C preprocessor for you. In this case the
above dependency line would become
file.o: commons.h
file.f: commons.h
letting make know that the C preprocessor must be rerun on file.F whenever commons.h is
updated.
When using the C preprocessor, you can ask it to search directories other than the current
directory. Likewise, sfmakedepend can be instructed to search other directories with -I dir
options. Note that it is legal to have more than one -I dir option as in:
sfmakedepend -I /usr/local/include -I /home/me/include *.F
Fortran 90 introduces some interesting dependencies. Two compilers I have access to (NAG f90
and IBM xlf) produce a private my_module.mod file if you define module My_Module in
file mod.f90. This file is used by the compiler when you use the module as a consistency check
(type-safe programming). If foo.f90 uses that module, you will need the following dependency
information:
foo.o: my_module.mod
my_module.mod: mod.o
This says that before compiling foo.f90 we need to have the file my_module.mod. This file in
turn depends on mod.o, so that mod.f90 must be compiled before foo.f90. The sgi is similar
except that it uses the file MY_MODULE.kmo to store the private module information. Use
sfmakedepend -g on the SGI.
Rather than creating extra module files, the Cray and Parasoft compilers store the module
information in the object file and then files which use the modules need to be compiled with extra
flags pointing to the module object files. For instance, if foo.f90 uses My_Module which was
defined in mod.f90, then you will need to compile mod.f90 first and provide the Cray compiler with
the extra option -p mod.o when compiling foo.f90. When using the Cray, use sfmakedepend -c
to get the dependency information:
147
foo.o: mod.o
$(CFT) $(FFLAGS) -c -p mod.o foo.f90
$(CFT) and $(FFLAGS) are assumed to be previously defined as the name of the compiler and
the compiler options, respectively.
Note: These f90 module dependencies can confuse some versions of make, especially of the
System V variety. We use gnu make because it can follow these chained dependencies and do the
right thing.
sfmakedepend assumes that all the files using and defining modules are in the same directory
and are all in the list of files to be searched. It seems that the industry has not settled on a practical
way to deal with a separate modules directory, anyway.
I sometimes include non-existent files as a compile time consistency check:
#ifndef PLOTS
#include "must_define_PLOTS" /* bogus include */
#endif
This program warns about include files it can’t find, but not if there is a “bogus” on the same line.
See the comments at the top of sfmakedepend for up-to-date information on the options. I
may someday get inspired to use a newer version of the getopt routine and rename the options to
have names like -SGI and -Cray.
148
I Subversion
The ROMS source code is distributed using Subversion (svn). There are svn clients available for
nearly every operating system and many resources available, including an O’Reilly book [9]. I’ll
just cover a few basics here, taken in part from the ROMS wiki.
If you wish to maintain your own copy of ROMS in a source code repository, you may want to
investigate git, which has the ability to download from an svn server. It too has an O’Reilly book
([46]), plus I enjoyed Swicegood’s book ([81]).
I.1 Overview
Subversion is a tool for managing software development that keeps track of who modified what and
allows the return to a previous version if changes don’t work as expected. All the ROMS/TOMS
files are stored in a SVN repository on www.myroms.org with access controlled by requiring au-
thentication with the same ROMS Username/Password combination assigned to registered users of
the ROMS Forum.
This svn repository is the official version of the code which only the developers are allowed to
change. Users should download the ROMS code to their local machines using an svn client. Don’t
attempt to use a regular web browser to browse or download files from the svn repository - there
are much better tools for interacting with the code repository.
We strongly recommend that users always check out the current trunk version since this has
the most recent updates and bug fixes. The tags version is kept largely as an historical record of
stable releases at the conclusion of major code upgrades.
Below is a general description of how subversion works. Please look at the svn book ([9]) for
more detailed information and the wiki for more on some available GUI clients.
149
I.3 Updates
Now and again, you might feel the urge to get up to speed with the latest changes that have been
made to the ROMS repository. When that happens, simply go to the directory that was “MyDir”
above and type:
svn update
Subversion will remember where you checked out from before and see if a newer revision exists. If
so, it will download and apply all the relevant changes.
I.5 Conflicts
Sometimes when you make changes to your copy of the ROMS code, those changes will conflict
with changes made to the repository. This means that the changes from the server overlapped with
your own, and now you have to manually choose between them.
Whenever a conflict occurs, three things typically occur to assist you in resolving that conflict:
• Subversion halts during the update, offering you several choices, and remembers that the file
is in a state of conflict if you don’t clear it right then.
• If Subversion considers the file to be mergeable, it places conflict markers (special strings of
text which delimit the “sides” of the conflict, usually “<” and “>” characters) into the file
to visibly demonstrate the overlapping areas.
• For every conflicted file, Subversion places three extra unversioned (not under Subversion
control) files in your working copy:
filename.mine : This is your file as it existed in your working copy (local copy) before
you updated your working copy. This file has only your latest changes in it. (If
Subversion considers the file to be unmergeable, then the .mine file isn’t created,
since it would be identical to the working file.)
filename.rOLDREV : This is the file that was the BASE revision before you updated your
working copy. That is, the file that you checked out before you made your latest
edits.
filename.rNEWREV : This is the file that your Subversion client just received from the
server when you updated your working copy. This file corresponds to the HEAD
(latest) revision of the repository.
For example, let’s say you checked out revision 280 and made some changes to a file, for instance
User/Functionals/ana_hmixcoef.h. Now you want to update your ROMS source code to take
advantage of a new algorithm but when you run svn update your ana_hmixcoef.h is now in
conflict with the new version in the repository:
150
> svn update
U Version
U ROMS/Modules/mod_mixing.F
U ROMS/Functionals/ana_hmixcoef.h
C User/Functionals/ana_hmixcoef.h
Updated to revision 291.
>
The above is with an older version of svn. The latest, greatest does this:
• Merge the conflicted text “by hand” by examining and editing the conflict markers within
the file.
• Run svn revert <filename> to throw away all of your local changes.
Once you’ve resolved the conflict, you need to let Subversion know by running “svn resolved”. This
removes the three temporary files and Subversion no longer considers the file to be in a state of
conflict. More on this below.
<<<<<<< .mine
#ifndef DISTRIBUTE
IF (Lanafile.and.(tile.eq.0)) THEN
#else
IF (Lanafile) THEN
#endif
=======
#ifdef DISTRIBUTE
IF (Lanafile) THEN
#else
IF (Lanafile.and.(tile.eq.0)) THEN
#endif
>>>>>>> .r291
After comparing the two code blocks (separated by the “=” symbols), you decide that you prefer
the logic from the repository so you remove the conflict markers and your code so the section now
looks like this:
151
#ifdef DISTRIBUTE
IF (Lanafile) THEN
#else
IF (Lanafile.and.(tile.eq.0)) THEN
#endif
Now you can save the file and let Subversion know that you have resolved the conflict:
> cd User/Functionals
> ls ana_hmixcoef.h*
ana_hmixcoef.h ana_hmixcoef.h.mine ana_hmixcoef.h.r280
ana_hmixcoef.h.r291
> cd User/Functionals
> svn revert ana_hmixcoef.h
Reverted ’ana_hmixcoef.h’
Note that when you revert a conflicted file, you don’t have to run “svn resolved”.
152
References
[1] J. S. Allen, P. A. Newberger, and J. Federiuk. Upwelling circulation on the oregon continental
shelf. part i: Response to idealized forcing. J. Phys. Oceanogr., 25:1843–1866, 1995.
[2] A. Arakawa and V. R. Lamb. Methods of computational physics, volume 17, pages 174–265.
Academic Press, 1977.
[4] A. Beckmann and D. B. Haidvogel. Numerical simulation of flow around a tall, isolated
seamount. part i: Problem formulation and model accuracy. J. Phys. Oceanogr., 23:1736–
1753, 1993.
[5] W.P. Budgell. Numerical simulation of ice-ocean variability in the barents sea region: Towards
dynamical downscaling. Ocean Dynamics, 2005. doi:10.1007/s10236-005-0008-3.
[6] J. A. Carton, B. S. Giese, and S. A. Grodsky. Sea level rise and the warming of the oceans in
the soda ocean reanalysis. J. Geophys. Res., 110, 2005. doi:10.1029/2004JC002817.
[7] F. Chai, R. C. Dugdale, T.-H. Peng, F. P. Wilkerson, and R. T. Barber. One dimensional
ecosystem model of the equatorial pacific upwelling system, part i: model development and
silicon and nitrogen cycle. Deep Sea Res. II, 49:2713–2745, 2002.
[9] Ben Collins-Sussman, Brian W. Fitzpatrick, and C. Michael Pilato. Version Control with Sub-
version. O’Reilly & Associates, Inc., Sebastopol, CA, second edition, 2008. http://svnbook.red-
bean.com/.
[10] E. E. Ebert and J. A. Curry. An intermediate one-dimensional thermodynamic sea ice model
for investigating ice-atmosphere interactions. J. Geophys. Res., 98:10085–10109, 1993.
[12] K. N. Fedorov. Layer thicknesses and effective diffusivities in the diffusive thermocline con-
vection in the ocean. In J. C. J. Nihoul and B. M. Jamart, editors, Small-scale turbulence and
mixing in the ocean, pages 471–479. Elsevier, New York, 1988.
[13] K. Fennel, J. Wilkin, J. Levin, J. Moisan, J. O’Reilly, and D. Haidvogel. Nitrogen cycling in
the mid atlantic bight and implications for the north atlantic nitrogen budget: Results from a
three-dimensional model. Global Biogeochem. Cycles, 20, 2006. doi:10.1029/2005GB002456.
[14] R. A. Flather. A tidal model of the northwest european continental shelf. Memoires de la
Société Royale de Sciences de Liège, 6:141–164, 1976.
[15] M. G. G. Foreman. Manual for tidal heights analysis and prediction. Technical Report 77-10,
Institute of Ocean Sciences, Patricia Bay, 1977 (revised 1996). Pacific Marine Science Report.
[16] M. G. G. Foreman. Manual for tidal currents analysis and prediction. Technical Report 77-10,
Institute of Ocean Sciences, Patricia Bay, 1978 (revised 1996). Pacific Marine Science Report.
[17] J. A. Francis and A. Schweiger. A new window opens on the arctic. Trans. Amer. Geophys.
Un., 81:77–83, 2000.
153
[18] P. J. S. Franks, J. S. Wroblewski, and G. R. Flierl. Behavior of a simple plankton model with
food-level acclimation by herbivores. Mar. Biol., 91:121–129, 1986.
[19] N. G. Freeman, A. M. Hale, and M. B. Danard. A modified sigma equations’ approach to the
numerical modeling of great lake hydrodynamics. J. Geophys. Res., 77(6):1050–1060, 1972.
[20] B. Galperin, L. H. Kantha, S. Hassid, and A. Rosati. A quasi-equilibrium turbulent energy
model for geophysical flows. J. Atmos. Sci., 45:55–62, 1988.
[21] J. M. N. T. Gray and P. D. Killworth. Sea ice ridging schemes. J. Phys. Oceanogr., 26:2420–
2428, 1996.
[22] S.M. Griffies, A. Gnanadesikan, R.C. Pacanowski, V. Larichev, J.K. Dukowicz, and R.D.
Smith. Isoneutral diffusion in a z-coordinate ocean model. J. Phys. Oceanogr., 28:805–830,
1998.
[23] S.M. Griffies and R.W. Hallberg. Biharmonic friction with a smagorinsky-like viscosity for use
in large-scale eddy-permitting ocean models. Mon. Wea. Rev., 128:2935–2946, 2000.
[24] D. B. Haidvogel, H. G. Arango, W. P. Budgell, B. D. Cornuelle, E. Curchitser, E. Di Lorenzo,
K. Fennel, W. R. Geyer, A. J. Hermann, L. Lanerolle, J. Levin, J. C. McWilliams, A. J.
Miller, A. M. Moore, T. M. Powell, A. F. Shchepetkin, C. R. Sherwood, R. P. Signell, J. C.
Warner, and J. Wilkin. Ocean forecasting in terrain-following coordinates: formulation and
skill assessment of the regional ocean modeling system. J. Comp. Phys., 227:3429–3430, 2007.
doi:10.1016/j.jcp.2007.01.016.
[25] D. B. Haidvogel, H. G. Arango, K. Hedstrom, A. Beckmann, P. Malanotte-Rizzoli, and A. F.
Shchepetkin. Model evaluation experiments in the north atlantic basin: Simulations in non-
linear terrain-following coordinates. Dyn. Atmos. Ocean., 32:239–281, 2000.
[26] D. B. Haidvogel and A. Beckmann. Numerical Ocean Circulation Modeling. Imperial College
Press, 1999.
[27] W. P. Hazard. Using cpp to aid portability. Computer Language, 8(11):49–54, 1991.
[28] K. S. Hedstrom. Technical manual for a coupled sea-ice/ocean circulation model (version 2).
Technical report, Institute of Marine and Coastal Sciences, New Brunswick, NJ, June 2000.
OCS Study MMS 2000-047.
[29] W. D. Hibler, III. A dynamic thermodynamic sea ice model. J. Phys. Oceanogr., 9:815–846,
1979.
[30] S. Hinckley, K. O. Coyle, G. Gibson, A. J. Hermann, and E. L. Dobbins. A biophysical npz
model with iron for the gulf of alaska: Reproducing the differences between an oceanic hnlc
ecosystem and a classical northern temperate shelf ecosystem. Deep Sea Res. II, 2009. in press.
[31] W. R. Holland, J. C. Chow, and F. O. Bryan. Application of a third-order upwind scheme in
the ncar ocean model. J. Climate, 11:1487–1493, 1998.
[32] E. C. Hunke. Viscous-plastic sea ice dynamics with the evp model: linearization issues. J.
Comp. Phys., 170:18–38, 2001.
[33] E. C. Hunke and J. K. Dukowicz. An elastic-viscous-plastic model for sea ice dynamics. J.
Phys. Oceanogr., 27:1849–1868, 1997.
[34] D. R. Jackett and T. J. McDougall. Stabilization of hydrographic data. J. Atmos. Ocean.
Tech., 12:381–389, 1995.
154
[35] Y. Kanarska, A. F. Shchepetkin, and J. C. McWilliams. Algorithm for non-hydrostatic dy-
namics in roms. Ocean Modeling, 18:143–174, 2007.
[37] B. W. Kernighan and D. M. Ritchie. The C Programming Language. Prentice Hall, Englewood
Cliffs, New Jersey 07632, second edition, 1988.
[39] H. Lamb. Hydrodynamcis. Cambridge University Press, 6 edition, 1932. (1945 Dover Publica-
tions reproduction).
[40] W. G. Large. Modeling and parameterization ocean planetary boundary layers. In E. P. Chas-
signet and J. Verron, editors, Ocean Modeling and Parameterization, pages 81–120. Kluwer
Academic Publishers, 1998.
[41] W. G. Large, J. C. McWilliams, and S. C. Doney. Oceanic vertical mixing: a review and a
model with a nonlocal boundary layer parameterization. Rev. Geophys., 32:363–403, 1994.
[42] W. G. Large and S. G. Yeager. The global climatology of an interannually varying air-sea flux
data set. Clim. Dyn., 33:341–364, 2008. DOI 10.1007/s00382-0008-0441-3.
[43] J. R. Ledwell, A. J. Wilson, and C. S. Low. Evidence for slow mixing across the pycnocline
from an open-ocean tracer-release experiment. Nature, 364:701–703, 1993.
[44] B. P. Leonard. A stable and accurate convective modelling procedure based on quadratic
upstream interpolation. Comput. Method Appl. Mech. Eng., 19:59–98, 1979.
[45] S.-J. Lin. A finite volume integration method for computing pressure gradient force in general
vertical coordinates. Quart. J. R. Met. Soc., 123:1749–1762, 1997.
[46] Jon Loeliger. Version Control with Git. O’Reilly & Associates, Inc., Sebastopol, CA, first
edition, 2009.
[47] A. Macks and J. Middleton. Numerical modelling of wind-driven upwelling and downwelling.
University of New South Wales, 1993.
[48] J. Mailhôt and R. Benoit. A finite-element model of the atmospheric boundary layer suitable
for use with numerical weather prediction models. J. Atmos. Sci., 39:2249–2266, 1982.
[49] P. Marchesiello, J. C. McWilliams, and A. Shchepetkin. Open boundary conditions for long-
term integration of regional oceanic models. Ocean Modelling, 3:1–20, 2001.
[50] L. Margolin and P. K. Smolarkievicz. Antidiffusive velocities for multipass donor cell advection.
SIAM J. Sci. Comput., pages 907–929, 1998.
[51] John D. McCalpin. A comparison of second-order and fourth-order pressure gradient algo-
rithms in a σ-coordinate ocean model. Int. J. Num. Meth. Fluids, 18:361–383, 1994.
155
[52] R. Mechlenburg. Managing Projects with GNU Make. O’Reilly & Associates, Inc., Sebastopol,
CA, 2005.
[53] G. L. Mellor. The three-dimensional current and surface wave equations. J. Phys. Oceanogr.,
33:1978–1989, 2003.
[54] G. L. Mellor. Some consequences of the three-dimensional currents and surface wave equation.
J. Phys. Oceanogr., 35:2291–2298, 2005.
[55] G. L. Mellor and L. Kantha. An ice-ocean coupled model. J. Geophys. Res., 94:10,937–10,954,
1989.
[56] G. L. Mellor and T. Yamada. A hierarchy of turbulence closure models for planetary boundary
layers. J. Atmos. Sci., 31:1791–1806, 1974.
[57] G. L. Mellor and T. Yamada. Development of a turbulence closure model for geophysical fluid
problems. Rev. Geophys. Space Phys., 20:851–875, 1982.
[58] W. A. Oost, G. J. Komen, C. M. J. Jacobs, and C. van Oort. New evidence for a relation
between wind stress and wave age from measurements during asgamage. Bound.-Layer Meteor.,
103:409–438, 2002.
[59] I. Orlanski. A simple boundary condition for unbounded hyperbolic flows. J. Comp. Phys.,
21(3):251–269, July 1976.
[60] C. L. Parkinson and W. M. Washington. A large-scale numerical model of sea ice. J. Geophys.
Res., 84:6565–6575, 1979.
[63] N. A. Phillips. A coordinate system having some special advantages for numerical forecasting.
J. Meteorology, 14(2):184–185, 1957.
[67] W. H. Raymond and H. L. Kuo. A radiation boundary condition for multi-dimensional flows.
Quart. J. R. Met. Soc., 110:535–551, 1984.
[68] R. Rew, G. Davis, S. Emmerson, and H. Davies. NetCDF User’s Guide. Unidata, University
Corporation for Atmospheric Research, Boulder, Colorado, 1996. Version 2.4.
156
[69] R. Sadourny and K. Maynard. Formulations of lateral diffusion in geophysical fluid dynamics
models. In C.A. Lin, R. Laprise, and H. Ritchie, editors, Numerical Methods of Atmospheric
and Oceanic Modelling, pages 547–556. NRC Research Press, 1997.
[70] A. J. Semtner, Jr. A model for the thermodynamic growth of sea ice in numerical investigations
of climate. J. Phys. Oceanogr., 6:379–389, 1976.
[73] A. F. Shchepetkin and J. C. McWilliams. The regional ocean modeling system (roms): A
split-explicit, free-surface, topography-following coordinates oceanic model. Ocean Modeling,
9:347–404, 2005.
[74] A. F. Shchepetkin and J. C. McWilliams. A correction note for “ocean forecasting in terrain-
following coordinates: formulation and skill assessment of the regional ocean modeling system”.
Ocean Modeling, 2008. submitted.
[76] J. Smagorinsky. General circulation experiments with the primitive equations. i. the basic
experiment. Mon. Wea. Rev., 91:99–164, 1963.
[78] Y. Song. A general pressure gradient formulation for ocean models. part i: Scheme design and
diagnostic analysis. Mon. Wea. Rev., 126:3213–3230, 1998.
[79] Y. Song and D. B. Haidvogel. A semi-implicit ocean circulation model using a generalized
topography-following coordinate system. J. Comp. Phys., 115(1):228–244, 1994.
[80] M. Steele, G. L. Mellor, and M. G. McPhee. Role of the molecular sublayer in the melting or
freezing of sea ice. J. Phys. Oceanogr., 19:139–147, 1989.
[81] Travis Swicegood. Pragmatic Version Control Using Git. Pragmatic Bookshelf, Raleigh, North
Carolina and Dallas, Texas, first edition, 2008.
[82] P. K. Taylor and M. A. Yelland. The dependence of sea surface roughness on the height and
steepness of the waves. J. Phys. Oceanogr., 31:572–590, 2001.
[84] I. B. Troen and L. Mahrt. A simple model of the atmospheric boundary layer; sensitivity to
surface evaporation. Boundary-Layer Meteor., 37:129–148, 1986.
[85] L. Umlauf and H. Burchard. A generic length-scale equation for geophysical turbulence models.
J. Marine Res., 61:235–265, 2001.
157
[86] R. C. Wajsowicz. A consistent formulation of the anisotropic stress tensor for use in models
of the large-scale ocean circulation. J. Comp. Phys., 105:333–338, 1993.
[88] D. J. Webb, B. A. De Cuevas, and C. S. Richmond. Improved advection schemes for ocean
models. J. Atmos. Ocean. Tech., 15:1171–1187, 1998.
[89] J. Wilkin and K. Hedstrom. User’s manual for an orthogonal curvilinear grid-generation
package. Institute for Naval Oceanography, 1991.
158
The Department of the Interior Mission
As the Nation's principal conservation agency, the Department of the Interior has responsibility for most
of our nationally owned public lands and natural resources. This includes fostering sound use of our land
and water resources; protecting our fish, wildlife, and biological diversity; preserving the environmental
and cultural values of our national parks and historical places; and providing for the enjoyment of life
through outdoor recreation. The Department assesses our energy and mineral resources and works to
ensure that their development is in the best interests of all our people by encouraging stewardship and
citizen participation in their care. The Department also has a major responsibility for American Indian
reservation communities and for people who live in island territories under U.S. administration.
Moreover, in working to meet its responsibilities, the Offshore Minerals Management Program
administers the OCS competitive leasing program and oversees the safe and environmentally sound
exploration and production of our Nation's offshore natural gas, oil and other mineral resources. The
MMS Minerals Revenue Management Program meets its responsibilities by ensuring the efficient,
timely and accurate collection and disbursement of revenue from mineral leasing and production due to
Indian tribes and allottees, States and the U.S. Treasury.
The MMS strives to fulfill its responsibilities through the general guiding principles of: (1) being
responsive to the public's concerns and interests by maintaining a dialogue with all potentially affected
parties and (2) carrying out its programs with an emphasis on working to enhance the quality of life for
all Americans by lending MMS assistance and expertise to economic development and environmental
protection.