register_ocean_bc Subroutine

private subroutine register_ocean_bc(cfg, schema)

&ocean_bc_nml: open-boundary condition config (P4.5 migration off the hand-rolled read_ocean_bc_nml). All defaults reproduce a closed-wall run (bit-identical to nmls that omit this block). The west/east/south/north edge-type enum lists every arm of ocean_bc_type_from_string (rdb_ocean_boundary_types.F90), not just the subset named in the config-type docstring — that function is what the parsed string is actually fed to, and the native reader accepted (and validate_config did not reject) any of its arms on any edge, so the schema must not narrow that.

Arguments

Type IntentOptional Attributes Name
type(config_t), intent(in), target :: cfg
type(nml_schema_t), intent(inout) :: schema

Calls

proc~~register_ocean_bc~~CallsGraph proc~register_ocean_bc register_ocean_bc proc~group_add nml_group_t%group_add proc~register_ocean_bc->proc~group_add proc~nml_enum nml_enum proc~register_ocean_bc->proc~nml_enum proc~nml_int nml_int proc~register_ocean_bc->proc~nml_int proc~nml_logical nml_logical proc~register_ocean_bc->proc~nml_logical proc~nml_real nml_real proc~register_ocean_bc->proc~nml_real proc~nml_real_array nml_real_array proc~register_ocean_bc->proc~nml_real_array proc~schema_add_group nml_schema_t%schema_add_group proc~register_ocean_bc->proc~schema_add_group error error proc~group_add->error proc~lower lower proc~group_add->proc~lower proc~schema_add_group->error proc~schema_add_group->proc~lower proc~move_group move_group proc~schema_add_group->proc~move_group

Called by

proc~~register_ocean_bc~~CalledByGraph proc~register_ocean_bc register_ocean_bc proc~build_rdb_schema build_rdb_schema proc~build_rdb_schema->proc~register_ocean_bc proc~read_config_from_string_impl read_config_from_string_impl proc~read_config_from_string_impl->proc~build_rdb_schema proc~read_config_impl read_config_impl proc~read_config_impl->proc~build_rdb_schema proc~read_config read_config proc~read_config->proc~read_config_impl proc~read_config_from_string read_config_from_string proc~read_config_from_string->proc~read_config_from_string_impl proc~build_pending_handle build_pending_handle proc~build_pending_handle->proc~read_config_from_string proc~rdb_ocean_create_from_string rdb_ocean_create_from_string proc~rdb_ocean_create_from_string->proc~build_pending_handle proc~rdb_ocean_create_pending rdb_ocean_create_pending proc~rdb_ocean_create_pending->proc~build_pending_handle

Variables

Type Visibility Attributes Name Initial
character(len=*), private, parameter :: edge_allowed(*) = [character(len=13)::"wall", "open", "tidal", "nested", "inflow", "discharge", "clamped", "sponge", "chapman", "periodic", "tripolar_fold"]
type(nml_group_t), private :: g
integer, private, pointer :: pi
logical, private, pointer :: pl
real(kind=wp), private, pointer :: pr
real(kind=wp), private, pointer :: pra(:)
character(len=:), private, pointer :: ps
type(nml_real_array_key_t), private :: rr_key

Local materialisation for every nml_real_array(...) result before g%add — NVHPC 26.5 corrupts unrelated heap state when a 4th-or-later real_array function-result temporary is passed directly to g%add(...) in the same subroutine (bisected in register_ocean_diag’s comment above; this group registers twelve, so every one uses the workaround).


