MOM6
A new ocean component model based on the Modular Ocean Model version 6 (MOM6) has been incorporated into CESM and is anticipated to replace POP2 as the default ocean component in CESM3. An early functional release of the MOM6 ocean component has been made available to users beginning with CESM2.2. Instructions for using MOM6 in CESM are available on the MOM_interface GitHub Wiki.
This DART-MOM6 interface was developed for MOM6 within the CESM framework.
MOM6 time
The default in CESM is to run with no leap years. To assimilate real observations, we need to switch to the Gregorian calendar to account for leap years.
./xmlchange CALENDAR=GREGORIAN
To illustrate what happens if you do not set CALENDAR=GREGORIAN, here is an example where the RUN_STARTDATE is set to 2015-02-01 and MOM6 is run for 10 days.
./xmlchange RUN_STARTDATE=2015-02-01
The MOM6 restart file has the following meta data, where Time is days from year 1.
double Time(Time) ;
Time:long_name = "Time" ;
Time:units = "days" ;
Time:axis = "T" ;
...
// global attributes:
:filename = "./c.T62_g16.ens3.mom6.r.2015-02-11-00000._0001.nc" ;
data:
Time = 735151 ;
}
The absence of leap years gives you inconsistent time information when comparing to observation times in YYYY-MM-DD:
Restart filename has the time 2015-02-11-00000.
The Time variable is Time = 735151 days, which is 2013/10/11
MOM6 checksum of restart files
When reading in restart files, MOM6 verifies a checksum for each variable
in the restart file. Data assimilation updates the data in the MOM6 restart file,
which will cause the checksum verification to fail. To use DART-MOM6 with CESM
turn off the checksum verification using the user_nml_mom
namelist option:
RESTART_CHECKSUMS_REQUIRED = False
model_nml
The namelist options for DART-MOM6 are as follows:
&model_nml
template_file = 'mom6.r.nc',
ocean_geometry = 'ocean_geometry.nc',
static_file = 'c.e22.GMOM.T62_g16.nuopc.001.mom6.static.nc',
model_state_variables = 'Salt ', 'QTY_SALINITY ', 'UPDATE',
'Temp ', 'QTY_POTENTIAL_TEMPERATURE', 'UPDATE',
'u ', 'QTY_U_CURRENT_COMPONENT ', 'UPDATE',
'v ', 'QTY_V_CURRENT_COMPONENT ', 'UPDATE',
'h ', 'QTY_LAYER_THICKNESS ', 'UPDATE',
assimilation_period_days = 1
assimilation_period_seconds = 1
/
template_file
is a MOM6 restart file. The size and shape of the state variables will be read from this netCDF file.ocean_geometry
is a MOM6 netCDF file containing the variablesD
, the basin depth in meters; andwet
, whether a point is land or ocean at the Earth’s surface.static_file
is a MOM6 netCDF file containing the grid information. The following three grids are read into DART:geolon(:,:) Longitude of tracer (T) points geolat(:,:) Latitude of tracer (T) points geolon_u(:,:) Longitude of zonal velocity (Cu) points geolat_u(:,:) Latitude of zonal velocity (Cu) points geolon_v(:,:) Longitude of meridional velocity (Cv) points geolat_v(:,:) Latitude of meridional velocity (Cv) point
Vertical Coordinate
The vertical coordinate in MOM6 is layer thickness which varies across the ensemble. To get the depth in meters at a particular layer, you must sum the layer thicknesses.
double h(Time, Layer, lath, lonh) ;
h:long_name = "Layer Thickness" ;
h:units = "m" ;
Land in the state
The MOM6 grid is global, so land is included in the state. To avoid updating land,
get_close_state
forces the distance to be very large for dry land and locations
below the sea floor.
Identifying land/ocean points at the surface can be simply done using the the longitude, latitude
of the given point. get_state_meta_data
is used to assign land points at the surface QTY_DRY_LAND.
The process to identify points below the sea floor requires the vertical location of the
point in meters. The conversion from model layer to depth in meters is done in
convert_vertical_state
. The depth is then used to identify points below the
basin depth in get_close_state
.
! Put any land or sea floor points very far away
! so they are not updated by assimilation
do ii = 1, num_close
if(loc_qtys(close_ind(ii)) == QTY_DRY_LAND) dist = 1.0e9_r8
lon_lat_vert = get_location(locs(close_ind(ii))) ! assuming VERTISHEIGHT
call get_model_variable_indices(loc_indx(ii), i, j, k)
if ( below_sea_floor(i,j,lon_lat_vert(3)) ) dist = 1.0e9_r8
enddo