rdb_ocean_dyn Module

Driver-level state + step routines for the outer (baroclinic) + inner (barotropic) split-explicit RK2 integrator of the ocean dynamical core. Carries the substep ratio n_inner, the fast-mode time-averaging accumulators, and energy/CFL diagnostic slots.


Uses

  • module~~rdb_ocean_dyn~~UsesGraph module~rdb_ocean_dyn rdb_ocean_dyn ieee_arithmetic ieee_arithmetic module~rdb_ocean_dyn->ieee_arithmetic iso_fortran_env iso_fortran_env module~rdb_ocean_dyn->iso_fortran_env module~rdb_barotropic_coupling rdb_barotropic_coupling module~rdb_ocean_dyn->module~rdb_barotropic_coupling module~rdb_barotropic_state rdb_barotropic_state module~rdb_ocean_dyn->module~rdb_barotropic_state module~rdb_barotropic_substep rdb_barotropic_substep module~rdb_ocean_dyn->module~rdb_barotropic_substep module~rdb_barotropic_workstate rdb_barotropic_workstate module~rdb_ocean_dyn->module~rdb_barotropic_workstate module~rdb_constants rdb_constants module~rdb_ocean_dyn->module~rdb_constants module~rdb_continuity rdb_continuity module~rdb_ocean_dyn->module~rdb_continuity module~rdb_coriolis_adv rdb_coriolis_adv module~rdb_ocean_dyn->module~rdb_coriolis_adv module~rdb_efp rdb_efp module~rdb_ocean_dyn->module~rdb_efp module~rdb_eos rdb_eos module~rdb_ocean_dyn->module~rdb_eos module~rdb_grid rdb_grid module~rdb_ocean_dyn->module~rdb_grid module~rdb_mem_report rdb_mem_report module~rdb_ocean_dyn->module~rdb_mem_report module~rdb_multilayer_state rdb_multilayer_state module~rdb_ocean_dyn->module~rdb_multilayer_state module~rdb_ocean_bottom_drag rdb_ocean_bottom_drag module~rdb_ocean_dyn->module~rdb_ocean_bottom_drag module~rdb_ocean_boundary_types rdb_ocean_boundary_types module~rdb_ocean_dyn->module~rdb_ocean_boundary_types module~rdb_ocean_bt_budget_probe rdb_ocean_bt_budget_probe module~rdb_ocean_dyn->module~rdb_ocean_bt_budget_probe module~rdb_ocean_bt_wide rdb_ocean_bt_wide module~rdb_ocean_dyn->module~rdb_ocean_bt_wide module~rdb_ocean_cavity_flux rdb_ocean_cavity_flux module~rdb_ocean_dyn->module~rdb_ocean_cavity_flux module~rdb_ocean_chksum rdb_ocean_chksum module~rdb_ocean_dyn->module~rdb_ocean_chksum module~rdb_ocean_console_stats rdb_ocean_console_stats module~rdb_ocean_dyn->module~rdb_ocean_console_stats module~rdb_ocean_eos_compute rdb_ocean_eos_compute module~rdb_ocean_dyn->module~rdb_ocean_eos_compute module~rdb_ocean_epbl rdb_ocean_epbl module~rdb_ocean_dyn->module~rdb_ocean_epbl module~rdb_ocean_fold_apply rdb_ocean_fold_apply module~rdb_ocean_dyn->module~rdb_ocean_fold_apply module~rdb_ocean_geothermal rdb_ocean_geothermal module~rdb_ocean_dyn->module~rdb_ocean_geothermal module~rdb_ocean_ghost_poison rdb_ocean_ghost_poison module~rdb_ocean_dyn->module~rdb_ocean_ghost_poison module~rdb_ocean_gm rdb_ocean_gm module~rdb_ocean_dyn->module~rdb_ocean_gm module~rdb_ocean_halo rdb_ocean_halo module~rdb_ocean_dyn->module~rdb_ocean_halo module~rdb_ocean_halo_state rdb_ocean_halo_state module~rdb_ocean_dyn->module~rdb_ocean_halo_state module~rdb_ocean_hdiff_tracer rdb_ocean_hdiff_tracer module~rdb_ocean_dyn->module~rdb_ocean_hdiff_tracer module~rdb_ocean_horizontal_viscosity rdb_ocean_horizontal_viscosity module~rdb_ocean_dyn->module~rdb_ocean_horizontal_viscosity module~rdb_ocean_ideal_age rdb_ocean_ideal_age module~rdb_ocean_dyn->module~rdb_ocean_ideal_age module~rdb_ocean_isopycnal_slopes rdb_ocean_isopycnal_slopes module~rdb_ocean_dyn->module~rdb_ocean_isopycnal_slopes module~rdb_ocean_kappa_shear rdb_ocean_kappa_shear module~rdb_ocean_dyn->module~rdb_ocean_kappa_shear module~rdb_ocean_ke_probe rdb_ocean_ke_probe module~rdb_ocean_dyn->module~rdb_ocean_ke_probe module~rdb_ocean_lateral_mix rdb_ocean_lateral_mix module~rdb_ocean_dyn->module~rdb_ocean_lateral_mix module~rdb_ocean_meke rdb_ocean_meke module~rdb_ocean_dyn->module~rdb_ocean_meke module~rdb_ocean_metrics rdb_ocean_metrics module~rdb_ocean_dyn->module~rdb_ocean_metrics module~rdb_ocean_min_thickness rdb_ocean_min_thickness module~rdb_ocean_dyn->module~rdb_ocean_min_thickness module~rdb_ocean_mle rdb_ocean_mle module~rdb_ocean_dyn->module~rdb_ocean_mle module~rdb_ocean_obc_baroclinic rdb_ocean_obc_baroclinic module~rdb_ocean_dyn->module~rdb_ocean_obc_baroclinic module~rdb_ocean_p_surf rdb_ocean_p_surf module~rdb_ocean_dyn->module~rdb_ocean_p_surf module~rdb_ocean_periodic rdb_ocean_periodic module~rdb_ocean_dyn->module~rdb_ocean_periodic module~rdb_ocean_porous rdb_ocean_porous module~rdb_ocean_dyn->module~rdb_ocean_porous module~rdb_ocean_pressure_force rdb_ocean_pressure_force module~rdb_ocean_dyn->module~rdb_ocean_pressure_force module~rdb_ocean_redi rdb_ocean_redi module~rdb_ocean_dyn->module~rdb_ocean_redi module~rdb_ocean_remap rdb_ocean_remap module~rdb_ocean_dyn->module~rdb_ocean_remap module~rdb_ocean_sponge rdb_ocean_sponge module~rdb_ocean_dyn->module~rdb_ocean_sponge module~rdb_ocean_surface_flux rdb_ocean_surface_flux module~rdb_ocean_dyn->module~rdb_ocean_surface_flux module~rdb_ocean_surface_stress rdb_ocean_surface_stress module~rdb_ocean_dyn->module~rdb_ocean_surface_stress module~rdb_ocean_tidal_mixing rdb_ocean_tidal_mixing module~rdb_ocean_dyn->module~rdb_ocean_tidal_mixing module~rdb_ocean_tides rdb_ocean_tides module~rdb_ocean_dyn->module~rdb_ocean_tides module~rdb_ocean_top_drag rdb_ocean_top_drag module~rdb_ocean_dyn->module~rdb_ocean_top_drag module~rdb_ocean_varmix rdb_ocean_varmix module~rdb_ocean_dyn->module~rdb_ocean_varmix module~rdb_ocean_vcoord rdb_ocean_vcoord module~rdb_ocean_dyn->module~rdb_ocean_vcoord module~rdb_ocean_vdiff rdb_ocean_vdiff module~rdb_ocean_dyn->module~rdb_ocean_vdiff module~rdb_ocean_vertical_advection rdb_ocean_vertical_advection module~rdb_ocean_dyn->module~rdb_ocean_vertical_advection module~rdb_ocean_vmix rdb_ocean_vmix module~rdb_ocean_dyn->module~rdb_ocean_vmix module~rdb_ocean_wave_speed rdb_ocean_wave_speed module~rdb_ocean_dyn->module~rdb_ocean_wave_speed module~rdb_profiler rdb_profiler module~rdb_ocean_dyn->module~rdb_profiler pic_logger pic_logger module~rdb_ocean_dyn->pic_logger pic_strings pic_strings module~rdb_ocean_dyn->pic_strings module~rdb_barotropic_coupling->ieee_arithmetic module~rdb_barotropic_coupling->module~rdb_barotropic_workstate module~rdb_barotropic_coupling->module~rdb_constants module~rdb_barotropic_coupling->module~rdb_coriolis_adv module~rdb_barotropic_coupling->module~rdb_grid module~rdb_barotropic_coupling->module~rdb_multilayer_state module~rdb_barotropic_coupling->module~rdb_ocean_bottom_drag module~rdb_barotropic_coupling->module~rdb_ocean_boundary_types module~rdb_barotropic_coupling->module~rdb_ocean_horizontal_viscosity module~rdb_barotropic_coupling->module~rdb_ocean_metrics module~rdb_barotropic_coupling->module~rdb_ocean_pressure_force module~rdb_barotropic_coupling->module~rdb_ocean_surface_stress module~rdb_barotropic_coupling->module~rdb_ocean_top_drag module~rdb_barotropic_state->iso_fortran_env module~rdb_barotropic_state->module~rdb_constants module~rdb_barotropic_state->module~rdb_grid module~rdb_barotropic_state->module~rdb_mem_report module~rdb_barotropic_substep->module~rdb_barotropic_workstate module~rdb_barotropic_substep->module~rdb_constants module~rdb_barotropic_substep->module~rdb_grid module~rdb_barotropic_substep->module~rdb_ocean_boundary_types module~rdb_barotropic_substep->module~rdb_ocean_halo module~rdb_barotropic_substep->module~rdb_ocean_metrics module~rdb_barotropic_substep->module~rdb_profiler module~rdb_bt_cont_type rdb_bt_cont_type module~rdb_barotropic_substep->module~rdb_bt_cont_type module~rdb_ocean_fold_exchange rdb_ocean_fold_exchange module~rdb_barotropic_substep->module~rdb_ocean_fold_exchange module~rdb_ocean_halo_counters rdb_ocean_halo_counters module~rdb_barotropic_substep->module~rdb_ocean_halo_counters module~rdb_barotropic_workstate->iso_fortran_env module~rdb_barotropic_workstate->module~rdb_constants module~rdb_barotropic_workstate->module~rdb_grid module~rdb_barotropic_workstate->module~rdb_mem_report pic_types pic_types module~rdb_constants->pic_types module~rdb_continuity->iso_fortran_env module~rdb_continuity->module~rdb_barotropic_state module~rdb_continuity->module~rdb_constants module~rdb_continuity->module~rdb_grid module~rdb_continuity->module~rdb_mem_report module~rdb_continuity->module~rdb_multilayer_state module~rdb_continuity->module~rdb_ocean_boundary_types module~rdb_continuity->module~rdb_ocean_fold_apply module~rdb_continuity->module~rdb_ocean_gm module~rdb_continuity->module~rdb_ocean_halo module~rdb_continuity->module~rdb_ocean_metrics module~rdb_continuity->module~rdb_ocean_mle module~rdb_continuity->module~rdb_ocean_periodic module~rdb_continuity->module~rdb_profiler module~rdb_ocean_fold rdb_ocean_fold module~rdb_continuity->module~rdb_ocean_fold module~rdb_continuity->module~rdb_ocean_fold_exchange module~rdb_recon_weno rdb_recon_weno module~rdb_continuity->module~rdb_recon_weno module~rdb_scratch_3d rdb_scratch_3d module~rdb_continuity->module~rdb_scratch_3d module~rdb_tracer rdb_tracer module~rdb_continuity->module~rdb_tracer module~rdb_coriolis_adv->iso_fortran_env module~rdb_coriolis_adv->module~rdb_barotropic_state module~rdb_coriolis_adv->module~rdb_constants module~rdb_coriolis_adv->module~rdb_grid module~rdb_coriolis_adv->module~rdb_mem_report module~rdb_coriolis_adv->module~rdb_multilayer_state module~rdb_coriolis_adv->module~rdb_ocean_metrics module~rdb_coriolis_adv->module~rdb_ocean_porous module~rdb_coriolis_adv->module~rdb_scratch_3d module~rdb_efp->ieee_arithmetic module~rdb_efp->iso_fortran_env module~rdb_eos->module~rdb_constants module~rdb_eos->module~rdb_grid module~rdb_grid->module~rdb_constants module~rdb_mem_report->iso_fortran_env module~rdb_mem_report->module~rdb_constants module~rdb_mem_report->pic_logger module~rdb_mem_report->pic_strings module~rdb_multilayer_state->iso_fortran_env module~rdb_multilayer_state->module~rdb_constants module~rdb_multilayer_state->module~rdb_efp module~rdb_multilayer_state->module~rdb_grid module~rdb_multilayer_state->module~rdb_mem_report module~rdb_multilayer_state->pic_logger module~rdb_error_ring rdb_error_ring module~rdb_multilayer_state->module~rdb_error_ring module~rdb_multilayer_state->module~rdb_tracer module~rdb_ocean_bottom_drag->iso_fortran_env module~rdb_ocean_bottom_drag->module~rdb_constants module~rdb_ocean_bottom_drag->module~rdb_grid module~rdb_ocean_bottom_drag->module~rdb_mem_report module~rdb_ocean_bottom_drag->module~rdb_multilayer_state module~rdb_ocean_bottom_drag->module~rdb_ocean_metrics module~rdb_ocean_bottom_drag->module~rdb_scratch_3d module~rdb_ocean_boundary_types->iso_fortran_env module~rdb_ocean_boundary_types->module~rdb_constants module~rdb_ocean_boundary_types->module~rdb_grid module~rdb_ocean_boundary_types->module~rdb_mem_report module~rdb_ocean_boundary_types->pic_logger module~rdb_ocean_status rdb_ocean_status module~rdb_ocean_boundary_types->module~rdb_ocean_status module~rdb_ocean_tide_astro rdb_ocean_tide_astro module~rdb_ocean_boundary_types->module~rdb_ocean_tide_astro pic_ascii pic_ascii module~rdb_ocean_boundary_types->pic_ascii module~rdb_ocean_bt_budget_probe->module~rdb_barotropic_workstate module~rdb_ocean_bt_budget_probe->module~rdb_constants module~rdb_ocean_bt_budget_probe->module~rdb_coriolis_adv module~rdb_ocean_bt_budget_probe->module~rdb_grid module~rdb_ocean_bt_budget_probe->module~rdb_multilayer_state module~rdb_ocean_bt_budget_probe->module~rdb_ocean_bottom_drag module~rdb_ocean_bt_budget_probe->module~rdb_ocean_horizontal_viscosity module~rdb_ocean_bt_budget_probe->module~rdb_ocean_pressure_force module~rdb_ocean_bt_budget_probe->module~rdb_ocean_surface_stress module~rdb_ocean_bt_wide->iso_fortran_env module~rdb_ocean_bt_wide->module~rdb_barotropic_substep module~rdb_ocean_bt_wide->module~rdb_barotropic_workstate module~rdb_ocean_bt_wide->module~rdb_constants module~rdb_ocean_bt_wide->module~rdb_grid module~rdb_ocean_bt_wide->module~rdb_mem_report module~rdb_ocean_bt_wide->module~rdb_ocean_boundary_types module~rdb_ocean_bt_wide->module~rdb_ocean_halo module~rdb_ocean_bt_wide->module~rdb_ocean_metrics module~rdb_ocean_bt_wide->module~rdb_profiler module~rdb_ocean_bt_wide->pic_logger module~rdb_ocean_cavity_flux->iso_fortran_env module~rdb_ocean_cavity_flux->module~rdb_constants module~rdb_ocean_cavity_flux->module~rdb_eos module~rdb_ocean_cavity_flux->module~rdb_grid module~rdb_ocean_cavity_flux->module~rdb_mem_report module~rdb_ocean_cavity_flux->module~rdb_multilayer_state module~rdb_ocean_cavity_flux->module~rdb_ocean_metrics module~rdb_ocean_cavity_flux->module~rdb_ocean_surface_flux module~rdb_ocean_cavity_melt rdb_ocean_cavity_melt module~rdb_ocean_cavity_flux->module~rdb_ocean_cavity_melt module~rdb_ocean_chksum->iso_fortran_env module~rdb_ocean_chksum->module~rdb_barotropic_workstate module~rdb_ocean_chksum->module~rdb_constants module~rdb_ocean_chksum->module~rdb_grid module~rdb_ocean_chksum->module~rdb_multilayer_state module~rdb_halo rdb_halo module~rdb_ocean_chksum->module~rdb_halo module~rdb_ocean_console_stats->ieee_arithmetic module~rdb_ocean_console_stats->iso_fortran_env module~rdb_ocean_console_stats->module~rdb_constants module~rdb_ocean_console_stats->module~rdb_efp module~rdb_ocean_console_stats->module~rdb_grid module~rdb_ocean_console_stats->module~rdb_multilayer_state module~rdb_ocean_console_stats->module~rdb_ocean_metrics module~rdb_ocean_console_stats->pic_logger module~rdb_ocean_console_stats->pic_strings module~rdb_console_stats rdb_console_stats module~rdb_ocean_console_stats->module~rdb_console_stats module~rdb_ocean_console_stats->module~rdb_halo module~rdb_ice_column rdb_ice_column module~rdb_ocean_console_stats->module~rdb_ice_column module~rdb_ocean_console_stats->module~rdb_ocean_halo_counters module~rdb_ocean_eos_compute->module~rdb_eos module~rdb_ocean_eos_compute->module~rdb_multilayer_state module~rdb_ocean_epbl->iso_fortran_env module~rdb_ocean_epbl->module~rdb_constants module~rdb_ocean_epbl->module~rdb_eos module~rdb_ocean_epbl->module~rdb_grid module~rdb_ocean_epbl->module~rdb_mem_report module~rdb_ocean_epbl->module~rdb_multilayer_state module~rdb_ocean_epbl->module~rdb_ocean_surface_flux module~rdb_ocean_epbl->module~rdb_ocean_surface_stress module~rdb_ocean_epbl->module~rdb_scratch_3d module~rdb_ocean_fold_apply->module~rdb_constants module~rdb_ocean_fold_apply->module~rdb_grid module~rdb_ocean_fold_apply->module~rdb_multilayer_state module~rdb_ocean_fold_apply->module~rdb_ocean_boundary_types module~rdb_ocean_fold_apply->module~rdb_ocean_fold module~rdb_ocean_fold_apply->module~rdb_ocean_fold_exchange module~rdb_ocean_geothermal->module~rdb_constants module~rdb_ocean_geothermal->module~rdb_grid module~rdb_ocean_geothermal->module~rdb_multilayer_state module~rdb_ocean_geothermal->module~rdb_ocean_surface_flux module~rdb_ocean_ghost_poison->ieee_arithmetic module~rdb_ocean_ghost_poison->module~rdb_barotropic_workstate module~rdb_ocean_ghost_poison->module~rdb_constants module~rdb_ocean_ghost_poison->module~rdb_grid module~rdb_ocean_ghost_poison->module~rdb_multilayer_state module~rdb_ocean_ghost_poison->module~rdb_ocean_surface_stress module~rdb_ocean_gm->ieee_arithmetic module~rdb_ocean_gm->iso_fortran_env module~rdb_ocean_gm->module~rdb_constants module~rdb_ocean_gm->module~rdb_grid module~rdb_ocean_gm->module~rdb_mem_report module~rdb_ocean_gm->module~rdb_multilayer_state module~rdb_ocean_gm->module~rdb_ocean_isopycnal_slopes module~rdb_ocean_gm->module~rdb_ocean_metrics module~rdb_ocean_halo->module~rdb_constants module~rdb_ocean_halo->module~rdb_ocean_periodic module~rdb_ocean_halo->pic_logger module~rdb_ocean_halo->pic_strings module~rdb_comm_env rdb_comm_env module~rdb_ocean_halo->module~rdb_comm_env module~rdb_decomp rdb_decomp module~rdb_ocean_halo->module~rdb_decomp module~rdb_ocean_halo->module~rdb_error_ring module~rdb_ocean_halo->module~rdb_ocean_halo_counters module~rdb_ocean_halo->module~rdb_ocean_status pic_mpi_lib pic_mpi_lib module~rdb_ocean_halo->pic_mpi_lib module~rdb_ocean_halo_state->module~rdb_constants module~rdb_ocean_halo_state->module~rdb_grid module~rdb_ocean_halo_state->module~rdb_multilayer_state module~rdb_ocean_halo_state->module~rdb_ocean_boundary_types module~rdb_ocean_halo_state->module~rdb_ocean_fold_apply module~rdb_ocean_halo_state->module~rdb_ocean_halo module~rdb_ocean_halo_state->module~rdb_ocean_periodic module~rdb_ocean_halo_state->module~rdb_ocean_surface_stress module~rdb_ocean_halo_state->module~rdb_profiler module~rdb_ice_state rdb_ice_state module~rdb_ocean_halo_state->module~rdb_ice_state module~rdb_ocean_halo_state->module~rdb_ocean_halo_counters module~rdb_ocean_hdiff_tracer->iso_fortran_env module~rdb_ocean_hdiff_tracer->module~rdb_constants module~rdb_ocean_hdiff_tracer->module~rdb_grid module~rdb_ocean_hdiff_tracer->module~rdb_mem_report module~rdb_ocean_hdiff_tracer->module~rdb_multilayer_state module~rdb_ocean_hdiff_tracer->module~rdb_ocean_boundary_types module~rdb_ocean_hdiff_tracer->module~rdb_ocean_metrics module~rdb_ocean_hdiff_tracer->module~rdb_scratch_3d module~rdb_ocean_hdiff_tracer->module~rdb_tracer module~rdb_ocean_horizontal_viscosity->iso_fortran_env module~rdb_ocean_horizontal_viscosity->module~rdb_constants module~rdb_ocean_horizontal_viscosity->module~rdb_grid module~rdb_ocean_horizontal_viscosity->module~rdb_mem_report module~rdb_ocean_horizontal_viscosity->module~rdb_multilayer_state module~rdb_ocean_horizontal_viscosity->module~rdb_ocean_lateral_mix module~rdb_ocean_horizontal_viscosity->module~rdb_ocean_metrics module~rdb_ocean_horizontal_viscosity->module~rdb_scratch_3d module~rdb_ocean_ideal_age->module~rdb_constants module~rdb_ocean_ideal_age->module~rdb_grid module~rdb_ocean_ideal_age->module~rdb_multilayer_state module~rdb_ocean_isopycnal_slopes->iso_fortran_env module~rdb_ocean_isopycnal_slopes->module~rdb_constants module~rdb_ocean_isopycnal_slopes->module~rdb_eos module~rdb_ocean_isopycnal_slopes->module~rdb_grid module~rdb_ocean_isopycnal_slopes->module~rdb_mem_report module~rdb_ocean_isopycnal_slopes->module~rdb_multilayer_state module~rdb_ocean_isopycnal_slopes->module~rdb_ocean_metrics module~rdb_ocean_kappa_shear->ieee_arithmetic module~rdb_ocean_kappa_shear->iso_fortran_env module~rdb_ocean_kappa_shear->module~rdb_constants module~rdb_ocean_kappa_shear->module~rdb_eos module~rdb_ocean_kappa_shear->module~rdb_grid module~rdb_ocean_kappa_shear->module~rdb_mem_report module~rdb_ocean_kappa_shear->module~rdb_multilayer_state module~rdb_massless rdb_massless module~rdb_ocean_kappa_shear->module~rdb_massless module~rdb_ocean_ke_probe->module~rdb_constants module~rdb_ocean_ke_probe->module~rdb_coriolis_adv module~rdb_ocean_ke_probe->module~rdb_grid module~rdb_ocean_ke_probe->module~rdb_multilayer_state module~rdb_ocean_ke_probe->module~rdb_ocean_metrics module~rdb_ocean_lateral_mix->iso_fortran_env module~rdb_ocean_lateral_mix->module~rdb_constants module~rdb_ocean_lateral_mix->module~rdb_grid module~rdb_ocean_lateral_mix->module~rdb_mem_report module~rdb_ocean_lateral_mix->module~rdb_multilayer_state module~rdb_ocean_lateral_mix->module~rdb_ocean_metrics module~rdb_ocean_lateral_mix->module~rdb_scratch_3d module~rdb_ocean_meke->iso_fortran_env module~rdb_ocean_meke->module~rdb_constants module~rdb_ocean_meke->module~rdb_grid module~rdb_ocean_meke->module~rdb_mem_report module~rdb_ocean_meke->module~rdb_multilayer_state module~rdb_ocean_meke->module~rdb_ocean_gm module~rdb_ocean_meke->module~rdb_ocean_metrics module~rdb_ocean_meke->module~rdb_ocean_varmix module~rdb_ocean_meke->module~rdb_ocean_wave_speed module~rdb_ocean_metrics->iso_fortran_env module~rdb_ocean_metrics->module~rdb_constants module~rdb_ocean_metrics->module~rdb_grid module~rdb_ocean_metrics->module~rdb_mem_report module~rdb_ocean_metrics->pic_logger module~rdb_ocean_metrics->pic_strings module~rdb_ocean_metrics->module~rdb_error_ring module~rdb_io_netcdf rdb_io_netcdf module~rdb_ocean_metrics->module~rdb_io_netcdf module~rdb_ocean_bipolar rdb_ocean_bipolar module~rdb_ocean_metrics->module~rdb_ocean_bipolar module~rdb_ocean_metrics->module~rdb_ocean_fold module~rdb_ocean_metrics->module~rdb_ocean_status netcdf netcdf module~rdb_ocean_metrics->netcdf module~rdb_ocean_min_thickness->module~rdb_constants module~rdb_ocean_min_thickness->module~rdb_grid module~rdb_ocean_min_thickness->module~rdb_multilayer_state module~rdb_remap_column rdb_remap_column module~rdb_ocean_min_thickness->module~rdb_remap_column module~rdb_ocean_mle->iso_fortran_env module~rdb_ocean_mle->module~rdb_constants module~rdb_ocean_mle->module~rdb_grid module~rdb_ocean_mle->module~rdb_mem_report module~rdb_ocean_mle->module~rdb_multilayer_state module~rdb_ocean_mle->module~rdb_ocean_boundary_types module~rdb_ocean_mle->module~rdb_ocean_epbl module~rdb_ocean_mle->module~rdb_ocean_metrics module~rdb_ocean_mle->module~rdb_ocean_surface_stress module~rdb_ocean_obc_baroclinic->module~rdb_barotropic_workstate module~rdb_ocean_obc_baroclinic->module~rdb_constants module~rdb_ocean_obc_baroclinic->module~rdb_grid module~rdb_ocean_obc_baroclinic->module~rdb_multilayer_state module~rdb_ocean_obc_baroclinic->module~rdb_ocean_boundary_types module~rdb_ocean_p_surf->iso_fortran_env module~rdb_ocean_p_surf->module~rdb_constants module~rdb_ocean_p_surf->module~rdb_grid module~rdb_ocean_p_surf->module~rdb_mem_report module~rdb_ocean_periodic->module~rdb_constants module~rdb_ocean_periodic->module~rdb_grid module~rdb_ocean_periodic->module~rdb_multilayer_state module~rdb_ocean_periodic->module~rdb_ocean_boundary_types module~rdb_ocean_porous->ieee_arithmetic module~rdb_ocean_porous->module~rdb_constants module~rdb_ocean_pressure_force->iso_fortran_env module~rdb_ocean_pressure_force->module~rdb_constants module~rdb_ocean_pressure_force->module~rdb_eos module~rdb_ocean_pressure_force->module~rdb_grid module~rdb_ocean_pressure_force->module~rdb_mem_report module~rdb_ocean_pressure_force->module~rdb_multilayer_state module~rdb_ocean_pressure_force->module~rdb_ocean_metrics module~rdb_ocean_pgf_reconstruct rdb_ocean_pgf_reconstruct module~rdb_ocean_pressure_force->module~rdb_ocean_pgf_reconstruct module~rdb_ocean_pressure_force->module~rdb_scratch_3d module~rdb_ocean_redi->iso_fortran_env module~rdb_ocean_redi->module~rdb_constants module~rdb_ocean_redi->module~rdb_eos module~rdb_ocean_redi->module~rdb_grid module~rdb_ocean_redi->module~rdb_mem_report module~rdb_ocean_redi->module~rdb_multilayer_state module~rdb_ocean_redi->module~rdb_ocean_boundary_types module~rdb_ocean_redi->module~rdb_ocean_metrics module~rdb_ocean_redi->module~rdb_tracer module~rdb_ocean_remap->module~rdb_constants module~rdb_ocean_remap->module~rdb_eos module~rdb_ocean_remap->module~rdb_grid module~rdb_ocean_remap->module~rdb_multilayer_state module~rdb_ocean_remap->module~rdb_ocean_vcoord module~rdb_ocean_remap->module~rdb_remap_column module~rdb_ocean_remap->module~rdb_tracer module~rdb_ocean_sponge->iso_fortran_env module~rdb_ocean_sponge->module~rdb_constants module~rdb_ocean_sponge->module~rdb_grid module~rdb_ocean_sponge->module~rdb_mem_report module~rdb_ocean_sponge->module~rdb_multilayer_state module~rdb_ocean_sponge->module~rdb_ocean_boundary_types module~rdb_ocean_surface_flux->iso_fortran_env module~rdb_ocean_surface_flux->module~rdb_constants module~rdb_ocean_surface_flux->module~rdb_grid module~rdb_ocean_surface_flux->module~rdb_mem_report module~rdb_ocean_surface_flux->module~rdb_multilayer_state module~rdb_ocean_surface_stress->iso_fortran_env module~rdb_ocean_surface_stress->module~rdb_constants module~rdb_ocean_surface_stress->module~rdb_grid module~rdb_ocean_surface_stress->module~rdb_mem_report module~rdb_ocean_surface_stress->module~rdb_multilayer_state module~rdb_ocean_surface_stress->module~rdb_scratch_3d module~rdb_ocean_tidal_mixing->iso_fortran_env module~rdb_ocean_tidal_mixing->module~rdb_constants module~rdb_ocean_tidal_mixing->module~rdb_eos module~rdb_ocean_tidal_mixing->module~rdb_grid module~rdb_ocean_tidal_mixing->module~rdb_mem_report module~rdb_ocean_tidal_mixing->module~rdb_multilayer_state module~rdb_ocean_tides->iso_fortran_env module~rdb_ocean_tides->module~rdb_constants module~rdb_ocean_tides->module~rdb_grid module~rdb_ocean_tides->module~rdb_mem_report module~rdb_ocean_tides->module~rdb_ocean_tide_astro module~rdb_ocean_top_drag->iso_fortran_env module~rdb_ocean_top_drag->module~rdb_constants module~rdb_ocean_top_drag->module~rdb_grid module~rdb_ocean_top_drag->module~rdb_mem_report module~rdb_ocean_top_drag->module~rdb_multilayer_state module~rdb_ocean_top_drag->module~rdb_scratch_3d module~rdb_ocean_varmix->iso_fortran_env module~rdb_ocean_varmix->module~rdb_constants module~rdb_ocean_varmix->module~rdb_grid module~rdb_ocean_varmix->module~rdb_mem_report module~rdb_ocean_varmix->module~rdb_multilayer_state module~rdb_ocean_varmix->module~rdb_ocean_isopycnal_slopes module~rdb_ocean_varmix->module~rdb_ocean_metrics module~rdb_ocean_varmix->module~rdb_ocean_wave_speed module~rdb_ocean_vcoord->iso_fortran_env module~rdb_ocean_vcoord->module~rdb_constants module~rdb_ocean_vcoord->module~rdb_eos module~rdb_ocean_vcoord->module~rdb_grid module~rdb_ocean_vcoord->module~rdb_mem_report module~rdb_vcoord rdb_vcoord module~rdb_ocean_vcoord->module~rdb_vcoord module~rdb_ocean_vdiff->iso_fortran_env module~rdb_ocean_vdiff->module~rdb_constants module~rdb_ocean_vdiff->module~rdb_eos module~rdb_ocean_vdiff->module~rdb_grid module~rdb_ocean_vdiff->module~rdb_mem_report module~rdb_ocean_vdiff->module~rdb_multilayer_state module~rdb_ocean_vdiff->pic_logger module~rdb_ocean_vdiff->module~rdb_scratch_3d module~rdb_ocean_vdiff->module~rdb_tracer module~rdb_ocean_vertical_advection->iso_fortran_env module~rdb_ocean_vertical_advection->module~rdb_constants module~rdb_ocean_vertical_advection->module~rdb_grid module~rdb_ocean_vertical_advection->module~rdb_mem_report module~rdb_ocean_vertical_advection->module~rdb_multilayer_state module~rdb_ocean_vertical_advection->module~rdb_scratch_3d module~rdb_ocean_vertical_advection->module~rdb_tracer module~rdb_ocean_vmix->iso_fortran_env module~rdb_ocean_vmix->module~rdb_constants module~rdb_ocean_vmix->module~rdb_eos module~rdb_ocean_vmix->module~rdb_grid module~rdb_ocean_vmix->module~rdb_mem_report module~rdb_ocean_vmix->module~rdb_multilayer_state module~rdb_ocean_vmix->module~rdb_ocean_surface_flux module~rdb_ocean_vmix->module~rdb_ocean_surface_stress module~rdb_ocean_wave_speed->iso_fortran_env module~rdb_ocean_wave_speed->module~rdb_constants module~rdb_ocean_wave_speed->module~rdb_grid module~rdb_ocean_wave_speed->module~rdb_mem_report module~rdb_ocean_wave_speed->module~rdb_multilayer_state module~rdb_ocean_wave_speed->module~rdb_ocean_metrics module~rdb_profiler->iso_fortran_env module~rdb_profiler->pic_logger module~rdb_bt_cont_type->module~rdb_barotropic_workstate module~rdb_bt_cont_type->module~rdb_constants module~rdb_comm_env->iso_fortran_env module~rdb_comm_env->module~rdb_constants module~rdb_comm_env->pic_mpi_lib module~rdb_console_stats->ieee_arithmetic module~rdb_console_stats->module~rdb_constants module~rdb_console_stats->module~rdb_efp module~rdb_console_stats->pic_logger module~rdb_console_stats->pic_strings module~rdb_config rdb_config module~rdb_decomp->module~rdb_config module~rdb_error_ring->pic_logger module~rdb_halo->iso_fortran_env module~rdb_halo->module~rdb_constants module~rdb_halo->module~rdb_efp module~rdb_halo->pic_logger module~rdb_halo->module~rdb_comm_env module~rdb_halo->module~rdb_decomp module~rdb_halo->pic_mpi_lib module~rdb_ice_column->module~rdb_constants module~rdb_ice_enthalpy rdb_ice_enthalpy module~rdb_ice_column->module~rdb_ice_enthalpy module~rdb_ice_mass rdb_ice_mass module~rdb_ice_column->module~rdb_ice_mass module~rdb_ice_optics rdb_ice_optics module~rdb_ice_column->module~rdb_ice_optics module~rdb_ice_state->iso_fortran_env module~rdb_ice_state->module~rdb_constants module~rdb_ice_state->module~rdb_grid module~rdb_ice_state->module~rdb_mem_report module~rdb_ice_state->module~rdb_ice_column module~rdb_ice_state->module~rdb_ice_enthalpy module~rdb_io_netcdf->iso_fortran_env module~rdb_io_netcdf->module~rdb_constants module~rdb_io_netcdf->pic_logger module~rdb_io_netcdf->pic_strings module~rdb_io_netcdf->module~rdb_error_ring module~rdb_io_netcdf->netcdf iso_c_binding iso_c_binding module~rdb_io_netcdf->iso_c_binding module~rdb_massless->module~rdb_constants module~rdb_ocean_bipolar->module~rdb_constants module~rdb_ocean_cavity_melt->ieee_arithmetic module~rdb_ocean_cavity_melt->module~rdb_constants module~rdb_ocean_cavity_melt->module~rdb_eos module~rdb_ocean_fold->module~rdb_constants module~rdb_ocean_fold_exchange->module~rdb_constants module~rdb_ocean_fold_exchange->pic_logger module~rdb_ocean_fold_exchange->pic_strings module~rdb_ocean_fold_exchange->module~rdb_comm_env module~rdb_ocean_fold_exchange->module~rdb_decomp module~rdb_ocean_fold_exchange->module~rdb_error_ring module~rdb_ocean_fold_exchange->module~rdb_ocean_fold module~rdb_ocean_fold_exchange->module~rdb_ocean_status module~rdb_ocean_fold_exchange->pic_mpi_lib module~rdb_ocean_fold_plan rdb_ocean_fold_plan module~rdb_ocean_fold_exchange->module~rdb_ocean_fold_plan module~rdb_ocean_halo_counters->iso_fortran_env module~rdb_ocean_halo_counters->pic_strings module~rdb_ocean_pgf_reconstruct->module~rdb_constants module~rdb_ocean_pgf_reconstruct->module~rdb_eos module~rdb_ocean_tide_astro->iso_fortran_env module~rdb_ocean_tide_astro->module~rdb_constants module~rdb_recon_weno->module~rdb_constants module~rdb_recon_weno->module~rdb_grid module~rdb_remap_column->module~rdb_constants module~rdb_scratch_3d->iso_fortran_env module~rdb_scratch_3d->module~rdb_constants module~rdb_scratch_3d->module~rdb_mem_report module~rdb_tracer->iso_fortran_env module~rdb_tracer->module~rdb_constants module~rdb_tracer->module~rdb_grid module~rdb_tracer->module~rdb_mem_report module~rdb_vcoord->module~rdb_constants module~rdb_vcoord->pic_logger module~rdb_vcoord->pic_strings module~rdb_config->module~rdb_constants module~rdb_config->pic_logger module~rdb_config->pic_strings module~rdb_config->module~rdb_error_ring module~rdb_config->module~rdb_ocean_status module~rdb_config->pic_ascii module~rdb_config->module~rdb_ice_enthalpy module~rdb_ice_init rdb_ice_init module~rdb_config->module~rdb_ice_init module~rdb_nml_schema rdb_nml_schema module~rdb_config->module~rdb_nml_schema module~rdb_ice_enthalpy->module~rdb_constants module~rdb_ice_mass->module~rdb_constants module~rdb_ice_mass->module~rdb_ice_enthalpy module~rdb_ice_optics->module~rdb_constants module~rdb_ice_optics->module~rdb_ice_enthalpy module~rdb_ice_init->module~rdb_constants module~rdb_ice_init->module~rdb_grid module~rdb_ice_init->module~rdb_multilayer_state module~rdb_ice_init->module~rdb_ocean_metrics module~rdb_ice_init->module~rdb_ice_column module~rdb_ice_init->module~rdb_ice_state module~rdb_ice_init->module~rdb_ice_enthalpy module~rdb_nml_schema->module~rdb_constants module~rdb_nml_schema->pic_logger module~rdb_nml_schema->module~rdb_error_ring

