&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 | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| type(config_t), | intent(in), | target | :: | cfg | ||
| type(nml_schema_t), | intent(inout) | :: | schema |
| 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 |
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