Source Code

   subroutine register_ocean_bc(cfg, schema)
      !! `&ocean_bc_nml`: open-boundary condition config (P4.5 migration
      !! off the hand-rolled `read_ocean_bc_nml`).  All defaults reproduce
      !! a closed-wall run (bit-identical to nmls that omit this block).
      !! The `west`/`east`/`south`/`north` edge-type enum lists every arm
      !! of `ocean_bc_type_from_string` (rdb_ocean_boundary_types.F90),
      !! not just the subset named in the config-type docstring — that
      !! function is what the parsed string is actually fed to, and the
      !! native reader accepted (and `validate_config` did not reject) any
      !! of its arms on any edge, so the schema must not narrow that.
      type(config_t), target, intent(in) :: cfg
      type(nml_schema_t), intent(inout) :: schema
      type(nml_group_t) :: g
      real(wp), pointer :: pr
      real(wp), pointer :: pra(:)
      integer, pointer :: pi
      logical, pointer :: pl
      character(len=:), pointer :: ps
      type(nml_real_array_key_t) :: rr_key
         !! Local materialisation for every `nml_real_array(...)` result
         !! before `g%add` — NVHPC 26.5 corrupts unrelated heap state when
         !! a 4th-or-later real_array function-result temporary is passed
         !! directly to `g%add(...)` in the same subroutine (bisected in
         !! `register_ocean_diag`'s comment above; this group registers
         !! twelve, so every one uses the workaround).
      character(len=*), parameter :: edge_allowed(*) = &
                                     [character(len=13) :: "wall", "open", "tidal", "nested", "inflow", &
                                                           "discharge", "clamped", "sponge", "chapman", "periodic", "tripolar_fold"]

      g%name = "ocean_bc"
      g%doc = "Open-boundary condition config: per-edge BC type, clamped/inflow "// &
              "Dirichlet values, sponge band, Orlanski radiation, full Flather, "// &
              "per-edge tidal constituents, tidal-OBC nodal correction, "// &
              "wall-velocity masking."

      ps => cfg%ocean%bc%west
      call g%add(nml_enum("west", ps, "West edge boundary type", allowed=edge_allowed))
      ps => cfg%ocean%bc%east
      call g%add(nml_enum("east", ps, "East edge boundary type", allowed=edge_allowed))
      ps => cfg%ocean%bc%south
      call g%add(nml_enum("south", ps, "South edge boundary type", allowed=edge_allowed))
      ps => cfg%ocean%bc%north
      call g%add(nml_enum("north", ps, &
                          "North edge boundary type ('tripolar_fold' is meaningful "// &
                          "here only — Murray bipolar cap; requires "// &
                          "grid_config='tripolar' + periodic west/east)", &
                          allowed=edge_allowed))

      pr => cfg%ocean%bc%west_clamped_eta
      call g%add(nml_real("west_clamped_eta", pr, "Clamped SSH, west edge", units="m"))
      pr => cfg%ocean%bc%east_clamped_eta
      call g%add(nml_real("east_clamped_eta", pr, "Clamped SSH, east edge", units="m"))
      pr => cfg%ocean%bc%south_clamped_eta
      call g%add(nml_real("south_clamped_eta", pr, "Clamped SSH, south edge", units="m"))
      pr => cfg%ocean%bc%north_clamped_eta
      call g%add(nml_real("north_clamped_eta", pr, "Clamped SSH, north edge", units="m"))
      pr => cfg%ocean%bc%west_clamped_u
      call g%add(nml_real("west_clamped_u", pr, "Clamped normal velocity, west edge", units="m/s"))
      pr => cfg%ocean%bc%east_clamped_u
      call g%add(nml_real("east_clamped_u", pr, "Clamped normal velocity, east edge", units="m/s"))
      pr => cfg%ocean%bc%south_clamped_v
      call g%add(nml_real("south_clamped_v", pr, "Clamped normal velocity, south edge", units="m/s"))
      pr => cfg%ocean%bc%north_clamped_v
      call g%add(nml_real("north_clamped_v", pr, "Clamped normal velocity, north edge", units="m/s"))

      pr => cfg%ocean%bc%west_inflow_S
      call g%add(nml_real("west_inflow_S", pr, "Inflow salinity, west edge", units="PSU"))
      pr => cfg%ocean%bc%west_inflow_T
      call g%add(nml_real("west_inflow_T", pr, "Inflow temperature, west edge", units="degC"))
      pr => cfg%ocean%bc%east_inflow_S
      call g%add(nml_real("east_inflow_S", pr, "Inflow salinity, east edge", units="PSU"))
      pr => cfg%ocean%bc%east_inflow_T
      call g%add(nml_real("east_inflow_T", pr, "Inflow temperature, east edge", units="degC"))
      pr => cfg%ocean%bc%south_inflow_S
      call g%add(nml_real("south_inflow_S", pr, "Inflow salinity, south edge", units="PSU"))
      pr => cfg%ocean%bc%south_inflow_T
      call g%add(nml_real("south_inflow_T", pr, "Inflow temperature, south edge", units="degC"))
      pr => cfg%ocean%bc%north_inflow_S
      call g%add(nml_real("north_inflow_S", pr, "Inflow salinity, north edge", units="PSU"))
      pr => cfg%ocean%bc%north_inflow_T
      call g%add(nml_real("north_inflow_T", pr, "Inflow temperature, north edge", units="degC"))

      pi => cfg%ocean%bc%sponge_width
      call g%add(nml_int("sponge_width", pi, "Sponge band width in cells (0 disables)"))
      pr => cfg%ocean%bc%sponge_strength
      call g%add(nml_real("sponge_strength", pr, &
                          "Peak sponge relaxation rate at the outer face of the band", &
                          units="1/s"))
      pl => cfg%ocean%bc%sponge_relax_tracers
      call g%add(nml_logical("sponge_relax_tracers", pl, &
                             "Extend the sponge relaxation to h_layer + tracers"))

      pr => cfg%ocean%bc%res_lscale_out
      call g%add(nml_real("res_lscale_out", pr, &
                          "Outflow reservoir length scale (0 = disabled)", units="m"))
      pr => cfg%ocean%bc%res_lscale_in
      call g%add(nml_real("res_lscale_in", pr, &
                          "Inflow reservoir length scale (0 = instantaneous inflow)", units="m"))

      ps => cfg%ocean%bc%radiation_scheme
      call g%add(nml_enum("radiation_scheme", ps, &
                          "'anomaly' = v1 BT-mean + zero-gradient anomaly (default); "// &
                          "'orlanski' = per-layer implicit-upwind radiation (Orlanski 1976)", &
                          allowed=[character(len=8) :: "anomaly", "orlanski"]))
      pr => cfg%ocean%bc%orlanski_rx_max
      call g%add(nml_real("orlanski_rx_max", pr, &
                          "Clamp on the Orlanski nondimensional phase speed", &
                          units="grid cells/step"))
      pr => cfg%ocean%bc%orlanski_gamma
      call g%add(nml_real("orlanski_gamma", pr, &
                          "Running-mean weight (0=full running mean, 1=instant)"))
      pr => cfg%ocean%bc%nudge_tau_in
      call g%add(nml_real("nudge_tau_in", pr, "Inflow nudging timescale (0 = off)", units="s"))
      pr => cfg%ocean%bc%nudge_tau_out
      call g%add(nml_real("nudge_tau_out", pr, "Outflow nudging timescale (0 = off)", units="s"))

      ps => cfg%ocean%bc%flather_form
      call g%add(nml_enum("flather_form", ps, &
                          "'legacy' = v1 Flather (u_ext=0, no interior vel, default); "// &
                          "'full' = half-characteristic form (Flather 1976)", &
                          allowed=[character(len=6) :: "legacy", "full"]))
      pr => cfg%ocean%bc%west_ext_u
      call g%add(nml_real("west_ext_u", pr, "Exterior barotropic u, west edge", units="m/s"))
      pr => cfg%ocean%bc%east_ext_u
      call g%add(nml_real("east_ext_u", pr, "Exterior barotropic u, east edge", units="m/s"))
      pr => cfg%ocean%bc%south_ext_v
      call g%add(nml_real("south_ext_v", pr, "Exterior barotropic v, south edge", units="m/s"))
      pr => cfg%ocean%bc%north_ext_v
      call g%add(nml_real("north_ext_v", pr, "Exterior barotropic v, north edge", units="m/s"))

      pi => cfg%ocean%bc%west_n_tidal
      call g%add(nml_int("west_n_tidal", pi, "Active tidal constituents, west edge", &
                         min=0, max=OBC_MAX_TIDAL_CFG))
      pra => cfg%ocean%bc%west_tidal_amp
      rr_key = nml_real_array("west_tidal_amp", pra, "Constituent amplitudes, west edge", &
                              units="m")
      call g%add(rr_key)
      pra => cfg%ocean%bc%west_tidal_phase
      rr_key = nml_real_array("west_tidal_phase", pra, "Constituent phases, west edge", &
                              units="rad")
      call g%add(rr_key)
      pra => cfg%ocean%bc%west_tidal_omega
      rr_key = nml_real_array("west_tidal_omega", pra, &
                              "Constituent angular frequencies, west edge", units="rad/s")
      call g%add(rr_key)

      pi => cfg%ocean%bc%east_n_tidal
      call g%add(nml_int("east_n_tidal", pi, "Active tidal constituents, east edge", &
                         min=0, max=OBC_MAX_TIDAL_CFG))
      pra => cfg%ocean%bc%east_tidal_amp
      rr_key = nml_real_array("east_tidal_amp", pra, "Constituent amplitudes, east edge", &
                              units="m")
      call g%add(rr_key)
      pra => cfg%ocean%bc%east_tidal_phase
      rr_key = nml_real_array("east_tidal_phase", pra, "Constituent phases, east edge", &
                              units="rad")
      call g%add(rr_key)
      pra => cfg%ocean%bc%east_tidal_omega
      rr_key = nml_real_array("east_tidal_omega", pra, &
                              "Constituent angular frequencies, east edge", units="rad/s")
      call g%add(rr_key)

      pi => cfg%ocean%bc%south_n_tidal
      call g%add(nml_int("south_n_tidal", pi, "Active tidal constituents, south edge", &
                         min=0, max=OBC_MAX_TIDAL_CFG))
      pra => cfg%ocean%bc%south_tidal_amp
      rr_key = nml_real_array("south_tidal_amp", pra, "Constituent amplitudes, south edge", &
                              units="m")
      call g%add(rr_key)
      pra => cfg%ocean%bc%south_tidal_phase
      rr_key = nml_real_array("south_tidal_phase", pra, "Constituent phases, south edge", &
                              units="rad")
      call g%add(rr_key)
      pra => cfg%ocean%bc%south_tidal_omega
      rr_key = nml_real_array("south_tidal_omega", pra, &
                              "Constituent angular frequencies, south edge", units="rad/s")
      call g%add(rr_key)

      pi => cfg%ocean%bc%north_n_tidal
      call g%add(nml_int("north_n_tidal", pi, "Active tidal constituents, north edge", &
                         min=0, max=OBC_MAX_TIDAL_CFG))
      pra => cfg%ocean%bc%north_tidal_amp
      rr_key = nml_real_array("north_tidal_amp", pra, "Constituent amplitudes, north edge", &
                              units="m")
      call g%add(rr_key)
      pra => cfg%ocean%bc%north_tidal_phase
      rr_key = nml_real_array("north_tidal_phase", pra, "Constituent phases, north edge", &
                              units="rad")
      call g%add(rr_key)
      pra => cfg%ocean%bc%north_tidal_omega
      rr_key = nml_real_array("north_tidal_omega", pra, &
                              "Constituent angular frequencies, north edge", units="rad/s")
      call g%add(rr_key)

      pl => cfg%ocean%bc%obc_tidal_nodal
      call g%add(nml_logical("obc_tidal_nodal", pl, &
                             "Apply the 18.6-yr nodal factor + equilibrium/nodal phase to "// &
                             "the open-boundary tidal elevation forcing (shares the "// &
                             "&ocean_tides_nml astro generator); when true *_tidal_phase "// &
                             "becomes a Greenwich phase lag"))
      pl => cfg%ocean%bc%mask_wall_velocity
      call g%add(nml_logical("mask_wall_velocity", pl, &
                             "Zero the T-cell wet-mask in the ghost cells beyond every "// &
                             "solid WALL edge at setup, so wall-normal C-grid face "// &
                             "velocities are masked rather than left as garbage "// &
                             "(default ON; set .false. to reproduce a pre-fix legacy "// &
                             "closed-basin baseline)"))

      call schema%add_group(g)
   end subroutine register_ocean_bc