Used by

  • module~~rdb_ocean_dyn~~UsedByGraph module~rdb_ocean_dyn rdb_ocean_dyn module~rdb_driver rdb_driver module~rdb_driver->module~rdb_ocean_dyn module~rdb_ocean_engine rdb_ocean_engine module~rdb_driver->module~rdb_ocean_engine module~rdb_ocean_state rdb_ocean_state module~rdb_driver->module~rdb_ocean_state module~rdb_ocean_api rdb_ocean_api module~rdb_ocean_api->module~rdb_ocean_dyn module~rdb_ocean_api->module~rdb_ocean_engine module~rdb_handle rdb_handle module~rdb_ocean_api->module~rdb_handle module~rdb_ocean_diag_derived rdb_ocean_diag_derived module~rdb_ocean_api->module~rdb_ocean_diag_derived module~rdb_ocean_diag_fills rdb_ocean_diag_fills module~rdb_ocean_api->module~rdb_ocean_diag_fills module~rdb_ocean_engine->module~rdb_ocean_dyn module~rdb_ocean_setup rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_setup module~rdb_ocean_engine->module~rdb_ocean_state module~rdb_ocean_engine->module~rdb_ocean_diag_derived module~rdb_ocean_engine->module~rdb_ocean_diag_fills module~rdb_ocean_setup->module~rdb_ocean_dyn module~rdb_ocean_setup->module~rdb_ocean_state module~rdb_ocean_state->module~rdb_ocean_dyn module~rdb_handle->module~rdb_ocean_engine module~rdb_handle->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_state module~rdb_ocean_diag_derived->module~rdb_ocean_diag_fills module~rdb_ocean_diag_fills->module~rdb_ocean_state

