ocean_cavity_dyn_config_t Derived Type

type, public :: ocean_cavity_dyn_config_t

Static ice-shelf cavity GEOMETRY (&ocean_cavity_dyn_nml, Phase 5.1). A prescribed, time-constant ice draft z_draft(i,j) (m, positive DOWN — the depth of the ice base below z = 0) is laid over the bed and absorbed into the barotropic DATUM:

bt_H_ref = b - z_draft      (was: bt_H_ref = b)

so the column starts with bt_eta = sum(h_layer) - bt_H_ref = 0 under the shelf and every consumer of the water-column thickness D = bt_H_ref + bt_eta is correct without its own cavity branch. This is Losch (2008) §2.1’s convention verbatim (“the ‘sea-surface height’ eta is the deviation from the ‘reference’ ice-shelf draft h”), not a divergence from it.

The isostatic load p_ice_ref = rho_ref*GRAVITY*z_draft (Pa) is built at configure and assembled into the top-of-column pressure

ms%p_top = metrics%p_ice_ref + sf%p_surf

whose consumers are the FV_MOM6 surface BC (&ocean_pgf_nml p_top_in_bc, REQUIRED unless the draft is uniform) and the in-situ EOS pressure (&ocean_psurf_nml in_eos). The load is deliberately NOT added to sf%p_surf: the datum bt_H_ref = b - z_draft already carries its whole barotropic effect, and eta_ib is built from the assembled sf%p_surf, so only the load ANOMALY belongs on that seam.

enable = .false. (default) keeps z_draft at its (1,1) placeholder, bt_H_ref = b, and every path bit-identical. Knob table: docs/generated_nml_knobs.md.


Inherited by

type~~ocean_cavity_dyn_config_t~~InheritedByGraph type~ocean_cavity_dyn_config_t ocean_cavity_dyn_config_t type~ocean_config_t ocean_config_t type~ocean_config_t->type~ocean_cavity_dyn_config_t cavity_dyn type~config_t config_t type~config_t->type~ocean_config_t ocean type~ocean_handle_t ocean_handle_t type~ocean_handle_t->type~config_t cfg

Components

Type Visibility Attributes Name Initial
character(len=32), public :: draft_config = "none"

Analytic draft shape. "none" (default): z_draft = 0 everywhere — the identity, even with enable = .true.. "flat": uniform draft_depth inside the shelf box [draft_x0, draft_x1] x [draft_y0, draft_y1], 0 outside (the open ocean beyond the calving front at draft_x1). "linear": z_draft = draft_depth + draft_slope*(x - draft_x0) inside the same box, clipped at 0 below. "file": a static 2-D NetCDF draft — NOT implemented (fails loud); the MPI-correct static-2-D reader is a later slice, and it is the only route to an ISOMIP+ draft, which has no analytic form (Asay-Davis et al. 2016 §3.1.1).

real(kind=wp), public :: draft_depth = 0.0_wp

Draft amplitude (m, positive down) — the uniform value for "flat", the value at draft_x0 for "linear". Under draft_source = "thickness" it is an ice THICKNESS instead.

character(len=256), public :: draft_file = ""

draft_config="file": path to the NetCDF carrying the static ice draft. The variable named by draft_var must be rank 3 in FORTRAN storage order (x, y, t) — which is how a C or Python writer (and ncdump) spells (nTime, ny, nx) — with a time coordinate variable; RECORD 1 is read and the field is never re-read. There is NO horizontal interpolation: the file must already be on the model grid (nx x ny physical cells), exactly as bathymetry_file and &ocean_zinit_nml file require. Single rank only (fail-loud otherwise).

character(len=16), public :: draft_sign = "depth"

draft_config="file": the SIGN CONVENTION of the file values. There is no default that guesses from the data — the two conventions differ by the whole ice load, and a field that is partly open water (zeros) is indistinguishable by inspection.

  • "depth" / "positive_down" (default) — the values ARE the ice-base depth, >= 0, Roundabout’s own convention.
  • "elevation" / "positive_up" — the values are the ice-base ELEVATION z_d, <= 0 under a floating shelf. Negated on load. This is what the ISOMIP+ geometry file needs: its iceDraft is “the elevation of the ice-ocean interface (z_d)”.

A file in the wrong convention produces a negative depth and is caught fail-loud by the existing non-negativity check, not silently accepted.

real(kind=wp), public :: draft_slope = 0.0_wp

"linear" only: d(draft)/dx, dimensionless (m of draft per m of x). Positive deepens the ice base toward +x. Converted from metres to GRID units at the dispatch (metres on a Cartesian grid, degrees on spherical/curvilinear), the same way &ocean_topo_nml slope_scale is.

