COD Class Examples

From WikiROMS
Jump to navigationJump to search
ROMS examples for Coastal Ocean Dynamics

Introduction

The page describes idealized configurations of ROMS that are used in Rutgers course 16:712:503 Coastal Ocean Dynamics to illustrate various aspects of ocean dynamics studied in lectures.

Obtaining the source code for examples

In almost all instances the ROMS files that have been customized for these examples are on the Rutgers OARC Amarel cluster amarel.rutgers.edu in directory /projects/dmcs_1/courses/cod. Users must be a member of UNIX group dmcs_1 to access these files.

To get started, copy all the files in /projects/dmcs_1/courses/cod to the working directory where you are locally compiling and running ROMS>. This is the directory where you ran the UPWELLING test case.

Verify you are in your working directory with

pwd

Then copy the .h and .in files with commands like this:

cp /projects/dmcs_1/courses/cod/*.h .
cp /projects/dmcs_1/courses/cod/*.in .

The * is the wildcard for all files in /projects/dmcs_1/courses/cod, and the dot . signifies that the target directory is the directory you are in.

Later in the class some of these files will be updated, and new files added, and when you copy them you will want to be more selective than using the * wildcard if you don't want to overwrite files you have modified for your own work.

What are these files?

cod_*.h files

Each class example has its own cod_*.h file that will be activated to control compilation by setting ROMS_APPLICATION in your personal build_roms.sh script. For example, for COD_1DMIX, you will edit build_roms.sh to set:

export ROMS_APPLICATION=COD_1DMIX

instead of the case UPWELLING that you had when you first ran ROMS.

Once you have copied the cod_*.h file to your working directory, and modified build_roms.sh, recompile by running the build script as you did before, e.g.

./build_roms.sh -j 4

This will create a new romsM executable file to run the COD example.

ana_*.h files

The analytical files are new versions of files in the ROMS/Functionals subdirectory that you downloaded with svn that have been modified to have blocks of code for each of the class examples. The modifications are marked by C-PreProcessor (CPP) directives such as, for example:

#ifdef COD_1DMIX
...
#endif

which will cause that section of code to be compiled when option COD_1DMIX is defined.

This is the way in which we modify ROMS for our own purposes. We can safely have the code for all the COD examples in one version of each ana_*.h file because the code segments are selectively activated with CPP directives.

Some of the class examples use default settings in the analytical files and do not need special instructions.

cod_*.in files

Each class example has its own roms_cod_*.in file that ROMS will read at run-time. This is equivalent to the file roms_upwelling.in that you used when you first ran ROMS.

The job.sh script you use to submit the class examples to the SLURM scheduler with the command sbatch job.sh will have to be modified (at the srun command) to use the appropriate roms_cod*.in file. For example:

srun --mpi=pmi2 ./romsM roms_cod_1dmix.in

Configuring your working directory files

For each class example you will go through the following steps to start.

Refer back to the instructions above for guidance:

  1. Copy the necessary COD example case files to your working directory.
  2. Modify build_roms.sh to set ROMS_APPLICATION= for example COD_1DMIX
  3. Compile ROMS, i.e. run build_roms.sh
  4. Modify your job.sh script to pass the correct input file, for example roms_cod_1dmix.in, to the srun command on the last line
    Note Notice: You must also modify job.sh to request the appropriate number of ntasks and ntasks-per-node. Review the entries for NtileI and NtileJ in roms_cod_*.in file and determine the correct values to use.
  5. Submit the job to SLURM with sbatch.
  6. Check for the creation of the netcdf output files.
  7. View the output and error log files, i.e. the files named something like out.hal0007.12345678.log and err.hal0007.12345678.log to verify the run was successful, or diagnose the problem.

In these examples, certain parameters are set in roms_cod_*.in to allow you to easily vary the configuration and explore how the ocean responds by re-running the example without recompiling.

Example COD_1DMIX

Experimental design

This example has been configured as a 3x3 horizontal grid points doubly-periodic domain. The restrictive number of horizontal points and the double periodicity causes the solution to degenerate to one that can only vary in the vertical.

Review the parameters of the configuration set in roms_cod_1dmix.in in the block of code headed Generic User parameters

! Generic User parameters, [1:NUSER].

NUSER = 8
! user parameters for COD 1DMIX case

! Coriolis depth wind heat strat press tidal wave ! f h stress flux dTdz grad period dissip ! simple steady wind

USER = 0.0d-04 20.0d0 0.06d0 0.0d0 0.5d0 0.0d0 12.42d0 0.01d0

The comment header lines indicate briefly what easy USER parameter sets:

  • USER(1) = Coriolis frequency (s-1)
  • USER(2) = water depth (m)
  • USER(3) = steady surface wind stress (Pa)
  • USER(4) = surface heat flux (W m-2)
  • USER(5) = initial temperature stratification (oC m-1)
  • USER(6) = magnitude of the oscillating body force pressure gradient forcing
  • USER(7) = period of the oscillating body force pressure gradient forcing (hours)
  • USER(8) = added turbulence at the sea surface due to wave breaking

The default configuration has an initial thermal stratification and imposes a steady wind stress starting at time = 0. This causes turbulent mixing from the surface downward into the water column, working against the thermal and hence density stratification. Once the stress reaches the seafloor, bottom drag begins to drive turbulent mixing in a bottom boundary layer.

Other parameters in any roms_cod_*.in you might want to alter are:

  • NTIMES which sets the number of time steps to run for
  • Hout and Aout, etc. logical flags that control what output is written to the NetCDF files
  • GLS_* generic length-turbulence closure parameters. See the (long) GLOSSARY at the bottom of the file for guidance on how to set these for a different closure scheme.
  • HISNAME, AVGNAME, etc. which set the names of the output files

Working with 1DMIX output in a Jupyter notebook

If you are a novice user of Python and Jupyter notebooks, you might find it useful to consult some of the resources collected by the Pythia Project in the Pythia Foundations Book A community learning resource for Python-based computing in the geosciences

The xroms package greatly facilitates working with ROMS output because it interprets the coordinate information that is recorded inside ROMS NetCDF files following CF (Climate-Forecasting) and CDM (Common Data Model) metadata conventions.

You can get started with this minimal example of using xroms to plot a time versus depth ribbon of the temperature.

These are more packages than you need import at first, but they are listed here for future reference:

import xarray as xr
import numpy as np
import hvplot.xarray
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import matplotlib
%matplotlib inline
import xroms
import cmocean.cm as cmo import xcmocean

Open the NetCDF "history" file with xroms.

hfile = 'his_cod_1dmix.nc'
ds = xroms.open_netcdf(hfile)

Plot a 2-D ribbon in time versus depth of temperature, at just one i,j grid cell. It would make no difference to choose xi_rho or eta_rho index of = 0, 1 or 2.

Here, the x,y, plot coordinates are given explicitly, otherwise Python chooses to plot them the other way around, which is not very physical to an oceanographer.

ds.temp.isel(xi_rho=1,eta_rho=1).plot(x="ocean_time",y="s_rho")

This is still somewhat unsatisfactory because the vertical coordinate, s_rho, is the non-dimensional ROMS s-coordinate, whereas we want to see this in physical space, z, in meters.

If you examine the description of this DataArray for variable temp (temperature)

ds.temp.cf.describe()

you will see that xroms has created generic CF Axes X, Y, Z, T and generic CF Coordinates appropriate to the data; here, vertical and time.

Remember, ROMS uses a staggered grid such that temperature, u and v are at different coordinate locations that have different names (x_rho, x_u, x_v, etc.). xroms is making it easy for you so you don't have to use different coordinate names every time you plot a different variable.

So, you can plot like this:

ds.temp.cf.isel(X=1,Y=1).cf.plot(x="time",y="vertical")

Note Notice: To use the generic Axes X,Y there is a .cf before isel, and to use the generic Coordinates there is a .cf before plot.

If you change temp to some other variable, this should also work.

Analysis exercise

Explore the dynamics of this mixing example by plotting time series and vertical profiles of some of the output, especially the netcdf variables named:

  • temperature (temp),
  • velocity (u,v),
  • bottom stress (bustr,bvstr),
  • vertical turbulent viscosity (AKv),
  • vertical turbulent diffusivity (AKt),
  • turbulent kinetic energy (tke),
  • GLS closure length scale parameter (gls) - figure out how to get length scale from gls and tke

For example, try plotting time series of temperature at two different depths, say s_rho = 29 (the surface) and s_rho = 18.

You should see the curves approach each other and become identical.

Plot time series also for velocity u and viscosity AKv. What's going on? What is the cause of the sudden, brief increase in eddy viscosity.

Plot sustr and bustr versus time.. Notice that they reach an equal and opposite equilibrium when the solution becomes steady, i.e. not changing in time.

An example iPython notebook that makes these sorts of plots, and demonstrates some of the features of xroms, is on Amarel in /projects/dmcs_1/courses/cod named plot_1dmix_steady.ipynb which you can copy to your working directory, edit, and experiment with.

More features of xroms

To advance beyond simply plotting ROMS output to dynamical analysis, xroms provides many built-in functions for computing derivatives and integrals, and mapping variables between the staggered vertical grid coordinates.

For a list of the features, run this in your notebook:

help(xroms.utilities)

For example, you can compute vertical derivatives of ROMS outputs using xroms.ddz. To do this you need to obtain, for the variable you wish to differentiate, its grid object that describes its coordinates. For example, vertical shear in velocity would be:

utmp = ds.u
ugrid = utmp.attrs["grid"]
dudz = xroms.ddz(utmp,ugrid)
ds["dudz"] = dudz
ds.dudz.cf.isel(X=1,Y=1).cmo.cfpcolormesh(x="time",y="vertical")

Read more about xroms capabilities by browsing the examples at https://github.com/xoceanmodel/xroms/tree/master/examples


Example COD_HUNTER_ESTUARY

Experimental design

This example is designed to simulate tidal variability in a simple version of a funnel shaped estuary. The estuary is triangular in width, with depth that shallows linearly from 20 m the mouth to 5 m at the head along the thalweg, which is the name given to the line of local maximum depth along the estuary axis. There are shallow flanks along the coast on either side of the thalweg, and there a simple continental shelf at the open ocean.

The model grid was designed by Eli Hunter, and has 128 by 32 points in the horizontal. The grid coordinates, bottom depth and land/sea mask are set in a netcdf grid file

The open ocean boundary conditions are radiation on temperature and salinity on all 3 boundaries. The velocity is periodic in the north-south direction. At the eastern boundary, sea level is set to vary as a simple tide with harmonics (frequency and amplitude) that are set in a netcdf tide forcing file.

The experiment starts from rest, i.e. u = v = zeta = 0. The initial temperature and salinity are uniform based on values set in the roms_cod_hunter_estuary.in file.

Since this grid is much larger than the previous 1D example, it will be desirable to run this in parallel using multiple cores on the Amarel cluster.

Getting the files

As for the previous COD_1DMIX example, you need a set of configuration files. These are:

  • cod_hunter_estuary.h which sets the compile time ROMS code options
  • roms_cod_hunter_estuary.in which sets the run time parameters
  • hunter_estuary_regular_grid.nc (the grid file)
  • hunter_estuary_tides.nc (the boundary tidal forcing harmonics file)

Copy these files from /projects/dmcs_1/courses/cod to your working directory.

To run this example you need to follow similar steps to the COD_1DMIX example:

  1. In build_roms.sh, set the ROMS_APPLICATION to COD_HUNTER_ESTUARY
  2. Compile ROMS using the build script
  3. Note the NtileI and NtileJ values in roms_cod_hunter_estuary.in and edit your SLURM script, i.e. the job.sh file, accordingly
  4. Modify the srun command in job.sh to use the correct roms.in file
  5. Run the model

As configured, this run takes about 3 minutes on 16 cores. If several students are running this at once, you may find the job waits for available resources before starting. You can monitor the status of your job in the queue with the squeue command.

To explore the role of estuary length in tidal response, there are two further grid files:

  • hunter_estuary_long_grid.nc
  • hunter_estuary_short_grid.nc

These have estuary lengths that are, respectively, twice and half the length of the regular grid.

To run this model with these alternative grids, you need to modify the input parameter GRDNAME in roms_cod_hunter_estuary.in.

Example COD_CTW

Experimental design

This example sets up ROMS to illustrate the response, in the form of Coastal Trapped Waves, of a coastal ocean to an along-shelf wind that blows for a few days in an isolated along-shelf band. Once the winds cease, the waves generated disperse at their inherent free CTW speeds and spatial patterns.

The model bathymetry is the simple exponentially increasing depth profile presented in class following the pioneering work of Buchwald and Adams (1968). The domain is a long periodic channel, so eventually the CTWs generated by the wind exit from one end and re-enter the domain, so keep that in mind in any interpretation of what is going on.

You can discover the particular configuration choices for this case by searching the analytical functionals (files ana_*.h) for the C-preprocessor (CPP) option COD_CTW. You can do this using the UNIX grep command.

grep COD_CTW ana*.h

This will list the files that have customized code for this case. You can then use UNIX commands more (or less) or the nano editor to browse the code if you want to see what goes into configuring ROMS. It's not required you do this, but if what we've been doing is too much of a black box for you this might be of interest. For example, you will see in ana_grid.h how the bathymetry is set, and in ana_smflux.h how the wind stress is switched on and off, and where spatially in the domain the stress is applied.

Getting the Files

From the /projects/dmcs_1/courses/cod folder you need to copy across the files cod_ctw.h and roms_cod_ctw.in.

Configuring the Example

The CPP option that activates this example is COD_CTW. Hopefully, by now, you have a pretty good idea of the steps to follow to instruct build_roms.sh to compile this example.

So, do that, and compile the model.

Next, modify or create a job.sh file to run this example. Remember what you have to check to match up the number of compute cores requested to the number of tiles in roms_cod_ctw.in.

Run the model.

You should have output files named *_ctw.nc

Modifying the CTW input parameters

The configuration parameters that can be adjusted in this example are set, as always, by the USER options in the roms_cod_ctw.in file. Here, these are:

! COD_CTW user parameters
      NUSER =  9

! Coriolis lambdaL L null dTdz dims (km) xwind ywind ! f (km) e-w n-s stress (Pa)

USER = 8.4e-5 2.7 80.0 0.0 0.00 4000.0 200.0 0.03 0.0

User(2) is lambda*L in the Buchwald and Adams (1968) idealized CTW problem presented in lectures.

User(3) is L, the shelf width in km. The code in ana_grid.h adjusts the minimum depth so that lambdaL changes both the width and steepness of shelf to match a uniform depth open ocean.

User(5) will introduce temperature stratification so that we can explore the effect of this on the speed of the CTWs generated.

User(8) sets the magnitude of the along-shelf wind stress.