Variables

Type Visibility Attributes Name Initial
integer, public, parameter :: SPLIT_SCHEME_PRED_CORR = 1

MOM6 predictor-corrector: off-centred predictor at pc_be·dt, slow tendencies on the u_av/h_av step time-means, ONE prognostic update in the corrector, forward-backward gravity-wave pairing. The DEFAULT (&ocean_bt_nml split_scheme = "pred_corr", since 2026-09-14).

Neutrally stable to ω·dt = 2, so it does not have the resting-state growth described above (17 000× less on the same file) and it lifts the internal-wave dt ceiling. It costs about 7 % more wall time per step than ssp_rk2 — not a different order. validate_config refuses it fail-loud outside its v1 envelope (eulerian_z, wet/dry, dt_tracer_advect_ratio > 1) rather than degrading silently; those configurations must pin ssp_rk2.

Was renamed twice. This scheme shipped as "mom6_pc", then briefly as "split_rk2" — a name that collided with dynamics/split_rk2/, the directory holding the outer-loop machinery of BOTH schemes, so it named the family as well as one member. A namelist still carrying EITHER dead spelling fails loud naming pred_corr (nml_enum’s retired list), never silently falls back to a default.

integer, public, parameter :: SPLIT_SCHEME_SSP_RK2 = 0