character(len=32), public :: draft_source = "draft"

What the draft is prescribed FROM. "draft" (default): the geometry above IS the ice-base depth. "thickness": the formula gives an ice THICKNESS, converted by the Boussinesq-isostatic (flotation) relation z_draft = rho_ice*h_ice/rho_0. "in_situ" (true isostasy, p_ice = g*integral(rho_hat)) needs a per-column root find, does not admit exact discrete rest, and is deliberately NOT implemented (fails loud).

character(len=64), public :: draft_var = "iceDraft"

draft_config="file": name of the 2-D variable to read. The default is the ISOMIP+ geometry file’s own spelling (Asay-Davis et al. 2016 Sect. 3.3).

real(kind=wp), public :: draft_x0 = -1.0e30_wp

Western edge of the shelf box (m, GLOBAL physical coordinate), and the ANCHOR of the "linear" profile (draft_depth is the draft AT draft_x0), which is why "linear" requires a finite value here. The default +/-1e30 on all four bounds is the “no limit on this side” sentinel: the shelf then covers the whole domain INCLUDING the ghost band, which is what a shelf that reaches a wall needs (a box stopping at x = 0 puts a phantom calving front one cell outside the west wall).

real(kind=wp), public :: draft_x1 = 1.0e30_wp

Eastern edge of the shelf box = the CALVING FRONT (m): beyond it the draft is 0 (open ocean). Default: no eastern limit.

real(kind=wp), public :: draft_y0 = -1.0e30_wp

Southern edge of the shelf box (m). Default: no limit.

real(kind=wp), public :: draft_y1 = 1.0e30_wp

Northern edge of the shelf box (m). Default: no limit.

logical, public :: enable = .false.

Master switch. Requires the ocean multilayer path, the split solver, &ocean_pgf_nml form="fv_mom6", vcoord_type in {sigma, zstar} and a single rank; mutually exclusive with wet/dry, porous barriers, sea ice, bt_halo > 0, tidal SAL and gfs_scale /= 1 (every one of those fails loud at configure, naming the knob and the reason).

real(kind=wp), public :: grounded_max_frac = 0.5_wp

Sanity bound: if more than this fraction of the interior columns ground, configure fails loud rather than silently running a domain that is mostly land.

real(kind=wp), public :: h_min_cavity = 10.0_wp

GROUNDING cutoff (m): a column whose water thickness b - z_draft is below this is LAND — it goes through the same seed_wet_mask_impl the bathymetry uses, so the static metric-zeroing land mask and the finite land-state hold for free. Never a thin film of water under grounded ice. ISOMIP+ §3.1.5 leaves the choice to the modeller and notes ~40 m (two cells) for z-level models; sigma is less restricted, hence 10 m.

real(kind=wp), public :: rho_ice = 918.0_wp

Ice density (kg/m^3), consulted ONLY by draft_source = "thickness".

logical, public :: trim_ic_for_p_surf = .false.

Trim the INITIAL column under the ice so it is at rest (MOM6 TRIM_IC_FOR_P_SURF, trim_for_ice). The load p_ice_ref = rho_ref*g*z_draft is the displaced weight at the REFERENCE density; a stratified column’s displaced water weighs g*int_{-z_draft}^{0} rho dz, and the difference is a depth- uniform bottom-pressure gradient the MOM6 barotropic split (&ocean_bt_nml bc_pgf_forcing) adjusts to. With the knob on, the load is kept (the ice MASS is what is prescribed) and each loaded column’s initial top is moved to the depth s where g*int_{-s}^{0} rho dz = p_ice_ref, i.e. an initial eta = z_draft - s (a few cm under ISOMIP+ COLD), with T/S then evaluated at the trimmed layer centres. Closed form, exact at the discrete FV interfaces: requires &ocean_eos_nml eos="linear" and &ocean_zinit_nml enable, source="linear" (the analytic profile is what defines rho above the ice base); anything else fails loud. Default off => bit-identical.


