-
Notifications
You must be signed in to change notification settings - Fork 165
Open Boundary Conditions
The boundaries pass from q-point to q-point. Each boundary segment is specified separately in the MOM_input file as shown below. The boundary conditions for the southern and western sides only work in symmetric mode.
The boundaries can be either specified or computed based on a radiation-type condition, possibly with nudging as well. There is one grid cell of ocean outside an open boundary. It is best to have land beyond that which can be filled in by the model if you use the MASK_OUTSIDE_OBCS option.
For setting up regional domains of MOM6, the regional-mom6 package by COSIMA is a good resource, especially the demo cases included there can be useful.
There was a "Flather" option for each of the four sides of the domain, which applied boundary conditions to the flow normal to the corresponding side. It applied these conditions to both the baroclinic and barotropic velocities, Orlanski and Flather, respectively. It is no longer available, however picking the "FLATHER, ORLANSKI" options is meant to reproduce the old answers.

Segments are a means of specifying pieces of open boundary, each being aligned with the i- or j-axis. We now support convex interior corners such as would be required by converting the peninsula between segment 1 and segment 2 in the figure to an open boundary.
We start by setting the number of segments:
- OBC_NUMBER_OF_SEGMENTS = 2
For each segment, there's a range of i or j at a fixed j or i. Set the fixed value first, then the range. The index order for the range will give the direction, going around the domain in a counter-clockwise direction.
Once the location of the boundary is set, determine its type. Up to eight descriptive words can be used. Some examples:
- OBC_SEGMENT_001 = "I=0,J=23:1,SIMPLE"
- OBC_SEGMENT_002 = "J=45,I=5:15,FLATHER, OBLIQUE, NUDGED"
For the I,J ranges, can use a shorthand of "N" for the northernmost or easternmost value instead of spelling out the numeric value:
- "I=N,J=5:N-2" (part of eastern boundary)
- "I=0,J=N:0" (entire western boundary)
- "I=N-2,J=N-10:N-2" (eastern boundary condition 2 rows in)
- Maybe even shorthand for the entire boundary being open? "IJ=N" (not yet)
For the whole boundary to be open, one should set:
- OBC_NUMBER_OF_SEGMENTS = 4
- OBC_SEGMENT_001 = "J=N,I=N:0,FLATHER"
- OBC_SEGMENT_002 = "J=0,I=0:N,FLATHER"
- OBC_SEGMENT_003 = "I=N,J=0:N,FLATHER"
- OBC_SEGMENT_004 = "I=0,J=N:0,FLATHER"
The order should not matter.
-
SIMPLE - the boundary values of normal velocities are specified. User-specified fields for open boundaries can be set via OBC_USER_CONFIG in MOM_input, DOME, for instance. This user code is currently the only way to provide the cross-boundary transport required for SIMPLE boundaries. Supercritical is another example.
-
SIMPLE_TAN - the boundary values of tangential velocities are specified. Does not need any user code for transports.
-
SIMPLE_GRAD - the boundary value of the normal gradient of tangential flow is specified.
-
GRADIENT - zero gradient of all fields near the boundary.
-
FLATHER - a radiation boundary condition on the barotropic flow which attempts to comply with exterior values, tidal or otherwise.
-
ORLANSKI - a radiation boundary condition on the baroclinic flow.
-
OBLIQUE - a radiation boundary condition for baroclinic flows using oblique phase speeds (Raymond and Kuo, 1984).
-
NUDGED - a modifier on the radiation conditions (ORLANSKI and OBLIQUE) to nudge to exterior velocity values.
-
ORLANSKI_TAN - a radiation boundary condition for the baroclinic flow tangential to the boundary.
-
NUDGED_TAN - a modifier on the radiation condition to nudge tangential flow to exterior velocity values.
-
ORLANSKI_GRAD - a radiation boundary condition for dvdx or dudy, contributing to the vorticity and strain computations.
-
NUDGED_GRAD - a modifier on the radiation condition to nudge dvdx or dudy to external values.
The above list is subject to change.
Note that FLATHER and NUDGED imply the need for boundary values, barotropic and baroclinic, respectively (SIMPLE is both baroclinic and barotropic). These can either come from an internal configuration using the "user" directory, from a set value in MOM_input, or from an external file.
- OBC_SEGMENT_001_DATA = “TEMP=file:xyz_%y.nc(theta),SALT=...”
- OBC_SEGMENT_003_DATA = "U=value:0.0,V=value:0.0,SSH=value:0.0
For the first example, the value in parentheses is the name of the variable in the file. Values of 0.0 on the boundary for U, V and SSH are the default. The dimensions of the variables in the file have to be in a certain order, namely
- time, vertical dimension, horizontal dimension 1, horizontal dimension 2.
For the sea surface height field, the vertical dimension does not apply. Note that for all variables (apart from sea surface height) a layer thickness variable dz_<variable_name>_segment_<00n> also has to be included in the file. Their dimensions have to be vertical dimension, horizontal dimension 1, horizontal dimension 2.
Boundary values can also come from user code, for example:
- OBC_USER_CONFIG = "dyed_obcs"
Note that setting an OBC_USER_CONFIG is a promise to handle all boundary values and cannot be used with OBC_SEGMENT_XXX_DATA unless the user code parses the OBC_SEGMENT_XXX_DATA strings. However, "dyed_obcs" are a special case and can be used with these DATA strings.
As for tracers, those can come from tracer code:
- USE_DYED_OBC_TRACER = True
- NUM_DYE_TRACERS = 3
OBCs on tangential velocities are applied via choices to the vorticity and strain boundary condition. These options are available globally. Set at most one of these:
- OBC_ZERO_VORTICITY = True
- OBC_FREESLIP_VORTICITY = True
- OBC_COMPUTED_VORTICITY = True ! Uses external tangential flow.
- OBC_SPECIFIED_VORTICITY = True ! Uses external dvdx or dudy.
Also, at most one of these:
- OBC_ZERO_STRAIN = True
- OBC_FREESLIP_STRAIN = True
- OBC_COMPUTED_STRAIN = True ! Uses external tangential flow.
- OBC_SPECIFIED_STRAIN = True ! Uses external dvdx or dudy.
When using biharmonic viscosity, you probably also want this:
- OBC_ZERO_BIHARMONIC = True
The gradient of kinetic energy is also set to zero across open boundaries.
For complicated domains with interior open boundaries, you can ask for help in masking the outside grid cells:
- MASK_OUTSIDE_OBCS
When using this option, MOM6 will compute the mask two ways and if they don't agree, it will die with an error message. This is a sanity check on the consistency of the boundary segments.
We are still investigating how best to set these:
- OBC_TRACER_RESERVOIR_LENGTH_SCALE_OUT = 1.0e3 ! [m] default = 0.0
- OBC_TRACER_RESERVOIR_LENGTH_SCALE_IN = 1.0e3 ! [m] default = 0.0
- OBC_SEGMENT_001_VELOCITY_NUDGING_TIMESCALES = 3, 360 ! [days]
Note that the reservoir lengths apply globally while the nudging timescales are per segment. The latter have two values, for inflow and outflow, where the inflow/outflow choice is based on a local phase speed. The tracer inflow/outflow choice is based on a local velocity.
By default, there is time filtering of the radiation phase speed set with the OBC_RAD_VEL_WT option. The default of 0.3 uses 0.3 of the current time's estimate and the rest from a running mean. Setting this to 1.0 turns off the filtering. With the filtering, the tangential velocity and/or its gradient use the phase speed of the normal velocity, while turning off the filtering allows them to compute their own phase speeds. We will be evaluating these options to see what works best, perhaps obsoleting inferior options.
If a domain is reentrant, there is a potential need for boundary segments to exist in the reentrant halo. It is possible to specify the end-point indices to extend into the reentrant halo up to ten grid points, but only parallel to the reentrant direction. For instance, a domain that's reentrant in x can have segments at fixed J with I indices extending beyond 0 to N. In fact, the user must extend the segments for a truly reentrant domain with a full-length open boundary.
One can now add tides to an open boundary, documented in the PR adding tides. MOM6 can internally compute the tides you ask for. A specification involving the eight major constituents as well as two long-period tides is as follows:
OBC_SEGMENT_001 = "J=N,I=N:0,FLATHER,ORLANSKI"
OBC_SEGMENT_002 = "J=0,I=0:N,FLATHER,ORLANSKI"
OBC_SEGMENT_003 = "I=N,J=0:N,FLATHER,ORLANSKI"
OBC_SEGMENT_004 = "I=0,J=N:0,FLATHER,ORLANSKI"
OBC_TIDE_N_CONSTITUENTS = 10
OBC_TIDE_CONSTITUENTS = "M2,S2,N2,K2,K1,O1,P1,Q1,MF,MM"
OBC_SEGMENT_001_DATA = "U=value:0.0,V=value:0.0,SSH=value:0.0,Uamp=file:tides_obc.nc(uamp),Uphase=file:tides_obc.nc(uphase),Vamp=file:tides_obc.nc(vamp),Vphase=file:tides_obc.nc(vphase),SSHamp=file:tides_obc.nc(zamp),SSHphase=file:tides_obc.nc(zphase)"
OBC_SEGMENT_002_DATA = "U=value:0.0,V=value:0.0,SSH=value:0.0,Uamp=file:tides_obc.nc(uamp),Uphase=file:tides_obc.nc(uphase),Vamp=file:tides_obc.nc(vamp),Vphase=file:tides_obc.nc(vphase),SSHamp=file:tides_obc.nc(zamp),SSHphase=file:tides_obc.nc(zphase)"
OBC_SEGMENT_003_DATA = "U=value:0.0,V=value:0.0,SSH=value:0.0,Uamp=file:tides_obc.nc(uamp),Uphase=file:tides_obc.nc(uphase),Vamp=file:tides_obc.nc(vamp),Vphase=file:tides_obc.nc(vphase),SSHamp=file:tides_obc.nc(zamp),SSHphase=file:tides_obc.nc(zphase)"
OBC_SEGMENT_004_DATA = "U=value:0.0,V=value:0.0,SSH=value:0.0,Uamp=file:tides_obc.nc(uamp),Uphase=file:tides_obc.nc(uphase),Vamp=file:tides_obc.nc(vamp),Vphase=file:tides_obc.nc(vphase),SSHamp=file:tides_obc.nc(zamp),SSHphase=file:tides_obc.nc(zphase)"
BRUSHCUTTER_MODE = True
This is independent of and in addition to the body force tides which were developed for the global model. It can make sense to specify both kinds of tidal forcing for regional domains.
This setting expects a netCDF file tides_obc.nc in the input directory. It has to contain the relevant information in a specific format:
- The first dimension has to be the time (even if tidal amplitudes and phases are constant over time).
- The second dimenstion has to be the tidal constituent. Its length has to be identical to OBC_TIDE_N_CONSTITUENTS and the order of the constituents has to be identical to what is given by OBC_TIDE_CONSTITUENTS.
- The third and fourth dimensions are the spatial dimensions.
- The variables have to be named uamp_segment_001, uamp_segment_002, ..., uphase_segment_001, uphase_segment_002, ..., etc.
- For tides it is recommended to use
BRUSHCUTTER_MODE = True, which means that the OBCs are expected on the supergrid (see here for the MOM6 grid convention).
This output of ncdump helps in understanding how a tidal OBC file has to look like for a grid with 1000 x 1000 grid points (only containing the forcing for uamp, the forcing for the other variables has to provided with the same dimensions):
netcdf init {
dimensions:
layer = 75 ;
latitude = 1000 ;
longitude = 1000 ;
latitude_super = 2001 ;
longitude_super = 2001 ;
time = UNLIMITED ; // (2 currently)
constituent = 10 ;
single_point = 1 ;
variables:
double time(time) ;
time:long_name = "julian day (UT)" ;
time:calendar = "julian" ;
time:units = "days since 1990-01-01 00:00:00" ;
time:field = "time, scalar, series" ;
time:conventions = "relative julian days with decimal part (as parts of the day )" ;
time:axis = "T" ;
double latitude(latitude) ;
latitude:units = "degrees_north" ;
latitude:long_name = "latitude" ;
double longitude(longitude) ;
longitude:units = "degrees_east" ;
longitude:long_name = "longitude" ;
double latitude_super(latitude_super) ;
latitude_super:units = "degrees_north" ;
latitude_super:long_name = "latitude_super" ;
double longitude_super(longitude_super) ;
longitude_super:units = "degrees_east" ;
longitude_super:long_name = "longitude_super" ;
double uamp_segment_001(time, constituent, single_point, longitude_super) ;
uamp_segment_001:_FillValue = 2147483647. ;
uamp_segment_001:units = "m s-1" ;
uamp_segment_001:long_name = "eastward_current_tidal_amplitude" ;
double uamp_segment_002(time, constituent, single_point, longitude_super) ;
uamp_segment_002:_FillValue = 2147483647. ;
uamp_segment_002:units = "m s-1" ;
uamp_segment_002:long_name = "eastward_current_tidal_amplitude" ;
double uamp_segment_003(time, constituent, latitude_super, single_point) ;
uamp_segment_003:_FillValue = 2147483647. ;
uamp_segment_003:units = "m s-1" ;
uamp_segment_003:long_name = "eastward_current_tidal_amplitude" ;
double uamp_segment_004(time, constituent, latitude_super, single_point) ;
uamp_segment_004:_FillValue = 2147483647. ;
uamp_segment_004:units = "m s-1" ;
uamp_segment_004:long_name = "eastward_current_tidal_amplitude" ;
}
It is also possible to use separate netCDF files for the different OBC segments.
More on the tides from Andrew Ross (independent of OBCs):
TIDE_NODAL_REF_DATE should be updated every year or so as the model goes forward.
TIDE_REF_DATE should not need to be changed as the model runs. It should just be a date within ~100 years of your model run to make the tide calculations more accurate. I pick January 1 on the very first year of the full model run, as you currently have. To get accurate tidal forcing you also need TIDE_USE_EQ_PHASE = True.
You shouldn't need to change TIDE_REF_DATE as the mode runs either, but what you set it to depends on how the phases in your tidal boundary conditions are defined:
- If the phase is a lag relative to the equilibrium tide at 0° longitude, you should set TIDE_USE_EQ_PHASE = True (this adds a calculation of the phase of the equilibrium tide at 0°) and set TIDE_REF_DATE to a date sometime close to your model run (I also pick the first January 1).
- If the phase is a lag relative to a local model time, you should set TIDE_USE_EQ_PHASE = False and set TIDE_REF_DATE to the local time.
I believe the first of these is the default, while the second happens via tracer and/or user code instead.
- OBC_SEGMENT_002_DATA = “SALT=IC”
- or OBC_SEGMENT_002_DATA = “TEMP=DOME”
To run with MERGED_CONTINUITY in SIS2, the ice-ocean stresses will be wrong if MOM_input and SIS_input differ in where the open boundaries are located. This is still very much a work in progress, but this works for now:
- OBC_NUMBER_OF_SEGMENTS = 4
- OBC_SEGMENT_001 = "J=N,I=N:0,FLATHER"
- OBC_SEGMENT_002 = "J=0,I=0:N,FLATHER"
- OBC_SEGMENT_003 = "I=N,J=0:N,FLATHER"
- OBC_SEGMENT_004 = "I=0,J=N:0,FLATHER"
More to come...