Two identical stages + SSP average (&ocean_bt_nml split_scheme = "ssp_rk2"). EXPERIMENTAL — a label on the ANSWER, not a deprecation: the path is fully supported, fully tested, and the stability suite runs an ssp_rk2 twin of every case whose namelist does not pin a scheme. It has the widest envelope (every vcoord including eulerian_z, wet/dry, dt_tracer_advect_ratio > 1) and is the only scheme wired through the windowed tracer-advection path, which is why six shipped namelists pin it.

What it costs you, measured. The two-stage average amplifies an internal gravity wave by √(1 + (ω·dt)⁴/4) per step, so it MANUFACTURES energy from a motionless stratified state. On validation_examples/ocean/eady/resting_stratified_channel.nml — a flat-bottomed periodic channel at rest, stably stratified, seeded with ±0.5 mK of noise and then left alone, with NO energy source of any kind — En reaches 2.992E-05 m²/s² by day 25 (7.7 mm/s of current out of nothing) and is still climbing on a 2.5-day e-folding. pred_corr on the identical file holds 1.739E-09 (17 000× less, 83-day e-folding). The cause is the OUTER time splitting and nothing else: substituting the Coriolis form (sadourny_hk, sadourny_energy), the ALE remap (vcoord = sigma) and the PGF form (fv_lite) each moves the answer by < 0.1 % — all three EXONERATED; eady_dT_dz = 0 drops En 119×, and REMOVING the lateral viscosity RAISES it — viscosity damps the mode, it is not its source.

Practically: the error is a gravity-wave-scale numerical noise floor that grows with (ω·dt)⁴, so it is set by how hard you push dt against the internal-wave period. A forced, energetic, viscous configuration runs decades above that floor and never notices it; a quiescent, weakly-damped or long spin-up one does, and there the manufactured energy IS the signal. Carried as a scoped XFAIL on resting_stratified_channel__ssp_rk2.

real(kind=wp), public, save :: bcdiag_S_ref = 35.0_wp
logical, public, save :: bcdiag_enabled = .false.
integer, public, save :: bcdiag_step_limit = 2

Probe only the first bcdiag_step_limit outer steps (keeps trace bounded).


Derived Types

type, public ::  ocean_dyn_t

Components

Type Visibility Attributes Name Initial
logical, public :: accel_visc_rem = .false.

MOM6 MOM_dynamics_split_RK2 parity: attenuate the slow EXPLICIT accelerations by the per-layer viscous remnant — u_new = u_entry + visc_rem·(u_applied − u_entry) after the CorAdv/PGF/hvisc/drag applies, before the BT correction — so friction-dominated near-massless layers cannot receive a full-strength dt·F kick (the 2026-07-28 forensics: explicit force × dt on outcropped mm-layers is the dt=800 blow-up injector; the fold/vdiff mopped ±30 m/s per stage until escape). &ocean_vdiff_nml accel_visc_rem — RETIRED (D1 follow-up): no MOM6 state-update equivalent, fail-loud at configure. Default off ⇒ bit-identical. Split path only (v1).

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

Phase-2/3 copy of cfg%ocean%isopycnal%angstrom_h (m). Used to compute isopycnal_vanish_tol for the reset and CFL gates; 0 ⇒ off ⇒ bit-identical.

real(kind=wp), public, allocatable :: avr_u0(:,:,:)
real(kind=wp), public, allocatable :: avr_v0(:,:,:)

accel_visc_rem stage-entry velocity snapshots. Eagerly allocated at setup (configure_ocean_bt) and device-mapped in ocean_dyn_enter_data_impl — but ONLY when the accel_visc_rem knob is on (unallocated / zero-footprint on the default-off path); released in destroy/exit_data.

integer, public :: bt_halo = 0

Wide-halo march-in width (0 = per-substep v1, bit-identical). Set by ocean_dyn_enable_bt_wide after init and enter_data.

integer, public :: bt_nonfin_step = 0

Faces whose BT-correction Δ was non-finite this stage (fold write skipped; pdc 2d5338f9). 0 on a healthy run.

type(bt_wide_t), public, allocatable :: bt_wide

Wide shadow state; allocated only when bt_halo > 0.

type(barotropic_workstate_t), public :: bt_work
logical, public :: cfl_ignore_vanished = .false.

Phase 3: when .true. AND vcoord is VCOORD_LAGRANGIAN, pass vanish_tol to compute_max_cfl and apply_velocity_truncation so vanished-layer face spikes are excluded from MaxCFL / panic and are zeroed (not CFL-clipped) by truncation.

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

Max realised inner CFL within the last outer step.

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

Realised outer CFL (diagnostic).

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

Advective-CFL truncation threshold (nondim). When > 0, any face whose |u|·dt/dx exceeds it is clipped to 0.9·cfl_trunc·dx/dt (sign preserved), then the maxvel cap is applied. 0 = off (bit-identical).

logical, public :: check_h_positive = .false.

DEBUG copy of cfg%ocean%isopycnal%check_h_positive. When .true., check_h_positive_or_die runs after each h_layer- writing stage and aborts on the first negative thickness, naming the stage. .false. ⇒ never called ⇒ bit-identical.

type(chksum_probe_t), public :: chksum_probe

MOM6-style per-phase field checksums + HOTFACE argmax rows (&ocean_debug_nml chksum + step window). Default off ⇒ bit-identical; when on, waits the device + reduces at each phase seam — the first-diverging-operator attribution probe.

logical, public :: debug_bt_budget = .false.

When .true., calls the BT-budget probe once per RK2 stage after the slow tendencies. Heavy (D->H transfers + prints). Default .false.; driven by ocean_debug_bt_budget namelist.

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

Inner barotropic substep length (s).

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

Outer baroclinic timestep length (s).

integer, public :: dt_therm_ratio = 1

Tracer/thermo step runs every dt_therm_ratio outer steps with effective dt = ratio · dt. 1 (default) = every step (bit-identical). Applies only when enable_thermodynamics.

integer, public :: dt_tracer_advect_ratio = 1

MOM6 DT_TRACER_ADVECT analogue. Horizontal tracer advection fires every dt_tracer_advect_ratio outer steps over the accumulated face transports (continuity_t%uhtr/vhtr). 1 (default) ⇒ every-step path verbatim (bit-identical). Configure requires dt_therm_ratio to be an integer multiple so the ALE remap never fires mid-accumulation-window.

logical, public :: enable_thermodynamics = .true.

Mirrors MOM6 ENABLE_THERMODYNAMICS. When .false. the step skips EOS, tracer hdiff, tracer vertical advection/diffusion, KPP non-local transport, and surface tracer flux. Tracers still advect horizontally but with alpha_T = beta_S = 0 can’t influence dynamics ⇒ adiabatic. Wire via &ocean_setup_nml ocean_enable_thermodynamics.

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

Exponential growth rate of the surface value (1/s), set by configure_ocean_tracers from &ocean_tracers_nml ideal_age_sfc_growth_rate. 0 (default) ⇒ young_val constant ⇒ no exp() ⇒ bit-identical.

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

Surface-band age value (s), set by configure_ocean_tracers from &ocean_tracers_nml ideal_age_young_val. 0 (default) = today’s hard-coded zero reset ⇒ bit-identical.

logical, public :: is_init = .false.

True between init and destroy. Prefer this to allocated(...) — tracks GPU device attachment too.

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

Total kinetic energy after the last outer step (diagnostic).

type(ke_probe_t), public :: ke_probe

Per-segment layer-KE attribution meter (&ocean_debug_nml ke_attr). Default off ⇒ bit-identical; when on, serialises the async velocity-apply chain (device waits + one reduction per segment) — debug only.

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

When > 0, face velocities are clipped to [-maxvel, +maxvel] after each outer step (safety net, not a fix). 0 = off.

integer, public :: n_inner = 0

Number of barotropic substeps per outer baroclinic step (0 = “auto, derived from CFL”).

integer, public :: n_nanzero_step = 0

Non-finite (NaN/Inf) face velocities zeroed by the truncation’s NaN-catch in the most recent outer step. MUST be 0 on a healthy run; any non-zero is a producer 0/0 upstream (loud — NaNs used to launder to ±maxvel silently, pdc 8c2fd674).

integer(kind=int64), public :: n_nanzero_total = 0_int64

Cumulative NaN-catch count over the run.

integer, public :: ntrunc_step = 0

Face components CFL-truncated in the most recent outer step (host-scalar reduction; reset each apply_velocity_truncation).

integer, public :: ntrunc_total = 0

Cumulative CFL-truncation count over the run (driver logs it).

integer, public :: outer_step_count = 0

Outer (baroclinic) step counter.

real(kind=wp), public :: pc_be = 0.6_wp

pred_corr predictor fraction (MOM6 BE, 0.6 in the control run): the predictor advances the provisional velocity to dt_pred = pc_be·dt (SPEC §2 P8); only the corrector takes the full step. Unused under ssp_rk2.

logical, public :: poison_ghosts = .false.

When .true., sentinel-NaN the exchange-covered ghost bands at each outer-step start (before any exchange or kernel). Any kernel consuming an unexchanged ghost produces a loud NaN at that step. Default .false. = bit-identical (untaken branch per step). Driven by &ocean_mpi_nml poison_ghosts via rdb_ocean_setup. Requires the bc optional argument (edge topology); no-op when bc is absent.

logical, public :: reset_vanished_u = .false.

Phase 2: when .true. AND vcoord is VCOORD_LAGRANGIAN, call reset_vanished_layer_velocities after each mask_layer_velocities (per-stage + RK2-averaged site) to zero face velocities where BOTH adjacent cell-thicknesses are at or below isopycnal_vanish_tol(angstrom_h).

integer, public :: split_scheme = SPLIT_SCHEME_PRED_CORR

Outer time-scheme selector (see the module constants). Kept in step with the &ocean_bt_nml split_scheme default in rdb_config.F90 — ocean_setup assigns this field from the config on BOTH branches (rdb_ocean_setup.F90, “SPEC S3”), so no production run reads this value, but a bare ocean_dyn_t built by a unit test inherits it and a divergence would have the Fortran suite exercising a scheme the model does not ship by default. The two have diverged before; change them in the same commit.

Read more…

Type-Bound Procedures

procedure, public, non_overridable :: bytes => ocean_dyn_bytes
procedure, public, non_overridable :: destroy => ocean_dyn_destroy
procedure, public, non_overridable :: enter_data => ocean_dyn_enter_data
procedure, public, non_overridable :: exit_data => ocean_dyn_exit_data
procedure, public, non_overridable :: init => ocean_dyn_init
procedure, public, non_overridable :: is_thermo_step => ocean_dyn_is_thermo_step
procedure, public, non_overridable :: is_tracer_advect_step => ocean_dyn_is_tracer_advect_step
procedure, public, non_overridable :: therm_dt => ocean_dyn_therm_dt

Functions

public pure function isopycnal_vanish_tol(angstrom_h, pd_floor) result(tol)

Shared vanish-tolerance for Phase-2/3 kernels: the layer is considered vanished when its thickness is at or below this value. Defined as max(angstrom_h, H_VANISHED) so both the physical floor (Phase 1) and the skip/merge marker are covered by a single threshold. Providing this as a pure helper ensures Phase 2 (reset_vanished_layer_velocities) and Phase 3 (apply_velocity_truncation gate + compute_max_cfl gate) cannot drift in their vanish definition.

Read more…

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: angstrom_h

Phase-1 floor (m); 0.0 when Phase 1 is off.

logical, intent(in), optional :: pd_floor

When .true. AND angstrom_h > H_VANISHED: lift the tolerance to angstrom_h + H_VANISHED (above the PD floor).

Return Value real(kind=wp)

public pure function ocean_dt_tracer_advect_ratios_ok(dt_therm_ratio, dt_tracer_advect_ratio) result(ok)

Configure-time validity of the (dt_therm_ratio, dt_tracer_advect_ratio) pair. Both must be >= 1 and dt_therm_ratio must be an integer multiple of dt_tracer_advect_ratio so the ALE remap (which fires at the DT_THERM cadence) never lands inside an open tracer-flux accumulation window. The setup layer (configure_ocean_vmix) calls this and error stops with a descriptive message on .false.; exposed as a pure predicate so the validation logic is unit-testable without constructing a full ocean state.

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: dt_therm_ratio
integer, intent(in) :: dt_tracer_advect_ratio

Return Value logical

private pure function gm_refreshes_varmix(gm, slopes, dyn) result(refreshes)

.true. when the GM block below this step already calls varmix_compute (GM present + enabled + slopes present, at a thermo step) — so the standalone Gap-1 resolution-function refresh must NOT run it again (avoids a double compute and preserves the GM+VarMix slope ordering bit-for-bit).

Arguments