Source Code

   type :: ocean_cavity_dyn_config_t
      !! Static ice-shelf cavity GEOMETRY (`&ocean_cavity_dyn_nml`,
      !! Phase 5.1).  A prescribed, time-constant ice draft `z_draft(i,j)`
      !! (m, positive DOWN — the depth of the ice base below `z = 0`) is
      !! laid over the bed and absorbed into the barotropic DATUM:
      !!
      !!     bt_H_ref = b - z_draft      (was: bt_H_ref = b)
      !!
      !! so the column starts with `bt_eta = sum(h_layer) - bt_H_ref = 0`
      !! under the shelf and every consumer of the water-column thickness
      !! `D = bt_H_ref + bt_eta` is correct without its own cavity branch.
      !! This is Losch (2008) §2.1's convention verbatim ("the
      !! 'sea-surface height' eta is the deviation from the 'reference'
      !! ice-shelf draft h"), not a divergence from it.
      !!
      !! The isostatic load `p_ice_ref = rho_ref*GRAVITY*z_draft` (Pa) is
      !! built at configure and assembled into the top-of-column pressure
      !!
      !!     ms%p_top = metrics%p_ice_ref + sf%p_surf
      !!
      !! whose consumers are the FV_MOM6 surface BC
      !! (`&ocean_pgf_nml p_top_in_bc`, REQUIRED unless the draft is
      !! uniform) and the in-situ EOS pressure (`&ocean_psurf_nml
      !! in_eos`).  The load is deliberately NOT added to `sf%p_surf`:
      !! the datum `bt_H_ref = b - z_draft` already carries its whole
      !! barotropic effect, and `eta_ib` is built from the assembled
      !! `sf%p_surf`, so only the load ANOMALY belongs on that seam.
      !!
      !! `enable = .false.` (default) keeps `z_draft` at its `(1,1)`
      !! placeholder, `bt_H_ref = b`, and every path bit-identical.
      !! Knob table: `docs/generated_nml_knobs.md`.
      logical :: enable = .false.
         !! Master switch.  Requires the ocean multilayer path, the split
         !! solver, `&ocean_pgf_nml form="fv_mom6"`, `vcoord_type` in
         !! {sigma, zstar} and a single rank; mutually exclusive with
         !! wet/dry, porous barriers, sea ice, `bt_halo > 0`, tidal SAL
         !! and `gfs_scale /= 1` (every one of those fails loud at
         !! configure, naming the knob and the reason).
      character(len=32) :: draft_config = "none"
         !! Analytic draft shape.  `"none"` (default): `z_draft = 0`
         !! everywhere — the identity, even with `enable = .true.`.
         !! `"flat"`: uniform `draft_depth` inside the shelf box
         !! `[draft_x0, draft_x1] x [draft_y0, draft_y1]`, 0 outside (the
         !! open ocean beyond the calving front at `draft_x1`).
         !! `"linear"`: `z_draft = draft_depth + draft_slope*(x - draft_x0)`
         !! inside the same box, clipped at 0 below.  `"file"`: a static
         !! 2-D NetCDF draft — NOT implemented (fails loud); the
         !! MPI-correct static-2-D reader is a later slice, and it is the
         !! only route to an ISOMIP+ draft, which has no analytic form
         !! (Asay-Davis et al. 2016 §3.1.1).
      character(len=32) :: draft_source = "draft"
         !! What the draft is prescribed FROM.  `"draft"` (default): the
         !! geometry above IS the ice-base depth.  `"thickness"`: the
         !! formula gives an ice THICKNESS, converted by the
         !! Boussinesq-isostatic (flotation) relation
         !! `z_draft = rho_ice*h_ice/rho_0`.  `"in_situ"` (true isostasy,
         !! `p_ice = g*integral(rho_hat)`) needs a per-column root find,
         !! does not admit exact discrete rest, and is deliberately NOT
         !! implemented (fails loud).
      real(wp) :: draft_depth = 0.0_wp
         !! Draft amplitude (m, positive down) — the uniform value for
         !! `"flat"`, the value at `draft_x0` for `"linear"`.  Under
         !! `draft_source = "thickness"` it is an ice THICKNESS instead.
      real(wp) :: draft_slope = 0.0_wp
         !! `"linear"` only: d(draft)/dx, dimensionless (m of draft per m
         !! of x).  Positive deepens the ice base toward +x.  Converted
         !! from metres to GRID units at the dispatch (metres on a
         !! Cartesian grid, degrees on spherical/curvilinear), the same
         !! way `&ocean_topo_nml slope_scale` is.
      real(wp) :: draft_x0 = -1.0e30_wp
         !! Western edge of the shelf box (m, GLOBAL physical coordinate),
         !! and the ANCHOR of the `"linear"` profile (`draft_depth` is the
         !! draft AT `draft_x0`), which is why `"linear"` requires a
         !! finite value here.  The default +/-1e30 on all four bounds is
         !! the "no limit on this side" sentinel: the shelf then covers
         !! the whole domain INCLUDING the ghost band, which is what a
         !! shelf that reaches a wall needs (a box stopping at x = 0 puts
         !! a phantom calving front one cell outside the west wall).
      real(wp) :: draft_x1 = 1.0e30_wp
         !! Eastern edge of the shelf box = the CALVING FRONT (m): beyond
         !! it the draft is 0 (open ocean).  Default: no eastern limit.
      real(wp) :: draft_y0 = -1.0e30_wp
         !! Southern edge of the shelf box (m).  Default: no limit.
      real(wp) :: draft_y1 = 1.0e30_wp
         !! Northern edge of the shelf box (m).  Default: no limit.
      character(len=256) :: draft_file = ""
         !! `draft_config="file"`: path to the NetCDF carrying the static
         !! ice draft.  The variable named by `draft_var` must be rank 3
         !! in FORTRAN storage order `(x, y, t)` — which is how a C or
         !! Python writer (and `ncdump`) spells `(nTime, ny, nx)` — with a
         !! time coordinate variable; RECORD 1 is read and the field is
         !! never re-read.  There is NO horizontal interpolation: the file
         !! must already be on the model grid (`nx x ny` physical cells),
         !! exactly as `bathymetry_file` and `&ocean_zinit_nml file`
         !! require.  Single rank only (fail-loud otherwise).
      character(len=64) :: draft_var = "iceDraft"
         !! `draft_config="file"`: name of the 2-D variable to read.  The
         !! default is the ISOMIP+ geometry file's own spelling
         !! (Asay-Davis et al. 2016 Sect. 3.3).
      character(len=16) :: draft_sign = "depth"
         !! `draft_config="file"`: the SIGN CONVENTION of the file values.
         !! There is no default that guesses from the data — the two
         !! conventions differ by the whole ice load, and a field that is
         !! partly open water (zeros) is indistinguishable by inspection.
         !!
         !!   * `"depth"` / `"positive_down"` (default) — the values ARE
         !!     the ice-base depth, `>= 0`, Roundabout's own convention.
         !!   * `"elevation"` / `"positive_up"` — the values are the
         !!     ice-base ELEVATION `z_d`, `<= 0` under a floating shelf.
         !!     Negated on load.  **This is what the ISOMIP+ geometry file
         !!     needs**: its `iceDraft` is "the elevation of the
         !!     ice-ocean interface (z_d)".
         !!
         !! A file in the wrong convention produces a negative depth and
         !! is caught fail-loud by the existing non-negativity check, not
         !! silently accepted.
      real(wp) :: h_min_cavity = 10.0_wp
         !! GROUNDING cutoff (m): a column whose water thickness
         !! `b - z_draft` is below this is LAND — it goes through the same
         !! `seed_wet_mask_impl` the bathymetry uses, so the static
         !! metric-zeroing land mask and the finite land-state hold for
         !! free.  Never a thin film of water under grounded ice.
         !! ISOMIP+ §3.1.5 leaves the choice to the modeller and notes
         !! ~40 m (two cells) for z-level models; sigma is less
         !! restricted, hence 10 m.
      real(wp) :: grounded_max_frac = 0.5_wp
         !! Sanity bound: if more than this fraction of the interior
         !! columns ground, configure fails loud rather than silently
         !! running a domain that is mostly land.
      real(wp) :: rho_ice = 918.0_wp
         !! Ice density (kg/m^3), consulted ONLY by
         !! `draft_source = "thickness"`.
      logical :: trim_ic_for_p_surf = .false.
         !! Trim the INITIAL column under the ice so it is at rest (MOM6
         !! `TRIM_IC_FOR_P_SURF`, `trim_for_ice`).  The load
         !! `p_ice_ref = rho_ref*g*z_draft` is the displaced weight at the
         !! REFERENCE density; a stratified column's displaced water weighs
         !! `g*int_{-z_draft}^{0} rho dz`, and the difference is a depth-
         !! uniform bottom-pressure gradient the MOM6 barotropic split
         !! (`&ocean_bt_nml bc_pgf_forcing`) adjusts to.  With the knob on,
         !! the load is kept (the ice MASS is what is prescribed) and each
         !! loaded column's initial top is moved to the depth `s` where
         !! `g*int_{-s}^{0} rho dz = p_ice_ref`, i.e. an initial
         !! `eta = z_draft - s` (a few cm under ISOMIP+ COLD), with T/S
         !! then evaluated at the trimmed layer centres.  Closed form, exact at
         !! the discrete FV interfaces: requires `&ocean_eos_nml
         !! eos="linear"` and `&ocean_zinit_nml enable, source="linear"`
         !! (the analytic profile is what defines `rho` above the ice
         !! base); anything else fails loud.  Default off => bit-identical.
   end type ocean_cavity_dyn_config_t