Type IntentOptional Attributes Name
type(ocean_gm_t), intent(in), optional :: gm
type(ocean_slopes_t), intent(in), optional :: slopes
type(ocean_dyn_t), intent(in) :: dyn

Return Value logical

private pure function lateral_mix_uses_resoln(lateral_mix, varmix) result(uses)

.true. when the lateral-mix compute call should be handed the VarMix resolution-function face fields (Gap 1): the lateral-mix slot is present + initialised with resoln_scaled_visc, AND VarMix is present + enabled (so res_fn_u/v carry a valid, up-to-date resolution function). Either absent / off ⇒ unscaled coefficients (bit-identical).

Arguments

Type IntentOptional Attributes Name
type(ocean_lateral_mix_t), intent(in), optional :: lateral_mix
type(ocean_varmix_t), intent(in), optional :: varmix

Return Value logical

private pure function ocean_dyn_bytes(this) result(nbytes)

Counted allocatable footprint of the split-RK2 driver (BT work state + wide-halo shadow state) slot (0 when unallocated).

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(in) :: this

Return Value integer(kind=int64)

private pure function ocean_dyn_is_thermo_step(this) result(yes)

Returns .true. if the thermodynamic / tracer kernels should fire on this outer step. dt_therm_ratio <= 1 (default) → always true (every step is a thermo step, bit-identical to prior behaviour). ratio >= 2 → fires every Nth step, aligned to outer_step_count = 0 for the IC snapshot.

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(in) :: this

Return Value logical

private pure function ocean_dyn_is_tracer_advect_step(this) result(yes)

Returns .true. when the windowed horizontal tracer-advect drain should fire on the current outer step, evaluated with the PRE-increment outer_step_count so it aligns bit-for-bit with is_thermo_step() (which gates the ALE remap on the same count).

Read more…

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(in) :: this

Return Value logical

private pure function ocean_dyn_therm_dt(this, dt) result(dt_th)

Effective dt for the thermo / tracer kernels. When dt_therm_ratio = 1 returns dt exactly; otherwise returns ratio · dt, since the kernels only fire every Nth step and must advance by that aggregate interval.

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(in) :: this
real(kind=wp), intent(in) :: dt

Return Value real(kind=wp)


Subroutines

public subroutine accel_visc_rem_reweight(n1, n2, n3, snap, rem, vel)

accel_visc_rem post-apply reweight: vel = snap + rem·(vel − snap) — the whole explicit-tendency sum accumulated since the snapshot is attenuated by the per-layer viscous remnant (linearity ⇒ identical to weighting each tendency individually, MOM6 u = u_init + dt·visc_rem· (CAu + PFu + diffu)). Faces with rem == 1 (the unconditioned source=1.0 init, and every face before the first vdiff fills the producer) are SKIPPED, not rewritten — snap + 1·(vel−snap) is not an FP identity, and the skip keeps rem≡1 bitwise inert. Friction-dominated near-massless layers (rem → 0) keep their entry velocity. Public only for the unit-test suite. Under mem:separate this do concurrent runs on the device-resident arrays in production (all mapped on the ocean state); unit tests must map their own arrays explicitly. The masked write stays inside the do concurrent body (legal — no cross-iteration dep).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n1
integer, intent(in) :: n2
integer, intent(in) :: n3
real(kind=wp), intent(in) :: snap(n1,n2,n3)
real(kind=wp), intent(in) :: rem(n1,n2,n3)
real(kind=wp), intent(inout) :: vel(n1,n2,n3)

public subroutine accel_visc_rem_snapshot(n1, n2, n3, vel, snap)

accel_visc_rem stage-entry snapshot: snap = vel, device-side. Public only for the unit-test suite. Under mem:separate this do concurrent runs on the device-resident arrays in production (both are mapped on the ocean state); unit tests must map their own arrays explicitly (!$acc enter data copyin / update self).

Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: n1
integer, intent(in) :: n2
integer, intent(in) :: n3
real(kind=wp), intent(in) :: vel(n1,n2,n3)
real(kind=wp), intent(out) :: snap(n1,n2,n3)

public subroutine apply_velocity_truncation(ms, metrics, dt, cfl_trunc, maxvel, ntrunc_step, vanish_tol, n_nanzero, clip_cell_metric, nan_i, nan_j, nan_k, nan_is_u, nan_dx, nan_visc_cfl, nu_h)

Post-RK2 velocity housekeeping: the advective-CFL truncation (E7) followed by the absolute maxvel cap. Called once at the end of each outer step (after the RK2 average, before the ALE remap) so the carried-forward / remapped velocity field is bounded. Replaces the bare apply_maxvel_clamp call at both ocean_dyn_step / ocean_dyn_step_split sites.

Read more…

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms
type(ocean_metrics_t), intent(in) :: metrics
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(in) :: cfl_trunc
real(kind=wp), intent(in) :: maxvel
integer, intent(out) :: ntrunc_step
real(kind=wp), intent(in), optional :: vanish_tol

When present (> 0): zero both-sided-vanished faces before the CFL clip. Absent / 0 ⇒ skip ⇒ bit-identical.

integer, intent(out), optional :: n_nanzero

Count of non-finite (NaN/Inf) face velocities zeroed by the step -1 NaN-catch this call. A non-finite velocity is a producer bug (a 0/0 upstream); it MUST be caught here so it can never launder to ±maxvel (nvfortran lowers the `if(u>hi)…else if(u

logical, intent(in), optional :: clip_cell_metric

When present AND .true.: the CFL clip bounds each face on the CELL metric max(idxT(i-1,j), idxT(i,j)) (v: idyT) — the SAME metric the console panic / compute_max_cfl uses — instead of the face metric idxCu/idyCv (pdc 6991988f). Guarantees the panic-visible CFL is bounded even where the face metric is anomalous at a grounding face (|u|·dt·idxCu ≤ cfl_trunc while |u|·dt·idxT > cfl_trunc — the θ-edge escape; measured at 1024²/dt=800 as MaxCFL 0.689 sailing past a 0.5 ceiling). Bit-identical on grids where idxCu == idxT. Absent / .false. ⇒ face metric ⇒ bit-identical.

integer, intent(out), optional :: nan_i

Grid location (local, including ghosts) of the FIRST non-finite face this call caught, in (k,j,i)-ascending scan order — actionable in place of the old bare count (“producer 0/0 upstream — investigate”; FINDINGS.md’s global-tripolar-aquaplanet debugging session had nothing better to go on). 0 when n_nanzero is absent/0 (nothing to report) or when none of these outputs were requested (the search is skipped entirely — see nan_dx/nan_visc_cfl).

integer, intent(out), optional :: nan_j

Grid location (local, including ghosts) of the FIRST non-finite face this call caught, in (k,j,i)-ascending scan order — actionable in place of the old bare count (“producer 0/0 upstream — investigate”; FINDINGS.md’s global-tripolar-aquaplanet debugging session had nothing better to go on). 0 when n_nanzero is absent/0 (nothing to report) or when none of these outputs were requested (the search is skipped entirely — see nan_dx/nan_visc_cfl).

integer, intent(out), optional :: nan_k

Grid location (local, including ghosts) of the FIRST non-finite face this call caught, in (k,j,i)-ascending scan order — actionable in place of the old bare count (“producer 0/0 upstream — investigate”; FINDINGS.md’s global-tripolar-aquaplanet debugging session had nothing better to go on). 0 when n_nanzero is absent/0 (nothing to report) or when none of these outputs were requested (the search is skipped entirely — see nan_dx/nan_visc_cfl).

logical, intent(out), optional :: nan_is_u

.true. if the first non-finite face was a u-face (u_face_x_layer), .false. if a v-face. Only meaningful when nan_i/nan_j/nan_k were actually found (n_nan > 0 AND the location search ran).

real(kind=wp), intent(out), optional :: nan_dx

Local cell size (m) at (nan_i, nan_j) — 1/max(idxT(i-1,j), idxT(i,j)) (v-face: idyT analogue), the SAME cell metric clip_cell_metric uses. Cheap (one extra metrics read at the single located cell, not a scan) — always computed alongside the location when a location was found.

real(kind=wp), intent(out), optional :: nan_visc_cfl

Local viscous CFL nu_h*dt/nan_dx^2 at the located cell — only computed when nu_h is supplied (the caller’s ocean_horizontal_viscosity_t%nu_h); 0 otherwise. Mirrors rdb_ocean_stability_audit’s configure-time check, evaluated HERE at the exact runtime location the NaN was caught, so a user reading the message can immediately see whether an under-resolved viscous CFL is the likely producer.

real(kind=wp), intent(in), optional :: nu_h

Constant horizontal viscosity (m^2/s), for nan_visc_cfl only. Absent ⇒ nan_visc_cfl (if requested) is 0.

public subroutine ocean_dyn_enable_bt_wide(dyn, grid, dx, dy, lon_west, lat_south, rad_earth, grid_config_str, f_0, beta, y_ref, coriolis_scheme_str, omega)

Allocate, initialise, and GPU-attach the wide-halo shadow state from dyn%bt_halo (already set by the caller).

Read more…

Arguments

Type IntentOptional Attributes Name
type(ocean_dyn_t), intent(inout) :: dyn

Dynamics state; bt_halo must be set before calling.

type(hgrid_t), intent(in) :: grid

Normal-width grid for this subdomain.

real(kind=wp), intent(in) :: dx

Cell spacing (m for Cartesian; deg for spherical).

real(kind=wp), intent(in) :: dy

Cell spacing (m for Cartesian; deg for spherical).

real(kind=wp), intent(in) :: lon_west

Spherical-grid parameters (ignored for Cartesian).

real(kind=wp), intent(in) :: lat_south

Spherical-grid parameters (ignored for Cartesian).

real(kind=wp), intent(in) :: rad_earth

Spherical-grid parameters (ignored for Cartesian).

character(len=*), intent(in) :: grid_config_str

Grid-config string (e.g. “cartesian”, “spherical”).

real(kind=wp), intent(in) :: f_0

Beta-plane Coriolis parameters.

real(kind=wp), intent(in) :: beta

Beta-plane Coriolis parameters.

real(kind=wp), intent(in) :: y_ref

Beta-plane Coriolis parameters.

character(len=*), intent(in) :: coriolis_scheme_str

Coriolis-scheme string (e.g. “beta_plane”).

real(kind=wp), intent(in), optional :: omega

Planetary rotation rate (1/s) for coriolis_scheme = "planetary" (&ocean_grid_nml omega). Absent => 0, which is only right for the beta plane: the wide clone’s planetary f used to be built with omega = 0, i.e. a non-rotating barotropic fast loop.

public subroutine ocean_dyn_flush_tracer_window(grid, metrics, dyn, ct, ms, bc)

Mandatory end-of-segment flush of the windowed tracer-advect accumulators (spec §(c) — MOM6’s n == n_max). Drains any OPEN accumulation window (t_dyn_rel_adv > 0) so no Lagrangian-advanced h_layer is ever paired with FROZEN hTr at an output write, a restart checkpoint, or the end of a run segment whose length is not an exact multiple of dt_tracer_advect_ratio.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_dyn_t), intent(in) :: dyn
type(continuity_t), intent(inout) :: ct
type(multilayer_state_t), intent(inout) :: ms
type(ocean_bc_state_t), intent(in), optional :: bc

public subroutine ocean_dyn_step(grid, metrics, dyn, eos, cor, ct, pgf, hv, bd, ss, va, hd, vd, vmix, ms, dt, sf, geo, lateral_mix, epbl, kshear, slopes, vmix_tidal, bc, t, td, cav)

Multilayer extension of ocean_dyn_step_barotropic. One SSP-RK2 outer step that orchestrates the full per-layer dynamical core:

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics

Curvilinear horizontal metrics — forwarded to the PGF (and, in slice 2, the other geometry-aware kernels).

type(ocean_dyn_t), intent(inout) :: dyn
type(eos_t), intent(in) :: eos
type(coriolis_adv_t), intent(inout) :: cor
type(continuity_t), intent(inout) :: ct
type(ocean_pressure_force_t), intent(inout) :: pgf
type(ocean_horizontal_viscosity_t), intent(inout) :: hv
type(ocean_bottom_drag_t), intent(inout) :: bd
type(ocean_surface_stress_t), intent(inout) :: ss
type(ocean_vertical_advection_t), intent(inout) :: va
type(ocean_hdiff_tracer_t), intent(inout) :: hd
type(ocean_vdiff_t), intent(inout) :: vd
type(ocean_vmix_t), intent(inout) :: vmix
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
type(ocean_surface_flux_t), intent(in), optional :: sf
type(ocean_geothermal_t), intent(in), optional :: geo

Geothermal bottom-heat-flux slot. Absent or enable=.false. preserves the historical no-geothermal path bit-identically.

type(ocean_lateral_mix_t), intent(inout), optional :: lateral_mix
type(ocean_epbl_t), intent(inout), optional :: epbl

Energetics-based PBL slot. Absent or enable=.false. preserves the historical PP81/KPP path bit-identically.

type(ocean_kappa_shear_t), intent(inout), optional :: kshear

Kappa-shear interior closure slot. Absent or enable=.false. preserves the historical path bit-identically.

type(ocean_slopes_t), intent(inout), optional :: slopes

Isopycnal-slope diagnostic slot. Absent or enable=.false. preserves the historical path bit-identically (diagnostic only — never feeds back into prognostics).

type(ocean_tidal_mixing_t), intent(inout), optional :: vmix_tidal

Tidal-mixing interior closure slot. Absent or enable=.false. preserves the historical path bit-identically.

type(ocean_bc_state_t), intent(in), optional :: bc

Boundary state — forwarded ONLY to the windowed tracer-advect drain so its single-rank periodic-x / north-fold seam wraps fire for periodic unsplit runs at dt_tracer_advect_ratio > 1. Absent ⇒ wall seams (the historical unsplit default); ratio = 1 never drains so this is inert there (bit-identical).

real(kind=wp), intent(in), optional :: t

Model time (s) since run start, used to evaluate the ideal-age vintage-mode surface value (PR-7). Mirrors the split driver’s t dummy (ocean_dyn_step_split). Absent ⇒ t = 0.

type(ocean_top_drag_t), intent(inout), optional :: td

Ice-shelf TOP-drag slot (&ocean_tdrag_nml). OPTIONAL so the many direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn; the production driver always passes it. Absent, or present and disabled, => no kernel launch and a bit-identical step.

type(ocean_cavity_flux_t), intent(inout), optional :: cav

Ice-shelf basal-melt slot (&ocean_cavity_melt_nml). OPTIONAL for the same reason td is: the direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn, and the production driver always passes it. Absent, disabled, or freshwater="virtual" => no kernel launch and a bit-identical step. It is threaded down here rather than acted on in engine_step_finalize because the real-freshwater volume must be spent in the SAME stage, at the SAME stage weight and from the SAME melt value as the salt and heat halves the surface-flux apply spends – see ocean_cavity_mass_step’s docstring.

public pure subroutine ocean_dyn_step_barotropic(grid, metrics, dyn, cor, ct, bs, dt)

Public only for the unit-test suite (no production module imports it); ignore when developing production code in other modules. Unsplit SSP-RK2 (Heun’s method) outer step on the barotropic C-grid state. Couples continuity-PPM (h-update) and the Sadourny Coriolis-advection tendency (u, v update) into one second-order-accurate step.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_dyn_t), intent(inout) :: dyn
type(coriolis_adv_t), intent(inout) :: cor
type(continuity_t), intent(inout) :: ct
type(barotropic_state_t), intent(inout) :: bs
real(kind=wp), intent(in) :: dt

public subroutine ocean_dyn_step_split(grid, metrics, dyn, eos, cor, ct, pgf, hv, bd, ss, va, hd, vd, vmix, ms, dt, n_inner, sf, geo, vcoord, bc, sp, t, lateral_mix, epbl, kshear, mle, slopes, gm, varmix, wavespeed, redi, meke, vmix_tidal, tides, psurf, td, cav)

Split-explicit SSP-RK2 outer step on the multilayer state. Parallel to ocean_dyn_step (the unsplit driver still ships for tests + reference). Phase 4b-MVP scope: gravity-wave-stability fix on momentum only. ALE-aware h_layer redistribution and full nonlinear-bt corrections are deferred to a follow-up branch.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics

Curvilinear horizontal metrics — forwarded to the PGF (and, in slice 2, the other geometry-aware kernels).

type(ocean_dyn_t), intent(inout) :: dyn
type(eos_t), intent(in) :: eos
type(coriolis_adv_t), intent(inout) :: cor
type(continuity_t), intent(inout) :: ct
type(ocean_pressure_force_t), intent(inout) :: pgf
type(ocean_horizontal_viscosity_t), intent(inout) :: hv
type(ocean_bottom_drag_t), intent(inout) :: bd
type(ocean_surface_stress_t), intent(inout) :: ss
type(ocean_vertical_advection_t), intent(inout) :: va
type(ocean_hdiff_tracer_t), intent(inout) :: hd
type(ocean_vdiff_t), intent(inout) :: vd
type(ocean_vmix_t), intent(inout) :: vmix
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
integer, intent(in) :: n_inner
type(ocean_surface_flux_t), intent(in), optional :: sf
type(ocean_geothermal_t), intent(in), optional :: geo

Geothermal bottom-heat-flux slot. Absent or enable=.false. preserves the historical no-geothermal path bit-identically.

type(ocean_vcoord_t), intent(inout), optional :: vcoord

Vertical-coordinate state. When present and vcoord%coord_type /= VCOORD_EULERIAN_Z, the orchestrator runs the ALE remap step after the RK2 average (Lagrangian- then-remap pattern, MOM6-style). Absent or EULERIAN_Z preserves the pre-existing Eulerian-z behaviour bit- identically.

type(ocean_bc_state_t), intent(inout), optional :: bc

Open-boundary config. Absent or all-OBC_WALL preserves the closed-wall behaviour bit-identically (the barotropic substep’s tag dispatch falls through to hard-zero). When any edge is non-WALL, the corresponding BC variant fires inside the barotropic substep’s per-substep wall closure.

type(ocean_sponge_t), intent(in), optional :: sp

Map-driven sponge slot (PR-23). Absent or enable=.false. (default) preserves the legacy bc-band sponge path bit- identically; enable=.true. supersedes it (exactly one of the two runs — see run_stage_split’s dispatch).

real(kind=wp), intent(in), optional :: t

Wall-clock time at the start of this outer step (s), used to evaluate the OBC_TIDAL constituent table.

type(ocean_lateral_mix_t), intent(inout), optional :: lateral_mix

Flow-aware lateral-viscosity closure (Leith / Smagorinsky). Absent or closure = LMIX_NONE falls through to the scalar nu_h in hv, bit-identically.

type(ocean_epbl_t), intent(inout), optional :: epbl

Energetics-based PBL slot. Absent or enable=.false. preserves the historical PP81/KPP path bit-identically.

type(ocean_kappa_shear_t), intent(inout), optional :: kshear

Kappa-shear interior closure slot. Absent or enable=.false. preserves the historical path bit-identically.

type(ocean_mle_t), intent(inout), optional :: mle

Fox-Kemper MLE slot (B5). Absent or enable=.false. preserves bit-identity. Transports are computed once per outer step at THERMO cadence (from the prior step’s epbl%mld) and folded into the continuity mass fluxes in both RK2 stages.

type(ocean_slopes_t), intent(inout), optional :: slopes

Isopycnal-slope diagnostics slot. Refreshed at THERMO cadence (the split driver otherwise never calls ocean_slopes_compute) so the GM slot has a fresh slope to consume. Absent or disabled ⇒ no-op.

type(ocean_gm_t), intent(inout), optional :: gm

Gent-McWilliams thickness-diffusion slot (capability [2]). Absent or enable=.false. preserves bit-identity. Its slopes / VarMix / MEKE inputs refresh at THERMO cadence at the top of the step; the bolus transport itself is computed from the post-dynamics thickness and applied as its own sequential operator EVERY outer step after the stage loop (run_gm_step, MOM6 thickness_diffuse after step_MOM_dyn_split_RK2).

type(ocean_varmix_t), intent(inout), optional :: varmix

VarMix slot (capability [4]): spatially-varying GM/Redi coefficients. When present + enable=.true. (and wavespeed present) varmix_compute fills the pre-CFL base khth_u/v at THERMO cadence BEFORE GM, and GM consumes them as its external base. Absent or disabled ⇒ GM uses its scalar khth ⇒ bit-identity.

type(ocean_wave_speed_t), intent(inout), optional :: wavespeed

Wave-speed slot supplying cg1 to the VarMix resolution function. Only read when varmix is active.

type(ocean_redi_t), intent(inout), optional :: redi

Redi continuous neutral-diffusion slot (capability [3]). Absent or enable=.false. preserves bit-identity. Phase-A neutral- surface coefficients are computed ONCE per outer step at THERMO cadence here (tracer-independent geometry); Phase B applies the rotated flux per tracer inside run_stage_split after the along-coordinate tracer_hdiff.

type(ocean_meke_t), intent(inout), optional :: meke

MEKE prognostic eddy-energy slot (capability [5]). Stepped once per outer step at THERMO cadence right after varmix_compute: it reads gm%gm_src from the PREVIOUS outer step’s GM operator (one-step lag; gm_src is restart-registered) and feeds the geom-mean of its derived kh into varmix%khth_u/v (+ khtr), which this step’s GM operator CFL-clamps after the dynamics. Absent or enable=.false. ⇒ no-op (bit-identical).

type(ocean_tidal_mixing_t), intent(inout), optional :: vmix_tidal

Tidal-mixing interior closure slot. Absent or enable=.false. preserves the historical path bit-identically.

type(ocean_tides_t), intent(inout), optional :: tides

Equilibrium body-force tide slot (C1) + scalar SAL (C2). When present and enable, eta_eq is refreshed ONCE per outer step (held static across the inner substep loop); scalar SAL then folds beta_sal*eta (lagged barotropic SSH) into the combined eta_forcing = eta_eq + eta_sal forwarded to the barotropic PGF. Absent / disabled / use_sal=.false. ⇒ bit-identical.

type(ocean_p_surf_t), intent(inout), optional :: psurf

Atmospheric surface-pressure loading / inverse barometer slot (PR-17). When present and enable, the assembled surface pressure sf%p_surf (read only; Pa) is converted to eta_ib = -p_surf/(rho0 g_bt) ONCE per outer step and folded into eta_seam = eta_ib [+ tide eta_forcing], which then feeds the barotropic PGF in place of the tide-only seam. Requires the PR-12 component set (sf%p_surf) — guarded at configure. Absent / disabled ⇒ bit-identical.

type(ocean_top_drag_t), intent(inout), optional :: td

Ice-shelf TOP-drag slot (&ocean_tdrag_nml). OPTIONAL so the many direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn; the production driver always passes it. Absent, or present and disabled, => no kernel launch and a bit-identical step.

type(ocean_cavity_flux_t), intent(inout), optional :: cav

Ice-shelf basal-melt slot (&ocean_cavity_melt_nml). OPTIONAL for the same reason td is: the direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn, and the production driver always passes it. Absent, disabled, or freshwater="virtual" => no kernel launch and a bit-identical step. It is threaded down here rather than acted on in engine_step_finalize because the real-freshwater volume must be spent in the SAME stage, at the SAME stage weight and from the SAME melt value as the salt and heat halves the surface-flux apply spends – see ocean_cavity_mass_step’s docstring.

public subroutine ocean_porous_refresh(grid, metrics, ms)

Recompute the porous-barrier layer-averaged open-area fractions from the current layer thicknesses. No-op (and untouched placeholder arrays) when &ocean_porous_nml enable is off.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(inout) :: metrics
type(multilayer_state_t), intent(in) :: ms

private pure subroutine apply_maxvel_clamp(ms, maxvel)

Truncate face velocities to |u| ≤ maxvel. MOM6’s MAXVEL analogue. Called once at the end of each outer step (after the RK2 average so the clipped state is what gets carried into the next stage). No-op when maxvel <= 0.

Read more…

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: maxvel

private subroutine apply_sw_and_restore(grid, metrics, sf, ms, therm_dt, therm_active)

The two cell-centred surface kernels that do NOT route through the assembler’s Q_heat / Q_salt, with their ice-shelf-cover dispatch. Shortwave penetration reads a pristine q_sw component (or moves a lump the masked deposit never added) and restoring forms its flux in-kernel from the live SST/SSS, so each needs the cover factor of its own; everything else the atmosphere contributes is already masked inside ocean_surface_flux_assemble.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_surface_flux_t), intent(in), optional :: sf

Forwarded; absent ⇒ both kernels no-op (their own contract).

type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: therm_dt
logical, intent(in) :: therm_active

private subroutine check_h_positive_or_die(grid, ms, label, stage, outer_step, check_layers)

&ocean_isopycnal_nml check_h_positive guard. Abort on the FIRST negative layer thickness, naming the pipeline stage that produced it, the offending (i,j,k), and that column’s full thickness profile.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(inout) :: ms
character(len=*), intent(in) :: label

Pipeline stage that last wrote h_layer (e.g. “after continuity”).

integer, intent(in) :: stage
integer, intent(in) :: outer_step
logical, intent(in) :: check_layers

.true. => also abort on a negative single LAYER. Pass .false. between the raw continuity update and the conservative borrow, where a transiently negative layer is legal; the column-total check runs unconditionally either way.

private subroutine check_remap_preconditions_or_die(grid, vcoord, nz, outer_step)

&vcoord_nml remap_check_preconditions guard (audit findings V5, V6).

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_vcoord_t), intent(in) :: vcoord
integer, intent(in) :: nz

Number of layers (ms%nz_ml).

integer, intent(in) :: outer_step

Outer-step index, for the abort message.

private subroutine check_vanished_invariant_or_die(grid, vcoord, ms, outer_step)

Fail-loud TRIPWIRE for invariant I1′ — h_layer <= H_VANISHED ⇒ hTr = h_layer·c_live (the donor live layer’s concentration; hTr = 0 in a column with no live layer) for every registered tracer. Gated on &vcoord_nml check_vanished_content (default .false.), which is the knob the stability suite turns on for the cases that actually have vanishing layers.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_vcoord_t), intent(in), optional :: vcoord
type(multilayer_state_t), intent(in) :: ms
integer, intent(in) :: outer_step

private pure subroutine copy_field_3d(src, dst, nx, ny, nz)

src -> dst flat copy on the device. Bare-array shim avoids the deep struct deref inside do-concurrent (tracer hTr lives in an array-of-derived-types registry).

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: src(nx,ny,nz)
real(kind=wp), intent(out) :: dst(nx,ny,nz)
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz

private pure subroutine mask_layer_velocities(grid, metrics, ms, bt_work)

Zero the per-layer face velocities at land faces (spec §14 C4 / R4(b.2) / MOM6 up = mask2dCu·(u+dt·accel)). Runs once per RK2 stage AFTER apply_bt_correction and inside the RK2 average so the additive layer tendencies + the BT correction cannot leave a re-ingested land-face velocity (a slow conservation leak). The transports themselves already ride zeroed metrics; this resets the prognostic velocity so derive_bt_from_layers next step sees zero there. All-wet ⇒ wet_u/v≡1 ⇒ literal no-op.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(multilayer_state_t), intent(inout) :: ms
type(barotropic_workstate_t), intent(in), optional :: bt_work

private pure subroutine mask_time_mean_velocities(metrics, ms)

Apply the land contract of mask_layer_velocities — static wet_u/wet_v, times the z-level open_u/open_v when zfixed_closed_faces is on — to the pred_corr time-mean velocities u_av/v_av. Called once, on the step-0 seed: the renormaliser’s u_cor, their only other writer, never writes a masked face, so what the seed leaves there is what every later step reads. (Wet/dry is refused under pred_corr, so its dynamic mask has no branch here.) All-wet, knob off ⇒ products with exactly 1, i.e. byte-identical.

Arguments

Type IntentOptional Attributes Name
type(ocean_metrics_t), intent(in) :: metrics
type(multilayer_state_t), intent(inout) :: ms

private subroutine ocean_accumulate_mass_out(ms, flux_h_layer, areaT, nghost, dt, weight)

Accumulate the net mass (kg) that left the domain this RK stage into ms%mass_out. flux_h_layer is the total horizontal divergence (h_layer -= dt·flux_h_layer), so -Σ_interior(−flux_h_layer)·areaT is the boundary outflux (interior faces telescope — divergence theorem), and it is the SAME field the thickness update consumes, so with the RK2 stage weight this closes the mass budget to round-off.

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: flux_h_layer(:,:,:)
real(kind=wp), intent(in) :: areaT(:,:)
integer, intent(in) :: nghost
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(in) :: weight

private subroutine ocean_dyn_destroy(this)

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(inout) :: this

private subroutine ocean_dyn_enter_data(this)

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(inout) :: this

private subroutine ocean_dyn_enter_data_impl(this)

Arguments

Type IntentOptional Attributes Name
type(ocean_dyn_t), intent(inout) :: this

private subroutine ocean_dyn_exit_data(this)

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(inout) :: this

private subroutine ocean_dyn_exit_data_impl(this)

Arguments

Type IntentOptional Attributes Name
type(ocean_dyn_t), intent(inout) :: this

private subroutine ocean_dyn_init(this, grid, nz_ml)

Initialise the barotropic working-state slot. Pass nz_ml to also allocate the split-driver slow-tendency accumulators (F_slow_u/v, F_bt_u/v, ubt_at_n/vbt_at_n). Barotropic-substep unit tests can skip the optional argument since they don’t exercise the split-driver coupling.

Arguments

Type IntentOptional Attributes Name
class(ocean_dyn_t), intent(inout) :: this
type(hgrid_t), intent(in) :: grid
integer, intent(in), optional :: nz_ml

private subroutine probe_dS(grid, ms, label, stage, outer_step)

Debug-gated diagnostic. Pulls h_layer + hTr_S from device and prints max|hTr_S/h_layer - bcdiag_S_ref| over interior columns. Early-returns when bcdiag_enabled = .false. or after bcdiag_step_limit outer steps have completed.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(inout) :: ms
character(len=*), intent(in) :: label
integer, intent(in) :: stage
integer, intent(in) :: outer_step

private subroutine probe_h_vs_eta_residual(grid, ms, bt_work, stage, outer_step)

Debug probe: print max|sum_k(h_layer) - (H_ref + bt_eta_end)| over interior cells. In Eulerian-z this is forced to zero by apply_bt_correction’s h-rescale. In Lagrangian mode the rescale is skipped, so this residual is what the slow continuity actually drifts to (expected to be FP). Watching how it grows over time across many outer steps is what pins down whether the long-run momentum NaN is FP accumulation in sum_k(h_layer) - H - bt_eta_end.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(inout) :: ms
type(barotropic_workstate_t), intent(in) :: bt_work
integer, intent(in) :: stage
integer, intent(in) :: outer_step

private subroutine refresh_tracer_ghosts(grid, ms, bc)

Re-fill every tracer’s ghost band from its owners: the halo exchange (MPI seams, and the local periodic wrap on an undecomposed periodic axis — the halo primitive does both), then the tripolar north fold on the rank that owns it. Thickness and velocity are left alone. Collective (every rank calls it).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(multilayer_state_t), intent(inout) :: ms
type(ocean_bc_state_t), intent(in), optional :: bc

private pure subroutine reset_vanished_layer_velocities(ms, vanish_tol)

Zero the per-layer face velocity at any face where BOTH adjacent centre-cell thicknesses are at or below vanish_tol (isopycnal_vanish_tol(angstrom_h) = max(angstrom_h, H_VANISHED)).

Read more…

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: vanish_tol

private pure subroutine restore_state(ms)

Copy the *_0 save buffers back into h_layer / u_face_x_layer / v_face_y_layer — the pred_corr between-stage reset (SPEC §2): the predictor’s provisional up/vp/hp are DISCARDED (only u_av/v_av/ h_av survive it), and the corrector advances from u^n / h^n. Tracers are untouched by the predictor (TR_MODE_NONE + no thermodynamics), so no tracer restore is needed.

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms

private pure subroutine rk2_average(ms)

State <- 0.5 * (state_0 + state) for h_layer, u_face_x_layer, v_face_y_layer. Tracer averages are done by the caller.

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms

private pure subroutine rk2_average_field_3d(saved, current, nx, ny, nz)

current <- 0.5 * (saved + current) on the device. Same bare-array shim rationale as copy_field_3d.

Arguments

Type IntentOptional Attributes Name
real(kind=wp), intent(in) :: saved(nx,ny,nz)
real(kind=wp), intent(inout) :: current(nx,ny,nz)
integer, intent(in) :: nx
integer, intent(in) :: ny
integer, intent(in) :: nz

private subroutine run_continuity_chain(grid, metrics, dyn, ct, hd, va, redi, varmix, ms, dt, therm_dt, therm_active, is_lagrangian, h_min_floor, mass_out_weight, h_only, stage_id, step_id, bc, mle)

The slow horizontal continuity + tracer chain (ghost fills → constrained continuity+tracer split → reservoirs → halo/wrap → tracer hdiff → Redi → vertical advection), extracted verbatim from run_stage_split so the pred_corr path can run it AFTER the velocity update + implicit friction (the forward-backward pairing, SPEC §2 C8/§1 fact 5) while the historical ssp_rk2 path keeps it before the applies (bit-identical). h_only selects the predictor’s TR_MODE_NONE (SPEC §2 P9); mass_out_weight is the per-call budget weight (0.5 per SSP stage; 0 for the discarded predictor state, 1 for the corrector).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_dyn_t), intent(inout) :: dyn
type(continuity_t), intent(inout) :: ct
type(ocean_hdiff_tracer_t), intent(inout) :: hd
type(ocean_vertical_advection_t), intent(inout) :: va
type(ocean_redi_t), intent(inout), optional :: redi
type(ocean_varmix_t), intent(inout), optional :: varmix
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
real(kind=wp), intent(in) :: therm_dt
logical, intent(in) :: therm_active
logical, intent(in) :: is_lagrangian
real(kind=wp), intent(in) :: h_min_floor
real(kind=wp), intent(in) :: mass_out_weight
logical, intent(in) :: h_only
integer, intent(in) :: stage_id
integer, intent(in) :: step_id
type(ocean_bc_state_t), intent(inout), optional :: bc
type(ocean_mle_t), intent(inout), optional :: mle

private subroutine run_gm_step(grid, metrics, dyn, ct, va, ms, dt, gm, slopes, varmix, wavespeed, vcoord, bc)

Gent-McWilliams thickness diffusion as its OWN sequential operator, run once per outer step AFTER the dynamics (the stage loop and, under ssp_rk2, the stage average) — where MOM6 calls thickness_diffuse after step_MOM_dyn_split_RK2, every dynamics step:

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_dyn_t), intent(inout) :: dyn
type(continuity_t), intent(inout) :: ct
type(ocean_vertical_advection_t), intent(inout) :: va
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
type(ocean_gm_t), intent(inout), optional :: gm
type(ocean_slopes_t), intent(inout), optional :: slopes
type(ocean_varmix_t), intent(inout), optional :: varmix
type(ocean_wave_speed_t), intent(inout), optional :: wavespeed
type(ocean_vcoord_t), intent(in), optional :: vcoord
type(ocean_bc_state_t), intent(inout), optional :: bc

private subroutine run_meke_step(grid, metrics, gm, varmix, wavespeed, hv, ms, dt, meke)

Thin dispatcher: call meke_step only when the MEKE slot is present AND enabled, forwarding the (also-optional) VarMix + wavespeed slots so the feedback seam + length scales engage when those are on. meke_step itself no-ops on enable=.false.; this guard avoids the call (and the present-propagation noise) when the slot is absent. hv%ke_diss (the lateral-viscosity KE dissipation rate) is forwarded for the frictional source; it is 0 unless hv%compute_ke_diss is set (and meke%frcoeff<0 ignores it) ⇒ inert by default.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics
type(ocean_gm_t), intent(in) :: gm
type(ocean_varmix_t), intent(inout), optional :: varmix
type(ocean_wave_speed_t), intent(in), optional :: wavespeed
type(ocean_horizontal_viscosity_t), intent(in) :: hv
type(multilayer_state_t), intent(in) :: ms
real(kind=wp), intent(in) :: dt
type(ocean_meke_t), intent(inout), optional :: meke

private subroutine run_stage(grid, metrics, dyn, eos, cor, ct, pgf, hv, bd, ss, va, hd, vd, vmix, ms, dt, stage, sf, geo, lateral_mix, epbl, kshear, slopes, vmix_tidal, td, cav)

One FE stage of the multilayer step. Order of operations:

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics

Curvilinear horizontal metrics — forwarded to the PGF.

type(ocean_dyn_t), intent(in) :: dyn
type(eos_t), intent(in) :: eos
type(coriolis_adv_t), intent(inout) :: cor
type(continuity_t), intent(inout) :: ct
type(ocean_pressure_force_t), intent(inout) :: pgf
type(ocean_horizontal_viscosity_t), intent(inout) :: hv
type(ocean_bottom_drag_t), intent(inout) :: bd
type(ocean_surface_stress_t), intent(inout) :: ss
type(ocean_vertical_advection_t), intent(inout) :: va
type(ocean_hdiff_tracer_t), intent(inout) :: hd
type(ocean_vdiff_t), intent(inout) :: vd
type(ocean_vmix_t), intent(inout) :: vmix
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
integer, intent(in) :: stage

RK2 stage (1 or 2); see vmix_apply_in_stage.

type(ocean_surface_flux_t), intent(in), optional :: sf
type(ocean_geothermal_t), intent(in), optional :: geo

Geothermal bottom-heat-flux slot. See ocean_dyn_step.

type(ocean_lateral_mix_t), intent(inout), optional :: lateral_mix
type(ocean_epbl_t), intent(inout), optional :: epbl
type(ocean_kappa_shear_t), intent(inout), optional :: kshear
type(ocean_slopes_t), intent(inout), optional :: slopes
type(ocean_tidal_mixing_t), intent(inout), optional :: vmix_tidal
type(ocean_top_drag_t), intent(inout), optional :: td

Ice-shelf TOP-drag slot (&ocean_tdrag_nml). OPTIONAL so the many direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn; the production driver always passes it. Absent, or present and disabled, => no kernel launch and a bit-identical step.

type(ocean_cavity_flux_t), intent(inout), optional :: cav

Ice-shelf basal-melt slot (&ocean_cavity_melt_nml). OPTIONAL for the same reason td is: the direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn, and the production driver always passes it. Absent, disabled, or freshwater="virtual" => no kernel launch and a bit-identical step. It is threaded down here rather than acted on in engine_step_finalize because the real-freshwater volume must be spent in the SAME stage, at the SAME stage weight and from the SAME melt value as the salt and heat halves the surface-flux apply spends – see ocean_cavity_mass_step’s docstring.

private subroutine run_stage_split(grid, metrics, dyn, eos, cor, ct, pgf, hv, bd, ss, va, hd, vd, vmix, ms, dt, n_inner, sf, geo, stage, vcoord, bc, sp, t, lateral_mix, epbl, kshear, mle, redi, varmix, vmix_tidal, meke, eta_forcing, td, cav, eta_pf_seam)

One FE stage of the split-explicit step. See the ocean_dyn_step_split header for the design.

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_metrics_t), intent(in) :: metrics

Curvilinear horizontal metrics — forwarded to the PGF (and, in slice 2, the other geometry-aware kernels).

type(ocean_dyn_t), intent(inout) :: dyn
type(eos_t), intent(in) :: eos
type(coriolis_adv_t), intent(inout) :: cor
type(continuity_t), intent(inout) :: ct
type(ocean_pressure_force_t), intent(inout) :: pgf
type(ocean_horizontal_viscosity_t), intent(inout) :: hv
type(ocean_bottom_drag_t), intent(inout) :: bd
type(ocean_surface_stress_t), intent(inout) :: ss
type(ocean_vertical_advection_t), intent(inout) :: va
type(ocean_hdiff_tracer_t), intent(inout) :: hd
type(ocean_vdiff_t), intent(inout) :: vd
type(ocean_vmix_t), intent(inout) :: vmix
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
integer, intent(in) :: n_inner
type(ocean_surface_flux_t), intent(in), optional :: sf
type(ocean_geothermal_t), intent(in), optional :: geo

Geothermal bottom-heat-flux slot. See ocean_dyn_step_split.

integer, intent(in), optional :: stage

Outer SSP-RK2 stage index (1 or 2) — only used by the debug probe so trace lines self-identify which half-step they came from. Production paths leave it unset.

type(ocean_vcoord_t), intent(in), optional :: vcoord

Vertical-coordinate state. When present and coord_type /= VCOORD_EULERIAN_Z the stage runs in Lagrangian mode: vertical advection is skipped (no compute_w_from_continuity / tracer_advect_vertical) and apply_bt_correction’s h-rescale is skipped. The MOM6-constrained slow continuity makes sum_k(h_layer) self-consistent with the barotropic-substep η; the ALE remap at the end of the outer step relayers (h, hTr) onto vcoord%target_h conservatively. Absent or EULERIAN_Z ⇒ the historical Eulerian-z code path.

type(ocean_bc_state_t), intent(inout), optional :: bc

Open-boundary config forwarded straight to the barotropic substep. Absent / all-OBC_WALL keeps the closed-wall path.

type(ocean_sponge_t), intent(in), optional :: sp

Map-driven sponge slot (PR-23). See ocean_dyn_step_split.

real(kind=wp), intent(in), optional :: t

Wall-clock time for OBC_TIDAL constituent evaluation.

type(ocean_lateral_mix_t), intent(inout), optional :: lateral_mix

Flow-aware lateral closure. See the matching arg on ocean_dyn_step_split.

type(ocean_epbl_t), intent(inout), optional :: epbl

EPBL slot. See the matching arg on ocean_dyn_step_split.

type(ocean_kappa_shear_t), intent(inout), optional :: kshear

Kappa-shear slot. See ocean_dyn_step_split.

type(ocean_mle_t), intent(inout), optional :: mle

Fox-Kemper MLE slot (B5). Forwarded to continuity_tracer_step_split to fold the precomputed uhml/vhml into the mass fluxes. See ocean_dyn_step_split.

type(ocean_redi_t), intent(inout), optional :: redi

Redi neutral-diffusion slot (capability [3]). The Phase-A coefficients are precomputed in ocean_dyn_step_split; here Phase B (redi_apply_flux) adds the rotated tracer flux after the along-coordinate tracer_hdiff, at THERMO cadence.

type(ocean_varmix_t), intent(inout), optional :: varmix

VarMix coefficient slot (capability [4]). When enabled, its per-face khtr_u/khtr_v feed the Redi flux (the Visbeck KhTr seam); absent / disabled ⇒ Redi uses its scalar khtr.

type(ocean_tidal_mixing_t), intent(inout), optional :: vmix_tidal

Tidal-mixing slot. See ocean_dyn_step_split.

type(ocean_meke_t), intent(in), optional :: meke

MEKE slot (capability [5]). Read-only here: when meke%backscatter is on, its ku field is injected into the resolved per-face harmonic viscosity right after ocean_lateral_mix_compute (the energy-return seam, Gap 2). Absent / backscatter off ⇒ bit-identical.

real(kind=wp), intent(in), optional :: eta_forcing(grid%nx_total,grid%ny_total)
type(ocean_top_drag_t), intent(inout), optional :: td

Ice-shelf TOP-drag slot (&ocean_tdrag_nml). OPTIONAL so the many direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn; the production driver always passes it. Absent, or present and disabled, => no kernel launch and a bit-identical step.

type(ocean_cavity_flux_t), intent(inout), optional :: cav

Ice-shelf basal-melt slot (&ocean_cavity_melt_nml). OPTIONAL for the same reason td is: the direct ocean_dyn_step* / run_stage* call sites in the test suite need no churn, and the production driver always passes it. Absent, disabled, or freshwater="virtual" => no kernel launch and a bit-identical step. It is threaded down here rather than acted on in engine_step_finalize because the real-freshwater volume must be spent in the SAME stage, at the SAME stage weight and from the SAME melt value as the salt and heat halves the surface-flux apply spends – see ocean_cavity_mass_step’s docstring.

real(kind=wp), intent(in), optional :: eta_pf_seam(grid%nx_total,grid%ny_total)

The part of the eta_forcing seam that ALSO reaches the slow PGF (eta_ib when &ocean_pgf_nml p_top_in_bc puts p_surf in the FV_MOM6 top BC). Absent ⇒ the slow PGF carries no seam load. Read only under &ocean_bt_nml bc_pgf_forcing. Equilibrium-tide elevation (C1), held static across the inner substep loop. Forwarded to barotropic_substep_nonlinear’s PGF; absent ⇒ bit-identical.

private pure subroutine save_state(ms)

Copy h_layer, u_face_x_layer, v_face_y_layer into the *_0 save buffers on the multilayer state. Per-tracer hTr is saved by the caller via copy_field_3d (the registry has to be walked on the host).

Arguments

Type IntentOptional Attributes Name
type(multilayer_state_t), intent(inout) :: ms

private subroutine visc_rem_halo_refresh(grid, bt_work, bc)

Exchange bt_work%visc_rem_u/v face halos right after production — MOM6’s pass_visc_rem group pass, run after every one of the three vertvisc_remnant calls. MPI halo first, then the periodic wrap, then the tripolar fold — the same ordering contract every other seam fill in this module follows (ocean_halo_exchange_ml_state then ocean_periodic_wrap_state then ocean_fold_wrap_state). visc_rem is a POSITIVE SCALAR on a face (the viscous-remnant fraction), not a true-vector flux component, so the fold uses ocean_fold_wrap_visc_rem (copy across the seam), NOT ocean_fold_wrap_stress’s negate-on-fold vector contract. bc absent (e.g. a direct unit-test call with no boundary state) ⇒ periodic wrap + fold are skipped; the halo exchange itself is unconditional (no-op on 1 rank, D0).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(ocean_bc_state_t), intent(in), optional :: bc

private subroutine visc_rem_precompute(grid, bt_work, vmix, vd, ss, bd, ms, dt, kshear, lambda_top_u, lambda_top_v, cover_u, cover_v, bc)

Refresh bt_work%visc_rem_u/v from the CURRENT stage state BEFORE the barotropic forcing assembly (PGF_BUG.md §9) — the MOM6-order parity (vertvisc_coef runs before btstep every stage). The stage-end producer alone leaves visc_rem at its init value (≡ 1) for the whole first stage, so the rem-weighted F_bt degenerates to the plain mean exactly when the spurious grounded-layer PGF is at its ballistic worst, and the Δu corrector then deposits the spurious column-mean into wet layers. Remnant-only vdiff call: builds the same matrix the stage-end solve will build (kv one stage stale — benign; the thickness field, which the BBL glue keys on, is current) and does NOT touch the velocities. Vertex kappa-shear: the corner Kv source enters this matrix too (same operator as the stage-end momentum solve — a remnant built without it would weight the BT corrector with a different friction operator than the one actually applied).

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(barotropic_workstate_t), intent(inout) :: bt_work
type(ocean_vmix_t), intent(in) :: vmix
type(ocean_vdiff_t), intent(inout) :: vd
type(ocean_surface_stress_t), intent(in) :: ss
type(ocean_bottom_drag_t), intent(in) :: bd
type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
type(ocean_kappa_shear_t), intent(in), optional :: kshear

Kappa-shear slot; only read when enabled + vertex mode (supplies the corner Kv source).

real(kind=wp), intent(in), optional :: lambda_top_u(grid%nx_total+1,grid%ny_total)
real(kind=wp), intent(in), optional :: lambda_top_v(grid%nx_total,grid%ny_total+1)

Ice-shelf top-drag Rayleigh rate — forwarded so the REMNANT is built from the same operator the stage-end momentum solve will build. A remnant built without a sink the solve has would weight the barotropic corrector with a friction operator that is not the one applied. EXPLICIT SHAPE for the reason spelled out on vmix_apply_in_stage’s twin dummies.

real(kind=wp), intent(in), optional :: cover_u(grid%nx_total+1,grid%ny_total)
real(kind=wp), intent(in), optional :: cover_v(grid%nx_total,grid%ny_total+1)

Face ice-cover masks, same reason.

type(ocean_bc_state_t), intent(in), optional :: bc

Forwarded ONLY for the post-production halo/periodic/fold refresh of visc_rem_u/v (visc_rem_halo_refresh, PR-1) — MOM6’s pass_visc_rem group pass, run after every vertvisc_remnant call.

private subroutine vmix_apply_in_stage(grid, dyn, vmix, vd, ss, bd, ms, dt, stage, sf, epbl, kshear, vmix_tidal, bt_work, lambda_top_u, lambda_top_v, cover_u, cover_v, apply_tracers, metrics, dt_remnant, bc)

Bundle the per-stage vmix closure / KPP overlay / KV_ML_INVZ2 / assembly gate / vdiff dispatch into one routine so the run_stage drivers can call vmix_apply_in_stage(grid, dyn, vmix, vd, ss, ms, dt, sf) instead of carrying 30 lines of nested if-branching.

Read more…

Arguments

Type IntentOptional Attributes Name
type(hgrid_t), intent(in) :: grid
type(ocean_dyn_t), intent(in) :: dyn
type(ocean_vmix_t), intent(inout) :: vmix
type(ocean_vdiff_t), intent(inout) :: vd
type(ocean_surface_stress_t), intent(in) :: ss
type(ocean_bottom_drag_t), intent(in) :: bd

Bottom-drag slot — supplies the bed-layer Rayleigh-rate field lambda_bot_u/v for the implicit-drag vdiff fold.

type(multilayer_state_t), intent(inout) :: ms
real(kind=wp), intent(in) :: dt
integer, intent(in) :: stage

RK2 stage (1 or 2): the EPBL/kappa-shear COLUMN SOLVES fire only at stage 1 of a thermo step (their kd is stage-invariant by design — recomputing at stage 2 doubled the closure cost for no accuracy: 19.6%% of GPU time was kappa-shear at 2x cadence). The merges still run EVERY stage (PP81 rewrites kv/kt per stage).

type(ocean_surface_flux_t), intent(in), optional :: sf
type(ocean_epbl_t), intent(inout), optional :: epbl

EPBL slot. When present and enabled, replaces the KPP overlay (configure enforces the mutual exclusion): epbl_compute refreshes kd_int at thermo cadence and the merge into vmix%kv / vmix%kt runs every stage (PP81 rewrites those arrays each stage).

type(ocean_kappa_shear_t), intent(inout), optional :: kshear

Kappa-shear interior closure slot. When present and enabled, kappa_shear_compute refreshes kd_int at thermo cadence and the additive merge into vmix%kv / vmix%kt runs every stage. Coexists with KPP / EPBL (no mutual exclusion).

type(ocean_tidal_mixing_t), intent(inout), optional :: vmix_tidal

St-Laurent/Simmons tidal-mixing interior closure slot. When present and enabled, tidal_mixing_compute refreshes kd_int at thermo cadence and the additive merge into vmix%kv / vmix%kt runs every stage. Coexists with KPP / EPBL / kappa-shear (no mutual exclusion).

type(barotropic_workstate_t), intent(inout), optional :: bt_work

The BT-corrector workstate — supplies visc_rem_u/v as the vdiff kernel’s OUTPUT. Present only from run_stage_split (the unsplit path has no BT correction to consume it). When present AND bt_work%bt_visc_rem_producer, the viscous remnant γ is (re)computed here, at step 9 of the CURRENT stage — the next stage’s forcing/renorm/bt_rem_from consumers read it, a one-stage (Δt/2) lag (see the step-9 call site below). Absent, or no consumer on, ⇒ no remnant work ⇒ bit-identical.

real(kind=wp), intent(in), optional :: lambda_top_u(grid%nx_total+1,grid%ny_total)
real(kind=wp), intent(in), optional :: lambda_top_v(grid%nx_total,grid%ny_total+1)

Ice-shelf top-drag Rayleigh rate (1/s) at u / v faces — the ocean_top_drag_t slot’s lambda_top_u/v, forwarded verbatim to vdiff_apply_momentum’s k = nz diagonal fold. Passed as ARRAYS rather than the slot itself because the slot is optional one level up: forwarding an absent optional ARRAY dummy on to another optional dummy is legal Fortran, whereas dereferencing an absent derived-type dummy is not. Absent, or vd%implicit_top_drag off ⇒ bit-identical.

Read more…
real(kind=wp), intent(in), optional :: cover_u(grid%nx_total+1,grid%ny_total)
real(kind=wp), intent(in), optional :: cover_v(grid%nx_total,grid%ny_total+1)

Face ice-cover masks (the OR of the two abutting cells). Present together with lambda_top_*; used to mask the wind RHS off on covered faces. Explicit-shape for the same reason.

logical, intent(in), optional :: apply_tracers

.false. = momentum-only: skip the tracer vdiff + KPP non-local applies regardless of the thermo gate. The pred_corr PREDICTOR passes this — MOM6’s predictor applies vertvisc(up, dt_pred) to the provisional velocity (so the spurious grounded-layer accelerations are absorbed BEFORE continuity forms u_av) but never touches tracers. Default .true. = historical.

type(ocean_metrics_t), intent(in), optional :: metrics

Metrics slot — supplies the halo-valid wet masks (wet_T/wet_u/wet_v) the kappa-shear VERTEX form’s corner gather needs, and metrics%geolatT — the C7 Henyey latitude factor’s only spatial input, forwarded to vmix_assemble (unread when bkgnd_henyey is off). Optional so the split_rk2/legacy call shapes stay valid; both consumers fail loud when their knob is on and the slot is absent — kappa_shear_compute for at_vertex, and vmix_assemble for bkgnd_henyey.

real(kind=wp), intent(in), optional :: dt_remnant

dt (the pred_corr PREDICTOR, where this routine is called with dt_vel = pc_be·dt), the visc_rem PRODUCER is split out of the velocity solve and re-run as its own remnant-only call at dt_remnant — matching MOM6’s VISC_REM_TIMESTEP_BUG = .false. default (vertvisc_remnant always at the outer step’s dt), never at dt_pred. Absent ⇒ the historical fused behaviour (remnant built from the SAME matrix as the velocity solve, at dt). See bt_forcing_visc_rem’s docstring in rdb_barotropic_workstate for the full call-point mapping.

type(ocean_bc_state_t), intent(in), optional :: bc

Open-boundary / periodic / tripolar-fold state — forwarded ONLY so the visc_rem halo refresh (visc_rem_halo_refresh) can re-wrap bt_work%visc_rem_u/v’s ghosts after production. Unread when do_remnant is false.