diff --git a/config_src/coupled_driver/MOM_surface_forcing.F90 b/config_src/coupled_driver/MOM_surface_forcing.F90 index fc646a4f56..09d7da3119 100644 --- a/config_src/coupled_driver/MOM_surface_forcing.F90 +++ b/config_src/coupled_driver/MOM_surface_forcing.F90 @@ -51,6 +51,11 @@ module MOM_surface_forcing public ice_ocn_bnd_type_chksum public forcing_save_restart +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> surface_forcing_CS is a structure containing pointers to the forcing fields !! which may be used to drive MOM. All fluxes are positive downward. type, public :: surface_forcing_CS ; private @@ -59,19 +64,19 @@ module MOM_surface_forcing !! the winds that are being provided in calls to !! update_ocean_model. logical :: use_temperature !< If true, temp and saln used as state variables - real :: wind_stress_multiplier !< A multiplier applied to incoming wind stress (nondim). + real :: wind_stress_multiplier !< A multiplier applied to incoming wind stress [nondim]. - real :: Rho0 !< Boussinesq reference density (kg/m^3) - real :: area_surf = -1.0 !< Total ocean surface area (m^2) - real :: latent_heat_fusion !< Latent heat of fusion (J/kg) - real :: latent_heat_vapor !< Latent heat of vaporization (J/kg) + real :: Rho0 !< Boussinesq reference density [kg m-3] + real :: area_surf = -1.0 !< Total ocean surface area [m2] + real :: latent_heat_fusion !< Latent heat of fusion [J kg-1] + real :: latent_heat_vapor !< Latent heat of vaporization [J kg-1] real :: max_p_surf !< The maximum surface pressure that can be - !! exerted by the atmosphere and floating sea-ice, - !! in Pa. This is needed because the FMS coupling - !! structure does not limit the water that can be - !! frozen out of the ocean and the ice-ocean heat - !! fluxes are treated explicitly. + !! exerted by the atmosphere and floating sea-ice [Pa]. + !! This is needed because the FMS coupling structure + !! does not limit the water that can be frozen out + !! of the ocean and the ice-ocean heat fluxes are + !! treated explicitly. logical :: use_limited_P_SSH !< If true, return the sea surface height with !! the correction for the atmospheric (and sea-ice) !! pressure limited by max_p_surf instead of the @@ -80,34 +85,34 @@ module MOM_surface_forcing !! type without any further adjustments to drive the ocean dynamics. !! The actual net mass source may differ due to corrections. - real :: gust_const !< Constant unresolved background gustiness for ustar (Pa) + real :: gust_const !< Constant unresolved background gustiness for ustar [Pa] logical :: read_gust_2d !< If true, use a 2-dimensional gustiness supplied from an input file. real, pointer, dimension(:,:) :: & TKE_tidal => NULL() !< Turbulent kinetic energy introduced to the bottom boundary layer - !! by drag on the tidal flows, in W m-2. + !! by drag on the tidal flows [W m-2]. real, pointer, dimension(:,:) :: & gust => NULL() !< A spatially varying unresolved background gustiness that - !! contributes to ustar (Pa). gust is used when read_gust_2d is true. + !! contributes to ustar [Pa]. gust is used when read_gust_2d is true. real, pointer, dimension(:,:) :: & - ustar_tidal => NULL() !< Tidal contribution to the bottom friction velocity (m/s) + ustar_tidal => NULL() !< Tidal contribution to the bottom friction velocity [m s-1] real :: cd_tides !< Drag coefficient that applies to the tides (nondimensional) - real :: utide !< Constant tidal velocity to use if read_tideamp is false, in m s-1. + real :: utide !< Constant tidal velocity to use if read_tideamp is false [m s-1]. logical :: read_tideamp !< If true, spatially varying tidal amplitude read from a file. logical :: rigid_sea_ice !< If true, sea-ice exerts a rigidity that acts to damp surface !! deflections (especially surface gravity waves). The default is false. - real :: Kv_sea_ice !< Viscosity in sea-ice that resists sheared vertical motions (m^2/s) + real :: Kv_sea_ice !< Viscosity in sea-ice that resists sheared vertical motions [m2 s-1] real :: density_sea_ice !< Typical density of sea-ice (kg/m^3). The value is only used to convert !! the ice pressure into appropriate units for use with Kv_sea_ice. real :: rigid_sea_ice_mass !< A mass per unit area of sea-ice beyond which sea-ice viscosity - !! becomes effective, in kg m-2, typically of order 1000 kg m-2. + !! becomes effective [kg m-2], typically of order 1000 kg m-2. logical :: allow_flux_adjustments !< If true, use data_override to obtain flux adjustments logical :: restore_salt !< If true, the coupled MOM driver adds a term to restore surface !! salinity to a specified value. logical :: restore_temp !< If true, the coupled MOM driver adds a term to restore sea !! surface temperature to a specified value. - real :: Flux_const !< Piston velocity for surface restoring (m/s) + real :: Flux_const !< Piston velocity for surface restoring [m s-1] logical :: salt_restore_as_sflux !< If true, SSS restore as salt flux instead of water flux logical :: adjust_net_srestore_to_zero !< Adjust srestore to zero (for both salt_flux or vprec) logical :: adjust_net_srestore_by_scaling !< Adjust srestore w/o moving zero contour @@ -116,7 +121,7 @@ module MOM_surface_forcing logical :: adjust_net_fresh_water_by_scaling !< Adjust net surface fresh-water w/o moving zero contour logical :: mask_srestore_under_ice !< If true, use an ice mask defined by frazil criteria !! for salinity restoring. - real :: ice_salt_concentration !< Salt concentration for sea ice (kg/kg) + real :: ice_salt_concentration !< Salt concentration for sea ice [kg/kg] logical :: mask_srestore_marginal_seas !< If true, then mask SSS restoring in marginal seas real :: max_delta_srestore !< Maximum delta salinity used for restoring real :: max_delta_trestore !< Maximum delta sst used for restoring @@ -152,33 +157,33 @@ module MOM_surface_forcing !> ice_ocean_boundary_type is a structure corresponding to forcing, but with the elements, units, !! and conventions that exactly conform to the use for MOM6-based coupled models. type, public :: ice_ocean_boundary_type - real, pointer, dimension(:,:) :: u_flux =>NULL() !< i-direction wind stress (Pa) - real, pointer, dimension(:,:) :: v_flux =>NULL() !< j-direction wind stress (Pa) - real, pointer, dimension(:,:) :: t_flux =>NULL() !< sensible heat flux (W/m2) - real, pointer, dimension(:,:) :: q_flux =>NULL() !< specific humidity flux (kg/m2/s) - real, pointer, dimension(:,:) :: salt_flux =>NULL() !< salt flux (kg/m2/s) - real, pointer, dimension(:,:) :: lw_flux =>NULL() !< long wave radiation (W/m2) - real, pointer, dimension(:,:) :: sw_flux_vis_dir =>NULL() !< direct visible sw radiation (W/m2) - real, pointer, dimension(:,:) :: sw_flux_vis_dif =>NULL() !< diffuse visible sw radiation (W/m2) - real, pointer, dimension(:,:) :: sw_flux_nir_dir =>NULL() !< direct Near InfraRed sw radiation (W/m2) - real, pointer, dimension(:,:) :: sw_flux_nir_dif =>NULL() !< diffuse Near InfraRed sw radiation (W/m2) - real, pointer, dimension(:,:) :: lprec =>NULL() !< mass flux of liquid precip (kg/m2/s) - real, pointer, dimension(:,:) :: fprec =>NULL() !< mass flux of frozen precip (kg/m2/s) - real, pointer, dimension(:,:) :: runoff =>NULL() !< mass flux of liquid runoff (kg/m2/s) - real, pointer, dimension(:,:) :: calving =>NULL() !< mass flux of frozen runoff (kg/m2/s) - real, pointer, dimension(:,:) :: stress_mag =>NULL() !< The time-mean magnitude of the stress on the ocean (Pa) - real, pointer, dimension(:,:) :: ustar_berg =>NULL() !< frictional velocity beneath icebergs (m/s) - real, pointer, dimension(:,:) :: area_berg =>NULL() !< area covered by icebergs(m2/m2) - real, pointer, dimension(:,:) :: mass_berg =>NULL() !< mass of icebergs(kg/m2) - real, pointer, dimension(:,:) :: runoff_hflx =>NULL() !< heat content of liquid runoff (W/m2) - real, pointer, dimension(:,:) :: calving_hflx =>NULL() !< heat content of frozen runoff (W/m2) + real, pointer, dimension(:,:) :: u_flux =>NULL() !< i-direction wind stress [Pa] + real, pointer, dimension(:,:) :: v_flux =>NULL() !< j-direction wind stress [Pa] + real, pointer, dimension(:,:) :: t_flux =>NULL() !< sensible heat flux [W m-2] + real, pointer, dimension(:,:) :: q_flux =>NULL() !< specific humidity flux [kg m-2 s-1] + real, pointer, dimension(:,:) :: salt_flux =>NULL() !< salt flux [kg m-2 s-1] + real, pointer, dimension(:,:) :: lw_flux =>NULL() !< long wave radiation [W m-2] + real, pointer, dimension(:,:) :: sw_flux_vis_dir =>NULL() !< direct visible sw radiation [W m-2] + real, pointer, dimension(:,:) :: sw_flux_vis_dif =>NULL() !< diffuse visible sw radiation [W m-2] + real, pointer, dimension(:,:) :: sw_flux_nir_dir =>NULL() !< direct Near InfraRed sw radiation [W m-2] + real, pointer, dimension(:,:) :: sw_flux_nir_dif =>NULL() !< diffuse Near InfraRed sw radiation [W m-2] + real, pointer, dimension(:,:) :: lprec =>NULL() !< mass flux of liquid precip [kg m-2 s-1] + real, pointer, dimension(:,:) :: fprec =>NULL() !< mass flux of frozen precip [kg m-2 s-1] + real, pointer, dimension(:,:) :: runoff =>NULL() !< mass flux of liquid runoff [kg m-2 s-1] + real, pointer, dimension(:,:) :: calving =>NULL() !< mass flux of frozen runoff [kg m-2 s-1] + real, pointer, dimension(:,:) :: stress_mag =>NULL() !< The time-mean magnitude of the stress on the ocean [Pa] + real, pointer, dimension(:,:) :: ustar_berg =>NULL() !< frictional velocity beneath icebergs [m s-1] + real, pointer, dimension(:,:) :: area_berg =>NULL() !< fractional area covered by icebergs [m2 m-2] + real, pointer, dimension(:,:) :: mass_berg =>NULL() !< mass of icebergs per unit ocean area [kg m-2] + real, pointer, dimension(:,:) :: runoff_hflx =>NULL() !< heat content of liquid runoff [W m-2] + real, pointer, dimension(:,:) :: calving_hflx =>NULL() !< heat content of frozen runoff [W m-2] real, pointer, dimension(:,:) :: p =>NULL() !< pressure of overlying ice and atmosphere - !< on ocean surface (Pa) - real, pointer, dimension(:,:) :: mi =>NULL() !< mass of ice (kg/m2) + !< on ocean surface [Pa] + real, pointer, dimension(:,:) :: mi =>NULL() !< mass of ice per unit ocean area [kg m-2] real, pointer, dimension(:,:) :: ice_rigidity =>NULL() !< rigidity of the sea ice, sea-ice and !! ice-shelves, expressed as a coefficient !! for divergence damping, as determined - !! outside of the ocean model in (m3/s) + !! outside of the ocean model [m3 s-1] integer :: xtype !< The type of the exchange - REGRID, REDIST or DIRECT type(coupler_2d_bc_type) :: fluxes !< A structure that may contain an array of named fields !! used for passive tracer fluxes. @@ -213,27 +218,26 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, G, US, CS, sfc !! surface state of the ocean. real, dimension(SZI_(G),SZJ_(G)) :: & - data_restore, & ! The surface value toward which to restore (g/kg or degC) - SST_anom, & ! Instantaneous sea surface temperature anomalies from a target value (deg C) - SSS_anom, & ! Instantaneous sea surface salinity anomalies from a target value (g/kg) + data_restore, & ! The surface value toward which to restore [ppt] or [degC] + SST_anom, & ! Instantaneous sea surface temperature anomalies from a target value [degC] + SSS_anom, & ! Instantaneous sea surface salinity anomalies from a target value [ppt] SSS_mean, & ! A (mean?) salinity about which to normalize local salinity - ! anomalies when calculating restorative precipitation anomalies (g/kg) + ! anomalies when calculating restorative precipitation anomalies [ppt] PmE_adj, & ! The adjustment to PminusE that will cause the salinity - ! to be restored toward its target value (kg/(m^2 * s)) - net_FW, & ! The area integrated net freshwater flux into the ocean (kg/s) - net_FW2, & ! The area integrated net freshwater flux into the ocean (kg/s) - work_sum, & ! A 2-d array that is used as the work space for a global - ! sum, used with units of m2 or (kg/s) - open_ocn_mask ! a binary field indicating where ice is present based on frazil criteria + ! to be restored toward its target value [kg m-1 s-1] + net_FW, & ! The area integrated net freshwater flux into the ocean [kg s-1] + net_FW2, & ! The area integrated net freshwater flux into the ocean [kg s-1] + work_sum, & ! A 2-d array that is used as the work space for global sums [m2] or [kg s-1] + open_ocn_mask ! a binary field indicating where ice is present based on frazil criteria [nondim] integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, i0, j0 integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB, isr, ier, jsr, jer integer :: isc_bnd, iec_bnd, jsc_bnd, jec_bnd - real :: delta_sss ! temporary storage for sss diff from restoring value - real :: delta_sst ! temporary storage for sst diff from restoring value + real :: delta_sss ! temporary storage for sss diff from restoring value [ppt] + real :: delta_sst ! temporary storage for sst diff from restoring value [degC] - real :: C_p ! heat capacity of seawater ( J/(K kg) ) + real :: C_p ! heat capacity of seawater [J degC-1 kg-1] real :: sign_for_net_FW_bug ! Should be +1. but an old bug can be recovered by using -1. call cpu_clock_begin(id_clock_forcing) @@ -574,20 +578,20 @@ subroutine convert_IOB_to_forces(IOB, forces, index_bounds, Time, G, US, CS, dt_ !! previous call to surface_forcing_init. real, optional, intent(in) :: dt_forcing !< A time interval over which to apply the !! current value of ustar as a weighted running - !! average, in s, or if 0 do not average ustar. + !! average [s], or if 0 do not average ustar. !! Missing is equivalent to 0. logical, optional, intent(in) :: reset_avg !< If true, reset the time average. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - rigidity_at_h, & ! Ice rigidity at tracer points (m3 s-1) - net_mass_src, & ! A temporary of net mass sources, in kg m-2 s-1. - ustar_tmp ! A temporary array of ustar values, in m s-1. - - real :: I_GEarth ! 1.0 / G%G_Earth (s^2/m) - real :: Kv_rho_ice ! (CS%kv_sea_ice / CS%density_sea_ice) ( m^5/(s*kg) ) - real :: mass_ice ! mass of sea ice at a face (kg/m^2) - real :: mass_eff ! effective mass of sea ice for rigidity (kg/m^2) + rigidity_at_h, & ! Ice rigidity at tracer points [m3 s-1] + net_mass_src, & ! A temporary of net mass sources [kg m-2 s-1]. + ustar_tmp ! A temporary array of ustar values [m s-1]. + + real :: I_GEarth ! 1.0 / G%G_Earth [s2 m-1] + real :: Kv_rho_ice ! (CS%kv_sea_ice / CS%density_sea_ice) [m5 s-1 kg-1] + real :: mass_ice ! mass of sea ice at a face [kg m-2] + real :: mass_eff ! effective mass of sea ice for rigidity [kg m-2] real :: wt1, wt2 ! Relative weights of previous and current values of ustar, ND. integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, i0, j0 @@ -798,28 +802,28 @@ subroutine extract_IOB_stresses(IOB, index_bounds, Time, G, US, CS, taux, tauy, type(surface_forcing_CS),pointer :: CS !< A pointer to the control structure returned by a !! previous call to surface_forcing_init. real, dimension(SZIB_(G),SZJ_(G)), & - optional, intent(inout) :: taux !< The zonal wind stresses on a C-grid, in Pa. + optional, intent(inout) :: taux !< The zonal wind stresses on a C-grid [Pa]. real, dimension(SZI_(G),SZJB_(G)), & - optional, intent(inout) :: tauy !< The meridional wind stresses on a C-grid, in Pa. + optional, intent(inout) :: tauy !< The meridional wind stresses on a C-grid [Pa]. real, dimension(SZI_(G),SZJ_(G)), & - optional, intent(inout) :: ustar !< The surface friction velocity, in Z s-1. + optional, intent(inout) :: ustar !< The surface friction velocity [Z s-1 ~> m s-1]. real, dimension(SZI_(G),SZJ_(G)), & optional, intent(out) :: gustless_ustar !< The surface friction velocity without - !! any contributions from gustiness, in Z s-1. + !! any contributions from gustiness [Z s-1 ~> m s-1]. integer, optional, intent(in) :: tau_halo !< The halo size of wind stresses to set, 0 by default. ! Local variables - real, dimension(SZI_(G),SZJ_(G)) :: taux_in_A ! Zonal wind stresses (in Pa) at h points - real, dimension(SZI_(G),SZJ_(G)) :: tauy_in_A ! Meridional wind stresses (in Pa) at h points - real, dimension(SZIB_(G),SZJ_(G)) :: taux_in_C ! Zonal wind stresses (in Pa) at u points - real, dimension(SZI_(G),SZJB_(G)) :: tauy_in_C ! Meridional wind stresses (in Pa) at v points - real, dimension(SZIB_(G),SZJB_(G)) :: taux_in_B ! Zonal wind stresses (in Pa) at q points - real, dimension(SZIB_(G),SZJB_(G)) :: tauy_in_B ! Meridional wind stresses (in Pa) at q points - - real :: gustiness ! unresolved gustiness that contributes to ustar (Pa) - real :: Irho0 ! Inverse of the mean density rescaled to (Z2 m / kg) - real :: taux2, tauy2 ! squared wind stresses (Pa^2) - real :: tau_mag ! magnitude of the wind stress (Pa) + real, dimension(SZI_(G),SZJ_(G)) :: taux_in_A ! Zonal wind stresses [Pa] at h points + real, dimension(SZI_(G),SZJ_(G)) :: tauy_in_A ! Meridional wind stresses [Pa] at h points + real, dimension(SZIB_(G),SZJ_(G)) :: taux_in_C ! Zonal wind stresses [Pa] at u points + real, dimension(SZI_(G),SZJB_(G)) :: tauy_in_C ! Meridional wind stresses [Pa] at v points + real, dimension(SZIB_(G),SZJB_(G)) :: taux_in_B ! Zonal wind stresses [Pa] at q points + real, dimension(SZIB_(G),SZJB_(G)) :: tauy_in_B ! Meridional wind stresses [Pa] at q points + + real :: gustiness ! unresolved gustiness that contributes to ustar [Pa] + real :: Irho0 ! Inverse of the mean density rescaled to [Z2 m kg-1 ~> m3 kg-1] + real :: taux2, tauy2 ! squared wind stresses [Pa2] + real :: tau_mag ! magnitude of the wind stress [Pa] logical :: do_ustar, do_gustless integer :: wind_stagger ! AGRID, BGRID_NE, or CGRID_NE (integers from MOM_domains) @@ -1005,9 +1009,9 @@ end subroutine extract_IOB_stresses !> Adds thermodynamic flux adjustments obtained via data_override !! Component name is 'OCN' !! Available adjustments are: -!! - hflx_adj (Heat flux into the ocean, in W m-2) -!! - sflx_adj (Salt flux into the ocean, in kg salt m-2 s-1) -!! - prcme_adj (Fresh water flux into the ocean, in kg m-2 s-1) +!! - hflx_adj (Heat flux into the ocean [W m-2]) +!! - sflx_adj (Salt flux into the ocean [kg salt m-2 s-1]) +!! - prcme_adj (Fresh water flux into the ocean [kg m-2 s-1]) subroutine apply_flux_adjustments(G, CS, Time, fluxes) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(surface_forcing_CS), pointer :: CS !< Surface forcing control structure @@ -1015,7 +1019,7 @@ subroutine apply_flux_adjustments(G, CS, Time, fluxes) type(forcing), intent(inout) :: fluxes !< Surface fluxes structure ! Local variables - real, dimension(SZI_(G),SZJ_(G)) :: temp_at_h ! Fluxes at h points (W m-2 or kg m-2 s-1) + real, dimension(SZI_(G),SZJ_(G)) :: temp_at_h ! Various fluxes at h points [W m-2] or [kg m-2 s-1] integer :: isc, iec, jsc, jec, i, j logical :: overrode_h @@ -1050,8 +1054,8 @@ end subroutine apply_flux_adjustments !> Adds mechanical forcing adjustments obtained via data_override !! Component name is 'OCN' !! Available adjustments are: -!! - taux_adj (Zonal wind stress delta, positive to the east, in Pa) -!! - tauy_adj (Meridional wind stress delta, positive to the north, in Pa) +!! - taux_adj (Zonal wind stress delta, positive to the east [Pa]) +!! - tauy_adj (Meridional wind stress delta, positive to the north [Pa]) subroutine apply_force_adjustments(G, CS, Time, forces) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(surface_forcing_CS), pointer :: CS !< Surface forcing control structure @@ -1059,8 +1063,8 @@ subroutine apply_force_adjustments(G, CS, Time, forces) type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces ! Local variables - real, dimension(SZI_(G),SZJ_(G)) :: tempx_at_h ! Delta to zonal wind stress at h points (Pa) - real, dimension(SZI_(G),SZJ_(G)) :: tempy_at_h ! Delta to meridional wind stress at h points (Pa) + real, dimension(SZI_(G),SZJ_(G)) :: tempx_at_h ! Delta to zonal wind stress at h points [Pa] + real, dimension(SZI_(G),SZJ_(G)) :: tempy_at_h ! Delta to meridional wind stress at h points [Pa] integer :: isc, iec, jsc, jec, i, j real :: dLonDx, dLonDy, rDlon, cosA, sinA, zonal_tau, merid_tau @@ -1137,7 +1141,7 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS) !! structure for this module ! Local variables - real :: utide ! The RMS tidal velocity, in m s-1. + real :: utide ! The RMS tidal velocity [m s-1]. type(directories) :: dirs logical :: new_sim, iceberg_flux_diags type(time_type) :: Time_frc @@ -1328,7 +1332,7 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS) endif -! Optionally read tidal amplitude from input file (m s-1) on model grid. +! Optionally read tidal amplitude from input file [m s-1] on model grid. ! Otherwise use default tidal amplitude for bottom frictionally-generated ! dissipation. Default cd_tides is chosen to yield approx 1 TWatt of ! work done against tides globally using OSU tidal amplitude. diff --git a/config_src/coupled_driver/ocean_model_MOM.F90 b/config_src/coupled_driver/ocean_model_MOM.F90 index 32cdd843ff..5af0b774b0 100644 --- a/config_src/coupled_driver/ocean_model_MOM.F90 +++ b/config_src/coupled_driver/ocean_model_MOM.F90 @@ -113,13 +113,13 @@ module ocean_model_mod real, pointer, dimension(:,:) :: & t_surf => NULL(), & !< SST on t-cell (degrees Kelvin) s_surf => NULL(), & !< SSS on t-cell (psu) - u_surf => NULL(), & !< i-velocity at the locations indicated by stagger, m/s. - v_surf => NULL(), & !< j-velocity at the locations indicated by stagger, m/s. + u_surf => NULL(), & !< i-velocity at the locations indicated by stagger [m s-1]. + v_surf => NULL(), & !< j-velocity at the locations indicated by stagger [m s-1]. sea_lev => NULL(), & !< Sea level in m after correction for surface pressure, - !! i.e. dzt(1) + eta_t + patm/rho0/grav (m) - frazil =>NULL(), & !< Accumulated heating (in Joules/m^2) from frazil + !! i.e. dzt(1) + eta_t + patm/rho0/grav [m] + frazil =>NULL(), & !< Accumulated heating [J m-2] from frazil !! formation in the ocean. - area => NULL() !< cell area of the ocean surface, in m2. + area => NULL() !< cell area of the ocean surface [m2]. type(coupler_2d_bc_type) :: fields !< A structure that may contain named !! arrays of tracer-related surface fields. integer :: avg_kount !< A count of contributions to running @@ -154,8 +154,8 @@ module ocean_model_mod logical :: icebergs_alter_ocean !< If true, the icebergs can change ocean the !! ocean dynamics and forcing fluxes. real :: press_to_z !< A conversion factor between pressure and ocean - !! depth in m, usually 1/(rho_0*g), in m Pa-1. - real :: C_p !< The heat capacity of seawater, in J K-1 kg-1. + !! depth in m, usually 1/(rho_0*g) [m Pa-1]. + real :: C_p !< The heat capacity of seawater [J degC-1 kg-1]. logical :: offline_tracer_mode = .false. !< If false, use the model in prognostic mode !! with the barotropic and baroclinic dynamics, thermodynamics, !! etc. stepped forward integrated in time. @@ -169,8 +169,8 @@ module ocean_model_mod !! If false, the two phases are advanced with !! separate calls. The default is true. ! The following 3 variables are only used here if single_step_call is false. - real :: dt !< (baroclinic) dynamics time step (seconds) - real :: dt_therm !< thermodynamics time step (seconds) + real :: dt !< (baroclinic) dynamics time step [s] + real :: dt_therm !< thermodynamics time step [s] logical :: thermo_spans_coupling !< If true, thermodynamic and tracer time !! steps can span multiple coupled time steps. logical :: diabatic_first !< If true, apply diabatic and thermodynamic @@ -239,8 +239,8 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn) !! tracer fluxes, and can be used to spawn related !! internal variables in the ice model. ! Local variables - real :: Rho0 ! The Boussinesq ocean density, in kg m-3. - real :: G_Earth ! The gravitational acceleration in m s-2. + real :: Rho0 ! The Boussinesq ocean density [kg m-3]. + real :: G_Earth ! The gravitational acceleration [m s-2]. real :: HFrz !< If HFrz > 0 (m), melt potential will be computed. !! The actual depth over which melt potential is computed will !! min(HFrz, OBLD), where OBLD is the boundary layer depth. @@ -439,7 +439,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda logical, optional, intent(in) :: end_cycle !< This indicates whether this call is to be !! treated as the last call to step_MOM in a !! time-stepping cycle; missing is like true. - real, optional, intent(in) :: cycle_length !< The duration of a coupled time stepping cycle, in s. + real, optional, intent(in) :: cycle_length !< The duration of a coupled time stepping cycle [s]. ! Local variables type(time_type) :: Time_seg_start ! Stores the ocean model time at the start of this call to allow @@ -447,11 +447,11 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda type(time_type) :: Time1 ! The value of the ocean model's time at the start of a call to step_MOM. integer :: index_bnds(4) ! The computational domain index bounds in the ice-ocean boundary type. real :: weight ! Flux accumulation weight of the current fluxes. - real :: dt_coupling ! The coupling time step in seconds. - real :: dt_therm ! A limited and quantized version of OS%dt_therm (sec) - real :: dt_dyn ! The dynamics time step in sec. - real :: dtdia ! The diabatic time step in sec. - real :: t_elapsed_seg ! The elapsed time in this update segment, in s. + real :: dt_coupling ! The coupling time step [s]. + real :: dt_therm ! A limited and quantized version of OS%dt_therm [s]. + real :: dt_dyn ! The dynamics time step [s]. + real :: dtdia ! The diabatic time step [s]. + real :: t_elapsed_seg ! The elapsed time in this update segment [s]. integer :: n ! The internal iteration counter. integer :: nts ! The number of baroclinic dynamics time steps in a thermodynamic step. integer :: n_max ! The number of calls to step_MOM dynamics in this call to update_ocean_model. @@ -820,9 +820,9 @@ subroutine convert_state_to_ocean_type(sfc_state, Ocean_sfc, G, patm, press_to_z !! visible ocean surface fields, whose elements !! have their data set here. type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure - real, optional, intent(in) :: patm(:,:) !< The pressure at the ocean surface, in Pa. + real, optional, intent(in) :: patm(:,:) !< The pressure at the ocean surface [Pa]. real, optional, intent(in) :: press_to_z !< A conversion factor between pressure and - !! ocean depth in m, usually 1/(rho_0*g), in m Pa-1. + !! ocean depth in m, usually 1/(rho_0*g) [m Pa-1]. ! Local variables real :: IgR0 character(len=48) :: val_str diff --git a/config_src/ice_solo_driver/MOM_surface_forcing.F90 b/config_src/ice_solo_driver/MOM_surface_forcing.F90 index 301b8a9eea..aec37b2a4a 100644 --- a/config_src/ice_solo_driver/MOM_surface_forcing.F90 +++ b/config_src/ice_solo_driver/MOM_surface_forcing.F90 @@ -74,8 +74,6 @@ module MOM_surface_forcing use MOM_tracer_flow_control, only : tracer_flow_control_CS use MOM_unit_scaling, only : unit_scale_type use MOM_variables, only : surface -! use MESO_surface_forcing, only : MESO_wind_forcing, MESO_buoyancy_forcing -! use MESO_surface_forcing, only : MESO_surface_forcing_init, MESO_surface_forcing_CS use user_surface_forcing, only : USER_wind_forcing, USER_buoyancy_forcing use user_surface_forcing, only : USER_surface_forcing_init, user_surface_forcing_CS use user_revise_forcing, only : user_alter_forcing, user_revise_forcing_init @@ -102,18 +100,18 @@ module MOM_surface_forcing real :: south_lat ! southern latitude of the domain real :: len_lat ! domain length in latitude - real :: Rho0 ! Boussinesq reference density (kg/m^3) - real :: G_Earth ! gravitational acceleration (m/s^2) - real :: Flux_const ! piston velocity for surface restoring (m/s) + real :: Rho0 ! Boussinesq reference density [kg m-3] + real :: G_Earth ! gravitational acceleration [m s-2] + real :: Flux_const ! piston velocity for surface restoring [m s-1] - real :: gust_const ! constant unresolved background gustiness for ustar (Pa) + real :: gust_const ! constant unresolved background gustiness for ustar [Pa] logical :: read_gust_2d ! if true, use 2-dimensional gustiness supplied from a file - real, pointer :: gust(:,:) => NULL() ! spatially varying unresolved background gustiness (Pa) + real, pointer :: gust(:,:) => NULL() ! spatially varying unresolved background gustiness [Pa] ! gust is used when read_gust_2d is true. - real, pointer :: T_Restore(:,:) => NULL() ! temperature to damp (restore) the SST to (deg C) - real, pointer :: S_Restore(:,:) => NULL() ! salinity to damp (restore) the SSS (g/kg) - real, pointer :: Dens_Restore(:,:) => NULL() ! density to damp (restore) surface density (kg/m^3) + real, pointer :: T_Restore(:,:) => NULL() ! temperature to damp (restore) the SST to [degC] + real, pointer :: S_Restore(:,:) => NULL() ! salinity to damp (restore) the SSS [ppt] + real, pointer :: Dens_Restore(:,:) => NULL() ! density to damp (restore) surface density [kg m-3] integer :: wind_last_lev_read = -1 ! The last time level read from the wind input files integer :: buoy_last_lev_read = -1 ! The last time level read from buoyancy input files @@ -167,6 +165,8 @@ module MOM_surface_forcing contains +!> This subroutine calls other subroutines in this file to get surface forcing fields. +!! It also allocates and initializes the fields in the flux type. subroutine set_forcing(sfc_state, forcing, fluxes, day_start, day_interval, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. @@ -176,21 +176,11 @@ subroutine set_forcing(sfc_state, forcing, fluxes, day_start, day_interval, G, U type(time_type), intent(in) :: day_interval !< Length of time over which these fluxes applied type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by - !! a previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call -! This subroutine calls other subroutines in this file to get surface forcing fields. -! It also allocates and initializes the fields in the flux type. - -! Arguments: -! (inout) state = structure describing ocean surface state -! (inout) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day_start = Start time of the fluxes -! (in) day_interval = Length of time over which these fluxes applied -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call - - real :: dt ! length of time in seconds over which fluxes applied + ! Local variables + real :: dt ! length of time over which fluxes applied [s] type(time_type) :: day_center ! central time of the fluxes. integer :: intdt integer :: isd, ied, jsd, jed @@ -297,17 +287,13 @@ subroutine set_forcing(sfc_state, forcing, fluxes, day_start, day_interval, G, U call cpu_clock_end(id_clock_forcing) end subroutine set_forcing +!> This subroutine allocates arrays for buoyancy forcing. subroutine buoyancy_forcing_allocate(fluxes, G, CS) - type(forcing), intent(inout) :: fluxes + type(forcing), intent(inout) :: fluxes !< A structure with pointers to thermodynamic + !! forcing fields that will be allocated here type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - type(surface_forcing_CS), pointer :: CS - -! This subroutine allocates arrays for buoyancy forcing. - -! Arguments: -! (inout) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call integer :: isd, ied, jsd, jed isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed @@ -336,6 +322,7 @@ subroutine buoyancy_forcing_allocate(fluxes, G, CS) end subroutine buoyancy_forcing_allocate +! This subroutine sets the surface wind stresses to zero subroutine wind_forcing_zero(sfc_state, forces, day, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. @@ -343,16 +330,8 @@ subroutine wind_forcing_zero(sfc_state, forces, day, G, US, CS) type(time_type), intent(in) :: day !< Time used for determining the fluxes. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - type(surface_forcing_CS), pointer :: CS - -! subroutine sets the surface wind stresses to zero - -! Arguments: -! state = structure describing ocean surface state -! (out) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call real :: PI integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq @@ -389,23 +368,17 @@ subroutine wind_forcing_zero(sfc_state, forces, day, G, US, CS) end subroutine wind_forcing_zero +!> This subroutine sets the surface wind stresses according to double gyre. subroutine wind_forcing_2gyre(sfc_state, forces, day, G, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces type(time_type), intent(in) :: day !< Time used for determining the fluxes. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - type(surface_forcing_CS), pointer :: CS - -! This subroutine sets the surface wind stresses according to double gyre. - -! Arguments: -! state = structure describing ocean surface state -! (out) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call + ! Local variables real :: PI integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB @@ -432,23 +405,17 @@ subroutine wind_forcing_2gyre(sfc_state, forces, day, G, CS) end subroutine wind_forcing_2gyre +!> This subroutine sets the surface wind stresses according to single gyre. subroutine wind_forcing_1gyre(sfc_state, forces, day, G, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces type(time_type), intent(in) :: day !< Time used for determining the fluxes. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - type(surface_forcing_CS), pointer :: CS - -! This subroutine sets the surface wind stresses according to single gyre. - -! Arguments: -! state = structure describing ocean surface state -! (out) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call + ! Local variables real :: PI integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB @@ -474,6 +441,7 @@ subroutine wind_forcing_1gyre(sfc_state, forces, day, G, CS) end subroutine wind_forcing_1gyre +!> This subroutine sets the surface wind stresses according to gyres. subroutine wind_forcing_gyres(sfc_state, forces, day, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. @@ -481,17 +449,10 @@ subroutine wind_forcing_gyres(sfc_state, forces, day, G, US, CS) type(time_type), intent(in) :: day !< Time used for determining the fluxes. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - type(surface_forcing_CS), pointer :: CS - -! This subroutine sets the surface wind stresses according to gyres. - -! Arguments: -! state = structure describing ocean surface state -! (out) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call + ! Local variables real :: PI, y integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB @@ -502,7 +463,7 @@ subroutine wind_forcing_gyres(sfc_state, forces, day, G, US, CS) isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed IsdB = G%IsdB ; IedB = G%IedB ; JsdB = G%JsdB ; JedB = G%JedB - ! steady surface wind stresses (Pa) + ! steady surface wind stresses [Pa] PI = 4.0*atan(1.0) do j=jsd,jed ; do I=IsdB,IedB @@ -526,7 +487,7 @@ subroutine wind_forcing_gyres(sfc_state, forces, day, G, US, CS) call callTree_leave("wind_forcing_gyres") end subroutine wind_forcing_gyres - +!> This subroutine sets the surface wind stresses by reading a file. subroutine wind_forcing_from_file(sfc_state, forces, day, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. @@ -534,24 +495,17 @@ subroutine wind_forcing_from_file(sfc_state, forces, day, G, US, CS) type(time_type), intent(in) :: day !< Time used for determining the fluxes. type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - type(surface_forcing_CS), pointer :: CS - -! This subroutine sets the surface wind stresses. - -! Arguments: -! state = structure describing ocean surface state -! (out) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call + ! Local variables integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB integer :: time_lev ! With fields from a file, this must ! be reset, depending on the time. character(len=200) :: filename ! The name of the input file. real :: temp_x(SZI_(G),SZJ_(G)) ! Pseudo-zonal and psuedo-meridional - real :: temp_y(SZI_(G),SZJ_(G)) ! wind stresses at h-points, in Pa. + real :: temp_y(SZI_(G),SZJ_(G)) ! wind stresses at h-points [Pa]. integer :: days, seconds call callTree_enter("wind_forcing_from_file, MOM_surface_forcing.F90") @@ -633,30 +587,21 @@ subroutine wind_forcing_from_file(sfc_state, forces, day, G, US, CS) end subroutine wind_forcing_from_file +!> This subroutine specifies the current surface fluxes of buoyancy, temperature and fresh water +!! by reading a file. It may also be modified to add surface fluxes of user provided tracers. subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. - type(forcing), intent(inout) :: fluxes + type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< Time used for determining the fluxes. real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure - type(surface_forcing_CS), pointer :: CS - -! This subroutine specifies the current surface fluxes of buoyancy -! temperature and fresh water. It may also be modified to add -! surface fluxes of user provided tracers. -! -! Arguments: -! state = structure describing ocean surface state -! (out) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) dt = amount of time over which the fluxes apply -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call - - real :: rhoXcp ! mean density times the heat capacity, in J m-3 K-1. - real :: Irho0 ! inverse Boussinesq reference density, in m3 kg-1. + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call + + real :: rhoXcp ! mean density times the heat capacity [J m-3 degC-1]. + real :: Irho0 ! inverse Boussinesq reference density [m3 kg-1]. integer :: i, j, is, ie, js, je, isd, ied, jsd, jed integer :: time_lev ! With fields from a file, this must @@ -667,12 +612,12 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, CS) real, dimension(SZI_(G),SZJ_(G)) :: & temp, & ! A 2-d temporary work array with various units. SST_anom, & ! Instantaneous sea surface temperature anomalies from a - ! target (observed) value, in deg C. + ! target (observed) value [degC]. SSS_anom, & ! Instantaneous sea surface salinity anomalies from a target - ! (observed) value, in g kg-1. + ! (observed) value [ppt]. SSS_mean ! A (mean?) salinity about which to normalize local salinity ! anomalies when calculating restorative precipitation - ! anomalies, in g kg-1. + ! anomalies [ppt]. call callTree_enter("buoyancy_forcing_from_files, MOM_surface_forcing.F90") @@ -838,28 +783,19 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, CS) end subroutine buoyancy_forcing_from_files +!> This subroutine specifies the current surface fluxes of buoyancy, temperature and fresh water. +!! It may also be modified to add surface fluxes of user provided tracers. +!! This case has zero surface buoyancy forcing. subroutine buoyancy_forcing_zero(sfc_state, fluxes, day, dt, G, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. - type(forcing), intent(inout) :: fluxes + type(forcing), intent(inout) :: fluxes !< A structure with pointers to thermodynamic forcing fields type(time_type), intent(in) :: day !< Time used for determining the fluxes. real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - type(surface_forcing_CS), pointer :: CS - -! This subroutine specifies the current surface fluxes of buoyancy -! temperature and fresh water. It may also be modified to add -! surface fluxes of user provided tracers. -! This case has zero surface buoyancy forcing. - -! Arguments: -! (inout) state = structure describing ocean surface state -! (inout) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) dt = amount of time over which the fluxes apply -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call integer :: i, j, is, ie, js, je @@ -867,7 +803,6 @@ subroutine buoyancy_forcing_zero(sfc_state, fluxes, day, dt, G, CS) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec - ! allocate and initialize arrays call buoyancy_forcing_allocate(fluxes, G, CS) @@ -896,29 +831,20 @@ subroutine buoyancy_forcing_zero(sfc_state, fluxes, day, dt, G, CS) call callTree_leave("buoyancy_forcing_zero") end subroutine buoyancy_forcing_zero - +!> This subroutine specifies the current surface fluxes of buoyancy, temperature and fresh water. +!! It may also be modified to add surface fluxes of user provided tracers. subroutine buoyancy_forcing_linear(sfc_state, fluxes, day, dt, G, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. - type(forcing), intent(inout) :: fluxes + type(forcing), intent(inout) :: fluxes !< A structure with pointers to thermodynamic forcing fields type(time_type), intent(in) :: day !< Time used for determining the fluxes. real, intent(in) :: dt !< The amount of time over which !! the fluxes apply, in s type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - type(surface_forcing_CS), pointer :: CS - -! This subroutine specifies the current surface fluxes of buoyancy -! temperature and fresh water. It may also be modified to add -! surface fluxes of user provided tracers. -! -! Arguments: -! (inout) state = structure describing ocean surface state -! (inout) fluxes = structure with pointers to forcing fields; unused have NULL ptrs -! (in) day = time of the fluxes -! (in) dt = amount of time over which the fluxes apply -! (in) G = ocean grid structure -! (in) CS = pointer to control struct returned by previous surface_forcing_init call + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by a + !! previous surface_forcing_init call + ! Local variables real :: y, T_restore, S_restore integer :: i, j, is, ie, js, je @@ -991,24 +917,19 @@ subroutine buoyancy_forcing_linear(sfc_state, fluxes, day, dt, G, CS) call callTree_leave("buoyancy_forcing_linear") end subroutine buoyancy_forcing_linear - +!> Save any restart files associated with the surface forcing. subroutine forcing_save_restart(CS, G, Time, directory, time_stamped, & filename_suffix) - type(surface_forcing_CS), pointer :: CS + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned + !! by a previous call to surface_forcing_init type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure - type(time_type), intent(in) :: Time - character(len=*), intent(in) :: directory - logical, optional, intent(in) :: time_stamped - character(len=*), optional, intent(in) :: filename_suffix -! Arguments: CS - A pointer to the control structure returned by a previous -! call to surface_forcing_init. -! (in) G - The ocean's grid structure. -! (in) Time - The model time at this call. This is needed for mpp_write calls. -! (in, opt) directory - An optional directory into which to write these restart files. -! (in, opt) time_stamped - If true, the restart file names include -! a unique time stamp. The default is false. -! (in, opt) filename_suffix - An optional suffix (e.g., a time-stamp) to append -! to the restart file names. + type(time_type), intent(in) :: Time !< The current model time + character(len=*), intent(in) :: directory !< The directory into which to write the + !! restart files + logical, optional, intent(in) :: time_stamped !< If true, the restart file names include + !! a unique time stamp. The default is false. + character(len=*), optional, intent(in) :: filename_suffix !< An optional suffix (e.g., a time- + !! stamp) to append to the restart file names. if (.not.associated(CS)) return if (.not.associated(CS%restart_CSp)) return @@ -1017,23 +938,19 @@ subroutine forcing_save_restart(CS, G, Time, directory, time_stamped, & end subroutine forcing_save_restart +!> Initialize the surface forcing, including setting parameters and allocating permanent memory. subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_CSp) - type(time_type), intent(in) :: Time + type(time_type), intent(in) :: Time !< The current model time type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters - type(diag_ctrl), target, intent(in) :: diag - type(surface_forcing_CS), pointer :: CS - type(tracer_flow_control_CS), pointer :: tracer_flow_CSp -! Arguments: Time - The current model time. -! (in) G - The ocean's grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. -! (in) diag - A structure that is used to regulate diagnostic output. -! (in/out) CS - A pointer that is set to point to the control structure -! for this module -! (in) tracer_flow_CSp - A pointer to the control structure of the tracer -! flow control module. + type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate diagnostic output. + type(surface_forcing_CS), pointer :: CS !< A pointer that is set to point to the control structure + !! for this module + type(tracer_flow_control_CS), pointer :: tracer_flow_CSp !< A pointer to the control structure of + !! the tracer flow control module. + + ! Local variables type(directories) :: dirs logical :: new_sim type(time_type) :: Time_frc @@ -1262,14 +1179,13 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C call cpu_clock_end(id_clock_forcing) end subroutine surface_forcing_init - +!> Clean up and deallocate any memory associated with this module and its children. subroutine surface_forcing_end(CS, fluxes) - type(surface_forcing_CS), pointer :: CS - type(forcing), optional, intent(inout) :: fluxes -! Arguments: CS - A pointer to the control structure returned by a previous -! call to surface_forcing_init, it will be deallocated here. -! (inout) fluxes - A structure containing pointers to any possible -! forcing fields. Unused fields have NULL ptrs. + type(surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned + !! by a previous surface_forcing_init call + !! that will be deallocated here. + type(forcing), optional, intent(inout) :: fluxes !< A structure containing pointers to any possible + !! forcing fields that will be deallocated here. if (present(fluxes)) call deallocate_forcing_type(fluxes) diff --git a/config_src/ice_solo_driver/user_surface_forcing.F90 b/config_src/ice_solo_driver/user_surface_forcing.F90 index 22ea1d08fb..33c66a3c40 100644 --- a/config_src/ice_solo_driver/user_surface_forcing.F90 +++ b/config_src/ice_solo_driver/user_surface_forcing.F90 @@ -62,6 +62,11 @@ module user_surface_forcing public USER_wind_forcing, USER_buoyancy_forcing, USER_surface_forcing_init +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + type, public :: user_surface_forcing_CS ; private ! This control structure should be used to store any run-time variables ! associated with the user-specified forcing. It can be readily modified @@ -74,11 +79,11 @@ module user_surface_forcing ! state variables. logical :: restorebuoy ! If true, use restoring surface buoyancy forcing. real :: Rho0 ! The density used in the Boussinesq - ! approximation, in kg m-3. - real :: G_Earth ! The gravitational acceleration in m s-2. - real :: Flux_const ! The restoring rate at the surface, in m s-1. + ! approximation [kg m-3]. + real :: G_Earth ! The gravitational acceleration [m s-2]. + real :: Flux_const ! The restoring rate at the surface [m s-1]. real :: gust_const ! A constant unresolved background gustiness - ! that contributes to ustar, in Pa. + ! that contributes to ustar [Pa]. type(diag_ctrl), pointer :: diag ! A structure that is used to regulate the ! timing of diagnostic output. @@ -86,9 +91,9 @@ module user_surface_forcing contains -!> This subroutine sets the surface wind stresses, forces%taux and forces%tauy. +!> This subroutine sets the surface wind stresses, forces%taux and forces%tauy, in [Pa]. !! These are the stresses in the direction of the model grid (i.e. the same -!! direction as the u- and v- velocities.) They are both in Pa. +!! direction as the u- and v- velocities). subroutine USER_wind_forcing(sfc_state, forces, day, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. @@ -99,20 +104,9 @@ subroutine USER_wind_forcing(sfc_state, forces, day, G, US, CS) type(user_surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned !! by a previous call to user_surface_forcing_init -! This subroutine sets the surface wind stresses, forces%taux and forces%tauy. -! These are the stresses in the direction of the model grid (i.e. the same -! direction as the u- and v- velocities.) They are both in Pa. -! In addition, this subroutine can be used to set the surface friction -! velocity, forces%ustar, in Z s-1. This is needed with a bulk mixed layer. -! -! Arguments: state - A structure containing fields that describe the -! surface state of the ocean. -! (out) fluxes - A structure containing pointers to any possible -! forcing fields. Unused fields have NULL ptrs. -! (in) day - Time of the fluxes. -! (in) G - The ocean's grid structure. -! (in) CS - A pointer to the control structure returned by a previous -! call to user_surface_forcing_init +! This subroutine sets the surface wind stresses, forces%taux and forces%tauy [Pa]. +! In addition, this subroutine can be used to set the surface friction velocity, +! forces%ustar [Z s-1 ~> m s-1], which is needed with a bulk mixed layer. integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB @@ -130,7 +124,7 @@ subroutine USER_wind_forcing(sfc_state, forces, day, G, US, CS) ! Allocate the forcing arrays, if necessary. call allocate_mech_forcing(G, forces, stress=.true., ustar=.true.) - ! Set the surface wind stresses, in units of Pa. A positive taux + ! Set the surface wind stresses [Pa]. A positive taux ! accelerates the ocean to the (pseudo-)east. ! The i-loop extends to is-1 so that taux can be used later in the @@ -142,8 +136,7 @@ subroutine USER_wind_forcing(sfc_state, forces, day, G, US, CS) forces%tauy(i,J) = G%mask2dCv(i,J) * 0.0 ! Change this to the desired expression. enddo ; enddo - ! Set the surface friction velocity, in units of m s-1. ustar - ! is always positive. + ! Set the surface friction velocity [Z s-1 ~> m s-1]. ustar is always positive. if (associated(forces%ustar)) then ; do j=js,je ; do i=is,ie ! This expression can be changed if desired, but need not be. forces%ustar(i,j) = US%m_to_Z * G%mask2dT(i,j) * sqrt(CS%gust_const/CS%Rho0 + & @@ -162,7 +155,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(user_surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned !! by a previous call to user_surface_forcing_init @@ -181,24 +174,13 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! are in W m-2 and positive for heat going into the ocean. All fresh water ! fluxes are in kg m-2 s-1 and positive for water moving into the ocean. -! Arguments: state - A structure containing fields that describe the -! surface state of the ocean. -! (out) fluxes - A structure containing pointers to any possible -! forcing fields. Unused fields have NULL ptrs. -! (in) day_start - Start time of the fluxes. -! (in) day_interval - Length of time over which these fluxes -! will be applied. -! (in) G - The ocean's grid structure. -! (in) CS - A pointer to the control structure returned by a previous -! call to user_surface_forcing_init - - real :: Temp_restore ! The temperature that is being restored toward, in C. - real :: Salin_restore ! The salinity that is being restored toward, in PSU. + real :: Temp_restore ! The temperature that is being restored toward [C]. + real :: Salin_restore ! The salinity that is being restored toward [ppt] real :: density_restore ! The potential density that is being restored - ! toward, in kg m-3. - real :: rhoXcp ! The mean density times the heat capacity, in J m-3 K-1. + ! toward [kg m-3]. + real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1]. real :: buoy_rest_const ! A constant relating density anomalies to the - ! restoring buoyancy flux, in m5 s-3 kg-1. + ! restoring buoyancy flux [m5 s-3 kg-1]. integer :: i, j, is, ie, js, je integer :: isd, ied, jsd, jed @@ -236,7 +218,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! Set whichever fluxes are to be used here. Any fluxes that ! are always zero do not need to be changed here. do j=js,je ; do i=is,ie - ! Fluxes of fresh water through the surface are in units of kg m-2 s-1 + ! Fluxes of fresh water through the surface are in units of [kg m-2 s-1] ! and are positive downward - i.e. evaporation should be negative. fluxes%evap(i,j) = -0.0 * G%mask2dT(i,j) fluxes%lprec(i,j) = 0.0 * G%mask2dT(i,j) @@ -244,7 +226,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! vprec will be set later, if it is needed for salinity restoring. fluxes%vprec(i,j) = 0.0 - ! Heat fluxes are in units of W m-2 and are positive into the ocean. + ! Heat fluxes are in units of [W m-2] and are positive into the ocean. fluxes%lw(i,j) = 0.0 * G%mask2dT(i,j) fluxes%latent(i,j) = 0.0 * G%mask2dT(i,j) fluxes%sens(i,j) = 0.0 * G%mask2dT(i,j) @@ -252,7 +234,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) enddo ; enddo else ! This is the buoyancy only mode. do j=js,je ; do i=is,ie - ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive + ! fluxes%buoy is the buoyancy flux into the ocean [m2 s-3]. A positive ! buoyancy flux is of the same sign as heating the ocean. fluxes%buoy(i,j) = 0.0 * G%mask2dT(i,j) enddo ; enddo @@ -268,8 +250,8 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) rhoXcp = CS%Rho0 * fluxes%C_p do j=js,je ; do i=is,ie - ! Set Temp_restore and Salin_restore to the temperature (in C) and - ! salinity (in PSU) that are being restored toward. + ! Set Temp_restore and Salin_restore to the temperature (in degC) and + ! salinity (in ppt or PSU) that are being restored toward. Temp_restore = 0.0 Salin_restore = 0.0 @@ -289,7 +271,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) buoy_rest_const = -1.0 * (CS%G_Earth * CS%Flux_const) / CS%Rho0 do j=js,je ; do i=is,ie ! Set density_restore to an expression for the surface potential - ! density in kg m-3 that is being restored toward. + ! density [kg m-3] that is being restored toward. density_restore = 1030.0 fluxes%buoy(i,j) = G%mask2dT(i,j) * buoy_rest_const * & @@ -309,16 +291,8 @@ subroutine USER_surface_forcing_init(Time, G, param_file, diag, CS) type(user_surface_forcing_CS), pointer :: CS !< A pointer that is set to point to !! the control structure for this module -! Arguments: Time - The current model time. -! (in) G - The ocean's grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. -! (in) diag - A structure that is used to regulate diagnostic output. -! (in/out) CS - A pointer that is set to point to the control structure -! for this module - -! This include declares and sets the variable "version". -#include "version_variable.h" + ! This include declares and sets the variable "version". +# include "version_variable.h" character(len=40) :: mdl = "user_surface_forcing" ! This module's name. if (associated(CS)) then diff --git a/config_src/mct_driver/MOM_ocean_model.F90 b/config_src/mct_driver/MOM_ocean_model.F90 index 1a3a06b4d8..64ef660dbf 100644 --- a/config_src/mct_driver/MOM_ocean_model.F90 +++ b/config_src/mct_driver/MOM_ocean_model.F90 @@ -247,8 +247,8 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, i ! Because of the way that indicies and domains are handled, Ocean_sfc must have ! been used in a previous call to initialize_ocean_type. - real :: Rho0 !< The Boussinesq ocean density, in kg m-3. - real :: G_Earth !< The gravitational acceleration in m s-2. + real :: Rho0 !< The Boussinesq ocean density [kg m-3]. + real :: G_Earth !< The gravitational acceleration [m s-2]. !! This include declares and sets the variable "version". real :: HFrz !< If HFrz > 0 (m), melt potential will be computed. !! The actual depth over which melt potential is computed will diff --git a/config_src/mct_driver/MOM_surface_forcing.F90 b/config_src/mct_driver/MOM_surface_forcing.F90 index 1e07e791e8..173ffd1e3d 100644 --- a/config_src/mct_driver/MOM_surface_forcing.F90 +++ b/config_src/mct_driver/MOM_surface_forcing.F90 @@ -94,10 +94,10 @@ module MOM_surface_forcing gust => NULL(), & !< spatially varying unresolved background !! gustiness that contributes to ustar (Pa). !! gust is used when read_gust_2d is true. - ustar_tidal => NULL() !< tidal contribution to the bottom friction velocity (m/s) + ustar_tidal => NULL() !< tidal contribution to the bottom friction velocity [m s-1] real :: cd_tides !< drag coefficient that applies to the tides (nondimensional) real :: utide !< constant tidal velocity to use if read_tideamp - !! is false, in m s-1. + !! is false [m s-1]. logical :: read_tideamp !< If true, spatially varying tidal amplitude read from a file. logical :: rigid_sea_ice !< If true, sea-ice exerts a rigidity that acts !! to damp surface deflections (especially surface @@ -110,7 +110,7 @@ module MOM_surface_forcing !! sea-ice viscosity becomes effective, in kg m-2, !! typically of order 1000 kg m-2. logical :: allow_flux_adjustments !< If true, use data_override to obtain flux adjustments - real :: Flux_const !< piston velocity for surface restoring (m/s) + real :: Flux_const !< piston velocity for surface restoring [m s-1] logical :: salt_restore_as_sflux !< If true, SSS restore as salt flux instead of water flux logical :: adjust_net_srestore_to_zero !< adjust srestore to zero (for both salt_flux or vprec) logical :: adjust_net_srestore_by_scaling !< adjust srestore w/o moving zero contour @@ -169,7 +169,7 @@ module MOM_surface_forcing real, pointer, dimension(:,:) :: fprec =>NULL() !< mass flux of frozen precip (kg/m2/s) real, pointer, dimension(:,:) :: runoff =>NULL() !< mass flux of liquid runoff (kg/m2/s) real, pointer, dimension(:,:) :: calving =>NULL() !< mass flux of frozen runoff (kg/m2/s) - real, pointer, dimension(:,:) :: ustar_berg =>NULL() !< frictional velocity beneath icebergs (m/s) + real, pointer, dimension(:,:) :: ustar_berg =>NULL() !< frictional velocity beneath icebergs [m s-1] real, pointer, dimension(:,:) :: area_berg =>NULL() !< area covered by icebergs(m2/m2) real, pointer, dimension(:,:) :: mass_berg =>NULL() !< mass of icebergs(kg/m2) real, pointer, dimension(:,:) :: runoff_hflx =>NULL() !< heat content of liquid runoff (W/m2) @@ -979,7 +979,7 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, restore_salt, !! temp/salt restoring will be applied ! local variables - real :: utide !< The RMS tidal velocity, in m s-1. + real :: utide !< The RMS tidal velocity [m s-1]. type(directories) :: dirs logical :: new_sim, iceberg_flux_diags type(time_type) :: Time_frc @@ -1150,7 +1150,7 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, restore_salt, endif -! Optionally read tidal amplitude from input file (m s-1) on model grid. +! Optionally read tidal amplitude from input file [m s-1] on model grid. ! Otherwise use default tidal amplitude for bottom frictionally-generated ! dissipation. Default cd_tides is chosen to yield approx 1 TWatt of ! work done against tides globally using OSU tidal amplitude. diff --git a/config_src/mct_driver/ocn_cap_methods.F90 b/config_src/mct_driver/ocn_cap_methods.F90 index 95fd084bdc..a04e3af4aa 100644 --- a/config_src/mct_driver/ocn_cap_methods.F90 +++ b/config_src/mct_driver/ocn_cap_methods.F90 @@ -154,7 +154,7 @@ subroutine ocn_export(ind, ocn_public, grid, o2x, dt_int, ncouple_per_day) real, dimension(grid%isd:grid%ied,grid%jsd:grid%jed) :: ssh !< Local copy of sea_lev with updated halo integer :: i, j, n, ig, jg !< Grid indices real :: slp_L, slp_R, slp_C, slope, u_min, u_max - real :: I_time_int !< The inverse of coupling time interval in s-1. + real :: I_time_int !< The inverse of coupling time interval [s-1]. !----------------------------------------------------------------------- diff --git a/config_src/mct_driver/ocn_comp_mct.F90 b/config_src/mct_driver/ocn_comp_mct.F90 index 97692ccc65..c2e8423e4b 100644 --- a/config_src/mct_driver/ocn_comp_mct.F90 +++ b/config_src/mct_driver/ocn_comp_mct.F90 @@ -765,7 +765,7 @@ end subroutine ocean_model_init_sfc !! x2o_Foxx_rof !! !! Variables in MOM6 fluxes that are **NOT** filled by the coupler: -!! ustar_berg, frictional velocity beneath icebergs (m/s) +!! ustar_berg, frictional velocity beneath icebergs [m s-1] !! area_berg, area covered by icebergs(m2/m2) !! mass_berg, mass of icebergs(kg/m2) !! runoff_hflx, heat content of liquid runoff (W/m2) @@ -804,8 +804,8 @@ end subroutine ocean_model_init_sfc !! !! Surface temperature (Kelvin) !! Surface salinity (psu) -!! Surface eastward velocity (m/s) -!! Surface northward velocity (m/s) +!! Surface eastward velocity [m s-1] +!! Surface northward velocity [m s-1] !! Zonal slope in the sea surface height !! Meridional slope in the sea surface height !! diff --git a/config_src/mct_driver/ocn_cpl_indices.F90 b/config_src/mct_driver/ocn_cpl_indices.F90 index 52f94f6106..645b358ec1 100644 --- a/config_src/mct_driver/ocn_cpl_indices.F90 +++ b/config_src/mct_driver/ocn_cpl_indices.F90 @@ -10,8 +10,8 @@ module ocn_cpl_indices type cpl_indices_type ! ocean to coupler integer :: o2x_So_t !< Surface potential temperature (deg C) - integer :: o2x_So_u !< Surface zonal velocity (m/s) - integer :: o2x_So_v !< Surface meridional velocity (m/s) + integer :: o2x_So_u !< Surface zonal velocity [m s-1] + integer :: o2x_So_v !< Surface meridional velocity [m s-1] integer :: o2x_So_s !< Surface salinity (PSU) integer :: o2x_So_dhdx !< Zonal slope in the sea surface height integer :: o2x_So_dhdy !< Meridional lope in the sea surface height diff --git a/config_src/solo_driver/MESO_surface_forcing.F90 b/config_src/solo_driver/MESO_surface_forcing.F90 index 68852f89d9..28dc5305f1 100644 --- a/config_src/solo_driver/MESO_surface_forcing.F90 +++ b/config_src/solo_driver/MESO_surface_forcing.F90 @@ -26,18 +26,18 @@ module MESO_surface_forcing logical :: use_temperature !< If true, temperature and salinity are used as state variables. logical :: restorebuoy !< If true, use restoring surface buoyancy forcing. - real :: Rho0 !< The density used in the Boussinesq approximation, in kg m-3. - real :: G_Earth !< The gravitational acceleration in m s-2. - real :: Flux_const !< The restoring rate at the surface, in m s-1. + real :: Rho0 !< The density used in the Boussinesq approximation [kg m-3]. + real :: G_Earth !< The gravitational acceleration [m s-2]. + real :: Flux_const !< The restoring rate at the surface [m s-1]. real :: gust_const !< A constant unresolved background gustiness - !! that contributes to ustar, in Pa. + !! that contributes to ustar [Pa]. real, dimension(:,:), pointer :: & - T_Restore(:,:) => NULL(), & !< The temperature to restore the SST toward, in C. - S_Restore(:,:) => NULL(), & !< The salinity to restore the sea surface salnity toward, in PSU. - PmE(:,:) => NULL(), & !< The prescribed precip minus evap, in m s-1. - Solar(:,:) => NULL() !< The shortwave forcing into the ocean, in W m-2 m s-1. + T_Restore(:,:) => NULL(), & !< The temperature to restore the SST toward [degC]. + S_Restore(:,:) => NULL(), & !< The salinity to restore the sea surface salnity toward [ppt] + PmE(:,:) => NULL(), & !< The prescribed precip minus evap [m s-1]. + Solar(:,:) => NULL() !< The shortwave forcing into the ocean [W m-2]. real, dimension(:,:), pointer :: Heat(:,:) => NULL() !< The prescribed longwave, latent and sensible - !! heat flux into the ocean, in W m-2. + !! heat flux into the ocean [W m-2]. character(len=200) :: inputdir !< The directory where NetCDF input files are. character(len=200) :: salinityrestore_file !< The file with the target sea surface salinity character(len=200) :: SSTrestore_file !< The file with the target sea surface temperature @@ -60,7 +60,7 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(MESO_surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by !! a previous call to MESO_surface_forcing_init @@ -75,13 +75,13 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! are in W m-2 and positive for heat going into the ocean. All fresh water ! fluxes are in kg m-2 s-1 and positive for water moving into the ocean. - real :: Temp_restore ! The temperature that is being restored toward, in C. - real :: Salin_restore ! The salinity that is being restored toward, in PSU. + real :: Temp_restore ! The temperature that is being restored toward [degC]. + real :: Salin_restore ! The salinity that is being restored toward [ppt] real :: density_restore ! The potential density that is being restored - ! toward, in kg m-3. - real :: rhoXcp ! The mean density times the heat capacity, in J m-3 K-1. + ! toward [kg m-3]. + real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1]. real :: buoy_rest_const ! A constant relating density anomalies to the - ! restoring buoyancy flux, in m5 s-3 kg-1. + ! restoring buoyancy flux [m5 s-3 kg-1]. integer :: i, j, is, ie, js, je integer :: isd, ied, jsd, jed @@ -137,7 +137,7 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! Set whichever fluxes are to be used here. Any fluxes that ! are always zero do not need to be changed here. do j=js,je ; do i=is,ie - ! Fluxes of fresh water through the surface are in units of kg m-2 s-1 + ! Fluxes of fresh water through the surface are in units of [kg m-2 s-1] ! and are positive downward - i.e. evaporation should be negative. fluxes%evap(i,j) = -0.0 * G%mask2dT(i,j) fluxes%lprec(i,j) = CS%PmE(i,j) * CS%Rho0 * G%mask2dT(i,j) @@ -145,7 +145,7 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! vprec will be set later, if it is needed for salinity restoring. fluxes%vprec(i,j) = 0.0 - ! Heat fluxes are in units of W m-2 and are positive into the ocean. + ! Heat fluxes are in units of [W m-2] and are positive into the ocean. fluxes%lw(i,j) = 0.0 * G%mask2dT(i,j) fluxes%latent(i,j) = 0.0 * G%mask2dT(i,j) fluxes%sens(i,j) = CS%Heat(i,j) * G%mask2dT(i,j) @@ -153,7 +153,7 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) enddo ; enddo else ! This is the buoyancy only mode. do j=js,je ; do i=is,ie - ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive + ! fluxes%buoy is the buoyancy flux into the ocean [m2 s-3]. A positive ! buoyancy flux is of the same sign as heating the ocean. fluxes%buoy(i,j) = 0.0 * G%mask2dT(i,j) enddo ; enddo @@ -169,8 +169,8 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) rhoXcp = CS%Rho0 * fluxes%C_p do j=js,je ; do i=is,ie - ! Set Temp_restore and Salin_restore to the temperature (in C) and - ! salinity (in PSU) that are being restored toward. + ! Set Temp_restore and Salin_restore to the temperature (in degC) and + ! salinity (in ppt or PSU) that are being restored toward. if (G%mask2dT(i,j) > 0) then fluxes%heat_added(i,j) = G%mask2dT(i,j) * & ((CS%T_Restore(i,j) - sfc_state%SST(i,j)) * rhoXcp * CS%Flux_const) @@ -192,7 +192,7 @@ subroutine MESO_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) buoy_rest_const = -1.0 * (CS%G_Earth * CS%Flux_const) / CS%Rho0 do j=js,je ; do i=is,ie ! Set density_restore to an expression for the surface potential - ! density in kg m-3 that is being restored toward. + ! density [kg m-3] that is being restored toward. density_restore = 1030.0 fluxes%buoy(i,j) = G%mask2dT(i,j) * buoy_rest_const * & diff --git a/config_src/solo_driver/MOM_driver.F90 b/config_src/solo_driver/MOM_driver.F90 index 5ccb00c1ae..14890af0f8 100644 --- a/config_src/solo_driver/MOM_driver.F90 +++ b/config_src/solo_driver/MOM_driver.F90 @@ -127,14 +127,14 @@ program MOM_main type(time_type) :: restart_time ! The next time to write restart files. type(time_type) :: Time_step_ocean ! A time_type version of dt_forcing. - real :: elapsed_time = 0.0 ! Elapsed time in this run in seconds. + real :: elapsed_time = 0.0 ! Elapsed time in this run [s]. logical :: elapsed_time_master ! If true, elapsed time is used to set the ! model's master clock (Time). This is needed ! if Time_step_ocean is not an exact ! representation of dt_forcing. - real :: dt_forcing ! The coupling time step in seconds. - real :: dt ! The baroclinic dynamics time step, in seconds. - real :: dt_off ! Offline time step in seconds + real :: dt_forcing ! The coupling time step [s]. + real :: dt ! The baroclinic dynamics time step [s]. + real :: dt_off ! Offline time step [s]. integer :: ntstep ! The number of baroclinic dynamics time steps ! within dt_forcing. real :: dt_therm @@ -150,7 +150,7 @@ program MOM_main ! restart file is saved at the end of a run segment ! unless Restart_control is negative. - real :: Time_unit ! The time unit in seconds for the following input fields. + real :: Time_unit ! The time unit for the following input fields [s]. type(time_type) :: restint ! The time between saves of the restart file. type(time_type) :: daymax ! The final day of the simulation. diff --git a/config_src/solo_driver/MOM_surface_forcing.F90 b/config_src/solo_driver/MOM_surface_forcing.F90 index d404edf9f3..75a1ec321a 100644 --- a/config_src/solo_driver/MOM_surface_forcing.F90 +++ b/config_src/solo_driver/MOM_surface_forcing.F90 @@ -78,32 +78,32 @@ module MOM_surface_forcing real :: south_lat !< southern latitude of the domain real :: len_lat !< domain length in latitude - real :: Rho0 !< Boussinesq reference density (kg/m^3) - real :: G_Earth !< gravitational acceleration (m/s^2) - real :: Flux_const !< piston velocity for surface restoring (m/s) - real :: Flux_const_T !< piston velocity for surface temperature restoring (m/s) - real :: Flux_const_S !< piston velocity for surface salinity restoring (m/s) - real :: latent_heat_fusion !< latent heat of fusion (J/kg) - real :: latent_heat_vapor !< latent heat of vaporization (J/kg) + real :: Rho0 !< Boussinesq reference density [kg m-3] + real :: G_Earth !< gravitational acceleration [m s-2] + real :: Flux_const !< piston velocity for surface restoring [m s-1] + real :: Flux_const_T !< piston velocity for surface temperature restoring [m s-1] + real :: Flux_const_S !< piston velocity for surface salinity restoring [m s-1] + real :: latent_heat_fusion !< latent heat of fusion [J kg-1] + real :: latent_heat_vapor !< latent heat of vaporization [J kg-1] real :: tau_x0 !< Constant zonal wind stress used in the WIND_CONFIG="const" forcing real :: tau_y0 !< Constant meridional wind stress used in the WIND_CONFIG="const" forcing - real :: gust_const !< constant unresolved background gustiness for ustar (Pa) + real :: gust_const !< constant unresolved background gustiness for ustar [Pa] logical :: read_gust_2d !< if true, use 2-dimensional gustiness supplied from a file - real, pointer :: gust(:,:) => NULL() !< spatially varying unresolved background gustiness (Pa) + real, pointer :: gust(:,:) => NULL() !< spatially varying unresolved background gustiness [Pa] !! gust is used when read_gust_2d is true. - real, pointer :: T_Restore(:,:) => NULL() !< temperature to damp (restore) the SST to (deg C) - real, pointer :: S_Restore(:,:) => NULL() !< salinity to damp (restore) the SSS (g/kg) - real, pointer :: Dens_Restore(:,:) => NULL() !< density to damp (restore) surface density (kg/m^3) + real, pointer :: T_Restore(:,:) => NULL() !< temperature to damp (restore) the SST to [degC] + real, pointer :: S_Restore(:,:) => NULL() !< salinity to damp (restore) the SSS [ppt] + real, pointer :: Dens_Restore(:,:) => NULL() !< density to damp (restore) surface density [kg m-3] integer :: buoy_last_lev_read = -1 !< The last time level read from buoyancy input files ! if WIND_CONFIG=='gyres' then use the following as = A, B, C and n respectively for ! taux = A + B*sin(n*pi*y/L) + C*cos(n*pi*y/L) - real :: gyres_taux_const !< A constant wind stress, in Pa. - real :: gyres_taux_sin_amp !< The amplitude of cosine wind stress gyres, in Pa, if WIND_CONFIG=='gyres'. - real :: gyres_taux_cos_amp !< The amplitude of cosine wind stress gyres, in Pa, if WIND_CONFIG=='gyres'. + real :: gyres_taux_const !< A constant wind stress [Pa]. + real :: gyres_taux_sin_amp !< The amplitude of cosine wind stress gyres [Pa], if WIND_CONFIG=='gyres'. + real :: gyres_taux_cos_amp !< The amplitude of cosine wind stress gyres [Pa], if WIND_CONFIG=='gyres'. real :: gyres_taux_n_pis !< The number of sine lobes in the basin if if WIND_CONFIG=='gyres' @@ -226,7 +226,7 @@ subroutine set_forcing(sfc_state, forces, fluxes, day_start, day_interval, G, US type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by !! a previous surface_forcing_init call ! Local variables - real :: dt ! length of time in seconds over which fluxes applied + real :: dt ! length of time over which fluxes applied [s] type(time_type) :: day_center ! central time of the fluxes. integer :: isd, ied, jsd, jed isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed @@ -360,8 +360,8 @@ subroutine wind_forcing_const(sfc_state, forces, tau_x0, tau_y0, day, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces - real, intent(in) :: tau_x0 !< The zonal wind stress in Pa - real, intent(in) :: tau_y0 !< The meridional wind stress in Pa + real, intent(in) :: tau_x0 !< The zonal wind stress [Pa] + real, intent(in) :: tau_y0 !< The meridional wind stress [Pa] type(time_type), intent(in) :: day !< The time of the fluxes type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type @@ -484,7 +484,7 @@ subroutine wind_forcing_gyres(sfc_state, forces, day, G, US, CS) is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB - ! steady surface wind stresses (Pa) + ! steady surface wind stresses [Pa] PI = 4.0*atan(1.0) do j=js-1,je+1 ; do I=is-1,Ieq @@ -522,7 +522,7 @@ subroutine wind_forcing_from_file(sfc_state, forces, day, G, US, CS) ! Local variables character(len=200) :: filename ! The name of the input file. real :: temp_x(SZI_(G),SZJ_(G)) ! Pseudo-zonal and psuedo-meridional - real :: temp_y(SZI_(G),SZJ_(G)) ! wind stresses at h-points, in Pa. + real :: temp_y(SZI_(G),SZJ_(G)) ! wind stresses at h-points [Pa]. integer :: time_lev_daily ! The time levels to read for fields with integer :: time_lev_monthly ! daily and montly cycles. integer :: time_lev ! The time level that is used for a field. @@ -671,8 +671,8 @@ subroutine wind_forcing_by_data_override(sfc_state, forces, day, G, US, CS) !! a previous surface_forcing_init call ! Local variables real :: temp_x(SZI_(G),SZJ_(G)) ! Pseudo-zonal and psuedo-meridional - real :: temp_y(SZI_(G),SZJ_(G)) ! wind stresses at h-points, in Pa. - real :: temp_ustar(SZI_(G),SZJ_(G)) ! ustar in m s-1 (not rescaled). + real :: temp_y(SZI_(G),SZJ_(G)) ! wind stresses at h-points [Pa]. + real :: temp_ustar(SZI_(G),SZJ_(G)) ! ustar [m s-1] (not rescaled). integer :: i, j, is_in, ie_in, js_in, je_in logical :: read_uStar @@ -735,7 +735,7 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by !! a previous surface_forcing_init call @@ -743,15 +743,15 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, CS) real, dimension(SZI_(G),SZJ_(G)) :: & temp, & ! A 2-d temporary work array with various units. SST_anom, & ! Instantaneous sea surface temperature anomalies from a - ! target (observed) value, in deg C. + ! target (observed) value [degC]. SSS_anom, & ! Instantaneous sea surface salinity anomalies from a target - ! (observed) value, in g kg-1. + ! (observed) value [ppt]. SSS_mean ! A (mean?) salinity about which to normalize local salinity ! anomalies when calculating restorative precipitation - ! anomalies, in g kg-1. + ! anomalies [ppt]. - real :: rhoXcp ! reference density times heat capacity (J/(m^3 * K)) - real :: Irho0 ! inverse of the Boussinesq reference density (m^3/kg) + real :: rhoXcp ! reference density times heat capacity [J m-3 degC-1] + real :: Irho0 ! inverse of the Boussinesq reference density [m3 kg-1] integer :: time_lev_daily ! time levels to read for fields with daily cycle integer :: time_lev_monthly ! time levels to read for fields with monthly cycle @@ -1013,7 +1013,7 @@ subroutine buoyancy_forcing_from_data_override(sfc_state, fluxes, day, dt, G, CS type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by !! a previous surface_forcing_init call @@ -1021,14 +1021,14 @@ subroutine buoyancy_forcing_from_data_override(sfc_state, fluxes, day, dt, G, CS real, dimension(SZI_(G),SZJ_(G)) :: & temp, & ! A 2-d temporary work array with various units. SST_anom, & ! Instantaneous sea surface temperature anomalies from a - ! target (observed) value, in deg C. + ! target (observed) value [degC]. SSS_anom, & ! Instantaneous sea surface salinity anomalies from a target - ! (observed) value, in g kg-1. + ! (observed) value [ppt]. SSS_mean ! A (mean?) salinity about which to normalize local salinity ! anomalies when calculating restorative precipitation - ! anomalies, in g kg-1. - real :: rhoXcp ! The mean density times the heat capacity, in J m-3 K-1. - real :: Irho0 ! The inverse of the Boussinesq density, in m3 kg-1. + ! anomalies [ppt]. + real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1]. + real :: Irho0 ! The inverse of the Boussinesq density [m3 kg-1]. integer :: time_lev_daily ! The time levels to read for fields with integer :: time_lev_monthly ! daily and montly cycles. @@ -1179,7 +1179,7 @@ subroutine buoyancy_forcing_zero(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by !! a previous surface_forcing_init call @@ -1222,7 +1222,7 @@ subroutine buoyancy_forcing_const(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by !! a previous surface_forcing_init call @@ -1264,7 +1264,7 @@ subroutine buoyancy_forcing_linear(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(surface_forcing_CS), pointer :: CS !< pointer to control struct returned by !! a previous surface_forcing_init call diff --git a/config_src/solo_driver/Neverland_surface_forcing.F90 b/config_src/solo_driver/Neverland_surface_forcing.F90 index 192d894661..94726a62c3 100644 --- a/config_src/solo_driver/Neverland_surface_forcing.F90 +++ b/config_src/solo_driver/Neverland_surface_forcing.F90 @@ -32,9 +32,9 @@ module Neverland_surface_forcing logical :: use_temperature !< If true, use temperature and salinity. logical :: restorebuoy !< If true, use restoring surface buoyancy forcing. real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. - real :: G_Earth !< The gravitational acceleration in m s-2. - real :: flux_const !< The restoring rate at the surface, in m s-1. + !! approximation [kg m-3]. + real :: G_Earth !< The gravitational acceleration [m s-2]. + real :: flux_const !< The restoring rate at the surface [m s-1]. real, dimension(:,:), pointer :: & buoy_restore(:,:) => NULL() !< The pattern to restore buoyancy to. character(len=200) :: inputdir !< The directory where NetCDF input files are. @@ -145,7 +145,7 @@ subroutine Neverland_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) type(Neverland_surface_forcing_CS), pointer :: CS !< Control structure for this module. ! Local variables real :: buoy_rest_const ! A constant relating density anomalies to the - ! restoring buoyancy flux, in m5 s-3 kg-1. + ! restoring buoyancy flux [m5 s-3 kg-1]. real :: density_restore ! De integer :: i, j, is, ie, js, je integer :: isd, ied, jsd, jed @@ -179,7 +179,7 @@ subroutine Neverland_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) "Temperature/salinity restoring not coded!" ) else ! This is the buoyancy only mode. do j=js,je ; do i=is,ie - ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive + ! fluxes%buoy is the buoyancy flux into the ocean [m2 s-3]. A positive ! buoyancy flux is of the same sign as heating the ocean. fluxes%buoy(i,j) = 0.0 * G%mask2dT(i,j) enddo ; enddo @@ -197,7 +197,7 @@ subroutine Neverland_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) buoy_rest_const = -1.0 * (CS%G_Earth * CS%flux_const) / CS%Rho0 do j=js,je ; do i=is,ie ! Set density_restore to an expression for the surface potential - ! density in kg m-3 that is being restored toward. + ! density [kg m-3] that is being restored toward. density_restore = 1030.0 fluxes%buoy(i,j) = G%mask2dT(i,j) * buoy_rest_const * & diff --git a/config_src/solo_driver/user_surface_forcing.F90 b/config_src/solo_driver/user_surface_forcing.F90 index 1d2cd158ae..a9787b9348 100644 --- a/config_src/solo_driver/user_surface_forcing.F90 +++ b/config_src/solo_driver/user_surface_forcing.F90 @@ -33,11 +33,11 @@ module user_surface_forcing logical :: use_temperature !< If true, temperature and salinity are used as state variables. logical :: restorebuoy !< If true, use restoring surface buoyancy forcing. - real :: Rho0 !< The density used in the Boussinesq approximation, in kg m-3. - real :: G_Earth !< The gravitational acceleration in m s-2. - real :: Flux_const !< The restoring rate at the surface, in m s-1. + real :: Rho0 !< The density used in the Boussinesq approximation [kg m-3]. + real :: G_Earth !< The gravitational acceleration [m s-2]. + real :: Flux_const !< The restoring rate at the surface [m s-1]. real :: gust_const !< A constant unresolved background gustiness - !! that contributes to ustar, in Pa. + !! that contributes to ustar [Pa]. type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the !! timing of diagnostic output. @@ -45,9 +45,9 @@ module user_surface_forcing contains -!> This subroutine sets the surface wind stresses, forces%taux and forces%tauy. +!> This subroutine sets the surface wind stresses, forces%taux and forces%tauy, in [Pa]. !! These are the stresses in the direction of the model grid (i.e. the same -!! direction as the u- and v- velocities.) They are both in Pa. +!! direction as the u- and v- velocities). subroutine USER_wind_forcing(sfc_state, forces, day, G, US, CS) type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. @@ -104,7 +104,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(time_type), intent(in) :: day !< The time of the fluxes real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(user_surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned !! by a previous call to user_surface_forcing_init @@ -124,13 +124,13 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! fluxes are in kg m-2 s-1 and positive for water moving into the ocean. ! Local variables - real :: Temp_restore ! The temperature that is being restored toward, in C. - real :: Salin_restore ! The salinity that is being restored toward, in PSU. + real :: Temp_restore ! The temperature that is being restored toward [degC]. + real :: Salin_restore ! The salinity that is being restored toward [ppt] real :: density_restore ! The potential density that is being restored - ! toward, in kg m-3. - real :: rhoXcp ! The mean density times the heat capacity, in J m-3 K-1. + ! toward [kg m-3]. + real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1]. real :: buoy_rest_const ! A constant relating density anomalies to the - ! restoring buoyancy flux, in m5 s-3 kg-1. + ! restoring buoyancy flux [m5 s-3 kg-1]. integer :: i, j, is, ie, js, je integer :: isd, ied, jsd, jed @@ -168,7 +168,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) ! Set whichever fluxes are to be used here. Any fluxes that ! are always zero do not need to be changed here. do j=js,je ; do i=is,ie - ! Fluxes of fresh water through the surface are in units of kg m-2 s-1 + ! Fluxes of fresh water through the surface are in units of [kg m-2 s-1] ! and are positive downward - i.e. evaporation should be negative. fluxes%evap(i,j) = -0.0 * G%mask2dT(i,j) fluxes%lprec(i,j) = 0.0 * G%mask2dT(i,j) @@ -184,7 +184,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) enddo ; enddo else ! This is the buoyancy only mode. do j=js,je ; do i=is,ie - ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive + ! fluxes%buoy is the buoyancy flux into the ocean [m2 s-3]. A positive ! buoyancy flux is of the same sign as heating the ocean. fluxes%buoy(i,j) = 0.0 * G%mask2dT(i,j) enddo ; enddo @@ -200,8 +200,8 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) rhoXcp = CS%Rho0 * fluxes%C_p do j=js,je ; do i=is,ie - ! Set Temp_restore and Salin_restore to the temperature (in C) and - ! salinity (in PSU) that are being restored toward. + ! Set Temp_restore and Salin_restore to the temperature (in degC) and + ! salinity (in PSU or ppt) that are being restored toward. Temp_restore = 0.0 Salin_restore = 0.0 @@ -221,7 +221,7 @@ subroutine USER_buoyancy_forcing(sfc_state, fluxes, day, dt, G, CS) buoy_rest_const = -1.0 * (CS%G_Earth * CS%Flux_const) / CS%Rho0 do j=js,je ; do i=is,ie ! Set density_restore to an expression for the surface potential - ! density in kg m-3 that is being restored toward. + ! density [kg m-3] that is being restored toward. density_restore = 1030.0 fluxes%buoy(i,j) = G%mask2dT(i,j) * buoy_rest_const * & diff --git a/src/ALE/MOM_ALE.F90 b/src/ALE/MOM_ALE.F90 index 6f81466685..f6c84dff5a 100644 --- a/src/ALE/MOM_ALE.F90 +++ b/src/ALE/MOM_ALE.F90 @@ -120,6 +120,11 @@ module MOM_ALE public ALE_remap_init_conds public ALE_register_diags +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> This routine is typically called (from initialize_MOM in file MOM.F90) @@ -130,7 +135,7 @@ subroutine ALE_init( param_file, GV, US, max_depth, CS) type(param_file_type), intent(in) :: param_file !< Parameter file type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(in) :: max_depth !< The maximum depth of the ocean, in Z. + real, intent(in) :: max_depth !< The maximum depth of the ocean [Z ~> m]. type(ALE_CS), pointer :: CS !< Module control structure ! Local variables @@ -272,7 +277,7 @@ subroutine adjustGridForIntegrity( CS, G, GV, h ) type(ocean_grid_type), intent(in) :: G !< Ocean grid informations type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid thickness that - !! are to be adjusted (m or Pa) + !! are to be adjusted [H ~> m or kg-2] call inflate_vanished_layers_old( CS%regridCS, G, GV, h(:,:,:) ) end subroutine adjustGridForIntegrity @@ -301,9 +306,9 @@ subroutine ALE_main( G, GV, US, h, u, v, tv, Reg, CS, dt, frac_shelf_h) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the - !! last time step in H (often m or Pa) - real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: u !< Zonal velocity field (m/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: v !< Meridional velocity field (m/s) + !! last time step [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), intent(inout) :: u !< Zonal velocity field [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), intent(inout) :: v !< Meridional velocity field [m s-1] type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure type(tracer_registry_type), pointer :: Reg !< Tracer registry structure type(ALE_CS), pointer :: CS !< Regridding parameters and options @@ -312,7 +317,7 @@ subroutine ALE_main( G, GV, US, h, u, v, tv, Reg, CS, dt, frac_shelf_h) ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: eta_preale - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step (m or Pa) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step [H ~> m or kg-2] integer :: nk, i, j, k, isc, iec, jsc, jec logical :: ice_shelf @@ -386,14 +391,14 @@ subroutine ALE_main_offline( G, GV, h, tv, Reg, CS, dt) type(ocean_grid_type), intent(in) :: G !< Ocean grid informations type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the - !! last time step (m or Pa) + !! last time step [H ~> m or kg-2] type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure type(tracer_registry_type), pointer :: Reg !< Tracer registry structure type(ALE_CS), pointer :: CS !< Regridding parameters and options real, optional, intent(in) :: dt !< Time step between calls to ALE_main() ! Local variables real, dimension(SZI_(G), SZJ_(G), SZK_(GV)+1) :: dzRegrid ! The change in grid interface positions - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step (m or Pa) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h_new ! New 3D grid obtained after last time step [H ~> m or kg-2] integer :: nk, i, j, k, isc, iec, jsc, jec nk = GV%ke; isc = G%isc; iec = G%iec; jsc = G%jsc; jec = G%jec @@ -518,10 +523,10 @@ subroutine ALE_offline_tracer_final( G, GV, h, tv, h_target, Reg, CS) type(ocean_grid_type), intent(in) :: G !< Ocean grid informations type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the - !! last time step (m or Pa) + !! last time step [H ~> m or kg-2] type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variable structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h_target !< Current 3D grid obtained after - !! last time step (m or Pa) + !! last time step [H ~> m or kg-2] type(tracer_registry_type), pointer :: Reg !< Tracer registry structure type(ALE_CS), pointer :: CS !< Regridding parameters and options ! Local variables @@ -562,8 +567,9 @@ subroutine check_grid( G, GV, h, threshold ) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Current 3D grid obtained after the - !! last time step (H units) - real, intent(in) :: threshold !< Value below which to flag issues (H units) + !! last time step [H ~> m or kg m-2] + real, intent(in) :: threshold !< Value below which to flag issues, + !! [H ~> m or kg m-2] ! Local variables integer :: i, j @@ -591,7 +597,7 @@ subroutine ALE_build_grid( G, GV, regridCS, remapCS, h, tv, debug, frac_shelf_h type(remapping_CS), intent(in) :: remapCS !< Remapping parameters and options type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamical variable structure real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the - !! last time step (m or Pa) + !! last time step [H ~> m or kg-2] logical, optional, intent(in) :: debug !< If true, show the call tree real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage ! Local variables @@ -717,15 +723,18 @@ subroutine remap_all_state_vars(CS_remapping, CS_ALE, G, GV, h_old, h_new, Reg, type(ALE_CS), intent(in) :: CS_ALE !< ALE control structure type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_old !< Thickness of source grid (m or Pa) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_new !< Thickness of destination grid (m or Pa) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_old !< Thickness of source grid + !! [H ~> m or kg-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_new !< Thickness of destination grid + !! [H ~> m or kg-2] type(tracer_registry_type), pointer :: Reg !< Tracer registry structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), & - optional, intent(in) :: dxInterface !< Change in interface position (Hm or Pa) + optional, intent(in) :: dxInterface !< Change in interface position + !! [H ~> m or kg-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - optional, intent(inout) :: u !< Zonal velocity component (m/s) + optional, intent(inout) :: u !< Zonal velocity component [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - optional, intent(inout) :: v !< Meridional velocity component (m/s) + optional, intent(inout) :: v !< Meridional velocity component [m s-1] logical, optional, intent(in) :: debug !< If true, show the call tree real, optional, intent(in) :: dt !< time step for diagnostics ! Local variables @@ -888,9 +897,11 @@ subroutine ALE_remap_scalar(CS, G, GV, nk_src, h_src, s_src, h_dst, s_dst, all_c type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure integer, intent(in) :: nk_src !< Number of levels on source grid - real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: h_src !< Level thickness of source grid (m or Pa) + real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: h_src !< Level thickness of source grid + !! [H ~> m or kg-2] real, dimension(SZI_(G),SZJ_(G),nk_src), intent(in) :: s_src !< Scalar on source grid - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(in) :: h_dst !< Level thickness of destination grid (m or Pa) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(in) :: h_dst !< Level thickness of destination grid + !! [H ~> m or kg-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)),intent(inout) :: s_dst !< Scalar on destination grid logical, optional, intent(in) :: all_cells !< If false, only reconstruct for !! non-vanished cells. Use all vanished @@ -961,7 +972,7 @@ subroutine pressure_gradient_plm( CS, S_t, S_b, T_t, T_b, G, GV, tv, h, bdry_ext intent(inout) :: T_b !< Temperature at the bottom edge of each layer type(thermo_var_ptrs), intent(in) :: tv !< thermodynamics structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< layer thickness in H + intent(in) :: h !< layer thickness [H ~> m or kg m-2] logical, intent(in) :: bdry_extrap !< If true, use high-order boundary !! extrapolation within boundary cells @@ -1035,7 +1046,7 @@ subroutine pressure_gradient_ppm( CS, S_t, S_b, T_t, T_b, G, GV, tv, h, bdry_ext intent(inout) :: T_b !< Temperature at the bottom edge of each layer type(thermo_var_ptrs), intent(in) :: tv !< thermodynamics structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< layer thicknesses in H + intent(in) :: h !< layer thicknesses [H ~> m or kg m-2] logical, intent(in) :: bdry_extrap !< If true, use high-order boundary !! extrapolation within boundary cells @@ -1102,7 +1113,7 @@ end subroutine pressure_gradient_ppm subroutine ALE_initRegridding(GV, US, max_depth, param_file, mdl, regridCS) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(in) :: max_depth !< The maximum depth of the ocean, in Z. + real, intent(in) :: max_depth !< The maximum depth of the ocean [Z ~> m]. type(param_file_type), intent(in) :: param_file !< parameter file character(len=*), intent(in) :: mdl !< Name of calling module type(regridding_CS), intent(out) :: regridCS !< Regridding parameters and work arrays @@ -1223,7 +1234,7 @@ subroutine ALE_initThicknessToCoord( CS, G, GV, h ) type(ALE_CS), intent(inout) :: CS !< module control structure type(ocean_grid_type), intent(in) :: G !< module grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: h !< layer thickness in H + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: h !< layer thickness [H ~> m or kg m-2] ! Local variables integer :: i, j, k diff --git a/src/ALE/MOM_regridding.F90 b/src/ALE/MOM_regridding.F90 index f7dcaa2648..2a1bcd5bcb 100644 --- a/src/ALE/MOM_regridding.F90 +++ b/src/ALE/MOM_regridding.F90 @@ -36,13 +36,18 @@ module MOM_regridding #include +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Regridding control structure type, public :: regridding_CS ; private !> This array is set by function setCoordinateResolution() !! It contains the "resolution" or delta coordinate of the target !! coorindate. It has the units of the target coordinate, e.g. - !! Z (often meters) for z*, non-dimensional for sigma, etc. + !! [Z ~> m] for z*, non-dimensional for sigma, etc. real, dimension(:), allocatable :: coordinateResolution !> This is a scaling factor that restores coordinateResolution to values in @@ -60,11 +65,11 @@ module MOM_regridding logical :: target_density_set = .false. !> This array is set by function set_regrid_max_depths() - !! It specifies the maximum depth that every interface is allowed to take, in H. + !! It specifies the maximum depth that every interface is allowed to take [H ~> m or kg m-2]. real, dimension(:), allocatable :: max_interface_depths !> This array is set by function set_regrid_max_thickness() - !! It specifies the maximum depth that every interface is allowed to take, in H. + !! It specifies the maximum depth that every interface is allowed to take [H ~> m or kg m-2]. real, dimension(:), allocatable :: max_layer_thickness integer :: nk !< Number of layers/levels in generated grid @@ -76,26 +81,26 @@ module MOM_regridding !> Interpolation control structure type(interp_CS_type) :: interp_CS - !> Minimum thickness allowed when building the new grid through regridding, in H. + !> Minimum thickness allowed when building the new grid through regridding [H ~> m or kg m-2]. real :: min_thickness !> Reference pressure for potential density calculations (Pa) real :: ref_pressure = 2.e7 - !> Weight given to old coordinate when blending between new and old grids (nondim) + !> Weight given to old coordinate when blending between new and old grids [nondim] !! Used only below depth_of_time_filter_shallow, with a cubic variation !! from zero to full effect between depth_of_time_filter_shallow and !! depth_of_time_filter_deep. real :: old_grid_weight = 0. - !> Depth above which no time-filtering of grid is applied (H units) + !> Depth above which no time-filtering of grid is applied [H ~> m or kg m-2] real :: depth_of_time_filter_shallow = 0. - !> Depth below which time-filtering of grid is applied at full effect (H units) + !> Depth below which time-filtering of grid is applied at full effect [H ~> m or kg m-2] real :: depth_of_time_filter_deep = 0. !> Fraction (between 0 and 1) of compressibility to add to potential density - !! profiles when interpolating for target grid positions. (nondim) + !! profiles when interpolating for target grid positions. [nondim] real :: compressibility_fraction = 0. !> If true, each interface is given a maximum depth based on a rescaling of @@ -172,13 +177,14 @@ subroutine initialize_regridding(CS, GV, US, max_depth, param_file, mdl, coord_m type(regridding_CS), intent(inout) :: CS !< Regridding control structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(in) :: max_depth !< The maximum depth of the ocean, in Z. + real, intent(in) :: max_depth !< The maximum depth of the ocean [Z ~> m]. type(param_file_type), intent(in) :: param_file !< Parameter file character(len=*), intent(in) :: mdl !< Name of calling module. character(len=*), intent(in) :: coord_mode !< Coordinate mode character(len=*), intent(in) :: param_prefix !< String to prefix to parameter names. !! If empty, causes main model parameters to be used. character(len=*), intent(in) :: param_suffix !< String to append to parameter names. + ! Local variables integer :: ke ! Number of levels character(len=80) :: string, string2, varName ! Temporary strings @@ -189,16 +195,19 @@ subroutine initialize_regridding(CS, GV, US, max_depth, param_file, mdl, coord_m logical :: tmpLogical, fix_haloclines, set_max, do_sum, main_parameters logical :: coord_is_state_dependent, ierr real :: filt_len, strat_tol, index_scale, tmpReal - real :: maximum_depth !< The maximum depth of the ocean, in m. + real :: maximum_depth ! The maximum depth of the ocean [m] (not in Z). real :: dz_fixed_sfc, Rho_avg_depth, nlay_sfc_int real :: adaptTimeRatio, adaptZoom, adaptZoomCoeff, adaptBuoyCoeff, adaptAlpha integer :: nz_fixed_sfc, k, nzf(4) - real, dimension(:), allocatable :: dz ! Resolution (thickness) in units of coordinate - real, dimension(:), allocatable :: h_max ! Maximum layer thicknesses, in m. - real, dimension(:), allocatable :: dz_max ! Thicknesses used to find maximum interface depths, in m. - real, dimension(:), allocatable :: z_max ! Maximum interface depths, in m. - real, dimension(:), allocatable :: rho_target ! Target density used in HYBRID mode - ! Thicknesses that give level centers corresponding to table 2 of WOA09 + real, dimension(:), allocatable :: dz ! Resolution (thickness) in units of coordinate, which may be + ! [m] or [Z ~> m] or [H ~> m or kg m-2] or [kg m-3] or other units. + real, dimension(:), allocatable :: h_max ! Maximum layer thicknesses [H ~> m or kg m-2] + real, dimension(:), allocatable :: z_max ! Maximum interface depths [H ~> m or kg m-2] or other + ! units depending on the coordinate + real, dimension(:), allocatable :: dz_max ! Thicknesses used to find maximum interface depths + ! [H ~> m or kg m-2] or other units + real, dimension(:), allocatable :: rho_target ! Target density used in HYBRID mode [kg m-3] + ! Thicknesses [m] that give level centers corresponding to table 2 of WOA09 real, dimension(40) :: woa09_dz = (/ 5., 10., 10., 15., 22.5, 25., 25., 25., & 37.5, 50., 50., 75., 100., 100., 100., 100., & 100., 100., 100., 100., 100., 100., 100., 175., & @@ -221,7 +230,7 @@ subroutine initialize_regridding(CS, GV, US, max_depth, param_file, mdl, coord_m if (main_parameters) then ! Read coordinate units parameter (main model = REGRIDDING_COORDINATE_UNITS) call get_param(param_file, mdl, "REGRIDDING_COORDINATE_UNITS", coord_units, & - "Units of the regridding coordinuate.",& + "Units of the regridding coordinuate.",& !### Spelling error "coordinuate" default=coordinateUnits(coord_mode)) else coord_units=coordinateUnits(coord_mode) @@ -911,10 +920,11 @@ end subroutine calc_h_new_by_dz !> Check that the total thickness of two grids match subroutine check_remapping_grid( G, GV, h, dzInterface, msg ) - type(ocean_grid_type), intent(in) :: G !< Grid structure - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses (m) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: dzInterface !< Change in interface positions (m) + type(ocean_grid_type), intent(in) :: G !< Grid structure + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: dzInterface !< Change in interface positions + !! [H ~> m or kg m-2] character(len=*), intent(in) :: msg !< Message to append to errors ! Local variables integer :: i, j @@ -929,8 +939,8 @@ end subroutine check_remapping_grid !> Check that the total thickness of new and old grids are consistent subroutine check_grid_column( nk, depth, h, dzInterface, msg ) integer, intent(in) :: nk !< Number of cells - real, intent(in) :: depth !< Depth of bottom (m or arbitrary units) - real, dimension(nk), intent(in) :: h !< Cell thicknesses (m or arbitrary units) + real, intent(in) :: depth !< Depth of bottom [Z ~> m] or arbitrary units + real, dimension(nk), intent(in) :: h !< Cell thicknesses [Z ~> m] or arbitrary units real, dimension(nk+1), intent(in) :: dzInterface !< Change in interface positions (same units as h) character(len=*), intent(in) :: msg !< Message to append to errors ! Local variables @@ -991,9 +1001,9 @@ end subroutine check_grid_column subroutine filtered_grid_motion( CS, nk, z_old, z_new, dz_g ) type(regridding_CS), intent(in) :: CS !< Regridding control structure integer, intent(in) :: nk !< Number of cells in source grid - real, dimension(nk+1), intent(in) :: z_old !< Old grid position (m) - real, dimension(CS%nk+1), intent(in) :: z_new !< New grid position (m) - real, dimension(CS%nk+1), intent(inout) :: dz_g !< Change in interface positions (m) + real, dimension(nk+1), intent(in) :: z_old !< Old grid position [m] + real, dimension(CS%nk+1), intent(in) :: z_new !< New grid position [m] + real, dimension(CS%nk+1), intent(inout) :: dz_g !< Change in interface positions [m] ! Local variables real :: sgn ! The sign convention for downward. real :: dz_tgt, zr1, z_old_k @@ -1132,8 +1142,9 @@ subroutine build_zstar_grid( CS, G, GV, h, dzInterface, frac_shelf_h) type(regridding_CS), intent(in) :: CS !< Regridding control structure type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H - real, dimension(SZI_(G),SZJ_(G), CS%nk+1), intent(inout) :: dzInterface !< The change in interface depth in H. + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G), CS%nk+1), intent(inout) :: dzInterface !< The change in interface depth + !! [H ~> m or kg m-2]. real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage. ! Local variables integer :: i, j, k @@ -1232,8 +1243,9 @@ subroutine build_sigma_grid( CS, G, GV, h, dzInterface ) type(regridding_CS), intent(in) :: CS !< Regridding control structure type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H - real, dimension(SZI_(G),SZJ_(G), CS%nk+1), intent(inout) :: dzInterface !< The change in interface depth in H. + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G), CS%nk+1), intent(inout) :: dzInterface !< The change in interface depth + !! [H ~> m or kg m-2] ! Local variables integer :: i, j, k @@ -1317,9 +1329,10 @@ subroutine build_rho_grid( G, GV, h, tv, dzInterface, remapCS, CS ) ! Arguments type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure - real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzInterface !< The change in interface depth in H + real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzInterface !< The change in interface depth + !! [H ~> m or kg m-2] type(remapping_CS), intent(in) :: remapCS !< The remapping control structure type(regridding_CS), intent(in) :: CS !< Regridding control structure @@ -1430,17 +1443,17 @@ end subroutine build_rho_grid subroutine build_grid_HyCOM1( G, GV, h, tv, h_new, dzInterface, CS ) type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Existing model thickness, in H units + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Existing model thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure type(regridding_CS), intent(in) :: CS !< Regridding control structure - real, dimension(SZI_(G),SZJ_(G),CS%nk), intent(inout) :: h_new !< New layer thicknesses (H units) + real, dimension(SZI_(G),SZJ_(G),CS%nk), intent(inout) :: h_new !< New layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),CS%nk+1), intent(inout) :: dzInterface !< Changes in interface position ! Local variables - real, dimension(SZK_(GV)+1) :: z_col ! Source interface positions relative to the surface in H units (m or kg m-2) - real, dimension(CS%nk+1) :: z_col_new ! New interface positions relative to the surface in H units (m or kg m-2) - real, dimension(SZK_(GV)+1) :: dz_col ! The realized change in z_col in H units (m or kg m-2) - real, dimension(SZK_(GV)) :: p_col ! Layer pressure in Pa + real, dimension(SZK_(GV)+1) :: z_col ! Source interface positions relative to the surface [H ~> m or kg m-2] + real, dimension(CS%nk+1) :: z_col_new ! New interface positions relative to the surface [H ~> m or kg m-2] + real, dimension(SZK_(GV)+1) :: dz_col ! The realized change in z_col [H ~> m or kg m-2] + real, dimension(SZK_(GV)) :: p_col ! Layer center pressure [Pa] integer :: i, j, k, nki real :: depth real :: h_neglect, h_neglect_edge @@ -1465,7 +1478,7 @@ subroutine build_grid_HyCOM1( G, GV, h, tv, h_new, dzInterface, CS ) z_col(1) = 0. ! Work downward rather than bottom up do K = 1, GV%ke - z_col(K+1) = z_col(K) + h(i,j,k) ! Work in units of h (m or Pa) + z_col(K+1) = z_col(K) + h(i,j,k) p_col(k) = CS%ref_pressure + CS%compressibility_fraction * & ( 0.5 * ( z_col(K) + z_col(K+1) ) * GV%H_to_Pa - CS%ref_pressure ) enddo @@ -1499,10 +1512,11 @@ end subroutine build_grid_HyCOM1 subroutine build_grid_adaptive(G, GV, h, tv, dzInterface, remapCS, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: dzInterface !< The change in interface depth in H + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: dzInterface !< The change in interface depth + !! [H ~> m or kg m-2] type(remapping_CS), intent(in) :: remapCS !< The remapping control structure type(regridding_CS), intent(in) :: CS !< Regridding control structure @@ -1564,14 +1578,15 @@ end subroutine build_grid_adaptive subroutine build_grid_SLight(G, GV, h, tv, dzInterface, CS) type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Existing model thickness, in H units + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Existing model thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: dzInterface !< Changes in interface position type(regridding_CS), intent(in) :: CS !< Regridding control structure - real, dimension(SZK_(GV)+1) :: z_col, z_col_new ! Interface positions relative to the surface in H units (m or kg m-2) - real, dimension(SZK_(GV)+1) :: dz_col ! The realized change in z_col in H units (m or kg m-2) - real, dimension(SZK_(GV)) :: p_col ! Layer pressure in Pa + real, dimension(SZK_(GV)+1) :: z_col ! Interface positions relative to the surface [H ~> m or kg m-2] + real, dimension(SZK_(GV)+1) :: z_col_new ! Interface positions relative to the surface [H ~> m or kg m-2] + real, dimension(SZK_(GV)+1) :: dz_col ! The realized change in z_col [H ~> m or kg m-2] + real, dimension(SZK_(GV)) :: p_col ! Layer center pressure [Pa] real :: depth integer :: i, j, k, nz real :: h_neglect, h_neglect_edge @@ -1595,7 +1610,7 @@ subroutine build_grid_SLight(G, GV, h, tv, dzInterface, CS) depth = G%bathyT(i,j) * GV%Z_to_H z_col(1) = 0. ! Work downward rather than bottom up do K=1,nz - z_col(K+1) = z_col(K) + h(i, j, k) ! Work in units of h (m or Pa) + z_col(K+1) = z_col(K) + h(i,j,k) p_col(k) = CS%ref_pressure + CS%compressibility_fraction * & ( 0.5 * ( z_col(K) + z_col(K+1) ) * GV%H_to_Pa - CS%ref_pressure ) enddo @@ -1627,8 +1642,8 @@ end subroutine build_grid_SLight subroutine adjust_interface_motion( CS, nk, h_old, dz_int ) type(regridding_CS), intent(in) :: CS !< Regridding control structure integer, intent(in) :: nk !< Number of layers in h_old - real, dimension(nk), intent(in) :: h_old !< Minium allowed thickness of h (H units) - real, dimension(CS%nk+1), intent(inout) :: dz_int !< Minium allowed thickness of h (H units) + real, dimension(nk), intent(in) :: h_old !< Minium allowed thickness of h [H ~> m or kg m-2] + real, dimension(CS%nk+1), intent(inout) :: dz_int !< Minium allowed thickness of h [H ~> m or kg m-2] ! Local variables integer :: k real :: h_new, eps, h_total, h_err @@ -1693,9 +1708,10 @@ subroutine build_grid_arbitrary( G, GV, h, dzInterface, h_new, CS ) ! Arguments type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(in) :: h !< Original layer thicknesses, in H - real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzInterface !< The change in interface depth in H - real, intent(inout) :: h_new !< New layer thicknesses, in H + real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(in) :: h !< Original layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzInterface !< The change in interface + !! depth [H ~> m or kg m-2] + real, intent(inout) :: h_new !< New layer thicknesses [H ~> m or kg m-2] type(regridding_CS), intent(in) :: CS !< Regridding control structure ! Local variables @@ -1799,7 +1815,7 @@ subroutine inflate_vanished_layers_old( CS, G, GV, h ) type(regridding_CS), intent(in) :: CS !< Regridding control structure type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] ! Local variables integer :: i, j, k @@ -1831,7 +1847,7 @@ subroutine convective_adjustment(G, GV, h, tv) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< A structure pointing to various thermodynamic variables !------------------------------------------------------------------------------ ! Check each water column to see whether it is stratified. If not, sort the @@ -1890,7 +1906,7 @@ end subroutine convective_adjustment !------------------------------------------------------------------------------ -!> Return a uniform resolution vector in the units of the coordinata +!> Return a uniform resolution vector in the units of the coordinate function uniformResolution(nk,coordMode,maxDepth,rhoLight,rhoHeavy) !------------------------------------------------------------------------------ ! Calculate a vector of uniform resolution in the units of the coordinate @@ -2195,30 +2211,32 @@ subroutine set_regrid_params( CS, boundary_extrapolation, min_thickness, old_gri adaptTimeRatio, adaptZoom, adaptZoomCoeff, adaptBuoyCoeff, adaptAlpha, adaptDoMin) type(regridding_CS), intent(inout) :: CS !< Regridding control structure logical, optional, intent(in) :: boundary_extrapolation !< Extrapolate in boundary cells - real, optional, intent(in) :: min_thickness !< Minimum thickness allowed when building the new grid (H) + real, optional, intent(in) :: min_thickness !< Minimum thickness allowed when building the + !! new grid [H ~> m or kg m-2] real, optional, intent(in) :: old_grid_weight !< Weight given to old coordinate when time-filtering grid character(len=*), optional, intent(in) :: interp_scheme !< Interpolation method for state-dependent coordinates - real, optional, intent(in) :: depth_of_time_filter_shallow !< Depth to start cubic (H units) - real, optional, intent(in) :: depth_of_time_filter_deep !< Depth to end cubic (H units) + real, optional, intent(in) :: depth_of_time_filter_shallow !< Depth to start cubic [H ~> m or kg m-2] + real, optional, intent(in) :: depth_of_time_filter_deep !< Depth to end cubic [H ~> m or kg m-2] real, optional, intent(in) :: compress_fraction !< Fraction of compressibility to add to potential density - real, optional, intent(in) :: dz_min_surface !< The fixed resolution in the topmost SLight_nkml_min layers (H) + real, optional, intent(in) :: dz_min_surface !< The fixed resolution in the topmost + !! SLight_nkml_min layers [H ~> m or kg m-2] integer, optional, intent(in) :: nz_fixed_surface !< The number of fixed-thickness layers at the top of the model real, optional, intent(in) :: Rho_ml_avg_depth !< Averaging depth over which to determine mixed layer potential - !! density (H) + !! density [H ~> m or kg m-2] real, optional, intent(in) :: nlay_ML_to_interior !< Number of layers to offset the mixed layer density to find - !! resolved stratification (nondim) + !! resolved stratification [nondim] logical, optional, intent(in) :: fix_haloclines !< Detect regions with much weaker stratification in the coordinate real, optional, intent(in) :: halocline_filt_len !< Length scale over which to filter T & S when looking for - !! spuriously unstable water mass profiles (m) + !! spuriously unstable water mass profiles [m] real, optional, intent(in) :: halocline_strat_tol !< Value of the stratification ratio that defines a problematic !! halocline region. logical, optional, intent(in) :: integrate_downward_for_e !< If true, integrate for interface positions downward !! from the top. - real, optional, intent(in) :: adaptTimeRatio !< Ratio of the ALE timestep to the grid timescale, ND. - real, optional, intent(in) :: adaptZoom !< Depth of near-surface zooming region, in H. - real, optional, intent(in) :: adaptZoomCoeff !< Coefficient of near-surface zooming diffusivity, ND. - real, optional, intent(in) :: adaptBuoyCoeff !< Coefficient of buoyancy diffusivity, ND. - real, optional, intent(in) :: adaptAlpha !< Scaling factor on optimization tendency, ND. + real, optional, intent(in) :: adaptTimeRatio !< Ratio of the ALE timestep to the grid timescale [nondim]. + real, optional, intent(in) :: adaptZoom !< Depth of near-surface zooming region [H ~> m or kg m-2]. + real, optional, intent(in) :: adaptZoomCoeff !< Coefficient of near-surface zooming diffusivity [nondim]. + real, optional, intent(in) :: adaptBuoyCoeff !< Coefficient of buoyancy diffusivity [nondim]. + real, optional, intent(in) :: adaptAlpha !< Scaling factor on optimization tendency [nondim]. logical, optional, intent(in) :: adaptDoMin !< If true, make a HyCOM-like mixed layer by !! preventing interfaces from being shallower than !! the depths specified by the regridding coordinate. @@ -2318,7 +2336,7 @@ end function get_rho_CS function getStaticThickness( CS, SSH, depth ) type(regridding_CS), intent(in) :: CS !< Regridding control structure real, intent(in) :: SSH !< The sea surface height, in the same units as depth - real, intent(in) :: depth !< The maximum depth of the grid, perhaps in m. + real, intent(in) :: depth !< The maximum depth of the grid, often [Z ~> m] real, dimension(CS%nk) :: getStaticThickness !< The returned thicknesses in the units of depth ! Local integer :: k diff --git a/src/ALE/MOM_remapping.F90 b/src/ALE/MOM_remapping.F90 index c0620122c1..f399aa2c0f 100644 --- a/src/ALE/MOM_remapping.F90 +++ b/src/ALE/MOM_remapping.F90 @@ -71,7 +71,7 @@ module MOM_remapping ! outside of the range 0 to 1. #define __USE_ROUNDOFF_SAFE_ADJUSTMENTS__ -real, parameter :: hNeglect_dflt = 1.E-30 !< A dimensional (H units) number that can be +real, parameter :: hNeglect_dflt = 1.E-30 !< A thickness [H ~> m or kg m-2] that can be !! added to thicknesses in a denominator without !! changing the numerical result, except where !! a division by zero would otherwise occur. diff --git a/src/ALE/coord_adapt.F90 b/src/ALE/coord_adapt.F90 index 22e3c91610..98bbeb7b10 100644 --- a/src/ALE/coord_adapt.F90 +++ b/src/ALE/coord_adapt.F90 @@ -18,7 +18,7 @@ module coord_adapt !> Number of layers/levels integer :: nk - !> Nominal near-surface resolution in H + !> Nominal near-surface resolution [H ~> m or kg m-2] real, allocatable, dimension(:) :: coordinateResolution !> Ratio of optimisation and diffusion timescales @@ -27,7 +27,7 @@ module coord_adapt !> Nondimensional coefficient determining how much optimisation to apply real :: adaptAlpha - !> Near-surface zooming depth in H + !> Near-surface zooming depth [H ~> m or kg m-2] real :: adaptZoom !> Near-surface zooming coefficient @@ -36,7 +36,7 @@ module coord_adapt !> Stratification-dependent diffusion coefficient real :: adaptBuoyCoeff - !> Reference density difference for stratification-dependent diffusion in kg m-3 + !> Reference density difference for stratification-dependent diffusion [kg m-3] real :: adaptDrho0 !> If true, form a HYCOM1-like mixed layet by preventing interfaces @@ -52,7 +52,8 @@ module coord_adapt subroutine init_coord_adapt(CS, nk, coordinateResolution, m_to_H) type(adapt_CS), pointer :: CS !< Unassociated pointer to hold the control structure integer, intent(in) :: nk !< Number of layers in the grid - real, dimension(:), intent(in) :: coordinateResolution !< Nominal near-surface resolution (H) + real, dimension(:), intent(in) :: coordinateResolution !< Nominal near-surface resolution [m] or + !! other units specified with m_to_H real, optional, intent(in) :: m_to_H !< A conversion factor from m to the units of thicknesses real :: m_to_H_rescale ! A unit conversion factor. @@ -72,7 +73,7 @@ subroutine init_coord_adapt(CS, nk, coordinateResolution, m_to_H) CS%adaptZoom = 200.0 * m_to_H_rescale CS%adaptZoomCoeff = 0.0 ! Nondim. CS%adaptBuoyCoeff = 0.0 ! Nondim. - CS%adaptDrho0 = 0.5 ! kg m-3 + CS%adaptDrho0 = 0.5 ! [kg m-3] end subroutine init_coord_adapt @@ -93,7 +94,7 @@ subroutine set_adapt_params(CS, adaptTimeRatio, adaptAlpha, adaptZoom, adaptZoom real, optional, intent(in) :: adaptTimeRatio !< Ratio of optimisation and diffusion timescales real, optional, intent(in) :: adaptAlpha !< Nondimensional coefficient determining !! how much optimisation to apply - real, optional, intent(in) :: adaptZoom !< Near-surface zooming depth, in H + real, optional, intent(in) :: adaptZoom !< Near-surface zooming depth [H ~> m or kg m-2] real, optional, intent(in) :: adaptZoomCoeff !< Near-surface zooming coefficient real, optional, intent(in) :: adaptBuoyCoeff !< Stratification-dependent diffusion coefficient real, optional, intent(in) :: adaptDrho0 !< Reference density difference for @@ -121,10 +122,10 @@ subroutine build_adapt_column(CS, G, GV, tv, i, j, zInt, tInt, sInt, h, zNext) !! thermodynamic variables integer, intent(in) :: i !< The i-index of the column to work on integer, intent(in) :: j !< The j-index of the column to work on - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: zInt !< Interface heights, in H (m or kg m-2). - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: tInt !< Interface temperatures, in C - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: sInt !< Interface salinities, in psu - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: zInt !< Interface heights [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: tInt !< Interface temperatures [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: sInt !< Interface salinities [ppt] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZK_(GV)+1), intent(inout) :: zNext !< updated interface positions ! Local variables diff --git a/src/ALE/coord_hycom.F90 b/src/ALE/coord_hycom.F90 index aad807b62d..6928425e33 100644 --- a/src/ALE/coord_hycom.F90 +++ b/src/ALE/coord_hycom.F90 @@ -39,8 +39,8 @@ module coord_hycom subroutine init_coord_hycom(CS, nk, coordinateResolution, target_density, interp_CS) type(hycom_CS), pointer :: CS !< Unassociated pointer to hold the control structure integer, intent(in) :: nk !< Number of layers in generated grid - real, dimension(nk), intent(in) :: coordinateResolution !< Nominal near-surface resolution (m) - real, dimension(nk+1),intent(in) :: target_density !< Interface target densities (kg/m3) + real, dimension(nk), intent(in) :: coordinateResolution !< Nominal near-surface resolution [m] + real, dimension(nk+1),intent(in) :: target_density !< Interface target densities [kg m-3] type(interp_CS_type), intent(in) :: interp_CS !< Controls for interpolation if (associated(CS)) call MOM_error(FATAL, "init_coord_hycom: CS already associated!") @@ -99,14 +99,14 @@ subroutine build_hycom1_column(CS, eqn_of_state, nz, depth, h, T, S, p_col, & type(hycom_CS), intent(in) :: CS !< Coordinate control structure type(EOS_type), pointer :: eqn_of_state !< Equation of state structure integer, intent(in) :: nz !< Number of levels - real, intent(in) :: depth !< Depth of ocean bottom (positive in H) - real, dimension(nz), intent(in) :: T !< Temperature of column (degC) - real, dimension(nz), intent(in) :: S !< Salinity of column (psu) - real, dimension(nz), intent(in) :: h !< Layer thicknesses, (in m or H) - real, dimension(nz), intent(in) :: p_col !< Layer pressure in Pa - real, dimension(nz+1), intent(in) :: z_col !< Interface positions relative to the surface in H units (m or kg m-2) + real, intent(in) :: depth !< Depth of ocean bottom (positive [H ~> m or kg m-2]) + real, dimension(nz), intent(in) :: T !< Temperature of column [degC] + real, dimension(nz), intent(in) :: S !< Salinity of column [ppt] + real, dimension(nz), intent(in) :: h !< Layer thicknesses, in [m] or [H ~> m or kg m-2] + real, dimension(nz), intent(in) :: p_col !< Layer pressure [Pa] + real, dimension(nz+1), intent(in) :: z_col !< Interface positions relative to the surface [H ~> m or kg m-2] real, dimension(CS%nk+1), intent(inout) :: z_col_new !< Absolute positions of interfaces - real, optional, intent(in) :: zScale !< Scaling factor from the input thicknesses in m + real, optional, intent(in) :: zScale !< Scaling factor from the input thicknesses in [m] !! to desired units for zInterface, perhaps m_to_H. real, optional, intent(in) :: h_neglect !< A negligibly small width for the !! purpose of cell reconstructions @@ -121,7 +121,7 @@ subroutine build_hycom1_column(CS, eqn_of_state, nz, depth, h, T, S, p_col, & real, dimension(CS%nk) :: h_col_new ! New layer thicknesses real :: z_scale real :: stretching ! z* stretching, converts z* to z. - real :: nominal_z ! Nominal depth of interface is using z* (m or Pa) + real :: nominal_z ! Nominal depth of interface when using z* [Z ~> m] real :: hNew logical :: maximum_depths_set ! If true, the maximum depths of interface have been set. logical :: maximum_h_set ! If true, the maximum layer thicknesses have been set. diff --git a/src/ALE/coord_rho.F90 b/src/ALE/coord_rho.F90 index ff539cb474..452b3dfa09 100644 --- a/src/ALE/coord_rho.F90 +++ b/src/ALE/coord_rho.F90 @@ -16,17 +16,17 @@ module coord_rho !> Number of layers integer :: nk - !> Minimum thickness allowed for layers, in m + !> Minimum thickness allowed for layers, often in [H ~> m or kg m-2] real :: min_thickness = 0. - !> Reference pressure for density calculations, in Pa + !> Reference pressure for density calculations [Pa] real :: ref_pressure !> If true, integrate for interface positions from the top downward. !! If false, integrate from the bottom upward, as does the rest of the model. logical :: integrate_downward_for_e = .false. - !> Nominal density of interfaces, in kg m-3 + !> Nominal density of interfaces [kg m-3] real, allocatable, dimension(:) :: target_density !> Interpolation control structure @@ -46,8 +46,8 @@ module coord_rho subroutine init_coord_rho(CS, nk, ref_pressure, target_density, interp_CS) type(rho_CS), pointer :: CS !< Unassociated pointer to hold the control structure integer, intent(in) :: nk !< Number of layers in the grid - real, intent(in) :: ref_pressure !< Nominal density of interfaces in Pa - real, dimension(:), intent(in) :: target_density !< Nominal density of interfaces in kg m-3 + real, intent(in) :: ref_pressure !< Coordinate reference pressure [Pa] + real, dimension(:), intent(in) :: target_density !< Nominal density of interfaces [kg m-3] type(interp_CS_type), intent(in) :: interp_CS !< Controls for interpolation if (associated(CS)) call MOM_error(FATAL, "init_coord_rho: CS already associated!") @@ -73,7 +73,7 @@ end subroutine end_coord_rho !> This subroutine can be used to set the parameters for the coord_rho module subroutine set_rho_params(CS, min_thickness, integrate_downward_for_e, interp_CS) type(rho_CS), pointer :: CS !< Coordinate control structure - real, optional, intent(in) :: min_thickness !< Minimum allowed thickness, in m + real, optional, intent(in) :: min_thickness !< Minimum allowed thickness [H ~> m or kg m-2] logical, optional, intent(in) :: integrate_downward_for_e !< If true, integrate for interface !! positions from the top downward. If false, integrate !! from the bottom upward, as does the rest of the model. @@ -96,7 +96,7 @@ subroutine build_rho_column(CS, nz, depth, h, T, S, eqn_of_state, z_interface, & type(rho_CS), intent(in) :: CS !< coord_rho control structure integer, intent(in) :: nz !< Number of levels on source grid (i.e. length of h, T, S) real, intent(in) :: depth !< Depth of ocean bottom (positive in m) - real, dimension(nz), intent(in) :: h !< Layer thicknesses, in H + real, dimension(nz), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(nz), intent(in) :: T !< T for source column real, dimension(nz), intent(in) :: S !< S for source column type(EOS_type), pointer :: eqn_of_state !< Equation of state structure @@ -189,18 +189,18 @@ subroutine build_rho_column_iteratively(CS, remapCS, nz, depth, h, T, S, eqn_of_ type(rho_CS), intent(in) :: CS !< Regridding control structure type(remapping_CS), intent(in) :: remapCS !< Remapping parameters and options integer, intent(in) :: nz !< Number of levels - real, intent(in) :: depth !< Depth of ocean bottom (positive in m) - real, dimension(nz), intent(in) :: h !< Layer thicknesses, in m - real, dimension(nz), intent(in) :: T !< T for column - real, dimension(nz), intent(in) :: S !< S for column + real, intent(in) :: depth !< Depth of ocean bottom [Z ~> m] + real, dimension(nz), intent(in) :: h !< Layer thicknesses in Z coordinates [Z ~> m] + real, dimension(nz), intent(in) :: T !< T for column [degC] + real, dimension(nz), intent(in) :: S !< S for column [ppt] type(EOS_type), pointer :: eqn_of_state !< Equation of state structure real, dimension(nz+1), intent(inout) :: zInterface !< Absolute positions of interfaces real, optional, intent(in) :: h_neglect !< A negligibly small width for the !! purpose of cell reconstructions - !! in the same units as h + !! in the same units as h [Z ~> m] real, optional, intent(in) :: h_neglect_edge !< A negligibly small width !! for the purpose of edge value calculations - !! in the same units as h + !! in the same units as h [Z ~> m] ! Local variables integer :: k, m integer :: count_nonzero_layers @@ -349,9 +349,9 @@ end subroutine copy_finite_thicknesses subroutine old_inflate_layers_1d( min_thickness, nk, h ) ! Argument - real, intent(in) :: min_thickness !< Minimum allowed thickness, in m + real, intent(in) :: min_thickness !< Minimum allowed thickness [H ~> m or kg m-2] integer, intent(in) :: nk !< Number of layers in the grid - real, dimension(:), intent(inout) :: h !< Layer thicknesses, in m + real, dimension(:), intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] ! Local variable integer :: k diff --git a/src/ALE/coord_sigma.F90 b/src/ALE/coord_sigma.F90 index addb313a37..3bf666ec52 100644 --- a/src/ALE/coord_sigma.F90 +++ b/src/ALE/coord_sigma.F90 @@ -28,7 +28,7 @@ module coord_sigma subroutine init_coord_sigma(CS, nk, coordinateResolution) type(sigma_CS), pointer :: CS !< Unassociated pointer to hold the control structure integer, intent(in) :: nk !< Number of layers in the grid - real, dimension(:), intent(in) :: coordinateResolution !< Nominal coordinate resolution (nondim) + real, dimension(:), intent(in) :: coordinateResolution !< Nominal coordinate resolution [nondim] if (associated(CS)) call MOM_error(FATAL, "init_coord_sigma: CS already associated!") allocate(CS) @@ -51,7 +51,7 @@ end subroutine end_coord_sigma !> This subroutine can be used to set the parameters for the coord_sigma module subroutine set_sigma_params(CS, min_thickness) type(sigma_CS), pointer :: CS !< Coordinate control structure - real, optional, intent(in) :: min_thickness !< Minimum allowed thickness, in H + real, optional, intent(in) :: min_thickness !< Minimum allowed thickness [H ~> m or kg m-2] if (.not. associated(CS)) call MOM_error(FATAL, "set_sigma_params: CS not associated") @@ -62,9 +62,9 @@ end subroutine set_sigma_params !> Build a sigma coordinate column subroutine build_sigma_column(CS, depth, totalThickness, zInterface) type(sigma_CS), intent(in) :: CS !< Coordinate control structure - real, intent(in) :: depth !< Depth of ocean bottom (positive in H, often m) - real, intent(in) :: totalThickness !< Column thickness (positive in H) - real, dimension(CS%nk+1), intent(inout) :: zInterface !< Absolute positions of interfaces in H + real, intent(in) :: depth !< Depth of ocean bottom (positive [H ~> m or kg m-2]) + real, intent(in) :: totalThickness !< Column thickness (positive [H ~> m or kg m-2]) + real, dimension(CS%nk+1), intent(inout) :: zInterface !< Absolute positions of interfaces [H ~> m or kg m-2] ! Local variables integer :: k diff --git a/src/ALE/coord_slight.F90 b/src/ALE/coord_slight.F90 index 7090bb4429..8eb623d664 100644 --- a/src/ALE/coord_slight.F90 +++ b/src/ALE/coord_slight.F90 @@ -17,27 +17,27 @@ module coord_slight !> Number of layers/levels integer :: nk - !> Minimum thickness allowed when building the new grid through regridding (H) + !> Minimum thickness allowed when building the new grid through regridding [H ~> m or kg m-2] real :: min_thickness - !> Reference pressure for potential density calculations (Pa) + !> Reference pressure for potential density calculations [Pa] real :: ref_pressure !> Fraction (between 0 and 1) of compressibility to add to potential density - !! profiles when interpolating for target grid positions. (nondim) + !! profiles when interpolating for target grid positions. [nondim] real :: compressibility_fraction ! The following 4 parameters were introduced for use with the SLight coordinate: - !> Depth over which to average to determine the mixed layer potential density (H) + !> Depth over which to average to determine the mixed layer potential density [H ~> m or kg m-2] real :: Rho_ML_avg_depth - !> Number of layers to offset the mixed layer density to find resolved stratification (nondim) + !> Number of layers to offset the mixed layer density to find resolved stratification [nondim] real :: nlay_ml_offset !> The number of fixed-thickness layers at the top of the model integer :: nz_fixed_surface = 2 - !> The fixed resolution in the topmost SLight_nkml_min layers (H) + !> The fixed resolution in the topmost SLight_nkml_min layers [H ~> m or kg m-2] real :: dz_ml_min !> If true, detect regions with much weaker stratification in the coordinate @@ -45,19 +45,19 @@ module coord_slight logical :: fix_haloclines = .false. !> A length scale over which to filter T & S when looking for spuriously - !! unstable water mass profiles, in H. + !! unstable water mass profiles [H ~> m or kg m-2]. real :: halocline_filter_length - !> A value of the stratification ratio that defines a problematic halocline region (nondim). + !> A value of the stratification ratio that defines a problematic halocline region [nondim]. real :: halocline_strat_tol - !> Nominal density of interfaces, in kg m-3. + !> Nominal density of interfaces [kg m-3]. real, allocatable, dimension(:) :: target_density - !> Maximum depths of interfaces, in H. + !> Maximum depths of interfaces [H ~> m or kg m-2]. real, allocatable, dimension(:) :: max_interface_depths - !> Maximum thicknesses of layers, in H. + !> Maximum thicknesses of layers [H ~> m or kg m-2]. real, allocatable, dimension(:) :: max_layer_thickness !> Interpolation control structure @@ -72,8 +72,8 @@ module coord_slight subroutine init_coord_slight(CS, nk, ref_pressure, target_density, interp_CS, m_to_H) type(slight_CS), pointer :: CS !< Unassociated pointer to hold the control structure integer, intent(in) :: nk !< Number of layers in the grid - real, intent(in) :: ref_pressure !< Nominal density of interfaces in Pa - real, dimension(:), intent(in) :: target_density !< Nominal density of interfaces in kg m-3 + real, intent(in) :: ref_pressure !< Coordinate reference pressure [Pa] + real, dimension(:), intent(in) :: target_density !< Nominal density of interfaces [kg m-3] type(interp_CS_type), intent(in) :: interp_CS !< Controls for interpolation real, optional, intent(in) :: m_to_H !< A conversion factor from m to the units of thicknesses @@ -117,28 +117,28 @@ subroutine set_slight_params(CS, max_interface_depths, max_layer_thickness, & halocline_filter_length, halocline_strat_tol, interp_CS) type(slight_CS), pointer :: CS !< Coordinate control structure real, dimension(:), & - optional, intent(in) :: max_interface_depths !< Maximum depths of interfaces in H + optional, intent(in) :: max_interface_depths !< Maximum depths of interfaces [H ~> m or kg m-2] real, dimension(:), & - optional, intent(in) :: max_layer_thickness !< Maximum thicknesses of layers in H + optional, intent(in) :: max_layer_thickness !< Maximum thicknesses of layers [H ~> m or kg m-2] real, optional, intent(in) :: min_thickness !< Minimum thickness allowed when building the - !! new grid through regridding, in H + !! new grid through regridding [H ~> m or kg m-2] real, optional, intent(in) :: compressibility_fraction !< Fraction (between 0 and 1) of !! compressibility to add to potential density profiles when - !! interpolating for target grid positions. (nondim) + !! interpolating for target grid positions. [nondim] real, optional, intent(in) :: dz_ml_min !< The fixed resolution in the topmost - !! SLight_nkml_min layers (H) + !! SLight_nkml_min layers [H ~> m or kg m-2] integer, optional, intent(in) :: nz_fixed_surface !< The number of fixed-thickness layers at the !! top of the model real, optional, intent(in) :: Rho_ML_avg_depth !< Depth over which to average to determine - !! the mixed layer potential density (H) + !! the mixed layer potential density [H ~> m or kg m-2] real, optional, intent(in) :: nlay_ML_offset !< Number of layers to offset the mixed layer - !! density to find resolved stratification (nondim) + !! density to find resolved stratification [nondim] logical, optional, intent(in) :: fix_haloclines !< If true, detect regions with much weaker than !! based on in-situ density, and use a stretched coordinate there. real, optional, intent(in) :: halocline_filter_length !< A length scale over which to filter T & S - !! when looking for spuriously unstable water mass profiles, in H. + !! when looking for spuriously unstable water mass profiles [H ~> m or kg m-2]. real, optional, intent(in) :: halocline_strat_tol !< A value of the stratification ratio that - !! defines a problematic halocline region (nondim). + !! defines a problematic halocline region [nondim]. type(interp_CS_type), & optional, intent(in) :: interp_CS !< Controls for interpolation @@ -185,17 +185,17 @@ subroutine build_slight_column(CS, eqn_of_state, H_to_Pa, H_subroundoff, & real, intent(in) :: H_to_Pa !< GV%H_to_Pa real, intent(in) :: H_subroundoff !< GV%H_subroundoff integer, intent(in) :: nz !< Number of levels - real, intent(in) :: depth !< Depth of ocean bottom (positive in H) + real, intent(in) :: depth !< Depth of ocean bottom (positive [H ~> m or kg m-2]) real, dimension(nz), intent(in) :: T_col !< T for column real, dimension(nz), intent(in) :: S_col !< S for column - real, dimension(nz), intent(in) :: h_col !< Layer thicknesses, in H units (m or kg m-2) + real, dimension(nz), intent(in) :: h_col !< Layer thicknesses [H ~> m or kg m-2] real, dimension(nz), intent(in) :: p_col !< Layer quantities - real, dimension(nz+1), intent(in) :: z_col !< Interface positions relative to the surface in H - real, dimension(nz+1), intent(inout) :: z_col_new !< Absolute positions of interfaces in H + real, dimension(nz+1), intent(in) :: z_col !< Interface positions relative to the surface [H ~> m or kg m-2] + real, dimension(nz+1), intent(inout) :: z_col_new !< Absolute positions of interfaces [H ~> m or kg m-2] real, optional, intent(in) :: h_neglect !< A negligibly small width for the purpose of - !! cell reconstructions in H. + !! cell reconstructions [H ~> m or kg m-2]. real, optional, intent(in) :: h_neglect_edge !< A negligibly small width for the purpose - !! of edge value calculations in H. + !! of edge value calculations [H ~> m or kg m-2]. ! Local variables real, dimension(nz) :: rho_col ! Layer quantities real, dimension(nz) :: T_f, S_f ! Filtered ayer quantities @@ -208,20 +208,20 @@ subroutine build_slight_column(CS, eqn_of_state, H_to_Pa, H_subroundoff, & real :: H_to_cPa real :: drIS, drR, Fn_now, I_HStol, Fn_zero_val real :: z_int_unst - real :: dz ! A uniform layer thickness in very shallow water, in H. - real :: dz_ur ! The total thickness of an unstable region, in H. + real :: dz ! A uniform layer thickness in very shallow water [H ~> m or kg m-2]. + real :: dz_ur ! The total thickness of an unstable region [H ~> m or kg m-2]. real :: wgt, cowgt ! A weight and its complement, nondim. - real :: rho_ml_av ! The average potential density in a near-surface region, in kg m-3. - real :: H_ml_av ! A thickness to try to use in taking the near-surface average, in H. - real :: rho_x_z ! A cumulative integral of a density, in kg m-3 H. - real :: z_wt ! The thickness actually used in taking the near-surface average, in H. + real :: rho_ml_av ! The average potential density in a near-surface region [kg m-3]. + real :: H_ml_av ! A thickness to try to use in taking the near-surface average [H ~> m or kg m-2]. + real :: rho_x_z ! A cumulative integral of a density [kg m-3 H ~> kg m-2 or kg2 m-5]. + real :: z_wt ! The thickness actually used in taking the near-surface average [H ~> m or kg m-2]. real :: k_interior ! The (real) value of k where the interior grid starts. real :: k_int2 ! The (real) value of k where the interior grid starts. - real :: z_interior ! The depth where the interior grid starts, in H. - real :: z_ml_fix ! The depth at which the fixed-thickness near-surface layers end, in H. + real :: z_interior ! The depth where the interior grid starts [H ~> m or kg m-2]. + real :: z_ml_fix ! The depth at which the fixed-thickness near-surface layers end [H ~> m or kg m-2]. real :: dz_dk ! The thickness of layers between the fixed-thickness - ! near-surface layars and the interior, in H. - real :: Lfilt ! A filtering lengthscale, in H. + ! near-surface layars and the interior [H ~> m or kg m-2]. + real :: Lfilt ! A filtering lengthscale [H ~> m or kg m-2]. logical :: maximum_depths_set ! If true, the maximum depths of interface have been set. logical :: maximum_h_set ! If true, the maximum layer thicknesses have been set. real :: k2_used, k2here, dz_sum, z_max @@ -503,7 +503,7 @@ subroutine rho_interfaces_col(rho_col, h_col, z_col, rho_tgt, nz, z_col_new, & real, dimension(nz,DEGREE_MAX+1) :: ppoly_i_coefficients ! Coefficients of polynomial logical, dimension(nz) :: unstable_lay ! If true, this layer is in an unstable region. logical, dimension(nz+1) :: unstable_int ! If true, this interface is in an unstable region. - real :: rt ! The current target density, in kg m-3. + real :: rt ! The current target density [kg m-3]. real :: zf ! The fractional z-position within a layer of the target density. real :: rfn real :: a(5) ! Coefficients of a local polynomial minus the target density. diff --git a/src/ALE/coord_zlike.F90 b/src/ALE/coord_zlike.F90 index 78e38ecd1b..1f4949431d 100644 --- a/src/ALE/coord_zlike.F90 +++ b/src/ALE/coord_zlike.F90 @@ -13,11 +13,11 @@ module coord_zlike !> Number of levels to be generated integer :: nk - !> Minimum thickness allowed for layers, in the same thickness units that will - !! be used in all subsequent calls to build_zstar_column with this structure. + !> Minimum thickness allowed for layers, in the same thickness units (perhaps [H ~> m or kg m-2]) + !! that will be used in all subsequent calls to build_zstar_column with this structure. real :: min_thickness - !> Target coordinate resolution, usually in Z (often m) + !> Target coordinate resolution, usually in [Z ~> m] real, allocatable, dimension(:) :: coordinateResolution end type zlike_CS @@ -29,7 +29,7 @@ module coord_zlike subroutine init_coord_zlike(CS, nk, coordinateResolution) type(zlike_CS), pointer :: CS !< Unassociated pointer to hold the control structure integer, intent(in) :: nk !< Number of levels in the grid - real, dimension(:), intent(in) :: coordinateResolution !< Target coordinate resolution, in Z (often m) + real, dimension(:), intent(in) :: coordinateResolution !< Target coordinate resolution [Z ~> m] if (associated(CS)) call MOM_error(FATAL, "init_coord_zlike: CS already associated!") allocate(CS) @@ -52,7 +52,7 @@ end subroutine end_coord_zlike !> Set parameters in the zlike structure subroutine set_zlike_params(CS, min_thickness) type(zlike_CS), pointer :: CS !< Coordinate control structure - real, optional, intent(in) :: min_thickness !< Minimum allowed thickness, in H + real, optional, intent(in) :: min_thickness !< Minimum allowed thickness [H ~> m or kg m-2] if (.not. associated(CS)) call MOM_error(FATAL, "set_zlike_params: CS not associated") diff --git a/src/ALE/regrid_interp.F90 b/src/ALE/regrid_interp.F90 index 9bc794a2ef..d2c384c15e 100644 --- a/src/ALE/regrid_interp.F90 +++ b/src/ALE/regrid_interp.F90 @@ -298,7 +298,7 @@ end subroutine interpolate_grid subroutine build_and_interpolate_grid(CS, densities, n0, h0, x0, target_values, & n1, h1, x1, h_neglect, h_neglect_edge) type(interp_CS_type), intent(in) :: CS !< A control structure for regrid_interp - real, dimension(:), intent(in) :: densities !< Input cell densities, in kg m-3 + real, dimension(:), intent(in) :: densities !< Input cell densities [kg m-3] real, dimension(:), intent(in) :: target_values !< Target values of interfaces integer, intent(in) :: n0 !< The number of points on the input grid real, dimension(:), intent(in) :: h0 !< Initial cell widths diff --git a/src/core/MOM.F90 b/src/core/MOM.F90 index b2d211796f..1b364d7ef0 100644 --- a/src/core/MOM.F90 +++ b/src/core/MOM.F90 @@ -136,6 +136,11 @@ module MOM #include +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> A structure with diagnostic IDs of the state variables type MOM_diag_IDs !>@{ 3-d state field diagnostic IDs @@ -148,32 +153,32 @@ module MOM !! the state of the ocean. type, public :: MOM_control_struct ; private real ALLOCABLE_, dimension(NIMEM_,NJMEM_,NKMEM_) :: & - h, & !< layer thickness (m or kg/m2 (H)) - T, & !< potential temperature (degrees C) - S !< salinity (ppt) + h, & !< layer thickness [H ~> m or kg m-2] + T, & !< potential temperature [degC] + S !< salinity [ppt] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: & - u, & !< zonal velocity component (m/s) - uh, & !< uh = u * h * dy at u grid points (m3/s or kg/s) - uhtr !< accumulated zonal thickness fluxes to advect tracers (m3 or kg) + u, & !< zonal velocity component [m s-1] + uh, & !< uh = u * h * dy at u grid points [H m2 s-1 ~> m3 s-1 or kg s-1] + uhtr !< accumulated zonal thickness fluxes to advect tracers [H m2 ~> m3 or kg] real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: & - v, & !< meridional velocity (m/s) - vh, & !< vh = v * h * dx at v grid points (m3/s or kg/s) - vhtr !< accumulated meridional thickness fluxes to advect tracers (m3 or kg) + v, & !< meridional velocity [m s-1] + vh, & !< vh = v * h * dx at v grid points [H m2 s-1 ~> m3 s-1 or kg s-1] + vhtr !< accumulated meridional thickness fluxes to advect tracers [H m2 ~> m3 or kg] real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: ssh_rint - !< A running time integral of the sea surface height, in s m. + !< A running time integral of the sea surface height [s m]. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: ave_ssh_ibc !< time-averaged (over a forcing time step) sea surface height - !! with a correction for the inverse barometer (meter) + !! with a correction for the inverse barometer [m] real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: eta_av_bc !< free surface height or column mass time averaged over the last - !! baroclinic dynamics time step (m or kg/m2) + !! baroclinic dynamics time step [H ~> m or kg m-2] real, dimension(:,:), pointer :: & - Hml => NULL() !< active mixed layer depth, in m + Hml => NULL() !< active mixed layer depth [m] real :: time_in_cycle !< The running time of the current time-stepping cycle !! in calls that step the dynamics, and also the length of - !! the time integral of ssh_rint, in s. + !! the time integral of ssh_rint [s]. real :: time_in_thermo_cycle !< The running time of the current time-stepping - !! cycle in calls that step the thermodynamics, in s. + !! cycle in calls that step the thermodynamics [s]. type(ocean_grid_type) :: G !< structure containing metrics and grid info type(verticalGrid_type), pointer :: & @@ -212,8 +217,8 @@ module MOM !! This is intended for running MOM6 in offline tracer mode type(time_type), pointer :: Time !< pointer to the ocean clock - real :: dt !< (baroclinic) dynamics time step (seconds) - real :: dt_therm !< thermodynamics time step (seconds) + real :: dt !< (baroclinic) dynamics time step [s] + real :: dt_therm !< thermodynamics time step [s] logical :: thermo_spans_coupling !< If true, thermodynamic and tracer time !! steps can span multiple coupled time steps. integer :: nstep_tot = 0 !< The total number of dynamic timesteps tcaaken @@ -234,10 +239,9 @@ module MOM logical :: mixedlayer_restrat !< If true, use submesoscale mixed layer restratifying scheme. logical :: useMEKE !< If true, call the MEKE parameterization. logical :: useWaves !< If true, update Stokes drift - real :: dtbt_reset_period !< The time interval in seconds between dynamic - !! recalculation of the barotropic time step. If - !! this is negative, it is never calculated, and - !! if it is 0, it is calculated every step. + real :: dtbt_reset_period !< The time interval between dynamic recalculation of the + !! barotropic time step [s]. If this is negative dtbt is never + !! calculated, and if it is 0, dtbt is calculated every step. type(time_type) :: dtbt_reset_interval !< A time_time representation of dtbt_reset_period. type(time_type) :: dtbt_reset_time !< The next time DTBT should be calculated. @@ -246,16 +250,16 @@ module MOM type(time_type) :: Z_diag_time !< next time to compute Z-space diagnostics real, dimension(:,:,:), pointer :: & - h_pre_dyn => NULL(), & !< The thickness before the transports, in H. - T_pre_dyn => NULL(), & !< Temperature before the transports, in degC. - S_pre_dyn => NULL() !< Salinity before the transports, in psu. + h_pre_dyn => NULL(), & !< The thickness before the transports [H ~> m or kg m-2]. + T_pre_dyn => NULL(), & !< Temperature before the transports [degC]. + S_pre_dyn => NULL() !< Salinity before the transports [ppt]. type(accel_diag_ptrs) :: ADp !< structure containing pointers to accelerations, !! for derived diagnostics (e.g., energy budgets) type(cont_diag_ptrs) :: CDp !< structure containing pointers to continuity equation !! terms, for derived diagnostics (e.g., energy budgets) real, dimension(:,:,:), pointer :: & - u_prev => NULL(), & !< previous value of u stored for diagnostics - v_prev => NULL() !< previous value of v stored for diagnostics + u_prev => NULL(), & !< previous value of u stored for diagnostics [m s-1] + v_prev => NULL() !< previous value of v stored for diagnostics [m s-1] logical :: interp_p_surf !< If true, linearly interpolate surface pressure !! over the coupling time step, using specified value @@ -264,9 +268,9 @@ module MOM !! a previous time-step or the ocean restart file. !! This is only valid when interp_p_surf is true. real, dimension(:,:), pointer :: & - p_surf_prev => NULL(), & !< surface pressure (Pa) at end previous call to step_MOM - p_surf_begin => NULL(), & !< surface pressure (Pa) at start of step_MOM_dyn_... - p_surf_end => NULL() !< surface pressure (Pa) at end of step_MOM_dyn_... + p_surf_prev => NULL(), & !< surface pressure [Pa] at end previous call to step_MOM + p_surf_begin => NULL(), & !< surface pressure [Pa] at start of step_MOM_dyn_... + p_surf_end => NULL() !< surface pressure [Pa] at end of step_MOM_dyn_... ! Variables needed to reach between start and finish phases of initialization logical :: write_IC !< If true, then the initial conditions will be written to file @@ -277,23 +281,23 @@ module MOM ! These elements are used to control the calculation and error checking of the surface state real :: Hmix !< Diagnostic mixed layer thickness over which to - !! average surface tracer properties (in depth units, Z) when - !! bulk mixed layer is not used, or a negative value + !! average surface tracer properties when a bulk + !! mixed layer is not used [Z ~> m], or a negative value !! if a bulk mixed layer is being used. real :: HFrz !< If HFrz > 0, melt potential will be computed. !! The actual depth over which melt potential is computed will !! min(HFrz, OBLD), where OBLD is the boundary layer depth. !! If HFrz <= 0 (default), melt potential will not be computed. real :: Hmix_UV !< Depth scale over which to average surface flow to - !! feedback to the coupler/driver (in depth units, Z) when + !! feedback to the coupler/driver [Z ~> m] when !! bulk mixed layer is not used, or a negative value !! if a bulk mixed layer is being used. logical :: check_bad_sfc_vals !< If true, scan surface state for ridiculous values. - real :: bad_val_ssh_max !< Maximum SSH before triggering bad value message - real :: bad_val_sst_max !< Maximum SST before triggering bad value message - real :: bad_val_sst_min !< Minimum SST before triggering bad value message - real :: bad_val_sss_max !< Maximum SSS before triggering bad value message - real :: bad_vol_col_thick !< Minimum column thickness before triggering bad value message + real :: bad_val_ssh_max !< Maximum SSH before triggering bad value message [m] + real :: bad_val_sst_max !< Maximum SST before triggering bad value message [degC] + real :: bad_val_sst_min !< Minimum SST before triggering bad value message [degC] + real :: bad_val_sss_max !< Maximum SSS before triggering bad value message [ppt] + real :: bad_val_col_thick !< Minimum column thickness before triggering bad value message [m] type(MOM_diag_IDs) :: IDs !< Handles used for diagnostics. type(transport_diag_IDs) :: transport_IDs !< Handles used for transport diagnostics. @@ -403,7 +407,7 @@ subroutine step_MOM(forces, fluxes, sfc_state, Time_start, time_interval, CS, & !! tracer and mass exchange forcing fields type(surface), intent(inout) :: sfc_state !< surface ocean state type(time_type), intent(in) :: Time_start !< starting time of a segment, as a time type - real, intent(in) :: time_interval !< time interval covered by this run segment, in s. + real, intent(in) :: time_interval !< time interval covered by this run segment [s]. type(MOM_control_struct), pointer :: CS !< control structure from initialize_MOM type(Wave_parameters_CS), & optional, pointer :: Waves !< An optional pointer to a wave property CS @@ -418,7 +422,7 @@ subroutine step_MOM(forces, fluxes, sfc_state, Time_start, time_interval, CS, & !! treated as the last call to step_MOM in a !! time-stepping cycle; missing is like true. real, optional, intent(in) :: cycle_length !< The amount of time in a coupled time - !! stepping cycle, in s. + !! stepping cycle [s]. logical, optional, intent(in) :: reset_therm !< This indicates whether the running sums of !! thermodynamic quantities should be reset. !! If missing, this is like start_cycle. @@ -435,17 +439,17 @@ subroutine step_MOM(forces, fluxes, sfc_state, Time_start, time_interval, CS, & integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, n integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB - real :: dt ! baroclinic time step (sec) - real :: dtth ! time step for thickness diffusion (sec) - real :: dtdia ! time step for diabatic processes (sec) - real :: dt_therm ! a limited and quantized version of CS%dt_therm (sec) - real :: dt_therm_here ! a further limited value of dt_therm (sec) + real :: dt ! baroclinic time step [s] + real :: dtth ! time step for thickness diffusion [s] + real :: dtdia ! time step for diabatic processes [s] + real :: dt_therm ! a limited and quantized version of CS%dt_therm [s] + real :: dt_therm_here ! a further limited value of dt_therm [s] real :: wt_end, wt_beg real :: bbl_time_int ! The amount of time over which the calculated BBL ! properties will apply, for use in diagnostics, or 0 - ! if it is not to be calculated anew (sec). - real :: rel_time = 0.0 ! relative time since start of this call (sec). + ! if it is not to be calculated anew [s]. + real :: rel_time = 0.0 ! relative time since start of this call [s]. logical :: calc_dtbt ! Indicates whether the dynamically adjusted ! barotropic time step needs to be updated. @@ -460,16 +464,16 @@ subroutine step_MOM(forces, fluxes, sfc_state, Time_start, time_interval, CS, & logical :: cycle_end ! If true, do calculations and diagnostics that are only done at ! the end of a stepping cycle (whatever that may mean). logical :: therm_reset ! If true, reset running sums of thermodynamic quantities. - real :: cycle_time ! The length of the coupled time-stepping cycle, in s. + real :: cycle_time ! The length of the coupled time-stepping cycle [s]. real, dimension(SZI_(CS%G),SZJ_(CS%G)) :: & - ssh ! sea surface height, which may be based on eta_av (meter) + ssh ! sea surface height, which may be based on eta_av [m] real, dimension(:,:,:), pointer :: & - u => NULL(), & ! u : zonal velocity component (m/s) - v => NULL(), & ! v : meridional velocity component (m/s) - h => NULL() ! h : layer thickness (meter (Bouss) or kg/m2 (non-Bouss)) + u => NULL(), & ! u : zonal velocity component [m s-1] + v => NULL(), & ! v : meridional velocity component [m s-1] + h => NULL() ! h : layer thickness [H ~> m or kg m-2] real, dimension(:,:), pointer :: & - p_surf => NULL() ! A pointer to the ocean surface pressure, in Pa. + p_surf => NULL() ! A pointer to the ocean surface pressure [Pa]. real :: I_wt_ssh type(time_type) :: Time_local, end_time_thermo, Time_temp @@ -876,16 +880,16 @@ subroutine step_MOM_dynamics(forces, p_surf_begin, p_surf_end, dt, dt_thermo, & type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces real, dimension(:,:), pointer :: p_surf_begin !< A pointer (perhaps NULL) to the surface !! pressure at the beginning of this dynamic - !! step, intent in, in Pa. + !! step, intent in [Pa]. real, dimension(:,:), pointer :: p_surf_end !< A pointer (perhaps NULL) to the surface !! pressure at the end of this dynamic step, - !! intent in, in Pa. - real, intent(in) :: dt !< time interval covered by this call, in s. + !! intent in [Pa]. + real, intent(in) :: dt !< time interval covered by this call [s]. real, intent(in) :: dt_thermo !< time interval covered by any updates that may - !! span multiple dynamics steps, in s. + !! span multiple dynamics steps [s]. real, intent(in) :: bbl_time_int !< time interval over which updates to the - !! bottom boundary layer properties will apply, - !! in s, or zero not to update the properties. + !! bottom boundary layer properties will apply [s], + !! or zero not to update the properties. type(MOM_control_struct), pointer :: CS !< control structure from initialize_MOM type(time_type), intent(in) :: Time_local !< End time of a segment, as a time type type(wave_parameters_CS), & @@ -900,9 +904,9 @@ subroutine step_MOM_dynamics(forces, p_surf_begin, p_surf_end, dt, dt_thermo, & ! various unit conversion factors type(MOM_diag_IDs), pointer :: IDs => NULL() ! A structure with the diagnostic IDs. real, dimension(:,:,:), pointer :: & - u => NULL(), & ! u : zonal velocity component (m/s) - v => NULL(), & ! v : meridional velocity component (m/s) - h => NULL() ! h : layer thickness (meter (Bouss) or kg/m2 (non-Bouss)) + u => NULL(), & ! u : zonal velocity component [m s-1] + v => NULL(), & ! v : meridional velocity component [m s-1] + h => NULL() ! h : layer thickness [H ~> m or kg m-2] logical :: calc_dtbt ! Indicates whether the dynamically adjusted ! barotropic time step needs to be updated. @@ -1062,7 +1066,7 @@ subroutine step_MOM_tracer_dyn(CS, G, GV, h, Time_local) type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< layer thicknesses after the transports (m or kg/m2) + intent(in) :: h !< layer thicknesses after the transports [H ~> m or kg m-2] type(time_type), intent(in) :: Time_local !< The model time at the end !! of the time step. type(group_pass_type) :: pass_T_S @@ -1131,14 +1135,14 @@ subroutine step_MOM_thermo(CS, G, GV, US, u, v, h, tv, fluxes, dtdia, & type(verticalGrid_type), intent(inout) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: u !< zonal velocity (m/s) + intent(inout) :: u !< zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: v !< meridional velocity (m/s) + intent(inout) :: v !< meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< layer thickness (m or kg/m2) + intent(inout) :: h !< layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< A structure pointing to various thermodynamic variables type(forcing), intent(inout) :: fluxes !< pointers to forcing fields - real, intent(in) :: dtdia !< The time interval over which to advance, in s + real, intent(in) :: dtdia !< The time interval over which to advance [s] type(time_type), intent(in) :: Time_end_thermo !< End of averaging interval for thermo diags logical, intent(in) :: update_BBL !< If true, calculate the bottom boundary layer properties. type(wave_parameters_CS), & @@ -1528,23 +1532,20 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, & type(unit_scale_type), pointer :: US => NULL() character(len=4), parameter :: vers_num = 'v2.0' -! This include declares and sets the variable "version". -#include "version_variable.h" + ! This include declares and sets the variable "version". +# include "version_variable.h" integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz integer :: IsdB, IedB, JsdB, JedB - real :: dtbt - real :: Z_diag_int ! minimum interval between calc depth-space diagnostics (sec) + real :: dtbt ! The barotropic timestep [s] + real :: Z_diag_int ! minimum interval between calc depth-space diagnosetics [s] - real, allocatable, dimension(:,:,:) :: e ! interface heights (meter) - real, allocatable, dimension(:,:) :: eta ! free surface height (m) or bottom press (Pa) - real, allocatable, dimension(:,:) :: area_shelf_h ! area occupied by ice shelf - real, dimension(:,:), allocatable, target :: frac_shelf_h ! fraction of total area occupied by ice shelf + real, allocatable, dimension(:,:) :: eta ! free surface height or column mass [H ~> m or kg m-2] + real, allocatable, dimension(:,:) :: area_shelf_h ! area occupied by ice shelf [m2] + real, dimension(:,:), allocatable, target :: frac_shelf_h ! fraction of total area occupied by ice shelf [nondim] real, dimension(:,:), pointer :: shelf_area => NULL() type(MOM_restart_CS), pointer :: restart_CSp_tmp => NULL() type(group_pass_type) :: tmp_pass_uv_T_S_h, pass_uv_T_S_h - ! GMM, the following *is not* used. Should we delete it? - type(group_pass_type) :: tmp_pass_Kv_shear real :: default_val ! default value for a parameter logical :: write_geom_files ! If true, write out the grid geometry files. @@ -1876,7 +1877,7 @@ subroutine initialize_MOM(Time, Time_init, param_file, dirs, CS, restart_CSp, & "The value of SST below which a bad value message is \n"//& "triggered, if CHECK_BAD_SURFACE_VALS is true.", & units="deg C", default=-2.1) - call get_param(param_file, "MOM", "BAD_VAL_COLUMN_THICKNESS", CS%bad_vol_col_thick, & + call get_param(param_file, "MOM", "BAD_VAL_COLUMN_THICKNESS", CS%bad_val_col_thick, & "The value of column thickness below which a bad value message is \n"//& "triggered, if CHECK_BAD_SURFACE_VALS is true.", units="m", & default=0.0) @@ -2487,7 +2488,7 @@ subroutine finish_MOM_initialization(Time, dirs, CS, restart_CSp) type(unit_scale_type), pointer :: US => NULL() ! Pointer to a structure containing ! various unit conversion factors type(MOM_restart_CS), pointer :: restart_CSp_tmp => NULL() - real, allocatable :: z_interface(:,:,:) ! Interface heights (meter) + real, allocatable :: z_interface(:,:,:) ! Interface heights [m] type(vardesc) :: vd call cpu_clock_begin(id_clock_init) @@ -2658,14 +2659,14 @@ subroutine adjust_ssh_for_p_atm(tv, G, GV, US, ssh, p_atm, use_EOS) type(ocean_grid_type), intent(in) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: ssh !< time mean surface height (m) - real, dimension(:,:), optional, pointer :: p_atm !< atmospheric pressure (Pascal) + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: ssh !< time mean surface height [m] + real, dimension(:,:), optional, pointer :: p_atm !< atmospheric pressure [Pa] logical, optional, intent(in) :: use_EOS !< If true, calculate the density for !! the SSH correction using the equation of state. real :: Rho_conv ! The density used to convert surface pressure to - ! a corrected effective SSH, in kg m-3. - real :: IgR0 ! The SSH conversion factor from Pa to m. + ! a corrected effective SSH [kg m-3]. + real :: IgR0 ! The SSH conversion factor from Pa to m [m Pa-1]. logical :: calc_rho integer :: i, j, is, ie, js, je @@ -2699,22 +2700,22 @@ subroutine extract_surface_state(CS, sfc_state) !! data in this structure is intent out. ! local - real :: hu, hv + real :: hu, hv ! Thicknesses interpolated to velocity points [H ~> m or kg m-2] type(ocean_grid_type), pointer :: G => NULL() !< pointer to a structure containing !! metrics and related information type(verticalGrid_type), pointer :: GV => NULL() real, dimension(:,:,:), pointer :: & - u => NULL(), & !< u : zonal velocity component (m/s) - v => NULL(), & !< v : meridional velocity component (m/s) - h => NULL() !< h : layer thickness (meter (Bouss) or kg/m2 (non-Bouss)) - real :: depth(SZI_(CS%G)) !< Distance from the surface in depth units (Z) + u => NULL(), & !< u : zonal velocity component [m s-1] + v => NULL(), & !< v : meridional velocity component [m s-1] + h => NULL() !< h : layer thickness [H ~> m or kg m-2] + real :: depth(SZI_(CS%G)) !< Distance from the surface in depth units [Z ~> m] real :: depth_ml !< Depth over which to average to determine mixed - !! layer properties (Z) - real :: dh !< Thickness of a layer within the mixed layer (Z) - real :: mass !< Mass per unit area of a layer (kg/m2) - real :: bathy_m !< The depth of bathymetry in m (not Z), used for error checking. - real :: T_freeze !< freezing temperature (oC) - real :: delT(SZI_(CS%G)) !< T-T_freeze (oC) + !! layer properties [Z ~> m] + real :: dh !< Thickness of a layer within the mixed layer [Z ~> m] + real :: mass !< Mass per unit area of a layer [kg m-2] + real :: bathy_m !< The depth of bathymetry [m] (not Z), used for error checking. + real :: T_freeze !< freezing temperature [degC] + real :: delT(SZI_(CS%G)) !< T-T_freeze [degC] logical :: use_temperature !< If true, temp and saln used as state variables. integer :: i, j, k, is, ie, js, je, nz, numberOfErrors integer :: isd, ied, jsd, jed @@ -2911,7 +2912,7 @@ subroutine extract_surface_state(CS, sfc_state) sfc_state%melt_potential(i,j) = 0.0 if (G%mask2dT(i,j)>0.) then - ! instantaneous melt_potential, in J/m^2 + ! instantaneous melt_potential [J m-2] sfc_state%melt_potential(i,j) = CS%tv%C_p * CS%GV%Rho0 * delT(i) endif enddo @@ -2983,7 +2984,7 @@ subroutine extract_surface_state(CS, sfc_state) localError = sfc_state%sea_lev(i,j)<=-bathy_m & .or. sfc_state%sea_lev(i,j)>= CS%bad_val_ssh_max & .or. sfc_state%sea_lev(i,j)<=-CS%bad_val_ssh_max & - .or. sfc_state%sea_lev(i,j) + bathy_m < CS%bad_vol_col_thick + .or. sfc_state%sea_lev(i,j) + bathy_m < CS%bad_val_col_thick if (use_temperature) localError = localError & .or. sfc_state%SSS(i,j)<0. & .or. sfc_state%SSS(i,j)>=CS%bad_val_sss_max & @@ -3071,9 +3072,9 @@ end subroutine get_MOM_state_elements !> Find the global integrals of various quantities. subroutine get_ocean_stocks(CS, mass, heat, salt, on_PE_only) type(MOM_control_struct), pointer :: CS !< MOM control structure - real, optional, intent(out) :: heat !< The globally integrated integrated ocean heat, in J. - real, optional, intent(out) :: salt !< The globally integrated integrated ocean salt, in kg. - real, optional, intent(out) :: mass !< The globally integrated integrated ocean mass, in kg. + real, optional, intent(out) :: heat !< The globally integrated integrated ocean heat [J]. + real, optional, intent(out) :: salt !< The globally integrated integrated ocean salt [kg]. + real, optional, intent(out) :: mass !< The globally integrated integrated ocean mass [kg]. logical, optional, intent(in) :: on_PE_only !< If present and true, only sum on the local PE. if (present(mass)) & diff --git a/src/core/MOM_CoriolisAdv.F90 b/src/core/MOM_CoriolisAdv.F90 index 948901ac63..450d71d23e 100644 --- a/src/core/MOM_CoriolisAdv.F90 +++ b/src/core/MOM_CoriolisAdv.F90 @@ -108,89 +108,88 @@ module MOM_CoriolisAdv !> Calculates the Coriolis and momentum advection contributions to the acceleration. subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) - type(ocean_grid_type), intent(in) :: G !< Ocen grid structure + type(ocean_grid_type), intent(in) :: G !< Ocen grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity (m/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity (m/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uh !< Zonal transport u*h*dy (m3/s or kg/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vh !< Meridional transport v*h*dx (m3/s or kg/s) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uh !< Zonal transport u*h*dy + !! [H m2 s-1 ~> m3 s-1 or kg s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vh !< Meridional transport v*h*dx + !! [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: CAu !< Zonal acceleration due to Coriolis - !! and momentum advection, in m/s2. + !! and momentum advection [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: CAv !< Meridional acceleration due to Coriolis - !! and momentum advection, in m/s2. + !! and momentum advection [m s-2]. type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure type(accel_diag_ptrs), intent(inout) :: AD !< Storage for acceleration diagnostics type(CoriolisAdv_CS), pointer :: CS !< Control structure for MOM_CoriolisAdv - ! Local variables + ! Local variables real, dimension(SZIB_(G),SZJB_(G)) :: & - q, & ! Layer potential vorticity, in m-1 s-1. - Ih_q, & ! The inverse of thickness interpolated to q pointes, in - ! units of m-1 or m2 kg-1. - Area_q ! The sum of the ocean areas at the 4 adjacent thickness - ! points, in m2. + q, & ! Layer potential vorticity [m-1 s-1]. + Ih_q, & ! The inverse of thickness interpolated to q points [H-1 ~> m-1 or m2 kg-1]. + Area_q ! The sum of the ocean areas at the 4 adjacent thickness points [m2]. real, dimension(SZIB_(G),SZJ_(G)) :: & a, b, c, d ! a, b, c, & d are combinations of the potential vorticities ! surrounding an h grid point. At small scales, a = q/4, - ! b = q/4, etc. All are in units of m-1 s-1 or m2 kg-1 s-1, + ! b = q/4, etc. All are in [H-1 s-1 ~> m-1 s-1 or m2 kg-1 s-1], ! and use the indexing of the corresponding u point. real, dimension(SZI_(G),SZJ_(G)) :: & - Area_h, & ! The ocean area at h points, in m2. Area_h is used to find the + Area_h, & ! The ocean area at h points [m2]. Area_h is used to find the ! average thickness in the denominator of q. 0 for land points. - KE ! Kinetic energy per unit mass, KE = (u^2 + v^2)/2, in m2 s-2. + KE ! Kinetic energy per unit mass [m2 s-2], KE = (u^2 + v^2)/2. real, dimension(SZIB_(G),SZJ_(G)) :: & hArea_u, & ! The cell area weighted thickness interpolated to u points - ! times the effective areas, in H m2. - KEx, & ! The zonal gradient of Kinetic energy per unit mass, - ! KEx = d/dx KE, in m s-2. - uh_center ! centered u times h at u-points + ! times the effective areas [H m2 ~> m3 or kg]. + KEx, & ! The zonal gradient of Kinetic energy per unit mass [m s-2], + ! KEx = d/dx KE. + uh_center ! Transport based on arithmetic mean h at u-points [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(G),SZJB_(G)) :: & hArea_v, & ! The cell area weighted thickness interpolated to v points - ! times the effective areas, in H m2. - KEy, & ! The meridonal gradient of Kinetic energy per unit mass, - ! KEy = d/dy KE, in m s-2. - vh_center ! centered v times h at v-points + ! times the effective areas [H m2 ~> m3 or kg]. + KEy, & ! The meridonal gradient of Kinetic energy per unit mass [m s-2], + ! KEy = d/dy KE. + vh_center ! Transport based on arithmetic mean h at v-points [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(G),SZJ_(G)) :: & uh_min, uh_max, & ! The smallest and largest estimates of the volume - vh_min, vh_max, & ! fluxes through the faces (i.e. u*h*dy & v*h*dx), - ! in m3 s-1 or kg s-1. + vh_min, vh_max, & ! fluxes through the faces (i.e. u*h*dy & v*h*dx) + ! [H m2 s-1 ~> m3 s-1 or kg s-1]. ep_u, ep_v ! Additional pseudo-Coriolis terms in the Arakawa and Lamb - ! discretization, in m-1 s-1 or m2 kg-1 s-1. + ! discretization [H-1 s-1 ~> m-1 s-1 or m2 kg-1 s-1]. real, dimension(SZIB_(G),SZJB_(G)) :: & - dvdx,dudy, &! Contributions to the circulation around q-points (m2 s-1) - abs_vort, & ! Absolute vorticity at q-points, in s-1. - q2, & ! Relative vorticity over thickness. + dvdx,dudy, &! Contributions to the circulation around q-points [m2 s-1] + abs_vort, & ! Absolute vorticity at q-points [s-1]. + q2, & ! Relative vorticity over thickness [H-1 s-1 ~> m-1 s-1 or m2 kg-1 s-1]. max_fvq, & ! The maximum or minimum of the min_fvq, & ! adjacent values of (-u) or v times - max_fuq, & ! the absolute vorticity, in m s-2. + max_fuq, & ! the absolute vorticity [m s-2]. min_fuq ! All are defined at q points. real, dimension(SZIB_(G),SZJB_(G),SZK_(G)) :: & - PV, & ! A diagnostic array of the potential vorticities, in m-1 s-1. - RV ! A diagnostic array of the relative vorticities, in s-1. - real :: fv1, fv2, fu1, fu2 ! (f+rv)*v or (f+rv)*u in m s-2. - real :: max_fv, max_fu ! The maximum or minimum of the neighbor- - real :: min_fv, min_fu ! max(min)_fu(v)q, in m s-2. + PV, & ! A diagnostic array of the potential vorticities [m-1 s-1]. + RV ! A diagnostic array of the relative vorticities [s-1]. + real :: fv1, fv2, fu1, fu2 ! (f+rv)*v or (f+rv)*u [m s-2]. + real :: max_fv, max_fu ! The maximum or minimum of the neighboring Coriolis + real :: min_fv, min_fu ! accelerations [m s-2], i.e. max(min)_fu(v)q. real, parameter :: C1_12=1.0/12.0 ! C1_12 = 1/12 real, parameter :: C1_24=1.0/24.0 ! C1_24 = 1/24 - real :: absolute_vorticity ! Absolute vorticity, in s-1. - real :: relative_vorticity ! Relative vorticity, in s-1. - real :: Ih ! Inverse of thickness, m-1 or m2 kg-1. - real :: max_Ihq, min_Ihq ! The maximum and minimum of the nearby Ihq. + real :: absolute_vorticity ! Absolute vorticity [s-1]. + real :: relative_vorticity ! Relative vorticity [s-1]. + real :: Ih ! Inverse of thickness [H-1 ~> m-1 or m2 kg-1]. + real :: max_Ihq, min_Ihq ! The maximum and minimum of the nearby Ihq [H-1 ~> m-1 or m2 kg-1]. real :: hArea_q ! The sum of area times thickness of the cells - ! surrounding a q point, in m3 or kg. + ! surrounding a q point [H m2 ~> m3 or kg]. real :: h_neglect ! A thickness that is so small it is usually - ! lost in roundoff and can be neglected, in m. - real :: temp1, temp2 ! Temporary variables, in m2 s-2. - real, parameter :: eps_vel=1.0e-10 ! A tiny, positive velocity, in m s-1. + ! lost in roundoff and can be neglected [H ~> m or kg m-2]. + real :: temp1, temp2 ! Temporary variables [m2 s-2]. + real, parameter :: eps_vel=1.0e-10 ! A tiny, positive velocity [m s-1]. - real :: uhc, vhc ! Centered estimates of uh and vh in m3 s-1 or kg s-1. - real :: uhm, vhm ! The input estimates of uh and vh in m3 s-1 or kg s-1. - real :: c1, c2, c3, slope ! Nondimensional parameters for the Coriolis - ! limiter scheme. + real :: uhc, vhc ! Centered estimates of uh and vh [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: uhm, vhm ! The input estimates of uh and vh [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: c1, c2, c3, slope ! Nondimensional parameters for the Coriolis limiter scheme. real :: Fe_m2 ! Nondimensional temporary variables asssociated with real :: rat_lin ! the ARAKAWA_LAMB_BLEND scheme. @@ -202,20 +201,17 @@ subroutine CorAdCalc(u, v, h, uh, vh, CAu, CAv, OBC, AD, G, GV, CS) ! the other two with the ARAKAWA_LAMB_BLEND scheme, ! nondimensional between 0 and 1. - real :: Heff1, Heff2 ! Temporary effective H at U or V points in m or kg m-2. - real :: Heff3, Heff4 ! Temporary effective H at U or V points in m or kg m-2. - real :: h_tiny ! A very small thickness, in m or kg m-2. - real :: UHeff, VHeff ! More temporary variables, in m3 s-1 or kg s-1. - real :: QUHeff,QVHeff ! More temporary variables, in m3 s-2 or kg s-2. + real :: Heff1, Heff2 ! Temporary effective H at U or V points [H ~> m or kg m-2]. + real :: Heff3, Heff4 ! Temporary effective H at U or V points [H ~> m or kg m-2]. + real :: h_tiny ! A very small thickness [H ~> m or kg m-2]. + real :: UHeff, VHeff ! More temporary variables [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: QUHeff,QVHeff ! More temporary variables [H m2 s-1 ~> m3 s-1 or kg s-1]. integer :: i, j, k, n, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz ! To work, the following fields must be set outside of the usual ! is to ie range before this subroutine is called: -! v[is-1,ie+1,ie+2], u[is-1,ie+1], vh[ie+1], uh[is-1], and -! h[is-1,ie+1,ie+2]. -! In the y-direction, the following fields must be set: -! v[js-1,je+1], u[js-1,je+1,je+2], vh[js-1], uh[je+1], and -! h[js-1,je+1,je+2]. +! v(is-1:ie+2,js-1:je+1), u(is-1:ie+1,js-1:je+2), h(is-1:ie+2,js-1:je+2), +! uh(is-1,ie,js:je+1) and vh(is:ie+1,js-1:je). if (.not.associated(CS)) call MOM_error(FATAL, & "MOM_CoriolisAdv: Module must be initialized before it is used.") @@ -842,21 +838,21 @@ end subroutine CorAdCalc !> Calculates the acceleration due to the gradient of kinetic energy. subroutine gradKE(u, v, h, KE, KEx, KEy, k, OBC, G, CS) type(ocean_grid_type), intent(in) :: G !< Ocen grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity (m/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity (m/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) - real, dimension(SZI_(G) ,SZJ_(G) ), intent(out) :: KE !< Kinetic energy (m2/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G) ,SZJ_(G) ), intent(out) :: KE !< Kinetic energy [m2 s-2] real, dimension(SZIB_(G),SZJ_(G) ), intent(out) :: KEx !< Zonal acceleration due to kinetic - !! energy gradient (m/s2) + !! energy gradient [m s-2] real, dimension(SZI_(G) ,SZJB_(G)), intent(out) :: KEy !< Meridional acceleration due to kinetic - !! energy gradient (m/s2) + !! energy gradient [m s-2] integer, intent(in) :: k !< Layer number to calculate for type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure type(CoriolisAdv_CS), pointer :: CS !< Control structure for MOM_CoriolisAdv ! Local variables - real :: um, up, vm, vp ! Temporary variables with units of m s-1. - real :: um2, up2, vm2, vp2 ! Temporary variables with units of m2 s-2. - real :: um2a, up2a, vm2a, vp2a ! Temporary variables with units of m4 s-2. + real :: um, up, vm, vp ! Temporary variables [m s-1]. + real :: um2, up2, vm2, vp2 ! Temporary variables [m2 s-2]. + real :: um2a, up2a, vm2a, vp2a ! Temporary variables [m4 s-2]. integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, n is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke diff --git a/src/core/MOM_PressureForce.F90 b/src/core/MOM_PressureForce.F90 index a872a5b88f..110963789b 100644 --- a/src/core/MOM_PressureForce.F90 +++ b/src/core/MOM_PressureForce.F90 @@ -49,23 +49,23 @@ subroutine PressureForce(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm, pbce, e type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: PFu !< Zonal pressure force acceleration (m/s2) + intent(out) :: PFu !< Zonal pressure force acceleration [m s-2] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: PFv !< Meridional pressure force acceleration (m/s2) + intent(out) :: PFv !< Meridional pressure force acceleration [m s-2] type(PressureForce_CS), pointer :: CS !< Pressure force control structure type(ALE_CS), pointer :: ALE_CSp !< ALE control structure real, dimension(:,:), & optional, pointer :: p_atm !< The pressure at the ice-ocean or - !! atmosphere-ocean interface in Pa. + !! atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: pbce !< The baroclinic pressure anomaly in each layer - !! due to eta anomalies, in m2 s-2 H-1. + !! due to eta anomalies [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), & optional, intent(out) :: eta !< The bottom mass used to calculate PFu and PFv, - !! in H, with any tidal contributions. + !! [H ~> m or kg m-2], with any tidal contributions. if (CS%Analytic_FV_PGF .and. CS%blocked_AFV) then if (GV%Boussinesq) then diff --git a/src/core/MOM_PressureForce_Montgomery.F90 b/src/core/MOM_PressureForce_Montgomery.F90 index 164229f894..09d3e64266 100644 --- a/src/core/MOM_PressureForce_Montgomery.F90 +++ b/src/core/MOM_PressureForce_Montgomery.F90 @@ -22,22 +22,27 @@ module MOM_PressureForce_Mont public PressureForce_Mont_Bouss, PressureForce_Mont_nonBouss, Set_pbce_Bouss public Set_pbce_nonBouss, PressureForce_Mont_init, PressureForce_Mont_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for the Montgomery potential form of pressure gradient type, public :: PressureForce_Mont_CS ; private logical :: tides !< If true, apply tidal momentum forcing. real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. - real :: Rho_atm !< The assumed atmospheric density, in kg m-3. + !! approximation [kg m-3]. + real :: Rho_atm !< The assumed atmospheric density [kg m-3]. !! By default, Rho_atm is 0. - real :: GFS_scale !< Ratio between gravity applied to top interface - !! and the gravitational acceleration of the planet. + real :: GFS_scale !< Ratio between gravity applied to top interface and the + !! gravitational acceleration of the planet [nondim]. !! Usually this ratio is 1. type(time_type), pointer :: Time => NULL() !< A pointer to the ocean model's clock. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to regulate !! the timing of diagnostic output. real, pointer :: PFu_bc(:,:,:) => NULL() !< Accelerations due to pressure real, pointer :: PFv_bc(:,:,:) => NULL() !< gradients deriving from density - !! gradients within layers, m s-2. + !! gradients within layers [m s-2]. !>@{ Diagnostic IDs integer :: id_PFu_bc = -1, id_PFv_bc = -1, id_e_tidal = -1 !!@} @@ -52,64 +57,63 @@ module MOM_PressureForce_Mont !! non-Boussinesq fluid using the compressibility compensated (if appropriate) !! Montgomery-potential form described in Hallberg (Ocean Mod., 2005). !! -!! To work, the following fields must be set outside of the usual -!! ie to ie, je to je range before this subroutine is called: -!! h[ie+1] and h[je+1] and and (if tv%form_of_EOS is set) T[ie+1], S[ie+1], -!! T[je+1], and S[je+1]. +!! To work, the following fields must be set outside of the usual (is:ie,js:je) +!! range before this subroutine is called: +!! h(isB:ie+1,jsB:je+1), T(isB:ie+1,jsB:je+1), and S(isB:ie+1,jsB:je+1). subroutine PressureForce_Mont_nonBouss(h, tv, PFu, PFv, G, GV, US, CS, p_atm, pbce, eta) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. - type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in kg/m2. + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, [H ~> kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration due to pressure gradients - !! (equal to -dM/dx) in m/s2. + !! (equal to -dM/dx) [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration due to pressure gradients - !! (equal to -dM/dy) in m/s2. + !! (equal to -dM/dy) [m s-2]. type(PressureForce_Mont_CS), pointer :: CS !< Control structure for Montgomery potential PGF real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean or - !! atmosphere-ocean in Pa. + !! atmosphere-ocean [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: pbce !< The baroclinic pressure anomaly in !! each layer due to free surface height anomalies, - !! in m2 s-2 H-1. - real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< Free surface height, in m. + !! [m2 s-2 H-1 ~> m s-2 or m4 kg-1 s-2]. + real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< Free surface height [H ~> kg m-1]. ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - M, & ! The Montgomery potential, M = (p/rho + gz) , in m2 s-2. - alpha_star, & ! Compression adjusted specific volume, in m3 kg-1. - dz_geo ! The change in geopotential across a layer, in m2 s-2. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p ! Interface pressure in Pa. + M, & ! The Montgomery potential, M = (p/rho + gz) [m2 s-2]. + alpha_star, & ! Compression adjusted specific volume [m3 kg-1]. + dz_geo ! The change in geopotential across a layer [m2 s-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p ! Interface pressure [Pa]. ! p may be adjusted (with a nonlinear equation of state) so that ! its derivative compensates for the adiabatic compressibility ! in seawater, but p will still be close to the pressure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), target :: & T_tmp, & ! Temporary array of temperatures where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in C. + ! than the mixed layer have the mixed layer's properties [degC]. S_tmp ! Temporary array of salinities where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in psu. + ! than the mixed layer have the mixed layer's properties [ppt]. real, dimension(SZI_(G)) :: Rho_cv_BL ! The coordinate potential density in the - ! deepest variable density near-surface layer, in kg m-3. + ! deepest variable density near-surface layer [kg m-3]. real, dimension(SZI_(G),SZJ_(G)) :: & dM, & ! A barotropic correction to the Montgomery potentials to - ! enable the use of a reduced gravity form of the equations, - ! in m2 s-2. - dp_star, & ! Layer thickness after compensation for compressibility, in Pa. - SSH, & ! The sea surface height anomaly, in depth units (Z). + ! enable the use of a reduced gravity form of the equations + ! [m2 s-2]. + dp_star, & ! Layer thickness after compensation for compressibility [Pa]. + SSH, & ! The sea surface height anomaly, in depth units [Z ~> m]. e_tidal, & ! Bottom geopotential anomaly due to tidal forces from - ! astronomical sources and self-attraction and loading, in Z. + ! astronomical sources and self-attraction and loading [Z ~> m]. geopot_bot ! Bottom geopotential relative to time-mean sea level, - ! including any tidal contributions, in units of m2 s-2. + ! including any tidal contributions [m2 s-2]. real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually 2e7 Pa = 2000 dbar). - real :: rho_in_situ(SZI_(G)) !In-situ density of a layer, in kg m-3. + ! density [Pa] (usually 2e7 Pa = 2000 dbar). + real :: rho_in_situ(SZI_(G)) !In-situ density of a layer [kg m-3]. real :: PFu_bc, PFv_bc ! The pressure gradient force due to along-layer - ! compensated density gradients, in m s-2. + ! compensated density gradients [m s-2] real :: dp_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in Pa. + ! in roundoff and can be neglected [Pa]. logical :: use_p_atm ! If true, use the atmospheric pressure. logical :: use_EOS ! If true, density is calculated from T & S using ! an equation of state. @@ -118,12 +122,12 @@ subroutine PressureForce_Mont_nonBouss(h, tv, PFu, PFv, G, GV, US, CS, p_atm, pb ! barotropic and baroclinic pieces. type(thermo_var_ptrs) :: tv_tmp! A structure of temporary T & S. - real :: I_gEarth ! The inverse of g_Earth, in s2 Z m-2 - real :: dalpha + real :: I_gEarth ! The inverse of g_Earth [s2 Z m-2 ~> s2 m-1] +! real :: dalpha real :: Pa_to_H ! A factor to convert from Pa to the thicknesss units (H). - real :: alpha_Lay(SZK_(G)) ! The specific volume of each layer, in kg m-3. + real :: alpha_Lay(SZK_(G)) ! The specific volume of each layer [kg m-3]. real :: dalpha_int(SZK_(G)+1) ! The change in specific volume across each - ! interface, in kg m-3. + ! interface [kg m-3]. integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb integer :: i, j, k is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke @@ -351,58 +355,57 @@ end subroutine PressureForce_Mont_nonBouss !! !! Determines the acceleration due to pressure forces. !! -!! To work, the following fields must be set outside of the usual -!! ie to ie, je to je range before this subroutine is called: -!! h[ie+1] and h[je+1] and (if tv%form_of_EOS is set) T[ie+1], S[ie+1], -!! T[je+1], and S[je+1]. +!! To work, the following fields must be set outside of the usual (is:ie,js:je) +!! range before this subroutine is called: +!! h(isB:ie+1,jsB:je+1), T(isB:ie+1,jsB:je+1), and S(isB:ie+1,jsB:je+1). subroutine PressureForce_Mont_Bouss(h, tv, PFu, PFv, G, GV, US, CS, p_atm, pbce, eta) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in m. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration due to pressure gradients - !! (equal to -dM/dx) in m/s2. + !! (equal to -dM/dx) [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration due to pressure gradients - !! (equal to -dM/dy) in m/s2. + !! (equal to -dM/dy) [m s2]. type(PressureForce_Mont_CS), pointer :: CS !< Control structure for Montgomery potential PGF real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean or - !! atmosphere-ocean in Pa. + !! atmosphere-ocean [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure anomaly in - !! each layer due to free surface height anomalies, - !! in m2 s-2 H-1. - real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< Free surface height, in m. + !! each layer due to free surface height anomalies + !! [m2 s-2 H-1 ~> m s-2]. + real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< Free surface height [H ~> m]. ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - M, & ! The Montgomery potential, M = (p/rho + gz) , in m2 s-2. + M, & ! The Montgomery potential, M = (p/rho + gz) [m2 s-2]. rho_star ! In-situ density divided by the derivative with depth of the - ! corrected e times (G_Earth/Rho0). In units of m s-2. + ! corrected e times (G_Earth/Rho0) [m2 Z-1 s-2 ~> m s-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: e ! Interface height in m. - ! e may be adjusted (with a nonlinearequation of state) so that + ! e may be adjusted (with a nonlinear equation of state) so that ! its derivative compensates for the adiabatic compressibility ! in seawater, but e will still be close to the interface depth. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), target :: & T_tmp, & ! Temporary array of temperatures where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in C. + ! than the mixed layer have the mixed layer's properties [degC]. S_tmp ! Temporary array of salinities where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in psu. + ! than the mixed layer have the mixed layer's properties [ppt]. real :: Rho_cv_BL(SZI_(G)) ! The coordinate potential density in - ! the deepest variable density near-surface layer, in kg m-3. + ! the deepest variable density near-surface layer [kg m-3]. real :: h_star(SZI_(G),SZJ_(G)) ! Layer thickness after compensation - ! for compressibility, in m. + ! for compressibility [Z ~> m]. real :: e_tidal(SZI_(G),SZJ_(G)) ! Bottom geopotential anomaly due to tidal ! forces from astronomical sources and self- - ! attraction and loading, in depth units (Z). + ! attraction and loading, in depth units [Z ~> m]. real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually 2e7 Pa = 2000 dbar). - real :: I_Rho0 ! 1/Rho0, in m3 kg-1. - real :: G_Rho0 ! G_Earth / Rho0 in m5 Z-1 s-2 kg-1. + ! density [Pa] (usually 2e7 Pa = 2000 dbar). + real :: I_Rho0 ! 1/Rho0 [m3 kg-1]. + real :: G_Rho0 ! G_Earth / Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1]. real :: PFu_bc, PFv_bc ! The pressure gradient force due to along-layer - ! compensated density gradients, in m s-2. - real :: dr ! Temporary variables. + ! compensated density gradients [m s-2] +! real :: dr ! Temporary variables. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. + ! in roundoff and can be neglected [Z ~> m]. logical :: use_p_atm ! If true, use the atmospheric pressure. logical :: use_EOS ! If true, density is calculated from T & S using ! an equation of state. @@ -603,33 +606,34 @@ end subroutine PressureForce_Mont_Bouss subroutine Set_pbce_Bouss(e, tv, G, GV, Rho0, GFS_scale, pbce, rho_star) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface height, in Z. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface height [Z ~> m]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, intent(in) :: Rho0 !< The "Boussinesq" ocean density, in kg m-3. - real, intent(in) :: GFS_scale !< Ratio between gravity applied to top interface - !! and the gravitational acceleration of the planet. - !! Usually this ratio is 1. + real, intent(in) :: Rho0 !< The "Boussinesq" ocean density [kg m-3]. + real, intent(in) :: GFS_scale !< Ratio between gravity applied to top + !! interface and the gravitational acceleration of + !! the planet [nondim]. Usually this ratio is 1. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(out) :: pbce !< The baroclinic pressure anomaly in each layer due - !! to free surface height anomalies, in m2 H-1 s-2. + !! to free surface height anomalies + !! [m2 H-1 s-2 ~> m4 kg-2 s-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(in) :: rho_star !< The layer densities (maybe compressibility - !! compensated), times g/rho_0, in m2 Z-1 s-2. + !! compensated), times g/rho_0 [m2 Z-1 s-2 ~> m s-2]. ! Local variables - real :: Ihtot(SZI_(G)) ! The inverse of the sum of the layer thicknesses, in H-1. - real :: press(SZI_(G)) ! Interface pressure, in Pa. - real :: T_int(SZI_(G)) ! Interface temperature in C. - real :: S_int(SZI_(G)) ! Interface salinity in PSU. - real :: dR_dT(SZI_(G)) ! Partial derivatives of density with temperature - real :: dR_dS(SZI_(G)) ! and salinity in kg m-3 K-1 and kg m-3 PSU-1. - real :: rho_in_situ(SZI_(G)) !In-situ density at the top of a layer. - real :: G_Rho0 ! G_Earth / Rho0 in m5 Z-1 s-2 kg-1. - real :: Rho0xG ! g_Earth * Rho0 in kg s-2 m-1 Z-1. + real :: Ihtot(SZI_(G)) ! The inverse of the sum of the layer thicknesses [H-1 ~> m-1 or m2 kg-1]. + real :: press(SZI_(G)) ! Interface pressure [Pa]. + real :: T_int(SZI_(G)) ! Interface temperature [degC]. + real :: S_int(SZI_(G)) ! Interface salinity [ppt]. + real :: dR_dT(SZI_(G)) ! Partial derivative of density with temperature [kg m-3 degC-1]. + real :: dR_dS(SZI_(G)) ! Partial derivative of density with salinity [kg m-3 ppt-1]. + real :: rho_in_situ(SZI_(G)) !In-situ density at the top of a layer [kg m-3]. + real :: G_Rho0 ! G_Earth / Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1] + real :: Rho0xG ! g_Earth * Rho0 [kg s-2 m-1 Z-1 ~> kg s-2 m-2] logical :: use_EOS ! If true, density is calculated from T & S using ! an equation of state. real :: z_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in Z. + ! in roundoff and can be neglected [Z ~> m]. integer :: Isq, Ieq, Jsq, Jeq, nz, i, j, k Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB ; nz = G%ke @@ -702,32 +706,31 @@ end subroutine Set_pbce_Bouss subroutine Set_pbce_nonBouss(p, tv, G, GV, GFS_scale, pbce, alpha_star) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: p !< Interface pressures, in Pa. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: p !< Interface pressures [Pa]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, intent(in) :: GFS_scale !< Ratio between gravity applied to top interface - !! and the gravitational acceleration of the planet. - !! Usually this ratio is 1. + real, intent(in) :: GFS_scale !< Ratio between gravity applied to top + !! interface and the gravitational acceleration of + !! the planet [nondim]. Usually this ratio is 1. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: pbce !< The baroclinic pressure anomaly in each layer due - !! to free surface height anomalies, in m2 H-1 s-2. + !! to free surface height anomalies + !! [m2 H-1 s-2 ~> m4 kg-2 s-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(in) :: alpha_star !< The layer specific volumes - !! (maybe compressibility compensated), in m3 kg-1. + !! (maybe compressibility compensated) [m3 kg-1]. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & dpbce, & ! A barotropic correction to the pbce to enable the use of - ! a reduced gravity form of the equations, in m4 s-2 kg-1. - C_htot ! dP_dH divided by the total ocean pressure, m2 kg-1. - real :: T_int(SZI_(G)) ! Interface temperature in C. - real :: S_int(SZI_(G)) ! Interface salinity in PSU. - real :: dR_dT(SZI_(G)) ! Partial derivatives of density with temperature - real :: dR_dS(SZI_(G)) ! and salinity in kg m-3 K-1 and kg m-3 PSU-1. - real :: rho_in_situ(SZI_(G)) !In-situ density at an interface, in kg m-3. - real :: alpha_Lay(SZK_(G)) ! The specific volume of each layer, in kg m-3. - real :: dalpha_int(SZK_(G)+1) ! The change in specific volume across each - ! interface, in kg m-3. - real :: dP_dH ! A factor that converts from thickness to pressure, - ! usually in Pa m2 kg-1. + ! a reduced gravity form of the equations [m4 s-2 kg-1]. + C_htot ! dP_dH divided by the total ocean pressure [m2 kg-1]. + real :: T_int(SZI_(G)) ! Interface temperature [degC]. + real :: S_int(SZI_(G)) ! Interface salinity [ppt]. + real :: dR_dT(SZI_(G)) ! Partial derivative of density with temperature [kg m-3 degC-1]. + real :: dR_dS(SZI_(G)) ! Partial derivative of density with salinity [kg m-3 ppt-1]. + real :: rho_in_situ(SZI_(G)) ! In-situ density at an interface [kg m-3]. + real :: alpha_Lay(SZK_(G)) ! The specific volume of each layer [kg m-3]. + real :: dalpha_int(SZK_(G)+1) ! The change in specific volume across each interface [kg m-3]. + real :: dP_dH ! A factor that converts from thickness to pressure [Pa H-1 ~> Pa m2 kg-1]. real :: dp_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in Pa. + ! in roundoff and can be neglected [Pa]. logical :: use_EOS ! If true, density is calculated from T & S using ! an equation of state. integer :: Isq, Ieq, Jsq, Jeq, nz, i, j, k diff --git a/src/core/MOM_PressureForce_analytic_FV.F90 b/src/core/MOM_PressureForce_analytic_FV.F90 index a674a43731..a8fcae3596 100644 --- a/src/core/MOM_PressureForce_analytic_FV.F90 +++ b/src/core/MOM_PressureForce_analytic_FV.F90 @@ -27,13 +27,18 @@ module MOM_PressureForce_AFV public PressureForce_AFV, PressureForce_AFV_init, PressureForce_AFV_end public PressureForce_AFV_Bouss, PressureForce_AFV_nonBouss +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Finite volume pressure gradient control structure type, public :: PressureForce_AFV_CS ; private logical :: tides !< If true, apply tidal momentum forcing. real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. + !! approximation [kg m-3]. real :: GFS_scale !< A scaling of the surface pressure gradients to - !! allow the use of a reduced gravity model. + !! allow the use of a reduced gravity model [nondim]. type(time_type), pointer :: Time !< A pointer to the ocean model's clock. type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the !! timing of diagnostic output. @@ -62,19 +67,19 @@ subroutine PressureForce_AFV(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm, pbc type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration (m/s2) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration (m/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration [m s-2] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration [m s-2] type(PressureForce_AFV_CS), pointer :: CS !< Finite volume PGF control structure type(ALE_CS), pointer :: ALE_CSp !< ALE control structure real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean - !! or atmosphere-ocean interface in Pa. + !! or atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure - !! anomaly in each layer due to eta anomalies, - !! in m2 s-2 H-1. + !! anomaly in each layer due to eta anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< The bottom mass used to - !! calculate PFu and PFv, in H, with any tidal + !! calculate PFu and PFv [H ~> m or kg m-2], with any tidal !! contributions or compressibility compensation. if (GV%Boussinesq) then @@ -91,85 +96,86 @@ end subroutine PressureForce_AFV !! the analytic finite volume form of the Pressure gradient, and does not !! make the Boussinesq approximation. !! -!! To work, the following fields must be set outside of the usual -!! ie to ie, je to je range before this subroutine is called: -!! h[ie+1] and h[je+1] and (if tv%eqn_of_state is set) T[ie+1], S[ie+1], -!! T[je+1], and S[je+1]. +!! To work, the following fields must be set outside of the usual (is:ie,js:je) +!! range before this subroutine is called: +!! h(isB:ie+1,jsB:je+1), T(isB:ie+1,jsB:je+1), and S(isB:ie+1,jsB:je+1). subroutine PressureForce_AFV_nonBouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm, pbce, eta) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> kg/m2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration (m/s2) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration (m/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration [m s-2] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration [m s-2] type(PressureForce_AFV_CS), pointer :: CS !< Finite volume PGF control structure type(ALE_CS), pointer :: ALE_CSp !< ALE control structure real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean - !! or atmosphere-ocean interface in Pa. + !! or atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure - !! anomaly in each layer due to eta anomalies, - !! in m2 s-2 H-1. + !! anomaly in each layer due to eta anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< The bottom mass used to - !! calculate PFu and PFv, in H, with any tidal + !! calculate PFu and PFv [H ~> m or kg m-2], with any tidal !! contributions or compressibility compensation. ! Local variables - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p ! Interface pressure in Pa. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p ! Interface pressure [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), target :: & T_tmp, & ! Temporary array of temperatures where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in C. + ! than the mixed layer have the mixed layer's properties [degC]. S_tmp ! Temporary array of salinities where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in psu. + ! than the mixed layer have the mixed layer's properties [ppt]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - S_t, S_b, T_t, T_b ! Top and bottom edge values for linear reconstructions - ! of salinity and temperature within each layer. + S_t, & ! Top and bottom edge values for linear reconstructions + S_b, & ! of salinity within each layer [ppt]. + T_t, & ! Top and bottom edge values for linear reconstructions + T_b ! of temperature within each layer [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & dza, & ! The change in geopotential anomaly between the top and bottom - ! of a layer, in m2 s-2. + ! of a layer [m2 s-2]. intp_dza ! The vertical integral in depth of the pressure anomaly less - ! the pressure anomaly at the top of the layer, in Pa m2 s-2. + ! the pressure anomaly at the top of the layer [Pa m2 s-2]. real, dimension(SZI_(G),SZJ_(G)) :: & - dp, & ! The (positive) change in pressure across a layer, in Pa. - SSH, & ! The sea surface height anomaly, in depth units (Z). + dp, & ! The (positive) change in pressure across a layer [Pa]. + SSH, & ! The sea surface height anomaly, in depth units [Z ~> m]. e_tidal, & ! The bottom geopotential anomaly due to tidal forces from - ! astronomical sources and self-attraction and loading, in Z. + ! astronomical sources and self-attraction and loading [Z ~> m]. dM, & ! The barotropic adjustment to the Montgomery potential to - ! account for a reduced gravity model, in m2 s-2. + ! account for a reduced gravity model [m2 s-2]. za ! The geopotential anomaly (i.e. g*e + alpha_0*pressure) at the - ! interface atop a layer, in m2 s-2. + ! interface atop a layer [m2 s-2]. real, dimension(SZI_(G)) :: Rho_cv_BL ! The coordinate potential density in the deepest variable - ! density near-surface layer, in kg m-3. + ! density near-surface layer [kg m-3]. real, dimension(SZIB_(G),SZJ_(G)) :: & intx_za ! The zonal integral of the geopotential anomaly along the - ! interface below a layer, divided by the grid spacing, m2 s-2. + ! interface below a layer, divided by the grid spacing [m2 s-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: & - intx_dza ! The change in intx_za through a layer, in m2 s-2. + intx_dza ! The change in intx_za through a layer [m2 s-2]. real, dimension(SZI_(G),SZJB_(G)) :: & inty_za ! The meridional integral of the geopotential anomaly along the - ! interface below a layer, divided by the grid spacing, m2 s-2. + ! interface below a layer, divided by the grid spacing [m2 s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: & - inty_dza ! The change in inty_za through a layer, in m2 s-2. + inty_dza ! The change in inty_za through a layer [m2 s-2]. real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually 2e7 Pa = 2000 dbar). + ! density, [Pa] (usually 2e7 Pa = 2000 dbar). real :: dp_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in Pa. - real :: g_Earth_z ! A scaled version of g_Earth, in m2 Z-1 s-2. - real :: I_gEarth ! The inverse of g_Earth_z, in s2 Z m-2 + ! in roundoff and can be neglected [Pa]. + real :: g_Earth_z ! A scaled version of g_Earth [m2 Z-1 s-2 ~> m s-2]. + real :: I_gEarth ! The inverse of g_Earth_z [s2 Z m-2 ~> s2 m-1] real :: alpha_anom ! The in-situ specific volume, averaged over a - ! layer, less alpha_ref, in m3 kg-1. + ! layer, less alpha_ref [m3 kg-1]. logical :: use_p_atm ! If true, use the atmospheric pressure. logical :: use_ALE ! If true, use an ALE pressure reconstruction. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. type(thermo_var_ptrs) :: tv_tmp! A structure of temporary T & S. - real :: alpha_ref ! A reference specific volume, in m3 kg-1, that is used + real :: alpha_ref ! A reference specific volume [m3 kg-1], that is used ! to reduce the impact of truncation errors. - real :: rho_in_situ(SZI_(G)) ! The in situ density, in kg m-3. + real :: rho_in_situ(SZI_(G)) ! The in situ density [kg m-3]. real :: Pa_to_H ! A factor to convert from Pa to the thicknesss units (H). -! real :: oneatm = 101325.0 ! 1 atm in Pa (kg/ms2) +! real :: oneatm = 101325.0 ! 1 atm in [Pa] = [kg m-1 s-2] real, parameter :: C1_6 = 1.0/6.0 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb integer :: i, j, k @@ -433,74 +439,73 @@ end subroutine PressureForce_AFV_nonBouss !! Determines the acceleration due to hydrostatic pressure forces, using !! the finite volume form of the terms and analytic integrals in depth. !! -!! To work, the following fields must be set outside of the usual -!! ie to ie, je to je range before this subroutine is called: -!! h[ie+1] and h[je+1] and (if tv%eqn_of_state is set) T[ie+1], S[ie+1], -!! T[je+1], and S[je+1]. +!! To work, the following fields must be set outside of the usual (is:ie,js:je) +!! range before this subroutine is called: +!! h(isB:ie+1,jsB:je+1), T(isB:ie+1,jsB:je+1), and S(isB:ie+1,jsB:je+1). subroutine PressureForce_AFV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm, pbce, eta) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration (m/s2) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration (m/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration [m s-2] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration [m s-2] type(PressureForce_AFV_CS), pointer :: CS !< Finite volume PGF control structure type(ALE_CS), pointer :: ALE_CSp !< ALE control structure real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean - !! or atmosphere-ocean interface in Pa. + !! or atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure - !! anomaly in each layer due to eta anomalies, - !! in m2 s-2 H-1. + !! anomaly in each layer due to eta anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< The bottom mass used to - !! calculate PFu and PFv, in H, with any tidal - !! contributions or compressibility compensation. + !! calculate PFu and PFv [H ~> m or kg m-2], with any + !! tidal contributions or compressibility compensation. ! Local variables - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: e ! Interface height in depth units (Z). + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: e ! Interface height in depth units [Z ~> m]. real, dimension(SZI_(G),SZJ_(G)) :: & e_tidal, & ! The bottom geopotential anomaly due to tidal forces from - ! astronomical sources and self-attraction and loading, in Z. + ! astronomical sources and self-attraction and loading [Z ~> m]. dM ! The barotropic adjustment to the Montgomery potential to - ! account for a reduced gravity model, in m2 s-2. + ! account for a reduced gravity model [m2 s-2]. real, dimension(SZI_(G)) :: & Rho_cv_BL ! The coordinate potential density in the deepest variable - ! density near-surface layer, in kg m-3. + ! density near-surface layer [kg m-3]. real, dimension(SZI_(G),SZJ_(G)) :: & - dz, & ! The change in geopotential thickness through a layer, m2 s-2. + dz, & ! The change in geopotential thickness through a layer [m2 s-2]. pa, & ! The pressure anomaly (i.e. pressure + g*RHO_0*e) at the - ! the interface atop a layer, in Pa. + ! the interface atop a layer [Pa]. dpa, & ! The change in pressure anomaly between the top and bottom - ! of a layer, in Pa. - intz_dpa ! The vertical integral in depth of the pressure anomaly less - ! the pressure anomaly at the top of the layer, in H Pa (m Pa). + ! of a layer [Pa]. + intz_dpa ! The vertical integral in depth of the pressure anomaly less the + ! pressure anomaly at the top of the layer [H Pa ~> m Pa or kg m-2 Pa]. real, dimension(SZIB_(G),SZJ_(G)) :: & intx_pa, & ! The zonal integral of the pressure anomaly along the interface - ! atop a layer, divided by the grid spacing, in Pa. - intx_dpa ! The change in intx_pa through a layer, in Pa. + ! atop a layer, divided by the grid spacing [Pa]. + intx_dpa ! The change in intx_pa through a layer [Pa]. real, dimension(SZI_(G),SZJB_(G)) :: & inty_pa, & ! The meridional integral of the pressure anomaly along the - ! interface atop a layer, divided by the grid spacing, in Pa. - inty_dpa ! The change in inty_pa through a layer, in Pa. + ! interface atop a layer, divided by the grid spacing [Pa]. + inty_dpa ! The change in inty_pa through a layer [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), target :: & T_tmp, & ! Temporary array of temperatures where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in C. + ! than the mixed layer have the mixed layer's properties [degC]. S_tmp ! Temporary array of salinities where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in psu. + ! than the mixed layer have the mixed layer's properties [ppt]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & S_t, S_b, T_t, T_b ! Top and bottom edge values for linear reconstructions ! of salinity and temperature within each layer. - real :: rho_in_situ(SZI_(G)) ! The in situ density, in kg m-3. + real :: rho_in_situ(SZI_(G)) ! The in situ density [kg m-3]. real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually 2e7 Pa = 2000 dbar). - real :: p0(SZI_(G)) ! An array of zeros to use for pressure in Pa. + ! density, [Pa] (usually 2e7 Pa = 2000 dbar). + real :: p0(SZI_(G)) ! An array of zeros to use for pressure [Pa]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. - real :: g_Earth_z ! A scaled version of g_Earth, in m2 Z-1 s-2. - real :: I_Rho0 ! 1/Rho0. - real :: G_Rho0 ! G_Earth / Rho0 in m5 Z-1 s-2 kg-1. - real :: Rho_ref ! The reference density in kg m-3. - real :: dz_neglect ! A minimal thickness in Z, like e. + ! in roundoff and can be neglected [H ~> m]. + real :: g_Earth_z ! A scaled version of g_Earth [m2 Z-1 s-2 ~> m s-2]. + real :: I_Rho0 ! 1/Rho0 [m3 kg-1]. + real :: G_Rho0 ! G_Earth / Rho0 in [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1]. + real :: Rho_ref ! The reference density [kg m-3]. + real :: dz_neglect ! A minimal thickness [Z ~> m], like e. logical :: use_p_atm ! If true, use the atmospheric pressure. logical :: use_ALE ! If true, use an ALE pressure reconstruction. logical :: use_EOS ! If true, density is calculated from T & S using an equation of state. diff --git a/src/core/MOM_PressureForce_blocked_AFV.F90 b/src/core/MOM_PressureForce_blocked_AFV.F90 index 74e29e0f69..a675eebaf4 100644 --- a/src/core/MOM_PressureForce_blocked_AFV.F90 +++ b/src/core/MOM_PressureForce_blocked_AFV.F90 @@ -27,13 +27,18 @@ module MOM_PressureForce_blk_AFV public PressureForce_blk_AFV, PressureForce_blk_AFV_init, PressureForce_blk_AFV_end public PressureForce_blk_AFV_Bouss, PressureForce_blk_AFV_nonBouss +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Finite volume pressure gradient control structure type, public :: PressureForce_blk_AFV_CS ; private logical :: tides !< If true, apply tidal momentum forcing. real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. + !! approximation [kg m-3]. real :: GFS_scale !< A scaling of the surface pressure gradients to - !! allow the use of a reduced gravity model. + !! allow the use of a reduced gravity model [nondim]. type(time_type), pointer :: Time !< A pointer to the ocean model's clock. type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the !! timing of diagnostic output. @@ -62,19 +67,19 @@ subroutine PressureForce_blk_AFV(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm, type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamic variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration (m/s2) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration (m/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration [m s-2] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration [m s-2] type(PressureForce_blk_AFV_CS), pointer :: CS !< Finite volume PGF control structure type(ALE_CS), pointer :: ALE_CSp !< ALE control structure real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean - !! or atmosphere-ocean interface in Pa. + !! or atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure - !! anomaly in each layer due to eta anomalies, - !! in m2 s-2 H-1. + !! anomaly in each layer due to eta anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< The bottom mass used to - !! calculate PFu and PFv, in H, with any tidal + !! calculate PFu and PFv [H ~> m or kg m-2], with any tidal !! contributions or compressibility compensation. if (GV%Boussinesq) then @@ -91,84 +96,83 @@ end subroutine PressureForce_blk_AFV !! analytic finite volume form of the Pressure gradient, and does not make the !! Boussinesq approximation. This version uses code-blocking for threads. !! -!! To work, the following fields must be set outside of the usual -!! ie to ie, je to je range before this subroutine is called: -!! h[ie+1] and h[je+1] and (if tv%eqn_of_state is set) T[ie+1], S[ie+1], -!! T[je+1], and S[je+1]. +!! To work, the following fields must be set outside of the usual (is:ie,js:je) +!! range before this subroutine is called: +!! h(isB:ie+1,jsB:je+1), T(isB:ie+1,jsB:je+1), and S(isB:ie+1,jsB:je+1). subroutine PressureForce_blk_AFV_nonBouss(h, tv, PFu, PFv, G, GV, US, CS, p_atm, pbce, eta) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration (m/s2) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration (m/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration [m s-2] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration [m s-2] type(PressureForce_blk_AFV_CS), pointer :: CS !< Finite volume PGF control structure real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean - !! or atmosphere-ocean interface in Pa. + !! or atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure - !! anomaly in each layer due to eta anomalies, - !! in m2 s-2 H-1. + !! anomaly in each layer due to eta anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< The bottom mass used to - !! calculate PFu and PFv, in H, with any tidal + !! calculate PFu and PFv [H ~> m or kg m-2], with any tidal !! contributions or compressibility compensation. ! Local variables - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p ! Interface pressure in Pa. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: p ! Interface pressure [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), target :: & T_tmp, & ! Temporary array of temperatures where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in C. + ! than the mixed layer have the mixed layer's properties [degC]. S_tmp ! Temporary array of salinities where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in psu. + ! than the mixed layer have the mixed layer's properties [ppt]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & dza, & ! The change in geopotential anomaly between the top and bottom - ! of a layer, in m2 s-2. + ! of a layer [m2 s-2]. intp_dza ! The vertical integral in depth of the pressure anomaly less - ! the pressure anomaly at the top of the layer, in Pa m2 s-2. + ! the pressure anomaly at the top of the layer [Pa m2 s-2]. real, dimension(SZI_(G),SZJ_(G)) :: & - dp, & ! The (positive) change in pressure across a layer, in Pa. - SSH, & ! The sea surface height anomaly, in depth units (Z). + dp, & ! The (positive) change in pressure across a layer [Pa]. + SSH, & ! The sea surface height anomaly, in depth units [Z ~> m]. e_tidal, & ! The bottom geopotential anomaly due to tidal forces from - ! astronomical sources and self-attraction and loading, in Z. + ! astronomical sources and self-attraction and loading [Z ~> m]. dM, & ! The barotropic adjustment to the Montgomery potential to - ! account for a reduced gravity model, in m2 s-2. + ! account for a reduced gravity model [m2 s-2]. za ! The geopotential anomaly (i.e. g*e + alpha_0*pressure) at the - ! interface atop a layer, in m2 s-2. + ! interface atop a layer [m2 s-2]. real, dimension(SZDI_(G%Block(1)),SZDJ_(G%Block(1))) :: & ! on block indices - dp_bk, & ! The (positive) change in pressure across a layer, in Pa. + dp_bk, & ! The (positive) change in pressure across a layer [Pa]. za_bk ! The geopotential anomaly (i.e. g*e + alpha_0*pressure) at the - ! interface atop a layer, in m2 s-2. + ! interface atop a layer [m2 s-2]. real, dimension(SZI_(G)) :: Rho_cv_BL ! The coordinate potential density in the deepest variable - ! density near-surface layer, in kg m-3. + ! density near-surface layer [kg m-3]. real, dimension(SZDIB_(G%Block(1)),SZDJ_(G%Block(1))) :: & ! on block indices intx_za_bk ! The zonal integral of the geopotential anomaly along the - ! interface below a layer, divided by the grid spacing, m2 s-2. + ! interface below a layer, divided by the grid spacing [m2 s-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: & - intx_dza ! The change in intx_za through a layer, in m2 s-2. + intx_dza ! The change in intx_za through a layer [m2 s-2]. real, dimension(SZDI_(G%Block(1)),SZDJB_(G%Block(1))) :: & ! on block indices inty_za_bk ! The meridional integral of the geopotential anomaly along the - ! interface below a layer, divided by the grid spacing, m2 s-2. + ! interface below a layer, divided by the grid spacing [m2 s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: & - inty_dza ! The change in inty_za through a layer, in m2 s-2. - real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually 2e7 Pa = 2000 dbar). - - real :: dp_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in Pa. - real :: g_Earth_z ! A scaled version of g_Earth, in m2 Z-1 s-2. - real :: I_gEarth ! The inverse of g_Earth_z, in s2 Z m-2 - real :: alpha_anom ! The in-situ specific volume, averaged over a - ! layer, less alpha_ref, in m3 kg-1. - logical :: use_p_atm ! If true, use the atmospheric pressure. + inty_dza ! The change in inty_za through a layer [m2 s-2]. + real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate + ! density [Pa] (usually 2e7 Pa = 2000 dbar). + + real :: dp_neglect ! A thickness that is so small it is usually lost + ! in roundoff and can be neglected [Pa]. + real :: g_Earth_z ! A scaled version of g_Earth [m2 Z-1 s-2 ~> m s-2]. + real :: I_gEarth ! The inverse of g_Earth_z [s2 Z m-2 ~> s2 m-1] + real :: alpha_anom ! The in-situ specific volume, averaged over a + ! layer, less alpha_ref [m3 kg-1]. + logical :: use_p_atm ! If true, use the atmospheric pressure. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. type(thermo_var_ptrs) :: tv_tmp! A structure of temporary T & S. - real :: alpha_ref ! A reference specific volume, in m3 kg-1, that is used + real :: alpha_ref ! A reference specific volume [m3 kg-1], that is used ! to reduce the impact of truncation errors. - real :: rho_in_situ(SZI_(G)) ! The in situ density, in kg m-3. + real :: rho_in_situ(SZI_(G)) ! The in situ density [kg m-3]. real :: Pa_to_H ! A factor to convert from Pa to the thicknesss units (H). -! real :: oneatm = 101325.0 ! 1 atm in Pa (kg/ms2) +! real :: oneatm = 101325.0 ! 1 atm in [Pa] = [kg m-1 s-2] real, parameter :: C1_6 = 1.0/6.0 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb integer :: is_bk, ie_bk, js_bk, je_bk, Isq_bk, Ieq_bk, Jsq_bk, Jeq_bk @@ -416,76 +420,75 @@ end subroutine PressureForce_blk_AFV_nonBouss !! the finite volume form of the terms and analytic integrals in depth, making !! the Boussinesq approximation. This version uses code-blocking for threads. !! -!! To work, the following fields must be set outside of the usual -!! ie to ie, je to je range before this subroutine is called: -!! h[ie+1] and h[je+1] and (if tv%eqn_of_state is set) T[ie+1], S[ie+1], -!! T[je+1], and S[je+1]. +!! To work, the following fields must be set outside of the usual (is:ie,js:je) +!! range before this subroutine is called: +!! h(isB:ie+1,jsB:je+1), T(isB:ie+1,jsB:je+1), and S(isB:ie+1,jsB:je+1). subroutine PressureForce_blk_AFV_Bouss(h, tv, PFu, PFv, G, GV, US, CS, ALE_CSp, p_atm, pbce, eta) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness in H (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration (m/s2) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration (m/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: PFu !< Zonal acceleration [m s-2] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: PFv !< Meridional acceleration [m s-2] type(PressureForce_blk_AFV_CS), pointer :: CS !< Finite volume PGF control structure type(ALE_CS), pointer :: ALE_CSp !< ALE control structure real, dimension(:,:), optional, pointer :: p_atm !< The pressure at the ice-ocean - !! or atmosphere-ocean interface in Pa. + !! or atmosphere-ocean interface [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(out) :: pbce !< The baroclinic pressure - !! anomaly in each layer due to eta anomalies, - !! in m2 s-2 H-1. + !! anomaly in each layer due to eta anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: eta !< The bottom mass used to - !! calculate PFu and PFv, in H, with any tidal + !! calculate PFu and PFv [H ~> m or kg m-2], with any tidal !! contributions or compressibility compensation. ! Local variables - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: e ! Interface height in depth units (Z). + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: e ! Interface height in depth units [Z ~> m]. real, dimension(SZI_(G),SZJ_(G)) :: & e_tidal, & ! The bottom geopotential anomaly due to tidal forces from - ! astronomical sources and self-attraction and loading, in depth units (Z). + ! astronomical sources and self-attraction and loading, in depth units [Z ~> m]. dM ! The barotropic adjustment to the Montgomery potential to - ! account for a reduced gravity model, in m2 s-2. + ! account for a reduced gravity model [m2 s-2]. real, dimension(SZI_(G)) :: & Rho_cv_BL ! The coordinate potential density in the deepest variable - ! density near-surface layer, in kg m-3. + ! density near-surface layer [kg m-3]. real, dimension(SZDI_(G%Block(1)),SZDJ_(G%Block(1))) :: & ! on block indices - dz_bk, & ! The change in geopotential thickness through a layer, m2 s-2. + dz_bk, & ! The change in geopotential thickness through a layer [m2 s-2]. pa_bk, & ! The pressure anomaly (i.e. pressure + g*RHO_0*e) at the - ! the interface atop a layer, in Pa. + ! the interface atop a layer [Pa]. dpa_bk, & ! The change in pressure anomaly between the top and bottom - ! of a layer, in Pa. - intz_dpa_bk ! The vertical integral in depth of the pressure anomaly less - ! the pressure anomaly at the top of the layer, in H Pa (m Pa). + ! of a layer [Pa]. + intz_dpa_bk ! The vertical integral in depth of the pressure anomaly less the + ! pressure anomaly at the top of the layer [H Pa ~> m Pa or kg m-2 Pa]. real, dimension(SZDIB_(G%Block(1)),SZDJ_(G%Block(1))) :: & ! on block indices intx_pa_bk, & ! The zonal integral of the pressure anomaly along the interface - ! atop a layer, divided by the grid spacing, in Pa. - intx_dpa_bk ! The change in intx_pa through a layer, in Pa. + ! atop a layer, divided by the grid spacing [Pa]. + intx_dpa_bk ! The change in intx_pa through a layer [Pa]. real, dimension(SZDI_(G%Block(1)),SZDJB_(G%Block(1))) :: & ! on block indices inty_pa_bk, & ! The meridional integral of the pressure anomaly along the - ! interface atop a layer, divided by the grid spacing, in Pa. - inty_dpa_bk ! The change in inty_pa through a layer, in Pa. + ! interface atop a layer, divided by the grid spacing [Pa]. + inty_dpa_bk ! The change in inty_pa through a layer [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), target :: & T_tmp, & ! Temporary array of temperatures where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in C. + ! than the mixed layer have the mixed layer's properties [degC]. S_tmp ! Temporary array of salinities where layers that are lighter - ! than the mixed layer have the mixed layer's properties, in psu. + ! than the mixed layer have the mixed layer's properties [ppt]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - S_t, S_b, T_t, T_b ! Top and bottom edge values for linear reconstructions - ! of salinity and temperature within each layer. - real :: rho_in_situ(SZI_(G)) ! The in situ density, in kg m-3. - real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually 2e7 Pa = 2000 dbar). - real :: p0(SZI_(G)) ! An array of zeros to use for pressure in Pa. - real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: I_Rho0 ! 1/Rho0. - real :: g_Earth_z ! A scaled version of g_Earth, in m2 Z-1 s-2. - real :: G_Rho0 ! G_Earth / Rho0 in m5 Z-1 s-2 kg-1. - real :: Rho_ref ! The reference density in kg m-3. - real :: dz_neglect ! A minimal thickness in Z, like e. - logical :: use_p_atm ! If true, use the atmospheric pressure. - logical :: use_ALE ! If true, use an ALE pressure reconstruction. + S_t, S_b, & ! Top and bottom edge salinities for linear reconstructions within each layer [ppt]. + T_t, T_b ! Top and bottom edge temperatures for linear reconstructions within each layer [degC]. + real :: rho_in_situ(SZI_(G)) ! The in situ density [kg m-3]. + real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate + ! density [Pa] (usually 2e7 Pa = 2000 dbar). + real :: p0(SZI_(G)) ! An array of zeros to use for pressure [Pa]. + real :: h_neglect ! A thickness that is so small it is usually lost + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: I_Rho0 ! 1/Rho0 [m3 kg-1]. + real :: g_Earth_z ! A scaled version of g_Earth [m2 Z-1 s-2 ~> m s-2]. + real :: G_Rho0 ! G_Earth / Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1]. + real :: Rho_ref ! The reference density [kg m-3]. + real :: dz_neglect ! A minimal thickness [Z ~> m], like e. + logical :: use_p_atm ! If true, use the atmospheric pressure. + logical :: use_ALE ! If true, use an ALE pressure reconstruction. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. type(thermo_var_ptrs) :: tv_tmp! A structure of temporary T & S. diff --git a/src/core/MOM_barotropic.F90 b/src/core/MOM_barotropic.F90 index 7095d370b6..cdc5ed0251 100644 --- a/src/core/MOM_barotropic.F90 +++ b/src/core/MOM_barotropic.F90 @@ -58,24 +58,29 @@ module MOM_barotropic public btcalc, bt_mass_source, btstep, barotropic_init, barotropic_end public register_barotropic_restarts, set_dtbt +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The barotropic stepping open boundary condition type type, private :: BT_OBC_type - real, dimension(:,:), pointer :: Cg_u => NULL() !< The external wave speed at u-points, in m s-1. - real, dimension(:,:), pointer :: Cg_v => NULL() !< The external wave speed at u-points, in m s-1. - real, dimension(:,:), pointer :: H_u => NULL() !< The total thickness at the u-points, in H (m or kg m-2). - real, dimension(:,:), pointer :: H_v => NULL() !< The total thickness at the v-points, in H (m or kg m-2). + real, dimension(:,:), pointer :: Cg_u => NULL() !< The external wave speed at u-points [m s-1]. + real, dimension(:,:), pointer :: Cg_v => NULL() !< The external wave speed at u-points [m s-1]. + real, dimension(:,:), pointer :: H_u => NULL() !< The total thickness at the u-points [H ~> m or kg m-2]. + real, dimension(:,:), pointer :: H_v => NULL() !< The total thickness at the v-points [H ~> m or kg m-2]. real, dimension(:,:), pointer :: uhbt => NULL() !< The zonal barotropic thickness fluxes specified - !! for open boundary conditions (if any), in units of H m2 s-1. + !! for open boundary conditions (if any) [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(:,:), pointer :: vhbt => NULL() !< The meridional barotropic thickness fluxes specified - !! for open boundary conditions (if any), in units of H m2 s-1. + !! for open boundary conditions (if any) [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(:,:), pointer :: ubt_outer => NULL() !< The zonal velocities just outside the domain, - !! as set by the open boundary conditions, in units of m s-1. + !! as set by the open boundary conditions [m s-1]. real, dimension(:,:), pointer :: vbt_outer => NULL() !< The meridional velocities just outside the domain, - !! as set by the open boundary conditions, in units of m s-1. + !! as set by the open boundary conditions [m s-1]. real, dimension(:,:), pointer :: eta_outer_u => NULL() !< The surface height outside of the domain - !! at a u-point with an open boundary condition, in units of H. + !! at a u-point with an open boundary condition [H ~> m or kg m-2]. real, dimension(:,:), pointer :: eta_outer_v => NULL() !< The surface height outside of the domain - !! at a v-point with an open boundary condition, in units of H. + !! at a v-point with an open boundary condition [H ~> m or kg m-2]. logical :: apply_u_OBCs !< True if this PE has an open boundary at a u-point. logical :: apply_v_OBCs !< True if this PE has an open boundary at a v-point. !>@{ Index ranges for the open boundary conditions @@ -98,53 +103,55 @@ module MOM_barotropic real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: frhatv !< The fraction of the total column thickness interpolated to v grid points in each layer, nondim. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: IDatu - !< Inverse of the basin depth at u grid points, in Z-1. + !< Inverse of the basin depth at u grid points [Z-1 ~> m-1]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: lin_drag_u - !< A spatially varying linear drag coefficient acting on the zonal barotropic flow, in H s-1. + !< A spatially varying linear drag coefficient acting on the zonal barotropic flow + !! [H s-1 ~> m s-1 or kg m-2 s-1]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: uhbt_IC !< The barotropic solvers estimate of the zonal transport as the initial condition for - !! the next call to btstep, in H m2 s-1. + !! the next call to btstep [H m2 s-1 ~> m3 s-1 or kg s-1]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: ubt_IC !< The barotropic solvers estimate of the zonal velocity that will be the initial - !! condition for the next call to btstep, in m s-1. + !! condition for the next call to btstep [m s-1]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: ubtav - !< The barotropic zonal velocity averaged over the baroclinic time step, m s-1. + !< The barotropic zonal velocity averaged over the baroclinic time step [m s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: IDatv - !< Inverse of the basin depth at v grid points, in Z-1. + !< Inverse of the basin depth at v grid points [Z-1 ~> m-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: lin_drag_v - !< A spatially varying linear drag coefficient acting on the zonal barotropic flow, in H s-1. + !< A spatially varying linear drag coefficient acting on the zonal barotropic flow + !! [H s-1 ~> m s-1 or kg m-2 s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: vhbt_IC !< The barotropic solvers estimate of the zonal transport as the initial condition for - !! the next call to btstep, in H m2 s-1. + !! the next call to btstep [H m2 s-1 ~> m3 s-1 or kg s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: vbt_IC !< The barotropic solvers estimate of the zonal velocity that will be the initial - !! condition for the next call to btstep, in m s-1. + !! condition for the next call to btstep [m s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: vbtav - !< The barotropic meridional velocity averaged over the baroclinic time step, m s-1. + !< The barotropic meridional velocity averaged over the baroclinic time step [m s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: eta_cor !< The difference between the free surface height from the barotropic calculation and the sum !! of the layer thicknesses. This difference is imposed as a forcing term in the barotropic - !! calculation over a baroclinic timestep, in H (m or kg m-2). + !! calculation over a baroclinic timestep [H ~> m or kg m-2]. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: eta_cor_bound - !< A limit on the rate at which eta_cor can be applied while avoiding instability, in units of H s-1. - !! This is only used if CS%bound_BT_corr is true. + !< A limit on the rate at which eta_cor can be applied while avoiding instability + !! [H s-1 ~> m s-1 or kg m-2 s-1]. This is only used if CS%bound_BT_corr is true. real ALLOCABLE_, dimension(NIMEMW_,NJMEMW_) :: & ua_polarity, & !< Test vector components for checking grid polarity. va_polarity, & !< Test vector components for checking grid polarity. - bathyT !< A copy of bathyT (ocean bottom depth) with wide halos, in depth units + bathyT !< A copy of bathyT (ocean bottom depth) with wide halos [Z ~> m] real ALLOCABLE_, dimension(NIMEMW_,NJMEMW_) :: IareaT !< This is a copy of G%IareaT with wide halos, but will !! still utilize the macro IareaT when referenced, m-2. real ALLOCABLE_, dimension(NIMEMBW_,NJMEMW_) :: & - D_u_Cor, & !< A simply averaged depth at u points, in Z. - dy_Cu, & !< A copy of G%dy_Cu with wide halos, in m. - IdxCu !< A copy of G%IdxCu with wide halos, in m-1. + D_u_Cor, & !< A simply averaged depth at u points [Z ~> m]. + dy_Cu, & !< A copy of G%dy_Cu with wide halos [m]. + IdxCu !< A copy of G%IdxCu with wide halos [m-1]. real ALLOCABLE_, dimension(NIMEMW_,NJMEMBW_) :: & - D_v_Cor, & !< A simply averaged depth at v points, in Z. - dx_Cv, & !< A copy of G%dx_Cv with wide halos, in m. - IdyCv !< A copy of G%IdyCv with wide halos, in m-1. + D_v_Cor, & !< A simply averaged depth at v points [Z ~> m]. + dx_Cv, & !< A copy of G%dx_Cv with wide halos [m]. + IdyCv !< A copy of G%IdyCv with wide halos [m-1]. real ALLOCABLE_, dimension(NIMEMBW_,NJMEMBW_) :: & - q_D !< f / D at PV points, in Z-1 s-1. + q_D !< f / D at PV points [Z-1 s-1 ~> m-1 s-1]. real, dimension(:,:,:), pointer :: frhatu1 => NULL() !< Predictor step values of frhatu stored for diagnostics. real, dimension(:,:,:), pointer :: frhatv1 => NULL() !< Predictor step values of frhatv stored for diagnostics. @@ -152,14 +159,13 @@ module MOM_barotropic type(BT_OBC_type) :: BT_OBC !< A structure with all of this modules fields !! for applying open boundary conditions. - real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. - real :: dtbt !< The barotropic time step, in s. + real :: Rho0 !< The density used in the Boussinesq approximation [kg m-3]. + real :: dtbt !< The barotropic time step [s]. real :: dtbt_fraction !< The fraction of the maximum time-step that !! should used. The default is 0.98. - real :: dtbt_max !< The maximum stable barotropic time step, in s. + real :: dtbt_max !< The maximum stable barotropic time step [s]. real :: dt_bt_filter !< The time-scale over which the barotropic mode - !! solutions are filtered, in s. This can never + !! solutions are filtered [s]. This can never !! be taken to be longer than 2*dt. The default, 0, !! applies no filtering. integer :: nstep_last = 0 !< The number of barotropic timesteps per baroclinic @@ -203,11 +209,10 @@ module MOM_barotropic logical :: dynamic_psurf !< If true, add a dynamic pressure due to a viscous !! ice shelf, for instance. real :: Dmin_dyn_psurf !< The minimum depth to use in limiting the size - !! of the dynamic surface pressure for stability, - !! in m. + !! of the dynamic surface pressure for stability [m]. real :: ice_strength_length !< The length scale at which the damping rate !! due to the ice strength should be the same as if - !! a Laplacian were applied, in m. + !! a Laplacian were applied [m]. real :: const_dyn_psurf !< The constant that scales the dynamic surface !! pressure, nondim. Stable values are < ~1.0. !! The default is 0.9. @@ -234,9 +239,9 @@ module MOM_barotropic logical :: debug !< If true, write verbose checksums for debugging purposes. logical :: debug_bt !< If true, write verbose checksums for debugging purposes. real :: vel_underflow !< Velocity components smaller than vel_underflow - !! are set to 0, in m s-1. + !! are set to 0 [m s-1]. real :: maxvel !< Velocity components greater than maxvel are - !! truncated to maxvel, in m s-1. + !! truncated to maxvel [m s-1]. real :: CFL_trunc !< If clip_velocity is true, velocity components will !! be truncated when they are large enough that the !! corresponding CFL number exceeds this value, nondim. @@ -307,40 +312,40 @@ module MOM_barotropic !> A desciption of the functional dependence of transport at a u-point type, private :: local_BT_cont_u_type real :: FA_u_EE !< The effective open face area for zonal barotropic transport - !! drawing from locations far to the east, in H m. + !! drawing from locations far to the east [H m ~> m2 or kg m-1]. real :: FA_u_E0 !< The effective open face area for zonal barotropic transport - !! drawing from nearby to the east, in H m. + !! drawing from nearby to the east [H m ~> m2 or kg m-1]. real :: FA_u_W0 !< The effective open face area for zonal barotropic transport - !! drawing from nearby to the west, in H m. + !! drawing from nearby to the west [H m ~> m2 or kg m-1]. real :: FA_u_WW !< The effective open face area for zonal barotropic transport - !! drawing from locations far to the west, in H m. - real :: uBT_WW !< uBT_WW is the barotropic velocity, in m s-1, beyond which the marginal + !! drawing from locations far to the west [H m ~> m2 or kg m-1]. + real :: uBT_WW !< uBT_WW is the barotropic velocity [m s-1], beyond which the marginal !! open face area is FA_u_WW. uBT_WW must be non-negative. - real :: uBT_EE !< uBT_EE is a barotropic velocity, in m s-1, beyond which the marginal + real :: uBT_EE !< uBT_EE is a barotropic velocity [m s-1], beyond which the marginal !! open face area is FA_u_EE. uBT_EE must be non-positive. - real :: uh_crvW !< The curvature of face area with velocity for flow from the west, in H s2 m-1. - real :: uh_crvE !< The curvature of face area with velocity for flow from the east, in H s2 m-1. - real :: uh_WW !< The zonal transport when ubt=ubt_WW, in H m2 s-1. - real :: uh_EE !< The zonal transport when ubt=ubt_EE, in H m2 s-1. + real :: uh_crvW !< The curvature of face area with velocity for flow from the west [H s2 m-1 ~> s2 or kg s2 m-3]. + real :: uh_crvE !< The curvature of face area with velocity for flow from the east [H s2 m-1 ~> s2 or kg s2 m-3]. + real :: uh_WW !< The zonal transport when ubt=ubt_WW [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: uh_EE !< The zonal transport when ubt=ubt_EE [H m2 s-1 ~> m3 s-1 or kg s-1]. end type local_BT_cont_u_type !> A desciption of the functional dependence of transport at a v-point type, private :: local_BT_cont_v_type real :: FA_v_NN !< The effective open face area for meridional barotropic transport - !! drawing from locations far to the north, in H m. + !! drawing from locations far to the north [H m ~> m2 or kg m-1]. real :: FA_v_N0 !< The effective open face area for meridional barotropic transport - !! drawing from nearby to the north, in H m. + !! drawing from nearby to the north [H m ~> m2 or kg m-1]. real :: FA_v_S0 !< The effective open face area for meridional barotropic transport - !! drawing from nearby to the south, in H m. + !! drawing from nearby to the south [H m ~> m2 or kg m-1]. real :: FA_v_SS !< The effective open face area for meridional barotropic transport - !! drawing from locations far to the south, in H m. - real :: vBT_SS !< vBT_SS is the barotropic velocity, in m s-1, beyond which the marginal + !! drawing from locations far to the south [H m ~> m2 or kg m-1]. + real :: vBT_SS !< vBT_SS is the barotropic velocity [m s-1], beyond which the marginal !! open face area is FA_v_SS. vBT_SS must be non-negative. - real :: vBT_NN !< vBT_NN is the barotropic velocity, in m s-1, beyond which the marginal + real :: vBT_NN !< vBT_NN is the barotropic velocity [m s-1], beyond which the marginal !! open face area is FA_v_NN. vBT_NN must be non-positive. - real :: vh_crvS !< The curvature of face area with velocity for flow from the south, in H s2 m-1. - real :: vh_crvn !< The curvature of face area with velocity for flow from the north, in H s2 m-1. - real :: vh_SS !< The meridional transport when vbt=vbt_SS, in H m2 s-1. - real :: vh_NN !< The meridional transport when vbt=vbt_NN, in H m2 s-1. + real :: vh_crvS !< The curvature of face area with velocity for flow from the south [H s2 m-1 ~> s2 or kg s2 m-3]. + real :: vh_crvn !< The curvature of face area with velocity for flow from the north [H s2 m-1 ~> s2 or kg s2 m-3]. + real :: vh_SS !< The meridional transport when vbt=vbt_SS [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: vh_NN !< The meridional transport when vbt=vbt_NN [H m2 s-1 ~> m3 s-1 or kg s-1]. end type local_BT_cont_v_type !> A container for passing around active tracer point memory limits @@ -385,38 +390,39 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: U_in !< The initial (3-D) zonal velocity, in m s-1. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: V_in !< The initial (3-D) meridional velocity, in m s-1. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: U_in !< The initial (3-D) zonal velocity [m s-1]. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: V_in !< The initial (3-D) meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: eta_in !< The initial barotropic free surface height - !! anomaly or column mass anomaly, in H (m or kg m-2). + !! anomaly or column mass anomaly [H ~> m or kg m-2]. real, intent(in) :: dt !< The time increment to integrate over. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: bc_accel_u !< The zonal baroclinic accelerations, in m s-2. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: bc_accel_u !< The zonal baroclinic accelerations [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: bc_accel_v !< The meridional baroclinic accelerations, - !! in m s-2. + !! [m s-2]. type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: pbce !< The baroclinic pressure anomaly in each layer - !! due to free surface height anomalies, in m2 H-1 s-2. + !! due to free surface height anomalies + !! [m2 H-1 s-2 ~> m s-2 or m4 kg-1 s-2]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: eta_PF_in !< The 2-D eta field (either SSH anomaly or !! column mass anomaly) that was used to calculate the input !! pressure gradient accelerations (or its final value if - !! eta_PF_start is provided, in m or kg m-2. + !! eta_PF_start is provided [H ~> m or kg m-2]. !! Note: eta_in, pbce, and eta_PF_in must have up-to-date !! values in the first point of their halos. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: U_Cor !< The (3-D) zonal-velocities used to - !! calculate the Coriolis terms in bc_accel_u, in m s-1. + !! calculate the Coriolis terms in bc_accel_u [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: V_Cor !< Ditto for meridonal bc_accel_v. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: accel_layer_u !< The zonal acceleration of each layer due - !! to the barotropic calculation, in m s-2. + !! to the barotropic calculation [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: accel_layer_v !< The meridional acceleration of each layer - !! due to the barotropic calculation, in m s-2. + !! due to the barotropic calculation [m s-2]. real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta_out !< The final barotropic free surface - !! height anomaly or column mass anomaly, in m or kg m-2. + !! height anomaly or column mass anomaly [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G)), intent(out) :: uhbtav !< the barotropic zonal volume or mass - !! fluxes averaged through the barotropic steps, in - !! m3 s-1 or kg s-1. + !! fluxes averaged through the barotropic steps + !! [H m2 s-1 ~> m3 or kg s-1]. real, dimension(SZI_(G),SZJB_(G)), intent(out) :: vhbtav !< the barotropic meridional volume or mass - !! fluxes averaged through the barotropic steps, in - !! m3 s-1 or kg s-1. + !! fluxes averaged through the barotropic steps + !! [H m2 s-1 ~> m3 or kg s-1]. type(barotropic_CS), pointer :: CS !< The control structure returned by a !! previous call to barotropic_init. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: visc_rem_u !< Both the fraction of the momentum @@ -425,31 +431,31 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, !! barotropic acceleration that a layer experiences after !! viscosity is applied, in the zonal direction. Nondimensional !! between 0 (at the bottom) and 1 (far above the bottom). - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: visc_rem_v !< Ditto for meridional direction. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: visc_rem_v !< Ditto for meridional direction [nondim]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(out) :: etaav !< The free surface height or column mass - !! averaged over the barotropic integration, in m or kg m-2. + !! averaged over the barotropic integration [H ~> m or kg m-2]. type(ocean_OBC_type), optional, pointer :: OBC !< The open boundary condition structure. type(BT_cont_type), optional, pointer :: BT_cont !< A structure with elements that describe !! the effective open face areas as a function of barotropic !! flow. real, dimension(:,:), optional, pointer :: eta_PF_start !< The eta field consistent with the pressure - !! gradient at the start of the barotropic stepping, in m or - !! kg m-2. + !! gradient at the start of the barotropic stepping + !! [H ~> m or kg m-2]. real, dimension(:,:), optional, pointer :: taux_bot !< The zonal bottom frictional stress from - !! ocean to the seafloor, in Pa. + !! ocean to the seafloor [Pa]. real, dimension(:,:), optional, pointer :: tauy_bot !< The meridional bottom frictional stress - !! from ocean to the seafloor, in Pa. + !! from ocean to the seafloor [Pa]. real, dimension(:,:,:), optional, pointer :: uh0 !< The zonal layer transports at reference - !! velocities, in H m s-1. - real, dimension(:,:,:), optional, pointer :: u_uh0 !< The velocities used to calculate uh0, in m s-1 + !! velocities [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + real, dimension(:,:,:), optional, pointer :: u_uh0 !< The velocities used to calculate uh0 [m s-1] real, dimension(:,:,:), optional, pointer :: vh0 !< The zonal layer transports at reference - !! velocities, in H m s-1. - real, dimension(:,:,:), optional, pointer :: v_vh0 !< The velocities used to calculate vh0, in m s-1 + !! velocities [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + real, dimension(:,:,:), optional, pointer :: v_vh0 !< The velocities used to calculate vh0 [m s-1] ! Local variables real :: ubt_Cor(SZIB_(G),SZJ_(G)) ! The barotropic velocities that had been real :: vbt_Cor(SZI_(G),SZJB_(G)) ! used to calculate the input Coriolis - ! terms, in m s-1. + ! terms [m s-1]. real :: wt_u(SZIB_(G),SZJ_(G),SZK_(G)) ! wt_u and wt_v are the real :: wt_v(SZI_(G),SZJB_(G),SZK_(G)) ! normalized weights to ! be used in calculating barotropic velocities, possibly with @@ -463,102 +469,102 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, real, dimension(SZI_(G),SZJ_(G)) :: & e_anom ! The anomaly in the sea surface height or column mass ! averaged between the beginning and end of the time step, - ! relative to eta_PF, with SAL effects included, in units - ! of H (m or kg m-2, the same as eta and h). + ! relative to eta_PF, with SAL effects included [H ~> m or kg m-2]. ! These are always allocated with symmetric memory and wide halos. - real :: q(SZIBW_(CS),SZJBW_(CS)) ! A pseudo potential vorticity in s-1 m-1. + real :: q(SZIBW_(CS),SZJBW_(CS)) ! A pseudo potential vorticity [s-1 Z-1 ~> s-1 m-1]. real, dimension(SZIBW_(CS),SZJW_(CS)) :: & - ubt, & ! The zonal barotropic velocity in m s-1. + ubt, & ! The zonal barotropic velocity [m s-1]. bt_rem_u, & ! The fraction of the barotropic zonal velocity that remains ! after a time step, the remainder being lost to bottom drag. ! bt_rem_u is a nondimensional number between 0 and 1. BT_force_u, & ! The vertical average of all of the u-accelerations that are - ! not explicitly included in the barotropic equation, m s-2. + ! not explicitly included in the barotropic equation [m s-2]. u_accel_bt, & ! The difference between the zonal acceleration from the - ! barotropic calculation and BT_force_u, in m s-2. - uhbt, & ! The zonal barotropic thickness fluxes, in H m2 s-1. + ! barotropic calculation and BT_force_u [m s-2]. + uhbt, & ! The zonal barotropic thickness fluxes [H m2 s-1 ~> m3 s-1 or kg s-1]. uhbt0, & ! The difference between the sum of the layer zonal thickness ! fluxes and the barotropic thickness flux using the same - ! velocity, in H m2 s-1. - ubt_old, & ! The starting value of ubt in a barotropic step, in m s-1. - ubt_first, & ! The starting value of ubt in a series of barotropic steps, in m s-1. - ubt_sum, & ! The sum of ubt over the time steps, in m s-1. - uhbt_sum, & ! The sum of uhbt over the time steps, in H m2 s-1. - ubt_wtd, & ! A weighted sum used to find the filtered final ubt, in m s-1. - ubt_trans, & ! The latest value of ubt used for a transport, in m s-1. + ! velocity [H m2 s-1 ~> m3 s-1 or kg s-1]. + ubt_old, & ! The starting value of ubt in a barotropic step [m s-1]. + ubt_first, & ! The starting value of ubt in a series of barotropic steps [m s-1]. + ubt_sum, & ! The sum of ubt over the time steps [m s-1]. + uhbt_sum, & ! The sum of uhbt over the time steps [H m2 s-1 ~> m3 s-1 or kg s-1]. + ubt_wtd, & ! A weighted sum used to find the filtered final ubt [m s-1]. + ubt_trans, & ! The latest value of ubt used for a transport [m s-1]. azon, bzon, & ! _zon & _mer are the values of the Coriolis force which czon, dzon, & ! are applied to the neighboring values of vbtav & ubtav, - amer, bmer, & ! respectively to get the barotropic inertial rotation, - cmer, dmer, & ! in units of s-1. - Cor_u, & ! The zonal Coriolis acceleration, in m s-2. + amer, bmer, & ! respectively to get the barotropic inertial rotation + cmer, dmer, & ! [s-1]. + Cor_u, & ! The zonal Coriolis acceleration [m s-2]. Cor_ref_u, & ! The zonal barotropic Coriolis acceleration due - ! to the reference velocities, in m s-2. - PFu, & ! The zonal pressure force acceleration, in m s-2. - Rayleigh_u, & ! A Rayleigh drag timescale operating at u-points, in s-1. - PFu_bt_sum, & ! The summed zonal barotropic pressure gradient force, in m s-2. - Coru_bt_sum, & ! The summed zonal barotropic Coriolis acceleration, in m s-2. - DCor_u, & ! A simply averaged depth at u points, in Z. + ! to the reference velocities [m s-2]. + PFu, & ! The zonal pressure force acceleration [m s-2]. + Rayleigh_u, & ! A Rayleigh drag timescale operating at u-points [s-1]. + PFu_bt_sum, & ! The summed zonal barotropic pressure gradient force [m s-2]. + Coru_bt_sum, & ! The summed zonal barotropic Coriolis acceleration [m s-2]. + DCor_u, & ! A simply averaged depth at u points [Z ~> m]. Datu ! Basin depth at u-velocity grid points times the y-grid - ! spacing, in H m. + ! spacing [H m ~> m2 or kg m-1]. real, dimension(SZIW_(CS),SZJBW_(CS)) :: & - vbt, & ! The meridional barotropic velocity in m s-1. + vbt, & ! The meridional barotropic velocity [m s-1]. bt_rem_v, & ! The fraction of the barotropic meridional velocity that ! remains after a time step, the rest being lost to bottom ! drag. bt_rem_v is a nondimensional number between 0 and 1. BT_force_v, & ! The vertical average of all of the v-accelerations that are - ! not explicitly included in the barotropic equation, m s-2. + ! not explicitly included in the barotropic equation [m s-2]. v_accel_bt, & ! The difference between the meridional acceleration from the - ! barotropic calculation and BT_force_v, in m s-2. - vhbt, & ! The meridional barotropic thickness fluxes, in H m2 s-1. + ! barotropic calculation and BT_force_v [m s-2]. + vhbt, & ! The meridional barotropic thickness fluxes [H m2 s-1 ~> m3 s-1 or kg s-1]. vhbt0, & ! The difference between the sum of the layer meridional ! thickness fluxes and the barotropic thickness flux using - ! the same velocities, in H m2 s-1. - vbt_old, & ! The starting value of vbt in a barotropic step, in m s-1. - vbt_first, & ! The starting value of ubt in a series of barotropic steps, in m s-1. - vbt_sum, & ! The sum of vbt over the time steps, in m s-1. - vhbt_sum, & ! The sum of vhbt over the time steps, in H m2 s-1. - vbt_wtd, & ! A weighted sum used to find the filtered final vbt, in m s-1. - vbt_trans, & ! The latest value of vbt used for a transport, in m s-1. - Cor_v, & ! The meridional Coriolis acceleration, in m s-2. + ! the same velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. + vbt_old, & ! The starting value of vbt in a barotropic step [m s-1]. + vbt_first, & ! The starting value of ubt in a series of barotropic steps [m s-1]. + vbt_sum, & ! The sum of vbt over the time steps [m s-1]. + vhbt_sum, & ! The sum of vhbt over the time steps [H m2 s-1 ~> m3 s-1 or kg s-1]. + vbt_wtd, & ! A weighted sum used to find the filtered final vbt [m s-1]. + vbt_trans, & ! The latest value of vbt used for a transport [m s-1]. + Cor_v, & ! The meridional Coriolis acceleration [m s-2]. Cor_ref_v, & ! The meridional barotropic Coriolis acceleration due - ! to the reference velocities, in m s-2. - PFv, & ! The meridional pressure force acceleration, in m s-2. - Rayleigh_v, & ! A Rayleigh drag timescale operating at v-points, in s-1. + ! to the reference velocities [m s-2]. + PFv, & ! The meridional pressure force acceleration [m s-2]. + Rayleigh_v, & ! A Rayleigh drag timescale operating at v-points [s-1]. PFv_bt_sum, & ! The summed meridional barotropic pressure gradient force, - ! in m s-2. + ! [m s-2]. Corv_bt_sum, & ! The summed meridional barotropic Coriolis acceleration, - ! in m s-2. - DCor_v, & ! A simply averaged depth at v points, in Z. + ! [m s-2]. + DCor_v, & ! A simply averaged depth at v points [Z ~> m]. Datv ! Basin depth at v-velocity grid points times the x-grid - ! spacing, in H m. + ! spacing [H m ~> m2 or kg m-1]. real, target, dimension(SZIW_(CS),SZJW_(CS)) :: & eta, & ! The barotropic free surface height anomaly or column mass - ! anomaly, in H (m or kg m-2) - eta_pred ! A predictor value of eta, in H (m or kg m-2) like eta. + ! anomaly [H ~> m or kg m-2] + eta_pred ! A predictor value of eta [H ~> m or kg m-2] like eta. real, dimension(:,:), pointer :: & eta_PF_BT ! A pointer to the eta array (either eta or eta_pred) that - ! determines the barotropic pressure force, in H (m or kg m-2) + ! determines the barotropic pressure force [H ~> m or kg m-2] real, dimension(SZIW_(CS),SZJW_(CS)) :: & - eta_sum, & ! eta summed across the timesteps, in m or kg m-2. - eta_wtd, & ! A weighted estimate used to calculate eta_out, in m or kg m-2. + eta_sum, & ! eta summed across the timesteps [H ~> m or kg m-2]. + eta_wtd, & ! A weighted estimate used to calculate eta_out [H ~> m or kg m-2]. eta_PF, & ! A local copy of the 2-D eta field (either SSH anomaly or ! column mass anomaly) that was used to calculate the input - ! pressure gradient accelerations, in m or kg m-2. + ! pressure gradient accelerations [H ~> m or kg m-2]. eta_PF_1, & ! The initial value of eta_PF, when interp_eta_PF is - ! true, in m or kg m-2. + ! true [H ~> m or kg m-2]. d_eta_PF, & ! The change in eta_PF over the barotropic time stepping when - ! interp_eta_PF is true, in m or kg m-2. + ! interp_eta_PF is true [H ~> m or kg m-2]. gtot_E, & ! gtot_X is the effective total reduced gravity used to relate gtot_W, & ! free surface height deviations to pressure forces (including gtot_N, & ! GFS and baroclinic contributions) in the barotropic momentum - gtot_S, & ! equations half a grid-point in the X-direction (X is N, S, - ! E, or W) from the thickness point. gtot_X has units of m2 H-1 s-2. + gtot_S, & ! equations half a grid-point in the X-direction (X is N, S, E, or W) + ! from the thickness point [m2 H-1 s-2 ~> m s-2 or m4 kg-1 s-2]. ! (See Hallberg, J Comp Phys 1997 for a discussion.) - eta_src, & ! The source of eta per barotropic timestep, in m or kg m-2. + eta_src, & ! The source of eta per barotropic timestep [H ~> m or kg m-2]. dyn_coef_eta, & ! The coefficient relating the changes in eta to the - ! dynamic surface pressure under rigid ice, in m2 s-2 H-1. - p_surf_dyn ! A dynamic surface pressure under rigid ice, in m2 s-2. + ! dynamic surface pressure under rigid ice + ! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. + p_surf_dyn ! A dynamic surface pressure under rigid ice [m2 s-2]. type(local_BT_cont_u_type), dimension(SZIBW_(CS),SZJW_(CS)) :: & BTCL_u ! A repackaged version of the u-point information in BT_cont. type(local_BT_cont_v_type), dimension(SZIW_(CS),SZJBW_(CS)) :: & @@ -570,15 +576,15 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, real, dimension(SZIW_(CS),SZJBW_(CS)) :: & vbt_prev, vhbt_prev, vbt_sum_prev, vhbt_sum_prev, vbt_wtd_prev ! for OBC - real :: mass_to_Z ! The depth unit converison divided by the mean density (Rho0), in m3 kg-1. + real :: mass_to_Z ! The depth unit converison divided by the mean density (Rho0) [m3 kg-1]. real :: visc_rem ! A work variable that may equal visc_rem_[uv]. Nondim. - real :: vel_prev ! The previous velocity in m s-1. - real :: dtbt ! The barotropic time step in s. + real :: vel_prev ! The previous velocity [m s-1]. + real :: dtbt ! The barotropic time step [s]. real :: bebt ! A copy of CS%bebt. real :: be_proj ! The fractional amount by which velocities are projected ! when project_velocity is true. For now be_proj is set ! to equal bebt, as they have similar roles and meanings. - real :: Idt ! The inverse of dt, in s-1. + real :: Idt ! The inverse of dt [s-1]. real :: det_de ! The partial derivative due to self-attraction and loading ! of the reference geopotential with the sea surface height. ! This is typically ~0.09 or less. @@ -588,7 +594,7 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, ! than physical problem would suggest. real :: Instep ! The inverse of the number of barotropic time steps ! to take. - real :: wt_end ! The weighting of the final value of eta_PF, ND. + real :: wt_end ! The weighting of the final value of eta_PF [nondim] integer :: nstep ! The number of barotropic time steps to take. type(time_type) :: & time_bt_start, & ! The starting time of the barotropic steps. @@ -600,24 +606,25 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, logical :: ice_is_rigid, nonblock_setup, interp_eta_PF logical :: project_velocity, add_uh0 - real :: dyn_coef_max ! The maximum stable value of dyn_coef_eta, in m2 s-2 H-1. - real :: ice_strength = 0.0 ! The effective strength of the ice in m s-2. + real :: dyn_coef_max ! The maximum stable value of dyn_coef_eta + ! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. + real :: ice_strength = 0.0 ! The effective strength of the ice [m s-2]. real :: Idt_max2 ! The squared inverse of the local maximum stable - ! barotropic time step, in s-2. + ! barotropic time step [s-2]. real :: H_min_dyn ! The minimum depth to use in limiting the size of the - ! dynamic surface pressure for stability, in H. + ! dynamic surface pressure for stability [H ~> m or kg m-2]. real :: H_eff_dx2 ! The effective total thickness divided by the grid spacing - ! squared, in H m-2. - real :: vel_tmp ! A temporary velocity, in m s-1. - real :: u_max_cor, v_max_cor ! The maximum corrective velocities, in m s-1. - real :: Htot ! The total thickness, in units of H. - real :: eta_cor_max ! The maximum fluid that can be added as a correction to eta, in H. + ! squared [H m-2 ~> m-1 or kg m-4]. + real :: vel_tmp ! A temporary velocity [m s-1]. + real :: u_max_cor, v_max_cor ! The maximum corrective velocities [m s-1]. + real :: Htot ! The total thickness [H ~> m or kg m-2]. + real :: eta_cor_max ! The maximum fluid that can be added as a correction to eta [H ~> m or kg m-2]. real :: accel_underflow ! An acceleration that is so small it should be zeroed out. real, allocatable, dimension(:) :: wt_vel, wt_eta, wt_accel, wt_trans, wt_accel2 real :: sum_wt_vel, sum_wt_eta, sum_wt_accel, sum_wt_trans real :: I_sum_wt_vel, I_sum_wt_eta, I_sum_wt_accel, I_sum_wt_trans - real :: dt_filt ! The half-width of the barotropic filter, in s. + real :: dt_filt ! The half-width of the barotropic filter [s]. real :: trans_wt1, trans_wt2 ! weight used to compute ubt_trans and vbt_trans integer :: nfilter @@ -1398,12 +1405,12 @@ subroutine btstep(U_in, V_in, eta_in, dt, bc_accel_u, bc_accel_v, forces, pbce, dyn_coef_max = CS%const_dyn_psurf * max(0.0, 1.0 - dtbt**2 * Idt_max2) / & (dtbt**2 * H_eff_dx2) - ! ice_strength has units of m s-2. rigidity_ice_[uv] has units of m3 s-1. + ! ice_strength has units of [m s-2]. rigidity_ice_[uv] has units of [m3 s-1]. ice_strength = ((forces%rigidity_ice_u(I,j) + forces%rigidity_ice_u(I-1,j)) + & (forces%rigidity_ice_v(i,J) + forces%rigidity_ice_v(i,J-1))) / & (CS%ice_strength_length**2 * dtbt) - ! Units of dyn_coef: m2 s-2 H-1 + ! Units of dyn_coef: [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1] dyn_coef_eta(i,j) = min(dyn_coef_max, ice_strength * GV%H_to_m) enddo ; enddo ; endif endif @@ -2264,33 +2271,33 @@ subroutine set_dtbt(G, GV, US, CS, eta, pbce, BT_cont, gtot_est, SSH_add) type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(barotropic_CS), pointer :: CS !< Barotropic control structure. real, dimension(SZI_(G),SZJ_(G)), optional, intent(in) :: eta !< The barotropic free surface - !! height anomaly or column mass anomaly, in H. + !! height anomaly or column mass anomaly [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(in) :: pbce !< The baroclinic pressure !! anomaly in each layer due to free surface - !! height anomalies, in m2 H-1 s-2. + !! height anomalies [m2 H-1 s-2 ~> m s-2 or m4 kg-1 s-2]. type(BT_cont_type), optional, pointer :: BT_cont !< A structure with elements that describe !! the effective open face areas as a !! function of barotropic flow. real, optional, intent(in) :: gtot_est !< An estimate of the total gravitational - !! acceleration, in m2 Z-1 s-2. + !! acceleration [m2 Z-1 s-2 ~> m s-2]. real, optional, intent(in) :: SSH_add !< An additional contribution to SSH to !! provide a margin of error when - !! calculating the external wave speed, in Z. + !! calculating the external wave speed [Z ~> m]. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & gtot_E, & ! gtot_X is the effective total reduced gravity used to relate gtot_W, & ! free surface height deviations to pressure forces (including gtot_N, & ! GFS and baroclinic contributions) in the barotropic momentum - gtot_S ! equations half a grid-point in the X-direction (X is N, S, - ! E, or W) from the thickness point. gtot_X has units of m2 H-1 s-2. + gtot_S ! equations half a grid-point in the X-direction (X is N, S, E, or W) + ! from the thickness point [m2 H-1 s-2 ~> m s-2 or m4 kg-1 s-2]. ! (See Hallberg, J Comp Phys 1997 for a discussion.) real, dimension(SZIBS_(G),SZJ_(G)) :: & Datu ! Basin depth at u-velocity grid points times the y-grid - ! spacing, in H m. + ! spacing [H m ~> m2 or kg m-1]. real, dimension(SZI_(G),SZJBS_(G)) :: & Datv ! Basin depth at v-velocity grid points times the x-grid - ! spacing, in H m. + ! spacing [H m ~> m2 or kg m-1]. real :: det_de ! The partial derivative due to self-attraction and loading ! of the reference geopotential with the sea surface height. ! This is typically ~0.09 or less. @@ -2299,7 +2306,7 @@ subroutine set_dtbt(G, GV, US, CS, eta, pbce, BT_cont, gtot_est, SSH_add) ! order 1. For stability, this may be made larger ! than physical problem would suggest. real :: add_SSH ! An additional contribution to SSH to provide a margin of error - ! when calculating the external wave speed, in Z. + ! when calculating the external wave speed [Z ~> m]. real :: min_max_dt2, Idt_max2, dtbt_max logical :: use_BT_cont type(memory_size_type) :: MS @@ -2381,33 +2388,35 @@ subroutine apply_velocity_OBCs(OBC, ubt, vbt, uhbt, vhbt, ubt_trans, vbt_trans, type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(memory_size_type), intent(in) :: MS !< A type that describes the memory sizes of !! the argument arrays. - real, dimension(SZIBW_(MS),SZJW_(MS)), intent(inout) :: ubt !< the zonal barotropic velocity, in m s-1. - real, dimension(SZIBW_(MS),SZJW_(MS)), intent(inout) :: uhbt !< the zonal barotropic transport, in H m2 s-1. + real, dimension(SZIBW_(MS),SZJW_(MS)), intent(inout) :: ubt !< the zonal barotropic velocity [m s-1]. + real, dimension(SZIBW_(MS),SZJW_(MS)), intent(inout) :: uhbt !< the zonal barotropic transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIBW_(MS),SZJW_(MS)), intent(inout) :: ubt_trans !< the zonal barotropic velocity used in - !! transport, m s-1. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(inout) :: vbt !< the meridional barotropic velocity, in m s-1. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(inout) :: vhbt !< the meridional barotropic transport, in H m2 s-1. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(inout) :: vbt_trans !< the meridional BT velocity used in transports, - !! m s-1. + !! transport [m s-1]. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(inout) :: vbt !< the meridional barotropic velocity [m s-1]. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(inout) :: vhbt !< the meridional barotropic transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(inout) :: vbt_trans !< the meridional BT velocity used in + !! transports [m s-1]. real, dimension(SZIW_(MS),SZJW_(MS)), intent(in) :: eta !< The barotropic free surface height anomaly or - !! column mass anomaly, in m or kg m-2. - real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: ubt_old !< The starting value of ubt in a barotropic step, - !! m s-1. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: vbt_old !< The starting value of vbt in a barotropic step, - !! m s-1. + !! column mass anomaly [H ~> m or kg m-2]. + real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: ubt_old !< The starting value of ubt in a barotropic + !! step [m s-1]. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: vbt_old !< The starting value of vbt in a barotropic + !! step [m s-1]. type(BT_OBC_type), intent(in) :: BT_OBC !< A structure with the private barotropic arrays !! related to the open boundary conditions, !! set by set_up_BT_OBC. integer, intent(in) :: halo !< The extra halo size to use here. - real, intent(in) :: dtbt !< The time step, in s. + real, intent(in) :: dtbt !< The time step [s]. real, intent(in) :: bebt !< The fractional weighting of the future velocity !! in determining the transport. logical, intent(in) :: use_BT_cont !< If true, use the BT_cont_types to calculate !! transports. - real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: Datu !< A fixed estimate of the face areas at u points, - !! in H m. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: Datv !< A fixed estimate of the face areas at v points, - !! in H m. + real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: Datu !< A fixed estimate of the face areas at u points + !! [H m ~> m2 or kg m-1]. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: Datv !< A fixed estimate of the face areas at v points + !! [H m ~> m2 or kg m-1]. type(local_BT_cont_u_type), dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: BTCL_u !< Structure of information used !! for a dynamic estimate of the face areas at !! u-points. @@ -2416,18 +2425,20 @@ subroutine apply_velocity_OBCs(OBC, ubt, vbt, uhbt, vhbt, ubt_trans, vbt_trans, !! v-points. real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: uhbt0 !< A correction to the zonal transport so that !! the barotropic functions agree with the sum - !! of the layer transpotts, in H m2 s-1. + !! of the layer transports + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: vhbt0 !< A correction to the meridional transport so that !! the barotropic functions agree with the sum - !! of the layer transpotts, in H m2 s-1. + !! of the layer transports + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. ! Local variables - real :: vel_prev ! The previous velocity in m s-1. + real :: vel_prev ! The previous velocity [m s-1]. real :: vel_trans ! The combination of the previous and current velocity - ! that does the mass transport, in m s-1. - real :: H_u ! The total thickness at the u-point, in H (often m or kg m-2). - real :: H_v ! The total thickness at the v-point, in H (often m or kg m-2). - real :: cfl ! The CFL number at the point in question, ND. + ! that does the mass transport [m s-1]. + real :: H_u ! The total thickness at the u-point [H ~> m or kg m-2]. + real :: H_v ! The total thickness at the v-point [H ~> m or kg m-2]. + real :: cfl ! The CFL number at the point in question [nondim] real :: u_inlet real :: v_inlet real :: h_in @@ -2551,7 +2562,7 @@ subroutine set_up_BT_OBC(OBC, eta, BT_OBC, BT_Domain, G, GV, MS, halo, use_BT_co type(memory_size_type), intent(in) :: MS !< A type that describes the memory sizes of the !! argument arrays. real, dimension(SZIW_(MS),SZJW_(MS)), intent(in) :: eta !< The barotropic free surface height anomaly or - !! column mass anomaly, in m or kg m-2. + !! column mass anomaly [H ~> m or kg m-2]. type(BT_OBC_type), intent(inout) :: BT_OBC !< A structure with the private barotropic arrays !! related to the open boundary conditions, !! set by set_up_BT_OBC. @@ -2561,10 +2572,10 @@ subroutine set_up_BT_OBC(OBC, eta, BT_OBC, BT_Domain, G, GV, MS, halo, use_BT_co integer, intent(in) :: halo !< The extra halo size to use here. logical, intent(in) :: use_BT_cont !< If true, use the BT_cont_types to calculate !! transports. - real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: Datu !< A fixed estimate of the face areas at u points, - !! in H m. - real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: Datv !< A fixed estimate of the face areas at v points, - !! in H m. + real, dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: Datu !< A fixed estimate of the face areas at u points + !! [H m ~> m2 or kg m-1]. + real, dimension(SZIW_(MS),SZJBW_(MS)), intent(in) :: Datv !< A fixed estimate of the face areas at v points + !! [H m ~> m2 or kg m-1]. type(local_BT_cont_u_type), dimension(SZIBW_(MS),SZJW_(MS)), intent(in) :: BTCL_u !< Structure of information used !! for a dynamic estimate of the face areas at !! u-points. @@ -2754,41 +2765,39 @@ subroutine btcalc(h, G, GV, CS, h_u, h_v, may_use_default, OBC) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(barotropic_CS), pointer :: CS !< The control structure returned by a previous !! call to barotropic_init. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - optional, intent(in) :: h_u !< The specified thicknesses at u-points, in m or kg m-2. + optional, intent(in) :: h_u !< The specified thicknesses at u-points [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - optional, intent(in) :: h_v !< The specified thicknesses at v-points, in m or kg m-2. + optional, intent(in) :: h_v !< The specified thicknesses at v-points [H ~> m or kg m-2]. logical, optional, intent(in) :: may_use_default !< An optional logical argument !! to indicate that the default velocity point - !! thickesses may be used for this particular + !! thicknesses may be used for this particular !! calculation, even though the setting of !! CS%hvel_scheme would usually require that h_u !! and h_v be passed in. type(ocean_OBC_type), optional, pointer :: OBC !< Open boundary control structure. ! Local variables -! All of these variables are in the same units as h - usually m or kg m-2. - real :: hatutot(SZIB_(G)) ! The sum of the layer thicknesses - real :: hatvtot(SZI_(G)) ! interpolated to the u & v grid points. - real :: Ihatutot(SZIB_(G)) ! Ihatutot and Ihatvtot are the inverses - real :: Ihatvtot(SZI_(G)) ! of hatutot and hatvtot, both in H-1. - real :: h_arith ! The arithmetic mean thickness, in H. - real :: h_harm ! The harmonic mean thicknesses, in H. + real :: hatutot(SZIB_(G)) ! The sum of the layer thicknesses interpolated to u points [H ~> m or kg m-2]. + real :: hatvtot(SZI_(G)) ! The sum of the layer thicknesses interpolated to v points [H ~> m or kg m-2]. + real :: Ihatutot(SZIB_(G)) ! Ihatutot is the inverse of hatutot [H-1 ~> m-1 or m2 kg-1]. + real :: Ihatvtot(SZI_(G)) ! Ihatvtot is the inverse of hatvtot [H-1 ~> m-1 or m2 kg-1]. + real :: h_arith ! The arithmetic mean thickness [H ~> m or kg m-2]. + real :: h_harm ! The harmonic mean thicknesses [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: wt_arith ! The nondimensional weight for the arithmetic - ! mean thickness. The harmonic mean uses - ! a weight of (1 - wt_arith). + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: wt_arith ! The nondimensional weight for the arithmetic mean thickness. + ! The harmonic mean uses a weight of (1 - wt_arith). real :: Rh ! A ratio of summed thicknesses, nondim. real :: e_u(SZIB_(G),SZK_(G)+1) ! The interface heights at u-velocity and - real :: e_v(SZI_(G),SZK_(G)+1) ! v-velocity points in H. - real :: D_shallow_u(SZI_(G)) ! The shallower of the adjacent depths in H. - real :: D_shallow_v(SZIB_(G))! The shallower of the adjacent depths in H. - real :: htot ! The sum of the layer thicknesses, in H. - real :: Ihtot ! The inverse of htot, in H-1. + real :: e_v(SZI_(G),SZK_(G)+1) ! v-velocity points [H ~> m or kg m-2]. + real :: D_shallow_u(SZI_(G)) ! The shallower of the adjacent depths [H ~> m or kg m-2]. + real :: D_shallow_v(SZIB_(G))! The shallower of the adjacent depths [H ~> m or kg m-2]. + real :: htot ! The sum of the layer thicknesses [H ~> m or kg m-2]. + real :: Ihtot ! The inverse of htot [H-1 ~> m-1 or m2 kg-1]. logical :: use_default, test_dflt, apply_OBCs integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, i, j, k @@ -3022,7 +3031,7 @@ end subroutine btcalc !> The function find_uhbt determines the zonal transport for a given velocity. function find_uhbt(u, BTC) result(uhbt) - real, intent(in) :: u !< The local zonal velocity, in m s-1 + real, intent(in) :: u !< The local zonal velocity [m s-1] type(local_BT_cont_u_type), intent(in) :: BTC !< A structure containing various fields that !! allow the barotropic transports to be calculated consistently !! with the layers' continuity equations. @@ -3046,13 +3055,13 @@ end function find_uhbt !! velocity that is consistent with a given transport. function uhbt_to_ubt(uhbt, BTC, guess) result(ubt) real, intent(in) :: uhbt !< The barotropic zonal transport that should be inverted for, - !! in units of H m2 s-1. + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. type(local_BT_cont_u_type), intent(in) :: BTC !< A structure containing various fields that allow the !! barotropic transports to be calculated consistently with the !! layers' continuity equations. real, optional, intent(in) :: guess !< A guess at what ubt will be. The result is not allowed !! to be dramatically larger than guess. - real :: ubt !< The result - The velocity that gives uhbt transport, in m s-1. + real :: ubt !< The result - The velocity that gives uhbt transport [m s-1]. ! Local variables real :: ubt_min, ubt_max, uhbt_err, derr_du @@ -3136,7 +3145,7 @@ end function uhbt_to_ubt !> The function find_vhbt determines the meridional transport for a given velocity. function find_vhbt(v, BTC) result(vhbt) - real, intent(in) :: v !< The local meridional velocity, in m s-1 + real, intent(in) :: v !< The local meridional velocity [m s-1] type(local_BT_cont_v_type), intent(in) :: BTC !< A structure containing various fields that !! allow the barotropic transports to be calculated consistently !! with the layers' continuity equations. @@ -3159,13 +3168,13 @@ end function find_vhbt !! velocity that is consistent with a given transport. function vhbt_to_vbt(vhbt, BTC, guess) result(vbt) real, intent(in) :: vhbt !< The barotropic meridional transport that should be - !! inverted for, in units of H m2 s-1. + !! inverted for [H m2 s-1 ~> m3 s-1 or kg s-1]. type(local_BT_cont_v_type), intent(in) :: BTC !< A structure containing various fields that allow the !! barotropic transports to be calculated consistently !! with the layers' continuity equations. real, optional, intent(in) :: guess !< A guess at what vbt will be. The result is not allowed !! to be dramatically larger than guess. - real :: vbt !< The result - The velocity that gives vhbt transport, in m s-1. + real :: vbt !< The result - The velocity that gives vhbt transport [m s-1]. ! Local variables real :: vbt_min, vbt_max, vhbt_err, derr_dv @@ -3382,13 +3391,15 @@ subroutine adjust_local_BT_cont_types(ubt, uhbt, vbt, vhbt, BTCL_u, BTCL_v, & G, MS, halo) type(memory_size_type), intent(in) :: MS !< A type that describes the memory sizes of the argument arrays. real, dimension(SZIBW_(MS),SZJW_(MS)), & - intent(in) :: ubt !< The linearization zonal barotropic velocity in m s-1. + intent(in) :: ubt !< The linearization zonal barotropic velocity [m s-1]. real, dimension(SZIBW_(MS),SZJW_(MS)), & - intent(in) :: uhbt !< The linearization zonal barotropic transport in H m2 s-1. + intent(in) :: uhbt !< The linearization zonal barotropic transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIW_(MS),SZJBW_(MS)), & - intent(in) :: vbt !< The linearization meridional barotropic velocity in m s-1. + intent(in) :: vbt !< The linearization meridional barotropic velocity [m s-1]. real, dimension(SZIW_(MS),SZJBW_(MS)), & - intent(in) :: vhbt !< The linearization meridional barotropic transport in H m2 s-1. + intent(in) :: vhbt !< The linearization meridional barotropic transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. type(local_BT_cont_u_type), dimension(SZIBW_(MS),SZJW_(MS)), & intent(out) :: BTCL_u !< A structure with the u information from BT_cont. type(local_BT_cont_v_type), dimension(SZIW_(MS),SZJBW_(MS)), & @@ -3477,9 +3488,9 @@ subroutine BT_cont_to_face_areas(BT_cont, Datu, Datv, G, MS, halo, maximize) type(memory_size_type), intent(in) :: MS !< A type that describes the memory !! sizes of the argument arrays. real, dimension(MS%isdw-1:MS%iedw,MS%jsdw:MS%jedw), & - intent(out) :: Datu !< The effective zonal face area, in H m. + intent(out) :: Datu !< The effective zonal face area [H m ~> m2 or kg m-1]. real, dimension(MS%isdw:MS%iedw,MS%jsdw-1:MS%jedw), & - intent(out) :: Datv !< The effective meridional face area, in H m. + intent(out) :: Datv !< The effective meridional face area [H m ~> m2 or kg m-1]. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. integer, optional, intent(in) :: halo !< The extra halo size to use here. logical, optional, intent(in) :: maximize !< If present and true, find the @@ -3525,22 +3536,22 @@ end subroutine swap subroutine find_face_areas(Datu, Datv, G, GV, CS, MS, eta, halo, add_max) type(memory_size_type), intent(in) :: MS !< A type that describes the memory sizes of the argument arrays. real, dimension(MS%isdw-1:MS%iedw,MS%jsdw:MS%jedw), & - intent(out) :: Datu !< The open zonal face area, in H m (m2 or kg m-1). + intent(out) :: Datu !< The open zonal face area [H m ~> m2 or kg m-1]. real, dimension(MS%isdw:MS%iedw,MS%jsdw-1:MS%jedw), & - intent(out) :: Datv !< The open meridional face area, in H m (m2 or kg m-1). + intent(out) :: Datv !< The open meridional face area [H m ~> m2 or kg m-1]. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(barotropic_CS), pointer :: CS !< The control structure returned by a previous !! call to barotropic_init. real, dimension(MS%isdw:MS%iedw,MS%jsdw:MS%jedw), & optional, intent(in) :: eta !< The barotropic free surface height anomaly - !! or column mass anomaly, in H (m or kg m-2). + !! or column mass anomaly [H ~> m or kg m-2]. integer, optional, intent(in) :: halo !< The halo size to use, default = 1. real, optional, intent(in) :: add_max !< A value to add to the maximum depth (used - !! to overestimate the external wave speed) in Z. + !! to overestimate the external wave speed) [Z ~> m]. ! Local variables - real :: H1, H2 ! Temporary total thicknesses, in m or kg m-2. + real :: H1, H2 ! Temporary total thicknesses [H ~> m or kg m-2]. integer :: i, j, is, ie, js, je, hs is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec hs = 1 ; if (present(halo)) hs = max(halo,0) @@ -3622,8 +3633,9 @@ end subroutine find_face_areas subroutine bt_mass_source(h, eta, set_cor, G, GV, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: eta !< The free surface height that is to be corrected, in m. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: eta !< The free surface height that is to be + !! corrected [H ~> m or kg m-2]. logical, intent(in) :: set_cor !< A flag to indicate whether to set the corrective !! fluxes (and update the slowly varying part of eta_cor) !! (.true.) or whether to incrementally update the @@ -3632,13 +3644,13 @@ subroutine bt_mass_source(h, eta, set_cor, G, GV, CS) !! to barotropic_init. ! Local variables - real :: h_tot(SZI_(G)) ! The sum of the layer thicknesses, in H. + real :: h_tot(SZI_(G)) ! The sum of the layer thicknesses [H ~> m or kg m-2]. real :: eta_h(SZI_(G)) ! The free surface height determined from - ! the sum of the layer thicknesses, in H. + ! the sum of the layer thicknesses [H ~> m or kg m-2]. real :: d_eta ! The difference between estimates of the total - ! thicknesses, in H. + ! thicknesses [H ~> m or kg m-2]. real :: limit_dt ! The fractional mass-source limit divided by the - ! thermodynamic time step, in s-1. + ! thermodynamic time step [s-1]. integer :: is, ie, js, je, nz, i, j, k real, parameter :: frac_cor = 0.25 real, parameter :: slow_rate = 0.125 @@ -3686,14 +3698,14 @@ subroutine barotropic_init(u, v, h, eta, Time, G, GV, US, param_file, diag, CS, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: eta !< Free surface height or column mass anomaly, in - !! m or kg m-2. + intent(in) :: eta !< Free surface height or column mass anomaly + !! [Z ~> m] or [H ~> kg m-2]. type(time_type), target, intent(in) :: Time !< The current model time. type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters. type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to regulate diagnostic @@ -3715,11 +3727,11 @@ subroutine barotropic_init(u, v, h, eta, Time, G, GV, US, param_file, diag, CS, #include "version_variable.h" ! Local variables character(len=40) :: mdl = "MOM_barotropic" ! This module's name. - real :: Datu(SZIBS_(G),SZJ_(G)) ! Zonal open face area in H m. - real :: Datv(SZI_(G),SZJBS_(G)) ! Meridional open face area in H m. - real :: gtot_estimate ! Summed GV%g_prime in m2 Z-1 s-2, to give an upper-bound estimate for pbce. + real :: Datu(SZIBS_(G),SZJ_(G)) ! Zonal open face area [H m ~> m2 or kg m-1]. + real :: Datv(SZI_(G),SZJBS_(G)) ! Meridional open face area [H m ~> m2 or kg m-1]. + real :: gtot_estimate ! Summed GV%g_prime [m2 Z-1 s-2 ~> m s-2], to give an upper-bound estimate for pbce. real :: SSH_extra ! An estimate of how much higher SSH might get, for use - ! in calculating the safe external wave speed, in Z. + ! in calculating the safe external wave speed [Z ~> m]. real :: dtbt_input, dtbt_tmp real :: wave_drag_scale ! A scaling factor for the barotropic linear wave drag ! piston velocities. diff --git a/src/core/MOM_boundary_update.F90 b/src/core/MOM_boundary_update.F90 index 6ca49256f2..ae78c6fd0d 100644 --- a/src/core/MOM_boundary_update.F90 +++ b/src/core/MOM_boundary_update.F90 @@ -115,7 +115,7 @@ subroutine update_OBC_data(OBC, G, GV, US, tv, h, CS, Time) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< layer thicknesses, in H + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< layer thicknesses [H ~> m or kg m-2] type(ocean_OBC_type), pointer :: OBC !< Open boundary structure type(update_OBC_CS), pointer :: CS !< Control structure for OBCs type(time_type), intent(in) :: Time !< Model time diff --git a/src/core/MOM_checksum_packages.F90 b/src/core/MOM_checksum_packages.F90 index d67695b8e6..a71f4bab48 100644 --- a/src/core/MOM_checksum_packages.F90 +++ b/src/core/MOM_checksum_packages.F90 @@ -44,15 +44,17 @@ subroutine MOM_state_chksum_5arg(mesg, u, v, h, uh, vh, G, GV, haloshift, symmet type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: uh !< Volume flux through zonal faces = u*h*dy, m3 s-1. + intent(in) :: uh !< Volume flux through zonal faces = u*h*dy + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: vh !< Volume flux through meridional faces = v*h*dx, in m3 s-1. + intent(in) :: vh !< Volume flux through meridional faces = v*h*dx + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. integer, optional, intent(in) :: haloshift !< The width of halos to check (default 0). logical, optional, intent(in) :: symmetric !< If true, do checksums on the fully symmetric !! computationoal domain. @@ -80,11 +82,11 @@ subroutine MOM_state_chksum_3arg(mesg, u, v, h, G, GV, haloshift, symmetric) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< Zonal velocity, in m s-1. + intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< Meridional velocity, in m s-1. + intent(in) :: v !< Meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. integer, optional, intent(in) :: haloshift !< The width of halos to check (default 0). logical, optional, intent(in) :: symmetric !< If true, do checksums on the fully symmetric !! computationoal domain. @@ -163,31 +165,32 @@ subroutine MOM_accel_chksum(mesg, CAu, CAv, PFu, PFv, diffu, diffv, G, GV, pbce, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & intent(in) :: CAu !< Zonal acceleration due to Coriolis - !! and momentum advection terms, in m s-2. + !! and momentum advection terms [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(in) :: CAv !< Meridional acceleration due to Coriolis - !! and momentum advection terms, in m s-2. + !! and momentum advection terms [m s-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & intent(in) :: PFu !< Zonal acceleration due to pressure gradients - !! (equal to -dM/dx) in m s-2. + !! (equal to -dM/dx) [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(in) :: PFv !< Meridional acceleration due to pressure gradients - !! (equal to -dM/dy) in m s-2. + !! (equal to -dM/dy) [m s-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & intent(in) :: diffu !< Zonal acceleration due to convergence of the - !! along-isopycnal stress tensor, in m s-2. + !! along-isopycnal stress tensor [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(in) :: diffv !< Meridional acceleration due to convergence of - !! the along-isopycnal stress tensor, in m s-2. + !! the along-isopycnal stress tensor [m s-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(in) :: pbce !< The baroclinic pressure anomaly in each layer - !! due to free surface height anomalies, in m2 s-2 H-1. + !! due to free surface height anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 s-2 kg-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(in) :: u_accel_bt !< The zonal acceleration from terms in the - !! barotropic solver,in m s-2. + !! barotropic solver [m s-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(in) :: v_accel_bt !< The meridional acceleration from terms in - !! the barotropic solver,in m s-2. + !! the barotropic solver [m s-2]. logical, optional, intent(in) :: symmetric !< If true, do checksums on the fully symmetric !! computationoal domain. @@ -216,15 +219,15 @@ subroutine MOM_state_stats(mesg, u, v, h, Temp, Salt, G, allowChange, permitDimi type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. character(len=*), intent(in) :: mesg !< A message that appears on the chksum lines. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, pointer, dimension(:,:,:), & - intent(in) :: Temp !< Temperature in degree C. + intent(in) :: Temp !< Temperature [degC]. real, pointer, dimension(:,:,:), & - intent(in) :: Salt !< Salinity, in ppt. + intent(in) :: Salt !< Salinity [ppt]. logical, optional, intent(in) :: allowChange !< do not flag an error !! if the statistics change. logical, optional, intent(in) :: permitDiminishing !< do not flag error diff --git a/src/core/MOM_continuity.F90 b/src/core/MOM_continuity.F90 index 121bbfbdb0..cf4dc09897 100644 --- a/src/core/MOM_continuity.F90 +++ b/src/core/MOM_continuity.F90 @@ -44,27 +44,27 @@ subroutine continuity(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, & type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< Zonal velocity, in m/s. + intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< Meridional velocity, in m/s. + intent(in) :: v !< Meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: hin !< Initial layer thickness, in m or kg/m2. + intent(in) :: hin !< Initial layer thickness [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Final layer thickness, in m or kg/m2. + intent(inout) :: h !< Final layer thickness [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & intent(out) :: uh !< Volume flux through zonal faces = - !! u*h*dy, in m3/s. + !! u*h*dy [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(out) :: vh !< Volume flux through meridional faces = - !! v*h*dx, in m3/s. - real, intent(in) :: dt !< Time increment, in s. + !! v*h*dx [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_CS), pointer :: CS !< Control structure for mom_continuity. real, dimension(SZIB_(G),SZJ_(G)), & optional, intent(in) :: uhbt !< The vertically summed volume - !! flux through zonal faces, in m3/s. + !! flux through zonal faces [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G)), & optional, intent(in) :: vhbt !< The vertically summed volume - !! flux through meridional faces, in m3/s. + !! flux through meridional faces [H m2 s-1 ~> m3 s-1 or kg s-1]. type(ocean_OBC_type), & optional, pointer :: OBC !< Open boundaries control structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & @@ -79,22 +79,22 @@ subroutine continuity(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, & !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: u_cor !< The zonal velocities that - !! give uhbt as the depth-integrated transport, in m/s. + !! give uhbt as the depth-integrated transport [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(out) :: v_cor !< The meridional velocities that - !! give vhbt as the depth-integrated transport, in m/s. + !! give vhbt as the depth-integrated transport [m s-1]. real, dimension(SZIB_(G),SZJ_(G)), & optional, intent(in) :: uhbt_aux !< A second summed zonal - !! volume flux in m3/s. + !! volume flux [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G)), & optional, intent(in) :: vhbt_aux !< A second summed meridional - !! volume flux in m3/s. + !! volume flux [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(inout) :: u_cor_aux !< The zonal velocities - !! that give uhbt_aux as the depth-integrated transport, in m/s. + !! that give uhbt_aux as the depth-integrated transport [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(inout) :: v_cor_aux !< The meridional velocities - !! that give vhbt_aux as the depth-integrated transport, in m/s. + !! that give vhbt_aux as the depth-integrated transport [m s-1]. type(BT_cont_type), & optional, pointer :: BT_cont !< A structure with elements !! that describe the effective open face areas as a function of barotropic flow. diff --git a/src/core/MOM_continuity_PPM.F90 b/src/core/MOM_continuity_PPM.F90 index bdf6e3f9b1..3f6b699b20 100644 --- a/src/core/MOM_continuity_PPM.F90 +++ b/src/core/MOM_continuity_PPM.F90 @@ -35,15 +35,15 @@ module MOM_continuity_PPM !! of the higher order interpolation. real :: tol_eta !< The tolerance for free-surface height !! discrepancies between the barotropic solution and - !! the sum of the layer thicknesses, in m. + !! the sum of the layer thicknesses [H ~> m or kg m-2]. real :: tol_vel !< The tolerance for barotropic velocity !! discrepancies between the barotropic solution and - !! the sum of the layer thicknesses, in m s-1. + !! the sum of the layer thicknesses [m s-1]. real :: tol_eta_aux !< The tolerance for free-surface height !! discrepancies between the barotropic solution and !! the sum of the layer thicknesses when calculating - !! the auxiliary corrected velocities, in m. - real :: CFL_limit_adjust !< The maximum CFL of the adjusted velocities, ND. + !! the auxiliary corrected velocities [H ~> m or kg m-2]. + real :: CFL_limit_adjust !< The maximum CFL of the adjusted velocities [nondim] logical :: aggress_adjust !< If true, allow the adjusted velocities to have a !! relative CFL change up to 0.5. False by default. logical :: vol_CFL !< If true, use the ratio of the open face lengths @@ -75,27 +75,28 @@ module MOM_continuity_PPM subroutine continuity_PPM(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, & visc_rem_u, visc_rem_v, u_cor, v_cor, & uhbt_aux, vhbt_aux, u_cor_aux, v_cor_aux, BT_cont) - ! In the following documentation, H is used for the units of thickness (usually m or kg m-2.) - type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. - type(continuity_PPM_CS), pointer :: CS !< Module's control structure. + type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. + type(continuity_PPM_CS), pointer :: CS !< Module's control structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< Zonal velocity, in m s-1. + intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< Meridional velocity, in m s-1. + intent(in) :: v !< Meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: hin !< Initial layer thickness, in H. + intent(in) :: hin !< Initial layer thickness [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Final layer thickness, in H. + intent(inout) :: h !< Final layer thickness [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: uh !< Zonal volume flux, u*h*dy, H m2 s-1. + intent(out) :: uh !< Zonal volume flux, u*h*dy [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: vh !< Meridional volume flux, v*h*dx, H m2 s-1. - real, intent(in) :: dt !< Time increment in s. + intent(out) :: vh !< Meridional volume flux, v*h*dx [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, intent(in) :: dt !< Time increment [s]. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. real, dimension(SZIB_(G),SZJ_(G)), & - optional, intent(in) :: uhbt !< The summed volume flux through zonal faces, H m2 s-1. + optional, intent(in) :: uhbt !< The summed volume flux through zonal faces + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G)), & - optional, intent(in) :: vhbt !< The summed volume flux through meridional faces, H m2 s-1. + optional, intent(in) :: vhbt !< The summed volume flux through meridional faces + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. type(ocean_OBC_type), & optional, pointer :: OBC !< Open boundaries control structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & @@ -114,29 +115,31 @@ subroutine continuity_PPM(u, v, hin, h, uh, vh, dt, G, GV, CS, uhbt, vhbt, OBC, !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: u_cor - !< The zonal velocities that give uhbt as the depth-integrated transport, in m s-1. + !< The zonal velocities that give uhbt as the depth-integrated transport [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(out) :: v_cor - !< The meridional velocities that give vhbt as the depth-integrated transport, in m s-1. + !< The meridional velocities that give vhbt as the depth-integrated transport [m s-1]. real, dimension(SZIB_(G),SZJ_(G)), & optional, intent(in) :: uhbt_aux - !< A second set of summed volume fluxes through zonal faces, in H m2 s-1. + !< A second set of summed volume fluxes through zonal faces + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G)), & optional, intent(in) :: vhbt_aux - !< A second set of summed volume fluxes through meridional faces, in H m2 s-1. + !< A second set of summed volume fluxes through meridional faces + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: u_cor_aux !< The zonal velocities that give uhbt_aux as the depth-integrated - !! transports, in m s-1. + !! transports [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(out) :: v_cor_aux !< The meridional velocities that give vhbt_aux as the depth-integrated - !! transports, in m s-1. + !! transports [m s-1]. type(BT_cont_type), optional, pointer :: BT_cont !< A structure with elements that describe !! the effective open face areas as a function of barotropic flow. ! Local variables - real :: h_min ! The minimum layer thickness, in H. h_min could be 0. + real :: h_min ! The minimum layer thickness [H ~> m or kg m-2]. h_min could be 0. type(loop_bounds_type) :: LB integer :: is, ie, js, je, nz, stencil integer :: i, j, k @@ -228,12 +231,13 @@ subroutine zonal_mass_flux(u, h_in, uh, dt, G, GV, CS, LB, uhbt, OBC, & type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< Ocean's vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< Zonal velocity, in m s-1. + intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_in !< Layer thickness used to calculate fluxes, in H. + intent(in) :: h_in !< Layer thickness used to calculate fluxes [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: uh !< Volume flux through zonal faces = u*h*dy, H m2 s-1. - real, intent(in) :: dt !< Time increment in s. + intent(out) :: uh !< Volume flux through zonal faces = u*h*dy + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. type(loop_bounds_type), intent(in) :: LB !< Loop bounds structure. type(ocean_OBC_type), & @@ -245,10 +249,11 @@ subroutine zonal_mass_flux(u, h_in, uh, dt, G, GV, CS, LB, uhbt, OBC, & !! acceleration that a layer experiences after viscosity is applied. !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZIB_(G),SZJ_(G)), & - optional, intent(in) :: uhbt !< The summed volume flux through zonal faces, H m2 s-1. + optional, intent(in) :: uhbt !< The summed volume flux through zonal faces + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G)), & optional, intent(in) :: uhbt_aux - !< A second set of summed volume fluxes through zonal faces, in H m2 s-1. + !< A second set of summed volume fluxes through zonal faces [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: u_cor !< The zonal velocitiess (u with a barotropic correction) @@ -256,31 +261,31 @@ subroutine zonal_mass_flux(u, h_in, uh, dt, G, GV, CS, LB, uhbt, OBC, & real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: u_cor_aux !< The zonal velocities (u with a barotropic correction) - !! that give uhbt_aux as the depth-integrated transports, in m s-1. + !! that give uhbt_aux as the depth-integrated transports [m s-1]. type(BT_cont_type), optional, pointer :: BT_cont !< A structure with elements that describe the !! effective open face areas as a function of barotropic flow. ! Local variables - real, dimension(SZIB_(G),SZK_(G)) :: duhdu ! Partial derivative of uh with u, in H m. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_L, h_R ! Left and right face thicknesses, in H. + real, dimension(SZIB_(G),SZK_(G)) :: duhdu ! Partial derivative of uh with u [H m ~> m2 or kg m-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_L, h_R ! Left and right face thicknesses [H ~> m or kg m-2]. real, dimension(SZIB_(G)) :: & - du, & ! Corrective barotropic change in the velocity, in m s-1. + du, & ! Corrective barotropic change in the velocity [m s-1]. du_min_CFL, & ! Min/max limits on du correction du_max_CFL, & ! to avoid CFL violations - duhdu_tot_0, & ! Summed partial derivative of uh with u, in H m. - uh_tot_0, & ! Summed transport with no barotropic correction in H m2 s-1. + duhdu_tot_0, & ! Summed partial derivative of uh with u [H m ~> m2 or kg m-1]. + uh_tot_0, & ! Summed transport with no barotropic correction [H m2 s-1 ~> m3 s-1 or kg s-1]. visc_rem_max ! The column maximum of visc_rem. logical, dimension(SZIB_(G)) :: do_I real, dimension(SZIB_(G),SZK_(G)) :: & visc_rem ! A 2-D copy of visc_rem_u or an array of 1's. - real, dimension(SZIB_(G)) :: FAuI ! A list of sums of zonal face areas, in H m. - real :: FA_u ! A sum of zonal face areas, in H m. + real, dimension(SZIB_(G)) :: FAuI ! A list of sums of zonal face areas [H m ~> m2 or kg m-1]. + real :: FA_u ! A sum of zonal face areas [H m ~> m2 or kg m-1]. real :: I_vrm ! 1.0 / visc_rem_max, nondim. real :: CFL_dt ! The maximum CFL ratio of the adjusted velocities divided by - ! the time step, in s-1. - real :: I_dt ! 1.0 / dt, in s-1. - real :: du_lim ! The velocity change that give a relative CFL of 1, in m s-1. - real :: dx_E, dx_W ! Effective x-grid spacings to the east and west, in m. + ! the time step [s-1]. + real :: I_dt ! 1.0 / dt [s-1]. + real :: du_lim ! The velocity change that give a relative CFL of 1 [m s-1]. + real :: dx_E, dx_W ! Effective x-grid spacings to the east and west [m]. integer :: i, j, k, ish, ieh, jsh, jeh, n, nz logical :: do_aux, local_specified_BC, use_visc_rem, set_BT_cont, any_simple_OBC logical :: local_Flather_OBC, local_open_BC, is_simple @@ -535,20 +540,20 @@ end subroutine zonal_mass_flux subroutine zonal_flux_layer(u, h, h_L, h_R, uh, duhdu, visc_rem, dt, G, j, & ish, ieh, do_I, vol_CFL, OBC) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZIB_(G)), intent(in) :: u !< Zonal velocity, in m s-1. + real, dimension(SZIB_(G)), intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZIB_(G)), intent(in) :: visc_rem !< Both the fraction of the !! momentum originally in a layer that remains after a time-step !! of viscosity, and the fraction of a time-step's worth of a barotropic !! acceleration that a layer experiences after viscosity is applied. !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). - real, dimension(SZI_(G)), intent(in) :: h !< Layer thickness, in H. - real, dimension(SZI_(G)), intent(in) :: h_L !< Left thickness, in H. - real, dimension(SZI_(G)), intent(in) :: h_R !< Right thickness, in H. + real, dimension(SZI_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G)), intent(in) :: h_L !< Left thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G)), intent(in) :: h_R !< Right thickness [H ~> m or kg m-2]. real, dimension(SZIB_(G)), intent(inout) :: uh !< Zonal mass or volume - !! transport, in H m2 s-1. + !! transport [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G)), intent(inout) :: duhdu !< Partial derivative of uh - !! with u, in H m. - real, intent(in) :: dt !< Time increment in s. + !! with u [H m ~> m2 or kg m-1]. + real, intent(in) :: dt !< Time increment [s]. integer, intent(in) :: j !< Spatial index. integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. @@ -557,10 +562,10 @@ subroutine zonal_flux_layer(u, h, h_L, h_R, uh, duhdu, visc_rem, dt, G, j, & !! ratio of face areas to the cell areas when estimating the CFL number. type(ocean_OBC_type), optional, pointer :: OBC !< Open boundaries control structure. ! Local variables - real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. + real :: CFL ! The CFL number based on the local velocity and grid spacing [nondim] real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. - real :: h_marg ! The marginal thickness of a flux, in H. + real :: h_marg ! The marginal thickness of a flux [H ~> m or kg m-2]. integer :: i logical :: local_open_BC @@ -611,15 +616,15 @@ end subroutine zonal_flux_layer subroutine zonal_face_thickness(u, h, h_L, h_R, h_u, dt, G, LB, vol_CFL, & marginal, visc_rem_u, OBC) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity, in m s-1. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness used to - !! calculate fluxes, in H. + !! calculate fluxes [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the - !! reconstruction, in H. + !! reconstruction [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the - !! reconstruction, in H. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: h_u !< Thickness at zonal faces, in H. - real, intent(in) :: dt !< Time increment in s. + !! reconstruction [H ~> m or kg m-2]. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: h_u !< Thickness at zonal faces [H ~> m or kg m-2]. + real, intent(in) :: dt !< Time increment [s]. type(loop_bounds_type), intent(in) :: LB !< Loop bounds structure. logical, intent(in) :: vol_CFL !< If true, rescale the ratio !! of face areas to the cell areas when estimating the CFL number. @@ -634,11 +639,11 @@ subroutine zonal_face_thickness(u, h, h_L, h_R, h_u, dt, G, LB, vol_CFL, & type(ocean_OBC_type), optional, pointer :: OBC !< Open boundaries control structure. ! Local variables - real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. + real :: CFL ! The CFL number based on the local velocity and grid spacing [nondim] real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. - real :: h_avg ! The average thickness of a flux, in H. - real :: h_marg ! The marginal thickness of a flux, in H. + real :: h_avg ! The average thickness of a flux [H ~> m or kg m-2]. + real :: h_marg ! The marginal thickness of a flux [H ~> m or kg m-2]. logical :: local_open_BC integer :: i, j, k, ish, ieh, jsh, jeh, nz, n ish = LB%ish ; ieh = LB%ieh ; jsh = LB%jsh ; jeh = LB%jeh ; nz = G%ke @@ -718,31 +723,32 @@ subroutine zonal_flux_adjust(u, h_in, h_L, h_R, uhbt, uh_tot_0, duhdu_tot_0, & du, du_max_CFL, du_min_CFL, dt, G, CS, visc_rem, & j, ish, ieh, do_I_in, full_precision, uh_3d, OBC) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity, in m s-1. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_in !< Layer thickness used to - !! calculate fluxes, in H. + !! calculate fluxes [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the - !! reconstruction, in H. + !! reconstruction [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the - !! reconstruction, in H. + !! reconstruction [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZK_(G)), intent(in) :: visc_rem !< Both the fraction of the !! momentum originally in a layer that remains after a time-step of viscosity, and !! the fraction of a time-step's worth of a barotropic acceleration that a layer !! experiences after viscosity is applied. !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZIB_(G)), optional, intent(in) :: uhbt !< The summed volume flux - !! through zonal faces, H m2 s-1. + !! through zonal faces [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, dimension(SZIB_(G)), intent(in) :: du_max_CFL !< Maximum acceptable - !! value of du, in m s-1. + !! value of du [m s-1]. real, dimension(SZIB_(G)), intent(in) :: du_min_CFL !< Minimum acceptable - !! value of du, in m s-1. + !! value of du [m s-1]. real, dimension(SZIB_(G)), intent(in) :: uh_tot_0 !< The summed transport - !! with 0 adjustment, in H m2 s-1. + !! with 0 adjustment [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G)), intent(in) :: duhdu_tot_0 !< The partial derivative - !! of du_err with du at 0 adjustment, in H m. + !! of du_err with du at 0 adjustment [H m ~> m2 or kg m-1]. real, dimension(SZIB_(G)), intent(out) :: du !< - !! The barotropic velocity adjustment, in m s-1. - real, intent(in) :: dt !< Time increment in s. + !! The barotropic velocity adjustment [m s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. integer, intent(in) :: j !< Spatial index. integer, intent(in) :: ish !< Start of index range. @@ -753,23 +759,23 @@ subroutine zonal_flux_adjust(u, h_in, h_L, h_R, uhbt, uh_tot_0, duhdu_tot_0, & !! A flag indicating how carefully to iterate. The !! default is .true. (more accurate). real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), optional, intent(inout) :: uh_3d !< - !! Volume flux through zonal faces = u*h*dy, H m2 s-1. + !! Volume flux through zonal faces = u*h*dy [H m2 s-1 ~> m3 s-1 or kg s-1]. type(ocean_OBC_type), optional, pointer :: OBC !< Open boundaries control structure. ! Local variables real, dimension(SZIB_(G),SZK_(G)) :: & - uh_aux, & ! An auxiliary zonal volume flux, in H m s-1. - duhdu ! Partial derivative of uh with u, in H m. + uh_aux, & ! An auxiliary zonal volume flux [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + duhdu ! Partial derivative of uh with u [H m ~> m2 or kg m-1]. real, dimension(SZIB_(G)) :: & - uh_err, & ! Difference between uhbt and the summed uh, in H m2 s-1. - uh_err_best, & ! The smallest value of uh_err found so far, in H m2 s-1. - u_new, & ! The velocity with the correction added, in m s-1. - duhdu_tot,&! Summed partial derivative of uh with u, in H m. + uh_err, & ! Difference between uhbt and the summed uh [H m2 s-1 ~> m3 s-1 or kg s-1]. + uh_err_best, & ! The smallest value of uh_err found so far [H m2 s-1 ~> m3 s-1 or kg s-1]. + u_new, & ! The velocity with the correction added [m s-1]. + duhdu_tot,&! Summed partial derivative of uh with u [H m ~> m2 or kg m-1]. du_min, & ! Min/max limits on du correction based on CFL limits - du_max ! and previous iterations, in m s-1. - real :: du_prev ! The previous value of du, in m s-1. - real :: ddu ! The change in du from the previous iteration, in m s-1. - real :: tol_eta ! The tolerance for the current iteration, in m. - real :: tol_vel ! The tolerance for velocity in the current iteration, m s-1. + du_max ! and previous iterations [m s-1]. + real :: du_prev ! The previous value of du [m s-1]. + real :: ddu ! The change in du from the previous iteration [m s-1]. + real :: tol_eta ! The tolerance for the current iteration [H ~> m or kg m-2]. + real :: tol_vel ! The tolerance for velocity in the current iteration [m s-1]. integer :: i, k, nz, itt, max_itts = 20 logical :: full_prec, domore, do_I(SZIB_(G)) @@ -880,24 +886,24 @@ subroutine set_zonal_BT_cont(u, h_in, h_L, h_R, BT_cont, uh_tot_0, duhdu_tot_0, du_max_CFL, du_min_CFL, dt, G, CS, visc_rem, & visc_rem_max, j, ish, ieh, do_I) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity, in m s-1. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Zonal velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_in !< Layer thickness used to - !! calculate fluxes, in H. + !! calculate fluxes [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the - !! reconstruction, in H. + !! reconstruction [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the - !! reconstruction, in H. + !! reconstruction [H ~> m or kg m-2]. type(BT_cont_type), intent(inout) :: BT_cont !< A structure with elements !! that describe the effective open face areas as a function of barotropic flow. real, dimension(SZIB_(G)), intent(in) :: uh_tot_0 !< The summed transport - !! with 0 adjustment, in H m2 s-1. + !! with 0 adjustment [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G)), intent(in) :: duhdu_tot_0 !< The partial derivative - !! of du_err with du at 0 adjustment, in H m. + !! of du_err with du at 0 adjustment [H m ~> m2 or kg m-1]. real, dimension(SZIB_(G)), intent(in) :: du_max_CFL !< Maximum acceptable - !! value of du, in m s-1. + !! value of du [m s-1]. real, dimension(SZIB_(G)), intent(in) :: du_min_CFL !< Minimum acceptable - !! value of du, in m s-1. - real, intent(in) :: dt !< Time increment in s. + !! value of du [m s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. real, dimension(SZIB_(G),SZK_(G)), intent(in) :: visc_rem !< Both the fraction of the !! momentum originally in a layer that remains after a time-step of viscosity, and @@ -912,26 +918,26 @@ subroutine set_zonal_BT_cont(u, h_in, h_L, h_R, BT_cont, uh_tot_0, duhdu_tot_0, !! which I values to work on. ! Local variables real, dimension(SZIB_(G)) :: & - du0, & ! The barotropic velocity increment that gives 0 transport, m s-1. + du0, & ! The barotropic velocity increment that gives 0 transport [m s-1]. duL, duR, & ! The barotropic velocity increments that give the westerly ! (duL) and easterly (duR) test velocities. zeros, & ! An array of full of 0's. - du_CFL, & ! The velocity increment that corresponds to CFL_min, in m s-1. + du_CFL, & ! The velocity increment that corresponds to CFL_min [m s-1]. u_L, u_R, & ! The westerly (u_L), easterly (u_R), and zero-barotropic - u_0, & ! transport (u_0) layer test velocities, in m s-1. + u_0, & ! transport (u_0) layer test velocities [m s-1]. FA_marg_L, & ! The effective layer marginal face areas with the westerly FA_marg_R, & ! (_L), easterly (_R), and zero-barotropic (_0) test - FA_marg_0, & ! velocities, in H m. + FA_marg_0, & ! velocities [H m ~> m2 or kg m-1]. uh_L, uh_R, & ! The layer transports with the westerly (_L), easterly (_R), - uh_0, & ! and zero-barotropic (_0) test velocities, in H m2 s-1. + uh_0, & ! and zero-barotropic (_0) test velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. FAmt_L, FAmt_R, & ! The summed effective marginal face areas for the 3 - FAmt_0, & ! test velocities, in H m. + FAmt_0, & ! test velocities [H m ~> m2 or kg m-1]. uhtot_L, & ! The summed transport with the westerly (uhtot_L) and - uhtot_R ! and easterly (uhtot_R) test velocities, in H m2 s-1. - real :: FA_0 ! The effective face area with 0 barotropic transport, in m H. - real :: FA_avg ! The average effective face area, in m H, nominally given by + uhtot_R ! and easterly (uhtot_R) test velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: FA_0 ! The effective face area with 0 barotropic transport [m H ~> m2 or kg m]. + real :: FA_avg ! The average effective face area [m H ~> m2 or kg m], nominally given by ! the realized transport divided by the barotropic velocity. - real :: visc_rem_lim ! The larger of visc_rem and min_visc_rem, ND. This + real :: visc_rem_lim ! The larger of visc_rem and min_visc_rem [nondim] This ! limiting is necessary to keep the inverse of visc_rem ! from leading to large CFL numbers. real :: min_visc_rem ! The smallest permitted value for visc_rem that is used @@ -939,8 +945,8 @@ subroutine set_zonal_BT_cont(u, h_in, h_L, h_R, BT_cont, uh_tot_0, duhdu_tot_0, ! flow direction. This is necessary to keep the inverse ! of visc_rem from leading to large CFL numbers. real :: CFL_min ! A minimal increment in the CFL to try to ensure that the - ! flow is truly upwind, ND. - real :: Idt ! The inverse of the time step, in s-1. + ! flow is truly upwind [nondim] + real :: Idt ! The inverse of the time step [s-1]. logical :: domore integer :: i, k, nz @@ -1045,12 +1051,12 @@ subroutine meridional_mass_flux(v, h_in, vh, dt, G, GV, CS, LB, vhbt, OBC, & visc_rem_v, v_cor, vhbt_aux, v_cor_aux, BT_cont) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< Ocean's vertical grid structure. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity, in m s-1. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_in !< Layer thickness used to - !! calculate fluxes, in H. + !! calculate fluxes [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: vh !< Volume flux through meridional - !! faces = v*h*dx, H m2 s-1. - real, intent(in) :: dt !< Time increment in s. + !! faces = v*h*dx [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. type(loop_bounds_type), intent(in) :: LB !< Loop bounds structure. type(ocean_OBC_type), optional, pointer :: OBC !< Open boundary condition type @@ -1062,42 +1068,42 @@ subroutine meridional_mass_flux(v, h_in, vh, dt, G, GV, CS, LB, vhbt, OBC, & !! that a layer experiences after viscosity is applied. Nondimensional between !! 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZI_(G),SZJB_(G)), optional, intent(in) :: vhbt !< The summed volume flux through - !< meridional faces, H m2 s-1. + !< meridional faces [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G)), optional, intent(in) :: vhbt_aux !< A second set of summed volume fluxes - !! through meridional faces, in H m2 s-1. + !! through meridional faces [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(out) :: v_cor !< The meridional velocitiess (v with a barotropic correction) - !! that give vhbt as the depth-integrated transport, m s-1. + !! that give vhbt as the depth-integrated transport [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(out) :: v_cor_aux !< The meridional velocities (v with a barotropic correction) - !! that give vhbt_aux as the depth-integrated transports, in m s-1. + !! that give vhbt_aux as the depth-integrated transports [m s-1]. type(BT_cont_type), optional, pointer :: BT_cont !< A structure with elements that describe !! the effective open face areas as a function of barotropic flow. ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & - dvhdv ! Partial derivative of vh with v, in m2. + dvhdv ! Partial derivative of vh with v [H m ~> m2 or kg m-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - h_L, h_R ! Left and right face thicknesses, in m. + h_L, h_R ! Left and right face thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G)) :: & - dv, & ! Corrective barotropic change in the velocity, in m s-1. + dv, & ! Corrective barotropic change in the velocity [m s-1]. dv_min_CFL, & ! Min/max limits on dv correction dv_max_CFL, & ! to avoid CFL violations - dvhdv_tot_0, & ! Summed partial derivative of vh with v, in H m. - vh_tot_0, & ! Summed transport with no barotropic correction in H m2 s-1. + dvhdv_tot_0, & ! Summed partial derivative of vh with v [H m ~> m2 or kg m-1]. + vh_tot_0, & ! Summed transport with no barotropic correction [H m2 s-1 ~> m3 s-1 or kg s-1]. visc_rem_max ! The column maximum of visc_rem. logical, dimension(SZI_(G)) :: do_I - real, dimension(SZI_(G)) :: FAvi ! A list of sums of meridional face areas, in H m. - real :: FA_v ! A sum of meridional face areas, in H m. + real, dimension(SZI_(G)) :: FAvi ! A list of sums of meridional face areas [H m ~> m2 or kg m-1]. + real :: FA_v ! A sum of meridional face areas [H m ~> m2 or kg m-1]. real, dimension(SZI_(G),SZK_(G)) :: & visc_rem ! A 2-D copy of visc_rem_v or an array of 1's. real :: I_vrm ! 1.0 / visc_rem_max, nondim. real :: CFL_dt ! The maximum CFL ratio of the adjusted velocities divided by - ! the time step, in s-1. - real :: I_dt ! 1.0 / dt, in s-1. - real :: dv_lim ! The velocity change that give a relative CFL of 1, in m s-1. - real :: dy_N, dy_S ! Effective y-grid spacings to the north and south, in m. + ! the time step [s-1]. + real :: I_dt ! 1.0 / dt [s-1]. + real :: dv_lim ! The velocity change that give a relative CFL of 1 [m s-1]. + real :: dy_N, dy_S ! Effective y-grid spacings to the north and south [m]. integer :: i, j, k, ish, ieh, jsh, jeh, n, nz logical :: do_aux, local_specified_BC, use_visc_rem, set_BT_cont, any_simple_OBC logical :: local_Flather_OBC, is_simple, local_open_BC @@ -1351,18 +1357,23 @@ end subroutine meridional_mass_flux subroutine merid_flux_layer(v, h, h_L, h_R, vh, dvhdv, visc_rem, dt, G, J, & ish, ieh, do_I, vol_CFL, OBC) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZI_(G)), intent(in) :: v !< Meridional velocity, in m s-1. + real, dimension(SZI_(G)), intent(in) :: v !< Meridional velocity [m s-1]. real, dimension(SZI_(G)), intent(in) :: visc_rem !< Both the fraction of the !! momentum originally in a layer that remains after a time-step !! of viscosity, and the fraction of a time-step's worth of a barotropic !! acceleration that a layer experiences after viscosity is applied. !! Non-dimensional between 0 (at the bottom) and 1 (far above the bottom). - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h !< Layer thickness used to calculate fluxes, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_R !< Right thickness in the reconstruction, in H. - real, dimension(SZI_(G)), intent(inout) :: vh !< Meridional mass or volume transport, in H m2 s-1. - real, dimension(SZI_(G)), intent(inout) :: dvhdv !< Partial derivative of vh with v, in H m. - real, intent(in) :: dt !< Time increment in s. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h !< Layer thickness used to calculate fluxes, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_L !< Left thickness in the reconstruction + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_R !< Right thickness in the reconstruction + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G)), intent(inout) :: vh !< Meridional mass or volume transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, dimension(SZI_(G)), intent(inout) :: dvhdv !< Partial derivative of vh with v + !! [H m ~> m2 or kg m-1]. + real, intent(in) :: dt !< Time increment [s]. integer, intent(in) :: j !< Spatial index. integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. @@ -1371,10 +1382,10 @@ subroutine merid_flux_layer(v, h, h_L, h_R, vh, dvhdv, visc_rem, dt, G, J, & !! ratio of face areas to the cell areas when estimating the CFL number. type(ocean_OBC_type), optional, pointer :: OBC !< Open boundaries control structure. ! Local variables - real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. + real :: CFL ! The CFL number based on the local velocity and grid spacing [nondim] real :: curv_3 ! A measure of the thickness curvature over a grid length, - ! with the same units as h_in. - real :: h_marg ! The marginal thickness of a flux, in m. + ! with the same units as h, i.e. [H ~> m or kg m-2]. + real :: h_marg ! The marginal thickness of a flux [H ~> m or kg m-2]. integer :: i logical :: local_open_BC @@ -1426,12 +1437,16 @@ end subroutine merid_flux_layer subroutine merid_face_thickness(v, h, h_L, h_R, h_v, dt, G, LB, vol_CFL, & marginal, visc_rem_v, OBC) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity, in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness used to calculate fluxes, in H. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: h_v !< Thickness at meridional faces, in H. - real, intent(in) :: dt !< Time increment in s. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness used to calculate fluxes, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the reconstruction, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the reconstruction, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: h_v !< Thickness at meridional faces, + !! [H ~> m or kg m-2]. + real, intent(in) :: dt !< Time increment [s]. type(loop_bounds_type), intent(in) :: LB !< Loop bounds structure. logical, intent(in) :: vol_CFL !< If true, rescale the ratio !! of face areas to the cell areas when estimating the CFL number. @@ -1445,11 +1460,11 @@ subroutine merid_face_thickness(v, h, h_L, h_R, h_v, dt, G, LB, vol_CFL, & type(ocean_OBC_type), optional, pointer :: OBC !< Open boundaries control structure. ! Local variables - real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. + real :: CFL ! The CFL number based on the local velocity and grid spacing [nondim] real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. - real :: h_avg ! The average thickness of a flux, in H. - real :: h_marg ! The marginal thickness of a flux, in H. + real :: h_avg ! The average thickness of a flux [H ~> m or kg m-2]. + real :: h_marg ! The marginal thickness of a flux [H ~> m or kg m-2]. logical :: local_open_BC integer :: i, j, k, ish, ieh, jsh, jeh, n, nz ish = LB%ish ; ieh = LB%ieh ; jsh = LB%jsh ; jeh = LB%jeh ; nz = G%ke @@ -1531,56 +1546,57 @@ subroutine meridional_flux_adjust(v, h_in, h_L, h_R, vhbt, vh_tot_0, dvhdv_tot_0 j, ish, ieh, do_I_in, full_precision, vh_3d, OBC) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< Meridional velocity, in m s-1. + intent(in) :: v !< Meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_in !< Layer thickness used to calculate fluxes, in H. + intent(in) :: h_in !< Layer thickness used to calculate fluxes [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)),& - intent(in) :: h_L !< Left thickness in the reconstruction, in H. + intent(in) :: h_L !< Left thickness in the reconstruction [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_R !< Right thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZK_(G)), & - intent(in) :: visc_rem + intent(in) :: h_R !< Right thickness in the reconstruction [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZK_(G)), intent(in) :: visc_rem !< Both the fraction of the momentum originally !! in a layer that remains after a time-step of viscosity, and the !! fraction of a time-step's worth of a barotropic acceleration that !! a layer experiences after viscosity is applied. Non-dimensional !! between 0 (at the bottom) and 1 (far above the bottom). real, dimension(SZI_(G)), & - optional, intent(in) :: vhbt !< The summed volume flux through meridional faces, H m2 s-1. - real, dimension(SZI_(G)), intent(in) :: dv_max_CFL !< Maximum acceptable value of dv, in m s-1. - real, dimension(SZI_(G)), intent(in) :: dv_min_CFL !< Minimum acceptable value of dv, in m s-1. - real, dimension(SZI_(G)), intent(in) :: vh_tot_0 !< The summed transport with 0 adjustment, in H m2 s-1. + optional, intent(in) :: vhbt !< The summed volume flux through meridional faces + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, dimension(SZI_(G)), intent(in) :: dv_max_CFL !< Maximum acceptable value of dv [m s-1]. + real, dimension(SZI_(G)), intent(in) :: dv_min_CFL !< Minimum acceptable value of dv [m s-1]. + real, dimension(SZI_(G)), intent(in) :: vh_tot_0 !< The summed transport with 0 adjustment + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G)), intent(in) :: dvhdv_tot_0 !< The partial derivative of dv_err with - !! dv at 0 adjustment, in H m. - real, dimension(SZI_(G)), intent(out) :: dv !< The barotropic velocity adjustment, in m s-1. - real, intent(in) :: dt !< Time increment in s. + !! dv at 0 adjustment [H m ~> m2 or kg m-1]. + real, dimension(SZI_(G)), intent(out) :: dv !< The barotropic velocity adjustment [m s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. integer, intent(in) :: j !< Spatial index. integer, intent(in) :: ish !< Start of index range. integer, intent(in) :: ieh !< End of index range. logical, dimension(SZI_(G)), & intent(in) :: do_I_in !< A flag indicating which I values to work on. - logical, optional, intent(in) :: full_precision !< A flag indicating - !! how carefully to iterate. The default is .true. (more accurate). + logical, optional, intent(in) :: full_precision !< A flag indicating how carefully to + !! iterate. The default is .true. (more accurate). real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - optional, intent(inout) :: vh_3d !< Volume flux through - !! meridional faces = v*h*dx, H m2 s-1. + optional, intent(inout) :: vh_3d !< Volume flux through meridional + !! faces = v*h*dx [H m2 s-1 ~> m3 s-1 or kg s-1]. type(ocean_OBC_type), optional, pointer :: OBC !< Open boundaries control structure. ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & - vh_aux, & ! An auxiliary meridional volume flux, in H m s-1. - dvhdv ! Partial derivative of vh with v, in H m. + vh_aux, & ! An auxiliary meridional volume flux [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + dvhdv ! Partial derivative of vh with v [H m ~> m2 or kg m-1]. real, dimension(SZI_(G)) :: & - vh_err, & ! Difference between vhbt and the summed vh, in H m2 s-1. - vh_err_best, & ! The smallest value of vh_err found so far, in H m2 s-1. - v_new, & ! The velocity with the correction added, in m s-1. - dvhdv_tot,&! Summed partial derivative of vh with u, in H m. + vh_err, & ! Difference between vhbt and the summed vh [H m2 s-1 ~> m3 s-1 or kg s-1]. + vh_err_best, & ! The smallest value of vh_err found so far [H m2 s-1 ~> m3 s-1 or kg s-1]. + v_new, & ! The velocity with the correction added [m s-1]. + dvhdv_tot,&! Summed partial derivative of vh with u [H m ~> m2 or kg m-1]. dv_min, & ! Min/max limits on dv correction based on CFL limits - dv_max ! and previous iterations, in m s-1. - real :: dv_prev ! The previous value of dv, in m s-1. - real :: ddv ! The change in dv from the previous iteration, in m s-1. - real :: tol_eta ! The tolerance for the current iteration, in m. - real :: tol_vel ! The tolerance for velocity in the current iteration, m s-1. + dv_max ! and previous iterations [m s-1]. + real :: dv_prev ! The previous value of dv [m s-1]. + real :: ddv ! The change in dv from the previous iteration [m s-1]. + real :: tol_eta ! The tolerance for the current iteration [H ~> m or kg m-2]. + real :: tol_vel ! The tolerance for velocity in the current iteration [m s-1]. integer :: i, k, nz, itt, max_itts = 20 logical :: full_prec, domore, do_I(SZI_(G)) @@ -1691,19 +1707,22 @@ subroutine set_merid_BT_cont(v, h_in, h_L, h_R, BT_cont, vh_tot_0, dvhdv_tot_0, dv_max_CFL, dv_min_CFL, dt, G, CS, visc_rem, & visc_rem_max, j, ish, ieh, do_I) type(ocean_grid_type), intent(inout) :: G !< Ocean's grid structure. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity, in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_in !< Layer thickness used to calculate fluxes, in H. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the reconstruction, in H. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Meridional velocity [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_in !< Layer thickness used to calculate fluxes, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_L !< Left thickness in the reconstruction, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h_R !< Right thickness in the reconstruction, + !! [H ~> m or kg m-2]. type(BT_cont_type), intent(inout) :: BT_cont !< A structure with elements !! that describe the effective open face areas as a function of barotropic flow. real, dimension(SZI_(G)), intent(in) :: vh_tot_0 !< The summed transport - !! with 0 adjustment, in H m2 s-1. + !! with 0 adjustment [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G)), intent(in) :: dvhdv_tot_0 !< The partial derivative - !! of du_err with dv at 0 adjustment, in H m. - real, dimension(SZI_(G)), intent(in) :: dv_max_CFL !< Maximum acceptable value of dv, in m s-1. - real, dimension(SZI_(G)), intent(in) :: dv_min_CFL !< Minimum acceptable value of dv, in m s-1. - real, intent(in) :: dt !< Time increment in s. + !! of du_err with dv at 0 adjustment [H m ~> m2 or kg m-1]. + real, dimension(SZI_(G)), intent(in) :: dv_max_CFL !< Maximum acceptable value of dv [m s-1]. + real, dimension(SZI_(G)), intent(in) :: dv_min_CFL !< Minimum acceptable value of dv [m s-1]. + real, intent(in) :: dt !< Time increment [s]. type(continuity_PPM_CS), pointer :: CS !< This module's control structure. real, dimension(SZI_(G),SZK_(G)), intent(in) :: visc_rem !< Both the fraction of the !! momentum originally in a layer that remains after a time-step @@ -1718,26 +1737,26 @@ subroutine set_merid_BT_cont(v, h_in, h_L, h_R, BT_cont, vh_tot_0, dvhdv_tot_0, !! which I values to work on. ! Local variables real, dimension(SZI_(G)) :: & - dv0, & ! The barotropic velocity increment that gives 0 transport, m s-1. + dv0, & ! The barotropic velocity increment that gives 0 transport [m s-1]. dvL, dvR, & ! The barotropic velocity increments that give the southerly ! (dvL) and northerly (dvR) test velocities. zeros, & ! An array of full of 0's. - dv_CFL, & ! The velocity increment that corresponds to CFL_min, in m s-1. + dv_CFL, & ! The velocity increment that corresponds to CFL_min [m s-1]. v_L, v_R, & ! The southerly (v_L), northerly (v_R), and zero-barotropic - v_0, & ! transport (v_0) layer test velocities, in m s-1. + v_0, & ! transport (v_0) layer test velocities [m s-1]. FA_marg_L, & ! The effective layer marginal face areas with the southerly FA_marg_R, & ! (_L), northerly (_R), and zero-barotropic (_0) test - FA_marg_0, & ! velocities, in H m. + FA_marg_0, & ! velocities [H m ~> m2 or kg m-1]. vh_L, vh_R, & ! The layer transports with the southerly (_L), northerly (_R) - vh_0, & ! and zero-barotropic (_0) test velocities, in H m2 s-1. + vh_0, & ! and zero-barotropic (_0) test velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. FAmt_L, FAmt_R, & ! The summed effective marginal face areas for the 3 - FAmt_0, & ! test velocities, in H m. + FAmt_0, & ! test velocities [H m ~> m2 or kg m-1]. vhtot_L, & ! The summed transport with the southerly (vhtot_L) and - vhtot_R ! and northerly (vhtot_R) test velocities, in H m2 s-1. - real :: FA_0 ! The effective face area with 0 barotropic transport, in m H. - real :: FA_avg ! The average effective face area, in m H, nominally given by + vhtot_R ! and northerly (vhtot_R) test velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: FA_0 ! The effective face area with 0 barotropic transport [H m ~> m2 or kg m-1]. + real :: FA_avg ! The average effective face area [H m ~> m2 or kg m-1], nominally given by ! the realized transport divided by the barotropic velocity. - real :: visc_rem_lim ! The larger of visc_rem and min_visc_rem, ND. This + real :: visc_rem_lim ! The larger of visc_rem and min_visc_rem [nondim] This ! limiting is necessary to keep the inverse of visc_rem ! from leading to large CFL numbers. real :: min_visc_rem ! The smallest permitted value for visc_rem that is used @@ -1745,8 +1764,8 @@ subroutine set_merid_BT_cont(v, h_in, h_L, h_R, BT_cont, vh_tot_0, dvhdv_tot_0, ! flow direction. This is necessary to keep the inverse ! of visc_rem from leading to large CFL numbers. real :: CFL_min ! A minimal increment in the CFL to try to ensure that the - ! flow is truly upwind, ND. - real :: Idt ! The inverse of the time step, in s-1. + ! flow is truly upwind [nondim] + real :: Idt ! The inverse of the time step [s-1]. logical :: domore integer :: i, k, nz @@ -1847,9 +1866,11 @@ end subroutine set_merid_BT_cont !> Calculates left/right edge values for PPM reconstruction. subroutine PPM_reconstruction_x(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_2nd, OBC) type(ocean_grid_type), intent(in) :: G !< Ocean's grid structure. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_R !< Right thickness in the reconstruction, in H. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_L !< Left thickness in the reconstruction, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_R !< Right thickness in the reconstruction, + !! [H ~> m or kg m-2]. type(loop_bounds_type), intent(in) :: LB !< Active loop bounds structure. real, intent(in) :: h_min !< The minimum thickness !! that can be obtained by a concave parabolic fit. @@ -1984,9 +2005,11 @@ end subroutine PPM_reconstruction_x !> Calculates left/right edge values for PPM reconstruction. subroutine PPM_reconstruction_y(h_in, h_L, h_R, G, LB, h_min, monotonic, simple_2nd, OBC) type(ocean_grid_type), intent(in) :: G !< Ocean's grid structure. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_R !< Right thickness in the reconstruction, in H. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_L !< Left thickness in the reconstruction, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: h_R !< Right thickness in the reconstruction, + !! [H ~> m or kg m-2]. type(loop_bounds_type), intent(in) :: LB !< Active loop bounds structure. real, intent(in) :: h_min !< The minimum thickness !! that can be obtained by a concave parabolic fit. @@ -2122,9 +2145,9 @@ end subroutine PPM_reconstruction_y !! than h_min, with a minimum of h_min otherwise. subroutine PPM_limit_pos(h_in, h_L, h_R, h_min, G, iis, iie, jis, jie) type(ocean_grid_type), intent(in) :: G !< Ocean's grid structure. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_R !< Right thickness in the reconstruction, in H. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_L !< Left thickness in the reconstruction [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_R !< Right thickness in the reconstruction [H ~> m or kg m-2]. real, intent(in) :: h_min !< The minimum thickness !! that can be obtained by a concave parabolic fit. integer, intent(in) :: iis !< Start of i index range. @@ -2163,9 +2186,11 @@ end subroutine PPM_limit_pos !! according to the monotonic prescription of Colella and Woodward, 1984. subroutine PPM_limit_CW84(h_in, h_L, h_R, G, iis, iie, jis, jie) type(ocean_grid_type), intent(in) :: G !< Ocean's grid structure. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_L !< Left thickness in the reconstruction, in H. - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_R !< Right thickness in the reconstruction, in H. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h_in !< Layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_L !< Left thickness in the reconstruction, + !! [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: h_R !< Right thickness in the reconstruction, + !! [H ~> m or kg m-2]. integer, intent(in) :: iis !< Start of i index range. integer, intent(in) :: iie !< End of i index range. integer, intent(in) :: jis !< Start of j index range. @@ -2211,7 +2236,7 @@ end function ratio_max !> Initializes continuity_ppm_cs subroutine continuity_PPM_init(Time, G, GV, param_file, diag, CS) - type(time_type), target, intent(in) :: Time !< Time increment in s. + type(time_type), target, intent(in) :: Time !< Time increment [s]. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. type(param_file_type), intent(in) :: param_file !< A structure indicating @@ -2221,7 +2246,7 @@ subroutine continuity_PPM_init(Time, G, GV, param_file, diag, CS) type(continuity_PPM_CS), pointer :: CS !< Module's control structure. !> This include declares and sets the variable "version". #include "version_variable.h" - real :: tol_eta_m ! An unscaled version of tol_eta, in m. + real :: tol_eta_m ! An unscaled version of tol_eta [m]. character(len=40) :: mdl = "MOM_continuity_PPM" ! This module's name. if (associated(CS)) then diff --git a/src/core/MOM_dynamics_split_RK2.F90 b/src/core/MOM_dynamics_split_RK2.F90 index c6cf3ab0e7..2a4eeaf21a 100644 --- a/src/core/MOM_dynamics_split_RK2.F90 +++ b/src/core/MOM_dynamics_split_RK2.F90 @@ -68,14 +68,14 @@ module MOM_dynamics_split_RK2 !> MOM_dynamics_split_RK2 module control structure type, public :: MOM_dyn_split_RK2_CS ; private real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: & - CAu, & !< CAu = f*v - u.grad(u) in m s-2. - PFu, & !< PFu = -dM/dx, in m s-2. - diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor, in m s-2. + CAu, & !< CAu = f*v - u.grad(u) [m s-2] + PFu, & !< PFu = -dM/dx [m s-2] + diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor [m s-2] real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: & - CAv, & !< CAv = -f*u - u.grad(v) in m s-2. - PFv, & !< PFv = -dM/dy, in m s-2. - diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor, in m s-2. + CAv, & !< CAv = -f*u - u.grad(v) [m s-2] + PFv, & !< PFv = -dM/dy [m s-2] + diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor [m s-2] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: visc_rem_u !< Both the fraction of the zonal momentum originally in a @@ -86,7 +86,7 @@ module MOM_dynamics_split_RK2 real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: u_accel_bt !< The zonal layer accelerations due to the difference between !! the barotropic accelerations and the baroclinic accelerations - !! that were fed into the barotopic calculation, in m s-2. + !! that were fed into the barotopic calculation [m s-2] real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: visc_rem_v !< Both the fraction of the meridional momentum originally in !! a layer that remains after a time-step of viscosity, and the @@ -96,34 +96,34 @@ module MOM_dynamics_split_RK2 real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: v_accel_bt !< The meridional layer accelerations due to the difference between !! the barotropic accelerations and the baroclinic accelerations - !! that were fed into the barotopic calculation, in m s-2. + !! that were fed into the barotopic calculation [m s-2] ! The following variables are only used with the split time stepping scheme. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: eta !< Instantaneous free surface height (in Boussinesq !! mode) or column mass anomaly (in non-Boussinesq - !! mode), in units of H (m or kg m-2) + !! mode) [H ~> m or kg m-2] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: u_av !< layer x-velocity with vertical mean replaced by !! time-mean barotropic velocity over a baroclinic - !! timestep (m s-1) + !! timestep [m s-1] real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: v_av !< layer y-velocity with vertical mean replaced by !! time-mean barotropic velocity over a baroclinic - !! timestep (m s-1) + !! timestep [m s-1] real ALLOCABLE_, dimension(NIMEM_,NJMEM_,NKMEM_) :: h_av !< arithmetic mean of two successive layer - !! thicknesses (m or kg m-2) + !! thicknesses [H ~> m or kg m-2] real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: eta_PF !< instantaneous SSH used in calculating PFu and - !! PFv (meter) + !! PFv [H ~> m or kg m-2] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: uhbt !< average x-volume or mass flux determined by the - !! barotropic solver (m3 s-1 or kg s-1). uhbt should - !! be (roughly?) equal to vertical sum of uh. + !! barotropic solver [H m2 s-1 ~> m3 s-1 or kg s-1]. + !! uhbt is roughly equal to the vertical sum of uh. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: vhbt !< average y-volume or mass flux determined by the - !! barotropic solver (m3 s-1 or kg s-1). vhbt should - !! be (roughly?) equal to vertical sum of vh. + !! barotropic solver [H m2 s-1 ~> m3 s-1 or kg s-1]. + !! vhbt is roughly equal to vertical sum of vh. real ALLOCABLE_, dimension(NIMEM_,NJMEM_,NKMEM_) :: pbce !< pbce times eta gives the baroclinic pressure !! anomaly in each layer due to free surface height - !! anomalies. pbce has units of m2 H-1 s-2. + !! anomalies [m2 H-1 s-2 ~> m s-2 or m4 kg-1 s-2]. - real, pointer, dimension(:,:) :: taux_bot => NULL() !< frictional x-bottom stress from the ocean to the seafloor (Pa) - real, pointer, dimension(:,:) :: tauy_bot => NULL() !< frictional y-bottom stress from the ocean to the seafloor (Pa) + real, pointer, dimension(:,:) :: taux_bot => NULL() !< frictional x-bottom stress from the ocean to the seafloor [Pa] + real, pointer, dimension(:,:) :: tauy_bot => NULL() !< frictional y-bottom stress from the ocean to the seafloor [Pa] type(BT_cont_type), pointer :: BT_cont => NULL() !< A structure with elements that describe the !! effective summed open face areas as a function !! of barotropic flow. @@ -235,32 +235,34 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, & type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - target, intent(inout) :: u !< zonal velocity (m/s) + target, intent(inout) :: u !< zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - target, intent(inout) :: v !< merid velocity (m/s) + target, intent(inout) :: v !< merid velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< layer thickness (m or kg/m2) + intent(inout) :: h !< layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< thermodynamic type type(vertvisc_type), intent(inout) :: visc !< vertical visc, bottom drag, and related type(time_type), intent(in) :: Time_local !< model time at end of time step - real, intent(in) :: dt !< time step (sec) + real, intent(in) :: dt !< time step [s] type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces real, dimension(:,:), pointer :: p_surf_begin !< surf pressure at start of this dynamic - !! time step (Pa) + !! time step [Pa] real, dimension(:,:), pointer :: p_surf_end !< surf pressure at end of this dynamic - !! time step (Pa) + !! time step [Pa] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - target, intent(inout) :: uh !< zonal volume/mass transport (m3/s or kg/s) + target, intent(inout) :: uh !< zonal volume/mass transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - target, intent(inout) :: vh !< merid volume/mass transport (m3/s or kg/s) + target, intent(inout) :: vh !< merid volume/mass transport + !! [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & intent(inout) :: uhtr !< accumulatated zonal volume/mass transport - !! since last tracer advection (m3 or kg) + !! since last tracer advection [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(inout) :: vhtr !< accumulatated merid volume/mass transport - !! since last tracer advection (m3 or kg) + !! since last tracer advection [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta_av !< free surface height or column mass time - !! averaged over time step (m or kg/m2) + !! averaged over time step [H ~> m or kg m-2] type(MOM_dyn_split_RK2_CS), pointer :: CS !< module control structure logical, intent(in) :: calc_dtbt !< if true, recalculate barotropic time step type(VarMix_CS), pointer :: VarMix !< specify the spatially varying viscosities @@ -269,39 +271,39 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, & !! fields related to the surface wave conditions real :: dt_pred ! The time step for the predictor part of the baroclinic time stepping. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: up ! Predicted zonal velocity in m s-1. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vp ! Predicted meridional velocity in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: hp ! Predicted thickness in m or kg m-2 (H). + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: up ! Predicted zonal velocity [m s-1]. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vp ! Predicted meridional velocity [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: hp ! Predicted thickness [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_bc_accel real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_bc_accel ! u_bc_accel and v_bc_accel are the summed baroclinic accelerations of each - ! layer calculated by the non-barotropic part of the model, both in m s-2. + ! layer calculated by the non-barotropic part of the model [m s-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target :: uh_in real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target :: vh_in ! uh_in and vh_in are the zonal or meridional mass transports that would be - ! obtained using the initial velocities, both in m3 s-1 or kg s-1. + ! obtained using the initial velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G)) :: uhbt_out real, dimension(SZI_(G),SZJB_(G)) :: vhbt_out ! uhbt_out and vhbt_out are the vertically summed transports from the - ! barotropic solver based on its final velocities, both in m3 s-1 or kg s-1. + ! barotropic solver based on its final velocities [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJ_(G)) :: eta_pred ! eta_pred is the predictor value of the free surface height or column mass, - ! in m or kg m-2. + ! [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target :: u_adj real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target :: v_adj ! u_adj and v_adj are the zonal or meridional velocities after u and v ! have been barotropically adjusted so the resulting transports match - ! uhbt_out and vhbt_out, both in m s-1. + ! uhbt_out and vhbt_out [m s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_old_rad_OBC real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_old_rad_OBC ! u_old_rad_OBC and v_old_rad_OBC are the starting velocities, which are - ! saved for use in the Flather open boundary condition code, both in m s-1. + ! saved for use in the Flather open boundary condition code [m s-1]. real :: Pa_to_eta ! A factor that converts pressures to the units of eta. real, pointer, dimension(:,:) :: & @@ -312,10 +314,9 @@ subroutine step_MOM_dyn_split_RK2(u, v, h, tv, visc, & real, pointer, dimension(:,:,:) :: & uh_ptr => NULL(), u_ptr => NULL(), vh_ptr => NULL(), v_ptr => NULL(), & u_init => NULL(), v_init => NULL(), & ! Pointers to u and v or u_adj and v_adj. - u_av, & ! The zonal velocity time-averaged over a time step, in m s-1. - v_av, & ! The meridional velocity time-averaged over a time step, in m s-1. - h_av ! The layer thickness time-averaged over a time step, in m or - ! kg m-2. + u_av, & ! The zonal velocity time-averaged over a time step [m s-1]. + v_av, & ! The meridional velocity time-averaged over a time step [m s-1]. + h_av ! The layer thickness time-averaged over a time step [H ~> m or kg m-2]. real :: Idt logical :: dyn_p_surf logical :: BT_cont_BT_thick ! If true, use the BT_cont_type to estimate the @@ -880,9 +881,9 @@ subroutine register_restarts_dyn_split_RK2(HI, GV, param_file, CS, restart_CS, u type(MOM_dyn_split_RK2_CS), pointer :: CS !< module control structure type(MOM_restart_CS), pointer :: restart_CS !< restart control structure real, dimension(SZIB_(HI),SZJ_(HI),SZK_(GV)), & - target, intent(inout) :: uh !< zonal volume/mass transport (m3/s or kg/s) + target, intent(inout) :: uh !< zonal volume/mass transport [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(HI),SZJB_(HI),SZK_(GV)), & - target, intent(inout) :: vh !< merid volume/mass transport (m3/s or kg/s) + target, intent(inout) :: vh !< merid volume/mass transport [H m2 s-1 ~> m3 s-1 or kg s-1] type(vardesc) :: vd character(len=40) :: mdl = "MOM_dynamics_split_RK2" ! This module's name. @@ -958,21 +959,21 @@ subroutine initialize_dyn_split_RK2(u, v, h, uh, vh, eta, Time, G, GV, US, param type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: u !< zonal velocity (m/s) + intent(inout) :: u !< zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: v !< merid velocity (m/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , intent(inout) :: h !< layer thickness (m or kg/m2) + intent(inout) :: v !< merid velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , intent(inout) :: h !< layer thickness [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - target, intent(inout) :: uh !< zonal volume/mass transport (m3 s-1 or kg s-1) + target, intent(inout) :: uh !< zonal volume/mass transport [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - target, intent(inout) :: vh !< merid volume/mass transport (m3 s-1 or kg s-1) - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: eta !< free surface height or column mass (m or kg m-2) + target, intent(inout) :: vh !< merid volume/mass transport [H m2 s-1 ~> m3 s-1 or kg s-1] + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: eta !< free surface height or column mass [H ~> m or kg m-2] type(time_type), target, intent(in) :: Time !< current model time type(param_file_type), intent(in) :: param_file !< parameter file for parsing type(diag_ctrl), target, intent(inout) :: diag !< to control diagnostics type(MOM_dyn_split_RK2_CS), pointer :: CS !< module control structure type(MOM_restart_CS), pointer :: restart_CS !< restart control structure - real, intent(in) :: dt !< time step (sec) + real, intent(in) :: dt !< time step [s] type(accel_diag_ptrs), target, intent(inout) :: Accel_diag !< points to momentum equation terms for !! budget analysis type(cont_diag_ptrs), target, intent(inout) :: Cont_diag !< points to terms in continuity equation diff --git a/src/core/MOM_dynamics_unsplit.F90 b/src/core/MOM_dynamics_unsplit.F90 index fa62036846..887a6c4f54 100644 --- a/src/core/MOM_dynamics_unsplit.F90 +++ b/src/core/MOM_dynamics_unsplit.F90 @@ -106,14 +106,14 @@ module MOM_dynamics_unsplit !> MOM_dynamics_unsplit module control structure type, public :: MOM_dyn_unsplit_CS ; private real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: & - CAu, & !< CAu = f*v - u.grad(u) in m s-2. - PFu, & !< PFu = -dM/dx, in m s-2. - diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor, in m s-2. + CAu, & !< CAu = f*v - u.grad(u) [m s-2]. + PFu, & !< PFu = -dM/dx [m s-2]. + diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor [m s-2]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: & - CAv, & !< CAv = -f*u - u.grad(v) in m s-2. - PFv, & !< PFv = -dM/dy, in m s-2. - diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor, in m s-2. + CAv, & !< CAv = -f*u - u.grad(v) [m s-2]. + PFv, & !< PFv = -dM/dy [m s-2]. + diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor [m s-2]. real, pointer, dimension(:,:) :: taux_bot => NULL() !< frictional x-bottom stress from the ocean to the seafloor (Pa) real, pointer, dimension(:,:) :: tauy_bot => NULL() !< frictional y-bottom stress from the ocean to the seafloor (Pa) @@ -186,32 +186,31 @@ subroutine step_MOM_dyn_unsplit(u, v, h, tv, visc, Time_local, dt, forces, & type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< The zonal velocity, in m s-1. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< The meridional velocity, in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses, in H. - !! (usually m or kg m-2). + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< The zonal velocity [m s-1]. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< The meridional velocity [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables. type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical !! viscosities, bottom drag viscosities, and related fields. type(time_type), intent(in) :: Time_local !< The model time at the end !! of the time step. - real, intent(in) :: dt !< The dynamics time step, in s. + real, intent(in) :: dt !< The dynamics time step [s]. type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces real, dimension(:,:), pointer :: p_surf_begin !< A pointer (perhaps NULL) to the surface - !! pressure at the start of this dynamic step, in Pa. + !! pressure at the start of this dynamic step [Pa]. real, dimension(:,:), pointer :: p_surf_end !< A pointer (perhaps NULL) to the surface - !! pressure at the end of this dynamic step, in Pa. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uh !< The zonal volume or mass transport, - !! in m3 s-1 or kg s-1. + !! pressure at the end of this dynamic step [Pa]. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uh !< The zonal volume or mass transport + !! [H m2 s-1 ~> m3 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vh !< The meridional volume or mass - !! transport, in m3 s-1 or kg s-1. + !! transport [H m2 s-1 ~> m3 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< The accumulated zonal volume or mass - !! transport since the last tracer advection, in m3 or kg. + !! transport since the last tracer advection [H m2 ~> m3 or kg]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< The accumulated meridional volume or mass - !! transport since the last tracer advection, in m3 or kg. + !! transport since the last tracer advection [H m2 ~> m3 or kg]. real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta_av !< The time-mean free surface height or - !! column mass, in H (m or kg m-2). + !! column mass [H ~> m or kg m-2]. type(MOM_dyn_unsplit_CS), pointer :: CS !< The control structure set up by !! initialize_dyn_unsplit. type(VarMix_CS), pointer :: VarMix !< A pointer to a structure with fields @@ -566,12 +565,11 @@ subroutine initialize_dyn_unsplit(u, v, h, Time, G, GV, US, param_file, diag, CS type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: u !< The zonal velocity, in m s-1. + intent(inout) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: v !< The meridional velocity, in m s-1. + intent(inout) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , & - intent(inout) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] type(time_type), target, intent(in) :: Time !< The current model time. type(param_file_type), intent(in) :: param_file !< A structure to parse !! for run-time parameters. diff --git a/src/core/MOM_dynamics_unsplit_RK2.F90 b/src/core/MOM_dynamics_unsplit_RK2.F90 index 472a9adabe..e3625dd6a3 100644 --- a/src/core/MOM_dynamics_unsplit_RK2.F90 +++ b/src/core/MOM_dynamics_unsplit_RK2.F90 @@ -102,14 +102,14 @@ module MOM_dynamics_unsplit_RK2 !> MOM_dynamics_unsplit_RK2 module control structure type, public :: MOM_dyn_unsplit_RK2_CS ; private real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: & - CAu, & !< CAu = f*v - u.grad(u) in m s-2. - PFu, & !< PFu = -dM/dx, in m s-2. - diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor, in m s-2. + CAu, & !< CAu = f*v - u.grad(u) [m s-2]. + PFu, & !< PFu = -dM/dx [m s-2]. + diffu !< Zonal acceleration due to convergence of the along-isopycnal stress tensor [m s-2]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: & - CAv, & !< CAv = -f*u - u.grad(v) in m s-2. - PFv, & !< PFv = -dM/dy, in m s-2. - diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor, in m s-2. + CAv, & !< CAv = -f*u - u.grad(v) [m s-2]. + PFv, & !< PFv = -dM/dy [m s-2]. + diffv !< Meridional acceleration due to convergence of the along-isopycnal stress tensor [m s-2]. real, pointer, dimension(:,:) :: taux_bot => NULL() !< frictional x-bottom stress from the ocean to the seafloor (Pa) real, pointer, dimension(:,:) :: tauy_bot => NULL() !< frictional y-bottom stress from the ocean to the seafloor (Pa) @@ -189,11 +189,11 @@ subroutine step_MOM_dyn_unsplit_RK2(u_in, v_in, h_in, tv, visc, Time_local, dt, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u_in !< The input and output zonal - !! velocity, in m s-1. + !! velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v_in !< The input and output meridional - !! velocity, in m s-1. + !! velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h_in !< The input and output layer thicknesses, - !! in m or kg m-2, depending on whether + !! [H ~> m or kg m-2], depending on whether !! the Boussinesq approximation is made. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables. @@ -202,27 +202,26 @@ subroutine step_MOM_dyn_unsplit_RK2(u_in, v_in, h_in, tv, visc, Time_local, dt, !! viscosities, and related fields. type(time_type), intent(in) :: Time_local !< The model time at the end of !! the time step. - real, intent(in) :: dt !< The baroclinic dynamics time step, - !! in s. + real, intent(in) :: dt !< The baroclinic dynamics time step [s]. type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces real, dimension(:,:), pointer :: p_surf_begin !< A pointer (perhaps NULL) to !! the surface pressure at the beginning - !! of this dynamic step, in Pa. + !! of this dynamic step [Pa]. real, dimension(:,:), pointer :: p_surf_end !< A pointer (perhaps NULL) to !! the surface pressure at the end of - !! this dynamic step, in Pa. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uh !< The zonal volume or mass transport, - !! in m3 s-1 or kg s-1. + !! this dynamic step [Pa]. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uh !< The zonal volume or mass transport + !! [H m2 s-1 ~> m3 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vh !< The meridional volume or mass - !! transport, in m3 s-1 or kg s-1. + !! transport [H m2 s-1 ~> m3 or kg s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< The accumulated zonal volume or !! mass transport since the last - !! tracer advection, in m3 or kg. + !! tracer advection [H m2 ~> m3 or kg]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< The accumulated meridional volume !! or mass transport since the last - !! tracer advection, in m3 or kg. + !! tracer advection [H m2 ~> m3 or kg]. real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta_av !< The time-mean free surface height - !! or column mass, in H (m or kg m-2). + !! or column mass [H ~> m or kg m-2]. type(MOM_dyn_unsplit_RK2_CS), pointer :: CS !< The control structure set up by !! initialize_dyn_unsplit_RK2. type(VarMix_CS), pointer :: VarMix !< A pointer to a structure with @@ -511,11 +510,9 @@ subroutine initialize_dyn_unsplit_RK2(u, v, h, Time, G, GV, US, param_file, diag type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< The zonal velocity, in m s-1. - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< The meridional velocity, - !! in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , intent(inout) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< The zonal velocity [m s-1]. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< The meridional velocity [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] type(time_type), target, intent(in) :: Time !< The current model time. type(param_file_type), intent(in) :: param_file !< A structure to parse !! for run-time parameters. @@ -528,7 +525,7 @@ subroutine initialize_dyn_unsplit_RK2(u, v, h, Time, G, GV, US, param_file, diag type(accel_diag_ptrs), target, intent(inout) :: Accel_diag !< A set of pointers to the !! various accelerations in the momentum equations, which can !! be used for later derived diagnostics, like energy budgets. - type(cont_diag_ptrs), target, intent(inout) :: Cont_diag ! m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Structure that contains pointers to the boundary forcing used to drive the !! liquid ocean simulated by MOM. !! @@ -45,76 +50,76 @@ module MOM_forcing_type ! surface stress components and turbulent velocity scale real, pointer, dimension(:,:) :: & - ustar => NULL(), & !< surface friction velocity scale (Z/s) + ustar => NULL(), & !< surface friction velocity scale [Z s-1 ~> m s-1]. ustar_gustless => NULL() !< surface friction velocity scale without any - !! any augmentation for gustiness (Z/s) + !! any augmentation for gustiness [Z s-1 ~> m s-1]. ! surface buoyancy force, used when temperature is not a state variable real, pointer, dimension(:,:) :: & - buoy => NULL() !< buoyancy flux (m^2/s^3) + buoy => NULL() !< buoyancy flux [m2 s-3] - ! radiative heat fluxes into the ocean (W/m^2) + ! radiative heat fluxes into the ocean [W m-2] real, pointer, dimension(:,:) :: & - sw => NULL(), & !< shortwave (W/m^2) - sw_vis_dir => NULL(), & !< visible, direct shortwave (W/m^2) - sw_vis_dif => NULL(), & !< visible, diffuse shortwave (W/m^2) - sw_nir_dir => NULL(), & !< near-IR, direct shortwave (W/m^2) - sw_nir_dif => NULL(), & !< near-IR, diffuse shortwave (W/m^2) - lw => NULL() !< longwave (W/m^2) (typically negative) - - ! turbulent heat fluxes into the ocean (W/m^2) + sw => NULL(), & !< shortwave [W m-2] + sw_vis_dir => NULL(), & !< visible, direct shortwave [W m-2] + sw_vis_dif => NULL(), & !< visible, diffuse shortwave [W m-2] + sw_nir_dir => NULL(), & !< near-IR, direct shortwave [W m-2] + sw_nir_dif => NULL(), & !< near-IR, diffuse shortwave [W m-2] + lw => NULL() !< longwave [W m-2] (typically negative) + + ! turbulent heat fluxes into the ocean [W m-2] real, pointer, dimension(:,:) :: & - latent => NULL(), & !< latent (W/m^2) (typically < 0) - sens => NULL(), & !< sensible (W/m^2) (typically negative) - heat_added => NULL() !< additional heat flux from SST restoring or flux adjustments (W/m^2) + latent => NULL(), & !< latent [W m-2] (typically < 0) + sens => NULL(), & !< sensible [W m-2] (typically negative) + heat_added => NULL() !< additional heat flux from SST restoring or flux adjustments [W m-2] ! components of latent heat fluxes used for diagnostic purposes real, pointer, dimension(:,:) :: & - latent_evap_diag => NULL(), & !< latent (W/m^2) from evaporating liquid water (typically < 0) - latent_fprec_diag => NULL(), & !< latent (W/m^2) from melting fprec (typically < 0) - latent_frunoff_diag => NULL() !< latent (W/m^2) from melting frunoff (calving) (typically < 0) + latent_evap_diag => NULL(), & !< latent [W m-2] from evaporating liquid water (typically < 0) + latent_fprec_diag => NULL(), & !< latent [W m-2] from melting fprec (typically < 0) + latent_frunoff_diag => NULL() !< latent [W m-2] from melting frunoff (calving) (typically < 0) - ! water mass fluxes into the ocean ( kg/(m^2 s) ); these fluxes impact the ocean mass + ! water mass fluxes into the ocean [kg m-2 s-1]; these fluxes impact the ocean mass real, pointer, dimension(:,:) :: & - evap => NULL(), & !< (-1)*fresh water flux evaporated out of the ocean ( kg/(m^2 s) ) - lprec => NULL(), & !< precipitating liquid water into the ocean ( kg/(m^2 s) ) - fprec => NULL(), & !< precipitating frozen water into the ocean ( kg/(m^2 s) ) - vprec => NULL(), & !< virtual liquid precip associated w/ SSS restoring ( kg/(m^2 s) ) - lrunoff => NULL(), & !< liquid river runoff entering ocean ( kg/(m^2 s) ) - frunoff => NULL(), & !< frozen river runoff (calving) entering ocean ( kg/(m^2 s) ) - seaice_melt => NULL(), & !< seaice melt (positive) or formation (negative) ( kg/(m^2 s) ) - netMassIn => NULL(), & !< Sum of water mass flux out of the ocean ( kg/(m^2 s) ) - netMassOut => NULL(), & !< Net water mass flux into of the ocean ( kg/(m^2 s) ) - netSalt => NULL() !< Net salt entering the ocean + evap => NULL(), & !< (-1)*fresh water flux evaporated out of the ocean [kg m-2 s-1] + lprec => NULL(), & !< precipitating liquid water into the ocean [kg m-2 s-1] + fprec => NULL(), & !< precipitating frozen water into the ocean [kg m-2 s-1] + vprec => NULL(), & !< virtual liquid precip associated w/ SSS restoring [kg m-2 s-1] + lrunoff => NULL(), & !< liquid river runoff entering ocean [kg m-2 s-1] + frunoff => NULL(), & !< frozen river runoff (calving) entering ocean [kg m-2 s-1] + seaice_melt => NULL(), & !< seaice melt (positive) or formation (negative) [kg m-2 s-1] + netMassIn => NULL(), & !< Sum of water mass flux out of the ocean [kg m-2 s-1] + netMassOut => NULL(), & !< Net water mass flux into of the ocean [kg m-2 s-1] + netSalt => NULL() !< Net salt entering the ocean [kgSalt m-2 s-1] ! heat associated with water crossing ocean surface real, pointer, dimension(:,:) :: & - heat_content_cond => NULL(), & !< heat content associated with condensating water (W/m^2) - heat_content_lprec => NULL(), & !< heat content associated with liquid >0 precip (W/m^2) (diagnostic) - heat_content_fprec => NULL(), & !< heat content associated with frozen precip (W/m^2) - heat_content_vprec => NULL(), & !< heat content associated with virtual >0 precip (W/m^2) - heat_content_lrunoff => NULL(), & !< heat content associated with liquid runoff (W/m^2) - heat_content_frunoff => NULL(), & !< heat content associated with frozen runoff (W/m^2) - heat_content_icemelt => NULL(), & !< heat content associated with liquid sea ice (W/m^2) - heat_content_massout => NULL(), & !< heat content associated with mass leaving ocean (W/m^2) - heat_content_massin => NULL() !< heat content associated with mass entering ocean (W/m^2) + heat_content_cond => NULL(), & !< heat content associated with condensating water [W m-2] + heat_content_lprec => NULL(), & !< heat content associated with liquid >0 precip [W m-2] (diagnostic) + heat_content_fprec => NULL(), & !< heat content associated with frozen precip [W m-2] + heat_content_vprec => NULL(), & !< heat content associated with virtual >0 precip [W m-2] + heat_content_lrunoff => NULL(), & !< heat content associated with liquid runoff [W m-2] + heat_content_frunoff => NULL(), & !< heat content associated with frozen runoff [W m-2] + heat_content_icemelt => NULL(), & !< heat content associated with liquid sea ice [W m-2] + heat_content_massout => NULL(), & !< heat content associated with mass leaving ocean [W m-2] + heat_content_massin => NULL() !< heat content associated with mass entering ocean [W m-2] ! salt mass flux (contributes to ocean mass only if non-Bouss ) real, pointer, dimension(:,:) :: & - salt_flux => NULL(), & !< net salt flux into the ocean ( kg salt/(m^2 s) ) - salt_flux_in => NULL(), & !< salt flux provided to the ocean from coupler ( kg salt/(m^2 s) ) + salt_flux => NULL(), & !< net salt flux into the ocean [kgSalt m-2 s-1] + salt_flux_in => NULL(), & !< salt flux provided to the ocean from coupler [kgSalt m-2 s-1] salt_flux_added => NULL() !< additional salt flux from restoring or flux adjustment before adjustment - !! to net zero ( kg salt/(m^2 s) ) + !! to net zero [kgSalt m-2 s-1] ! applied surface pressure from other component models (e.g., atmos, sea ice, land ice) real, pointer, dimension(:,:) :: p_surf_full => NULL() - !< Pressure at the top ocean interface (Pa). + !< Pressure at the top ocean interface [Pa]. !! if there is sea-ice, then p_surf_flux is at ice-ocean interface real, pointer, dimension(:,:) :: p_surf => NULL() - !< Pressure at the top ocean interface (Pa) as used to drive the ocean model. + !< Pressure at the top ocean interface [Pa] as used to drive the ocean model. !! If p_surf is limited, p_surf may be smaller than p_surf_full, otherwise they are the same. real, pointer, dimension(:,:) :: p_surf_SSH => NULL() - !< Pressure at the top ocean interface that is used in corrections to the sea surface + !< Pressure at the top ocean interface [Pa] that is used in corrections to the sea surface !! height field that is passed back to the calling routines. !! p_surf_SSH may point to p_surf or to p_surf_full. logical :: accumulate_p_surf = .false. !< If true, the surface pressure due to the atmosphere @@ -124,40 +129,40 @@ module MOM_forcing_type ! tide related inputs real, pointer, dimension(:,:) :: & - TKE_tidal => NULL(), & !< tidal energy source driving mixing in bottom boundary layer (W/m^2) - ustar_tidal => NULL() !< tidal contribution to bottom ustar (m/s) + TKE_tidal => NULL(), & !< tidal energy source driving mixing in bottom boundary layer [W m-2] + ustar_tidal => NULL() !< tidal contribution to bottom ustar [m s-1] ! iceberg related inputs real, pointer, dimension(:,:) :: & - ustar_berg => NULL(), & !< iceberg contribution to top ustar (Z/s) - area_berg => NULL(), & !< area of ocean surface covered by icebergs (m2/m2) - mass_berg => NULL() !< mass of icebergs (kg/m2) + ustar_berg => NULL(), & !< iceberg contribution to top ustar [Z s-1 ~> m s-1]. + area_berg => NULL(), & !< area of ocean surface covered by icebergs [m2 m-2] + mass_berg => NULL() !< mass of icebergs [kg m-2] ! land ice-shelf related inputs - real, pointer, dimension(:,:) :: ustar_shelf => NULL() !< Friction velocity under ice-shelves (in Z/s) + real, pointer, dimension(:,:) :: ustar_shelf => NULL() !< Friction velocity under ice-shelves [Z s-1 ~> m s-1]. !! as computed by the ocean at the previous time step. - real, pointer, dimension(:,:) :: frac_shelf_h => NULL() !< Fractional ice shelf coverage of h-cells, nondimensional - !! cells, nondimensional from 0 to 1. This is only + real, pointer, dimension(:,:) :: frac_shelf_h => NULL() !< Fractional ice shelf coverage of + !! h-cells, nondimensional from 0 to 1. This is only !! associated if ice shelves are enabled, and are !! exactly 0 away from shelves or on land. real, pointer, dimension(:,:) :: iceshelf_melt => NULL() !< Ice shelf melt rate (positive) - !! or freezing (negative) (in m/year) + !! or freezing (negative) [m year-1] ! Scalars set by surface forcing modules - real :: vPrecGlobalAdj !< adjustment to restoring vprec to zero out global net ( kg/(m^2 s) ) - real :: saltFluxGlobalAdj !< adjustment to restoring salt flux to zero out global net ( kg salt/(m^2 s) ) - real :: netFWGlobalAdj !< adjustment to net fresh water to zero out global net ( kg/(m^2 s) ) - real :: vPrecGlobalScl !< scaling of restoring vprec to zero out global net ( -1..1 ) - real :: saltFluxGlobalScl !< scaling of restoring salt flux to zero out global net ( -1..1 ) - real :: netFWGlobalScl !< scaling of net fresh water to zero out global net ( -1..1 ) + real :: vPrecGlobalAdj !< adjustment to restoring vprec to zero out global net [kg m-2 s-1] + real :: saltFluxGlobalAdj !< adjustment to restoring salt flux to zero out global net [kgSalt m-2 s-1] + real :: netFWGlobalAdj !< adjustment to net fresh water to zero out global net [kg m-2 s-1] + real :: vPrecGlobalScl !< scaling of restoring vprec to zero out global net ( -1..1 ) [nondim] + real :: saltFluxGlobalScl !< scaling of restoring salt flux to zero out global net ( -1..1 ) [nondim] + real :: netFWGlobalScl !< scaling of net fresh water to zero out global net ( -1..1 ) [nondim] logical :: fluxes_used = .true. !< If true, all of the heat, salt, and mass !! fluxes have been applied to the ocean. real :: dt_buoy_accum = -1.0 !< The amount of time over which the buoyancy fluxes - !! should be applied, in s. If negative, this forcing + !! should be applied [s]. If negative, this forcing !! type variable has not yet been inialized. - real :: C_p !< heat capacity of seawater ( J/(K kg) ). + real :: C_p !< heat capacity of seawater [J kg-1 degC-1]. !! C_p is is the same value as in thermovar_ptrs_type. ! passive tracer surface fluxes @@ -179,17 +184,17 @@ module MOM_forcing_type type, public :: mech_forcing ! surface stress components and turbulent velocity scale real, pointer, dimension(:,:) :: & - taux => NULL(), & !< zonal wind stress (Pa) - tauy => NULL(), & !< meridional wind stress (Pa) - ustar => NULL(), & !< surface friction velocity scale (Z/s) - net_mass_src => NULL() !< The net mass source to the ocean, in kg m-2 s-1. + taux => NULL(), & !< zonal wind stress [Pa] + tauy => NULL(), & !< meridional wind stress [Pa] + ustar => NULL(), & !< surface friction velocity scale [Z s-1 ~> m s-1]. + net_mass_src => NULL() !< The net mass source to the ocean [kg m-2 s-1]. ! applied surface pressure from other component models (e.g., atmos, sea ice, land ice) real, pointer, dimension(:,:) :: p_surf_full => NULL() - !< Pressure at the top ocean interface (Pa). + !< Pressure at the top ocean interface [Pa]. !! if there is sea-ice, then p_surf_flux is at ice-ocean interface real, pointer, dimension(:,:) :: p_surf => NULL() - !< Pressure at the top ocean interface (Pa) as used to drive the ocean model. + !< Pressure at the top ocean interface [Pa] as used to drive the ocean model. !! If p_surf is limited, p_surf may be smaller than p_surf_full, otherwise they are the same. real, pointer, dimension(:,:) :: p_surf_SSH => NULL() !< Pressure at the top ocean interface that is used in corrections to the sea surface @@ -198,21 +203,21 @@ module MOM_forcing_type ! iceberg related inputs real, pointer, dimension(:,:) :: & - area_berg => NULL(), & !< area of ocean surface covered by icebergs (m2/m2) - mass_berg => NULL() !< mass of icebergs (kg/m2) + area_berg => NULL(), & !< fractional area of ocean surface covered by icebergs [m2 m-2] + mass_berg => NULL() !< mass of icebergs per unit ocean area [kg m-2] ! land ice-shelf related inputs real, pointer, dimension(:,:) :: frac_shelf_u => NULL() !< Fractional ice shelf coverage of u-cells, - !! nondimensional from 0 to 1. This is only associated if ice shelves are enabled, + !! nondimensional from 0 to 1 [nondim]. This is only associated if ice shelves are enabled, !! and is exactly 0 away from shelves or on land. real, pointer, dimension(:,:) :: frac_shelf_v => NULL() !< Fractional ice shelf coverage of v-cells, - !! nondimensional from 0 to 1. This is only associated if ice shelves are enabled, + !! nondimensional from 0 to 1 [nondim]. This is only associated if ice shelves are enabled, !! and is exactly 0 away from shelves or on land. real, pointer, dimension(:,:) :: & - rigidity_ice_u => NULL(), & !< Depth-integrated lateral viscosity of ice shelves or sea ice at u-points (m3/s) - rigidity_ice_v => NULL() !< Depth-integrated lateral viscosity of ice shelves or sea ice at v-points (m3/s) + rigidity_ice_u => NULL(), & !< Depth-integrated lateral viscosity of ice shelves or sea ice at u-points [m3 s-1] + rigidity_ice_v => NULL() !< Depth-integrated lateral viscosity of ice shelves or sea ice at v-points [m3 s-1] real :: dt_force_accum = -1.0 !< The amount of time over which the mechanical forcing fluxes - !! have been averaged, in s. + !! have been averaged [s]. logical :: net_mass_src_set = .false. !< If true, an estimate of net_mass_src has been provided. logical :: accumulate_p_surf = .false. !< If true, the surface pressure due to the atmosphere !! and various types of ice needs to be accumulated, and the @@ -341,20 +346,21 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, type(optics_type), pointer :: optics !< pointer to optics integer, intent(in) :: nsw !< number of bands of penetrating SW integer, intent(in) :: j !< j-index to work on - real, intent(in) :: dt !< time step in seconds - real, intent(in) :: FluxRescaleDepth !< min ocean depth before scale away fluxes (H) + real, intent(in) :: dt !< time step [s] + real, intent(in) :: FluxRescaleDepth !< min ocean depth before fluxes + !! are scaled away [H ~> m or kg m-2] logical, intent(in) :: useRiverHeatContent !< logical for river heat content logical, intent(in) :: useCalvingHeatContent !< logical for calving heat content real, dimension(SZI_(G),SZK_(G)), & - intent(in) :: h !< layer thickness (in H units) + intent(in) :: h !< layer thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZK_(G)), & - intent(in) :: T !< layer temperatures (deg C) + intent(in) :: T !< layer temperatures [degC] real, dimension(SZI_(G)), intent(out) :: netMassInOut !< net mass flux (non-Bouss) or volume flux !! (if Bouss) of water in/out of ocean over - !! a time step (H units) + !! a time step [H ~> m or kg m-2] real, dimension(SZI_(G)), intent(out) :: netMassOut !< net mass flux (non-Bouss) or volume flux !! (if Bouss) of water leaving ocean surface - !! over a time step (H units). + !! over a time step [H ~> m or kg m-2]. !! netMassOut < 0 means mass leaves ocean. real, dimension(SZI_(G)), intent(out) :: net_heat !< net heat at the surface accumulated over a !! time step for coupler + restoring. @@ -362,41 +368,47 @@ subroutine extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, !! (1) downwelling (penetrative) SW, !! (2) evaporation heat content, !! (since do not yet know evap temperature). - !! Units of net_heat are (K * H). - real, dimension(SZI_(G)), intent(out) :: net_salt !< surface salt flux into the ocean accumulated - !! over a time step (ppt * H) + !! [degC H ~> degC m or degC kg m-2]. + real, dimension(SZI_(G)), intent(out) :: net_salt !< surface salt flux into the ocean + !! accumulated over a time step + !! [ppt H ~> ppt m or ppt kg m-2]. real, dimension(:,:), intent(out) :: pen_SW_bnd !< penetrating SW flux, split into bands. - !! Units are (deg K * H) and array size - !! nsw x SZI_(G), where nsw=number of SW bands - !! in pen_SW_bnd. This heat flux is not part - !! of net_heat. + !! [degC H ~> degC m or degC kg m-2] + !! and array size nsw x SZI_(G), where + !! nsw=number of SW bands in pen_SW_bnd. + !! This heat flux is not part of net_heat. type(thermo_var_ptrs), intent(inout) :: tv !< structure containing pointers to available !! thermodynamic fields. Used to keep !! track of the heat flux associated with net !! mass fluxes into the ocean. logical, intent(in) :: aggregate_FW !< For determining how to aggregate forcing. real, dimension(SZI_(G)), & - optional, intent(out) :: nonpenSW !< Non-penetrating SW in degC H, used in net_heat. + optional, intent(out) :: nonpenSW !< Non-penetrating SW used in net_heat + !! [degC H ~> degC m or degC kg m-2]. !! Summed over SW bands when diagnosing nonpenSW. real, dimension(SZI_(G)), & - optional, intent(out) :: net_Heat_rate !< Rate of net surface heating in H K s-1. + optional, intent(out) :: net_Heat_rate !< Rate of net surface heating + !! [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1]. real, dimension(SZI_(G)), & - optional, intent(out) :: net_salt_rate !< Surface salt flux into the ocean in ppt H s-1. + optional, intent(out) :: net_salt_rate !< Surface salt flux into the ocean + !! [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1]. real, dimension(SZI_(G)), & - optional, intent(out) :: netmassInOut_rate !< Rate of net mass flux into the ocean in H s-1. + optional, intent(out) :: netmassInOut_rate !< Rate of net mass flux into the ocean + !! [H s-1 ~> m s-1 or kg m-2 s-1]. real, dimension(:,:), & - optional, intent(out) :: pen_sw_bnd_rate !< Rate of penetrative shortwave heating in degC H s-1. + optional, intent(out) :: pen_sw_bnd_rate !< Rate of penetrative shortwave heating + !! [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1]. logical, optional, intent(in) :: skip_diags !< If present and true, skip calculating diagnostics ! local - real :: htot(SZI_(G)) ! total ocean depth (m for Bouss or kg/m^2 for non-Bouss) - real :: Pen_sw_tot(SZI_(G)) ! sum across all bands of Pen_SW (K * H) + real :: htot(SZI_(G)) ! total ocean depth [H ~> m or kg m-2] + real :: Pen_sw_tot(SZI_(G)) ! sum across all bands of Pen_SW [degC H ~> degC m or degC kg m-2]. real :: pen_sw_tot_rate(SZI_(G)) ! Similar but sum but as a rate (no dt in calculation) - real :: Ih_limit ! inverse depth at which surface fluxes start to be limited (1/H) + real :: Ih_limit ! inverse depth at which surface fluxes start to be limited [H-1 ~> m-1 or m2 kg-1] real :: scale ! scale scales away fluxes if depth < FluxRescaleDepth real :: J_m2_to_H ! converts J/m^2 to H units (m for Bouss and kg/m^2 for non-Bouss) - real :: Irho0 ! 1.0 / Rho0 - real :: I_Cp ! 1.0 / C_p + real :: Irho0 ! 1.0 / Rho0 [m3 kg-1] + real :: I_Cp ! 1.0 / C_p [kg decC J-1] logical :: calculate_diags ! Indicate to calculate/update diagnostic arrays character(len=200) :: mesg integer :: is, ie, nz, i, k, n @@ -761,43 +773,44 @@ subroutine extractFluxes2d(G, GV, fluxes, optics, nsw, dt, FluxRescaleDepth, & netMassInOut, netMassOut, net_heat, Net_salt, Pen_SW_bnd, tv, & aggregate_FW) - type(ocean_grid_type), intent(in) :: G !< ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - type(forcing), intent(inout) :: fluxes !< structure containing pointers to forcing. - type(optics_type), pointer :: optics !< pointer to optics - integer, intent(in) :: nsw !< number of bands of penetrating SW - real, intent(in) :: dt !< time step in seconds - real, intent(in) :: FluxRescaleDepth !< min ocean depth before scale away fluxes (H) + type(ocean_grid_type), intent(in) :: G !< ocean grid structure + type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure + type(forcing), intent(inout) :: fluxes !< structure containing pointers to forcing. + type(optics_type), pointer :: optics !< pointer to optics + integer, intent(in) :: nsw !< number of bands of penetrating SW + real, intent(in) :: dt !< time step [s] + real, intent(in) :: FluxRescaleDepth !< min ocean depth before fluxes + !! are scaled away [H ~> m or kg m-2] logical, intent(in) :: useRiverHeatContent !< logical for river heat content logical, intent(in) :: useCalvingHeatContent !< logical for calving heat content real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< layer thickness (in H units) + intent(in) :: h !< layer thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: T !< layer temperatures (deg C) - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: netMassInOut !< net mass flux (non-Bouss) or volume flux - !! (if Bouss) of water in/out of ocean over - !! a time step (H units) - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: netMassOut !< net mass flux (non-Bouss) or volume flux - !! (if Bouss) of water leaving ocean surface - !! over a time step (H units). - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_heat !< net heat at the surface accumulated over a - !! time step associated with coupler + restore. - !! Exclude two terms from net_heat: - !! (1) downwelling (penetrative) SW, - !! (2) evaporation heat content, - !! (since do not yet know temperature of evap). - !! Units of net_heat are (K * H). - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_salt !< surface salt flux into the ocean accumulated - !! over a time step (ppt * H) - real, dimension(:,:,:), intent(out) :: pen_SW_bnd !< penetrating shortwave flux, split into bands. - !! Units (deg K * H) & array size nsw x SZI_(G), - !! where nsw=number of SW bands in pen_SW_bnd. - !! This heat flux is not in net_heat. - type(thermo_var_ptrs), intent(inout) :: tv !< structure containing pointers to available - !! thermodynamic fields. Here it is used to keep - !! track of the heat flux associated with net - !! mass fluxes into the ocean. - logical, intent(in) :: aggregate_FW !< For determining how to aggregate the forcing. + intent(in) :: T !< layer temperatures [degC] + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: netMassInOut !< net mass flux (non-Bouss) or volume flux + !! (if Bouss) of water in/out of ocean over + !! a time step [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: netMassOut !< net mass flux (non-Bouss) or volume flux + !! (if Bouss) of water leaving ocean surface + !! over a time step [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_heat !< net heat at the surface accumulated over a + !! time step associated with coupler + restore. + !! Exclude two terms from net_heat: + !! (1) downwelling (penetrative) SW, + !! (2) evaporation heat content, + !! (since do not yet know temperature of evap). + !! [degC H ~> degC m or degC kg m-2] + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_salt !< surface salt flux into the ocean accumulated + !! over a time step [ppt H ~> ppt m or ppt kg m-2] + real, dimension(:,:,:), intent(out) :: pen_SW_bnd !< penetrating shortwave flux, split into bands. + !! [degC H ~> degC m or degC kg m-2] array size + !! nsw x SZI_(G), where nsw=number of SW bands in + !! pen_SW_bnd. This heat flux is not in net_heat. + type(thermo_var_ptrs), intent(inout) :: tv !< structure containing pointers to available + !! thermodynamic fields. Here it is used to keep + !! track of the heat flux associated with net + !! mass fluxes into the ocean. + logical, intent(in) :: aggregate_FW !< For determining how to aggregate the forcing. integer :: j !$OMP parallel do default(none) shared(G, GV, fluxes, optics, nsw,dt,FluxRescaleDepth, & @@ -825,26 +838,29 @@ subroutine calculateBuoyancyFlux1d(G, GV, US, fluxes, optics, h, Temp, Salt, tv, type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(forcing), intent(inout) :: fluxes !< surface fluxes type(optics_type), pointer :: optics !< penetrating SW optics - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness (H) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< prognostic temp(deg C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< salinity (ppt) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< prognostic temp [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< salinity [ppt] type(thermo_var_ptrs), intent(inout) :: tv !< thermodynamics type integer, intent(in) :: j !< j-row to work on - real, dimension(SZI_(G),SZK_(G)+1), intent(inout) :: buoyancyFlux !< buoyancy flux (m^2/s^3) - real, dimension(SZI_(G)), intent(inout) :: netHeatMinusSW !< surf Heat flux (K H/s) - real, dimension(SZI_(G)), intent(inout) :: netSalt !< surf salt flux (ppt H/s) + real, dimension(SZI_(G),SZK_(G)+1), intent(inout) :: buoyancyFlux !< buoyancy flux [m2 s-3] + real, dimension(SZI_(G)), intent(inout) :: netHeatMinusSW !< surf Heat flux + !! [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1] + real, dimension(SZI_(G)), intent(inout) :: netSalt !< surf salt flux + !! [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1] logical, optional, intent(in) :: skip_diags !< If present and true, skip calculating !! diagnostics inside extractFluxes1d() ! local variables integer :: nsw, start, npts, k real, parameter :: dt = 1. ! to return a rate from extractFluxes1d - real, dimension( SZI_(G) ) :: netH ! net FW flux (m/s for Bouss) - real, dimension( SZI_(G) ) :: netEvap ! net FW flux leaving ocean via evaporation (m/s for Bouss) - real, dimension( SZI_(G) ) :: netHeat ! net temp flux (K m/s) + real, dimension( SZI_(G) ) :: netH ! net FW flux [H s-1 ~> m s-1 or kg m-2 s-1] + real, dimension( SZI_(G) ) :: netEvap ! net FW flux leaving ocean via evaporation + ! [H s-1 ~> m s-1 or kg m-2 s-1] + real, dimension( SZI_(G) ) :: netHeat ! net temp flux [degC H s-1 ~> degC m s-2 or degC kg m-2 s-1] real, dimension( optics%nbands, SZI_(G) ) :: penSWbnd ! SW penetration bands - real, dimension( SZI_(G) ) :: pressure ! pressurea the surface (Pa) - real, dimension( SZI_(G) ) :: dRhodT ! density partial derivative wrt temp - real, dimension( SZI_(G) ) :: dRhodS ! density partial derivative wrt saln + real, dimension( SZI_(G) ) :: pressure ! pressurea the surface [Pa] + real, dimension( SZI_(G) ) :: dRhodT ! density partial derivative wrt temp [kg m-3 degC-1] + real, dimension( SZI_(G) ) :: dRhodS ! density partial derivative wrt saln [kg m-3 ppt-1] real, dimension(SZI_(G),SZK_(G)+1) :: netPen logical :: useRiverHeatContent @@ -868,9 +884,9 @@ subroutine calculateBuoyancyFlux1d(G, GV, US, fluxes, optics, h, Temp, Salt, tv, ! The surface forcing is contained in the fluxes type. ! We aggregate the thermodynamic forcing for a time step into the following: - ! netH = water (H units/s) added/removed via surface fluxes - ! netHeat = heat (degC * H/s) via surface fluxes - ! netSalt = salt ( g(salt)/m2 for non-Bouss and ppt*m for Bouss /s) via surface fluxes + ! netH = water added/removed via surface fluxes [H s-1 ~> m s-1 or kg m-2 s-1] + ! netHeat = heat via surface fluxes [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1] + ! netSalt = salt via surface fluxes [ppt H s-1 ~> ppt m s-1 or gSalt m-2 s-1] ! Note that unlike other calls to extractFLuxes1d() that return the time-integrated flux ! this call returns the rate because dt=1 call extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, & @@ -915,18 +931,20 @@ subroutine calculateBuoyancyFlux2d(G, GV, US, fluxes, optics, h, Temp, Salt, tv, type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(forcing), intent(inout) :: fluxes !< surface fluxes type(optics_type), pointer :: optics !< SW ocean optics - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness (H) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< temperature (deg C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< salinity (ppt) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< salinity [ppt] type(thermo_var_ptrs), intent(inout) :: tv !< thermodynamics type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: buoyancyFlux !< buoy flux (m^2/s^3) - real, dimension(SZI_(G),SZJ_(G)), optional, intent(inout) :: netHeatMinusSW !< surf temp flux (K H) - real, dimension(SZI_(G),SZJ_(G)), optional, intent(inout) :: netSalt !< surf salt flux (ppt H) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: buoyancyFlux !< buoy flux [m2 s-3] + real, dimension(SZI_(G),SZJ_(G)), optional, intent(inout) :: netHeatMinusSW !< surf temp flux + !! [degC H ~> degC m or degC kg m-2] + real, dimension(SZI_(G),SZJ_(G)), optional, intent(inout) :: netSalt !< surf salt flux + !! [ppt H ~> ppt m or ppt kg m-2] logical, optional, intent(in) :: skip_diags !< If present and true, skip calculating !! diagnostics inside extractFluxes1d() ! local variables - real, dimension( SZI_(G) ) :: netT ! net temperature flux (K m/s) - real, dimension( SZI_(G) ) :: netS ! net saln flux (ppt m/s) + real, dimension( SZI_(G) ) :: netT ! net temperature flux [degC H s-1 ~> degC m s-2 or degC kg m-2 s-1] + real, dimension( SZI_(G) ) :: netS ! net saln flux !! [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1] integer :: j netT(G%isc:G%iec) = 0. ; netS(G%isc:G%iec) = 0. @@ -1761,7 +1779,7 @@ subroutine forcing_accumulate(flux_tmp, forces, fluxes, dt, G, wt2) type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces type(forcing), intent(inout) :: fluxes !< A structure containing time-averaged !! thermodynamic forcing fields - real, intent(in) :: dt !< The elapsed time since the last call to this subroutine, in s + real, intent(in) :: dt !< The elapsed time since the last call to this subroutine [s] type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure real, intent(out) :: wt2 !< The relative weight of the new fluxes @@ -1780,7 +1798,7 @@ subroutine fluxes_accumulate(flux_tmp, fluxes, dt, G, wt2, forces) !! thermodynamic forcing fields type(forcing), intent(inout) :: fluxes !< A structure containing time-averaged !! thermodynamic forcing fields - real, intent(in) :: dt !< The elapsed time since the last call to this subroutine, in s + real, intent(in) :: dt !< The elapsed time since the last call to this subroutine [s] type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure real, intent(out) :: wt2 !< The relative weight of the new fluxes type(mech_forcing), optional, intent(in) :: forces !< A structure with the driving mechanical forces @@ -1923,7 +1941,7 @@ subroutine copy_common_forcing_fields(forces, fluxes, G, skip_pres) type(ocean_grid_type), intent(in) :: G !< grid type logical, optional, intent(in) :: skip_pres !< If present and true, do not copy pressure fields. - real :: taux2, tauy2 ! Squared wind stress components, in Pa^2. + real :: taux2, tauy2 ! Squared wind stress components [Pa2]. logical :: do_pres integer :: i, j, is, ie, js, je is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -1966,11 +1984,11 @@ subroutine set_derived_forcing_fields(forces, fluxes, G, US, Rho0) type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields type(ocean_grid_type), intent(in) :: G !< grid type type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(in) :: Rho0 !< A reference density of seawater, in kg m-3, + real, intent(in) :: Rho0 !< A reference density of seawater [kg m-3], !! as used to calculate ustar. - real :: taux2, tauy2 ! Squared wind stress components, in Pa^2. - real :: Irho0 ! Inverse of the mean density rescaled to (Z2 m / kg) + real :: taux2, tauy2 ! Squared wind stress components [Pa2]. + real :: Irho0 ! Inverse of the mean density rescaled to [Z2 m / kg ~> m3 kg-1] integer :: i, j, is, ie, js, je is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -2017,7 +2035,7 @@ subroutine get_net_mass_forcing(fluxes, G, net_mass_src) type(forcing), intent(in) :: fluxes !< A structure containing thermodynamic forcing fields type(ocean_grid_type), intent(in) :: G !< The ocean grid type real, dimension(SZI_(G),SZJ_(G)), intent(out) :: net_mass_src !< The net mass flux of water into the ocean - !! in kg m-2 s-1. + !! [kg m-2 s-1]. integer :: i, j, is, ie, js, je is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -2051,7 +2069,7 @@ subroutine copy_back_forcing_fields(fluxes, forces, G) type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces type(ocean_grid_type), intent(in) :: G !< grid type - real :: taux2, tauy2 ! Squared wind stress components, in Pa^2. + real :: taux2, tauy2 ! Squared wind stress components [Pa2]. integer :: i, j, is, ie, js, je is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec diff --git a/src/core/MOM_grid.F90 b/src/core/MOM_grid.F90 index e226598b7f..7893b6ed86 100644 --- a/src/core/MOM_grid.F90 +++ b/src/core/MOM_grid.F90 @@ -16,6 +16,11 @@ module MOM_grid public MOM_grid_init, MOM_grid_end, set_derived_metrics, set_first_direction public isPointInCell, hor_index_type, get_global_grid_size, rescale_grid_bathymetry +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Ocean grid type. See mom_grid for details. type, public :: ocean_grid_type type(MOM_domain_type), pointer :: Domain => NULL() !< Ocean model domain @@ -70,12 +75,12 @@ module MOM_grid mask2dT, & !< 0 for land points and 1 for ocean points on the h-grid. Nd. geoLatT, & !< The geographic latitude at q points in degrees of latitude or m. geoLonT, & !< The geographic longitude at q points in degrees of longitude or m. - dxT, & !< dxT is delta x at h points, in m. - IdxT, & !< 1/dxT in m-1. - dyT, & !< dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. - IdyT, & !< dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. - areaT, & !< The area of an h-cell, in m2. - IareaT, & !< 1/areaT, in m-2. + dxT, & !< dxT is delta x at h points [m]. + IdxT, & !< 1/dxT [m-1]. + dyT, & !< dyT is delta y at h points [m]. + IdyT, & !< IdyT is 1/dyT [m-1]. + areaT, & !< The area of an h-cell [m2]. + IareaT, & !< 1/areaT [m-2]. sin_rot, & !< The sine of the angular rotation between the local model grid's northward !! and the true northward directions. cos_rot !< The cosine of the angular rotation between the local model grid's northward @@ -85,36 +90,36 @@ module MOM_grid mask2dCu, & !< 0 for boundary points and 1 for ocean points on the u grid. Nondim. geoLatCu, & !< The geographic latitude at u points in degrees of latitude or m. geoLonCu, & !< The geographic longitude at u points in degrees of longitude or m. - dxCu, & !< dxCu is delta x at u points, in m. - IdxCu, & !< 1/dxCu in m-1. - dyCu, & !< dyCu is delta y at u points, in m. - IdyCu, & !< 1/dyCu in m-1. - dy_Cu, & !< The unblocked lengths of the u-faces of the h-cell in m. - IareaCu, & !< The masked inverse areas of u-grid cells in m2. - areaCu !< The areas of the u-grid cells in m2. + dxCu, & !< dxCu is delta x at u points [m]. + IdxCu, & !< 1/dxCu [m-1]. + dyCu, & !< dyCu is delta y at u points [m]. + IdyCu, & !< 1/dyCu [m-1]. + dy_Cu, & !< The unblocked lengths of the u-faces of the h-cell [m]. + IareaCu, & !< The masked inverse areas of u-grid cells [m2]. + areaCu !< The areas of the u-grid cells [m2]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: & mask2dCv, & !< 0 for boundary points and 1 for ocean points on the v grid. Nondim. geoLatCv, & !< The geographic latitude at v points in degrees of latitude or m. geoLonCv, & !< The geographic longitude at v points in degrees of longitude or m. - dxCv, & !< dxCv is delta x at v points, in m. - IdxCv, & !< 1/dxCv in m-1. - dyCv, & !< dyCv is delta y at v points, in m. - IdyCv, & !< 1/dyCv in m-1. - dx_Cv, & !< The unblocked lengths of the v-faces of the h-cell in m. - IareaCv, & !< The masked inverse areas of v-grid cells in m2. - areaCv !< The areas of the v-grid cells in m2. + dxCv, & !< dxCv is delta x at v points [m]. + IdxCv, & !< 1/dxCv [m-1]. + dyCv, & !< dyCv is delta y at v points [m]. + IdyCv, & !< 1/dyCv [m-1]. + dx_Cv, & !< The unblocked lengths of the v-faces of the h-cell [m]. + IareaCv, & !< The masked inverse areas of v-grid cells [m2]. + areaCv !< The areas of the v-grid cells [m2]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & mask2dBu, & !< 0 for boundary points and 1 for ocean points on the q grid. Nondim. geoLatBu, & !< The geographic latitude at q points in degrees of latitude or m. geoLonBu, & !< The geographic longitude at q points in degrees of longitude or m. - dxBu, & !< dxBu is delta x at q points, in m. - IdxBu, & !< 1/dxBu in m-1. - dyBu, & !< dyBu is delta y at q points, in m. - IdyBu, & !< 1/dyBu in m-1. - areaBu, & !< areaBu is the area of a q-cell, in m2 - IareaBu !< IareaBu = 1/areaBu in m-2. + dxBu, & !< dxBu is delta x at q points [m]. + IdxBu, & !< 1/dxBu [m-1]. + dyBu, & !< dyBu is delta y at q points [m]. + IdyBu, & !< 1/dyBu [m-1]. + areaBu, & !< areaBu is the area of a q-cell [m2] + IareaBu !< IareaBu = 1/areaBu [m-2]. real, pointer, dimension(:) :: & gridLatT => NULL(), & !< The latitude of T points for the purpose of labeling the output axes. @@ -131,27 +136,27 @@ module MOM_grid y_axis_units !< The units that are used in labeling the y coordinate axes. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - bathyT !< Ocean bottom depth at tracer points, in depth units. + bathyT !< Ocean bottom depth at tracer points, in depth units [Z ~> m]. logical :: bathymetry_at_vel !< If true, there are separate values for the !! basin depths at velocity points. Otherwise the effects of !! of topography are entirely determined from thickness points. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: & - Dblock_u, & !< Topographic depths at u-points at which the flow is blocked, in depth units. - Dopen_u !< Topographic depths at u-points at which the flow is open at width dy_Cu, in depth units. + Dblock_u, & !< Topographic depths at u-points at which the flow is blocked [Z ~> m]. + Dopen_u !< Topographic depths at u-points at which the flow is open at width dy_Cu [Z ~> m]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: & - Dblock_v, & !< Topographic depths at v-points at which the flow is blocked, in depth units. - Dopen_v !< Topographic depths at v-points at which the flow is open at width dx_Cv, in depth units. + Dblock_v, & !< Topographic depths at v-points at which the flow is blocked [Z ~> m]. + Dopen_v !< Topographic depths at v-points at which the flow is open at width dx_Cv [Z ~> m]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & - CoriolisBu !< The Coriolis parameter at corner points, in s-1. + CoriolisBu !< The Coriolis parameter at corner points [s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - df_dx, & !< Derivative d/dx f (Coriolis parameter) at h-points, in s-1 m-1. - df_dy !< Derivative d/dy f (Coriolis parameter) at h-points, in s-1 m-1. - real :: g_Earth !< The gravitational acceleration in m s-2. + df_dx, & !< Derivative d/dx f (Coriolis parameter) at h-points [s-1 m-1]. + df_dy !< Derivative d/dy f (Coriolis parameter) at h-points [s-1 m-1]. + real :: g_Earth !< The gravitational acceleration [m s-2]. ! These variables are global sums that are useful for 1-d diagnostics - real :: areaT_global !< Global sum of h-cell area in m2 - real :: IareaT_global !< Global sum of inverse h-cell area (1/areaT_global) in m2. + real :: areaT_global !< Global sum of h-cell area [m2] + real :: IareaT_global !< Global sum of inverse h-cell area (1/areaT_global) [m2]. ! These variables are for block structures. integer :: nblocks !< The number of sub-PE blocks on this PE @@ -163,8 +168,8 @@ module MOM_grid real :: west_lon !< The longitude (or x-coordinate) of the first u-line real :: len_lat = 0. !< The latitudinal (or y-coord) extent of physical domain real :: len_lon = 0. !< The longitudinal (or x-coord) extent of physical domain - real :: Rad_Earth = 6.378e6 !< The radius of the planet in meters. - real :: max_depth !< The maximum depth of the ocean in depth units (Z). + real :: Rad_Earth = 6.378e6 !< The radius of the planet [m]. + real :: max_depth !< The maximum depth of the ocean in depth units [Z ~> m]. end type ocean_grid_type contains diff --git a/src/core/MOM_interface_heights.F90 b/src/core/MOM_interface_heights.F90 index 745e8c5b39..de0064932d 100644 --- a/src/core/MOM_interface_heights.F90 +++ b/src/core/MOM_interface_heights.F90 @@ -32,17 +32,15 @@ subroutine find_eta_3d(h, tv, G, GV, US, eta, eta_bt, halo_size, eta_to_m) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). - type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to - !! various thermodynamic - !! variables. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various + !! thermodynamic variables. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(out) :: eta !< layer interface heights - !! (Z or 1/eta_to_m m). + !! [Z ~> m] or 1/eta_to_m m). real, dimension(SZI_(G),SZJ_(G)), optional, intent(in) :: eta_bt !< optional barotropic !! variable that gives the "correct" free surface height (Boussinesq) or total water !! column mass per unit area (non-Boussinesq). This is used to dilate the layer. - !! thicknesses when calculating interfaceheights, in H (m or kg m-2). + !! thicknesses when calculating interfaceheights [H ~> m or kg m-2]. integer, optional, intent(in) :: halo_size !< width of halo points on !! which to calculate eta. real, optional, intent(in) :: eta_to_m !< The conversion factor from @@ -51,7 +49,7 @@ subroutine find_eta_3d(h, tv, G, GV, US, eta, eta_bt, halo_size, eta_to_m) ! Local variables real :: p(SZI_(G),SZJ_(G),SZK_(G)+1) real :: dz_geo(SZI_(G),SZJ_(G),SZK_(G)) ! The change in geopotential height - ! across a layer, in m2 s-2. + ! across a layer [m2 s-2]. real :: dilate(SZI_(G)) ! non-dimensional dilation factor real :: htot(SZI_(G)) ! total thickness H real :: I_gEarth @@ -147,27 +145,24 @@ subroutine find_eta_2d(h, tv, G, GV, US, eta, eta_bt, halo_size, eta_to_m) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). - type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to - !! various thermodynamic - !! variables. - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta !< free surface height - !! relative to mean sea - !! level (z=0) (m). + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various + !! thermodynamic variables. + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta !< free surface height relative to + !! mean sea level (z=0) often [Z ~> m]. real, dimension(SZI_(G),SZJ_(G)), optional, intent(in) :: eta_bt !< optional barotropic !! variable that gives the "correct" free surface height (Boussinesq) or total - !! water column mass per unit area (non-Boussinesq), in H (m or kg m-2). + !! water column mass per unit area (non-Boussinesq) [H ~> m or kg m-2]. integer, optional, intent(in) :: halo_size !< width of halo points on !! which to calculate eta. real, optional, intent(in) :: eta_to_m !< The conversion factor from !! the units of eta to m; by default this is US%Z_to_m. ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: & - p ! The pressure in Pa. + p ! The pressure at interfaces [Pa]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - dz_geo ! The change in geopotential height across a layer, in m2 s-2. - real :: htot(SZI_(G)) ! The sum of all layers' thicknesses, in H. + dz_geo ! The change in geopotential height across a layer [m2 s-2]. + real :: htot(SZI_(G)) ! The sum of all layers' thicknesses [H ~> m or kg m-2]. real :: I_gEarth real :: Z_to_eta, H_to_eta, H_to_rho_eta ! Unit conversion factors with obvious names. integer i, j, k, is, ie, js, je, nz, halo diff --git a/src/core/MOM_isopycnal_slopes.F90 b/src/core/MOM_isopycnal_slopes.F90 index c6bbff50fd..11975aa5dc 100644 --- a/src/core/MOM_isopycnal_slopes.F90 +++ b/src/core/MOM_isopycnal_slopes.F90 @@ -15,6 +15,11 @@ module MOM_isopycnal_slopes public calc_isoneutral_slopes +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Calculate isopycnal slopes, and optionally return N2 used in calculation. @@ -23,67 +28,68 @@ subroutine calc_isoneutral_slopes(G, GV, US, h, e, tv, dt_kappa_smooth, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface heights (in Z or units + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface heights [Z ~> m] or units !! given by 1/eta_to_m) type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables real, intent(in) :: dt_kappa_smooth !< A smoothing vertical diffusivity - !! times a smoothing timescale, in Z2. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: slope_x !< Isopycnal slope in i-direction (nondim) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(inout) :: slope_y !< Isopycnal slope in j-direction (nondim) + !! times a smoothing timescale [Z2 ~> m2]. + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: slope_x !< Isopycnal slope in i-direction [nondim] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(inout) :: slope_y !< Isopycnal slope in j-direction [nondim] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), & optional, intent(inout) :: N2_u !< Brunt-Vaisala frequency squared at - !! interfaces between u-points (s-2) + !! interfaces between u-points [s-2] real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), & optional, intent(inout) :: N2_v !< Brunt-Vaisala frequency squared at - !! interfaces between u-points (s-2) + !! interfaces between u-points [s-2] integer, optional, intent(in) :: halo !< Halo width over which to compute ! real, optional, intent(in) :: eta_to_m !< The conversion factor from the units ! (This argument has been tested but for now serves no purpose.) !! of eta to m; US%Z_to_m by default. ! Local variables real, dimension(SZI_(G), SZJ_(G), SZK_(G)) :: & - T, & ! The temperature (or density) in C, with the values in + T, & ! The temperature [degC], with the values in ! in massless layers filled vertically by diffusion. - S, & ! The filled salinity, in PSU, with the values in + S, & ! The filled salinity [ppt], with the values in ! in massless layers filled vertically by diffusion. - Rho ! Density itself, when a nonlinear equation of state is - ! not in use. + Rho ! Density itself, when a nonlinear equation of state is not in use [kg m-3]. real, dimension(SZI_(G), SZJ_(G), SZK_(G)+1) :: & - pres ! The pressure at an interface, in Pa. + pres ! The pressure at an interface [Pa]. real, dimension(SZIB_(G)) :: & - drho_dT_u, & ! The derivatives of density with temperature and - drho_dS_u ! salinity at u points, in kg m-3 K-1 and kg m-3 psu-1. + drho_dT_u, & ! The derivative of density with temperature at u points [kg m-3 degC-1]. + drho_dS_u ! The derivative of density with salinity at u points [kg m-3 ppt-1]. real, dimension(SZI_(G)) :: & - drho_dT_v, & ! The derivatives of density with temperature and - drho_dS_v ! salinity at v points, in kg m-3 K-1 and kg m-3 psu-1. + drho_dT_v, & ! The derivative of density with temperature at v points [kg m-3 degC-1]. + drho_dS_v ! The derivative of density with salinity at v points [kg m-3 ppt-1]. real, dimension(SZIB_(G)) :: & - T_u, S_u, & ! Temperature, salinity, and pressure on the interface at - pres_u ! the u-point in the horizontal. + T_u, & ! Temperature on the interface at the u-point [degC]. + S_u, & ! Salinity on the interface at the u-point [ppt]. + pres_u ! Pressure on the interface at the u-point [Pa]. real, dimension(SZI_(G)) :: & - T_v, S_v, & ! Temperature, salinity, and pressure on the interface at - pres_v ! the v-point in the horizontal. + T_v, & ! Temperature on the interface at the v-point [degC]. + S_v, & ! Salinity on the interface at the v-point [ppt]. + pres_v ! Pressure on the interface at the v-point [Pa]. real :: drdiA, drdiB ! Along layer zonal- and meridional- potential density real :: drdjA, drdjB ! gradients in the layers above (A) and below(B) the - ! interface times the grid spacing, in kg m-3. - real :: drdkL, drdkR ! Vertical density differences across an interface, - ! in kg m-3. - real :: hg2A, hg2B, hg2L, hg2R ! Squares of geometric mean thicknesses, in H2. - real :: haA, haB, haL, haR ! Arithmetic mean thicknesses in H. - real :: dzaL, dzaR ! Temporary thicknesses in eta units (Z?). + ! interface times the grid spacing [kg m-3]. + real :: drdkL, drdkR ! Vertical density differences across an interface [kg m-3]. + real :: hg2A, hg2B ! Squares of geometric mean thicknesses [H2 ~> m2 or kg2 m-4]. + real :: hg2L, hg2R ! Squares of geometric mean thicknesses [H2 ~> m2 or kg2 m-4]. + real :: haA, haB, haL, haR ! Arithmetic mean thicknesses [H ~> m or kg m-2]. + real :: dzaL, dzaR ! Temporary thicknesses in eta units [Z ~> m]. real :: wtA, wtB, wtL, wtR ! Unscaled weights, with various units. - real :: drdx, drdy ! Zonal and meridional density gradients, in kg m-4. - real :: drdz ! Vertical density gradient, in units of kg m-3 Z-1. + real :: drdx, drdy ! Zonal and meridional density gradients [kg m-4]. + real :: drdz ! Vertical density gradient [kg m-3 Z-1 ~> kg m-4]. real :: Slope ! The slope of density surfaces, calculated in a way ! that is always between -1 and 1. - real :: mag_grad2 ! The squared magnitude of the 3-d density gradient, in kg2 m-8. + real :: mag_grad2 ! The squared magnitude of the 3-d density gradient [kg2 m-8]. real :: slope2_Ratio ! The ratio of the slope squared to slope_max squared. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: h_neglect2 ! h_neglect^2, in H2. - real :: dz_neglect ! A thickness in m that is so small it is usually lost - ! in roundoff and can be neglected, in eta units (Z?). + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: h_neglect2 ! h_neglect^2 [H2 ~> m2 or kg2 m-4]. + real :: dz_neglect ! A change in interface heighs that is so small it is usually lost + ! in roundoff and can be neglected [Z ~> m]. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. real :: G_Rho0, N2, dzN2, H_x(SZIB_(G)), H_y(SZI_(G)) @@ -228,7 +234,7 @@ subroutine calc_isoneutral_slopes(G, GV, US, h, e, tv, dt_kappa_smooth, & slope_x(I,j,K) = 0.0 endif - if (present_N2_u) N2_u(I,j,k) = G_Rho0 * drdz * G%mask2dCu(I,j) ! Square of Brunt-Vaisala frequency (s-2) + if (present_N2_u) N2_u(I,j,k) = G_Rho0 * drdz * G%mask2dCu(I,j) ! Square of Brunt-Vaisala frequency [s-2] else ! With .not.use_EOS, the layers are constant density. slope_x(I,j,K) = (Z_to_L*(e(i,j,K)-e(i+1,j,K))) * G%IdxCu(I,j) @@ -312,7 +318,7 @@ subroutine calc_isoneutral_slopes(G, GV, US, h, e, tv, dt_kappa_smooth, & slope_y(i,J,K) = 0.0 endif - if (present_N2_v) N2_v(i,J,k) = G_Rho0 * drdz * G%mask2dCv(i,J) ! Square of Brunt-Vaisala frequency (s-2) + if (present_N2_v) N2_v(i,J,k) = G_Rho0 * drdz * G%mask2dCv(i,J) ! Square of Brunt-Vaisala frequency [s-2] else ! With .not.use_EOS, the layers are constant density. slope_y(i,J,K) = (Z_to_L*(e(i,j,K)-e(i,j+1,K))) * G%IdyCv(i,J) @@ -328,22 +334,22 @@ end subroutine calc_isoneutral_slopes subroutine vert_fill_TS(h, T_in, S_in, kappa_dt, T_f, S_f, G, GV, halo_here) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T_in !< Temperature (deg C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S_in !< Salinity (psu) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T_in !< Temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S_in !< Salinity [ppt] real, intent(in) :: kappa_dt !< A vertical diffusivity to use for smoothing - !! times a smoothing timescale, in Z2. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T_f !< Filled temperature (deg C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S_f !< Filed salinity (psu) + !! times a smoothing timescale [Z2 ~> m2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T_f !< Filled temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S_f !< Filed salinity [ppt] integer, optional, intent(in) :: halo_here !< Halo width over which to compute ! Local variables real :: ent(SZI_(G),SZK_(G)+1) ! The diffusive entrainment (kappa*dt)/dz - ! between layers in a timestep in m or kg m-2. + ! between layers in a timestep [H ~> m or kg m-2]. real :: b1(SZI_(G)), d1(SZI_(G)) ! b1, c1, and d1 are variables used by the real :: c1(SZI_(G),SZK_(G)) ! tridiagonal solver. real :: kap_dt_x2 ! The product of 2*kappa*dt, converted to - ! the same units as h, in m2 or kg2 m-4. - real :: h_neglect ! A negligible thickness, in m or kg m-2, to + ! the same units as h squared, [H2 ~> m2 or kg2 m-4]. + real :: h_neglect ! A negligible thickness [H ~> m or kg m-2], to ! allow for zero thicknesses. integer :: i, j, k, is, ie, js, je, nz, halo diff --git a/src/core/MOM_open_boundary.F90 b/src/core/MOM_open_boundary.F90 index 8fd4cc06f5..c59eafc4c2 100644 --- a/src/core/MOM_open_boundary.F90 +++ b/src/core/MOM_open_boundary.F90 @@ -73,9 +73,9 @@ module MOM_open_boundary real, pointer, dimension(:,:,:) :: buffer_src=>NULL() !< buffer for segment data located at cell faces !! and on the original vertical grid integer :: nk_src !< Number of vertical levels in the source data - real, dimension(:,:,:), pointer :: dz_src=>NULL() !< vertical grid cell spacing of the incoming segment data (m) + real, dimension(:,:,:), pointer :: dz_src=>NULL() !< vertical grid cell spacing of the incoming segment data [m] real, dimension(:,:,:), pointer :: buffer_dst=>NULL() !< buffer src data remapped to the target vertical grid - real, dimension(:,:), pointer :: bt_vel=>NULL() !< barotropic velocity (m s-1) + real, dimension(:,:), pointer :: bt_vel=>NULL() !< barotropic velocity [m s-1] real :: value !< constant value if fid is equal to -1 end type OBC_segment_data_type @@ -135,32 +135,32 @@ module MOM_open_boundary integer :: Ie_obc !< i-indices of boundary segment. integer :: Js_obc !< j-indices of boundary segment. integer :: Je_obc !< j-indices of boundary segment. - real :: Velocity_nudging_timescale_in !< Nudging timescale on inflow (s). - real :: Velocity_nudging_timescale_out !< Nudging timescale on outflow (s). + real :: Velocity_nudging_timescale_in !< Nudging timescale on inflow [s]. + real :: Velocity_nudging_timescale_out !< Nudging timescale on outflow [s]. logical :: on_pe !< true if segment is located in the computational domain logical :: temp_segment_data_exists !< true if temperature data arrays are present logical :: salt_segment_data_exists !< true if salinity data arrays are present - real, pointer, dimension(:,:) :: Cg=>NULL() !< The external gravity - !! wave speed (m -s) at OBC-points. - real, pointer, dimension(:,:) :: Htot=>NULL() !< The total column thickness (m) at OBC-points. - real, pointer, dimension(:,:,:) :: h=>NULL() !< The cell thickness (m) at OBC-points. + real, pointer, dimension(:,:) :: Cg=>NULL() !< The external gravity wave speed [m s-1] + !! at OBC-points. + real, pointer, dimension(:,:) :: Htot=>NULL() !< The total column thickness [m] at OBC-points. + real, pointer, dimension(:,:,:) :: h=>NULL() !< The cell thickness [m] at OBC-points. real, pointer, dimension(:,:,:) :: normal_vel=>NULL() !< The layer velocity normal to the OB - !! segment (m s-1). + !! segment [m s-1]. real, pointer, dimension(:,:,:) :: tangential_vel=>NULL() !< The layer velocity tangential to the - !! OB segment (m s-1). + !! OB segment [m s-1]. real, pointer, dimension(:,:,:) :: tangential_grad=>NULL() !< The gradient of the velocity tangential - !! to the OB segment (m s-1). + !! to the OB segment [m s-1]. real, pointer, dimension(:,:,:) :: normal_trans=>NULL() !< The layer transport normal to the OB - !! segment (m3 s-1). + !! segment [m3 s-1]. real, pointer, dimension(:,:) :: normal_vel_bt=>NULL() !< The barotropic velocity normal to - !! the OB segment (m s-1). - real, pointer, dimension(:,:) :: eta=>NULL() !< The sea-surface elevation along the segment (m). + !! the OB segment [m s-1]. + real, pointer, dimension(:,:) :: eta=>NULL() !< The sea-surface elevation along the segment [m]. real, pointer, dimension(:,:,:) :: grad_normal=>NULL() !< The gradient of the normal flow along the - !! segment (s-1) + !! segment [s-1] real, pointer, dimension(:,:,:) :: grad_tan=>NULL() !< The gradient of the tangential flow along the - !! segment (s-1) + !! segment [s-1] real, pointer, dimension(:,:,:) :: grad_gradient=>NULL() !< The gradient of the gradient of tangential flow along the - !! segment (m-1 s-1) + !! segment [m-1 s-1] real, pointer, dimension(:,:,:) :: rx_normal=>NULL() !< The rx_old_u value for radiation coeff !! for normal velocity real, pointer, dimension(:,:,:) :: ry_normal=>NULL() !< The tangential value for radiation coeff @@ -168,14 +168,14 @@ module MOM_open_boundary real, pointer, dimension(:,:,:) :: cff_normal=>NULL() !< The denominator for oblique radiation !! for normal velocity real, pointer, dimension(:,:,:) :: nudged_normal_vel=>NULL() !< The layer velocity normal to the OB segment - !! that values should be nudged towards (m s-1). + !! that values should be nudged towards [m s-1]. real, pointer, dimension(:,:,:) :: nudged_tangential_vel=>NULL() !< The layer velocity tangential to the OB segment - !! that values should be nudged towards (m s-1). + !! that values should be nudged towards [m s-1]. real, pointer, dimension(:,:,:) :: nudged_tangential_grad=>NULL() !< The layer dvdx or dudy towards which nudging - !! can occur (s-1). + !! can occur [s-1]. type(segment_tracer_registry_type), pointer :: tr_Reg=> NULL()!< A pointer to the tracer registry for the segment. type(hor_index_type) :: HI !< Horizontal index ranges - real :: Tr_InvLscale3_out !< An effective inverse length scale cubed (m-3) + real :: Tr_InvLscale3_out !< An effective inverse length scale cubed [m-3] real :: Tr_InvLscale3_in !< for restoring the tracer concentration in a !! ficticious reservior towards interior values !! when flow is exiting the domain, or towards @@ -226,7 +226,7 @@ module MOM_open_boundary logical :: zero_biharmonic = .false. !< If True, zeros the Laplacian of flow on open boundaries for !! use in the biharmonic viscosity term. logical :: brushcutter_mode = .false. !< If True, read data on supergrid. - real :: g_Earth !< The gravitational acceleration in m s-2. + real :: g_Earth !< The gravitational acceleration [m s-2]. ! Properties of the segments used. type(OBC_segment_type), pointer, dimension(:) :: & segment => NULL() !< List of segment objects. @@ -241,7 +241,7 @@ module MOM_open_boundary !! new time level (1) or the running mean (0) for velocities. !! Valid values range from 0 to 1, with a default of 0.3. real :: rx_max !< The maximum magnitude of the baroclinic radiation - !! velocity (or speed of characteristics), in m s-1. The + !! velocity (or speed of characteristics) [m s-1]. The !! default value is 10 m s-1. logical :: OBC_pe !< Is there an open boundary on this tile? type(remapping_CS), pointer :: remap_CS !< ALE remapping control structure for segments only @@ -251,10 +251,10 @@ module MOM_open_boundary real, pointer, dimension(:,:,:) :: cff_normal => NULL() !< Array storage for restarts real :: silly_h !< A silly value of thickness outside of the domain that !! can be used to test the independence of the OBCs to - !! this external data, in m. + !! this external data [H ~> m or kg m-2]. real :: silly_u !< A silly value of velocity outside of the domain that !! can be used to test the independence of the OBCs to - !! this external data, in m/s. + !! this external data [m s-1]. end type ocean_OBC_type !> Control structure for open boundaries that read from files. @@ -1412,8 +1412,8 @@ end subroutine open_boundary_impose_normal_slope subroutine open_boundary_impose_land_mask(OBC, G, areaCu, areaCv) type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure type(dyn_horgrid_type), intent(inout) :: G !< Ocean grid structure - real, dimension(SZIB_(G),SZJ_(G)), intent(inout) :: areaCu !< Area of a u-cell (m2) - real, dimension(SZI_(G),SZJB_(G)), intent(inout) :: areaCv !< Area of a u-cell (m2) + real, dimension(SZIB_(G),SZJ_(G)), intent(inout) :: areaCu !< Area of a u-cell [m2] + real, dimension(SZI_(G),SZJB_(G)), intent(inout) :: areaCv !< Area of a u-cell [m2] ! Local variables integer :: i, j, n type(OBC_segment_type), pointer :: segment => NULL() @@ -2836,8 +2836,8 @@ end subroutine deallocate_OBC_segment_data subroutine open_boundary_test_extern_uv(G, OBC, u, v) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(ocean_OBC_type), pointer :: OBC !< Open boundary structure - real, dimension(SZIB_(G),SZJ_(G), SZK_(G)),intent(inout) :: u !< Zonal velocity (m/s) - real, dimension(SZI_(G),SZJB_(G), SZK_(G)),intent(inout) :: v !< Meridional velocity (m/s) + real, dimension(SZIB_(G),SZJ_(G), SZK_(G)),intent(inout) :: u !< Zonal velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G), SZK_(G)),intent(inout) :: v !< Meridional velocity [m s-1] ! Local variables integer :: i, j, k, n @@ -2879,7 +2879,7 @@ end subroutine open_boundary_test_extern_uv subroutine open_boundary_test_extern_h(G, OBC, h) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(ocean_OBC_type), pointer :: OBC !< Open boundary structure - real, dimension(SZI_(G),SZJ_(G), SZK_(G)),intent(inout) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G), SZK_(G)),intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] ! Local variables integer :: i, j, k, n @@ -2921,7 +2921,7 @@ subroutine update_OBC_segment_data(G, GV, OBC, tv, h, Time) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(ocean_OBC_type), pointer :: OBC !< Open boundary structure type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(inout) :: h !< Thickness + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(inout) :: h !< Thickness [m] type(time_type), intent(in) :: Time !< Model time ! Local variables integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed @@ -2930,7 +2930,7 @@ subroutine update_OBC_segment_data(G, GV, OBC, tv, h, Time) character(len=200) :: filename, OBC_file, inputdir ! Strings for file/path type(OBC_segment_type), pointer :: segment => NULL() integer, dimension(4) :: siz,siz2 - real :: sumh ! column sum of thicknesses (m) + real :: sumh ! column sum of thicknesses [m] integer :: ni_seg, nj_seg ! number of src gridpoints along the segments integer :: i2, j2 ! indices for referencing local domain array integer :: is_obc, ie_obc, js_obc, je_obc ! segment indices within local domain diff --git a/src/core/MOM_variables.F90 b/src/core/MOM_variables.F90 index 4aa14cb082..c623848c15 100644 --- a/src/core/MOM_variables.F90 +++ b/src/core/MOM_variables.F90 @@ -19,6 +19,11 @@ module MOM_variables public allocate_surface_state, deallocate_surface_state, MOM_thermovar_chksum public ocean_grid_type, alloc_BT_cont_type, dealloc_BT_cont_type +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> A structure for creating arrays of pointers to 3D arrays type, public :: p3d real, dimension(:,:,:), pointer :: p => NULL() !< A pointer to a 3D array @@ -32,38 +37,38 @@ module MOM_variables !! will be returned to a the calling program type, public :: surface real, allocatable, dimension(:,:) :: & - SST, & !< The sea surface temperature in C. - SSS, & !< The sea surface salinity in psu. - sfc_density, & !< The mixed layer density in kg m-3. - Hml, & !< The mixed layer depth in m. - u, & !< The mixed layer zonal velocity in m s-1. - v, & !< The mixed layer meridional velocity in m s-1. - sea_lev, & !< The sea level in m. If a reduced surface gravity is + SST, & !< The sea surface temperature [degC]. + SSS, & !< The sea surface salinity [ppt ~> psu or gSalt/kg]. + sfc_density, & !< The mixed layer density [kg m-3]. + Hml, & !< The mixed layer depth [m]. + u, & !< The mixed layer zonal velocity [m s-1]. + v, & !< The mixed layer meridional velocity [m s-1]. + sea_lev, & !< The sea level [m]. If a reduced surface gravity is !! used, that is compensated for in sea_lev. - melt_potential, & !< instantaneous amount of heat that can be used to melt sea ice, - !! in J m-2. This is computed w.r.t. surface freezing temperature. - ocean_mass, & !< The total mass of the ocean in kg m-2. - ocean_heat, & !< The total heat content of the ocean in C kg m-2. - ocean_salt, & !< The total salt content of the ocean in kgSalt m-2. + melt_potential, & !< Instantaneous amount of heat that can be used to melt sea ice [J m-2]. + !! This is computed w.r.t. surface freezing temperature. + ocean_mass, & !< The total mass of the ocean [kg m-2]. + ocean_heat, & !< The total heat content of the ocean in [degC kg m-2]. + ocean_salt, & !< The total salt content of the ocean in [kgSalt m-2]. salt_deficit !< The salt needed to maintain the ocean column at a minimum - !! salinity of 0.01 PSU over the call to step_MOM, in kgSalt m-2. + !! salinity of 0.01 PSU over the call to step_MOM [kgSalt m-2]. logical :: T_is_conT = .false. !< If true, the temperature variable SST is actually the - !! conservative temperature, in degC. + !! conservative temperature in [degC]. logical :: S_is_absS = .false. !< If true, the salinity variable SSS is actually the - !! absolute salinity, in g/kg. + !! absolute salinity in [g/kg]. real, pointer, dimension(:,:) :: & - taux_shelf => NULL(), & !< The zonal stresses on the ocean under shelves, in Pa. - tauy_shelf => NULL() !< The meridional stresses on the ocean under shelves, in Pa. + taux_shelf => NULL(), & !< The zonal stresses on the ocean under shelves [Pa]. + tauy_shelf => NULL() !< The meridional stresses on the ocean under shelves [Pa]. real, pointer, dimension(:,:) :: frazil => NULL() !< The energy needed to heat the ocean column to the freezing point during the call - !! to step_MOM, in J m-2. + !! to step_MOM [J m-2]. real, pointer, dimension(:,:) :: TempxPmE => NULL() !< The net inflow of water into the ocean times the temperature at which this inflow - !! occurs during the call to step_MOM, in deg C kg m-2. This should be prescribed in the + !! occurs during the call to step_MOM [degC kg m-2]. This should be prescribed in the !! forcing fields, but as it often is not, this is a useful heat budget diagnostic. real, pointer, dimension(:,:) :: internal_heat => NULL() !< Any internal or geothermal heat sources that are applied to the ocean integrated - !! over the call to step_MOM, in deg C kg m-2. + !! over the call to step_MOM [degC kg m-2]. type(coupler_2d_bc_type) :: tr_fields !< A structure that may contain an !! array of named fields describing tracer-related quantities. !### NOTE: ALL OF THE ARRAYS IN TR_FIELDS USE THE COUPLER'S INDEXING CONVENTION AND HAVE NO @@ -76,41 +81,39 @@ module MOM_variables !! potential temperature, salinity, heat capacity, and the equation of state control structure. type, public :: thermo_var_ptrs ! If allocated, the following variables have nz layers. - real, pointer :: T(:,:,:) => NULL() !< Potential temperature in C. - real, pointer :: S(:,:,:) => NULL() !< Salnity in psu or ppt. + real, pointer :: T(:,:,:) => NULL() !< Potential temperature [degC]. + real, pointer :: S(:,:,:) => NULL() !< Salnity [PSU] or [gSalt/kg], generically [ppt]. type(EOS_type), pointer :: eqn_of_state => NULL() !< Type that indicates the !! equation of state to use. - real :: P_Ref !< The coordinate-density reference pressure in Pa. + real :: P_Ref !< The coordinate-density reference pressure [Pa]. !! This is the pressure used to calculate Rml from !! T and S when eqn_of_state is associated. - real :: C_p !< The heat capacity of seawater, in J K-1 kg-1. + real :: C_p !< The heat capacity of seawater [J degC-1 kg-1]. !! When conservative temperature is used, this is - !! constant and exactly 3991.86795711963 J K kg-1. + !! constant and exactly 3991.86795711963 J degC-1 kg-1. logical :: T_is_conT = .false. !< If true, the temperature variable tv%T is - !! actually the conservative temperature, in degC. + !! actually the conservative temperature [degC]. logical :: S_is_absS = .false. !< If true, the salinity variable tv%S is - !! actually the absolute salinity, in g/kg. + !! actually the absolute salinity in units of [gSalt/kg]. ! These arrays are accumulated fluxes for communication with other components. real, dimension(:,:), pointer :: frazil => NULL() !< The energy needed to heat the ocean column to the - !! freezing point since calculate_surface_state was - !! last called, in units of J m-2. + !! freezing point since calculate_surface_state was2 + !! last called [J m-2]. real, dimension(:,:), pointer :: salt_deficit => NULL() !< The salt needed to maintain the ocean column !! at a minumum salinity of 0.01 PSU since the last time - !! that calculate_surface_state was called, in units - !! of gSalt m-2. + !! that calculate_surface_state was called, [gSalt m-2]. real, dimension(:,:), pointer :: TempxPmE => NULL() !< The net inflow of water into the ocean times the !! temperature at which this inflow occurs since the - !! last call to calculate_surface_state, in units of - !! deg C kg m-2. This should be prescribed in the - !! forcing fields, but as it often is not, this is a - !! useful heat budget diagnostic. + !! last call to calculate_surface_state [degC kg m-2]. + !! This should be prescribed in the forcing fields, but + !! as it often is not, this is a useful heat budget diagnostic. real, dimension(:,:), pointer :: internal_heat => NULL() !< Any internal or geothermal heat sources that !! have been applied to the ocean since the last call to - !! calculate_surface_state, in units of deg C kg m-2. + !! calculate_surface_state [degC kg m-2]. end type thermo_var_ptrs !> Pointers to all of the prognostic variables allocated in MOM_variables.F90 and MOM.F90. @@ -120,29 +123,30 @@ module MOM_variables !! they refer to in MOM.F90. type, public :: ocean_internal_state real, pointer, dimension(:,:,:) :: & - T => NULL(), & !< Pointer to the temperature state variable, in deg C - S => NULL(), & !< Pointer to the salinity state variable, in PSU or g/kg - u => NULL(), & !< Pointer to the zonal velocity, in m s-1 - v => NULL(), & !< Pointer to the meridional velocity, in m s-1 - h => NULL() !< Pointer to the layer thicknesses, in H (often m or kg m-2) + T => NULL(), & !< Pointer to the temperature state variable [degC] + S => NULL(), & !< Pointer to the salinity state variable [ppt ~> PSU or g/kg] + u => NULL(), & !< Pointer to the zonal velocity [m s-1] + v => NULL(), & !< Pointer to the meridional velocity [m s-1] + h => NULL() !< Pointer to the layer thicknesses [H ~> m or kg m-2] real, pointer, dimension(:,:,:) :: & - uh => NULL(), & !< Pointer to zonal transports, in H m2 s-1 - vh => NULL() !< Pointer to meridional transports, in H m2 s-1 + uh => NULL(), & !< Pointer to zonal transports [H m2 s-1 ~> m3 s-1 or kg s-1] + vh => NULL() !< Pointer to meridional transports [H m2 s-1 ~> m3 s-1 or kg s-1] real, pointer, dimension(:,:,:) :: & - CAu => NULL(), & !< Pointer to the zonal Coriolis and Advective acceleration, in m s-2 - CAv => NULL(), & !< Pointer to the meridional Coriolis and Advective acceleration, in m s-2 - PFu => NULL(), & !< Pointer to the zonal Pressure force acceleration, in m s-2 - PFv => NULL(), & !< Pointer to the meridional Pressure force acceleration, in m s-2 - diffu => NULL(), & !< Pointer to the zonal acceleration due to lateral viscosity, in m s-2 - diffv => NULL(), & !< Pointer to the meridional acceleration due to lateral viscosity, in m s-2 - pbce => NULL(), & !< Pointer to the baroclinic pressure force dependency on free surface movement, in s-2 - u_accel_bt => NULL(), & !< Pointer to the zonal barotropic-solver acceleration, in m s-2 - v_accel_bt => NULL() !< Pointer to the meridional barotropic-solver acceleration, in m s-2 + CAu => NULL(), & !< Pointer to the zonal Coriolis and Advective acceleration [m s-2] + CAv => NULL(), & !< Pointer to the meridional Coriolis and Advective acceleration [m s-2] + PFu => NULL(), & !< Pointer to the zonal Pressure force acceleration [m s-2] + PFv => NULL(), & !< Pointer to the meridional Pressure force acceleration [m s-2] + diffu => NULL(), & !< Pointer to the zonal acceleration due to lateral viscosity [m s-2] + diffv => NULL(), & !< Pointer to the meridional acceleration due to lateral viscosity [m s-2] + pbce => NULL(), & !< Pointer to the baroclinic pressure force dependency on free surface movement + !! [m2 s-2 H-1 ~> m s-2 or m4 kg-1 s-2] + u_accel_bt => NULL(), & !< Pointer to the zonal barotropic-solver acceleration [m s-2] + v_accel_bt => NULL() !< Pointer to the meridional barotropic-solver acceleration [m s-2] real, pointer, dimension(:,:,:) :: & - u_av => NULL(), & !< Pointer to zonal velocity averaged over the timestep, in m s-1 - v_av => NULL(), & !< Pointer to meridional velocity averaged over the timestep, in m s-1 - u_prev => NULL(), & !< Pointer to zonal velocity at the end of the last timestep, in m s-1 - v_prev => NULL() !< Pointer to meridional velocity at the end of the last timestep, in m s-1 + u_av => NULL(), & !< Pointer to zonal velocity averaged over the timestep [m s-1] + v_av => NULL(), & !< Pointer to meridional velocity averaged over the timestep [m s-1] + u_prev => NULL(), & !< Pointer to zonal velocity at the end of the last timestep [m s-1] + v_prev => NULL() !< Pointer to meridional velocity at the end of the last timestep [m s-1] end type ocean_internal_state !> Pointers to arrays with accelerations, which can later be used for derived diagnostics, like energy balances. @@ -150,28 +154,28 @@ module MOM_variables ! Each of the following fields has nz layers. real, pointer, dimension(:,:,:) :: & - diffu => NULL(), & !< Zonal acceleration due to along isopycnal viscosity, in m s-2. - diffv => NULL(), & !< Meridional acceleration due to along isopycnal viscosity, in m s-2. - CAu => NULL(), & !< Zonal Coriolis and momentum advection accelerations, in m s-2. - CAv => NULL(), & !< Meridional Coriolis and momentum advection accelerations, in m s-2. - PFu => NULL(), & !< Zonal acceleration due to pressure forces, in m s-2. - PFv => NULL(), & !< Meridional acceleration due to pressure forces, in m s-2. - du_dt_visc => NULL(), &!< Zonal acceleration due to vertical viscosity, in m s-2. - dv_dt_visc => NULL(), &!< Meridional acceleration due to vertical viscosity, in m s-2. - du_dt_dia => NULL(), & !< Zonal acceleration due to diapycnal mixing, in m s-2. - dv_dt_dia => NULL() !< Meridional acceleration due to diapycnal mixing, in m s-2. + diffu => NULL(), & !< Zonal acceleration due to along isopycnal viscosity [m s-2] + diffv => NULL(), & !< Meridional acceleration due to along isopycnal viscosity [m s-2] + CAu => NULL(), & !< Zonal Coriolis and momentum advection accelerations [m s-2] + CAv => NULL(), & !< Meridional Coriolis and momentum advection accelerations [m s-2] + PFu => NULL(), & !< Zonal acceleration due to pressure forces [m s-2] + PFv => NULL(), & !< Meridional acceleration due to pressure forces [m s-2] + du_dt_visc => NULL(), &!< Zonal acceleration due to vertical viscosity [m s-2] + dv_dt_visc => NULL(), &!< Meridional acceleration due to vertical viscosity [m s-2] + du_dt_dia => NULL(), & !< Zonal acceleration due to diapycnal mixing [m s-2] + dv_dt_dia => NULL() !< Meridional acceleration due to diapycnal mixing [m s-2] real, pointer, dimension(:,:,:) :: du_other => NULL() !< Zonal velocity changes due to any other processes that are - !! not due to any explicit accelerations, in m s-1. + !! not due to any explicit accelerations [m s-1]. real, pointer, dimension(:,:,:) :: dv_other => NULL() !< Meridional velocity changes due to any other processes that are - !! not due to any explicit accelerations, in m s-1. + !! not due to any explicit accelerations [m s-1]. ! These accelerations are sub-terms included in the accelerations above. - real, pointer :: gradKEu(:,:,:) => NULL() !< gradKEu = - d/dx(u2), in m s-2. - real, pointer :: gradKEv(:,:,:) => NULL() !< gradKEv = - d/dy(u2), in m s-2. - real, pointer :: rv_x_v(:,:,:) => NULL() !< rv_x_v = rv * v at u, in m s-2. - real, pointer :: rv_x_u(:,:,:) => NULL() !< rv_x_u = rv * u at v, in m s-2. + real, pointer :: gradKEu(:,:,:) => NULL() !< gradKEu = - d/dx(u2) [m s-2] + real, pointer :: gradKEv(:,:,:) => NULL() !< gradKEv = - d/dy(u2) [m s-2] + real, pointer :: rv_x_v(:,:,:) => NULL() !< rv_x_v = rv * v at u [m s-2] + real, pointer :: rv_x_u(:,:,:) => NULL() !< rv_x_u = rv * u at v [m s-2] end type accel_diag_ptrs @@ -180,109 +184,109 @@ module MOM_variables ! Each of the following fields has nz layers. real, pointer, dimension(:,:,:) :: & - uh => NULL(), & !< Resolved zonal layer thickness fluxes, in m3 s-1 or kg s-1 - vh => NULL(), & !< Resolved meridional layer thickness fluxes, in m3 s-1 or kg s-1 - uhGM => NULL(), & !< Isopycnal height diffusion induced zonal volume fluxes in m3 s-1 or kg s-1 - vhGM => NULL() !< Isopycnal height diffusion induced meridional volume fluxes in m3 s-1 or kg s-1 + uh => NULL(), & !< Resolved zonal layer thickness fluxes, [H m2 s-1 ~> m3 s-1 or kg s-1] + vh => NULL(), & !< Resolved meridional layer thickness fluxes, [H m2 s-1 ~> m3 s-1 or kg s-1] + uhGM => NULL(), & !< Isopycnal height diffusion induced zonal volume fluxes [H m2 s-1 ~> m3 s-1 or kg s-1] + vhGM => NULL() !< Isopycnal height diffusion induced meridional volume fluxes [H m2 s-1 ~> m3 s-1 or kg s-1] ! Each of the following fields is found at nz+1 interfaces. - real, pointer :: diapyc_vel(:,:,:) => NULL() !< The net diapycnal velocity, in m s-1 or kg m-2 s-1 + real, pointer :: diapyc_vel(:,:,:) => NULL() !< The net diapycnal velocity [H s-1 ~> m s-1 or kg m-2 s-1] end type cont_diag_ptrs !> Vertical viscosities, drag coefficients, and related fields. type, public :: vertvisc_type real :: Prandtl_turb !< The Prandtl number for the turbulent diffusion - !! that is captured in Kd_shear. + !! that is captured in Kd_shear [nondim]. real, pointer, dimension(:,:) :: & - bbl_thick_u => NULL(), & !< The bottom boundary layer thickness at the u-points, in Z. - bbl_thick_v => NULL(), & !< The bottom boundary layer thickness at the v-points, in Z. - kv_bbl_u => NULL(), & !< The bottom boundary layer viscosity at the u-points, in Z2 s-1. - kv_bbl_v => NULL(), & !< The bottom boundary layer viscosity at the v-points, in Z2 s-1. - ustar_BBL => NULL() !< The turbulence velocity in the bottom boundary layer at h points, in Z s-1. + bbl_thick_u => NULL(), & !< The bottom boundary layer thickness at the u-points [Z ~> m]. + bbl_thick_v => NULL(), & !< The bottom boundary layer thickness at the v-points [Z ~> m]. + kv_bbl_u => NULL(), & !< The bottom boundary layer viscosity at the u-points [Z2 s-1 ~> m2 s-1]. + kv_bbl_v => NULL(), & !< The bottom boundary layer viscosity at the v-points [Z2 s-1 ~> m2 s-1]. + ustar_BBL => NULL() !< The turbulence velocity in the bottom boundary layer at h points [Z s-1 ~> m s-1]. real, pointer, dimension(:,:) :: TKE_BBL => NULL() !< A term related to the bottom boundary layer source of turbulent kinetic - !! energy, currently in units of m3 s-3, but will later be changed to W m-2. + !! energy, currently in [m3 s-3], but will later be changed to [W m-2]. real, pointer, dimension(:,:) :: & - taux_shelf => NULL(), & !< The zonal stresses on the ocean under shelves, in Pa. - tauy_shelf => NULL() !< The meridional stresses on the ocean under shelves, in Pa. + taux_shelf => NULL(), & !< The zonal stresses on the ocean under shelves [Pa]. + tauy_shelf => NULL() !< The meridional stresses on the ocean under shelves [Pa]. real, pointer, dimension(:,:) :: tbl_thick_shelf_u => NULL() - !< Thickness of the viscous top boundary layer under ice shelves at u-points, in Z. + !< Thickness of the viscous top boundary layer under ice shelves at u-points [Z ~> m]. real, pointer, dimension(:,:) :: tbl_thick_shelf_v => NULL() - !< Thickness of the viscous top boundary layer under ice shelves at v-points, in Z. + !< Thickness of the viscous top boundary layer under ice shelves at v-points [Z ~> m]. real, pointer, dimension(:,:) :: kv_tbl_shelf_u => NULL() - !< Viscosity in the viscous top boundary layer under ice shelves at u-points, in Z2 s-1. + !< Viscosity in the viscous top boundary layer under ice shelves at u-points [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:) :: kv_tbl_shelf_v => NULL() - !< Viscosity in the viscous top boundary layer under ice shelves at v-points, in Z2 s-1. + !< Viscosity in the viscous top boundary layer under ice shelves at v-points [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:) :: nkml_visc_u => NULL() - !< The number of layers in the viscous surface mixed layer at u-points (nondimensional). + !< The number of layers in the viscous surface mixed layer at u-points [nondim]. !! This is not an integer because there may be fractional layers, and it is stored in !! terms of layers, not depth, to facilitate the movement of the viscous boundary layer !! with the flow. real, pointer, dimension(:,:) :: nkml_visc_v => NULL() - !< The number of layers in the viscous surface mixed layer at v-points (nondimensional). + !< The number of layers in the viscous surface mixed layer at v-points [nondim]. real, pointer, dimension(:,:) :: & - MLD => NULL() !< Instantaneous active mixing layer depth (H units). + MLD => NULL() !< Instantaneous active mixing layer depth [H ~> m or kg m-2]. real, pointer, dimension(:,:,:) :: & - Ray_u => NULL(), & !< The Rayleigh drag velocity to be applied to each layer at u-points, in Z s-1. - Ray_v => NULL() !< The Rayleigh drag velocity to be applied to each layer at v-points, in Z s-1. + Ray_u => NULL(), & !< The Rayleigh drag velocity to be applied to each layer at u-points [Z s-1 ~> m s-1]. + Ray_v => NULL() !< The Rayleigh drag velocity to be applied to each layer at v-points [Z s-1 ~> m s-1]. real, pointer, dimension(:,:,:) :: Kd_extra_T => NULL() !< The extra diffusivity of temperature due to double diffusion relative to the - !! diffusivity of density, in Z2 s-1. + !! diffusivity of density [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: Kd_extra_S => NULL() !< The extra diffusivity of salinity due to double diffusion relative to the - !! diffusivity of density, in Z2 s-1. + !! diffusivity of density [Z2 s-1 ~> m2 s-1]. ! One of Kd_extra_T and Kd_extra_S is always 0. Kd_extra_S is positive for salt fingering; ! Kd_extra_T is positive for double diffusive convection. They are only allocated if ! DOUBLE_DIFFUSION is true. real, pointer, dimension(:,:,:) :: Kd_shear => NULL() !< The shear-driven turbulent diapycnal diffusivity at the interfaces between layers - !! in tracer columns, in Z2 s-1. + !! in tracer columns [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: Kv_shear => NULL() !< The shear-driven turbulent vertical viscosity at the interfaces between layers - !! in tracer columns, in Z2 s-1. + !! in tracer columns [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: Kv_shear_Bu => NULL() !< The shear-driven turbulent vertical viscosity at the interfaces between layers in - !! corner columns, in Z2 s-1. + !! corner columns [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: Kv_slow => NULL() !< The turbulent vertical viscosity component due to "slow" processes (e.g., tidal, - !! background, convection etc), in Z2 s-1. + !! background, convection etc) [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: TKE_turb => NULL() - !< The turbulent kinetic energy per unit mass at the interfaces, in m2 s-2. + !< The turbulent kinetic energy per unit mass at the interfaces [m2 s-2]. !! This may be at the tracer or corner points - logical :: add_Kv_slow !< If True, add Kv_slow when calculating the 'coupling coefficient' (a[k]) - !! at the interfaces. This is done in find_coupling_coef. + logical :: add_Kv_slow !< If True, add Kv_slow when calculating the 'coupling coefficient' (a_cpl) + !! at the interfaces in find_coupling_coef. end type vertvisc_type !> Container for information about the summed layer transports !! and how they will vary as the barotropic velocity is changed. type, public :: BT_cont_type real, allocatable :: FA_u_EE(:,:) !< The effective open face area for zonal barotropic transport - !! drawing from locations far to the east, in H m. + !! drawing from locations far to the east [H m ~> m2 or kg m-1]. real, allocatable :: FA_u_E0(:,:) !< The effective open face area for zonal barotropic transport - !! drawing from nearby to the east, in H m. + !! drawing from nearby to the east [H m ~> m2 or kg m-1]. real, allocatable :: FA_u_W0(:,:) !< The effective open face area for zonal barotropic transport - !! drawing from nearby to the west, in H m. + !! drawing from nearby to the west [H m ~> m2 or kg m-1]. real, allocatable :: FA_u_WW(:,:) !< The effective open face area for zonal barotropic transport - !! drawing from locations far to the west, in H m. - real, allocatable :: uBT_WW(:,:) !< uBT_WW is the barotropic velocity, in m s-1, beyond which the marginal + !! drawing from locations far to the west [H m ~> m2 or kg m-1]. + real, allocatable :: uBT_WW(:,:) !< uBT_WW is the barotropic velocity [m s-1], beyond which the marginal !! open face area is FA_u_WW. uBT_WW must be non-negative. - real, allocatable :: uBT_EE(:,:) !< uBT_EE is a barotropic velocity, in m s-1, beyond which the marginal + real, allocatable :: uBT_EE(:,:) !< uBT_EE is a barotropic velocity [m s-1], beyond which the marginal !! open face area is FA_u_EE. uBT_EE must be non-positive. real, allocatable :: FA_v_NN(:,:) !< The effective open face area for meridional barotropic transport - !! drawing from locations far to the north, in H m. + !! drawing from locations far to the north [H m ~> m2 or kg m-1]. real, allocatable :: FA_v_N0(:,:) !< The effective open face area for meridional barotropic transport - !! drawing from nearby to the north, in H m. + !! drawing from nearby to the north [H m ~> m2 or kg m-1]. real, allocatable :: FA_v_S0(:,:) !< The effective open face area for meridional barotropic transport - !! drawing from nearby to the south, in H m. + !! drawing from nearby to the south [H m ~> m2 or kg m-1]. real, allocatable :: FA_v_SS(:,:) !< The effective open face area for meridional barotropic transport - !! drawing from locations far to the south, in H m. - real, allocatable :: vBT_SS(:,:) !< vBT_SS is the barotropic velocity, in m s-1, beyond which the marginal + !! drawing from locations far to the south [H m ~> m2 or kg m-1]. + real, allocatable :: vBT_SS(:,:) !< vBT_SS is the barotropic velocity, [m s-1], beyond which the marginal !! open face area is FA_v_SS. vBT_SS must be non-negative. - real, allocatable :: vBT_NN(:,:) !< vBT_NN is the barotropic velocity, in m s-1, beyond which the marginal + real, allocatable :: vBT_NN(:,:) !< vBT_NN is the barotropic velocity, [m s-1], beyond which the marginal !! open face area is FA_v_NN. vBT_NN must be non-positive. - real, allocatable :: h_u(:,:,:) !< An effective thickness at zonal faces, in H. - real, allocatable :: h_v(:,:,:) !< An effective thickness at meridional faces, in H. + real, allocatable :: h_u(:,:,:) !< An effective thickness at zonal faces [H ~> m or kg m-2]. + real, allocatable :: h_v(:,:,:) !< An effective thickness at meridional faces [H ~> m or kg m-2]. type(group_pass_type) :: pass_polarity_BT !< Structure for polarity group halo updates type(group_pass_type) :: pass_FA_uv !< Structure for face area group halo updates end type BT_cont_type diff --git a/src/core/MOM_verticalGrid.F90 b/src/core/MOM_verticalGrid.F90 index 92f303e12b..a824553a84 100644 --- a/src/core/MOM_verticalGrid.F90 +++ b/src/core/MOM_verticalGrid.F90 @@ -15,15 +15,20 @@ module MOM_verticalGrid public setVerticalGridAxes, fix_restart_scaling public get_flux_units, get_thickness_units, get_tr_flux_units +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Describes the vertical ocean grid, including unit conversion factors type, public :: verticalGrid_type ! Commonly used parameters integer :: ke !< The number of layers/levels in the vertical - real :: max_depth !< The maximum depth of the ocean in Z (often m). - real :: g_Earth !< The gravitational acceleration in m2 Z-1 s-2. + real :: max_depth !< The maximum depth of the ocean [Z ~> m]. + real :: g_Earth !< The gravitational acceleration [m2 Z-1 s-2 ~> m s-2]. real :: Rho0 !< The density used in the Boussinesq approximation or nominal - !! density used to convert depths into mass units, in kg m-3. + !! density used to convert depths into mass units [kg m-3]. ! Vertical coordinate descriptions for diagnostics and I/O character(len=40) :: zAxisUnits !< The units that vertical coordinates are written in @@ -35,15 +40,15 @@ module MOM_verticalGrid ! The following variables give information about the vertical grid. logical :: Boussinesq !< If true, make the Boussinesq approximation. - real :: Angstrom_H !< A one-Angstrom thickness in the model thickness units. - real :: Angstrom_Z !< A one-Angstrom thickness in the model depth units. - real :: Angstrom_m !< A one-Angstrom thickness in m. + real :: Angstrom_H !< A one-Angstrom thickness in the model thickness units [H ~> m or kg m-2]. + real :: Angstrom_Z !< A one-Angstrom thickness in the model depth units [Z ~> m]. + real :: Angstrom_m !< A one-Angstrom thickness [m]. real :: H_subroundoff !< A thickness that is so small that it can be added to a thickness of - !! Angstrom or larger without changing it at the bit level, in thickness units. + !! Angstrom or larger without changing it at the bit level [H ~> m or kg m-2]. !! If Angstrom is 0 or exceedingly small, this is negligible compared to 1e-17 m. real, allocatable, dimension(:) :: & - g_prime, & !< The reduced gravity at each interface, in m2 Z-1 s-2. - Rlay !< The target coordinate value (potential density) in each layer in kg m-3. + g_prime, & !< The reduced gravity at each interface [m2 Z-1 s-2 ~> m s-2]. + Rlay !< The target coordinate value (potential density) in each layer [kg m-3]. integer :: nkml = 0 !< The number of layers at the top that should be treated !! as parts of a homogenous region. integer :: nk_rho_varies = 0 !< The number of layers at the top where the @@ -52,7 +57,7 @@ module MOM_verticalGrid real :: kg_m2_to_H !< A constant that translates thicknesses from kg m-2 to the units of thickness. real :: m_to_H !< A constant that translates distances in m to the units of thickness. real :: H_to_m !< A constant that translates distances in the units of thickness to m. - real :: H_to_Pa !< A constant that translates the units of thickness to pressure in Pa. + real :: H_to_Pa !< A constant that translates the units of thickness to pressure [Pa]. real :: H_to_Z !< A constant that translates thickness units to the units of depth. real :: Z_to_H !< A constant that translates depth units to thickness units. diff --git a/src/diagnostics/MOM_PointAccel.F90 b/src/diagnostics/MOM_PointAccel.F90 index 7a03c1e06f..a642cd0205 100644 --- a/src/diagnostics/MOM_PointAccel.F90 +++ b/src/diagnostics/MOM_PointAccel.F90 @@ -47,17 +47,17 @@ module MOM_PointAccel ! that are used to step the physical model forward. They all use the same ! names as the variables they point to in MOM.F90 real, pointer, dimension(:,:,:) :: & - u_av => NULL(), & !< Time average u-velocity in m s-1. - v_av => NULL(), & !< Time average velocity in m s-1. - u_prev => NULL(), & !< Previous u-velocity in m s-1. - v_prev => NULL(), & !< Previous v-velocity in m s-1. - T => NULL(), & !< Temperature in deg C. - S => NULL(), & !< Salinity in ppt - u_accel_bt => NULL(), & !< Barotropic u-acclerations in m s-2. - v_accel_bt => NULL() !< Barotropic v-acclerations in m s-2. + u_av => NULL(), & !< Time average u-velocity [m s-1]. + v_av => NULL(), & !< Time average velocity [m s-1]. + u_prev => NULL(), & !< Previous u-velocity [m s-1]. + v_prev => NULL(), & !< Previous v-velocity [m s-1]. + T => NULL(), & !< Temperature [degC]. + S => NULL(), & !< Salinity [ppt]. + u_accel_bt => NULL(), & !< Barotropic u-acclerations [m s-2] + v_accel_bt => NULL() !< Barotropic v-acclerations [m s-2] real, pointer, dimension(:,:,:) :: pbce => NULL() !< pbce times eta gives the baroclinic - !! pressure anomaly in each layer due to free surface height anomalies. - !! pbce has units of m s-2. + !! pressure anomaly in each layer due to free surface height anomalies + !! [m2 s-2 H-1 ~> m s-2 or m4 kg-1 s-2]. end type PointAccel_CS @@ -73,24 +73,24 @@ subroutine write_u_accel(I, j, um, hin, ADp, CDp, dt, G, GV, US, CS, vel_rpt, st type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: um !< The new zonal velocity, in m s-1. + intent(in) :: um !< The new zonal velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: hin !< The layer thickness, in H. + intent(in) :: hin !< The layer thickness [H ~> m or kg m-2]. type(accel_diag_ptrs), intent(in) :: ADp !< A structure pointing to the various !! accelerations in the momentum equations. type(cont_diag_ptrs), intent(in) :: CDp !< A structure with pointers to various terms !! in the continuity equations. - real, intent(in) :: dt !< The ocean dynamics time step, in s. + real, intent(in) :: dt !< The ocean dynamics time step [s]. type(PointAccel_CS), pointer :: CS !< The control structure returned by a previous !! call to PointAccel_init. - real, intent(in) :: vel_rpt !< The velocity magnitude that triggers a report, in m s-1. + real, intent(in) :: vel_rpt !< The velocity magnitude that triggers a report [m s-1]. real, optional, intent(in) :: str !< The surface wind stress integrated over a time - !! step, in m2 s-1. + !! step divided by the Boussinesq density [m2 s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - optional, intent(in) :: a !< The layer coupling coefficients from vertvisc, Z s-1. + optional, intent(in) :: a !< The layer coupling coefficients from vertvisc [Z s-1 ~> m s-1]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & optional, intent(in) :: hv !< The layer thicknesses at velocity grid points, - !! from vertvisc, in H. + !! from vertvisc [H ~> m or kg m-2]. ! Local variables real :: f_eff, CFL real :: Angstrom @@ -404,24 +404,24 @@ subroutine write_v_accel(i, J, vm, hin, ADp, CDp, dt, G, GV, US, CS, vel_rpt, st type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: vm !< The new meridional velocity, in m s-1. + intent(in) :: vm !< The new meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: hin !< The layer thickness, in H. + intent(in) :: hin !< The layer thickness [H ~> m or kg m-2]. type(accel_diag_ptrs), intent(in) :: ADp !< A structure pointing to the various !! accelerations in the momentum equations. type(cont_diag_ptrs), intent(in) :: CDp !< A structure with pointers to various terms in !! the continuity equations. - real, intent(in) :: dt !< The ocean dynamics time step, in s. + real, intent(in) :: dt !< The ocean dynamics time step [s]. type(PointAccel_CS), pointer :: CS !< The control structure returned by a previous !! call to PointAccel_init. - real, intent(in) :: vel_rpt !< The velocity magnitude that triggers a report, in m s-1. + real, intent(in) :: vel_rpt !< The velocity magnitude that triggers a report [m s-1]. real, optional, intent(in) :: str !< The surface wind stress integrated over a time - !! step, in m2 s-1. + !! step divided by the Boussinesq density [m2 s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - optional, intent(in) :: a !< The layer coupling coefficients from vertvisc, Z s-1. + optional, intent(in) :: a !< The layer coupling coefficients from vertvisc [Z s-1 ~> m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & optional, intent(in) :: hv !< The layer thicknesses at velocity grid points, - !! from vertvisc, in H. + !! from vertvisc [H ~> m or kg m-2]. ! Local variables real :: f_eff, CFL real :: Angstrom diff --git a/src/diagnostics/MOM_debugging.F90 b/src/diagnostics/MOM_debugging.F90 index 92ee5898d5..79a56cae2f 100644 --- a/src/diagnostics/MOM_debugging.F90 +++ b/src/diagnostics/MOM_debugging.F90 @@ -726,7 +726,7 @@ end subroutine chksum_vec_A2d function totalStuff(HI, hThick, areaT, stuff) type(hor_index_type), intent(in) :: HI !< A horizontal index type real, dimension(HI%isd:,HI%jsd:,:), intent(in) :: hThick !< The array of thicknesses to use as weights - real, dimension(HI%isd:,HI%jsd:), intent(in) :: areaT !< The array of cell areas in m2 + real, dimension(HI%isd:,HI%jsd:), intent(in) :: areaT !< The array of cell areas [m2] real, dimension(HI%isd:,HI%jsd:,:), intent(in) :: stuff !< The array of stuff to be summed real :: totalStuff !< the globally integrated amoutn of stuff ! Local variables @@ -746,7 +746,7 @@ end function totalStuff subroutine totalTandS(HI, hThick, areaT, temperature, salinity, mesg) type(hor_index_type), intent(in) :: HI !< A horizontal index type real, dimension(HI%isd:,HI%jsd:,:), intent(in) :: hThick !< The array of thicknesses to use as weights - real, dimension(HI%isd:,HI%jsd:), intent(in) :: areaT !< The array of cell areas in m2 + real, dimension(HI%isd:,HI%jsd:), intent(in) :: areaT !< The array of cell areas [m2] real, dimension(HI%isd:,HI%jsd:,:), intent(in) :: temperature !< The temperature field to sum real, dimension(HI%isd:,HI%jsd:,:), intent(in) :: salinity !< The salinity field to sum character(len=*), intent(in) :: mesg !< An identifying message diff --git a/src/diagnostics/MOM_diag_to_Z.F90 b/src/diagnostics/MOM_diag_to_Z.F90 index 424b241c46..3c50f00061 100644 --- a/src/diagnostics/MOM_diag_to_Z.F90 +++ b/src/diagnostics/MOM_diag_to_Z.F90 @@ -38,16 +38,21 @@ module MOM_diag_to_Z public register_Zint_diag public calc_Zint_diags +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure for the MOM_diag_to_Z module type, public :: diag_to_Z_CS ; private ! The following arrays are used to store diagnostics calculated in this ! module and unavailable outside of it. real, pointer, dimension(:,:,:) :: & - u_z => NULL(), & !< zonal velocity remapped to depth space (m/s) - v_z => NULL(), & !< meridional velocity remapped to depth space (m/s) - uh_z => NULL(), & !< zonal transport remapped to depth space (m3/s or kg/s) - vh_z => NULL() !< meridional transport remapped to depth space (m3/s or kg/s) + u_z => NULL(), & !< zonal velocity remapped to depth space [m s-1] + v_z => NULL(), & !< meridional velocity remapped to depth space [m s-1] + uh_z => NULL(), & !< zonal transport remapped to depth space [H m2 s-1 ~> m3 s-1 or kg s-1] + vh_z => NULL() !< meridional transport remapped to depth space [H m2 s-1 ~> m3 s-1 or kg s-1] type(p3d) :: tr_z(MAX_FIELDS_) !< array of tracers, remapped to depth space type(p3d) :: tr_model(MAX_FIELDS_) !< pointers to an array of tracers @@ -67,7 +72,7 @@ module MOM_diag_to_Z integer :: num_tr_used = 0 !< Th enumber of tracers in use. integer :: nk_zspace = -1 !< The number of levels in the z-space output - real, pointer :: Z_int(:) => NULL() !< interface depths of the z-space file, in Z + real, pointer :: Z_int(:) => NULL() !< interface depths of the z-space file [Z ~> m]. !>@{ Axis groups for z-space diagnostic output type(axes_grp) :: axesBz, axesTz, axesCuz, axesCvz @@ -145,11 +150,11 @@ subroutine calculate_Z_diag_fields(u, v, h, ssh_in, frac_shelf_h, G, GV, US, CS) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G)), & intent(in) :: ssh_in !< Sea surface height in meters. real, dimension(:,:), pointer :: frac_shelf_h !< The fraction of the cell area covered by @@ -158,29 +163,29 @@ subroutine calculate_Z_diag_fields(u, v, h, ssh_in, frac_shelf_h, G, GV, US, CS) !! to diag_to_Z_init. ! Local variables ! Note the deliberately reversed axes in h_f, u_f, v_f, and tr_f. - real :: ssh(SZI_(G),SZJ_(G)) ! copy of ssh_in whose halos can be updated (meter or kg/m2) - real :: e(SZK_(G)+2) ! z-star interface heights in Z - real :: h_f(SZK_(G)+1,SZI_(G)) ! thicknesses of massive layers (meter or kg/m2) + real :: ssh(SZI_(G),SZJ_(G)) ! copy of ssh_in whose halos can be updated [H ~> m or kg m-2] + real :: e(SZK_(G)+2) ! z-star interface heights [Z ~> m]. + real :: h_f(SZK_(G)+1,SZI_(G)) ! thicknesses of massive layers [H ~> m or kg m-2] real :: u_f(SZK_(G)+1,SZIB_(G))! zonal velocity component in any massive layer real :: v_f(SZK_(G)+1,SZI_(G)) ! meridional velocity component in any massive layer real :: tr_f(SZK_(G),max(CS%num_tr_used,1),SZI_(G)) ! tracer concentration in massive layers integer :: nk_valid(SZIB_(G)) ! number of massive layers in a column - real :: D_pt(SZIB_(G)) ! bottom depth in Z - real :: shelf_depth(SZIB_(G)) ! ice shelf depth in Z - real :: htot ! summed layer thicknesses (meter or kg/m2) + real :: D_pt(SZIB_(G)) ! bottom depth [Z ~> m]. + real :: shelf_depth(SZIB_(G)) ! ice shelf depth [Z ~> m]. + real :: htot ! summed layer thicknesses [H ~> m or kg m-2] real :: dilate ! proportion by which to dilate every layer real :: wt(SZK_(G)+1) ! fractional weight for each layer in the - ! range between k_top and k_bot (nondim) + ! range between k_top and k_bot [nondim] real :: z1(SZK_(G)+1) ! z1 and z2 are the depths of the top and bottom real :: z2(SZK_(G)+1) ! limits of the part of a layer that contributes ! to a depth level, relative to the cell center - ! and normalized by the cell thickness (nondim) + ! and normalized by the cell thickness [nondim] ! Note that -1/2 <= z1 < z2 <= 1/2. real :: sl_tr(max(CS%num_tr_used,1)) ! normalized slope of the tracer ! within the cell, in tracer units - real :: Angstrom ! A minimal layer thickness, in H. + real :: Angstrom ! A minimal layer thickness [H ~> m or kg m-2]. real :: slope ! normalized slope of a variable within the cell real :: layer_ave(CS%nk_zspace) @@ -500,11 +505,10 @@ subroutine calculate_Z_transport(uh_int, vh_int, h, dt, G, GV, CS) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid !! structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uh_int !< Time integrated zonal - !! transport (m3 or kg). + !! transport [H m2 ~> m3 or kg]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vh_int !< Time integrated meridional - !! transport (m3 or kg). - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + !! transport [H m2 ~> m3 or kg]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, intent(in) :: dt !< The time difference in s since !! the last call to this !! subroutine. @@ -513,32 +517,32 @@ subroutine calculate_Z_transport(uh_int, vh_int, h, dt, G, GV, CS) !! diag_to_Z_init. ! Local variables real, dimension(SZI_(G), SZJ_(G)) :: & - htot, & ! total layer thickness, in H + htot, & ! total layer thickness [H ~> m or kg m-2] dilate ! Factor by which to dilate layers to convert them - ! into z* space, in Z H-1. (-G%D < z* < 0) + ! into z* space [Z H-1 ~> 1 or m3 kg-1]. (-G%D < z* < 0) real, dimension(SZI_(G), max(CS%nk_zspace,1)) :: & - uh_Z ! uh_int interpolated into depth space (m3 or kg) + uh_Z ! uh_int interpolated into depth space [H m2 ~> m3 or kg] real, dimension(SZIB_(G), max(CS%nk_zspace,1)) :: & - vh_Z ! vh_int interpolated into depth space (m3 or kg) + vh_Z ! vh_int interpolated into depth space [H m2 ~> m3 or kg] real :: h_rem ! dilated thickness of a layer that has yet to be mapped - ! into depth space (in Z) + ! into depth space [Z ~> m] real :: uh_rem ! integrated zonal transport of a layer that has yet to be - ! mapped into depth space (m3 or kg) + ! mapped into depth space [H m2 ~> m3 or kg] real :: vh_rem ! integrated meridional transport of a layer that has yet - ! to be mapped into depth space (m3 or kg) + ! to be mapped into depth space [H m2 ~> m3 or kg] real :: h_here ! thickness of a layer that is within the range of the - ! current depth level (in Z) + ! current depth level [Z ~> m] real :: h_above ! thickness of a layer that is above the current depth - ! level (in Z) + ! level [Z ~> m] real :: uh_here ! zonal transport of a layer that is attributed to the - ! current depth level (m3 or kg) + ! current depth level [H m2 ~> m3 or kg] real :: vh_here ! meridional transport of a layer that is attributed to - ! the current depth level (m3 or kg) - real :: Idt ! inverse of the time step (sec) + ! the current depth level [H m2 ~> m3 or kg] + real :: Idt ! inverse of the time step [s] - real :: z_int_above(SZIB_(G)) ! height of the interface atop a layer (meter or kg/m2) + real :: z_int_above(SZIB_(G)) ! height of the interface atop a layer [H ~> m or kg m-2] integer :: kz(SZIB_(G)) ! index of depth level that is being contributed to @@ -670,10 +674,10 @@ subroutine find_overlap(e, Z_top, Z_bot, k_max, k_start, k_top, k_bot, wt, z1, z real, dimension(:), intent(out) :: wt !< Relative weights of each layer from k_top to k_bot. real, dimension(:), intent(out) :: z1 !< Depth of the top limits of the part of !! a layer that contributes to a depth level, relative to the cell center and normalized - !! by the cell thickness (nondim). Note that -1/2 <= z1 < z2 <= 1/2. + !! by the cell thickness [nondim]. Note that -1/2 <= z1 < z2 <= 1/2. real, dimension(:), intent(out) :: z2 !< Depths of the bottom limit of the part of !! a layer that contributes to a depth level, relative to the cell center and normalized - !! by the cell thickness (nondim). Note that -1/2 <= z1 < z2 <= 1/2. + !! by the cell thickness [nondim]. Note that -1/2 <= z1 < z2 <= 1/2. ! Local variables real :: Ih, e_c, tot_wt, I_totwt integer :: k @@ -747,7 +751,7 @@ end subroutine find_limited_slope subroutine calc_Zint_diags(h, in_ptrs, ids, num_diags, G, GV, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(p3d), dimension(:), intent(in) :: in_ptrs !< Pointers to the diagnostics to be regridded integer, dimension(:), intent(in) :: ids !< The diagnostic IDs of the diagnostics integer, intent(in) :: num_diags !< The number of diagnostics to regrid @@ -761,7 +765,7 @@ subroutine calc_Zint_diags(h, in_ptrs, ids, num_diags, G, GV, CS) real, dimension(max(num_diags,1),SZI_(G),SZK_(G)+1) :: diag2d real, dimension(SZI_(G)) :: & - htot, & ! summed layer thicknesses (meter or kg/m2) + htot, & ! summed layer thicknesses [H ~> m or kg m-2] dilate ! proportion by which to dilate every layer real :: wt ! weighting of the interface above in the ! interpolation to target depths diff --git a/src/diagnostics/MOM_diagnostics.F90 b/src/diagnostics/MOM_diagnostics.F90 index 3ea4e65506..cd3c87b922 100644 --- a/src/diagnostics/MOM_diagnostics.F90 +++ b/src/diagnostics/MOM_diagnostics.F90 @@ -42,13 +42,18 @@ module MOM_diagnostics public register_transport_diags, post_transport_diagnostics public MOM_diagnostics_init, MOM_diagnostics_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure for the MOM_diagnostics module type, public :: diagnostics_CS ; private real :: mono_N2_column_fraction = 0. !< The lower fraction of water column over which N2 is limited as !! monotonic for the purposes of calculating the equivalent !! barotropic wave speed. real :: mono_N2_depth = -1. !< The depth below which N2 is limited as monotonic for the purposes of - !! calculating the equivalent barotropic wave speed. (m) + !! calculating the equivalent barotropic wave speed [m]. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to !! regulate the timing of diagnostic output. @@ -57,49 +62,48 @@ module MOM_diagnostics ! following fields have nz+1 levels. real, pointer, dimension(:,:,:) :: & - e => NULL(), & !< interface height (metre) - e_D => NULL() !< interface height above bottom (metre) + e => NULL(), & !< interface height [Z ~> m] + e_D => NULL() !< interface height above bottom [Z ~> m] ! following fields have nz layers. real, pointer, dimension(:,:,:) :: & - du_dt => NULL(), & !< net i-acceleration in m/s2 - dv_dt => NULL(), & !< net j-acceleration in m/s2 - dh_dt => NULL(), & !< thickness rate of change in (m/s) or kg/(m2*s) - p_ebt => NULL() !< Equivalent barotropic modal structure + du_dt => NULL(), & !< net i-acceleration [m s-2] + dv_dt => NULL(), & !< net j-acceleration [m s-2] + dh_dt => NULL(), & !< thickness rate of change [H s-1 ~> m s-1 or kg m-2 s-1] + p_ebt => NULL() !< Equivalent barotropic modal structure [nondim] real, pointer, dimension(:,:,:) :: h_Rlay => NULL() !< Layer thicknesses in potential density - !! coordinates, in m (Bouss) or kg/m2 (non-Bouss) + !! coordinates [H ~> m or kg m-2] real, pointer, dimension(:,:,:) :: uh_Rlay => NULL() !< Zonal transports in potential density - !! coordinates in m3/s (Bouss) or kg/s (non-Bouss) + !! coordinates [H m2 s-1 ~> m3 s-1 or kg s-1] real, pointer, dimension(:,:,:) :: vh_Rlay => NULL() !< Meridional transports in potential density - !! coordinates in m3/s (Bouss) or kg/s (non-Bouss) + !! coordinates [H m2 s-1 ~> m3 s-1 or kg s-1] real, pointer, dimension(:,:,:) :: uhGM_Rlay => NULL() !< Zonal Gent-McWilliams transports in potential density - !! coordinates, in m3/s (Bouss) or kg/s (non-Bouss) + !! coordinates [H m2 s-1 ~> m3 s-1 or kg s-1] real, pointer, dimension(:,:,:) :: vhGM_Rlay => NULL() !< Meridional Gent-McWilliams transports in potential density - !! coordinates, in m3/s (Bouss) or kg/s (non-Bouss) + !! coordinates [H m2 s-1 ~> m3 s-1 or kg s-1] ! following fields are 2-D. real, pointer, dimension(:,:) :: & - cg1 => NULL(), & !< First baroclinic gravity wave speed, in m s-1 - Rd1 => NULL(), & !< First baroclinic deformation radius, in m + cg1 => NULL(), & !< First baroclinic gravity wave speed [m s-1] + Rd1 => NULL(), & !< First baroclinic deformation radius [m] cfl_cg1 => NULL(), & !< CFL for first baroclinic gravity wave speed, nondim cfl_cg1_x => NULL(), & !< i-component of CFL for first baroclinic gravity wave speed, nondim cfl_cg1_y => NULL() !< j-component of CFL for first baroclinic gravity wave speed, nondim - ! arrays to hold diagnostics in the layer-integrated energy budget. - ! all except KE have units of m3 s-3 (when Boussinesq). + ! The following arrays hold diagnostics in the layer-integrated energy budget. real, pointer, dimension(:,:,:) :: & - KE => NULL(), & !< KE per unit mass, in m2 s-2 - dKE_dt => NULL(), & !< time derivative of the layer KE - PE_to_KE => NULL(), & !< potential energy to KE term - KE_CorAdv => NULL(), & !< KE source from the combined Coriolis and advection terms. + KE => NULL(), & !< KE per unit mass [m2 s-2] + dKE_dt => NULL(), & !< time derivative of the layer KE [m3 s-3] + PE_to_KE => NULL(), & !< potential energy to KE term [m3 s-3] + KE_CorAdv => NULL(), & !< KE source from the combined Coriolis and advection terms [m3 s-3]. !! The Coriolis source should be zero, but is not due to truncation !! errors. There should be near-cancellation of the global integral !! of this spurious Coriolis source. - KE_adv => NULL(),& !< KE source from along-layer advection - KE_visc => NULL(),& !< KE source from vertical viscosity - KE_horvisc => NULL(),& !< KE source from horizontal viscosity - KE_dia => NULL() !< KE source from diapycnal diffusion + KE_adv => NULL(), & !< KE source from along-layer advection [m3 s-3] + KE_visc => NULL(), & !< KE source from vertical viscosity [m3 s-3] + KE_horvisc => NULL(), & !< KE source from horizontal viscosity [m3 s-3] + KE_dia => NULL() !< KE source from diapycnal diffusion [m3 s-3] !>@{ Diagnostic IDs integer :: id_u = -1, id_v = -1, id_h = -1 @@ -185,28 +189,28 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: uh !< Transport through zonal faces = u*h*dy, in H m2 s-1. - !! I.e. units are m3/s(Bouss) or kg/s(non-Bouss). + intent(in) :: uh !< Transport through zonal faces = u*h*dy, + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: vh !< Transport through meridional faces = v*h*dx, in H m2 s-1. - !! I.e. units are m3/s(Bouss) or kg/s(non-Bouss). + intent(in) :: vh !< Transport through meridional faces = v*h*dx, + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables. type(accel_diag_ptrs), intent(in) :: ADp !< structure with pointers to !! accelerations in momentum equation. type(cont_diag_ptrs), intent(in) :: CDp !< structure with pointers to !! terms in continuity equation. - real, dimension(:,:), pointer :: p_surf !< A pointer to the surface pressure, in Pa. + real, dimension(:,:), pointer :: p_surf !< A pointer to the surface pressure [Pa]. !! If p_surf is not associated, it is the same !! as setting the surface pressure to 0. - real, intent(in) :: dt !< The time difference in s since the last - !! call to this subroutine. + real, intent(in) :: dt !< The time difference since the last + !! call to this subroutine [s]. type(diag_grid_storage), intent(in) :: diag_pre_sync !< Target grids from previous timestep type(diagnostics_CS), intent(inout) :: CS !< Control structure returned by a !! previous call to diagnostics_init. @@ -214,11 +218,11 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & optional, intent(in) :: eta_bt !< An optional barotropic !! variable that gives the "correct" free surface height (Boussinesq) or total water column !! mass per unit area (non-Boussinesq). This is used to dilate the layer thicknesses when - !! calculating interface heights, in m or kg m-2. + !! calculating interface heights [H ~> m or kg m-2]. ! Local variables integer i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, nkmb - ! coordinate variable potential density, in kg m-3. + ! coordinate variable potential density [kg m-3]. real :: Rcv(SZI_(G),SZJ_(G),SZK_(G)) ! Two temporary work arrays real :: work_3d(SZI_(G),SZJ_(G),SZK_(G)) @@ -229,13 +233,13 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & real :: pressure_1d(SZI_(G)) ! Temporary array for pressure when calling EOS real :: wt, wt_p - ! squared Coriolis parameter at to h-points (1/s2) + ! squared Coriolis parameter at to h-points [s-2] real :: f2_h - ! magnitude of the gradient of f (1/(m*s)) + ! magnitude of the gradient of f [s-1 m-1] real :: mag_beta - ! frequency squared used to avoid division by 0 (1/s2) + ! frequency squared used to avoid division by 0 [s-2] ! value is roughly (pi / (the age of the universe) )^2. real, parameter :: absurdly_small_freq2 = 1e-34 @@ -323,7 +327,7 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & call post_data(CS%id_masso, masso, CS%diag) endif - ! diagnose thickness/volumes of grid cells (meter) + ! diagnose thickness/volumes of grid cells [m] if (CS%id_thkcello>0 .or. CS%id_volcello>0) then if (GV%Boussinesq) then ! thkcello = h for Boussinesq if (CS%id_thkcello > 0) then ; if (GV%H_to_m == 1.0) then @@ -342,7 +346,7 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & endif else ! thkcello = dp/(rho*g) for non-Boussinesq do j=js,je - if (associated(p_surf)) then ! Pressure loading at top of surface layer (Pa) + if (associated(p_surf)) then ! Pressure loading at top of surface layer [Pa] do i=is,ie pressure_1d(i) = p_surf(i,j) enddo @@ -352,16 +356,16 @@ subroutine calculate_diagnostic_fields(u, v, h, uh, vh, tv, ADp, CDp, p_surf, & enddo endif do k=1,nz ! Integrate vertically downward for pressure - do i=is,ie ! Pressure for EOS at the layer center (Pa) + do i=is,ie ! Pressure for EOS at the layer center [Pa] pressure_1d(i) = pressure_1d(i) + 0.5*GV%H_to_Pa*h(i,j,k) enddo - ! Store in-situ density (kg/m3) in work_3d + ! Store in-situ density [kg m-3] in work_3d call calculate_density(tv%T(:,j,k),tv%S(:,j,k), pressure_1d, & work_3d(:,j,k), is, ie-is+1, tv%eqn_of_state) do i=is,ie ! Cell thickness = dz = dp/(g*rho) (meter); store in work_3d work_3d(i,j,k) = (GV%H_to_kg_m2*h(i,j,k)) / work_3d(i,j,k) enddo - do i=is,ie ! Pressure for EOS at the bottom interface (Pa) + do i=is,ie ! Pressure for EOS at the bottom interface [Pa] pressure_1d(i) = pressure_1d(i) + 0.5*GV%H_to_Pa*h(i,j,k) enddo enddo ! k @@ -695,8 +699,8 @@ end subroutine calculate_diagnostic_fields !! weights that should be assigned to elements k and k+1. subroutine find_weights(Rlist, R_in, k, nz, wt, wt_p) real, dimension(:), & - intent(in) :: Rlist !< The list of target densities, in kg m-3 - real, intent(in) :: R_in !< The density being inserted into Rlist, in kg m-3 + intent(in) :: Rlist !< The list of target densities [kg m-3] + real, intent(in) :: R_in !< The density being inserted into Rlist [kg m-3] integer, intent(inout) :: k !< The value of k such that Rlist(k) <= R_in < Rlist(k+1) !! The input value is a first guess integer, intent(in) :: nz !< The number of layers in Rlist @@ -765,30 +769,30 @@ subroutine calculate_vertical_integrals(h, tv, p_surf, G, GV, US, CS) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables. - real, dimension(:,:), pointer :: p_surf !< A pointer to the surface pressure, in Pa. + real, dimension(:,:), pointer :: p_surf !< A pointer to the surface pressure [Pa]. !! If p_surf is not associated, it is the same !! as setting the surface pressure to 0. type(diagnostics_CS), intent(inout) :: CS !< Control structure returned by a !! previous call to diagnostics_init. real, dimension(SZI_(G), SZJ_(G)) :: & - z_top, & ! Height of the top of a layer or the ocean, in Z. + z_top, & ! Height of the top of a layer or the ocean [Z ~> m]. z_bot, & ! Height of the bottom of a layer (for id_mass) or the - ! (positive) depth of the ocean (for id_col_ht), in Z. - mass, & ! integrated mass of the water column, in kg m-2. For + ! (positive) depth of the ocean (for id_col_ht) [Z ~> m]. + mass, & ! integrated mass of the water column [kg m-2]. For ! non-Boussinesq models this is rho*dz. For Boussinesq ! models, this is either the integral of in-situ density ! (rho*dz for col_mass) or reference density (Rho_0*dz for mass_wt). btm_pres,&! The pressure at the ocean bottom, or CMIP variable 'pbo'. ! This is the column mass multiplied by gravity plus the pressure - ! at the ocean surface. - dpress, & ! Change in hydrostatic pressure across a layer, in Pa. + ! at the ocean surface [Pa]. + dpress, & ! Change in hydrostatic pressure across a layer [Pa]. tr_int ! vertical integral of a tracer times density, - ! (Rho_0 in a Boussinesq model) in TR kg m-2. - real :: IG_Earth ! Inverse of gravitational acceleration, in s2 m-1. + ! (Rho_0 in a Boussinesq model) [TR kg m-2]. + real :: IG_Earth ! Inverse of gravitational acceleration [s2 m-1]. integer :: i, j, k, is, ie, js, je, nz is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke @@ -879,17 +883,17 @@ subroutine calculate_energy_diagnostics(u, v, h, uh, vh, ADp, CDp, G, GV, CS) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: uh !< Transport through zonal faces=u*h*dy, in H m2 s-1. - !! I.e. units are m3/s (Bouss) or kg/s(non-Bouss). + intent(in) :: uh !< Transport through zonal faces=u*h*dy, + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: vh !< Transport through merid faces=v*h*dx, in H m2 s-1. - !! I.e. units are m3/s (Bouss) or kg/s(non-Bouss). + intent(in) :: vh !< Transport through merid faces=v*h*dx, + !! [H m2 s-1 ~> m3 s-1 or kg s-1]. type(accel_diag_ptrs), intent(in) :: ADp !< Structure pointing to accelerations in momentum equation. type(cont_diag_ptrs), intent(in) :: CDp !< Structure pointing to terms in continuity equations. type(diagnostics_CS), intent(inout) :: CS !< Control structure returned by a previous call to @@ -1106,7 +1110,7 @@ end subroutine register_time_deriv !> This subroutine calculates all registered time derivatives. subroutine calculate_derivs(dt, G, CS) - real, intent(in) :: dt !< The time interval over which differences occur, in s. + real, intent(in) :: dt !< The time interval over which differences occur [s]. type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(diagnostics_CS), intent(inout) :: CS !< Control structure returned by previous call to !! diagnostics_init. @@ -1136,7 +1140,7 @@ subroutine post_surface_dyn_diags(IDs, G, diag, sfc_state, ssh) type(diag_ctrl), intent(in) :: diag !< regulates diagnostic output type(surface), intent(in) :: sfc_state !< structure describing the ocean surface state real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: ssh !< Time mean surface height without corrections for ice displacement (m) + intent(in) :: ssh !< Time mean surface height without corrections for ice displacement [m] ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: work_2d ! A 2-d work array @@ -1173,18 +1177,18 @@ subroutine post_surface_thermo_diags(IDs, G, GV, US, diag, dt_int, sfc_state, tv type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(diag_ctrl), intent(in) :: diag !< regulates diagnostic output - real, intent(in) :: dt_int !< total time step associated with these diagnostics, in s. + real, intent(in) :: dt_int !< total time step associated with these diagnostics [s]. type(surface), intent(in) :: sfc_state !< structure describing the ocean surface state type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: ssh !< Time mean surface height without corrections for ice displacement (m) + intent(in) :: ssh !< Time mean surface height without corrections for ice displacement [m] real, dimension(SZI_(G),SZJ_(G)), intent(in) :: ssh_ibc !< Time mean surface height with corrections - !! for ice displacement and the inverse barometer (m) + !! for ice displacement and the inverse barometer [m] real, dimension(SZI_(G),SZJ_(G)) :: work_2d ! A 2-d work array real, dimension(SZI_(G),SZJ_(G)) :: & - zos ! dynamic sea lev (zero area mean) from inverse-barometer adjusted ssh (meter) - real :: I_time_int ! The inverse of the time interval in s-1. + zos ! dynamic sea lev (zero area mean) from inverse-barometer adjusted ssh [m] + real :: I_time_int ! The inverse of the time interval [s-1]. real :: zos_area_mean, volo, ssh_ga integer :: i, j, is, ie, js, je @@ -1314,26 +1318,29 @@ subroutine post_transport_diagnostics(G, GV, uhtr, vhtr, h, IDs, diag_pre_dyn, d type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: uhtr !< Accumulated zonal thickness fluxes - !! used to advect tracers (m3 or kg) + !! used to advect tracers [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: vhtr !< Accumulated meridional thickness fluxes - !! used to advect tracers (m3 or kg) + !! used to advect tracers [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< The updated layer thicknesses, in H + intent(in) :: h !< The updated layer thicknesses [H ~> m or kg m-2] type(transport_diag_IDs), intent(in) :: IDs !< A structure with the diagnostic IDs. type(diag_grid_storage), intent(inout) :: diag_pre_dyn !< Stored grids from before dynamics type(diag_ctrl), intent(inout) :: diag !< regulates diagnostic output - real, intent(in) :: dt_trans !< total time step associated with the transports, in s. + real, intent(in) :: dt_trans !< total time step associated with the transports [s]. type(diag_to_Z_CS), pointer :: diag_to_Z_CSp !< A control structure for remapping !! the transports to depth space type(tracer_registry_type), pointer :: Reg !< Pointer to the tracer registry - real, dimension(SZIB_(G), SZJ_(G)) :: umo2d ! Diagnostics of integrated mass transport, in kg s-1 - real, dimension(SZI_(G), SZJB_(G)) :: vmo2d ! Diagnostics of integrated mass transport, in kg s-1 - real, dimension(SZIB_(G), SZJ_(G), SZK_(G)) :: umo ! Diagnostics of layer mass transport, in kg s-1 - real, dimension(SZI_(G), SZJB_(G), SZK_(G)) :: vmo ! Diagnostics of layer mass transport, in kg s-1 - real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_tend ! Change in layer thickness due to dynamics m s-1 - real :: Idt - real :: H_to_kg_m2_dt ! A conversion factor from accumulated transports to fluxes, in kg m-2 H-1 s-1. + ! Local variables + real, dimension(SZIB_(G), SZJ_(G)) :: umo2d ! Diagnostics of integrated mass transport [kg s-1] + real, dimension(SZI_(G), SZJB_(G)) :: vmo2d ! Diagnostics of integrated mass transport [kg s-1] + real, dimension(SZIB_(G), SZJ_(G), SZK_(G)) :: umo ! Diagnostics of layer mass transport [kg s-1] + real, dimension(SZI_(G), SZJB_(G), SZK_(G)) :: vmo ! Diagnostics of layer mass transport [kg s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_tend ! Change in layer thickness due to dynamics + ! [H s-1 ~> m s-1 or kg m-2 s-1]. + real :: Idt ! The inverse of the time interval [s-1] + real :: H_to_kg_m2_dt ! A conversion factor from accumulated transports to fluxes + ! [kg m-2 H-1 s-1 ~> kg m-3 s-1 or s-1]. integer :: i, j, k, is, ie, js, je, nz is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke diff --git a/src/diagnostics/MOM_sum_output.F90 b/src/diagnostics/MOM_sum_output.F90 index 92028dabf4..e6dcbf11bc 100644 --- a/src/diagnostics/MOM_sum_output.F90 +++ b/src/diagnostics/MOM_sum_output.F90 @@ -33,14 +33,19 @@ module MOM_sum_output public write_energy, accumulate_net_input, MOM_sum_output_init +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + integer, parameter :: NUM_FIELDS = 17 !< Number of diagnostic fields !> A list of depths and corresponding globally integrated ocean area at each !! depth and the ocean volume below each depth. type :: Depth_List - real :: depth !< A depth, in m. - real :: area !< The cross-sectional area of the ocean at that depth, in m2. - real :: vol_below !< The ocean volume below that depth, in m3. + real :: depth !< A depth [m]. + real :: area !< The cross-sectional area of the ocean at that depth [m2]. + real :: vol_below !< The ocean volume below that depth [m3]. end type Depth_List !> The control structure for the MOM_sum_output module @@ -57,28 +62,28 @@ module MOM_sum_output logical :: read_depth_list !< Read the depth list from a file if it exists !! and write it if it doesn't. character(len=200) :: depth_list_file !< The name of the depth list file. - real :: D_list_min_inc !< The minimum increment, in Z, between the depths of the + real :: D_list_min_inc !< The minimum increment [Z ~> m], between the depths of the !! entries in the depth-list file, 0 by default. logical :: use_temperature !< If true, temperature and salinity are state variables. real :: fresh_water_input !< The total mass of fresh water added by surface fluxes - !! since the last time that write_energy was called, in kg. + !! since the last time that write_energy was called [kg]. real :: mass_prev !< The total ocean mass the last time that - !! write_energy was called, in kg. + !! write_energy was called [kg]. real :: salt_prev !< The total amount of salt in the ocean the last - !! time that write_energy was called, in PSU kg. + !! time that write_energy was called [ppt kg]. real :: net_salt_input !< The total salt added by surface fluxes since the last - !! time that write_energy was called, in PSU kg. + !! time that write_energy was called [ppt kg]. real :: heat_prev !< The total amount of heat in the ocean the last - !! time that write_energy was called, in Joules. + !! time that write_energy was called [J]. real :: net_heat_input !< The total heat added by surface fluxes since the last - !! the last time that write_energy was called, in Joules. + !! the last time that write_energy was called [J]. type(EFP_type) :: fresh_water_in_EFP !< An extended fixed point version of fresh_water_input type(EFP_type) :: net_salt_in_EFP !< An extended fixed point version of net_salt_input type(EFP_type) :: net_heat_in_EFP !< An extended fixed point version of net_heat_input type(EFP_type) :: heat_prev_EFP !< An extended fixed point version of heat_prev type(EFP_type) :: salt_prev_EFP !< An extended fixed point version of salt_prev type(EFP_type) :: mass_prev_EFP !< An extended fixed point version of mass_prev - real :: dt !< The baroclinic dynamics time step, in s. + real :: dt !< The baroclinic dynamics time step [s]. type(time_type) :: energysavedays !< The interval between writing the energies !! and other integral quantities of the run. @@ -93,14 +98,14 @@ module MOM_sum_output !! of calls to write_energy and revert to the standard !! energysavedays interval - real :: timeunit !< The length of the units for the time axis, in s. + real :: timeunit !< The length of the units for the time axis [s]. logical :: date_stamped_output !< If true, use dates (not times) in messages to stdout. type(time_type) :: Start_time !< The start time of the simulation. ! Start_time is set in MOM_initialization.F90 integer, pointer :: ntrunc => NULL() !< The number of times the velocity has been !! truncated since the last call to write_energy. real :: max_Energy !< The maximum permitted energy per unit mass. If there is - !! more energy than this, the model should stop, in m2 s-2. + !! more energy than this, the model should stop [m2 s-2]. integer :: maxtrunc !< The number of truncations per energy save !! interval at which the run is stopped. logical :: write_stocks !< If true, write the integrated tracer amounts @@ -131,8 +136,9 @@ subroutine MOM_sum_output_init(G, US, param_file, directory, ntrnc, & type(Sum_output_CS), pointer :: CS !< A pointer that is set to point to the !! control structure for this module. ! Local variables - real :: Time_unit ! The time unit in seconds for ENERGYSAVEDAYS. - real :: Rho_0, maxvel + real :: Time_unit ! The time unit in seconds for ENERGYSAVEDAYS. + real :: Rho_0 ! A reference density [kg m-3] + real :: maxvel ! The maximum permitted velocity [m s-1] ! This include declares and sets the variable "version". #include "version_variable.h" character(len=40) :: mdl = "MOM_sum_output" ! This module's name. @@ -273,11 +279,11 @@ subroutine write_energy(u, v, h, tv, day, n, G, GV, US, CS, tracer_CSp, OBC, dt_ type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables. type(time_type), intent(in) :: day !< The current model time. @@ -291,69 +297,69 @@ subroutine write_energy(u, v, h, tv, day, n, G, GV, US, CS, tracer_CSp, OBC, dt_ optional, pointer :: OBC !< Open boundaries control structure. type(time_type), optional, intent(in) :: dt_forcing !< The forcing time step ! Local variables - real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! The height of interfaces, in Z. - real :: areaTm(SZI_(G),SZJ_(G)) ! A masked version of areaT, in m2. - real :: KE(SZK_(G)) ! The total kinetic energy of a layer, in J. - real :: PE(SZK_(G)+1)! The available potential energy of an interface, in J. - real :: KE_tot ! The total kinetic energy, in J. - real :: PE_tot ! The total available potential energy, in J. + real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! The height of interfaces [Z ~> m]. + real :: areaTm(SZI_(G),SZJ_(G)) ! A masked version of areaT [m2]. + real :: KE(SZK_(G)) ! The total kinetic energy of a layer [J]. + real :: PE(SZK_(G)+1)! The available potential energy of an interface [J]. + real :: KE_tot ! The total kinetic energy [J]. + real :: PE_tot ! The total available potential energy [J]. real :: Z_0APE(SZK_(G)+1) ! The uniform depth which overlies the same - ! volume as is below an interface, in Z. + ! volume as is below an interface [Z ~> m]. real :: H_0APE(SZK_(G)+1) ! A version of Z_0APE, converted to m, usually positive. real :: toten ! The total kinetic & potential energies of - ! all layers, in Joules (i.e. kg m2 s-2). + ! all layers [J] (i.e. kg m2 s-2). real :: En_mass ! The total kinetic and potential energies divided by - ! the total mass of the ocean, in m2 s-2. - real :: vol_lay(SZK_(G)) ! The volume of fluid in a layer, in Z m2. - real :: volbelow ! The volume of all layers beneath an interface in Z m2. - real :: mass_lay(SZK_(G)) ! The mass of fluid in a layer, in kg. - real :: mass_tot ! The total mass of the ocean in kg. - real :: vol_tot ! The total ocean volume in m3. + ! the total mass of the ocean [m2 s-2]. + real :: vol_lay(SZK_(G)) ! The volume of fluid in a layer [Z m2 ~> m3]. + real :: volbelow ! The volume of all layers beneath an interface [Z m2 ~> m3]. + real :: mass_lay(SZK_(G)) ! The mass of fluid in a layer [kg]. + real :: mass_tot ! The total mass of the ocean [kg]. + real :: vol_tot ! The total ocean volume [m3]. real :: mass_chg ! The change in total ocean mass of fresh water since - ! the last call to this subroutine, in kg. + ! the last call to this subroutine [kg]. real :: mass_anom ! The change in fresh water that cannot be accounted for - ! by the surface fluxes, in kg. - real :: Salt ! The total amount of salt in the ocean, in PSU kg. + ! by the surface fluxes [kg]. + real :: Salt ! The total amount of salt in the ocean [ppt kg]. real :: Salt_chg ! The change in total ocean salt since the last call - ! to this subroutine, in PSU kg. + ! to this subroutine [ppt kg]. real :: Salt_anom ! The change in salt that cannot be accounted for by - ! the surface fluxes, in PSU kg. - real :: salin ! The mean salinity of the ocean, in PSU. + ! the surface fluxes [ppt kg]. + real :: salin ! The mean salinity of the ocean [ppt]. real :: salin_chg ! The change in total salt since the last call - ! to this subroutine divided by total mass, in PSU. + ! to this subroutine divided by total mass [ppt]. real :: salin_anom ! The change in total salt that cannot be accounted for by - ! the surface fluxes divided by total mass in PSU. - real :: salin_mass_in ! The mass of salt input since the last call, kg. - real :: Heat ! The total amount of Heat in the ocean, in Joules. + ! the surface fluxes divided by total mass [ppt]. + real :: salin_mass_in ! The mass of salt input since the last call [kg]. + real :: Heat ! The total amount of Heat in the ocean [J]. real :: Heat_chg ! The change in total ocean heat since the last call - ! to this subroutine, in Joules. + ! to this subroutine [J]. real :: Heat_anom ! The change in heat that cannot be accounted for by - ! the surface fluxes, in Joules. - real :: temp ! The mean potential temperature of the ocean, in C. + ! the surface fluxes [J]. + real :: temp ! The mean potential temperature of the ocean [degC]. real :: temp_chg ! The change in total heat divided by total heat capacity - ! of the ocean since the last call to this subroutine, C. + ! of the ocean since the last call to this subroutine, degC. real :: temp_anom ! The change in total heat that cannot be accounted for ! by the surface fluxes, divided by the total heat - ! capacity of the ocean, in C. - real :: hint ! The deviation of an interface from H, in Z. + ! capacity of the ocean [degC]. + real :: hint ! The deviation of an interface from H [Z ~> m]. real :: hbot ! 0 if the basin is deeper than H, or the - ! height of the basin depth over H otherwise, - ! in Z. This makes PE only include real fluid. - real :: hbelow ! The depth of fluid in all layers beneath an interface, in Z. + ! height of the basin depth over H otherwise [Z ~> m]. + ! This makes PE only include real fluid. + real :: hbelow ! The depth of fluid in all layers beneath an interface [Z ~> m]. type(EFP_type) :: & mass_EFP, & ! Extended fixed point sums of total mass, etc. salt_EFP, heat_EFP, salt_chg_EFP, heat_chg_EFP, mass_chg_EFP, & mass_anom_EFP, salt_anom_EFP, heat_anom_EFP - real :: CFL_trans ! A transport-based definition of the CFL number, nondim. - real :: CFL_lin ! A simpler definition of the CFL number, nondim. - real :: max_CFL(2) ! The maxima of the CFL numbers, nondim. - real :: Irho0 ! The inverse of the reference density, in m3 kg-1. + real :: CFL_trans ! A transport-based definition of the CFL number [nondim]. + real :: CFL_lin ! A simpler definition of the CFL number [nondim]. + real :: max_CFL(2) ! The maxima of the CFL numbers [nondim]. + real :: Irho0 ! The inverse of the reference density [m3 kg-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & tmp1 ! A temporary array real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: & - PE_pt ! The potential energy at each point, in J. + PE_pt ! The potential energy at each point [J]. real, dimension(SZI_(G),SZJ_(G)) :: & - Temp_int, Salt_int ! Layer and cell integrated heat and salt, in J and g Salt. + Temp_int, Salt_int ! Layer and cell integrated heat and salt [J] and [g Salt]. real :: H_to_kg_m2 ! Local copy of a unit conversion factor. integer :: num_nc_fields ! The number of fields that will actually go into ! the NetCDF file. @@ -731,7 +737,7 @@ subroutine write_energy(u, v, h, tv, day, n, G, GV, US, CS, tracer_CSp, OBC, dt_ if (GV%Boussinesq) then mass_anom_EFP = mass_chg_EFP - CS%fresh_water_in_EFP else - ! net_salt_input needs to be converted from psu m s-1 to kg m-2 s-1. + ! net_salt_input needs to be converted from ppt m s-1 to kg m-2 s-1. mass_anom_EFP = mass_chg_EFP - CS%fresh_water_in_EFP if (CS%use_temperature) & salin_mass_in = 0.001*EFP_to_real(CS%net_salt_in_EFP) @@ -906,29 +912,29 @@ subroutine accumulate_net_input(fluxes, sfc_state, dt, G, CS) !! forcing fields. Unused fields are unallocated. type(surface), intent(in) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. - real, intent(in) :: dt !< The amount of time over which to average, in s. + real, intent(in) :: dt !< The amount of time over which to average [s]. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(Sum_output_CS), pointer :: CS !< The control structure returned by a previous call !! to MOM_sum_output_init. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - FW_in, & ! The net fresh water input, integrated over a timestep in kg. + FW_in, & ! The net fresh water input, integrated over a timestep [kg]. salt_in, & ! The total salt added by surface fluxes, integrated - ! over a time step in ppt*kg. + ! over a time step [ppt kg]. heat_in ! The total heat added by surface fluxes, integrated - ! over a time step in Joules. + ! over a time step [J]. real :: FW_input ! The net fresh water input, integrated over a timestep - ! and summed over space, in kg. + ! and summed over space [kg]. real :: salt_input ! The total salt added by surface fluxes, integrated - ! over a time step and summed over space, in ppt * kg. + ! over a time step and summed over space [ppt kg]. real :: heat_input ! The total heat added by boundary fluxes, integrated - ! over a time step and summed over space, in Joules. - real :: C_p ! The heat capacity of seawater, in J K-1 kg-1. + ! over a time step and summed over space [J]. + real :: C_p ! The heat capacity of seawater [J degC-1 kg-1]. type(EFP_type) :: & - FW_in_EFP, & ! Extended fixed point versions of FW_input, salt_input, and - salt_in_EFP, & ! heat_input, in kg, ppt*kg, and Joules. - heat_in_EFP + FW_in_EFP, & ! Extended fixed point version of FW_input [kg] + salt_in_EFP, & ! Extended fixed point version of salt_input [ppt kg] + heat_in_EFP ! Extended fixed point version of heat_input [J] real :: inputs(3) ! A mixed array for combining the sums integer :: i, j, is, ie, js, je @@ -998,7 +1004,7 @@ subroutine accumulate_net_input(fluxes, sfc_state, dt, G, CS) ! enddo ; enddo ; endif if (associated(fluxes%salt_flux)) then ; do j=js,je ; do i=is,ie - ! convert salt_flux from kg (salt)/(m^2 s) to ppt * (m/s). + ! convert salt_flux from kg (salt)/(m^2 s) to ppt * [m s-1]. salt_in(i,j) = dt*G%areaT(i,j)*(1000.0*fluxes%salt_flux(i,j)) enddo ; enddo ; endif endif @@ -1060,15 +1066,15 @@ subroutine create_depth_list(G, CS) !! in which the ordered depth list is stored. ! Local variables real, dimension(G%Domain%niglobal*G%Domain%njglobal + 1) :: & - Dlist, & !< The global list of bottom depths, in Z. - AreaList !< The global list of cell areas, in m2. + Dlist, & !< The global list of bottom depths [Z ~> m]. + AreaList !< The global list of cell areas [m2]. integer, dimension(G%Domain%niglobal*G%Domain%njglobal+1) :: & indx2 !< The position of an element in the original unsorted list. - real :: Dnow !< The depth now being considered for sorting, in Z. - real :: Dprev !< The most recent depth that was considered, in Z. - real :: vol !< The running sum of open volume below a deptn, in Z m2. - real :: area !< The open area at the current depth, in m2. - real :: D_list_prev !< The most recent depth added to the list, in Z. + real :: Dnow !< The depth now being considered for sorting [Z ~> m]. + real :: Dprev !< The most recent depth that was considered [Z ~> m]. + real :: vol !< The running sum of open volume below a deptn [Z m2 ~> m3]. + real :: area !< The open area at the current depth [m2]. + real :: D_list_prev !< The most recent depth added to the list [Z ~> m]. logical :: add_to_list !< This depth should be included as an entry on the list. integer :: ir, indxt diff --git a/src/diagnostics/MOM_wave_speed.F90 b/src/diagnostics/MOM_wave_speed.F90 index 3a136bcd9b..0c4b0386a4 100644 --- a/src/diagnostics/MOM_wave_speed.F90 +++ b/src/diagnostics/MOM_wave_speed.F90 @@ -19,6 +19,11 @@ module MOM_wave_speed public wave_speed, wave_speeds, wave_speed_init, wave_speed_set_param +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for MOM_wave_speed type, public :: wave_speed_CS ; private logical :: use_ebt_mode = .false. !< If true, calculate the equivalent barotropic wave speed instead @@ -30,7 +35,7 @@ module MOM_wave_speed !! wave speed. This parameter controls the default behavior of !! wave_speed() which can be overridden by optional arguments. real :: mono_N2_depth = -1. !< The depth below which N2 is limited as monotonic for the purposes of - !! calculating the equivalent barotropic wave speed. (Z) + !! calculating the equivalent barotropic wave speed [Z ~> m]. !! This parameter controls the default behavior of wave_speed() which !! can be overridden by optional arguments. type(remapping_CS) :: remapping_CS !< Used for vertical remapping when calculating equivalent barotropic @@ -47,9 +52,9 @@ subroutine wave_speed(h, tv, G, GV, US, cg1, CS, full_halos, use_ebt_mode, & type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness in units of H (m or kg/m2) + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: cg1 !< First mode internal wave speed (m/s) + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: cg1 !< First mode internal wave speed [m s-1] type(wave_speed_CS), pointer :: CS !< Control structure for MOM_wave_speed logical, optional, intent(in) :: full_halos !< If true, do the calculation !! over the entire computational domain. @@ -60,19 +65,18 @@ subroutine wave_speed(h, tv, G, GV, US, cg1, CS, full_halos, use_ebt_mode, & !! for the purposes of calculating vertical modal structure. real, optional, intent(in) :: mono_N2_depth !< A depth below which N2 is limited as !! monotonic for the purposes of calculating vertical - !! modal structure, in m. + !! modal structure [m]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - optional, intent(out) :: modal_structure !< Normalized model structure (non-dim) + optional, intent(out) :: modal_structure !< Normalized model structure [nondim] ! Local variables real, dimension(SZK_(G)+1) :: & dRho_dT, dRho_dS, & pres, T_int, S_int, & - gprime ! The reduced gravity across each interface, in m2 Z-1 s-2. + gprime ! The reduced gravity across each interface [m2 Z-1 s-2 ~> m s-2]. real, dimension(SZK_(G)) :: & Igl, Igu ! The inverse of the reduced gravity across an interface times - ! the thickness of the layer below (Igl) or above (Igu) it, - ! in units of s2 m-2. + ! the thickness of the layer below (Igl) or above (Igu) it [s2 m-2]. real, dimension(SZK_(G),SZI_(G)) :: & Hf, Tf, Sf, Rf real, dimension(SZK_(G)) :: & @@ -80,16 +84,16 @@ subroutine wave_speed(h, tv, G, GV, US, cg1, CS, full_halos, use_ebt_mode, & real det, ddet, detKm1, detKm2, ddetKm1, ddetKm2 real :: lam, dlam, lam0 real :: min_h_frac - real :: Z_to_Pa ! A conversion factor from thickesses (in Z) to pressure (in Pa) + real :: Z_to_Pa ! A conversion factor from thicknesses (in Z) to pressure (in Pa) real, dimension(SZI_(G)) :: & - htot, hmin, & ! Thicknesses in Z. + htot, hmin, & ! Thicknesses [Z ~> m]. H_here, HxT_here, HxS_here, HxR_here real :: speed2_tot real :: I_Hnew, drxh_sum - real :: L2_to_Z2 ! A scaling factor squared from units of lateral distances to depths, in Z2 m-2. + real :: L2_to_Z2 ! A scaling factor squared from units of lateral distances to depths [Z2 m-2 ~> 1]. real, parameter :: tol1 = 0.0001, tol2 = 0.001 real, pointer, dimension(:,:,:) :: T => NULL(), S => NULL() - real :: g_Rho0 ! G_Earth/Rho0 in m4 s-2 kg-1. + real :: g_Rho0 ! G_Earth/Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1]. real :: rescale, I_rescale integer :: kf(SZI_(G)) integer, parameter :: max_itt = 10 @@ -451,7 +455,7 @@ subroutine wave_speed(h, tv, G, GV, US, cg1, CS, full_halos, use_ebt_mode, & mode_struct(1:kc)=0. endif ! Note that remapping_core_h requires that the same units be used - ! for both the source and target grid thicknesses, here in H. + ! for both the source and target grid thicknesses, here [H ~> m or kg m-2]. call remapping_core_h(CS%remapping_CS, kc, GV%Z_to_H*Hc(:), mode_struct, & nz, h(i,j,:), modal_structure(i,j,:), 1.0e-30*GV%m_to_H, 1.0e-10*GV%m_to_H) endif @@ -515,10 +519,10 @@ subroutine wave_speeds(h, tv, G, GV, US, nmodes, cn, CS, full_halos) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables integer, intent(in) :: nmodes !< Number of modes - real, dimension(G%isd:G%ied,G%jsd:G%jed,nmodes), intent(out) :: cn !< Waves speeds (m/s) + real, dimension(G%isd:G%ied,G%jsd:G%jed,nmodes), intent(out) :: cn !< Waves speeds [m s-1] type(wave_speed_CS), optional, pointer :: CS !< Control structure for MOM_wave_speed logical, optional, intent(in) :: full_halos !< If true, do the calculation !! over the entire computational domain. @@ -526,11 +530,10 @@ subroutine wave_speeds(h, tv, G, GV, US, nmodes, cn, CS, full_halos) real, dimension(SZK_(G)+1) :: & dRho_dT, dRho_dS, & pres, T_int, S_int, & - gprime ! The reduced gravity across each interface, in m s-2. + gprime ! The reduced gravity across each interface [m s-2] real, dimension(SZK_(G)) :: & Igl, Igu ! The inverse of the reduced gravity across an interface times - ! the thickness of the layer below (Igl) or above (Igu) it, - ! in units of s2 m-2. + ! the thickness of the layer below (Igl) or above (Igu) it [s2 m-2]. real, dimension(SZK_(G)-1) :: & a_diag, b_diag, c_diag ! diagonals of tridiagonal matrix; one value for each @@ -559,18 +562,18 @@ subroutine wave_speeds(h, tv, G, GV, US, nmodes, cn, CS, full_halos) integer :: numint ! number of widows (intervals) in root searching range integer :: nrootsfound ! number of extra roots found (not including 1st root) real :: min_h_frac - real :: Z_to_Pa ! A conversion factor from thickesses (in Z) to pressure (in Pa) + real :: Z_to_Pa ! A conversion factor from thicknesses (in Z) to pressure (in Pa) real, dimension(SZI_(G)) :: & - htot, hmin, & ! Thicknesses in Z. + htot, hmin, & ! Thicknesses [Z ~> m]. H_here, HxT_here, HxS_here, HxR_here - real :: speed2_tot ! overestimate of the mode-1 speed squared, m2 s-2 + real :: speed2_tot ! overestimate of the mode-1 speed squared [m2 s-2] real :: speed2_min ! minimum mode speed (squared) to consider in root searching real, parameter :: reduct_factor = 0.5 ! factor used in setting speed2_min real :: I_Hnew, drxh_sum real, parameter :: tol1 = 0.0001, tol2 = 0.001 real, pointer, dimension(:,:,:) :: T => NULL(), S => NULL() - real :: g_Rho0 ! G_Earth/Rho0 in m4 s-2 kg-1. + real :: g_Rho0 ! G_Earth/Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1]. integer :: kf(SZI_(G)) integer, parameter :: max_itt = 10 logical :: use_EOS ! If true, density is calculated from T & S using the equation of state. diff --git a/src/diagnostics/MOM_wave_structure.F90 b/src/diagnostics/MOM_wave_structure.F90 index 7e82c02ec8..28ad4c6bfc 100644 --- a/src/diagnostics/MOM_wave_structure.F90 +++ b/src/diagnostics/MOM_wave_structure.F90 @@ -27,25 +27,30 @@ module MOM_wave_structure public wave_structure, wave_structure_init +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure for the MOM_wave_structure module type, public :: wave_structure_CS ; !private type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to !! regulate the timing of diagnostic output. real, allocatable, dimension(:,:,:) :: w_strct - !< Vertical structure of vertical velocity (normalized), in m s-1. + !< Vertical structure of vertical velocity (normalized) [m s-1]. real, allocatable, dimension(:,:,:) :: u_strct - !< Vertical structure of horizontal velocity (normalized), in m s-1. + !< Vertical structure of horizontal velocity (normalized) [m s-1]. real, allocatable, dimension(:,:,:) :: W_profile !< Vertical profile of w_hat(z), where !! w(x,y,z,t) = w_hat(z)*exp(i(kx+ly-freq*t)) is the full time- - !! varying vertical velocity with w_hat(z) = W0*w_strct(z), in m s-1. + !! varying vertical velocity with w_hat(z) = W0*w_strct(z) [m s-1]. real, allocatable, dimension(:,:,:) :: Uavg_profile !< Vertical profile of the magnitude of horizontal velocity, - !! (u^2+v^2)^0.5, averaged over a period, in m s-1. + !! (u^2+v^2)^0.5, averaged over a period [m s-1]. real, allocatable, dimension(:,:,:) :: z_depths - !< Depths of layer interfaces, in m. + !< Depths of layer interfaces [m]. real, allocatable, dimension(:,:,:) :: N2 - !< Squared buoyancy frequency at each interface, in S-2. + !< Squared buoyancy frequency at each interface [s-2]. integer, allocatable, dimension(:,:):: num_intfaces !< Number of layer interfaces (including surface and bottom) real :: int_tide_source_x !< X Location of generation site @@ -87,33 +92,27 @@ subroutine wave_structure(h, tv, G, GV, US, cn, ModeNum, freq, CS, En, full_halo type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: cn !< The (non-rotational) mode - !! internal gravity wave speed, - !! in m s-1. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: cn !< The (non-rotational) mode internal + !! gravity wave speed [m s-1]. integer, intent(in) :: ModeNum !< Mode number - real, intent(in) :: freq !< Intrinsic wave frequency, in s-1. - type(wave_structure_CS), pointer :: CS !< The control structure returned - !! by a previous call to - !! wave_structure_init. + real, intent(in) :: freq !< Intrinsic wave frequency [s-1]. + type(wave_structure_CS), pointer :: CS !< The control structure returned by a + !! previous call to wave_structure_init. real, dimension(SZI_(G),SZJ_(G)), & - optional, intent(in) :: En !< Internal wave energy density, - !! in Jm-2. + optional, intent(in) :: En !< Internal wave energy density [J m-2]. logical,optional, intent(in) :: full_halos !< If true, do the calculation - !! over the entire computational - !! domain. + !! over the entire computational domain. ! Local variables real, dimension(SZK_(G)+1) :: & dRho_dT, dRho_dS, & pres, T_int, S_int, & - gprime ! The reduced gravity across each interface, in m2 Z-1 s-2. + gprime ! The reduced gravity across each interface [m2 Z-1 s-2 ~> m s-2]. real, dimension(SZK_(G)) :: & Igl, Igu ! The inverse of the reduced gravity across an interface times - ! the thickness of the layer below (Igl) or above (Igu) it, - ! in units of s2 m-2. + ! the thickness of the layer below (Igl) or above (Igu) it [s2 m-2]. real, dimension(SZK_(G),SZI_(G)) :: & Hf, Tf, Sf, Rf real, dimension(SZK_(G)) :: & @@ -125,7 +124,7 @@ subroutine wave_structure(h, tv, G, GV, US, cn, ModeNum, freq, CS, En, full_halo real :: min_h_frac real :: H_to_pres real, dimension(SZI_(G)) :: & - hmin, & ! Thicknesses in Z. + hmin, & ! Thicknesses [Z ~> m]. H_here, HxT_here, HxS_here, HxR_here real :: speed2_tot real :: I_Hnew, drxh_sum @@ -152,7 +151,7 @@ subroutine wave_structure(h, tv, G, GV, US, cn, ModeNum, freq, CS, En, full_halo real :: w2avg ! average of squared vertical velocity structure funtion real :: int_dwdz2, int_w2, int_N2w2, KE_term, PE_term, W0 ! terms in vertically averaged energy equation - real :: gp_unscaled ! A version of gprime rescaled to units of m s-2. + real :: gp_unscaled ! A version of gprime rescaled to [m s-2]. real, dimension(SZK_(G)-1) :: lam_z ! product of eigen value and gprime(k); one value for each ! interface (excluding surface and bottom) real, dimension(SZK_(G)-1) :: a_diag, b_diag, c_diag diff --git a/src/equation_of_state/MOM_EOS.F90 b/src/equation_of_state/MOM_EOS.F90 index 9a823d23eb..b06ffa0a79 100644 --- a/src/equation_of_state/MOM_EOS.F90 +++ b/src/equation_of_state/MOM_EOS.F90 @@ -51,6 +51,11 @@ module MOM_EOS public gsw_sp_from_sr, gsw_pt_from_ct public extract_member_EOS +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Calculates density of sea water from T, S and P interface calculate_density module procedure calculate_density_scalar, calculate_density_array @@ -86,14 +91,14 @@ module MOM_EOS !! code for the integrals of density. logical :: Compressible = .true. !< If true, in situ density is a function of pressure. ! The following parameters are used with the linear equation of state only. - real :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. - real :: dRho_dT !< The partial derivatives of density with temperature - real :: dRho_dS !< and salinity, in kg m-3 K-1 and kg m-3 psu-1. + real :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. + real :: dRho_dT !< The partial derivative of density with temperature [kg m-3 degC-1] + real :: dRho_dS !< The partial derivative of density with salinity [kg m-3 ppt-1]. ! The following parameters are use with the linear expression for the freezing ! point only. - real :: TFr_S0_P0 !< The freezing potential temperature at S=0, P=0 in deg C. - real :: dTFr_dS !< The derivative of freezing point with salinity, in deg C PSU-1. - real :: dTFr_dp !< The derivative of freezing point with pressure, in deg C Pa-1. + real :: TFr_S0_P0 !< The freezing potential temperature at S=0, P=0 [degC]. + real :: dTFr_dS !< The derivative of freezing point with salinity [degC ppt-1]. + real :: dTFr_dp !< The derivative of freezing point with pressure [degC Pa-1]. ! logical :: test_EOS = .true. ! If true, test the equation of state end type EOS_type @@ -126,12 +131,12 @@ module MOM_EOS !> Calls the appropriate subroutine to calculate density of sea water for scalar inputs. !! If rho_ref is present, the anomaly with respect to rho_ref is returned. subroutine calculate_density_scalar(T, S, pressure, rho, EOS, rho_ref) - real, intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, intent(in) :: S !< Salinity (PSU) - real, intent(in) :: pressure !< Pressure (Pa) - real, intent(out) :: rho !< Density (in-situ if pressure is local) (kg m-3) + real, intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, intent(in) :: S !< Salinity [ppt] + real, intent(in) :: pressure !< Pressure [Pa] + real, intent(out) :: rho !< Density (in-situ if pressure is local) [kg m-3] type(EOS_type), pointer :: EOS !< Equation of state structure - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. if (.not.associated(EOS)) call MOM_error(FATAL, & "calculate_density_scalar called with an unassociated EOS_type EOS.") @@ -158,14 +163,14 @@ end subroutine calculate_density_scalar !> Calls the appropriate subroutine to calculate the density of sea water for 1-D array inputs. !! If rho_ref is present, the anomaly with respect to rho_ref is returned. subroutine calculate_density_array(T, S, pressure, rho, start, npts, EOS, rho_ref) - real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, dimension(:), intent(in) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: pressure !< Pressure (Pa) - real, dimension(:), intent(out) :: rho !< Density (in-situ if pressure is local) (kg m-3) + real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, dimension(:), intent(in) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: pressure !< Pressure [Pa] + real, dimension(:), intent(out) :: rho !< Density (in-situ if pressure is local) [kg m-3] integer, intent(in) :: start !< Start index for computation integer, intent(in) :: npts !< Number of point to compute type(EOS_type), pointer :: EOS !< Equation of state structure - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. if (.not.associated(EOS)) call MOM_error(FATAL, & "calculate_density_array called with an unassociated EOS_type EOS.") @@ -192,12 +197,12 @@ end subroutine calculate_density_array !> Calls the appropriate subroutine to calculate specific volume of sea water !! for scalar inputs. subroutine calculate_spec_vol_scalar(T, S, pressure, specvol, EOS, spv_ref) - real, intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, intent(in) :: S !< Salinity (PSU) - real, intent(in) :: pressure !< Pressure (Pa) - real, intent(out) :: specvol !< specific volume (in-situ if pressure is local) (m3 kg-1) + real, intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, intent(in) :: S !< Salinity [ppt] + real, intent(in) :: pressure !< Pressure [Pa] + real, intent(out) :: specvol !< specific volume (in-situ if pressure is local) [m3 kg-1] type(EOS_type), pointer :: EOS !< Equation of state structure - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. real :: rho @@ -233,14 +238,14 @@ end subroutine calculate_spec_vol_scalar !! for 1-D array inputs. subroutine calculate_spec_vol_array(T, S, pressure, specvol, start, npts, EOS, spv_ref) real, dimension(:), intent(in) :: T !< potential temperature relative to the surface - !! in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: specvol !< in situ specific volume in kg m-3. + !! [degC]. + real, dimension(:), intent(in) :: S !< salinity [ppt]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: specvol !< in situ specific volume [kg m-3]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. type(EOS_type), pointer :: EOS !< Equation of state structure - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. real, dimension(size(specvol)) :: rho @@ -275,10 +280,10 @@ end subroutine calculate_spec_vol_array !> Calls the appropriate subroutine to calculate the freezing point for scalar inputs. subroutine calculate_TFreeze_scalar(S, pressure, T_fr, EOS) - real, intent(in) :: S !< Salinity (PSU) - real, intent(in) :: pressure !< Pressure (Pa) + real, intent(in) :: S !< Salinity [ppt] + real, intent(in) :: pressure !< Pressure [Pa] real, intent(out) :: T_fr !< Freezing point potential temperature referenced - !! to the surface (degC) + !! to the surface [degC] type(EOS_type), pointer :: EOS !< Equation of state structure if (.not.associated(EOS)) call MOM_error(FATAL, & @@ -301,10 +306,10 @@ end subroutine calculate_TFreeze_scalar !> Calls the appropriate subroutine to calculate the freezing point for a 1-D array. subroutine calculate_TFreeze_array(S, pressure, T_fr, start, npts, EOS) - real, dimension(:), intent(in) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: pressure !< Pressure (Pa) + real, dimension(:), intent(in) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: pressure !< Pressure [Pa] real, dimension(:), intent(out) :: T_fr !< Freezing point potential temperature referenced - !! to the surface (degC) + !! to the surface [degC] integer, intent(in) :: start !< Starting index within the array integer, intent(in) :: npts !< The number of values to calculate type(EOS_type), pointer :: EOS !< Equation of state structure @@ -329,17 +334,17 @@ end subroutine calculate_TFreeze_array !> Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs. subroutine calculate_density_derivs_array(T, S, pressure, drho_dT, drho_dS, start, npts, EOS) - real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, dimension(:), intent(in) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: pressure !< Pressure (Pa) + real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, dimension(:), intent(in) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: pressure !< Pressure [Pa] real, dimension(:), intent(out) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, dimension(:), intent(out) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 ppt-1]. integer, intent(in) :: start !< Starting index within the array integer, intent(in) :: npts !< The number of values to calculate type(EOS_type), pointer :: EOS !< Equation of state structure - !! + if (.not.associated(EOS)) call MOM_error(FATAL, & "calculate_density_derivs called with an unassociated EOS_type EOS.") @@ -365,13 +370,13 @@ end subroutine calculate_density_derivs_array !> Calls the appropriate subroutines to calculate density derivatives by promoting a scalar !! to a one-element array subroutine calculate_density_derivs_scalar(T, S, pressure, drho_dT, drho_dS, EOS) - real, intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, intent(in) :: S !< Salinity (PSU) - real, intent(in) :: pressure !< Pressure (Pa) + real, intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, intent(in) :: S !< Salinity [ppt] + real, intent(in) :: pressure !< Pressure [Pa] real, intent(out) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 ppt-1]. type(EOS_type), pointer :: EOS !< Equation of state structure if (.not.associated(EOS)) call MOM_error(FATAL, & "calculate_density_derivs called with an unassociated EOS_type EOS.") @@ -394,18 +399,23 @@ end subroutine calculate_density_derivs_scalar !> Calls the appropriate subroutine to calculate density second derivatives for 1-D array inputs. subroutine calculate_density_second_derivs_array(T, S, pressure, drho_dS_dS, drho_dS_dT, drho_dT_dT, & drho_dS_dP, drho_dT_dP, start, npts, EOS) - real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, dimension(:), intent(in) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: pressure !< Pressure (Pa) - real, dimension(:), intent(out) :: drho_dS_dS !< Partial derivative of beta with respect to S - real, dimension(:), intent(out) :: drho_dS_dT !< Partial derivative of beta with resepct to T - real, dimension(:), intent(out) :: drho_dT_dT !< Partial derivative of alpha with respect to T - real, dimension(:), intent(out) :: drho_dS_dP !< Partial derivative of beta with respect to pressure - real, dimension(:), intent(out) :: drho_dT_dP !< Partial derivative of alpha with respect to pressure + real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, dimension(:), intent(in) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: pressure !< Pressure [Pa] + real, dimension(:), intent(out) :: drho_dS_dS !< Partial derivative of beta with respect + !! to S [kg m-3 ppt-2] + real, dimension(:), intent(out) :: drho_dS_dT !< Partial derivative of beta with respcct + !! to T [kg m-3 ppt-1 degC-1] + real, dimension(:), intent(out) :: drho_dT_dT !< Partial derivative of alpha with respect + !! to T [kg m-3 degC-2] + real, dimension(:), intent(out) :: drho_dS_dP !< Partial derivative of beta with respect + !! to pressure [kg m-3 ppt-1 Pa-1] + real, dimension(:), intent(out) :: drho_dT_dP !< Partial derivative of alpha with respect + !! to pressure [kg m-3 degC-1 Pa-1] integer, intent(in) :: start !< Starting index within the array integer, intent(in) :: npts !< The number of values to calculate type(EOS_type), pointer :: EOS !< Equation of state structure - !! + if (.not.associated(EOS)) call MOM_error(FATAL, & "calculate_density_derivs called with an unassociated EOS_type EOS.") @@ -429,16 +439,21 @@ end subroutine calculate_density_second_derivs_array !> Calls the appropriate subroutine to calculate density second derivatives for scalar nputs. subroutine calculate_density_second_derivs_scalar(T, S, pressure, drho_dS_dS, drho_dS_dT, drho_dT_dT, & drho_dS_dP, drho_dT_dP, EOS) - real, intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, intent(in) :: S !< Salinity (PSU) - real, intent(in) :: pressure !< Pressure (Pa) - real, intent(out) :: drho_dS_dS !< Partial derivative of beta with respect to S - real, intent(out) :: drho_dS_dT !< Partial derivative of beta with resepct to T - real, intent(out) :: drho_dT_dT !< Partial derivative of alpha with respect to T - real, intent(out) :: drho_dS_dP !< Partial derivative of beta with respect to pressure - real, intent(out) :: drho_dT_dP !< Partial derivative of alpha with respect to pressure + real, intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, intent(in) :: S !< Salinity [ppt] + real, intent(in) :: pressure !< Pressure [Pa] + real, intent(out) :: drho_dS_dS !< Partial derivative of beta with respect + !! to S [kg m-3 ppt-2] + real, intent(out) :: drho_dS_dT !< Partial derivative of beta with respcct + !! to T [kg m-3 ppt-1 degC-1] + real, intent(out) :: drho_dT_dT !< Partial derivative of alpha with respect + !! to T [kg m-3 degC-2] + real, intent(out) :: drho_dS_dP !< Partial derivative of beta with respect + !! to pressure [kg m-3 ppt-1 Pa-1] + real, intent(out) :: drho_dT_dP !< Partial derivative of alpha with respect + !! to pressure [kg m-3 degC-1 Pa-1] type(EOS_type), pointer :: EOS !< Equation of state structure - !! + if (.not.associated(EOS)) call MOM_error(FATAL, & "calculate_density_derivs called with an unassociated EOS_type EOS.") @@ -461,13 +476,13 @@ end subroutine calculate_density_second_derivs_scalar !> Calls the appropriate subroutine to calculate specific volume derivatives for an array. subroutine calculate_specific_vol_derivs(T, S, pressure, dSV_dT, dSV_dS, start, npts, EOS) - real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, dimension(:), intent(in) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: pressure !< Pressure (Pa) + real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, dimension(:), intent(in) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: pressure !< Pressure [Pa] real, dimension(:), intent(out) :: dSV_dT !< The partial derivative of specific volume with potential - !! temperature, in m3 kg-1 K-1. - real, dimension(:), intent(out) :: dSV_dS !< The partial derivative of specific volume with salinity, - !! in m3 kg-1 / (g/kg). + !! temperature [m3 kg-1 degC-1]. + real, dimension(:), intent(out) :: dSV_dS !< The partial derivative of specific volume with salinity + !! [m3 kg-1 ppt-1]. integer, intent(in) :: start !< Starting index within the array integer, intent(in) :: npts !< The number of values to calculate type(EOS_type), pointer :: EOS !< Equation of state structure @@ -509,10 +524,10 @@ end subroutine calculate_specific_vol_derivs !> Calls the appropriate subroutine to calculate the density and compressibility for 1-D array inputs. subroutine calculate_compress(T, S, pressure, rho, drho_dp, start, npts, EOS) - real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface (degC) - real, dimension(:), intent(in) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: pressure !< Pressure (Pa) - real, dimension(:), intent(out) :: rho !< In situ density in kg m-3. + real, dimension(:), intent(in) :: T !< Potential temperature referenced to the surface [degC] + real, dimension(:), intent(in) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: pressure !< Pressure [Pa] + real, dimension(:), intent(out) :: rho !< In situ density [kg m-3]. real, dimension(:), intent(out) :: drho_dp !< The partial derivative of density with pressure !! (also the inverse of the square of sound speed) in s2 m-2. integer, intent(in) :: start !< Starting index within the array @@ -552,13 +567,13 @@ subroutine int_specific_vol_dp(T, S, p_t, p_b, alpha_ref, HI, EOS, & bathyP, dP_tiny, useMassWghtInterp) type(hor_index_type), intent(in) :: HI !< The horizontal index structure real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: T !< Potential temperature referenced to the surface (degC) + intent(in) :: T !< Potential temperature referenced to the surface [degC] real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: S !< Salinity (PSU) + intent(in) :: S !< Salinity [ppt] real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_t !< Pressure at the top of the layer in Pa. + intent(in) :: p_t !< Pressure at the top of the layer [Pa]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_b !< Pressure at the bottom of the layer in Pa. + intent(in) :: p_b !< Pressure at the bottom of the layer [Pa]. real, intent(in) :: alpha_ref !< A mean specific volume that is subtracted out !! to reduce the magnitude of each of the integrals, m3 kg-1. The !! calculation is mathematically identical with different values of @@ -566,22 +581,22 @@ subroutine int_specific_vol_dp(T, S, p_t, p_b, alpha_ref, HI, EOS, & type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(out) :: dza !< The change in the geopotential anomaly across - !! the layer, in m2 s-2. + !! the layer [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & optional, intent(out) :: intp_dza !< The integral in pressure through the layer of the !! geopotential anomaly relative to the anomaly at the bottom of the - !! layer, in Pa m2 s-2. + !! layer [Pa m2 s-2]. real, dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), & optional, intent(out) :: intx_dza !< The integral in x of the difference between the !! geopotential anomaly at the top and bottom of the layer divided by - !! the x grid spacing, in m2 s-2. + !! the x grid spacing [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), & optional, intent(out) :: inty_dza !< The integral in y of the difference between the !! geopotential anomaly at the top and bottom of the layer divided by - !! the y grid spacing, in m2 s-2. + !! the y grid spacing [m2 s-2]. integer, optional, intent(in) :: halo_size !< The width of halo points on which to calculate dza. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - optional, intent(in) :: bathyP !< The pressure at the bathymetry in Pa + optional, intent(in) :: bathyP !< The pressure at the bathymetry [Pa] real, optional, intent(in) :: dP_tiny !< A miniscule pressure change with !! the same units as p_t (Pa?) logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting @@ -621,36 +636,36 @@ subroutine int_density_dz(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, EOS, & type(hor_index_type), intent(in) :: HII !< Ocean horizontal index structures for the input arrays type(hor_index_type), intent(in) :: HIO !< Ocean horizontal index structures for the output arrays real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T !< Potential temperature referenced to the surface (degC) + intent(in) :: T !< Potential temperature referenced to the surface [degC] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S !< Salinity (PSU) + intent(in) :: S !< Salinity [ppt] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_t !< Height at the top of the layer in depth units (Z). + intent(in) :: z_t !< Height at the top of the layer in depth units [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_b !< Height at the bottom of the layer in Z. - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is subtracted out to + intent(in) :: z_b !< Height at the bottom of the layer [Z ~> m]. + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is subtracted out to !! reduce the magnitude of each of the integrals. - real, intent(in) :: rho_0 !< A density, in kg m-3, that is used to calculate the + real, intent(in) :: rho_0 !< A density [kg m-3], that is used to calculate the !! pressure (as p~=-z*rho_0*G_e) used in the equation of state. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m2 Z-1 s-2. + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m2 Z-1 s-2 ~> m s-2]. type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & - intent(out) :: dpa !< The change in the pressure anomaly across the layer, in Pa. + intent(out) :: dpa !< The change in the pressure anomaly across the layer [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & optional, intent(out) :: intz_dpa !< The integral through the thickness of the layer of !! the pressure anomaly relative to the anomaly at the - !! top of the layer, in Pa Z. + !! top of the layer [Pa Z ~> Pa m]. real, dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), & optional, intent(out) :: intx_dpa !< The integral in x of the difference between the !! pressure anomaly at the top and bottom of the layer - !! divided by the x grid spacing, in Pa. + !! divided by the x grid spacing [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), & optional, intent(out) :: inty_dpa !< The integral in y of the difference between the !! pressure anomaly at the top and bottom of the layer - !! divided by the y grid spacing, in Pa. + !! divided by the y grid spacing [Pa]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - optional, intent(in) :: bathyT !< The depth of the bathymetry in units of Z. - real, optional, intent(in) :: dz_neglect !< A miniscule thickness change, in Z. + optional, intent(in) :: bathyT !< The depth of the bathymetry [Z ~> m]. + real, optional, intent(in) :: dz_neglect !< A miniscule thickness change [Z ~> m]. logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting to !! interpolate T/S for top and bottom integrals. @@ -799,16 +814,16 @@ subroutine EOS_manual_init(EOS, form_of_EOS, form_of_TFreeze, EOS_quadrature, Co logical, optional, intent(in) :: EOS_quadrature !< If true, always use the generic (quadrature) !! code for the integrals of density. logical, optional, intent(in) :: Compressible !< If true, in situ density is a function of pressure. - real , optional, intent(in) :: Rho_T0_S0 !< Density at T=0 degC and S=0 ppt (kg m-3) + real , optional, intent(in) :: Rho_T0_S0 !< Density at T=0 degC and S=0 ppt [kg m-3] real , optional, intent(in) :: drho_dT !< Partial derivative of density with temperature - !! in (kg m-3 degC-1) + !! in [kg m-3 degC-1] real , optional, intent(in) :: dRho_dS !< Partial derivative of density with salinity - !! in (kg m-3 ppt-1) - real , optional, intent(in) :: TFr_S0_P0 !< The freezing potential temperature at S=0, P=0 in deg C. - real , optional, intent(in) :: dTFr_dS !< The derivative of freezing point with salinity, - !! in deg C PSU-1. - real , optional, intent(in) :: dTFr_dp !< The derivative of freezing point with pressure, - !! in deg C Pa-1. + !! in [kg m-3 ppt-1] + real , optional, intent(in) :: TFr_S0_P0 !< The freezing potential temperature at S=0, P=0 [degC]. + real , optional, intent(in) :: dTFr_dS !< The derivative of freezing point with salinity + !! in [degC ppt-1]. + real , optional, intent(in) :: dTFr_dp !< The derivative of freezing point with pressure + !! in [degC Pa-1]. if (present(form_of_EOS )) EOS%form_of_EOS = form_of_EOS if (present(form_of_TFreeze)) EOS%form_of_TFreeze = form_of_TFreeze @@ -843,9 +858,9 @@ end subroutine EOS_end !! EOS_type (EOS argument) to be set to use the linear equation of state !! independent from the rest of the model. subroutine EOS_use_linear(Rho_T0_S0, dRho_dT, dRho_dS, EOS, use_quadrature) - real, intent(in) :: Rho_T0_S0 !< Density at T=0 degC and S=0 ppt (kg m-3) - real, intent(in) :: dRho_dT !< Partial derivative of density with temperature (kg m-3 degC-1) - real, intent(in) :: dRho_dS !< Partial derivative of density with salinity (kg m-3 ppt-1) + real, intent(in) :: Rho_T0_S0 !< Density at T=0 degC and S=0 ppt [kg m-3] + real, intent(in) :: dRho_dT !< Partial derivative of density with temperature [kg m-3 degC-1] + real, intent(in) :: dRho_dS !< Partial derivative of density with salinity [kg m-3 ppt-1] logical, optional, intent(in) :: use_quadrature !< If true, always use the generic (quadrature) !! code for the integrals of density. type(EOS_type), pointer :: EOS !< Equation of state structure @@ -872,56 +887,56 @@ subroutine int_density_dz_generic(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, type(hor_index_type), intent(in) :: HII !< Horizontal index type for input variables. type(hor_index_type), intent(in) :: HIO !< Horizontal index type for output variables. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T !< Potential temperature of the layer in C. + intent(in) :: T !< Potential temperature of the layer [degC]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S !< Salinity of the layer in PSU. + intent(in) :: S !< Salinity of the layer [ppt]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_t !< Height at the top of the layer in depth units (Z). + intent(in) :: z_t !< Height at the top of the layer in depth units [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_b !< Height at the bottom of the layer in Z. - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is + intent(in) :: z_b !< Height at the bottom of the layer [Z ~> m]. + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is !! subtracted out to reduce the magnitude !! of each of the integrals. - real, intent(in) :: rho_0 !< A density, in kg m-3, that is used + real, intent(in) :: rho_0 !< A density [kg m-3], that is used !! to calculate the pressure (as p~=-z*rho_0*G_e) !! used in the equation of state. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m2 Z-1 s-2. + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m2 Z-1 s-2 ~> m s-2]. type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & intent(out) :: dpa !< The change in the pressure anomaly - !! across the layer, in Pa. + !! across the layer [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & optional, intent(out) :: intz_dpa !< The integral through the thickness of the !! layer of the pressure anomaly relative to the - !! anomaly at the top of the layer, in Pa Z. + !! anomaly at the top of the layer [Pa Z ~> Pa m]. real, dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), & optional, intent(out) :: intx_dpa !< The integral in x of the difference between !! the pressure anomaly at the top and bottom of the - !! layer divided by the x grid spacing, in Pa. + !! layer divided by the x grid spacing [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), & optional, intent(out) :: inty_dpa !< The integral in y of the difference between !! the pressure anomaly at the top and bottom of the - !! layer divided by the y grid spacing, in Pa. + !! layer divided by the y grid spacing [Pa]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - optional, intent(in) :: bathyT !< The depth of the bathymetry in units of Z. - real, optional, intent(in) :: dz_neglect !< A miniscule thickness change, in Z. + optional, intent(in) :: bathyT !< The depth of the bathymetry [Z ~> m]. + real, optional, intent(in) :: dz_neglect !< A miniscule thickness change [Z ~> m]. logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting to !! interpolate T/S for top and bottom integrals. real :: T5(5), S5(5), p5(5), r5(5) - real :: rho_anom ! The depth averaged density anomaly in kg m-3. + real :: rho_anom ! The depth averaged density anomaly [kg m-3]. real :: w_left, w_right real, parameter :: C1_90 = 1.0/90.0 ! Rational constants. real :: GxRho, I_Rho - real :: dz ! The layer thickness, in Z. - real :: hWght ! A pressure-thickness below topography, in Z. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Z. - real :: iDenom ! The inverse of the denominator in the weights, in Z-2. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: dz ! The layer thickness [Z ~> m]. + real :: hWght ! A pressure-thickness below topography [Z ~> m]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Z ~> m]. + real :: iDenom ! The inverse of the denominator in the weights [Z-2 ~> m-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intz(5) ! The gravitational acceleration times the integrals of density - ! with height at the 5 sub-column locations, in Pa. + ! with height at the 5 sub-column locations [Pa]. logical :: do_massWeight ! Indicates whether to do mass weighting. integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, i, j, m, n, ioff, joff @@ -1059,42 +1074,41 @@ subroutine int_density_dz_generic_plm (T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, & type(hor_index_type), intent(in) :: HII !< Ocean horizontal index structures for the input arrays type(hor_index_type), intent(in) :: HIO !< Ocean horizontal index structures for the output arrays real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T_t !< Potential temperatue at the cell top (degC) + intent(in) :: T_t !< Potential temperatue at the cell top [degC] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T_b !< Potential temperatue at the cell bottom (degC) + intent(in) :: T_b !< Potential temperatue at the cell bottom [degC] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S_t !< Salinity at the cell top (ppt) + intent(in) :: S_t !< Salinity at the cell top [ppt] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S_b !< Salinity at the cell bottom (ppt) + intent(in) :: S_b !< Salinity at the cell bottom [ppt] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & intent(in) :: z_t !< The geometric height at the top of the layer, - !! in depth units (Z), usually m. + !! in depth units [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_b !< The geometric height at the bottom of the layer in Z. - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is subtracted out to + intent(in) :: z_b !< The geometric height at the bottom of the layer [Z ~> m]. + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is subtracted out to !! reduce the magnitude of each of the integrals. - real, intent(in) :: rho_0 !< A density, in kg m-3, that is used to calculate the + real, intent(in) :: rho_0 !< A density [kg m-3], that is used to calculate the !! pressure (as p~=-z*rho_0*G_e) used in the equation of state. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m2 Z-1 s-2. - real, intent(in) :: dz_subroundoff !< A miniscule thickness - !! change with the same units as z_t + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m2 Z-1 s-2 ~> m s-2]. + real, intent(in) :: dz_subroundoff !< A miniscule thickness change [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: bathyT !< The depth of the bathymetry in units of Z. + intent(in) :: bathyT !< The depth of the bathymetry [Z ~> m]. type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & - intent(out) :: dpa !< The change in the pressure anomaly across the layer, in Pa. + intent(out) :: dpa !< The change in the pressure anomaly across the layer [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & optional, intent(out) :: intz_dpa !< The integral through the thickness of the layer of !! the pressure anomaly relative to the anomaly at the - !! top of the layer, in Pa Z. + !! top of the layer [Pa Z]. real, dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), & optional, intent(out) :: intx_dpa !< The integral in x of the difference between the !! pressure anomaly at the top and bottom of the layer - !! divided by the x grid spacing, in Pa. + !! divided by the x grid spacing [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), & optional, intent(out) :: inty_dpa !< The integral in y of the difference between the !! pressure anomaly at the top and bottom of the layer - !! divided by the y grid spacing, in Pa. + !! divided by the y grid spacing [Pa]. logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting to !! interpolate T/S for top and bottom integrals. ! This subroutine calculates (by numerical quadrature) integrals of @@ -1109,32 +1123,32 @@ subroutine int_density_dz_generic_plm (T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, & ! a linear interpolation is used to compute intermediate values. ! Local variables - real :: T5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Temperatures along a line of subgrid locations, in degC - real :: S5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Salinities along a line of subgrid locations, in ppt - real :: p5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Pressures along a line of subgrid locations, in Pa - real :: r5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Densities along a line of subgrid locations, in kg m-3 - real :: T15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Temperatures at an array of subgrid locations, in degC - real :: S15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Salinities at an array of subgrid locations, in ppt - real :: p15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Pressures at an array of subgrid locations, in Pa - real :: r15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Densities at an array of subgrid locations, in kg m-3 - real :: wt_t(5), wt_b(5) ! Top and bottom weights, ND. - real :: rho_anom ! A density anomaly in kg m-3. - real :: w_left, w_right ! Left and right weights, ND. + real :: T5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Temperatures along a line of subgrid locations [degC]. + real :: S5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Salinities along a line of subgrid locations [ppt]. + real :: p5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Pressures along a line of subgrid locations [Pa]. + real :: r5((5*HIO%iscB+1):(5*(HIO%iecB+2))) ! Densities along a line of subgrid locations [kg m-3]. + real :: T15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Temperatures at an array of subgrid locations [degC]. + real :: S15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Salinities at an array of subgrid locations [ppt]. + real :: p15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Pressures at an array of subgrid locations [Pa]. + real :: r15((15*HIO%iscB+1):(15*(HIO%iecB+1))) ! Densities at an array of subgrid locations [kg m-3]. + real :: wt_t(5), wt_b(5) ! Top and bottom weights [nondim]. + real :: rho_anom ! A density anomaly [kg m-3]. + real :: w_left, w_right ! Left and right weights [nondim]. real :: intz(5) ! The gravitational acceleration times the integrals of density - ! with height at the 5 sub-column locations, in Pa. - real, parameter :: C1_90 = 1.0/90.0 ! A rational constant, ND. - real :: GxRho ! Gravitational acceleration times density, in kg m-1 Z-1 s-2. - real :: I_Rho ! The inverse of the reference density, in m3 kg-1. - real :: dz(HIO%iscB:HIO%iecB+1) ! Layer thicknesses at tracer points in Z. - real :: dz_x(5,HIO%iscB:HIO%iecB) ! Layer thicknesses along an x-line of subrid locations, in Z. - real :: dz_y(5,HIO%isc:HIO%iec) ! Layer thicknesses along a y-line of subrid locations, in Z. + ! with height at the 5 sub-column locations [Pa]. + real, parameter :: C1_90 = 1.0/90.0 ! A rational constant [nondim]. + real :: GxRho ! Gravitational acceleration times density [kg m-1 Z-1 s-2 ~> kg m-2 s-2]. + real :: I_Rho ! The inverse of the reference density [m3 kg-1]. + real :: dz(HIO%iscB:HIO%iecB+1) ! Layer thicknesses at tracer points [Z ~> m]. + real :: dz_x(5,HIO%iscB:HIO%iecB) ! Layer thicknesses along an x-line of subrid locations [Z ~> m]. + real :: dz_y(5,HIO%isc:HIO%iec) ! Layer thicknesses along a y-line of subrid locations [Z ~> m]. real :: weight_t, weight_b ! Nondimensional wieghts of the top and bottom. real :: massWeightToggle ! A nondimensional toggle factor (0 or 1). - real :: Ttl, Tbl, Ttr, Tbr ! Temperatures at the velocity cell corners, in degC. - real :: Stl, Sbl, Str, Sbr ! Salinities at the velocity cell corners, in ppt. - real :: hWght ! A topographically limited thicknes weight, in Z. - real :: hL, hR ! Thicknesses to the left and right, in Z. - real :: iDenom ! The denominator of the thickness weight expressions, in Z-2. + real :: Ttl, Tbl, Ttr, Tbr ! Temperatures at the velocity cell corners [degC]. + real :: Stl, Sbl, Str, Sbr ! Salinities at the velocity cell corners [ppt]. + real :: hWght ! A topographically limited thicknes weight [Z ~> m]. + real :: hL, hR ! Thicknesses to the left and right [Z ~> m]. + real :: iDenom ! The denominator of the thickness weight expressions [Z-2 ~> m-2]. integer :: Isq, Ieq, Jsq, Jeq, i, j, m, n integer :: iin, jin, ioff, joff integer :: pos @@ -1356,20 +1370,20 @@ end subroutine int_density_dz_generic_plm !> Find the depth at which the reconstructed pressure matches P_tgt subroutine find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_tgt, & rho_ref, G_e, EOS, P_b, z_out, z_tol) - real, intent(in) :: T_t !< Potential temperatue at the cell top (degC) - real, intent(in) :: T_b !< Potential temperatue at the cell bottom (degC) - real, intent(in) :: S_t !< Salinity at the cell top (ppt) - real, intent(in) :: S_b !< Salinity at the cell bottom (ppt) - real, intent(in) :: z_t !< Absolute height of top of cell (Z) (Boussinesq ????) - real, intent(in) :: z_b !< Absolute height of bottom of cell (Z) - real, intent(in) :: P_t !< Anomalous pressure of top of cell, relative to g*rho_ref*z_t (Pa) - real, intent(in) :: P_tgt !< Target pressure at height z_out, relative to g*rho_ref*z_out (Pa) + real, intent(in) :: T_t !< Potential temperatue at the cell top [degC] + real, intent(in) :: T_b !< Potential temperatue at the cell bottom [degC] + real, intent(in) :: S_t !< Salinity at the cell top [ppt] + real, intent(in) :: S_b !< Salinity at the cell bottom [ppt] + real, intent(in) :: z_t !< Absolute height of top of cell [Z ~> m]. (Boussinesq ????) + real, intent(in) :: z_b !< Absolute height of bottom of cell [Z ~> m]. + real, intent(in) :: P_t !< Anomalous pressure of top of cell, relative to g*rho_ref*z_t [Pa] + real, intent(in) :: P_tgt !< Target pressure at height z_out, relative to g*rho_ref*z_out [Pa] real, intent(in) :: rho_ref !< Reference density with which calculation are anomalous to - real, intent(in) :: G_e !< Gravitational acceleration (m2 Z-1 s-2) + real, intent(in) :: G_e !< Gravitational acceleration [m2 Z-1 s-2 ~> m s-2] type(EOS_type), pointer :: EOS !< Equation of state structure - real, intent(out) :: P_b !< Pressure at the bottom of the cell (Pa) - real, intent(out) :: z_out !< Absolute depth at which anomalous pressure = p_tgt (Z) - real, optional, intent(in) :: z_tol !< The tolerance in finding z_out, in Z. + real, intent(out) :: P_b !< Pressure at the bottom of the cell [Pa] + real, intent(out) :: z_out !< Absolute depth at which anomalous pressure = p_tgt [Z ~> m]. + real, optional, intent(in) :: z_tol !< The tolerance in finding z_out [Z ~> m]. ! Local variables real :: top_weight, bottom_weight, rho_anom, w_left, w_right, GxRho, dz, dp, F_guess, F_l, F_r real :: Pa, Pa_left, Pa_right, Pa_tol ! Pressure anomalies, P = integral of g*(rho-rho_ref) dz @@ -1395,7 +1409,7 @@ subroutine find_depth_of_pressure_in_cell(T_t, T_b, S_t, S_b, z_t, z_b, P_t, P_t Pa_left = P_t - P_tgt ! Pa_left < 0 F_r = 1. Pa_right = P_b - P_tgt ! Pa_right > 0 - Pa_tol = GxRho * 1.e-5 ! 1e-5 has diimensions of m, but should be converted to the units of z. + Pa_tol = GxRho * 1.e-5 ! 1e-5 has dimensions of m, but should be converted to the units of z. if (present(z_tol)) Pa_tol = GxRho * z_tol F_guess = F_l - Pa_left / ( Pa_right -Pa_left ) * ( F_r - F_l ) Pa = Pa_right - Pa_left ! To get into iterative loop @@ -1428,16 +1442,16 @@ end subroutine find_depth_of_pressure_in_cell !> Returns change in anomalous pressure change from top to non-dimensional !! position pos between z_t and z_b real function frac_dp_at_pos(T_t, T_b, S_t, S_b, z_t, z_b, rho_ref, G_e, pos, EOS) - real, intent(in) :: T_t !< Potential temperatue at the cell top (degC) - real, intent(in) :: T_b !< Potential temperatue at the cell bottom (degC) - real, intent(in) :: S_t !< Salinity at the cell top (ppt) - real, intent(in) :: S_b !< Salinity at the cell bottom (ppt) - real, intent(in) :: z_t !< The geometric height at the top of the layer, usually in m - real, intent(in) :: z_b !< The geometric height at the bottom of the layer, usually in m - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is subtracted out to + real, intent(in) :: T_t !< Potential temperatue at the cell top [degC] + real, intent(in) :: T_b !< Potential temperatue at the cell bottom [degC] + real, intent(in) :: S_t !< Salinity at the cell top [ppt] + real, intent(in) :: S_b !< Salinity at the cell bottom [ppt] + real, intent(in) :: z_t !< The geometric height at the top of the layer [Z ~> m] + real, intent(in) :: z_b !< The geometric height at the bottom of the layer [Z ~> m] + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is subtracted out to !! reduce the magnitude of each of the integrals. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m s-2. - real, intent(in) :: pos !< The fractional vertical position, nondim, 0 to 1. + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m s-2] + real, intent(in) :: pos !< The fractional vertical position, 0 to 1 [nondim]. type(EOS_type), pointer :: EOS !< Equation of state structure ! Local variables real, parameter :: C1_90 = 1.0/90.0 ! Rational constants. @@ -1475,41 +1489,41 @@ subroutine int_density_dz_generic_ppm (T, T_t, T_b, S, S_t, S_b, & type(hor_index_type), intent(in) :: HII !< Ocean horizontal index structures for the input arrays type(hor_index_type), intent(in) :: HIO !< Ocean horizontal index structures for the output arrays real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T !< Potential temperature referenced to the surface (degC) + intent(in) :: T !< Potential temperature referenced to the surface [degC] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T_t !< Potential temperatue at the cell top (degC) + intent(in) :: T_t !< Potential temperatue at the cell top [degC] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: T_b !< Potential temperatue at the cell bottom (degC) + intent(in) :: T_b !< Potential temperatue at the cell bottom [degC] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S !< Salinity (PSU) + intent(in) :: S !< Salinity [ppt] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S_t !< Salinity at the cell top (ppt) + intent(in) :: S_t !< Salinity at the cell top [ppt] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S_b !< Salinity at the cell bottom (ppt) + intent(in) :: S_b !< Salinity at the cell bottom [ppt] real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_t !< Height at the top of the layer in m. + intent(in) :: z_t !< Height at the top of the layer [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_b !< Height at the bottom of the layer in m. - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is subtracted out to + intent(in) :: z_b !< Height at the bottom of the layer [Z ~> m]. + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is subtracted out to !! reduce the magnitude of each of the integrals. - real, intent(in) :: rho_0 !< A density, in kg m-3, that is used to calculate the + real, intent(in) :: rho_0 !< A density [kg m-3], that is used to calculate the !! pressure (as p~=-z*rho_0*G_e) used in the equation of state. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m s-2. + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m s-2] type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & - intent(out) :: dpa !< The change in the pressure anomaly across the layer, in Pa. + intent(out) :: dpa !< The change in the pressure anomaly across the layer [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & optional, intent(out) :: intz_dpa !< The integral through the thickness of the layer of !! the pressure anomaly relative to the anomaly at the - !! top of the layer, in Pa m. + !! top of the layer [Pa Z ~> Pa m]. real, dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), & optional, intent(out) :: intx_dpa !< The integral in x of the difference between the !! pressure anomaly at the top and bottom of the layer - !! divided by the x grid spacing, in Pa. + !! divided by the x grid spacing [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), & optional, intent(out) :: inty_dpa !< The integral in y of the difference between the !! pressure anomaly at the top and bottom of the layer - !! divided by the y grid spacing, in Pa. + !! divided by the y grid spacing [Pa]. ! This subroutine calculates (by numerical quadrature) integrals of ! pressure anomalies across layers, which are required for calculating the @@ -1521,35 +1535,8 @@ subroutine int_density_dz_generic_ppm (T, T_t, T_b, S, S_t, S_b, & ! It is assumed that the salinity and temperature profiles are linear in the ! vertical. The top and bottom values within each layer are provided and ! a linear interpolation is used to compute intermediate values. -! -! Arguments: T - potential temperature relative to the surface in C -! (the 't' and 'b' subscripts refer to the values at -! the top and the bottom of each layer) -! (in) S - salinity in PSU. -! (the 't' and 'b' subscripts refer to the values at -! the top and the bottom of each layer) -! (in) z_t - height at the top of the layer in m. -! (in) z_b - height at the top of the layer in m. -! (in) rho_ref - A mean density, in kg m-3, that is subtracted out to reduce -! the magnitude of each of the integrals. -! (The pressure is calucated as p~=-z*rho_0*G_e.) -! (in) rho_0 - A density, in kg m-3, that is used to calculate the pressure -! (as p~=-z*rho_0*G_e) used in the equation of state. -! (in) G_e - The Earth's gravitational acceleration, in m s-2. -! (in) G - The ocean's grid structure. -! (in) form_of_eos - integer that selects the eqn of state. -! (out) dpa - The change in the pressure anomaly across the layer, -! in Pa. -! (out,opt) intz_dpa - The integral through the thickness of the layer of the -! pressure anomaly relative to the anomaly at the top of -! the layer, in Pa m. -! (out,opt) intx_dpa - The integral in x of the difference between the -! pressure anomaly at the top and bottom of the layer -! divided by the x grid spacing, in Pa. -! (out,opt) inty_dpa - The integral in y of the difference between the -! pressure anomaly at the top and bottom of the layer -! divided by the y grid spacing, in Pa. + ! Local variables real :: T5(5), S5(5), p5(5), r5(5) real :: rho_anom real :: w_left, w_right, intz(5) @@ -1557,8 +1544,8 @@ subroutine int_density_dz_generic_ppm (T, T_t, T_b, S, S_t, S_b, & real :: GxRho, I_Rho real :: dz real :: weight_t, weight_b - real :: s0, s1, s2 ! parabola coefficients for S - real :: t0, t1, t2 ! parabola coefficients for T + real :: s0, s1, s2 ! parabola coefficients for S [ppt] + real :: t0, t1, t2 ! parabola coefficients for T [degC] real :: xi ! normalized coordinate real :: T_top, T_mid, T_bot real :: S_top, S_mid, S_bot @@ -1939,37 +1926,37 @@ subroutine int_spec_vol_dp_generic(T, S, p_t, p_b, alpha_ref, HI, EOS, & bathyP, dP_neglect, useMassWghtInterp) type(hor_index_type), intent(in) :: HI !< A horizontal index type structure. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: T !< Potential temperature of the layer in C. + intent(in) :: T !< Potential temperature of the layer [degC]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: S !< Salinity of the layer in PSU. + intent(in) :: S !< Salinity of the layer [ppt]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_t !< Pressure atop the layer in Pa. + intent(in) :: p_t !< Pressure atop the layer [Pa]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_b !< Pressure below the layer in Pa. + intent(in) :: p_b !< Pressure below the layer [Pa]. real, intent(in) :: alpha_ref !< A mean specific volume that is !! subtracted out to reduce the magnitude of each of the - !! integrals, in m3 kg-1. The calculation is mathematically + !! integrals [m3 kg-1]. The calculation is mathematically !! identical with different values of alpha_ref, but alpha_ref !! alters the effects of roundoff, and answers do change. type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(out) :: dza !< The change in the geopotential anomaly - !! across the layer, in m2 s-2. + !! across the layer [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & optional, intent(out) :: intp_dza !< The integral in pressure through the !! layer of the geopotential anomaly relative to the anomaly - !! at the bottom of the layer, in Pa m2 s-2. + !! at the bottom of the layer [Pa m2 s-2]. real, dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), & optional, intent(out) :: intx_dza !< The integral in x of the difference !! between the geopotential anomaly at the top and bottom of - !! the layer divided by the x grid spacing, in m2 s-2. + !! the layer divided by the x grid spacing [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), & optional, intent(out) :: inty_dza !< The integral in y of the difference !! between the geopotential anomaly at the top and bottom of - !! the layer divided by the y grid spacing, in m2 s-2. + !! the layer divided by the y grid spacing [m2 s-2]. integer, optional, intent(in) :: halo_size !< The width of halo points on which to calculate dza. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - optional, intent(in) :: bathyP !< The pressure at the bathymetry in Pa + optional, intent(in) :: bathyP !< The pressure at the bathymetry [Pa] real, optional, intent(in) :: dP_neglect !< A miniscule pressure change with !! the same units as p_t (Pa?) logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting @@ -1983,18 +1970,18 @@ subroutine int_spec_vol_dp_generic(T, S, p_t, p_b, alpha_ref, HI, EOS, & ! series for log(1-eps/1+eps) that assumes that |eps| < 0.34. real :: T5(5), S5(5), p5(5), a5(5) - real :: alpha_anom ! The depth averaged specific density anomaly in m3 kg-1. - real :: dp ! The pressure change through a layer, in Pa. -! real :: dp_90(2:4) ! The pressure change through a layer divided by 90, in Pa. - real :: hWght ! A pressure-thickness below topography, in Pa. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Pa. - real :: iDenom ! The inverse of the denominator in the weights, in Pa-2. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: alpha_anom ! The depth averaged specific density anomaly [m3 kg-1]. + real :: dp ! The pressure change through a layer [Pa]. +! real :: dp_90(2:4) ! The pressure change through a layer divided by 90 [Pa]. + real :: hWght ! A pressure-thickness below topography [Pa]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Pa]. + real :: iDenom ! The inverse of the denominator in the weights [Pa-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intp(5) ! The integrals of specific volume with pressure at the - ! 5 sub-column locations, in m2 s-2. + ! 5 sub-column locations [m2 s-2]. logical :: do_massWeight ! Indicates whether to do mass weighting. real, parameter :: C1_90 = 1.0/90.0 ! A rational constant. integer :: Isq, Ieq, Jsq, Jeq, ish, ieh, jsh, jeh, i, j, m, n, halo @@ -2129,42 +2116,42 @@ subroutine int_spec_vol_dp_generic_plm(T_t, T_b, S_t, S_b, p_t, p_b, alpha_ref, intp_dza, intx_dza, inty_dza, useMassWghtInterp) type(hor_index_type), intent(in) :: HI !< A horizontal index type structure. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: T_t !< Potential temperature at the top of the layer in C. + intent(in) :: T_t !< Potential temperature at the top of the layer [degC]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: T_b !< Potential temperature at the bottom of the layer in C. + intent(in) :: T_b !< Potential temperature at the bottom of the layer [degC]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: S_t !< Salinity at the top the layer in PSU. + intent(in) :: S_t !< Salinity at the top the layer [ppt]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: S_b !< Salinity at the bottom the layer in PSU. + intent(in) :: S_b !< Salinity at the bottom the layer [ppt]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_t !< Pressure atop the layer in Pa. + intent(in) :: p_t !< Pressure atop the layer [Pa]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_b !< Pressure below the layer in Pa. + intent(in) :: p_b !< Pressure below the layer [Pa]. real, intent(in) :: alpha_ref !< A mean specific volume that is !! subtracted out to reduce the magnitude of each of the - !! integrals, in m3 kg-1. The calculation is mathematically + !! integrals [m3 kg-1]. The calculation is mathematically !! identical with different values of alpha_ref, but alpha_ref !! alters the effects of roundoff, and answers do change. real, intent(in) :: dP_neglect !< A miniscule pressure change with !! the same units as p_t (Pa?) real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: bathyP !< The pressure at the bathymetry in Pa + intent(in) :: bathyP !< The pressure at the bathymetry [Pa] type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(out) :: dza !< The change in the geopotential anomaly - !! across the layer, in m2 s-2. + !! across the layer [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & optional, intent(out) :: intp_dza !< The integral in pressure through the !! layer of the geopotential anomaly relative to the anomaly - !! at the bottom of the layer, in Pa m2 s-2. + !! at the bottom of the layer [Pa m2 s-2]. real, dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), & optional, intent(out) :: intx_dza !< The integral in x of the difference !! between the geopotential anomaly at the top and bottom of - !! the layer divided by the x grid spacing, in m2 s-2. + !! the layer divided by the x grid spacing [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), & optional, intent(out) :: inty_dza !< The integral in y of the difference !! between the geopotential anomaly at the top and bottom of - !! the layer divided by the y grid spacing, in m2 s-2. + !! the layer divided by the y grid spacing [m2 s-2]. logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting !! to interpolate T/S for top and bottom integrals. @@ -2180,18 +2167,18 @@ subroutine int_spec_vol_dp_generic_plm(T_t, T_b, S_t, S_b, p_t, p_b, alpha_ref, real :: wt_t(5), wt_b(5) real :: T_top, T_bot, S_top, S_bot, P_top, P_bot - real :: alpha_anom ! The depth averaged specific density anomaly in m3 kg-1. - real :: dp ! The pressure change through a layer, in Pa. - real :: dp_90(2:4) ! The pressure change through a layer divided by 90, in Pa. - real :: hWght ! A pressure-thickness below topography, in Pa. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Pa. - real :: iDenom ! The inverse of the denominator in the weights, in Pa-2. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: alpha_anom ! The depth averaged specific density anomaly [m3 kg-1]. + real :: dp ! The pressure change through a layer [Pa]. + real :: dp_90(2:4) ! The pressure change through a layer divided by 90 [Pa]. + real :: hWght ! A pressure-thickness below topography [Pa]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Pa]. + real :: iDenom ! The inverse of the denominator in the weights [Pa-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intp(5) ! The integrals of specific volume with pressure at the - ! 5 sub-column locations, in m2 s-2. + ! 5 sub-column locations [m2 s-2]. real, parameter :: C1_90 = 1.0/90.0 ! A rational constant. logical :: do_massWeight ! Indicates whether to do mass weighting. integer :: Isq, Ieq, Jsq, Jeq, i, j, m, n, pos @@ -2355,10 +2342,10 @@ subroutine convert_temp_salt_for_TEOS10(T, S, press, G, kd, mask_z, EOS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZI_(G),SZJ_(G), SZK_(G)), & - intent(inout) :: T !< Potential temperature referenced to the surface (degC) + intent(inout) :: T !< Potential temperature referenced to the surface [degC] real, dimension(SZI_(G),SZJ_(G), SZK_(G)), & - intent(inout) :: S !< Salinity (PSU) - real, dimension(:), intent(in) :: press !< Pressure at the top of the layer in Pa. + intent(inout) :: S !< Salinity [ppt] + real, dimension(:), intent(in) :: press !< Pressure at the top of the layer [Pa]. type(EOS_type), pointer :: EOS !< Equation of state structure real, dimension(SZI_(G),SZJ_(G), SZK_(G)), & intent(in) :: mask_z !< 3d mask regulating which points to convert. @@ -2393,16 +2380,16 @@ subroutine extract_member_EOS(EOS, form_of_EOS, form_of_TFreeze, EOS_quadrature, logical, optional, intent(out) :: EOS_quadrature !< If true, always use the generic (quadrature) !! code for the integrals of density. logical, optional, intent(out) :: Compressible !< If true, in situ density is a function of pressure. - real , optional, intent(out) :: Rho_T0_S0 !< Density at T=0 degC and S=0 ppt (kg m-3) + real , optional, intent(out) :: Rho_T0_S0 !< Density at T=0 degC and S=0 ppt [kg m-3] real , optional, intent(out) :: drho_dT !< Partial derivative of density with temperature - !! in (kg m-3 degC-1) + !! in [kg m-3 degC-1] real , optional, intent(out) :: dRho_dS !< Partial derivative of density with salinity - !! in (kg m-3 ppt-1) - real , optional, intent(out) :: TFr_S0_P0 !< The freezing potential temperature at S=0, P=0 in deg C. - real , optional, intent(out) :: dTFr_dS !< The derivative of freezing point with salinity, - !! in deg C PSU-1. - real , optional, intent(out) :: dTFr_dp !< The derivative of freezing point with pressure, - !! in deg C Pa-1. + !! in [kg m-3 ppt-1] + real , optional, intent(out) :: TFr_S0_P0 !< The freezing potential temperature at S=0, P=0 [degC]. + real , optional, intent(out) :: dTFr_dS !< The derivative of freezing point with salinity + !! [degC PSU-1]. + real , optional, intent(out) :: dTFr_dp !< The derivative of freezing point with pressure + !! [degC Pa-1]. if (present(form_of_EOS )) form_of_EOS = EOS%form_of_EOS if (present(form_of_TFreeze)) form_of_TFreeze = EOS%form_of_TFreeze diff --git a/src/equation_of_state/MOM_EOS_NEMO.F90 b/src/equation_of_state/MOM_EOS_NEMO.F90 index c925301607..97ed9f8540 100644 --- a/src/equation_of_state/MOM_EOS_NEMO.F90 +++ b/src/equation_of_state/MOM_EOS_NEMO.F90 @@ -22,9 +22,9 @@ module MOM_EOS_NEMO public calculate_density_derivs_nemo public calculate_density_scalar_nemo, calculate_density_array_nemo -!> Compute the in situ density of sea water (units of kg/m^3), or its anomaly with respect to +!> Compute the in situ density of sea water ([kg m-3]), or its anomaly with respect to !! a reference density, from absolute salinity (g/kg), conservative temperature (in deg C), -!! and pressure in Pa, using the expressions derived for use with NEMO +!! and pressure [Pa], using the expressions derived for use with NEMO interface calculate_density_nemo module procedure calculate_density_scalar_nemo, calculate_density_array_nemo end interface calculate_density_nemo @@ -174,15 +174,15 @@ module MOM_EOS_NEMO contains !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from absolute salinity (S in g/kg), conservative temperature -!! (T in deg C), and pressure in Pa. It uses the expressions derived for use +!! [kg m-3]) from absolute salinity (S [g kg-1]), conservative temperature +!! (T [degC]), and pressure [Pa]. It uses the expressions derived for use !! with NEMO. subroutine calculate_density_scalar_nemo(T, S, pressure, rho, rho_ref) - real, intent(in) :: T !< Conservative temperature in C. - real, intent(in) :: S !< Absolute salinity in g/kg. - real, intent(in) :: pressure !< Pressure in Pa. - real, intent(out) :: rho !< In situ density in kg m-3. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, intent(in) :: T !< Conservative temperature [degC]. + real, intent(in) :: S !< Absolute salinity [g kg-1]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: rho !< In situ density [kg m-3]. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. real :: al0, p0, lambda integer :: j @@ -199,17 +199,17 @@ subroutine calculate_density_scalar_nemo(T, S, pressure, rho, rho_ref) end subroutine calculate_density_scalar_nemo !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from absolute salinity (S in g/kg), conservative temperature -!! (T in deg C), and pressure in Pa. It uses the expressions derived for use +!! [kg m-3]) from absolute salinity (S [g kg-1]), conservative temperature +!! (T [degC]), and pressure [Pa]. It uses the expressions derived for use !! with NEMO. subroutine calculate_density_array_nemo(T, S, pressure, rho, start, npts, rho_ref) - real, dimension(:), intent(in) :: T !< Conservative temperature in C. - real, dimension(:), intent(in) :: S !< Absolute salinity in g/kg - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: rho !< in situ density in kg m-3. + real, dimension(:), intent(in) :: T !< Conservative temperature [degC]. + real, dimension(:), intent(in) :: S !< Absolute salinity [g kg-1]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: rho !< in situ density [kg m-3]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Local variables real :: zp, zt, zh, zs, zr0, zn, zn0, zn1, zn2, zn3, zs0 @@ -265,13 +265,13 @@ end subroutine calculate_density_array_nemo !> For a given thermodynamic state, calculate the derivatives of density with conservative !! temperature and absolute salinity, using the expressions derived for use with NEMO. subroutine calculate_density_derivs_array_nemo(T, S, pressure, drho_dT, drho_dS, start, npts) - real, intent(in), dimension(:) :: T !< Conservative temperature in C. - real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + real, intent(in), dimension(:) :: T !< Conservative temperature [degC]. + real, intent(in), dimension(:) :: S !< Absolute salinity [g kg-1]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. real, intent(out), dimension(:) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out), dimension(:) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 ppt-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -339,13 +339,13 @@ end subroutine calculate_density_derivs_array_nemo !> Wrapper to calculate_density_derivs_array for scalar inputs subroutine calculate_density_derivs_scalar_nemo(T, S, pressure, drho_dt, drho_ds) - real, intent(in) :: T !< Potential temperature relative to the surface in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. + real, intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in) :: S !< Salinity [g kg-1]. + real, intent(in) :: pressure !< Pressure [Pa]. real, intent(out) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 ppt-1]. ! Local variables real :: al0, p0, lambda integer :: j @@ -361,18 +361,18 @@ subroutine calculate_density_derivs_scalar_nemo(T, S, pressure, drho_dt, drho_ds drho_ds = drds0(1) end subroutine calculate_density_derivs_scalar_nemo -!> Compute the in situ density of sea water (rho in units of kg/m^3) and the compressibility -!! (drho/dp = C_sound^-2, stored as drho_dp in units of s2 m-2) from absolute salinity -!! (sal in g/kg), conservative temperature (T in deg C), and pressure in Pa, using the expressions +!> Compute the in situ density of sea water (rho in [kg m-3]) and the compressibility +!! (drho/dp = C_sound^-2, stored as drho_dp [s2 m-2]) from absolute salinity +!! (sal in g/kg), conservative temperature (T [degC]), and pressure [Pa], using the expressions !! derived for use with NEMO. subroutine calculate_compress_nemo(T, S, pressure, rho, drho_dp, start, npts) - real, intent(in), dimension(:) :: T !< Conservative temperature in C. - real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. - real, intent(out), dimension(:) :: rho !< In situ density in kg m-3. + real, intent(in), dimension(:) :: T !< Conservative temperature [degC]. + real, intent(in), dimension(:) :: S !< Absolute salinity [g/kg]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. + real, intent(out), dimension(:) :: rho !< In situ density [kg m-3]. real, intent(out), dimension(:) :: drho_dp !< The partial derivative of density with pressure !! (also the inverse of the square of sound speed) - !! in s2 m-2. + !! [s2 m-2]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. diff --git a/src/equation_of_state/MOM_EOS_TEOS10.F90 b/src/equation_of_state/MOM_EOS_TEOS10.F90 index 4a139582a3..bbe9982b6f 100644 --- a/src/equation_of_state/MOM_EOS_TEOS10.F90 +++ b/src/equation_of_state/MOM_EOS_TEOS10.F90 @@ -22,16 +22,16 @@ module MOM_EOS_TEOS10 public calculate_density_second_derivs_teos10 public gsw_sp_from_sr, gsw_pt_from_ct -!> Compute the in situ density of sea water (units of kg/m^3), or its anomaly with respect to +!> Compute the in situ density of sea water ([kg m-3]), or its anomaly with respect to !! a reference density, from absolute salinity (g/kg), conservative temperature (in deg C), -!! and pressure in Pa, using the TEOS10 expressions. +!! and pressure [Pa], using the TEOS10 expressions. interface calculate_density_teos10 module procedure calculate_density_scalar_teos10, calculate_density_array_teos10 end interface calculate_density_teos10 -!> Compute the in situ specific volume of sea water (in units of m^3/kg), or an anomaly with respect +!> Compute the in situ specific volume of sea water (in [m3 kg-1]), or an anomaly with respect !! to a reference specific volume, from absolute salinity (in g/kg), conservative temperature -!! (in deg C), and pressure in Pa, using the TEOS10 expressions. +!! (in deg C), and pressure [Pa], using the TEOS10 expressions. interface calculate_spec_vol_teos10 module procedure calculate_spec_vol_scalar_teos10, calculate_spec_vol_array_teos10 end interface calculate_spec_vol_teos10 @@ -53,15 +53,15 @@ module MOM_EOS_TEOS10 contains !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from absolute salinity (S in g/kg), conservative temperature -!! (T in deg C), and pressure in Pa. It uses the expression from the +!! [kg m-3]) from absolute salinity (S [g kg-1]), conservative temperature +!! (T [degC]), and pressure [Pa]. It uses the expression from the !! TEOS10 website. subroutine calculate_density_scalar_teos10(T, S, pressure, rho, rho_ref) - real, intent(in) :: T !< Conservative temperature in C. - real, intent(in) :: S !< Absolute salinity in g/kg. - real, intent(in) :: pressure !< Pressure in Pa. - real, intent(out) :: rho !< In situ density in kg m-3. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, intent(in) :: T !< Conservative temperature [degC]. + real, intent(in) :: S !< Absolute salinity [g kg-1]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: rho !< In situ density [kg m-3]. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Local variables real, dimension(1) :: T0, S0, pressure0 @@ -77,17 +77,17 @@ subroutine calculate_density_scalar_teos10(T, S, pressure, rho, rho_ref) end subroutine calculate_density_scalar_teos10 !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from absolute salinity (S in g/kg), conservative temperature -!! (T in deg C), and pressure in Pa. It uses the expression from the +!! [kg m-3]) from absolute salinity (S [g kg-1]), conservative temperature +!! (T [degC]), and pressure [Pa]. It uses the expression from the !! TEOS10 website. subroutine calculate_density_array_teos10(T, S, pressure, rho, start, npts, rho_ref) - real, dimension(:), intent(in) :: T !< Conservative temperature in C. - real, dimension(:), intent(in) :: S !< Absolute salinity in g/kg - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: rho !< in situ density in kg m-3. + real, dimension(:), intent(in) :: T !< Conservative temperature [degC]. + real, dimension(:), intent(in) :: S !< Absolute salinity [g kg-1] + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: rho !< in situ density [kg m-3]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Local variables real :: zs, zt, zp @@ -109,15 +109,15 @@ subroutine calculate_density_array_teos10(T, S, pressure, rho, start, npts, rho_ end subroutine calculate_density_array_teos10 !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from absolute salinity (S in g/kg), conservative temperature (T in deg C) -!! and pressure in Pa, using the TEOS10 equation of state. +!! [m3 kg-1]) from absolute salinity (S [g kg-1]), conservative temperature (T [degC]) +!! and pressure [Pa], using the TEOS10 equation of state. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_scalar_teos10(T, S, pressure, specvol, spv_ref) - real, intent(in) :: T !< Conservative temperature in C. - real, intent(in) :: S !< Absolute salinity in g/kg - real, intent(in) :: pressure !< pressure in Pa. - real, intent(out) :: specvol !< in situ specific volume in m3 kg-1. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, intent(in) :: T !< Conservative temperature [degC]. + real, intent(in) :: S !< Absolute salinity [g kg-1] + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: specvol !< in situ specific volume [m3 kg-1]. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables real, dimension(1) :: T0, S0, pressure0, spv0 @@ -130,18 +130,18 @@ end subroutine calculate_spec_vol_scalar_teos10 !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from absolute salinity (S in g/kg), conservative temperature (T in deg C) -!! and pressure in Pa, using the TEOS10 equation of state. +!! [m3 kg-1]) from absolute salinity (S [g kg-1]), conservative temperature (T [degC]) +!! and pressure [Pa], using the TEOS10 equation of state. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_array_teos10(T, S, pressure, specvol, start, npts, spv_ref) real, dimension(:), intent(in) :: T !< Conservative temperature relative to the surface - !! in C. - real, dimension(:), intent(in) :: S !< salinity in g/kg. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: specvol !< in situ specific volume in m3 kg-1. + !! [degC]. + real, dimension(:), intent(in) :: S !< salinity [g kg-1]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: specvol !< in situ specific volume [m3 kg-1]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables real :: zs, zt, zp @@ -166,13 +166,13 @@ end subroutine calculate_spec_vol_array_teos10 !> For a given thermodynamic state, calculate the derivatives of density with conservative !! temperature and absolute salinity, using the TEOS10 expressions. subroutine calculate_density_derivs_array_teos10(T, S, pressure, drho_dT, drho_dS, start, npts) - real, intent(in), dimension(:) :: T !< Conservative temperature in C. - real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + real, intent(in), dimension(:) :: T !< Conservative temperature [degC]. + real, intent(in), dimension(:) :: S !< Absolute salinity [g kg-1]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. real, intent(out), dimension(:) :: drho_dT !< The partial derivative of density with conservative - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out), dimension(:) :: drho_dS !< The partial derivative of density with absolute salinity, - !! in kg m-3 (g/kg)-1. + !! [kg m-3 (g/kg)-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -197,13 +197,13 @@ end subroutine calculate_density_derivs_array_teos10 !> For a given thermodynamic state, calculate the derivatives of density with conservative !! temperature and absolute salinity, using the TEOS10 expressions. subroutine calculate_density_derivs_scalar_teos10(T, S, pressure, drho_dT, drho_dS) - real, intent(in) :: T !< Conservative temperature in C - real, intent(in) :: S !< Absolute Salinity in g/kg - real, intent(in) :: pressure !< Pressure in Pa. + real, intent(in) :: T !< Conservative temperature [degC] + real, intent(in) :: S !< Absolute Salinity [g kg-1] + real, intent(in) :: pressure !< pressure [Pa]. real, intent(out) :: drho_dT !< The partial derivative of density with conservative - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out) :: drho_dS !< The partial derivative of density with absolute salinity, - !! in kg m-3 (g/kg)-1. + !! [kg m-3 (g/kg)-1]. ! Local variables real :: zs, zt, zp @@ -218,13 +218,13 @@ end subroutine calculate_density_derivs_scalar_teos10 !> For a given thermodynamic state, calculate the derivatives of specific volume with conservative !! temperature and absolute salinity, using the TEOS10 expressions. subroutine calculate_specvol_derivs_teos10(T, S, pressure, dSV_dT, dSV_dS, start, npts) - real, intent(in), dimension(:) :: T !< Conservative temperature in C. - real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + real, intent(in), dimension(:) :: T !< Conservative temperature [degC]. + real, intent(in), dimension(:) :: S !< Absolute salinity [g kg-1]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. real, intent(out), dimension(:) :: dSV_dT !< The partial derivative of specific volume with - !! conservative temperature, in m3 kg-1 K-1. + !! conservative temperature [m3 kg-1 degC-1]. real, intent(out), dimension(:) :: dSV_dS !< The partial derivative of specific volume with - !! absolute salinity, in m3 kg-1 / (g/kg). + !! absolute salinity [m3 kg-1 (g/kg)-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -249,9 +249,9 @@ end subroutine calculate_specvol_derivs_teos10 !> Calculate the 5 second derivatives of the equation of state for scalar inputs subroutine calculate_density_second_derivs_scalar_teos10(T, S, pressure, drho_dS_dS, drho_dS_dT, & drho_dT_dT, drho_dS_dP, drho_dT_dP) - real, intent(in) :: T !< Conservative temperature in C - real, intent(in) :: S !< Absolute Salinity in g/kg - real, intent(in) :: pressure !< Pressure in Pa. + real, intent(in) :: T !< Conservative temperature [degC] + real, intent(in) :: S !< Absolute Salinity [g kg-1] + real, intent(in) :: pressure !< pressure [Pa]. real, intent(out) :: drho_dS_dS !< Partial derivative of beta with respect to S real, intent(out) :: drho_dS_dT !< Partial derivative of beta with resepct to T real, intent(out) :: drho_dT_dT !< Partial derivative of alpha with respect to T @@ -274,9 +274,9 @@ end subroutine calculate_density_second_derivs_scalar_teos10 !> Calculate the 5 second derivatives of the equation of state for scalar inputs subroutine calculate_density_second_derivs_array_teos10(T, S, pressure, drho_dS_dS, drho_dS_dT, & drho_dT_dT, drho_dS_dP, drho_dT_dP, start, npts) - real, dimension(:), intent(in) :: T !< Conservative temperature in C - real, dimension(:), intent(in) :: S !< Absolute Salinity in g/kg - real, dimension(:), intent(in) :: pressure !< Pressure in Pa. + real, dimension(:), intent(in) :: T !< Conservative temperature [degC] + real, dimension(:), intent(in) :: S !< Absolute Salinity [g kg-1] + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. real, dimension(:), intent(out) :: drho_dS_dS !< Partial derivative of beta with respect to S real, dimension(:), intent(out) :: drho_dS_dT !< Partial derivative of beta with resepct to T real, dimension(:), intent(out) :: drho_dT_dT !< Partial derivative of alpha with respect to T @@ -306,18 +306,18 @@ subroutine calculate_density_second_derivs_array_teos10(T, S, pressure, drho_dS_ end subroutine calculate_density_second_derivs_array_teos10 !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) and the compressibility (drho/dp = C_sound^-2) -!! (drho_dp in units of s2 m-2) from absolute salinity (sal in g/kg), -!! conservative temperature (T in deg C), and pressure in Pa. It uses the +!! [kg m-3]) and the compressibility (drho/dp = C_sound^-2) +!! (drho_dp [s2 m-2]) from absolute salinity (sal in g/kg), +!! conservative temperature (T [degC]), and pressure [Pa]. It uses the !! subroutines from TEOS10 website subroutine calculate_compress_teos10(T, S, pressure, rho, drho_dp, start, npts) - real, intent(in), dimension(:) :: T !< Conservative temperature in C. - real, intent(in), dimension(:) :: S !< Absolute salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. - real, intent(out), dimension(:) :: rho !< In situ density in kg m-3. + real, intent(in), dimension(:) :: T !< Conservative temperature [degC]. + real, intent(in), dimension(:) :: S !< Absolute salinity [g kg-1]. + real, intent(in), dimension(:) :: pressure !< Pressure [Pa]. + real, intent(out), dimension(:) :: rho !< In situ density [kg m-3]. real, intent(out), dimension(:) :: drho_dp !< The partial derivative of density with pressure !! (also the inverse of the square of sound speed) - !! in s2 m-2. + !! [s2 m-2]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. diff --git a/src/equation_of_state/MOM_EOS_UNESCO.F90 b/src/equation_of_state/MOM_EOS_UNESCO.F90 index eaad8d0128..c7dbad3b66 100644 --- a/src/equation_of_state/MOM_EOS_UNESCO.F90 +++ b/src/equation_of_state/MOM_EOS_UNESCO.F90 @@ -16,16 +16,16 @@ module MOM_EOS_UNESCO public calculate_density_derivs_UNESCO public calculate_density_scalar_UNESCO, calculate_density_array_UNESCO -!> Compute the in situ density of sea water (in units of kg/m^3), or its anomaly with respect to -!! a reference density, from salinity (in psu), potential temperature (in deg C), and pressure in Pa, +!> Compute the in situ density of sea water (in [kg m-3]), or its anomaly with respect to +!! a reference density, from salinity [PSU], potential temperature [degC], and pressure [Pa], !! using the UNESCO (1981) equation of state. interface calculate_density_UNESCO module procedure calculate_density_scalar_UNESCO, calculate_density_array_UNESCO end interface calculate_density_UNESCO -!> Compute the in situ specific volume of sea water (in units of m^3/kg), or an anomaly with respect -!! to a reference specific volume, from salinity (in psu), potential temperature (in deg C), and -!! pressure in Pa, using the UNESCO (1981) equation of state. +!> Compute the in situ specific volume of sea water (in [m3 kg-1]), or an anomaly with respect +!! to a reference specific volume, from salinity [PSU], potential temperature [degC], and +!! pressure [Pa], using the UNESCO (1981) equation of state. interface calculate_spec_vol_UNESCO module procedure calculate_spec_vol_scalar_UNESCO, calculate_spec_vol_array_UNESCO end interface calculate_spec_vol_UNESCO @@ -54,14 +54,14 @@ module MOM_EOS_UNESCO contains !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from salinity (S in psu), potential temperature -!! (T in deg C), and pressure in Pa, using the UNESCO (1981) equation of state. +!! [kg m-3]) from salinity (S [PSU]), potential temperature +!! (T [degC]), and pressure [Pa], using the UNESCO (1981) equation of state. subroutine calculate_density_scalar_UNESCO(T, S, pressure, rho, rho_ref) - real, intent(in) :: T !< Potential temperature relative to the surface in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. - real, intent(out) :: rho !< In situ density in kg m-3. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: rho !< In situ density [kg m-3]. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Local variables real, dimension(1) :: T0, S0, pressure0 @@ -77,24 +77,24 @@ subroutine calculate_density_scalar_UNESCO(T, S, pressure, rho, rho_ref) end subroutine calculate_density_scalar_UNESCO !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from salinity (S in psu), potential temperature -!! (T in deg C), and pressure in Pa, using the UNESCO (1981) equation of state. +!! [kg m-3]) from salinity (S [PSU]), potential temperature +!! (T [degC]), and pressure [Pa], using the UNESCO (1981) equation of state. subroutine calculate_density_array_UNESCO(T, S, pressure, rho, start, npts, rho_ref) - real, dimension(:), intent(in) :: T !< potential temperature relative to the surface in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: rho !< in situ density in kg m-3. + real, dimension(:), intent(in) :: T !< potential temperature relative to the surface [degC]. + real, dimension(:), intent(in) :: S !< salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: rho !< in situ density [kg m-3]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Local variables - real :: t_local, t2, t3, t4, t5 ! Temperature to the 1st - 5th power. - real :: s_local, s32, s2 ! Salinity to the 1st, 3/2, & 2nd power. - real :: p1, p2 ! Pressure (in bars) to the 1st and 2nd power. - real :: rho0 ! Density at 1 bar pressure, in kg m-3. - real :: sig0 ! The anomaly of rho0 from R00, in kg m-3. - real :: ks ! The secant bulk modulus in bar. + real :: t_local, t2, t3, t4, t5 ! Temperature to the 1st - 5th power [degC^n]. + real :: s_local, s32, s2 ! Salinity to the 1st, 3/2, & 2nd power [PSU^n]. + real :: p1, p2 ! Pressure (in bars) to the 1st and 2nd power [bar] and [bar2]. + real :: rho0 ! Density at 1 bar pressure [kg m-3]. + real :: sig0 ! The anomaly of rho0 from R00 [kg m-3]. + real :: ks ! The secant bulk modulus [bar]. integer :: j do j=start,start+npts-1 @@ -131,16 +131,16 @@ subroutine calculate_density_array_UNESCO(T, S, pressure, rho, start, npts, rho_ end subroutine calculate_density_array_UNESCO !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from salinity (S in psu), potential temperature (T in deg C) -!! and pressure in Pa, using the UNESCO (1981) equation of state. +!! [m3 kg-1]) from salinity (S [PSU]), potential temperature (T [degC]) +!! and pressure [Pa], using the UNESCO (1981) equation of state. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_scalar_UNESCO(T, S, pressure, specvol, spv_ref) real, intent(in) :: T !< potential temperature relative to the surface - !! in C. - real, intent(in) :: S !< salinity in PSU. - real, intent(in) :: pressure !< pressure in Pa. - real, intent(out) :: specvol !< in situ specific volume in m3 kg-1. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + !! [degC]. + real, intent(in) :: S !< salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: specvol !< in situ specific volume [m3 kg-1]. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables real, dimension(1) :: T0, S0, pressure0, spv0 @@ -152,25 +152,25 @@ subroutine calculate_spec_vol_scalar_UNESCO(T, S, pressure, specvol, spv_ref) end subroutine calculate_spec_vol_scalar_UNESCO !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from salinity (S in psu), potential temperature (T in deg C) -!! and pressure in Pa, using the UNESCO (1981) equation of state. +!! [m3 kg-1]) from salinity (S [PSU]), potential temperature (T [degC]) +!! and pressure [Pa], using the UNESCO (1981) equation of state. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_array_UNESCO(T, S, pressure, specvol, start, npts, spv_ref) real, dimension(:), intent(in) :: T !< potential temperature relative to the surface - !! in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: specvol !< in situ specific volume in m3 kg-1. + !! [degC]. + real, dimension(:), intent(in) :: S !< salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: specvol !< in situ specific volume [m3 kg-1]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables - real :: t_local, t2, t3, t4, t5; ! Temperature to the 1st - 5th power. - real :: s_local, s32, s2; ! Salinity to the 1st, 3/2, & 2nd power. - real :: p1, p2; ! Pressure (in bars) to the 1st and 2nd power. - real :: rho0; ! Density at 1 bar pressure, in kg m-3. - real :: ks; ! The secant bulk modulus in bar. + real :: t_local, t2, t3, t4, t5 ! Temperature to the 1st - 5th power [degC^n]. + real :: s_local, s32, s2 ! Salinity to the 1st, 3/2, & 2nd power [PSU^n]. + real :: p1, p2 ! Pressure (in bars) to the 1st and 2nd power [bar] and [bar2]. + real :: rho0 ! Density at 1 bar pressure [kg m-3]. + real :: ks ! The secant bulk modulus [bar]. integer :: j do j=start,start+npts-1 @@ -211,27 +211,27 @@ end subroutine calculate_spec_vol_array_UNESCO !! with potential temperature and salinity. subroutine calculate_density_derivs_UNESCO(T, S, pressure, drho_dT, drho_dS, start, npts) real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in), dimension(:) :: S !< Salinity in PSU. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + !! [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< Pressure [Pa]. real, intent(out), dimension(:) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out), dimension(:) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 PSU-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. ! Local variables - real :: t_local, t2, t3, t4, t5; ! Temperature to the 1st - 5th power. - real :: s12, s_local, s32, s2; ! Salinity to the 1/2 - 2nd powers. - real :: p1, p2; ! Pressure (in bars) to the 1st & 2nd power. - real :: rho0; ! Density at 1 bar pressure, in kg m-3. - real :: ks; ! The secant bulk modulus, in bar. - real :: drho0_dT; ! Derivative of rho0 with T, in kg m-3 K-1. - real :: drho0_dS; ! Derivative of rho0 with S, kg m-3 psu-1. - real :: dks_dT; ! Derivative of ks with T, in bar K-1. - real :: dks_dS; ! Derivative of ks with S, in bar psu-1. - real :: denom; ! 1.0 / (ks - p1) in bar-1. + real :: t_local, t2, t3, t4, t5 ! Temperature to the 1st - 5th power [degC^n]. + real :: s12, s_local, s32, s2 ! Salinity to the 1/2 - 2nd powers [PSU^n]. + real :: p1, p2 ! Pressure to the 1st & 2nd power [bar] and [bar2]. + real :: rho0 ! Density at 1 bar pressure [kg m-3]. + real :: ks ! The secant bulk modulus [bar]. + real :: drho0_dT ! Derivative of rho0 with T [kg m-3 degC-1]. + real :: drho0_dS ! Derivative of rho0 with S [kg m-3 PSU-1]. + real :: dks_dT ! Derivative of ks with T [bar degC-1]. + real :: dks_dS ! Derivative of ks with S [bar psu-1]. + real :: denom ! 1.0 / (ks - p1) [bar-1]. integer :: j do j=start,start+npts-1 @@ -282,24 +282,24 @@ end subroutine calculate_density_derivs_UNESCO !! salinity, potential temperature, and pressure. subroutine calculate_compress_UNESCO(T, S, pressure, rho, drho_dp, start, npts) real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in), dimension(:) :: S !< Salinity in PSU. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. - real, intent(out), dimension(:) :: rho !< In situ density in kg m-3. + !! [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< Pressure [Pa]. + real, intent(out), dimension(:) :: rho !< In situ density [kg m-3]. real, intent(out), dimension(:) :: drho_dp !< The partial derivative of density with pressure !! (also the inverse of the square of sound speed) - !! in s2 m-2. + !! [s2 m-2]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. ! Local variables - real :: t_local, t2, t3, t4, t5; ! Temperature to the 1st - 5th power. - real :: s_local, s32, s2; ! Salinity to the 1st, 3/2, & 2nd power. - real :: p1, p2; ! Pressure (in bars) to the 1st and 2nd power. - real :: rho0; ! Density at 1 bar pressure, in kg m-3. - real :: ks; ! The secant bulk modulus in bar. + real :: t_local, t2, t3, t4, t5 ! Temperature to the 1st - 5th power [degC^n]. + real :: s_local, s32, s2 ! Salinity to the 1st, 3/2, & 2nd power [PSU^n]. + real :: p1, p2 ! Pressure to the 1st & 2nd power [bar] and [bar2]. + real :: rho0 ! Density at 1 bar pressure [kg m-3]. + real :: ks ! The secant bulk modulus [bar]. real :: ks_0, ks_1, ks_2 - real :: dks_dp; ! The derivative of the secant bulk modulus + real :: dks_dp ! The derivative of the secant bulk modulus ! with pressure, nondimensional. integer :: j diff --git a/src/equation_of_state/MOM_EOS_Wright.F90 b/src/equation_of_state/MOM_EOS_Wright.F90 index a4535ec961..899f32b27d 100644 --- a/src/equation_of_state/MOM_EOS_Wright.F90 +++ b/src/equation_of_state/MOM_EOS_Wright.F90 @@ -20,17 +20,22 @@ module MOM_EOS_Wright public calculate_density_second_derivs_wright public int_density_dz_wright, int_spec_vol_dp_wright +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. -!> Compute the in situ density of sea water (in units of kg/m^3), or its anomaly with respect to -!! a reference density, from salinity (in psu), potential temperature (in deg C), and pressure in Pa, + +!> Compute the in situ density of sea water (in [kg m-3]), or its anomaly with respect to +!! a reference density, from salinity (in psu), potential temperature (in deg C), and pressure [Pa], !! using the expressions from Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. interface calculate_density_wright module procedure calculate_density_scalar_wright, calculate_density_array_wright end interface calculate_density_wright -!> Compute the in situ specific volume of sea water (in units of m^3/kg), or an anomaly with respect +!> Compute the in situ specific volume of sea water (in [m3 kg-1]), or an anomaly with respect !! to a reference specific volume, from salinity (in psu), potential temperature (in deg C), and -!! pressure in Pa, using the expressions from Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. +!! pressure [Pa], using the expressions from Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. interface calculate_spec_vol_wright module procedure calculate_spec_vol_scalar_wright, calculate_spec_vol_array_wright end interface calculate_spec_vol_wright @@ -69,20 +74,20 @@ module MOM_EOS_Wright contains !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from salinity (S in psu), potential temperature -!! (T in deg C), and pressure in Pa. It uses the expression from +!! [kg m-3]) from salinity (S [PSU]), potential temperature +!! (T [degC]), and pressure [Pa]. It uses the expression from !! Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. subroutine calculate_density_scalar_wright(T, S, pressure, rho, rho_ref) - real, intent(in) :: T !< Potential temperature relative to the surface in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. - real, intent(out) :: rho !< In situ density in kg m-3. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: rho !< In situ density [kg m-3]. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! *====================================================================* ! * This subroutine computes the in situ density of sea water (rho in * -! * units of kg/m^3) from salinity (S in psu), potential temperature * -! * (T in deg C), and pressure in Pa. It uses the expression from * +! * [kg m-3]) from salinity (S [PSU]), potential temperature * +! * (T [degC]), and pressure [Pa]. It uses the expression from * ! * Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. * ! * Coded by R. Hallberg, 7/00 * ! *====================================================================* @@ -99,17 +104,17 @@ subroutine calculate_density_scalar_wright(T, S, pressure, rho, rho_ref) end subroutine calculate_density_scalar_wright !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) from salinity (S in psu), potential temperature -!! (T in deg C), and pressure in Pa. It uses the expression from +!! [kg m-3]) from salinity (S [PSU]), potential temperature +!! (T [degC]), and pressure [Pa]. It uses the expression from !! Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. subroutine calculate_density_array_wright(T, S, pressure, rho, start, npts, rho_ref) - real, dimension(:), intent(in) :: T !< potential temperature relative to the surface in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: rho !< in situ density in kg m-3. + real, dimension(:), intent(in) :: T !< potential temperature relative to the surface [degC]. + real, dimension(:), intent(in) :: S !< salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: rho !< in situ density [kg m-3]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Original coded by R. Hallberg, 7/00, anomaly coded in 3/18. ! Local variables @@ -138,16 +143,16 @@ subroutine calculate_density_array_wright(T, S, pressure, rho, start, npts, rho_ end subroutine calculate_density_array_wright !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from salinity (S in psu), potential temperature (T in deg C) -!! and pressure in Pa. It uses the expression from +!! [m3 kg-1]) from salinity (S [PSU]), potential temperature (T [degC]) +!! and pressure [Pa]. It uses the expression from !! Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_scalar_wright(T, S, pressure, specvol, spv_ref) - real, intent(in) :: T !< potential temperature relative to the surface in C. - real, intent(in) :: S !< salinity in PSU. - real, intent(in) :: pressure !< pressure in Pa. - real, intent(out) :: specvol !< in situ specific volume in m3 kg-1. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, intent(in) :: T !< potential temperature relative to the surface [degC]. + real, intent(in) :: S !< salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: specvol !< in situ specific volume [m3 kg-1]. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables real, dimension(1) :: T0, S0, pressure0, spv0 @@ -159,19 +164,19 @@ subroutine calculate_spec_vol_scalar_wright(T, S, pressure, specvol, spv_ref) end subroutine calculate_spec_vol_scalar_wright !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from salinity (S in psu), potential temperature (T in deg C) -!! and pressure in Pa. It uses the expression from +!! [m3 kg-1]) from salinity (S [PSU]), potential temperature (T [degC]) +!! and pressure [Pa]. It uses the expression from !! Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_array_wright(T, S, pressure, specvol, start, npts, spv_ref) - real, dimension(:), intent(in) :: T !< potential temperature relative to the surface - !! in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: specvol !< in situ specific volume in m3 kg-1. + real, dimension(:), intent(in) :: T !< potential temperature relative to the + !! surface [degC]. + real, dimension(:), intent(in) :: S !< salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: specvol !< in situ specific volume [m3 kg-1]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables real :: al0, p0, lambda @@ -192,14 +197,14 @@ end subroutine calculate_spec_vol_array_wright !> For a given thermodynamic state, return the thermal/haline expansion coefficients subroutine calculate_density_derivs_array_wright(T, S, pressure, drho_dT, drho_dS, start, npts) - real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in), dimension(:) :: S !< Salinity in PSU. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + real, intent(in), dimension(:) :: T !< Potential temperature relative to the + !! surface [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. real, intent(out), dimension(:) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out), dimension(:) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 PSU-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -227,13 +232,13 @@ end subroutine calculate_density_derivs_array_wright !> The scalar version of calculate_density_derivs which promotes scalar inputs to a 1-element array and then !! demotes the output back to a scalar subroutine calculate_density_derivs_scalar_wright(T, S, pressure, drho_dT, drho_dS) - real, intent(in) :: T !< Potential temperature relative to the surface in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. + real, intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. real, intent(out) :: drho_dT !< The partial derivative of density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, intent(out) :: drho_dS !< The partial derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 PSU-1]. ! Local variables needed to promote the input/output scalars to 1-element arrays real, dimension(1) :: T0, S0, P0 @@ -251,14 +256,19 @@ end subroutine calculate_density_derivs_scalar_wright !> Second derivatives of density with respect to temperature, salinity, and pressure subroutine calculate_density_second_derivs_array_wright(T, S, P, drho_ds_ds, drho_ds_dt, drho_dt_dt, & drho_ds_dp, drho_dt_dp, start, npts) - real, dimension(:), intent(in ) :: T !< Potential temperature referenced to 0 dbar - real, dimension(:), intent(in ) :: S !< Salinity in PSU - real, dimension(:), intent(in ) :: P !< Pressure in Pa - real, dimension(:), intent( out) :: drho_ds_ds !< Partial derivative of beta with respect to S - real, dimension(:), intent( out) :: drho_ds_dt !< Partial derivative of beta with resepct to T - real, dimension(:), intent( out) :: drho_dt_dt !< Partial derivative of alpha with respect to T - real, dimension(:), intent( out) :: drho_ds_dp !< Partial derivative of beta with respect to pressure - real, dimension(:), intent( out) :: drho_dt_dp !< Partial derivative of alpha with respect to pressure + real, dimension(:), intent(in ) :: T !< Potential temperature referenced to 0 dbar [degC] + real, dimension(:), intent(in ) :: S !< Salinity [PSU] + real, dimension(:), intent(in ) :: P !< Pressure [Pa] + real, dimension(:), intent( out) :: drho_ds_ds !< Partial derivative of beta with respect + !! to S [kg m-3 PSU-2] + real, dimension(:), intent( out) :: drho_ds_dt !< Partial derivative of beta with respcct + !! to T [kg m-3 PSU-1 degC-1] + real, dimension(:), intent( out) :: drho_dt_dt !< Partial derivative of alpha with respect + !! to T [kg m-3 degC-2] + real, dimension(:), intent( out) :: drho_ds_dp !< Partial derivative of beta with respect + !! to pressure [kg m-3 PSU-1 Pa-1] + real, dimension(:), intent( out) :: drho_dt_dp !< Partial derivative of alpha with respect + !! to pressure [kg m-3 degC-1 Pa-1] integer, intent(in ) :: start !< Starting index in T,S,P integer, intent(in ) :: npts !< Number of points to loop over @@ -299,13 +309,18 @@ end subroutine calculate_density_second_derivs_array_wright subroutine calculate_density_second_derivs_scalar_wright(T, S, P, drho_ds_ds, drho_ds_dt, drho_dt_dt, & drho_ds_dp, drho_dt_dp) real, intent(in ) :: T !< Potential temperature referenced to 0 dbar - real, intent(in ) :: S !< Salinity in PSU - real, intent(in ) :: P !< Pressure in Pa - real, intent( out) :: drho_ds_ds !< Partial derivative of beta with respect to S - real, intent( out) :: drho_ds_dt !< Partial derivative of beta with resepct to T - real, intent( out) :: drho_dt_dt !< Partial derivative of alpha with respect to T - real, intent( out) :: drho_ds_dp !< Partial derivative of beta with respect to pressure - real, intent( out) :: drho_dt_dp !< Partial derivative of alpha with respect to pressure + real, intent(in ) :: S !< Salinity [PSU] + real, intent(in ) :: P !< pressure [Pa] + real, intent( out) :: drho_ds_ds !< Partial derivative of beta with respect + !! to S [kg m-3 PSU-2] + real, intent( out) :: drho_ds_dt !< Partial derivative of beta with respcct + !! to T [kg m-3 PSU-1 degC-1] + real, intent( out) :: drho_dt_dt !< Partial derivative of alpha with respect + !! to T [kg m-3 degC-2] + real, intent( out) :: drho_ds_dp !< Partial derivative of beta with respect + !! to pressure [kg m-3 PSU-1 Pa-1] + real, intent( out) :: drho_dt_dp !< Partial derivative of alpha with respect + !! to pressure [kg m-3 degC-1 Pa-1] ! Local variables real, dimension(1) :: T0, S0, P0 real, dimension(1) :: drdsds, drdsdt, drdtdt, drdsdp, drdtdp @@ -325,13 +340,13 @@ end subroutine calculate_density_second_derivs_scalar_wright !> For a given thermodynamic state, return the partial derivatives of specific volume !! with temperature and salinity subroutine calculate_specvol_derivs_wright(T, S, pressure, dSV_dT, dSV_dS, start, npts) - real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface in C. - real, intent(in), dimension(:) :: S !< Salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. real, intent(out), dimension(:) :: dSV_dT !< The partial derivative of specific volume with - !! potential temperature, in m3 kg-1 K-1. + !! potential temperature [m3 kg-1 degC-1]. real, intent(out), dimension(:) :: dSV_dS !< The partial derivative of specific volume with - !! salinity, in m3 kg-1 / (g/kg). + !! salinity [m3 kg-1 / Pa]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -356,19 +371,19 @@ subroutine calculate_specvol_derivs_wright(T, S, pressure, dSV_dT, dSV_dS, start end subroutine calculate_specvol_derivs_wright !> This subroutine computes the in situ density of sea water (rho in -!! units of kg/m^3) and the compressibility (drho/dp = C_sound^-2) -!! (drho_dp in units of s2 m-2) from salinity (sal in psu), potential -!! temperature (T in deg C), and pressure in Pa. It uses the expressions +!! [kg m-3]) and the compressibility (drho/dp = C_sound^-2) +!! (drho_dp [s2 m-2]) from salinity (sal in psu), potential +!! temperature (T [degC]), and pressure [Pa]. It uses the expressions !! from Wright, 1997, J. Atmos. Ocean. Tech., 14, 735-740. !! Coded by R. Hallberg, 1/01 subroutine calculate_compress_wright(T, S, pressure, rho, drho_dp, start, npts) - real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface in C. - real, intent(in), dimension(:) :: S !< Salinity in PSU. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. - real, intent(out), dimension(:) :: rho !< In situ density in kg m-3. + real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. + real, intent(out), dimension(:) :: rho !< In situ density [kg m-3]. real, intent(out), dimension(:) :: drho_dp !< The partial derivative of density with pressure !! (also the inverse of the square of sound speed) - !! in s2 m-2. + !! [s2 m-2]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -398,58 +413,58 @@ subroutine int_density_dz_wright(T, S, z_t, z_b, rho_ref, rho_0, G_e, HII, HIO, type(hor_index_type), intent(in) :: HIO !< The horizontal index type for the output arrays. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & intent(in) :: T !< Potential temperature relative to the surface - !! in C. + !! [degC]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S !< Salinity in PSU. + intent(in) :: S !< Salinity [PSU]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_t !< Height at the top of the layer in depth units (Z). + intent(in) :: z_t !< Height at the top of the layer in depth units [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_b !< Height at the top of the layer in Z. - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is subtracted out + intent(in) :: z_b !< Height at the top of the layer [Z ~> m]. + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is subtracted out !! to reduce the magnitude of each of the integrals. !! (The pressure is calucated as p~=-z*rho_0*G_e.) - real, intent(in) :: rho_0 !< Density, in kg m-3, that is used to calculate the + real, intent(in) :: rho_0 !< Density [kg m-3], that is used to calculate the !! pressure (as p~=-z*rho_0*G_e) used in the !! equation of state. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m2 Z-1 s-2. + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m2 Z-1 s-2 ~> m s-2]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & intent(out) :: dpa !< The change in the pressure anomaly across the - !! layer, in Pa. + !! layer [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & optional, intent(out) :: intz_dpa !< The integral through the thickness of the layer !! of the pressure anomaly relative to the anomaly - !! at the top of the layer, in Pa Z. + !! at the top of the layer [Pa Z ~> Pa m]. real, dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), & optional, intent(out) :: intx_dpa !< The integral in x of the difference between the !! pressure anomaly at the top and bottom of the - !! layer divided by the x grid spacing, in Pa. + !! layer divided by the x grid spacing [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), & optional, intent(out) :: inty_dpa !< The integral in y of the difference between the !! pressure anomaly at the top and bottom of the - !! layer divided by the y grid spacing, in Pa. + !! layer divided by the y grid spacing [Pa]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - optional, intent(in) :: bathyT !< The depth of the bathymetry in units of Z. - real, optional, intent(in) :: dz_neglect !< A miniscule thickness change in Z. + optional, intent(in) :: bathyT !< The depth of the bathymetry [Z ~> m]. + real, optional, intent(in) :: dz_neglect !< A miniscule thickness change [Z ~> m]. logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting to !! interpolate T/S for top and bottom integrals. ! Local variables real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed) :: al0_2d, p0_2d, lambda_2d real :: al0, p0, lambda - real :: rho_anom ! The density anomaly from rho_ref, in kg m-3. + real :: rho_anom ! The density anomaly from rho_ref [kg m-3]. real :: eps, eps2, rem real :: GxRho, I_Rho real :: p_ave, I_al0, I_Lzz - real :: dz ! The layer thickness, in Z. - real :: hWght ! A pressure-thickness below topography, in Z. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Z. - real :: iDenom ! The inverse of the denominator in the weights, in m-Z. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: dz ! The layer thickness [Z ~> m]. + real :: hWght ! A pressure-thickness below topography [Z ~> m]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Z ~> m]. + real :: iDenom ! The inverse of the denominator in the weights [Z-2 ~> m-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intz(5) ! The integrals of density with height at the - ! 5 sub-column locations, in Pa. + ! 5 sub-column locations [Pa]. logical :: do_massWeight ! Indicates whether to do mass weighting. real, parameter :: C1_3 = 1.0/3.0, C1_7 = 1.0/7.0 ! Rational constants. real, parameter :: C1_9 = 1.0/9.0, C1_90 = 1.0/90.0 ! Rational constants. @@ -602,40 +617,38 @@ subroutine int_spec_vol_dp_wright(T, S, p_t, p_b, spv_ref, HI, dza, & type(hor_index_type), intent(in) :: HI !< The ocean's horizontal index type. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(in) :: T !< Potential temperature relative to the surface - !! in C. + !! [degC]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: S !< Salinity in PSU. + intent(in) :: S !< Salinity [PSU]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_t !< Pressure at the top of the layer in Pa. + intent(in) :: p_t !< Pressure at the top of the layer [Pa]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_b !< Pressure at the top of the layer in Pa. + intent(in) :: p_b !< Pressure at the top of the layer [Pa]. real, intent(in) :: spv_ref !< A mean specific volume that is subtracted out - !! to reduce the magnitude of each of the integrals, m3 kg-1.The calculation is + !! to reduce the magnitude of each of the integrals [m3 kg-1]. The calculation is !! mathematically identical with different values of spv_ref, but this reduces the !! effects of roundoff. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(out) :: dza !< The change in the geopotential anomaly across - !! the layer, in m2 s-2. + !! the layer [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & optional, intent(out) :: intp_dza !< The integral in pressure through the layer of !! the geopotential anomaly relative to the anomaly - !! at the bottom of the layer, in Pa m2 s-2. + !! at the bottom of the layer [Pa m2 s-2]. real, dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), & optional, intent(out) :: intx_dza !< The integral in x of the difference between the !! geopotential anomaly at the top and bottom of - !! the layer divided by the x grid spacing, - !! in m2 s-2. + !! the layer divided by the x grid spacing [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), & optional, intent(out) :: inty_dza !< The integral in y of the difference between the !! geopotential anomaly at the top and bottom of - !! the layer divided by the y grid spacing, - !! in m2 s-2. + !! the layer divided by the y grid spacing [m2 s-2]. integer, optional, intent(in) :: halo_size !< The width of halo points on which to calculate !! dza. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - optional, intent(in) :: bathyP !< The pressure at the bathymetry in Pa + optional, intent(in) :: bathyP !< The pressure at the bathymetry [Pa] real, optional, intent(in) :: dP_neglect !< A miniscule pressure change with - !! the same units as p_t (Pa?) + !! the same units as p_t [Pa] logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting !! to interpolate T/S for top and bottom integrals. @@ -644,17 +657,17 @@ subroutine int_spec_vol_dp_wright(T, S, p_t, p_b, spv_ref, HI, dza, & real :: al0, p0, lambda real :: p_ave real :: rem, eps, eps2 - real :: alpha_anom ! The depth averaged specific density anomaly in m3 kg-1. - real :: dp ! The pressure change through a layer, in Pa. - real :: hWght ! A pressure-thickness below topography, in Pa. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Pa. - real :: iDenom ! The inverse of the denominator in the weights, in Pa-2. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: alpha_anom ! The depth averaged specific volume anomaly [m3 kg-1]. + real :: dp ! The pressure change through a layer [Pa]. + real :: hWght ! A pressure-thickness below topography [Pa]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Pa]. + real :: iDenom ! The inverse of the denominator in the weights [Pa-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intp(5) ! The integrals of specific volume with pressure at the - ! 5 sub-column locations, in m2 s-2. + ! 5 sub-column locations [m2 s-2]. logical :: do_massWeight ! Indicates whether to do mass weighting. real, parameter :: C1_3 = 1.0/3.0, C1_7 = 1.0/7.0 ! Rational constants. real, parameter :: C1_9 = 1.0/9.0, C1_90 = 1.0/90.0 ! Rational constants. diff --git a/src/equation_of_state/MOM_EOS_linear.F90 b/src/equation_of_state/MOM_EOS_linear.F90 index d63929bd62..55b3835681 100644 --- a/src/equation_of_state/MOM_EOS_linear.F90 +++ b/src/equation_of_state/MOM_EOS_linear.F90 @@ -16,16 +16,21 @@ module MOM_EOS_linear public calculate_density_second_derivs_linear public int_density_dz_linear, int_spec_vol_dp_linear +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Compute the density of sea water (in kg/m^3), or its anomaly from a reference density, !! using a simple linear equation of state from salinity (in psu), potential temperature (in deg C) -!! and pressure in Pa. +!! and pressure [Pa]. interface calculate_density_linear module procedure calculate_density_scalar_linear, calculate_density_array_linear end interface calculate_density_linear !> Compute the specific volume of sea water (in m^3/kg), or its anomaly from a reference value, !! using a simple linear equation of state from salinity (in psu), potential temperature (in deg C) -!! and pressure in Pa. +!! and pressure [Pa]. interface calculate_spec_vol_linear module procedure calculate_spec_vol_scalar_linear, calculate_spec_vol_array_linear end interface calculate_spec_vol_linear @@ -46,20 +51,20 @@ module MOM_EOS_linear contains !> This subroutine computes the density of sea water with a trivial -!! linear equation of state (in kg m-3) from salinity (sal in PSU), -!! potential temperature (T in deg C), and pressure in Pa. +!! linear equation of state (in [kg m-3]) from salinity (sal [PSU]), +!! potential temperature (T [degC]), and pressure [Pa]. subroutine calculate_density_scalar_linear(T, S, pressure, rho, & Rho_T0_S0, dRho_dT, dRho_dS, rho_ref) - real, intent(in) :: T !< Potential temperature relative to the surface in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. - real, intent(out) :: rho !< In situ density in kg m-3. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. + real, intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: rho !< In situ density [kg m-3]. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. real, intent(in) :: dRho_dT !< The derivatives of density with temperature - !! in kg m-3 C-1. + !! [kg m-3 degC-1]. real, intent(in) :: dRho_dS !< The derivatives of density with salinity - !! in kg m-3 psu-1. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + !! in [kg m-3 ppt-1]. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. if (present(rho_ref)) then rho = (Rho_T0_S0 - rho_ref) + (dRho_dT*T + dRho_dS*S) @@ -71,21 +76,21 @@ end subroutine calculate_density_scalar_linear !> This subroutine computes the density of sea water with a trivial !! linear equation of state (in kg/m^3) from salinity (sal in psu), -!! potential temperature (T in deg C), and pressure in Pa. +!! potential temperature (T [degC]), and pressure [Pa]. subroutine calculate_density_array_linear(T, S, pressure, rho, start, npts, & Rho_T0_S0, dRho_dT, dRho_dS, rho_ref) - real, dimension(:), intent(in) :: T !< potential temperature relative to the surface in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: rho !< in situ density in kg m-3. + real, dimension(:), intent(in) :: T !< potential temperature relative to the surface [degC]. + real, dimension(:), intent(in) :: S !< salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: rho !< in situ density [kg m-3]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. real, intent(in) :: dRho_dT !< The derivatives of density with temperature - !! in kg m-3 C-1. + !! [kg m-3 degC-1]. real, intent(in) :: dRho_dS !< The derivatives of density with salinity - !! in kg m-3 psu-1. - real, optional, intent(in) :: rho_ref !< A reference density in kg m-3. + !! in [kg m-3 ppt-1]. + real, optional, intent(in) :: rho_ref !< A reference density [kg m-3]. ! Local variables integer :: j @@ -98,20 +103,20 @@ subroutine calculate_density_array_linear(T, S, pressure, rho, start, npts, & end subroutine calculate_density_array_linear !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from salinity (S in psu), potential temperature (T in deg C) -!! and pressure in Pa, using a trivial linear equation of state for density. +!! [m3 kg-1]) from salinity (S [PSU]), potential temperature (T [degC]) +!! and pressure [Pa], using a trivial linear equation of state for density. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_scalar_linear(T, S, pressure, specvol, & Rho_T0_S0, dRho_dT, dRho_dS, spv_ref) real, intent(in) :: T !< potential temperature relative to the surface - !! in C. - real, intent(in) :: S !< salinity in PSU. - real, intent(in) :: pressure !< pressure in Pa. - real, intent(out) :: specvol !< in situ specific volume in m3 kg-1. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. - real, intent(in) :: dRho_dT !< The derivatives of density with temperature in kg m-3 C-1. - real, intent(in) :: dRho_dS !< The derivatives of density with salinity in kg m-3 psu-1. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + !! [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< Pressure [Pa]. + real, intent(out) :: specvol !< In situ specific volume [m3 kg-1]. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. + real, intent(in) :: dRho_dT !< The derivatives of density with temperature [kg m-3 degC-1]. + real, intent(in) :: dRho_dS !< The derivatives of density with salinity [kg m-3 ppt-1]. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables integer :: j @@ -125,22 +130,22 @@ subroutine calculate_spec_vol_scalar_linear(T, S, pressure, specvol, & end subroutine calculate_spec_vol_scalar_linear !> This subroutine computes the in situ specific volume of sea water (specvol in -!! units of m^3/kg) from salinity (S in psu), potential temperature (T in deg C) -!! and pressure in Pa, using a trivial linear equation of state for density. +!! [m3 kg-1]) from salinity (S [PSU]), potential temperature (T [degC]) +!! and pressure [Pa], using a trivial linear equation of state for density. !! If spv_ref is present, specvol is an anomaly from spv_ref. subroutine calculate_spec_vol_array_linear(T, S, pressure, specvol, start, npts, & Rho_T0_S0, dRho_dT, dRho_dS, spv_ref) real, dimension(:), intent(in) :: T !< potential temperature relative to the surface - !! in C. - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pressure !< pressure in Pa. - real, dimension(:), intent(out) :: specvol !< in situ specific volume in m3 kg-1. + !! [degC]. + real, dimension(:), intent(in) :: S !< Salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< Pressure [Pa]. + real, dimension(:), intent(out) :: specvol !< in situ specific volume [m3 kg-1]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. - real, intent(in) :: dRho_dT !< The derivatives of density with temperature in kg m-3 C-1. - real, intent(in) :: dRho_dS !< The derivatives of density with salinity in kg m-3 psu-1. - real, optional, intent(in) :: spv_ref !< A reference specific volume in m3 kg-1. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. + real, intent(in) :: dRho_dT !< The derivatives of density with temperature [kg m-3 degC-1]. + real, intent(in) :: dRho_dS !< The derivatives of density with salinity [kg m-3 ppt-1]. + real, optional, intent(in) :: spv_ref !< A reference specific volume [m3 kg-1]. ! Local variables integer :: j @@ -158,16 +163,16 @@ end subroutine calculate_spec_vol_array_linear subroutine calculate_density_derivs_array_linear(T, S, pressure, drho_dT_out, & drho_dS_out, Rho_T0_S0, dRho_dT, dRho_dS, start, npts) real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in), dimension(:) :: S !< Salinity in PSU. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + !! [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< Pressure [Pa]. real, intent(out), dimension(:) :: drho_dT_out !< The partial derivative of density with - !! potential temperature, in kg m-3 K-1. + !! potential temperature [kg m-3 degC-1]. real, intent(out), dimension(:) :: drho_dS_out !< The partial derivative of density with - !! salinity, in kg m-3 psu-1. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. - real, intent(in) :: dRho_dT !< The derivatives of density with temperature in kg m-3 C-1. - real, intent(in) :: dRho_dS !< The derivatives of density with salinity in kg m-3 psu-1. + !! salinity [kg m-3 ppt-1]. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. + real, intent(in) :: dRho_dT !< The derivative of density with temperature [kg m-3 degC-1]. + real, intent(in) :: dRho_dS !< The derivative of density with salinity [kg m-3 ppt-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. ! Local variables @@ -185,16 +190,16 @@ end subroutine calculate_density_derivs_array_linear subroutine calculate_density_derivs_scalar_linear(T, S, pressure, drho_dT_out, & drho_dS_out, Rho_T0_S0, dRho_dT, dRho_dS) real, intent(in) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. + !! [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. real, intent(out) :: drho_dT_out !< The partial derivative of density with - !! potential temperature, in kg m-3 K-1. + !! potential temperature [kg m-3 degC-1]. real, intent(out) :: drho_dS_out !< The partial derivative of density with - !! salinity, in kg m-3 psu-1. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. - real, intent(in) :: dRho_dT !< The derivatives of density with temperature in kg m-3 C-1. - real, intent(in) :: dRho_dS !< The derivatives of density with salinity in kg m-3 psu-1. + !! salinity [kg m-3 ppt-1]. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. + real, intent(in) :: dRho_dT !< The derivatives of density with temperature [kg m-3 degC-1]. + real, intent(in) :: dRho_dS !< The derivatives of density with salinity [kg m-3 ppt-1]. drho_dT_out = dRho_dT drho_dS_out = dRho_dS @@ -202,17 +207,21 @@ end subroutine calculate_density_derivs_scalar_linear !> This subroutine calculates the five, partial second derivatives of density w.r.t. !! potential temperature and salinity and pressure which for a linear equation of state should all be 0. -subroutine calculate_density_second_derivs_scalar_linear(T, S,pressure, drho_dS_dS, drho_dS_dT, drho_dT_dT,& - drho_dS_dP, drho_dT_dP) - real, intent(in) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pressure !< Pressure in Pa. - real, intent(out) :: drho_dS_dS !< The partial derivative of density with - real, intent(out) :: drho_dS_dT !< The partial derivative of density with - real, intent(out) :: drho_dT_dT !< The partial derivative of density with - real, intent(out) :: drho_dS_dP !< The partial derivative of density with - real, intent(out) :: drho_dT_dP !< The partial derivative of density with +subroutine calculate_density_second_derivs_scalar_linear(T, S, pressure, drho_dS_dS, drho_dS_dT, & + drho_dT_dT, drho_dS_dP, drho_dT_dP) + real, intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, intent(in) :: S !< Salinity [PSU]. + real, intent(in) :: pressure !< pressure [Pa]. + real, intent(out) :: drho_dS_dS !< The second derivative of density with + !! salinity [kg m-3 PSU-2]. + real, intent(out) :: drho_dS_dT !< The second derivative of density with + !! temperature and salinity [kg m-3 ppt-1 degC-1]. + real, intent(out) :: drho_dT_dT !< The second derivative of density with + !! temperature [kg m-3 degC-2]. + real, intent(out) :: drho_dS_dP !< The second derivative of density with + !! salinity and pressure [kg m-3 PSU-1 Pa-1]. + real, intent(out) :: drho_dT_dP !< The second derivative of density with + !! temperature and pressure [kg m-3 degC-1 Pa-1]. drho_dS_dS = 0. drho_dS_dT = 0. @@ -226,15 +235,19 @@ end subroutine calculate_density_second_derivs_scalar_linear !! potential temperature and salinity and pressure which for a linear equation of state should all be 0. subroutine calculate_density_second_derivs_array_linear(T, S,pressure, drho_dS_dS, drho_dS_dT, drho_dT_dT,& drho_dS_dP, drho_dT_dP, start, npts) - real, dimension(:), intent(in) :: T !< Potential temperature relative to the surface - !! in C. - real, dimension(:), intent(in) :: S !< Salinity in PSU. - real, dimension(:), intent(in) :: pressure !< Pressure in Pa. - real, dimension(:), intent(out) :: drho_dS_dS !< The partial derivative of density with - real, dimension(:), intent(out) :: drho_dS_dT !< The partial derivative of density with - real, dimension(:), intent(out) :: drho_dT_dT !< The partial derivative of density with - real, dimension(:), intent(out) :: drho_dS_dP !< The partial derivative of density with - real, dimension(:), intent(out) :: drho_dT_dP !< The partial derivative of density with + real, dimension(:), intent(in) :: T !< Potential temperature relative to the surface [degC]. + real, dimension(:), intent(in) :: S !< Salinity [PSU]. + real, dimension(:), intent(in) :: pressure !< pressure [Pa]. + real, dimension(:), intent(out) :: drho_dS_dS !< The second derivative of density with + !! salinity [kg m-3 PSU-2]. + real, dimension(:), intent(out) :: drho_dS_dT !< The second derivative of density with + !! temperature and salinity [kg m-3 ppt-1 degC-1]. + real, dimension(:), intent(out) :: drho_dT_dT !< The second derivative of density with + !! temperature [kg m-3 degC-2]. + real, dimension(:), intent(out) :: drho_dS_dP !< The second derivative of density with + !! salinity and pressure [kg m-3 PSU-1 Pa-1]. + real, dimension(:), intent(out) :: drho_dT_dP !< The second derivative of density with + !! temperature and pressure [kg m-3 degC-1 Pa-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. ! Local variables @@ -253,20 +266,20 @@ end subroutine calculate_density_second_derivs_array_linear subroutine calculate_specvol_derivs_linear(T, S, pressure, dSV_dT, dSV_dS, & start, npts, Rho_T0_S0, dRho_dT, dRho_dS) real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in), dimension(:) :: S !< Salinity in g/kg. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. + !! [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. real, intent(out), dimension(:) :: dSV_dS !< The partial derivative of specific volume with - !! salinity, in m3 kg-1 / (g/kg). + !! salinity [m3 kg-1 PSU-1]. real, intent(out), dimension(:) :: dSV_dT !< The partial derivative of specific volume with - !! potential temperature, in m3 kg-1 K-1. + !! potential temperature [m3 kg-1 degC-1]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. real, intent(in) :: dRho_dT !< The derivative of density with - !! temperature, in kg m-3 C-1. + !! temperature, [kg m-3 degC-1]. real, intent(in) :: dRho_dS !< The derivative of density with - !! salinity, in kg m-3 psu-1. + !! salinity [kg m-3 ppt-1]. ! Local variables real :: I_rho2 integer :: j @@ -286,20 +299,20 @@ end subroutine calculate_specvol_derivs_linear subroutine calculate_compress_linear(T, S, pressure, rho, drho_dp, start, npts,& Rho_T0_S0, dRho_dT, dRho_dS) real, intent(in), dimension(:) :: T !< Potential temperature relative to the surface - !! in C. - real, intent(in), dimension(:) :: S !< Salinity in PSU. - real, intent(in), dimension(:) :: pressure !< Pressure in Pa. - real, intent(out), dimension(:) :: rho !< In situ density in kg m-3. + !! [degC]. + real, intent(in), dimension(:) :: S !< Salinity [PSU]. + real, intent(in), dimension(:) :: pressure !< pressure [Pa]. + real, intent(out), dimension(:) :: rho !< In situ density [kg m-3]. real, intent(out), dimension(:) :: drho_dp !< The partial derivative of density with pressure !! (also the inverse of the square of sound speed) - !! in s2 m-2. + !! [s2 m-2]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. real, intent(in) :: dRho_dT !< The derivative of density with - !! temperature, in kg m-3 C-1. + !! temperature [kg m-3 degC-1]. real, intent(in) :: dRho_dS !< The derivative of density with - !! salinity, in kg m-3 psu-1. + !! salinity [kg m-3 ppt-1]. ! Local variables integer :: j @@ -319,59 +332,59 @@ subroutine int_density_dz_linear(T, S, z_t, z_b, rho_ref, rho_0_pres, G_e, HII, type(hor_index_type), intent(in) :: HIO !< The horizontal index type for the output arrays. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & intent(in) :: T !< Potential temperature relative to the surface - !! in C. + !! [degC]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: S !< Salinity in PSU. + intent(in) :: S !< Salinity [PSU]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_t !< Height at the top of the layer in depth units (Z). + intent(in) :: z_t !< Height at the top of the layer in depth units [Z ~> m]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - intent(in) :: z_b !< Height at the top of the layer in Z. - real, intent(in) :: rho_ref !< A mean density, in kg m-3, that is subtracted + intent(in) :: z_b !< Height at the top of the layer [Z ~> m]. + real, intent(in) :: rho_ref !< A mean density [kg m-3], that is subtracted !! out to reduce the magnitude of each of the !! integrals. - real, intent(in) :: rho_0_pres !< A density, in kg m-3, that is used to calculate + real, intent(in) :: rho_0_pres !< A density [kg m-3], that is used to calculate !! the pressure (as p~=-z*rho_0_pres*G_e) used in !! the equation of state. rho_0_pres is not used !! here. - real, intent(in) :: G_e !< The Earth's gravitational acceleration, in m2 Z-1 s-2. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. + real, intent(in) :: G_e !< The Earth's gravitational acceleration [m2 Z-1 s-2 ~> m s-2]. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. real, intent(in) :: dRho_dT !< The derivative of density with temperature, - !! in kg m-3 C-1. + !! [kg m-3 degC-1]. real, intent(in) :: dRho_dS !< The derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 ppt-1]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & intent(out) :: dpa !< The change in the pressure anomaly across the - !! layer, in Pa. + !! layer [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%jsd:HIO%jed), & optional, intent(out) :: intz_dpa !< The integral through the thickness of the layer !! of the pressure anomaly relative to the anomaly - !! at the top of the layer, in Pa Z. + !! at the top of the layer [Pa Z]. real, dimension(HIO%IsdB:HIO%IedB,HIO%jsd:HIO%jed), & optional, intent(out) :: intx_dpa !< The integral in x of the difference between the !! pressure anomaly at the top and bottom of the - !! layer divided by the x grid spacing, in Pa. + !! layer divided by the x grid spacing [Pa]. real, dimension(HIO%isd:HIO%ied,HIO%JsdB:HIO%JedB), & optional, intent(out) :: inty_dpa !< The integral in y of the difference between the !! pressure anomaly at the top and bottom of the - !! layer divided by the y grid spacing, in Pa. + !! layer divided by the y grid spacing [Pa]. real, dimension(HII%isd:HII%ied,HII%jsd:HII%jed), & - optional, intent(in) :: bathyT !< The depth of the bathymetry in units of Z. - real, optional, intent(in) :: dz_neglect !< A miniscule thickness change in Z. + optional, intent(in) :: bathyT !< The depth of the bathymetry [Z ~> m]. + real, optional, intent(in) :: dz_neglect !< A miniscule thickness change [Z ~> m]. logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting to !! interpolate T/S for top and bottom integrals. ! Local variables - real :: rho_anom ! The density anomaly from rho_ref, in kg m-3. - real :: raL, raR ! rho_anom to the left and right, in kg m-3. - real :: dz, dzL, dzR ! Layer thicknesses in Z. - real :: hWght ! A pressure-thickness below topography, in Z. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Z. - real :: iDenom ! The inverse of the denominator in the weights, in Z-2. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: rho_anom ! The density anomaly from rho_ref [kg m-3]. + real :: raL, raR ! rho_anom to the left and right [kg m-3]. + real :: dz, dzL, dzR ! Layer thicknesses [Z ~> m]. + real :: hWght ! A pressure-thickness below topography [Z ~> m]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Z ~> m]. + real :: iDenom ! The inverse of the denominator in the weights [Z-2 ~> m-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intz(5) ! The integrals of density with height at the - ! 5 sub-column locations, in Pa. + ! 5 sub-column locations [Pa]. logical :: do_massWeight ! Indicates whether to do mass weighting. real, parameter :: C1_6 = 1.0/6.0, C1_90 = 1.0/90.0 ! Rational constants. integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, i, j, ioff, joff, m @@ -492,60 +505,60 @@ subroutine int_spec_vol_dp_linear(T, S, p_t, p_b, alpha_ref, HI, Rho_T0_S0, & type(hor_index_type), intent(in) :: HI !< The ocean's horizontal index type. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(in) :: T !< Potential temperature relative to the surface - !! in C. + !! [degC]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: S !< Salinity in PSU. + intent(in) :: S !< Salinity [PSU]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_t !< Pressure at the top of the layer in Pa. + intent(in) :: p_t !< Pressure at the top of the layer [Pa]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - intent(in) :: p_b !< Pressure at the top of the layer in Pa. + intent(in) :: p_b !< Pressure at the top of the layer [Pa]. real, intent(in) :: alpha_ref !< A mean specific volume that is subtracted out !! to reduce the magnitude of each of the integrals, m3 kg-1. The calculation is !! mathematically identical with different values of alpha_ref, but this reduces the !! effects of roundoff. - real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0, in kg m-3. - real, intent(in) :: dRho_dT !< The derivative of density with temperature, - !! in kg m-3 C-1. + real, intent(in) :: Rho_T0_S0 !< The density at T=0, S=0 [kg m-3]. + real, intent(in) :: dRho_dT !< The derivative of density with temperature + !! [kg m-3 degC-1]. real, intent(in) :: dRho_dS !< The derivative of density with salinity, - !! in kg m-3 psu-1. + !! in [kg m-3 ppt-1]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & intent(out) :: dza !< The change in the geopotential anomaly across - !! the layer, in m2 s-2. + !! the layer [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & optional, intent(out) :: intp_dza !< The integral in pressure through the layer of !! the geopotential anomaly relative to the anomaly - !! at the bottom of the layer, in Pa m2 s-2. + !! at the bottom of the layer [Pa m2 s-2]. real, dimension(HI%IsdB:HI%IedB,HI%jsd:HI%jed), & optional, intent(out) :: intx_dza !< The integral in x of the difference between the !! geopotential anomaly at the top and bottom of - !! the layer divided by the x grid spacing, - !! in m2 s-2. + !! the layer divided by the x grid spacing + !! [m2 s-2]. real, dimension(HI%isd:HI%ied,HI%JsdB:HI%JedB), & optional, intent(out) :: inty_dza !< The integral in y of the difference between the !! geopotential anomaly at the top and bottom of - !! the layer divided by the y grid spacing, - !! in m2 s-2. + !! the layer divided by the y grid spacing + !! [m2 s-2]. integer, optional, intent(in) :: halo_size !< The width of halo points on which to calculate dza. real, dimension(HI%isd:HI%ied,HI%jsd:HI%jed), & - optional, intent(in) :: bathyP !< The pressure at the bathymetry in Pa + optional, intent(in) :: bathyP !< The pressure at the bathymetry [Pa] real, optional, intent(in) :: dP_neglect !< A miniscule pressure change with - !! the same units as p_t (Pa?) + !! the same units as p_t [Pa] logical, optional, intent(in) :: useMassWghtInterp !< If true, uses mass weighting !! to interpolate T/S for top and bottom integrals. ! Local variables - real :: dRho_TS ! The density anomaly due to T and S, in kg m-3. - real :: alpha_anom ! The specific volume anomaly from 1/rho_ref, in m3 kg-1. - real :: aaL, aaR ! rho_anom to the left and right, in kg m-3. - real :: dp, dpL, dpR ! Layer pressure thicknesses in Pa. - real :: hWght ! A pressure-thickness below topography, in Pa. - real :: hL, hR ! Pressure-thicknesses of the columns to the left and right, in Pa. - real :: iDenom ! The inverse of the denominator in the weights, in Pa-2. - real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column, nonDim. - real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column, nonDim. - real :: wt_L, wt_R ! The linear weights of the left and right columns, nonDim. - real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns, nonDim. + real :: dRho_TS ! The density anomaly due to T and S [kg m-3]. + real :: alpha_anom ! The specific volume anomaly from 1/rho_ref [m3 kg-1]. + real :: aaL, aaR ! rho_anom to the left and right [kg m-3]. + real :: dp, dpL, dpR ! Layer pressure thicknesses [Pa]. + real :: hWght ! A pressure-thickness below topography [Pa]. + real :: hL, hR ! Pressure-thicknesses of the columns to the left and right [Pa]. + real :: iDenom ! The inverse of the denominator in the weights [Pa-2]. + real :: hWt_LL, hWt_LR ! hWt_LA is the weighted influence of A on the left column [nondim]. + real :: hWt_RL, hWt_RR ! hWt_RA is the weighted influence of A on the right column [nondim]. + real :: wt_L, wt_R ! The linear weights of the left and right columns [nondim]. + real :: wtT_L, wtT_R ! The weights for tracers from the left and right columns [nondim]. real :: intp(5) ! The integrals of specific volume with pressure at the - ! 5 sub-column locations, in m2 s-2. + ! 5 sub-column locations [m2 s-2]. logical :: do_massWeight ! Indicates whether to do mass weighting. real, parameter :: C1_6 = 1.0/6.0, C1_90 = 1.0/90.0 ! Rational constants. integer :: Isq, Ieq, Jsq, Jeq, ish, ieh, jsh, jeh, i, j, m, halo diff --git a/src/equation_of_state/MOM_TFreeze.F90 b/src/equation_of_state/MOM_TFreeze.F90 index 99937181c0..50233cae60 100644 --- a/src/equation_of_state/MOM_TFreeze.F90 +++ b/src/equation_of_state/MOM_TFreeze.F90 @@ -13,14 +13,14 @@ module MOM_TFreeze public calculate_TFreeze_linear, calculate_TFreeze_Millero, calculate_TFreeze_teos10 -!> Compute the freezing point potential temperature (in deg C) from salinity (in psu) and -!! pressure (in Pa) using a simple linear expression, with coefficients passed in as arguments. +!> Compute the freezing point potential temperature [degC] from salinity [ppt] and +!! pressure [Pa] using a simple linear expression, with coefficients passed in as arguments. interface calculate_TFreeze_linear module procedure calculate_TFreeze_linear_scalar, calculate_TFreeze_linear_array end interface calculate_TFreeze_linear -!> Compute the freezing point potential temperature (in deg C) from salinity (in psu) and -!! pressure (in Pa) using the expression from Millero (1978) (and in appendix A of Gill 1982), +!> Compute the freezing point potential temperature [degC] from salinity [PSU] and +!! pressure [Pa] using the expression from Millero (1978) (and in appendix A of Gill 1982), !! but with the of the pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an !! expression for potential temperature (not in situ temperature), using a !! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar). @@ -28,8 +28,8 @@ module MOM_TFreeze module procedure calculate_TFreeze_Millero_scalar, calculate_TFreeze_Millero_array end interface calculate_TFreeze_Millero -!> Compute the freezing point conservative temperature (in deg C) from absolute salinity (in g/kg) -!! and pressure (in Pa) using the TEOS10 package. +!> Compute the freezing point conservative temperature [degC] from absolute salinity [g/kg] +!! and pressure [Pa] using the TEOS10 package. interface calculate_TFreeze_teos10 module procedure calculate_TFreeze_teos10_scalar, calculate_TFreeze_teos10_array end interface calculate_TFreeze_teos10 @@ -37,38 +37,38 @@ module MOM_TFreeze contains !> This subroutine computes the freezing point potential temperature -!! (in deg C) from salinity (in psu), and pressure (in Pa) using a simple +!! [degC] from salinity [ppt], and pressure [Pa] using a simple !! linear expression, with coefficients passed in as arguments. subroutine calculate_TFreeze_linear_scalar(S, pres, T_Fr, TFr_S0_P0, & dTFr_dS, dTFr_dp) - real, intent(in) :: S !< salinity in PSU. - real, intent(in) :: pres !< pressure in Pa. - real, intent(out) :: T_Fr !< Freezing point potential temperature in deg C. - real, intent(in) :: TFr_S0_P0 !< The freezing point at S=0, p=0, in deg C. + real, intent(in) :: S !< salinity [ppt]. + real, intent(in) :: pres !< pressure [Pa]. + real, intent(out) :: T_Fr !< Freezing point potential temperature [degC]. + real, intent(in) :: TFr_S0_P0 !< The freezing point at S=0, p=0 [degC]. real, intent(in) :: dTFr_dS !< The derivative of freezing point with salinity, - !! in deg C PSU-1. + !! [degC ppt-1]. real, intent(in) :: dTFr_dp !< The derivative of freezing point with pressure, - !! in deg C Pa-1. + !! [degC Pa-1]. T_Fr = (TFr_S0_P0 + dTFr_dS*S) + dTFr_dp*pres end subroutine calculate_TFreeze_linear_scalar !> This subroutine computes an array of freezing point potential temperatures -!! (in deg C) from salinity (in psu), and pressure (in Pa) using a simple +!! [degC] from salinity [ppt], and pressure [Pa] using a simple !! linear expression, with coefficients passed in as arguments. subroutine calculate_TFreeze_linear_array(S, pres, T_Fr, start, npts, & TFr_S0_P0, dTFr_dS, dTFr_dp) - real, dimension(:), intent(in) :: S !< salinity in PSU. - real, dimension(:), intent(in) :: pres !< pressure in Pa. - real, dimension(:), intent(out) :: T_Fr !< Freezing point potential temperature in deg C. + real, dimension(:), intent(in) :: S !< salinity [ppt]. + real, dimension(:), intent(in) :: pres !< pressure [Pa]. + real, dimension(:), intent(out) :: T_Fr !< Freezing point potential temperature [degC]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. - real, intent(in) :: TFr_S0_P0 !< The freezing point at S=0, p=0, in deg C. + real, intent(in) :: TFr_S0_P0 !< The freezing point at S=0, p=0, [degC]. real, intent(in) :: dTFr_dS !< The derivative of freezing point with salinity, - !! in deg C PSU-1. + !! [degC PSU-1]. real, intent(in) :: dTFr_dp !< The derivative of freezing point with pressure, - !! in deg C Pa-1. + !! [degC Pa-1]. integer :: j do j=start,start+npts-1 @@ -78,15 +78,15 @@ subroutine calculate_TFreeze_linear_array(S, pres, T_Fr, start, npts, & end subroutine calculate_TFreeze_linear_array !> This subroutine computes the freezing point potential temperature -!! (in deg C) from salinity (in psu), and pressure (in Pa) using the expression +!! [degC] from salinity [ppt], and pressure [Pa] using the expression !! from Millero (1978) (and in appendix A of Gill 1982), but with the of the !! pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an !! expression for potential temperature (not in situ temperature), using a !! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar). subroutine calculate_TFreeze_Millero_scalar(S, pres, T_Fr) real, intent(in) :: S !< Salinity in PSU. - real, intent(in) :: pres !< Pressure in Pa. - real, intent(out) :: T_Fr !< Freezing point potential temperature in deg C. + real, intent(in) :: pres !< Pressure [Pa]. + real, intent(out) :: T_Fr !< Freezing point potential temperature [degC]. ! Local variables real, parameter :: cS1 = -0.0575, cS3_2 = 1.710523e-3, cS2 = -2.154996e-4 @@ -97,15 +97,15 @@ subroutine calculate_TFreeze_Millero_scalar(S, pres, T_Fr) end subroutine calculate_TFreeze_Millero_scalar !> This subroutine computes the freezing point potential temperature -!! (in deg C) from salinity (in psu), and pressure (in Pa) using the expression +!! [degC] from salinity [ppt], and pressure [Pa] using the expression !! from Millero (1978) (and in appendix A of Gill 1982), but with the of the !! pressure dependence changed from 7.53e-8 to 7.75e-8 to make this an !! expression for potential temperature (not in situ temperature), using a !! value that is correct at the freezing point at 35 PSU and 5e6 Pa (500 dbar). subroutine calculate_TFreeze_Millero_array(S, pres, T_Fr, start, npts) - real, dimension(:), intent(in) :: S !< Salinity in PSU. - real, dimension(:), intent(in) :: pres !< Pressure in Pa. - real, dimension(:), intent(out) :: T_Fr !< Freezing point potential temperature in deg C. + real, dimension(:), intent(in) :: S !< Salinity [PSU]. + real, dimension(:), intent(in) :: pres !< Pressure [Pa]. + real, dimension(:), intent(out) :: T_Fr !< Freezing point potential temperature [degC]. integer, intent(in) :: start !< The starting point in the arrays. integer, intent(in) :: npts !< The number of values to calculate. @@ -122,12 +122,12 @@ subroutine calculate_TFreeze_Millero_array(S, pres, T_Fr, start, npts) end subroutine calculate_TFreeze_Millero_array !> This subroutine computes the freezing point conservative temperature -!! (in deg C) from absolute salinity (in g/kg), and pressure (in Pa) using the +!! [degC] from absolute salinity [g/kg], and pressure [Pa] using the !! TEOS10 package. subroutine calculate_TFreeze_teos10_scalar(S, pres, T_Fr) - real, intent(in) :: S !< Absolute salinity in g/kg. - real, intent(in) :: pres !< Pressure in Pa. - real, intent(out) :: T_Fr !< Freezing point conservative temperature in deg C. + real, intent(in) :: S !< Absolute salinity [g/kg]. + real, intent(in) :: pres !< Pressure [Pa]. + real, intent(out) :: T_Fr !< Freezing point conservative temperature [degC]. ! Local variables real, dimension(1) :: S0, pres0 @@ -142,12 +142,12 @@ subroutine calculate_TFreeze_teos10_scalar(S, pres, T_Fr) end subroutine calculate_TFreeze_teos10_scalar !> This subroutine computes the freezing point conservative temperature -!! (in deg C) from absolute salinity (in g/kg), and pressure (in Pa) using the +!! [degC] from absolute salinity [g/kg], and pressure [Pa] using the !! TEOS10 package. subroutine calculate_TFreeze_teos10_array(S, pres, T_Fr, start, npts) - real, dimension(:), intent(in) :: S !< absolute salinity in g/kg. - real, dimension(:), intent(in) :: pres !< pressure in Pa. - real, dimension(:), intent(out) :: T_Fr !< Freezing point conservative temperature in deg C. + real, dimension(:), intent(in) :: S !< absolute salinity [g/kg]. + real, dimension(:), intent(in) :: pres !< pressure [Pa]. + real, dimension(:), intent(out) :: T_Fr !< Freezing point conservative temperature [degC]. integer, intent(in) :: start !< the starting point in the arrays. integer, intent(in) :: npts !< the number of values to calculate. diff --git a/src/framework/MOM_diag_mediator.F90 b/src/framework/MOM_diag_mediator.F90 index db9e391610..7d6fd2be60 100644 --- a/src/framework/MOM_diag_mediator.F90 +++ b/src/framework/MOM_diag_mediator.F90 @@ -161,8 +161,8 @@ module MOM_diag_mediator integer :: ied !< The end i-index of cell centers within the data domain integer :: jsd !< The start j-index of cell centers within the data domain integer :: jed !< The end j-index of cell centers within the data domain - real :: time_int !< The time interval in s for any fields - !! that are offered for averaging. + real :: time_int !< The time interval for any fields + !! that are offered for averaging [s]. type(time_type) :: time_end !< The end time of the valid !! interval for any offered field. logical :: ave_enabled = .false. !< True if averaging is enabled. @@ -950,7 +950,7 @@ subroutine post_data_3d(diag_field_id, field, diag_cs, is_static, mask, alt_h) real, optional, intent(in) :: mask(:,:,:) !< If present, use this real array as the data mask. real, dimension(:,:,:), & target, optional, intent(in) :: alt_h !< An alternate thickness to use for vertically - !! remapping this diagnostic, in H. + !! remapping this diagnostic [H ~> m or kg m-2]. ! Local variables type(diag_type), pointer :: diag => null() @@ -1244,7 +1244,7 @@ end subroutine post_xy_average !> This subroutine enables the accumulation of time averages over the specified time interval. subroutine enable_averaging(time_int_in, time_end_in, diag_cs) - real, intent(in) :: time_int_in !< The time interval in s over which any + real, intent(in) :: time_int_in !< The time interval [s] over which any !! values that are offered are valid. type(time_type), intent(in) :: time_end_in !< The end time of the valid interval type(diag_ctrl), intent(inout) :: diag_CS !< Structure used to regulate diagnostic output @@ -1271,7 +1271,7 @@ end subroutine disable_averaging !! currently enabled. .true. is returned if it is. function query_averaging_enabled(diag_cs, time_int, time_end) type(diag_ctrl), intent(in) :: diag_CS !< Structure used to regulate diagnostic output - real, optional, intent(out) :: time_int !< Current setting of diag%time_int, in s + real, optional, intent(out) :: time_int !< Current setting of diag%time_int [s] type(time_type), optional, intent(out) :: time_end !< Current setting of diag%time_end logical :: query_averaging_enabled diff --git a/src/framework/MOM_dyn_horgrid.F90 b/src/framework/MOM_dyn_horgrid.F90 index 51c45bc1b9..11155d73e6 100644 --- a/src/framework/MOM_dyn_horgrid.F90 +++ b/src/framework/MOM_dyn_horgrid.F90 @@ -13,6 +13,11 @@ module MOM_dyn_horgrid public create_dyn_horgrid, destroy_dyn_horgrid, set_derived_dyn_horgrid public rescale_dyn_horgrid_bathymetry +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Describes the horizontal ocean grid with only dynamic memory arrays type, public :: dyn_horgrid_type type(MOM_domain_type), pointer :: Domain => NULL() !< Ocean model domain @@ -62,56 +67,56 @@ module MOM_dyn_horgrid !! during the course of the run via calls to set_first_direction. real, allocatable, dimension(:,:) :: & - mask2dT, & !< 0 for land points and 1 for ocean points on the h-grid. Nd. - geoLatT, & !< The geographic latitude at q points in degrees of latitude or m. - geoLonT, & !< The geographic longitude at q points in degrees of longitude or m. - dxT, & !< dxT is delta x at h points, in m. - IdxT, & !< 1/dxT in m-1. - dyT, & !< dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. - IdyT, & !< dyT is delta y at h points, in m, and IdyT is 1/dyT in m-1. - areaT, & !< The area of an h-cell, in m2. - IareaT !< 1/areaT, in m-2. + mask2dT, & !< 0 for land points and 1 for ocean points on the h-grid [nondim]. + geoLatT, & !< The geographic latitude at q points [degrees of latitude] or [m]. + geoLonT, & !< The geographic longitude at q points [degrees of longitude] or [m]. + dxT, & !< dxT is delta x at h points [m]. + IdxT, & !< 1/dxT [m-1]. + dyT, & !< dyT is delta y at h points [m]. + IdyT, & !< IdyT is 1/dyT [m-1]. + areaT, & !< The area of an h-cell [m2]. + IareaT !< 1/areaT [m-2]. real, allocatable, dimension(:,:) :: sin_rot !< The sine of the angular rotation between the local model grid's northward - !! and the true northward directions. + !! and the true northward directions [nondim]. real, allocatable, dimension(:,:) :: cos_rot !< The cosine of the angular rotation between the local model grid's northward - !! and the true northward directions. + !! and the true northward directions [nondim]. real, allocatable, dimension(:,:) :: & - mask2dCu, & !< 0 for boundary points and 1 for ocean points on the u grid. Nondim. - geoLatCu, & !< The geographic latitude at u points in degrees of latitude or m. - geoLonCu, & !< The geographic longitude at u points in degrees of longitude or m. - dxCu, & !< dxCu is delta x at u points, in m. - IdxCu, & !< 1/dxCu in m-1. - dyCu, & !< dyCu is delta y at u points, in m. - IdyCu, & !< 1/dyCu in m-1. - dy_Cu, & !< The unblocked lengths of the u-faces of the h-cell in m. - IareaCu, & !< The masked inverse areas of u-grid cells in m2. - areaCu !< The areas of the u-grid cells in m2. + mask2dCu, & !< 0 for boundary points and 1 for ocean points on the u grid [nondim]. + geoLatCu, & !< The geographic latitude at u points [degrees of latitude] or [m]. + geoLonCu, & !< The geographic longitude at u points [degrees of longitude] or [m]. + dxCu, & !< dxCu is delta x at u points [m]. + IdxCu, & !< 1/dxCu [m-1]. + dyCu, & !< dyCu is delta y at u points [m]. + IdyCu, & !< 1/dyCu [m-1]. + dy_Cu, & !< The unblocked lengths of the u-faces of the h-cell [m]. + IareaCu, & !< The masked inverse areas of u-grid cells [m2]. + areaCu !< The areas of the u-grid cells [m2]. real, allocatable, dimension(:,:) :: & - mask2dCv, & !< 0 for boundary points and 1 for ocean points on the v grid. Nondim. - geoLatCv, & !< The geographic latitude at v points in degrees of latitude or m. - geoLonCv, & !< The geographic longitude at v points in degrees of longitude or m. - dxCv, & !< dxCv is delta x at v points, in m. - IdxCv, & !< 1/dxCv in m-1. - dyCv, & !< dyCv is delta y at v points, in m. - IdyCv, & !< 1/dyCv in m-1. - dx_Cv, & !< The unblocked lengths of the v-faces of the h-cell in m. - IareaCv, & !< The masked inverse areas of v-grid cells in m2. - areaCv !< The areas of the v-grid cells in m2. + mask2dCv, & !< 0 for boundary points and 1 for ocean points on the v grid [nondim]. + geoLatCv, & !< The geographic latitude at v points [degrees of latitude] or [m]. + geoLonCv, & !< The geographic longitude at v points [degrees of longitude] or [m]. + dxCv, & !< dxCv is delta x at v points [m]. + IdxCv, & !< 1/dxCv [m-1]. + dyCv, & !< dyCv is delta y at v points [m]. + IdyCv, & !< 1/dyCv [m-1]. + dx_Cv, & !< The unblocked lengths of the v-faces of the h-cell [m]. + IareaCv, & !< The masked inverse areas of v-grid cells [m2]. + areaCv !< The areas of the v-grid cells [m2]. real, allocatable, dimension(:,:) :: & - mask2dBu, & !< 0 for boundary points and 1 for ocean points on the q grid. Nondim. - geoLatBu, & !< The geographic latitude at q points in degrees of latitude or m. - geoLonBu, & !< The geographic longitude at q points in degrees of longitude or m. - dxBu, & !< dxBu is delta x at q points, in m. - IdxBu, & !< 1/dxBu in m-1. - dyBu, & !< dyBu is delta y at q points, in m. - IdyBu, & !< 1/dyBu in m-1. - areaBu, & !< areaBu is the area of a q-cell, in m2 - IareaBu !< IareaBu = 1/areaBu in m-2. + mask2dBu, & !< 0 for boundary points and 1 for ocean points on the q grid [nondim]. + geoLatBu, & !< The geographic latitude at q points [degrees of latitude] or [m]. + geoLonBu, & !< The geographic longitude at q points [degrees of longitude] or [m]. + dxBu, & !< dxBu is delta x at q points [m]. + IdxBu, & !< 1/dxBu [m-1]. + dyBu, & !< dyBu is delta y at q points [m]. + IdyBu, & !< 1/dyBu [m-1]. + areaBu, & !< areaBu is the area of a q-cell [m2] + IareaBu !< IareaBu = 1/areaBu [m-2]. real, pointer, dimension(:) :: gridLatT => NULL() !< The latitude of T points for the purpose of labeling the output axes. @@ -131,26 +136,26 @@ module MOM_dyn_horgrid ! Except on a Cartesian grid, these are usually some variant of "degrees". real, allocatable, dimension(:,:) :: & - bathyT !< Ocean bottom depth at tracer points, in depth units. + bathyT !< Ocean bottom depth at tracer points, in depth units [Z ~> m]. logical :: bathymetry_at_vel !< If true, there are separate values for the !! basin depths at velocity points. Otherwise the effects of !! of topography are entirely determined from thickness points. real, allocatable, dimension(:,:) :: & - Dblock_u, & !< Topographic depths at u-points at which the flow is blocked, in Z. - Dopen_u !< Topographic depths at u-points at which the flow is open at width dy_Cu, in Z. + Dblock_u, & !< Topographic depths at u-points at which the flow is blocked [Z ~> m]. + Dopen_u !< Topographic depths at u-points at which the flow is open at width dy_Cu [Z ~> m]. real, allocatable, dimension(:,:) :: & - Dblock_v, & !< Topographic depths at v-points at which the flow is blocked, in Z. - Dopen_v !< Topographic depths at v-points at which the flow is open at width dx_Cv, in Z. + Dblock_v, & !< Topographic depths at v-points at which the flow is blocked [Z ~> m]. + Dopen_v !< Topographic depths at v-points at which the flow is open at width dx_Cv [Z ~> m]. real, allocatable, dimension(:,:) :: & - CoriolisBu !< The Coriolis parameter at corner points, in s-1. + CoriolisBu !< The Coriolis parameter at corner points [s-1]. real, allocatable, dimension(:,:) :: & - df_dx, & !< Derivative d/dx f (Coriolis parameter) at h-points, in s-1 m-1. - df_dy !< Derivative d/dy f (Coriolis parameter) at h-points, in s-1 m-1. + df_dx, & !< Derivative d/dx f (Coriolis parameter) at h-points [s-1 m-1]. + df_dy !< Derivative d/dy f (Coriolis parameter) at h-points [s-1 m-1]. ! These variables are global sums that are useful for 1-d diagnostics - real :: areaT_global !< Global sum of h-cell area in m2 - real :: IareaT_global !< Global sum of inverse h-cell area (1/areaT_global) in m2 + real :: areaT_global !< Global sum of h-cell area [m2] + real :: IareaT_global !< Global sum of inverse h-cell area (1/areaT_global) [m-2] ! These parameters are run-time parameters that are used during some ! initialization routines (but not all) @@ -158,8 +163,8 @@ module MOM_dyn_horgrid real :: west_lon !< The longitude (or x-coordinate) of the first u-line real :: len_lat = 0. !< The latitudinal (or y-coord) extent of physical domain real :: len_lon = 0. !< The longitudinal (or x-coord) extent of physical domain - real :: Rad_Earth = 6.378e6 !< The radius of the planet in meters. - real :: max_depth !< The maximum depth of the ocean in Z. + real :: Rad_Earth = 6.378e6 !< The radius of the planet [m]. + real :: max_depth !< The maximum depth of the ocean [Z ~> m]. end type dyn_horgrid_type contains diff --git a/src/framework/MOM_io.F90 b/src/framework/MOM_io.F90 index db0afa3d8a..c516c96e86 100644 --- a/src/framework/MOM_io.F90 +++ b/src/framework/MOM_io.F90 @@ -97,7 +97,7 @@ subroutine create_file(unit, filename, vars, novars, fields, threading, timeunit integer, intent(in) :: novars !< number of fields written to filename type(fieldtype), intent(inout) :: fields(:) !< array of fieldtypes for each variable integer, optional, intent(in) :: threading !< SINGLE_FILE or MULTIPLE - real, optional, intent(in) :: timeunit !< length, in seconds, of the units for time. The + real, optional, intent(in) :: timeunit !< length of the units for time [s]. The !! default value is 86400.0, for 1 day. type(ocean_grid_type), optional, intent(in) :: G !< ocean horizontal grid structure; G or dG !! is required if the new file uses any @@ -357,7 +357,7 @@ subroutine reopen_file(unit, filename, vars, novars, fields, threading, timeunit integer, intent(in) :: novars !< number of fields written to filename type(fieldtype), intent(inout) :: fields(:) !< array of fieldtypes for each variable integer, optional, intent(in) :: threading !< SINGLE_FILE or MULTIPLE - real, optional, intent(in) :: timeunit !< length, in seconds, of the units for time. The + real, optional, intent(in) :: timeunit !< length of the units for time [s]. The !! default value is 86400.0, for 1 day. type(ocean_grid_type), optional, intent(in) :: G !< ocean horizontal grid structure; G or dG !! is required if a new file uses any diff --git a/src/framework/MOM_spatial_means.F90 b/src/framework/MOM_spatial_means.F90 index 281b38c10a..00f1474879 100644 --- a/src/framework/MOM_spatial_means.F90 +++ b/src/framework/MOM_spatial_means.F90 @@ -65,7 +65,7 @@ function global_layer_mean(var, h, G, GV) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: var !< The variable to average - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZK_(GV)) :: global_layer_mean real, dimension(SZI_(G), SZJ_(G), SZK_(GV)) :: tmpForSumming, weight @@ -97,7 +97,7 @@ function global_volume_mean(var, h, G, GV) real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: var !< The variable being averaged real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real :: global_volume_mean !< The thickness-weighted average of var real :: weight_here @@ -123,7 +123,7 @@ function global_mass_integral(h, G, GV, var, on_PE_only) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & optional, intent(in) :: var !< The variable being integrated logical, optional, intent(in) :: on_PE_only !< If present and true, the sum is only diff --git a/src/ice_shelf/MOM_ice_shelf.F90 b/src/ice_shelf/MOM_ice_shelf.F90 index 82ae988f4f..fa4d2b0581 100644 --- a/src/ice_shelf/MOM_ice_shelf.F90 +++ b/src/ice_shelf/MOM_ice_shelf.F90 @@ -62,6 +62,11 @@ module MOM_ice_shelf public shelf_calc_flux, add_shelf_flux, initialize_ice_shelf, ice_shelf_end public ice_shelf_save_restart, solo_time_step, add_shelf_forces +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure that contains ice shelf parameters and diagnostics handles type, public :: ice_shelf_CS ; private ! Parameters @@ -74,32 +79,32 @@ module MOM_ice_shelf type(ocean_grid_type), pointer :: ocn_grid => NULL() !< A pointer to the ocean model grid !! The rest is private real :: flux_factor = 1.0 !< A factor that can be used to turn off ice shelf - !! melting (flux_factor = 0). + !! melting (flux_factor = 0) [nondim]. character(len=128) :: restart_output_dir = ' ' !< The directory in which to write restart files type(ice_shelf_state), pointer :: ISS => NULL() !< A structure with elements that describe !! the ice-shelf state type(ice_shelf_dyn_CS), pointer :: dCS => NULL() !< The control structure for the ice-shelf dynamics. real, pointer, dimension(:,:) :: & - utide => NULL() !< tidal velocity, in m/s - - real :: ustar_bg !< A minimum value for ustar under ice shelves, in Z s-1. - real :: cdrag !< drag coefficient under ice shelves , non-dimensional. - real :: g_Earth !< The gravitational acceleration in m s-2. - real :: Cp !< The heat capacity of sea water, in J kg-1 K-1. - real :: Rho0 !< A reference ocean density in kg/m3. - real :: Cp_ice !< The heat capacity of fresh ice, in J kg-1 K-1. + utide => NULL() !< tidal velocity [m s-1] + + real :: ustar_bg !< A minimum value for ustar under ice shelves [Z s-1 ~> m s-1]. + real :: cdrag !< drag coefficient under ice shelves [nondim]. + real :: g_Earth !< The gravitational acceleration [m s-2] + real :: Cp !< The heat capacity of sea water [J kg-1 degC-1]. + real :: Rho0 !< A reference ocean density [kg m-3]. + real :: Cp_ice !< The heat capacity of fresh ice [J kg-1 degC-1]. real :: gamma_t !< The (fixed) turbulent exchange velocity in the - !< 2-equation formulation, in m s-1. - real :: Salin_ice !< The salinity of shelf ice, in PSU. - real :: Temp_ice !< The core temperature of shelf ice, in C. - real :: kv_ice !< The viscosity of ice, in m2 s-1. - real :: density_ice !< A typical density of ice, in kg m-3. - real :: rho_ice !< Nominal ice density in kg m-2 Z-1 - real :: kv_molec !< The molecular kinematic viscosity of sea water, m2 s-1. - real :: kd_molec_salt!< The molecular diffusivity of salt, in m2 s-1. - real :: kd_molec_temp!< The molecular diffusivity of heat, in m2 s-1. - real :: Lat_fusion !< The latent heat of fusion, in J kg-1. + !< 2-equation formulation [m s-1]. + real :: Salin_ice !< The salinity of shelf ice [ppt]. + real :: Temp_ice !< The core temperature of shelf ice [degC]. + real :: kv_ice !< The viscosity of ice [m2 s-1]. + real :: density_ice !< A typical density of ice [kg m-3]. + real :: rho_ice !< Nominal ice density [kg m-2 Z-1 ~> kg m-3]. + real :: kv_molec !< The molecular kinematic viscosity of sea water [m2 s-1]. + real :: kd_molec_salt!< The molecular diffusivity of salt [m2 s-1]. + real :: kd_molec_temp!< The molecular diffusivity of heat [m2 s-1]. + real :: Lat_fusion !< The latent heat of fusion [J kg-1]. real :: Gamma_T_3EQ !< Nondimensional heat-transfer coefficient, used in the 3Eq. formulation !< This number should be specified by the user. real :: col_thick_melt_threshold !< if the mixed layer is below this threshold, melt rate @@ -122,14 +127,14 @@ module MOM_ice_shelf !! should be exclusive) real :: density_ocean_avg !< this does not affect ocean circulation OR thermodynamics !! it is to estimate the gravitational driving force at the - !! shelf front(until we think of a better way to do it- + !! shelf front (until we think of a better way to do it, !! but any difference will be negligible) logical :: calve_to_mask !< If true, calve any ice that passes outside of a masked area - real :: min_thickness_simple_calve !< min. ice shelf thickness criteria for calving, in Z - real :: T0 !< temperature at ocean surface in the restoring region, in degC - real :: S0 !< Salinity at ocean surface in the restoring region, in ppt. - real :: input_flux !< Ice volume flux at an upstream open boundary, in m3 s-1. - real :: input_thickness !< Ice thickness at an upstream open boundary, in m. + real :: min_thickness_simple_calve !< min. ice shelf thickness criteria for calving [Z ~> m]. + real :: T0 !< temperature at ocean surface in the restoring region [degC] + real :: S0 !< Salinity at ocean surface in the restoring region [ppt]. + real :: input_flux !< Ice volume flux at an upstream open boundary [m3 s-1]. + real :: input_thickness !< Ice thickness at an upstream open boundary [m]. type(time_type) :: Time !< The component's time. type(EOS_type), pointer :: eqn_of_state => NULL() !< Type that indicates the @@ -191,7 +196,7 @@ subroutine shelf_calc_flux(state, fluxes, Time, time_step, CS, forces) !! thermodynamic or mass-flux forcing fields. type(time_type), intent(in) :: Time !< Start time of the fluxes. real, intent(in) :: time_step !< Length of time over which - !! these fluxes will be applied, in s. + !! these fluxes will be applied [s]. type(ice_shelf_CS), pointer :: CS !< A pointer to the control structure !! returned by a previous call to !! initialize_ice_shelf. @@ -204,16 +209,16 @@ subroutine shelf_calc_flux(state, fluxes, Time, time_step, CS, forces) !! the ice-shelf state real, dimension(SZI_(CS%grid)) :: & - Rhoml, & !< Ocean mixed layer density in kg m-3. + Rhoml, & !< Ocean mixed layer density [kg m-3]. dR0_dT, & !< Partial derivative of the mixed layer density - !< with temperature, in units of kg m-3 K-1. + !< with temperature [kg m-3 degC-1]. dR0_dS, & !< Partial derivative of the mixed layer density - !< with salinity, in units of kg m-3 psu-1. - p_int !< The pressure at the ice-ocean interface, in Pa. + !< with salinity [kg m-3 ppt-1]. + p_int !< The pressure at the ice-ocean interface [Pa]. real, dimension(SZI_(CS%grid),SZJ_(CS%grid)) :: & - exch_vel_t, & !< Sub-shelf thermal exchange velocity, in m/s - exch_vel_s !< Sub-shelf salt exchange velocity, in m/s + exch_vel_t, & !< Sub-shelf thermal exchange velocity [m s-1] + exch_vel_s !< Sub-shelf salt exchange velocity [m s-1] real, dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: & mass_flux !< total mass flux of freshwater across @@ -226,23 +231,24 @@ subroutine shelf_calc_flux(state, fluxes, Time, time_step, CS, forces) !! viscosity is linearly increasing. (Was 1/8. Why?) real, parameter :: RC = 0.20 ! critical flux Richardson number. real :: I_ZETA_N !< The inverse of ZETA_N. - real :: LF, I_LF !< Latent Heat of fusion (J kg-1) and its inverse. + real :: LF, I_LF !< Latent Heat of fusion [J kg-1] and its inverse. real :: I_VK !< The inverse of VK. - real :: PR, SC !< The Prandtl number and Schmidt number, nondim. + real :: PR, SC !< The Prandtl number and Schmidt number [nondim]. ! 3 equations formulation variables real, dimension(SZDI_(CS%grid),SZDJ_(CS%grid)) :: & - Sbdry !< Salinities in the ocean at the interface with the ice shelf, in PSU. + Sbdry !< Salinities in the ocean at the interface with the ice shelf [ppt]. real :: Sbdry_it real :: Sbdry1, Sbdry2, S_a, S_b, S_c ! use to find salt roots - real :: dS_it !< The interface salinity change during an iteration, in PSU. - real :: hBL_neut !< The neutral boundary layer thickness, in m. + real :: dS_it !< The interface salinity change during an iteration [ppt]. + real :: hBL_neut !< The neutral boundary layer thickness [m]. real :: hBL_neut_h_molec !< The ratio of the neutral boundary layer thickness - !! to the molecular boundary layer thickness, ND. - real :: wT_flux !< The vertical fluxes of heat and buoyancy just inside the - real :: wB_flux !< ocean, in C m s-1 and m2 s-3, ###CURRENTLY POSITIVE UPWARD. - real :: dB_dS !< The derivative of buoyancy with salinity, in m s-2 PSU-1. - real :: dB_dT !< The derivative of buoyancy with temperature, in m s-2 C-1. + !! to the molecular boundary layer thickness [nondim]. + !### THESE ARE CURRENTLY POSITIVE UPWARD. + real :: wT_flux !< The vertical flux of heat just inside the ocean [degC m s-1]. + real :: wB_flux !< The vertical flux of heat just inside the ocean [m2 s-3]. + real :: dB_dS !< The derivative of buoyancy with salinity [m s-2 ppt-1]. + real :: dB_dT !< The derivative of buoyancy with temperature [m s-2 degC-1]. real :: I_n_star, n_star_term, absf real :: dIns_dwB !< The partial derivative of I_n_star with wB_flux, in ???. real :: dT_ustar, dS_ustar @@ -623,7 +629,7 @@ subroutine shelf_calc_flux(state, fluxes, Time, time_step, CS, forces) !!!!!!!!!!!!!!!!!!!!!!!!!!!!End of safety checks !!!!!!!!!!!!!!!!!!! enddo ; enddo ! i- and j-loops - ! mass flux (kg/s), part of ISOMIP diags. + ! mass flux [kg s-1], part of ISOMIP diags. mass_flux(:,:) = 0.0 mass_flux(:,:) = ISS%water_flux(:,:) * ISS%area_shelf_h(:,:) @@ -695,10 +701,10 @@ subroutine change_thickness_using_melt(ISS, G, time_step, fluxes, rho_ice, debug type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(ice_shelf_state), intent(inout) :: ISS !< A structure with elements that describe !! the ice-shelf state - real, intent(in) :: time_step !< The time step for this update, in s. + real, intent(in) :: time_step !< The time step for this update [s]. type(forcing), intent(inout) :: fluxes !< structure containing pointers to any possible !! thermodynamic or mass-flux forcing fields. - real, intent(in) :: rho_ice !< The density of ice-shelf ice, in kg m-2 Z-1. + real, intent(in) :: rho_ice !< The density of ice-shelf ice [kg m-2 Z-1 ~> kg m-3]. logical, optional, intent(in) :: debug !< If present and true, write chksums ! locals @@ -750,8 +756,8 @@ subroutine add_shelf_forces(G, CS, forces, do_shelf_area) type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces logical, optional, intent(in) :: do_shelf_area !< If true find the shelf-covered areas. - real :: kv_rho_ice ! The viscosity of ice divided by its density, in m5 kg-1 s-1. - real :: press_ice ! The pressure of the ice shelf per unit area of ocean (not ice) in Pa. + real :: kv_rho_ice ! The viscosity of ice divided by its density [m5 kg-1 s-1]. + real :: press_ice ! The pressure of the ice shelf per unit area of ocean (not ice) [Pa]. logical :: find_area ! If true find the shelf areas at u & v points. type(ice_shelf_state), pointer :: ISS => NULL() ! A structure with elements that describe ! the ice-shelf state @@ -829,7 +835,7 @@ subroutine add_shelf_pressure(G, CS, fluxes) type(ice_shelf_CS), intent(in) :: CS !< This module's control structure. type(forcing), intent(inout) :: fluxes !< A structure of surface fluxes that may be updated. - real :: press_ice !< The pressure of the ice shelf per unit area of ocean (not ice) in Pa. + real :: press_ice !< The pressure of the ice shelf per unit area of ocean (not ice) [Pa]. integer :: i, j, is, ie, js, je, isd, ied, jsd, jed is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -859,32 +865,32 @@ subroutine add_shelf_flux(G, CS, state, fluxes) type(forcing), intent(inout) :: fluxes !< A structure of surface fluxes that may be used/updated. ! local variables - real :: Irho0 !< The inverse of the mean density in m3 kg-1. - real :: frac_area !< The fractional area covered by the ice shelf, nondim. + real :: Irho0 !< The inverse of the mean density [m3 kg-1]. + real :: frac_area !< The fractional area covered by the ice shelf [nondim]. real :: shelf_mass0 !< Total ice shelf mass at previous time (Time-dt). real :: shelf_mass1 !< Total ice shelf mass at current time (Time). - real :: delta_mass_shelf!< Change in ice shelf mass over one time step in kg/s - real :: taux2, tauy2 !< The squared surface stresses, in Pa. - real :: press_ice !< The pressure of the ice shelf per unit area of ocean (not ice) in Pa. + real :: delta_mass_shelf!< Change in ice shelf mass over one time step [kg s-1] + real :: taux2, tauy2 !< The squared surface stresses [Pa]. + real :: press_ice !< The pressure of the ice shelf per unit area of ocean (not ice) [Pa]. real :: asu1, asu2 !< Ocean areas covered by ice shelves at neighboring u- - real :: asv1, asv2 !< and v-points, in m2. - real :: fraz !< refreezing rate in kg m-2 s-1 - real :: mean_melt_flux !< spatial mean melt flux kg/s - real :: sponge_area !< total area of sponge region - real :: t0 !< The previous time (Time-dt) in sec. + real :: asv1, asv2 !< and v-points [m2]. + real :: fraz !< refreezing rate [kg m-2 s-1] + real :: mean_melt_flux !< spatial mean melt flux [kg s-1] or [kg m-2 s-1] at various points in the code. + real :: sponge_area !< total area of sponge region [m2] + real :: t0 !< The previous time (Time-dt) [s]. type(time_type) :: Time0!< The previous time (Time-dt) real, dimension(SZDI_(G),SZDJ_(G)) :: last_mass_shelf !< Ice shelf mass - !! at at previous time (Time-dt), in kg/m^2 - real, dimension(SZDI_(G),SZDJ_(G)) :: last_h_shelf !< Ice shelf thickness in Z - !! at at previous time (Time-dt), in m + !! at at previous time (Time-dt) [kg m-2] + real, dimension(SZDI_(G),SZDJ_(G)) :: last_h_shelf !< Ice shelf thickness [Z ~> m] + !! at at previous time (Time-dt) real, dimension(SZDI_(G),SZDJ_(G)) :: last_hmask !< Ice shelf mask !! at at previous time (Time-dt) - real, dimension(SZDI_(G),SZDJ_(G)) :: last_area_shelf_h !< Ice shelf area - !! at at previous time (Time-dt), m^2 + real, dimension(SZDI_(G),SZDJ_(G)) :: last_area_shelf_h !< Ice shelf area [m2] + !! at at previous time (Time-dt) type(ice_shelf_state), pointer :: ISS => NULL() !< A structure with elements that describe !! the ice-shelf state - real :: kv_rho_ice ! The viscosity of ice divided by its density, in m5 kg-1 s-1. + real :: kv_rho_ice ! The viscosity of ice divided by its density [m5 kg-1 s-1] real, parameter :: rho_fw = 1000.0 ! fresh water density character(len=160) :: mesg ! The text of an error message integer :: i, j, is, ie, js, je, isd, ied, jsd, jed @@ -1050,7 +1056,7 @@ subroutine add_shelf_flux(G, CS, state, fluxes) enddo ; enddo if (CS%DEBUG) then - write(mesg,*) 'Mean melt flux (kg/(m^2 s)), dt = ', mean_melt_flux, CS%time_step + write(mesg,*) 'Mean melt flux [kg m-2 s-1], dt = ', mean_melt_flux, CS%time_step call MOM_mesg(mesg) call MOM_forcing_chksum("After constant sea level", fluxes, G, CS%US, haloshift=0) endif @@ -1739,10 +1745,10 @@ end subroutine ice_shelf_end !> This routine is for stepping a stand-alone ice shelf model without an ocean. subroutine solo_time_step(CS, time_step, nsteps, Time, min_time_step_in) type(ice_shelf_CS), pointer :: CS !< A pointer to the ice shelf control structure - real, intent(in) :: time_step !< The time interval for this update, in s. + real, intent(in) :: time_step !< The time interval for this update [s]. integer, intent(inout) :: nsteps !< The running number of ice shelf steps. type(time_type), intent(inout) :: Time !< The current model time - real, optional, intent(in) :: min_time_step_in !< The minimum permitted time step in s. + real, optional, intent(in) :: min_time_step_in !< The minimum permitted time step [s]. type(ocean_grid_type), pointer :: G => NULL() type(unit_scale_type), pointer :: US => NULL() ! Pointer to a structure containing diff --git a/src/ice_shelf/MOM_ice_shelf_dynamics.F90 b/src/ice_shelf/MOM_ice_shelf_dynamics.F90 index 050fad5089..b53021bbb2 100644 --- a/src/ice_shelf/MOM_ice_shelf_dynamics.F90 +++ b/src/ice_shelf/MOM_ice_shelf_dynamics.F90 @@ -32,12 +32,17 @@ module MOM_ice_shelf_dynamics public ice_time_step_CFL, ice_shelf_dyn_end public shelf_advance_front, ice_shelf_min_thickness_calve, calve_to_mask +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure for the ice shelf dynamics. type, public :: ice_shelf_dyn_CS ; private - real, pointer, dimension(:,:) :: u_shelf => NULL() !< the zonal (?) velocity of the ice shelf/sheet, - !! in meters per second??? on q-points (B grid) - real, pointer, dimension(:,:) :: v_shelf => NULL() !< the meridional velocity of the ice shelf/sheet, - !! in m/s ?? on q-points (B grid) + real, pointer, dimension(:,:) :: u_shelf => NULL() !< the zonal (?) velocity of the ice shelf/sheet + !! on q-points (B grid) [m s-1]?? + real, pointer, dimension(:,:) :: v_shelf => NULL() !< the meridional velocity of the ice shelf/sheet + !! on q-points (B grid) [m s-1]?? real, pointer, dimension(:,:) :: u_face_mask => NULL() !< mask for velocity boundary conditions on the C-grid !! u-face - this is because the FEM cares about FACES THAT GET INTEGRATED OVER, @@ -52,9 +57,9 @@ module MOM_ice_shelf_dynamics real, pointer, dimension(:,:) :: u_face_mask_bdry => NULL() !< A duplicate copy of u_face_mask? real, pointer, dimension(:,:) :: v_face_mask_bdry => NULL() !< A duplicate copy of v_face_mask? real, pointer, dimension(:,:) :: u_flux_bdry_val => NULL() !< The ice volume flux into the cell through open boundary - !! u-faces (where u_face_mask=4), in Z m2 s-1??? + !! u-faces (where u_face_mask=4) [Z m2 s-1 ~> m3 s-1]?? real, pointer, dimension(:,:) :: v_flux_bdry_val => NULL() !< The ice volume flux into the cell through open boundary - !! v-faces (where v_face_mask=4), in Z m2 s-1??? + !! v-faces (where v_face_mask=4) [Z m2 s-1 ~> m3 s-1]?? ! needed where u_face_mask is equal to 4, similary for v_face_mask real, pointer, dimension(:,:) :: umask => NULL() !< u-mask on the actual degrees of freedom (B grid) !! 1=normal node, 3=inhomogeneous boundary node, @@ -65,39 +70,39 @@ module MOM_ice_shelf_dynamics real, pointer, dimension(:,:) :: calve_mask => NULL() !< a mask to prevent the ice shelf front from !! advancing past its initial position (but it may retreat) real, pointer, dimension(:,:) :: t_shelf => NULL() !< Veritcally integrated temperature in the ice shelf/stream, - !! in degC on corner-points (B grid) + !! on corner-points (B grid) [degC] real, pointer, dimension(:,:) :: tmask => NULL() !< A mask on tracer points that is 1 where there is ice. - real, pointer, dimension(:,:) :: ice_visc => NULL() !< Glen's law ice viscosity, perhaps in m. - real, pointer, dimension(:,:) :: thickness_bdry_val => NULL() !< The ice thickness at an inflowing boundary, in Z. - real, pointer, dimension(:,:) :: u_bdry_val => NULL() !< The zonal ice velocity at inflowing boundaries in m/s??? - real, pointer, dimension(:,:) :: v_bdry_val => NULL() !< The meridional ice velocity at inflowing boundaries in m/s??? - real, pointer, dimension(:,:) :: h_bdry_val => NULL() !< The ice thickness at inflowing boundaries, in m. - real, pointer, dimension(:,:) :: t_bdry_val => NULL() !< The ice temperature at inflowing boundaries, in deg C. + real, pointer, dimension(:,:) :: ice_visc => NULL() !< Glen's law ice viscosity, perhaps in [m]. + real, pointer, dimension(:,:) :: thickness_bdry_val => NULL() !< The ice thickness at an inflowing boundary [Z ~> m]. + real, pointer, dimension(:,:) :: u_bdry_val => NULL() !< The zonal ice velocity at inflowing boundaries [m s-1]?? + real, pointer, dimension(:,:) :: v_bdry_val => NULL() !< The meridional ice velocity at inflowing boundaries [m s-1]?? + real, pointer, dimension(:,:) :: h_bdry_val => NULL() !< The ice thickness at inflowing boundaries [m]. + real, pointer, dimension(:,:) :: t_bdry_val => NULL() !< The ice temperature at inflowing boundaries [degC]. real, pointer, dimension(:,:) :: taub_beta_eff => NULL() !< nonlinear part of "linearized" basal stress. !! The exact form depends on basal law exponent and/or whether flow is "hybridized" a la Goldberg 2011 real, pointer, dimension(:,:) :: OD_rt => NULL() !< A running total for calculating OD_av. real, pointer, dimension(:,:) :: float_frac_rt => NULL() !< A running total for calculating float_frac. - real, pointer, dimension(:,:) :: OD_av => NULL() !< The time average open ocean depth, in Z. + real, pointer, dimension(:,:) :: OD_av => NULL() !< The time average open ocean depth [Z ~> m]. real, pointer, dimension(:,:) :: float_frac => NULL() !< Fraction of the time a cell is "exposed", i.e. the column !! thickness is below a threshold. !### [if float_frac = 1 ==> grounded; obviously counterintuitive; might fix] integer :: OD_rt_counter = 0 !< A counter of the number of contributions to OD_rt. - real :: velocity_update_time_step !< The time in s to update the ice shelf velocity through the - !! nonlinear elliptic equation, or 0 to update every timestep. + real :: velocity_update_time_step !< The time interval over which to update the ice shelf velocity + !! using the nonlinear elliptic equation, or 0 to update every timestep [s]. ! DNGoldberg thinks this should be done no more often than about once a day ! (maybe longer) because it will depend on ocean values that are averaged over ! this time interval, and solving for the equiliabrated flow will begin to lose ! meaning if it is done too frequently. - real :: elapsed_velocity_time !< The elapsed time since the ice velocies were last udated, in s. + real :: elapsed_velocity_time !< The elapsed time since the ice velocies were last udated [s]. - real :: g_Earth !< The gravitational acceleration in m s-2. - real :: density_ice !< A typical density of ice, in kg m-3. + real :: g_Earth !< The gravitational acceleration [m s-2]. + real :: density_ice !< A typical density of ice [kg m-3]. - logical :: GL_regularize !< whether to regularize the floatation condition - !! at the grounding line a la Goldberg Holland Schoof 2009 + logical :: GL_regularize !< Specifies whether to regularize the floatation condition + !! at the grounding line as in Goldberg Holland Schoof 2009 integer :: n_sub_regularize !< partition of cell over which to integrate for !! interpolated grounding line the (rectangular) is @@ -111,20 +116,20 @@ module MOM_ice_shelf_dynamics real :: CFL_factor !< A factor used to limit subcycled advective timestep in uncoupled runs !! i.e. dt <= CFL_factor * min(dx / u) - real :: A_glen_isothermal !< Ice viscosity parameter in Glen's Lawa, in Pa-1/3 a. + real :: A_glen_isothermal !< Ice viscosity parameter in Glen's Lawa, [Pa-1/3 year]. real :: n_glen !< Nonlinearity exponent in Glen's Law - real :: eps_glen_min !< Min. strain rate to avoid infinite Glen's law viscosity, in a-1. + real :: eps_glen_min !< Min. strain rate to avoid infinite Glen's law viscosity, [year-1]. real :: C_basal_friction !< Ceofficient in sliding law tau_b = C u^(n_basal_friction), in !! units="Pa (m-a)-(n_basal_friction) real :: n_basal_friction !< Exponent in sliding law tau_b = C u^(m_slide) - real :: density_ocean_avg !< this does not affect ocean circulation OR thermodynamics - !! it is to estimate the gravitational driving force at the - !! shelf front(until we think of a better way to do it- - !! but any difference will be negligible) + real :: density_ocean_avg !< This does not affect ocean circulation or thermodynamics. + !! It is used to estimate the gravitational driving force at the + !! shelf front (until we think of a better way to do it, + !! but any difference will be negligible). real :: thresh_float_col_depth !< The water column depth over which the shelf if considered to be floating logical :: moving_shelf_front !< Specify whether to advance shelf front (and calve). logical :: calve_to_mask !< If true, calve off the ice shelf when it passes the edge of a mask. - real :: min_thickness_simple_calve !< min. ice shelf thickness criteria for calving, in Z + real :: min_thickness_simple_calve !< min. ice shelf thickness criteria for calving [Z ~> m]. real :: cg_tolerance !< The tolerance in the CG solver, relative to initial residual, that !! deterimnes when to stop the conguage gradient iterations. @@ -133,7 +138,7 @@ module MOM_ice_shelf_dynamics integer :: cg_max_iterations !< The maximum number of iterations that can be used in the CG solver integer :: nonlin_solve_err_mode !< 1: exit vel solve based on nonlin residual !! 2: exit based on "fixed point" metric (|u - u_last| / |u| < tol where | | is infty-norm - logical :: use_reproducing_sums !< use new reproducing sums of Bob & Alistair for global sums. + logical :: use_reproducing_sums !< Use reproducing global sums. ! ids for outputting intermediate thickness in advection subroutine (debugging) !integer :: id_h_after_uflux = -1, id_h_after_vflux = -1, id_h_after_adv = -1 @@ -565,11 +570,11 @@ end subroutine initialize_diagnostic_fields !> This function returns the global maximum timestep that can be taken based on the current !! ice velocities. Because it involves finding a global minimum, it can be suprisingly expensive. function ice_time_step_CFL(CS, ISS, G) - type(ice_shelf_dyn_CS), intent(inout) :: CS !< The ice shelf dynamics control structure + type(ice_shelf_dyn_CS), intent(inout) :: CS !< The ice shelf dynamics control structure type(ice_shelf_state), intent(inout) :: ISS !< A structure with elements that describe - !! the ice-shelf state - type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. - real :: ice_time_step_CFL !< The maximum permitted timestep, in s, based on the ice velocities. + !! the ice-shelf state + type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. + real :: ice_time_step_CFL !< The maximum permitted timestep based on the ice velocities [s]. real :: ratio, min_ratio real :: local_u_max, local_v_max @@ -601,11 +606,11 @@ subroutine update_ice_shelf(CS, ISS, G, US, time_step, Time, ocean_mass, coupled !! the ice-shelf state type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. type(unit_scale_type), intent(in) :: US !< Pointer to a structure containing unit conversion factors - real, intent(in) :: time_step !< time step in sec + real, intent(in) :: time_step !< time step [s] type(time_type), intent(in) :: Time !< The current model time real, dimension(SZDI_(G),SZDJ_(G)), & - optional, intent(in) :: ocean_mass !< If present this is the mass puer unit area - !! of the ocean in kg m-2. + optional, intent(in) :: ocean_mass !< If present this is the mass per unit area + !! of the ocean [kg m-2]. logical, optional, intent(in) :: coupled_grounding !< If true, the grounding line is !! determined by coupled ice-ocean dynamics logical, optional, intent(in) :: must_update_vel !< Always update the ice velocities if true. @@ -663,17 +668,11 @@ subroutine ice_shelf_advect(CS, ISS, G, time_step, Time) type(ice_shelf_state), intent(inout) :: ISS !< A structure with elements that describe !! the ice-shelf state type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. - real, intent(in) :: time_step !< time step in sec + real, intent(in) :: time_step !< time step [s] type(time_type), intent(in) :: Time !< The current model time -! time_step: time step in sec ! 3/8/11 DNG -! Arguments: -! CS - A structure containing the ice shelf state - including current velocities -! h0 - an array containing the thickness at the beginning of the call -! h_after_uflux - an array containing the thickness after advection in u-direction -! h_after_vflux - similar ! ! This subroutine takes the velocity (on the Bgrid) and timesteps h_t = - div (uh) once. ! ADDITIONALLY, it will update the volume of ice in partially-filled cells, and update @@ -704,7 +703,7 @@ subroutine ice_shelf_advect(CS, ISS, G, time_step, Time) ! o--- (3) ---o ! - real, dimension(SZDI_(G),SZDJ_(G)) :: h_after_uflux, h_after_vflux ! Ice thicknesses in Z. + real, dimension(SZDI_(G),SZDJ_(G)) :: h_after_uflux, h_after_vflux ! Ice thicknesses [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G),4) :: flux_enter integer :: isd, ied, jsd, jed, i, j, isc, iec, jsc, jec real :: rho, spy @@ -772,16 +771,16 @@ subroutine ice_shelf_solve_outer(CS, ISS, G, US, u, v, iters, time) type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. type(unit_scale_type), intent(in) :: US !< Pointer to a structure containing unit conversion factors real, dimension(SZDIB_(G),SZDJB_(G)), & - intent(inout) :: u !< The zonal ice shelf velocity at vertices, in m/year + intent(inout) :: u !< The zonal ice shelf velocity at vertices [m year-1] real, dimension(SZDIB_(G),SZDJB_(G)), & - intent(inout) :: v !< The meridional ice shelf velocity at vertices, in m/year + intent(inout) :: v !< The meridional ice shelf velocity at vertices [m year-1] integer, intent(out) :: iters !< The number of iterations used in the solver. type(time_type), intent(in) :: Time !< The current model time real, dimension(SZDIB_(G),SZDJB_(G)) :: TAUDX, TAUDY, u_prev_iterate, v_prev_iterate, & u_bdry_cont, v_bdry_cont, Au, Av, err_u, err_v, & u_last, v_last - real, dimension(SZDIB_(G),SZDJB_(G)) :: H_node ! Ice shelf thickness at corners, in Z. + real, dimension(SZDIB_(G),SZDJB_(G)) :: H_node ! Ice shelf thickness at corners [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)) :: float_cond ! An array indicating where the ice ! shelf is floating: 0 if floating, 1 if not. character(len=160) :: mesg ! The text of an error message @@ -1034,16 +1033,16 @@ subroutine ice_shelf_solve_inner(CS, ISS, G, u, v, taudx, taudy, H_node, float_c !! the ice-shelf state type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. real, dimension(SZDIB_(G),SZDJB_(G)), & - intent(inout) :: u !< The zonal ice shelf velocity at vertices, in m/year + intent(inout) :: u !< The zonal ice shelf velocity at vertices [m year-1] real, dimension(SZDIB_(G),SZDJB_(G)), & - intent(inout) :: v !< The meridional ice shelf velocity at vertices, in m/year + intent(inout) :: v !< The meridional ice shelf velocity at vertices [m year-1] real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: taudx !< The x-direction driving stress, in ??? real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: taudy !< The y-direction driving stress, in ??? real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: H_node !< The ice shelf thickness at nodal (corner) - !! points, in Z. + !! points [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: float_cond !< An array indicating where the ice !! shelf is floating: 0 if floating, 1 if not. @@ -1416,18 +1415,18 @@ end subroutine ice_shelf_solve_inner subroutine ice_shelf_advect_thickness_x(CS, G, time_step, hmask, h0, h_after_uflux, flux_enter) type(ice_shelf_dyn_CS), intent(in) :: CS !< A pointer to the ice shelf control structure type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. - real, intent(in) :: time_step !< The time step for this update, in s. + real, intent(in) :: time_step !< The time step for this update [s]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: h0 !< The initial ice shelf thicknesses in Z. + intent(in) :: h0 !< The initial ice shelf thicknesses [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: h_after_uflux !< The ice shelf thicknesses after - !! the zonal mass fluxes, in Z. + !! the zonal mass fluxes [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G),4), & intent(inout) :: flux_enter !< The ice volume flux into the cell - !! through the 4 cell boundaries, in Z m2 + !! through the 4 cell boundaries [Z m2 ~> m3]. ! use will be made of ISS%hmask here - its value at the boundary will be zero, just like uncovered cells @@ -1450,7 +1449,7 @@ subroutine ice_shelf_advect_thickness_x(CS, G, time_step, hmask, h0, h_after_ufl integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, gjed, gied integer :: i_off, j_off logical :: at_east_bdry, at_west_bdry, one_off_west_bdry, one_off_east_bdry - real, dimension(-2:2) :: stencil ! Thicknesses in Z. + real, dimension(-2:2) :: stencil ! Thicknesses [Z ~> m]. real :: u_face, & ! positive if out flux_diff_cell, phi, dxh, dyh, dxdyh character (len=1) :: debug_str @@ -1646,19 +1645,19 @@ end subroutine ice_shelf_advect_thickness_x subroutine ice_shelf_advect_thickness_y(CS, G, time_step, hmask, h_after_uflux, h_after_vflux, flux_enter) type(ice_shelf_dyn_CS), intent(in) :: CS !< A pointer to the ice shelf control structure type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. - real, intent(in) :: time_step !< The time step for this update, in s. + real, intent(in) :: time_step !< The time step for this update [s]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: h_after_uflux !< The ice shelf thicknesses after - !! the zonal mass fluxes, in Z. + !! the zonal mass fluxes [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: h_after_vflux !< The ice shelf thicknesses after - !! the meridional mass fluxes, in Z. + !! the meridional mass fluxes [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G),4), & intent(inout) :: flux_enter !< The ice volume flux into the cell - !! through the 4 cell boundaries, in Z m2 + !! through the 4 cell boundaries [Z m2 ~> m3]. ! use will be made of ISS%hmask here - its value at the boundary will be zero, just like uncovered cells @@ -1681,7 +1680,7 @@ subroutine ice_shelf_advect_thickness_y(CS, G, time_step, hmask, h_after_uflux, integer :: i, j, is, ie, js, je, isd, ied, jsd, jed, gjed, gied integer :: i_off, j_off logical :: at_north_bdry, at_south_bdry, one_off_west_bdry, one_off_east_bdry - real, dimension(-2:2) :: stencil ! Thicknesses in Z + real, dimension(-2:2) :: stencil ! Thicknesses [Z ~> m]. real :: v_face, & ! positive if out flux_diff_cell, phi, dxh, dyh, dxdyh character(len=1) :: debug_str @@ -1691,7 +1690,7 @@ subroutine ice_shelf_advect_thickness_y(CS, G, time_step, hmask, h_after_uflux, do i=isd+2,ied-2 if (((i+i_off) <= G%domain%niglobal+G%domain%nihalo) .AND. & - ((i+i_off) >= G%domain%nihalo+1)) then ! based on mehmet's code - only if btw east & west boundaries + ((i+i_off) >= G%domain%nihalo+1)) then ! based on Mehmet's code - only if btw east & west boundaries stencil(:) = -1 @@ -1859,7 +1858,7 @@ subroutine shelf_advance_front(CS, ISS, G, flux_enter) type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. real, dimension(SZDI_(G),SZDJ_(G),4), & intent(inout) :: flux_enter !< The ice volume flux into the cell - !! through the 4 cell boundaries, in Z m2 + !! through the 4 cell boundaries [Z m2 ~> m3]. ! in this subroutine we go through the computational cells only and, if they are empty or partial cells, ! we find the reference thickness and update the shelf mass and partial area fraction and the hmask if necessary @@ -2034,13 +2033,13 @@ end subroutine shelf_advance_front subroutine ice_shelf_min_thickness_calve(G, h_shelf, area_shelf_h, hmask, thickness_calve) type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: h_shelf !< The ice shelf thickness, in Z. + intent(inout) :: h_shelf !< The ice shelf thickness [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf - real, intent(in) :: thickness_calve !< The thickness at which to trigger calving, in Z. + real, intent(in) :: thickness_calve !< The thickness at which to trigger calving [Z ~> m]. integer :: i,j @@ -2061,9 +2060,9 @@ end subroutine ice_shelf_min_thickness_calve subroutine calve_to_mask(G, h_shelf, area_shelf_h, hmask, calve_mask) type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: h_shelf !< The ice shelf thickness, in Z. + intent(inout) :: h_shelf !< The ice shelf thickness [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -2090,7 +2089,7 @@ subroutine calc_shelf_driving_stress(CS, ISS, G, US, TAUD_X, TAUD_Y, OD) type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. type(unit_scale_type), intent(in) :: US !< Pointer to a structure containing unit conversion factors real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: OD !< ocean floor depth at tracer points, in Z + intent(in) :: OD !< ocean floor depth at tracer points [Z ~> m]. real, dimension(SZDIB_(G),SZDJB_(G)), & intent(inout) :: TAUD_X !< X-direction driving stress at q-points real, dimension(SZDIB_(G),SZDJB_(G)), & @@ -2107,8 +2106,8 @@ subroutine calc_shelf_driving_stress(CS, ISS, G, US, TAUD_X, TAUD_Y, OD) ! "average" ocean depth -- and is needed to find surface elevation ! (it is assumed that base_ice = bed + OD) - real, dimension(SIZE(OD,1),SIZE(OD,2)) :: S, & ! surface elevation, in Z - BASE ! basal elevation of shelf/stream, in Z + real, dimension(SIZE(OD,1),SIZE(OD,2)) :: S, & ! surface elevation [Z ~> m]. + BASE ! basal elevation of shelf/stream [Z ~> m]. real :: rho, rhow, sx, sy, neumann_val, dxh, dyh, dxdyh, grav @@ -2283,8 +2282,8 @@ subroutine init_boundary_values(CS, G, time, hmask, input_flux, input_thick, new real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf - real, intent(in) :: input_flux !< The integrated inward ice thickness flux in Z m2 s-1. - real, intent(in) :: input_thick !< The ice thickness at boundaries, in Z. + real, intent(in) :: input_flux !< The integrated inward ice thickness flux [Z m2 s-1 ~> m3 s-1] + real, intent(in) :: input_thick !< The ice thickness at boundaries [Z ~> m]. logical, optional, intent(in) :: new_sim !< If present and false, this run is being restarted ! this will be a per-setup function. the boundary values of thickness and velocity @@ -2361,9 +2360,9 @@ subroutine CG_action(uret, vret, u, v, Phi, Phisub, umask, vmask, hmask, H_node, intent(in) :: Phisub !< Quadrature structure weights at subgridscale !! locations for finite element calculations real, dimension(SZDIB_(G),SZDJB_(G)), & - intent(in) :: u !< The zonal ice shelf velocity at vertices, in m/year + intent(in) :: u !< The zonal ice shelf velocity at vertices [m year-1] real, dimension(SZDIB_(G),SZDJB_(G)), & - intent(in) :: v !< The meridional ice shelf velocity at vertices, in m/year + intent(in) :: v !< The meridional ice shelf velocity at vertices [m year-1] real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: umask !< A coded mask indicating the nature of the !! zonal flow at the corner point @@ -2372,7 +2371,7 @@ subroutine CG_action(uret, vret, u, v, Phi, Phisub, umask, vmask, hmask, H_node, !! meridional flow at the corner point real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: H_node !< The ice shelf thickness at nodal (corner) - !! points, in Z. + !! points [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -2384,14 +2383,14 @@ subroutine CG_action(uret, vret, u, v, Phi, Phisub, umask, vmask, hmask, H_node, intent(in) :: float_cond !< An array indicating where the ice !! shelf is floating: 0 if floating, 1 if not. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: bathyT !< The depth of ocean bathymetry at tracer points, in Z. + intent(in) :: bathyT !< The depth of ocean bathymetry at tracer points [Z ~> m]. real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: beta !< A field related to the nonlinear part of the !! "linearized" basal stress. The exact form and !! units depend on the basal law exponent. ! and/or whether flow is "hybridized" real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: dxdyh !< The tracer cell area, in m2 + intent(in) :: dxdyh !< The tracer cell area [m2] real, intent(in) :: dens_ratio !< The density of ice divided by the density !! of seawater, nondimensional integer, intent(in) :: is !< The starting i-index to work on @@ -2561,11 +2560,11 @@ subroutine CG_action_subgrid_basal(Phisub, H, U, V, DXDYH, bathyT, dens_ratio, U real, dimension(:,:,:,:,:,:), & intent(in) :: Phisub !< Quadrature structure weights at subgridscale !! locations for finite element calculations - real, dimension(2,2), intent(in) :: H !< The ice shelf thickness at nodal (corner) points, in Z. - real, dimension(2,2), intent(in) :: U !< The zonal ice shelf velocity at vertices, in m/year - real, dimension(2,2), intent(in) :: V !< The meridional ice shelf velocity at vertices, in m/year - real, intent(in) :: DXDYH !< The tracer cell area, in m2 - real, intent(in) :: bathyT !< The depth of ocean bathymetry at tracer points, in Z. + real, dimension(2,2), intent(in) :: H !< The ice shelf thickness at nodal (corner) points [Z ~> m]. + real, dimension(2,2), intent(in) :: U !< The zonal ice shelf velocity at vertices [m year-1] + real, dimension(2,2), intent(in) :: V !< The meridional ice shelf velocity at vertices [m year-1] + real, intent(in) :: DXDYH !< The tracer cell area [m2] + real, intent(in) :: bathyT !< The depth of ocean bathymetry at tracer points [Z ~> m]. real, intent(in) :: dens_ratio !< The density of ice divided by the density !! of seawater, nondimensional real, dimension(2,2), intent(inout) :: Ucontr !< A field related to the subgridscale contributions to @@ -2625,7 +2624,7 @@ subroutine matrix_diagonal(CS, G, float_cond, H_node, nu, beta, hmask, dens_rati !! shelf is floating: 0 if floating, 1 if not. real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: H_node !< The ice shelf thickness at nodal - !! (corner) points, in Z. + !! (corner) points [Z ~> m]. real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: nu !< A field related to the ice viscosity from Glen's !! flow law. The exact form and units depend on the @@ -2767,9 +2766,9 @@ subroutine CG_diagonal_subgrid_basal (Phisub, H_node, DXDYH, bathyT, dens_ratio, intent(in) :: Phisub !< Quadrature structure weights at subgridscale !! locations for finite element calculations real, dimension(2,2), intent(in) :: H_node !< The ice shelf thickness at nodal (corner) - !! points, in Z - real, intent(in) :: DXDYH !< The tracer cell area, in m2 - real, intent(in) :: bathyT !< The depth of ocean bathymetry at tracer points, in Z + !! points [Z ~> m]. + real, intent(in) :: DXDYH !< The tracer cell area [m2] + real, intent(in) :: bathyT !< The depth of ocean bathymetry at tracer points [Z ~> m]. real, intent(in) :: dens_ratio !< The density of ice divided by the density !! of seawater, nondimensional real, dimension(2,2), intent(inout) :: Ucontr !< A field related to the subgridscale contributions to @@ -2813,7 +2812,7 @@ subroutine apply_boundary_values(CS, ISS, G, time, Phisub, H_node, nu, beta, flo !! locations for finite element calculations real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: H_node !< The ice shelf thickness at nodal - !! (corner) points, in Z. + !! (corner) points [Z ~> m]. real, dimension(SZDIB_(G),SZDJB_(G)), & intent(in) :: nu !< A field related to the ice viscosity from Glen's !! flow law. The exact form and units depend on the @@ -2992,9 +2991,9 @@ subroutine calc_shelf_visc(CS, ISS, G, US, u, v) type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. type(unit_scale_type), intent(in) :: US !< Pointer to a structure containing unit conversion factors real, dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), & - intent(inout) :: u !< The zonal ice shelf velocity, in m/year. + intent(inout) :: u !< The zonal ice shelf velocity [m year-1]. real, dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), & - intent(inout) :: v !< The meridional ice shelf velocity, in m/year. + intent(inout) :: v !< The meridional ice shelf velocity [m year-1]. ! update DEPTH_INTEGRATED viscosity, based on horizontal strain rates - this is for bilinear FEM solve ! so there is an "upper" and "lower" bilinear viscosity @@ -3050,7 +3049,7 @@ subroutine update_OD_ffrac(CS, G, US, ocean_mass, find_avg) type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. type(unit_scale_type), intent(in) :: US !< Pointer to a structure containing unit conversion factors real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: ocean_mass !< The mass per unit area of the ocean in kg m-2. + intent(in) :: ocean_mass !< The mass per unit area of the ocean [kg m-2]. logical, intent(in) :: find_avg !< If true, find the average of OD and ffrac, and !! reset the underlying running sums to 0. @@ -3089,7 +3088,7 @@ subroutine update_OD_ffrac_uncoupled(CS, G, h_shelf) type(ice_shelf_dyn_CS), intent(inout) :: CS !< A pointer to the ice shelf control structure type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: h_shelf !< the thickness of the ice shelf in Z + intent(in) :: h_shelf !< the thickness of the ice shelf [Z ~> m]. integer :: i, j, iters, isd, ied, jsd, jed real :: rhoi_rhow, OD @@ -3121,7 +3120,7 @@ subroutine bilinear_shape_functions (X, Y, Phi, area) real, dimension(4), intent(in) :: Y !< The y-positions of the vertices of the quadrilateral. real, dimension(8,4), intent(inout) :: Phi !< The gradients of bilinear basis elements at Gaussian !! quadrature points surrounding the cell verticies. - real, intent(out) :: area !< The quadrilateral cell area, in m2. + real, intent(out) :: area !< The quadrilateral cell area [m2]. ! X and Y must be passed in the form ! 3 - 4 @@ -3408,13 +3407,13 @@ end subroutine update_velocity_masks subroutine interpolate_H_to_B(G, h_shelf, hmask, H_node) type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: h_shelf !< The ice shelf thickness at tracer points, in Z. + intent(in) :: h_shelf !< The ice shelf thickness at tracer points [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf real, dimension(SZDIB_(G),SZDJB_(G)), & intent(inout) :: H_node !< The ice shelf thickness at nodal (corner) - !! points, in Z. + !! points [Z ~> m]. integer :: i, j, isc, iec, jsc, jec, num_h, k, l real :: summ @@ -3476,21 +3475,12 @@ subroutine ice_shelf_temp(CS, ISS, G, US, time_step, melt_rate, Time) !! the ice-shelf state type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. type(unit_scale_type), intent(in) :: US !< Pointer to a structure containing unit conversion factors - real, intent(in) :: time_step !< The time step for this update, in s. + real, intent(in) :: time_step !< The time step for this update [s]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: melt_rate !< basal melt rate in kg/m^2/s + intent(in) :: melt_rate !< basal melt rate [kg m-2 s-1] type(time_type), intent(in) :: Time !< The current model time -! time_step: time step in sec -! melt_rate: basal melt rate in kg/m^2/s - ! 5/23/12 OVS -! Arguments: -! CS - A structure containing the ice shelf state - including current velocities -! t0 - an array containing temperature at the beginning of the call -! t_after_uflux - an array containing the temperature after advection in u-direction -! t_after_vflux - similar -! ! This subroutine takes the velocity (on the Bgrid) and timesteps ! (HT)_t = - div (uHT) + (adot Tsurf -bdot Tbot) once and then calculates T=HT/H ! @@ -3620,18 +3610,18 @@ end subroutine ice_shelf_temp subroutine ice_shelf_advect_temp_x(CS, G, time_step, hmask, h0, h_after_uflux, flux_enter) type(ice_shelf_dyn_CS), intent(in) :: CS !< A pointer to the ice shelf control structure type(ocean_grid_type), intent(inout) :: G !< The grid structure used by the ice shelf. - real, intent(in) :: time_step !< The time step for this update, in s. + real, intent(in) :: time_step !< The time step for this update [s]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf real, dimension(SZDI_(G),SZDJ_(G)), & - intent(in) :: h0 !< The initial ice shelf thicknesses in Z. + intent(in) :: h0 !< The initial ice shelf thicknesses [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: h_after_uflux !< The ice shelf thicknesses after - !! the zonal mass fluxes, in m. + !! the zonal mass fluxes [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G),4), & intent(inout) :: flux_enter !< The integrated temperature flux into - !! the cell through the 4 cell boundaries, in degC Z m2 + !! the cell through the 4 cell boundaries [degC Z m2 ~> degC m3] ! use will be made of ISS%hmask here - its value at the boundary will be zero, just like uncovered cells @@ -3851,19 +3841,19 @@ end subroutine ice_shelf_advect_temp_x subroutine ice_shelf_advect_temp_y(CS, G, time_step, hmask, h_after_uflux, h_after_vflux, flux_enter) type(ice_shelf_dyn_CS), intent(in) :: CS !< A pointer to the ice shelf control structure type(ocean_grid_type), intent(in) :: G !< The grid structure used by the ice shelf. - real, intent(in) :: time_step !< The time step for this update, in s. + real, intent(in) :: time_step !< The time step for this update [s]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf real, dimension(SZDI_(G),SZDJ_(G)), & intent(in) :: h_after_uflux !< The ice shelf thicknesses after - !! the zonal mass fluxes, in Z. + !! the zonal mass fluxes [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: h_after_vflux !< The ice shelf thicknesses after - !! the meridional mass fluxes, in Z. + !! the meridional mass fluxes [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G),4), & intent(inout) :: flux_enter !< The integrated temperature flux into - !! the cell through the 4 cell boundaries, in degC Z m2 + !! the cell through the 4 cell boundaries [degC Z m2 ~> degC m3] ! use will be made of ISS%hmask here - its value at the boundary will be zero, just like uncovered cells diff --git a/src/ice_shelf/MOM_ice_shelf_initialize.F90 b/src/ice_shelf/MOM_ice_shelf_initialize.F90 index efbc22f64d..945b634e91 100644 --- a/src/ice_shelf/MOM_ice_shelf_initialize.F90 +++ b/src/ice_shelf/MOM_ice_shelf_initialize.F90 @@ -17,15 +17,20 @@ module MOM_ice_shelf_initialize !MJHpublic initialize_ice_shelf_boundary, initialize_ice_thickness public initialize_ice_thickness +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Initialize ice shelf thickness subroutine initialize_ice_thickness(h_shelf, area_shelf_h, hmask, G, US, PF) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: h_shelf !< The ice shelf thickness, in Z. + intent(inout) :: h_shelf !< The ice shelf thickness [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -55,9 +60,9 @@ end subroutine initialize_ice_thickness subroutine initialize_ice_thickness_from_file(h_shelf, area_shelf_h, hmask, G, US, PF) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: h_shelf !< The ice shelf thickness, in m. + intent(inout) :: h_shelf !< The ice shelf thickness [m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -67,7 +72,7 @@ subroutine initialize_ice_thickness_from_file(h_shelf, area_shelf_h, hmask, G, U ! This subroutine reads ice thickness and area from a file and puts it into ! h_shelf and area_shelf_h in m (and dimensionless) and updates hmask character(len=200) :: filename,thickness_file,inputdir ! Strings for file/path - character(len=200) :: thickness_varname, area_varname! Variable name in file + character(len=200) :: thickness_varname, area_varname ! Variable name in file character(len=40) :: mdl = "initialize_ice_thickness_from_file" ! This subroutine's name. integer :: i, j, isc, jsc, iec, jec real :: len_sidestress, mask, udh @@ -142,9 +147,9 @@ end subroutine initialize_ice_thickness_from_file subroutine initialize_ice_thickness_channel(h_shelf, area_shelf_h, hmask, G, US, PF) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: h_shelf !< The ice shelf thickness, in Z. + intent(inout) :: h_shelf !< The ice shelf thickness [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -243,18 +248,18 @@ end subroutine initialize_ice_thickness_channel ! intent(inout) :: u_face_mask_bdry !< A boundary-type mask at C-grid u faces ! real, dimension(SZIB_(G),SZJ_(G)), & ! intent(inout) :: u_flux_bdry_val !< The boundary thickness flux through - !! C-grid u faces, in m2 s-1. + !! C-grid u faces [m2 s-1]. ! real, dimension(SZI_(G),SZJB_(G)), & ! intent(inout) :: v_face_mask_bdry !< A boundary-type mask at C-grid v faces ! real, dimension(SZI_(G),SZJB_(G)), & ! intent(inout) :: v_flux_bdry_val !< The boundary thickness flux through - !! C-grid v faces, in m2 s-1. + !! C-grid v faces [m2 s-1]. ! real, dimension(SZIB_(G),SZJB_(G)), & ! intent(inout) :: u_bdry_val !< The zonal ice shelf velocity at open - !! boundary vertices, in m/yr. + !! boundary vertices [m yr-1]. ! real, dimension(SZIB_(G),SZJB_(G)), & ! intent(inout) :: v_bdry_val !< The meridional ice shelf velocity at open - !! boundary vertices, in m/yr. + !! boundary vertices [m yr-1]. ! real, dimension(SZDI_(G),SZDJ_(G)), & ! intent(inout) :: h_bdry_val !< The ice shelf thickness at open boundaries ! real, dimension(SZDI_(G),SZDJ_(G)), & @@ -299,18 +304,18 @@ end subroutine initialize_ice_thickness_channel ! intent(inout) :: u_face_mask_bdry !< A boundary-type mask at C-grid u faces ! real, dimension(SZIB_(G),SZJ_(G)), & ! intent(inout) :: u_flux_bdry_val !< The boundary thickness flux through - !! C-grid u faces, in m2 s-1. + !! C-grid u faces [m2 s-1]. ! real, dimension(SZI_(G),SZJB_(G)), & ! intent(inout) :: v_face_mask_bdry !< A boundary-type mask at C-grid v faces ! real, dimension(SZI_(G),SZJB_(G)), & ! intent(inout) :: v_flux_bdry_val !< The boundary thickness flux through - !! C-grid v faces, in m2 s-1. + !! C-grid v faces [m2 s-1]. ! real, dimension(SZIB_(G),SZJB_(G)), & ! intent(inout) :: u_bdry_val !< The zonal ice shelf velocity at open - !! boundary vertices, in m/yr. + !! boundary vertices [m yr-1]. ! real, dimension(SZIB_(G),SZJB_(G)), & ! intent(inout) :: v_bdry_val !< The meridional ice shelf velocity at open - !! boundary vertices, in m/yr. + !! boundary vertices [m yr-1]. ! real, dimension(SZDI_(G),SZDJ_(G)), & ! intent(inout) :: h_bdry_val !< The ice shelf thickness at open boundaries ! real, dimension(SZDI_(G),SZDJ_(G)), & diff --git a/src/ice_shelf/MOM_ice_shelf_state.F90 b/src/ice_shelf/MOM_ice_shelf_state.F90 index fe9ec8d74b..414a3389d6 100644 --- a/src/ice_shelf/MOM_ice_shelf_state.F90 +++ b/src/ice_shelf/MOM_ice_shelf_state.F90 @@ -23,9 +23,9 @@ module MOM_ice_shelf_state !> Structure that describes the ice shelf state type, public :: ice_shelf_state real, pointer, dimension(:,:) :: & - mass_shelf => NULL(), & !< The mass per unit area of the ice shelf or sheet, in kg m-2. - area_shelf_h => NULL(), & !< The area per cell covered by the ice shelf, in m2. - h_shelf => NULL(), & !< the thickness of the shelf in m, redundant with mass but may + mass_shelf => NULL(), & !< The mass per unit area of the ice shelf or sheet [kg m-2]. + area_shelf_h => NULL(), & !< The area per cell covered by the ice shelf [m2]. + h_shelf => NULL(), & !< the thickness of the shelf [m], redundant with mass but may !! make the code more readable hmask => NULL(),& !< Mask used to indicate ice-covered or partiall-covered cells !! 1: fully covered, solve for velocity here (for now all @@ -38,16 +38,16 @@ module MOM_ice_shelf_state !! otherwise the wrong nodes will be included in velocity calcs. tflux_ocn => NULL(), & !< The UPWARD sensible ocean heat flux at the - !! ocean-ice interface, in W m-2. + !! ocean-ice interface [m-2]. salt_flux => NULL(), & !< The downward salt flux at the ocean-ice - !! interface, in kg m-2 s-1. + !! interface [kg m-2 s-1]. water_flux => NULL(), & !< The net downward liquid water flux at the - !! ocean-ice interface, in kg m-2 s-1. + !! ocean-ice interface [kg m-2 s-1]. tflux_shelf => NULL(), & !< The UPWARD diffusive heat flux in the ice - !! shelf at the ice-ocean interface, in W m-2. + !! shelf at the ice-ocean interface [W m-2]. tfreeze => NULL() !< The freezing point potential temperature - !! an the ice-ocean interface, in deg C. + !! an the ice-ocean interface [degC]. end type ice_shelf_state diff --git a/src/ice_shelf/MOM_marine_ice.F90 b/src/ice_shelf/MOM_marine_ice.F90 index 8592273775..d4e83561a7 100644 --- a/src/ice_shelf/MOM_marine_ice.F90 +++ b/src/ice_shelf/MOM_marine_ice.F90 @@ -25,12 +25,12 @@ module MOM_marine_ice !> Control structure for MOM_marine_ice type, public :: marine_ice_CS ; private - real :: kv_iceberg !< The viscosity of the icebergs in m2/s (for ice rigidity) + real :: kv_iceberg !< The viscosity of the icebergs [m2 s-1] (for ice rigidity) real :: berg_area_threshold !< Fraction of grid cell which iceberg must occupy !! so that fluxes below are set to zero. (0.5 is a !! good value to use.) Not applied for negative values. - real :: latent_heat_fusion !< Latent heat of fusion - real :: density_iceberg !< A typical density of icebergs in kg/m3 (for ice rigidity) + real :: latent_heat_fusion !< Latent heat of fusion [J kg-1] + real :: density_iceberg !< A typical density of icebergs [kg m-3] (for ice rigidity) type(time_type), pointer :: Time !< A pointer to the ocean model's clock. type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the timing of diagnostic output. @@ -48,10 +48,10 @@ subroutine iceberg_forces(G, forces, use_ice_shelf, sfc_state, & type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. logical, intent(in) :: use_ice_shelf !< If true, this configuration uses ice shelves. - real, intent(in) :: time_step !< The coupling time step, in s. + real, intent(in) :: time_step !< The coupling time step [s]. type(marine_ice_CS), pointer :: CS !< Pointer to the control structure for MOM_marine_ice - real :: kv_rho_ice ! The viscosity of ice divided by its density, in m5 kg-1 s-1. + real :: kv_rho_ice ! The viscosity of ice divided by its density [m5 kg-1 s-1]. integer :: i, j, is, ie, js, je is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec !This routine adds iceberg data to the ice shelf data (if ice shelf is used) @@ -110,11 +110,11 @@ subroutine iceberg_fluxes(G, fluxes, use_ice_shelf, sfc_state, & type(surface), intent(inout) :: sfc_state !< A structure containing fields that !! describe the surface state of the ocean. logical, intent(in) :: use_ice_shelf !< If true, this configuration uses ice shelves. - real, intent(in) :: time_step !< The coupling time step, in s. + real, intent(in) :: time_step !< The coupling time step [s]. type(marine_ice_CS), pointer :: CS !< Pointer to the control structure for MOM_marine_ice - real :: fraz ! refreezing rate in kg m-2 s-1 - real :: I_dt_LHF ! The inverse of the timestep times the latent heat of fusion, in kg J-1 s-1. + real :: fraz ! refreezing rate [kg m-2 s-1] + real :: I_dt_LHF ! The inverse of the timestep times the latent heat of fusion [kg J-1 s-1]. integer :: i, j, is, ie, js, je, isd, ied, jsd, jed is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec isd = G%isd ; jsd = G%jsd ; ied = G%ied ; jed = G%jed @@ -152,8 +152,8 @@ subroutine iceberg_fluxes(G, fluxes, use_ice_shelf, sfc_state, & if (associated(fluxes%latent)) fluxes%latent(i,j) = 0.0 if (associated(fluxes%evap)) fluxes%evap(i,j) = 0.0 - ! Add frazil formation diagnosed by the ocean model (J m-2) in the - ! form of surface layer evaporation (kg m-2 s-1). Update lprec in the + ! Add frazil formation diagnosed by the ocean model [J m-2] in the + ! form of surface layer evaporation [kg m-2 s-1]. Update lprec in the ! control structure for diagnostic purposes. if (associated(sfc_state%frazil)) then diff --git a/src/ice_shelf/user_shelf_init.F90 b/src/ice_shelf/user_shelf_init.F90 index 60dd6ec18f..2829f712e0 100644 --- a/src/ice_shelf/user_shelf_init.F90 +++ b/src/ice_shelf/user_shelf_init.F90 @@ -20,15 +20,20 @@ module user_shelf_init public USER_initialize_shelf_mass, USER_update_shelf_mass public USER_init_ice_thickness +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure for the user_ice_shelf module type, public :: user_ice_shelf_CS ; private - real :: Rho_ocean !< The ocean's typical density, in kg m-2 Z-1. - real :: max_draft !< The maximum ocean draft of the ice shelf, in Z. - real :: min_draft !< The minimum ocean draft of the ice shelf, in Z. - real :: flat_shelf_width !< The range over which the shelf is min_draft thick. - real :: shelf_slope_scale !< The range over which the shelf slopes. - real :: pos_shelf_edge_0 !< The x-position of the shelf edge at time 0, in km. - real :: shelf_speed !< The ice shelf speed of translation, in km day-1 + real :: Rho_ocean !< The ocean's typical density [kg m-2 Z-1]. + real :: max_draft !< The maximum ocean draft of the ice shelf [Z ~> m]. + real :: min_draft !< The minimum ocean draft of the ice shelf [Z ~> m]. + real :: flat_shelf_width !< The range over which the shelf is min_draft thick [km]. + real :: shelf_slope_scale !< The range over which the shelf slopes [km]. + real :: pos_shelf_edge_0 !< The x-position of the shelf edge at time 0 [km]. + real :: shelf_speed !< The ice shelf speed of translation [km day-1] logical :: first_call = .true. !< If true, this module has not been called before. end type user_ice_shelf_CS @@ -40,11 +45,11 @@ subroutine USER_initialize_shelf_mass(mass_shelf, area_shelf_h, h_shelf, hmask, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZDI_(G),SZDJ_(G)), & intent(out) :: mass_shelf !< The ice shelf mass per unit area averaged - !! over the full ocean cell, in kg m-2. + !! over the full ocean cell [kg m-2]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(out) :: h_shelf !< The ice shelf thickness, in m. + intent(out) :: h_shelf !< The ice shelf thickness [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(out) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(out) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(out) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -54,19 +59,10 @@ subroutine USER_initialize_shelf_mass(mass_shelf, area_shelf_h, h_shelf, hmask, logical, intent(in) :: new_sim !< If true, this is a new run; otherwise it is !! being started from a restart file. -! Arguments: mass_shelf - The mass per unit area averaged over the full ocean -! cell, in kg m-2. (Intent out) -! (out) area_shelf_h - The area of the ocean cell that is covered by the -! rigid ice shelf, in m2. -! (in) G - The ocean's grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. - - ! This subroutine sets up the initial mass and area covered by the ice shelf. - real :: Rho_ocean ! The ocean's typical density, in kg m-3. - real :: max_draft ! The maximum ocean draft of the ice shelf, in m. - real :: min_draft ! The minimum ocean draft of the ice shelf, in m. + real :: Rho_ocean ! The ocean's typical density [kg m-3]. + real :: max_draft ! The maximum ocean draft of the ice shelf [Z ~> m]. + real :: min_draft ! The minimum ocean draft of the ice shelf [Z ~> m]. real :: flat_shelf_width ! The range over which the shelf is min_draft thick. real :: c1 ! The maximum depths in m. character(len=40) :: mdl = "USER_initialize_shelf_mass" ! This subroutine's name. @@ -107,9 +103,9 @@ end subroutine USER_initialize_shelf_mass subroutine USER_init_ice_thickness(h_shelf, area_shelf_h, hmask, G, US, param_file) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZDI_(G),SZDJ_(G)), & - intent(out) :: h_shelf !< The ice shelf thickness, in m. + intent(out) :: h_shelf !< The ice shelf thickness [m]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(out) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(out) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(out) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -130,11 +126,11 @@ subroutine USER_update_shelf_mass(mass_shelf, area_shelf_h, h_shelf, hmask, G, C type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: mass_shelf !< The ice shelf mass per unit area averaged - !! over the full ocean cell, in kg m-2. + !! over the full ocean cell [kg m-2]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf, in m2. + intent(inout) :: area_shelf_h !< The area per cell covered by the ice shelf [m2]. real, dimension(SZDI_(G),SZDJ_(G)), & - intent(inout) :: h_shelf !< The ice shelf thickness, in Z. + intent(inout) :: h_shelf !< The ice shelf thickness [Z ~> m]. real, dimension(SZDI_(G),SZDJ_(G)), & intent(inout) :: hmask !< A mask indicating which tracer points are !! partly or fully covered by an ice-shelf @@ -142,13 +138,6 @@ subroutine USER_update_shelf_mass(mass_shelf, area_shelf_h, h_shelf, hmask, G, C type(time_type), intent(in) :: Time !< The current model time logical, intent(in) :: new_sim !< If true, this the start of a new run. -! Arguments: mass_shelf - The mass per unit area averaged over the full ocean -! cell, in kg m-2. (Intent out) -! (out) area_shelf_h - The area of the ocean cell that is covered by the -! rigid ice shelf, in m2. -! (in) G - The ocean's grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. real :: c1, edge_pos, slope_pos integer :: i, j diff --git a/src/initialization/MOM_coord_initialization.F90 b/src/initialization/MOM_coord_initialization.F90 index ad66762fef..8899627cc7 100644 --- a/src/initialization/MOM_coord_initialization.F90 +++ b/src/initialization/MOM_coord_initialization.F90 @@ -25,6 +25,11 @@ module MOM_coord_initialization public MOM_initialize_coord +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + character(len=40) :: mdl = "MOM_coord_initialization" !< This module's name. contains @@ -39,7 +44,7 @@ subroutine MOM_initialize_coord(GV, US, PF, write_geom, output_dir, tv, max_dept logical, intent(in) :: write_geom !< If true, write grid geometry files. character(len=*), intent(in) :: output_dir !< The directory into which to write files. type(thermo_var_ptrs), intent(inout) :: tv !< The thermodynamic variable structure. - real, intent(in) :: max_depth !< The ocean's maximum depth, in Z. + real, intent(in) :: max_depth !< The ocean's maximum depth [Z ~> m]. ! Local character(len=200) :: config logical :: debug @@ -119,15 +124,15 @@ end subroutine MOM_initialize_coord !> Sets the layer densities (Rlay) and the interface reduced gravities (g). subroutine set_coord_from_gprime(Rlay, g_prime, GV, US, param_file) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters ! Local variables - real :: g_int ! Reduced gravities across the internal interfaces, in m s-2. - real :: g_fs ! Reduced gravity across the free surface, in m s-2. + real :: g_int ! Reduced gravities across the internal interfaces [m s-2]. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. character(len=40) :: mdl = "set_coord_from_gprime" ! This subroutine's name. integer :: k, nz nz = GV%ke @@ -153,16 +158,16 @@ end subroutine set_coord_from_gprime !> Sets the layer densities (Rlay) and the interface reduced gravities (g). subroutine set_coord_from_layer_density(Rlay, g_prime, GV, US, param_file) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters ! Local variables - real :: g_fs ! Reduced gravity across the free surface, in m s-2. - real :: Rlay_Ref! The surface layer's target density, in kg m-3. - real :: RLay_range ! The range of densities, in kg m-3. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. + real :: Rlay_Ref! The surface layer's target density [kg m-3]. + real :: RLay_range ! The range of densities [kg m-3]. character(len=40) :: mdl = "set_coord_from_layer_density" ! This subroutine's name. integer :: k, nz nz = GV%ke @@ -196,21 +201,20 @@ end subroutine set_coord_from_layer_density subroutine set_coord_from_TS_ref(Rlay, g_prime, GV, US, param_file, eqn_of_state, & P_Ref) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time !! parameters type(EOS_type), pointer :: eqn_of_state !< integer selecting the equation of state. - real, intent(in) :: P_Ref !< The coordinate-density reference pressure - !! in Pa. + real, intent(in) :: P_Ref !< The coordinate-density reference pressure [Pa]. ! Local variables real :: T_ref ! Reference temperature real :: S_ref ! Reference salinity - real :: g_int ! Reduced gravities across the internal interfaces, in m s-2. - real :: g_fs ! Reduced gravity across the free surface, in m s-2. + real :: g_int ! Reduced gravities across the internal interfaces [m s-2]. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. character(len=40) :: mdl = "set_coord_from_TS_ref" ! This subroutine's name. integer :: k, nz nz = GV%ke @@ -248,19 +252,18 @@ end subroutine set_coord_from_TS_ref subroutine set_coord_from_TS_profile(Rlay, g_prime, GV, US, param_file, & eqn_of_state, P_Ref) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time !! parameters type(EOS_type), pointer :: eqn_of_state !< integer that selects equation of state. - real, intent(in) :: P_Ref !< The coordinate-density reference pressure - !! in Pa. + real, intent(in) :: P_Ref !< The coordinate-density reference pressure [Pa]. ! Local variables real, dimension(GV%ke) :: T0, S0, Pref - real :: g_fs ! Reduced gravity across the free surface, in m s-2. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. integer :: k, nz character(len=40) :: mdl = "set_coord_from_TS_profile" ! This subroutine's name. character(len=200) :: filename, coord_file, inputdir ! Strings for file/path @@ -297,24 +300,25 @@ end subroutine set_coord_from_TS_profile subroutine set_coord_from_TS_range(Rlay, g_prime, GV, US, param_file, & eqn_of_state, P_Ref) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time !! parameters type(EOS_type), pointer :: eqn_of_state !< integer that selects equation of state - real, intent(in) :: P_Ref !< The coordinate-density reference pressure - !! in Pa. + real, intent(in) :: P_Ref !< The coordinate-density reference pressure [Pa] + + ! Local variables real, dimension(GV%ke) :: T0, S0, Pref - real :: S_Ref, S_Light, S_Dense ! Salinity range parameters in PSU. - real :: T_Ref, T_Light, T_Dense ! Temperature range parameters in dec C. + real :: S_Ref, S_Light, S_Dense ! Salinity range parameters [ppt]. + real :: T_Ref, T_Light, T_Dense ! Temperature range parameters [decC]. real :: res_rat ! The ratio of density space resolution in the denser part ! of the range to that in the lighter part of the range. ! Setting this greater than 1 increases the resolution for ! the denser water. - real :: g_fs ! Reduced gravity across the free surface, in m s-2. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. real :: a1, frac_dense, k_frac integer :: k, nz, k_light character(len=40) :: mdl = "set_coord_from_TS_range" ! This subroutine's name. @@ -379,14 +383,14 @@ end subroutine set_coord_from_TS_range ! Sets the layer densities (Rlay) and the interface reduced gravities (g) from data in file. subroutine set_coord_from_file(Rlay, g_prime, GV, US, param_file) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters ! Local variables - real :: g_fs ! Reduced gravity across the free surface, in m s-2. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. integer :: k, nz character(len=40) :: mdl = "set_coord_from_file" ! This subroutine's name. character(len=40) :: coord_var @@ -430,9 +434,9 @@ end subroutine set_coord_from_file !! (defaulting to 2.0 if not defined) subroutine set_coord_linear(Rlay, g_prime, GV, US, param_file) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces - !! in m2 Z-1 s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters @@ -474,14 +478,14 @@ end subroutine set_coord_linear !! might be used. subroutine set_coord_to_none(Rlay, g_prime, GV, US, param_file) real, dimension(:), intent(out) :: Rlay !< The layers' target coordinate values - !! (potential density). + !! (potential density) [kg m-3]. real, dimension(:), intent(out) :: g_prime !< The reduced gravity across the interfaces, - !! in m s-2. + !! [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters ! Local variables - real :: g_fs ! Reduced gravity across the free surface, in m s-2. + real :: g_fs ! Reduced gravity across the free surface [m s-2]. character(len=40) :: mdl = "set_coord_to_none" ! This subroutine's name. integer :: k, nz nz = GV%ke diff --git a/src/initialization/MOM_fixed_initialization.F90 b/src/initialization/MOM_fixed_initialization.F90 index 63774b98f8..c2f188bc6f 100644 --- a/src/initialization/MOM_fixed_initialization.F90 +++ b/src/initialization/MOM_fixed_initialization.F90 @@ -146,7 +146,7 @@ subroutine MOM_initialize_fixed(G, US, OBC, PF, write_geom, output_dir) endif ! Calculate the value of the Coriolis parameter at the latitude ! -! of the q grid points, in s-1. +! of the q grid points [s-1]. call MOM_initialize_rotation(G%CoriolisBu, G, PF) ! Calculate the components of grad f (beta) call MOM_calculate_grad_Coriolis(G%dF_dx, G%dF_dy, G) @@ -169,18 +169,20 @@ subroutine MOM_initialize_fixed(G, US, OBC, PF, write_geom, output_dir) end subroutine MOM_initialize_fixed !> MOM_initialize_topography makes the appropriate call to set up the bathymetry. At this -!! point the topography is in units of m, but this can be changed later. +!! point the topography is in units of [m], but this can be changed later. subroutine MOM_initialize_topography(D, max_depth, G, PF, US) type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type real, dimension(G%isd:G%ied,G%jsd:G%jed), & - intent(out) :: D !< Ocean bottom depth in m + intent(out) :: D !< Ocean bottom depth [m] type(param_file_type), intent(in) :: PF !< Parameter file structure - real, intent(out) :: max_depth !< Maximum depth of model in m + real, intent(out) :: max_depth !< Maximum depth of model [m] type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type -! This subroutine makes the appropriate call to set up the bottom depth. -! This is a separate subroutine so that it can be made public and shared with -! the ice-sheet code or other components. + ! This subroutine makes the appropriate call to set up the bottom depth. + ! This is a separate subroutine so that it can be made public and shared with + ! the ice-sheet code or other components. + + ! Local variables real :: m_to_Z, Z_to_m ! Dimensional rescaling factors character(len=40) :: mdl = "MOM_initialize_topography" ! This subroutine's name. character(len=200) :: config diff --git a/src/initialization/MOM_grid_initialize.F90 b/src/initialization/MOM_grid_initialize.F90 index a0a354858f..3da13a3063 100644 --- a/src/initialization/MOM_grid_initialize.F90 +++ b/src/initialization/MOM_grid_initialize.F90 @@ -24,6 +24,11 @@ module MOM_grid_initialize public set_grid_metrics, initialize_masks, Adcroft_reciprocal +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Global positioning system (aka container for information to describe the grid) type, public :: GPS ; private real :: len_lon !< The longitudinal or x-direction length of the domain. @@ -32,7 +37,7 @@ module MOM_grid_initialize !! starting value for the x-axis. real :: south_lat !< The southern latitude of the domain or the equivalent !! starting value for the y-axis. - real :: Rad_Earth !< The radius of the Earth, in m. + real :: Rad_Earth !< The radius of the Earth [m]. real :: Lat_enhance_factor !< The amount by which the meridional resolution !! is enhanced within LAT_EQ_ENHANCE of the equator. real :: Lat_eq_enhance !< The latitude range to the north and south of the equator @@ -1222,9 +1227,9 @@ subroutine initialize_masks(G, PF, US) type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type ! Local variables real :: m_to_Z_scale ! A unit conversion factor from m to Z. - real :: Dmin ! The depth for masking in the same units as G%bathyT (Z). - real :: min_depth ! The minimum ocean depth in the same units as G%bathyT (Z). - real :: mask_depth ! The depth shallower than which to mask a point as land, in Z. + real :: Dmin ! The depth for masking in the same units as G%bathyT [Z ~> m]. + real :: min_depth ! The minimum ocean depth in the same units as G%bathyT [Z ~> m]. + real :: mask_depth ! The depth shallower than which to mask a point as land [Z ~> m]. character(len=40) :: mdl = "MOM_grid_init initialize_masks" integer :: i, j diff --git a/src/initialization/MOM_shared_initialization.F90 b/src/initialization/MOM_shared_initialization.F90 index 113c3b3a85..7613eae6b0 100644 --- a/src/initialization/MOM_shared_initialization.F90 +++ b/src/initialization/MOM_shared_initialization.F90 @@ -30,6 +30,11 @@ module MOM_shared_initialization public read_face_length_list, set_velocity_depth_max, set_velocity_depth_min public compute_global_grid_integrals, write_ocean_geometry_file +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains ! ----------------------------------------------------------------------------- @@ -51,7 +56,7 @@ end subroutine MOM_shared_init_init !> MOM_initialize_rotation makes the appropriate call to set up the Coriolis parameter. subroutine MOM_initialize_rotation(f, G, PF, US) type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type - real, dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), intent(out) :: f !< The Coriolis parameter in s-1 + real, dimension(G%IsdB:G%IedB,G%JsdB:G%JedB), intent(out) :: f !< The Coriolis parameter [s-1] type(param_file_type), intent(in) :: PF !< Parameter file structure type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type @@ -303,11 +308,11 @@ subroutine initialize_topography_named(D, G, param_file, topog_config, max_depth ! Local variables real :: m_to_Z ! A dimensional rescaling factor. - real :: min_depth ! The minimum depth in Z. + real :: min_depth ! The minimum depth [Z ~> m]. real :: PI ! 3.1415926... calculated as 4*atan(1) real :: D0 ! A constant to make the maximum basin depth MAXIMUM_DEPTH. - real :: expdecay ! A decay scale of associated with the sloping boundaries, in m. - real :: Dedge ! The depth in Z at the basin edge + real :: expdecay ! A decay scale of associated with the sloping boundaries [m]. + real :: Dedge ! The depth [Z ~> m], at the basin edge ! real :: south_lat, west_lon, len_lon, len_lat, Rad_earth integer :: i, j, is, ie, js, je, isd, ied, jsd, jed character(len=40) :: mdl = "initialize_topography_named" ! This subroutine's name. diff --git a/src/initialization/MOM_state_initialization.F90 b/src/initialization/MOM_state_initialization.F90 index 83347d2089..4c7b720f67 100644 --- a/src/initialization/MOM_state_initialization.F90 +++ b/src/initialization/MOM_state_initialization.F90 @@ -106,6 +106,11 @@ module MOM_state_initialization public MOM_initialize_state +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + character(len=40) :: mdl = "MOM_state_initialization" !< This module's name. contains @@ -119,14 +124,13 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< The zonal velocity that is being initialized, - !! in m s-1 + intent(out) :: u !< The zonal velocity that is being + !! initialized [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(out) :: v !< The meridional velocity that is being - !! initialized, in m s-1 + !! initialized [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: h !< Layer thicknesses, in H (usually m or - !! kg m-2) + intent(out) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< A structure pointing to various thermodynamic !! variables type(time_type), intent(inout) :: Time !< Time at the start of the run segment. @@ -150,13 +154,12 @@ subroutine MOM_initialize_state(u, v, h, tv, Time, G, GV, US, PF, dirs, & character(len=200) :: config real :: H_rescale ! A rescaling factor for thicknesses from the representation in ! a restart file to the internal representation in this run. - real :: dt ! The baroclinic dynamics timestep for this run, in s. + real :: dt ! The baroclinic dynamics timestep for this run [s]. logical :: from_Z_file, useALE logical :: new_sim integer :: write_geom logical :: use_temperature, use_sponge, use_OBC - logical :: use_EOS ! If true, density is calculated from T & S using an - ! equation of state. + logical :: use_EOS ! If true, density is calculated from T & S using an equation of state. logical :: depress_sfc ! If true, remove the mass that would be displaced ! by a large surface pressure by squeezing the column. logical :: trim_ic_for_p_surf ! If true, remove the mass that would be displaced @@ -609,7 +612,7 @@ subroutine initialize_thickness_from_file(h, G, GV, US, param_file, file_has_thi type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in m. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, intent(in) :: file_has_thickness !< If true, this file contains layer @@ -700,11 +703,11 @@ subroutine adjustEtaToFitBathymetry(G, GV, US, eta, h) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: eta !< Interface heights, in Z - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses, in H + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: eta !< Interface heights [Z ~> m]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] ! Local variables integer :: i, j, k, is, ie, js, je, nz, contractions, dilations - real :: hTolerance = 0.1 !< Tolerance to exceed adjustment criteria (m) + real :: hTolerance = 0.1 !< Tolerance to exceed adjustment criteria [Z ~> m] real :: hTmp, eTmp, dilate character(len=100) :: mesg @@ -774,7 +777,7 @@ subroutine initialize_thickness_uniform(h, G, GV, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -830,17 +833,17 @@ subroutine initialize_thickness_list(h, G, GV, US, param_file, just_read_params) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables character(len=40) :: mdl = "initialize_thickness_list" ! This subroutine's name. - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), + real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units [Z ~> m], ! usually negative because it is positive upward. real :: eta1D(SZK_(G)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). + ! positive upward, in depth units [Z ~> m]. logical :: just_read ! If true, just read parameters but set nothing. character(len=200) :: filename, eta_file, inputdir ! Strings for file/path character(len=72) :: eta_var @@ -907,24 +910,23 @@ end subroutine initialize_thickness_search !> Converts thickness from geometric to pressure units subroutine convert_thickness(h, G, GV, US, tv) - type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure + type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Input geometric layer thicknesses (in H units), - !! being converted to layer pressure - !! thicknesses (also in H units). - type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various - !! thermodynamic variables + intent(inout) :: h !< Input geometric layer thicknesses being converted + !! to layer pressure [H ~> m or kg m-2]. + type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various + !! thermodynamic variables ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & p_top, p_bot real :: dz_geo(SZI_(G),SZJ_(G)) ! The change in geopotential height - ! across a layer, in m2 s-2. + ! across a layer [m2 s-2]. real :: rho(SZI_(G)) real :: I_gEarth - real :: Hm_rho_to_Pa ! A conversion factor from the input geometric thicknesses - ! times the layer densities into Pa, in Pa m3 / H kg. + real :: Hm_rho_to_Pa ! A conversion factor from the input geometric thicknesses times the + ! layer densities into Pa [Pa m3 H-1 kg-1 ~> s-2 m2 or s-2 m5 kg-1]. logical :: Boussinesq integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz integer :: itt, max_itt @@ -990,17 +992,17 @@ subroutine depress_surface(h, G, GV, US, param_file, tv, just_read_params) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - eta_sfc ! The free surface height that the model should use, in m. + eta_sfc ! The free surface height that the model should use [m]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: & - eta ! The free surface height that the model should use, in m. - real :: dilate ! A ratio by which layers are dilated, nondim. + eta ! The free surface height that the model should use [m]. + real :: dilate ! A ratio by which layers are dilated [nondim]. real :: scale_factor ! A scaling factor for the eta_sfc values that are read ! in, which can be used to change units, for example. character(len=40) :: mdl = "depress_surface" ! This subroutine's name. @@ -1071,18 +1073,18 @@ end subroutine depress_surface !! where the hydrostatic pressure matches an imposed surface pressure read from file. subroutine trim_for_ice(PF, G, GV, US, ALE_CSp, tv, h, just_read_params) type(param_file_type), intent(in) :: PF !< Parameter file structure - type(ocean_grid_type), intent(in) :: G !< Ocean grid structure + type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(ALE_CS), pointer :: ALE_CSp !< ALE control structure type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamics structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thickness (H units, m or Pa) + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables character(len=200) :: mdl = "trim_for_ice" - real, dimension(SZI_(G),SZJ_(G)) :: p_surf ! Imposed pressure on ocean at surface (Pa) + real, dimension(SZI_(G),SZJ_(G)) :: p_surf ! Imposed pressure on ocean at surface [Pa] real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: S_t, S_b ! Top and bottom edge values for reconstructions real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: T_t, T_b ! of salinity and temperature within each layer. character(len=200) :: inputdir, filename, p_surf_file, p_surf_var ! Strings for file/path @@ -1152,21 +1154,21 @@ subroutine cut_off_column_top(nk, tv, GV, G_earth, depth, min_thickness, & integer, intent(in) :: nk !< Number of layers type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, intent(in) :: G_earth !< Gravitational acceleration (m2 Z-1 s-2) - real, intent(in) :: depth !< Depth of ocean column (Z) - real, intent(in) :: min_thickness !< Smallest thickness allowed (Z) - real, dimension(nk), intent(inout) :: T !< Layer mean temperature - real, dimension(nk), intent(in) :: T_t !< Temperature at top of layer - real, dimension(nk), intent(in) :: T_b !< Temperature at bottom of layer - real, dimension(nk), intent(inout) :: S !< Layer mean salinity - real, dimension(nk), intent(in) :: S_t !< Salinity at top of layer - real, dimension(nk), intent(in) :: S_b !< Salinity at bottom of layer - real, intent(in) :: p_surf !< Imposed pressure on ocean at surface (Pa) - real, dimension(nk), intent(inout) :: h !< Layer thickness (H units, m or Pa) + real, intent(in) :: G_earth !< Gravitational acceleration [m2 Z-1 s-2 ~> m s-2] + real, intent(in) :: depth !< Depth of ocean column [Z ~> m]. + real, intent(in) :: min_thickness !< Smallest thickness allowed [Z ~> m]. + real, dimension(nk), intent(inout) :: T !< Layer mean temperature [degC] + real, dimension(nk), intent(in) :: T_t !< Temperature at top of layer [degC] + real, dimension(nk), intent(in) :: T_b !< Temperature at bottom of layer [degC] + real, dimension(nk), intent(inout) :: S !< Layer mean salinity [ppt] + real, dimension(nk), intent(in) :: S_t !< Salinity at top of layer [ppt] + real, dimension(nk), intent(in) :: S_b !< Salinity at bottom of layer [ppt] + real, intent(in) :: p_surf !< Imposed pressure on ocean at surface [Pa] + real, dimension(nk), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] type(remapping_CS), pointer :: remap_CS !< Remapping structure for remapping T and S, !! if associated real, optional, intent(in) :: z_tol !< The tolerance with which to find the depth - !! matching the specified pressure, in Z. + !! matching the specified pressure [Z ~> m]. ! Local variables real, dimension(nk+1) :: e ! Top and bottom edge values for reconstructions @@ -1236,9 +1238,9 @@ end subroutine cut_off_column_top subroutine initialize_velocity_from_file(u, v, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< The zonal velocity that is being initialized, in m s-1 + intent(out) :: u !< The zonal velocity that is being initialized [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: v !< The meridional velocity that is being initialized, in m s-1 + intent(out) :: v !< The meridional velocity that is being initialized [m s-1] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to !! parse for modelparameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -1276,9 +1278,9 @@ end subroutine initialize_velocity_from_file subroutine initialize_velocity_zero(u, v, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< The zonal velocity that is being initialized, in m s-1 + intent(out) :: u !< The zonal velocity that is being initialized [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: v !< The meridional velocity that is being initialized, in m s-1 + intent(out) :: v !< The meridional velocity that is being initialized [m s-1] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to !! parse for modelparameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -1310,9 +1312,9 @@ end subroutine initialize_velocity_zero subroutine initialize_velocity_uniform(u, v, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< The zonal velocity that is being initialized, in m s-1 + intent(out) :: u !< The zonal velocity that is being initialized [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: v !< The meridional velocity that is being initialized, in m s-1 + intent(out) :: v !< The meridional velocity that is being initialized [m s-1] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to !! parse for modelparameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -1350,9 +1352,9 @@ end subroutine initialize_velocity_uniform subroutine initialize_velocity_circular(u, v, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< The zonal velocity that is being initialized, in m s-1 + intent(out) :: u !< The zonal velocity that is being initialized [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: v !< The meridional velocity that is being initialized, in m s-1 + intent(out) :: v !< The meridional velocity that is being initialized [m s-1] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to !! parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -1370,7 +1372,7 @@ subroutine initialize_velocity_circular(u, v, G, param_file, just_read_params) call get_param(param_file, mdl, "CIRCULAR_MAX_U", circular_max_u, & "The amplitude of zonal flow from which to scale the\n"// & - "circular stream function (m/s).", & + "circular stream function [m s-1].", & units="m s-1", default=0., do_not_log=just_read) if (just_read) return ! All run-time parameters have been read, so return. @@ -1410,8 +1412,10 @@ end subroutine initialize_velocity_circular !> Initializes temperature and salinity from file subroutine initialize_temp_salt_from_file(T, S, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is being initialized. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is being initialized. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is + !! being initialized [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is + !! being initialized [ppt] type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. @@ -1463,12 +1467,14 @@ end subroutine initialize_temp_salt_from_file !> Initializes temperature and salinity from a 1D profile subroutine initialize_temp_salt_from_profile(T, S, G, param_file, just_read_params) - type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is being initialized. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is being initialized. - type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters + type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is + !! being initialized [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is + !! being initialized [ppt] + type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters logical, optional, intent(in) :: just_read_params !< If present and true, this call will - !! only read parameters without changing h. + !! only read parameters without changing h. ! Local variables real, dimension(SZK_(G)) :: T0, S0 integer :: i, j, k @@ -1508,23 +1514,26 @@ end subroutine initialize_temp_salt_from_profile subroutine initialize_temp_salt_fit(T, S, G, GV, param_file, eqn_of_state, P_Ref, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is being initialized. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is being initialized. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is + !! being initialized [degC]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is being + !! initialized [ppt]. type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time !! parameters. type(EOS_type), pointer :: eqn_of_state !< Integer that selects the equatio of state. real, intent(in) :: P_Ref !< The coordinate-density reference pressure - !! in Pa. + !! [Pa]. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables - real :: T0(SZK_(G)), S0(SZK_(G)) - real :: T_Ref ! Reference Temperature - real :: S_Ref ! Reference Salinity - real :: pres(SZK_(G)) ! An array of the reference pressure in Pa. - real :: drho_dT(SZK_(G)) ! Derivative of density with temperature in kg m-3 K-1. - real :: drho_dS(SZK_(G)) ! Derivative of density with salinity in kg m-3 PSU-1. - real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 in kg m-3. + real :: T0(SZK_(G)) ! Layer potential temperatures [degC] + real :: S0(SZK_(G)) ! Layer salinities [degC] + real :: T_Ref ! Reference Temperature [degC] + real :: S_Ref ! Reference Salinity [ppt] + real :: pres(SZK_(G)) ! An array of the reference pressure [Pa]. + real :: drho_dT(SZK_(G)) ! Derivative of density with temperature [kg m-3 degC-1]. + real :: drho_dS(SZK_(G)) ! Derivative of density with salinity [kg m-3 ppt-1]. + real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 [kg m-3]. logical :: fit_salin ! If true, accept the prescribed temperature and fit the salinity. logical :: just_read ! If true, just read parameters but set nothing. character(len=40) :: mdl = "initialize_temp_salt_fit" ! This subroutine's name. @@ -1597,8 +1606,10 @@ end subroutine initialize_temp_salt_fit !! number, not the physical position). subroutine initialize_temp_salt_linear(T, S, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is being initialized. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is being initialized. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T !< The potential temperature that is + !! being initialized [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S !< The salinity that is + !! being initialized [ppt] type(param_file_type), intent(in) :: param_file !< A structure to parse for !! run-time parameters logical, optional, intent(in) :: just_read_params !< If present and true, @@ -1675,16 +1686,16 @@ subroutine initialize_sponges_file(G, GV, US, use_temperature, tv, param_file, C type(time_type), intent(in) :: Time !< Time at the start of the run segment. Time_in !! overrides any value set for Time. ! Local variables - real, allocatable, dimension(:,:,:) :: eta ! The target interface heights, in m. - real, allocatable, dimension(:,:,:) :: h ! The target interface thicknesses, in m. + real, allocatable, dimension(:,:,:) :: eta ! The target interface heights [Z ~> m]. + real, allocatable, dimension(:,:,:) :: h ! The target interface thicknesses [H ~> m or kg m-2]. real, dimension (SZI_(G),SZJ_(G),SZK_(G)) :: & tmp, tmp2 ! A temporary array for tracers. real, dimension (SZI_(G),SZJ_(G)) :: & tmp_2d ! A temporary array for tracers. - real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate, in s-1. - real :: pres(SZI_(G)) ! An array of the reference pressure, in Pa. + real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1]. + real :: pres(SZI_(G)) ! An array of the reference pressure [Pa]. integer :: i, j, k, is, ie, js, je, nz integer :: isd, ied, jsd, jed @@ -1897,7 +1908,7 @@ end subroutine set_velocity_depth_min subroutine MOM_temp_salt_initialize_from_Z(h, tv, G, GV, US, PF, just_read_params) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: h !< Layer thicknesses being initialized, in H + intent(out) :: h !< Layer thicknesses being initialized [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< A structure pointing to various thermodynamic !! variables including temperature and salinity type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure @@ -1936,11 +1947,11 @@ subroutine MOM_temp_salt_initialize_from_Z(h, tv, G, GV, US, PF, just_read_param integer :: kd, inconsistent integer :: nkd ! number of levels to use for regridding input arrays - real :: eps_Z ! A negligibly thin layer thickness, in Z. + real :: eps_Z ! A negligibly thin layer thickness [Z ~> m]. real :: PI_180 ! for conversion from degrees to radians real, dimension(:,:), pointer :: shelf_area => NULL() - real :: min_depth ! The minimum depth in Z. + real :: min_depth ! The minimum depth [Z ~> m]. real :: dilate real :: missing_value_temp, missing_value_salt logical :: correct_thickness @@ -1959,19 +1970,19 @@ subroutine MOM_temp_salt_initialize_from_Z(h, tv, G, GV, US, PF, just_read_param real, dimension(:), allocatable :: z_edges_in, z_in, Rb real, dimension(:,:,:), allocatable, target :: temp_z, salt_z, mask_z real, dimension(:,:,:), allocatable :: rho_z - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: zi ! Interface heights in Z. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: zi ! Interface heights [Z ~> m]. real, dimension(SZI_(G),SZJ_(G)) :: nlevs - real, dimension(SZI_(G)) :: press ! Pressures in Pa. + real, dimension(SZI_(G)) :: press ! Pressures [Pa]. ! Local variables for ALE remapping - real, dimension(:), allocatable :: hTarget ! Target thicknesses in Z. + real, dimension(:), allocatable :: hTarget ! Target thicknesses [Z ~> m]. real, dimension(:,:), allocatable :: area_shelf_h real, dimension(:,:), allocatable, target :: frac_shelf_h real, dimension(:,:,:), allocatable, target :: tmpT1dIn, tmpS1dIn real, dimension(:,:,:), allocatable :: tmp_mask_in - real, dimension(:,:,:), allocatable :: h1 ! Thicknesses in H. + real, dimension(:,:,:), allocatable :: h1 ! Thicknesses [H ~> m or kg m-2]. real, dimension(:,:,:), allocatable :: dz_interface ! Change in position of interface due to regridding - real :: zTopOfCell, zBottomOfCell ! Heights in Z units + real :: zTopOfCell, zBottomOfCell ! Heights in Z units [Z ~> m]. type(regridding_CS) :: regridCS ! Regridding parameters and work arrays type(remapping_CS) :: remapCS ! Remapping parameters and work arrays @@ -2092,7 +2103,7 @@ subroutine MOM_temp_salt_initialize_from_Z(h, tv, G, GV, US, PF, just_read_param ! lon (degrees_E), lat (degrees_N), depth(meters) ! variables: ! ptemp(lon,lat,depth) : degC, potential temperature - ! salt (lon,lat,depth) : PSU, salinity + ! salt (lon,lat,depth) : ppt, salinity ! ! The first record will be read if there are multiple time levels. ! The observation grid MUST tile the model grid. If the model grid extends diff --git a/src/initialization/MOM_tracer_initialization_from_Z.F90 b/src/initialization/MOM_tracer_initialization_from_Z.F90 index 1baf30fcc3..27511e1593 100644 --- a/src/initialization/MOM_tracer_initialization_from_Z.F90 +++ b/src/initialization/MOM_tracer_initialization_from_Z.F90 @@ -33,6 +33,11 @@ module MOM_tracer_initialization_from_Z public :: MOM_initialize_tracer_from_Z +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + character(len=40) :: mdl = "MOM_tracer_initialization_from_Z" !< This module's name. contains @@ -45,7 +50,7 @@ subroutine MOM_initialize_tracer_from_Z(h, tr, G, GV, US, PF, src_file, src_var_ type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in H (often m or kg m-2). + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. real, dimension(:,:,:), pointer :: tr !< Pointer to array to be initialized type(param_file_type), intent(in) :: PF !< parameter file character(len=*), intent(in) :: src_file !< source filename @@ -77,9 +82,9 @@ subroutine MOM_initialize_tracer_from_Z(h, tr, G, GV, US, PF, src_file, src_var_ real, allocatable, dimension(:), target :: z_edges_in, z_in ! Local variables for ALE remapping - real, dimension(:,:,:), allocatable :: hSrc ! Source thicknesses in H units. - real, dimension(:), allocatable :: h1 ! A 1-d column of source thicknesses in Z. - real :: zTopOfCell, zBottomOfCell, z_bathy ! Heights in Z. + real, dimension(:,:,:), allocatable :: hSrc ! Source thicknesses [H ~> m or kg m-2]. + real, dimension(:), allocatable :: h1 ! A 1-d column of source thicknesses [Z ~> m]. + real :: zTopOfCell, zBottomOfCell, z_bathy ! Heights [Z ~> m]. type(remapping_CS) :: remapCS ! Remapping parameters and work arrays real :: missing_value diff --git a/src/initialization/midas_vertmap.F90 b/src/initialization/midas_vertmap.F90 index 23bda0fce0..a985cf2982 100644 --- a/src/initialization/midas_vertmap.F90 +++ b/src/initialization/midas_vertmap.F90 @@ -13,6 +13,11 @@ module MIDAS_vertmap public find_interfaces, meshgrid #endif +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Fill grid edges interface fill_boundaries module procedure fill_boundaries_real @@ -25,7 +30,7 @@ module MIDAS_vertmap contains #ifdef PY_SOLO -!> Calculate seawater equation of state, given T[degC],S[PSU],p[Pa] +!> Calculate seawater equation of state, given T[degC], S[PSU], and p[Pa] !! Returns density [kg m-3] !! !! These EOS routines are needed only for the stand-alone version of the code @@ -33,9 +38,9 @@ module MIDAS_vertmap !! sea water using the formulae given by Wright, 1997, J. Atmos. !! Ocean. Tech., 14, 735-740. function wright_eos_2d(T,S,p) result(rho) - real(kind=8), dimension(:,:), intent(in) :: T,S !< temperature (degC) and Salinity (psu) - real, intent(in) :: p !< pressure (Pa) - real(kind=8), dimension(size(T,1),size(T,2)) :: rho !< potential density (kg m-3) + real(kind=8), dimension(:,:), intent(in) :: T,S !< temperature [degC] and Salinity [psu] + real, intent(in) :: p !< pressure [Pa] + real(kind=8), dimension(size(T,1),size(T,2)) :: rho !< potential density [kg m-3] ! Local variables real(kind=8) :: a0,a1,a2,b0,b1,b2,b3,b4,b5,c0,c1,c2,c3,c4,c5 real(kind=8) :: al0,lam,p0,I_denom @@ -63,16 +68,16 @@ function wright_eos_2d(T,S,p) result(rho) end function wright_eos_2d !> Calculate seawater thermal expansion coefficient given T[degC],S[PSU],p[Pa] -!! Returns density [kg m-3 C-1] +!! Returns density [kg m-3 degC-1] !! !! The subroutines in this file implement the equation of state for !! sea water using the formulae given by Wright, 1997, J. Atmos. !! Ocean. Tech., 14, 735-740. function alpha_wright_eos_2d(T,S,p) result(drho_dT) - real(kind=8), dimension(:,:), intent(in) :: T,S !< temperature (degC) and Salinity (psu) - real, intent(in) :: p !< pressure (Pa) + real(kind=8), dimension(:,:), intent(in) :: T,S !< temperature [degC] and Salinity [psu] + real, intent(in) :: p !< pressure [Pa] real(kind=8), dimension(size(T,1),size(T,2)) :: drho_dT !< partial derivative of density with - !! respect to temperature (kg m-3 C-1) + !! respect to temperature [kg m-3 degC-1] ! Local variables real(kind=8) :: a0,a1,a2,b0,b1,b2,b3,b4,b5,c0,c1,c2,c3,c4,c5 real(kind=8) :: al0,lam,p0,I_denom,I_denom2 @@ -109,10 +114,10 @@ end function alpha_wright_eos_2d !! sea water using the formulae given by Wright, 1997, J. Atmos. !! Ocean. Tech., 14, 735-740. function beta_wright_eos_2d(T,S,p) result(drho_dS) - real(kind=8), dimension(:,:), intent(in) :: T,S !< temperature (degC) and salinity (psu) - real, intent(in) :: p !< pressure (Pa) + real(kind=8), dimension(:,:), intent(in) :: T,S !< temperature [degC] and salinity [psu] + real, intent(in) :: p !< pressure [Pa] real(kind=8), dimension(size(T,1),size(T,2)) :: drho_dS !< partial derivative of density with - !! respect to salinity (kg m-3 PSU-1) + !! respect to salinity [kg m-3 PSU-1] ! Local variables real(kind=8) :: a0,a1,a2,b0,b1,b2,b3,b4,b5,c0,c1,c2,c3,c4,c5 real(kind=8) :: al0,lam,p0,I_denom,I_denom2 @@ -146,10 +151,11 @@ end function beta_wright_eos_2d function tracer_z_init(tr_in, z_edges, e, nkml, nkbl, land_fill, wet, nlay, nlevs, & debug, i_debug, j_debug, eps_z) result(tr) real, dimension(:,:,:), intent(in) :: tr_in !< The z-space array of tracer concentrations that is read in. - real, dimension(size(tr_in,3)+1), intent(in) :: z_edges !< The depths of the cell edges in the input z* data (Z or m) + real, dimension(size(tr_in,3)+1), intent(in) :: z_edges !< The depths of the cell edges in the input z* data + !! [Z ~> m or m] integer, intent(in) :: nlay !< The number of vertical layers in the target grid real, dimension(size(tr_in,1),size(tr_in,2),nlay+1), & - intent(in) :: e !< The depths of the target layer interfaces (Z or m) + intent(in) :: e !< The depths of the target layer interfaces [Z ~> m or m] integer, intent(in) :: nkml !< The number of mixed layers integer, intent(in) :: nkbl !< The number of buffer layers real, intent(in) :: land_fill !< fill in data over land (1) @@ -160,7 +166,7 @@ function tracer_z_init(tr_in, z_edges, e, nkml, nkbl, land_fill, wet, nlay, nlev logical, optional, intent(in) :: debug !< optional debug flag integer, optional, intent(in) :: i_debug !< i-index of point for debugging integer, optional, intent(in) :: j_debug !< j-index of point for debugging - real, optional, intent(in) :: eps_z !< A negligibly small layer thickness in the units of Z. + real, optional, intent(in) :: eps_z !< A negligibly small layer thickness [Z ~> m or m]. real, dimension(size(tr_in,1),size(tr_in,2),nlay) :: tr !< tracers in layer space ! Local variables @@ -170,12 +176,12 @@ function tracer_z_init(tr_in, z_edges, e, nkml, nkbl, land_fill, wet, nlay, nlev integer, dimension(size(tr_in,1),size(tr_in,2)) :: nlevs_data !< number of valid levels in the input dataset integer :: n,i,j,k,l,nx,ny,nz,nt,kz integer :: k_top,k_bot,k_bot_prev,kk,kstart - real :: sl_tr ! The tracer concentration slope times the layer thickess, in tracer units. - real :: epsln_Z ! A negligibly thin layer thickness, in Z. + real :: sl_tr ! The tracer concentration slope times the layer thickness, in tracer units. + real :: epsln_Z ! A negligibly thin layer thickness [Z ~> m]. real, dimension(size(tr_in,3)) :: wt !< The fractional weight for each layer in the range between z1 and z2 real, dimension(size(tr_in,3)) :: z1, z2 ! z1 and z2 are the fractional depths of the top and bottom ! limits of the part of a z-cell that contributes to a layer, relative - ! to the cell center and normalized by the cell thickness, nondim. + ! to the cell center and normalized by the cell thickness [nondim]. ! Note that -1/2 <= z1 <= z2 <= 1/2. logical :: debug_msg, debug_, debug_pt @@ -340,10 +346,10 @@ end function bisect_fast !> This subroutine determines the potential temperature and salinity that !! is consistent with the target density using provided initial guess subroutine determine_temperature(temp, salt, R, p_ref, niter, land_fill, h, k_start) - real(kind=8), dimension(:,:,:), intent(inout) :: temp !< potential temperature (degC) - real(kind=8), dimension(:,:,:), intent(inout) :: salt !< salinity (PSU) - real(kind=8), dimension(size(temp,3)), intent(in) :: R !< desired potential density, in kg m-3. - real, intent(in) :: p_ref !< reference pressure, in Pa. + real(kind=8), dimension(:,:,:), intent(inout) :: temp !< potential temperature [degC] + real(kind=8), dimension(:,:,:), intent(inout) :: salt !< salinity [PSU] + real(kind=8), dimension(size(temp,3)), intent(in) :: R !< desired potential density [kg m-3]. + real, intent(in) :: p_ref !< reference pressure [Pa]. integer, intent(in) :: niter !< maximum number of iterations integer, intent(in) :: k_start !< starting index (i.e. below the buffer layer) real, intent(in) :: land_fill !< land fill value @@ -355,10 +361,10 @@ subroutine determine_temperature(temp, salt, R, p_ref, niter, land_fill, h, k_st !> This subroutine determines the potential temperature and salinity that !! is consistent with the target density using provided initial guess subroutine determine_temperature(temp, salt, R, p_ref, niter, land_fill, h, k_start, eos) - real, dimension(:,:,:), intent(inout) :: temp !< potential temperature (degC) - real, dimension(:,:,:), intent(inout) :: salt !< salinity (PSU) - real, dimension(size(temp,3)), intent(in) :: R !< desired potential density, in kg m-3. - real, intent(in) :: p_ref !< reference pressure, in Pa. + real, dimension(:,:,:), intent(inout) :: temp !< potential temperature [degC] + real, dimension(:,:,:), intent(inout) :: salt !< salinity [PSU] + real, dimension(size(temp,3)), intent(in) :: R !< desired potential density [kg m-3]. + real, intent(in) :: p_ref !< reference pressure [Pa]. integer, intent(in) :: niter !< maximum number of iterations integer, intent(in) :: k_start !< starting index (i.e. below the buffer layer) real, intent(in) :: land_fill !< land fill value @@ -459,16 +465,16 @@ end subroutine determine_temperature !! of each layer that overlaps that depth range. !! Note that by convention, e decreases with increasing k and Z_top > Z_bot. subroutine find_overlap(e, Z_top, Z_bot, k_max, k_start, k_top, k_bot, wt, z1, z2) - real, dimension(:), intent(in) :: e !< The interface positions, in m or Z. - real, intent(in) :: Z_top !< The top of the range being mapped to, in m or Z. - real, intent(in) :: Z_bot !< The bottom of the range being mapped to, in m or Z. + real, dimension(:), intent(in) :: e !< The interface positions, [Z ~> m] or other units. + real, intent(in) :: Z_top !< The top of the range being mapped to, [Z ~> m] or other units. + real, intent(in) :: Z_bot !< The bottom of the range being mapped to, [Z ~> m] or other units. integer, intent(in) :: k_max !< The number of valid layers. integer, intent(in) :: k_start !< The layer at which to start searching. integer, intent(out) :: k_top !< The index of the top layer that overlap with the depth range. integer, intent(out) :: k_bot !< The index of the bottom layer that overlap with the depth range. - real, dimension(:), intent(out) :: wt !< The relative weights of each layer from k_top to k_bot, nondim. - real, dimension(:), intent(out) :: z1 !< Depth of the top limit of layer that contributes to a level, nondim. - real, dimension(:), intent(out) :: z2 !< Depth of the bottom limit of layer that contributes to a level, nondim. + real, dimension(:), intent(out) :: wt !< The relative weights of each layer from k_top to k_bot [nondim]. + real, dimension(:), intent(out) :: z1 !< Depth of the top limit of layer that contributes to a level [nondim]. + real, dimension(:), intent(out) :: z2 !< Depth of the bottom limit of layer that contributes to a level [nondim]. ! Local variables real :: Ih, e_c, tot_wt, I_totwt @@ -522,7 +528,7 @@ end subroutine find_overlap !! a piecewise limited scheme. function find_limited_slope(val, e, k) result(slope) real, dimension(:), intent(in) :: val !< An column the values that are being interpolated. - real, dimension(:), intent(in) :: e !< A column's interface heights, in Z or m. + real, dimension(:), intent(in) :: e !< A column's interface heights [Z ~> m] or other units. integer, intent(in) :: k !< The layer whose slope is being determined. real :: slope !< The normalized slope in the intracell distribution of val. ! Local variables @@ -555,19 +561,19 @@ end function find_limited_slope !> Find interface positions corresponding to density profile function find_interfaces(rho, zin, Rb, depth, nlevs, nkml, nkbl, hml, debug, eps_z) result(zi) real, dimension(:,:,:), & - intent(in) :: rho !< potential density in z-space (kg m-3) + intent(in) :: rho !< potential density in z-space [kg m-3] real, dimension(size(rho,3)), & - intent(in) :: zin !< Input data levels, in Z (often m). - real, dimension(:), intent(in) :: Rb !< target interface densities (kg m-3) + intent(in) :: zin !< Input data levels [Z ~> m or m]. + real, dimension(:), intent(in) :: Rb !< target interface densities [kg m-3] real, dimension(size(rho,1),size(rho,2)), & - intent(in) :: depth !< ocean depth in Z + intent(in) :: depth !< ocean depth [Z ~> m]. real, dimension(size(rho,1),size(rho,2)), & optional, intent(in) :: nlevs !< number of valid points in each column logical, optional, intent(in) :: debug !< optional debug flag integer, optional, intent(in) :: nkml !< number of mixed layer pieces integer, optional, intent(in) :: nkbl !< number of buffer layer pieces - real, optional, intent(in) :: hml !< mixed layer depth, in Z - real, optional, intent(in) :: eps_z !< A negligibly small layer thickness in the units of Z. + real, optional, intent(in) :: hml !< mixed layer depth [Z ~> m]. + real, optional, intent(in) :: eps_z !< A negligibly small layer thickness [Z ~> m or m]. real, dimension(size(rho,1),size(rho,2),size(Rb,1)) :: zi !< The returned interface, in the same units az zin. ! Local variables @@ -583,8 +589,8 @@ function find_interfaces(rho, zin, Rb, depth, nlevs, nkml, nkbl, hml, debug, eps integer :: n,i,j,k,l,nx,ny,nz,nt integer :: nlay,kk,nkml_,nkbl_ logical :: debug_ = .false. - real :: epsln_Z ! A negligibly thin layer thickness, in Z. - real :: epsln_rho ! A negligibly small density change, in kg m-3. + real :: epsln_Z ! A negligibly thin layer thickness [Z ~> m]. + real :: epsln_rho ! A negligibly small density change [kg m-3]. real, parameter :: zoff=0.999 nlay=size(Rb)-1 @@ -708,7 +714,7 @@ end subroutine meshgrid !! in each region is an approximation to del2(zi)=0 subject to !! boundary conditions along the valid points curve bounding this region. subroutine smooth_heights(zi,fill,bad,sor,niter,cyclic_x, tripolar_n) - real, dimension(:,:), intent(inout) :: zi !< interface positions (m) + real, dimension(:,:), intent(inout) :: zi !< interface positions [m] or arbitrary integer, dimension(size(zi,1),size(zi,2)), intent(in) :: fill !< points to be smoothed integer, dimension(size(zi,1),size(zi,2)), intent(in) :: bad !< ignore these points real, intent(in) :: sor !< successive over-relaxation coefficient (typically 0.6) diff --git a/src/ocean_data_assim/MOM_oda_driver.F90 b/src/ocean_data_assim/MOM_oda_driver.F90 index 1ac6c2a035..1a9bf92c57 100644 --- a/src/ocean_data_assim/MOM_oda_driver.F90 +++ b/src/ocean_data_assim/MOM_oda_driver.F90 @@ -73,7 +73,7 @@ module MOM_oda_driver_mod type(domain2d), pointer :: mpp_domain => NULL() !< Pointer to a mpp domain object for DA type(grid_type), pointer :: oda_grid !< local tracer grid - real, pointer, dimension(:,:,:) :: h => NULL() ! NULL() ! m or kg m-2] for DA type(thermo_var_ptrs), pointer :: tv => NULL() !< pointer to thermodynamic variables integer :: ni !< global i-direction grid size integer :: nj !< global j-direction grid size @@ -323,7 +323,7 @@ subroutine set_prior_tracer(Time, G, GV, h, tv, CS) type(time_type), intent(in) :: Time !< The current model time type(ocean_grid_type), pointer :: G !< domain and grid information for ocean model type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables type(ODA_CS), pointer :: CS !< ocean DA control structure @@ -383,7 +383,7 @@ end subroutine set_prior_tracer subroutine get_posterior_tracer(Time, CS, h, tv, increment) type(time_type), intent(in) :: Time !< the current model time type(ODA_CS), pointer :: CS !< ocean DA control structure - real, dimension(:,:,:), pointer :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(:,:,:), pointer :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), pointer :: tv !< A structure pointing to various thermodynamic variables logical, optional, intent(in) :: increment !< True if returning increment only @@ -545,11 +545,11 @@ end subroutine save_obs_diff !> Apply increments to tracers subroutine apply_oda_tracer_increments(dt,G,tv,h,CS) - real, intent(in) :: dt !< The tracer timestep (seconds) + real, intent(in) :: dt !< The tracer timestep [s] type(ocean_grid_type), intent(in) :: G !< ocean grid structure type(thermo_var_ptrs), intent(inout) :: tv !< A structure pointing to various thermodynamic variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< layer thickness (m or kg/m2) + intent(in) :: h !< layer thickness [H ~> m or kg m-2] type(ODA_CS), intent(inout) :: CS !< the data assimilation structure end subroutine apply_oda_tracer_increments diff --git a/src/parameterizations/lateral/MOM_MEKE.F90 b/src/parameterizations/lateral/MOM_MEKE.F90 index a7433c58bb..21e06ebcef 100644 --- a/src/parameterizations/lateral/MOM_MEKE.F90 +++ b/src/parameterizations/lateral/MOM_MEKE.F90 @@ -31,40 +31,40 @@ module MOM_MEKE !> Control structure that contains MEKE parameters and diagnostics handles type, public :: MEKE_CS ; private ! Parameters - real :: MEKE_FrCoeff !< Efficiency of conversion of ME into MEKE (non-dim) - real :: MEKE_GMcoeff !< Efficiency of conversion of PE into MEKE (non-dim) - real :: MEKE_damping !< Local depth-independent MEKE dissipation rate in s-1. + real :: MEKE_FrCoeff !< Efficiency of conversion of ME into MEKE [nondim] + real :: MEKE_GMcoeff !< Efficiency of conversion of PE into MEKE [nondim] + real :: MEKE_damping !< Local depth-independent MEKE dissipation rate [s-1]. real :: MEKE_Cd_scale !< The ratio of the bottom eddy velocity to the column mean !! eddy velocity, i.e. sqrt(2*MEKE). This should be less than 1 !! to account for the surface intensification of MEKE. - real :: MEKE_Cb !< Coefficient in the \f$\gamma_{bot}\f$ expression (non-dim) - real :: MEKE_min_gamma!< Minimum value of gamma_b^2 allowed (non-dim) - real :: MEKE_Ct !< Coefficient in the \f$\gamma_{bt}\f$ expression (non-dim) + real :: MEKE_Cb !< Coefficient in the \f$\gamma_{bot}\f$ expression [nondim] + real :: MEKE_min_gamma!< Minimum value of gamma_b^2 allowed [nondim] + real :: MEKE_Ct !< Coefficient in the \f$\gamma_{bt}\f$ expression [nondim] logical :: visc_drag !< If true use the vertvisc_type to calculate bottom drag. logical :: Rd_as_max_scale !< If true the length scale can not exceed the !! first baroclinic deformation radius. logical :: use_old_lscale !< Use the old formula for mixing length scale. - real :: cdrag !< The bottom drag coefficient for MEKE (non-dim). - real :: MEKE_BGsrc !< Background energy source for MEKE in W/kg (= m2 s-3). - real :: MEKE_dtScale !< Scale factor to accelerate time-stepping (non-dim.) - real :: MEKE_KhCoeff !< Scaling factor to convert MEKE into Kh (non-dim.) - real :: MEKE_Uscale !< MEKE velocity scale for bottom drag (m/s) - real :: MEKE_KH !< Background lateral diffusion of MEKE (m^2/s) - real :: MEKE_K4 !< Background bi-harmonic diffusivity (of MEKE) (m^4/s) + real :: cdrag !< The bottom drag coefficient for MEKE [nondim]. + real :: MEKE_BGsrc !< Background energy source for MEKE [W kg-1] (= m2 s-3). + real :: MEKE_dtScale !< Scale factor to accelerate time-stepping [nondim] + real :: MEKE_KhCoeff !< Scaling factor to convert MEKE into Kh [nondim] + real :: MEKE_Uscale !< MEKE velocity scale for bottom drag [m s-1] + real :: MEKE_KH !< Background lateral diffusion of MEKE [m2 s-1] + real :: MEKE_K4 !< Background bi-harmonic diffusivity (of MEKE) [m4 s-1] real :: KhMEKE_Fac !< A factor relating MEKE%Kh to the diffusivity used for - !! MEKE itself (nondimensional). + !! MEKE itself [nondim]. real :: viscosity_coeff !< The scaling coefficient in the expression for !! viscosity used to parameterize lateral momentum mixing !! by unresolved eddies represented by MEKE. - real :: Lfixed !< Fixed mixing length scale, in m. - real :: aDeform !< Weighting towards deformation scale of mixing length (non-dim.) - real :: aRhines !< Weighting towards Rhines scale of mixing length (non-dim.) - real :: aFrict !< Weighting towards frictional arrest scale of mixing length (non-dim.) - real :: aEady !< Weighting towards Eady scale of mixing length (non-dim.) - real :: aGrid !< Weighting towards grid scale of mixing length (non-dim.) - real :: MEKE_advection_factor !< A scaling in front of the advection of MEKE (non-dim.) + real :: Lfixed !< Fixed mixing length scale [m]. + real :: aDeform !< Weighting towards deformation scale of mixing length [nondim] + real :: aRhines !< Weighting towards Rhines scale of mixing length [nondim] + real :: aFrict !< Weighting towards frictional arrest scale of mixing length [nondim] + real :: aEady !< Weighting towards Eady scale of mixing length [nondim] + real :: aGrid !< Weighting towards grid scale of mixing length [nondim] + real :: MEKE_advection_factor !< A scaling in front of the advection of MEKE [nondim] real :: MEKE_topographic_beta !< Weight for how much topographic beta is considered - !! when computing beta in Rhines scale (non-dim.) + !! when computing beta in Rhines scale [nondim] logical :: initialize !< If True, invokes a steady state solver to calculate MEKE. logical :: debug !< If true, write out checksums of data for debugging @@ -98,48 +98,48 @@ subroutine step_forward_MEKE(MEKE, h, SN_u, SN_v, visc, dt, G, GV, US, CS, hu, h type(ocean_grid_type), intent(inout) :: G !< Ocean grid. type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness in H (m or kg m-2). - real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: SN_u !< Eady growth rate at u-points (s-1). - real, dimension(SZI_(G),SZJB_(G)), intent(in) :: SN_v !< Eady growth rate at v-points (s-1). + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. + real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: SN_u !< Eady growth rate at u-points [s-1]. + real, dimension(SZI_(G),SZJB_(G)), intent(in) :: SN_v !< Eady growth rate at v-points [s-1]. type(vertvisc_type), intent(in) :: visc !< The vertical viscosity type. - real, intent(in) :: dt !< Model(baroclinic) time-step (s). + real, intent(in) :: dt !< Model(baroclinic) time-step [s]. type(MEKE_CS), pointer :: CS !< MEKE control structure. - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: hu !< Zonal mass flux (H m2 s-1). - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: hv !< Meridional mass flux (H m2 s-1). + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: hu !< Zonal mass flux [H m2 s-1 ~> m3 s-1 or kg s-1]. + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: hv !< Meridional mass flux [H m2 s-1 ~> m3 s-1 or kg s-1] ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - mass, & ! The total mass of the water column, in kg m-2. - I_mass, & ! The inverse of mass, in m2 kg-1. - src, & ! The sum of all MEKE sources, in m2 s-3. - MEKE_decay, & ! The MEKE decay timescale, in s-1. - MEKE_GM_src, & ! The MEKE source from thickness mixing, in m2 s-3. - MEKE_mom_src, & ! The MEKE source from momentum, in m2 s-3. + mass, & ! The total mass of the water column [kg m-2]. + I_mass, & ! The inverse of mass [m2 kg-1]. + src, & ! The sum of all MEKE sources [m2 s-3]. + MEKE_decay, & ! The MEKE decay timescale [s-1]. + MEKE_GM_src, & ! The MEKE source from thickness mixing [m2 s-3]. + MEKE_mom_src, & ! The MEKE source from momentum [m2 s-3]. drag_rate_visc, & - drag_rate, & ! The MEKE spindown timescale due to bottom drag, in s-1. - LmixScale, & ! Square of eddy mixing length, in m2. - barotrFac2, & ! Ratio of EKE_barotropic / EKE (nondim)/ - bottomFac2 ! Ratio of EKE_bottom / EKE (nondim)/ + drag_rate, & ! The MEKE spindown timescale due to bottom drag [s-1]. + LmixScale, & ! Square of eddy mixing length [m2]. + barotrFac2, & ! Ratio of EKE_barotropic / EKE [nondim] + bottomFac2 ! Ratio of EKE_bottom / EKE [nondim] real, dimension(SZIB_(G),SZJ_(G)) :: & - MEKE_uflux, & ! The zonal diffusive flux of MEKE, in kg m2 s-3. - Kh_u, & ! The zonal diffusivity that is actually used, in m2 s-1. - baroHu, & ! Depth integrated zonal mass flux (H m2 s-1). + MEKE_uflux, & ! The zonal diffusive flux of MEKE [kg m2 s-3]. + Kh_u, & ! The zonal diffusivity that is actually used [m2 s-1]. + baroHu, & ! Depth integrated zonal mass flux [H m2 s-1 ~> m3 s-1 or kg s-1]. drag_vel_u ! A (vertical) viscosity associated with bottom drag at - ! u-points, in m s-1. + ! u-points [m s-1]. real, dimension(SZI_(G),SZJB_(G)) :: & - MEKE_vflux, & ! The meridional diffusive flux of MEKE, in kg m2 s-3. - Kh_v, & ! The meridional diffusivity that is actually used, in m2 s-1. - baroHv, & ! Depth integrated meridional mass flux (H m2 s-1). + MEKE_vflux, & ! The meridional diffusive flux of MEKE [kg m2 s-3]. + Kh_v, & ! The meridional diffusivity that is actually used [m2 s-1]. + baroHv, & ! Depth integrated meridional mass flux [H m2 s-1 ~> m3 s-1 or kg s-1]. drag_vel_v ! A (vertical) viscosity associated with bottom drag at - ! v-points, in m s-1. + ! v-points [m s-1]. real :: Kh_here, Inv_Kh_max, K4_here real :: cdrag2 real :: advFac - real :: mass_neglect ! A negligible mass, in kg m-2. - real :: ldamping ! The MEKE damping rate in s-1. - real :: Rho0 ! A density used to convert mass to distance, in kg m-3. - real :: sdt ! dt to use locally (could be scaled to accelerate) - real :: sdt_damp ! dt for damping (sdt could be split). + real :: mass_neglect ! A negligible mass [kg m-2]. + real :: ldamping ! The MEKE damping rate [s-1]. + real :: Rho0 ! A density used to convert mass to distance [kg m-3]. + real :: sdt ! dt to use locally [s] (could be scaled to accelerate) + real :: sdt_damp ! dt for damping [s] (sdt could be split). logical :: use_drag_rate ! Flag to indicate drag_rate is finite integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz @@ -553,8 +553,8 @@ subroutine MEKE_equilibrium(CS, MEKE, G, GV, US, SN_u, SN_v, drag_rate_visc, I_m type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(MEKE_CS), pointer :: CS !< MEKE control structure. type(MEKE_type), pointer :: MEKE !< MEKE data. - real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: SN_u !< Eady growth rate at u-points (s-1). - real, dimension(SZI_(G),SZJB_(G)), intent(in) :: SN_v !< Eady growth rate at v-points (s-1). + real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: SN_u !< Eady growth rate at u-points [s-1]. + real, dimension(SZI_(G),SZJB_(G)), intent(in) :: SN_v !< Eady growth rate at v-points [s-1]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: drag_rate_visc !< Mean flow contrib. to drag rate real, dimension(SZI_(G),SZJ_(G)), intent(in) :: I_mass !< Inverse of column mass. ! Local variables @@ -563,7 +563,7 @@ subroutine MEKE_equilibrium(CS, MEKE, G, GV, US, SN_u, SN_v, drag_rate_visc, I_m real :: EKE, EKEmin, EKEmax, resid, ResMin, ResMax, EKEerr real :: FatH ! Coriolis parameter at h points; to compute topographic beta integer :: i, j, is, ie, js, je, n1, n2 - real, parameter :: tolerance = 1.e-12 ! Width of EKE bracket in m^2 s^-2. + real, parameter :: tolerance = 1.e-12 ! Width of EKE bracket [m2 s-2]. logical :: useSecant, debugIteration is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -682,12 +682,12 @@ subroutine MEKE_lengthScales(CS, MEKE, G, US, SN_u, SN_v, & type(MEKE_type), pointer :: MEKE !< MEKE data. type(ocean_grid_type), intent(inout) :: G !< Ocean grid. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: SN_u !< Eady growth rate at u-points (s-1). - real, dimension(SZI_(G),SZJB_(G)), intent(in) :: SN_v !< Eady growth rate at v-points (s-1). - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: EKE !< Eddy kinetic energy (m2/s2). + real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: SN_u !< Eady growth rate at u-points [s-1]. + real, dimension(SZI_(G),SZJB_(G)), intent(in) :: SN_v !< Eady growth rate at v-points [s-1]. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: EKE !< Eddy kinetic energy [m2 s-2]. real, dimension(SZI_(G),SZJ_(G)), intent(out) :: bottomFac2 !< gamma_b^2 real, dimension(SZI_(G),SZJ_(G)), intent(out) :: barotrFac2 !< gamma_t^2 - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: LmixScale !< Eddy mixing length (m). + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: LmixScale !< Eddy mixing length [m]. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: Lrhines, Leady real :: beta, SN, FatH @@ -727,19 +727,19 @@ end subroutine MEKE_lengthScales subroutine MEKE_lengthScales_0d(CS, area, beta, depth, Rd_dx, SN, EKE, Z_to_L, & bottomFac2, barotrFac2, LmixScale, Lrhines, Leady) type(MEKE_CS), pointer :: CS !< MEKE control structure. - real, intent(in) :: area !< Grid cell area (m2) - real, intent(in) :: beta !< Planetary beta = |grad F| (s-1 m-1) - real, intent(in) :: depth !< Ocean depth (Z) - real, intent(in) :: Rd_dx !< Resolution Ld/dx (nondim). - real, intent(in) :: SN !< Eady growth rate (s-1). - real, intent(in) :: EKE !< Eddy kinetic energy (m s-1). + real, intent(in) :: area !< Grid cell area [m2] + real, intent(in) :: beta !< Planetary beta = |grad F| [s-1 m-1] + real, intent(in) :: depth !< Ocean depth [Z ~> m] + real, intent(in) :: Rd_dx !< Resolution Ld/dx [nondim]. + real, intent(in) :: SN !< Eady growth rate [s-1]. + real, intent(in) :: EKE !< Eddy kinetic energy [m s-1]. real, intent(in) :: Z_to_L !< A conversion factor from depth units (Z) to !! the units for lateral distances (L). real, intent(out) :: bottomFac2 !< gamma_b^2 real, intent(out) :: barotrFac2 !< gamma_t^2 - real, intent(out) :: LmixScale !< Eddy mixing length (m). - real, intent(out) :: Lrhines !< Rhines length scale (m). - real, intent(out) :: Leady !< Eady length scale (m). + real, intent(out) :: LmixScale !< Eddy mixing length [m]. + real, intent(out) :: Lrhines !< Rhines length scale [m]. + real, intent(out) :: Leady !< Eady length scale [m]. ! Local variables real :: Lgrid, Ldeform, LdeformLim, Ue, Lfrict diff --git a/src/parameterizations/lateral/MOM_MEKE_types.F90 b/src/parameterizations/lateral/MOM_MEKE_types.F90 index 2b637af239..22ed34c6c2 100644 --- a/src/parameterizations/lateral/MOM_MEKE_types.F90 +++ b/src/parameterizations/lateral/MOM_MEKE_types.F90 @@ -8,18 +8,18 @@ module MOM_MEKE_types type, public :: MEKE_type ! Variables real, dimension(:,:), pointer :: & - MEKE => NULL(), & !< Vertically averaged eddy kinetic energy, in m2 s-2. - GM_src => NULL(), & !< MEKE source due to thickness mixing (GM), in W m-2. - mom_src => NULL(),& !< MEKE source from lateral friction in the momentum equations, in W m-2. - Kh => NULL(), & !< The MEKE-derived lateral mixing coefficient in m2 s-1. - Rd_dx_h => NULL() !< The deformation radius compared with the grid spacing, nondim. + MEKE => NULL(), & !< Vertically averaged eddy kinetic energy [m2 s-2]. + GM_src => NULL(), & !< MEKE source due to thickness mixing (GM) [W m-2]. + mom_src => NULL(),& !< MEKE source from lateral friction in the momentum equations [W m-2]. + Kh => NULL(), & !< The MEKE-derived lateral mixing coefficient [m2 s-1. + Rd_dx_h => NULL() !< The deformation radius compared with the grid spacing [nondim]. !! Rd_dx_h is copied from VarMix_CS. - real, dimension(:,:), pointer :: Ku => NULL() !< The MEKE-derived lateral viscosity coefficient in m2 s-1. + real, dimension(:,:), pointer :: Ku => NULL() !< The MEKE-derived lateral viscosity coefficient [m2 s-1]. !! This viscosity can be negative when representing backscatter !! from unresolved eddies (see Jansen and Held, 2014). ! Parameters - real :: KhTh_fac = 1.0 !< Multiplier to map Kh(MEKE) to KhTh, nondim - real :: KhTr_fac = 1.0 !< Multiplier to map Kh(MEKE) to KhTr, nondim. + real :: KhTh_fac = 1.0 !< Multiplier to map Kh(MEKE) to KhTh [nondim] + real :: KhTr_fac = 1.0 !< Multiplier to map Kh(MEKE) to KhTr [nondim]. real :: backscatter_Ro_pow = 0.0 !< Power in Rossby number function for backscatter. real :: backscatter_Ro_c = 0.0 !< Coefficient in Rossby number function for backscatter. end type MEKE_type diff --git a/src/parameterizations/lateral/MOM_hor_visc.F90 b/src/parameterizations/lateral/MOM_hor_visc.F90 index 3be015faa4..a980704d21 100644 --- a/src/parameterizations/lateral/MOM_hor_visc.F90 +++ b/src/parameterizations/lateral/MOM_hor_visc.F90 @@ -60,94 +60,94 @@ module MOM_hor_visc !! scales quadratically with the velocity shears. logical :: use_Kh_bg_2d !< Read 2d background viscosity from a file. real :: Kh_bg_min !< The minimum value allowed for Laplacian horizontal - !! viscosity, in m2 s-1. The default is 0.0 + !! viscosity [m2 s-1]. The default is 0.0 logical :: use_land_mask !< Use the land mask for the computation of thicknesses !! at velocity locations. This eliminates the dependence on !! arbitrary values over land or outside of the domain. !! Default is False to maintain answers with legacy experiments !! but should be changed to True for new experiments. logical :: anisotropic !< If true, allow anisotropic component to the viscosity. - real :: Kh_aniso !< The anisotropic viscosity in m2 s-1. + real :: Kh_aniso !< The anisotropic viscosity [m2 s-1]. logical :: dynamic_aniso !< If true, the anisotropic viscosity is recomputed as a function !! of state. This is set depending on ANISOTROPIC_MODE. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: Kh_bg_xx - !< The background Laplacian viscosity at h points, in units - !! of m2 s-1. The actual viscosity may be the larger of this + !< The background Laplacian viscosity at h points [m2 s-1]. + !! The actual viscosity may be the larger of this !! viscosity and the Smagorinsky and Leith viscosities. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: Kh_bg_2d - !< The background Laplacian viscosity at h points, in units - !! of m2 s-1. The actual viscosity may be the larger of this + !< The background Laplacian viscosity at h points [m2 s-1]. + !! The actual viscosity may be the larger of this !! viscosity and the Smagorinsky and Leith viscosities. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: Ah_bg_xx - !< The background biharmonic viscosity at h points, in units - !! of m4 s-1. The actual viscosity may be the larger of this + !< The background biharmonic viscosity at h points [m4 s-1]. + !! The actual viscosity may be the larger of this !! viscosity and the Smagorinsky and Leith viscosities. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: Biharm_Const2_xx !< A constant relating the biharmonic viscosity to the - !! square of the velocity shear, in m4 s. This value is + !! square of the velocity shear [m4 s]. This value is !! set to be the magnitude of the Coriolis terms once the !! velocity differences reach a value of order 1/2 MAXVEL. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: reduction_xx !< The amount by which stresses through h points are reduced !! due to partial barriers. Nondimensional. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - Kh_Max_xx, & !< The maximum permitted Laplacian viscosity, m2 s-1. - Ah_Max_xx, & !< The maximum permitted biharmonic viscosity, m4 s-1. + Kh_Max_xx, & !< The maximum permitted Laplacian viscosity [m2 s-1]. + Ah_Max_xx, & !< The maximum permitted biharmonic viscosity [m4 s-1]. n1n2_h, & !< Factor n1*n2 in the anisotropic direction tensor at h-points n1n1_m_n2n2_h !< Factor n1**2-n2**2 in the anisotropic direction tensor at h-points real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: Kh_bg_xy - !< The background Laplacian viscosity at q points, in units - !! of m2 s-1. The actual viscosity may be the larger of this + !< The background Laplacian viscosity at q points [m2 s-1]. + !! The actual viscosity may be the larger of this !! viscosity and the Smagorinsky and Leith viscosities. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: Ah_bg_xy - !< The background biharmonic viscosity at q points, in units - !! of m4 s-1. The actual viscosity may be the larger of this + !< The background biharmonic viscosity at q points [m4 s-1]. + !! The actual viscosity may be the larger of this !! viscosity and the Smagorinsky and Leith viscosities. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: Biharm_Const2_xy !< A constant relating the biharmonic viscosity to the - !! square of the velocity shear, in m4 s. This value is + !! square of the velocity shear [m4 s]. This value is !! set to be the magnitude of the Coriolis terms once the !! velocity differences reach a value of order 1/2 MAXVEL. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: reduction_xy !< The amount by which stresses through q points are reduced - !! due to partial barriers. Nondimensional. + !! due to partial barriers [nondim]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & - Kh_Max_xy, & !< The maximum permitted Laplacian viscosity, m2 s-1. - Ah_Max_xy, & !< The maximum permitted biharmonic viscosity, m4 s-1. + Kh_Max_xy, & !< The maximum permitted Laplacian viscosity [m2 s-1]. + Ah_Max_xy, & !< The maximum permitted biharmonic viscosity [m4 s-1]. n1n2_q, & !< Factor n1*n2 in the anisotropic direction tensor at q-points n1n1_m_n2n2_q !< Factor n1**2-n2**2 in the anisotropic direction tensor at q-points real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - dx2h, & !< Pre-calculated dx^2 at h points, in m2 - dy2h, & !< Pre-calculated dy^2 at h points, in m2 - dx_dyT, & !< Pre-calculated dx/dy at h points, nondim - dy_dxT !< Pre-calculated dy/dx at h points, nondim + dx2h, & !< Pre-calculated dx^2 at h points [m2] + dy2h, & !< Pre-calculated dy^2 at h points [m2] + dx_dyT, & !< Pre-calculated dx/dy at h points [nondim] + dy_dxT !< Pre-calculated dy/dx at h points [nondim] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & - dx2q, & !< Pre-calculated dx^2 at q points, in m2 - dy2q, & !< Pre-calculated dy^2 at q points, in m2 - dx_dyBu, & !< Pre-calculated dx/dy at q points, nondim - dy_dxBu !< Pre-calculated dy/dx at q points, nondim + dx2q, & !< Pre-calculated dx^2 at q points [m2] + dy2q, & !< Pre-calculated dy^2 at q points [m2] + dx_dyBu, & !< Pre-calculated dx/dy at q points [nondim] + dy_dxBu !< Pre-calculated dy/dx at q points [nondim] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_) :: & - Idx2dyCu, & !< 1/(dx^2 dy) at u points, in m-3 - Idxdy2u !< 1/(dx dy^2) at u points, in m-3 + Idx2dyCu, & !< 1/(dx^2 dy) at u points [m-3] + Idxdy2u !< 1/(dx dy^2) at u points [m-3] real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_) :: & - Idx2dyCv, & !< 1/(dx^2 dy) at v points, in m-3 - Idxdy2v !< 1/(dx dy^2) at v points, in m-3 + Idx2dyCv, & !< 1/(dx^2 dy) at v points [m-3] + Idxdy2v !< 1/(dx dy^2) at v points [m-3] ! The following variables are precalculated time-invariant combinations of ! parameters and metric terms. real ALLOCABLE_, dimension(NIMEM_,NJMEM_) :: & - Laplac_Const_xx, & !< Laplacian metric-dependent constants (nondim) - Biharm_Const_xx, & !< Biharmonic metric-dependent constants (nondim) - Laplac3_Const_xx, & !< Laplacian metric-dependent constants (nondim) - Biharm5_Const_xx !< Biharmonic metric-dependent constants (nondim) + Laplac_Const_xx, & !< Laplacian metric-dependent constants [nondim] + Biharm_Const_xx, & !< Biharmonic metric-dependent constants [nondim] + Laplac3_Const_xx, & !< Laplacian metric-dependent constants [nondim] + Biharm5_Const_xx !< Biharmonic metric-dependent constants [nondim] real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEMB_PTR_) :: & - Laplac_Const_xy, & !< Laplacian metric-dependent constants (nondim) - Biharm_Const_xy, & !< Biharmonic metric-dependent constants (nondim) - Laplac3_Const_xy, & !< Laplacian metric-dependent constants (nondim) - Biharm5_Const_xy !< Biharmonic metric-dependent constants (nondim) + Laplac_Const_xy, & !< Laplacian metric-dependent constants [nondim] + Biharm_Const_xy, & !< Biharmonic metric-dependent constants [nondim] + Laplac3_Const_xy, & !< Laplacian metric-dependent constants [nondim] + Biharm5_Const_xy !< Biharmonic metric-dependent constants [nondim] type(diag_ctrl), pointer :: diag => NULL() !< structure to regulate diagnostics @@ -179,18 +179,17 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, CS, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & intent(out) :: diffu !< Zonal acceleration due to convergence of - !! along-coordinate stress tensor (m/s2) + !! along-coordinate stress tensor [m s-2] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & intent(out) :: diffv !< Meridional acceleration due to convergence - !! of along-coordinate stress tensor (m/s2). + !! of along-coordinate stress tensor [m s-2]. type(MEKE_type), pointer :: MEKE !< Pointer to a structure containing fields !! related to Mesoscale Eddy Kinetic Energy. type(VarMix_CS), pointer :: VarMix !< Pointer to a structure with fields that @@ -200,72 +199,72 @@ subroutine horizontal_viscosity(u, v, h, diffu, diffv, MEKE, VarMix, G, GV, CS, type(ocean_OBC_type), optional, pointer :: OBC !< Pointer to an open boundary condition type ! Local variables real, dimension(SZIB_(G),SZJ_(G)) :: & - u0, & ! Laplacian of u (m-1 s-1) - h_u ! Thickness interpolated to u points, in H. + u0, & ! Laplacian of u [m-1 s-1] + h_u ! Thickness interpolated to u points [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJB_(G)) :: & - v0, & ! Laplacian of v (m-1 s-1) - h_v ! Thickness interpolated to v points, in H. + v0, & ! Laplacian of v [m-1 s-1] + h_v ! Thickness interpolated to v points [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G)) :: & - sh_xx, & ! horizontal tension (du/dx - dv/dy) (1/sec) including metric terms - str_xx,& ! str_xx is the diagonal term in the stress tensor (H m2 s-2) - bhstr_xx,& ! A copy of str_xx that only contains the biharmonic contribution (H m2 s-2) - div_xx, & ! horizontal divergence (du/dx + dv/dy) (1/sec) including metric terms - FrictWorkIntz ! depth integrated energy dissipated by lateral friction (W/m2) + sh_xx, & ! horizontal tension (du/dx - dv/dy) including metric terms [s-1] + str_xx,& ! str_xx is the diagonal term in the stress tensor [H m2 s-2 ~> m3 s-2 or kg s-2] + bhstr_xx,& ! A copy of str_xx that only contains the biharmonic contribution [H m2 s-2 ~> m3 s-2 or kg s-2] + div_xx, & ! horizontal divergence (du/dx + dv/dy) including metric terms [s-1] + FrictWorkIntz ! depth integrated energy dissipated by lateral friction [W m-2] real, dimension(SZIB_(G),SZJB_(G)) :: & - dvdx, dudy, & ! components in the shearing strain (s-1) - sh_xy, & ! horizontal shearing strain (du/dy + dv/dx) (1/sec) including metric terms - str_xy, & ! str_xy is the cross term in the stress tensor (H m2 s-2) - bhstr_xy, & ! A copy of str_xy that only contains the biharmonic contribution (H m2 s-2) - vort_xy ! vertical vorticity (dv/dx - du/dy) (1/sec) including metric terms + dvdx, dudy, & ! components in the shearing strain [s-1] + sh_xy, & ! horizontal shearing strain (du/dy + dv/dx) including metric terms [s-1] + str_xy, & ! str_xy is the cross term in the stress tensor [H m2 s-2 ~> m3 s-2 or kg s-2] + bhstr_xy, & ! A copy of str_xy that only contains the biharmonic contribution [H m2 s-2 ~> m3 s-2 or kg s-2] + vort_xy ! vertical vorticity (dv/dx - du/dy) including metric terms [s-1] real, dimension(SZI_(G),SZJB_(G)) :: & - vort_xy_dx, & ! x-derivative of vertical vorticity (d/dx(dv/dx - du/dy)) (m-1 sec-1) including metric terms - div_xx_dy ! y-derivative of horizontal divergence (d/dy(du/dx + dv/dy)) (m-1 sec-1) including metric terms + vort_xy_dx, & ! x-derivative of vertical vorticity (d/dx(dv/dx - du/dy)) including metric terms [m-1 s-1] + div_xx_dy ! y-derivative of horizontal divergence (d/dy(du/dx + dv/dy)) including metric terms [m-1 s-1] real, dimension(SZIB_(G),SZJ_(G)) :: & - vort_xy_dy, & ! y-derivative of vertical vorticity (d/dy(dv/dx - du/dy)) (m-1 sec-1) including metric terms - div_xx_dx ! x-derivative of horizontal divergence (d/dx(du/dx + dv/dy)) (m-1 sec-1) including metric terms + vort_xy_dy, & ! y-derivative of vertical vorticity (d/dy(dv/dx - du/dy)) including metric terms [m-1 s-1] + div_xx_dx ! x-derivative of horizontal divergence (d/dx(du/dx + dv/dy)) including metric terms [m-1 s-1] real, dimension(SZIB_(G),SZJB_(G),SZK_(G)) :: & - Ah_q, & ! biharmonic viscosity at corner points (m4/s) - Kh_q ! Laplacian viscosity at corner points (m2/s) + Ah_q, & ! biharmonic viscosity at corner points [m4 s-1] + Kh_q ! Laplacian viscosity at corner points [m2 s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - Ah_h, & ! biharmonic viscosity at thickness points (m4/s) - Kh_h, & ! Laplacian viscosity at thickness points (m2/s) - FrictWork ! energy dissipated by lateral friction (W/m2) - - real :: Ah ! biharmonic viscosity (m4/s) - real :: Kh ! Laplacian viscosity (m2/s) - real :: AhSm ! Smagorinsky biharmonic viscosity (m4/s) - real :: KhSm ! Smagorinsky Laplacian viscosity (m2/s) - real :: AhLth ! 2D Leith biharmonic viscosity (m4/s) - real :: KhLth ! 2D Leith Laplacian viscosity (m2/s) + Ah_h, & ! biharmonic viscosity at thickness points [m4 s-1] + Kh_h, & ! Laplacian viscosity at thickness points [m2 s-1] + FrictWork ! energy dissipated by lateral friction [W m-2] + + real :: Ah ! biharmonic viscosity [m4 s-1] + real :: Kh ! Laplacian viscosity [m2 s-1] + real :: AhSm ! Smagorinsky biharmonic viscosity [m4 s-1] + real :: KhSm ! Smagorinsky Laplacian viscosity [m2 s-1] + real :: AhLth ! 2D Leith biharmonic viscosity [m4 s-1] + real :: KhLth ! 2D Leith Laplacian viscosity [m2 s-1] real :: mod_Leith ! nondimensional coefficient for divergence part of modified Leith ! viscosity. Here set equal to nondimensional Laplacian Leith constant. ! This is set equal to zero if modified Leith is not used. - real :: Shear_mag ! magnitude of the shear (1/s) - real :: Vort_mag ! magnitude of the vorticity (1/s) - real :: h2uq, h2vq ! temporary variables in units of H^2 (i.e. m2 or kg2 m-4). + real :: Shear_mag ! magnitude of the shear [s-1] + real :: Vort_mag ! magnitude of the vorticity [s-1] + real :: h2uq, h2vq ! temporary variables [H2 ~> m2 or kg2 m-4]. real :: hu, hv ! Thicknesses interpolated by arithmetic means to corner ! points; these are first interpolated to u or v velocity - ! points where masks are applied, in units of H (i.e. m or kg m-2). - real :: hq ! harmonic mean of the harmonic means of the u- & v- - ! point thicknesses, in H; This form guarantees that hq/hu < 4. - real :: h_neglect ! thickness so small it can be lost in roundoff and so neglected (H) - real :: h_neglect3 ! h_neglect^3, in H3 + ! points where masks are applied [H ~> m or kg m-2]. + real :: hq ! harmonic mean of the harmonic means of the u- & v- poing thicknesses, + ! [H ~> m or kg m-2]; This form guarantees that hq/hu < 4. + real :: h_neglect ! thickness so small it can be lost in roundoff and so neglected [H ~> m or kg m-2] + real :: h_neglect3 ! h_neglect^3 [H3 ~> m3 or kg3 m-6] real :: hrat_min ! minimum thicknesses at the 4 neighboring ! velocity points divided by the thickness at the stress - ! point (h or q point) (nondimensional) + ! point (h or q point) [nondim] real :: visc_bound_rem ! fraction of overall viscous bounds that - ! remain to be applied (nondim) + ! remain to be applied [nondim] real :: Kh_scale ! A factor between 0 and 1 by which the horizontal - ! Laplacian viscosity is rescaled - real :: RoScl ! The scaling function for MEKE source term - real :: FatH ! abs(f) at h-point for MEKE source term (s-1) - real :: local_strain ! Local variable for interpolating computed strain rates (s-1). + ! Laplacian viscosity is rescaled [nondim] + real :: RoScl ! The scaling function for MEKE source term [nondim] + real :: FatH ! abs(f) at h-point for MEKE source term [s-1] + real :: local_strain ! Local variable for interpolating computed strain rates [s-1]. logical :: rescale_Kh, legacy_bound logical :: find_FrictWork @@ -965,34 +964,34 @@ subroutine hor_visc_init(Time, G, param_file, diag, CS) real, dimension(SZIB_(G),SZJ_(G)) :: u0u, u0v real, dimension(SZI_(G),SZJB_(G)) :: v0u, v0v ! u0v is the Laplacian sensitivities to the v velocities - ! at u points, in m-2, with u0u, v0u, and v0v defined similarly. - real :: grid_sp_h2 ! Harmonic mean of the squares of the grid - real :: grid_sp_h3 ! Harmonic mean of the squares of the grid^(3/2) - real :: grid_sp_q2 ! spacings at h and q points (m2) - real :: grid_sp_q3 ! spacings at h and q points^(3/2) (m3) - real :: Kh_Limit ! A coefficient (1/s) used, along with the + ! at u points [m-2], with u0u, v0u, and v0v defined similarly. + real :: grid_sp_h2 ! Harmonic mean of the squares of the grid [m2] + real :: grid_sp_h3 ! Harmonic mean of the squares of the grid^(3/2) [m3] + real :: grid_sp_q2 ! spacings at h and q points [m2] + real :: grid_sp_q3 ! spacings at h and q points^(3/2) [m3] + real :: Kh_Limit ! A coefficient [s-1] used, along with the ! grid spacing, to limit Laplacian viscosity. real :: fmax ! maximum absolute value of f at the four - ! vorticity points around a thickness point (1/s) - real :: BoundCorConst ! constant (s2/m2) - real :: Ah_Limit ! coefficient (1/s) used, along with the + ! vorticity points around a thickness point [s-1] + real :: BoundCorConst ! A constant used when using viscosity to bound the Coriolis accelerations [s2 m-2] + real :: Ah_Limit ! coefficient [s-1] used, along with the ! grid spacing, to limit biharmonic viscosity - real :: Kh ! Lapacian horizontal viscosity (m2/s) - real :: Ah ! biharmonic horizontal viscosity (m4/s) - real :: Kh_vel_scale ! this speed (m/s) times grid spacing gives Lap visc - real :: Ah_vel_scale ! this speed (m/s) times grid spacing cubed gives bih visc + real :: Kh ! Lapacian horizontal viscosity [m2 s-1] + real :: Ah ! biharmonic horizontal viscosity [m4 s-1] + real :: Kh_vel_scale ! this speed [m s-1] times grid spacing gives Lap visc + real :: Ah_vel_scale ! this speed [m s-1] times grid spacing cubed gives bih visc real :: Smag_Lap_const ! nondimensional Laplacian Smagorinsky constant real :: Smag_bi_const ! nondimensional biharmonic Smagorinsky constant real :: Leith_Lap_const ! nondimensional Laplacian Leith constant real :: Leith_bi_const ! nondimensional biharmonic Leith constant - real :: dt ! dynamics time step (sec) - real :: Idt ! inverse of dt (1/s) + real :: dt ! dynamics time step [s] + real :: Idt ! inverse of dt [s-1] real :: denom ! work variable; the denominator of a fraction - real :: maxvel ! largest permitted velocity components (m/s) + real :: maxvel ! largest permitted velocity components [m s-1] real :: bound_Cor_vel ! grid-scale velocity variations at which value ! the quadratically varying biharmonic viscosity - ! balances Coriolis acceleration (m/s) - real :: Kh_sin_lat ! Amplitude of latitudinally dependent viscosity (m2/s) + ! balances Coriolis acceleration [m s-1] + real :: Kh_sin_lat ! Amplitude of latitudinally dependent viscosity [m2 s-1] real :: Kh_pwr_of_sine ! Power used to raise sin(lat) when using Kh_sin_lat logical :: bound_Cor_def ! parameter setting of BOUND_CORIOLIS logical :: get_all ! If true, read and log all parameters, regardless of @@ -1619,8 +1618,8 @@ end subroutine hor_visc_init !! With n1=1 and n2=0, this recovers the approach of Large et al, 2001. subroutine align_aniso_tensor_to_grid(CS, n1, n2) type(hor_visc_CS), pointer :: CS !< Control structure for horizontal viscosity - real, intent(in) :: n1 !< i-component of direction vector (nondim) - real, intent(in) :: n2 !< j-component of direction vector (nondim) + real, intent(in) :: n1 !< i-component of direction vector [nondim] + real, intent(in) :: n2 !< j-component of direction vector [nondim] ! Local variables real :: recip_n2_norm diff --git a/src/parameterizations/lateral/MOM_internal_tides.F90 b/src/parameterizations/lateral/MOM_internal_tides.F90 index 527eca30bc..4052f948a3 100644 --- a/src/parameterizations/lateral/MOM_internal_tides.F90 +++ b/src/parameterizations/lateral/MOM_internal_tides.F90 @@ -74,7 +74,7 @@ module MOM_internal_tides !< energy lost due to wave breaking [W m-2] real, allocatable, dimension(:,:) :: TKE_itidal_loss_fixed !< fixed part of the energy lost due to small-scale drag - !! [kg Z-2] here; will be multiplied by N and En to get into [W m-2] + !! [kg Z-2 ~> kg m-2] here; will be multiplied by N and En to get into [W m-2] real, allocatable, dimension(:,:,:,:,:) :: TKE_itidal_loss !< energy lost due to small-scale wave drag [W m-2] real, allocatable, dimension(:,:) :: tot_leak_loss !< Energy loss rates due to misc bakground processes, @@ -87,13 +87,13 @@ module MOM_internal_tides !! summed over angle, frequency and mode [W m-2] real, allocatable, dimension(:,:) :: tot_allprocesses_loss !< Energy loss rates due to all processes, !! summed over angle, frequency and mode [W m-2] - real :: q_itides !< fraction of local dissipation (nondimensional) + real :: q_itides !< fraction of local dissipation [nondim] real :: En_sum !< global sum of energy for use in debugging type(time_type), pointer :: Time => NULL() !< A pointer to the model's clock. character(len=200) :: inputdir !< directory to look for coastline angle file real :: decay_rate !< A constant rate at which internal tide energy is !! lost to the interior ocean internal wave field. - real :: cdrag !< The bottom drag coefficient (non-dim). + real :: cdrag !< The bottom drag coefficient [nondim]. logical :: apply_background_drag !< If true, apply a drag due to background processes as a sink. logical :: apply_bottom_drag @@ -106,7 +106,7 @@ module MOM_internal_tides !< The internal wave energy density as a function of (i,j,angle,frequency,mode) real, dimension(:,:,:), pointer :: En_restart => NULL() !< The internal wave energy density as a function of (i,j,angle); temporary for restart - real, allocatable, dimension(:) :: frequency !< The frequency of each band, in s-1. + real, allocatable, dimension(:) :: frequency !< The frequency of each band [s-1]. !### Delete later real :: int_tide_source_x !< X Location of generation site for internal tide testing @@ -157,21 +157,20 @@ subroutine propagate_int_tide(h, tv, cn, TKE_itidal_input, vel_btTide, Nb, dt, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Pointer to thermodynamic variables !! (needed for wave structure). real, dimension(SZI_(G),SZJ_(G)), intent(in) :: TKE_itidal_input !< The energy input to the - !! internal waves, in W m-2. + !! internal waves [W m-2]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: vel_btTide !< Barotropic velocity read - !! from file, in m s-1. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Nb !< Near-bottom buoyancy frequency, in s-1. + !! from file [m s-1]. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Nb !< Near-bottom buoyancy frequency [s-1]. real, intent(in) :: dt !< Length of time over which these fluxes - !! will be applied, in s. + !! will be applied [s]. type(int_tide_CS), pointer :: CS !< The control structure returned by a !! previous call to int_tide_init. real, dimension(SZI_(G),SZJ_(G),CS%nMode), & - intent(in) :: cn !< The internal wave speeds of each mode, in m s-1. + intent(in) :: cn !< The internal wave speeds of each mode [m s-1]. ! Local variables real, dimension(SZI_(G),SZJ_(G),2) :: & test @@ -433,7 +432,7 @@ subroutine propagate_int_tide(h, tv, cn, TKE_itidal_input, vel_btTide, Nb, dt, & ! Dissipate energy if Fr>1; done here with an arbitrary time scale if (Fr2_max > 1.0) then En_initial = sum(CS%En(i,j,:,fr,m)) ! for debugging - ! Calculate effective decay rate (s-1) if breaking occurs over a time step + ! Calculate effective decay rate [s-1] if breaking occurs over a time step loss_rate = (1/Fr2_max - 1.0)/dt do a=1,CS%nAngle ! Determine effective dissipation rate (Wm-2) @@ -587,7 +586,7 @@ subroutine sum_En(G, CS, En, label) type(int_tide_CS), pointer :: CS !< The control structure returned by a !! previous call to int_tide_init. real, dimension(G%isd:G%ied,G%jsd:G%jed,CS%NAngle), & - intent(in) :: En !< The energy density of the internal tides, in J m-2. + intent(in) :: En !< The energy density of the internal tides [J m-2]. character(len=*), intent(in) :: label !< A label to use in error messages ! Local variables integer :: m,fr,a @@ -624,23 +623,23 @@ end subroutine sum_En !! scattering over small-scale roughness along the lines of Jayne & St. Laurent (2001). subroutine itidal_lowmode_loss(G, US, CS, Nb, Ub, En, TKE_loss_fixed, TKE_loss, dt, full_halos) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. - type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type + type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(int_tide_CS), pointer :: CS !< The control structure returned by a !! previous call to int_tide_init. real, dimension(G%isd:G%ied,G%jsd:G%jed), & - intent(in) :: Nb !< Near-bottom stratification, in s-1. + intent(in) :: Nb !< Near-bottom stratification [s-1]. real, dimension(G%isd:G%ied,G%jsd:G%jed,CS%nFreq,CS%nMode), & - intent(inout) :: Ub !< Rms (over one period) near-bottom horizontal - !! mode velocity, in m s-1. + intent(inout) :: Ub !< RMS (over one period) near-bottom horizontal + !! mode velocity [m s-1]. real, dimension(G%isd:G%ied,G%jsd:G%jed), & - intent(in) :: TKE_loss_fixed !< Fixed part of energy loss, - !! in kg Z-2 (rho*kappa*h^2). + intent(in) :: TKE_loss_fixed !< Fixed part of energy loss [kg Z-2 ~> kg m-2] + !! (rho*kappa*h^2). real, dimension(G%isd:G%ied,G%jsd:G%jed,CS%NAngle,CS%nFreq,CS%nMode), & - intent(inout) :: En !< Energy density of the internal waves, in J m-2. + intent(inout) :: En !< Energy density of the internal waves [J m-2]. real, dimension(G%isd:G%ied,G%jsd:G%jed,CS%NAngle,CS%nFreq,CS%nMode), & - intent(out) :: TKE_loss !< Energy loss rate, in W m-2 + intent(out) :: TKE_loss !< Energy loss rate [W m-2] !! (q*rho*kappa*h^2*N*U^2). - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. logical,optional, intent(in) :: full_halos !< If true, do the calculation over the !! entirecomputational domain. ! Local variables @@ -651,7 +650,7 @@ subroutine itidal_lowmode_loss(G, US, CS, Nb, Ub, En, TKE_loss_fixed, TKE_loss, real :: frac_per_sector ! fraction of energy in each wedge real :: q_itides ! fraction of energy actually lost to mixing (remainder, 1-q, is ! assumed to stay in propagating mode for now - BDM) - real :: loss_rate ! approximate loss rate for implicit calc, s-1 + real :: loss_rate ! approximate loss rate for implicit calc [s-1] real, parameter :: En_negl = 1e-30 ! negilibly small number to prevent division by zero is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec @@ -721,7 +720,7 @@ subroutine get_lowmode_loss(i,j,G,CS,mechanism,TKE_loss_sum) !! previous call to int_tide_init. character(len=*), intent(in) :: mechanism !< The named mechanism of loss to return real, intent(out) :: TKE_loss_sum !< Total energy loss rate due to specified - !! mechanism, in W m-2. + !! mechanism [W m-2]. if (mechanism == 'LeakDrag') TKE_loss_sum = CS%tot_leak_loss(i,j) ! not used for mixing yet if (mechanism == 'QuadDrag') TKE_loss_sum = CS%tot_quad_loss(i,j) ! not used for mixing yet @@ -738,11 +737,11 @@ subroutine refract(En, cn, freq, dt, G, NAngle, use_PPMang) real, dimension(G%isd:G%ied,G%jsd:G%jed,NAngle), & intent(inout) :: En !< The internal gravity wave energy density as a !! function of space and angular resolution, - !! in J m-2 radian-1. + !! [J m-2 radian-1]. real, dimension(G%isd:G%ied,G%jsd:G%jed), & - intent(in) :: cn !< Baroclinic mode speed, in m s-1. - real, intent(in) :: freq !< Wave frequency, in s-1. - real, intent(in) :: dt !< Time step, in s. + intent(in) :: cn !< Baroclinic mode speed [m s-1]. + real, intent(in) :: freq !< Wave frequency [s-1]. + real, intent(in) :: dt !< Time step [s]. logical, intent(in) :: use_PPMang !< If true, use PPM for advection rather !! than upwind. ! Local variables @@ -757,12 +756,12 @@ subroutine refract(En, cn, freq, dt, G, NAngle, use_PPMang) Flux_E real, dimension(SZI_(G),SZJ_(G),1-stencil:NAngle+stencil) :: & CFL_ang - real :: f2 ! The squared Coriolis parameter, in s-2. - real :: favg ! The average Coriolis parameter at a point, in s-1. - real :: df2_dy, df2_dx ! The x- and y- gradients of the squared Coriolis parameter, in s-2 m-1. - real :: df_dy, df_dx ! The x- and y- gradients of the Coriolis parameter, in s-1 m-1. - real :: dlnCn_dx ! The x-gradient of the wave speed divided by itself in m-1. - real :: dlnCn_dy ! The y-gradient of the wave speed divided by itself in m-1. + real :: f2 ! The squared Coriolis parameter [s-2]. + real :: favg ! The average Coriolis parameter at a point [s-1]. + real :: df2_dy, df2_dx ! The x- and y- gradients of the squared Coriolis parameter [s-2 m-1]. + real :: df_dy, df_dx ! The x- and y- gradients of the Coriolis parameter [s-1 m-1]. + real :: dlnCn_dx ! The x-gradient of the wave speed divided by itself [m-1]. + real :: dlnCn_dy ! The y-gradient of the wave speed divided by itself [m-1]. real :: Angle_size, dt_Angle_size, angle real :: Ifreq, Kmag2, I_Kmag real, parameter :: cn_subRO = 1e-100 @@ -873,15 +872,15 @@ end subroutine refract subroutine PPM_angular_advect(En2d, CFL_ang, Flux_En, NAngle, dt, halo_ang) integer, intent(in) :: NAngle !< The number of wave orientations in the !! discretized wave energy spectrum. - real, intent(in) :: dt !< Time increment in s. + real, intent(in) :: dt !< Time increment [s]. integer, intent(in) :: halo_ang !< The halo size in angular space real, dimension(1-halo_ang:NAngle+halo_ang), & intent(in) :: En2d !< The internal gravity wave energy density as a - !! function of angular resolution, in J m-2 radian-1. + !! function of angular resolution [J m-2 radian-1]. real, dimension(1-halo_ang:NAngle+halo_ang), & intent(in) :: CFL_ang !< The CFL number of the energy advection across angles real, dimension(0:NAngle), intent(out) :: Flux_En !< The time integrated internal wave energy flux - !! across angles, in J m-2 radian-1. + !! across angles [J m-2 radian-1]. ! Local variables real :: flux real :: u_ang @@ -958,26 +957,26 @@ subroutine propagate(En, cn, freq, dt, G, CS, NAngle) real, dimension(G%isd:G%ied,G%jsd:G%jed,NAngle), & intent(inout) :: En !< The internal gravity wave energy density as a !! function of space and angular resolution, - !! in J m-2 radian-1. + !! [J m-2 radian-1]. real, dimension(G%isd:G%ied,G%jsd:G%jed), & - intent(in) :: cn !< Baroclinic mode speed, in m s-1. - real, intent(in) :: freq !< Wave frequency, in s-1. - real, intent(in) :: dt !< Time step, in s. + intent(in) :: cn !< Baroclinic mode speed [m s-1]. + real, intent(in) :: freq !< Wave frequency [s-1]. + real, intent(in) :: dt !< Time step [s]. type(int_tide_CS), pointer :: CS !< The control structure returned by a !! previous call to int_tide_init. ! Local variables real, dimension(G%IsdB:G%IedB,G%JsdB:G%JedB) :: & - speed ! The magnitude of the group velocity at the q points for corner adv, in m s-1. + speed ! The magnitude of the group velocity at the q points for corner adv [m s-1]. integer, parameter :: stencil = 2 real, dimension(SZIB_(G),SZJ_(G)) :: & - speed_x ! The magnitude of the group velocity at the Cu points, in m s-1. + speed_x ! The magnitude of the group velocity at the Cu points [m s-1]. real, dimension(SZI_(G),SZJB_(G)) :: & - speed_y ! The magnitude of the group velocity at the Cv points, in m s-1. + speed_y ! The magnitude of the group velocity at the Cv points [m s-1]. real, dimension(0:NAngle) :: & cos_angle, sin_angle real, dimension(NAngle) :: & Cgx_av, Cgy_av, dCgx, dCgy - real :: f2 ! The squared Coriolis parameter, in s-2. + real :: f2 ! The squared Coriolis parameter [s-2]. real :: Angle_size, I_Angle_size, angle real :: Ifreq, freq2 real, parameter :: cn_subRO = 1e-100 @@ -1081,14 +1080,14 @@ subroutine propagate_corner_spread(En, energized_wedge, NAngle, speed, dt, G, CS type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. real, dimension(G%isd:G%ied,G%jsd:G%jed), & intent(inout) :: En !< The energy density integrated over an angular - !! band, in W m-2, intent in/out. + !! band [W m-2], intent in/out. real, dimension(G%IsdB:G%IedB,G%Jsd:G%Jed), & intent(in) :: speed !< The magnitude of the group velocity at the cell - !! corner points, in m s-1. + !! corner points [m s-1]. integer, intent(in) :: energized_wedge !< Index of current ray direction. integer, intent(in) :: NAngle !< The number of wave orientations in the !! discretized wave energy spectrum. - real, intent(in) :: dt !< Time increment in s. + real, intent(in) :: dt !< Time increment [s]. type(int_tide_CS), pointer :: CS !< The control structure returned by a previous !! call to continuity_PPM_init. type(loop_bounds_type), intent(in) :: LB !< A structure with the active energy loop bounds. @@ -1344,27 +1343,27 @@ subroutine propagate_x(En, speed_x, Cgx_av, dCgx, dt, G, Nangle, CS, LB) !! discretized wave energy spectrum. real, dimension(G%isd:G%ied,G%jsd:G%jed,Nangle), & intent(inout) :: En !< The energy density integrated over an angular - !! band, in J m-2, intent in/out. + !! band [J m-2], intent in/out. real, dimension(G%IsdB:G%IedB,G%jsd:G%jed), & intent(in) :: speed_x !< The magnitude of the group velocity at the - !! Cu points, in m s-1. + !! Cu points [m s-1]. real, dimension(Nangle), intent(in) :: Cgx_av !< The average x-projection in each angular band. real, dimension(Nangle), intent(in) :: dCgx !< The difference in x-projections between the !! edges of each angular band. - real, intent(in) :: dt !< Time increment in s. + real, intent(in) :: dt !< Time increment [s]. type(int_tide_CS), pointer :: CS !< The control structure returned by a previous call !! to continuity_PPM_init. type(loop_bounds_type), intent(in) :: LB !< A structure with the active energy loop bounds. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - EnL, EnR ! Left and right face energy densities, in J m-2. + EnL, EnR ! Left and right face energy densities [J m-2]. real, dimension(SZIB_(G),SZJ_(G)) :: & - flux_x ! The internal wave energy flux, in J s-1. + flux_x ! The internal wave energy flux [J s-1]. real, dimension(SZIB_(G)) :: & cg_p, cg_m, flux1, flux2 !real, dimension(SZI_(G),SZJB_(G),Nangle) :: En_m, En_p real, dimension(SZI_(G),SZJB_(G),Nangle) :: & - Fdt_m, Fdt_p! Left and right energy fluxes, in J + Fdt_m, Fdt_p! Left and right energy fluxes [J] integer :: i, j, k, ish, ieh, jsh, jeh, a ish = LB%ish ; ieh = LB%ieh ; jsh = LB%jsh ; jeh = LB%jeh @@ -1427,27 +1426,27 @@ subroutine propagate_y(En, speed_y, Cgy_av, dCgy, dt, G, Nangle, CS, LB) !! discretized wave energy spectrum. real, dimension(G%isd:G%ied,G%jsd:G%jed,Nangle), & intent(inout) :: En !< The energy density integrated over an angular - !! band, in J m-2, intent in/out. + !! band [J m-2], intent in/out. real, dimension(G%isd:G%ied,G%JsdB:G%JedB), & intent(in) :: speed_y !< The magnitude of the group velocity at the - !! Cv points, in m s-1. + !! Cv points [m s-1]. real, dimension(Nangle), intent(in) :: Cgy_av !< The average y-projection in each angular band. real, dimension(Nangle), intent(in) :: dCgy !< The difference in y-projections between the !! edges of each angular band. - real, intent(in) :: dt !< Time increment in s. + real, intent(in) :: dt !< Time increment [s]. type(int_tide_CS), pointer :: CS !< The control structure returned by a previous call !! to continuity_PPM_init. type(loop_bounds_type), intent(in) :: LB !< A structure with the active energy loop bounds. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - EnL, EnR ! South and north face energy densities, in J m-2. + EnL, EnR ! South and north face energy densities [J m-2]. real, dimension(SZI_(G),SZJB_(G)) :: & - flux_y ! The internal wave energy flux, in J s-1. + flux_y ! The internal wave energy flux [J s-1]. real, dimension(SZI_(G)) :: & cg_p, cg_m, flux1, flux2 !real, dimension(SZI_(G),SZJB_(G),Nangle) :: En_m, En_p real, dimension(SZI_(G),SZJB_(G),Nangle) :: & - Fdt_m, Fdt_p! South and north energy fluxes, in J + Fdt_m, Fdt_p! South and north energy fluxes [J] character(len=160) :: mesg ! The text of an error message integer :: i, j, k, ish, ieh, jsh, jeh, a @@ -1513,23 +1512,22 @@ end subroutine propagate_y !> Evaluates the zonal mass or volume fluxes in a layer. subroutine zonal_flux_En(u, h, hL, hR, uh, dt, G, j, ish, ieh, vol_CFL) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. - real, dimension(SZIB_(G)), intent(in) :: u !< The zonal velocity, in m s-1. - real, dimension(SZI_(G)), intent(in) :: h !< Energy density used to calculate the fluxes, - !! in J m-2. - real, dimension(SZI_(G)), intent(in) :: hL !< Left- Energy densities in the reconstruction, - !! in J m-2. - real, dimension(SZI_(G)), intent(in) :: hR !< Right- Energy densities in the reconstruction, - !! in J m-2. - real, dimension(SZIB_(G)), intent(inout) :: uh !< The zonal energy transport, - !! in J s-1. - real, intent(in) :: dt !< Time increment in s. + real, dimension(SZIB_(G)), intent(in) :: u !< The zonal velocity [m s-1]. + real, dimension(SZI_(G)), intent(in) :: h !< Energy density used to calculate the fluxes + !! [J m-2]. + real, dimension(SZI_(G)), intent(in) :: hL !< Left- Energy densities in the reconstruction + !! [J m-2]. + real, dimension(SZI_(G)), intent(in) :: hR !< Right- Energy densities in the reconstruction + !! [J m-2]. + real, dimension(SZIB_(G)), intent(inout) :: uh !< The zonal energy transport [J s-1]. + real, intent(in) :: dt !< Time increment [s]. integer, intent(in) :: j !< The j-index to work on. integer, intent(in) :: ish !< The start i-index range to work on. integer, intent(in) :: ieh !< The end i-index range to work on. logical, intent(in) :: vol_CFL !< If true, rescale the ratio of face areas to !! the cell areas when estimating the CFL number. ! Local variables - real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. + real :: CFL ! The CFL number based on the local velocity and grid spacing [nondim]. real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. integer :: i @@ -1557,16 +1555,15 @@ end subroutine zonal_flux_En !> Evaluates the meridional mass or volume fluxes in a layer. subroutine merid_flux_En(v, h, hL, hR, vh, dt, G, J, ish, ieh, vol_CFL) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. - real, dimension(SZI_(G)), intent(in) :: v !< The meridional velocity, in m s-1. + real, dimension(SZI_(G)), intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h !< Energy density used to calculate the - !! fluxes, in J m-2. + !! fluxes [J m-2]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: hL !< Left- Energy densities in the - !! reconstruction, in J m-2. + !! reconstruction [J m-2]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: hR !< Right- Energy densities in the - !! reconstruction, in J m-2. - real, dimension(SZI_(G)), intent(inout) :: vh !< The meridional energy transport, - !! in J s-1. - real, intent(in) :: dt !< Time increment in s. + !! reconstruction [J m-2]. + real, dimension(SZI_(G)), intent(inout) :: vh !< The meridional energy transport [J s-1]. + real, intent(in) :: dt !< Time increment [s]. integer, intent(in) :: J !< The j-index to work on. integer, intent(in) :: ish !< The start i-index range to work on. integer, intent(in) :: ieh !< The end i-index range to work on. @@ -1574,7 +1571,7 @@ subroutine merid_flux_En(v, h, hL, hR, vh, dt, G, J, ish, ieh, vol_CFL) !! areas to the cell areas when estimating !! the CFL number. ! Local variables - real :: CFL ! The CFL number based on the local velocity and grid spacing, ND. + real :: CFL ! The CFL number based on the local velocity and grid spacing [nondim]. real :: curv_3 ! A measure of the thickness curvature over a grid length, ! with the same units as h_in. integer :: i @@ -1605,8 +1602,8 @@ subroutine reflect(En, NAngle, CS, G, LB) !! discretized wave energy spectrum. real, dimension(G%isd:G%ied,G%jsd:G%jed,NAngle), & intent(inout) :: En !< The internal gravity wave energy density as a - !! function of space and angular resolution, - !! in J m-2 radian-1. + !! function of space and angular resolution + !! [J m-2 radian-1]. type(int_tide_CS), pointer :: CS !< The control structure returned by a !! previous call to int_tide_init. type(loop_bounds_type), intent(in) :: LB !< A structure with the active energy loop bounds. @@ -1719,8 +1716,8 @@ subroutine teleport(En, NAngle, CS, G, LB) !! discretized wave energy spectrum. real, dimension(G%isd:G%ied,G%jsd:G%jed,NAngle), & intent(inout) :: En !< The internal gravity wave energy density as a - !! function of space and angular resolution, - !! in J m-2 radian-1. + !! function of space and angular resolution + !! [J m-2 radian-1]. type(int_tide_CS), pointer :: CS !< The control structure returned by a !! previous call to int_tide_init. type(loop_bounds_type), intent(in) :: LB !< A structure with the active energy loop bounds. @@ -1819,7 +1816,7 @@ subroutine correct_halo_rotation(En, test, G, NAngle) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(:,:,:,:,:), intent(inout) :: En !< The internal gravity wave energy density as a !! function of space, angular orientation, frequency, - !! and vertical mode, in J m-2 radian-1. + !! and vertical mode [J m-2 radian-1]. real, dimension(SZI_(G),SZJ_(G),2), & intent(in) :: test !< An x-unit vector that has been passed through !! the halo updates, to enable the rotation of the diff --git a/src/parameterizations/lateral/MOM_lateral_mixing_coeffs.F90 b/src/parameterizations/lateral/MOM_lateral_mixing_coeffs.F90 index 4963ba4bf0..3f250bc935 100644 --- a/src/parameterizations/lateral/MOM_lateral_mixing_coeffs.F90 +++ b/src/parameterizations/lateral/MOM_lateral_mixing_coeffs.F90 @@ -56,11 +56,11 @@ module MOM_lateral_mixing_coeffs logical :: calculate_Eady_growth_rate !< If true, calculate all the Eady growth rate. !! This parameter is set depending on other parameters. real, dimension(:,:), pointer :: & - SN_u => NULL(), & !< S*N at u-points (s^-1) - SN_v => NULL(), & !< S*N at v-points (s^-1) - L2u => NULL(), & !< Length scale^2 at u-points (m^2) - L2v => NULL(), & !< Length scale^2 at v-points (m^2) - cg1 => NULL(), & !< The first baroclinic gravity wave speed in m s-1. + SN_u => NULL(), & !< S*N at u-points [s-1] + SN_v => NULL(), & !< S*N at v-points [s-1] + L2u => NULL(), & !< Length scale^2 at u-points [m2] + L2v => NULL(), & !< Length scale^2 at v-points [m2] + cg1 => NULL(), & !< The first baroclinic gravity wave speed [m s-1]. Res_fn_h => NULL(), & !< Non-dimensional function of the ratio the first baroclinic !! deformation radius to the grid spacing at h points. Res_fn_q => NULL(), & !< Non-dimensional function of the ratio the first baroclinic @@ -78,19 +78,19 @@ module MOM_lateral_mixing_coeffs beta_dx2_v => NULL(), & !< The magnitude of the gradient of the Coriolis parameter !! times the grid spacing squared at v points. f2_dx2_h => NULL(), & !< The Coriolis parameter squared times the grid - !! spacing squared at h, in m2 s-2. + !! spacing squared at h [m-2 s-2]. f2_dx2_q => NULL(), & !< The Coriolis parameter squared times the grid - !! spacing squared at q, in m2 s-2. + !! spacing squared at q [m-2 s-2]. f2_dx2_u => NULL(), & !< The Coriolis parameter squared times the grid - !! spacing squared at u, in m2 s-2. + !! spacing squared at u [m-2 s-2]. f2_dx2_v => NULL(), & !< The Coriolis parameter squared times the grid - !! spacing squared at v, in m2 s-2. - Rd_dx_h => NULL() !< Deformation radius over grid spacing (non-dim.) + !! spacing squared at v [m-2 s-2]. + Rd_dx_h => NULL() !< Deformation radius over grid spacing [nondim] real, dimension(:,:,:), pointer :: & - slope_x => NULL(), & !< Zonal isopycnal slope (non-dimensional) - slope_y => NULL(), & !< Meridional isopycnal slope (non-dimensional) - ebt_struct => NULL() !< Vertical structure function to scale diffusivities with (non-dim) + slope_x => NULL(), & !< Zonal isopycnal slope [nondim] + slope_y => NULL(), & !< Meridional isopycnal slope [nondim] + ebt_struct => NULL() !< Vertical structure function to scale diffusivities with [nondim] ! Parameters integer :: VarMix_Ktop !< Top layer to start downward integrals @@ -101,14 +101,14 @@ module MOM_lateral_mixing_coeffs real :: Res_coef_visc !< A non-dimensional number that determines the function !! of resolution, used for lateral viscosity, as: !! F = 1 / (1 + (Res_coef_visc*Ld/dx)^Res_fn_power) - real :: kappa_smooth !< A diffusivity for smoothing T/S in vanished layers (m2/s) + real :: kappa_smooth !< A diffusivity for smoothing T/S in vanished layers [m2 s-1] integer :: Res_fn_power_khth !< The power of dx/Ld in the KhTh resolution function. Any !! positive integer power may be used, but even powers !! and especially 2 are coded to be more efficient. integer :: Res_fn_power_visc !< The power of dx/Ld in the Kh resolution function. Any !! positive integer power may be used, but even powers !! and especially 2 are coded to be more efficient. - real :: Visbeck_S_max !< Upper bound on slope used in Eady growth rate (nondim). + real :: Visbeck_S_max !< Upper bound on slope used in Eady growth rate [nondim]. ! Diagnostics !>@{ @@ -132,15 +132,15 @@ module MOM_lateral_mixing_coeffs !> Calculates and stores the non-dimensional resolution functions subroutine calc_resoln_function(h, tv, G, GV, US, CS) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(VarMix_CS), pointer :: CS !< Variable mixing coefficients ! Local variables - real :: cg1_q ! The gravity wave speed interpolated to q points, in m s-1. - real :: cg1_u ! The gravity wave speed interpolated to u points, in m s-1. - real :: cg1_v ! The gravity wave speed interpolated to v points, in m s-1. + real :: cg1_q ! The gravity wave speed interpolated to q points [m s-1]. + real :: cg1_u ! The gravity wave speed interpolated to u points [m s-1]. + real :: cg1_v ! The gravity wave speed interpolated to v points [m s-1]. real :: dx_term integer :: power_2 integer :: is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz @@ -174,7 +174,7 @@ subroutine calc_resoln_function(h, tv, G, GV, US, CS) endif ! Calculate and store the ratio between deformation radius and grid-spacing - ! at h-points (non-dimensional). + ! at h-points [nondim]. if (CS%calculate_rd_dx) then if (.not. associated(CS%Rd_dx_h)) call MOM_error(FATAL, & "calc_resoln_function: %Rd_dx_h is not associated with calculate_rd_dx.") @@ -382,15 +382,15 @@ subroutine calc_slope_functions(h, tv, dt, G, GV, US, CS) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables - real, intent(in) :: dt !< Time increment (s) + real, intent(in) :: dt !< Time increment [s] type(VarMix_CS), pointer :: CS !< Variable mixing coefficients ! Local variables real, dimension(SZI_(G), SZJ_(G), SZK_(G)+1) :: & - e ! The interface heights relative to mean sea level, in m. - real, dimension(SZIB_(G), SZJ_(G), SZK_(G)+1) :: N2_u ! Square of Brunt-Vaisala freq at u-points, in s-2 - real, dimension(SZI_(G), SZJB_(G), SZK_(G)+1) :: N2_v ! Square of Brunt-Vaisala freq at v-points, in s-2 + e ! The interface heights relative to mean sea level [Z ~> m]. + real, dimension(SZIB_(G), SZJ_(G), SZK_(G)+1) :: N2_u ! Square of Brunt-Vaisala freq at u-points [s-2] + real, dimension(SZI_(G), SZJB_(G), SZK_(G)+1) :: N2_v ! Square of Brunt-Vaisala freq at v-points [s-2] if (.not. associated(CS)) call MOM_error(FATAL, "MOM_lateral_mixing_coeffs.F90, calc_slope_functions:"//& "Module must be initialized before it is used.") @@ -423,19 +423,18 @@ end subroutine calc_slope_functions subroutine calc_Visbeck_coeffs(h, slope_x, slope_y, N2_u, N2_v, G, GV, CS) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(in) :: slope_x !< Zonal isoneutral slope - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(in) :: N2_u !< Brunt-Vaisala frequency at u-points (1/s2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(in) :: N2_u !< Brunt-Vaisala frequency at u-points [s-2] real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(in) :: slope_y !< Meridional isoneutral slope - real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(in) :: N2_v !< Brunt-Vaisala frequency at v-points (1/s2) + real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(in) :: N2_v !< Brunt-Vaisala frequency at v-points [s-2] type(VarMix_CS), pointer :: CS !< Variable mixing coefficients ! Local variables - real :: Khth_Loc ! Locally calculated thickness mixing coefficient (m2/s) - real :: S2 ! Interface slope squared (non-dim) - real :: N2 ! Brunt-Vaisala frequency (1/s) - real :: Hup, Hdn ! Thickness from above, below (m or kg m-2) - real :: H_geom ! The geometric mean of Hup*Hdn, in m or kg m-2. + real :: S2 ! Interface slope squared [nondim] + real :: N2 ! Brunt-Vaisala frequency [s-1] + real :: Hup, Hdn ! Thickness from above, below [H ~> m or kg m-2] + real :: H_geom ! The geometric mean of Hup*Hdn [H ~> m or kg m-2]. integer :: is, ie, js, je, nz integer :: i, j, k, kb_max real :: S2max, wNE, wSE, wSW, wNW @@ -575,27 +574,26 @@ end subroutine calc_Visbeck_coeffs !! interface positions only, not accounting for density variations. subroutine calc_slope_functions_using_just_e(h, G, GV, US, CS, e, calculate_slopes) type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(VarMix_CS), pointer :: CS !< Variable mixing coefficients - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface position (m) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface position [Z ~> m] logical, intent(in) :: calculate_slopes !< If true, calculate slopes internally !! otherwise use slopes stored in CS ! Local variables - real :: E_x(SZIB_(G), SZJ_(G)) ! X-slope of interface at u points (for diagnostics) - real :: E_y(SZI_(G), SZJB_(G)) ! Y-slope of interface at v points (for diagnostics) - real :: Khth_Loc ! Locally calculated thickness mixing coefficient (m2/s) - real :: H_cutoff ! Local estimate of a minimum thickness for masking (m) + real :: E_x(SZIB_(G), SZJ_(G)) ! X-slope of interface at u points [nondim] (for diagnostics) + real :: E_y(SZI_(G), SZJB_(G)) ! Y-slope of interface at v points [nondim] (for diagnostics) + real :: H_cutoff ! Local estimate of a minimum thickness for masking [H ~> m or kg m-2] real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: S2 ! Interface slope squared (non-dim) - real :: N2 ! Brunt-Vaisala frequency (1/s) - real :: Hup, Hdn ! Thickness from above, below (m or kg m-2) - real :: H_geom ! The geometric mean of Hup*Hdn, in m or kg m-2. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: S2 ! Interface slope squared [nondim] + real :: N2 ! Brunt-Vaisala frequency [s-1] + real :: Hup, Hdn ! Thickness from above, below [H ~> m or kg m-2] + real :: H_geom ! The geometric mean of Hup*Hdn [H ~> m or kg m-2]. real :: Z_to_L ! A conversion factor between from units for e to the ! units for lateral distances. - real :: one_meter ! One meter in thickness units of m or kg m-2. + real :: one_meter ! One meter in thickness units [H ~> m or kg m-2]. integer :: is, ie, js, je, nz integer :: i, j, k, kb_max real :: SN_u_local(SZIB_(G), SZJ_(G),SZK_(G)) @@ -722,7 +720,7 @@ subroutine VarMix_init(Time, G, GV, US, param_file, diag, CS) real :: KhTr_Slope_Cff, KhTh_Slope_Cff, oneOrTwo, N2_filter_depth real :: KhTr_passivity_coeff real, parameter :: absurdly_small_freq2 = 1e-34 ! A miniscule frequency - ! squared that is used to avoid division by 0, in s-2. This + ! squared that is used to avoid division by 0 [s-2]. This ! value is roughly (pi / (the age of the universe) )^2. logical :: Gill_equatorial_Ld, use_FGNV_streamfn, use_MEKE, in_use real :: MLE_front_length diff --git a/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 b/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 index 55c906ae26..d2a1abb730 100644 --- a/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 +++ b/src/parameterizations/lateral/MOM_mixed_layer_restrat.F90 @@ -29,38 +29,41 @@ module MOM_mixed_layer_restrat public mixedlayer_restrat_init public mixedlayer_restrat_register_restarts +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for mom_mixed_layer_restrat type, public :: mixedlayer_restrat_CS ; private - real :: ml_restrat_coef !< A non-dimensional factor by which the - !! instability is enhanced over what would be - !! predicted based on the resolved gradients. This - !! increases with grid spacing^2, up to something + real :: ml_restrat_coef !< A non-dimensional factor by which the instability is enhanced + !! over what would be predicted based on the resolved gradients + !! [nondim]. This increases with grid spacing^2, up to something !! of order 500. - real :: ml_restrat_coef2 !< As for ml_restrat_coef but using the slow filtered MLD. - real :: front_length !< If non-zero, is the frontal-length scale used to calculate the + real :: ml_restrat_coef2 !< As for ml_restrat_coef but using the slow filtered MLD [nondim]. + real :: front_length !< If non-zero, is the frontal-length scale [m] used to calculate the !! upscaling of buoyancy gradients that is otherwise represented !! by the parameter FOX_KEMPER_ML_RESTRAT_COEF. If MLE_FRONT_LENGTH is !! non-zero, it is recommended to set FOX_KEMPER_ML_RESTRAT_COEF=1.0. logical :: MLE_use_PBL_MLD !< If true, use the MLD provided by the PBL parameterization. !! if false, MLE will calculate a MLD based on a density difference !! based on the parameter MLE_DENSITY_DIFF. - real :: MLE_MLD_decay_time !< Time-scale to use in a running-mean when MLD is retreating (s). - real :: MLE_MLD_decay_time2 !< Time-scale to use in a running-mean when filtered MLD is retreating (s). - real :: MLE_density_diff !< Density difference used in detecting mixed-layer - !! depth (kg/m3). + real :: MLE_MLD_decay_time !< Time-scale to use in a running-mean when MLD is retreating [s]. + real :: MLE_MLD_decay_time2 !< Time-scale to use in a running-mean when filtered MLD is retreating [s]. + real :: MLE_density_diff !< Density difference used in detecting mixed-layer depth [kgm-3]. real :: MLE_tail_dh !< Fraction by which to extend the mixed-layer restratification !! depth used for a smoother stream function at the base of - !! the mixed-layer. - real :: MLE_MLD_stretch !< A scaling coefficient for stretching/shrinking the MLD - !! used in the MLE scheme. This simply multiplies MLD wherever used. + !! the mixed-layer [nondim]. + real :: MLE_MLD_stretch !< A scaling coefficient for stretching/shrinking the MLD used in + !! the MLE scheme [nondim]. This simply multiplies MLD wherever used. logical :: MLE_use_MLD_ave_bug !< If true, do not account for MLD mismatch to interface positions. logical :: debug = .false. !< If true, calculate checksums of fields for debugging. type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the !! timing of diagnostic output. real, dimension(:,:), pointer :: & - MLD_filtered => NULL(), & !< Time-filtered MLD (H units) - MLD_filtered_slow => NULL() !< Slower time-filtered MLD (H units) + MLD_filtered => NULL(), & !< Time-filtered MLD [H ~> m or kg m-2] + MLD_filtered_slow => NULL() !< Slower time-filtered MLD [H ~> m or kg m-2] !>@{ !! Diagnostic identifier @@ -89,14 +92,16 @@ subroutine mixedlayer_restrat(h, uhtr, vhtr, tv, forces, dt, MLD, VarMix, G, GV, type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness (H units = m or kg/m2) - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux (m3 or kg) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux (m3 or kg) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux + !! [H m2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux + !! [H m2 ~> m3 or kg] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables structure type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces - real, intent(in) :: dt !< Time increment (sec) + real, intent(in) :: dt !< Time increment [s] real, dimension(:,:), pointer :: MLD !< Mixed layer depth provided by the - !! PBL scheme (H units) + !! PBL scheme [H ~> m or kg m-2] type(VarMix_CS), pointer :: VarMix !< Container for derived fields type(mixedlayer_restrat_CS), pointer :: CS !< Module control structure @@ -117,61 +122,61 @@ subroutine mixedlayer_restrat_general(h, uhtr, vhtr, tv, forces, dt, MLD_in, Var type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness (H units = m or kg/m2) - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux (m3 or kg) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux (m3 or kg) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux + !! [H m2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux + !! [H m2 ~> m3 or kg] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables structure type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces - real, intent(in) :: dt !< Time increment (sec) + real, intent(in) :: dt !< Time increment [s] real, dimension(:,:), pointer :: MLD_in !< Mixed layer depth provided by the - !! PBL scheme, in m (not H) + !! PBL scheme [m] (not H) type(VarMix_CS), pointer :: VarMix !< Container for derived fields type(mixedlayer_restrat_CS), pointer :: CS !< Module control structure ! Local variables - real :: uhml(SZIB_(G),SZJ_(G),SZK_(G)) ! zonal mixed layer transport (m3/s or kg/s) - real :: vhml(SZI_(G),SZJB_(G),SZK_(G)) ! merid mixed layer transport (m3/s or kg/s) + real :: uhml(SZIB_(G),SZJ_(G),SZK_(G)) ! zonal mixed layer transport [H m2 s-1 ~> m3 s-1 or kg s-1] + real :: vhml(SZI_(G),SZJB_(G),SZK_(G)) ! merid mixed layer transport [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & h_avail ! The volume available for diffusion out of each face of each - ! sublayer of the mixed layer, divided by dt, in units - ! of H * m2 s-1 (i.e., m3 s-1 or kg s-1). + ! sublayer of the mixed layer, divided by dt [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJ_(G)) :: & - MLD_fast, & ! Mixed layer depth actually used in MLE restratification parameterization (H units) - htot_fast, & ! The sum of the thicknesses of layers in the mixed layer (H units) - Rml_av_fast, & ! g_Rho0 times the average mixed layer density (m s-2) - MLD_slow, & ! Mixed layer depth actually used in MLE restratification parameterization (H units) - htot_slow, & ! The sum of the thicknesses of layers in the mixed layer (H units) - Rml_av_slow ! g_Rho0 times the average mixed layer density (m s-2) - real :: g_Rho0 ! G_Earth/Rho0 (m5 Z-1 s-2 kg-1) - real :: rho_ml(SZI_(G)) ! Potential density relative to the surface (kg m-3) - real :: p0(SZI_(G)) ! A pressure of 0 (Pa) - - real :: h_vel ! htot interpolated onto velocity points in Z (not H). - real :: absf ! absolute value of f, interpolated to velocity points (s-1) - real :: u_star ! surface friction velocity, interpolated to velocity points (Z s-1) - real :: mom_mixrate ! rate at which momentum is homogenized within mixed layer (s-1) - real :: timescale ! mixing growth timescale (sec) - real :: h_neglect ! tiny thickness usually lost in roundoff so can be neglected (H units) - real :: dz_neglect ! A tiny thickness (in Z) that is usually lost in roundoff so can be neglected - real :: I4dt ! 1/(4 dt) (sec-1) - real :: Ihtot,Ihtot_slow! total mixed layer thickness + MLD_fast, & ! Mixed layer depth actually used in MLE restratification parameterization [H ~> m or kg m-2] + htot_fast, & ! The sum of the thicknesses of layers in the mixed layer [H ~> m or kg m-2] + Rml_av_fast, & ! g_Rho0 times the average mixed layer density [m s-2] + MLD_slow, & ! Mixed layer depth actually used in MLE restratification parameterization [H ~> m or kg m-2] + htot_slow, & ! The sum of the thicknesses of layers in the mixed layer [H ~> m or kg m-2] + Rml_av_slow ! g_Rho0 times the average mixed layer density [m s-2] + real :: g_Rho0 ! G_Earth/Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1] + real :: rho_ml(SZI_(G)) ! Potential density relative to the surface [kg m-3] + real :: p0(SZI_(G)) ! A pressure of 0 [Pa] + + real :: h_vel ! htot interpolated onto velocity points [Z ~> m] (not H). + real :: absf ! absolute value of f, interpolated to velocity points [s-1] + real :: u_star ! surface friction velocity, interpolated to velocity points [Z s-1 ~> m s-1]. + real :: mom_mixrate ! rate at which momentum is homogenized within mixed layer [s-1] + real :: timescale ! mixing growth timescale [s] + real :: h_neglect ! tiny thickness usually lost in roundoff so can be neglected [H ~> m or kg m-2] + real :: dz_neglect ! A tiny thickness that is usually lost in roundoff so can be neglected [Z ~> m] + real :: I4dt ! 1/(4 dt) [s-1] + real :: Ihtot,Ihtot_slow! Inverses of the total mixed layer thickness [H-1 ~> m-1 or m2 kg-1] real :: a(SZK_(G)) ! A non-dimensional value relating the overall flux ! magnitudes (uDml & vDml) to the realized flux in a ! layer. The vertical sum of a() through the pieces of ! the mixed layer must be 0. real :: b(SZK_(G)) ! As for a(k) but for the slow-filtered MLD real :: uDml(SZIB_(G)) ! The zonal and meridional volume fluxes in the upper - real :: vDml(SZI_(G)) ! half of the mixed layer in H m2 s-1 (m3 s-1 or kg s-1). + real :: vDml(SZI_(G)) ! half of the mixed layer [H m2 s-1 ~> m3 s-1 or kg s-1]. real :: uDml_slow(SZIB_(G)) ! The zonal and meridional volume fluxes in the upper - real :: vDml_slow(SZI_(G)) ! half of the mixed layer in H m2 s-1 (m3 s-1 or kg s-1). - real :: utimescale_diag(SZIB_(G),SZJ_(G)) ! restratification timescales - real :: vtimescale_diag(SZI_(G),SZJB_(G)) ! in the zonal and meridional - ! directions, in s, stored in 2-D - ! arrays for diagnostic purposes. + real :: vDml_slow(SZI_(G)) ! half of the mixed layer [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: utimescale_diag(SZIB_(G),SZJ_(G)) ! restratification timescales in the zonal and + real :: vtimescale_diag(SZI_(G),SZJB_(G)) ! meridional directions [s], stored in 2-D arrays + ! for diagnostic purposes. real :: uDml_diag(SZIB_(G),SZJ_(G)), vDml_diag(SZI_(G),SZJB_(G)) integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz real, dimension(SZI_(G)) :: rhoSurf, deltaRhoAtKm1, deltaRhoAtK - real, dimension(SZI_(G)) :: dK, dKm1 ! Depths of layer centers, in H. - real, dimension(SZI_(G)) :: pRef_MLD ! A reference pressure for calculating the mixed layer densities, in Pa. + real, dimension(SZI_(G)) :: dK, dKm1 ! Depths of layer centers [H ~> m or kg m-2]. + real, dimension(SZI_(G)) :: pRef_MLD ! A reference pressure for calculating the mixed layer densities [Pa]. real, dimension(SZI_(G)) :: rhoAtK, rho1, d1, pRef_N2 ! Used for N2 real :: aFac, bFac, ddRho real :: hAtVel, zpa, zpb, dh, res_scaling_fac, I_l_f @@ -546,47 +551,48 @@ subroutine mixedlayer_restrat_BML(h, uhtr, vhtr, tv, forces, dt, G, GV, US, CS) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness (H units = m or kg/m2) - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux (m3 or kg) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux (m3 or kg) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux + !! [H m2 ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux + !! [H m2 ~> m3 or kg] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamic variables structure type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces - real, intent(in) :: dt !< Time increment (sec) + real, intent(in) :: dt !< Time increment [s] type(mixedlayer_restrat_CS), pointer :: CS !< Module control structure ! Local variables - real :: uhml(SZIB_(G),SZJ_(G),SZK_(G)) ! zonal mixed layer transport (m3/s or kg/s) - real :: vhml(SZI_(G),SZJB_(G),SZK_(G)) ! merid mixed layer transport (m3/s or kg/s) + real :: uhml(SZIB_(G),SZJ_(G),SZK_(G)) ! zonal mixed layer transport [H m2 s-1 ~> m3 s-1 or kg s-1] + real :: vhml(SZI_(G),SZJB_(G),SZK_(G)) ! merid mixed layer transport [H m2 s-1 ~> m3 s-1 or kg s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & h_avail ! The volume available for diffusion out of each face of each - ! sublayer of the mixed layer, divided by dt, in units - ! of H m2 s-1 (i.e., m3 s-1 or kg s-1). + ! sublayer of the mixed layer, divided by dt [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZI_(G),SZJ_(G)) :: & - htot, & ! The sum of the thicknesses of layers in the mixed layer (H units) - Rml_av ! g_Rho0 times the average mixed layer density (m s-2) - real :: g_Rho0 ! G_Earth/Rho0 (m5 Z-1 s-2 kg-1) - real :: Rho0(SZI_(G)) ! Potential density relative to the surface (kg m-3) - real :: p0(SZI_(G)) ! A pressure of 0 (Pa) - - real :: h_vel ! htot interpolated onto velocity points (Z; not H) - real :: absf ! absolute value of f, interpolated to velocity points (s-1) - real :: u_star ! surface friction velocity, interpolated to velocity points (Z s-1) - real :: mom_mixrate ! rate at which momentum is homogenized within mixed layer (s-1) - real :: timescale ! mixing growth timescale (sec) - real :: h_neglect ! tiny thickness usually lost in roundoff and can be neglected (H units) - real :: dz_neglect ! tiny thickness (in Z) that usually lost in roundoff and can be neglected (meter) + htot, & ! The sum of the thicknesses of layers in the mixed layer [H ~> m or kg m-2] + Rml_av ! g_Rho0 times the average mixed layer density [m s-2] + real :: g_Rho0 ! G_Earth/Rho0 [m5 Z-1 s-2 kg-1 ~> m4 s-2 kg-1] + real :: Rho0(SZI_(G)) ! Potential density relative to the surface [kg m-3] + real :: p0(SZI_(G)) ! A pressure of 0 [Pa] + + real :: h_vel ! htot interpolated onto velocity points [Z ~> m]. (The units are not H.) + real :: absf ! absolute value of f, interpolated to velocity points [s-1] + real :: u_star ! surface friction velocity, interpolated to velocity points [Z s-1 ~> m s-1]. + real :: mom_mixrate ! rate at which momentum is homogenized within mixed layer [s-1] + real :: timescale ! mixing growth timescale [s] + real :: h_neglect ! tiny thickness usually lost in roundoff and can be neglected [H ~> m or kg m-2] + real :: dz_neglect ! tiny thickness that usually lost in roundoff and can be neglected [Z ~> m] real :: I4dt ! 1/(4 dt) - real :: I2htot ! Twice the total mixed layer thickness at velocity points (H units) - real :: z_topx2 ! depth of the top of a layer at velocity points (H units) - real :: hx2 ! layer thickness at velocity points (H units) + real :: I2htot ! Twice the total mixed layer thickness at velocity points [H ~> m or kg m-2] + real :: z_topx2 ! depth of the top of a layer at velocity points [H ~> m or kg m-2] + real :: hx2 ! layer thickness at velocity points [H ~> m or kg m-2] real :: a(SZK_(G)) ! A non-dimensional value relating the overall flux ! magnitudes (uDml & vDml) to the realized flux in a ! layer. The vertical sum of a() through the pieces of ! the mixed layer must be 0. real :: uDml(SZIB_(G)) ! The zonal and meridional volume fluxes in the upper - real :: vDml(SZI_(G)) ! half of the mixed layer in H m2 s-1 (m3 s-1 or kg s-1). + real :: vDml(SZI_(G)) ! half of the mixed layer [H m2 s-1 ~> m3 s-1 or kg s-1]. real :: utimescale_diag(SZIB_(G),SZJ_(G)) ! The restratification timescales real :: vtimescale_diag(SZI_(G),SZJB_(G)) ! in the zonal and meridional - ! directions (sec), stored in 2-D + ! directions [s], stored in 2-D ! arrays for diagnostic purposes. real :: uDml_diag(SZIB_(G),SZJ_(G)), vDml_diag(SZI_(G),SZJB_(G)) logical :: use_EOS ! If true, density is calculated from T & S using an equation of state. diff --git a/src/parameterizations/lateral/MOM_thickness_diffuse.F90 b/src/parameterizations/lateral/MOM_thickness_diffuse.F90 index f4e95bbb17..802e26a404 100644 --- a/src/parameterizations/lateral/MOM_thickness_diffuse.F90 +++ b/src/parameterizations/lateral/MOM_thickness_diffuse.F90 @@ -20,43 +20,48 @@ module MOM_thickness_diffuse implicit none ; private +#include + public thickness_diffuse, thickness_diffuse_init, thickness_diffuse_end public vert_fill_TS -#include +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. !> Control structure for thickness diffusion type, public :: thickness_diffuse_CS ; private - real :: Khth !< Background interface depth diffusivity (m2 s-1) - real :: Khth_Slope_Cff !< Slope dependence coefficient of Khth (m2 s-1) + real :: Khth !< Background interface depth diffusivity [m2 s-1] + real :: Khth_Slope_Cff !< Slope dependence coefficient of Khth [m2 s-1] real :: max_Khth_CFL !< Maximum value of the diffusive CFL for thickness diffusion - real :: Khth_Min !< Minimum value of Khth (m2 s-1) - real :: Khth_Max !< Maximum value of Khth (m2 s-1), or 0 for no max - real :: slope_max !< Slopes steeper than slope_max are limited in some way. + real :: Khth_Min !< Minimum value of Khth [m2 s-1] + real :: Khth_Max !< Maximum value of Khth [m2 s-1], or 0 for no max + real :: slope_max !< Slopes steeper than slope_max are limited in some way [nondim]. real :: kappa_smooth !< Vertical diffusivity used to interpolate more - !! sensible values of T & S into thin layers. + !! sensible values of T & S into thin layers [Z2 s-1 ~> m2 s-1]. logical :: thickness_diffuse !< If true, interfaces heights are diffused. logical :: use_FGNV_streamfn !< If true, use the streamfunction formulation of !! Ferrari et al., 2010, which effectively emphasizes !! graver vertical modes by smoothing in the vertical. real :: FGNV_scale !< A coefficient scaling the vertical smoothing term in the - !! Ferrari et al., 2010, streamfunction formulation. - real :: FGNV_c_min !< A minium wave speed used in the Ferrari et al., 2010, - !! streamfunction formulation (m s-1). + !! Ferrari et al., 2010, streamfunction formulation [nondim]. + real :: FGNV_c_min !< A minimum wave speed used in the Ferrari et al., 2010, + !! streamfunction formulation [m s-1]. real :: N2_floor !< A floor for Brunt-Vasaila frequency in the Ferrari et al., 2010, - !! streamfunction formulation (s-2). + !! streamfunction formulation [s-2]. logical :: detangle_interfaces !< If true, add 3-d structured interface height !! diffusivities to horizontally smooth jagged layers. real :: detangle_time !< If detangle_interfaces is true, this is the !! timescale over which maximally jagged grid-scale - !! thickness variations are suppressed. This must be + !! thickness variations are suppressed [s]. This must be !! longer than DT, or 0 (the default) to use DT. integer :: nkml !< number of layers within mixed layer logical :: debug !< write verbose checksums for debugging purposes type(diag_ctrl), pointer :: diag => NULL() !< structure used to regulate timing of diagnostics - real, pointer :: GMwork(:,:) => NULL() !< Work by thickness diffusivity (W m-2) - real, pointer :: diagSlopeX(:,:,:) => NULL() !< Diagnostic: zonal neutral slope (nondim) - real, pointer :: diagSlopeY(:,:,:) => NULL() !< Diagnostic: zonal neutral slope (nondim) + real, pointer :: GMwork(:,:) => NULL() !< Work by thickness diffusivity [W m-2] + real, pointer :: diagSlopeX(:,:,:) => NULL() !< Diagnostic: zonal neutral slope [nondim] + real, pointer :: diagSlopeY(:,:,:) => NULL() !< Diagnostic: zonal neutral slope [nondim] !>@{ !! Diagnostic identifier @@ -77,51 +82,53 @@ subroutine thickness_diffuse(h, uhtr, vhtr, tv, dt, G, GV, US, MEKE, VarMix, CDp type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness (m or kg/m2) - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux (m2 H) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux (m2 H) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Accumulated zonal mass flux + !! [m2 H ~> m3 or kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Accumulated meridional mass flux + !! [m2 H ~> m3 or kg] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure - real, intent(in) :: dt !< Time increment (s) + real, intent(in) :: dt !< Time increment [s] type(MEKE_type), pointer :: MEKE !< MEKE control structure type(VarMix_CS), pointer :: VarMix !< Variable mixing coefficients type(cont_diag_ptrs), intent(inout) :: CDp !< Diagnostics for the continuity equation type(thickness_diffuse_CS), pointer :: CS !< Control structure for thickness diffusion ! Local variables real :: e(SZI_(G), SZJ_(G), SZK_(G)+1) ! heights of interfaces, relative to mean - ! sea level, in Z, positive up. - real :: uhD(SZIB_(G), SZJ_(G), SZK_(G)) ! uhD & vhD are the diffusive u*h & - real :: vhD(SZI_(G), SZJB_(G), SZK_(G)) ! v*h fluxes (m2 H s-1) + ! sea level [Z ~> m], positive up. + real :: uhD(SZIB_(G), SZJ_(G), SZK_(G)) ! Diffusive u*h fluxes [m2 H s-1 ~> m3 s-1 or kg s-1] + real :: vhD(SZI_(G), SZJB_(G), SZK_(G)) ! Diffusive v*h fluxes [m2 H s-1 ~> m3 s-1 or kg s-1] real, dimension(SZIB_(G), SZJ_(G), SZK_(G)+1) :: & - KH_u, & ! interface height diffusivities in u-columns (m2 s-1) + KH_u, & ! interface height diffusivities in u-columns [m2 s-1] int_slope_u ! A nondimensional ratio from 0 to 1 that gives the relative ! weighting of the interface slopes to that calculated also ! using density gradients at u points. The physically correct ! slopes occur at 0, while 1 is used for numerical closures. real, dimension(SZI_(G), SZJB_(G), SZK_(G)+1) :: & - KH_v, & ! interface height diffusivities in v-columns (m2 s-1) + KH_v, & ! interface height diffusivities in v-columns [m2 s-1] int_slope_v ! A nondimensional ratio from 0 to 1 that gives the relative ! weighting of the interface slopes to that calculated also ! using density gradients at v points. The physically correct ! slopes occur at 0, while 1 is used for numerical closures. real, dimension(SZI_(G), SZJ_(G), SZK_(G)) :: & - KH_t ! diagnosed diffusivity at tracer points (m^2/s) + KH_t ! diagnosed diffusivity at tracer points [m2 s-1] real, dimension(SZIB_(G), SZJ_(G)) :: & - KH_u_CFL ! The maximum stable interface height diffusivity at u grid points (m2 s-1) + KH_u_CFL ! The maximum stable interface height diffusivity at u grid points [m2 s-1] real, dimension(SZI_(G), SZJB_(G)) :: & - KH_v_CFL ! The maximum stable interface height diffusivity at v grid points (m2 s-1) + KH_v_CFL ! The maximum stable interface height diffusivity at v grid points [m2 s-1] real :: Khth_Loc_u(SZIB_(G), SZJ_(G)) - real :: Khth_Loc(SZIB_(G), SZJB_(G)) ! locally calculated thickness diffusivity (m2/s) + real :: Khth_Loc(SZIB_(G), SZJB_(G)) ! locally calculated thickness diffusivity [m2 s-1] real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real, dimension(:,:), pointer :: cg1 => null() !< Wave speed (m/s) + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real, dimension(:,:), pointer :: cg1 => null() !< Wave speed [m s-1] logical :: use_VarMix, Resoln_scaled, use_stored_slopes, khth_use_ebt_struct integer :: i, j, k, is, ie, js, je, nz - real :: hu(SZI_(G), SZJ_(G)) ! u-thickness (H) - real :: hv(SZI_(G), SZJ_(G)) ! v-thickness (H) - real :: KH_u_lay(SZI_(G), SZJ_(G)) ! layer ave thickness diffusivities (m2/sec) - real :: KH_v_lay(SZI_(G), SZJ_(G)) ! layer ave thickness diffusivities (m2/sec) + real :: hu(SZI_(G), SZJ_(G)) ! u-thickness [H ~> m or kg m-2] + real :: hv(SZI_(G), SZJ_(G)) ! v-thickness [H ~> m or kg m-2] + real :: KH_u_lay(SZI_(G), SZJ_(G)) ! layer ave thickness diffusivities [m2 s-1] + real :: KH_v_lay(SZI_(G), SZJ_(G)) ! layer ave thickness diffusivities [m2 s-1] if (.not. associated(CS)) call MOM_error(FATAL, "MOM_thickness_diffuse:"// & "Module must be initialized before it is used.") @@ -161,7 +168,7 @@ subroutine thickness_diffuse(h, uhtr, vhtr, tv, dt, G, GV, US, MEKE, VarMix, CDp (dt*(G%IdxCv(i,J)*G%IdxCv(i,J) + G%IdyCv(i,J)*G%IdyCv(i,J))) enddo ; enddo - ! Calculates interface heights, e, in m. + ! Calculates interface heights, e, in [Z ~> m]. call find_eta(h, tv, G, GV, US, e, halo_size=1) ! Set the diffusivities. @@ -334,7 +341,7 @@ subroutine thickness_diffuse(h, uhtr, vhtr, tv, dt, G, GV, US, MEKE, VarMix, CDp ! Diagnose diffusivity at T-cell point. Do simple average, rather than ! thickness-weighted average, in order that KH_t is depth-independent ! in the case where KH_u and KH_v are depth independent. Otherwise, - ! if use thickess weighted average, the variations of thickness with + ! if use thickness weighted average, the variations of thickness with ! depth will place a spurious depth dependence to the diagnosed KH_t. if (CS%id_KH_t > 0 .or. CS%id_KH_t1 > 0) then do k=1,nz @@ -403,18 +410,20 @@ subroutine thickness_diffuse_full(h, e, Kh_u, Kh_v, tv, uhD, vhD, cg1, dt, G, GV type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness in H (m or kg/m2) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface positions (Z) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface positions [Z ~> m] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(in) :: Kh_u !< Thickness diffusivity on interfaces - !! at u points (m2/s) + !! at u points [m2 s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(in) :: Kh_v !< Thickness diffusivity on interfaces - !! at v points (m2/s) + !! at v points [m2 s-1] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: uhD !< Zonal mass fluxes (m2 H s-1) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: vhD !< Meridional mass fluxes (m2 H s-1) - real, dimension(:,:), pointer :: cg1 !< Wave speed (m/s) - real, intent(in) :: dt !< Time increment (s) - type(MEKE_type), pointer :: MEKE !< MEKE control structue + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: uhD !< Zonal mass fluxes + !! [H m2 s-1 ~> m3 s-1 or kg s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: vhD !< Meridional mass fluxes + !! [H m2 s-1 ~> m3 s-1 or kg s-1] + real, dimension(:,:), pointer :: cg1 !< Wave speed [m s-1] + real, intent(in) :: dt !< Time increment [s] + type(MEKE_type), pointer :: MEKE !< MEKE control structure type(thickness_diffuse_CS), pointer :: CS !< Control structure for thickness diffusion real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), optional, intent(in) :: int_slope_u !< Ratio that determine how much of !! the isopycnal slopes are taken directly from the @@ -429,84 +438,88 @@ subroutine thickness_diffuse_full(h, e, Kh_u, Kh_v, tv, uhD, vhD, cg1, dt, G, GV ! Local variables real, dimension(SZI_(G), SZJ_(G), SZK_(G)) :: & - T, & ! The temperature (or density) in C, with the values in + T, & ! The temperature (or density) [degC], with the values in ! in massless layers filled vertically by diffusion. - S, & ! The filled salinity, in PSU, with the values in + S, & ! The filled salinity [ppt], with the values in ! in massless layers filled vertically by diffusion. - Rho, & ! Density itself, when a nonlinear equation of state is + Rho, & ! Density itself [kg m-3], when a nonlinear equation of state is ! not in use. h_avail, & ! The mass available for diffusion out of each face, divided - ! by dt, in H m2 s-1. + ! by dt [H m2 s-1 ~> m3 s-1 or kg s-1]. h_frac ! The fraction of the mass in the column above the bottom - ! interface of a layer that is within a layer, ND. 0 m3 s-1 or kg s-1]. real, dimension(SZIB_(G)) :: & - drho_dT_u, & ! The derivatives of density with temperature and - drho_dS_u ! salinity at u points, in kg m-3 K-1 and kg m-3 psu-1. + drho_dT_u, & ! The derivative of density with temperature at u points [kg m-3 degC-1] + drho_dS_u ! The derivative of density with salinity at u points [kg m-3 ppt-1]. real, dimension(SZI_(G)) :: & - drho_dT_v, & ! The derivatives of density with temperature and - drho_dS_v ! salinity at v points, in kg m-3 K-1 and kg m-3 psu-1. - real :: uhtot(SZIB_(G), SZJ_(G)) ! The vertical sum of uhD, in m3 s-1. - real :: vhtot(SZI_(G), SZJB_(G)) ! The vertical sum of vhD, in m3 s-1. + drho_dT_v, & ! The derivative of density with temperature at v points [kg m-3 degC-1] + drho_dS_v ! The derivative of density with salinity at v points [kg m-3 ppt-1]. + real :: uhtot(SZIB_(G), SZJ_(G)) ! The vertical sum of uhD [H m2 s-1 ~> m3 s-1 or kg s-1]. + real :: vhtot(SZI_(G), SZJB_(G)) ! The vertical sum of vhD [H m2 s-1 ~> m3 s-1 or kg s-1]. real, dimension(SZIB_(G)) :: & - T_u, S_u, & ! Temperature, salinity, and pressure on the interface at - pres_u ! the u-point in the horizontal. + T_u, & ! Temperature on the interface at the u-point [degC]. + S_u, & ! Salinity on the interface at the u-point [ppt]. + pres_u ! Pressure on the interface at the u-point [Pa]. real, dimension(SZI_(G)) :: & - T_v, S_v, & ! Temperature, salinity, and pressure on the interface at - pres_v ! the v-point in the horizontal. + T_v, & ! Temperature on the interface at the v-point [degC]. + S_v, & ! Salinity on the interface at the v-point [ppt]. + pres_v ! Pressure on the interface at the v-point [Pa]. real :: Work_u(SZIB_(G), SZJ_(G)) ! The work being done by the thickness - real :: Work_v(SZI_(G), SZJB_(G)) ! diffusion integrated over a cell, in W. - real :: Work_h ! The work averaged over an h-cell in W m-2. - real :: I4dt ! 1 / 4 dt in s-1. + real :: Work_v(SZI_(G), SZJB_(G)) ! diffusion integrated over a cell [W]. + real :: Work_h ! The work averaged over an h-cell [W m-2]. + real :: I4dt ! 1 / 4 dt [s-1]. real :: drdiA, drdiB ! Along layer zonal- and meridional- potential density real :: drdjA, drdjB ! gradients in the layers above (A) and below(B) the - ! interface times the grid spacing, in kg m-3. - real :: drdkL, drdkR ! Vertical density differences across an interface, in kg m-3. - real :: drdi_u(SZIB_(G), SZK_(G)+1) ! Copy of drdi at u-points in kg m-3. - real :: drdj_v(SZI_(G), SZK_(G)+1) ! Copy of drdj at v-points in kg m-3. - real :: drdkDe_u(SZIB_(G), SZK_(G)+1) ! Lateral difference of product of drdk and e at u-points, in Z kg m-3. - real :: drdkDe_v(SZI_(G), SZK_(G)+1) ! Lateral difference of product of drdk and e at v-points, in Z kg m-3. - real :: hg2A, hg2B, hg2L, hg2R ! Squares of geometric mean thicknesses, in H2. - real :: haA, haB, haL, haR ! Arithmetic mean thicknesses in H. - real :: dzaL, dzaR ! Temporary thicknesses in Z. + ! interface times the grid spacing [kg m-3]. + real :: drdkL, drdkR ! Vertical density differences across an interface [kg m-3]. + real :: drdi_u(SZIB_(G), SZK_(G)+1) ! Copy of drdi at u-points [kg m-3]. + real :: drdj_v(SZI_(G), SZK_(G)+1) ! Copy of drdj at v-points [kg m-3]. + real :: drdkDe_u(SZIB_(G),SZK_(G)+1) ! Lateral difference of product of drdk and e at u-points + ! [Z kg m-3 ~> kg m-2]. + real :: drdkDe_v(SZI_(G),SZK_(G)+1) ! Lateral difference of product of drdk and e at v-points + ! [Z kg m-3 ~> kg m-2]. + real :: hg2A, hg2B, hg2L, hg2R ! Squares of geometric mean thicknesses [H2 ~> m2 or kg2 m-4]. + real :: haA, haB, haL, haR ! Arithmetic mean thicknesses [H ~> m or kg m-2]. + real :: dzaL, dzaR ! Temporary thicknesses [Z ~> m]. real :: wtA, wtB, wtL, wtR ! Unscaled weights, with various units. - real :: drdx, drdy ! Zonal and meridional density gradients, in kg m-4. - real :: drdz ! Vertical density gradient, in units of kg m-3 Z-1. - real :: h_harm ! Harmonic mean layer thickness, in H. - real :: c2_h_u(SZIB_(G), SZK_(G)+1) ! Wave speed squared divided by h at u-points, m2 Z-1 s-2. - real :: c2_h_v(SZI_(G), SZK_(G)+1) ! Wave speed squared divided by h at v-points, m2 Z-1 s-2. - real :: hN2_u(SZIB_(G), SZK_(G)+1) ! Thickness in m times N2 at interfaces above u-points, m2 Z-1 s-2. - real :: hN2_v(SZI_(G), SZK_(G)+1) ! Thickness in m times N2 at interfaces above v-points, m2 Z-1 s-2. - real :: Sfn_est ! Two preliminary estimates (before limiting) of the - ! overturning streamfunction, both in Z m2 s-1. - real :: Sfn_unlim_u(SZIB_(G), SZK_(G)+1) ! Streamfunction for u-points (Z m2 s-1) - real :: Sfn_unlim_v(SZI_(G), SZK_(G)+1) ! Streamfunction for v-points (Z m2 s-1) + real :: drdx, drdy ! Zonal and meridional density gradients [kg m-4]. + real :: drdz ! Vertical density gradient [kg m-3 Z-1 ~> kg m-4]. + real :: h_harm ! Harmonic mean layer thickness [H ~> m or kg m-2]. + real :: c2_h_u(SZIB_(G), SZK_(G)+1) ! Wave speed squared divided by h at u-points [m2 Z-1 s-2 ~> m s-2]. + real :: c2_h_v(SZI_(G), SZK_(G)+1) ! Wave speed squared divided by h at v-points [m2 Z-1 s-2 ~> m s-2]. + real :: hN2_u(SZIB_(G), SZK_(G)+1) ! Thickness in m times N2 at interfaces above u-points [m2 Z-1 s-2 ~> m s-2]. + real :: hN2_v(SZI_(G), SZK_(G)+1) ! Thickness in m times N2 at interfaces above v-points [m2 Z-1 s-2 ~> m s-2]. + real :: Sfn_est ! A preliminary estimate (before limiting) of the overturning + ! streamfunction [Z m2 s-1 ~> m3 s-1]. + real :: Sfn_unlim_u(SZIB_(G), SZK_(G)+1) ! Streamfunction for u-points [Z m2 s-1 ~> m3 s-1]. + real :: Sfn_unlim_v(SZI_(G), SZK_(G)+1) ! Streamfunction for v-points [Z m2 s-1 ~> m3 s-1]. real :: slope2_Ratio_u(SZIB_(G), SZK_(G)+1) ! The ratio of the slope squared to slope_max squared. real :: slope2_Ratio_v(SZI_(G), SZK_(G)+1) ! The ratio of the slope squared to slope_max squared. - real :: Sfn_in_h ! The overturning streamfunction, in H m2 s-1 (note units different from other Sfn vars). + real :: Sfn_in_h ! The overturning streamfunction [H m2 s-1 ~> m3 s-1 or kg s-1] (note that + ! the units are different from other Sfn vars). real :: Sfn_safe ! The streamfunction that goes linearly back to 0 at the surface. This is a - ! good thing to use when the slope is so large as to be meaningless (Z m2 s-1). + ! good thing to use when the slope is so large as to be meaningless [Z m2 s-1 ~> m3 s-1]. real :: Slope ! The slope of density surfaces, calculated in a way ! that is always between -1 and 1, nondimensional. - real :: mag_grad2 ! The squared magnitude of the 3-d density gradient, in kg2 m-8. + real :: mag_grad2 ! The squared magnitude of the 3-d density gradient [kg2 m-8]. real :: I_slope_max2 ! The inverse of slope_max squared, nondimensional. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: h_neglect2 ! h_neglect^2, in H2. - real :: dz_neglect ! A thickness in Z that is so small it is usually lost - ! in roundoff and can be neglected, in Z. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: h_neglect2 ! h_neglect^2 [H2 ~> m2 or kg2 m-4]. + real :: dz_neglect ! A thickness [Z ~> m], that is so small it is usually lost + ! in roundoff and can be neglected [Z ~> m]. real :: G_scale ! The gravitational acceleration times some unit conversion - ! factors, in m3 Z-1 H-1 s-2. + ! factors [m3 Z-1 H-1 s-2 ~> m s-2 or m4 kg-1 s-2]. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. logical :: find_work ! If true, find the change in energy due to the fluxes. - integer :: nk_linear ! The number of layers over which the streamfunction - ! goes to 0. - real :: G_rho0 ! g/Rho0 in m5 Z-1 s-2 + integer :: nk_linear ! The number of layers over which the streamfunction goes to 0. + real :: G_rho0 ! g/Rho0 [m5 Z-1 s-2 ~> m4 s-2]. real :: N2_floor ! A floor for N2 to avoid degeneracy in the elliptic solver - ! times unit conversion factors (s-2 m2 Z-2) + ! times unit conversion factors [s-2 m2 Z-2 ~> s-2] real, dimension(SZIB_(G), SZJ_(G), SZK_(G)+1) :: diag_sfn_x, diag_sfn_unlim_x ! Diagnostics real, dimension(SZI_(G), SZJB_(G), SZK_(G)+1) :: diag_sfn_y, diag_sfn_unlim_y ! Diagnostics logical :: present_int_slope_u, present_int_slope_v @@ -697,7 +710,7 @@ subroutine thickness_diffuse_full(h, e, Kh_u, Kh_v, tv, uhD, vhD, cg1, dt, G, GV endif if (CS%id_slope_x > 0) CS%diagSlopeX(I,j,k) = Slope - ! Estimate the streamfunction at each interface (m3 s-1). + ! Estimate the streamfunction at each interface [m3 s-1]. Sfn_unlim_u(I,K) = -((KH_u(I,j,K)*G%dy_Cu(I,j))*US%m_to_Z*Slope) ! Avoid moving dense water upslope from below the level of @@ -943,7 +956,7 @@ subroutine thickness_diffuse_full(h, e, Kh_u, Kh_v, tv, uhD, vhD, cg1, dt, G, GV endif if (CS%id_slope_y > 0) CS%diagSlopeY(I,j,k) = Slope - ! Estimate the streamfunction at each interface (m3 s-1). + ! Estimate the streamfunction at each interface [m3 s-1]. Sfn_unlim_v(i,K) = -((KH_v(i,J,K)*G%dx_Cv(i,J))*US%m_to_Z*Slope) ! Avoid moving dense water upslope from below the level of @@ -1151,9 +1164,9 @@ end subroutine thickness_diffuse_full !> Tridiagonal solver for streamfunction at interfaces subroutine streamfn_solver(nk, c2_h, hN2, sfn) integer, intent(in) :: nk !< Number of layers - real, dimension(nk), intent(in) :: c2_h !< Wave speed squared over thickness in layers (m s-2) - real, dimension(nk+1), intent(in) :: hN2 !< Thickness times N2 at interfaces (m s-2) - real, dimension(nk+1), intent(inout) :: sfn !< Streamfunction (Z m2 s-1 or arbitrary units) + real, dimension(nk), intent(in) :: c2_h !< Wave speed squared over thickness in layers [m s-2] + real, dimension(nk+1), intent(in) :: hN2 !< Thickness times N2 at interfaces [m s-2] + real, dimension(nk+1), intent(inout) :: sfn !< Streamfunction [Z m2 s-1 ~> m3 s-1] or arbitrary units !! On entry, equals diffusivity times slope. !! On exit, equals the streamfunction. ! Local variables @@ -1187,18 +1200,18 @@ subroutine add_detangling_Kh(h, e, Kh_u, Kh_v, KH_u_CFL, KH_v_CFL, tv, dt, G, GV type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (H) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface positions (Z) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: e !< Interface positions [Z ~> m] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Kh_u !< Thickness diffusivity on interfaces - !! at u points (m2/s) + !! at u points [m2 s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)+1), intent(inout) :: Kh_v !< Thickness diffusivity on interfaces - !! at v points (m2/s) + !! at v points [m2 s-1] real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: Kh_u_CFL !< Maximum stable thickness diffusivity - !! at u points (m2/s) + !! at u points [m2 s-1] real, dimension(SZI_(G),SZJB_(G)), intent(in) :: Kh_v_CFL !< Maximum stable thickness diffusivity - !! at v points (m2/s) + !! at v points [m2 s-1] type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure - real, intent(in) :: dt !< Time increment (s) + real, intent(in) :: dt !< Time increment [s] type(thickness_diffuse_CS), pointer :: CS !< Control structure for thickness diffusion real, dimension(SZIB_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: int_slope_u !< Ratio that determine how much of !! the isopycnal slopes are taken directly from the @@ -1211,17 +1224,17 @@ subroutine add_detangling_Kh(h, e, Kh_u, Kh_v, KH_u_CFL, KH_v_CFL, tv, dt, G, GV ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & de_top ! The distances between the top of a layer and the top of the - ! region where the detangling is applied, in H. + ! region where the detangling is applied [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: & Kh_lay_u ! The tentative interface height diffusivity for each layer at - ! u points, in m2 s-1. + ! u points [m2 s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: & Kh_lay_v ! The tentative interface height diffusivity for each layer at - ! v points, in m2 s-1. + ! v points [m2 s-1]. real, dimension(SZI_(G),SZJ_(G)) :: & de_bot ! The distances from the bottom of the region where the - ! detangling is applied, in H. - real :: h1, h2 ! The thinner and thicker surrounding thicknesses, in H, + ! detangling is applied [H ~> m or kg m-2]. + real :: h1, h2 ! The thinner and thicker surrounding thicknesses [H ~> m or kg m-2], ! with the thinner modified near the boundaries to mask out ! thickness variations due to topography, etc. real :: jag_Rat ! The nondimensional jaggedness ratio for a layer, going @@ -1229,45 +1242,45 @@ subroutine add_detangling_Kh(h, e, Kh_u, Kh_v, KH_u_CFL, KH_v_CFL, tv, dt, G, GV ! between the arithmetic and harmonic mean thicknesses ! normalized by the arithmetic mean thickness. real :: Kh_scale ! A ratio by which Kh_u_CFL is scaled for maximally jagged - ! layers, nondim. - real :: Kh_det ! The detangling diffusivity, in m2 s-1. + ! layers [nondim]. + real :: Kh_det ! The detangling diffusivity [m2 s-1]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: I_sl ! The absolute value of the larger in magnitude of the slopes ! above and below. real :: Rsl ! The ratio of the smaller magnitude slope to the larger - ! magnitude one, ND. 0 <= Rsl <1. - real :: IRsl ! The (limited) inverse of Rsl, ND. 1 < IRsl <= 1e9. + ! magnitude one [nondim]. 0 <= Rsl <1. + real :: IRsl ! The (limited) inverse of Rsl [nondim]. 1 < IRsl <= 1e9. real :: dH ! The thickness gradient divided by the damping timescale ! and the ratio of the face length to the adjacent cell - ! areas for comparability with the diffusivities, in m2 s-1. - real :: adH ! The absolute value of dH, in m2 s-1. + ! areas for comparability with the diffusivities [m2 s-1]. + real :: adH ! The absolute value of dH [m2 s-1]. real :: sign ! 1 or -1, with the same sign as the layer thickness gradient. - real :: sl_K ! The sign-corrected slope of the interface above, ND. - real :: sl_Kp1 ! The sign-corrected slope of the interface below, ND. - real :: I_sl_K ! The (limited) inverse of sl_K, ND. - real :: I_sl_Kp1 ! The (limited) inverse of sl_Kp1, ND. + real :: sl_K ! The sign-corrected slope of the interface above [nondim]. + real :: sl_Kp1 ! The sign-corrected slope of the interface below [nondim]. + real :: I_sl_K ! The (limited) inverse of sl_K [nondim]. + real :: I_sl_Kp1 ! The (limited) inverse of sl_Kp1 [nondim]. real :: I_4t ! A quarter of a unit conversion factor divided by - ! the damping timescale, in s-1. + ! the damping timescale [s-1]. real :: Fn_R ! A function of Rsl, such that Rsl < Fn_R < 1. real :: denom, I_denom ! A denominator and its inverse, various units. - real :: Kh_min ! A local floor on the diffusivity, in m2 s-1. - real :: Kh_max ! A local ceiling on the diffusivity, in m2 s-1. + real :: Kh_min ! A local floor on the diffusivity [m2 s-1]. + real :: Kh_max ! A local ceiling on the diffusivity [m2 s-1]. real :: wt1, wt2 ! Nondimensional weights. ! Variables used only in testing code. ! real, dimension(SZK_(G)) :: uh_here ! real, dimension(SZK_(G)+1) :: Sfn - real :: dKh ! An increment in the diffusivity, in m2 s-1. + real :: dKh ! An increment in the diffusivity [m2 s-1]. real, dimension(SZIB_(G),SZK_(G)+1) :: & - Kh_bg, & ! The background (floor) value of Kh, in m2 s-1. - Kh, & ! The tentative value of Kh, in m2 s-1. - Kh_detangle, & ! The detangling diffusivity that could be used, in m2 s-1. + Kh_bg, & ! The background (floor) value of Kh [m2 s-1]. + Kh, & ! The tentative value of Kh [m2 s-1]. + Kh_detangle, & ! The detangling diffusivity that could be used [m2 s-1]. Kh_min_max_p, & ! The smallest ceiling that can be placed on Kh(I,K) - ! based on the value of Kh(I,K+1), in m2 s-1. + ! based on the value of Kh(I,K+1) [m2 s-1]. Kh_min_max_m, & ! The smallest ceiling that can be placed on Kh(I,K) - ! based on the value of Kh(I,K-1), in m2 s-1. + ! based on the value of Kh(I,K-1) [m2 s-1]. ! The following are variables that define the relationships between ! successive values of Kh. ! Search for Kh that satisfy... @@ -1275,14 +1288,14 @@ subroutine add_detangling_Kh(h, e, Kh_u, Kh_v, KH_u_CFL, KH_v_CFL, tv, dt, G, GV ! Kh(I,K) >= Kh_min_p(I,K)*Kh(I,K+1) + Kh0_min_p(I,K) ! Kh(I,K) <= Kh_max_m(I,K)*Kh(I,K-1) + Kh0_max_m(I,K) ! Kh(I,K) <= Kh_max_p(I,K)*Kh(I,K+1) + Kh0_max_p(I,K) - Kh_min_m , & ! See above, ND. - Kh0_min_m , & ! See above, in m2 s-1. - Kh_max_m , & ! See above, ND. - Kh0_max_m, & ! See above, in m2 s-1. - Kh_min_p , & ! See above, ND. - Kh0_min_p , & ! See above, in m2 s-1. - Kh_max_p , & ! See above, ND. - Kh0_max_p ! See above, in m2 s-1. + Kh_min_m , & ! See above [nondim]. + Kh0_min_m , & ! See above [m2 s-1]. + Kh_max_m , & ! See above [nondim]. + Kh0_max_m, & ! See above [m2 s-1]. + Kh_min_p , & ! See above [nondim]. + Kh0_min_p , & ! See above [m2 s-1]. + Kh_max_p , & ! See above [nondim]. + Kh0_max_p ! See above [m2 s-1]. real, dimension(SZIB_(G)) :: & Kh_max_max ! The maximum diffusivity permitted in a column. logical, dimension(SZIB_(G)) :: & @@ -1605,31 +1618,27 @@ end subroutine add_detangling_Kh subroutine vert_fill_TS(h, T_in, S_in, kappa, dt, T_f, S_f, G, GV, halo_here) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness in H (m or kg/m2) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T_in !< Input temperature (C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S_in !< Input salinity (ppt) - real, intent(in) :: kappa !< Constant diffusivity to use (Z2/s) - real, intent(in) :: dt !< Time increment (s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T_f !< Filled temperature (C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S_f !< Filled salinity (ppt) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T_in !< Input temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S_in !< Input salinity [ppt] + real, intent(in) :: kappa !< Constant diffusivity to use [Z2 s-1 ~> m2 s-1] + real, intent(in) :: dt !< Time increment [s] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: T_f !< Filled temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: S_f !< Filled salinity [ppt] integer, optional, intent(in) :: halo_here !< Number of halo points to work on, !! 0 by default ! Local variables real :: ent(SZI_(G),SZK_(G)+1) ! The diffusive entrainment (kappa*dt)/dz - ! between layers in a timestep in m or kg m-2. + ! between layers in a timestep [H ~> m or kg m-2]. real :: b1(SZI_(G)), d1(SZI_(G)) ! b1, c1, and d1 are variables used by the real :: c1(SZI_(G),SZK_(G)) ! tridiagonal solver. - real :: kap_dt_x2 ! The product of 2*kappa*dt, converted to - ! the same units as h, in m2 or kg2 m-4. - real :: h0 ! A negligible thickness, in m or kg m-2, to - ! allow for zero thicknesses. - real :: h_neglect ! A thickness that is so small it is usually - ! lost in roundoff and can be neglected - ! (m for Bouss and kg/m^2 for non-Bouss). - ! 0 < h_neglect << h0. + real :: kap_dt_x2 ! The product of 2*kappa*dt [H2 ~> m2 or kg2 m-4]. + real :: h0 ! A negligible thickness to allow for zero + ! thicknesses [H ~> m or kg m-2]. + real :: h_neglect ! A thickness that is so small it is usually lost in roundoff + ! and can be neglected [H ~> m or kg m-2]. 0 < h_neglect << h0. real :: h_tr ! h_tr is h at tracer points with a tiny thickness - ! added to ensure positive definiteness - ! (m for Bouss, kg/m^2 for non-Bouss) + ! added to ensure positive definiteness [H ~> m or kg m-2]. integer :: i, j, k, is, ie, js, je, nz, halo halo=0 ; if (present(halo_here)) halo = max(halo_here,0) diff --git a/src/parameterizations/lateral/MOM_tidal_forcing.F90 b/src/parameterizations/lateral/MOM_tidal_forcing.F90 index a552bfe1ca..075c69ed65 100644 --- a/src/parameterizations/lateral/MOM_tidal_forcing.F90 +++ b/src/parameterizations/lateral/MOM_tidal_forcing.F90 @@ -22,7 +22,7 @@ module MOM_tidal_forcing integer, parameter :: MAX_CONSTITUENTS = 10 !< The maximum number of tidal !! constituents that could be used. -!> The control structure for the MOM_tidal_forcing mldule +!> The control structure for the MOM_tidal_forcing module type, public :: tidal_forcing_CS ; private logical :: use_sal_scalar !< If true, use the scalar approximation when !! calculating self-attraction and loading. @@ -36,10 +36,10 @@ module MOM_tidal_forcing !! and bottom geopotential anomalies. integer :: nc !< The number of tidal constituents in use. real, dimension(MAX_CONSTITUENTS) :: & - freq, & !< The frequency of a tidal constituent, in s-1. + freq, & !< The frequency of a tidal constituent [s-1]. phase0, & !< The phase of a tidal constituent at time 0, in radians. - amp, & !< The amplitude of a tidal constituent at time 0, in m. - love_no !< The Love number of a tidal constituent at time 0, ND. + amp, & !< The amplitude of a tidal constituent at time 0 [m]. + love_no !< The Love number of a tidal constituent at time 0 [nondim]. integer :: struct(MAX_CONSTITUENTS) !< An encoded spatial structure for each constituent character (len=16) :: const_name(MAX_CONSTITUENTS) !< The name of each constituent @@ -48,10 +48,10 @@ module MOM_tidal_forcing cos_struct => NULL(), & !< be associated with the astronomical forcing. cosphasesal => NULL(), & !< The cosine and sine of the phase of the sinphasesal => NULL(), & !< self-attraction and loading amphidromes. - ampsal => NULL(), & !< The amplitude of the SAL, in m. + ampsal => NULL(), & !< The amplitude of the SAL [m]. cosphase_prev => NULL(), & !< The cosine and sine of the phase of the sinphase_prev => NULL(), & !< amphidromes in the previous tidal solutions. - amp_prev => NULL() !< The amplitude of the previous tidal solution, in m. + amp_prev => NULL() !< The amplitude of the previous tidal solution [m]. end type tidal_forcing_CS integer :: id_clock_tides !< CPU clock for tides @@ -379,7 +379,7 @@ subroutine tidal_forcing_sensitivity(G, CS, deta_tidal_deta) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(tidal_forcing_CS), pointer :: CS !< The control structure returned by a previous call to tidal_forcing_init. real, intent(out) :: deta_tidal_deta !< The partial derivative of eta_tidal with - !! the local value of eta, nondim. + !! the local value of eta [nondim]. if (CS%USE_SAL_SCALAR .and. CS%USE_PREV_TIDES) then deta_tidal_deta = 2.0*CS%SAL_SCALAR @@ -400,14 +400,14 @@ subroutine calc_tidal_forcing(Time, eta, eta_tidal, G, CS, deta_tidal_deta, m_to type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(time_type), intent(in) :: Time !< The time for the caluculation. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: eta !< The sea surface height anomaly from - !! a time-mean geoid in depth units (Z). + !! a time-mean geoid [Z ~> m]. real, dimension(SZI_(G),SZJ_(G)), intent(out) :: eta_tidal !< The tidal forcing geopotential height - !! anomalies, in depth units (Z). + !! anomalies [Z ~> m]. type(tidal_forcing_CS), pointer :: CS !< The control structure returned by a !! previous call to tidal_forcing_init. real, optional, intent(out) :: deta_tidal_deta !< The partial derivative of !! eta_tidal with the local value of - !! eta, nondim. + !! eta [nondim]. real, optional, intent(in) :: m_to_Z !< A scaling factor from m to the units of eta. ! Local variables diff --git a/src/parameterizations/vertical/MOM_ALE_sponge.F90 b/src/parameterizations/vertical/MOM_ALE_sponge.F90 index b08e77e213..7678a4b799 100644 --- a/src/parameterizations/vertical/MOM_ALE_sponge.F90 +++ b/src/parameterizations/vertical/MOM_ALE_sponge.F90 @@ -56,6 +56,11 @@ module MOM_ALE_sponge public get_ALE_sponge_thicknesses, get_ALE_sponge_nz_data public initialize_ALE_sponge, apply_ALE_sponge, ALE_sponge_end, init_ALE_sponge_diags +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> A structure for creating arrays of pointers to 3D arrays with extra gridding information type :: p3d integer :: id !< id for FMS external time interpolator @@ -105,9 +110,9 @@ module MOM_ALE_sponge integer, pointer :: col_i_v(:) => NULL() !< Array of the i-indicies of each v-columns being damped. integer, pointer :: col_j_v(:) => NULL() !< Array of the j-indicies of each v-columns being damped. - real, pointer :: Iresttime_col(:) => NULL() !< The inverse restoring time of each tracer column. - real, pointer :: Iresttime_col_u(:) => NULL() !< The inverse restoring time of each u-column. - real, pointer :: Iresttime_col_v(:) => NULL() !< The inverse restoring time of each v-column. + real, pointer :: Iresttime_col(:) => NULL() !< The inverse restoring time of each tracer column [s-1]. + real, pointer :: Iresttime_col_u(:) => NULL() !< The inverse restoring time of each u-column [s-1]. + real, pointer :: Iresttime_col_v(:) => NULL() !< The inverse restoring time of each v-column [s-1]. type(p3d) :: var(MAX_FIELDS_) !< Pointers to the fields that are being damped. type(p2d) :: Ref_val(MAX_FIELDS_) !< The values to which the fields are damped. @@ -134,25 +139,25 @@ module MOM_ALE_sponge !! points are included in the sponges. It also stores the target interface heights. subroutine initialize_ALE_sponge_fixed(Iresttime, G, param_file, CS, data_h, nz_data) - type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure (in). - integer, intent(in) :: nz_data !< The total number of sponge input layers (in). - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Iresttime !< The inverse of the restoring time, in s-1 (in). + type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. + integer, intent(in) :: nz_data !< The total number of sponge input layers. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Iresttime !< The inverse of the restoring time [s-1]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file - !! to parse for model parameter values (in). + !! to parse for model parameter values. type(ALE_sponge_CS), pointer :: CS !< A pointer that is set to point to the control !! structure for this module (in/out). real, dimension(SZI_(G),SZJ_(G),nz_data), intent(in) :: data_h !< The thicknesses of the sponge - !! input layers, in thickness units (H). + !! input layers [H ~> m or kg m-2]. ! This include declares and sets the variable "version". #include "version_variable.h" character(len=40) :: mdl = "MOM_sponge" ! This module's name. logical :: use_sponge - real, allocatable, dimension(:,:,:) :: data_hu !< thickness at u points - real, allocatable, dimension(:,:,:) :: data_hv !< thickness at v points - real, allocatable, dimension(:,:) :: Iresttime_u !< inverse of the restoring time at u points, s-1 - real, allocatable, dimension(:,:) :: Iresttime_v !< inverse of the restoring time at v points, s-1 + real, allocatable, dimension(:,:,:) :: data_hu !< thickness at u points [H ~> m or kg m-2] + real, allocatable, dimension(:,:,:) :: data_hv !< thickness at v points [H ~> m or kg m-2] + real, allocatable, dimension(:,:) :: Iresttime_u !< inverse of the restoring time at u points [s-1] + real, allocatable, dimension(:,:) :: Iresttime_v !< inverse of the restoring time at v points [s-1] logical :: bndExtrapolation = .true. ! If true, extrapolate boundaries integer :: i, j, k, col, total_sponge_cols, total_sponge_cols_u, total_sponge_cols_v character(len=10) :: remapScheme @@ -333,7 +338,7 @@ end function get_ALE_sponge_nz_data subroutine get_ALE_sponge_thicknesses(G, data_h, sponge_mask, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure (in). real, allocatable, dimension(:,:,:), & - intent(inout) :: data_h !< The thicknesses of the sponge input layers, in H. + intent(inout) :: data_h !< The thicknesses of the sponge input layers [H ~> m or kg m-2]. logical, dimension(SZI_(G),SZJ_(G)), & intent(out) :: sponge_mask !< A logical mask that is true where !! sponges are being applied. @@ -369,10 +374,10 @@ end subroutine get_ALE_sponge_thicknesses !! points are included in the sponges. subroutine initialize_ALE_sponge_varying(Iresttime, G, param_file, CS) - type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure (in). - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Iresttime !< The inverse of the restoring time, in s-1 (in). + type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Iresttime !< The inverse of the restoring time [s-1]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to parse - !! for model parameter values (in). + !! for model parameter values. type(ALE_sponge_CS), pointer :: CS !< A pointer that is set to point to the control !! structure for this module (in/out). @@ -382,8 +387,8 @@ subroutine initialize_ALE_sponge_varying(Iresttime, G, param_file, CS) #include "version_variable.h" character(len=40) :: mdl = "MOM_sponge" ! This module's name. logical :: use_sponge - real, allocatable, dimension(:,:) :: Iresttime_u !< inverse of the restoring time at u points, s-1 - real, allocatable, dimension(:,:) :: Iresttime_v !< inverse of the restoring time at v points, s-1 + real, allocatable, dimension(:,:) :: Iresttime_u !< inverse of the restoring time at u points [s-1] + real, allocatable, dimension(:,:) :: Iresttime_v !< inverse of the restoring time at v points [s-1] logical :: bndExtrapolation = .true. ! If true, extrapolate boundaries integer :: i, j, k, col, total_sponge_cols, total_sponge_cols_u, total_sponge_cols_v character(len=10) :: remapScheme @@ -597,7 +602,7 @@ subroutine set_up_ALE_sponge_field_varying(filename, fieldname, Time, G, GV, f_p ! Local variables real, allocatable, dimension(:,:,:) :: sp_val !< Field to be used in the sponge real, allocatable, dimension(:,:,:) :: mask_z !< Field mask for the sponge data - real, allocatable, dimension(:), target :: z_in, z_edges_in ! Heights in Z. + real, allocatable, dimension(:), target :: z_in, z_edges_in ! Heights [Z ~> m]. real :: missing_value integer :: j, k, col integer :: isd,ied,jsd,jed @@ -607,9 +612,9 @@ subroutine set_up_ALE_sponge_field_varying(filename, fieldname, Time, G, GV, f_p character(len=256) :: mesg ! String for error messages ! Local variables for ALE remapping - real, dimension(:), allocatable :: hsrc ! Source thicknesses in Z + real, dimension(:), allocatable :: hsrc ! Source thicknesses [Z ~> m]. real, dimension(:), allocatable :: tmpT1d - real :: zTopOfCell, zBottomOfCell ! Heights in Z + real :: zTopOfCell, zBottomOfCell ! Heights [Z ~> m]. type(remapping_CS) :: remapCS ! Remapping parameters and work arrays if (.not.associated(CS)) return @@ -841,15 +846,15 @@ subroutine apply_ALE_sponge(h, dt, G, GV, US, CS, Time) type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thickness, in H (in) - real, intent(in) :: dt !< The amount of time covered by this call, in s (in). + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] (in) + real, intent(in) :: dt !< The amount of time covered by this call [s]. type(ALE_sponge_CS), pointer :: CS !< A pointer to the control structure for this module !! that is set by a previous call to initialize_sponge (in). type(time_type), optional, intent(in) :: Time !< The current model date - real :: damp ! The timestep times the local damping coefficient. ND. - real :: I1pdamp ! I1pdamp is 1/(1 + damp). Nondimensional. - real :: Idt ! 1.0/dt, in s-1. + real :: damp ! The timestep times the local damping coefficient [nondim]. + real :: I1pdamp ! I1pdamp is 1/(1 + damp). [nondim]. + real :: Idt ! 1.0/dt [s-1]. real :: m_to_Z ! A unit conversion factor from m to Z. real, allocatable, dimension(:) :: tmp_val2 ! data values on the original grid real, dimension(SZK_(G)) :: tmp_val1 ! data values remapped to model grid diff --git a/src/parameterizations/vertical/MOM_CVMix_KPP.F90 b/src/parameterizations/vertical/MOM_CVMix_KPP.F90 index 67c4173b96..ef0e9504ac 100644 --- a/src/parameterizations/vertical/MOM_CVMix_KPP.F90 +++ b/src/parameterizations/vertical/MOM_CVMix_KPP.F90 @@ -80,10 +80,10 @@ module MOM_CVMix_KPP logical :: computeMoninObukhov !< If True, compute Monin-Obukhov limit for OBLdepth logical :: passiveMode !< If True, makes KPP passive meaning it does NOT alter the diffusivity real :: deepOBLoffset !< If non-zero, is a distance from the bottom that the OBL can not - !! penetrate through (m) - real :: minOBLdepth !< If non-zero, is a minimum depth for the OBL (m) - real :: surf_layer_ext !< Fraction of OBL depth considered in the surface layer (nondim) - real :: minVtsqr !< Min for the squared unresolved velocity used in Rib CVMix calculation (m2/s2) + !! penetrate through [m] + real :: minOBLdepth !< If non-zero, is a minimum depth for the OBL [m] + real :: surf_layer_ext !< Fraction of OBL depth considered in the surface layer [nondim] + real :: minVtsqr !< Min for the squared unresolved velocity used in Rib CVMix calculation [m2 s-2] logical :: fixedOBLdepth !< If True, will fix the OBL depth at fixedOBLdepth_value real :: fixedOBLdepth_value !< value for the fixed OBL depth when fixedOBLdepth==True. logical :: debug !< If True, calculate checksums and write debugging information @@ -101,7 +101,7 @@ module MOM_CVMix_KPP !! in the vicinity of vanished layers. ! smg: obsolete below logical :: correctSurfLayerAvg !< If true, applies a correction to the averaging of surface layer properties - real :: surfLayerDepth !< A guess at the depth of the surface layer (which should 0.1 of OBLdepth) (m) + real :: surfLayerDepth !< A guess at the depth of the surface layer (which should 0.1 of OBLdepth) [m] ! smg: obsolete above integer :: SW_METHOD !< Sets method for using shortwave radiation in surface buoyancy flux logical :: LT_K_Enhancement !< Flags if enhancing mixing coefficients due to LT @@ -143,25 +143,25 @@ module MOM_CVMix_KPP !!@} ! Diagnostics arrays - real, allocatable, dimension(:,:) :: OBLdepth !< Depth (positive) of OBL (m) - real, allocatable, dimension(:,:) :: OBLdepth_original !< Depth (positive) of OBL (m) without smoothing + real, allocatable, dimension(:,:) :: OBLdepth !< Depth (positive) of OBL [m] + real, allocatable, dimension(:,:) :: OBLdepth_original !< Depth (positive) of OBL [m] without smoothing real, allocatable, dimension(:,:) :: kOBL !< Level (+fraction) of OBL extent - real, allocatable, dimension(:,:) :: OBLdepthprev !< previous Depth (positive) of OBL (m) - real, allocatable, dimension(:,:,:) :: dRho !< Bulk difference in density (kg/m3) - real, allocatable, dimension(:,:,:) :: Uz2 !< Square of bulk difference in resolved velocity (m2/s2) + real, allocatable, dimension(:,:) :: OBLdepthprev !< previous Depth (positive) of OBL [m] + real, allocatable, dimension(:,:,:) :: dRho !< Bulk difference in density [kg m-3] + real, allocatable, dimension(:,:,:) :: Uz2 !< Square of bulk difference in resolved velocity [m2 s-2] real, allocatable, dimension(:,:,:) :: BulkRi !< Bulk Richardson number for each layer (dimensionless) real, allocatable, dimension(:,:,:) :: sigma !< Sigma coordinate (dimensionless) - real, allocatable, dimension(:,:,:) :: Ws !< Turbulent velocity scale for scalars (m/s) - real, allocatable, dimension(:,:,:) :: N !< Brunt-Vaisala frequency (1/s) - real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency (1/s2) - real, allocatable, dimension(:,:,:) :: Vt2 !< Unresolved squared turbulence velocity for bulk Ri (m2/s2) - real, allocatable, dimension(:,:,:) :: Kt_KPP !< Temp diffusivity from KPP (m2/s) - real, allocatable, dimension(:,:,:) :: Ks_KPP !< Scalar diffusivity from KPP (m2/s) - real, allocatable, dimension(:,:,:) :: Kv_KPP !< Viscosity due to KPP (m2/s) - real, allocatable, dimension(:,:) :: Tsurf !< Temperature of surface layer (C) - real, allocatable, dimension(:,:) :: Ssurf !< Salinity of surface layer (ppt) - real, allocatable, dimension(:,:) :: Usurf !< i-velocity of surface layer (m/s) - real, allocatable, dimension(:,:) :: Vsurf !< j-velocity of surface layer (m/s) + real, allocatable, dimension(:,:,:) :: Ws !< Turbulent velocity scale for scalars [m s-1] + real, allocatable, dimension(:,:,:) :: N !< Brunt-Vaisala frequency [s-1] + real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency [s-2] + real, allocatable, dimension(:,:,:) :: Vt2 !< Unresolved squared turbulence velocity for bulk Ri [m2 s-2] + real, allocatable, dimension(:,:,:) :: Kt_KPP !< Temp diffusivity from KPP [m2 s-1] + real, allocatable, dimension(:,:,:) :: Ks_KPP !< Scalar diffusivity from KPP [m2 s-1] + real, allocatable, dimension(:,:,:) :: Kv_KPP !< Viscosity due to KPP [m2 s-1] + real, allocatable, dimension(:,:) :: Tsurf !< Temperature of surface layer [degC] + real, allocatable, dimension(:,:) :: Ssurf !< Salinity of surface layer [ppt] + real, allocatable, dimension(:,:) :: Usurf !< i-velocity of surface layer [m s-1] + real, allocatable, dimension(:,:) :: Vsurf !< j-velocity of surface layer [m s-1] real, allocatable, dimension(:,:,:) :: EnhK !< Enhancement for mixing coefficient real, allocatable, dimension(:,:,:) :: EnhVt2 !< Enhancement for Vt2 @@ -586,30 +586,33 @@ subroutine KPP_calculate(CS, G, GV, US, h, uStar, & type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(wave_parameters_CS), optional, pointer :: Waves !< Wave CS - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses (units of H) - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: uStar !< Surface friction velocity (Z/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: buoyFlux !< Surface buoyancy flux (m2/s3) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Kt !< (in) Vertical diffusivity of heat w/o KPP (Z2/s) - !< (out) Vertical diffusivity including KPP (Z2/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Ks !< (in) Vertical diffusivity of salt w/o KPP (Z2/s) - !< (out) Vertical diffusivity including KPP (Z2/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Kv !< (in) Vertical viscosity w/o KPP (Z2/s) - !< (out) Vertical viscosity including KPP (Z2/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: nonLocalTransHeat !< Temp non-local transport (m/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: nonLocalTransScalar !< scalar non-local transport (m/s) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: uStar !< Surface friction velocity [Z s-1 ~> m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: buoyFlux !< Surface buoyancy flux [m2 s-3] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Kt !< (in) Vertical diffusivity of heat w/o KPP + !! (out) Vertical diffusivity including KPP + !! [Z2 s-1 ~> m2 s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Ks !< (in) Vertical diffusivity of salt w/o KPP + !! (out) Vertical diffusivity including KPP + !! [Z2 s-1 ~> m2 s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: Kv !< (in) Vertical viscosity w/o KPP + !! (out) Vertical viscosity including KPP + !! [Z2 s-1 ~> m2 s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: nonLocalTransHeat !< Temp non-local transport [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(inout) :: nonLocalTransScalar !< scalar non-local transport [m s-1] ! Local variables integer :: i, j, k ! Loop indices - real, dimension( G%ke ) :: cellHeight ! Cell center heights referenced to surface (m) (negative in ocean) - real, dimension( G%ke+1 ) :: iFaceHeight ! Interface heights referenced to surface (m) (negative in ocean) - real, dimension( G%ke+1, 2) :: Kdiffusivity ! Vertical diffusivity at interfaces (m2/s) - real, dimension( G%ke+1 ) :: Kviscosity ! Vertical viscosity at interfaces (m2/s) - real, dimension( G%ke+1, 2) :: nonLocalTrans ! Non-local transport for heat/salt at interfaces (non-dimensional) + real, dimension( G%ke ) :: cellHeight ! Cell center heights referenced to surface [m] (negative in ocean) + real, dimension( G%ke+1 ) :: iFaceHeight ! Interface heights referenced to surface [m] (negative in ocean) + real, dimension( G%ke+1, 2) :: Kdiffusivity ! Vertical diffusivity at interfaces [m2 s-1] + real, dimension( G%ke+1 ) :: Kviscosity ! Vertical viscosity at interfaces [m2 s-1] + real, dimension( G%ke+1, 2) :: nonLocalTrans ! Non-local transport for heat/salt at interfaces [nondim] real :: surfFricVel, surfBuoyFlux real :: sigma, sigmaRatio - real :: dh ! The local thickness used for calculating interface positions (m) - real :: hcorr ! A cumulative correction arising from inflation of vanished layers (m) + real :: dh ! The local thickness used for calculating interface positions [m] + real :: hcorr ! A cumulative correction arising from inflation of vanished layers [m] ! For Langmuir Calculations real :: LangEnhK ! Langmuir enhancement for mixing coefficient @@ -674,28 +677,28 @@ subroutine KPP_calculate(CS, G, GV, US, h, uStar, & ! If option "MatchBoth" is selected in CVMix, MOM should be capable of matching. if (.not. (CS%MatchTechnique == 'MatchBoth')) then - Kdiffusivity(:,:) = 0. ! Diffusivities for heat and salt (m2/s) - Kviscosity(:) = 0. ! Viscosity (m2/s) + Kdiffusivity(:,:) = 0. ! Diffusivities for heat and salt [m2 s-1] + Kviscosity(:) = 0. ! Viscosity [m2 s-1] else Kdiffusivity(:,1) = US%Z_to_m**2 * Kt(i,j,:) Kdiffusivity(:,2) = US%Z_to_m**2 * Ks(i,j,:) Kviscosity(:) = US%Z_to_m**2 * Kv(i,j,:) endif - call CVMix_coeffs_kpp(Kviscosity(:), & ! (inout) Total viscosity (m2/s) - Kdiffusivity(:,1), & ! (inout) Total heat diffusivity (m2/s) - Kdiffusivity(:,2), & ! (inout) Total salt diffusivity (m2/s) - iFaceHeight, & ! (in) Height of interfaces (m) - cellHeight, & ! (in) Height of level centers (m) - Kviscosity(:), & ! (in) Original viscosity (m2/s) - Kdiffusivity(:,1), & ! (in) Original heat diffusivity (m2/s) - Kdiffusivity(:,2), & ! (in) Original salt diffusivity (m2/s) - CS%OBLdepth(i,j), & ! (in) OBL depth (m) + call CVMix_coeffs_kpp(Kviscosity(:), & ! (inout) Total viscosity [m2 s-1] + Kdiffusivity(:,1), & ! (inout) Total heat diffusivity [m2 s-1] + Kdiffusivity(:,2), & ! (inout) Total salt diffusivity [m2 s-1] + iFaceHeight, & ! (in) Height of interfaces [m] + cellHeight, & ! (in) Height of level centers [m] + Kviscosity(:), & ! (in) Original viscosity [m2 s-1] + Kdiffusivity(:,1), & ! (in) Original heat diffusivity [m2 s-1] + Kdiffusivity(:,2), & ! (in) Original salt diffusivity [m2 s-1] + CS%OBLdepth(i,j), & ! (in) OBL depth [m] CS%kOBL(i,j), & ! (in) level (+fraction) of OBL extent - nonLocalTrans(:,1),& ! (out) Non-local heat transport (non-dimensional) - nonLocalTrans(:,2),& ! (out) Non-local salt transport (non-dimensional) - surfFricVel, & ! (in) Turbulent friction velocity at surface (m/s) - surfBuoyFlux, & ! (in) Buoyancy flux at surface (m2/s3) + nonLocalTrans(:,1),& ! (out) Non-local heat transport [nondim] + nonLocalTrans(:,2),& ! (out) Non-local salt transport [nondim] + surfFricVel, & ! (in) Turbulent friction velocity at surface [m s-1] + surfBuoyFlux, & ! (in) Buoyancy flux at surface [m2 s-3] G%ke, & ! (in) Number of levels to compute coeffs for G%ke, & ! (in) Number of levels in array shape CVMix_kpp_params_user=CS%KPP_params ) @@ -801,9 +804,9 @@ subroutine KPP_calculate(CS, G, GV, US, h, uStar, & !BGR Now computing VT2 above so can modify for LT ! therefore, don't repeat this operation here ! CS%Vt2(i,j,:) = CVmix_kpp_compute_unresolved_shear( & -! cellHeight(1:G%ke), & ! Depth of cell center (m) -! ws_cntr=Ws_1d, & ! Turbulent velocity scale profile, at centers (m/s) -! N_iface=CS%N(i,j,:), & ! Buoyancy frequency at interface (1/s) +! cellHeight(1:G%ke), & ! Depth of cell center [m] +! ws_cntr=Ws_1d, & ! Turbulent velocity scale profile, at centers [m s-1] +! N_iface=CS%N(i,j,:), & ! Buoyancy frequency at interface [s-1] ! CVmix_kpp_params_user=CS%KPP_params ) ! KPP parameters endif @@ -876,24 +879,24 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF type(ocean_grid_type), intent(inout) :: G !< Ocean grid type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses (units of H) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< potential/cons temp (deg C) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< Salinity (ppt) - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Velocity i-component (m/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Velocity j-component (m/s) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Temp !< potential/cons temp [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: Salt !< Salinity [ppt] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< Velocity i-component [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< Velocity j-component [m s-1] type(EOS_type), pointer :: EOS !< Equation of state - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: uStar !< Surface friction velocity (Z/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: buoyFlux !< Surface buoyancy flux (m2/s3) + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: uStar !< Surface friction velocity [Z s-1 ~> m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: buoyFlux !< Surface buoyancy flux [m2 s-3] type(wave_parameters_CS), optional, pointer :: Waves !< Wave CS ! Local variables integer :: i, j, k, km1 ! Loop indices - real, dimension( G%ke ) :: cellHeight ! Cell center heights referenced to surface (m) (negative in ocean) - real, dimension( G%ke+1 ) :: iFaceHeight ! Interface heights referenced to surface (m) (negative in ocean) - real, dimension( G%ke+1 ) :: N2_1d ! Brunt-Vaisala frequency squared, at interfaces (1/s2) - real, dimension( G%ke ) :: Ws_1d ! Profile of vertical velocity scale for scalars (m/s) + real, dimension( G%ke ) :: cellHeight ! Cell center heights referenced to surface [m] (negative in ocean) + real, dimension( G%ke+1 ) :: iFaceHeight ! Interface heights referenced to surface [m] (negative in ocean) + real, dimension( G%ke+1 ) :: N2_1d ! Brunt-Vaisala frequency squared, at interfaces [s-2] + real, dimension( G%ke ) :: Ws_1d ! Profile of vertical velocity scale for scalars [m s-1] real, dimension( G%ke ) :: deltaRho ! delta Rho in numerator of Bulk Ri number - real, dimension( G%ke ) :: deltaU2 ! square of delta U (shear) in denominator of Bulk Ri (m2/s2) + real, dimension( G%ke ) :: deltaU2 ! square of delta U (shear) in denominator of Bulk Ri [m2 s-2] real, dimension( G%ke ) :: surfBuoyFlux2 real, dimension( G%ke ) :: BulkRi_1d ! Bulk Richardson number for each layer @@ -906,16 +909,16 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF real :: surfFricVel, surfBuoyFlux, Coriolis real :: GoRho, pRef, rho1, rhoK, Uk, Vk, sigma, sigmaRatio - real :: zBottomMinusOffset ! Height of bottom plus a little bit (m) + real :: zBottomMinusOffset ! Height of bottom plus a little bit [m] real :: SLdepth_0d ! Surface layer depth = surf_layer_ext*OBLdepth. - real :: hTot ! Running sum of thickness used in the surface layer average (m) - real :: delH ! Thickness of a layer (m) + real :: hTot ! Running sum of thickness used in the surface layer average [m] + real :: delH ! Thickness of a layer [m] real :: surfHtemp, surfTemp ! Integral and average of temp over the surface layer real :: surfHsalt, surfSalt ! Integral and average of saln over the surface layer real :: surfHu, surfU ! Integral and average of u over the surface layer real :: surfHv, surfV ! Integral and average of v over the surface layer - real :: dh ! The local thickness used for calculating interface positions (m) - real :: hcorr ! A cumulative correction arising from inflation of vanished layers (m) + real :: dh ! The local thickness used for calculating interface positions [m] + real :: hcorr ! A cumulative correction arising from inflation of vanished layers [m] integer :: kk, ksfc, ktmp ! For Langmuir Calculations @@ -1101,17 +1104,17 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF ! sigma=CS%surf_layer_ext for this calculation. call CVMix_kpp_compute_turbulent_scales( & CS%surf_layer_ext, & ! (in) Normalized surface layer depth; sigma = CS%surf_layer_ext - -cellHeight, & ! (in) Assume here that OBL depth (m) = -cellHeight(k) - surfBuoyFlux2, & ! (in) Buoyancy flux at surface (m2/s3) - surfFricVel, & ! (in) Turbulent friction velocity at surface (m/s) - w_s=Ws_1d, & ! (out) Turbulent velocity scale profile (m/s) + -cellHeight, & ! (in) Assume here that OBL depth [m] = -cellHeight(k) + surfBuoyFlux2, & ! (in) Buoyancy flux at surface [m2 s-3] + surfFricVel, & ! (in) Turbulent friction velocity at surface [m s-1] + w_s=Ws_1d, & ! (out) Turbulent velocity scale profile [m s-1] CVMix_kpp_params_user=CS%KPP_params ) !Compute CVMix VT2 CS%Vt2(i,j,:) = CVmix_kpp_compute_unresolved_shear( & - zt_cntr=cellHeight(1:G%ke), & ! Depth of cell center (m) - ws_cntr=Ws_1d, & ! Turbulent velocity scale profile, at centers (m/s) - N_iface=CS%N(i,j,:), & ! Buoyancy frequency at interface (1/s) + zt_cntr=cellHeight(1:G%ke), & ! Depth of cell center [m] + ws_cntr=Ws_1d, & ! Turbulent velocity scale profile, at centers [m s-1] + N_iface=CS%N(i,j,:), & ! Buoyancy frequency at interface [s-1] CVmix_kpp_params_user=CS%KPP_params ) ! KPP parameters !Modify CVMix VT2 @@ -1157,12 +1160,12 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF ! Calculate Bulk Richardson number from eq (21) of LMD94 BulkRi_1d = CVmix_kpp_compute_bulk_Richardson( & - zt_cntr = cellHeight(1:G%ke), & ! Depth of cell center (m) - delta_buoy_cntr=GoRho*deltaRho, & ! Bulk buoyancy difference, Br-B(z) (1/s) - delta_Vsqr_cntr=deltaU2, & ! Square of resolved velocity difference (m2/s2) + zt_cntr = cellHeight(1:G%ke), & ! Depth of cell center [m] + delta_buoy_cntr=GoRho*deltaRho, & ! Bulk buoyancy difference, Br-B(z) [s-1] + delta_Vsqr_cntr=deltaU2, & ! Square of resolved velocity difference [m2 s-2] Vt_sqr_cntr=CS%Vt2(i,j,:), & - ws_cntr=Ws_1d, & ! Turbulent velocity scale profile (m/s) - N_iface=CS%N(i,j,:)) ! Buoyancy frequency (1/s) + ws_cntr=Ws_1d, & ! Turbulent velocity scale profile [m s-1] + N_iface=CS%N(i,j,:)) ! Buoyancy frequency [s-1] surfBuoyFlux = buoyFlux(i,j,1) ! This is only used in kpp_compute_OBL_depth to limit @@ -1170,13 +1173,13 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF call CVMix_kpp_compute_OBL_depth( & BulkRi_1d, & ! (in) Bulk Richardson number - iFaceHeight, & ! (in) Height of interfaces (m) - CS%OBLdepth(i,j), & ! (out) OBL depth (m) + iFaceHeight, & ! (in) Height of interfaces [m] + CS%OBLdepth(i,j), & ! (out) OBL depth [m] CS%kOBL(i,j), & ! (out) level (+fraction) of OBL extent - zt_cntr=cellHeight, & ! (in) Height of cell centers (m) - surf_fric=surfFricVel, & ! (in) Turbulent friction velocity at surface (m/s) - surf_buoy=surfBuoyFlux, & ! (in) Buoyancy flux at surface (m2/s3) - Coriolis=Coriolis, & ! (in) Coriolis parameter (1/s) + zt_cntr=cellHeight, & ! (in) Height of cell centers [m] + surf_fric=surfFricVel, & ! (in) Turbulent friction velocity at surface [m s-1] + surf_buoy=surfBuoyFlux, & ! (in) Buoyancy flux at surface [m2 s-3] + Coriolis=Coriolis, & ! (in) Coriolis parameter [s-1] CVMix_kpp_params_user=CS%KPP_params ) ! KPP parameters ! A hack to avoid KPP reaching the bottom. It was needed during development @@ -1236,24 +1239,24 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF ! enddo ! BulkRi_1d = CVMix_kpp_compute_bulk_Richardson( & - ! cellHeight(1:G%ke), & ! Depth of cell center (m) - ! GoRho*deltaRho, & ! Bulk buoyancy difference, Br-B(z) (1/s) - ! deltaU2, & ! Square of resolved velocity difference (m2/s2) - ! ws_cntr=Ws_1d, & ! Turbulent velocity scale profile (m/s) - ! N_iface=CS%N ) ! Buoyancy frequency (1/s) + ! cellHeight(1:G%ke), & ! Depth of cell center [m] + ! GoRho*deltaRho, & ! Bulk buoyancy difference, Br-B(z) [s-1] + ! deltaU2, & ! Square of resolved velocity difference [m2 s-2] + ! ws_cntr=Ws_1d, & ! Turbulent velocity scale profile [m s-1] + ! N_iface=CS%N ) ! Buoyancy frequency [s-1] ! surfBuoyFlux = buoyFlux(i,j,1) ! This is only used in kpp_compute_OBL_depth to limit ! ! h to Monin-Obukov (default is false, ie. not used) ! call CVMix_kpp_compute_OBL_depth( & ! BulkRi_1d, & ! (in) Bulk Richardson number - ! iFaceHeight, & ! (in) Height of interfaces (m) - ! CS%OBLdepth(i,j), & ! (out) OBL depth (m) + ! iFaceHeight, & ! (in) Height of interfaces [m] + ! CS%OBLdepth(i,j), & ! (out) OBL depth [m] ! CS%kOBL(i,j), & ! (out) level (+fraction) of OBL extent - ! zt_cntr=cellHeight, & ! (in) Height of cell centers (m) - ! surf_fric=surfFricVel, & ! (in) Turbulent friction velocity at surface (m/s) - ! surf_buoy=surfBuoyFlux, & ! (in) Buoyancy flux at surface (m2/s3) - ! Coriolis=Coriolis, & ! (in) Coriolis parameter (1/s) + ! zt_cntr=cellHeight, & ! (in) Height of cell centers [m] + ! surf_fric=surfFricVel, & ! (in) Turbulent friction velocity at surface [m s-1] + ! surf_buoy=surfBuoyFlux, & ! (in) Buoyancy flux at surface [m2 s-3] + ! Coriolis=Coriolis, & ! (in) Coriolis parameter [s-1] ! CVMix_kpp_params_user=CS%KPP_params ) ! KPP parameters ! if (CS%deepOBLoffset>0.) then @@ -1278,10 +1281,10 @@ subroutine KPP_compute_BLD(CS, G, GV, US, h, Temp, Salt, u, v, EOS, uStar, buoyF if (CS%id_Ws > 0) then call CVMix_kpp_compute_turbulent_scales( & -CellHeight/CS%OBLdepth(i,j), & ! (in) Normalized boundary layer coordinate - CS%OBLdepth(i,j), & ! (in) OBL depth (m) - surfBuoyFlux, & ! (in) Buoyancy flux at surface (m2/s3) - surfFricVel, & ! (in) Turbulent friction velocity at surface (m/s) - w_s=Ws_1d, & ! (out) Turbulent velocity scale profile (m/s) + CS%OBLdepth(i,j), & ! (in) OBL depth [m] + surfBuoyFlux, & ! (in) Buoyancy flux at surface [m2 s-3] + surfFricVel, & ! (in) Turbulent friction velocity at surface [m s-1] + w_s=Ws_1d, & ! (out) Turbulent velocity scale profile [m s-1] CVMix_kpp_params_user=CS%KPP_params) ! KPP parameters CS%Ws(i,j,:) = Ws_1d(:) endif @@ -1326,20 +1329,20 @@ end subroutine KPP_compute_BLD !> Apply a 1-1-4-1-1 Laplacian filter one time on BLD to reduce any horizontal two-grid-point noise subroutine KPP_smooth_BLD(CS,G,GV,h) ! Arguments - type(KPP_CS), pointer :: CS !< Control structure - type(ocean_grid_type), intent(inout) :: G !< Ocean grid - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses (units of H) + type(KPP_CS), pointer :: CS !< Control structure + type(ocean_grid_type), intent(inout) :: G !< Ocean grid + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thicknesses [H ~> m or kg m-2] ! local real, dimension(SZI_(G),SZJ_(G)) :: OBLdepth_original ! Original OBL depths computed by CVMix - real, dimension( G%ke ) :: cellHeight ! Cell center heights referenced to surface (m) + real, dimension( G%ke ) :: cellHeight ! Cell center heights referenced to surface [m] ! (negative in the ocean) - real, dimension( G%ke+1 ) :: iFaceHeight ! Interface heights referenced to surface (m) + real, dimension( G%ke+1 ) :: iFaceHeight ! Interface heights referenced to surface [m] ! (negative in the ocean) real :: wc, ww, we, wn, ws ! averaging weights for smoothing - real :: dh ! The local thickness used for calculating interface positions (m) - real :: hcorr ! A cumulative correction arising from inflation of vanished layers (m) + real :: dh ! The local thickness used for calculating interface positions [m] + real :: hcorr ! A cumulative correction arising from inflation of vanished layers [m] real :: pref integer :: i, j, k, s @@ -1430,7 +1433,7 @@ subroutine KPP_get_BLD(CS, BLD, G) type(KPP_CS), pointer :: CS !< Control structure for !! this module type(ocean_grid_type), intent(in) :: G !< Grid structure - real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: BLD!< bnd. layer depth (m) + real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: BLD!< bnd. layer depth [m] ! Local variables integer :: i,j do j = G%jsc, G%jec ; do i = G%isc, G%iec @@ -1442,15 +1445,16 @@ end subroutine KPP_get_BLD subroutine KPP_NonLocalTransport_temp(CS, G, GV, h, nonLocalTrans, surfFlux, & dt, scalar, C_p) - type(KPP_CS), intent(in) :: CS !< Control structure - type(ocean_grid_type), intent(in) :: G !< Ocean grid - type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thickness (units of H) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: nonLocalTrans !< Non-local transport (non-dimensional) - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfFlux !< Surface flux of scalar (H/s * scalar) - real, intent(in) :: dt !< Time-step (s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: scalar !< temperature - real, intent(in) :: C_p !< Seawater specific heat capacity (J/(kg*K)) + type(KPP_CS), intent(in) :: CS !< Control structure + type(ocean_grid_type), intent(in) :: G !< Ocean grid + type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: nonLocalTrans !< Non-local transport [nondim] + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfFlux !< Surface flux of scalar + !! [conc H s-1 ~> conc m s-1 or conc kg m-2 s-1] + real, intent(in) :: dt !< Time-step [s] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: scalar !< temperature + real, intent(in) :: C_p !< Seawater specific heat capacity [J kg-1 degC-1] integer :: i, j, k real, dimension( SZI_(G), SZJ_(G), SZK_(G) ) :: dtracer @@ -1504,11 +1508,12 @@ subroutine KPP_NonLocalTransport_saln(CS, G, GV, h, nonLocalTrans, surfFlux, dt, type(KPP_CS), intent(in) :: CS !< Control structure type(ocean_grid_type), intent(in) :: G !< Ocean grid type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thickness (units of H) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: nonLocalTrans !< Non-local transport (non-dimensional) - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfFlux !< Surface flux of scalar (H/s * scalar) - real, intent(in) :: dt !< Time-step (s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: scalar !< Scalar (scalar units) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer/level thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(in) :: nonLocalTrans !< Non-local transport [nondim] + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: surfFlux !< Surface flux of scalar + !! [conc H s-1 ~> conc m s-1 or conc kg m-2 s-1] + real, intent(in) :: dt !< Time-step [s] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: scalar !< Scalar (scalar units [conc]) integer :: i, j, k real, dimension( SZI_(G), SZJ_(G), SZK_(G) ) :: dtracer diff --git a/src/parameterizations/vertical/MOM_CVMix_conv.F90 b/src/parameterizations/vertical/MOM_CVMix_conv.F90 index 215c1c4dbf..19327cd007 100644 --- a/src/parameterizations/vertical/MOM_CVMix_conv.F90 +++ b/src/parameterizations/vertical/MOM_CVMix_conv.F90 @@ -27,11 +27,11 @@ module MOM_CVMix_conv type, public :: CVMix_conv_cs ! Parameters - real :: kd_conv_const !< diffusivity constant used in convective regime (m2/s) - real :: kv_conv_const !< viscosity constant used in convective regime (m2/s) + real :: kd_conv_const !< diffusivity constant used in convective regime [m2 s-1] + real :: kv_conv_const !< viscosity constant used in convective regime [m2 s-1] real :: bv_sqr_conv !< Threshold for squared buoyancy frequency - !! needed to trigger Brunt-Vaisala parameterization (1/s^2) - real :: min_thickness !< Minimum thickness allowed (m) + !! needed to trigger Brunt-Vaisala parameterization [s-2] + real :: min_thickness !< Minimum thickness allowed [m] logical :: debug !< If true, turn on debugging ! Daignostic handles and pointers @@ -41,9 +41,9 @@ module MOM_CVMix_conv !!@} ! Diagnostics arrays - real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency (1/s2) - real, allocatable, dimension(:,:,:) :: kd_conv !< Diffusivity added by convection (m2/s) - real, allocatable, dimension(:,:,:) :: kv_conv !< Viscosity added by convection (m2/s) + real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency [s-2] + real, allocatable, dimension(:,:,:) :: kd_conv !< Diffusivity added by convection [m2 s-1] + real, allocatable, dimension(:,:,:) :: kv_conv !< Viscosity added by convection [m2 s-1] end type CVMix_conv_cs @@ -152,21 +152,21 @@ subroutine calculate_CVMix_conv(h, tv, G, GV, US, CS, hbl) type(ocean_grid_type), intent(in) :: G !< Grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in m or kg m-2. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure. type(CVMix_conv_cs), pointer :: CS !< The control structure returned !! by a previous call to CVMix_conv_init. - real, dimension(:,:), optional, pointer :: hbl!< Depth of ocean boundary layer (m) + real, dimension(:,:), optional, pointer :: hbl!< Depth of ocean boundary layer [m] ! local variables real, dimension(SZK_(G)) :: rho_lwr !< Adiabatic Water Density, this is a dummy !! variable since here convection is always !! computed based on Brunt Vaisala. real, dimension(SZK_(G)) :: rho_1d !< water density in a column, this is also !! a dummy variable, same reason as above. - real, dimension(SZK_(G)+1) :: kv_col !< Viscosities at interfaces in the column (m2 s-1) - real, dimension(SZK_(G)+1) :: kd_col !< Diffusivities at interfaces in the column (m2 s-1) - real, dimension(SZK_(G)+1) :: iFaceHeight !< Height of interfaces (m) - real, dimension(SZK_(G)) :: cellHeight !< Height of cell centers (m) + real, dimension(SZK_(G)+1) :: kv_col !< Viscosities at interfaces in the column [m2 s-1] + real, dimension(SZK_(G)+1) :: kd_col !< Diffusivities at interfaces in the column [m2 s-1] + real, dimension(SZK_(G)+1) :: iFaceHeight !< Height of interfaces [m] + real, dimension(SZK_(G)) :: cellHeight !< Height of cell centers [m] integer :: kOBL !< level of OBL extent real :: pref, g_o_rho0, rhok, rhokm1, dz, dh, hcorr integer :: i, j, k diff --git a/src/parameterizations/vertical/MOM_CVMix_ddiff.F90 b/src/parameterizations/vertical/MOM_CVMix_ddiff.F90 index 7f01b39378..0e80f166c5 100644 --- a/src/parameterizations/vertical/MOM_CVMix_ddiff.F90 +++ b/src/parameterizations/vertical/MOM_CVMix_ddiff.F90 @@ -26,16 +26,16 @@ module MOM_CVMix_ddiff type, public :: CVMix_ddiff_cs ! Parameters - real :: strat_param_max !< maximum value for the stratification parameter (nondim) + real :: strat_param_max !< maximum value for the stratification parameter [nondim] real :: kappa_ddiff_s !< leading coefficient in formula for salt-fingering regime - !! for salinity diffusion (m^2/s) - real :: ddiff_exp1 !< interior exponent in salt-fingering regime formula (nondim) - real :: ddiff_exp2 !< exterior exponent in salt-fingering regime formula (nondim) - real :: mol_diff !< molecular diffusivity (m^2/s) - real :: kappa_ddiff_param1 !< exterior coefficient in diffusive convection regime (nondim) - real :: kappa_ddiff_param2 !< middle coefficient in diffusive convection regime (nondim) - real :: kappa_ddiff_param3 !< interior coefficient in diffusive convection regime (nondim) - real :: min_thickness !< Minimum thickness allowed (m) + !! for salinity diffusion [m2 s-1] + real :: ddiff_exp1 !< interior exponent in salt-fingering regime formula [nondim] + real :: ddiff_exp2 !< exterior exponent in salt-fingering regime formula [nondim] + real :: mol_diff !< molecular diffusivity [m2 s-1] + real :: kappa_ddiff_param1 !< exterior coefficient in diffusive convection regime [nondim] + real :: kappa_ddiff_param2 !< middle coefficient in diffusive convection regime [nondim] + real :: kappa_ddiff_param3 !< interior coefficient in diffusive convection regime [nondim] + real :: min_thickness !< Minimum thickness allowed [m] character(len=4) :: diff_conv_type !< type of diffusive convection to use. Options are Marmorino & !! Caldwell 1976 ("MC76"; default) and Kelley 1988, 1990 ("K90") logical :: debug !< If true, turn on debugging @@ -47,9 +47,9 @@ module MOM_CVMix_ddiff !!@} ! Diagnostics arrays -! real, allocatable, dimension(:,:,:) :: KT_extra !< Double diffusion diffusivity for temp (Z2/s) -! real, allocatable, dimension(:,:,:) :: KS_extra !< Double diffusion diffusivity for salt (Z2/s) - real, allocatable, dimension(:,:,:) :: R_rho !< Double-diffusion density ratio (nondim) +! real, allocatable, dimension(:,:,:) :: KT_extra !< Double diffusion diffusivity for temp [Z2 s-1 ~> m2 s-1] +! real, allocatable, dimension(:,:,:) :: KS_extra !< Double diffusion diffusivity for salt [Z2 s-1 ~> m2 s-1] + real, allocatable, dimension(:,:,:) :: R_rho !< Double-diffusion density ratio [nondim] end type CVMix_ddiff_cs @@ -167,32 +167,32 @@ subroutine compute_ddiff_coeffs(h, tv, G, GV, US, j, Kd_T, Kd_S, CS) type(ocean_grid_type), intent(in) :: G !< Grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in m or kg m-2. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(out) :: Kd_T !< Interface double diffusion diapycnal - !! diffusivity for temp (Z2/sec). + !! diffusivity for temp [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(out) :: Kd_S !< Interface double diffusion diapycnal - !! diffusivity for salt (Z2/sec). - type(CVMix_ddiff_cs), pointer :: CS !< The control structure returned + !! diffusivity for salt [Z2 s-1 ~> m2 s-1]. + type(CVMix_ddiff_cs), pointer :: CS !< The control structure returned !! by a previous call to CVMix_ddiff_init. - integer, intent(in) :: j !< Meridional grid indice. + integer, intent(in) :: j !< Meridional grid indice. ! Local variables real, dimension(SZK_(G)) :: & - cellHeight, & !< Height of cell centers (m) - dRho_dT, & !< partial derivatives of density wrt temp (kg m-3 degC-1) - dRho_dS, & !< partial derivatives of density wrt saln (kg m-3 PPT-1) - pres_int, & !< pressure at each interface (Pa) - temp_int, & !< temp and at interfaces (degC) - salt_int, & !< salt at at interfaces + cellHeight, & !< Height of cell centers [m] + dRho_dT, & !< partial derivatives of density wrt temp [kg m-3 degC-1] + dRho_dS, & !< partial derivatives of density wrt saln [kg m-3 ppt-1] + pres_int, & !< pressure at each interface [Pa] + temp_int, & !< temp and at interfaces [degC] + salt_int, & !< salt at at interfaces [ppt] alpha_dT, & !< alpha*dT across interfaces beta_dS, & !< beta*dS across interfaces - dT, & !< temp. difference between adjacent layers (degC) - dS !< salt difference between adjacent layers + dT, & !< temp. difference between adjacent layers [degC] + dS !< salt difference between adjacent layers [ppt] real, dimension(SZK_(G)+1) :: & - Kd1_T, & !< Diapycanal diffusivity of temperature, in m2 s-1. - Kd1_S !< Diapycanal diffusivity of salinity, in m2 s-1. + Kd1_T, & !< Diapycanal diffusivity of temperature [m2 s-1]. + Kd1_S !< Diapycanal diffusivity of salinity [m2 s-1]. - real, dimension(SZK_(G)+1) :: iFaceHeight !< Height of interfaces (m) + real, dimension(SZK_(G)+1) :: iFaceHeight !< Height of interfaces [m] integer :: kOBL !< level of OBL extent real :: pref, g_o_rho0, rhok, rhokm1, dz, dh, hcorr integer :: i, k diff --git a/src/parameterizations/vertical/MOM_CVMix_shear.F90 b/src/parameterizations/vertical/MOM_CVMix_shear.F90 index 9b33e7dd8e..06fa74bdc7 100644 --- a/src/parameterizations/vertical/MOM_CVMix_shear.F90 +++ b/src/parameterizations/vertical/MOM_CVMix_shear.F90 @@ -22,6 +22,11 @@ module MOM_CVMix_shear public calculate_CVMix_shear, CVMix_shear_init, CVMix_shear_is_used, CVMix_shear_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure including parameters for CVMix interior shear schemes. type, public :: CVMix_shear_cs ! TODO: private logical :: use_LMD94 !< Flags to use the LMD94 scheme @@ -31,8 +36,8 @@ module MOM_CVMix_shear real :: Nu_zero !< LMD94 maximum interior diffusivity real :: KPP_exp !< Exponent of unitless factor of diff. !! for KPP internal shear mixing scheme. - real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency (1/s2) - real, allocatable, dimension(:,:,:) :: S2 !< Squared shear frequency (1/s2) + real, allocatable, dimension(:,:,:) :: N2 !< Squared Brunt-Vaisala frequency [s-2] + real, allocatable, dimension(:,:,:) :: S2 !< Squared shear frequency [s-2] real, allocatable, dimension(:,:,:) :: ri_grad !< Gradient Richardson number real, allocatable, dimension(:,:,:) :: ri_grad_smooth !< Gradient Richardson number !! after smoothing @@ -55,14 +60,14 @@ subroutine calculate_CVMix_shear(u_H, v_H, h, tv, kd, kv, G, GV, US, CS ) type(ocean_grid_type), intent(in) :: G !< Grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: u_H !< Initial zonal velocity on T points, in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: v_H !< Initial meridional velocity on T points, in m s-1. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in m or kg m-2. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: u_H !< Initial zonal velocity on T points [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: v_H !< Initial meridional velocity on T points [m s-1]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(out) :: kd !< The vertical diffusivity at each interface - !! (not layer!) in Z2 s-1. + !! (not layer!) [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), intent(out) :: kv !< The vertical viscosity at each interface - !! (not layer!) in Z2 s-1. + !! (not layer!) [Z2 s-1 ~> m2 s-1]. type(CVMix_shear_cs), pointer :: CS !< The control structure returned by a previous call to !! CVMix_shear_init. ! Local variables @@ -71,8 +76,8 @@ subroutine calculate_CVMix_shear(u_H, v_H, h, tv, kd, kv, G, GV, US, CS ) real :: pref, DU, DV, DRHO, DZ, N2, S2, dummy real, dimension(2*(G%ke)) :: pres_1d, temp_1d, salt_1d, rho_1d real, dimension(G%ke+1) :: Ri_Grad !< Gradient Richardson number - real, dimension(G%ke+1) :: Kvisc !< Vertical viscosity at interfaces (m2/s) - real, dimension(G%ke+1) :: Kdiff !< Diapycnal diffusivity at interfaces (m2/s) + real, dimension(G%ke+1) :: Kvisc !< Vertical viscosity at interfaces [m2 s-1] + real, dimension(G%ke+1) :: Kdiff !< Diapycnal diffusivity at interfaces [m2 s-1] real, parameter :: epsln = 1.e-10 !< Threshold to identify vanished layers ! some constants diff --git a/src/parameterizations/vertical/MOM_bkgnd_mixing.F90 b/src/parameterizations/vertical/MOM_bkgnd_mixing.F90 index 4aea0b8d5d..7d683944a2 100644 --- a/src/parameterizations/vertical/MOM_bkgnd_mixing.F90 +++ b/src/parameterizations/vertical/MOM_bkgnd_mixing.F90 @@ -29,18 +29,23 @@ module MOM_bkgnd_mixing public calculate_bkgnd_mixing public sfc_bkgnd_mixing +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure including parameters for this module. type, public :: bkgnd_mixing_cs ! TODO: private ! Parameters real :: Bryan_Lewis_c1 !< The vertical diffusivity values for Bryan-Lewis profile - !! at |z|=D (m2/s) + !! at |z|=D [m2 s-1] real :: Bryan_Lewis_c2 !< The amplitude of variation in diffusivity for the - !! Bryan-Lewis diffusivity profile (m2/s) + !! Bryan-Lewis diffusivity profile [m2 s-1] real :: Bryan_Lewis_c3 !< The inverse length scale for transition region in the - !! Bryan-Lewis diffusivity profile (1/m) + !! Bryan-Lewis diffusivity profile [m-1] real :: Bryan_Lewis_c4 !< The depth where diffusivity is Bryan_Lewis_bl1 in the - !! Bryan-Lewis profile (m) + !! Bryan-Lewis profile [m] real :: bckgrnd_vdc1 !< Background diffusivity (Ledwell) when !! horiz_varying_background=.true. real :: bckgrnd_vdc_eq !! Equatorial diffusivity (Gregg) when @@ -49,8 +54,8 @@ module MOM_bkgnd_mixing !! horiz_varying_background=.true. real :: bckgrnd_vdc_ban !< Banda Sea diffusivity (Gordon) when !! horiz_varying_background=.true. - real :: Kd_min !< minimum diapycnal diffusivity (Z2/s) - real :: Kd !< interior diapycnal diffusivity (Z2/s) + real :: Kd_min !< minimum diapycnal diffusivity [Z2 s-1 ~> m2 s-1] + real :: Kd !< interior diapycnal diffusivity [Z2 s-1 ~> m2 s-1] real :: N0_2Omega !< ratio of the typical Buoyancy frequency to !! twice the Earth's rotation period, used with the !! Henyey scaling from the mixing @@ -59,9 +64,9 @@ module MOM_bkgnd_mixing real :: Kd_tanh_lat_scale !< A nondimensional scaling for the range of !! diffusivities with Kd_tanh_lat_fn. Valid values !! are in the range of -2 to 2; 0.4 reproduces CM2M. - real :: Kdml !< mixed layer diapycnal diffusivity (Z2/s) + real :: Kdml !< mixed layer diapycnal diffusivity [Z2 s-1 ~> m2 s-1] !! when bulkmixedlayer==.false. - real :: Hmix !< mixed layer thickness (Z) when bulkmixedlayer==.false. + real :: Hmix !< mixed layer thickness [Z ~> m] when bulkmixedlayer==.false. logical :: Kd_tanh_lat_fn !< If true, use the tanh dependence of Kd_sfc on !! latitude, like GFDL CM2.1/CM2M. There is no !! physical justification for this form, and it can @@ -95,10 +100,10 @@ module MOM_bkgnd_mixing integer :: id_kd_bkgnd = -1 !< Diagnotic IDs integer :: id_kv_bkgnd = -1 !< Diagnostic IDs - real, allocatable, dimension(:,:) :: Kd_sfc !< surface value of the diffusivity (Z2/s) + real, allocatable, dimension(:,:) :: Kd_sfc !< surface value of the diffusivity [Z2 s-1 ~> m2 s-1] ! Diagnostics arrays - real, allocatable, dimension(:,:,:) :: kd_bkgnd !< Background diffusivity (Z2/s) - real, allocatable, dimension(:,:,:) :: kv_bkgnd !< Background viscosity (Z2/s) + real, allocatable, dimension(:,:,:) :: kd_bkgnd !< Background diffusivity [Z2 s-1 ~> m2 s-1] + real, allocatable, dimension(:,:,:) :: kv_bkgnd !< Background viscosity [Z2 s-1 ~> m2 s-1] character(len=40) :: bkgnd_scheme_str = "none" !< Background scheme identifier @@ -120,7 +125,7 @@ subroutine bkgnd_mixing_init(Time, G, GV, US, param_file, diag, CS) type(bkgnd_mixing_cs), pointer :: CS !< This module's control structure. ! Local variables - real :: Kv ! The interior vertical viscosity (m2/s) - read to set prandtl + real :: Kv ! The interior vertical viscosity [m2 s-1] - read to set prandtl ! number unless it is provided as a parameter real :: prandtl_bkgnd_comp ! Kv/CS%Kd. Gets compared with user-specified prandtl_bkgnd. @@ -330,7 +335,7 @@ subroutine sfc_bkgnd_mixing(G, US, CS) ! local variables real :: I_x30 !< 2/acos(2) = 1/(sin(30 deg) * acosh(1/sin(30 deg))) real :: deg_to_rad !< factor converting degrees to radians, pi/180. - real :: abs_sin !< absolute value of sine of latitude (nondim) + real :: abs_sin !< absolute value of sine of latitude [nondim] real :: epsilon integer :: i, j, k, is, ie, js, je @@ -380,30 +385,31 @@ subroutine calculate_bkgnd_mixing(h, tv, N2_lay, kd_lay, Kv, j, G, GV, US, CS) type(ocean_grid_type), intent(in) :: G !< Grid structure. type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in m or kg m-2. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure. real, dimension(SZI_(G),SZK_(G)), intent(in) :: N2_lay !< squared buoyancy frequency associated - !! with layers (1/s2) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: kd_lay !< Diapycnal diffusivity of each layer Z2 s-1. + !! with layers [s-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: kd_lay !< Diapycnal diffusivity of each layer + !! [Z2 s-1 ~> m2 s-1]. real, dimension(:,:,:), pointer :: Kv !< The "slow" vertical viscosity at each interface - !! (not layer!) in Z2 s-1 + !! (not layer!) [Z2 s-1 ~> m2 s-1] integer, intent(in) :: j !< Meridional grid index type(bkgnd_mixing_cs), pointer :: CS !< The control structure returned by !! a previous call to bkgnd_mixing_init. ! local variables - real, dimension(SZK_(G)+1) :: depth_int !< distance from surface of the interfaces (m) - real, dimension(SZK_(G)+1) :: Kd_col !< Diffusivities at the interfaces (m2 s-1) - real, dimension(SZK_(G)+1) :: Kv_col !< Viscosities at the interfaces (m2 s-1) - real, dimension(SZI_(G)) :: depth !< distance from surface of an interface (Z) - real :: depth_c !< depth of the center of a layer (Z) - real :: I_Hmix !< inverse of fixed mixed layer thickness (1/Z) - real :: I_2Omega !< 1/(2 Omega) (sec) + real, dimension(SZK_(G)+1) :: depth_int !< distance from surface of the interfaces [m] + real, dimension(SZK_(G)+1) :: Kd_col !< Diffusivities at the interfaces [m2 s-1] + real, dimension(SZK_(G)+1) :: Kv_col !< Viscosities at the interfaces [m2 s-1] + real, dimension(SZI_(G)) :: depth !< distance from surface of an interface [Z ~> m] + real :: depth_c !< depth of the center of a layer [Z ~> m] + real :: I_Hmix !< inverse of fixed mixed layer thickness [Z-1 ~> m-1] + real :: I_2Omega !< 1/(2 Omega) [s] real :: N_2Omega real :: N02_N2 real :: I_x30 !< 2/acos(2) = 1/(sin(30 deg) * acosh(1/sin(30 deg))) real :: deg_to_rad !< factor converting degrees to radians, pi/180. - real :: abs_sin !< absolute value of sine of latitude (nondim) + real :: abs_sin !< absolute value of sine of latitude [nondim] real :: epsilon real :: bckgrnd_vdc_psin !< PSI diffusivity in northern hemisphere real :: bckgrnd_vdc_psis !< PSI diffusivity in southern hemisphere diff --git a/src/parameterizations/vertical/MOM_bulk_mixed_layer.F90 b/src/parameterizations/vertical/MOM_bulk_mixed_layer.F90 index 5d74f0d4d2..9b3aee8e7d 100644 --- a/src/parameterizations/vertical/MOM_bulk_mixed_layer.F90 +++ b/src/parameterizations/vertical/MOM_bulk_mixed_layer.F90 @@ -23,6 +23,11 @@ module MOM_bulk_mixed_layer public bulkmixedlayer, bulkmixedlayer_init +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure with parameters for the MOM_bulk_mixed_layer module type, public :: bulkmixedlayer_CS ; private integer :: nkml !< The number of layers in the mixed layer. @@ -31,33 +36,32 @@ module MOM_bulk_mixed_layer real :: mstar !< The ratio of the friction velocity cubed to the !! TKE input to the mixed layer, nondimensional. real :: nstar !< The fraction of the TKE input to the mixed layer - !! available to drive entrainment, nondim. + !! available to drive entrainment [nondim]. real :: nstar2 !< The fraction of potential energy released by - !! convective adjustment that drives entrainment, ND. + !! convective adjustment that drives entrainment [nondim]. logical :: absorb_all_SW !< If true, all shortwave radiation is absorbed by the !! ocean, instead of passing through to the bottom mud. real :: TKE_decay !< The ratio of the natural Ekman depth to the TKE !! decay scale, nondimensional. real :: bulk_Ri_ML !< The efficiency with which mean kinetic energy !! released by mechanically forced entrainment of - !! the mixed layer is converted to TKE, nondim. + !! the mixed layer is converted to TKE [nondim]. real :: bulk_Ri_convective !< The efficiency with which convectively - !! released mean kinetic energy becomes TKE, nondim. - real :: Hmix_min !< The minimum mixed layer thickness in H. + !! released mean kinetic energy becomes TKE [nondim]. + real :: Hmix_min !< The minimum mixed layer thickness [H ~> m or kg m-2]. real :: H_limit_fluxes !< When the total ocean depth is less than this - !! value, in H, scale away all surface forcing to + !! value [H ~> m or kg m-2], scale away all surface forcing to !! avoid boiling the ocean. - real :: ustar_min !< A minimum value of ustar to avoid numerical problems, - !! in Z s-1. If the value is small enough, this should - !! not affect the solution. - real :: omega !< The Earth's rotation rate, in s-1. + real :: ustar_min !< A minimum value of ustar to avoid numerical problems [Z s-1 ~> m s-1]. + !! If the value is small enough, this should not affect the solution. + real :: omega !< The Earth's rotation rate [s-1]. real :: dT_dS_wt !< When forced to extrapolate T & S to match the - !! layer densities, this factor (in deg C / PSU) is + !! layer densities, this factor (in degC / ppt) is !! combined with the derivatives of density with T & S !! to determines what direction is orthogonal to !! density contours. It should be a typical value of !! (dR/dS) / (dR/dT) in oceanic profiles. - !! 6 K psu-1 might be reasonable. + !! 6 degC ppt-1 might be reasonable. real :: BL_extrap_lim !< A limit on the density range over which !! extrapolation can occur when detraining from the !! buffer layers, relative to the density range @@ -83,12 +87,12 @@ module MOM_bulk_mixed_layer logical :: TKE_diagnostics = .false. !< If true, calculate extensive diagnostics of the TKE budget logical :: do_rivermix = .false. !< Provide additional TKE to mix river runoff !! at the river mouths to rivermix_depth - real :: rivermix_depth = 0.0 !< The depth of mixing if do_rivermix is true, in Z. + real :: rivermix_depth = 0.0 !< The depth of mixing if do_rivermix is true [Z ~> m]. logical :: limit_det !< If true, limit the extent of buffer layer !! detrainment to be consistent with neighbors. real :: lim_det_dH_sfc !< The fractional limit in the change between grid !! points of the surface region (mixed & buffer - !! layer) thickness, nondim. 0.5 by default. + !! layer) thickness [nondim]. 0.5 by default. real :: lim_det_dH_bathy !< The fraction of the total depth by which the !! thickness of the surface region (mixed & buffer !! layer) is allowed to change between grid points. @@ -104,11 +108,11 @@ module MOM_bulk_mixed_layer real :: Allowed_T_chg !< The amount by which temperature is allowed !! to exceed previous values during detrainment, K. real :: Allowed_S_chg !< The amount by which salinity is allowed - !! to exceed previous values during detrainment, PSU. + !! to exceed previous values during detrainment, ppt. - ! These are terms in the mixed layer TKE budget, all in Z m2 s-3. + ! These are terms in the mixed layer TKE budget, all in [Z m2 s-3 ~> m3 s-3]. real, allocatable, dimension(:,:) :: & - ML_depth, & !< The mixed layer depth in H. + ML_depth, & !< The mixed layer depth [H ~> m or kg m-2]. diag_TKE_wind, & !< The wind source of TKE. diag_TKE_RiBulk, & !< The resolved KE source of TKE. diag_TKE_conv, & !< The convective source of TKE. @@ -175,169 +179,165 @@ subroutine bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, US, C type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: h_3d !< Layer thickness, in m or kg m-2. - !! (Intent in/out) The units of h are - !! referred to as H below. + intent(inout) :: h_3d !< Layer thickness [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: u_3d !< Zonal velocities interpolated to h points, - !! m s-1. + intent(in) :: u_3d !< Zonal velocities interpolated to h points + !! [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: v_3d !< Zonal velocities interpolated to h points, - !! m s-1. + intent(in) :: v_3d !< Zonal velocities interpolated to h points + !! [m s-1]. type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent !! fields have NULL ptrs. type(forcing), intent(inout) :: fluxes !< A structure containing pointers to any !! possible forcing fields. Unused fields !! have NULL ptrs. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(inout) :: ea !< The amount of fluid moved downward into a !! layer; this should be increased due to - !! mixed layer detrainment, in the same units - !! as h - usually m or kg m-2 (i.e., H). + !! mixed layer detrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(inout) :: eb !< The amount of fluid moved upward into a !! layer; this should be increased due to - !! mixed layer entrainment, in the same units - !! as h - usually m or kg m-2 (i.e., H). + !! mixed layer entrainment [H ~> m or kg m-2]. type(bulkmixedlayer_CS), pointer :: CS !< The control structure returned by a !! previous call to mixedlayer_init. type(optics_type), pointer :: optics !< The structure containing the inverse of the !! vertical absorption decay scale for - !! penetrating shortwave radiation, in m-1. - real, dimension(:,:), pointer :: Hml !< Active mixed layer depth, in m. + !! penetrating shortwave radiation [m-1]. + real, dimension(:,:), pointer :: Hml !< Active mixed layer depth [m]. logical, intent(in) :: aggregate_FW_forcing !< If true, the net incoming and !! outgoing surface freshwater fluxes are !! combined before being applied, instead of !! being applied separately. real, optional, intent(in) :: dt_diag !< The diagnostic time step, !! which may be less than dt if there are - !! two callse to mixedlayer, in s. + !! two callse to mixedlayer [s]. logical, optional, intent(in) :: last_call !< if true, this is the last call !! to mixedlayer in the current time step, so !! diagnostics will be written. The default is !! .true. - ! Local variiables + ! Local variables real, dimension(SZI_(G),SZK_(GV)) :: & eaml, & ! The amount of fluid moved downward into a layer due to mixed - ! mixed layer detrainment, in m. (I.e. entrainment from above.) + ! layer detrainment [H ~> m or kg m-2]. (I.e. entrainment from above.) ebml ! The amount of fluid moved upward into a layer due to mixed - ! mixed layer detrainment, in m. (I.e. entrainment from below.) + ! layer detrainment [H ~> m or kg m-2]. (I.e. entrainment from below.) ! If there is resorting, the vertical coordinate for these variables is the ! new, sorted index space. Here layer 0 is an initially massless layer that ! will be used to hold the new mixed layer properties. real, dimension(SZI_(G),SZK0_(GV)) :: & - h, & ! The layer thickness, in H (often m or kg m-2). - T, & ! The layer temperatures, in deg C. - S, & ! The layer salinities, in psu. - R0, & ! The potential density referenced to the surface, in kg m-3. - Rcv ! The coordinate variable potential density, in kg m-3. + h, & ! The layer thickness [H ~> m or kg m-2]. + T, & ! The layer temperatures [degC]. + S, & ! The layer salinities [ppt]. + R0, & ! The potential density referenced to the surface [kg m-3]. + Rcv ! The coordinate variable potential density [kg m-3]. real, dimension(SZI_(G),SZK_(GV)) :: & - u, & ! The zonal velocity, in m s-1. - v, & ! The meridional velocity, in m s-1. - h_orig, & ! The original thickness in H (often m or kg m-2). + u, & ! The zonal velocity [m s-1]. + v, & ! The meridional velocity [m s-1]. + h_orig, & ! The original thickness [H ~> m or kg m-2]. d_eb, & ! The downward increase across a layer in the entrainment from - ! below, in H. The sign convention is that positive values of + ! below [H ~> m or kg m-2]. The sign convention is that positive values of ! d_eb correspond to a gain in mass by a layer by upward motion. d_ea, & ! The upward increase across a layer in the entrainment from - ! above, in H. The sign convention is that positive values of + ! above [H ~> m or kg m-2]. The sign convention is that positive values of ! d_ea mean a net gain in mass by a layer from downward motion. - eps ! The (small) thickness that must remain in a layer, in H. + eps ! The (small) thickness that must remain in a layer [H ~> m or kg m-2]. integer, dimension(SZI_(G),SZK_(GV)) :: & ksort ! The sorted k-index that each original layer goes to. real, dimension(SZI_(G),SZJ_(G)) :: & - h_miss ! The summed absolute mismatch, in Z. + h_miss ! The summed absolute mismatch [Z ~> m]. real, dimension(SZI_(G)) :: & TKE, & ! The turbulent kinetic energy available for mixing over a - ! time step, in Z m2 s-2. + ! time step [Z m2 s-2 ~> m3 s-2]. Conv_En, & ! The turbulent kinetic energy source due to mixing down to - ! the depth of free convection, in Z m2 s-2. + ! the depth of free convection [Z m2 s-2 ~> m3 s-2]. htot, & ! The total depth of the layers being considered for - ! entrainment, in H. + ! entrainment [H ~> m or kg m-2]. R0_tot, & ! The integrated potential density referenced to the surface - ! of the layers which are fully entrained, in H kg m-3. + ! of the layers which are fully entrained [H kg m-3 ~> kg m-2 or kg2 m-5]. Rcv_tot, & ! The integrated coordinate value potential density of the - ! layers that are fully entrained, in H kg m-3. + ! layers that are fully entrained [H kg m-3 ~> kg m-2 or kg2 m-5]. Ttot, & ! The integrated temperature of layers which are fully - ! entrained, in H K. - Stot, & ! The integrated salt of layers which are fully entrained, - ! in H PSU. + ! entrained [degC H ~> degC m or degC kg m-2]. + Stot, & ! The integrated salt of layers which are fully entrained + ! [H ppt ~> m ppt or ppt kg m-2]. uhtot, & ! The depth integrated zonal and meridional velocities in the - vhtot, & ! mixed layer, in H m s-1. + vhtot, & ! mixed layer [H m s-1 ~> m2 s-1 or kg m-1 s-1]. netMassInOut, & ! The net mass flux (if non-Boussinsq) or volume flux (if ! Boussinesq - i.e. the fresh water flux (P+R-E)) into the - ! ocean over a time step, in H. - NetMassOut, & ! The mass flux (if non-Boussinesq) or volume flux (if - ! Boussinesq) over a time step from evaporating fresh water (H) - Net_heat, & ! The net heating at the surface over a time step in K H. Any - ! penetrating shortwave radiation is not included in Net_heat. - Net_salt, & ! The surface salt flux into the ocean over a time step, psu H. - Idecay_len_TKE, & ! The inverse of a turbulence decay length scale, in H-1. + ! ocean over a time step [H ~> m or kg m-2]. + NetMassOut, & ! The mass flux (if non-Boussinesq) or volume flux (if Boussinesq) + ! over a time step from evaporating fresh water [H ~> m or kg m-2] + Net_heat, & ! The net heating at the surface over a time step [degC H ~> degC m or degC kg m-2]. + ! Any penetrating shortwave radiation is not included in Net_heat. + Net_salt, & ! The surface salt flux into the ocean over a time step, ppt H. + Idecay_len_TKE, & ! The inverse of a turbulence decay length scale [H-1 ~> m-1 or m2 kg-1]. p_ref, & ! Reference pressure for the potential density governing mixed ! layer dynamics, almost always 0 (or 1e5) Pa. p_ref_cv, & ! Reference pressure for the potential density which defines - ! the coordinate variable, set to P_Ref, in Pa. + ! the coordinate variable, set to P_Ref [Pa]. dR0_dT, & ! Partial derivative of the mixed layer potential density with - ! temperature, in units of kg m-3 K-1. + ! temperature [kg m-3 degC-1]. dRcv_dT, & ! Partial derivative of the coordinate variable potential - ! density in the mixed layer with temperature, in kg m-3 K-1. + ! density in the mixed layer with temperature [kg m-3 degC-1]. dR0_dS, & ! Partial derivative of the mixed layer potential density with - ! salinity, in units of kg m-3 psu-1. + ! salinity [kg m-3 ppt-1]. dRcv_dS, & ! Partial derivative of the coordinate variable potential - ! density in the mixed layer with salinity, in kg m-3 psu-1. + ! density in the mixed layer with salinity [kg m-3 ppt-1]. TKE_river ! The turbulent kinetic energy available for mixing at rivermouths over a - ! time step, in Z m2 s-2. + ! time step [Z m2 s-2 ~> m3 s-2]. real, dimension(max(CS%nsw,1),SZI_(G)) :: & Pen_SW_bnd ! The penetrating fraction of the shortwave heating integrated - ! over a time step in each band, in K H. + ! over a time step in each band [degC H ~> degC m or degC kg m-2]. real, dimension(max(CS%nsw,1),SZI_(G),SZK_(GV)) :: & - opacity_band ! The opacity in each band, in H-1. The indicies are band, i, k. + opacity_band ! The opacity in each band [H-1 ~> m-1 or m2 kg-1]. The indicies are band, i, k. real :: cMKE(2,SZI_(G)) ! Coefficients of HpE and HpE^2 used in calculating the - ! denominator of MKE_rate, in m-1 and m-2. - real :: Irho0 ! 1.0 / rho_0 + ! denominator of MKE_rate; the two elements have differing + ! units of [H-1 ~> m-1 or m2 kg-1] and [H-2 ~> m-2 or m4 kg-2]. + real :: Irho0 ! 1.0 / rho_0 [m3 kg-1] real :: Inkml, Inkmlm1! 1.0 / REAL(nkml) and 1.0 / REAL(nkml-1) - real :: Ih ! The inverse of a thickness, in H-1. - real :: Idt ! The inverse of the timestep in s-1. - real :: Idt_diag ! The inverse of the timestep used for diagnostics in s-1. + real :: Ih ! The inverse of a thickness [H-1 ~> m-1 or m2 kg-1]. + real :: Idt ! The inverse of the timestep [s-1]. + real :: Idt_diag ! The inverse of the timestep used for diagnostics [s-1]. real :: RmixConst real, dimension(SZI_(G)) :: & - dKE_FC, & ! The change in mean kinetic energy due to free convection, - ! in Z m2 s-2. - h_CA ! The depth to which convective adjustment has gone in H. + dKE_FC, & ! The change in mean kinetic energy due to free convection + ! [Z m2 s-2 ~> m3 s-2]. + h_CA ! The depth to which convective adjustment has gone [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(GV)) :: & dKE_CA, & ! The change in mean kinetic energy due to convective - ! adjustment, in Z m2 s-2. + ! adjustment [Z m2 s-2 ~> m3 s-2]. cTKE ! The turbulent kinetic energy source due to convective - ! adjustment, Z m2 s-2. + ! adjustment [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G),SZJ_(G)) :: & Hsfc_max, & ! The thickness of the surface region (mixed and buffer layers) - ! after entrainment but before any buffer layer detrainment, in Z. + ! after entrainment but before any buffer layer detrainment [Z ~> m]. Hsfc_used, & ! The thickness of the surface region after buffer layer - ! detrainment, in units of Z. + ! detrainment [Z ~> m]. Hsfc_min, & ! The minimum thickness of the surface region based on the ! new mixed layer depth and the previous thickness of the - ! neighboring water columns, in Z. - h_sum, & ! The total thickness of the water column, in H. - hmbl_prev ! The previous thickness of the mixed and buffer layers, in H. + ! neighboring water columns [Z ~> m]. + h_sum, & ! The total thickness of the water column [H ~> m or kg m-2]. + hmbl_prev ! The previous thickness of the mixed and buffer layers [H ~> m or kg m-2]. real, dimension(SZI_(G)) :: & Hsfc, & ! The thickness of the surface region (mixed and buffer - ! layers before detrainment in to the interior, in H. + ! layers before detrainment in to the interior [H ~> m or kg m-2]. max_BL_det ! If non-negative, the maximum amount of entrainment from - ! the buffer layers that will be allowed this time step, in H. + ! the buffer layers that will be allowed this time step [H ~> m or kg m-2]. real :: dHsfc, dHD ! Local copies of nondimensional parameters. - real :: H_nbr ! A minimum thickness based on neighboring thicknesses, in H. + real :: H_nbr ! A minimum thickness based on neighboring thicknesses [H ~> m or kg m-2]. - real :: absf_x_H ! The absolute value of f times the mixed layer thickness, - ! in units of Z s-1. - real :: kU_star ! Ustar times the Von Karmen constant, in Z s-1. - real :: dt__diag ! A copy of dt_diag (if present) or dt, in s. + real :: absf_x_H ! The absolute value of f times the mixed layer thickness [Z s-1 ~> m s-1]. + real :: kU_star ! Ustar times the Von Karmen constant [Z s-1 ~> m s-1]. + real :: dt__diag ! A copy of dt_diag (if present) or dt [s]. logical :: write_diags ! If true, write out diagnostics with this step. logical :: reset_diags ! If true, zero out the accumulated diagnostics. integer :: i, j, k, is, ie, js, je, nz, nkmb, n @@ -452,7 +452,7 @@ subroutine bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, US, C enddo ; enddo if (id_clock_EOS>0) call cpu_clock_begin(id_clock_EOS) - ! Calculate an estimate of the mid-mixed layer pressure (in Pa) + ! Calculate an estimate of the mid-mixed layer pressure [Pa] do i=is,ie ; p_ref(i) = 0.0 ; enddo do k=1,CS%nkml ; do i=is,ie p_ref(i) = p_ref(i) + 0.5*GV%H_to_Pa*h(i,k) @@ -499,7 +499,7 @@ subroutine bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, US, C ! as follows: ! TKE_river[m3 s-3] = 0.5*rivermix_depth*g*Irho0*drho_ds* ! River*(Samb - Sriver) = CS%mstar*U_star^3 - ! where River is in units of m s-1. + ! where River is in units of [m s-1]. ! Samb = Ambient salinity at the mouth of the estuary ! rivermix_depth = The prescribed depth over which to mix river inflow ! drho_ds = The gradient of density wrt salt at the ambient surface salinity. @@ -518,10 +518,10 @@ subroutine bulkmixedlayer(h_3d, u_3d, v_3d, tv, fluxes, dt, ea, eb, G, GV, US, C ! The surface forcing is contained in the fluxes type. ! We aggregate the thermodynamic forcing for a time step into the following: - ! netMassInOut = water (H units) added/removed via surface fluxes - ! netMassOut = water (H units) removed via evaporating surface fluxes - ! net_heat = heat (degC * H) via surface fluxes - ! net_salt = salt ( g(salt)/m2 for non-Bouss and ppt*m/s for Bouss ) via surface fluxes + ! netMassInOut = water [H ~> m or kg m-2] added/removed via surface fluxes + ! netMassOut = water [H ~> m or kg m-2] removed via evaporating surface fluxes + ! net_heat = heat via surface fluxes [degC H ~> degC m or degC kg m-2] + ! net_salt = salt via surface fluxes [ppt H ~> dppt m or gSalt m-2] ! Pen_SW_bnd = components to penetrative shortwave radiation call extractFluxes1d(G, GV, fluxes, optics, nsw, j, dt, & CS%H_limit_fluxes, CS%use_river_heat_content, CS%use_calving_heat_content, & @@ -796,30 +796,30 @@ subroutine convective_adjustment(h, u, v, R0, Rcv, T, S, eps, d_eb, & dKE_CA, cTKE, j, G, GV, CS, nz_conv) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: h !< Layer thickness, in H (often m or kg m-2). + real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2]. !! The units of h are referred to as H below. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: u !< Zonal velocities interpolated to h !! points, m s-1. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: v !< Zonal velocities interpolated to h !! points, m s-1. - real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: T !< Layer temperatures, in deg C. - real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: S !< Layer salinities, in psu. + real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: T !< Layer temperatures [degC]. + real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: S !< Layer salinities [ppt]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: R0 !< Potential density referenced to - !! surface pressure, in kg m-3. + !! surface pressure [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: Rcv !< The coordinate defining potential - !! density, in kg m-3. + !! density [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: d_eb !< The downward increase across a layer - !! in the entrainment from below, in H. + !! in the entrainment from below [H ~> m or kg m-2]. !! Positive values go with mass gain by !! a layer. real, dimension(SZI_(G),SZK_(GV)), intent(in) :: eps !< The negligibly small amount of water - !! that will be left in each layer, in H. + !! that will be left in each layer [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(GV)), intent(out) :: dKE_CA !< The vertically integrated change in !! kinetic energy due to convective - !! adjustment, in Z m2 s-2. + !! adjustment [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G),SZK_(GV)), intent(out) :: cTKE !< The buoyant turbulent kinetic energy - !! source due to convective adjustment, - !! in Z m2 s-2. + !! source due to convective adjustment + !! [Z m2 s-2 ~> m3 s-2]. integer, intent(in) :: j !< The j-index to work on. type(bulkmixedlayer_CS), pointer :: CS !< The control structure for this module. integer, optional, intent(in) :: nz_conv !< If present, the number of layers @@ -833,22 +833,22 @@ subroutine convective_adjustment(h, u, v, R0, Rcv, T, S, eps, d_eb, & ! Local variables real, dimension(SZI_(G)) :: & htot, & ! The total depth of the layers being considered for - ! entrainment, in H. + ! entrainment [H ~> m or kg m-2]. R0_tot, & ! The integrated potential density referenced to the surface - ! of the layers which are fully entrained, in H kg m-3. + ! of the layers which are fully entrained [H kg m-3 ~> kg m-2 or kg2 m-5]. Rcv_tot, & ! The integrated coordinate value potential density of the - ! layers that are fully entrained, in H kg m-3. + ! layers that are fully entrained [H kg m-3 ~> kg m-2 or kg2 m-5]. Ttot, & ! The integrated temperature of layers which are fully - ! entrained, in H K. - Stot, & ! The integrated salt of layers which are fully entrained, - ! in H PSU. + ! entrained [degC H ~> degC m or degC kg m-2]. + Stot, & ! The integrated salt of layers which are fully entrained + ! [H ppt ~> m ppt or ppt kg m-2]. uhtot, & ! The depth integrated zonal and meridional velocities in - vhtot, & ! the mixed layer, in H m s-1. + vhtot, & ! the mixed layer [H m s-1 ~> m2 s-1 or kg m-1 s-1]. KE_orig, & ! The total mean kinetic energy in the mixed layer before ! convection, H m2 s-2. - h_orig_k1 ! The depth of layer k1 before convective adjustment, in H. - real :: h_ent ! The thickness from a layer that is entrained, in H. - real :: Ih ! The inverse of a thickness, in H-1. + h_orig_k1 ! The depth of layer k1 before convective adjustment [H ~> m or kg m-2]. + real :: h_ent ! The thickness from a layer that is entrained [H ~> m or kg m-2]. + real :: Ih ! The inverse of a thickness [H-1 ~> m-1 or m2 kg-1]. real :: g_H2_2Rho0 ! Half the gravitational acceleration times the square of ! the conversion from H to Z divided by the mean density, ! in m7 s-2 Z-1 H-2 kg-1. !### CHECK UNITS @@ -933,73 +933,73 @@ subroutine mixedlayer_convection(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZK_(GV)), & - intent(inout) :: h !< Layer thickness, in H (often m or kg m-2). + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2]. !! The units of h are referred to as H below. real, dimension(SZI_(G),SZK_(GV)), & intent(inout) :: d_eb !< The downward increase across a layer in the - !! layer in the entrainment from below, in H. + !! layer in the entrainment from below [H ~> m or kg m-2]. !! Positive values go with mass gain by a layer. - real, dimension(SZI_(G)), intent(out) :: htot !< The accumulated mixed layer thickness, in H. - real, dimension(SZI_(G)), intent(out) :: Ttot !< The depth integrated mixed layer temperature, - !! in deg C H. - real, dimension(SZI_(G)), intent(out) :: Stot !< The depth integrated mixed layer salinity, - !! in psu H. + real, dimension(SZI_(G)), intent(out) :: htot !< The accumulated mixed layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G)), intent(out) :: Ttot !< The depth integrated mixed layer temperature + !! [degC H ~> degC m or degC kg m-2]. + real, dimension(SZI_(G)), intent(out) :: Stot !< The depth integrated mixed layer salinity + !! [ppt H ~> ppt m or ppt kg m-2]. real, dimension(SZI_(G)), intent(out) :: uhtot !< The depth integrated mixed layer zonal !! velocity, H m s-1. real, dimension(SZI_(G)), intent(out) :: vhtot !< The integrated mixed layer meridional !! velocity, H m s-1. - real, dimension(SZI_(G)), intent(out) :: R0_tot !< The integrated mixed layer potential - !! density referenced to 0 pressure, in H kg m-2. + real, dimension(SZI_(G)), intent(out) :: R0_tot !< The integrated mixed layer potential density referenced + !! to 0 pressure [H kg m-2 ~> kg m-1 or kg2 m-4]. real, dimension(SZI_(G)), intent(out) :: Rcv_tot !< The integrated mixed layer coordinate - !! variable potential density, in H kg m-2. + !! variable potential density [H kg m-2 ~> kg m-1 or kg2 m-4]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: u !< Zonal velocities interpolated to h points, m s-1. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: v !< Zonal velocities interpolated to h points, m s-1. real, dimension(SZI_(G),SZK_(GV)), & - intent(in) :: T !< Layer temperatures, in deg C. + intent(in) :: T !< Layer temperatures [degC]. real, dimension(SZI_(G),SZK_(GV)), & - intent(in) :: S !< Layer salinities, in psu. + intent(in) :: S !< Layer salinities [ppt]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: R0 !< Potential density referenced to - !! surface pressure, in kg m-3. + !! surface pressure [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: Rcv !< The coordinate defining potential - !! density, in kg m-3. + !! density [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: eps !< The negligibly small amount of water - !! that will be left in each layer, in H. + !! that will be left in each layer [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: dR0_dT !< The partial derivative of R0 with respect to - !! temperature, in kg m-3 degC-1. + !! temperature [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dT !< The partial derivative of Rcv with respect to - !! temperature, in kg m-3 degC-1. + !! temperature [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dR0_dS !< The partial derivative of R0 with respect to - !! salinity, in kg m-3 psu-1. + !! salinity [kg m-3 ppt-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dS !< The partial derivative of Rcv with respect to - !! salinity, in kg m-3 psu-1. + !! salinity [kg m-3 ppt-1]. real, dimension(SZI_(G)), intent(in) :: netMassInOut !< The net mass flux (if non-Boussinesq) !! or volume flux (if Boussinesq) into the ocean - !! within a time step in H. (I.e. P+R-E.) + !! within a time step [H ~> m or kg m-2]. (I.e. P+R-E.) real, dimension(SZI_(G)), intent(in) :: netMassOut !< The mass or volume flux out of the ocean - !! within a time step in H. - real, dimension(SZI_(G)), intent(in) :: Net_heat !< The net heating at the surface over a - !! time step in K H. Any penetrating shortwave - !! radiation is not included in Net_heat. + !! within a time step [H ~> m or kg m-2]. + real, dimension(SZI_(G)), intent(in) :: Net_heat !< The net heating at the surface over a time + !! step [degC H ~> degC m or degC kg m-2]. Any penetrating + !! shortwave radiation is not included in Net_heat. real, dimension(SZI_(G)), intent(in) :: Net_salt !< The net surface salt flux into the ocean - !! over a time step in psu H. + !! over a time step [ppt H ~> ppt m or ppt kg m-2]. integer, intent(in) :: nsw !< The number of bands of penetrating !! shortwave radiation. real, dimension(:,:), intent(inout) :: Pen_SW_bnd !< The penetrating shortwave !! heating at the sea surface in each - !! penetrating band, in K H, + !! penetrating band [degC H ~> degC m or degC kg m-2], !! size nsw x SZI_(G). real, dimension(:,:,:), intent(in) :: opacity_band !< The opacity in each band of penetrating - !! shortwave radiation, in H-1. + !! shortwave radiation [H-1 ~> m-1 or m2 kg-1]. !! The indicies of opacity_band are band, i, k. real, dimension(SZI_(G)), intent(out) :: Conv_en !< The buoyant turbulent kinetic energy source - !! due to free convection, in Z m2 s-2. + !! due to free convection [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G)), intent(out) :: dKE_FC !< The vertically integrated change in kinetic - !! energy due to free convection, in Z m2 s-2. + !! energy due to free convection [Z m2 s-2 ~> m3 s-2]. integer, intent(in) :: j !< The j-index to work on. integer, dimension(SZI_(G),SZK_(GV)), & intent(in) :: ksort !< The density-sorted k-indices. @@ -1011,7 +1011,7 @@ subroutine mixedlayer_convection(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, & type(forcing), intent(inout) :: fluxes !< A structure containing pointers to any !! possible forcing fields. Unused fields !! have NULL ptrs. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. logical, intent(in) :: aggregate_FW_forcing !< If true, the net incoming and !! outgoing surface freshwater fluxes are !! combined before being applied, instead of @@ -1023,40 +1023,40 @@ subroutine mixedlayer_convection(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, & ! Local variables real, dimension(SZI_(G)) :: & - massOutRem, & ! Evaporation that remains to be supplied, in H. - netMassIn ! mass entering through ocean surface (H) + massOutRem, & ! Evaporation that remains to be supplied [H ~> m or kg m-2]. + netMassIn ! mass entering through ocean surface [H ~> m or kg m-2] real :: SW_trans ! The fraction of shortwave radiation - ! that is not absorbed in a layer, ND. + ! that is not absorbed in a layer [nondim]. real :: Pen_absorbed ! The amount of penetrative shortwave radiation - ! that is absorbed in a layer, in units of K H. + ! that is absorbed in a layer [degC H ~> degC m or degC kg m-2]. real :: h_avail ! The thickness in a layer available for - ! entrainment, in H. - real :: h_ent ! The thickness from a layer that is entrained, in H. - real :: T_precip ! The temperature of the precipitation, in deg C. + ! entrainment [H ~> m or kg m-2]. + real :: h_ent ! The thickness from a layer that is entrained [H ~> m or kg m-2]. + real :: T_precip ! The temperature of the precipitation [degC]. real :: C1_3, C1_6 ! 1/3 and 1/6. real :: En_fn, Frac, x1 ! Nondimensional temporary variables. - real :: dr, dr0 ! Temporary variables with units of kg m-3 H. - real :: dr_ent, dr_comp ! Temporary variables with units of kg m-3 H. - real :: dr_dh ! The partial derivative of dr_ent with h_ent, in kg m-3. + real :: dr, dr0 ! Temporary variables [kg m-3 H ~> kg m-2 or kg2 m-5]. + real :: dr_ent, dr_comp ! Temporary variables [kg m-3 H ~> kg m-2 or kg2 m-5]. + real :: dr_dh ! The partial derivative of dr_ent with h_ent [kg m-3]. real :: h_min, h_max ! The minimum, maximum, and previous estimates for - real :: h_prev ! h_ent, in H. - real :: h_evap ! The thickness that is evaporated, in H. + real :: h_prev ! h_ent [H ~> m or kg m-2]. + real :: h_evap ! The thickness that is evaporated [H ~> m or kg m-2]. real :: dh_Newt ! The Newton's method estimate of the change in - ! h_ent between iterations, in H. + ! h_ent between iterations [H ~> m or kg m-2]. real :: g_H2_2Rho0 ! Half the gravitational acceleration times the square of ! the conversion from H to Z divided by the mean density, - ! in m7 s-2 Z-1 H-2 kg-1. !### CHECK UNITS - real :: Angstrom ! The minimum layer thickness, in H. - real :: opacity ! The opacity converted to units of H-1. + ! [m7 s-2 Z-1 H-2 kg-1 ~> m4 s-2 kg-1 or m10 s-2 kg-3]. + real :: Angstrom ! The minimum layer thickness [H ~> m or kg m-2]. + real :: opacity ! The opacity converted to inverse thickness units [H-1 ~> m-1 or m2 kg-1] real :: sum_Pen_En ! The potential energy change due to penetrating - ! shortwave radiation, integrated over a layer, in - ! H kg m-3. - real :: Idt ! 1.0/dt + ! shortwave radiation, integrated over a layer + ! [H kg m-3 ~> kg m-2 or kg2 m-5]. + real :: Idt ! 1.0/dt [s-1] real :: netHeatOut ! accumulated heat content of mass leaving ocean integer :: is, ie, nz, i, k, ks, itt, n real, dimension(max(nsw,1)) :: & - C2, & ! Temporary variable with units of kg m-3 H-1. - r_SW_top ! Temporary variables with units of H kg m-3. + C2, & ! Temporary variable [kg m-3 H-1 ~> kg m-4 or m-1]. + r_SW_top ! Temporary variables [H kg m-3 ~> kg m-2 or kg2 m-5]. Angstrom = GV%Angstrom_H C1_3 = 1.0/3.0 ; C1_6 = 1.0/6.0 @@ -1301,39 +1301,39 @@ subroutine find_starting_TKE(htot, h_CA, fluxes, Conv_En, cTKE, dKE_FC, dKE_CA, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G)), intent(in) :: htot !< The accumlated mixed layer thickness, in H - !! (often m or kg m-2). + real, dimension(SZI_(G)), intent(in) :: htot !< The accumulated mixed layer thickness + !! [H ~> m or kg m-2] real, dimension(SZI_(G)), intent(in) :: h_CA !< The mixed layer depth after convective - !! adjustment, in H. + !! adjustment [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to any !! possible forcing fields. Unused fields !! have NULL ptrs. real, dimension(SZI_(G)), intent(inout) :: Conv_En !< The buoyant turbulent kinetic energy source - !! due to free convection, in Z m2 s-2. + !! due to free convection [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G)), intent(in) :: dKE_FC !< The vertically integrated change in - !! kinetic energy due to free convection, - !! in Z m2 s-2. + !! kinetic energy due to free convection + !! [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: cTKE !< The buoyant turbulent kinetic energy - !! source due to convective adjustment, - !! in Z m2 s-2. + !! source due to convective adjustment + !! [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: dKE_CA !< The vertically integrated change in !! kinetic energy due to convective - !! adjustment, in Z m2 s-2. + !! adjustment [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G)), intent(out) :: TKE !< The turbulent kinetic energy available for - !! mixing over a time step, in Z m2 s-2. + !! mixing over a time step [Z m2 s-2 ~> m3 s-2]. real, dimension(SZI_(G)), intent(out) :: Idecay_len_TKE !< The inverse of the vertical decay - !! scale for TKE, in H-1. + !! scale for TKE [H-1 ~> m-1 or m2 kg-1]. real, dimension(SZI_(G)), intent(in) :: TKE_river !< The turbulent kinetic energy available !! for driving mixing at river mouths - !! integrated over a time step, in Z m2 s-2. + !! integrated over a time step [Z m2 s-2 ~> m3 s-2]. real, dimension(2,SZI_(G)), intent(out) :: cMKE !< Coefficients of HpE and HpE^2 in !! calculating the denominator of MKE_rate, - !! in H-1 and H-2. - real, intent(in) :: dt !< The time step in s. + !! [H-1 ~> m-1 or m2 kg-1] and [H-2 ~> m-2 or m4 kg-2]. + real, intent(in) :: dt !< The time step [s]. real, intent(in) :: Idt_diag !< The inverse of the accumulated diagnostic - !! time interval, in s-1. + !! time interval [s-1]. integer, intent(in) :: j !< The j-index to work on. integer, dimension(SZI_(G),SZK_(GV)), & intent(in) :: ksort !< The density-sorted k-indicies. @@ -1343,24 +1343,24 @@ subroutine find_starting_TKE(htot, h_CA, fluxes, Conv_En, cTKE, dKE_FC, dKE_CA, ! convection to drive mechanical entrainment. ! Local variables - real :: dKE_conv ! The change in mean kinetic energy due to all convection, in Z m2 s-2. + real :: dKE_conv ! The change in mean kinetic energy due to all convection [Z m2 s-2 ~> m3 s-2]. real :: nstar_FC ! The effective efficiency with which the energy released by - ! free convection is converted to TKE, often ~0.2, ND. + ! free convection is converted to TKE, often ~0.2 [nondim]. real :: nstar_CA ! The effective efficiency with which the energy released by - ! convective adjustment is converted to TKE, often ~0.2, ND. + ! convective adjustment is converted to TKE, often ~0.2 [nondim]. real :: TKE_CA ! The potential energy released by convective adjustment if - ! that release is positive, in Z m2 s2. - real :: MKE_rate_CA ! MKE_rate for convective adjustment, ND, 0 to 1. - real :: MKE_rate_FC ! MKE_rate for free convection, ND, 0 to 1. - real :: totEn_Z ! The total potential energy released by convection, Z3 s-2. - real :: Ih ! The inverse of a thickness, in H-1. - real :: exp_kh ! The nondimensional decay of TKE across a layer, ND. + ! that release is positive [Z m2 s-2 ~> m3 s-2]. + real :: MKE_rate_CA ! MKE_rate for convective adjustment [nondim], 0 to 1. + real :: MKE_rate_FC ! MKE_rate for free convection [nondim], 0 to 1. + real :: totEn_Z ! The total potential energy released by convection, [Z3 s-2 ~> m3 s-2]. + real :: Ih ! The inverse of a thickness [H-1 ~> m-1 or m2 kg-1]. + real :: exp_kh ! The nondimensional decay of TKE across a layer [nondim]. real :: absf ! The absolute value of f averaged to thickness points, s-1. - real :: U_star ! The friction velocity in Z s-1. - real :: absf_Ustar ! The absolute value of f divided by U_star, in Z-1. - real :: wind_TKE_src ! The surface wind source of TKE, in Z m2 s-3. + real :: U_star ! The friction velocity [Z s-1 ~> m s-1]. + real :: absf_Ustar ! The absolute value of f divided by U_star [Z-1 ~> m-1]. + real :: wind_TKE_src ! The surface wind source of TKE [Z m2 s-3 ~> m3 s-3]. real :: diag_wt ! The ratio of the current timestep to the diagnostic - ! timestep (which may include 2 calls), ND. + ! timestep (which may include 2 calls) [nondim]. integer :: is, ie, nz, i is = G%isc ; ie = G%iec ; nz = GV%ke @@ -1489,63 +1489,63 @@ subroutine mechanical_entrainment(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZK_(GV)), & - intent(inout) :: h !< Layer thickness, in m or kg m-2. - !! The units of h are referred to as H below. + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(GV)), & intent(inout) :: d_eb !< The downward increase across a layer in the - !! layer in the entrainment from below, in H. + !! layer in the entrainment from below [H ~> m or kg m-2]. !! Positive values go with mass gain by a layer. - real, dimension(SZI_(G)), intent(inout) :: htot !< The accumlated mixed layer thickness, in H. - real, dimension(SZI_(G)), intent(inout) :: Ttot !< The depth integrated mixed layer temperature, - !! in deg C H. - real, dimension(SZI_(G)), intent(inout) :: Stot !< The depth integrated mixed layer salinity, - !! in psu H. + real, dimension(SZI_(G)), intent(inout) :: htot !< The accumlated mixed layer thickness [H ~> m or kg m-2]. + real, dimension(SZI_(G)), intent(inout) :: Ttot !< The depth integrated mixed layer temperature + !! [degC H ~> degC m or degC kg m-2]. + real, dimension(SZI_(G)), intent(inout) :: Stot !< The depth integrated mixed layer salinity + !! [ppt H ~> ppt m or ppt kg m-2]. real, dimension(SZI_(G)), intent(inout) :: uhtot !< The depth integrated mixed layer zonal !! velocity, H m s-1. real, dimension(SZI_(G)), intent(inout) :: vhtot !< The integrated mixed layer meridional !! velocity, H m s-1. - real, dimension(SZI_(G)), intent(inout) :: R0_tot !< The integrated mixed layer potential - !! density referenced to 0 pressure, in H kg m-3. - real, dimension(SZI_(G)), intent(inout) :: Rcv_tot !< The integrated mixed layer coordinate - !! variable potential density, in H kg m-3. + real, dimension(SZI_(G)), intent(inout) :: R0_tot !< The integrated mixed layer potential density + !! referenced to 0 pressure [H kg m-3 ~> kg m-2 or kg2 m-5]. + real, dimension(SZI_(G)), intent(inout) :: Rcv_tot !< The integrated mixed layer coordinate variable + !! potential density [H kg m-3 ~> kg m-2 or kg2 m-5]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: u !< Zonal velocities interpolated to h points, m s-1. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: v !< Zonal velocities interpolated to h points, m s-1. real, dimension(SZI_(G),SZK_(GV)), & - intent(in) :: T !< Layer temperatures, in deg C. + intent(in) :: T !< Layer temperatures [degC]. real, dimension(SZI_(G),SZK_(GV)), & - intent(in) :: S !< Layer salinities, in psu. + intent(in) :: S !< Layer salinities [ppt]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: R0 !< Potential density referenced to - !! surface pressure, in kg m-3. + !! surface pressure [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: Rcv !< The coordinate defining potential - !! density, in kg m-3. + !! density [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), & intent(in) :: eps !< The negligibly small amount of water - !! that will be left in each layer, in H. + !! that will be left in each layer [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: dR0_dT !< The partial derivative of R0 with respect to - !! temperature, in kg m-3 degC-1. + !! temperature [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dT !< The partial derivative of Rcv with respect to - !! temperature, in kg m-3 degC-1. - real, dimension(2,SZI_(G)), intent(in) :: cMKE !< Coefficients of HpE and HpE^2 used in calculating - !! the denominator of MKE_rate, in m-1 and m-2. + !! temperature [kg m-3 degC-1]. + real, dimension(2,SZI_(G)), intent(in) :: cMKE !< Coefficients of HpE and HpE^2 used in calculating the + !! denominator of MKE_rate; the two elements have differing + !! units of [H-1 ~> m-1 or m2 kg-1] and [H-2 ~> m-2 or m4 kg-2]. real, intent(in) :: Idt_diag !< The inverse of the accumulated diagnostic - !! time interval, in s-1. + !! time interval [s-1]. integer, intent(in) :: nsw !< The number of bands of penetrating !! shortwave radiation. - real, dimension(:,:), intent(inout) :: Pen_SW_bnd !< The penetrating shortwave - !! heating at the sea surface in each - !! penetrating band, in K H, + real, dimension(:,:), intent(inout) :: Pen_SW_bnd !< The penetrating shortwave heating at the + !! sea surface in each penetrating band + !! [degC H ~> degC m or degC kg m-2], !! size nsw x SZI_(G). real, dimension(:,:,:), intent(in) :: opacity_band !< The opacity in each band of penetrating - !! shortwave radiation, in H-1. - !! The indicies of opacity_band are band, i, k. + !! shortwave radiation [H-1 ~> m-1 or m2 kg-1]. + !! The indicies of opacity_band are (band, i, k). real, dimension(SZI_(G)), intent(inout) :: TKE !< The turbulent kinetic energy !! available for mixing over a time - !! step, in Z m2 s-2. - real, dimension(SZI_(G)), intent(inout) :: Idecay_len_TKE !< The vertical TKE decay rate, in H-1. + !! step [Z m2 s-2 ~> m3 s-2]. + real, dimension(SZI_(G)), intent(inout) :: Idecay_len_TKE !< The vertical TKE decay rate [H-1 ~> m-1 or m2 kg-1]. integer, intent(in) :: j !< The j-index to work on. integer, dimension(SZI_(G),SZK_(GV)), & intent(in) :: ksort !< The density-sorted k-indicies. @@ -1557,38 +1557,38 @@ subroutine mechanical_entrainment(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, & real :: SW_trans ! The fraction of shortwave radiation that is not ! absorbed in a layer, nondimensional. real :: Pen_absorbed ! The amount of penetrative shortwave radiation - ! that is absorbed in a layer, in units of K m. - real :: h_avail ! The thickness in a layer available for entrainment in H. - real :: h_ent ! The thickness from a layer that is entrained, in H. - real :: h_min, h_max ! Limits on the solution for h_ent, in H. + ! that is absorbed in a layer [degC H ~> degC m or degC kg m-2]. + real :: h_avail ! The thickness in a layer available for entrainment [H ~> m or kg m-2]. + real :: h_ent ! The thickness from a layer that is entrained [H ~> m or kg m-2]. + real :: h_min, h_max ! Limits on the solution for h_ent [H ~> m or kg m-2]. real :: dh_Newt ! The Newton's method estimate of the change in - ! h_ent between iterations, in H. + ! h_ent between iterations [H ~> m or kg m-2]. real :: MKE_rate ! The fraction of the energy in resolved shears ! within the mixed layer that will be eliminated ! within a timestep, nondim, 0 to 1. - real :: HpE ! The current thickness plus entrainment, H. + real :: HpE ! The current thickness plus entrainment [H ~> m or kg m-2]. real :: g_H_2Rho0 ! Half the gravitational acceleration times the ! conversion from H to m divided by the mean density, ! in m5 s-2 H-1 kg-1. - real :: TKE_full_ent ! The TKE remaining if a layer is fully entrained, - ! in units of Z m2 s-2. + real :: TKE_full_ent ! The TKE remaining if a layer is fully entrained + ! [Z m2 s-2 ~> m3 s-2]. real :: dRL ! Work required to mix water from the next layer - ! across the mixed layer, in m2 s-2. + ! across the mixed layer [m2 s-2]. real :: Pen_En_Contrib ! Penetrating SW contributions to the changes in - ! TKE, divided by layer thickness in m, in m2 s-2. - real :: C1 ! A temporary variable in units of m2 s-2. + ! TKE, divided by layer thickness in m [m2 s-2]. + real :: C1 ! A temporary variable [m2 s-2]. real :: dMKE ! A temporary variable related to the release of mean ! kinetic energy, with units of H Z m2 s-2. - real :: TKE_ent ! The TKE that remains if h_ent were entrained, in Z m2 s-2. + real :: TKE_ent ! The TKE that remains if h_ent were entrained [Z m2 s-2 ~> m3 s-2]. real :: TKE_ent1 ! The TKE that would remain, without considering the - ! release of mean kinetic energy, in Z m2 s2. - real :: dTKE_dh ! The partial derivative of TKE with h_ent, in Z m2 s-2 H-1. + ! release of mean kinetic energy [Z m2 s-2 ~> m3 s-2]. + real :: dTKE_dh ! The partial derivative of TKE with h_ent [Z m2 s-2 H-1 ~> m2 s-2 or m5 s-2 kg-1]. real :: Pen_dTKE_dh_Contrib ! The penetrating shortwave contribution to - ! dTKE_dh, in m2 s-2. - real :: EF4_val ! The result of EF4() (see later), in H-1. + ! dTKE_dh [m2 s-2]. + real :: EF4_val ! The result of EF4() (see later) [H-1 ~> m-1 or m2 kg-1]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: dEF4_dh ! The partial derivative of EF4 with h, in H-2. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: dEF4_dh ! The partial derivative of EF4 with h [H-2 ~> m-2 or m4 kg-2]. real :: Pen_En1 ! A nondimensional temporary variable. real :: kh, exp_kh ! Nondimensional temporary variables related to the real :: f1_kh ! fractional decay of TKE across a layer. @@ -1596,8 +1596,8 @@ subroutine mechanical_entrainment(h, d_eb, htot, Ttot, Stot, uhtot, vhtot, & real :: f1_x1, f2_x1 ! the relative decay of TKE and SW radiation across real :: f3_x1 ! a layer, and exponential-related functions of x1. real :: E_HxHpE ! Entrainment divided by the product of the new and old - ! thicknesses, in H-1. - real :: Hmix_min ! The minimum mixed layer depth in H. + ! thicknesses [H-1 ~> m-1 or m2 kg-1]. + real :: Hmix_min ! The minimum mixed layer depth [H ~> m or kg m-2]. real :: opacity real :: C1_3, C1_6, C1_24 ! 1/3, 1/6, and 1/24. integer :: is, ie, nz, i, k, ks, itt, n @@ -1828,32 +1828,16 @@ end subroutine mechanical_entrainment subroutine sort_ML(h, R0, eps, G, GV, CS, ksort) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZK_(GV)), intent(in) :: h !< Layer thickness, in m or kg m-2. - !! (Intent in/out) The units of h are - !! referred to as H below. + real, dimension(SZI_(G),SZK_(GV)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(GV)), intent(in) :: R0 !< The potential density used to sort - !! the layers, in kg m-3. + !! the layers [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), intent(in) :: eps !< The (small) thickness that must - !! remain in each layer, in H. + !! remain in each layer [H ~> m or kg m-2]. type(bulkmixedlayer_CS), pointer :: CS !< The control structure returned by a !! previous call to mixedlayer_init. integer, dimension(SZI_(G),SZK_(GV)), intent(out) :: ksort !< The k-index to use in the sort. -! This subroutine generates an array of indices that are sorted by layer -! density. - -! Arguments: h - Layer thickness, in m or kg m-2. (Intent in/out) The units -! of h are referred to as H below. -! (in) R0 - The potential density used to sort the layers, in kg m-3. -! (in) eps - The (small) thickness that must remain in each layer, in H. -! (in) tv - A structure containing pointers to any available -! thermodynamic fields. Absent fields have NULL ptrs. -! (in) j - The meridional row to work on. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! mixedlayer_init. -! (out) ksort - The k-index to use in the sort. + ! Local variables real :: R0sort(SZI_(G),SZK_(GV)) integer :: nsort(SZI_(G)) logical :: done_sorting(SZI_(G)) @@ -1897,28 +1881,26 @@ subroutine resort_ML(h, T, S, R0, Rcv, RcvTgt, eps, d_ea, d_eb, ksort, G, GV, CS type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid !! structure. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: h !< Layer thickness, in m or kg m-2. - !! (Intent in/out) The units of h - !! are referred to as H below. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2]. !! Layer 0 is the new mixed layer. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: T !< Layer temperatures, in deg C. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: S !< Layer salinities, in psu. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: T !< Layer temperatures [degC]. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: S !< Layer salinities [ppt]. real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: R0 !< Potential density referenced to - !! surface pressure, in kg m-3. + !! surface pressure [kg m-3]. real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: Rcv !< The coordinate defining - !! potential density, in kg m-3. + !! potential density [kg m-3]. real, dimension(SZK_(GV)), intent(in) :: RcvTgt !< The target value of Rcv for each - !! layer, in kg m-3. + !! layer [kg m-3]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: eps !< The (small) thickness that must - !! remain in each layer, in H. + !! remain in each layer [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: d_ea !< The upward increase across a !! layer in the entrainment from - !! above, in m or kg m-2 (H). + !! above [H ~> m or kg m-2]. !! Positive d_ea goes with layer !! thickness increases. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: d_eb !< The downward increase across a !! layer in the entrainment from - !! below, in H. Positive values go + !! below [H ~> m or kg m-2]. Positive values go !! with mass gain by a layer. integer, dimension(SZI_(G),SZK_(GV)), intent(in) :: ksort !< The density-sorted k-indicies. type(bulkmixedlayer_CS), pointer :: CS !< The control structure for this @@ -1926,49 +1908,19 @@ subroutine resort_ML(h, T, S, R0, Rcv, RcvTgt, eps, d_ea, d_eb, ksort, G, GV, CS real, dimension(SZI_(G)), intent(in) :: dR0_dT !< The partial derivative of !! potential density referenced !! to the surface with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dR0_dS !< The partial derivative of !! cpotential density referenced !! to the surface with salinity, - !! in kg m-3 psu-1. + !! [kg m-3 ppt-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dT !< The partial derivative of !! coordinate defining potential !! density with potential - !! temperature, in kg m-3 K-1. + !! temperature [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dS !< The partial derivative of !! coordinate defining potential !! density with salinity, - !! in kg m-3 psu-1. - -! This subroutine actually moves properties between layers to achieve a -! resorted state, with all of the resorted water either moved into the correct -! interior layers or in the top nkmb layers. -! -! Arguments: h - Layer thickness, in m or kg m-2. (Intent in/out) The units of -! h are referred to as H below. Layer 0 is the new mixed layer. -! (in/out) T - Layer temperatures, in deg C. -! (in/out) S - Layer salinities, in psu. -! (in/out) R0 - Potential density referenced to surface pressure, in kg m-3. -! (in/out) Rcv - The coordinate defining potential density, in kg m-3. -! (in) RcvTgt - The target value of Rcv for each layer, in kg m-3. -! (in) eps - The (small) thickness that must remain in each layer, in H. -! (in/out) d_ea - The upward increase across a layer in the entrainment from -! above, in m or kg m-2 (H). Positive d_ea goes with layer -! thickness increases. -! (in/out) d_eb - The downward increase across a layer in the entrainment from -! below, in H. Positive values go with mass gain by a layer. -! (in) ksort - The density-sorted k-indicies. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure for this module. -! (in/out) dR0_dT - The partial derivative of potential density referenced -! to the surface with potential temperature, in kg m-3 K-1. -! (in/out) dR0_dS - The partial derivative of cpotential density referenced -! to the surface with salinity, in kg m-3 psu-1. -! (in/out) dRcv_dT - The partial derivative of coordinate defining potential -! density with potential temperature, in kg m-3 K-1. -! (in/out) dRcv_dS - The partial derivative of coordinate defining potential -! density with salinity, in kg m-3 psu-1. + !! [kg m-3 ppt-1]. ! If there are no massive light layers above the deepest of the mixed- and ! buffer layers, do nothing (except perhaps to reshuffle these layers). @@ -1982,6 +1934,8 @@ subroutine resort_ML(h, T, S, R0, Rcv, RcvTgt, eps, d_ea, d_eb, ksort, G, GV, CS ! those buffer layers into peices that match the target density of the two ! nearest interior layers. ! Otherwise, if there are more than nkbl+1 remaining massive layers + + ! Local variables real :: h_move, h_tgt_old, I_hnew real :: dT_dS_wt2, dT_dR, dS_dR, I_denom real :: Rcv_int @@ -2249,146 +2203,122 @@ subroutine mixedlayer_detrain_2(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, j, dR0_dT, dR0_dS, dRcv_dT, dRcv_dS, max_BL_det) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: h !< Layer thickness, in m or kg m-2. - !! (Intent in/out) The units of h are - !! referred to as H below. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2]. !! Layer 0 is the new mixed layer. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: T !< Potential temperature, in C. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: S !< Salinity, in psu. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: T !< Potential temperature [degC]. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: S !< Salinity [ppt]. real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: R0 !< Potential density referenced to - !! surface pressure, in kg m-3. + !! surface pressure [kg m-3]. real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: Rcv !< The coordinate defining potential - !! density, in kg m-3. + !! density [kg m-3]. real, dimension(SZK_(GV)), intent(in) :: RcvTgt !< The target value of Rcv for each - !! layer, in kg m-3. - real, intent(in) :: dt !< Time increment, in s. - real, intent(in) :: dt_diag !< The diagnostic time step, in s. + !! layer [kg m-3]. + real, intent(in) :: dt !< Time increment [s]. + real, intent(in) :: dt_diag !< The diagnostic time step [s]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: d_ea !< The upward increase across a layer in - !! the entrainment from above, in m or - !! kg m-2 (H). Positive d_ea goes with - !! layer thickness increases. + !! the entrainment from above + !! [H ~> m or kg m-2]. Positive d_ea + !! goes with layer thickness increases. integer, intent(in) :: j !< The meridional row to work on. type(bulkmixedlayer_CS), pointer :: CS !< The control structure returned by a !! previous call to mixedlayer_init. real, dimension(SZI_(G)), intent(in) :: dR0_dT !< The partial derivative of !! potential density referenced to the !! surface with potential temperature, - !! in kg m-3 K-1. + !! [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dR0_dS !< The partial derivative of !! cpotential density referenced to the - !! surface with salinity, - !! in kg m-3 psu-1. + !! surface with salinity + !! [kg m-3 ppt-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dT !< The partial derivative of !! coordinate defining potential density !! with potential temperature, - !! in kg m-3 K-1. + !! [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dS !< The partial derivative of !! coordinate defining potential density - !! with salinity, in kg m-3 psu-1. + !! with salinity [kg m-3 ppt-1]. real, dimension(SZI_(G)), intent(in) :: max_BL_det !< If non-negative, the maximum !! detrainment permitted from the buffer - !! layers, in H. + !! layers [H ~> m or kg m-2]. ! This subroutine moves any water left in the former mixed layers into the ! two buffer layers and may also move buffer layer water into the interior ! isopycnal layers. -! Arguments: h - Layer thickness, in m or kg m-2. (Intent in/out) The units of -! h are referred to as H below. Layer 0 is the new mixed layer. -! (in/out) T - Potential temperature, in C. -! (in/out) S - Salinity, in psu. -! (in/out) R0 - Potential density referenced to surface pressure, in kg m-3. -! (in/out) Rcv - The coordinate defining potential density, in kg m-3. -! (in) RcvTgt - The target value of Rcv for each layer, in kg m-3. -! (in) dt - Time increment, in s. -! (in) dt_diag - The diagnostic time step, in s. -! (in/out) d_ea - The upward increase across a layer in the entrainment from -! above, in m or kg m-2 (H). Positive d_ea goes with layer -! thickness increases. -! (in) j - The meridional row to work on. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! mixedlayer_init. -! (in) max_BL_det - If non-negative, the maximum detrainment permitted -! from the buffer layers, in H. -! (in) dR0_dT - The partial derivative of potential density referenced -! to the surface with potential temperature, in kg m-3 K-1. -! (in) dR0_dS - The partial derivative of cpotential density referenced -! to the surface with salinity, in kg m-3 psu-1. -! (in) dRcv_dT - The partial derivative of coordinate defining potential -! density with potential temperature, in kg m-3 K-1. -! (in) dRcv_dS - The partial derivative of coordinate defining potential -! density with salinity, in kg m-3 psu-1. + ! Local variables real :: h_to_bl ! The total thickness detrained to the buffer - ! layers, in H (the units of h). - real :: R0_to_bl, Rcv_to_bl ! The depth integrated amount of R0, Rcv, T - real :: T_to_bl, S_to_bl ! and S that is detrained to the buffer layer, - ! in H kg m-3, H kg m-3, K H, and psu H. - - real :: h_min_bl ! The minimum buffer layer thickness, in H. + ! layers [H ~> m or kg m-2]. + real :: R0_to_bl ! The depth integrated amount of R0 that is detrained to the + ! buffer layer [H kg m-3 ~> kg m-2 or kg2 m-5] + real :: Rcv_to_bl ! The depth integrated amount of Rcv that is detrained to the + ! buffer layer [H kg m-3 ~> kg m-2 or kg2 m-5] + real :: T_to_bl ! The depth integrated amount of T that is detrained to the + ! buffer layer [degC H ~> degC m or degC kg m-2] + real :: S_to_bl ! The depth integrated amount of S that is detrained to the + ! buffer layer [ppt H ~> ppt m or ppt kg m-2] + real :: h_min_bl ! The minimum buffer layer thickness [H ~> m or kg m-2]. real :: h_min_bl_thick ! The minimum buffer layer thickness when the - ! mixed layer is very large, in H. + ! mixed layer is very large [H ~> m or kg m-2]. real :: h_min_bl_frac_ml = 0.05 ! The minimum buffer layer thickness relative ! to the total mixed layer thickness for thin - ! mixed layers, nondim., maybe 0.1/CS%nkbl. + ! mixed layers [nondim], maybe 0.1/CS%nkbl. real :: h1, h2 ! Scalar variables holding the values of - ! h(i,CS%nkml+1) and h(i,CS%nkml+2), in H. - real :: h1_avail ! The thickess of the upper buffer layer + ! h(i,CS%nkml+1) and h(i,CS%nkml+2) [H ~> m or kg m-2]. + real :: h1_avail ! The thickness of the upper buffer layer ! available to move into the lower buffer - ! layer, in H. + ! layer [H ~> m or kg m-2]. real :: stays ! stays is the thickness of the upper buffer - ! layer that remains there, in units of H. + ! layer that remains there [H ~> m or kg m-2]. real :: stays_min, stays_max ! The minimum and maximum permitted values of - ! stays, in units of H. + ! stays [H ~> m or kg m-2]. logical :: mergeable_bl ! If true, it is an option to combine the two ! buffer layers and create water that matches ! the target density of an interior layer. real :: stays_merge ! If the two buffer layers can be combined ! stays_merge is the thickness of the upper - ! layer that remains, in units of H. - real :: stays_min_merge ! The minimum allowed value of stays_merge in H. + ! layer that remains [H ~> m or kg m-2]. + real :: stays_min_merge ! The minimum allowed value of stays_merge [H ~> m or kg m-2]. - real :: dR0_2dz, dRcv_2dz ! Half the vertical gradients of R0, Rcv, T, and -! real :: dT_2dz, dS_2dz ! S, in kg m-4, kg m-4, K m-1, and psu m-1. + real :: dR0_2dz, dRcv_2dz ! Half the vertical gradients of R0 and Rcv [kg m-3 H-1 ~> kg m-4 or m-1] +! real :: dT_2dz, dS_2dz ! Half the vertical gradients of T and S, in degC H-1, and ppt H-1. real :: scale_slope ! A nondimensional number < 1 used to scale down ! the slope within the upper buffer layer when ! water MUST be detrained to the lower layer. real :: dPE_extrap ! The potential energy change due to dispersive ! advection or mixing layers, divided by - ! rho_0*g, in units of H2. + ! rho_0*g [H2 ~> m2 or kg2 m-4]. real :: dPE_det, dPE_merge ! The energy required to mix the detrained water ! into the buffer layer or the merge the two - ! buffer layers, both in units of J H2 Z m-5. + ! buffer layers [J H2 Z m-5 ~> J m-2 or J kg2 m-8]. real :: h_from_ml ! The amount of additional water that must be - ! drawn from the mixed layer, in H. + ! drawn from the mixed layer [H ~> m or kg m-2]. real :: h_det_h2 ! The amount of detrained water and mixed layer ! water that will go directly into the lower - ! buffer layer, in H. - real :: h_det_to_h2, h_ml_to_h2 ! All of the variables hA_to_hB are the - real :: h_det_to_h1, h_ml_to_h1 ! thickess fluxes from one layer to another, - real :: h1_to_h2, h1_to_k0 ! in H, with h_det the detrained water, h_ml + ! buffer layer [H ~> m or kg m-2]. + real :: h_det_to_h2, h_ml_to_h2 ! All of the variables hA_to_hB are the thickness fluxes + real :: h_det_to_h1, h_ml_to_h1 ! from one layer to another [H ~> m or kg m-2], + real :: h1_to_h2, h1_to_k0 ! with h_det the detrained water, h_ml real :: h2_to_k1, h2_to_k1_rem ! the actively mixed layer, h1 and h2 the upper ! and lower buffer layers, and k0 and k1 the ! interior layers that are just lighter and ! just denser than the lower buffer layer. - real :: R0_det, T_det, S_det ! Detrained values of R0, T, and S. + real :: R0_det, T_det, S_det ! Detrained values of R0 [kg m-3], T [degC], and S [ppt]. real :: Rcv_stays, R0_stays ! Values of Rcv and R0 that stay in a layer. real :: T_stays, S_stays ! Values of T and S that stay in a layer. real :: dSpice_det, dSpice_stays! The spiciness difference between an original ! buffer layer and the water that moves into ! an interior layer or that stays in that - ! layer, in kg m-3. + ! layer [kg m-3]. real :: dSpice_lim, dSpice_lim2 ! Limits to the spiciness difference between ! the lower buffer layer and the water that - ! moves into an interior layer, in kg m-3. + ! moves into an interior layer [kg m-3]. real :: dSpice_2dz ! The vertical gradient of spiciness used for - ! advection, in kg m-4. + ! advection [kg m-3 H-1 ~> kg m-4 or m-1]. real :: dPE_ratio ! Multiplier of dPE_det at which merging is ! permitted - here (detrainment_per_day/dt)*30 @@ -2396,34 +2326,34 @@ subroutine mixedlayer_detrain_2(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, j, real :: num_events ! The number of detrainment events over which ! to prefer merging the buffer layers. real :: detrainment_timescale ! The typical timescale for a detrainment - ! event, in s. + ! event [s]. real :: dPE_time_ratio ! Larger of 1 and the detrainment_timescale ! over dt, nondimensional. real :: dT_dS_gauge, dS_dT_gauge ! The relative scales of temperature and ! salinity changes in defining spiciness, in - ! K psu-1 and psu K-1. - real :: I_denom ! A work variable with units of psu2 m6 kg-2. - - real :: G_2 ! 1/2 G_Earth, in m2 Z-1 s-2. - real :: Rho0xG ! Rho0 times G_Earth, in kg m-1 Z-1 s-2. - real :: I2Rho0 ! 1 / (2 Rho0), in m3 kg-1. - real :: Idt_H2 ! The square of the conversion from thickness - ! to Z divided by the time step in Z2 H-2 s-1. + ! [degC ppt-1] and [ppt degC-1]. + real :: I_denom ! A work variable with units of [ppt2 m6 kg-2]. + + real :: G_2 ! 1/2 G_Earth [m2 Z-1 s-2 ~> m s-2]. + real :: Rho0xG ! Rho0 times G_Earth [kg m-1 Z-1 s-2 ~> kg m-2 s-2]. + real :: I2Rho0 ! 1 / (2 Rho0) [m3 kg-1]. + real :: Idt_H2 ! The square of the conversion from thickness to Z + ! divided by the time step [Z2 H-2 s-1 ~> s-1 or m6 kg-2 s-1]. logical :: stable_Rcv ! If true, the buffer layers are stable with ! respect to the coordinate potential density. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. - real :: s1en ! A work variable with units of H2 kg m s-3. - real :: s1, s2, bh0 ! Work variables with units of H. - real :: s3sq ! A work variable with units of H2. + real :: s1en ! A work variable [H2 kg m s-3 ~> kg m3 s-3 or kg3 m-3 s-3]. + real :: s1, s2, bh0 ! Work variables [H ~> m or kg m-2]. + real :: s3sq ! A work variable [H2 ~> m2 or kg2 m-4]. real :: I_ya, b1 ! Nondimensional work variables. real :: Ih, Ihdet, Ih1f, Ih2f ! Assorted inverse thickness work variables, - real :: Ihk0, Ihk1, Ih12 ! all with units of H-1. + real :: Ihk0, Ihk1, Ih12 ! all in [H-1 ~> m-1 or m2 kg-1]. real :: dR1, dR2, dR2b, dRk1 ! Assorted density difference work variables, - real :: dR0, dR21, dRcv ! all with units of kg m-3. + real :: dR0, dR21, dRcv ! all in [kg m-3]. real :: dRcv_stays, dRcv_det, dRcv_lim - real :: Angstrom ! The minumum layer thickness, in H. + real :: Angstrom ! The minumum layer thickness [H ~> m or kg m-2]. real :: h2_to_k1_lim, T_new, S_new, T_max, T_min, S_max, S_min character(len=200) :: mesg @@ -3173,27 +3103,25 @@ subroutine mixedlayer_detrain_1(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, d_e j, G, GV, CS, dRcv_dT, dRcv_dS, max_BL_det) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: h !< Layer thickness, in m or kg m-2. - !! (Intent in/out) The units of h are - !! referred to as H below. Layer 0 is - !! the new mixed layer. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: T !< Potential temperature, in C. - real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: S !< Salinity, in psu. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2]. + !! Layer 0 is the new mixed layer. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: T !< Potential temperature [degC]. + real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: S !< Salinity [ppt]. real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: R0 !< Potential density referenced to - !! surface pressure, in kg m-3. + !! surface pressure [kg m-3]. real, dimension(SZI_(G),SZK0_(GV)), intent(inout) :: Rcv !< The coordinate defining potential - !! density, in kg m-3. + !! density [kg m-3]. real, dimension(SZK_(GV)), intent(in) :: RcvTgt !< The target value of Rcv for each - !! layer, in kg m-3. - real, intent(in) :: dt !< Time increment, in s. + !! layer [kg m-3]. + real, intent(in) :: dt !< Time increment [s]. real, intent(in) :: dt_diag !< The accumulated time interval for - !! diagnostics, in s. + !! diagnostics [s]. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: d_ea !< The upward increase across a layer in - !! the entrainment from above, in m or - !! kg m-2 (H). Positive d_ea goes with - !! layer thickness increases. + !! the entrainment from above + !! [H ~> m or kg m-2]. Positive d_ea + !! goes with layer thickness increases. real, dimension(SZI_(G),SZK_(GV)), intent(inout) :: d_eb !< The downward increase across a layer - !! in the entrainment from below, in H. + !! in the entrainment from below [H ~> m or kg m-2]. !! Positive values go with mass gain by !! a layer. integer, intent(in) :: j !< The meridional row to work on. @@ -3201,60 +3129,33 @@ subroutine mixedlayer_detrain_1(h, T, S, R0, Rcv, RcvTgt, dt, dt_diag, d_ea, d_e !! previous call to mixedlayer_init. real, dimension(SZI_(G)), intent(in) :: dRcv_dT !< The partial derivative of !! coordinate defining potential density - !! with potential temperature, - !! in kg m-3 K-1. + !! with potential temperature + !! [kg m-3 degC-1]. real, dimension(SZI_(G)), intent(in) :: dRcv_dS !< The partial derivative of !! coordinate defining potential density - !! with salinity, in kg m-3 psu-1. + !! with salinity [kg m-3 ppt-1]. real, dimension(SZI_(G)), intent(in) :: max_BL_det !< If non-negative, the maximum !! detrainment permitted from the buffer - !! layers, in H. + !! layers [H ~> m or kg m-2]. -! This subroutine moves any water left in the former mixed layers into the -! single buffer layers and may also move buffer layer water into the interior -! isopycnal layers. - -! Arguments: h - Layer thickness, in m or kg m-2. (Intent in/out) The units of -! h are referred to as H below. Layer 0 is the new mixed layer. -! (in/out) T - Potential temperature, in C. -! (in/out) S - Salinity, in psu. -! (in/out) R0 - Potential density referenced to surface pressure, in kg m-3. -! (in/out) Rcv - The coordinate defining potential density, in kg m-3. -! (in) RcvTgt - The target value of Rcv for each layer, in kg m-3. -! (in) dt - Time increment, in s. -! (in/out) d_ea - The upward increase across a layer in the entrainment from -! above, in m or kg m-2 (H). Positive d_ea goes with layer -! thickness increases. -! (in/out) d_eb - The downward increase across a layer in the entrainment from -! below, in H. Positive values go with mass gain by a layer. -! (in) j - The meridional row to work on. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! mixedlayer_init. -! (in) max_BL_det - If non-negative, the maximum detrainment permitted -! from the buffer layers, in H. -! (in/out) dRcv_dT - The partial derivative of coordinate defining potential -! density with potential temperature, in kg m-3 K-1. -! (in/out) dRcv_dS - The partial derivative of coordinate defining potential -! density with salinity, in kg m-3 psu-1. - real :: Ih ! The inverse of a thickness, in H-1. + ! Local variables + real :: Ih ! The inverse of a thickness [H-1 ~> m-1 or m2 kg-1]. real :: h_ent ! The thickness from a layer that is - ! entrained, in H. - real :: max_det_rem(SZI_(G)) ! Remaining permitted detrainment, in H. + ! entrained [H ~> m or kg m-2]. + real :: max_det_rem(SZI_(G)) ! Remaining permitted detrainment [H ~> m or kg m-2]. real :: detrain(SZI_(G)) ! The thickness of fluid to detrain - ! from the mixed layer, in H. - real :: Idt ! The inverse of the timestep in s-1. + ! from the mixed layer [H ~> m or kg m-2]. + real :: Idt ! The inverse of the timestep [s-1]. real :: dT_dR, dS_dR, dRml, dR0_dRcv, dT_dS_wt2 - real :: I_denom ! A work variable with units of psu2 m6 kg-2. + real :: I_denom ! A work variable [ppt2 m6 kg-2]. real :: Sdown, Tdown real :: dt_Time, Timescale = 86400.0*30.0! *365.0/12.0 - real :: g_H2_2Rho0dt ! Half the gravitational acceleration times the square of - ! the conversion from H to m divided by the mean - ! density times the time step, in m7 s-3 Z-1 H-2 kg-1. !### CHECK UNITS - real :: g_H2_2dt ! Half the gravitational acceleration times the - ! square of the conversion from H to m divided - ! by the diagnostic time step, in m4 Z-1 H-2 s-3. + real :: g_H2_2Rho0dt ! Half the gravitational acceleration times the square of the + ! conversion from H to m divided by the mean density times the time + ! step [m7 s-3 Z-1 H-2 kg-1 ~> m4 s-3 kg-1 or m10 s-3 kg-3]. + real :: g_H2_2dt ! Half the gravitational acceleration times the square of the + ! conversion from H to m divided by the diagnostic time step + ! [m4 Z-1 H-2 s-3 ~> m s-3 or m7 kg-2 s-3]. logical :: splittable_BL(SZI_(G)), orthogonal_extrap real :: x1 @@ -3761,36 +3662,25 @@ end subroutine bulkmixedlayer_init !! R = exp(-L*(H+E)) integral(LH to L(H+E)) L/(1-(1+x)exp(-x)) dx. !! The approximation to the integrand is good to within -2% at x~.3 !! and +25% at x~3.5, but the exponential deemphasizes the importance of -!! large x. When L=0, EF4 returns E/((H+E)*H). -function EF4(H, E, L, dR_de) - real, intent(in) :: H !< Total thickness, in m or kg m-2. (Intent in) The units of h - !! are referred to as H below. - real, intent(in) :: E !< Entrainment, in units of H. - real, intent(in) :: L !< The e-folding scale in H-1. - real, optional, intent(inout) :: dR_de !< The partial derivative of the result R with E, in H-2. - real :: EF4 -! This subroutine returns an approximation to the integral -! R = exp(-L*(H+E)) integral(LH to L(H+E)) L/(1-(1+x)exp(-x)) dx. -! The approximation to the integrand is good to within -2% at x~.3 -! and +25% at x~3.5, but the exponential deemphasizes the importance of -! large x. When L=0, EF4 returns E/((H+E)*H). -! -! Arguments: h - Total thickness, in m or kg m-2. (Intent in) The units -! of h are referred to as H below. -! (in) E - Entrainment, in units of H. -! (in) L - The e-folding scale in H-1. -! (out) dR_de - the partial derivative of the result R with E, in H-2. -! (return value) R - The integral, in units of H-1. +!! large x. When L=0, EF4 returns E/((Ht+E)*Ht). +function EF4(Ht, En, I_L, dR_de) + real, intent(in) :: Ht !< Total thickness [H ~> m or kg m-2]. + real, intent(in) :: En !< Entrainment [H ~> m or kg m-2]. + real, intent(in) :: I_L !< The e-folding scale [H-1 ~> m-1 or m2 kg-1] + real, optional, intent(inout) :: dR_de !< The partial derivative of the result R with E [H-2 ~> m-2 or m4 kg-2]. + real :: EF4 !< The integral [H-1 ~> m-1 or m2 kg-1]. + + ! Local variables real :: exp_LHpE ! A nondimensional exponential decay. - real :: I_HpE ! An inverse thickness plus entrainment, in H-1. - real :: R ! The result of the integral above, in H-1. + real :: I_HpE ! An inverse thickness plus entrainment [H-1 ~> m-1 or m2 kg-1]. + real :: Res ! The result of the integral above [H-1 ~> m-1 or m2 kg-1]. - exp_LHpE = exp(-L*(E+H)) - I_HpE = 1.0/(H+E) - R = exp_LHpE * (E*I_HpE/H - 0.5*L*log(H*I_HpE) + 0.5*L*L*E) + exp_LHpE = exp(-I_L*(En+Ht)) + I_HpE = 1.0/(Ht+En) + Res = exp_LHpE * (En*I_HpE/Ht - 0.5*I_L*log(Ht*I_HpE) + 0.5*I_L*I_L*En) if (PRESENT(dR_de)) & - dR_de = -L*R + exp_LHpE*(I_HpE*I_HpE + 0.5*L*I_HpE + 0.5*L*L) - EF4 = R + dR_de = -I_L*Res + exp_LHpE*(I_HpE*I_HpE + 0.5*I_L*I_HpE + 0.5*I_L*I_L) + EF4 = Res end function EF4 diff --git a/src/parameterizations/vertical/MOM_diabatic_aux.F90 b/src/parameterizations/vertical/MOM_diabatic_aux.F90 index 161967c59a..7cb566ddba 100644 --- a/src/parameterizations/vertical/MOM_diabatic_aux.F90 +++ b/src/parameterizations/vertical/MOM_diabatic_aux.F90 @@ -28,11 +28,16 @@ module MOM_diabatic_aux public make_frazil, adjust_salt, insert_brine, differential_diffuse_T_S, triDiagTS public find_uv_at_h, diagnoseMLDbyDensityDifference, applyBoundaryFluxesInOut +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for diabatic_aux type, public :: diabatic_aux_CS ; private logical :: do_rivermix = .false. !< Provide additional TKE to mix river runoff at the !! river mouths to a depth of "rivermix_depth" - real :: rivermix_depth = 0.0 !< The depth to which rivers are mixed if do_rivermix = T, in Z. + real :: rivermix_depth = 0.0 !< The depth to which rivers are mixed if do_rivermix = T [Z ~> m]. logical :: reclaim_frazil !< If true, try to use any frazil heat deficit to !! to cool the topmost layer down to the freezing !! point. The default is false. @@ -61,10 +66,14 @@ module MOM_diabatic_aux integer :: id_nonpenSW_diag = -1 !< Diagnostic ID of Non-penetrative shortwave heating ! Optional diagnostic arrays - real, allocatable, dimension(:,:) :: createdH !< The amount of volume added in order to avoid grounding (m/s) - real, allocatable, dimension(:,:,:) :: penSW_diag !< Heating in a layer from convergence of penetrative SW (W/m2) - real, allocatable, dimension(:,:,:) :: penSWflux_diag !< Penetrative SW flux at base of grid layer (W/m2) - real, allocatable, dimension(:,:) :: nonpenSW_diag !< Non-downwelling SW radiation (W/m2) at ocean surface + real, allocatable, dimension(:,:) :: createdH !< The amount of volume added in order to + !! avoid grounding [m s-1] + real, allocatable, dimension(:,:,:) :: penSW_diag !< Heating in a layer from convergence of + !! penetrative SW [W m-2] + real, allocatable, dimension(:,:,:) :: penSWflux_diag !< Penetrative SW flux at base of grid + !! layer [W m-2] + real, allocatable, dimension(:,:) :: nonpenSW_diag !< Non-downwelling SW radiation at ocean + !! surface [W m-2] end type diabatic_aux_CS @@ -82,36 +91,23 @@ subroutine make_frazil(h, tv, G, GV, CS, p_surf, halo) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Structure containing pointers to any available !! thermodynamic fields. type(diabatic_aux_CS), intent(in) :: CS !< The control structure returned by a previous !! call to diabatic_aux_init. real, dimension(SZI_(G),SZJ_(G)), & - optional, intent(in) :: p_surf !< The pressure at the ocean surface, in Pa. + optional, intent(in) :: p_surf !< The pressure at the ocean surface [Pa]. integer, optional, intent(in) :: halo !< Halo width over which to calculate frazil -! Frazil formation keeps the temperature above the freezing point. -! This subroutine warms any water that is colder than the (currently -! surface) freezing point up to the freezing point and accumulates -! the required heat (in J m-2) in tv%frazil. -! The expression, below, for the freezing point of sea water comes -! from Millero (1978) via Appendix A of Gill, 1982. - -! Arguments: h - Layer thickness, in m or kg m-2. -! (in/out) tv - A structure containing pointers to any available -! thermodynamic fields. Absent fields have NULL ptrs. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! diabatic_driver_init. + ! Local variables real, dimension(SZI_(G)) :: & - fraz_col, & ! The accumulated heat requirement due to frazil, in J. - T_freeze, & ! The freezing potential temperature at the current salinity, C. + fraz_col, & ! The accumulated heat requirement due to frazil [J]. + T_freeze, & ! The freezing potential temperature at the current salinity [degC]. ps ! pressure real, dimension(SZI_(G),SZK_(G)) :: & - pressure ! The pressure at the middle of each layer in Pa. - real :: hc ! A layer's heat capacity in J m-2 K-1. + pressure ! The pressure at the middle of each layer [Pa]. + real :: hc ! A layer's heat capacity [J m-2 degC-1]. logical :: T_fr_set ! True if the freezing point has been calculated for a ! row of points. integer :: i, j, k, is, ie, js, je, nz @@ -215,31 +211,31 @@ subroutine differential_diffuse_T_S(h, tv, visc, dt, G, GV) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Structure containing pointers to any !! available thermodynamic fields. type(vertvisc_type), intent(in) :: visc !< Structure containing vertical viscosities, bottom !! boundary layer properies, and related fields. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. ! local variables real, dimension(SZI_(G)) :: & - b1_T, b1_S, & ! Variables used by the tridiagonal solvers of T & S, in H. - d1_T, d1_S ! Variables used by the tridiagonal solvers, nondim. + b1_T, b1_S, & ! Variables used by the tridiagonal solvers of T & S [H ~> m or kg m-2]. + d1_T, d1_S ! Variables used by the tridiagonal solvers [nondim]. real, dimension(SZI_(G),SZK_(G)) :: & - c1_T, c1_S ! Variables used by the tridiagonal solvers, in H. + c1_T, c1_S ! Variables used by the tridiagonal solvers [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)+1) :: & - mix_T, mix_S ! Mixing distances in both directions across each interface, in H. + mix_T, mix_S ! Mixing distances in both directions across each interface [H ~> m or kg m-2]. real :: h_tr ! h_tr is h at tracer points with a tiny thickness - ! added to ensure positive definiteness, in H. + ! added to ensure positive definiteness [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: I_h_int ! The inverse of the thickness associated with an - ! interface, in H-1. + ! interface [H-1 ~> m-1 or m2 kg-1]. real :: b_denom_T ! The first term in the denominators for the expressions - real :: b_denom_S ! for b1_T and b1_S, both in H. + real :: b_denom_S ! for b1_T and b1_S, both [H ~> m or kg m-2]. real, dimension(:,:,:), pointer :: T=>NULL(), S=>NULL() - real, dimension(:,:,:), pointer :: Kd_T=>NULL(), Kd_S=>NULL() ! Diffusivities in Z2 s-1. + real, dimension(:,:,:), pointer :: Kd_T=>NULL(), Kd_S=>NULL() ! Diffusivities [Z2 s-1 ~> m2 s-1]. integer :: i, j, k, is, ie, js, je, nz is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke @@ -318,7 +314,7 @@ subroutine adjust_salt(h, tv, G, GV, CS, halo) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Structure containing pointers to any !! available thermodynamic fields. type(diabatic_aux_CS), intent(in) :: CS !< The control structure returned by a previous @@ -381,14 +377,14 @@ subroutine insert_brine(h, tv, G, GV, fluxes, nkmb, CS, dt, id_brine_lay) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Structure containing pointers to any !! available thermodynamic fields type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes integer, intent(in) :: nkmb !< The number of layers in the mixed and buffer layers type(diabatic_aux_CS), intent(in) :: CS !< The control structure returned by a previous !! call to diabatic_aux_init - real, intent(in) :: dt !< The thermodyanmic time step, in s. + real, intent(in) :: dt !< The thermodyanmic time step [s]. integer, intent(in) :: id_brine_lay !< The handle for a diagnostic !! which layer receivees the brine. @@ -403,7 +399,7 @@ subroutine insert_brine(h, tv, G, GV, fluxes, nkmb, CS, dt, id_brine_lay) real :: S(SZI_(G),SZK_(G)) real :: h_2d(SZI_(G),SZK_(G)) real :: Rcv(SZI_(G),SZK_(G)) - real :: mc ! A layer's mass in kg m-2 . + real :: mc ! A layer's mass [kg m-2]. real :: s_new,R_new,t0,scale, cdz integer :: i, j, k, is, ie, js, je, nz, ks @@ -504,13 +500,14 @@ subroutine triDiagTS(G, GV, is, ie, js, je, hold, ea, eb, T, S) integer, intent(in) :: ie !< The end i-index to work on. integer, intent(in) :: js !< The start j-index to work on. integer, intent(in) :: je !< The end j-index to work on. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: hold !< The layer thicknesses before entrainment, in H. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: hold !< The layer thicknesses before entrainment, + !! [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: ea !< The amount of fluid entrained from the layer - !! above within this time step, in units of H. + !! above within this time step [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: eb !< The amount of fluid entrained from the layer - !! below within this time step, in units of H. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: T !< Layer potential temperatures, in degC. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: S !< Layer salinities, in PSU. + !! below within this time step [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: T !< Layer potential temperatures [degC]. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: S !< Layer salinities [ppt]. ! Local variables real :: b1(SZIB_(G)), d1(SZIB_(G)) ! b1, c1, and d1 are variables used by the @@ -549,28 +546,28 @@ subroutine find_uv_at_h(u, v, h, u_h, v_h, G, GV, ea, eb) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1 + intent(in) :: u !< The zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1 + intent(in) :: v !< The meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u_h !< Zonal velocity interpolated to h points, in m s-1. + intent(out) :: u_h !< Zonal velocity interpolated to h points [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: v_h !< Meridional velocity interpolated to h points, in m s-1. + intent(out) :: v_h !< Meridional velocity interpolated to h points [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(in) :: ea !< The amount of fluid entrained from the layer - !! above within this time step, in units of H. + !! above within this time step [H ~> m or kg m-2]. !! Omitting ea is the same as setting it to 0. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(in) :: eb !< The amount of fluid entrained from the layer - !! below within this time step, in units of H. + !! below within this time step [H ~> m or kg m-2]. !! Omitting eb is the same as setting it to 0. ! local variables - real :: b_denom_1 ! The first term in the denominator of b1 in m or kg m-2. + real :: b_denom_1 ! The first term in the denominator of b1 [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m or kg m-2. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: b1(SZI_(G)), d1(SZI_(G)), c1(SZI_(G),SZK_(G)) real :: a_n(SZI_(G)), a_s(SZI_(G)) ! Fractional weights of the neighboring real :: a_e(SZI_(G)), a_w(SZI_(G)) ! velocity points, ~1/2 in the open @@ -652,26 +649,26 @@ subroutine diagnoseMLDbyDensityDifference(id_MLD, h, tv, densityDiff, G, GV, US, type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type integer, intent(in) :: id_MLD !< Handle (ID) of MLD diagnostic real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in H (usually m or kg m-3) + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any !! available thermodynamic fields. - real, intent(in) :: densityDiff !< Density difference to determine MLD (kg/m3) + real, intent(in) :: densityDiff !< Density difference to determine MLD [kg m-3] type(diag_ctrl), pointer :: diagPtr !< Diagnostics structure integer, optional, intent(in) :: id_N2subML !< Optional handle (ID) of subML stratification integer, optional, intent(in) :: id_MLDsq !< Optional handle (ID) of squared MLD ! Local variables - real, dimension(SZI_(G)) :: deltaRhoAtKm1, deltaRhoAtK ! Density differences, in kg m-3. - real, dimension(SZI_(G)) :: pRef_MLD, pRef_N2 ! Reference pressures in Pa. - real, dimension(SZI_(G)) :: dK, dKm1, d1 ! Depths in Z. - real, dimension(SZI_(G)) :: rhoSurf, rhoAtK, rho1 ! Densities used for N2, in kg m-3. - real, dimension(SZI_(G), SZJ_(G)) :: MLD ! Diagnosed mixed layer depth, in Z. - real, dimension(SZI_(G), SZJ_(G)) :: subMLN2 ! Diagnosed stratification below ML, in s-2. - real, dimension(SZI_(G), SZJ_(G)) :: MLD2 ! Diagnosed MLD^2, in Z2. + real, dimension(SZI_(G)) :: deltaRhoAtKm1, deltaRhoAtK ! Density differences [kg m-3]. + real, dimension(SZI_(G)) :: pRef_MLD, pRef_N2 ! Reference pressures [Pa]. + real, dimension(SZI_(G)) :: dK, dKm1, d1 ! Depths [Z ~> m]. + real, dimension(SZI_(G)) :: rhoSurf, rhoAtK, rho1 ! Densities used for N2 [kg m-3]. + real, dimension(SZI_(G), SZJ_(G)) :: MLD ! Diagnosed mixed layer depth [Z ~> m]. + real, dimension(SZI_(G), SZJ_(G)) :: subMLN2 ! Diagnosed stratification below ML [s-2]. + real, dimension(SZI_(G), SZJ_(G)) :: MLD2 ! Diagnosed MLD^2 [Z2 ~> m2]. real :: Rho_x_gE ! The product of density, gravitational acceleartion and a unit - ! conversion factor, in kg m-1 Z-1 s-2. - real :: gE_Rho0 ! The gravitational acceleration divided by a mean density, in m4 s-2 kg-1. - real :: dz_subML ! Depth below ML over which to diagnose stratification, in Z. + ! conversion factor [kg m-1 Z-1 s-2 ~> kg m-2 s-2]. + real :: gE_Rho0 ! The gravitational acceleration divided by a mean density [m4 s-2 kg-1]. + real :: dz_subML ! Depth below ML over which to diagnose stratification [Z ~> m]. integer :: i, j, is, ie, js, je, k, nz, id_N2, id_SQ real :: aFac, ddRho @@ -771,29 +768,29 @@ subroutine applyBoundaryFluxesInOut(CS, G, GV, US, dt, fluxes, optics, h, tv, & type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(in) :: dt !< Time-step over which forcing is applied (s) + real, intent(in) :: dt !< Time-step over which forcing is applied [s] type(forcing), intent(inout) :: fluxes !< Surface fluxes container type(optics_type), pointer :: optics !< Optical properties container real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thickness in H units + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< Structure containing pointers to any !! available thermodynamic fields. logical, intent(in) :: aggregate_FW_forcing !< If False, treat in/out fluxes separately. real, intent(in) :: evap_CFL_limit !< The largest fraction of a layer that - !! can be evaporated in one time-step (non-dim). + !! can be evaporated in one time-step [nondim]. real, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! heat and freshwater fluxes is applied, in m. + !! heat and freshwater fluxes is applied [m]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: cTKE !< Turbulent kinetic energy requirement to mix - !! forcing through each layer, in W m-2 + !! forcing through each layer [W m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: dSV_dT !< Partial derivative of specific volume with - !! potential temperature, in m3 kg-1 K-1. + !! potential temperature [m3 kg-1 degC-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & optional, intent(out) :: dSV_dS !< Partial derivative of specific volume with - !! salinity, in m3 kg-1 / (g kg-1). + !! salinity [m3 kg-1 ppt-1]. real, dimension(SZI_(G),SZJ_(G)), & - optional, intent(out) :: SkinBuoyFlux !< Buoyancy flux at surface in Z2 s-3 + optional, intent(out) :: SkinBuoyFlux !< Buoyancy flux at surface [Z2 s-3 ~> m2 s-3]. ! Local variables integer, parameter :: maxGroundings = 5 @@ -801,24 +798,27 @@ subroutine applyBoundaryFluxesInOut(CS, G, GV, US, dt, fluxes, optics, h, tv, & real :: H_limit_fluxes, IforcingDepthScale, Idt real :: dThickness, dTemp, dSalt real :: fractionOfForcing, hOld, Ithickness - real :: RivermixConst ! A constant used in implementing river mixing, in Pa s. + real :: RivermixConst ! A constant used in implementing river mixing [Pa s]. real, dimension(SZI_(G)) :: & - d_pres, & ! pressure change across a layer (Pa) - p_lay, & ! average pressure in a layer (Pa) - pres, & ! pressure at an interface (Pa) - netMassInOut, & ! surface water fluxes (H units) over time step - netMassIn, & ! mass entering ocean surface (H units) over a time step - netMassOut, & ! mass leaving ocean surface (H units) over a time step - netHeat, & ! heat (degC * H) via surface fluxes, excluding - ! Pen_SW_bnd and netMassOut + d_pres, & ! pressure change across a layer [Pa] + p_lay, & ! average pressure in a layer [Pa] + pres, & ! pressure at an interface [Pa] + netMassInOut, & ! surface water fluxes [H ~> m or kg m-2] over time step + netMassIn, & ! mass entering ocean surface [H ~> m or kg m-2] over a time step + netMassOut, & ! mass leaving ocean surface [H ~> m or kg m-2] over a time step + netHeat, & ! heat via surface fluxes excluding Pen_SW_bnd and netMassOut + ! [degC H ~> degC m or degC kg m-2] netSalt, & ! surface salt flux ( g(salt)/m2 for non-Bouss and ppt*H for Bouss ) + ! [ppt H ~> ppt m or ppt kg m-2] nonpenSW, & ! non-downwelling SW, which is absorbed at ocean surface - SurfPressure, & ! Surface pressure (approximated as 0.0) - dRhodT, & ! change in density per change in temperature - dRhodS, & ! change in density per change in salinity - netheat_rate, & ! netheat but for dt=1 (e.g. returns a rate) + ! [degC H ~> degC m or degC kg m-2] + SurfPressure, & ! Surface pressure (approximated as 0.0) [Pa] + dRhodT, & ! change in density per change in temperature [kg m-3 degC-1] + dRhodS, & ! change in density per change in salinity [kg m-3 ppt-1] + netheat_rate, & ! netheat but for dt=1 [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1] netsalt_rate, & ! netsalt but for dt=1 (e.g. returns a rate) - netMassInOut_rate! netmassinout but for dt=1 (e.g. returns a rate) + ! [ppt H s-1 ~> ppt m s-1 or ppt kg m-2 s-1] + netMassInOut_rate! netmassinout but for dt=1 [H s-1 ~> m s-1 or kg m-2 s-1] real, dimension(SZI_(G), SZK_(G)) :: h2d, T2d real, dimension(SZI_(G), SZK_(G)) :: pen_TKE_2d, dSV_dT_2d real, dimension(SZI_(G),SZK_(G)+1) :: netPen @@ -829,7 +829,8 @@ subroutine applyBoundaryFluxesInOut(CS, G, GV, US, dt, fluxes, optics, h, tv, & real :: Temp_in, Salin_in ! real :: I_G_Earth real :: g_Hconv2 - real :: GoRho ! g_Earth times a unit conversion factor divided by density, in Z m3 s-2 kg-1 + real :: GoRho ! g_Earth times a unit conversion factor divided by density + ! [Z m3 s-2 kg-1 ~> m4 s-2 kg-1] logical :: calculate_energetics logical :: calculate_buoyancy integer :: i, j, is, ie, js, je, k, nz, n, nsw @@ -921,14 +922,14 @@ subroutine applyBoundaryFluxesInOut(CS, G, GV, US, dt, fluxes, optics, h, tv, & ! The surface forcing is contained in the fluxes type. ! We aggregate the thermodynamic forcing for a time step into the following: - ! netMassInOut = surface water fluxes (H units) over time step + ! netMassInOut = surface water fluxes [H ~> m or kg m-2] over time step ! = lprec + fprec + vprec + evap + lrunoff + frunoff ! note that lprec generally has sea ice melt/form included. - ! netMassOut = net mass leaving ocean surface (H units) over a time step. + ! netMassOut = net mass leaving ocean surface [H ~> m or kg m-2] over a time step. ! netMassOut < 0 means mass leaves ocean. - ! netHeat = heat (degC * H) via surface fluxes, excluding the part + ! netHeat = heat via surface fluxes [degC H ~> degC m or degC kg m-2], excluding the part ! contained in Pen_SW_bnd; and excluding heat_content of netMassOut < 0. - ! netSalt = surface salt fluxes ( g(salt)/m2 for non-Bouss and ppt*H for Bouss ) + ! netSalt = surface salt fluxes [ppt H ~> dppt m or gSalt m-2] ! Pen_SW_bnd = components to penetrative shortwave radiation split according to bands. ! This field provides that portion of SW from atmosphere that in fact ! enters to the ocean and participates in pentrative SW heating. @@ -1034,7 +1035,7 @@ subroutine applyBoundaryFluxesInOut(CS, G, GV, US, dt, fluxes, optics, h, tv, & ! as follows: ! TKE_river[m3 s-3] = 0.5*rivermix_depth*g*(1/rho)*drho_ds* ! River*(Samb - Sriver) = CS%mstar*U_star^3 - ! where River is in units of m s-1. + ! where River is in units of [m s-1]. ! Samb = Ambient salinity at the mouth of the estuary ! rivermix_depth = The prescribed depth over which to mix river inflow ! drho_ds = The gradient of density wrt salt at the ambient surface salinity. @@ -1204,7 +1205,7 @@ subroutine applyBoundaryFluxesInOut(CS, G, GV, US, dt, fluxes, optics, h, tv, & tv%T(i,j,k) = T2d(i,k) enddo ; enddo - ! Diagnose heating (W/m2) applied to a grid cell from SW penetration + ! Diagnose heating [W m-2] applied to a grid cell from SW penetration ! Also diagnose the penetrative SW heat flux at base of layer. if (CS%id_penSW_diag > 0 .or. CS%id_penSWflux_diag > 0) then diff --git a/src/parameterizations/vertical/MOM_diabatic_driver.F90 b/src/parameterizations/vertical/MOM_diabatic_driver.F90 index 4506177f41..200d3efdf7 100644 --- a/src/parameterizations/vertical/MOM_diabatic_driver.F90 +++ b/src/parameterizations/vertical/MOM_diabatic_driver.F90 @@ -85,6 +85,11 @@ module MOM_diabatic_driver public adiabatic_driver_init public legacy_diabatic +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for this module type, public:: diabatic_CS; private logical :: bulkmixedlayer !< If true, a refined bulk mixed layer is used with @@ -148,15 +153,15 @@ module MOM_diabatic_driver !! operating. real :: Kd_BBL_tr !< A bottom boundary layer tracer diffusivity that !! will allow for explicitly specified bottom fluxes - !! in Z2 s-1. The entrainment at the bottom is at + !! [Z2 s-1 ~> m2 s-1]. The entrainment at the bottom is at !! least sqrt(Kd_BBL_tr*dt) over the same distance. real :: Kd_min_tr !< A minimal diffusivity that should always be !! applied to tracers, especially in massless layers - !! near the bottom, in Z2 s-1. + !! near the bottom [Z2 s-1 ~> m2 s-1]. real :: minimum_forcing_depth = 0.001 !< The smallest depth over which heat and freshwater - !! fluxes are applied, in m. + !! fluxes are applied [m]. real :: evap_CFL_limit = 0.8 !< The largest fraction of a layer that can be - !! evaporated in one time-step (non-dim). + !! evaporated in one time-step [nondim]. integer :: halo_TS_diff = 0 !< The temperature, salinity and thickness halo size that !! must be valid for the diffusivity calculations. logical :: useKPP = .false. !< use CVMix/KPP diffusivities and non-local transport @@ -241,11 +246,11 @@ module MOM_diabatic_driver type(group_pass_type) :: pass_Kv !< For group halo pass type(diag_grid_storage) :: diag_grids_prev!< Stores diagnostic grids at some previous point in the algorithm ! Data arrays for communicating between components - real, allocatable, dimension(:,:,:) :: KPP_NLTheat !< KPP non-local transport for heat (m/s) - real, allocatable, dimension(:,:,:) :: KPP_NLTscalar !< KPP non-local transport for scalars (m/s) - real, allocatable, dimension(:,:,:) :: KPP_buoy_flux !< KPP forcing buoyancy flux (m^2/s^3) - real, allocatable, dimension(:,:) :: KPP_temp_flux !< KPP effective temperature flux (K m/s) - real, allocatable, dimension(:,:) :: KPP_salt_flux !< KPP effective salt flux (ppt m/s) + real, allocatable, dimension(:,:,:) :: KPP_NLTheat !< KPP non-local transport for heat [m s-1] + real, allocatable, dimension(:,:,:) :: KPP_NLTscalar !< KPP non-local transport for scalars [m s-1] + real, allocatable, dimension(:,:,:) :: KPP_buoy_flux !< KPP forcing buoyancy flux [m2 s-3] + real, allocatable, dimension(:,:) :: KPP_temp_flux !< KPP effective temperature flux [degC m s-1] + real, allocatable, dimension(:,:) :: KPP_salt_flux !< KPP effective salt flux [ppt m s-1] type(time_type), pointer :: Time !< Pointer to model time (needed for sponges) end type diabatic_CS @@ -265,12 +270,12 @@ subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, & type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< zonal velocity (m/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< meridional velocity (m/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< thickness (m for Bouss / kg/m2 for non-Bouss) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< zonal velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< meridional velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< points to thermodynamic fields !! unused have NULL ptrs - real, dimension(:,:), pointer :: Hml !< mixed layer depth, m + real, dimension(:,:), pointer :: Hml !< mixed layer depth [m] type(forcing), intent(inout) :: fluxes !< points to forcing fields !! unused fields have NULL ptrs type(vertvisc_type), intent(inout) :: visc !< vertical viscosities, BBL properies, and @@ -278,7 +283,7 @@ subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, & !! equations, to enable the later derived !! diagnostics, like energy budgets type(cont_diag_ptrs), intent(inout) :: CDp !< points to terms in continuity equations - real, intent(in) :: dt !< time increment (seconds) + real, intent(in) :: dt !< time increment [s] type(time_type), intent(in) :: Time_end !< Time at the end of the interval type(diabatic_CS), pointer :: CS !< module control structure type(Wave_parameters_CS), optional, pointer :: Waves !< Surface gravity waves @@ -286,29 +291,29 @@ subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, & ! local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & ea_s, & ! amount of fluid entrained from the layer above within - ! one time step (m for Bouss, kg/m^2 for non-Bouss) + ! one time step [H ~> m or kg m-2] eb_s, & ! amount of fluid entrained from the layer below within - ! one time step (m for Bouss, kg/m^2 for non-Bouss) + ! one time step [H ~> m or kg m-2] ea_t, & ! amount of fluid entrained from the layer above within - ! one time step (m for Bouss, kg/m^2 for non-Bouss) + ! one time step [H ~> m or kg m-2] eb_t, & ! amount of fluid entrained from the layer below within - ! one time step (m for Bouss, kg/m^2 for non-Bouss) - Kd_lay, & ! diapycnal diffusivity of layers (Z^2/sec) - h_orig, & ! initial layer thicknesses (m for Bouss, kg/m^2 for non-Bouss) - h_prebound, & ! initial layer thicknesses (m for Bouss, kg/m^2 for non-Bouss) + ! one time step [H ~> m or kg m-2] + Kd_lay, & ! diapycnal diffusivity of layers [Z2 s-1 ~> m2 s-1] + h_orig, & ! initial layer thicknesses [H ~> m or kg m-2] + h_prebound, & ! initial layer thicknesses [H ~> m or kg m-2] ! hold, & ! layer thickness before diapycnal entrainment, and later ! the initial layer thicknesses (if a mixed layer is used), - ! (m for Bouss, kg/m^2 for non-Bouss) + ! [H ~> m or kg m-2] dSV_dT, & ! The partial derivatives of specific volume with temperature - dSV_dS, & ! and salinity in m^3/(kg K) and m^3/(kg ppt). - cTKE, & ! convective TKE requirements for each layer in J/m^2. + dSV_dS, & ! and salinity in [m3 kg-1 degC-1] and [m3 kg-1 ppt-1]. + cTKE, & ! convective TKE requirements for each layer [J/m^2]. u_h, & ! zonal and meridional velocities at thickness points after - v_h ! entrainment (m/s) + v_h ! entrainment [m s-1] real, dimension(SZI_(G),SZJ_(G),CS%nMode) :: & cn ! baroclinic gravity wave speeds real, dimension(SZI_(G),SZJ_(G)) :: & Rcv_ml, & ! coordinate density of mixed layer, used for applying sponges - SkinBuoyFlux! 2d surface buoyancy flux (Z2/s3), used by ePBL + SkinBuoyFlux! 2d surface buoyancy flux [Z2 s-3 ~> m2 s-3], used by ePBL real, dimension(SZI_(G),SZJ_(G),G%ke) :: h_diag ! diagnostic array for thickness real, dimension(SZI_(G),SZJ_(G),G%ke) :: temp_diag ! diagnostic array for temp real, dimension(SZI_(G),SZJ_(G),G%ke) :: saln_diag ! diagnostic array for salinity @@ -321,32 +326,32 @@ subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, & ! These are targets so that the space can be shared with eaml & ebml. eatr, & ! The equivalent of ea and eb for tracers, which differ from ea and ebtr ! eb in that they tend to homogenize tracers in massless layers - ! near the boundaries in H (m for Bouss and kg/m^2 for non-Bouss) + ! near the boundaries [H ~> m or kg m-2] (for Bous or non-Bouss) real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), target :: & - Kd_int, & ! diapycnal diffusivity of interfaces (m^2/s) - Kd_heat, & ! diapycnal diffusivity of heat (Z^2/s) - Kd_salt, & ! diapycnal diffusivity of salt and passive tracers (Z^2/s) - Kd_ePBL, & ! test array of diapycnal diffusivities at interfaces (Z^2/s) - eta, & ! Interface heights before diapycnal mixing, in m. - Tdif_flx, & ! diffusive diapycnal heat flux across interfaces (K m/s) - Tadv_flx, & ! advective diapycnal heat flux across interfaces (K m/s) - Sdif_flx, & ! diffusive diapycnal salt flux across interfaces (ppt m/s) - Sadv_flx ! advective diapycnal salt flux across interfaces (ppt m/s) + Kd_int, & ! diapycnal diffusivity of interfaces [Z2 s-1 ~> m2 s-1] + Kd_heat, & ! diapycnal diffusivity of heat [Z2 s-1 ~> m2 s-1] + Kd_salt, & ! diapycnal diffusivity of salt and passive tracers [Z2 s-1 ~> m2 s-1] + Kd_ePBL, & ! test array of diapycnal diffusivities at interfaces [Z2 s-1 ~> m2 s-1] + eta, & ! Interface heights before diapycnal mixing [m]. + Tdif_flx, & ! diffusive diapycnal heat flux across interfaces [degC m s-1] + Tadv_flx, & ! advective diapycnal heat flux across interfaces [degC m s-1] + Sdif_flx, & ! diffusive diapycnal salt flux across interfaces [ppt m s-1] + Sadv_flx ! advective diapycnal salt flux across interfaces [ppt m s-1] ! The following 5 variables are only used with a bulk mixed layer. real, pointer, dimension(:,:,:) :: & - eaml, & ! The equivalent of ea and eb due to mixed layer processes, in H - ebml ! (m for Bouss and kg/m^2 for non-Bouss). These will be + eaml, & ! The equivalent of ea and eb due to mixed layer processes [H ~> m or kg m-2] + ebml ! [H ~> m or kg m-2]. These will be ! pointers to eatr and ebtr so as to reuse the memory as ! the arrays are not needed at the same time. integer :: kb(SZI_(G),SZJ_(G)) ! index of the lightest layer denser - ! than the buffer laye (nondimensional) + ! than the buffer layer [nondim] real :: p_ref_cv(SZI_(G)) ! Reference pressure for the potential ! density which defines the coordinate - ! variable, set to P_Ref, in Pa. + ! variable, set to P_Ref [Pa]. logical :: in_boundary(SZI_(G)) ! True if there are no massive layers below, ! where massive is defined as sufficiently thick that @@ -354,28 +359,27 @@ subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, & ! the entrainment - usually sqrt(Kd*dt). real :: b_denom_1 ! The first term in the denominator of b1 - ! (m for Bouss, kg/m^2 for non-Bouss) + ! [H ~> m or kg m-2] real :: h_neglect ! A thickness that is so small it is usually lost ! in roundoff and can be neglected - ! (m for Bouss and kg/m^2 for non-Bouss) - real :: h_neglect2 ! h_neglect^2 (m^2 for Bouss, kg^2/m^4 for non-Bouss) + ! [H ~> m or kg m-2] + real :: h_neglect2 ! h_neglect^2 [H2 ~> m2 or kg2 m-4] real :: add_ent ! Entrainment that needs to be added when mixing tracers - ! (m for Bouss and kg/m^2 for non-Bouss) - real :: eaval ! eaval is 2*ea at velocity grid points (m for Bouss, kg/m^2 for non-Bouss) - real :: hval ! hval is 2*h at velocity grid points (m for Bouss, kg/m^2 for non-Bouss) + ! [H ~> m or kg m-2] + real :: eaval ! eaval is 2*ea at velocity grid points [H ~> m or kg m-2] + real :: hval ! hval is 2*h at velocity grid points [H ~> m or kg m-2] real :: h_tr ! h_tr is h at tracer points with a tiny thickness - ! added to ensure positive definiteness (m for Bouss, kg/m^2 for non-Bouss) + ! added to ensure positive definiteness [H ~> m or kg m-2] real :: Tr_ea_BBL ! The diffusive tracer thickness in the BBL that is - ! coupled to the bottom within a timestep (m) + ! coupled to the bottom within a timestep [H ~> m or kg m-2] - real :: htot(SZIB_(G)) ! The summed thickness from the bottom, in H. + real :: htot(SZIB_(G)) ! The summed thickness from the bottom [H ~> m or kg m-2]. real :: b1(SZIB_(G)), d1(SZIB_(G)) ! b1, c1, and d1 are variables used by the real :: c1(SZIB_(G),SZK_(G)) ! tridiagonal solver. - real :: Ent_int ! The diffusive entrainment rate at an interface - ! (H units = m for Bouss, kg/m^2 for non-Bouss). - real :: dt_mix ! amount of time over which to apply mixing (seconds) - real :: Idt ! inverse time step (1/s) + real :: Ent_int ! The diffusive entrainment rate at an interface [H ~> m or kg m-2] + real :: dt_mix ! amount of time over which to apply mixing [s] + real :: Idt ! inverse time step [s-1] type(p3d) :: z_ptrs(7) ! pointers to diagnostics to be interpolated to depth integer :: num_z_diags ! number of diagnostics to be interpolated to depth @@ -386,7 +390,7 @@ subroutine diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_end, & integer :: ig, jg ! global indices for testing testing itide point source (BDM) logical :: avg_enabled ! for testing internal tides (BDM) - real :: Kd_add_here ! An added diffusivity in Z2/s + real :: Kd_add_here ! An added diffusivity [Z2 s-1 ~> m2 s-1]. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB @@ -1151,9 +1155,9 @@ subroutine legacy_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_en type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< zonal velocity (m/s) - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< meridional velocity (m/s) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< thickness (m for Bouss / kg/m2 for non-Bouss) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u !< zonal velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v !< meridional velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< points to thermodynamic fields !! unused have NULL ptrs real, dimension(:,:), pointer :: Hml !< active mixed layer depth @@ -1164,34 +1168,34 @@ subroutine legacy_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_en !! equations, to enable the later derived !! diagnostics, like energy budgets type(cont_diag_ptrs), intent(inout) :: CDp !< points to terms in continuity equations - real, intent(in) :: dt !< time increment (seconds) + real, intent(in) :: dt !< time increment [s] type(time_type), intent(in) :: Time_end !< Time at the end of the interval type(diabatic_CS), pointer :: CS !< module control structure type(Wave_parameters_CS), optional, pointer :: Waves !< Surface gravity waves real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & ea, & ! amount of fluid entrained from the layer above within - ! one time step (m for Bouss, kg/m^2 for non-Bouss) + ! one time step [H ~> m or kg m-2] eb, & ! amount of fluid entrained from the layer below within - ! one time step (m for Bouss, kg/m^2 for non-Bouss) - Kd_lay, & ! diapycnal diffusivity of layers (Z^2/sec) - h_orig, & ! initial layer thicknesses (m for Bouss, kg/m^2 for non-Bouss) - h_prebound, & ! initial layer thicknesses (m for Bouss, kg/m^2 for non-Bouss) + ! one time step [H ~> m or kg m-2] + Kd_lay, & ! diapycnal diffusivity of layers [Z2 s-1 ~> m2 s-1] + h_orig, & ! initial layer thicknesses [H ~> m or kg m-2] + h_prebound, & ! initial layer thicknesses [H ~> m or kg m-2] hold, & ! layer thickness before diapycnal entrainment, and later ! the initial layer thicknesses (if a mixed layer is used), - ! (m for Bouss, kg/m^2 for non-Bouss) - dSV_dT, & ! The partial derivatives of specific volume with temperature - dSV_dS, & ! and salinity in m^3/(kg K) and m^3/(kg ppt). - cTKE, & ! convective TKE requirements for each layer in J/m^2. + ! [H ~> m or kg m-2] + dSV_dT, & ! The partial derivative of specific volume with temperature [m3 kg-1 degC-1] + dSV_dS, & ! The partial derivative of specific volume with salinity [m3 kg-1 ppt-1]. + cTKE, & ! convective TKE requirements for each layer [J m-2]. u_h, & ! zonal and meridional velocities at thickness points after - v_h ! entrainment (m/s) + v_h ! entrainment [m s-1] real, dimension(SZI_(G),SZJ_(G),CS%nMode) :: & cn ! baroclinic gravity wave speeds (formerly cg1 - BDM) real, dimension(SZI_(G),SZJ_(G)) :: & Rcv_ml, & ! coordinate density of mixed layer, used for applying sponges - SkinBuoyFlux! 2d surface buoyancy flux (m2/s3), used by ePBL + SkinBuoyFlux! 2d surface buoyancy flux [m2 s-3], used by ePBL real, dimension(SZI_(G),SZJ_(G),G%ke) :: h_diag ! diagnostic array for thickness real, dimension(SZI_(G),SZJ_(G),G%ke) :: temp_diag ! diagnostic array for temp real, dimension(SZI_(G),SZJ_(G),G%ke) :: saln_diag ! diagnostic array for salinity @@ -1204,32 +1208,32 @@ subroutine legacy_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_en ! These are targets so that the space can be shared with eaml & ebml. eatr, & ! The equivalent of ea and eb for tracers, which differ from ea and ebtr ! eb in that they tend to homogenize tracers in massless layers - ! near the boundaries (m for Bouss and kg/m^2 for non-Bouss) + ! near the boundaries [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), target :: & - Kd_int, & ! diapycnal diffusivity of interfaces (m^2/s) - Kd_heat, & ! diapycnal diffusivity of heat (Z^2/s) - Kd_salt, & ! diapycnal diffusivity of salt and passive tracers (Z^2/s) - Kd_ePBL, & ! test array of diapycnal diffusivities at interfaces (Z^2/s) - eta, & ! Interface heights before diapycnal mixing, in m. - Tdif_flx, & ! diffusive diapycnal heat flux across interfaces (K m/s) - Tadv_flx, & ! advective diapycnal heat flux across interfaces (K m/s) - Sdif_flx, & ! diffusive diapycnal salt flux across interfaces (ppt m/s) - Sadv_flx ! advective diapycnal salt flux across interfaces (ppt m/s) + Kd_int, & ! diapycnal diffusivity of interfaces [Z2 s-1 ~> m2 s-1] + Kd_heat, & ! diapycnal diffusivity of heat [Z2 s-1 ~> m2 s-1] + Kd_salt, & ! diapycnal diffusivity of salt and passive tracers [Z2 s-1 ~> m2 s-1] + Kd_ePBL, & ! test array of diapycnal diffusivities at interfaces [Z2 s-1 ~> m2 s-1] + eta, & ! Interface heights before diapycnal mixing [m]. + Tdif_flx, & ! diffusive diapycnal heat flux across interfaces [degC m s-1] + Tadv_flx, & ! advective diapycnal heat flux across interfaces [degC m s-1] + Sdif_flx, & ! diffusive diapycnal salt flux across interfaces [ppt m s-1] + Sadv_flx ! advective diapycnal salt flux across interfaces [ppt m s-1] ! The following 5 variables are only used with a bulk mixed layer. real, pointer, dimension(:,:,:) :: & eaml, & ! The equivalent of ea and eb due to mixed layer processes, - ebml ! (m for Bouss and kg/m^2 for non-Bouss). These will be + ebml ! [H ~> m or kg m-2]. These will be ! pointers to eatr and ebtr so as to reuse the memory as ! the arrays are not needed at the same time. integer :: kb(SZI_(G),SZJ_(G)) ! index of the lightest layer denser - ! than the buffer laye (nondimensional) + ! than the buffer layer [nondim] real :: p_ref_cv(SZI_(G)) ! Reference pressure for the potential ! density which defines the coordinate - ! variable, set to P_Ref, in Pa. + ! variable, set to P_Ref [Pa]. logical :: in_boundary(SZI_(G)) ! True if there are no massive layers below, ! where massive is defined as sufficiently thick that @@ -1237,28 +1241,27 @@ subroutine legacy_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_en ! the entrainment - usually sqrt(Kd*dt). real :: b_denom_1 ! The first term in the denominator of b1 - ! (m for Bouss, kg/m^2 for non-Bouss) + ! [H ~> m or kg m-2] real :: h_neglect ! A thickness that is so small it is usually lost ! in roundoff and can be neglected - ! (m for Bouss and kg/m^2 for non-Bouss) - real :: h_neglect2 ! h_neglect^2 (m^2 for Bouss, kg^2/m^4 for non-Bouss) + ! [H ~> m or kg m-2] + real :: h_neglect2 ! h_neglect^2 [H2 ~> m2 or kg2 m-4] real :: add_ent ! Entrainment that needs to be added when mixing tracers - ! (m for Bouss and kg/m^2 for non-Bouss) - real :: eaval ! eaval is 2*ea at velocity grid points (m for Bouss, kg/m^2 for non-Bouss) - real :: hval ! hval is 2*h at velocity grid points (m for Bouss, kg/m^2 for non-Bouss) + ! [H ~> m or kg m-2] + real :: eaval ! eaval is 2*ea at velocity grid points [H ~> m or kg m-2] + real :: hval ! hval is 2*h at velocity grid points [H ~> m or kg m-2] real :: h_tr ! h_tr is h at tracer points with a tiny thickness - ! added to ensure positive definiteness (m for Bouss, kg/m^2 for non-Bouss) + ! added to ensure positive definiteness [H ~> m or kg m-2] real :: Tr_ea_BBL ! The diffusive tracer thickness in the BBL that is - ! coupled to the bottom within a timestep (m) + ! coupled to the bottom within a timestep [H ~> m or kg m-2] - real :: htot(SZIB_(G)) ! The summed thickness from the bottom, in m. + real :: htot(SZIB_(G)) ! The summed thickness from the bottom [H ~> m or kg m-2]. real :: b1(SZIB_(G)), d1(SZIB_(G)) ! b1, c1, and d1 are variables used by the real :: c1(SZIB_(G),SZK_(G)) ! tridiagonal solver. - real :: Ent_int ! The diffusive entrainment rate at an interface - ! (H units = m for Bouss, kg/m^2 for non-Bouss). - real :: dt_mix ! amount of time over which to apply mixing (seconds) - real :: Idt ! inverse time step (1/s) + real :: Ent_int ! The diffusive entrainment rate at an interface [H ~> m or kg m-2]. + real :: dt_mix ! amount of time over which to apply mixing [s] + real :: Idt ! inverse time step [s-1] type(p3d) :: z_ptrs(7) ! pointers to diagnostics to be interpolated to depth integer :: num_z_diags ! number of diagnostics to be interpolated to depth @@ -1269,7 +1272,7 @@ subroutine legacy_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_en integer :: ig, jg ! global indices for testing testing itide point source (BDM) logical :: avg_enabled ! for testing internal tides (BDM) - real :: Kd_add_here ! An added diffusivity in Z2/s + real :: Kd_add_here ! An added diffusivity [Z2 s-1 ~> m2 s-1]. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke Isq = G%IscB ; Ieq = G%IecB ; Jsq = G%JscB ; Jeq = G%JecB @@ -2070,7 +2073,7 @@ subroutine legacy_diabatic(u, v, h, tv, Hml, fluxes, visc, ADp, CDp, dt, Time_en ! mixing of passive tracers from massless boundary layers to interior call cpu_clock_begin(id_clock_tracers) if (CS%mix_boundary_tracers) then - Tr_ea_BBL = sqrt(dt*CS%Kd_BBL_tr) + Tr_ea_BBL = sqrt(dt*CS%Kd_BBL_tr) !### I think this needs GV%Z_to_H !$OMP parallel do default(shared) private(htot,in_boundary,add_ent) do j=js,je do i=is,ie @@ -2447,9 +2450,9 @@ subroutine extract_diabatic_member(CS, opacity_CSp, optics_CSp, & type(opacity_CS), optional, pointer :: opacity_CSp !< A pointer to be set to the opacity control structure type(optics_type), optional, pointer :: optics_CSp !< A pointer to be set to the optics control structure real, optional, intent( out) :: evap_CFL_limit ! CS%opacity_CSp @@ -2465,10 +2468,10 @@ subroutine extract_diabatic_member(CS, opacity_CSp, optics_CSp, & subroutine adiabatic(h, tv, fluxes, dt, G, GV, CS) type(ocean_grid_type), intent(inout) :: G !< ocean grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< thickness (m for Bouss or kg/m2 for non-Bouss) + intent(inout) :: h !< thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< points to thermodynamic fields type(forcing), intent(inout) :: fluxes !< boundary fluxes - real, intent(in) :: dt !< time step (seconds) + real, intent(in) :: dt !< time step [s] type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(diabatic_CS), pointer :: CS !< module control structure @@ -2489,16 +2492,16 @@ subroutine diagnose_diabatic_diff_tendency(tv, h, temp_old, saln_old, dt, G, GV, type(ocean_grid_type), intent(in) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(thermo_var_ptrs), intent(in) :: tv !< points to updated thermodynamic fields - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< thickness (m or kg/m2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: temp_old !< temperature prior to diabatic physics - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: saln_old !< salinity prior to diabatic physics (PPT) - real, intent(in) :: dt !< time step (sec) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: saln_old !< salinity prior to diabatic physics [ppt] + real, intent(in) :: dt !< time step [s] type(diabatic_CS), pointer :: CS !< module control structure ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: work_3d real, dimension(SZI_(G),SZJ_(G)) :: work_2d - real :: Idt ! The inverse of the timestep, in s-1 + real :: Idt ! The inverse of the timestep [s-1] real :: ppt2mks = 0.001 ! Conversion factor from g/kg to kg/kg. integer :: i, j, k, is, ie, js, je, nz @@ -2575,20 +2578,20 @@ subroutine diagnose_boundary_forcing_tendency(tv, h, temp_old, saln_old, h_old, type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(thermo_var_ptrs), intent(in) :: tv !< points to updated thermodynamic fields real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< thickness after boundary flux application (m or kg/m2) + intent(in) :: h !< thickness after boundary flux application [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: temp_old !< temperature prior to boundary flux application + intent(in) :: temp_old !< temperature prior to boundary flux application [degC] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: saln_old !< salinity prior to boundary flux application (PPT) + intent(in) :: saln_old !< salinity prior to boundary flux application [ppt] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< thickness prior to boundary flux application (m or kg/m2) - real, intent(in) :: dt !< time step (sec) + intent(in) :: h_old !< thickness prior to boundary flux application [H ~> m or kg m-2] + real, intent(in) :: dt !< time step [s] type(diabatic_CS), pointer :: CS !< module control structure ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: work_3d real, dimension(SZI_(G),SZJ_(G)) :: work_2d - real :: Idt ! The inverse of the timestep, in s-1 + real :: Idt ! The inverse of the timestep [s-1] real :: ppt2mks = 0.001 ! Conversion factor from g/kg to kg/kg. integer :: i, j, k, is, ie, js, je, nz @@ -2671,9 +2674,9 @@ subroutine diagnose_frazil_tendency(tv, h, temp_old, dt, G, GV, CS) type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(diabatic_CS), pointer :: CS !< module control structure type(thermo_var_ptrs), intent(in) :: tv !< points to updated thermodynamic fields - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< thickness (m or kg/m2) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: temp_old !< temperature prior to frazil formation - real, intent(in) :: dt !< time step (sec) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: temp_old !< temperature prior to frazil formation [degC] + real, intent(in) :: dt !< time step [s] real, dimension(SZI_(G),SZJ_(G)) :: work_2d real :: Idt diff --git a/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 b/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 index 4fbdc9d8c3..53e4b29178 100644 --- a/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 +++ b/src/parameterizations/vertical/MOM_diapyc_energy_req.F90 @@ -18,6 +18,11 @@ module MOM_diapyc_energy_req public diapyc_energy_req_init, diapyc_energy_req_calc, diapyc_energy_req_test, diapyc_energy_req_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> This control structure holds parameters for the MOM_diapyc_energy_req module type, public :: diapyc_energy_req_CS ; private logical :: initialized = .false. !< A variable that is here because empty @@ -46,25 +51,24 @@ subroutine diapyc_energy_req_test(h_3d, dt, tv, G, GV, US, CS, Kd_int) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(G%isd:G%ied,G%jsd:G%jed,GV%ke), & - intent(in) :: h_3d !< Layer thickness before entrainment, in H. + intent(in) :: h_3d !< Layer thickness before entrainment [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers to any !! available thermodynamic fields. !! Absent fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, - !! in s. + real, intent(in) :: dt !< The amount of time covered by this call [s]. type(diapyc_energy_req_CS), pointer :: CS !< This module's control structure. real, dimension(G%isd:G%ied,G%jsd:G%jed,GV%ke+1), & - optional, intent(in) :: Kd_int !< Interface diffusivities in Z2 s-1. + optional, intent(in) :: Kd_int !< Interface diffusivities [Z2 s-1 ~> m2 s-1]. ! Local variables real, dimension(GV%ke) :: & - T0, S0, & ! T0 & S0 are columns of initial temperatures and salinities, in degC and g/kg. - h_col ! h_col is a column of thicknesses h at tracer points, in H (m or kg m-2). + T0, S0, & ! T0 & S0 are columns of initial temperatures and salinities [degC] and g/kg. + h_col ! h_col is a column of thicknesses h at tracer points [H ~> m or kg m-2]. real, dimension(GV%ke+1) :: & - Kd, & ! A column of diapycnal diffusivities at interfaces, in Z2 s-1. - h_top, h_bot ! Distances from the top or bottom, in H. + Kd, & ! A column of diapycnal diffusivities at interfaces [Z2 s-1 ~> m2 s-1]. + h_top, h_bot ! Distances from the top or bottom [H ~> m or kg m-2]. real :: ustar, absf, htot - real :: energy_Kd ! The energy used by diapycnal mixing in W m-2. + real :: energy_Kd ! The energy used by diapycnal mixing [W m-2]. real :: tmp1 ! A temporary array. integer :: i, j, k, is, ie, js, je, nz, itt logical :: may_print @@ -119,14 +123,14 @@ subroutine diapyc_energy_req_calc(h_in, T_in, S_in, Kd, energy_Kd, dt, tv, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(GV%ke), intent(in) :: h_in !< Layer thickness before entrainment, - !! in H (m or kg m-2). - real, dimension(GV%ke), intent(in) :: T_in !< The layer temperatures, in degC. - real, dimension(GV%ke), intent(in) :: S_in !< The layer salinities, in g kg-1. - real, dimension(GV%ke+1), intent(in) :: Kd !< The interfaces diapycnal diffusivities, - !! in Z2 s-1. - real, intent(in) :: dt !< The amount of time covered by this call, in s. + !! [H ~> m or kg m-2]. + real, dimension(GV%ke), intent(in) :: T_in !< The layer temperatures [degC]. + real, dimension(GV%ke), intent(in) :: S_in !< The layer salinities [ppt]. + real, dimension(GV%ke+1), intent(in) :: Kd !< The interfaces diapycnal diffusivities + !! [Z2 s-1 ~> m2 s-1]. + real, intent(in) :: dt !< The amount of time covered by this call [s]. real, intent(out) :: energy_Kd !< The column-integrated rate of energy - !! consumption by diapycnal diffusion, in W m-2. + !! consumption by diapycnal diffusion [W m-2]. type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers to any !! available thermodynamic fields. !! Absent fields have NULL ptrs. @@ -143,100 +147,100 @@ subroutine diapyc_energy_req_calc(h_in, T_in, S_in, Kd, energy_Kd, dt, tv, & ! for other bits of code. real, dimension(GV%ke) :: & - p_lay, & ! Average pressure of a layer, in Pa. - dSV_dT, & ! Partial derivative of specific volume with temperature, in m3 kg-1 K-1. - dSV_dS, & ! Partial derivative of specific volume with salinity, in m3 kg-1 / (g kg-1). - T0, S0, & ! Initial temperatures and salinities. - Te, Se, & ! Running incomplete estimates of the new temperatures and salinities. - Te_a, Se_a, & ! Running incomplete estimates of the new temperatures and salinities. - Te_b, Se_b, & ! Running incomplete estimates of the new temperatures and salinities. - Tf, Sf, & ! New final values of the temperatures and salinities. - dTe, dSe, & ! Running (1-way) estimates of temperature and salinity change. - dTe_a, dSe_a, & ! Running (1-way) estimates of temperature and salinity change. - dTe_b, dSe_b, & ! Running (1-way) estimates of temperature and salinity change. - Th_a, & ! An effective temperature times a thickness in the layer above, - ! including implicit mixing effects with other yet higher layers, in K H. - Sh_a, & ! An effective salinity times a thickness in the layer above, - ! including implicit mixing effects with other yet higher layers, in ppt H. - Th_b, & ! An effective temperature times a thickness in the layer below, - ! including implicit mixing effects with other yet lower layers, in K H. - Sh_b, & ! An effective salinity times a thickness in the layer below, - ! including implicit mixing effects with other yet lower layers, in ppt H. + p_lay, & ! Average pressure of a layer [Pa]. + dSV_dT, & ! Partial derivative of specific volume with temperature [m3 kg-1 degC-1]. + dSV_dS, & ! Partial derivative of specific volume with salinity [m3 kg-1 ppt-1]. + T0, S0, & ! Initial temperatures and salinities [degC] and [ppt]. + Te, Se, & ! Running incomplete estimates of the new temperatures and salinities [degC] and [ppt]. + Te_a, Se_a, & ! Running incomplete estimates of the new temperatures and salinities [degC] and [ppt]. + Te_b, Se_b, & ! Running incomplete estimates of the new temperatures and salinities [degC] and [ppt]. + Tf, Sf, & ! New final values of the temperatures and salinities [degC] and [ppt]. + dTe, dSe, & ! Running (1-way) estimates of temperature and salinity change [degC] and [ppt]. + dTe_a, dSe_a, & ! Running (1-way) estimates of temperature and salinity change [degC] and [ppt]. + dTe_b, dSe_b, & ! Running (1-way) estimates of temperature and salinity change [degC] and [ppt]. + Th_a, & ! An effective temperature times a thickness in the layer above, including implicit + ! mixing effects with other yet higher layers [degC H ~> degC m or degC kg m-2]. + Sh_a, & ! An effective salinity times a thickness in the layer above, including implicit + ! mixing effects with other yet higher layers [ppt H ~> ppt m or ppt kg m-2]. + Th_b, & ! An effective temperature times a thickness in the layer below, including implicit + ! mixing effects with other yet lower layers [degC H ~> degC m or degC kg m-2]. + Sh_b, & ! An effective salinity times a thickness in the layer below, including implicit + ! mixing effects with other yet lower layers [ppt H ~> ppt m or ppt kg m-2]. dT_to_dPE, & ! Partial derivative of column potential energy with the temperature - dS_to_dPE, & ! and salinity changes within a layer, in J m-2 K-1 and J m-2 / (g kg-1). + dS_to_dPE, & ! and salinity changes within a layer [J m-2 degC-1] and [J m-2 ppt-1]. dT_to_dColHt, & ! Partial derivatives of the total column height with the temperature - dS_to_dColHt, & ! and salinity changes within a layer, in Z K-1 and Z ppt-1. + dS_to_dColHt, & ! and salinity changes within a layer [Z degC-1 ~> m degC-1] and [Z ppt-1 ~> m ppt-1]. dT_to_dColHt_a, & ! Partial derivatives of the total column height with the temperature dS_to_dColHt_a, & ! and salinity changes within a layer, including the implicit effects - ! of mixing with layers higher in the water colun, in Z K-1 and Z ppt-1. + ! of mixing with layers higher in the water colun [Z degC-1 ~> m degC-1] and [Z ppt-1 ~> m ppt-1]. dT_to_dColHt_b, & ! Partial derivatives of the total column height with the temperature dS_to_dColHt_b, & ! and salinity changes within a layer, including the implicit effects - ! of mixing with layers lower in the water colun, in Z K-1 and Z ppt-1. + ! of mixing with layers lower in the water colun [Z degC-1 ~> m degC-1] and [Z ppt-1 ~> m ppt-1]. dT_to_dPE_a, & ! Partial derivatives of column potential energy with the temperature dS_to_dPE_a, & ! and salinity changes within a layer, including the implicit effects ! of mixing with layers higher in the water column, in - ! units of J m-2 K-1 and J m-2 ppt-1. + ! units of [J m-2 degC-1] and [J m-2 ppt-1]. dT_to_dPE_b, & ! Partial derivatives of column potential energy with the temperature dS_to_dPE_b, & ! and salinity changes within a layer, including the implicit effects ! of mixing with layers lower in the water column, in - ! units of J m-2 K-1 and J m-2 ppt-1. + ! units of [J m-2 degC-1] and [J m-2 ppt-1]. hp_a, & ! An effective pivot thickness of the layer including the effects - ! of coupling with layers above, in H. This is the first term + ! of coupling with layers above [H ~> m or kg m-2]. This is the first term ! in the denominator of b1 in a downward-oriented tridiagonal solver. hp_b, & ! An effective pivot thickness of the layer including the effects - ! of coupling with layers below, in H. This is the first term + ! of coupling with layers below [H ~> m or kg m-2]. This is the first term ! in the denominator of b1 in an upward-oriented tridiagonal solver. - c1_a, & ! c1_a is used by a downward-oriented tridiagonal solver, ND. - c1_b, & ! c1_b is used by an upward-oriented tridiagonal solver, ND. + c1_a, & ! c1_a is used by a downward-oriented tridiagonal solver [nondim]. + c1_b, & ! c1_b is used by an upward-oriented tridiagonal solver [nondim]. h_tr ! h_tr is h at tracer points with a h_neglect added to - ! ensure positive definiteness, in m or kg m-2. + ! ensure positive definiteness [H ~> m or kg m-2]. real, dimension(GV%ke+1) :: & - pres, & ! Interface pressures in Pa. + pres, & ! Interface pressures [Pa]. pres_Z, & ! Interface pressures with a rescaling factor to convert interface height - ! movements into changes in column potential energy, in J m-2 Z-1. - z_Int, & ! Interface heights relative to the surface, in H. - N2, & ! An estimate of the buoyancy frequency in s-2. + ! movements into changes in column potential energy [J m-2 Z-1 ~> J m-3]. + z_Int, & ! Interface heights relative to the surface [H ~> m or kg m-2]. + N2, & ! An estimate of the buoyancy frequency [s-2]. Kddt_h, & ! The diapycnal diffusivity times a timestep divided by the - ! average thicknesses around a layer, in H (m or kg m-2). + ! average thicknesses around a layer [H ~> m or kg m-2]. Kddt_h_a, & ! The value of Kddt_h for layers above the central point in the - ! tridiagonal solver, in H. + ! tridiagonal solver [H ~> m or kg m-2]. Kddt_h_b, & ! The value of Kddt_h for layers below the central point in the - ! tridiagonal solver, in H. + ! tridiagonal solver [H ~> m or kg m-2]. Kd_so_far ! The value of Kddt_h that has been applied already in - ! calculating the energy changes, in H (m or kg m-2). + ! calculating the energy changes [H ~> m or kg m-2]. real, dimension(GV%ke+1,4) :: & PE_chg_k, & ! The integrated potential energy change within a timestep due ! to the diffusivity at interface K for 4 different orders of - ! accumulating the diffusivities, in J m-2. + ! accumulating the diffusivities [J m-2]. ColHt_cor_k ! The correction to the potential energy change due to - ! changes in the net column height, in J m-2. + ! changes in the net column height [J m-2]. real :: & - b1 ! b1 is used by the tridiagonal solver, in H-1. + b1 ! b1 is used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. real :: & - I_b1 ! The inverse of b1, in H. - real :: Kd0 ! The value of Kddt_h that has already been applied, in H. - real :: dKd ! The change in the value of Kddt_h, in H. + I_b1 ! The inverse of b1 [H ~> m or kg m-2]. + real :: Kd0 ! The value of Kddt_h that has already been applied [H ~> m or kg m-2]. + real :: dKd ! The change in the value of Kddt_h [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: dTe_term ! A diffusivity-independent term related to the temperature - ! change in the layer below the interface, in K H. + ! change in the layer below the interface [degC H ~> degC m or degC kg m-2]. real :: dSe_term ! A diffusivity-independent term related to the salinity - ! change in the layer below the interface, in ppt H. - real :: Kddt_h_guess ! A guess of the final value of Kddt_h, in H. - real :: dMass ! The mass per unit area within a layer, in kg m-2. - real :: dPres ! The hydrostatic pressure change across a layer, in Pa. + ! change in the layer below the interface [ppt H ~> ppt m or ppt kg m-2]. + real :: Kddt_h_guess ! A guess of the final value of Kddt_h [H ~> m or kg m-2]. + real :: dMass ! The mass per unit area within a layer [kg m-2]. + real :: dPres ! The hydrostatic pressure change across a layer [Pa]. real :: dMKE_max ! The maximum amount of mean kinetic energy that could be ! converted to turbulent kinetic energy if the velocity in ! the layer below an interface were homogenized with all of - ! the water above the interface, in J m-2 = kg s-2. - real :: rho_here ! The in-situ density, in kg m-3. + ! the water above the interface [J m-2 = kg s-2]. + real :: rho_here ! The in-situ density [kg m-3]. real :: PE_change ! The change in column potential energy from applying Kddt_h at the - ! present interface, in J m-2. + ! present interface [J m-2]. real :: ColHt_cor ! The correction to PE_chg that is made due to a net - ! change in the column height, in J m-2. - real :: htot ! A running sum of thicknesses, in H. - real :: dTe_t2, dT_km1_t2, dT_k_t2 ! Temporary arrays describing temperature changes. - real :: dSe_t2, dS_km1_t2, dS_k_t2 ! Temporary arrays describing salinity changes. + ! change in the column height [J m-2]. + real :: htot ! A running sum of thicknesses [H ~> m or kg m-2]. + real :: dTe_t2, dT_km1_t2, dT_k_t2 ! Temporary arrays describing temperature changes [degC]. + real :: dSe_t2, dS_km1_t2, dS_k_t2 ! Temporary arrays describing salinity changes [ppt]. logical :: do_print ! The following are a bunch of diagnostic arrays for debugging purposes. @@ -966,88 +970,88 @@ subroutine find_PE_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, & PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0, ColHt_cor) real, intent(in) :: Kddt_h0 !< The previously used diffusivity at an interface times !! the time step and divided by the average of the - !! thicknesses around the interface, in units of H (m or kg-2). + !! thicknesses around the interface [H ~> m or kg m-2]. real, intent(in) :: dKddt_h !< The trial change in the diffusivity at an interface times !! the time step and divided by the average of the - !! thicknesses around the interface, in units of H (m or kg-2). + !! thicknesses around the interface [H ~> m or kg m-2]. real, intent(in) :: hp_a !< The effective pivot thickness of the layer above the !! interface, given by h_k plus a term that !! is a fraction (determined from the tridiagonal solver) of - !! Kddt_h for the interface above, in H. + !! Kddt_h for the interface above [H ~> m or kg m-2]. real, intent(in) :: hp_b !< The effective pivot thickness of the layer below the !! interface, given by h_k plus a term that !! is a fraction (determined from the tridiagonal solver) of - !! Kddt_h for the interface above, in H. + !! Kddt_h for the interface above [H ~> m or kg m-2]. real, intent(in) :: Th_a !< An effective temperature times a thickness in the layer !! above, including implicit mixing effects with other - !! yet higher layers, in K H. + !! yet higher layers [degC H ~> degC m or degC kg m-2]. real, intent(in) :: Sh_a !< An effective salinity times a thickness in the layer !! above, including implicit mixing effects with other - !! yet higher layers, in K H. + !! yet higher layers [ppt H ~> ppt m or ppt kg m-2]. real, intent(in) :: Th_b !< An effective temperature times a thickness in the layer !! below, including implicit mixing effects with other - !! yet lower layers, in K H. + !! yet lower layers [degC H ~> degC m or degC kg m-2]. real, intent(in) :: Sh_b !< An effective salinity times a thickness in the layer !! below, including implicit mixing effects with other - !! yet lower layers, in K H. + !! yet lower layers [ppt H ~> ppt m or ppt kg m-2]. real, intent(in) :: dT_to_dPE_a !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers above, in J m-2 K-1. + !! in the temperatures of all the layers above [J m-2 degC-1]. real, intent(in) :: dS_to_dPE_a !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers above, in J m-2 ppt-1. + !! in the salinities of all the layers above [J m-2 ppt-1]. real, intent(in) :: dT_to_dPE_b !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers below, in J m-2 K-1. + !! in the temperatures of all the layers below [J m-2 degC-1]. real, intent(in) :: dS_to_dPE_b !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers below, in J m-2 ppt-1. + !! in the salinities of all the layers below [J m-2 ppt-1]. real, intent(in) :: pres_Z !< The hydrostatic interface pressure, which is used to relate !! the changes in column thickness to the energy that is radiated - !! as gravity waves and unavailable to drive mixing, in J m-2 Z-1. + !! as gravity waves and unavailable to drive mixing [J m-2 Z-1 ~> J m-3]. real, intent(in) :: dT_to_dColHt_a !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers above, in Z K-1. + !! in the temperatures of all the layers above [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHt_a !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers above, in Z ppt-1. + !! in the salinities of all the layers above [Z ppt-1 ~> m ppt-1]. real, intent(in) :: dT_to_dColHt_b !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers below, in Z K-1. + !! in the temperatures of all the layers below [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHt_b !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers below, in Z ppt-1. + !! in the salinities of all the layers below [Z ppt-1 ~> m ppt-1]. real, optional, intent(out) :: PE_chg !< The change in column potential energy from applying - !! Kddt_h at the present interface, in J m-2. + !! Kddt_h at the present interface [J m-2]. real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h, - !! in units of J m-2 H-1. + !! [J m-2 H-1 ~> J m-3 or J kg-1]. real, optional, intent(out) :: dPE_max !< The maximum change in column potential energy that could !! be realizedd by applying a huge value of Kddt_h at the - !! present interface, in J m-2. + !! present interface [J m-2]. real, optional, intent(out) :: dPEc_dKd_0 !< The partial derivative of PE_chg with Kddt_h in the - !! limit where Kddt_h = 0, in J m-2 H-1. + !! limit where Kddt_h = 0 [J m-2 H-1 ~> J m-3 or J kg-1]. real, optional, intent(out) :: ColHt_cor !< The correction to PE_chg that is made due to a net - !! change in the column height, in J m-2. + !! change in the column height [J m-2]. - real :: hps ! The sum of the two effective pivot thicknesses, in H. - real :: bdt1 ! A product of the two pivot thicknesses plus a diffusive term, in H2. - real :: dT_c ! The core term in the expressions for the temperature changes, in K H2. - real :: dS_c ! The core term in the expressions for the salinity changes, in psu H2. + real :: hps ! The sum of the two effective pivot thicknesses [H ~> m or kg m-2]. + real :: bdt1 ! A product of the two pivot thicknesses plus a diffusive term [H2 ~> m2 or kg2 m-4]. + real :: dT_c ! The core term in the expressions for the temperature changes [degC H2 ~> degC m2 or degC kg2 m-4]. + real :: dS_c ! The core term in the expressions for the salinity changes [psu H2 ~> psu m2 or psu kg2 m-4]. real :: PEc_core ! The diffusivity-independent core term in the expressions - ! for the potential energy changes, J m-3. + ! for the potential energy changes [J m-3]. real :: ColHt_core ! The diffusivity-independent core term in the expressions - ! for the column height changes, J m-3. - real :: ColHt_chg ! The change in the column height, in m. - real :: y1 ! A local temporary term, in units of H-3 or H-4 in various contexts. + ! for the column height changes [J m-3]. + real :: ColHt_chg ! The change in the column height [Z ~> m]. + real :: y1 ! A local temporary term, in [H-3] or [H-4] in various contexts. ! The expression for the change in potential energy used here is derived ! from the expression for the final estimates of the changes in temperature @@ -1116,65 +1120,65 @@ subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0) real, intent(in) :: Kddt_h !< The diffusivity at an interface times the time step and !! divided by the average of the thicknesses around the - !! interface, in units of H (m or kg-2). - real, intent(in) :: h_k !< The thickness of the layer below the interface, in H. + !! interface [H ~> m or kg m-2]. + real, intent(in) :: h_k !< The thickness of the layer below the interface [H ~> m or kg m-2]. real, intent(in) :: b_den_1 !< The first term in the denominator of the pivot !! for the tridiagonal solver, given by h_k plus a term that !! is a fraction (determined from the tridiagonal solver) of - !! Kddt_h for the interface above, in H. - real, intent(in) :: dTe_term !< A diffusivity-independent term related to the - !! temperature change in the layer below the interface, in K H. - real, intent(in) :: dSe_term !< A diffusivity-independent term related to the - !! salinity change in the layer below the interface, in ppt H. + !! Kddt_h for the interface above [H ~> m or kg m-2]. + real, intent(in) :: dTe_term !< A diffusivity-independent term related to the temperature change + !! in the layer below the interface [degC H ~> degC m or degC kg m-2]. + real, intent(in) :: dSe_term !< A diffusivity-independent term related to the salinity change + !! in the layer below the interface [ppt H ~> ppt m or ppt kg m-2]. real, intent(in) :: dT_km1_t2 !< A diffusivity-independent term related to the - !! temperature change in the layer above the interface, in K. + !! temperature change in the layer above the interface [degC]. real, intent(in) :: dS_km1_t2 !< A diffusivity-independent term related to the - !! salinity change in the layer above the interface, in ppt. + !! salinity change in the layer above the interface [ppt]. real, intent(in) :: pres_Z !< The hydrostatic interface pressure, which is used to relate !! the changes in column thickness to the energy that is radiated - !! as gravity waves and unavailable to drive mixing, in J m-2 Z-1. + !! as gravity waves and unavailable to drive mixing [J m-2 Z-1 ~> J m-3]. real, intent(in) :: dT_to_dPE_k !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers below, in J m-2 K-1. + !! in the temperatures of all the layers below [J m-2 degC-1]. real, intent(in) :: dS_to_dPE_k !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers below, in J m-2 ppt-1. + !! in the salinities of all the layers below [J m-2 ppt-1]. real, intent(in) :: dT_to_dPEa !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers above, in J m-2 K-1. + !! in the temperatures of all the layers above [J m-2 degC-1]. real, intent(in) :: dS_to_dPEa !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers above, in J m-2 ppt-1. + !! in the salinities of all the layers above [J m-2 ppt-1]. real, intent(in) :: dT_to_dColHt_k !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers below, in Z K-1. + !! in the temperatures of all the layers below [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHt_k !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers below, in Z ppt-1. + !! in the salinities of all the layers below [Z ppt-1 ~> m ppt-1]. real, intent(in) :: dT_to_dColHta !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers above, in Z K-1. + !! in the temperatures of all the layers above [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHta !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers above, in Z ppt-1. + !! in the salinities of all the layers above [Z ppt-1 ~> m ppt-1]. real, optional, intent(out) :: PE_chg !< The change in column potential energy from applying - !! Kddt_h at the present interface, in J m-2. + !! Kddt_h at the present interface [J m-2]. real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h, - !! in units of J m-2 H-1. + !! [J m-2 H-1 ~> J m-3 or J kg-1]. real, optional, intent(out) :: dPE_max !< The maximum change in column potential energy that could - !! be realizedd by applying a huge value of Kddt_h at the - !! present interface, in J m-2. + !! be realized by applying a huge value of Kddt_h at the + !! present interface [J m-2]. real, optional, intent(out) :: dPEc_dKd_0 !< The partial derivative of PE_chg with Kddt_h in the - !! limit where Kddt_h = 0, in J m-2 H-1. + !! limit where Kddt_h = 0 [J m-2 H-1 ~> J m-3 or J kg-1]. ! This subroutine determines the total potential energy change due to mixing ! at an interface, including all of the implicit effects of the prescribed @@ -1185,16 +1189,17 @@ subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & ! this routine can also be used for an upward pass with the sense of direction ! reversed. - real :: b1 ! b1 is used by the tridiagonal solver, in H-1. - real :: b1Kd ! Temporary array (nondim.) - real :: ColHt_chg ! The change in column thickness in m. - real :: dColHt_max ! The change in column thickess for infinite diffusivity, in m. - real :: dColHt_dKd ! The partial derivative of column thickess with diffusivity, in s m-1. - real :: dT_k, dT_km1 ! Temporary arrays in K. - real :: dS_k, dS_km1 ! Temporary arrays in ppt. - real :: I_Kr_denom, dKr_dKd ! Temporary arrays in H-2 and nondim. - real :: ddT_k_dKd, ddT_km1_dKd ! Temporary arrays in K H-1. - real :: ddS_k_dKd, ddS_km1_dKd ! Temporary arrays in ppt H-1. + real :: b1 ! b1 is used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. + real :: b1Kd ! Temporary array [nondim] + real :: ColHt_chg ! The change in column thickness [Z ~> m]. + real :: dColHt_max ! The change in column thickness for infinite diffusivity [Z ~> m]. + real :: dColHt_dKd ! The partial derivative of column thickness with diffusivity [s Z-1 ~> s m-1]. + real :: dT_k, dT_km1 ! Temporary arrays [degC]. + real :: dS_k, dS_km1 ! Temporary arrays [ppt]. + real :: I_Kr_denom ! Temporary arrays [H-2 ~> m-2 or m4 kg-2]. + real :: dKr_dKd ! Nondimensional temporary array [nondim]. + real :: ddT_k_dKd, ddT_km1_dKd ! Temporary arrays [degC H-1 ~> m-1 or m2 kg-1]. + real :: ddS_k_dKd, ddS_km1_dKd ! Temporary arrays [ppt H-1 ~> ppt m-1 or ppt m2 kg-1]. b1 = 1.0 / (b_den_1 + Kddt_h) b1Kd = Kddt_h*b1 diff --git a/src/parameterizations/vertical/MOM_energetic_PBL.F90 b/src/parameterizations/vertical/MOM_energetic_PBL.F90 index 9e32cd2aa9..5d4d70ec30 100644 --- a/src/parameterizations/vertical/MOM_energetic_PBL.F90 +++ b/src/parameterizations/vertical/MOM_energetic_PBL.F90 @@ -25,6 +25,11 @@ module MOM_energetic_PBL public energetic_PBL, energetic_PBL_init, energetic_PBL_end public energetic_PBL_get_MLD +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> This control structure holds parameters for the MOM_energetic_PBL module type, public :: energetic_PBL_CS ; private real :: mstar !< The ratio of the friction velocity cubed to the TKE available to @@ -32,26 +37,26 @@ module MOM_energetic_PBL !! integrated shear production minus the vertically integrated !! dissipation of TKE produced by shear. real :: nstar !< The fraction of the TKE input to the mixed layer available to drive - !! entrainment, nondim. This quantity is the vertically integrated + !! entrainment [nondim]. This quantity is the vertically integrated !! buoyancy production minus the vertically integrated dissipation of !! TKE produced by buoyancy. real :: MixLenExponent !< Exponent in the mixing length shape-function. !! 1 is law-of-the-wall at top and bottom, !! 2 is more KPP like. - real :: TKE_decay !< The ratio of the natural Ekman depth to the TKE decay scale, nondim. + real :: TKE_decay !< The ratio of the natural Ekman depth to the TKE decay scale [nondim]. real :: MKE_to_TKE_effic !< The efficiency with which mean kinetic energy released by !! mechanically forced entrainment of the mixed layer is converted to - !! TKE, nondim. + !! TKE [nondim]. ! real :: Hmix_min !< The minimum mixed layer thickness in m. - real :: ustar_min !< A minimum value of ustar to avoid numerical problems, in m s-1. + real :: ustar_min !< A minimum value of ustar to avoid numerical problems [m s-1]. !! If the value is small enough, this should not affect the solution. - real :: omega !< The Earth's rotation rate, in s-1. + real :: omega !< The Earth's rotation rate [s-1]. real :: omega_frac !< When setting the decay scale for turbulence, use this fraction of !! the absolute rotation rate blended with the local value of f, as !! sqrt((1-of)*f^2 + of*4*omega^2). real :: wstar_ustar_coef !< A ratio relating the efficiency with which convectively released !! energy is converted to a turbulent velocity, relative to - !! mechanically forced turbulent kinetic energy, nondim. + !! mechanically forced turbulent kinetic energy [nondim]. !! Making this larger increases the diffusivity. real :: vstar_scale_fac !< An overall nondimensional scaling factor for vstar times a unit !! conversion factor. Making this larger increases the diffusivity. @@ -63,8 +68,8 @@ module MOM_energetic_PBL !! boundary layer thickness. The default is 0, but a !! value of 0.1 might be better justified by observations. real :: MLD_tol !< A tolerance for determining the boundary layer thickness when - !! Use_MLD_iteration is true, in Z. - real :: min_mix_len !< The minimum mixing length scale that will be used by ePBL, in Z. + !! Use_MLD_iteration is true [Z ~> m]. + real :: min_mix_len !< The minimum mixing length scale that will be used by ePBL [Z ~> m]. !! The default (0) does not set a minimum. real :: N2_Dissipation_Scale_Neg !< A nondimensional scaling factor controlling the loss of TKE !! due to enhanced dissipation in the presence of negative (unstable) @@ -136,30 +141,30 @@ module MOM_energetic_PBL type(diag_ctrl), pointer :: diag=>NULL() !< A structure that is used to regulate the !! timing of diagnostic output. - ! These are terms in the mixed layer TKE budget, all in J m-2 = kg s-2. + ! These are terms in the mixed layer TKE budget, all in [J m-2] = [kg s-2]. real, allocatable, dimension(:,:) :: & - diag_TKE_wind, & !< The wind source of TKE, in J m-2. - diag_TKE_MKE, & !< The resolved KE source of TKE, in J m-2. - diag_TKE_conv, & !< The convective source of TKE, in J m-2. - diag_TKE_forcing, & !< The TKE sink required to mix surface penetrating shortwave heating, in J m-2. - diag_TKE_mech_decay, & !< The decay of mechanical TKE, in J m-2. - diag_TKE_conv_decay, & !< The decay of convective TKE, in J m-2. - diag_TKE_mixing,& !< The work done by TKE to deepen the mixed layer, in J m-2. + diag_TKE_wind, & !< The wind source of TKE [J m-2]. + diag_TKE_MKE, & !< The resolved KE source of TKE [J m-2]. + diag_TKE_conv, & !< The convective source of TKE [J m-2]. + diag_TKE_forcing, & !< The TKE sink required to mix surface penetrating shortwave heating [J m-2]. + diag_TKE_mech_decay, & !< The decay of mechanical TKE [J m-2]. + diag_TKE_conv_decay, & !< The decay of convective TKE [J m-2]. + diag_TKE_mixing,& !< The work done by TKE to deepen the mixed layer [J m-2]. ! Additional output parameters also 2d - ML_depth, & !< The mixed layer depth in Z. (result after iteration step) - ML_depth2, & !< The mixed layer depth in Z. (guess for iteration step) - Enhance_M, & !< The enhancement to the turbulent velocity scale (non-dim) - MSTAR_MIX, & !< Mstar used in EPBL - MSTAR_LT, & !< Mstar for Langmuir turbulence - MLD_EKMAN, & !< MLD over Ekman length - MLD_OBUKHOV, & !< MLD over Obukhov length - EKMAN_OBUKHOV, & !< Ekman over Obukhov length - LA, & !< Langmuir number - LA_MOD !< Modified Langmuir number + ML_depth, & !< The mixed layer depth [Z ~> m]. (result after iteration step) + ML_depth2, & !< The mixed layer depth [Z ~> m]. (guess for iteration step) + Enhance_M, & !< The enhancement to the turbulent velocity scale [nondim] + MSTAR_MIX, & !< Mstar used in EPBL [nondim] + MSTAR_LT, & !< Mstar for Langmuir turbulence [nondim] + MLD_EKMAN, & !< MLD over Ekman length [nondim] + MLD_OBUKHOV, & !< MLD over Obukhov length [nondim] + EKMAN_OBUKHOV, & !< Ekman over Obukhov length [nondim] + LA, & !< Langmuir number [nondim] + LA_MOD !< Modified Langmuir number [nondim] real, allocatable, dimension(:,:,:) :: & - Velocity_Scale, & !< The velocity scale used in getting Kd - Mixing_Length !< The length scale used in getting Kd + Velocity_Scale, & !< The velocity scale used in getting Kd [Z s-1 ~> m s-1] + Mixing_Length !< The length scale used in getting Kd [Z ~> m] !>@{ Diagnostic IDs integer :: id_ML_depth = -1, id_TKE_wind = -1, id_TKE_mixing = -1 integer :: id_TKE_MKE = -1, id_TKE_conv = -1, id_TKE_forcing = -1 @@ -185,41 +190,41 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, US, CS type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: h_3d !< Layer thicknesses, in H (usually m or kg m-2). + intent(inout) :: h_3d !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: u_3d !< Zonal velocities interpolated to h points, - !! m s-1. + intent(in) :: u_3d !< Zonal velocities interpolated to h points + !! [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: v_3d !< Zonal velocities interpolated to h points, - !! m s-1. + intent(in) :: v_3d !< Zonal velocities interpolated to h points + !! [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: dSV_dT !< The partial derivative of in-situ specific - !! volume with potential temperature, - !! in m3 kg-1 K-1. + !! volume with potential temperature + !! [m3 kg-1 degC-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: dSV_dS !< The partial derivative of in-situ specific - !! volume with salinity, in m3 kg-1 ppt-1. + !! volume with salinity [m3 kg-1 ppt-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: TKE_forced !< The forcing requirements to homogenize the !! forcing that has been applied to each layer - !! through each layer, in J m-2. + !! through each layer [J m-2]. type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs. type(forcing), intent(inout) :: fluxes !< A structure containing pointers to any !! possible forcing fields. Unused fields have !! NULL ptrs. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), & - intent(out) :: Kd_int !< The diagnosed diffusivities at interfaces, - !! in Z2 s-1. + intent(out) :: Kd_int !< The diagnosed diffusivities at interfaces + !! [Z2 s-1 ~> m2 s-1]. type(energetic_PBL_CS), pointer :: CS !< The control structure returned by a previous !! call to mixedlayer_init. real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: Buoy_Flux !< The surface buoyancy flux in Z2/s3. + intent(in) :: Buoy_Flux !< The surface buoyancy flux [Z2 s-3 ~> m2 s-3]. real, optional, intent(in) :: dt_diag !< The diagnostic time step, which may be less !! than dt if there are two callse to - !! mixedlayer, in s. + !! mixedlayer [s]. logical, optional, intent(in) :: last_call !< If true, this is the last call to !! mixedlayer in the current time step, so !! diagnostics will be written. The default @@ -227,11 +232,11 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, US, CS real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & optional, intent(out) :: dT_expected !< The values of temperature change that !! should be expected when the returned - !! diffusivities are applied, in K. + !! diffusivities are applied [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & optional, intent(out) :: dS_expected !< The values of salinity change that !! should be expected when the returned - !! diffusivities are applied, in psu. + !! diffusivities are applied [ppt]. type(wave_parameters_CS), & optional, pointer :: Waves !< Wave CS @@ -257,147 +262,149 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, US, CS ! For a traditional Kraus-Turner mixed layer, the values are: ! mstar = 1.25, nstar = 0.4, TKE_decay = 0.0, conv_decay = 0.0 + ! Local variables real, dimension(SZI_(G),SZK_(GV)) :: & - h, & ! The layer thickness, in H (usually m or kg m-2). - T, & ! The layer temperatures, in deg C. - S, & ! The layer salinities, in psu. - u, & ! The zonal velocity, in m s-1. - v ! The meridional velocity, in m s-1. + h, & ! The layer thickness [H ~> m or kg m-2]. + T, & ! The layer temperatures [degC]. + S, & ! The layer salinities [ppt]. + u, & ! The zonal velocity [m s-1]. + v ! The meridional velocity [m s-1]. real, dimension(SZI_(G),SZK_(GV)+1) :: & - Kd, & ! The diapycnal diffusivity, in m2 s-1. - pres, & ! Interface pressures in Pa. + Kd, & ! The diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. + pres, & ! Interface pressures [Pa]. pres_Z, & ! Interface pressures with a rescaling factor to convert interface height - ! movements into changes in column potential energy, in J m-2 Z-1. + ! movements into changes in column potential energy [J m-2 Z-1 ~> J m-3]. hb_hs ! The distance from the bottom over the thickness of the - ! water column, nondim. + ! water column [nondim]. real, dimension(SZI_(G)) :: & mech_TKE, & ! The mechanically generated turbulent kinetic energy - ! available for mixing over a time step, in J m-2 = kg s-2. + ! available for mixing over a time step [J m-2 = kg s-2]. conv_PErel, & ! The potential energy that has been convectively released - ! during this timestep, in J m-2 = kg s-2. A portion nstar_FC + ! during this timestep [J m-2 = kg s-2]. A portion nstar_FC ! of conv_PErel is available to drive mixing. - htot, & ! The total depth of the layers above an interface, in H. + htot, & ! The total depth of the layers above an interface [H ~> m or kg m-2]. uhtot, & ! The depth integrated zonal and meridional velocities in the - vhtot, & ! layers above, in H m s-1. - mech_TKE_top, & ! The value of mech_TKE at the top of the column, in J m-2. - conv_PErel_top, & ! The value of conv_PErel at the top of the column, in J m-2. + vhtot, & ! layers above [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + mech_TKE_top, & ! The value of mech_TKE at the top of the column [J m-2]. + conv_PErel_top, & ! The value of conv_PErel at the top of the column [J m-2]. - Idecay_len_TKE, & ! The inverse of a turbulence decay length scale, in H-1. - h_sum, & ! The total thickness of the water column, in H. - absf ! The absolute value of f, in s-1. + Idecay_len_TKE, & ! The inverse of a turbulence decay length scale [H-1 ~> m-1 or m2 kg-1]. + h_sum, & ! The total thickness of the water column [H ~> m or kg m-2]. + absf ! The absolute value of f [s-1]. real, dimension(SZI_(G),SZK_(GV)) :: & dT_to_dColHt, & ! Partial derivatives of the total column height with the temperature - dS_to_dColHt, & ! and salinity changes within a layer, in Z K-1 and Z ppt-1. + dS_to_dColHt, & ! and salinity changes within a layer [Z degC-1 ~> m degC-1] and [Z ppt-1 ~> m ppt-1]. dT_to_dPE, & ! Partial derivatives of column potential energy with the temperature - dS_to_dPE, & ! and salinity changes within a layer, in J m-2 K-1 and J m-2 ppt-1. + dS_to_dPE, & ! and salinity changes within a layer, in [J m-2 degC-1] and [J m-2 ppt-1]. dT_to_dColHt_a, & ! Partial derivatives of the total column height with the temperature dS_to_dColHt_a, & ! and salinity changes within a layer, including the implicit effects - ! of mixing with layers higher in the water colun, in Z K-1 and Z ppt-1. + ! of mixing with layers higher in the water colun [Z degC-1 ~> m degC-1] and [Z ppt-1 ~> m ppt-1]. dT_to_dPE_a, & ! Partial derivatives of column potential energy with the temperature dS_to_dPE_a ! and salinity changes within a layer, including the implicit effects ! of mixing with layers higher in the water column, in - ! units of J m-2 K-1 and J m-2 ppt-1. + ! units of [J m-2 degC-1] and [J m-2 ppt-1]. real, dimension(SZK_(GV)) :: & - T0, S0, & ! Initial values of T and S in the column, in K and ppt. - Te, Se, & ! Estimated final values of T and S in the column, in K and ppt. - c1, & ! c1 is used by the tridiagonal solver, ND. + T0, S0, & ! Initial values of T and S in the column, in [degC] and [ppt]. + Te, Se, & ! Estimated final values of T and S in the column, in [degC] and [ppt]. + c1, & ! c1 is used by the tridiagonal solver [nondim]. dTe, dSe ! Running (1-way) estimates of temperature and salinity change. real, dimension(SZK_(GV)) :: & - Th_a, & ! An effective temperature times a thickness in the layer above, - ! including implicit mixing effects with other yet higher layers, in K H. - Sh_a, & ! An effective salinity times a thickness in the layer above, - ! including implicit mixing effects with other yet higher layers, in K H. - Th_b, & ! An effective temperature times a thickness in the layer below, - ! including implicit mixing effects with other yet lower layers, in K H. - Sh_b ! An effective salinity times a thickness in the layer below, - ! including implicit mixing effects with other yet lower layers, in K H. + Th_a, & ! An effective temperature times a thickness in the layer above, including implicit + ! mixing effects with other yet higher layers [degC H ~> degC m or degC kg m-2]. + Sh_a, & ! An effective salinity times a thickness in the layer above, including implicit + ! mixing effects with other yet higher layers [ppt H ~> ppt m or ppt kg m-2]. + Th_b, & ! An effective temperature times a thickness in the layer below, including implicit + ! mixing effects with other yet lower layers [degC H ~> degC m or degC kg m-2]. + Sh_b ! An effective salinity times a thickness in the layer below, including implicit + ! mixing effects with other yet lower layers [ppt H ~> ppt m or ppt kg m-2]. real, dimension(SZI_(G)) :: & hp_a ! An effective pivot thickness of the layer including the effects - ! of coupling with layers above, in H. This is the first term + ! of coupling with layers above [H ~> m or kg m-2]. This is the first term ! in the denominator of b1 in a downward-oriented tridiagonal solver. real, dimension(SZK_(GV)+1) :: & MixLen_shape, & ! A nondimensional shape factor for the mixing length that ! gives it an appropriate assymptotic value at the bottom of ! the boundary layer. Kddt_h ! The diapycnal diffusivity times a timestep divided by the - ! average thicknesses around a layer, in H (m or kg m-2). - real :: b1 ! b1 is inverse of the pivot used by the tridiagonal solver, in H-1. + ! average thicknesses around a layer [H ~> m or kg m-2]. + real :: b1 ! b1 is inverse of the pivot used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: dMass ! The mass per unit area within a layer, in kg m-2. - real :: dPres ! The hydrostatic pressure change across a layer, in Pa. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: dMass ! The mass per unit area within a layer [kg m-2]. + real :: dPres ! The hydrostatic pressure change across a layer [Pa]. real :: dMKE_max ! The maximum amount of mean kinetic energy that could be ! converted to turbulent kinetic energy if the velocity in ! the layer below an interface were homogenized with all of - ! the water above the interface, in J m-2 = kg s-2. + ! the water above the interface [J m-2 = kg s-2]. real :: MKE2_Hharm ! Twice the inverse of the harmonic mean of the thickness ! of a layer and the thickness of the water above, used in - ! the MKE conversion equation, in H-1. + ! the MKE conversion equation [H-1 ~> m-1 or m2 kg-1]. real :: dt_h ! The timestep divided by the averages of the thicknesses around - ! a layer, times a thickness conversion factor, in H s m-2. - real :: h_bot ! The distance from the bottom, in H. - real :: h_rsum ! The running sum of h from the top, in Z. - real :: I_hs ! The inverse of h_sum, in H-1. - real :: I_MLD ! The inverse of the current value of MLD, in Z-1. + ! a layer, times a thickness conversion factor [H s m-2 ~> s m-1 or kg s m-4]. + real :: h_bot ! The distance from the bottom [H ~> m or kg m-2]. + real :: h_rsum ! The running sum of h from the top [Z ~> m]. + real :: I_hs ! The inverse of h_sum [H-1 ~> m-1 or m2 kg-1]. + real :: I_MLD ! The inverse of the current value of MLD [Z-1 ~> m-1]. real :: h_tt ! The distance from the surface or up to the next interface ! that did not exhibit turbulent mixing from this scheme plus - ! a surface mixing roughness length given by h_tt_min, in H. - real :: h_tt_min ! A surface roughness length, in H. + ! a surface mixing roughness length given by h_tt_min [H ~> m or kg m-2]. + real :: h_tt_min ! A surface roughness length [H ~> m or kg m-2]. real :: C1_3 ! = 1/3. real :: vonKar ! The vonKarman constant. - real :: I_dtrho ! 1.0 / (dt * Rho0) in m3 kg-1 s-1. This is + real :: I_dtrho ! 1.0 / (dt * Rho0) in [m3 kg-1 s-1]. This is ! used convert TKE back into ustar^3. - real :: U_star ! The surface friction velocity, in Z s-1. - real :: U_Star_Mean ! The surface friction without gustiness in Z s-1. - real :: vstar ! An in-situ turbulent velocity, in m s-1. + real :: U_star ! The surface friction velocity [Z s-1 ~> m s-1]. + real :: U_Star_Mean ! The surface friction without gustiness [Z s-1 ~> m s-1]. + real :: vstar ! An in-situ turbulent velocity [m s-1]. real :: Enhance_M ! An enhancement factor for vstar, based here on Langmuir impact. - real :: LA ! The Langmuir number (non-dim) + real :: LA ! The Langmuir number [nondim] real :: LAmod ! A modified Langmuir number accounting for other parameters. real :: hbs_here ! The local minimum of hb_hs and MixLen_shape, times a - ! conversion factor from H to Z, in Z H-1. - real :: nstar_FC ! The fraction of conv_PErel that can be converted to mixing, nondim. + ! conversion factor from H to Z [Z H-1 ~> 1 or m3 kg-1]. + real :: nstar_FC ! The fraction of conv_PErel that can be converted to mixing [nondim]. real :: TKE_reduc ! The fraction by which TKE and other energy fields are - ! reduced to support mixing, nondim. between 0 and 1. - real :: tot_TKE ! The total TKE available to support mixing at interface K, in J m-2. - real :: TKE_here ! The total TKE at this point in the algorithm, in J m-2. + ! reduced to support mixing [nondim]. between 0 and 1. + real :: tot_TKE ! The total TKE available to support mixing at interface K [J m-2]. + real :: TKE_here ! The total TKE at this point in the algorithm [J m-2]. real :: dT_km1_t2 ! A diffusivity-independent term related to the temperature - ! change in the layer above the interface, in K. + ! change in the layer above the interface [degC]. real :: dS_km1_t2 ! A diffusivity-independent term related to the salinity - ! change in the layer above the interface, in ppt. + ! change in the layer above the interface [ppt]. real :: dTe_term ! A diffusivity-independent term related to the temperature - ! change in the layer below the interface, in K H. + ! change in the layer below the interface [degC H ~> degC m or degC kg m-2]. real :: dSe_term ! A diffusivity-independent term related to the salinity - ! change in the layer above the interface, in ppt H. - real :: dTe_t2 ! A part of dTe_term, in K H. - real :: dSe_t2 ! A part of dSe_term, in ppt H. - real :: dPE_conv ! The convective change in column potential energy, in J m-2. - real :: MKE_src ! The mean kinetic energy source of TKE due to Kddt_h(K), in J m-2. - real :: dMKE_src_dK ! The partial derivative of MKE_src with Kddt_h(K), in J m-2 H-1. - real :: Kd_guess0 ! A first guess of the diapycnal diffusivity, in Z2 s-1. - real :: PE_chg_g0 ! The potential energy change when Kd is Kd_guess0 + ! change in the layer above the interface [ppt H ~> ppt m or ppt kg m-2]. + real :: dTe_t2 ! A part of dTe_term [degC H ~> degC m or degC kg m-2]. + real :: dSe_t2 ! A part of dSe_term [ppt H ~> ppt m or ppt kg m-2]. + real :: dPE_conv ! The convective change in column potential energy [J m-2]. + real :: MKE_src ! The mean kinetic energy source of TKE due to Kddt_h(K) [J m-2]. + real :: dMKE_src_dK ! The partial derivative of MKE_src with Kddt_h(K) [J m-2 H-1 ~> J m-3 or J kg-1]. + real :: Kd_guess0 ! A first guess of the diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. + real :: PE_chg_g0 ! The potential energy change when Kd is Kd_guess0 [J m-2] real :: dPEa_dKd_g0 real :: Kddt_h_g0 ! The first guess diapycnal diffusivity times a timestep divided - ! by the average thicknesses around a layer, in H (m or kg m-2). + ! by the average thicknesses around a layer [H ~> m or kg m-2]. real :: PE_chg_max ! The maximum PE change for very large values of Kddt_h(K). real :: dPEc_dKd_Kd0 ! The partial derivative of PE change with Kddt_h(K) - ! for very small values of Kddt_h(K), in J m-2 H-1. + ! for very small values of Kddt_h(K) [J m-2 H-1 ~> J m-3 or J kg-1]. real :: PE_chg ! The change in potential energy due to mixing at an - ! interface, in J m-2, positive for the column increasing + ! interface [J m-2], positive for the column increasing ! in potential energy (i.e., consuming TKE). real :: TKE_left ! The amount of turbulent kinetic energy left for the most - ! recent guess at Kddt_h(K), in J m-2. - real :: dPEc_dKd ! The partial derivative of PE_chg with Kddt_h(K), in J m-2 H-1. - real :: TKE_left_min, TKE_left_max, Kddt_h_max, Kddt_h_min - real :: Kddt_h_guess ! A guess at the value of Kddt_h(K), in H. - real :: Kddt_h_next ! The next guess at the value of Kddt_h(K), in H. - real :: dKddt_h ! The change between guesses at Kddt_h(K), in H. - real :: dKddt_h_Newt ! The change between guesses at Kddt_h(K) with Newton's method, in H. - real :: Kddt_h_newt ! The Newton's method next guess for Kddt_h(K), in H. - real :: exp_kh ! The nondimensional decay of TKE across a layer, ND. + ! recent guess at Kddt_h(K) [J m-2]. + real :: dPEc_dKd ! The partial derivative of PE_chg with Kddt_h(K) [J m-2 H-1 ~> J m-3 or J kg-1]. + real :: TKE_left_min, TKE_left_max ! Maximum and minimum values of TKE_left [J m-2]. + real :: Kddt_h_max, Kddt_h_min ! Maximum and minimum values of Kddt_h(K) [H ~> m or kg m-2]. + real :: Kddt_h_guess ! A guess at the value of Kddt_h(K) [H ~> m or kg m-2]. + real :: Kddt_h_next ! The next guess at the value of Kddt_h(K) [H ~> m or kg m-2]. + real :: dKddt_h ! The change between guesses at Kddt_h(K) [H ~> m or kg m-2]. + real :: dKddt_h_Newt ! The change between guesses at Kddt_h(K) with Newton's method [H ~> m or kg m-2]. + real :: Kddt_h_newt ! The Newton's method next guess for Kddt_h(K) [H ~> m or kg m-2]. + real :: exp_kh ! The nondimensional decay of TKE across a layer [nondim]. logical :: use_Newt ! Use Newton's method for the next guess at Kddt_h(K). logical :: convectively_stable logical, dimension(SZI_(G)) :: & @@ -407,20 +414,20 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, US, CS ! from the surface. ! The following is only used as a diagnostic. - real :: dt__diag ! A copy of dt_diag (if present) or dt, in s. - real :: IdtdR0 ! = 1.0 / (dt__diag * Rho0), in m3 kg-1 s-1. + real :: dt__diag ! A copy of dt_diag (if present) or dt [s]. + real :: IdtdR0 ! = 1.0 / (dt__diag * Rho0) [m3 kg-1 s-1]. real, dimension(SZI_(G),SZJ_(G)) :: & - Hsfc_used ! The thickness of the surface region in Z + Hsfc_used ! The thickness of the surface region [Z ~> m]. logical :: write_diags ! If true, write out diagnostics with this step. logical :: reset_diags ! If true, zero out the accumulated diagnostics. - ! Local column copies of energy change diagnostics, all in J m-2. + ! Local column copies of energy change diagnostics, all [J m-2]. real :: dTKE_conv, dTKE_forcing, dTKE_mixing real :: dTKE_MKE, dTKE_mech_decay, dTKE_conv_decay !---------------------------------------------------------------------- !/BGR added Aug24,2016 for adding iteration to get boundary layer depth ! - needed to compute new mixing length. - real :: MLD_guess, MLD_found ! Mixing Layer depth guessed/found for iteration, in Z. - real :: max_MLD, min_MLD ! Iteration bounds, in Z, which are adjusted at each step + real :: MLD_guess, MLD_found ! Mixing Layer depth guessed/found for iteration [Z ~> m]. + real :: max_MLD, min_MLD ! Iteration bounds [Z ~> m], which are adjusted at each step ! - These are initialized based on surface/bottom ! 1. The iteration guesses a value (possibly from ! prev step or neighbor). @@ -470,9 +477,9 @@ subroutine energetic_PBL(h_3d, u_3d, v_3d, tv, fluxes, dt, Kd_int, G, GV, US, CS real :: N2_dissipation real :: Bf_STABLE ! Buoyancy flux, capped at 0 (negative only) real :: Bf_UNSTABLE ! Buoyancy flux, floored at 0 (positive only) - real :: Stab_Scale ! Composite of stabilizing Ekman scale and Monin-Obukhov length scales, in Z - real :: iL_Ekman ! Inverse of Ekman length scale, in Z-1 - real :: iL_Obukhov ! Inverse of Obukhov length scale, in Z-1 + real :: Stab_Scale ! Composite of stabilizing Ekman scale and Monin-Obukhov length scales [Z ~> m]. + real :: iL_Ekman ! Inverse of Ekman length scale [Z-1 ~> m-1]. + real :: iL_Obukhov ! Inverse of Obukhov length scale [Z-1 ~> m-1]. real :: MLD_o_Ekman ! > real :: MLD_o_Obukhov_stab ! Ratios of length scales where MLD is boundary layer depth real :: Ekman_o_Obukhov_stab ! > @@ -1551,88 +1558,88 @@ subroutine find_PE_chg(Kddt_h0, dKddt_h, hp_a, hp_b, Th_a, Sh_a, Th_b, Sh_b, & PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0, ColHt_cor) real, intent(in) :: Kddt_h0 !< The previously used diffusivity at an interface times !! the time step and divided by the average of the - !! thicknesses around the interface, in units of H (m or kg-2). + !! thicknesses around the interface [H ~> m or kg m-2]. real, intent(in) :: dKddt_h !< The trial change in the diffusivity at an interface times !! the time step and divided by the average of the - !! thicknesses around the interface, in units of H (m or kg-2). + !! thicknesses around the interface [H ~> m or kg m-2]. real, intent(in) :: hp_a !< The effective pivot thickness of the layer above the !! interface, given by h_k plus a term that !! is a fraction (determined from the tridiagonal solver) of - !! Kddt_h for the interface above, in H. + !! Kddt_h for the interface above [H ~> m or kg m-2]. real, intent(in) :: hp_b !< The effective pivot thickness of the layer below the !! interface, given by h_k plus a term that !! is a fraction (determined from the tridiagonal solver) of - !! Kddt_h for the interface above, in H. + !! Kddt_h for the interface above [H ~> m or kg m-2]. real, intent(in) :: Th_a !< An effective temperature times a thickness in the layer !! above, including implicit mixing effects with other - !! yet higher layers, in K H. + !! yet higher layers [degC H ~> degC m or degC kg m-2]. real, intent(in) :: Sh_a !< An effective salinity times a thickness in the layer !! above, including implicit mixing effects with other - !! yet higher layers, in K H. + !! yet higher layers [degC H ~> degC m or degC kg m-2]. real, intent(in) :: Th_b !< An effective temperature times a thickness in the layer !! below, including implicit mixing effects with other - !! yet lower layers, in K H. + !! yet lower layers [degC H ~> degC m or degC kg m-2]. real, intent(in) :: Sh_b !< An effective salinity times a thickness in the layer !! below, including implicit mixing effects with other - !! yet lower layers, in K H. + !! yet lower layers [degC H ~> degC m or degC kg m-2]. real, intent(in) :: dT_to_dPE_a !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers above, in J m-2 K-1. + !! in the temperatures of all the layers above [J m-2 degC-1]. real, intent(in) :: dS_to_dPE_a !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers above, in J m-2 ppt-1. + !! in the salinities of all the layers above [J m-2 ppt-1]. real, intent(in) :: dT_to_dPE_b !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers below, in J m-2 K-1. + !! in the temperatures of all the layers below [J m-2 degC-1]. real, intent(in) :: dS_to_dPE_b !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers below, in J m-2 ppt-1. + !! in the salinities of all the layers below [J m-2 ppt-1]. real, intent(in) :: pres_Z !< The rescaled hydrostatic interface pressure, which relates !! the changes in column thickness to the energy that is radiated - !! as gravity waves and unavailable to drive mixing, in J m-2 Z-1. + !! as gravity waves and unavailable to drive mixing [J m-2 Z-1 ~> J m-3]. real, intent(in) :: dT_to_dColHt_a !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers above, in Z K-1. + !! in the temperatures of all the layers above [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHt_a !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers above, in Z ppt-1. + !! in the salinities of all the layers above [Z ppt-1 ~> m ppt-1]. real, intent(in) :: dT_to_dColHt_b !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers below, in Z K-1. + !! in the temperatures of all the layers below [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHt_b !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers below, in Z ppt-1. + !! in the salinities of all the layers below [Z ppt-1 ~> m ppt-1]. real, optional, intent(out) :: PE_chg !< The change in column potential energy from applying - !! Kddt_h at the present interface, in J m-2. - real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h, - !! in units of J m-2 H-1. + !! Kddt_h at the present interface [J m-2]. + real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h + !! [J m-2 H-1 ~> J m-3 or J kg-1]. real, optional, intent(out) :: dPE_max !< The maximum change in column potential energy that could !! be realizedd by applying a huge value of Kddt_h at the - !! present interface, in J m-2. + !! present interface [J m-2]. real, optional, intent(out) :: dPEc_dKd_0 !< The partial derivative of PE_chg with Kddt_h in the - !! limit where Kddt_h = 0, in J m-2 H-1. + !! limit where Kddt_h = 0 [J m-2 H-1 ~> J m-3 or J kg-1]. real, optional, intent(out) :: ColHt_cor !< The correction to PE_chg that is made due to a net - !! change in the column height, in J m-2. + !! change in the column height [J m-2]. - real :: hps ! The sum of the two effective pivot thicknesses, in H. - real :: bdt1 ! A product of the two pivot thicknesses plus a diffusive term, in H2. - real :: dT_c ! The core term in the expressions for the temperature changes, in K H2. - real :: dS_c ! The core term in the expressions for the salinity changes, in psu H2. + real :: hps ! The sum of the two effective pivot thicknesses [H ~> m or kg m-2]. + real :: bdt1 ! A product of the two pivot thicknesses plus a diffusive term [H2 ~> m2 or kg2 m-4]. + real :: dT_c ! The core term in the expressions for the temperature changes [degC H2 ~> degC m2 or degC kg2 m-4]. + real :: dS_c ! The core term in the expressions for the salinity changes [ppt H2 ~> ppt m2 or ppt kg2 m-4]. real :: PEc_core ! The diffusivity-independent core term in the expressions - ! for the potential energy changes, J m-3. + ! for the potential energy changes [J m-3]. real :: ColHt_core ! The diffusivity-independent core term in the expressions - ! for the column height changes, J m-3. - real :: ColHt_chg ! The change in the column height, in m. - real :: y1 ! A local temporary term, in units of H-3 or H-4 in various contexts. + ! for the column height changes [J m-3]. + real :: ColHt_chg ! The change in the column height [H ~> m or kg m-2]. + real :: y1 ! A local temporary term, [H-3 ~> m-3 or m6 kg-3] or [H-4 ~> m-4 or m8 kg-4] in various contexts. ! The expression for the change in potential energy used here is derived ! from the expression for the final estimates of the changes in temperature @@ -1700,65 +1707,65 @@ subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & PE_chg, dPEc_dKd, dPE_max, dPEc_dKd_0) real, intent(in) :: Kddt_h !< The diffusivity at an interface times the time step and !! divided by the average of the thicknesses around the - !! interface, in units of H (m or kg-2). - real, intent(in) :: h_k !< The thickness of the layer below the interface, in H. + !! interface [H ~> m or kg m-2]. + real, intent(in) :: h_k !< The thickness of the layer below the interface [H ~> m or kg m-2]. real, intent(in) :: b_den_1 !< The first term in the denominator of the pivot !! for the tridiagonal solver, given by h_k plus a term that !! is a fraction (determined from the tridiagonal solver) of - !! Kddt_h for the interface above, in H. - real, intent(in) :: dTe_term !< A diffusivity-independent term related to the - !! temperature change in the layer below the interface, in K H. - real, intent(in) :: dSe_term !< A diffusivity-independent term related to the - !! salinity change in the layer below the interface, in ppt H. + !! Kddt_h for the interface above [H ~> m or kg m-2]. + real, intent(in) :: dTe_term !< A diffusivity-independent term related to the temperature change + !! in the layer below the interface [degC H ~> degC m or degC kg m-2]. + real, intent(in) :: dSe_term !< A diffusivity-independent term related to the salinity change + !! in the layer below the interface [ppt H ~> ppt m or ppt kg m-2]. real, intent(in) :: dT_km1_t2 !< A diffusivity-independent term related to the - !! temperature change in the layer above the interface, in K. + !! temperature change in the layer above the interface [degC]. real, intent(in) :: dS_km1_t2 !< A diffusivity-independent term related to the - !! salinity change in the layer above the interface, in ppt. + !! salinity change in the layer above the interface [ppt]. real, intent(in) :: pres_Z !< The rescaled hydrostatic interface pressure, which relates !! the changes in column thickness to the energy that is radiated - !! as gravity waves and unavailable to drive mixing, in J m-2 Z-1. + !! as gravity waves and unavailable to drive mixing [J m-2 Z-1 ~> J m-3]. real, intent(in) :: dT_to_dPE_k !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers below, in J m-2 K-1. + !! in the temperatures of all the layers below [J m-2 degC-1]. real, intent(in) :: dS_to_dPE_k !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers below, in J m-2 ppt-1. + !! in the salinities of all the layers below [J m-2 ppt-1]. real, intent(in) :: dT_to_dPEa !< A factor (pres_lay*mass_lay*dSpec_vol/dT) relating !! a layer's temperature change to the change in column !! potential energy, including all implicit diffusive changes - !! in the temperatures of all the layers above, in J m-2 K-1. + !! in the temperatures of all the layers above [J m-2 degC-1]. real, intent(in) :: dS_to_dPEa !< A factor (pres_lay*mass_lay*dSpec_vol/dS) relating !! a layer's salinity change to the change in column !! potential energy, including all implicit diffusive changes - !! in the salinities of all the layers above, in J m-2 ppt-1. + !! in the salinities of all the layers above [J m-2 ppt-1]. real, intent(in) :: dT_to_dColHt_k !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers below, in Z K-1. + !! in the temperatures of all the layers below [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHt_k !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers below, in Z ppt-1. + !! in the salinities of all the layers below [Z ppt-1 ~> m ppt-1]. real, intent(in) :: dT_to_dColHta !< A factor (mass_lay*dSColHtc_vol/dT) relating !! a layer's temperature change to the change in column !! height, including all implicit diffusive changes - !! in the temperatures of all the layers above, in Z K-1. + !! in the temperatures of all the layers above [Z degC-1 ~> m degC-1]. real, intent(in) :: dS_to_dColHta !< A factor (mass_lay*dSColHtc_vol/dS) relating !! a layer's salinity change to the change in column !! height, including all implicit diffusive changes - !! in the salinities of all the layers above, in Z ppt-1. + !! in the salinities of all the layers above [Z ppt-1 ~> m ppt-1]. real, optional, intent(out) :: PE_chg !< The change in column potential energy from applying - !! Kddt_h at the present interface, in J m-2. - real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h, - !! in units of J m-2 H-1. + !! Kddt_h at the present interface [J m-2]. + real, optional, intent(out) :: dPEc_dKd !< The partial derivative of PE_chg with Kddt_h + !! [J m-2 H-1 ~> J m-3 or J kg-1]. real, optional, intent(out) :: dPE_max !< The maximum change in column potential energy that could !! be realizedd by applying a huge value of Kddt_h at the - !! present interface, in J m-2. + !! present interface [J m-2]. real, optional, intent(out) :: dPEc_dKd_0 !< The partial derivative of PE_chg with Kddt_h in the - !! limit where Kddt_h = 0, in J m-2 H-1. + !! limit where Kddt_h = 0 [J m-2 H-1 ~> J m-3 or J kg-1]. ! This subroutine determines the total potential energy change due to mixing ! at an interface, including all of the implicit effects of the prescribed @@ -1769,16 +1776,17 @@ subroutine find_PE_chg_orig(Kddt_h, h_k, b_den_1, dTe_term, dSe_term, & ! this routine can also be used for an upward pass with the sense of direction ! reversed. - real :: b1 ! b1 is used by the tridiagonal solver, in H-1. - real :: b1Kd ! Temporary array (nondim.) - real :: ColHt_chg ! The change in column thickness in m. - real :: dColHt_max ! The change in column thickess for infinite diffusivity, in m. - real :: dColHt_dKd ! The partial derivative of column thickess with diffusivity, in s m-1. - real :: dT_k, dT_km1 ! Temporary arrays in K. - real :: dS_k, dS_km1 ! Temporary arrays in ppt. - real :: I_Kr_denom, dKr_dKd ! Temporary arrays in H-2 and nondim. - real :: ddT_k_dKd, ddT_km1_dKd ! Temporary arrays in K H-1. - real :: ddS_k_dKd, ddS_km1_dKd ! Temporary arrays in ppt H-1. + real :: b1 ! b1 is used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. + real :: b1Kd ! Temporary array [nondim] + real :: ColHt_chg ! The change in column thickness [Z ~> m]. + real :: dColHt_max ! The change in column thickness for infinite diffusivity [Z ~> m]. + real :: dColHt_dKd ! The partial derivative of column thickness with diffusivity [s Z-1 ~> s m-1]. + real :: dT_k, dT_km1 ! Temporary arrays [degC]. + real :: dS_k, dS_km1 ! Temporary arrays [ppt]. + real :: I_Kr_denom ! Temporary array [H-2 ~> m-2 or m4 kg-2] + real :: dKr_dKd ! Nondimensional temporary array. + real :: ddT_k_dKd, ddT_km1_dKd ! Temporary arrays [degC H-1 ~> m-1 or m2 kg-1]. + real :: ddS_k_dKd, ddS_km1_dKd ! Temporary arrays [ppt H-1 ~> ppt m-1 or ppt m2 kg-1]. b1 = 1.0 / (b_den_1 + Kddt_h) b1Kd = Kddt_h*b1 @@ -1849,7 +1857,7 @@ subroutine energetic_PBL_get_MLD(CS, MLD, G, US, m_to_MLD_units) type(energetic_PBL_CS), pointer :: CS !< Control structure for ePBL type(ocean_grid_type), intent(in) :: G !< Grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G)), intent(out) :: MLD !< Depth of ePBL active mixing layer, in m + real, dimension(SZI_(G),SZJ_(G)), intent(out) :: MLD !< Depth of ePBL active mixing layer [m or other units] real, optional, intent(in) :: m_to_MLD_units !< A conversion factor to the desired units for MLD ! Local variables real :: scale ! A dimensional rescaling factor @@ -1865,10 +1873,10 @@ end subroutine energetic_PBL_get_MLD !> Computes wind speed from ustar_air based on COARE 3.5 Cd relationship subroutine ust_2_u10_coare3p5(USTair, U10, GV, US) - real, intent(in) :: USTair !< Ustar in the air, in m s-1. + real, intent(in) :: USTair !< Ustar in the air [m s-1]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(out) :: U10 !< The 10 m wind speed, in m s-1. + real, intent(out) :: U10 !< The 10 m wind speed [m s-1]. real, parameter :: vonkar = 0.4 real, parameter :: nu=1e-6 @@ -1911,14 +1919,14 @@ end subroutine ust_2_u10_coare3p5 !> This subroutine returns the Langmuir number, given ustar and the boundary !! layer thickness, inclusion conversion to the 10m wind. subroutine get_LA_windsea(ustar, hbl, GV, US, LA) - real, intent(in) :: ustar !< The water-side surface friction velocity (m/s) - real, intent(in) :: hbl !< The ocean boundary layer depth (m) + real, intent(in) :: ustar !< The water-side surface friction velocity [m s-1] + real, intent(in) :: hbl !< The ocean boundary layer depth [m] type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, intent(out) :: LA !< The Langmuir number returned from this module ! Original description: ! This function returns the enhancement factor, given the 10-meter -! wind (m/s), friction velocity (m/s) and the boundary layer depth (m). +! wind [m s-1], friction velocity [m s-1] and the boundary layer depth [m]. ! Update (Jan/25): ! Converted from function to subroutine, now returns Langmuir number. ! Computes 10m wind internally, so only ustar and hbl need passed to @@ -2011,16 +2019,9 @@ subroutine energetic_PBL_init(Time, G, GV, US, param_file, diag, CS) type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to regulate diagnostic output type(energetic_PBL_CS), pointer :: CS !< A pointer that is set to point to the control !! structure for this module -! Arguments: Time - The current model time. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) param_file - A structure indicating the open file to parse for -! model parameter values. -! (in) diag - A structure that is used to regulate diagnostic output. -! (in/out) CS - A pointer that is set to point to the control structure -! for this module -! This include declares and sets the variable "version". -#include "version_variable.h" + ! Local variables + ! This include declares and sets the variable "version". +# include "version_variable.h" character(len=40) :: mdl = "MOM_energetic_PBL" ! This module's name. real :: omega_frac_dflt integer :: isd, ied, jsd, jed @@ -2241,8 +2242,8 @@ subroutine energetic_PBL_init(Time, G, GV, US, param_file, diag, CS) CS%id_TKE_conv = register_diag_field('ocean_model', 'ePBL_TKE_conv', diag%axesT1, & Time, 'Convective source of mixed layer TKE', 'm3 s-3') CS%id_TKE_forcing = register_diag_field('ocean_model', 'ePBL_TKE_forcing', diag%axesT1, & - Time, 'TKE consumed by mixing surface forcing or penetrative shortwave radation'//& - ' through model layers', 'm3 s-3') + Time, 'TKE consumed by mixing surface forcing or penetrative shortwave radation '//& + 'through model layers', 'm3 s-3') CS%id_TKE_mixing = register_diag_field('ocean_model', 'ePBL_TKE_mixing', diag%axesT1, & Time, 'TKE consumed by mixing that deepens the mixed layer', 'm3 s-3') CS%id_TKE_mech_decay = register_diag_field('ocean_model', 'ePBL_TKE_mech_decay', diag%axesT1, & diff --git a/src/parameterizations/vertical/MOM_entrain_diffusive.F90 b/src/parameterizations/vertical/MOM_entrain_diffusive.F90 index af9eb9bfba..824bab78b2 100644 --- a/src/parameterizations/vertical/MOM_entrain_diffusive.F90 +++ b/src/parameterizations/vertical/MOM_entrain_diffusive.F90 @@ -20,6 +20,11 @@ module MOM_entrain_diffusive public entrainment_diffusive, entrain_diffusive_init, entrain_diffusive_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure holding parametes for the MOM_entrain_diffusive module type, public :: entrain_diffusive_CS ; private logical :: bulkmixedlayer !< If true, a refined bulk mixed layer is used with @@ -28,7 +33,8 @@ module MOM_entrain_diffusive !! their target variables by the diapycnal mixing. integer :: max_ent_it !< The maximum number of iterations that may be used to !! calculate the diapycnal entrainment. - real :: Tolerance_Ent !< The tolerance with which to solve for entrainment values, in m. + real :: Tolerance_Ent !< The tolerance with which to solve for entrainment values + !! [H ~> m or kg m-2]. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to !! regulate the timing of diagnostic output. integer :: id_Kd = -1 !< Diagnostic ID for diffusivity @@ -48,37 +54,35 @@ subroutine entrainment_diffusive(u, v, h, tv, fluxes, dt, G, GV, US, CS, ea, eb, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any available !! thermodynamic fields. Absent fields have NULL !! ptrs. type(forcing), intent(in) :: fluxes !< A structure of surface fluxes that may !! be used. - real, intent(in) :: dt !< The time increment in s. + real, intent(in) :: dt !< The time increment [s]. type(entrain_diffusive_CS), pointer :: CS !< The control structure returned by a previous !! call to entrain_diffusive_init. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(out) :: ea !< The amount of fluid entrained from the layer - !! above within this time step, in the same units - !! as h, m or kg m-2. + !! above within this time step [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(out) :: eb !< The amount of fluid entrained from the layer - !! below within this time step, in the same units - !! as h, m or kg m-2. + !! below within this time step [H ~> m or kg m-2]. integer, dimension(SZI_(G),SZJ_(G)), & optional, intent(inout) :: kb_out !< The index of the lightest layer denser than !! the buffer layer. ! At least one of the two following arguments must be present. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - optional, intent(in) :: Kd_Lay !< The diapycnal diffusivity of layers, - !! in Z2 s-1. + optional, intent(in) :: Kd_Lay !< The diapycnal diffusivity of layers + !! [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - optional, intent(in) :: Kd_int !< The diapycnal diffusivity of interfaces, - !! in Z2 s-1. + optional, intent(in) :: Kd_int !< The diapycnal diffusivity of interfaces + !! [Z2 s-1 ~> m2 s-1]. ! This subroutine calculates ea and eb, the rates at which a layer entrains ! from the layers above and below. The entrainment rates are proportional to @@ -86,35 +90,32 @@ subroutine entrainment_diffusive(u, v, h, tv, fluxes, dt, G, GV, US, CS, ea, eb, ! differences between layers. The scheme that is used here is described in ! detail in Hallberg, Mon. Wea. Rev. 2000. -! In the comments below, H is used as shorthand for the units of h, m or kg m-2. real, dimension(SZI_(G),SZK_(G)) :: & - dtKd ! The layer diapycnal diffusivity times the time step, translated - ! into the same unints as h, m2 or kg2 m-4 (i.e. H2). + dtKd ! The layer diapycnal diffusivity times the time step [H2 ~> m2 or kg2 m-4]. real, dimension(SZI_(G),SZK_(G)+1) :: & - dtKd_int ! The diapycnal diffusivity at the interfaces times the time step, - ! translated into the same unints as h, m2 or kg2 m-4 (i.e. H2). + dtKd_int ! The diapycnal diffusivity at the interfaces times the time step [H2 ~> m2 or kg2 m-4] real, dimension(SZI_(G),SZK_(G)) :: & F, & ! The density flux through a layer within a time step divided by the - ! density difference across the interface below the layer, in H. + ! density difference across the interface below the layer [H ~> m or kg m-2]. maxF, & ! maxF is the maximum value of F that will not deplete all of the - ! layers above or below a layer within a timestep, in H. + ! layers above or below a layer within a timestep [H ~> m or kg m-2]. minF, & ! minF is the minimum flux that should be expected in the absence of - ! interactions between layers, in H. - Fprev, &! The previous estimate of F, in H. + ! interactions between layers [H ~> m or kg m-2]. + Fprev, &! The previous estimate of F [H ~> m or kg m-2]. dFdfm, &! The partial derivative of F with respect to changes in F of the - ! neighboring layers. Nondimensional. + ! neighboring layers. [nondim] h_guess ! An estimate of the layer thicknesses after entrainment, but ! before the entrainments are adjusted to drive the layer - ! densities toward their target values, in H. + ! densities toward their target values [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)+1) :: & Ent_bl ! The average entrainment upward and downward across - ! each interface around the buffer layers, in H. + ! each interface around the buffer layers [H ~> m or kg m-2]. real, allocatable, dimension(:,:,:) :: & Kd_eff, & ! The effective diffusivity that actually applies to each ! layer after the effects of boundary conditions are - ! considered, in m2 s-1. + ! considered [Z2 s-1 ~> m2 s-1]. diff_work ! The work actually done by diffusion across each - ! interface, in W m-2. Sum vertically for the total work. + ! interface [W m-2]. Sum vertically for the total work. real :: hm, fm, fr, fk ! Work variables with units of H, H, H, and H2. @@ -122,80 +123,81 @@ subroutine entrainment_diffusive(u, v, h, tv, fluxes, dt, G, GV, US, CS, ea, eb, real :: c1(SZI_(G),SZK_(G)) ! tridiagonal solver. real, dimension(SZI_(G)) :: & - htot, & ! The total thickness above or below a layer in H. + htot, & ! The total thickness above or below a layer [H ~> m or kg m-2]. Rcv, & ! Value of the coordinate variable (potential density) - ! based on the simulated T and S and P_Ref, kg m-3. - pres, & ! Reference pressure (P_Ref) in Pa. + ! based on the simulated T and S and P_Ref [kg m-3]. + pres, & ! Reference pressure (P_Ref) [Pa]. eakb, & ! The entrainment from above by the layer below the buffer - ! layer (i.e. layer kb), in H. - ea_kbp1, & ! The entrainment from above by layer kb+1, in H. - eb_kmb, & ! The entrainment from below by the deepest buffer layer, in H. + ! layer (i.e. layer kb) [H ~> m or kg m-2]. + ea_kbp1, & ! The entrainment from above by layer kb+1 [H ~> m or kg m-2]. + eb_kmb, & ! The entrainment from below by the deepest buffer layer [H ~> m or kg m-2]. dS_kb, & ! The reference potential density difference across the - ! interface between the buffer layers and layer kb, in kg m-3. + ! interface between the buffer layers and layer kb [kg m-3]. dS_anom_lim, &! The amount by which dS_kb is reduced when limits are - ! applied, in kg m-3. + ! applied [kg m-3]. I_dSkbp1, & ! The inverse of the potential density difference across the - ! interface below layer kb, in m3 kg-1. - dtKd_kb, & ! The diapycnal diffusivity in layer kb times the time step, - ! in units of H2. + ! interface below layer kb [m3 kg-1]. + dtKd_kb, & ! The diapycnal diffusivity in layer kb times the time step + ! [H2 ~> m2 or kg2 m-4]. maxF_correct, & ! An amount by which to correct maxF due to excessive - ! surface heat loss, in H. - zeros, & ! An array of all zeros. (Usually used with units of H.) - max_eakb, & ! The maximum value of eakb that might be realized, in H. - min_eakb, & ! The minimum value of eakb that might be realized, in H. + ! surface heat loss [H ~> m or kg m-2]. + zeros, & ! An array of all zeros. (Usually used with [H ~> m or kg m-2].) + max_eakb, & ! The maximum value of eakb that might be realized [H ~> m or kg m-2]. + min_eakb, & ! The minimum value of eakb that might be realized [H ~> m or kg m-2]. err_max_eakb0, & ! The value of error returned by determine_Ea_kb err_min_eakb0, & ! when eakb = min_eakb and max_eakb and ea_kbp1 = 0. err_eakb0, & ! A value of error returned by determine_Ea_kb. F_kb, & ! The value of F in layer kb, or equivalently the entrainment - ! from below by layer kb, in H. - dFdfm_kb, & ! The partial derivative of F with fm, nondim. See dFdfm. - maxF_kb, & ! The maximum value of F_kb that might be realized, in H. - eakb_maxF, & ! The value of eakb that gives F_kb=maxF_kb, in H. - F_kb_maxEnt ! The value of F_kb when eakb = max_eakb, in H. + ! from below by layer kb [H ~> m or kg m-2]. + dFdfm_kb, & ! The partial derivative of F with fm [nondim]. See dFdfm. + maxF_kb, & ! The maximum value of F_kb that might be realized [H ~> m or kg m-2]. + eakb_maxF, & ! The value of eakb that gives F_kb=maxF_kb [H ~> m or kg m-2]. + F_kb_maxEnt ! The value of F_kb when eakb = max_eakb [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)) :: & Sref, & ! The reference potential density of the mixed and buffer layers, ! and of the two lightest interior layers (kb and kb+1) copied - ! into layers kmb+1 and kmb+2, in kg m-3. + ! into layers kmb+1 and kmb+2 [kg m-3]. h_bl ! The thicknesses of the mixed and buffer layers, and of the two ! lightest interior layers (kb and kb+1) copied into layers kmb+1 - ! and kmb+2, in H. + ! and kmb+2 [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)) :: & ds_dsp1, & ! The coordinate variable (sigma-2) difference across an ! interface divided by the difference across the interface - ! below it. Nondimensional. + ! below it. [nondim] dsp1_ds, & ! The inverse coordinate variable (sigma-2) difference ! across an interface times the difference across the - ! interface above it. Nondimensional. - I2p2dsp1_ds, & ! 1 / (2 + 2 * ds_k+1 / ds_k). Nondimensional. + ! interface above it. [nondim] + I2p2dsp1_ds, & ! 1 / (2 + 2 * ds_k+1 / ds_k). [nondim] grats ! 2*(2 + ds_k+1 / ds_k + ds_k / ds_k+1) = - ! 4*ds_Lay*(1/ds_k + 1/ds_k+1). Nondim. + ! 4*ds_Lay*(1/ds_k + 1/ds_k+1). [nondim] real :: dRHo ! The change in locally referenced potential density between - ! the layers above and below an interface, in kg m-3. - real :: g_2dt ! 0.5 * G_Earth / dt, times unit conversion factors, in m3 H-2 s-3. + ! the layers above and below an interface [kg m-3]. + real :: g_2dt ! 0.5 * G_Earth / dt, times unit conversion factors + ! [m3 H-2 s-3 ~> m s-3 or m7 kg-2 s-3]. real, dimension(SZI_(G)) :: & - pressure, & ! The pressure at an interface, in Pa. + pressure, & ! The pressure at an interface [Pa]. T_eos, S_eos, & ! The potential temperature and salinity at which to - ! evaluate dRho_dT and dRho_dS, in degC and PSU. + ! evaluate dRho_dT and dRho_dS [degC] and [ppt]. dRho_dT, dRho_dS ! The partial derivatives of potential density with - ! temperature and salinity, in kg m-3 K-1 and kg m-3 psu-1. + ! temperature and salinity, [kg m-3 degC-1] and [kg m-3 ppt-1]. - real :: tolerance ! The tolerance within which E must be converged, in H. - real :: Angstrom ! The minimum layer thickness, in H. + real :: tolerance ! The tolerance within which E must be converged [H ~> m or kg m-2]. + real :: Angstrom ! The minimum layer thickness [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: F_cor ! A correction to the amount of F that is used to - ! entrain from the layer above, in H. - real :: Kd_here ! The effective diapycnal diffusivity, in H2 s-1. - real :: h_avail ! The thickness that is available for entrainment, in H. + ! entrain from the layer above [H ~> m or kg m-2]. + real :: Kd_here ! The effective diapycnal diffusivity [H2 s-1 ~> m2 s-1 or kg2 m-4 s-1]. + real :: h_avail ! The thickness that is available for entrainment [H ~> m or kg m-2]. real :: dS_kb_eff ! The value of dS_kb after limiting is taken into account. real :: Rho_cor ! The depth-integrated potential density anomaly that - ! needs to be corrected for, in kg m-2. - real :: ea_cor ! The corrective adjustment to eakb, in H. + ! needs to be corrected for [H kg m-3 ~> kg m-2 or kg2 m-5]. + real :: ea_cor ! The corrective adjustment to eakb [H ~> m or kg m-2]. real :: h1 ! The layer thickness after entrainment through the - ! interface below is taken into account, in H. - real :: Idt ! The inverse of the time step, in s-1. + ! interface below is taken into account [H ~> m or kg m-2]. + real :: Idt ! The inverse of the time step [s-1]. logical :: do_any logical :: do_i(SZI_(G)), did_i(SZI_(G)), reiterate, correct_density @@ -893,9 +895,9 @@ subroutine F_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb, real, dimension(SZI_(G),SZK_(G)), intent(in) :: F !< The density flux through a layer within !! a time step divided by the density !! difference across the interface below - !! the layer, in H. + !! the layer [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] integer, dimension(SZI_(G)), intent(in) :: kb !< The index of the lightest layer denser than !! the deepest buffer layer. integer, intent(in) :: kmb !< The number of mixed and buffer layers. @@ -906,16 +908,16 @@ subroutine F_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb, !! a layer over the difference across the !! interface above the layer. real, dimension(SZI_(G)), intent(in) :: eakb !< The entrainment from above by the layer - !! below the buffer layer, in H. + !! below the buffer layer [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)), intent(in) :: Ent_bl !< The average entrainment upward and !! downward across each interface around - !! the buffer layers, in H. + !! the buffer layers [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: ea !< The amount of fluid entrained from the layer - !! above within this time step, in H. + !! above within this time step [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: eb !< The amount of fluid entrained from the layer - !! below within this time step, in H. + !! below within this time step [H ~> m or kg m-2]. logical, dimension(SZI_(G)), & optional, intent(in) :: do_i_in !< Indicates which i-points to work on. ! This subroutine calculates the actual entrainments (ea and eb) and the @@ -923,7 +925,7 @@ subroutine F_to_ent(F, h, kb, kmb, j, G, GV, CS, dsp1_ds, eakb, Ent_bl, ea, eb, ! mixed layer. real :: h1 ! The thickness in excess of the minimum that will remain - ! after exchange with the layer below, in m or kg m-2. + ! after exchange with the layer below [H ~> m or kg m-2]. logical :: do_i(SZI_(G)) integer :: i, k, is, ie, nz @@ -1021,12 +1023,11 @@ subroutine set_Ent_bl(h, dtKd_int, tv, kb, kmb, do_i, G, GV, CS, j, Ent_bl, Sref type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZK_(G)+1), & intent(in) :: dtKd_int !< The diapycnal diffusivity across - !! each interface times the time step, - !! in H2. + !! each interface times the time step + !! [H2 ~> m2 or kg2 m-4]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent !! fields have NULL ptrs. @@ -1041,51 +1042,34 @@ subroutine set_Ent_bl(h, dtKd_int, tv, kb, kmb, do_i, G, GV, CS, j, Ent_bl, Sref real, dimension(SZI_(G),SZK_(G)+1), & intent(out) :: Ent_bl !< The average entrainment upward and !! downward across each interface around - !! the buffer layers, in H. - real, dimension(SZI_(G),SZK_(G)), intent(out) :: Sref !< The coordinate potential density - - !! 1000 for each layer, in kg m-3. - real, dimension(SZI_(G),SZK_(G)), intent(out) :: h_bl !< The thickness of each layer, in H. - -! Arguments: h - Layer thickness, in m or kg m-2 (abbreviated as H below). -! (in) dtKd_int - The diapycnal diffusivity across each interface times -! the time step, in H2. -! (in) tv - A structure containing pointers to any available -! thermodynamic fields. Absent fields have NULL ptrs. -! (in) kb - The index of the lightest layer denser than the -! buffer layer or 1 if there is no buffer layer. -! (in) do_i - A logical variable indicating which i-points to work on. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - This module's control structure. -! (in) j - The meridional index upon which to work. -! (out) Ent_bl - The average entrainment upward and downward across -! each interface around the buffer layers, in H. -! (out) Sref - The coordinate potential density - 1000 for each layer, -! in kg m-3. -! (out) h_bl - The thickness of each layer, in H. + !! the buffer layers [H ~> m or kg m-2]. + real, dimension(SZI_(G),SZK_(G)), intent(out) :: Sref !< The coordinate potential density minus + !! 1000 for each layer [kg m-3]. + real, dimension(SZI_(G),SZK_(G)), intent(out) :: h_bl !< The thickness of each layer [H ~> m or kg m-2]. ! This subroutine sets the average entrainment across each of the interfaces ! between buffer layers within a timestep. It also causes thin and relatively ! light interior layers to be entrained by the deepest buffer layer. ! Also find the initial coordinate potential densities (Sref) of each layer. - ! Does there need to be limiting when the layers below are all thin? + + ! Local variables real, dimension(SZI_(G)) :: & - b1, d1, & ! Variables used by the tridiagonal solver, in H-1 and ND. + b1, d1, & ! Variables used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1] and [nondim]. Rcv, & ! Value of the coordinate variable (potential density) - ! based on the simulated T and S and P_Ref, kg m-3. - pres, & ! Reference pressure (P_Ref) in Pa. - frac_rem, & ! The fraction of the diffusion remaining, ND. - h_interior ! The interior thickness available for entrainment, in H. + ! based on the simulated T and S and P_Ref [kg m-3]. + pres, & ! Reference pressure (P_Ref) [Pa]. + frac_rem, & ! The fraction of the diffusion remaining [nondim]. + h_interior ! The interior thickness available for entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G), SZK_(G)) :: & S_est ! An estimate of the coordinate potential density - 1000 after - ! entrainment for each layer, in kg m-3. - real :: max_ent ! The maximum possible entrainment, in H. - real :: dh ! An available thickness, in H. + ! entrainment for each layer [kg m-3]. + real :: max_ent ! The maximum possible entrainment [H ~> m or kg m-2]. + real :: dh ! An available thickness [H ~> m or kg m-2]. real :: Kd_x_dt ! The diffusion that remains after thin layers are - ! entrained, in H2. + ! entrained [H2 ~> m2 or kg2 m-4]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. integer :: i, k, is, ie, nz is = G%isc ; ie = G%iec ; nz = G%ke @@ -1213,15 +1197,13 @@ subroutine determine_dSkb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid !! structure. - real, dimension(SZI_(G),SZK_(G)), intent(in) :: h_bl !< Layer thickness, in m or kg m-2 - !! (abbreviated as H below). - real, dimension(SZI_(G),SZK_(G)), intent(in) :: Sref !< Reference potential vorticity - !! (in kg m-3?). + real, dimension(SZI_(G),SZK_(G)), intent(in) :: h_bl !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZK_(G)), intent(in) :: Sref !< Reference potential density [kg m-3] real, dimension(SZI_(G),SZK_(G)), intent(in) :: Ent_bl !< The average entrainment upward and !! downward across each interface - !! around the buffer layers, in H. + !! around the buffer layers [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: E_kb !< The entrainment by the top interior - !! layer, in H. + !! layer [H ~> m or kg m-2]. integer, intent(in) :: is !< The start of the i-index range to work on. integer, intent(in) :: ie !< The end of the i-index range to work on. integer, intent(in) :: kmb !< The number of mixed and buffer layers. @@ -1233,35 +1215,18 @@ subroutine determine_dSkb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, & !! and the topmost interior layer. !! dSkb > 0. real, dimension(SZI_(G)), optional, intent(inout) :: ddSkb_dE !< The partial derivative of dSkb - !! with E, in kg m-3 H-1. + !! with E [kg m-3 H-1 ~> kg m-4 or m-1]. real, dimension(SZI_(G)), optional, intent(inout) :: dSlay !< The limited potential density !! difference across the topmost !! interior layer. 0 < dSkb real, dimension(SZI_(G)), optional, intent(inout) :: ddSlay_dE !< The partial derivative of dSlay - !! with E, in kg m-3 H-1. + !! with E [kg m-3 H-1 ~> kg m-4 or m-1]. real, dimension(SZI_(G)), optional, intent(inout) :: dS_anom_lim !< A limiting value to use for !! the density anomalies below the - !! buffer layer, in kg m-3. + !! buffer layer [kg m-3]. logical, dimension(SZI_(G)), optional, intent(in) :: do_i_in !< If present, determines which !! columns are worked on. -! Arguments: h_bl - Layer thickness, in m or kg m-2 (abbreviated as H below). -! (in) Sref - Reference potential vorticity (in kg m-3?) -! (in) Ent_bl - The average entrainment upward and downward across -! each interface around the buffer layers, in H. -! (in) E_kb - The entrainment by the top interior layer, in H. -! (in) is, ie - The range of i-indices to work on. -! (in) kmb - The number of mixed and buffer layers. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) limit - If true, limit dSkb and dSlay to avoid negative values. -! (out) dSkb - The limited potential density difference across the -! interface between the bottommost buffer layer and the -! topmost interior layer. dSkb > 0. -! (out,opt) dSlay - The limited potential density difference across the -! topmost interior layer. 0 < dSkb -! (out,opt) ddSkb_dE - The partial derivative of dSkb with E, in kg m-3 H-1. -! (out,opt) ddSlay_dE - The partial derivative of dSlay with E, in kg m-3 H-1. -! (in,opt) do_i_in - If present, determines which columns are worked on. + ! Note that dSkb, ddSkb_dE, dSlay, ddSlay_dE, and dS_anom_lim are declared ! intent inout because they should not change where do_i_in is false. @@ -1277,6 +1242,8 @@ subroutine determine_dSkb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, & ! exceed the density differences across an interface. ! Additionally, the partial derivatives of dSkb and dSlay with E_kb could ! also be returned. + + ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & b1, c1, & ! b1 and c1 are variables used by the tridiagonal solver. S, dS_dE, & ! The coordinate density and its derivative with R. @@ -1286,19 +1253,19 @@ subroutine determine_dSkb(h_bl, Sref, Ent_bl, E_kb, is, ie, kmb, G, GV, limit, & real :: d1(SZI_(G)) ! d1 = 1.0-c1 is also used by the tridiagonal solver. real :: src ! A source term for dS_dR. real :: h1 ! The thickness in excess of the minimum that will remain - ! after exchange with the layer below, in m or kg m-2. + ! after exchange with the layer below [H ~> m or kg m-2]. logical, dimension(SZI_(G)) :: do_i real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: h_tr ! h_tr is h at tracer points with a tiny thickness - ! added to ensure positive definiteness, in m or kg m-2. - real :: b_denom_1 ! The first term in the denominator of b1 in m or kg m-2. + ! added to ensure positive definiteness [H ~> m or kg m-2]. + real :: b_denom_1 ! The first term in the denominator of b1 [H ~> m or kg m-2]. real :: rat real :: dS_kbp1, IdS_kbp1 real :: deriv_dSLay - real :: Inv_term ! Nondimensional. - real :: f1, df1_drat ! Nondimensional temporary variables. - real :: z, dz_drat, f2, df2_dz, expz ! Nondimensional temporary variables. + real :: Inv_term ! [nondim] + real :: f1, df1_drat ! Temporary variables [nondim]. + real :: z, dz_drat, f2, df2_dz, expz ! Temporary variables [nondim]. real :: eps_dSLay, eps_dSkb ! Small nondimensional constants. integer :: i, k @@ -1471,27 +1438,27 @@ subroutine F_kb_to_ea_kb(h_bl, Sref, Ent_bl, I_dSkbp1, F_kb, kmb, i, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZK_(G)), & intent(in) :: h_bl !< Layer thickness, with the top interior - !! layer at k-index kmb+1, in units of m - !! or kg m-2 (abbreviated as H below). + !! layer at k-index kmb+1 [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)), & intent(in) :: Sref !< The coordinate reference potential density, !! with the value of the topmost interior layer - !! at index kmb+1, in units of kg m-3. + !! at index kmb+1 [kg m-3]. real, dimension(SZI_(G),SZK_(G)), & intent(in) :: Ent_bl !< The average entrainment upward and downward - !! across each interface around the buffer layers, in H. + !! across each interface around the buffer layers, + !! [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: I_dSkbp1 !< The inverse of the difference in reference !! potential density across the base of the - !! uppermost interior layer, in units of m3 kg-1. + !! uppermost interior layer [m3 kg-1]. real, dimension(SZI_(G)), intent(in) :: F_kb !< The entrainment from below by the - !! uppermost interior layer, in H + !! uppermost interior layer [H ~> m or kg m-2] integer, intent(in) :: kmb !< The number of mixed and buffer layers. integer, intent(in) :: i !< The i-index to work on type(entrain_diffusive_CS), pointer :: CS !< This module's control structure. real, dimension(SZI_(G)), intent(inout) :: ea_kb !< The entrainment from above by the layer below - !! the buffer layer (i.e. layer kb), in H. + !! the buffer layer (i.e. layer kb) [H ~> m or kg m-2]. real, optional, intent(in) :: tol_in !< A tolerance for the iterative determination - !! of the entrainment, in H. + !! of the entrainment [H ~> m or kg m-2]. real :: max_ea, min_ea real :: err, err_min, err_max @@ -1603,28 +1570,27 @@ subroutine determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZK_(G)), intent(in) :: h_bl !< Layer thickness, with the top interior - !! layer at k-index kmb+1, in units of m - !! or kg m-2 (abbreviated as H below). + !! layer at k-index kmb+1 [H ~> m or kg m-2]. real, dimension(SZI_(G),SZK_(G)), intent(in) :: Sref !< The coordinate reference potential !! density, with the value of the !! topmost interior layer at layer - !! kmb+1, in units of kg m-3. + !! kmb+1 [kg m-3]. real, dimension(SZI_(G),SZK_(G)), intent(in) :: Ent_bl !< The average entrainment upward and !! downward across each interface around - !! the buffer layers, in H. + !! the buffer layers [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: I_dSkbp1 !< The inverse of the difference in !! reference potential density across !! the base of the uppermost interior - !! layer, in units of m3 kg-1. + !! layer [m3 kg-1]. real, dimension(SZI_(G)), intent(in) :: dtKd_kb !< The diapycnal diffusivity in the top - !! interior layer times the time step, - !! in H2. + !! interior layer times the time step + !! [H2 ~> m2 or kg2 m-4]. real, dimension(SZI_(G)), intent(in) :: ea_kbp1 !< The entrainment from above by layer - !! kb+1, in H. + !! kb+1 [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: min_eakb !< The minimum permissible rate of - !! entrainment, in H. + !! entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: max_eakb !< The maximum permissible rate of - !! entrainment, in H. + !! entrainment [H ~> m or kg m-2]. integer, intent(in) :: kmb !< The number of mixed and buffer layers. integer, intent(in) :: is !< The start of the i-index range to work on. integer, intent(in) :: ie !< The end of the i-index range to work on. @@ -1632,8 +1598,8 @@ subroutine determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, & !! i-points to work on. type(entrain_diffusive_CS), pointer :: CS !< This module's control structure. real, dimension(SZI_(G)), intent(inout) :: Ent !< The entrainment rate of the uppermost - !! interior layer, in H. The input value - !! is the first guess. + !! interior layer [H ~> m or kg m-2]. + !! The input value is the first guess. real, dimension(SZI_(G)), optional, intent(out) :: error !< The error (locally defined in this !! routine) associated with the returned !! solution. @@ -1646,69 +1612,42 @@ subroutine determine_Ea_kb(h_bl, dtKd_kb, Sref, I_dSkbp1, Ent_bl, ea_kbp1, & real, dimension(SZI_(G)), optional, intent(out) :: F_kb !< The entrainment from below by the !! uppermost interior layer !! corresponding to the returned - !! value of Ent, in H. + !! value of Ent [H ~> m or kg m-2]. real, dimension(SZI_(G)), optional, intent(out) :: dFdfm_kb !< The partial derivative of F_kb with - !! ea_kbp1, nondim. - -! Arguments: h_bl - Layer thickness, with the top interior layer at k-index -! kmb+1, in units of m or kg m-2 (abbreviated as H below). -! (in) dtKd_kb - The diapycnal diffusivity in the top interior layer times -! the time step, in H2. -! (in) Sref - The coordinate reference potential density, with the -! value of the topmost interior layer at layer kmb+1, -! in units of kg m-3. -! (in) I_dSkbp1 - The inverse of the difference in reference potential -! density across the base of the uppermost interior layer, -! in units of m3 kg-1. -! (in) Ent_bl - The average entrainment upward and downward across -! each interface around the buffer layers, in H. -! (in) ea_kbp1 - The entrainment from above by layer kb+1, in H. -! (in) min_eakb - The minimum permissible rate of entrainment, in H. -! (in) max_eakb - The maximum permissible rate of entrainment, in H. -! (in) is, ie - The range of i-indices to work on. -! (in) do_i - A logical variable indicating which i-points to work on. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - This module's control structure. -! (in/out) Ent - The entrainment rate of the uppermost interior layer, in H. -! The input value is the first guess. -! (out,opt) error - The error (locally defined in this routine) associated with -! the returned solution. -! (in,opt) error_min_eakb0, error_max_eakb0 - The errors (locally defined) -! associated with min_eakb and max_eakb when ea_kbp1 = 0, -! returned from a previous call to this routine. -! (out,opt) F_kb - The entrainment from below by the uppermost interior layer -! corresponding to the returned value of Ent, in H. -! (out,out) dFdfm_kb - The partial derivative of F_kb with ea_kbp1, nondim. + !! ea_kbp1 [nondim]. ! This subroutine determines the entrainment from above by the top interior ! layer (labeled kb elsewhere) given an entrainment by the layer below it, ! constrained to be within the provided bounds. + + ! Local variables real, dimension(SZI_(G)) :: & dS_kb, & ! The coordinate-density difference between the ! layer kb and deepest buffer layer, limited to - ! ensure that it is positive, in kg m-3. + ! ensure that it is positive [kg m-3]. dS_Lay, & ! The coordinate-density difference across layer ! kb, limited to ensure that it is positive and not - ! too much bigger than dS_kb or dS_kbp1, in kg m-3. - ddSkb_dE, ddSlay_dE, & ! The derivatives of dS_kb and dS_Lay with E, - ! in units of kg m-3 H-1. - derror_dE, & ! The derivative of err with E, in H. - err, & ! The "error" whose zero is being sought, in H2. - E_min, E_max, & ! The minimum and maximum values of E, in H. - error_minE, error_maxE ! err when E = E_min or E = E_max, in H2. - real :: err_est ! An estimate of what err will be, in H2. + ! too much bigger than dS_kb or dS_kbp1 [kg m-3]. + ddSkb_dE, ddSlay_dE, & ! The derivatives of dS_kb and dS_Lay with E + ! [kg m-3 H-1 ~> kg m-4 or m-1]. + derror_dE, & ! The derivative of err with E [H ~> m or kg m-2]. + err, & ! The "error" whose zero is being sought [H2 ~> m2 or kg2 m-4]. + E_min, E_max, & ! The minimum and maximum values of E [H ~> m or kg m-2]. + error_minE, error_maxE ! err when E = E_min or E = E_max [H2 ~> m2 or kg2 m-4]. + real :: err_est ! An estimate of what err will be [H2 ~> m2 or kg2 m-4]. real :: eL ! 1 or 0, depending on whether increases in E lead ! to decreases in the entrainment from below by the ! deepest buffer layer. - real :: fa, fk, fm, fr ! Temporary variables used to calculate err, in ND, H2, H, H. - real :: tolerance ! The tolerance within which E must be converged, in H. - real :: E_prev ! The previous value of E, in H. + real :: fa ! Temporary variable used to calculate err [nondim]. + real :: fk ! Temporary variable used to calculate err [H2 ~> m2 or kg2 m-4]. + real :: fm, fr ! Temporary variables used to calculate err [H ~> m or kg m-2]. + real :: tolerance ! The tolerance within which E must be converged [H ~> m or kg m-2]. + real :: E_prev ! The previous value of E [H ~> m or kg m-2]. logical, dimension(SZI_(G)) :: false_position ! If true, the false position ! method might be used for the next iteration. logical, dimension(SZI_(G)) :: redo_i ! If true, more work is needed on this column. logical :: do_any - real :: large_err ! A large error measure, in H2. + real :: large_err ! A large error measure [H2 ~> m2 or kg2 m-4]. integer :: i, it integer, parameter :: MAXIT = 30 @@ -1843,31 +1782,30 @@ subroutine find_maxF_kb(h_bl, Sref, Ent_bl, I_dSkbp1, min_ent_in, max_ent_in, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZK_(G)), & - intent(in) :: h_bl !< Layer thickness, in m or kg m-2 - !! (abbreviated as H below). + intent(in) :: h_bl !< Layer thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZK_(G)), & - intent(in) :: Sref !< Reference potential density (in kg m-3?). + intent(in) :: Sref !< Reference potential density [kg m-3]. real, dimension(SZI_(G),SZK_(G)), & intent(in) :: Ent_bl !< The average entrainment upward and !! downward across each interface around - !! the buffer layers, in H. + !! the buffer layers [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: I_dSkbp1 !< The inverse of the difference in !! reference potential density across the - !! base of the uppermost interior layer, - !! in units of m3 kg-1. + !! base of the uppermost interior layer + !! [m3 kg-1]. real, dimension(SZI_(G)), intent(in) :: min_ent_in !< The minimum value of ent to search, - !! in H. + !! [H ~> m or kg m-2]. real, dimension(SZI_(G)), intent(in) :: max_ent_in !< The maximum value of ent to search, - !! in H. + !! [H ~> m or kg m-2]. integer, intent(in) :: kmb !< The number of mixed and buffer layers. integer, intent(in) :: is !< The start of the i-index range to work on. integer, intent(in) :: ie !< The end of the i-index range to work on. type(entrain_diffusive_CS), pointer :: CS !< This module's control structure. real, dimension(SZI_(G)), intent(out) :: maxF !< The maximum value of F !! = ent*ds_kb*I_dSkbp1 found in the range - !! min_ent < ent < max_ent, in H. + !! min_ent < ent < max_ent [H ~> m or kg m-2]. real, dimension(SZI_(G)), & - optional, intent(out) :: ent_maxF !< The value of ent at that maximum, in H. + optional, intent(out) :: ent_maxF !< The value of ent at that maximum [H ~> m or kg m-2]. logical, dimension(SZI_(G)), & optional, intent(in) :: do_i_in !< A logical array indicating which columns !! to work on. @@ -1875,7 +1813,7 @@ subroutine find_maxF_kb(h_bl, Sref, Ent_bl, I_dSkbp1, min_ent_in, max_ent_in, & optional, intent(out) :: F_lim_maxent !< If present, do not apply the limit in !! finding the maximum value, but return the !! limited value at ent=max_ent_in in this - !! array, in H. + !! array [H ~> m or kg m-2]. real, dimension(SZI_(G)), & optional, intent(in) :: F_thresh !< If F_thresh is present, return the first !! value found that has F > F_thresh, or @@ -2181,7 +2119,7 @@ subroutine entrain_diffusive_init(Time, G, GV, US, param_file, diag, CS) call get_param(param_file, mdl, "MAX_ENT_IT", CS%max_ent_it, & "The maximum number of iterations that may be used to \n"//& "calculate the interior diapycnal entrainment.", default=5) -! In this module, KD is only used to set the default for TOLERANCE_ENT. (m2 s-1) +! In this module, KD is only used to set the default for TOLERANCE_ENT. [m2 s-1] call get_param(param_file, mdl, "KD", Kd, fail_if_missing=.true.) call get_param(param_file, mdl, "DT", dt, & "The (baroclinic) dynamics time step.", units = "s", & diff --git a/src/parameterizations/vertical/MOM_full_convection.F90 b/src/parameterizations/vertical/MOM_full_convection.F90 index 299c230e0b..5fd3d67b36 100644 --- a/src/parameterizations/vertical/MOM_full_convection.F90 +++ b/src/parameterizations/vertical/MOM_full_convection.F90 @@ -22,43 +22,43 @@ subroutine full_convection(G, GV, h, tv, T_adj, S_adj, p_surf, Kddt_smooth, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: T_adj !< Adjusted potential temperature in degC. + intent(out) :: T_adj !< Adjusted potential temperature [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: S_adj !< Adjusted salinity in ppt. - real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface in Pa (or NULL). + intent(out) :: S_adj !< Adjusted salinity [ppt]. + real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface [Pa] (or NULL). real, intent(in) :: Kddt_smooth !< A smoothing vertical - !! diffusivity times a timestep, in H2. + !! diffusivity times a timestep [H2 ~> m2 or kg2 m-4]. real, optional, intent(in) :: Kddt_convect !< A large convecting vertical - !! diffusivity times a timestep, in H2. + !! diffusivity times a timestep [H2 ~> m2 or kg2 m-4]. integer, optional, intent(in) :: halo !< Halo width over which to compute ! Local variables real, dimension(SZI_(G),SZK_(G)+1) :: & drho_dT, & ! The derivatives of density with temperature and - drho_dS ! salinity, in kg m-3 K-1 and kg m-3 psu-1. + drho_dS ! salinity [kg m-3 degC-1] and [kg m-3 ppt-1]. real :: h_neglect, h0 ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. ! logical :: use_EOS ! If true, density is calculated from T & S using an equation of state. real, dimension(SZI_(G),SZK0_(G)) :: & Te_a, & ! A partially updated temperature estimate including the influnce from - ! mixing with layers above rescaled by a factor of d_a, in degC. + ! mixing with layers above rescaled by a factor of d_a [degC]. ! This array is discreted on tracer cells, but contains an extra ! layer at the top for algorithmic convenience. Se_a ! A partially updated salinity estimate including the influnce from - ! mixing with layers above rescaled by a factor of d_a, in ppt. + ! mixing with layers above rescaled by a factor of d_a [ppt]. ! This array is discreted on tracer cells, but contains an extra ! layer at the top for algorithmic convenience. real, dimension(SZI_(G),SZK_(G)+1) :: & Te_b, & ! A partially updated temperature estimate including the influnce from - ! mixing with layers below rescaled by a factor of d_b, in degC. + ! mixing with layers below rescaled by a factor of d_b [degC]. ! This array is discreted on tracer cells, but contains an extra ! layer at the bottom for algorithmic convenience. Se_b ! A partially updated salinity estimate including the influnce from - ! mixing with layers below rescaled by a factor of d_b, in ppt. + ! mixing with layers below rescaled by a factor of d_b [ppt]. ! This array is discreted on tracer cells, but contains an extra ! layer at the bottom for algorithmic convenience. real, dimension(SZI_(G),SZK_(G)+1) :: & @@ -73,12 +73,12 @@ subroutine full_convection(G, GV, h, tv, T_adj, S_adj, p_surf, Kddt_smooth, & ! and layers below in the final properies with a upward-first solver, nondim. ! d_b = 1.0 - c_b real, dimension(SZI_(G),SZK_(G)+1) :: & - mix !< The amount of mixing across the interface between layers, in H. - real :: mix_len ! The length-scale of mixing, when it is active, in H - real :: h_b, h_a ! The thicknessses of the layers above and below in interface, in H - real :: b_b, b_a ! Inverse pivots used by the tridiagonal solver, in H-1. + mix !< The amount of mixing across the interface between layers [H ~> m or kg m-2]. + real :: mix_len ! The length-scale of mixing, when it is active [H ~> m or kg m-2] + real :: h_b, h_a ! The thicknessses of the layers above and below an interface [H ~> m or kg m-2] + real :: b_b, b_a ! Inverse pivots used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. - real :: kap_dt_x2 ! The product of 2*kappa*dt in H2 (often m2 or kg2 m-4). + real :: kap_dt_x2 ! The product of 2*kappa*dt [H2 ~> m2 or kg2 m-4]. logical, dimension(SZI_(G)) :: do_i ! Do more work on this column. logical, dimension(SZI_(G)) :: last_down ! The last setup pass was downward. @@ -281,20 +281,20 @@ end subroutine full_convection !! above and below, including partial calculations from a tridiagonal solver. function is_unstable(dRho_dT, dRho_dS, h_a, h_b, mix_A, mix_B, T_a, T_b, S_a, S_b, & Te_aa, Te_bb, Se_aa, Se_bb, d_A, d_B) - real, intent(in) :: dRho_dT !< The derivative of in situ density with temperature in kg m-3 degC-1 - real, intent(in) :: dRho_dS !< The derivative of in situ density with salinity in kg m-3 ppt-1 - real, intent(in) :: h_a !< The thickness of the layer above, in H - real, intent(in) :: h_b !< The thickness of the layer below, in H - real, intent(in) :: mix_A !< The time integrated mixing rate of the interface above, in H - real, intent(in) :: mix_B !< The time integrated mixing rate of the interface below, in H - real, intent(in) :: T_a !< The initial temperature of the layer above, in degC - real, intent(in) :: T_b !< The initial temperature of the layer below, in degC - real, intent(in) :: S_a !< The initial salinity of the layer below, in ppt - real, intent(in) :: S_b !< The initial salinity of the layer below, in ppt - real, intent(in) :: Te_aa !< The estimated temperature two layers above rescaled by d_A, in degC - real, intent(in) :: Te_bb !< The estimated temperature two layers below rescaled by d_B, in degC - real, intent(in) :: Se_aa !< The estimated salinity two layers above rescaled by d_A, in ppt - real, intent(in) :: Se_bb !< The estimated salinity two layers below rescaled by d_B, in ppt + real, intent(in) :: dRho_dT !< The derivative of in situ density with temperature [kg m-3 degC-1] + real, intent(in) :: dRho_dS !< The derivative of in situ density with salinity [kg m-3 ppt-1] + real, intent(in) :: h_a !< The thickness of the layer above [H ~> m or kg m-2] + real, intent(in) :: h_b !< The thickness of the layer below [H ~> m or kg m-2] + real, intent(in) :: mix_A !< The time integrated mixing rate of the interface above [H ~> m or kg m-2] + real, intent(in) :: mix_B !< The time integrated mixing rate of the interface below [H ~> m or kg m-2] + real, intent(in) :: T_a !< The initial temperature of the layer above [degC] + real, intent(in) :: T_b !< The initial temperature of the layer below [degC] + real, intent(in) :: S_a !< The initial salinity of the layer below [ppt] + real, intent(in) :: S_b !< The initial salinity of the layer below [ppt] + real, intent(in) :: Te_aa !< The estimated temperature two layers above rescaled by d_A [degC] + real, intent(in) :: Te_bb !< The estimated temperature two layers below rescaled by d_B [degC] + real, intent(in) :: Se_aa !< The estimated salinity two layers above rescaled by d_A [ppt] + real, intent(in) :: Se_bb !< The estimated salinity two layers below rescaled by d_B [ppt] real, intent(in) :: d_A !< The rescaling dependency across the interface above, nondim. real, intent(in) :: d_B !< The rescaling dependency across the interface below, nondim. logical :: is_unstable !< The return value, true if the profile is statically unstable @@ -321,33 +321,34 @@ subroutine smoothed_dRdT_dRdS(h, tv, Kddt, dR_dT, dR_dS, G, GV, j, p_surf, halo) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables - real, intent(in) :: Kddt !< A diffusivity times a time increment, in H2. + real, intent(in) :: Kddt !< A diffusivity times a time increment [H2 ~> m2 or kg2 m-4]. real, dimension(SZI_(G),SZK_(G)+1), & intent(out) :: dR_dT !< Derivative of locally referenced - !! potential density with temperature, kg m-3 K-1 + !! potential density with temperature [kg m-3 degC-1] real, dimension(SZI_(G),SZK_(G)+1), & intent(out) :: dR_dS !< Derivative of locally referenced - !! potential density with salinity, kg m-3 ppt-1 + !! potential density with salinity [kg m-3 ppt-1] integer, intent(in) :: j !< The j-point to work on. - real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface in Pa (or NULL). + real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface [Pa]. integer, optional, intent(in) :: halo !< Halo width over which to compute + ! Local variables real :: mix(SZI_(G),SZK_(G)+1) ! The diffusive mixing length (kappa*dt)/dz - ! between layers within in a timestep in H. + ! between layers within in a timestep [H ~> m or kg m-2]. real :: b1(SZI_(G)), d1(SZI_(G)) ! b1, c1, and d1 are variables used by the real :: c1(SZI_(G),SZK_(G)) ! tridiagonal solver. - real :: T_f(SZI_(G),SZK_(G)) ! Filtered temperatures in degC - real :: S_f(SZI_(G),SZK_(G)) ! Filtered salinities in ppt - real :: pres(SZI_(G)) ! Interface pressures, in Pa. - real :: T_EOS(SZI_(G)) ! Filtered and vertically averaged temperatures in degC - real :: S_EOS(SZI_(G)) ! Filtered and vertically averaged salinities in ppt - real :: kap_dt_x2 ! The product of 2*kappa*dt in H2 (often m2 or kg2 m-4). - real :: h_neglect, h0 ! Negligible thicknesses, in H (m or kg m-2), to - ! allow for zero thicknesses. - real :: h_tr ! The thickness at tracer points, plus h_neglect, in H. + real :: T_f(SZI_(G),SZK_(G)) ! Filtered temperatures [degC] + real :: S_f(SZI_(G),SZK_(G)) ! Filtered salinities [ppt] + real :: pres(SZI_(G)) ! Interface pressures [Pa]. + real :: T_EOS(SZI_(G)) ! Filtered and vertically averaged temperatures [degC] + real :: S_EOS(SZI_(G)) ! Filtered and vertically averaged salinities [ppt] + real :: kap_dt_x2 ! The product of 2*kappa*dt [H2 ~> m2 or kg2 m-4]. + real :: h_neglect, h0 ! Negligible thicknesses to allow for zero thicknesses, + ! [H ~> m or kg m-2]. + real :: h_tr ! The thickness at tracer points, plus h_neglect [H ~> m or kg m-2]. integer :: i, k, is, ie, nz if (present(halo)) then diff --git a/src/parameterizations/vertical/MOM_geothermal.F90 b/src/parameterizations/vertical/MOM_geothermal.F90 index c09d85f5b5..7ca06c6139 100644 --- a/src/parameterizations/vertical/MOM_geothermal.F90 +++ b/src/parameterizations/vertical/MOM_geothermal.F90 @@ -24,10 +24,10 @@ module MOM_geothermal type, public :: geothermal_CS ; private real :: dRcv_dT_inplace !< The value of dRcv_dT above which (dRcv_dT is !! negative) the water is heated in place instead - !! of moving upward between layers, in kg m-3 K-1. - real, pointer :: geo_heat(:,:) => NULL() !< The geothermal heat flux, in W m-2. + !! of moving upward between layers [kg m-3 degC-1]. + real, pointer :: geo_heat(:,:) => NULL() !< The geothermal heat flux [W m-2]. real :: geothermal_thick !< The thickness over which geothermal heating is - !! applied, in m. + !! applied [m] (not [H]). logical :: apply_geothermal !< If true, geothermal heating will be applied !! otherwise GEOTHERMAL_SCALE has been set to 0 and !! there is no heat to apply. @@ -47,59 +47,58 @@ module MOM_geothermal !! be applied to the ocean is returned (WHERE)? subroutine geothermal(h, tv, dt, ea, eb, G, GV, CS, halo) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. - type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid - !! structure. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers !! to any available thermodynamic !! fields. Absent fields have NULL !! ptrs. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: ea !< The amount of fluid moved !! downward into a layer; this !! should be increased due to mixed - !! layer detrainment, in the same - !! units as h - usually m or kg m-2 - !! (i.e., H). + !! layer detrainment [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: eb !< The amount of fluid moved upward !! into a layer; this should be !! increased due to mixed layer - !! entrainment, in the same units as - !! h - usually m or kg m-2 (i.e., H) + !! entrainment [H ~> m or kg m-2]. type(geothermal_CS), pointer :: CS !< The control structure returned by !! a previous call to !! geothermal_init. integer, optional, intent(in) :: halo !< Halo width over which to work ! Local variables real, dimension(SZI_(G)) :: & - heat_rem, & ! remaining heat (H * degC) - h_geo_rem, & ! remaining thickness to apply geothermal heating (units of H) - Rcv_BL, & ! coordinate density in the deepest variable density layer (kg/m3) - p_ref ! coordiante densities reference pressure (Pa) + heat_rem, & ! remaining heat [H degC ~> m degC or kg degC m-2] + h_geo_rem, & ! remaining thickness to apply geothermal heating [H ~> m or kg m-2] + Rcv_BL, & ! coordinate density in the deepest variable density layer [kg m-3] + p_ref ! coordiante densities reference pressure [Pa] real, dimension(2) :: & - T2, S2, & ! temp and saln in the present and target layers (degC and ppt) - dRcv_dT_, & ! partial derivative of coordinate density wrt temp (kg m-3 K-1) - dRcv_dS_ ! partial derivative of coordinate density wrt saln (kg m-3 ppt-1) - - real :: Angstrom, H_neglect ! small thicknesses in H - real :: Rcv ! coordinate density of present layer (kg m-3) - real :: Rcv_tgt ! coordinate density of target layer (kg m-3) - real :: dRcv ! difference between Rcv and Rcv_tgt (kg m-3) + T2, S2, & ! temp and saln in the present and target layers [degC] and [ppt] + dRcv_dT_, & ! partial derivative of coordinate density wrt temp [kg m-3 degC-1] + dRcv_dS_ ! partial derivative of coordinate density wrt saln [kg m-3 ppt-1] + + real :: Angstrom, H_neglect ! small thicknesses [H ~> m or kg m-2] + real :: Rcv ! coordinate density of present layer [kg m-3] + real :: Rcv_tgt ! coordinate density of target layer [kg m-3] + real :: dRcv ! difference between Rcv and Rcv_tgt [kg m-3] real :: dRcv_dT ! partial derivative of coordinate density wrt temp - ! in the present layer (kg m-3 K-1); usually negative - real :: h_heated ! thickness that is being heated (units of H) - real :: heat_avail ! heating available for the present layer (units of Kelvin * H) - real :: heat_in_place ! heating to warm present layer w/o movement between layers (K * H) - real :: heat_trans ! heating available to move water from present layer to target layer (K * H) - real :: heating ! heating used to move water from present layer to target layer (K * H) + ! in the present layer [kg m-3 degC-1]; usually negative + real :: h_heated ! thickness that is being heated [H ~> m or kg m-2] + real :: heat_avail ! heating available for the present layer [degC H ~> degC m or degC kg m-2] + real :: heat_in_place ! heating to warm present layer w/o movement between layers + ! [degC H ~> degC m or degC kg m-2] + real :: heat_trans ! heating available to move water from present layer to target + ! layer [degC H ~> degC m or degC kg m-2] + real :: heating ! heating used to move water from present layer to target layer + ! [degC H ~> degC m or degC kg m-2] ! 0 <= heating <= heat_trans - real :: h_transfer ! thickness moved between layers (units of H) - real :: wt_in_place ! relative weighting that goes from 0 to 1 (non-dim) - real :: I_h ! inverse thickness (units of 1/H) - real :: dTemp ! temperature increase in a layer (Kelvin) - real :: Irho_cp ! inverse of heat capacity per unit layer volume (units K H m2 J-1) + real :: h_transfer ! thickness moved between layers [H ~> m or kg m-2] + real :: wt_in_place ! relative weighting that goes from 0 to 1 [nondim] + real :: I_h ! inverse thickness [H-1 ~> m-1 or m2 kg-1] + real :: dTemp ! temperature increase in a layer [degC] + real :: Irho_cp ! inverse of heat capacity per unit layer volume + ! [degC H m2 J-1 ~> degC m3 J-1 or degC kg J-1] logical :: do_i(SZI_(G)) integer :: i, j, k, is, ie, js, je, nz, k2, i2 diff --git a/src/parameterizations/vertical/MOM_internal_tide_input.F90 b/src/parameterizations/vertical/MOM_internal_tide_input.F90 index c2b303426b..111e8d44e2 100644 --- a/src/parameterizations/vertical/MOM_internal_tide_input.F90 +++ b/src/parameterizations/vertical/MOM_internal_tide_input.F90 @@ -26,16 +26,21 @@ module MOM_int_tide_input public set_int_tide_input, int_tide_input_init, int_tide_input_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> This control structure holds parameters that regulate internal tide energy inputs. type, public :: int_tide_input_CS ; private logical :: debug !< If true, write verbose checksums for debugging. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to !! regulate the timing of diagnostic output. - real :: TKE_itide_max !< Maximum Internal tide conversion (W m-2) - !! available to mix above the BBL + real :: TKE_itide_max !< Maximum Internal tide conversion + !! available to mix above the BBL [W m-2] real, allocatable, dimension(:,:) :: TKE_itidal_coef - !< The time-invariant field that enters the TKE_itidal input calculation, in J m-2. + !< The time-invariant field that enters the TKE_itidal input calculation [J m-2]. character(len=200) :: inputdir !< The directory for input files. !>@{ Diagnostic IDs @@ -46,10 +51,10 @@ module MOM_int_tide_input !> This type is used to exchange fields related to the internal tides. type, public :: int_tide_input_type real, allocatable, dimension(:,:) :: & - TKE_itidal_input, & !< The internal tide TKE input at the bottom of the ocean, in W m-2. - h2, & !< The squared topographic roughness height, in Z2. - tideamp, & !< The amplitude of the tidal velocities, in m s-1. - Nb !< The bottom stratification, in s-1. + TKE_itidal_input, & !< The internal tide TKE input at the bottom of the ocean [W m-2]. + h2, & !< The squared topographic roughness height [Z2 ~> m2]. + tideamp, & !< The amplitude of the tidal velocities [m s-1]. + Nb !< The bottom stratification [s-1]. end type int_tide_input_type contains @@ -59,22 +64,22 @@ subroutine set_int_tide_input(u, v, h, tv, fluxes, itide, dt, G, GV, US, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< The zonal velocity, in m s-1 - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< The meridional velocity, in m s-1 - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u !< The zonal velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v !< The meridional velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to the !! thermodynamic fields type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes type(int_tide_input_type), intent(inout) :: itide !< A structure containing fields related !! to the internal tide sources. - real, intent(in) :: dt !< The time increment in s. + real, intent(in) :: dt !< The time increment [s]. type(int_tide_input_CS), pointer :: CS !< This module's control structure. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - N2_bot ! The bottom squared buoyancy frequency, in s-2. + N2_bot ! The bottom squared buoyancy frequency [s-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - T_f, S_f ! The temperature and salinity in C and PSU with the values in + T_f, S_f ! The temperature and salinity in [degC] and [ppt] with the values in ! the massless layers filled vertically by diffusion. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. @@ -90,8 +95,8 @@ subroutine set_int_tide_input(u, v, h, tv, fluxes, itide, dt, G, GV, US, CS) if (.not.associated(CS)) call MOM_error(FATAL,"set_diffusivity: "//& "Module must be initialized before it is used.") - kappa_fill = 1.e-3*US%m_to_Z**2 !### Dimensional constant in m2 s-1. - dt_fill = 7200. !### Dimensionalconstant in s. + kappa_fill = 1.e-3*US%m_to_Z**2 !### Dimensional constant [m2 s-1]. + dt_fill = 7200. !### Dimensionalconstant [s]. use_EOS = associated(tv%eqn_of_state) @@ -124,35 +129,35 @@ subroutine find_N2_bottom(h, tv, T_f, S_f, h2, fluxes, G, GV, US, N2_bot) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to the !! thermodynamic fields real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T_f !< Temperature after vertical filtering to - !! smooth out the values in thin layers, in degC. + !! smooth out the values in thin layers [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S_f !< Salinity after vertical filtering to - !! smooth out the values in thin layers, in PSU. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h2 !< Bottom topographic roughness, in Z2 + !! smooth out the values in thin layers [ppt]. + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: h2 !< Bottom topographic roughness [Z2 ~> m2]. type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes type(int_tide_input_CS), pointer :: CS !< This module's control structure. real, dimension(SZI_(G),SZJ_(G)), intent(out) :: N2_bot !< The squared buoyancy freqency at the - !! ocean bottom, in s-2. + !! ocean bottom [s-2]. ! Local variables real, dimension(SZI_(G),SZK_(G)+1) :: & dRho_int ! The unfiltered density differences across interfaces. real, dimension(SZI_(G)) :: & - pres, & ! The pressure at each interface, in Pa. - Temp_int, & ! The temperature at each interface, in degC. - Salin_int, & ! The salinity at each interface, in PSU. + pres, & ! The pressure at each interface [Pa]. + Temp_int, & ! The temperature at each interface [degC]. + Salin_int, & ! The salinity at each interface [ppt]. drho_bot, & - h_amp, & ! The amplitude of topographic roughness, in Z. - hb, & ! The depth below a layer, in Z. - z_from_bot, & ! The height of a layer center above the bottom, in Z. + h_amp, & ! The amplitude of topographic roughness [Z ~> m]. + hb, & ! The depth below a layer [Z ~> m]. + z_from_bot, & ! The height of a layer center above the bottom [Z ~> m]. dRho_dT, & ! The partial derivatives of density with temperature and - dRho_dS ! salinity, in kg m-3 degC-1 and kg m-3 PSU-1. + dRho_dS ! salinity [kg m-3 degC-1] and [kg m-3 ppt-1]. - real :: dz_int ! The thickness associated with an interface, in Z. + real :: dz_int ! The thickness associated with an interface [Z ~> m]. real :: G_Rho0 ! The gravitation acceleration divided by the Boussinesq - ! density, in Z m3 s-2 kg-1. + ! density [Z m3 s-2 kg-1 ~> m4 s-2 kg-1]. logical :: do_i(SZI_(G)), do_any integer :: i, j, k, is, ie, js, je, nz is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke @@ -255,11 +260,11 @@ subroutine int_tide_input_init(Time, G, GV, US, param_file, diag, CS, itide) character(len=200) :: filename, tideamp_file, h2_file real :: mask_itidal - real :: utide ! constant tidal amplitude (m s-1) to be used if + real :: utide ! constant tidal amplitude [m s-1] to be used if ! tidal amplitude file is not present. real :: kappa_h2_factor ! factor for the product of wavenumber * rms sgs height. real :: kappa_itides ! topographic wavenumber and non-dimensional scaling - real :: min_zbot_itides ! Minimum ocean depth for internal tide conversion, in Z. + real :: min_zbot_itides ! Minimum ocean depth for internal tide conversion [Z ~> m]. integer :: i, j, is, ie, js, je, isd, ied, jsd, jed if (associated(CS)) then diff --git a/src/parameterizations/vertical/MOM_kappa_shear.F90 b/src/parameterizations/vertical/MOM_kappa_shear.F90 index 525dfb1cb0..a92106444e 100644 --- a/src/parameterizations/vertical/MOM_kappa_shear.F90 +++ b/src/parameterizations/vertical/MOM_kappa_shear.F90 @@ -26,6 +26,11 @@ module MOM_kappa_shear public Calculate_kappa_shear, Calc_kappa_shear_vertex, kappa_shear_init public kappa_shear_is_used, kappa_shear_at_vertex +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> This control structure holds the parameters that regulate shear mixing type, public :: Kappa_shear_CS ; private real :: RiNo_crit !< The critical shear Richardson number for @@ -36,13 +41,13 @@ module MOM_kappa_shear !! is 0.085-0.089. real :: FRi_curvature !< A constant giving the curvature of the function !! of the Richardson number that relates shear to - !! sources in the kappa equation, Nondim. + !! sources in the kappa equation [nondim]. !! The values found by Jackson et al. are -0.97 - -0.89. real :: C_N !< The coefficient for the decay of TKE due to - !! stratification (i.e. proportional to N*tke), ND. + !! stratification (i.e. proportional to N*tke) [nondim]. !! The values found by Jackson et al. are 0.24-0.28. real :: C_S !< The coefficient for the decay of TKE due to - !! shear (i.e. proportional to |S|*tke), ND. + !! shear (i.e. proportional to |S|*tke) [nondim]. !! The values found by Jackson et al. are 0.14-0.12. real :: lambda !< The coefficient for the buoyancy length scale !! in the kappa equation. Nondimensional. @@ -50,8 +55,8 @@ module MOM_kappa_shear real :: lambda2_N_S !< The square of the ratio of the coefficients of !! the buoyancy and shear scales in the diffusivity !! equation, 0 to eliminate the shear scale. Nondim. - real :: TKE_bg !< The background level of TKE, in m2 s-2. - real :: kappa_0 !< The background diapycnal diffusivity, in Z2 s-1. + real :: TKE_bg !< The background level of TKE [m2 s-2]. + real :: kappa_0 !< The background diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. real :: kappa_tol_err !< The fractional error in kappa that is tolerated. real :: Prandtl_turb !< Prandtl number used to convert Kd_shear into viscosity. integer :: nkml !< The number of layers in the mixed layer, as @@ -68,7 +73,7 @@ module MOM_kappa_shear !! massive layers in this calculation. ! I can think of no good reason why this should be false. - RWH real :: vel_underflow !< Velocity components smaller than vel_underflow - !! are set to 0, in m s-1. + !! are set to 0 [m s-1]. ! logical :: layer_stagger = .false. ! If true, do the calculations centered at ! layers, rather than the interfaces. logical :: debug = .false. !< If true, write verbose debugging messages. @@ -93,33 +98,32 @@ subroutine Calculate_kappa_shear(u_in, v_in, h, tv, p_surf, kappa_io, tke_io, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: u_in !< Initial zonal velocity, in m s-1. (Intent in) + intent(in) :: u_in !< Initial zonal velocity [m s-1]. (Intent in) real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: v_in !< Initial meridional velocity, in m s-1. + intent(in) :: v_in !< Initial meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs. - real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface in Pa - !! (or NULL). + real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface [Pa] (or NULL). real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), & intent(inout) :: kappa_io !< The diapycnal diffusivity at each interface - !! (not layer!) in Z2 s-1. Initially this is the + !! (not layer!) [Z2 s-1 ~> m2 s-1]. Initially this is the !! value from the previous timestep, which may !! accelerate the iteration toward convergence. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), & intent(inout) :: tke_io !< The turbulent kinetic energy per unit mass at - !! each interface (not layer!) in m2 s-2. + !! each interface (not layer!) [m2 s-2]. !! Initially this is the value from the previous !! timestep, which may accelerate the iteration !! toward convergence. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), & intent(inout) :: kv_io !< The vertical viscosity at each interface - !! (not layer!) in Z2 s-1. This discards any + !! (not layer!) [Z2 s-1 ~> m2 s-1]. This discards any !! previous value (i.e. it is intent out) and !! simply sets Kv = Prandtl * Kd_shear - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. type(Kappa_shear_CS), pointer :: CS !< The control structure returned by a previous !! call to kappa_shear_init. logical, optional, intent(in) :: initialize_all !< If present and false, the previous @@ -132,29 +136,27 @@ subroutine Calculate_kappa_shear(u_in, v_in, h, tv, p_surf, kappa_io, tke_io, & real, dimension(SZI_(G),SZK_(GV)+1) :: & kappa_2d, tke_2d ! 2-D versions of various kappa_io and tke_io. real, dimension(SZK_(GV)) :: & - u, & ! The zonal velocity after a timestep of mixing, in m s-1. - v, & ! The meridional velocity after a timestep of mixing, in m s-1. - Idz, & ! The inverse of the distance between TKE points, in Z-1. - T, & ! The potential temperature after a timestep of mixing, in C. - Sal, & ! The salinity after a timestep of mixing, in psu. - dz, & ! The layer thickness, in Z. - u0xdz, & ! The initial zonal velocity times dz, in Z m s-1. - v0xdz, & ! The initial meridional velocity times dz, in Z m s-1. - T0xdz, & ! The initial temperature times dz, in C Z. - S0xdz ! The initial salinity times dz, in PSU Z. + u, & ! The zonal velocity after a timestep of mixing [m s-1]. + v, & ! The meridional velocity after a timestep of mixing [m s-1]. + Idz, & ! The inverse of the distance between TKE points [Z-1 ~> m-1]. + T, & ! The potential temperature after a timestep of mixing [degC]. + Sal, & ! The salinity after a timestep of mixing [ppt]. + dz, & ! The layer thickness [Z ~> m]. + u0xdz, & ! The initial zonal velocity times dz [Z m s-1 ~> m2 s-1]. + v0xdz, & ! The initial meridional velocity times dz [Z m s-1 ~> m2 s-1]. + T0xdz, & ! The initial temperature times dz [degC Z ~> degC m]. + S0xdz ! The initial salinity times dz [ppt Z ~> ppt m]. real, dimension(SZK_(GV)+1) :: & - kappa, & ! The shear-driven diapycnal diffusivity at an interface, in - ! units of Z2 s-1. - tke, & ! The Turbulent Kinetic Energy per unit mass at an interface, - ! in units of m2 s-2. - kappa_avg, & ! The time-weighted average of kappa, in Z2 s-1. - tke_avg ! The time-weighted average of TKE, in m2 s-2. - real :: f2 ! The squared Coriolis parameter of each column, in s-2. - real :: surface_pres ! The top surface pressure, in Pa. - - real :: dz_in_lay ! The running sum of the thickness in a layer, in Z. - real :: k0dt ! The background diffusivity times the timestep, in Z2. - real :: dz_massless ! A layer thickness that is considered massless, in Z. + kappa, & ! The shear-driven diapycnal diffusivity at an interface [Z2 s-1 ~> m2 s-1]. + tke, & ! The Turbulent Kinetic Energy per unit mass at an interface [m2 s-2]. + kappa_avg, & ! The time-weighted average of kappa [Z2 s-1 ~> m2 s-1]. + tke_avg ! The time-weighted average of TKE [m2 s-2]. + real :: f2 ! The squared Coriolis parameter of each column [s-2]. + real :: surface_pres ! The top surface pressure [Pa]. + + real :: dz_in_lay ! The running sum of the thickness in a layer [Z ~> m]. + real :: k0dt ! The background diffusivity times the timestep [Z2 ~> m2]. + real :: dz_massless ! A layer thickness that is considered massless [Z ~> m]. logical :: use_temperature ! If true, temperature and salinity have been ! allocated and are being used as state variables. logical :: new_kappa = .true. ! If true, ignore the value of kappa from the @@ -164,7 +166,7 @@ subroutine Calculate_kappa_shear(u_in, v_in, h, tv, p_surf, kappa_io, tke_io, & ! interfaces and the interfaces with massless layers ! merged into nearby massive layers. real, dimension(SZK_(GV)+1) :: kf ! The fractional weight of interface kc+1 for - ! interpolating back to the original index space, ND. + ! interpolating back to the original index space [nondim]. integer :: is, ie, js, je, i, j, k, nz, nzc ! Diagnostics that should be deleted? @@ -181,7 +183,7 @@ subroutine Calculate_kappa_shear(u_in, v_in, h, tv, p_surf, kappa_io, tke_io, & real :: wt(SZK_(GV)+1), wt_tot, I_wt_tot, wt_itt real, dimension(SZK_(GV)+1) :: & Ri_k, tke_prev, dtke, dkap, dtke_norm, & - ksrc_av ! The average through the iterations of k_src, in s-1. + ksrc_av ! The average through the iterations of k_src [s-1]. real, dimension(SZK_(GV)+1,0:max_debug_itt) :: & tke_it1, N2_it1, Sh2_it1, ksrc_it1, kappa_it1, kprev_it1 real, dimension(SZK_(GV)+1,1:max_debug_itt) :: & @@ -382,35 +384,35 @@ subroutine Calc_kappa_shear_vertex(u_in, v_in, h, T_in, S_in, tv, p_surf, kappa_ type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: u_in !< Initial zonal velocity, in m s-1. (Intent in) + intent(in) :: u_in !< Initial zonal velocity [m s-1]. (Intent in) real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(in) :: v_in !< Initial meridional velocity, in m s-1. + intent(in) :: v_in !< Initial meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: T_in !< Layer potential temperatures in degC + intent(in) :: T_in !< Layer potential temperatures [degC] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & intent(in) :: S_in !< Layer salinities in ppt. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs. - real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface in Pa + real, dimension(:,:), pointer :: p_surf !< The pressure at the ocean surface [Pa] !! (or NULL). real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), & intent(out) :: kappa_io !< The diapycnal diffusivity at each interface - !! (not layer!) in Z2 s-1. + !! (not layer!) [Z2 s-1 ~> m2 s-1]. real, dimension(SZIB_(G),SZJB_(G),SZK_(GV)+1), & intent(inout) :: tke_io !< The turbulent kinetic energy per unit mass at - !! each interface (not layer!) in m2 s-2. + !! each interface (not layer!) [m2 s-2]. !! Initially this is the value from the previous !! timestep, which may accelerate the iteration !! toward convergence. real, dimension(SZIB_(G),SZJB_(G),SZK_(GV)+1), & - intent(inout) :: kv_io !< The vertical viscosity at each interface in Z2 s-1. + intent(inout) :: kv_io !< The vertical viscosity at each interface [Z2 s-1 ~> m2 s-1]. !! The previous value is used to initialize kappa !! in the vertex columes as Kappa = Kv/Prandtl !! to accelerate the iteration toward covergence. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. type(Kappa_shear_CS), pointer :: CS !< The control structure returned by a previous !! call to kappa_shear_init. logical, optional, intent(in) :: initialize_all !< If present and false, the previous @@ -421,34 +423,32 @@ subroutine Calc_kappa_shear_vertex(u_in, v_in, h, T_in, S_in, tv, p_surf, kappa_ h_2d, & ! A 2-D version of h, but converted to m. u_2d, v_2d, T_2d, S_2d, rho_2d ! 2-D versions of u_in, v_in, T, S, and rho. real, dimension(SZIB_(G),SZK_(GV)+1,2) :: & - kappa_2d ! Quasi 2-D versions of kappa_io, in Z2 s-1. + kappa_2d ! Quasi 2-D versions of kappa_io [Z2 s-1 ~> m2 s-1]. real, dimension(SZIB_(G),SZK_(GV)+1) :: & - tke_2d ! 2-D version tke_io in m2 s-2. + tke_2d ! 2-D version tke_io [m2 s-2]. real, dimension(SZK_(GV)) :: & - u, & ! The zonal velocity after a timestep of mixing, in m s-1. - v, & ! The meridional velocity after a timestep of mixing, in m s-1. - Idz, & ! The inverse of the distance between TKE points, in Z-1. - T, & ! The potential temperature after a timestep of mixing, in C. - Sal, & ! The salinity after a timestep of mixing, in psu. - dz, & ! The layer thickness, in Z. - u0xdz, & ! The initial zonal velocity times dz, in m Z s-1. - v0xdz, & ! The initial meridional velocity times dz, in m Z s-1. - T0xdz, & ! The initial temperature times dz, in C Z. - S0xdz ! The initial salinity times dz, in PSU Z. + u, & ! The zonal velocity after a timestep of mixing [m s-1]. + v, & ! The meridional velocity after a timestep of mixing [m s-1]. + Idz, & ! The inverse of the distance between TKE points [Z-1 ~> m-1]. + T, & ! The potential temperature after a timestep of mixing [degC]. + Sal, & ! The salinity after a timestep of mixing [ppt]. + dz, & ! The layer thickness [Z ~> m]. + u0xdz, & ! The initial zonal velocity times dz [m Z s-1 ~> m2 s-1]. + v0xdz, & ! The initial meridional velocity times dz [m Z s-1 ~> m2 s-1]. + T0xdz, & ! The initial temperature times dz [degC Z ~> degC m]. + S0xdz ! The initial salinity times dz [ppt Z ~> ppt m]. real, dimension(SZK_(GV)+1) :: & - kappa, & ! The shear-driven diapycnal diffusivity at an interface, in - ! units of m2 s-1. - tke, & ! The Turbulent Kinetic Energy per unit mass at an interface, - ! in units of m2 s-2. - kappa_avg, & ! The time-weighted average of kappa, in Z2 s-1. - tke_avg ! The time-weighted average of TKE, in m2 s-2. - real :: f2 ! The squared Coriolis parameter of each column, in s-2. - real :: surface_pres ! The top surface pressure, in Pa. - - real :: dz_in_lay ! The running sum of the thickness in a layer, in Z. - real :: k0dt ! The background diffusivity times the timestep, in Z2. - real :: dz_massless ! A layer thickness that is considered massless, in Z. - real :: I_hwt ! The inverse of the masked thickness weights, in H-1. + kappa, & ! The shear-driven diapycnal diffusivity at an interface [Z2 s-1 ~> m2 s-1]. + tke, & ! The Turbulent Kinetic Energy per unit mass at an interface [m2 s-2]. + kappa_avg, & ! The time-weighted average of kappa [Z2 s-1 ~> m2 s-1]. + tke_avg ! The time-weighted average of TKE [m2 s-2]. + real :: f2 ! The squared Coriolis parameter of each column [s-2]. + real :: surface_pres ! The top surface pressure [Pa]. + + real :: dz_in_lay ! The running sum of the thickness in a layer [Z ~> m]. + real :: k0dt ! The background diffusivity times the timestep [Z2 ~> m2]. + real :: dz_massless ! A layer thickness that is considered massless [Z ~> m]. + real :: I_hwt ! The inverse of the masked thickness weights [H-1 ~> m-1 or m2 kg-1]. real :: I_Prandtl logical :: use_temperature ! If true, temperature and salinity have been ! allocated and are being used as state variables. @@ -460,7 +460,7 @@ subroutine Calc_kappa_shear_vertex(u_in, v_in, h, T_in, S_in, tv, p_surf, kappa_ ! interfaces and the interfaces with massless layers ! merged into nearby massive layers. real, dimension(SZK_(GV)+1) :: kf ! The fractional weight of interface kc+1 for - ! interpolating back to the original index space, ND. + ! interpolating back to the original index space [nondim]. integer :: IsB, IeB, JsB, JeB, i, j, k, nz, nzc, J2, J2m1 ! Diagnostics that should be deleted? @@ -477,7 +477,7 @@ subroutine Calc_kappa_shear_vertex(u_in, v_in, h, T_in, S_in, tv, p_surf, kappa_ real :: wt(SZK_(GV)+1), wt_tot, I_wt_tot, wt_itt real, dimension(SZK_(GV)+1) :: & Ri_k, tke_prev, dtke, dkappa, dtke_norm, & - ksrc_av ! The average through the iterations of k_src, in s-1. + ksrc_av ! The average through the iterations of k_src [s-1]. real, dimension(SZK_(GV)+1,0:max_debug_itt) :: & tke_it1, N2_it1, Sh2_it1, ksrc_it1, kappa_it1, kprev_it1 real, dimension(SZK_(GV)+1,1:max_debug_itt) :: & @@ -714,28 +714,28 @@ subroutine kappa_shear_column(kappa, tke, dt, nzc, f2, surface_pres, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZK_(GV)+1), & - intent(inout) :: kappa !< The time-weighted average of kappa, in Z2 s-1. + intent(inout) :: kappa !< The time-weighted average of kappa [Z2 s-1 ~> m2 s-1]. real, dimension(SZK_(GV)+1), & intent(inout) :: tke !< The Turbulent Kinetic Energy per unit mass at - !! an interface, in units of m2 s-2. + !! an interface [m2 s-2]. integer, intent(in) :: nzc !< The number of active layers in the column. - real, intent(in) :: f2 !< The square of the Coriolis parameter, in s-2. - real, intent(in) :: surface_pres !< The surface pressure, in Pa. + real, intent(in) :: f2 !< The square of the Coriolis parameter [s-2]. + real, intent(in) :: surface_pres !< The surface pressure [Pa]. real, dimension(SZK_(GV)), & - intent(in) :: dz !< The layer thickness, in Z. + intent(in) :: dz !< The layer thickness [Z ~> m]. real, dimension(SZK_(GV)), & - intent(in) :: u0xdz !< The initial zonal velocity times dz, in Z m s-1. + intent(in) :: u0xdz !< The initial zonal velocity times dz [Z m s-1 ~> m2 s-1]. real, dimension(SZK_(GV)), & - intent(in) :: v0xdz !< The initial meridional velocity times dz, in Z m s-1. + intent(in) :: v0xdz !< The initial meridional velocity times dz [Z m s-1 ~> m2 s-1]. real, dimension(SZK_(GV)), & - intent(in) :: T0xdz !< The initial temperature times dz, in C Z. + intent(in) :: T0xdz !< The initial temperature times dz [degC Z ~> degC m]. real, dimension(SZK_(GV)), & - intent(in) :: S0xdz !< The initial salinity times dz, in PSU Z. + intent(in) :: S0xdz !< The initial salinity times dz [ppt Z ~> ppt m]. real, dimension(SZK_(GV)+1), & - intent(out) :: kappa_avg !< The time-weighted average of kappa, in Z2 s-1. + intent(out) :: kappa_avg !< The time-weighted average of kappa [Z2 s-1 ~> m2 s-1]. real, dimension(SZK_(GV)+1), & - intent(out) :: tke_avg !< The time-weighted average of TKE, in m2 s-2. - real, intent(in) :: dt !< Time increment, in s. + intent(out) :: tke_avg !< The time-weighted average of TKE [m2 s-2]. + real, intent(in) :: dt !< Time increment [s]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs. @@ -743,70 +743,69 @@ subroutine kappa_shear_column(kappa, tke, dt, nzc, f2, surface_pres, & !! call to kappa_shear_init. real, dimension(nzc) :: & - u, & ! The zonal velocity after a timestep of mixing, in m s-1. - v, & ! The meridional velocity after a timestep of mixing, in m s-1. - Idz, & ! The inverse of the distance between TKE points, in Z-1. - T, & ! The potential temperature after a timestep of mixing, in C. - Sal, & ! The salinity after a timestep of mixing, in psu. + u, & ! The zonal velocity after a timestep of mixing [m s-1]. + v, & ! The meridional velocity after a timestep of mixing [m s-1]. + Idz, & ! The inverse of the distance between TKE points [Z-1 ~> m-1]. + T, & ! The potential temperature after a timestep of mixing [degC]. + Sal, & ! The salinity after a timestep of mixing [ppt]. u_test, v_test, T_test, S_test real, dimension(nzc+1) :: & - N2, & ! The squared buoyancy frequency at an interface, in s-2. + N2, & ! The squared buoyancy frequency at an interface [s-2]. dz_Int, & ! The extent of a finite-volume space surrounding an interface, - ! as used in calculating kappa and TKE, in Z. + ! as used in calculating kappa and TKE [Z ~> m]. I_dz_int, & ! The inverse of the distance between velocity & density points - ! above and below an interface, in Z-1. This is used to + ! above and below an interface [Z-1 ~> m-1]. This is used to ! calculate N2, shear, and fluxes, and it might differ from ! 1/dz_Int, as they have different uses. - S2, & ! The squared shear at an interface, in s-2. + S2, & ! The squared shear at an interface [s-2]. a1, & ! a1 is the coupling between adjacent interfaces in the TKE, - ! velocity, and density equations, in Z s-1 or Z. + ! velocity, and density equations [Z s-1 ~> m s-1] or [Z ~> m] c1, & ! c1 is used in the tridiagonal (and similar) solvers. - k_src, & ! The shear-dependent source term in the kappa equation, in s-1. - kappa_src, & ! The shear-dependent source term in the kappa equation in s-1. - kappa_out, & ! The kappa that results from the kappa equation, in Z2 s-1. - kappa_mid, & ! The average of the initial and predictor estimates of kappa, - ! in units of Z2 s-1. - tke_pred, & ! The value of TKE from a predictor step, in m2 s-2. - kappa_pred, & ! The value of kappa from a predictor step, in Z2 s-1. - pressure, & ! The pressure at an interface, in Pa. - T_int, & ! The temperature interpolated to an interface, in C. - Sal_int, & ! The salinity interpolated to an interface, in psu. - dbuoy_dT, & ! The partial derivatives of buoyancy with changes in - dbuoy_dS, & ! temperature and salinity, in Z s-2 K-1 and Z s-2 psu-1. + k_src, & ! The shear-dependent source term in the kappa equation [s-1]. + kappa_src, & ! The shear-dependent source term in the kappa equation [s-1]. + kappa_out, & ! The kappa that results from the kappa equation [Z2 s-1 ~> m2 s-1]. + kappa_mid, & ! The average of the initial and predictor estimates of kappa [Z2 s-1 ~> m2 s-1]. + tke_pred, & ! The value of TKE from a predictor step [m2 s-2]. + kappa_pred, & ! The value of kappa from a predictor step [Z2 s-1 ~> m2 s-1]. + pressure, & ! The pressure at an interface [Pa]. + T_int, & ! The temperature interpolated to an interface [degC]. + Sal_int, & ! The salinity interpolated to an interface [ppt]. + dbuoy_dT, & ! The partial derivatives of buoyancy with changes in temperature + dbuoy_dS, & ! and salinity, [Z s-2 degC-1 ~> m s-2 degC-1] and [Z s-2 ppt-1 ~> m s-2 ppt-1]. I_L2_bdry, & ! The inverse of the square of twice the harmonic mean - ! distance to the top and bottom boundaries, in Z-2. - K_Q, & ! Diffusivity divided by TKE, in Z2 m-2 s. - K_Q_tmp, & ! A temporary copy of diffusivity divided by TKE, in Z2 m-2 s. - local_src_avg, & ! The time-integral of the local source, nondim. - tol_min, & ! Minimum tolerated ksrc for the corrector step, in s-1. - tol_max, & ! Maximum tolerated ksrc for the corrector step, in s-1. - tol_chg, & ! The tolerated change integrated in time, nondim. - dist_from_top, & ! The distance from the top surface, in Z. + ! distance to the top and bottom boundaries [Z-2 ~> m-2]. + K_Q, & ! Diffusivity divided by TKE [Z2 m-2 s ~> s]. + K_Q_tmp, & ! A temporary copy of diffusivity divided by TKE [Z2 m-2 s ~> s]. + local_src_avg, & ! The time-integral of the local source [nondim]. + tol_min, & ! Minimum tolerated ksrc for the corrector step [s-1]. + tol_max, & ! Maximum tolerated ksrc for the corrector step [s-1]. + tol_chg, & ! The tolerated change integrated in time [nondim]. + dist_from_top, & ! The distance from the top surface [Z ~> m]. local_src ! The sum of all sources of kappa, including kappa_src and - ! sources from the elliptic term, in s-1. + ! sources from the elliptic term [s-1]. - real :: dist_from_bot ! The distance from the bottom surface, in Z. + real :: dist_from_bot ! The distance from the bottom surface [Z ~> m]. real :: b1 ! The inverse of the pivot in the tridiagonal equations. real :: bd1 ! A term in the denominator of b1. real :: d1 ! 1 - c1 in the tridiagonal equations. - real :: gR0 ! Rho_0 times g in kg m-2 s-2. - real :: g_R0 ! g_R0 is g/Rho in Z m3 kg-1 s-2. - real :: Norm ! A factor that normalizes two weights to 1, in Z-2. + real :: gR0 ! Rho_0 times g [kg m-2 s-2]. + real :: g_R0 ! g_R0 is g/Rho [Z m3 kg-1 s-2 ~> m4 kg-1 s-2]. + real :: Norm ! A factor that normalizes two weights to 1 [Z-2 ~> m-2]. real :: tol_dksrc, tol2 ! ### Tolerances that need to be set better later. real :: tol_dksrc_low ! The tolerance for the fractional decrease in ksrc ! within an iteration. 0 < tol_dksrc_low < 1. real :: Ri_crit ! The critical shear Richardson number for shear- ! driven mixing. The theoretical value is 0.25. - real :: dt_rem ! The remaining time to advance the solution, in s. - real :: dt_now ! The time step used in the current iteration, in s. - real :: dt_wt ! The fractional weight of the current iteration, ND. + real :: dt_rem ! The remaining time to advance the solution [s]. + real :: dt_now ! The time step used in the current iteration [s]. + real :: dt_wt ! The fractional weight of the current iteration [nondim]. real :: dt_test ! A time-step that is being tested for whether it - ! gives acceptably small changes in k_src, in s. - real :: Idtt ! Idtt = 1 / dt_test, in s-1. - real :: dt_inc ! An increment to dt_test that is being tested, in s. + ! gives acceptably small changes in k_src [s]. + real :: Idtt ! Idtt = 1 / dt_test [s-1]. + real :: dt_inc ! An increment to dt_test that is being tested [s]. - real :: k0dt ! The background diffusivity times the timestep, in Z2. + real :: k0dt ! The background diffusivity times the timestep [Z2 ~> m2]. logical :: valid_dt ! If true, all levels so far exhibit acceptably small ! changes in k_src. logical :: use_temperature ! If true, temperature and salinity have been @@ -1234,42 +1233,41 @@ subroutine calculate_projected_state(kappa, u0, v0, T0, S0, dt, nz, & integer, intent(in) :: nz !< The number of layers (after eliminating massless !! layers?). real, dimension(nz+1), intent(in) :: kappa !< The diapycnal diffusivity at interfaces, - !! in Z2 s-1. - real, dimension(nz), intent(in) :: u0 !< The initial zonal velocity, in m s-1. - real, dimension(nz), intent(in) :: v0 !< The initial meridional velocity, in m s-1. - real, dimension(nz), intent(in) :: T0 !< The initial temperature, in C. - real, dimension(nz), intent(in) :: S0 !< The initial salinity, in PSU. - real, dimension(nz), intent(in) :: dz !< The grid spacing of layers, in Z. - real, dimension(nz+1), intent(in) :: I_dz_int !< The inverse of the layer's thicknesses, - !! in Z-1. + !! [Z2 s-1 ~> m2 s-1]. + real, dimension(nz), intent(in) :: u0 !< The initial zonal velocity [m s-1]. + real, dimension(nz), intent(in) :: v0 !< The initial meridional velocity [m s-1]. + real, dimension(nz), intent(in) :: T0 !< The initial temperature [degC]. + real, dimension(nz), intent(in) :: S0 !< The initial salinity [ppt]. + real, dimension(nz), intent(in) :: dz !< The grid spacing of layers [Z ~> m]. + real, dimension(nz+1), intent(in) :: I_dz_int !< The inverse of the layer's thicknesses + !! [Z-1 ~> m-1]. real, dimension(nz+1), intent(in) :: dbuoy_dT !< The partial derivative of buoyancy with - !! temperature, in Z s-2 C-1. + !! temperature [Z s-2 degC-1 ~> m s-2 degC-1]. real, dimension(nz+1), intent(in) :: dbuoy_dS !< The partial derivative of buoyancy with - !! salinity, in Z s-2 PSU-1. - real, intent(in) :: dt !< The time step in s. - real, dimension(nz), intent(inout) :: u !< The zonal velocity after dt, in m s-1. - real, dimension(nz), intent(inout) :: v !< The meridional velocity after dt, in m s-1. - real, dimension(nz), intent(inout) :: T !< The temperature after dt, in C. - real, dimension(nz), intent(inout) :: Sal !< The salinity after dt, in PSU. + !! salinity [Z s-2 ppt-1 ~> m s-2 ppt-1]. + real, intent(in) :: dt !< The time step [s]. + real, dimension(nz), intent(inout) :: u !< The zonal velocity after dt [m s-1]. + real, dimension(nz), intent(inout) :: v !< The meridional velocity after dt [m s-1]. + real, dimension(nz), intent(inout) :: T !< The temperature after dt [degC]. + real, dimension(nz), intent(inout) :: Sal !< The salinity after dt [ppt]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(nz+1), optional, & - intent(inout) :: N2 !< The buoyancy frequency squared at interfaces, - !! in s-2. + intent(inout) :: N2 !< The buoyancy frequency squared at interfaces [s-2]. real, dimension(nz+1), optional, & - intent(inout) :: S2 !< The squared shear at interfaces, in s-2. + intent(inout) :: S2 !< The squared shear at interfaces [s-2]. integer, optional, intent(in) :: ks_int !< The topmost k-index with a non-zero diffusivity. integer, optional, intent(in) :: ke_int !< The bottommost k-index with a non-zero !! diffusivity. real, optional, intent(in) :: vel_underflow !< If present and true, any velocities that !! are smaller in magnitude than this value are - !! set to 0, in m s-1. + !! set to 0 [m s-1]. ! Local variables real, dimension(nz+1) :: c1 real :: L2_to_Z2 ! A conversion factor from horizontal length units to vertical depth - ! units squared, in Z2 m-2. - real :: underflow_vel ! Velocities smaller in magnitude than underflow_vel are set to 0, in m s-1. + ! units squared [Z2 m-2 ~> 1]. + real :: underflow_vel ! Velocities smaller in magnitude than underflow_vel are set to 0 [m s-1]. real :: a_a, a_b, b1, d1, bd1, b1nz_0 integer :: k, ks, ke @@ -1370,90 +1368,88 @@ end subroutine calculate_projected_state subroutine find_kappa_tke(N2, S2, kappa_in, Idz, dz_Int, I_L2_bdry, f2, & nz, CS, GV, US, K_Q, tke, kappa, kappa_src, local_src) integer, intent(in) :: nz !< The number of layers to work on. - real, dimension(nz+1), intent(in) :: N2 !< The buoyancy frequency squared at interfaces, - !! in s-2. - real, dimension(nz+1), intent(in) :: S2 !< The squared shear at interfaces, in s-2. - real, dimension(nz+1), intent(in) :: kappa_in !< The initial guess at the diffusivity, - !! in Z2 s-1. - real, dimension(nz+1), intent(in) :: dz_Int !< The thicknesses associated with interfaces, - !! in Z-1. + real, dimension(nz+1), intent(in) :: N2 !< The buoyancy frequency squared at interfaces [s-2]. + real, dimension(nz+1), intent(in) :: S2 !< The squared shear at interfaces [s-2]. + real, dimension(nz+1), intent(in) :: kappa_in !< The initial guess at the diffusivity + !! [Z2 s-1 ~> m2 s-1]. + real, dimension(nz+1), intent(in) :: dz_Int !< The thicknesses associated with interfaces + !! [Z-1 ~> m-1]. real, dimension(nz+1), intent(in) :: I_L2_bdry !< The inverse of the squared distance to - !! boundaries, m2. - real, dimension(nz), intent(in) :: Idz !< The inverse grid spacing of layers, in Z-1. - real, intent(in) :: f2 !< The squared Coriolis parameter, in s-2. + !! boundaries [m-2]. + real, dimension(nz), intent(in) :: Idz !< The inverse grid spacing of layers [Z-1 ~> m-1]. + real, intent(in) :: f2 !< The squared Coriolis parameter [s-2]. type(Kappa_shear_CS), pointer :: CS !< A pointer to this module's control structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(nz+1), intent(inout) :: K_Q !< The shear-driven diapycnal diffusivity divided by !! the turbulent kinetic energy per unit mass at - !! interfaces, in s. + !! interfaces [s]. real, dimension(nz+1), intent(out) :: tke !< The turbulent kinetic energy per unit mass at - !! interfaces, in units of m2 s-2. - real, dimension(nz+1), intent(out) :: kappa !< The diapycnal diffusivity at interfaces, - !! in Z2 s-1. + !! interfaces [m2 s-2]. + real, dimension(nz+1), intent(out) :: kappa !< The diapycnal diffusivity at interfaces + !! [Z2 s-1 ~> m2 s-1]. real, dimension(nz+1), optional, & - intent(out) :: kappa_src !< The source term for kappa, in s-1. + intent(out) :: kappa_src !< The source term for kappa [s-1]. real, dimension(nz+1), optional, & intent(out) :: local_src !< The sum of all local sources for kappa, - !! in s-1. + !! [s-1]. ! This subroutine calculates new, consistent estimates of TKE and kappa. ! Local variables real, dimension(nz) :: & - aQ, & ! aQ is the coupling between adjacent interfaces in the TKE - ! equations, in m s-1. - dQdz ! Half the partial derivative of TKE with depth, m s-2. + aQ, & ! aQ is the coupling between adjacent interfaces in the TKE equations [m s-1]. + dQdz ! Half the partial derivative of TKE with depth [m s-2]. real, dimension(nz+1) :: & - dK, & ! The change in kappa, in Z2 s-1. - dQ, & ! The change in TKE, in m2 s-2. + dK, & ! The change in kappa [Z2 s-1 ~> m2 s-1]. + dQ, & ! The change in TKE [m2 s-2]. cQ, cK, & ! cQ and cK are the upward influences in the tridiagonal and - ! hexadiagonal solvers for the TKE and kappa equations, ND. + ! hexadiagonal solvers for the TKE and kappa equations [nondim]. I_Ld2, & ! 1/Ld^2, where Ld is the effective decay length scale - ! for kappa, in units of Z-2. - TKE_decay, & ! The local TKE decay rate in s-1. - k_src, & ! The source term in the kappa equation, in s-1. - dQmdK, & ! With Newton's method the change in dQ(k-1) due to dK(k), m2 s Z-2. - dKdQ, & ! With Newton's method the change in dK(k) due to dQ(k), Z2 m-2 s-1. + ! for kappa [Z-2 ~> m-2]. + TKE_decay, & ! The local TKE decay rate [s-1]. + k_src, & ! The source term in the kappa equation [s-1]. + dQmdK, & ! With Newton's method the change in dQ(k-1) due to dK(k) [m2 s Z-2 ~> s]. + dKdQ, & ! With Newton's method the change in dK(k) due to dQ(k) [Z2 m-2 s-1 ~> s-1]. e1 ! The fractional change in a layer TKE due to a change in the ! TKE of the layer above when all the kappas below are 0. ! e1 is nondimensional, and 0 < e1 < 1. real :: tke_src ! The net source of TKE due to mixing against the shear - ! and stratification, in m2 s-3. (For convenience, + ! and stratification [m2 s-3]. (For convenience, ! a term involving the non-dissipation of q0 is also ! included here.) - real :: bQ, bK ! The inverse of the pivot in the tridiagonal equations, in Z-1. + real :: bQ, bK ! The inverse of the pivot in the tridiagonal equations [Z-1 ~> m-1]. real :: bd1 ! A term in the denominator of bQ or bK. real :: cQcomp, cKcomp ! 1 - cQ or 1 - cK in the tridiagonal equations. real :: c_s2 ! The coefficient for the decay of TKE due to ! shear (i.e. proportional to |S|*tke), nondimensional. real :: c_n2 ! The coefficient for the decay of TKE due to - ! stratification (i.e. proportional to N*tke), nondim. + ! stratification (i.e. proportional to N*tke) [nondim]. real :: Ri_crit ! The critical shear Richardson number for shear- ! driven mixing. The theoretical value is 0.25. - real :: q0 ! The background level of TKE, in m2 s-2. + real :: q0 ! The background level of TKE [m2 s-2]. real :: Ilambda2 ! 1.0 / CS%lambda**2. real :: TKE_min ! The minimum value of shear-driven TKE that can be - ! solved for, in m2 s-2. - real :: kappa0 ! The background diapycnal diffusivity, in Z2 s-1. - real :: max_err ! The maximum value of norm_err in a column, nondim. - real :: kappa_trunc ! Diffusivities smaller than this are rounded to 0, Z2 s-1. + ! solved for [m2 s-2]. + real :: kappa0 ! The background diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. + real :: max_err ! The maximum value of norm_err in a column [nondim]. + real :: kappa_trunc ! Diffusivities smaller than this are rounded to 0 [Z2 s-1 ~> m2 s-1]. real :: eden1, eden2, I_eden, ome ! Variables used in calculating e1. - real :: diffusive_src ! The diffusive source in the kappa equation, in m s-1. + real :: diffusive_src ! The diffusive source in the kappa equation [m s-1]. real :: chg_by_k0 ! The value of k_src that leads to an increase of - ! kappa_0 if only the diffusive term is a sink, in s-1. + ! kappa_0 if only the diffusive term is a sink [s-1]. - real :: kappa_mean ! A mean value of kappa, in Z2 s-1. + real :: kappa_mean ! A mean value of kappa [Z2 s-1 ~> m2 s-1]. real :: Newton_test ! The value of relative error that will cause the next ! iteration to use Newton's method. ! Temporary variables used in the Newton's method iterations. real :: decay_term_k ! The decay term in the diffusivity equation real :: decay_term_Q ! The decay term in the TKE equation - real :: I_Q ! The inverse of TKE, in s2 m-2 + real :: I_Q ! The inverse of TKE [s2 m-2] real :: kap_src real :: v1, v2 real :: Z2_to_L2 ! A conversion factor from vertical depth units to horizontal length - ! units squared, in m2 Z-2. + ! units squared [m2 Z-2]. real :: tol_err ! The tolerance for max_err that determines when to ! stop iterating. real :: Newton_err ! The tolerance for max_err that determines when to @@ -1478,13 +1474,13 @@ subroutine find_kappa_tke(N2, S2, kappa_in, Idz, dz_Int, I_L2_bdry, f2, & integer :: max_debug_itt ; parameter(max_debug_itt=20) real :: K_err_lin, Q_err_lin real, dimension(nz+1) :: & - kappa_prev, & ! The value of kappa at the start of the current iteration, in Z2 s-1. - TKE_prev ! The value of TKE at the start of the current iteration, in m2 s-2. + kappa_prev, & ! The value of kappa at the start of the current iteration [Z2 s-1 ~> m2 s-1]. + TKE_prev ! The value of TKE at the start of the current iteration [m2 s-2]. real, dimension(nz+1,1:max_debug_itt) :: & tke_it1, kappa_it1, kprev_it1, & ! Various values from each iteration. dkappa_it1, K_Q_it1, d_dkappa_it1, dkappa_norm_it1 real :: norm_err ! The absolute change in kappa between iterations, - ! normalized by the value of kappa, nondim. + ! normalized by the value of kappa [nondim]. real :: max_TKE_err, min_TKE_err, TKE_err(nz) ! Various normalized TKE changes. integer :: it2 #endif @@ -1577,7 +1573,7 @@ subroutine find_kappa_tke(N2, S2, kappa_in, Idz, dz_Int, I_L2_bdry, f2, & ! terms. ke_tke = max(ke_kappa,ke_kappa_prev)+1 - ! aQ is the coupling between adjacent interfaces in Z s-1. + ! aQ is the coupling between adjacent interfaces [Z s-1 ~> m s-1]. do k=1,min(ke_tke,nz) aQ(k) = (0.5*(kappa(K)+kappa(K+1)) + kappa0) * Idz(k) enddo diff --git a/src/parameterizations/vertical/MOM_opacity.F90 b/src/parameterizations/vertical/MOM_opacity.F90 index db90deeaca..e89ded7e13 100644 --- a/src/parameterizations/vertical/MOM_opacity.F90 +++ b/src/parameterizations/vertical/MOM_opacity.F90 @@ -31,15 +31,15 @@ module MOM_opacity !! water properties into the opacity (i.e., the e-folding depth) and !! (perhaps) the number of bands of penetrating shortwave radiation to use. real :: pen_sw_scale !< The vertical absorption e-folding depth of the - !! penetrating shortwave radiation, in m. + !! penetrating shortwave radiation [m]. real :: pen_sw_scale_2nd !< The vertical absorption e-folding depth of the - !! (2nd) penetrating shortwave radiation, in m. + !! (2nd) penetrating shortwave radiation [m]. real :: SW_1ST_EXP_RATIO !< Ratio for 1st exp decay in Two Exp decay opacity real :: pen_sw_frac !< The fraction of shortwave radiation that is !! penetrating with a constant e-folding approach. real :: blue_frac !< The fraction of the penetrating shortwave - !! radiation that is in the blue band, ND. - real :: opacity_land_value !< The value to use for opacity over land, in m-1. + !! radiation that is in the blue band [nondim]. + real :: opacity_land_value !< The value to use for opacity over land [m-1]. !! The default is 10 m-1 - a value for muddy water. integer :: sbc_chl !< An integer handle used in time interpolation of !! chlorophyll read from a file. @@ -79,25 +79,16 @@ subroutine set_opacity(optics, fluxes, G, GV, CS) type(opacity_CS), pointer :: CS !< The control structure earlier set up by !! opacity_init. -! Arguments: (inout) opacity - The inverse of the vertical absorption decay -! scale for penetrating shortwave radiation, in m-1. -! (inout) fluxes - A structure containing pointers to any possible -! forcing fields. Unused fields have NULL ptrs. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure earlier set up by opacity_init. - ! local variables integer :: i, j, k, n, is, ie, js, je, nz - real :: inv_sw_pen_scale ! The inverse of the e-folding scale, in m-1. + real :: inv_sw_pen_scale ! The inverse of the e-folding scale [m-1]. real :: Inv_nbands ! The inverse of the number of bands of penetrating ! shortwave radiation. logical :: call_for_surface ! if horizontal slice is the surface layer real :: tmp(SZI_(G),SZJ_(G),SZK_(G)) ! A 3-d temporary array. - real :: chl(SZI_(G),SZJ_(G),SZK_(G)) ! The concentration of chlorophyll-A - ! in mg m-3. + real :: chl(SZI_(G),SZJ_(G),SZK_(G)) ! The concentration of chlorophyll-A [mg m-3]. real :: Pen_SW_tot(SZI_(G),SZJ_(G)) ! The penetrating shortwave radiation - ! summed across all bands, in W m-2. + ! summed across all bands [W m-2]. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke if (.not. associated(CS)) call MOM_error(FATAL, "set_opacity: "// & @@ -210,18 +201,17 @@ subroutine opacity_from_chl(optics, fluxes, G, CS, chl_in) optional, intent(in) :: chl_in !< A 3-d field of chlorophyll A, !! in mg m-3. - real :: chl_data(SZI_(G),SZJ_(G)) ! The chlorophyll A concentrations in - ! a layer, in mg/m^3. + real :: chl_data(SZI_(G),SZJ_(G)) ! The chlorophyll A concentrations in a layer [mg m-3]. real :: Inv_nbands ! The inverse of the number of bands of penetrating ! shortwave radiation. real :: Inv_nbands_nir ! The inverse of the number of bands of penetrating ! near-infrafed radiation. real :: SW_pen_tot ! The sum across the bands of the penetrating - ! shortwave radiation, in W m-2. + ! shortwave radiation [W m-2]. real :: SW_vis_tot ! The sum across the visible bands of shortwave - ! radiation, in W m-2. + ! radiation [W m-2]. real :: SW_nir_tot ! The sum across the near infrared bands of shortwave - ! radiation, in W m-2. + ! radiation [W m-2]. type(time_type) :: day character(len=128) :: mesg integer :: i, j, k, n, is, ie, js, je, nz, nbands diff --git a/src/parameterizations/vertical/MOM_regularize_layers.F90 b/src/parameterizations/vertical/MOM_regularize_layers.F90 index 5bf74bf66c..989b2f0154 100644 --- a/src/parameterizations/vertical/MOM_regularize_layers.F90 +++ b/src/parameterizations/vertical/MOM_regularize_layers.F90 @@ -42,7 +42,7 @@ module MOM_regularize_layers real :: h_def_tol4 !< The value of the relative thickness deficit at which to do !! detrainment from the buffer layers to the interior at full !! force, now 50% of the way from h_def_tol1 to 1. - real :: Hmix_min !< The minimum mixed layer thickness in H. + real :: Hmix_min !< The minimum mixed layer thickness [H ~> m or kg m-2]. type(time_type), pointer :: Time => NULL() !< A pointer to the ocean model's clock. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to !! regulate the timing of diagnostic output. @@ -78,21 +78,19 @@ subroutine regularize_layers(h, tv, dt, ea, eb, G, GV, CS) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: ea !< The amount of fluid moved downward into a !! layer; this should be increased due to mixed - !! layer detrainment, in the same units as - !! h - usually m or kg m-2 (i.e., H). + !! layer detrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: eb !< The amount of fluid moved upward into a layer !! this should be increased due to mixed layer - !! entrainment, in the same units as h - usually - !! m or kg m-2 (i.e., H). + !! entrainment [H ~> m or kg m-2]. type(regularize_layers_CS), pointer :: CS !< The control structure returned by a previous !! call to regularize_layers_init. ! Local variables @@ -118,32 +116,30 @@ subroutine regularize_surface(h, tv, dt, ea, eb, G, GV, CS) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(inout) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs. - real, intent(in) :: dt !< Time increment, in s. + real, intent(in) :: dt !< Time increment [s]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: ea !< The amount of fluid moved downward into a !! layer; this should be increased due to mixed - !! layer detrainment, in the same units as h - - !! usually m or kg m-2 (i.e., H). + !! layer detrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: eb !< The amount of fluid moved upward into a layer !! this should be increased due to mixed layer - !! entrainment, in the same units as h - usually - !! m or kg m-2 (i.e., H). + !! entrainment [H ~> m or kg m-2]. type(regularize_layers_CS), pointer :: CS !< The control structure returned by a previous !! call to regularize_layers_init. ! Local variables real, dimension(SZIB_(G),SZJ_(G)) :: & - def_rat_u ! The ratio of the thickness deficit to the minimum depth, ND. + def_rat_u ! The ratio of the thickness deficit to the minimum depth [nondim]. real, dimension(SZI_(G),SZJB_(G)) :: & - def_rat_v ! The ratio of the thickness deficit to the minimum depth, ND. + def_rat_v ! The ratio of the thickness deficit to the minimum depth [nondim]. real, dimension(SZI_(G),SZJ_(G)) :: & - def_rat_h ! The ratio of the thickness deficit to the minimum depth, ND. + def_rat_h ! The ratio of the thickness deficit to the minimum depth [nondim]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: & - e ! The interface depths, in H, positive upward. + e ! The interface depths [H ~> m or kg m-2], positive upward. #ifdef DEBUG_CODE real, dimension(SZIB_(G),SZJ_(G)) :: & @@ -153,51 +149,51 @@ subroutine regularize_surface(h, tv, dt, ea, eb, G, GV, CS) real, dimension(SZI_(G),SZJB_(G)) :: & def_rat_h2, def_rat_h3 real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1) :: & - ef ! The filtered interface depths, in H, positive upward. + ef ! The filtered interface depths [H ~> m or kg m-2], positive upward. #endif real, dimension(SZI_(G),SZK_(G)+1) :: & - e_filt, e_2d ! The interface depths, in H, positive upward. + e_filt, e_2d ! The interface depths [H ~> m or kg m-2], positive upward. real, dimension(SZI_(G),SZK_(G)) :: & - h_2d, & ! A 2-d version of h, in H. - T_2d, & ! A 2-d version of tv%T, in deg C. - S_2d, & ! A 2-d version of tv%S, in PSU. - Rcv, & ! A 2-d version of the coordinate density, in kg m-3. - h_2d_init, & ! The initial value of h_2d, in H. - T_2d_init, & ! THe initial value of T_2d, in deg C. - S_2d_init, & ! The initial value of S_2d, in PSU. + h_2d, & ! A 2-d version of h [H ~> m or kg m-2]. + T_2d, & ! A 2-d version of tv%T [degC]. + S_2d, & ! A 2-d version of tv%S [ppt]. + Rcv, & ! A 2-d version of the coordinate density [kg m-3]. + h_2d_init, & ! The initial value of h_2d [H ~> m or kg m-2]. + T_2d_init, & ! THe initial value of T_2d [degC]. + S_2d_init, & ! The initial value of S_2d [ppt]. d_eb, & ! The downward increase across a layer in the entrainment from - ! below, in H. The sign convention is that positive values of + ! below [H ~> m or kg m-2]. The sign convention is that positive values of ! d_eb correspond to a gain in mass by a layer by upward motion. d_ea ! The upward increase across a layer in the entrainment from - ! above, in H. The sign convention is that positive values of + ! above [H ~> m or kg m-2]. The sign convention is that positive values of ! d_ea mean a net gain in mass by a layer from downward motion. real, dimension(SZI_(G)) :: & p_ref_cv, & ! Reference pressure for the potential density which defines - ! the coordinate variable, set to P_Ref, in Pa. + ! the coordinate variable, set to P_Ref [Pa]. Rcv_tol, & ! A tolerence, relative to the target density differences - ! between layers, for detraining into the interior, ND. + ! between layers, for detraining into the interior [nondim]. h_add_tgt, h_add_tot, & h_tot1, Th_tot1, Sh_tot1, & h_tot3, Th_tot3, Sh_tot3, & h_tot2, Th_tot2, Sh_tot2 real, dimension(SZK_(G)) :: & - h_prev_1d ! The previous thicknesses, in H. - real :: I_dtol ! The inverse of the tolerance changes, nondim. - real :: I_dtol34 ! The inverse of the tolerance changes, nondim. - real :: h1, h2 ! Temporary thicknesses, in H. - real :: e_e, e_w, e_n, e_s ! Temporary interface heights, in H. - real :: wt ! The weight of the filted interfaces in setting the targets, ND. - real :: scale ! A scaling factor, ND. + h_prev_1d ! The previous thicknesses [H ~> m or kg m-2]. + real :: I_dtol ! The inverse of the tolerance changes [nondim]. + real :: I_dtol34 ! The inverse of the tolerance changes [nondim]. + real :: h1, h2 ! Temporary thicknesses [H ~> m or kg m-2]. + real :: e_e, e_w, e_n, e_s ! Temporary interface heights [H ~> m or kg m-2]. + real :: wt ! The weight of the filted interfaces in setting the targets [nondim]. + real :: scale ! A scaling factor [nondim]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real, dimension(SZK_(G)+1) :: & int_flux, int_Tflux, int_Sflux, int_Rflux real :: h_add real :: h_det_tot real :: max_def_rat real :: Rcv_min_det ! The lightest (min) and densest (max) coordinate density - real :: Rcv_max_det ! that can detrain into a layer, in kg m-3. + real :: Rcv_max_det ! that can detrain into a layer [kg m-3]. real :: int_top, int_bot real :: h_predicted @@ -727,44 +723,43 @@ subroutine find_deficit_ratios(e, def_rat_u, def_rat_v, G, GV, CS, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - intent(in) :: e !< Interface depths, in m or kg m-2. + intent(in) :: e !< Interface depths [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G)), & intent(out) :: def_rat_u !< The thickness deficit ratio at u points, - !! nondim. + !! [nondim]. real, dimension(SZI_(G),SZJB_(G)), & intent(out) :: def_rat_v !< The thickness deficit ratio at v points, - !! nondim. + !! [nondim]. type(regularize_layers_CS), pointer :: CS !< The control structure returned by a !! previous call to regularize_layers_init. real, dimension(SZIB_(G),SZJ_(G)), & optional, intent(out) :: def_rat_u_2lay !< The thickness deficit ratio at u !! points when the mixed and buffer layers - !! are aggregated into 1 layer, nondim. + !! are aggregated into 1 layer [nondim]. real, dimension(SZI_(G),SZJB_(G)), & optional, intent(out) :: def_rat_v_2lay !< The thickness deficit ratio at v !! pointswhen the mixed and buffer layers - !! are aggregated into 1 layer, nondim. + !! are aggregated into 1 layer [nondim]. integer, optional, intent(in) :: halo !< An extra-wide halo size, 0 by default. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - optional, intent(in) :: h !< Layer thicknesses, in H (usually m or kg - !! m-2); if h is not present, vertical - !! differences in interface heights are used - !! instead. + optional, intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. + !! If h is not present, vertical differences + !! in interface heights are used instead. ! Local variables real, dimension(SZIB_(G),SZJ_(G)) :: & - h_def_u, & ! The vertically summed thickness deficits at u-points, in H. + h_def_u, & ! The vertically summed thickness deficits at u-points [H ~> m or kg m-2]. h_norm_u, & ! The vertically summed arithmetic mean thickness by which - ! h_def_u is normalized, in H. + ! h_def_u is normalized [H ~> m or kg m-2]. h_def2_u real, dimension(SZI_(G),SZJB_(G)) :: & - h_def_v, & ! The vertically summed thickness deficits at v-points, in H. + h_def_v, & ! The vertically summed thickness deficits at v-points [H ~> m or kg m-2]. h_norm_v, & ! The vertically summed arithmetic mean thickness by which - ! h_def_v is normalized, in H. + ! h_def_v is normalized [H ~> m or kg m-2]. h_def2_v real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: Hmix_min ! CS%Hmix_min converted to units of H. - real :: h1, h2 ! Temporary thicknesses, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: Hmix_min ! A local copy of CS%Hmix_min [H ~> m or kg m-2]. + real :: h1, h2 ! Temporary thicknesses [H ~> m or kg m-2]. integer :: i, j, k, is, ie, js, je, nz, nkmb is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke diff --git a/src/parameterizations/vertical/MOM_set_diffusivity.F90 b/src/parameterizations/vertical/MOM_set_diffusivity.F90 index 79ba2914f5..e4214c8d16 100644 --- a/src/parameterizations/vertical/MOM_set_diffusivity.F90 +++ b/src/parameterizations/vertical/MOM_set_diffusivity.F90 @@ -47,6 +47,11 @@ module MOM_set_diffusivity public set_diffusivity_init public set_diffusivity_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> This control structure contains parameters for MOM_set_diffusivity. type, public :: set_diffusivity_CS ; private logical :: debug !< If true, write verbose checksums for debugging. @@ -66,34 +71,33 @@ module MOM_set_diffusivity logical :: use_LOTW_BBL_diffusivity !< If true, use simpler/less precise, BBL diffusivity. logical :: LOTW_BBL_use_omega !< If true, use simpler/less precise, BBL diffusivity. real :: BBL_effic !< efficiency with which the energy extracted - !! by bottom drag drives BBL diffusion (nondim) - real :: cdrag !< quadratic drag coefficient (nondim) + !! by bottom drag drives BBL diffusion [nondim] + real :: cdrag !< quadratic drag coefficient [nondim] real :: IMax_decay !< inverse of a maximum decay scale for - !! bottom-drag driven turbulence, (1/Z) - real :: Kv !< The interior vertical viscosity (Z2/s) - real :: Kd !< interior diapycnal diffusivity (Z2/s) - real :: Kd_min !< minimum diapycnal diffusivity (Z2/s) - real :: Kd_max !< maximum increment for diapycnal diffusivity (Z2/s) + !! bottom-drag driven turbulence [Z-1 ~> m-1]. + real :: Kv !< The interior vertical viscosity [Z2 s-1 ~> m2 s-1]. + real :: Kd !< interior diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. + real :: Kd_min !< minimum diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. + real :: Kd_max !< maximum increment for diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. !! Set to a negative value to have no limit. real :: Kd_add !< uniform diffusivity added everywhere without - !! filtering or scaling (Z2/s) - real :: Kdml !< mixed layer diapycnal diffusivity (Z2/s) + !! filtering or scaling [Z2 s-1 ~> m2 s-1]. + real :: Kdml !< mixed layer diapycnal diffusivity [Z2 s-1 ~> m2 s-1]. !! when bulkmixedlayer==.false. - real :: Hmix !< mixed layer thickness (meter) when - !! bulkmixedlayer==.false. + real :: Hmix !< mixed layer thickness [meter] when BULKMIXEDLAYER==.false. type(diag_ctrl), pointer :: diag => NULL() !< structure to regulate diagnostic output timing logical :: limit_dissipation !< If enabled, dissipation is limited to be larger !! than the following: - real :: dissip_min !< Minimum dissipation (Z2 m-2 W m-3) - real :: dissip_N0 !< Coefficient a in minimum dissipation = a+b*N (Z2 m-2 W m-3) - real :: dissip_N1 !< Coefficient b in minimum dissipation = a+b*N (Z2 m-2 W m-3 s) - real :: dissip_N2 !< Coefficient c in minimum dissipation = c*N2 (Z2 m-2 W m-3 s2) - real :: dissip_Kd_min !< Minimum Kd (Z2/s) with dissipation Rho0*Kd_min*N^2 + real :: dissip_min !< Minimum dissipation [Z2 m-2 W m-3 ~> W m-3] + real :: dissip_N0 !< Coefficient a in minimum dissipation = a+b*N [Z2 m-2 W m-3 ~> W m-3] + real :: dissip_N1 !< Coefficient b in minimum dissipation = a+b*N [Z2 m-2 W m-3 s ~> J m-3] + real :: dissip_N2 !< Coefficient c in minimum dissipation = c*N2 [Z2 m-2 W m-3 s2 ~> J s m-3] + real :: dissip_Kd_min !< Minimum Kd [Z2 s-1 ~> m2 s-1], with dissipation Rho0*Kd_min*N^2 - real :: TKE_itide_max !< maximum internal tide conversion (W m-2) + real :: TKE_itide_max !< maximum internal tide conversion [W m-2] !! available to mix above the BBL - real :: omega !< Earth's rotation frequency (s-1) + real :: omega !< Earth's rotation frequency [s-1] logical :: ML_radiation !< allow a fraction of TKE available from wind work !! to penetrate below mixed layer base with a vertical !! decay scale determined by the minimum of @@ -105,23 +109,23 @@ module MOM_set_diffusivity !! of exp(-h_ML*Idecay_len_TkE), where Idecay_len_TKE is !! calculated the same way as in the mixed layer code. !! The diapycnal diffusivity is KD(k) = E/(N2(k)+OMEGA2), - !! where N2 is the squared buoyancy frequency (s-2) and OMEGA2 + !! where N2 is the squared buoyancy frequency [s-2] and OMEGA2 !! is the rotation rate of the earth squared. real :: ML_rad_kd_max !< Maximum diapycnal diffusivity due to turbulence - !! radiated from the base of the mixed layer (Z2/s) + !! radiated from the base of the mixed layer [Z2 s-1 ~> m2 s-1]. real :: ML_rad_efold_coeff !< non-dim coefficient to scale penetration depth real :: ML_rad_coeff !< coefficient, which scales MSTAR*USTAR^3 to !! obtain energy available for mixing below - !! mixed layer base (nondimensional) + !! mixed layer base [nondim] logical :: ML_rad_TKE_decay !< If true, apply same exponential decay !! to ML_rad as applied to the other surface !! sources of TKE in the mixed layer code. real :: ustar_min !< A minimum value of ustar to avoid numerical - !! problems (Z/s). If the value is small enough, + !! problems [Z s-1 ~> m s-1]. If the value is small enough, !! this parameter should not affect the solution. - real :: TKE_decay !< ratio of natural Ekman depth to TKE decay scale (nondim) + real :: TKE_decay !< ratio of natural Ekman depth to TKE decay scale [nondim] real :: mstar !< ratio of friction velocity cubed to - !! TKE input to the mixed layer (nondim) + !! TKE input to the mixed layer [nondim] logical :: ML_use_omega !< If true, use absolute rotation rate instead !! of the vertical component of rotation when !! setting the decay scale for mixed layer turbulence. @@ -140,8 +144,8 @@ module MOM_set_diffusivity logical :: simple_TKE_to_Kd !< If true, uses a simple estimate of Kd/TKE that !! does not rely on a layer-formulation. real :: Max_Rrho_salt_fingers !< max density ratio for salt fingering - real :: Max_salt_diff_salt_fingers !< max salt diffusivity for salt fingers (m2/s) - real :: Kv_molecular !< molecular visc for double diff convect (m2/s) + real :: Max_salt_diff_salt_fingers !< max salt diffusivity for salt fingers [Z2 s-1 ~> m2 s-1] + real :: Kv_molecular !< molecular visc for double diff convect [Z2 s-1 ~> m2 s-1] character(len=200) :: inputdir !< The directory in which input files are found type(user_change_diff_CS), pointer :: user_change_diff_CSp => NULL() !< Control structure for a child module @@ -166,17 +170,17 @@ module MOM_set_diffusivity !> This structure has memory for used in calculating diagnostics of diffusivity type diffusivity_diags real, pointer, dimension(:,:,:) :: & - N2_3d => NULL(), & !< squared buoyancy frequency at interfaces (1/s2) - Kd_user => NULL(), & !< user-added diffusivity at interfaces (m2/s) - Kd_BBL => NULL(), & !< BBL diffusivity at interfaces (m2/s) - Kd_work => NULL(), & !< layer integrated work by diapycnal mixing (W/m2) - maxTKE => NULL(), & !< energy required to entrain to h_max (m3/s3) - KT_extra => NULL(), & !< double diffusion diffusivity for temp (Z2/s) - KS_extra => NULL() !< double diffusion diffusivity for saln (Z2/s) + N2_3d => NULL(), & !< squared buoyancy frequency at interfaces [s-2] + Kd_user => NULL(), & !< user-added diffusivity at interfaces [Z2 s-1 ~> m2 s-1] + Kd_BBL => NULL(), & !< BBL diffusivity at interfaces [Z2 s-1 ~> m2 s-1] + Kd_work => NULL(), & !< layer integrated work by diapycnal mixing [W m-2] + maxTKE => NULL(), & !< energy required to entrain to h_max [m3 s-3] + KT_extra => NULL(), & !< double diffusion diffusivity for temp [Z2 s-1 ~> m2 s-1]. + KS_extra => NULL() !< double diffusion diffusivity for saln [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: TKE_to_Kd => NULL() - !< conversion rate (~1.0 / (G_Earth + dRho_lay)) - !! between TKE dissipated within a layer and Kd - !! in that layer, in Z2 s-1 / m3 s-3 = Z2 s2 m-3 + !< conversion rate (~1.0 / (G_Earth + dRho_lay)) between TKE + !! dissipated within a layer and Kd in that layer + !! [Z2 s-1 / m3 s-3 = Z2 s2 m-3 ~> s2 m-1] end type diffusivity_diags @@ -202,15 +206,15 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u_h !< Zonal velocity interpolated to h points, in m s-1. + intent(in) :: u_h !< Zonal velocity interpolated to h points [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: v_h !< Meridional velocity interpolated to h points, in m s-1. + intent(in) :: v_h !< Meridional velocity interpolated to h points [m s-1]. type(thermo_var_ptrs), intent(inout) :: tv !< Structure with pointers to thermodynamic !! fields. Out is for tv%TempxPmE. type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes @@ -218,42 +222,42 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, & !! properties of the ocean. type(vertvisc_type), intent(inout) :: visc !< Structure containing vertical viscosities, bottom !! boundary layer properies, and related fields. - real, intent(in) :: dt !< Time increment (sec). + real, intent(in) :: dt !< Time increment [s]. type(set_diffusivity_CS), pointer :: CS !< Module control structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(out) :: Kd_lay !< Diapycnal diffusivity of each layer (m2/sec). + intent(out) :: Kd_lay !< Diapycnal diffusivity of each layer [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - optional, intent(out) :: Kd_int !< Diapycnal diffusivity at each interface (m2/sec). + optional, intent(out) :: Kd_int !< Diapycnal diffusivity at each interface [Z2 s-1 ~> m2 s-1]. ! local variables real, dimension(SZI_(G)) :: & - N2_bot ! bottom squared buoyancy frequency (1/s2) + N2_bot ! bottom squared buoyancy frequency [s-2] type(diffusivity_diags) :: dd ! structure w/ arrays of pointers to avail diags real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - T_f, S_f ! Temperature and salinity (in deg C and ppt) with + T_f, S_f ! Temperature and salinity [degC] and [ppt] with ! massless layers filled vertically by diffusion. real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - T_adj, S_adj ! Temperature and salinity (in deg C and ppt) + T_adj, S_adj ! Temperature and salinity [degC] and [ppt] ! after full convective adjustment. real, dimension(SZI_(G),SZK_(G)) :: & - N2_lay, & !< squared buoyancy frequency associated with layers (1/s2) - maxTKE, & !< energy required to entrain to h_max (m3/s3) + N2_lay, & !< squared buoyancy frequency associated with layers [s-2] + maxTKE, & !< energy required to entrain to h_max [m3 s-3] TKE_to_Kd !< conversion rate (~1.0 / (G_Earth + dRho_lay)) between !< TKE dissipated within a layer and Kd in that layer, in - !< m2 s-1 / m3 s-3 = s2 m-1. + !< m2 s-1 / m3 s-3 = [s2 m-1]. real, dimension(SZI_(G),SZK_(G)+1) :: & - N2_int, & !< squared buoyancy frequency associated at interfaces (1/s2) - dRho_int, & !< locally ref potential density difference across interfaces (kg/m3) - KT_extra, & !< double difusion diffusivity of temperature (Z2/sec) - KS_extra !< double difusion diffusivity of salinity (Z2/sec) + N2_int, & !< squared buoyancy frequency associated at interfaces [s-2] + dRho_int, & !< locally ref potential density difference across interfaces [kg m-3] + KT_extra, & !< double difusion diffusivity of temperature [Z2 s-1 ~> m2 s-1] + KS_extra !< double difusion diffusivity of salinity [Z2 s-1 ~> m2 s-1] - real :: I_Rho0 ! inverse of Boussinesq density (m3/kg) - real :: dissip ! local variable for dissipation calculations (Z2 W/m5) - real :: Omega2 ! squared absolute rotation rate (1/s2) + real :: I_Rho0 ! inverse of Boussinesq density [m3 kg-1] + real :: dissip ! local variable for dissipation calculations [Z2 W m-5 ~> W m-3] + real :: Omega2 ! squared absolute rotation rate [s-2] logical :: use_EOS ! If true, compute density from T/S using equation of state. type(p3d) :: z_ptrs(6) ! pointers to diagns to be interpolated into depth space @@ -278,8 +282,8 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, & "Module must be initialized before it is used.") I_Rho0 = 1.0/GV%Rho0 - kappa_fill = 1.e-3*US%m_to_Z**2 !### Dimensional constant in m2 s-1. - dt_fill = 7200. !### Dimensionalconstant in s. + kappa_fill = 1.e-3*US%m_to_Z**2 !### Dimensional constant [m2 s-1]. + dt_fill = 7200. !### Dimensionalconstant [s]. Omega2 = CS%Omega*CS%Omega use_EOS = associated(tv%eqn_of_state) @@ -494,12 +498,12 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, & endif if (CS%limit_dissipation) then - do k=2,nz-1 ; do i=is,ie ! This calculates the dissipation ONLY from Kd calculated in this routine - ! dissip has units of W/m3 (kg/m3 * m2/s * 1/s2 = J/s/m3) + ! dissip has units of W/m3 (= kg/m3 * m2/s * 1/s2) ! 1) a global constant, ! 2) a dissipation proportional to N (aka Gargett) and ! 3) dissipation corresponding to a (nearly) constant diffusivity. + do k=2,nz-1 ; do i=is,ie dissip = max( CS%dissip_min, & ! Const. floor on dissip. CS%dissip_N0 + CS%dissip_N1 * sqrt(N2_lay(i,k)), & ! Floor aka Gargett CS%dissip_N2 * N2_lay(i,k) ) ! Floor of Kd_min*rho0/F_Ri @@ -508,11 +512,6 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, & enddo ; enddo if (present(Kd_int)) then ; do K=2,nz ; do i=is,ie - ! This calculates the dissipation ONLY from Kd calculated in this routine - ! dissip has units of W/m3 (kg/m3 * m2/s * 1/s2 = J/s/m3) - ! 1) a global constant, - ! 2) a dissipation proportional to N (aka Gargett) and - ! 3) dissipation corresponding to a (nearly) constant diffusivity. dissip = max( CS%dissip_min, & ! Const. floor on dissip. CS%dissip_N0 + CS%dissip_N1 * sqrt(N2_int(i,K)), & ! Floor aka Gargett CS%dissip_N2 * N2_int(i,K) ) ! Floor of Kd_min*rho0/F_Ri @@ -524,7 +523,7 @@ subroutine set_diffusivity(u, v, h, u_h, v_h, tv, fluxes, optics, visc, dt, & if (associated(dd%Kd_work)) then do k=1,nz ; do i=is,ie dd%Kd_Work(i,j,k) = GV%Rho0 * US%Z_to_m**3*Kd_lay(i,j,k) * N2_lay(i,k) * & - GV%H_to_Z*h(i,j,k) ! Watt m-2 s or kg s-3 + GV%H_to_Z*h(i,j,k) ! Watt m-2 s = kg s-3 enddo ; enddo endif enddo ! j-loop @@ -665,57 +664,57 @@ subroutine find_TKE_to_Kd(h, tv, dRho_int, N2_lay, j, dt, G, GV, US, CS, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any available !! thermodynamic fields. real, dimension(SZI_(G),SZK_(G)+1), intent(in) :: dRho_int !< Change in locally referenced potential density - !! across each interface, in kg m-3. + !! across each interface [kg m-3]. real, dimension(SZI_(G),SZK_(G)), intent(in) :: N2_lay !< The squared buoyancy frequency of the - !! layers, in s-2. + !! layers [s-2]. integer, intent(in) :: j !< j-index of row to work on - real, intent(in) :: dt !< Time increment (sec). + real, intent(in) :: dt !< Time increment [s]. type(set_diffusivity_CS), pointer :: CS !< Diffusivity control structure real, dimension(SZI_(G),SZK_(G)), intent(out) :: TKE_to_Kd !< The conversion rate between the TKE !! TKE dissipated within a layer and the !! diapycnal diffusivity witin that layer, - !! usually (~Rho_0 / (G_Earth * dRho_lay)), - !! in Z2 s-1 / m3 s-3 = Z2 s2 m-3 + !! usually (~Rho_0 / (G_Earth * dRho_lay)) + !! [Z2 s-1 / m3 s-3 = Z2 s2 m-3 ~> s2 m-1] real, dimension(SZI_(G),SZK_(G)), intent(out) :: maxTKE !< The energy required to for a layer to entrain - !! to its maximum realizable thickness, in m3 s-3 + !! to its maximum realizable thickness [m3 s-3] integer, dimension(SZI_(G)), intent(out) :: kb !< Index of lightest layer denser than the buffer !! layer, or -1 without a bulk mixed layer. ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & ds_dsp1, & ! coordinate variable (sigma-2) difference across an ! interface divided by the difference across the interface - ! below it (nondimensional) + ! below it [nondim] dsp1_ds, & ! inverse coordinate variable (sigma-2) difference ! across an interface times the difference across the - ! interface above it (nondimensional) - rho_0, & ! Layer potential densities relative to surface pressure (kg/m3) + ! interface above it [nondim] + rho_0, & ! Layer potential densities relative to surface pressure [kg m-3] maxEnt ! maxEnt is the maximum value of entrainment from below (with ! compensating entrainment from above to keep the layer ! density from changing) that will not deplete all of the - ! layers above or below a layer within a timestep (Z) + ! layers above or below a layer within a timestep [Z ~> m]. real, dimension(SZI_(G)) :: & htot, & ! total thickness above or below a layer, or the - ! integrated thickness in the BBL (Z) + ! integrated thickness in the BBL [Z ~> m]. mFkb, & ! total thickness in the mixed and buffer layers - ! times ds_dsp1 (Z) + ! times ds_dsp1 [Z ~> m]. p_ref, & ! array of tv%P_Ref pressures Rcv_kmb, & ! coordinate density in the lowest buffer layer p_0 ! An array of 0 pressures real :: dh_max ! maximum amount of entrainment a layer could ! undergo before entraining all fluid in the layers - ! above or below (Z) - real :: dRho_lay ! density change across a layer (kg/m3) - real :: Omega2 ! rotation rate squared (1/s2) - real :: G_Rho0 ! gravitation accel divided by Bouss ref density (m4 s-2 kg-1) - real :: I_Rho0 ! inverse of Boussinesq reference density (m3/kg) - real :: I_dt ! 1/dt (1/sec) - real :: H_neglect ! negligibly small thickness (units as h) - real :: hN2pO2 ! h * (N^2 + Omega^2), in m3 s-2 Z-2. + ! above or below [Z ~> m]. + real :: dRho_lay ! density change across a layer [kg m-3] + real :: Omega2 ! rotation rate squared [s-2] + real :: G_Rho0 ! gravitation accel divided by Bouss ref density [m4 s-2 kg-1] + real :: I_Rho0 ! inverse of Boussinesq reference density [m3 kg-1] + real :: I_dt ! 1/dt [s-1] + real :: H_neglect ! negligibly small thickness [H ~> m or kg m-2] + real :: hN2pO2 ! h (N^2 + Omega^2), in [m3 s-2 Z-2 ~> m s-2]. logical :: do_i(SZI_(G)) integer :: i, k, is, ie, nz, i_rem, kmb, kb_min @@ -869,45 +868,45 @@ subroutine find_N2(h, tv, T_f, S_f, fluxes, j, G, GV, US, CS, dRho_int, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any available !! thermodynamic fields. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: T_f !< layer temp in C with the values in massless layers - !! filled vertically by diffusion. + intent(in) :: T_f !< layer temperature with the values in massless layers + !! filled vertically by diffusion [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: S_f !< Layer salinities in PPT with values in massless - !! layers filled vertically by diffusion. + intent(in) :: S_f !< Layer salinities with values in massless + !! layers filled vertically by diffusion [ppt]. type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes integer, intent(in) :: j !< j-index of row to work on type(set_diffusivity_CS), pointer :: CS !< Diffusivity control structure real, dimension(SZI_(G),SZK_(G)+1), & intent(out) :: dRho_int !< Change in locally referenced potential density - !! across each interface, in kg m-3. + !! across each interface [kg m-3]. real, dimension(SZI_(G),SZK_(G)+1), & - intent(out) :: N2_int !< The squared buoyancy frequency at the interfaces, in s-2. + intent(out) :: N2_int !< The squared buoyancy frequency at the interfaces [s-2]. real, dimension(SZI_(G),SZK_(G)), & - intent(out) :: N2_lay !< The squared buoyancy frequency of the layers, in s-2. - real, dimension(SZI_(G)), intent(out) :: N2_bot !< The near-bottom squared buoyancy frequency, in s-2. + intent(out) :: N2_lay !< The squared buoyancy frequency of the layers [s-2]. + real, dimension(SZI_(G)), intent(out) :: N2_bot !< The near-bottom squared buoyancy frequency [s-2]. ! Local variables real, dimension(SZI_(G),SZK_(G)+1) :: & dRho_int_unfilt, & ! unfiltered density differences across interfaces - dRho_dT, & ! partial derivative of density wrt temp (kg m-3 degC-1) - dRho_dS ! partial derivative of density wrt saln (kg m-3 PPT-1) + dRho_dT, & ! partial derivative of density wrt temp [kg m-3 degC-1] + dRho_dS ! partial derivative of density wrt saln [kg m-3 ppt-1] real, dimension(SZI_(G)) :: & - pres, & ! pressure at each interface (Pa) - Temp_int, & ! temperature at each interface (degC) - Salin_int, & ! salinity at each interface (PPT) + pres, & ! pressure at each interface [Pa] + Temp_int, & ! temperature at each interface [degC] + Salin_int, & ! salinity at each interface [ppt] drho_bot, & - h_amp, & ! The topographic roughness amplitude, in Z. - hb, & ! The thickness of the bottom layer in Z - z_from_bot ! The hieght above the bottom in Z + h_amp, & ! The topographic roughness amplitude [Z ~> m]. + hb, & ! The thickness of the bottom layer [Z ~> m]. + z_from_bot ! The hieght above the bottom [Z ~> m]. real :: Rml_base ! density of the deepest variable density layer - real :: dz_int ! thickness associated with an interface (Z) + real :: dz_int ! thickness associated with an interface [Z ~> m]. real :: G_Rho0 ! gravitation acceleration divided by Bouss reference density - ! times some unit conversion factors, in (Z m3 s-2 kg-1) + ! times some unit conversion factors [Z m3 s-2 kg-1 ~> m4 s-2 kg-1]. real :: H_neglect ! negligibly small thickness, in the same units as h. logical :: do_i(SZI_(G)), do_any @@ -1046,47 +1045,47 @@ subroutine double_diffusion(tv, h, T_f, S_f, j, G, GV, US, CS, Kd_T_dd, Kd_S_dd) type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any available !! thermodynamic fields; absent fields have NULL ptrs. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: T_f !< layer temp in C with the values in massless layers - !! filled vertically by diffusion. + intent(in) :: T_f !< layer temperatures with the values in massless layers + !! filled vertically by diffusion [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: S_f !< Layer salinities in PPT with values in massless - !! layers filled vertically by diffusion. + intent(in) :: S_f !< Layer salinities with values in massless + !! layers filled vertically by diffusion [ppt]. integer, intent(in) :: j !< Meridional index upon which to work. type(set_diffusivity_CS), pointer :: CS !< Module control structure. real, dimension(SZI_(G),SZK_(G)+1), & intent(out) :: Kd_T_dd !< Interface double diffusion diapycnal - !! diffusivity for temp (Z2/sec). + !! diffusivity for temp [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZK_(G)+1), & intent(out) :: Kd_S_dd !< Interface double diffusion diapycnal - !! diffusivity for saln (Z2/sec). + !! diffusivity for saln [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G)) :: & - dRho_dT, & ! partial derivatives of density wrt temp (kg m-3 degC-1) - dRho_dS, & ! partial derivatives of density wrt saln (kg m-3 PPT-1) - pres, & ! pressure at each interface (Pa) - Temp_int, & ! temp and saln at interfaces - Salin_int - - real :: alpha_dT ! density difference between layers due to temp diffs (kg/m3) - real :: beta_dS ! density difference between layers due to saln diffs (kg/m3) - - real :: Rrho ! vertical density ratio - real :: diff_dd ! factor for double-diffusion (nondim) - real :: Kd_dd ! The dominant double diffusive diffusivity in Z2/sec + dRho_dT, & ! partial derivatives of density wrt temp [kg m-3 degC-1] + dRho_dS, & ! partial derivatives of density wrt saln [kg m-3 ppt-1] + pres, & ! pressure at each interface [Pa] + Temp_int, & ! temperature at interfaces [degC] + Salin_int ! Salinity at interfaces [ppt] + + real :: alpha_dT ! density difference between layers due to temp diffs [kg m-3] + real :: beta_dS ! density difference between layers due to saln diffs [kg m-3] + + real :: Rrho ! vertical density ratio [nondim] + real :: diff_dd ! factor for double-diffusion [nondim] + real :: Kd_dd ! The dominant double diffusive diffusivity [Z2 s-1 ~> m2 s-1] real :: prandtl ! flux ratio for diffusive convection regime - real, parameter :: Rrho0 = 1.9 ! limit for double-diffusive density ratio - real :: dsfmax ! max diffusivity in case of salt fingering (Z2/sec) - real :: Kv_molecular ! molecular viscosity (Z2/sec) + real, parameter :: Rrho0 = 1.9 ! limit for double-diffusive density ratio [nondim] + real :: dsfmax ! max diffusivity in case of salt fingering [Z2 s-1 ~> m2 s-1] + real :: Kv_molecular ! molecular viscosity [Z2 s-1 ~> m2 s-1] integer :: i, k, is, ie, nz is = G%isc ; ie = G%iec ; nz = G%ke if (associated(tv%eqn_of_state)) then - dsfmax = US%m_to_Z**2 * 1.e-4 ! max salt fingering diffusivity rescaled to (Z2/sec) - Kv_molecular = US%m_to_Z**2 * 1.5e-6 ! molecular viscosity rescaled to (Z2/sec) + dsfmax = US%m_to_Z**2 * 1.e-4 ! max salt fingering diffusivity rescaled to [Z2 s-1 ~> m2 s-1] + Kv_molecular = US%m_to_Z**2 * 1.5e-6 ! molecular viscosity rescaled to [Z2 s-1 ~> m2 s-1] do i=is,ie pres(i) = 0.0 ; Kd_T_dd(i,1) = 0.0 ; Kd_S_dd(i,1) = 0.0 @@ -1134,11 +1133,11 @@ subroutine add_drag_diffusivity(h, u, v, tv, fluxes, visc, j, TKE_to_Kd, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1 + intent(in) :: u !< The zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1 + intent(in) :: v !< The meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any available !! thermodynamic fields. type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes @@ -1148,44 +1147,46 @@ subroutine add_drag_diffusivity(h, u, v, tv, fluxes, visc, j, TKE_to_Kd, & real, dimension(SZI_(G),SZK_(G)), intent(in) :: TKE_to_Kd !< The conversion rate between the TKE !! TKE dissipated within a layer and the !! diapycnal diffusivity witin that layer, - !! usually (~Rho_0 / (G_Earth * dRho_lay)), - !! in Z2 s-1 / m3 s-3 = Z2 s2 m-3 + !! usually (~Rho_0 / (G_Earth * dRho_lay)) + !! [Z2 s-1 / m3 s-3 = Z2 s2 m-3 ~> s2 m-1] real, dimension(SZI_(G),SZK_(G)), intent(in) :: maxTKE !< The energy required to for a layer to entrain - !! to its maximum realizable thickness, in m3 s-3 + !! to its maximum realizable thickness [m3 s-3] integer, dimension(SZI_(G)), intent(in) :: kb !< Index of lightest layer denser than the buffer !! layer, or -1 without a bulk mixed layer type(set_diffusivity_CS), pointer :: CS !< Diffusivity control structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers, in Z2 s-1 + intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers, + !! [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces, in Z2 s-1 - real, dimension(:,:,:), pointer :: Kd_BBL !< Interface BBL diffusivity, in m2 s-1 + intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces, + !! [Z2 s-1 ~> m2 s-1]. + real, dimension(:,:,:), pointer :: Kd_BBL !< Interface BBL diffusivity [Z2 s-1 ~> m2 s-1]. ! This routine adds diffusion sustained by flow energy extracted by bottom drag. real, dimension(SZK_(G)+1) :: & - Rint ! coordinate density of an interface (kg/m3) + Rint ! coordinate density of an interface [kg m-3] real, dimension(SZI_(G)) :: & htot, & ! total thickness above or below a layer, or the - ! integrated thickness in the BBL (Z) - rho_htot, & ! running integral with depth of density (Z kg/m3) + ! integrated thickness in the BBL [Z ~> m]. + rho_htot, & ! running integral with depth of density [Z kg m-3 ~> kg m-2] gh_sum_top, & ! BBL value of g'h that can be supported by - ! the local ustar, times R0_g (kg/m2) - Rho_top, & ! density at top of the BBL (kg/m3) + ! the local ustar, times R0_g [kg m-2] + Rho_top, & ! density at top of the BBL [kg m-3] TKE, & ! turbulent kinetic energy available to drive - ! bottom-boundary layer mixing in a layer (m3/s3) - I2decay ! inverse of twice the TKE decay scale (1/Z) - - real :: TKE_to_layer ! TKE used to drive mixing in a layer (m3/s3) - real :: TKE_Ray ! TKE from layer Rayleigh drag used to drive mixing in layer (m3/s3) - real :: TKE_here ! TKE that goes into mixing in this layer (m3/s3) - real :: dRl, dRbot ! temporaries holding density differences (kg/m3) - real :: cdrag_sqrt ! square root of the drag coefficient (nondimensional) - real :: ustar_h ! value of ustar at a thickness point (Z/s) - real :: absf ! average absolute Coriolis parameter around a thickness point (1/s) - real :: R0_g ! Rho0 / G_Earth (kg s2 Z-1 m-4) - real :: I_rho0 ! 1 / RHO0 - real :: delta_Kd ! increment to Kd from the bottom boundary layer mixing (Z2/s) + ! bottom-boundary layer mixing in a layer [m3 s-3] + I2decay ! inverse of twice the TKE decay scale [Z-1 ~> m-1]. + + real :: TKE_to_layer ! TKE used to drive mixing in a layer [m3 s-3] + real :: TKE_Ray ! TKE from layer Rayleigh drag used to drive mixing in layer [m3 s-3] + real :: TKE_here ! TKE that goes into mixing in this layer [m3 s-3] + real :: dRl, dRbot ! temporaries holding density differences [kg m-3] + real :: cdrag_sqrt ! square root of the drag coefficient [nondim] + real :: ustar_h ! value of ustar at a thickness point [Z s-1 ~> m s-1]. + real :: absf ! average absolute Coriolis parameter around a thickness point [s-1] + real :: R0_g ! Rho0 / G_Earth [kg s2 Z-1 m-4 ~> kg s2 m-5] + real :: I_rho0 ! 1 / RHO0 [m3 kg-1] + real :: delta_Kd ! increment to Kd from the bottom boundary layer mixing [Z2 s-1 ~> m2 s-1]. logical :: Rayleigh_drag ! Set to true if Rayleigh drag velocities ! defined in visc, on the assumption that this ! extracted energy also drives diapycnal mixing. @@ -1369,11 +1370,11 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< u component of flow (m s-1) + intent(in) :: u !< u component of flow [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< v component of flow (m s-1) + intent(in) :: v !< v component of flow [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness (m or kg m-2) + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any available !! thermodynamic fields. type(forcing), intent(in) :: fluxes !< Surface fluxes structure @@ -1381,35 +1382,35 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & !! boundary layer properies, and related fields. integer, intent(in) :: j !< j-index of row to work on real, dimension(SZI_(G),SZK_(G)+1), & - intent(in) :: N2_int !< Square of Brunt-Vaisala at interfaces (s-2) + intent(in) :: N2_int !< Square of Brunt-Vaisala at interfaces [s-2] type(set_diffusivity_CS), pointer :: CS !< Diffusivity control structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: Kd_lay !< Layer net diffusivity (m2 s-1) + intent(inout) :: Kd_lay !< Layer net diffusivity [Z2 s-1 ~> m2 s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - intent(inout) :: Kd_int !< Interface net diffusivity (m2 s-1) - real, dimension(:,:,:), pointer :: Kd_BBL !< Interface BBL diffusivity (m2 s-1) + intent(inout) :: Kd_int !< Interface net diffusivity [Z2 s-1 ~> m2 s-1] + real, dimension(:,:,:), pointer :: Kd_BBL !< Interface BBL diffusivity [Z2 s-1 ~> m2 s-1] ! Local variables - real :: TKE_column ! net TKE input into the column (m3 s-3) - real :: TKE_to_layer ! TKE used to drive mixing in a layer (m3 s-3) - real :: TKE_Ray ! TKE from a layer Rayleigh drag used to drive mixing in that layer (m3 s-3) - real :: TKE_remaining ! remaining TKE available for mixing in this layer and above (m3 s-3) - real :: TKE_consumed ! TKE used for mixing in this layer (m3 s-3) - real :: TKE_Kd_wall ! TKE associated with unlimited law of the wall mixing (m3 s-3) - real :: cdrag_sqrt ! square root of the drag coefficient (nondimensional) - real :: ustar ! value of ustar at a thickness point (Z/s) - real :: ustar2 ! square of ustar, for convenience (Z2/s2) - real :: absf ! average absolute value of Coriolis parameter around a thickness point (1/sec) - real :: dh, dhm1 ! thickness of layers k and k-1, respecitvely (Z) - real :: z_bot ! distance to interface k from bottom (Z) - real :: D_minus_z ! distance to interface k from surface (Z) - real :: total_thickness ! total thickness of water column (Z) - real :: Idecay ! inverse of decay scale used for "Joule heating" loss of TKE with height (1/Z) - real :: Kd_wall ! Law of the wall diffusivity (Z2/s) - real :: Kd_lower ! diffusivity for lower interface (Z2/sec) - real :: ustar_D ! u* x D (Z2/s) + real :: TKE_column ! net TKE input into the column [m3 s-3] + real :: TKE_to_layer ! TKE used to drive mixing in a layer [m3 s-3] + real :: TKE_Ray ! TKE from a layer Rayleigh drag used to drive mixing in that layer [m3 s-3] + real :: TKE_remaining ! remaining TKE available for mixing in this layer and above [m3 s-3] + real :: TKE_consumed ! TKE used for mixing in this layer [m3 s-3] + real :: TKE_Kd_wall ! TKE associated with unlimited law of the wall mixing [m3 s-3] + real :: cdrag_sqrt ! square root of the drag coefficient [nondim] + real :: ustar ! value of ustar at a thickness point [Z s-1 ~> m s-1]. + real :: ustar2 ! square of ustar, for convenience [Z2 s-2 ~> m2 s-2] + real :: absf ! average absolute value of Coriolis parameter around a thickness point [s-1] + real :: dh, dhm1 ! thickness of layers k and k-1, respecitvely [Z ~> m]. + real :: z_bot ! distance to interface k from bottom [Z ~> m]. + real :: D_minus_z ! distance to interface k from surface [Z ~> m]. + real :: total_thickness ! total thickness of water column [Z ~> m]. + real :: Idecay ! inverse of decay scale used for "Joule heating" loss of TKE with height [Z-1 ~> m-1]. + real :: Kd_wall ! Law of the wall diffusivity [Z2 s-1 ~> m2 s-1]. + real :: Kd_lower ! diffusivity for lower interface [Z2 s-1 ~> m2 s-1] + real :: ustar_D ! u* x D [Z2 s-1 ~> m2 s-1]. real :: I_Rho0 ! 1 / rho0 - real :: N2_min ! Minimum value of N2 to use in calculation of TKE_Kd_wall (1/s2) + real :: N2_min ! Minimum value of N2 to use in calculation of TKE_Kd_wall [s-2] logical :: Rayleigh_drag ! Set to true if there are Rayleigh drag velocities defined in visc, on ! the assumption that this extracted energy also drives diapycnal mixing. integer :: i, k, km1 @@ -1435,7 +1436,7 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & absf = 0.25*((abs(G%CoriolisBu(I-1,J-1)) + abs(G%CoriolisBu(I,J))) + & (abs(G%CoriolisBu(I-1,J)) + abs(G%CoriolisBu(I,J-1)))) ! Non-zero on equator! - ! u* at the bottom, in m s-1. + ! u* at the bottom [m s-1]. ustar = visc%ustar_BBL(i,j) ustar2 = ustar**2 ! In add_drag_diffusivity(), fluxes%ustar_tidal is added in. This might be double counting @@ -1447,17 +1448,17 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & Idecay = CS%IMax_decay if ((ustar > 0.0) .and. (absf > CS%IMax_decay*ustar)) Idecay = absf / ustar - ! Energy input at the bottom, in m3 s-3. + ! Energy input at the bottom [m3 s-3]. ! (Note that visc%TKE_BBL is in m3 s-3, set in set_BBL_TKE().) ! I am still unsure about sqrt(cdrag) in this expressions - AJA TKE_column = cdrag_sqrt * visc%TKE_BBL(i,j) - ! Add in tidal dissipation energy at the bottom, in m3 s-3. - ! Note that TKE_tidal is in W m-2. + ! Add in tidal dissipation energy at the bottom [m3 s-3]. + ! Note that TKE_tidal is in [W m-2]. if (associated(fluxes%TKE_tidal)) TKE_column = TKE_column + fluxes%TKE_tidal(i,j) * I_Rho0 TKE_column = CS%BBL_effic * TKE_column ! Only use a fraction of the mechanical dissipation for mixing. TKE_remaining = TKE_column - total_thickness = ( sum(h(i,j,:)) + GV%H_subroundoff )* GV%H_to_Z ! Total column thickness, in m. + total_thickness = ( sum(h(i,j,:)) + GV%H_subroundoff )* GV%H_to_Z ! Total column thickness [Z ~> m]. ustar_D = ustar * total_thickness z_bot = 0. Kd_lower = 0. ! Diffusivity on bottom boundary. @@ -1465,9 +1466,9 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & ! Work upwards from the bottom, accumulating work used until it exceeds the available TKE input ! at the bottom. do k=G%ke,2,-1 - dh = GV%H_to_Z * h(i,j,k) ! Thickness of this level in Z. + dh = GV%H_to_Z * h(i,j,k) ! Thickness of this level [Z ~> m]. km1 = max(k-1, 1) - dhm1 = GV%H_to_Z * h(i,j,km1) ! Thickness of level above in Z. + dhm1 = GV%H_to_Z * h(i,j,km1) ! Thickness of level above [Z ~> m]. ! Add in additional energy input from bottom-drag against slopes (sides) if (Rayleigh_drag) TKE_remaining = TKE_remaining + & @@ -1481,10 +1482,10 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & ! This is energy loss in addition to work done as mixing, apparently to Joule heating. TKE_remaining = exp(-Idecay*dh) * TKE_remaining - z_bot = z_bot + h(i,j,k)*GV%H_to_Z ! Distance between upper interface of layer and the bottom, in Z. + z_bot = z_bot + h(i,j,k)*GV%H_to_Z ! Distance between upper interface of layer and the bottom [Z ~> m]. D_minus_z = max(total_thickness - z_bot, 0.) ! Thickness above layer, Z. - ! Diffusivity using law of the wall, limited by rotation, at height z, in m2/s. + ! Diffusivity using law of the wall, limited by rotation, at height z [m2 s-1]. ! This calculation is at the upper interface of the layer if ( ustar_D + absf * ( z_bot * D_minus_z ) == 0.) then Kd_wall = 0. @@ -1493,7 +1494,7 @@ subroutine add_LOTW_BBL_diffusivity(h, u, v, tv, fluxes, visc, j, N2_int, & ( ustar_D + absf * ( z_bot * D_minus_z ) ) endif - ! TKE associated with Kd_wall, in m3 s-2. + ! TKE associated with Kd_wall [m3 s-2]. ! This calculation if for the volume spanning the interface. TKE_Kd_wall = US%Z_to_m**3*Kd_wall * 0.5 * (dh + dhm1) * max(N2_int(i,k), N2_min) @@ -1530,38 +1531,39 @@ subroutine add_MLrad_diffusivity(h, fluxes, j, G, GV, US, CS, Kd_lay, TKE_to_Kd, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(forcing), intent(in) :: fluxes !< Surface fluxes structure type(set_diffusivity_CS), pointer :: CS !< Diffusivity control structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers, in Z2 s-1. + intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers [Z2 s-1 ~> m2 s-1]. integer, intent(in) :: j !< The j-index to work on real, dimension(SZI_(G),SZK_(G)), intent(in) :: TKE_to_Kd !< The conversion rate between the TKE !! TKE dissipated within a layer and the !! diapycnal diffusivity witin that layer, - !! usually (~Rho_0 / (G_Earth * dRho_lay)), - !! in Z2 s-1 / m3 s-3 = Z2 s2 m-3 + !! usually (~Rho_0 / (G_Earth * dRho_lay)) + !! [Z2 s-1 / m3 s-3 = Z2 s2 m-3 ~> s2 m-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - optional, intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces, in Z2 s-1. + optional, intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces + !! [Z2 s-1 ~> m2 s-1]. ! This routine adds effects of mixed layer radiation to the layer diffusivities. - real, dimension(SZI_(G)) :: h_ml ! Mixed layer thickness, in Z. + real, dimension(SZI_(G)) :: h_ml ! Mixed layer thickness [Z ~> m]. real, dimension(SZI_(G)) :: TKE_ml_flux - real, dimension(SZI_(G)) :: I_decay ! A decay rate in Z-1. - real, dimension(SZI_(G)) :: Kd_mlr_ml ! Diffusivities associated with mixed layer radiation, in Z2 s-1. + real, dimension(SZI_(G)) :: I_decay ! A decay rate [Z-1 ~> m-1]. + real, dimension(SZI_(G)) :: Kd_mlr_ml ! Diffusivities associated with mixed layer radiation [Z2 s-1 ~> m2 s-1]. - real :: f_sq ! The square of the local Coriolis parameter or a related variable, in s-2. - real :: h_ml_sq ! The square of the mixed layer thickness, in Z2. - real :: ustar_sq ! ustar squared in Z2 s-2. - real :: Kd_mlr ! A diffusivity associated with mixed layer turbulence radiation, in Z2 s-1. + real :: f_sq ! The square of the local Coriolis parameter or a related variable [s-2]. + real :: h_ml_sq ! The square of the mixed layer thickness [Z2 ~> m2]. + real :: ustar_sq ! ustar squared [Z2 s-2 ~> m2 s-2] + real :: Kd_mlr ! A diffusivity associated with mixed layer turbulence radiation [Z2 s-1 ~> m2 s-1]. real :: C1_6 ! 1/6 - real :: Omega2 ! rotation rate squared (1/s2) - real :: z1 ! layer thickness times I_decay (nondim) - real :: dzL ! thickness converted to Z + real :: Omega2 ! rotation rate squared [s-2]. + real :: z1 ! layer thickness times I_decay [nondim] + real :: dzL ! thickness converted to heights [Z ~> m]. real :: I_decay_len2_TKE ! squared inverse decay lengthscale for - ! TKE, as used in the mixed layer code (1/Z2) - real :: h_neglect ! negligibly small thickness (Z) + ! TKE, as used in the mixed layer code [Z-2 ~> m-2]. + real :: h_neglect ! negligibly small thickness [Z ~> m]. logical :: do_any, do_i(SZI_(G)) integer :: i, k, is, ie, nz, kml @@ -1660,11 +1662,11 @@ subroutine set_BBL_TKE(u, v, h, fluxes, visc, G, GV, US, CS) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1 + intent(in) :: u !< The zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1 + intent(in) :: v !< The meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(forcing), intent(in) :: fluxes !< A structure of thermodynamic surface fluxes type(vertvisc_type), intent(in) :: visc !< Structure containing vertical viscosities, bottom !! boundary layer properies, and related fields. @@ -1675,21 +1677,21 @@ subroutine set_BBL_TKE(u, v, h, fluxes, visc, G, GV, US, CS) real, dimension(SZI_(G)) :: & htot ! total thickness above or below a layer, or the - ! integrated thickness in the BBL (Z) + ! integrated thickness in the BBL [Z ~> m]. real, dimension(SZIB_(G)) :: & - uhtot, & ! running integral of u in the BBL (Z m/s) - ustar, & ! bottom boundary layer turbulence speed (Z/s) - u2_bbl ! square of the mean zonal velocity in the BBL (m2/s2) + uhtot, & ! running integral of u in the BBL [Z m s-1 ~> m2 s-1] + ustar, & ! bottom boundary layer turbulence speed [Z s-1 ~> m s-1]. + u2_bbl ! square of the mean zonal velocity in the BBL [m2 s-2] - real :: vhtot(SZI_(G)) ! running integral of v in the BBL (Z m/sec) + real :: vhtot(SZI_(G)) ! running integral of v in the BBL [Z m s-1 ~> m2 s-1] real, dimension(SZI_(G),SZJB_(G)) :: & - vstar, & ! ustar at at v-points (Z/s) - v2_bbl ! square of average meridional velocity in BBL (m2/s2) + vstar, & ! ustar at at v-points [Z s-1 ~> m s-1]. + v2_bbl ! square of average meridional velocity in BBL [m2 s-2] - real :: cdrag_sqrt ! square root of the drag coefficient (nondim) - real :: hvel ! thickness at velocity points (Z) + real :: cdrag_sqrt ! square root of the drag coefficient [nondim] + real :: hvel ! thickness at velocity points [Z ~> m]. logical :: domore, do_i(SZI_(G)) integer :: i, j, k, is, ie, js, je, nz @@ -1796,8 +1798,7 @@ subroutine set_density_ratios(h, tv, kb, G, GV, CS, j, ds_dsp1, rho_0) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m - !! or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< Structure containing pointers to any !! available thermodynamic fields; absent !! fields have NULL ptrs. @@ -1809,31 +1810,18 @@ subroutine set_density_ratios(h, tv, kb, G, GV, CS, j, ds_dsp1, rho_0) real, dimension(SZI_(G),SZK_(G)), intent(out) :: ds_dsp1 !< Coordinate variable (sigma-2) !! difference across an interface divided by !! the difference across the interface below - !! it (nondimensional) + !! it [nondim] real, dimension(SZI_(G),SZK_(G)), & optional, intent(in) :: rho_0 !< Layer potential densities relative to - !! surface press (kg/m3). - -! Arguments: -! (in) h - layer thickness (meter) -! (in) tv - structure containing pointers to any available -! thermodynamic fields; absent fields have NULL ptrs -! (in) kb - index of lightest layer denser than the buffer layer -! (in) G - ocean grid structure -! (in) GV - The ocean's vertical grid structure. -! (in) CS - control structure returned by previous call to diabatic_entrain_init -! (in) j - meridional index upon which to work -! (in) ds_dsp1 - coordinate variable (sigma-2) difference across an -! interface divided by the difference across the interface -! below it (nondimensional) -! (in) rho_0 - layer potential densities relative to surface press (kg/m3) - - real :: g_R0 ! g_R0 is g/Rho (m5 Z-1 kg-1 s-2) + !! surface press [kg m-3]. + + ! Local variables + real :: g_R0 ! g_R0 is g/Rho [m5 Z-1 kg-1 s-2 ~> m4 kg-1 s-2] real :: eps, tmp ! nondimensional temproray variables real :: a(SZK_(G)), a_0(SZK_(G)) ! nondimensional temporary variables real :: p_ref(SZI_(G)) ! an array of tv%P_Ref pressures - real :: Rcv(SZI_(G),SZK_(G)) ! coordinate density in the mixed and buffer layers (kg/m3) - real :: I_Drho ! temporary variable (m3/kg) + real :: Rcv(SZI_(G),SZK_(G)) ! coordinate density in the mixed and buffer layers [kg m-3] + real :: I_Drho ! temporary variable [m3 kg-1] integer :: i, k, k3, is, ie, nz, kmb is = G%isc ; ie = G%iec ; nz = G%ke diff --git a/src/parameterizations/vertical/MOM_set_viscosity.F90 b/src/parameterizations/vertical/MOM_set_viscosity.F90 index cb80ebb0c0..7eba2fbac0 100644 --- a/src/parameterizations/vertical/MOM_set_viscosity.F90 +++ b/src/parameterizations/vertical/MOM_set_viscosity.F90 @@ -34,24 +34,27 @@ module MOM_set_visc public set_viscous_BBL, set_viscous_ML, set_visc_init, set_visc_end public set_visc_register_restarts +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for MOM_set_visc type, public :: set_visc_CS ; private - real :: Hbbl !< The static bottom boundary layer thickness, in - !! the same units as thickness (m or kg m-2). + real :: Hbbl !< The static bottom boundary layer thickness [H ~> m or kg m-2] real :: cdrag !< The quadratic drag coefficient. real :: c_Smag !< The Laplacian Smagorinsky coefficient for !! calculating the drag in channels. real :: drag_bg_vel !< An assumed unresolved background velocity for - !! calculating the bottom drag, in m s-1. - real :: BBL_thick_min !< The minimum bottom boundary layer thickness in - !! the same units as thickness (H, often m or kg m-2). + !! calculating the bottom drag [m s-1]. + real :: BBL_thick_min !< The minimum bottom boundary layer thickness [H ~> m or kg m-2]. !! This might be Kv / (cdrag * drag_bg_vel) to give !! Kv as the minimum near-bottom viscosity. real :: Htbl_shelf !< A nominal thickness of the surface boundary layer for use - !! in calculating the near-surface velocity, in units of H. - real :: Htbl_shelf_min !< The minimum surface boundary layer thickness in H. - real :: KV_BBL_min !< The minimum viscosity in the bottom boundary layer, in Z2 s-1. - real :: KV_TBL_min !< The minimum viscosity in the top boundary layer, in Z2 s-1. + !! in calculating the near-surface velocity [H ~> m or kg m-2]. + real :: Htbl_shelf_min !< The minimum surface boundary layer thickness [H ~> m or kg m-2]. + real :: KV_BBL_min !< The minimum viscosity in the bottom boundary layer [Z2 s-1 ~> m2 s-1]. + real :: KV_TBL_min !< The minimum viscosity in the top boundary layer [Z2 s-1 ~> m2 s-1]. logical :: bottomdraglaw !< If true, the bottom stress is calculated with a !! drag law c_drag*|u|*u. The velocity magnitude !! may be an assumed value or it may be based on the @@ -68,9 +71,9 @@ module MOM_set_visc !! determine the mixed layer thickness for viscosity. real :: bulk_Ri_ML !< The bulk mixed layer used to determine the !! thickness of the viscous mixed layer. Nondim. - real :: omega !< The Earth's rotation rate, in s-1. + real :: omega !< The Earth's rotation rate [s-1]. real :: ustar_min !< A minimum value of ustar to avoid numerical - !! problems, in Z s-1. If the value is small enough, + !! problems [Z s-1 ~> m s-1]. If the value is small enough, !! this should not affect the solution. real :: TKE_decay !< The ratio of the natural Ekman depth to the TKE !! decay scale, nondimensional. @@ -104,11 +107,11 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, symmetrize) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any !! available thermodynamic fields. Absent fields !! have NULL ptrs.. @@ -122,134 +125,133 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, symmetrize) ! Local variables real, dimension(SZIB_(G)) :: & - ustar, & ! The bottom friction velocity, in m s-1. + ustar, & ! The bottom friction velocity [Z s-1 ~> m s-1]. T_EOS, & ! The temperature used to calculate the partial derivatives - ! of density with T and S, in deg C. + ! of density with T and S [degC]. S_EOS, & ! The salinity used to calculate the partial derivatives - ! of density with T and S, in PSU. + ! of density with T and S [ppt]. dR_dT, & ! Partial derivative of the density in the bottom boundary - ! layer with temperature, in units of kg m-3 K-1. + ! layer with temperature [kg m-3 degC-1]. dR_dS, & ! Partial derivative of the density in the bottom boundary - ! layer with salinity, in units of kg m-3 psu-1. - press ! The pressure at which dR_dT and dR_dS are evaluated, in Pa. - real :: htot ! Sum of the layer thicknesses up to some - ! point, in H (i.e., m or kg m-2). - real :: htot_vel ! Sum of the layer thicknesses up to some - ! point, in H (i.e., m or kg m-2). - - real :: Rhtot ! Running sum of thicknesses times the - ! layer potential densities in H kg m-3. + ! layer with salinity [kg m-3 ppt-1]. + press ! The pressure at which dR_dT and dR_dS are evaluated [Pa]. + real :: htot ! Sum of the layer thicknesses up to some point [H ~> m or kg m-2]. + real :: htot_vel ! Sum of the layer thicknesses up to some point [H ~> m or kg m-2]. + + real :: Rhtot ! Running sum of thicknesses times the layer potential + ! densities [H kg m-3 ~> kg m-2 or kg2 m-5]. real, dimension(SZIB_(G),SZJ_(G)) :: & - D_u, & ! Bottom depth interpolated to u points, in depth units (m). + D_u, & ! Bottom depth interpolated to u points [Z ~> m]. mask_u ! A mask that disables any contributions from u points that - ! are land or past open boundary conditions, nondim., 0 or 1. + ! are land or past open boundary conditions [nondim], 0 or 1. real, dimension(SZI_(G),SZJB_(G)) :: & - D_v, & ! Bottom depth interpolated to v points, in depth units (m). + D_v, & ! Bottom depth interpolated to v points [Z ~> m]. mask_v ! A mask that disables any contributions from v points that - ! are land or past open boundary conditions, nondim., 0 or 1. + ! are land or past open boundary conditions [nondim], 0 or 1. real, dimension(SZIB_(G),SZK_(G)) :: & h_at_vel, & ! Layer thickness at a velocity point, using an upwind-biased ! second order accurate estimate based on the previous velocity - ! direction, in H. + ! direction [H ~> m or kg m-2]. h_vel, & ! Arithmetic mean of the layer thicknesses adjacent to a - ! velocity point, in H. + ! velocity point [H ~> m or kg m-2]. T_vel, & ! Arithmetic mean of the layer temperatures adjacent to a - ! velocity point, in deg C. + ! velocity point [degC]. S_vel, & ! Arithmetic mean of the layer salinities adjacent to a - ! velocity point, in PSU. + ! velocity point [ppt]. Rml_vel ! Arithmetic mean of the layer coordinate densities adjacent - ! to a velocity point, in kg m-3. + ! to a velocity point [kg m-3]. real :: h_vel_pos ! The arithmetic mean thickness at a velocity point - ! plus H_neglect to avoid 0 values, in H. + ! plus H_neglect to avoid 0 values [H ~> m or kg m-2]. real :: ustarsq ! 400 times the square of ustar, times ! Rho0 divided by G_Earth and the conversion - ! from m to thickness units, in kg m-2 or kg2 m-5. + ! from m to thickness units [H kg m-3 ~> kg m-2 or kg2 m-5]. real :: cdrag_sqrt_Z ! Square root of the drag coefficient, times a unit conversion - ! factor from lateral lengths to vertical depths, in Z m-1. - real :: cdrag_sqrt ! Square root of the drag coefficient, nd. + ! factor from lateral lengths to vertical depths [Z m-1 ~> 1]. + real :: cdrag_sqrt ! Square root of the drag coefficient [nondim]. real :: oldfn ! The integrated energy required to ! entrain up to the bottom of the layer, - ! divided by G_Earth, in H kg m-3. + ! divided by G_Earth [H kg m-3 ~> kg m-2 or kg2 m-5]. real :: Dfn ! The increment in oldfn for entraining - ! the layer, in H kg m-3. + ! the layer [H kg m-3 ~> kg m-2 or kg2 m-5]. real :: Dh ! The increment in layer thickness from - ! the present layer, in H. - real :: bbl_thick ! The thickness of the bottom boundary layer in H. - real :: bbl_thick_Z ! The thickness of the bottom boundary layer in Z. + ! the present layer [H ~> m or kg m-2]. + real :: bbl_thick ! The thickness of the bottom boundary layer [H ~> m or kg m-2]. + real :: bbl_thick_Z ! The thickness of the bottom boundary layer [Z ~> m]. real :: C2f ! C2f = 2*f at velocity points. real :: U_bg_sq ! The square of an assumed background ! velocity, for calculating the mean ! magnitude near the bottom for use in the - ! quadratic bottom drag, in m2 s-2. + ! quadratic bottom drag [m2 s-2]. real :: hwtot ! Sum of the thicknesses used to calculate - ! the near-bottom velocity magnitude, in H. + ! the near-bottom velocity magnitude [H ~> m or kg m-2]. real :: hutot ! Running sum of thicknesses times the - ! velocity magnitudes, in H m s-1. - real :: Thtot ! Running sum of thickness times temperature, in H C. - real :: Shtot ! Running sum of thickness times salinity, in H psu. + ! velocity magnitudes [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + real :: Thtot ! Running sum of thickness times temperature [degC H ~> degC m or degC kg m-2]. + real :: Shtot ! Running sum of thickness times salinity [ppt H ~> ppt m or ppt kg m-2]. real :: hweight ! The thickness of a layer that is within Hbbl - ! of the bottom, in H. - real :: v_at_u, u_at_v ! v at a u point or vice versa, m s-1. - real :: Rho0x400_G ! 400*Rho0/G_Earth, times unit conversion factors, in kg s2 H m-3 Z-2. + ! of the bottom [H ~> m or kg m-2]. + real :: v_at_u, u_at_v ! v at a u point or vice versa [m s-1]. + real :: Rho0x400_G ! 400*Rho0/G_Earth, times unit conversion factors + ! [kg s2 H m-3 Z-2 ~> kg s2 m-4 or kg2 s2 m-7]. ! The 400 is a constant proposed by Killworth and Edwards, 1999. real, dimension(SZI_(G),SZJ_(G),max(GV%nk_rho_varies,1)) :: & - Rml ! The mixed layer coordinate density, in kg m-3. + Rml ! The mixed layer coordinate density [kg m-3]. real :: p_ref(SZI_(G)) ! The pressure used to calculate the coordinate - ! density, in Pa (usually set to 2e7 Pa = 2000 dbar). + ! density [Pa] (usually set to 2e7 Pa = 2000 dbar). - ! The units H in the following are thickness units - typically m or kg m-2. - real :: D_vel ! The bottom depth at a velocity point, in H. - real :: Dp, Dm ! The depths at the edges of a velocity cell, in H. + real :: D_vel ! The bottom depth at a velocity point [H ~> m or kg m-2]. + real :: Dp, Dm ! The depths at the edges of a velocity cell [H ~> m or kg m-2]. real :: a ! a is the curvature of the bottom depth across a - ! cell, times the cell width squared, in H. - real :: a_3, a_12, C24_a ! a/3, a/12, and 24/a, in H, H, and H-1. + ! cell, times the cell width squared [H ~> m or kg m-2]. + real :: a_3, a_12 ! a/3 and a/12 [H ~> m or kg m-2]. + real :: C24_a ! 24/a [H-1 ~> m-1 or m2 kg-1]. real :: slope ! The absolute value of the bottom depth slope across - ! a cell times the cell width, in H. + ! a cell times the cell width [H ~> m or kg m-2]. real :: apb_4a, ax2_3apb ! Various nondimensional ratios of a and slope. - real :: a2x48_apb3, Iapb, Ibma_2 ! Combinations of a and slope with units of H-1. - ! All of the following "volumes" have units of meters as they are normalized + real :: a2x48_apb3, Iapb, Ibma_2 ! Combinations of a and slope [H-1 ~> m-1 or m2 kg-1]. + ! All of the following "volumes" have units of thickness because they are normalized ! by the full horizontal area of a velocity cell. - real :: Vol_open ! The cell volume above which it is open, in H. - real :: Vol_direct ! With less than Vol_direct (in H), there is a direct + real :: Vol_open ! The cell volume above which it is open [H ~> m or kg m-2]. + real :: Vol_direct ! With less than Vol_direct [H ~> m or kg m-2], there is a direct ! solution of a cubic equation for L. real :: Vol_2_reg ! The cell volume above which there are two separate - ! open areas that must be integrated, in H. + ! open areas that must be integrated [H ~> m or kg m-2]. real :: vol ! The volume below the interface whose normalized - ! width is being sought, in H. + ! width is being sought [H ~> m or kg m-2]. real :: vol_below ! The volume below the interface below the one that - ! is currently under consideration, in H. + ! is currently under consideration [H ~> m or kg m-2]. real :: Vol_err ! The error in the volume with the latest estimate of - ! L, or the error for the interface below, in H. - real :: Vol_quit ! The volume error below which to quit iterating, in H. - real :: Vol_tol ! A volume error tolerance, in H. + ! L, or the error for the interface below [H ~> m or kg m-2]. + real :: Vol_quit ! The volume error below which to quit iterating [H ~> m or kg m-2]. + real :: Vol_tol ! A volume error tolerance [H ~> m or kg m-2]. real :: L(SZK_(G)+1) ! The fraction of the full cell width that is open at ! the depth of each interface, nondimensional. - real :: L_direct ! The value of L above volume Vol_direct, nondim. + real :: L_direct ! The value of L above volume Vol_direct [nondim]. real :: L_max, L_min ! Upper and lower bounds on the correct value for L. real :: Vol_err_max ! The volume errors for the upper and lower bounds on - real :: Vol_err_min ! the correct value for L, in H. - real :: Vol_0 ! A deeper volume with known width L0, in H. - real :: L0 ! The value of L above volume Vol_0, nondim. - real :: dVol ! vol - Vol_0, in H. + real :: Vol_err_min ! the correct value for L [H ~> m or kg m-2]. + real :: Vol_0 ! A deeper volume with known width L0 [H ~> m or kg m-2]. + real :: L0 ! The value of L above volume Vol_0 [nondim]. + real :: dVol ! vol - Vol_0 [H ~> m or kg m-2]. real :: dV_dL2 ! The partial derivative of volume with L squared - ! evaluated at L=L0, in H. + ! evaluated at L=L0 [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: ustH ! ustar converted to units of H s-1. - real :: root ! A temporary variable with units of H s-1. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: ustH ! ustar converted to units of H s-1 [H s-1 ~> m s-1 or kg m-2 s-1]. + real :: root ! A temporary variable [H s-1 ~> m s-1 or kg m-2 s-1]. - real :: Cell_width ! The transverse width of the velocity cell, in m. + real :: Cell_width ! The transverse width of the velocity cell [m]. real :: Rayleigh ! A nondimensional value that is multiplied by the layer's - ! velocity magnitude to give the Rayleigh drag velocity, - ! times a lateral to vertical distance conversion factor, in Z L-1. + ! velocity magnitude to give the Rayleigh drag velocity, times + ! a lateral to vertical distance conversion factor [Z L-1 ~> 1]. real :: gam ! The ratio of the change in the open interface width - ! to the open interface width atop a cell, nondim. + ! to the open interface width atop a cell [nondim]. real :: BBL_frac ! The fraction of a layer's drag that goes into the - ! viscous bottom boundary layer, nondim. + ! viscous bottom boundary layer [nondim]. real :: BBL_visc_frac ! The fraction of all the drag that is expressed as - ! a viscous bottom boundary layer, nondim. + ! a viscous bottom boundary layer [nondim]. real, parameter :: C1_3 = 1.0/3.0, C1_6 = 1.0/6.0, C1_12 = 1.0/12.0 real :: C2pi_3 ! An irrational constant, 2/3 pi. real :: tmp ! A temporary variable. @@ -906,20 +908,20 @@ end subroutine set_viscous_BBL function set_v_at_u(v, h, G, i, j, k, mask2dCv, OBC) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1 + intent(in) :: v !< The meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] integer, intent(in) :: i !< The i-index of the u-location to work on. integer, intent(in) :: j !< The j-index of the u-location to work on. integer, intent(in) :: k !< The k-index of the u-location to work on. real, dimension(SZI_(G),SZJB_(G)),& intent(in) :: mask2dCv !< A multiplicative mask of the v-points type(ocean_OBC_type), pointer :: OBC !< A pointer to an open boundary condition structure - real :: set_v_at_u !< The retur value of v at u points, in m s-1. + real :: set_v_at_u !< The retur value of v at u points [m s-1]. ! This subroutine finds a thickness-weighted value of v at the u-points. - real :: hwt(0:1,-1:0) ! Masked weights used to average u onto v, in H. - real :: hwt_tot ! The sum of the masked thicknesses, in H. + real :: hwt(0:1,-1:0) ! Masked weights used to average u onto v [H ~> m or kg m-2]. + real :: hwt_tot ! The sum of the masked thicknesses [H ~> m or kg m-2]. integer :: i0, j0, i1, j1 do j0 = -1,0 ; do i0 = 0,1 ; i1 = i+i0 ; J1 = J+j0 @@ -949,20 +951,20 @@ end function set_v_at_u function set_u_at_v(u, h, G, i, j, k, mask2dCu, OBC) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1 + intent(in) :: u !< The zonal velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] integer, intent(in) :: i !< The i-index of the u-location to work on. integer, intent(in) :: j !< The j-index of the u-location to work on. integer, intent(in) :: k !< The k-index of the u-location to work on. real, dimension(SZIB_(G),SZJ_(G)), & intent(in) :: mask2dCu !< A multiplicative mask of the u-points type(ocean_OBC_type), pointer :: OBC !< A pointer to an open boundary condition structure - real :: set_u_at_v !< The return value of u at v points, in m s-1. + real :: set_u_at_v !< The return value of u at v points [m s-1]. ! This subroutine finds a thickness-weighted value of u at the v-points. - real :: hwt(-1:0,0:1) ! Masked weights used to average u onto v, in H. - real :: hwt_tot ! The sum of the masked thicknesses, in H. + real :: hwt(-1:0,0:1) ! Masked weights used to average u onto v [H ~> m or kg m-2]. + real :: hwt_tot ! The sum of the masked thicknesses [H ~> m or kg m-2]. integer :: i0, j0, i1, j1 do j0 = 0,1 ; do i0 = -1,0 ; I1 = I+i0 ; j1 = j+j0 @@ -998,18 +1000,18 @@ subroutine set_viscous_ML(u, v, h, tv, forces, visc, dt, G, GV, US, CS, symmetri type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: u !< The zonal velocity, in m s-1. + intent(in) :: u !< The zonal velocity [m s-1]. real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: v !< The meridional velocity, in m s-1. + intent(in) :: v !< The meridional velocity [m s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any available !! thermodynamic fields. Absent fields have !! NULL ptrs. type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical viscosities and !! related fields. - real, intent(in) :: dt !< Time increment in s. + real, intent(in) :: dt !< Time increment [s]. type(set_visc_CS), pointer :: CS !< The control structure returned by a previous !! call to vertvisc_init. logical, optional, intent(in) :: symmetrize !< If present and true, do extra calculations @@ -1018,97 +1020,95 @@ subroutine set_viscous_ML(u, v, h, tv, forces, visc, dt, G, GV, US, CS, symmetri ! Local variables real, dimension(SZIB_(G)) :: & htot, & ! The total depth of the layers being that are within the - ! surface mixed layer, in H. + ! surface mixed layer [H ~> m or kg m-2]. Thtot, & ! The integrated temperature of layers that are within the - ! surface mixed layer, in H degC. + ! surface mixed layer [H degC ~> m degC or kg degC m-2]. Shtot, & ! The integrated salt of layers that are within the - ! surface mixed layer H PSU. - Rhtot, & ! The integrated density of layers that are within the - ! surface mixed layer, in H kg m-3. Rhtot is only used if no + ! surface mixed layer [H ppt ~> m ppt or kg ppt m-2]. + Rhtot, & ! The integrated density of layers that are within the surface mixed layer + ! [H kg m-3 ~> kg m-2 or kg2 m-5]. Rhtot is only used if no ! equation of state is used. uhtot, & ! The depth integrated zonal and meridional velocities within - vhtot, & ! the surface mixed layer, in H m s-1. - Idecay_len_TKE, & ! The inverse of a turbulence decay length scale, in H-1. + vhtot, & ! the surface mixed layer [H m s-1 ~> m2 s-1 or kg m-1 s-1]. + Idecay_len_TKE, & ! The inverse of a turbulence decay length scale [H-1 ~> m-1 or m2 kg-1]. dR_dT, & ! Partial derivative of the density at the base of layer nkml - ! (roughly the base of the mixed layer) with temperature, in - ! units of kg m-3 K-1. + ! (roughly the base of the mixed layer) with temperature [kg m-3 degC-1]. dR_dS, & ! Partial derivative of the density at the base of layer nkml - ! (roughly the base of the mixed layer) with salinity, in units - ! of kg m-3 psu-1. - ustar, & ! The surface friction velocity under ice shelves, in Z s-1. - press, & ! The pressure at which dR_dT and dR_dS are evaluated, in Pa. - T_EOS, & ! T_EOS and S_EOS are the potential temperature and salnity at which dR_dT and dR_dS - S_EOS ! which dR_dT and dR_dS are evaluated, in degC and PSU. + ! (roughly the base of the mixed layer) with salinity [kg m-3 ppt-1]. + ustar, & ! The surface friction velocity under ice shelves [Z s-1 ~> m s-1]. + press, & ! The pressure at which dR_dT and dR_dS are evaluated [Pa]. + T_EOS, & ! The potential temperature at which dR_dT and dR_dS are evaluated [degC] + S_EOS ! The salinity at which dR_dT and dR_dS are evaluated [ppt]. real, dimension(SZIB_(G),SZJ_(G)) :: & mask_u ! A mask that disables any contributions from u points that - ! are land or past open boundary conditions, nondim., 0 or 1. + ! are land or past open boundary conditions [nondim], 0 or 1. real, dimension(SZI_(G),SZJB_(G)) :: & mask_v ! A mask that disables any contributions from v points that - ! are land or past open boundary conditions, nondim., 0 or 1. + ! are land or past open boundary conditions [nondim], 0 or 1. real :: h_at_vel(SZIB_(G),SZK_(G))! Layer thickness at velocity points, ! using an upwind-biased second order accurate estimate based - ! on the previous velocity direction, in H. + ! on the previous velocity direction [H ~> m or kg m-2]. integer :: k_massive(SZIB_(G)) ! The k-index of the deepest layer yet found ! that has more than h_tiny thickness and will be in the ! viscous mixed layer. real :: Uh2 ! The squared magnitude of the difference between the velocity ! integrated through the mixed layer and the velocity of the - ! interior layer layer times the depth of the the mixed layer, - ! in H2 m2 s-2. - real :: htot_vel ! Sum of the layer thicknesses up to some - ! point, in H (i.e., m or kg m-2). + ! interior layer layer times the depth of the the mixed layer + ! [H2 m2 s-2 ~> m4 s-2 or kg2 m-2 s-2]. + real :: htot_vel ! Sum of the layer thicknesses up to some point [H ~> m or kg m-2]. real :: hwtot ! Sum of the thicknesses used to calculate - ! the near-bottom velocity magnitude, in H. + ! the near-bottom velocity magnitude [H ~> m or kg m-2]. real :: hutot ! Running sum of thicknesses times the - ! velocity magnitudes, in H m s-1. + ! velocity magnitudes [H m s-1 ~> m2 s-1 or kg m-1 s-1]. real :: hweight ! The thickness of a layer that is within Hbbl - ! of the bottom, in H. - real :: tbl_thick_Z ! The thickness of the top boundary layer in Z. - - real :: hlay ! The layer thickness at velocity points, in H. - real :: I_2hlay ! 1 / 2*hlay, in H-1. - real :: T_lay ! The layer temperature at velocity points, in deg C. - real :: S_lay ! The layer salinity at velocity points, in PSU. - real :: Rlay ! The layer potential density at velocity points, in kg m-3. - real :: Rlb ! The potential density of the layer below, in kg m-3. - real :: v_at_u ! The meridonal velocity at a zonal velocity point in m s-1. - real :: u_at_v ! The zonal velocity at a meridonal velocity point in m s-1. + ! of the bottom [H ~> m or kg m-2]. + real :: tbl_thick_Z ! The thickness of the top boundary layer [Z ~> m]. + + real :: hlay ! The layer thickness at velocity points [H ~> m or kg m-2]. + real :: I_2hlay ! 1 / 2*hlay [H-1 ~> m-1 or m2 kg-1]. + real :: T_lay ! The layer temperature at velocity points [degC]. + real :: S_lay ! The layer salinity at velocity points [ppt]. + real :: Rlay ! The layer potential density at velocity points [kg m-3]. + real :: Rlb ! The potential density of the layer below [kg m-3]. + real :: v_at_u ! The meridonal velocity at a zonal velocity point [m s-1]. + real :: u_at_v ! The zonal velocity at a meridonal velocity point [m s-1]. real :: gHprime ! The mixed-layer internal gravity wave speed squared, based ! on the mixed layer thickness and density difference across - ! the base of the mixed layer, in m2 s-2. + ! the base of the mixed layer [m2 s-2]. real :: RiBulk ! The bulk Richardson number below which water is in the ! viscous mixed layer, including reduction for turbulent ! decay. Nondimensional. real :: dt_Rho0 ! The time step divided by the conversion from the layer - ! thickness to layer mass, in s H m2 kg-1. - real :: g_H_Rho0 ! The gravitational acceleration times the conversion from - ! H to m divided by the mean density, in m5 s-2 H-1 kg-1. + ! thickness to layer mass [s H m2 kg-1 ~> s m3 kg-1 or s]. + real :: g_H_Rho0 ! The gravitational acceleration times the conversion from H to m divided + ! by the mean density [m5 s-2 H-1 kg-1 ~> m4 s-2 kg-1 or m7 s-2 kg-2]. real :: ustarsq ! 400 times the square of ustar, times ! Rho0 divided by G_Earth and the conversion - ! from m to thickness units, in kg m-2 or kg2 m-5. + ! from m to thickness units [H kg m-3 ~> kg m-2 or kg2 m-5]. real :: cdrag_sqrt_Z ! Square root of the drag coefficient, times a unit conversion - ! factor from lateral lengths to vertical depths, in Z m-1. - real :: cdrag_sqrt ! Square root of the drag coefficient, ND. + ! factor from lateral lengths to vertical depths [Z m-1 ~> 1]. + real :: cdrag_sqrt ! Square root of the drag coefficient [nondim]. real :: oldfn ! The integrated energy required to ! entrain up to the bottom of the layer, - ! divided by G_Earth, in H kg m-3. + ! divided by G_Earth [H kg m-3 ~> kg m-2 or kg2 m-5]. real :: Dfn ! The increment in oldfn for entraining - ! the layer, in H kg m-3. + ! the layer [H kg m-3 ~> kg m-2 or kg2 m-5]. real :: Dh ! The increment in layer thickness from - ! the present layer, in H. + ! the present layer [H ~> m or kg m-2]. real :: U_bg_sq ! The square of an assumed background velocity, for ! calculating the mean magnitude near the top for use in - ! the quadratic surface drag, in m2. - real :: h_tiny ! A very small thickness, in H. Layers that are less than + ! the quadratic surface drag [m2 s-2]. + real :: h_tiny ! A very small thickness [H ~> m or kg m-2]. Layers that are less than ! h_tiny can not be the deepest in the viscous mixed layer. real :: absf ! The absolute value of f averaged to velocity points, s-1. - real :: U_star ! The friction velocity at velocity points, in Z s-1. + real :: U_star ! The friction velocity at velocity points [Z s-1 ~> m s-1]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: Rho0x400_G ! 400*Rho0/G_Earth, times unit conversion factors, in kg s2 H m-3 Z-2. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: Rho0x400_G ! 400*Rho0/G_Earth, times unit conversion factors + ! [kg s2 H m-3 Z-2 ~> kg s2 m-4 or kg2 s2 m-7]. ! The 400 is a constant proposed by Killworth and Edwards, 1999. - real :: ustar1 ! ustar in units of H/s - real :: h2f2 ! (h*2*f)^2 + real :: ustar1 ! ustar [H s-1 ~> m s-1 or kg m-2 s-1] + real :: h2f2 ! (h*2*f)^2 [H2 s-2 ~> m2 s-2 or kg2 m-4 s-2] logical :: use_EOS, do_any, do_any_shelf, do_i(SZIB_(G)) integer :: i, j, k, is, ie, js, je, Isq, Ieq, Jsq, Jeq, nz, K2, nkmb, nkml, n type(ocean_OBC_type), pointer :: OBC => NULL() @@ -1683,7 +1683,7 @@ subroutine set_visc_register_restarts(HI, GV, param_file, visc, restart_CS) logical :: adiabatic, useKPP, useEPBL logical :: use_CVMix_shear, MLE_use_PBL_MLD, use_CVMix_conv integer :: isd, ied, jsd, jed, nz - real :: hfreeze !< If hfreeze > 0 (m), melt potential will be computed. + real :: hfreeze !< If hfreeze > 0 [m], melt potential will be computed. character(len=40) :: mdl = "MOM_set_visc" ! This module's name. isd = HI%isd ; ied = HI%ied ; jsd = HI%jsd ; jed = HI%jed ; nz = GV%ke diff --git a/src/parameterizations/vertical/MOM_shortwave_abs.F90 b/src/parameterizations/vertical/MOM_shortwave_abs.F90 index 410a41583a..cf0da1c5f3 100644 --- a/src/parameterizations/vertical/MOM_shortwave_abs.F90 +++ b/src/parameterizations/vertical/MOM_shortwave_abs.F90 @@ -20,16 +20,16 @@ module MOM_shortwave_abs integer :: nbands !< number of penetrating bands of SW radiation - real, pointer, dimension(:,:,:,:) :: opacity_band => NULL() !< SW optical depth per unit thickness (1/m) + real, pointer, dimension(:,:,:,:) :: opacity_band => NULL() !< SW optical depth per unit thickness [m-1] !! The number of radiation bands is most rapidly varying (first) index. - real, pointer, dimension(:,:,:) :: SW_pen_band => NULL() !< shortwave radiation (W/m^2) at the surface + real, pointer, dimension(:,:,:) :: SW_pen_band => NULL() !< shortwave radiation [W m-2] at the surface !! in each of the nbands bands that penetrates beyond the surface. !! The most rapidly varying dimension is the band. real, pointer, dimension(:) :: & - min_wavelength_band => NULL(), & !< The minimum wavelength in each band of penetrating shortwave radiation (nm) - max_wavelength_band => NULL() !< The maximum wavelength in each band of penetrating shortwave radiation (nm) + min_wavelength_band => NULL(), & !< The minimum wavelength in each band of penetrating shortwave radiation [nm] + max_wavelength_band => NULL() !< The maximum wavelength in each band of penetrating shortwave radiation [nm] end type optics_type @@ -48,21 +48,20 @@ subroutine absorbRemainingSW(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or - !! kg m-2). - real, dimension(:,:,:), intent(in) :: opacity_band !< Opacity in each band of - !! penetrating shortwave radiation (1/H). + real, dimension(SZI_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. + real, dimension(:,:,:), intent(in) :: opacity_band !< Opacity in each band of penetrating + !! shortwave radiation [H-1 ~> m-1 or m2 kg-1]. !! The indicies are band, i, k. integer, intent(in) :: nsw !< Number of bands of penetrating !! shortwave radiation. integer, intent(in) :: j !< j-index to work on. - real, intent(in) :: dt !< Time step (seconds). + real, intent(in) :: dt !< Time step [s]. real, intent(in) :: H_limit_fluxes !< If the total ocean depth is !! less than this, they are scaled away - !! to avoid numerical instabilities. (H) - !! This would not be necessary if a - !! finite heat capacity mud-layer - !! were added. + !! to avoid numerical instabilities + !! [H ~> m or kg m-2]. This would + !! not be necessary if a finite heat + !! capacity mud-layer were added. logical, intent(in) :: adjustAbsorptionProfile !< If true, apply !! heating above the layers in which it !! should have occurred to get the @@ -76,27 +75,27 @@ subroutine absorbRemainingSW(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, !! shortwave that should be absorbed by !! each layer. real, dimension(SZI_(G),SZK_(G)), intent(inout) :: T !< Layer potential/conservative - !! temperatures (deg C) + !! temperatures [degC] real, dimension(:,:), intent(inout) :: Pen_SW_bnd !< Penetrating shortwave heating in - !! each band that hits the bottom and - !! will be redistributed through the - !! water column (units of K*H), size - !! nsw x SZI_(G). + !! each band that hits the bottom and will + !! will be redistributed through the water + !! column [degC H ~> degC m or degC kg m-2], + !! size nsw x SZI_(G). real, dimension(SZI_(G),SZK_(G)), optional, intent(in) :: eps !< Small thickness that must remain in !! each layer, and which will not be - !! subject to heating (units of H) + !! subject to heating [H ~> m or kg m-2] integer, dimension(SZI_(G),SZK_(G)), optional, intent(in) :: ksort !< Density-sorted k-indicies. - real, dimension(SZI_(G)), optional, intent(in) :: htot !< Total mixed layer thickness, in H . + real, dimension(SZI_(G)), optional, intent(in) :: htot !< Total mixed layer thickness [H ~> m or kg m-2]. real, dimension(SZI_(G)), optional, intent(inout) :: Ttot !< Depth integrated mixed layer - !! temperature (units of K H). + !! temperature [degC H ~> degC m or degC kg m-2] real, dimension(SZI_(G),SZK_(G)), optional, intent(in) :: dSV_dT !< The partial derivative of specific - !! volume with temperature, in m3 kg-1 K-1. + !! volume with temperature [m3 kg-1 degC-1]. real, dimension(SZI_(G),SZK_(G)), optional, intent(inout) :: TKE !< The TKE sink from mixing the heating - !! throughout a layer, in J m-2. + !! throughout a layer [J m-2]. ! Local variables real, dimension(SZI_(G),SZK_(G)) :: & T_chg_above ! A temperature change that will be applied to all the thick - ! layers above a given layer, in K. This is only nonzero if + ! layers above a given layer [degC]. This is only nonzero if ! adjustAbsorptionProfile is true, in which case the net ! change in the temperature of a layer is the sum of the ! direct heating of that layer plus T_chg_above from all of @@ -104,33 +103,33 @@ subroutine absorbRemainingSW(G, GV, h, opacity_band, nsw, j, dt, H_limit_fluxes, ! radiation that hits the bottom. real, dimension(SZI_(G)) :: & h_heat, & ! The thickness of the water column that will be heated by - ! any remaining shortwave radiation (H units). + ! any remaining shortwave radiation [H ~> m or kg m-2]. T_chg, & ! The temperature change of thick layers due to the remaining - ! shortwave radiation and contributions from T_chg_above, in K. + ! shortwave radiation and contributions from T_chg_above [degC]. Pen_SW_rem ! The sum across all wavelength bands of the penetrating shortwave ! heating that hits the bottom and will be redistributed through - ! the water column (in units of K H) + ! the water column [degC H ~> degC m or degC kg m-2] real :: SW_trans ! fraction of shortwave radiation that is not - ! absorbed in a layer (nondimensional) + ! absorbed in a layer [nondim] real :: unabsorbed ! fraction of the shortwave radiation that ! is not absorbed because the layers are too thin real :: Ih_limit ! inverse of the total depth at which the - ! surface fluxes start to be limited (1/H) - real :: h_min_heat ! minimum thickness layer that should get heated (H) - real :: opt_depth ! optical depth of a layer (non-dim) - real :: exp_OD ! exp(-opt_depth) (non-dim) + ! surface fluxes start to be limited [H-1 ~> m-1 or m2 kg-1] + real :: h_min_heat ! minimum thickness layer that should get heated [H ~> m or kg m-2] + real :: opt_depth ! optical depth of a layer [nondim] + real :: exp_OD ! exp(-opt_depth) [nondim] real :: heat_bnd ! heating due to absorption in the current ! layer by the current band, including any piece that - ! is moved upward (K H units) + ! is moved upward [degC H ~> degC m or degC kg m-2] real :: SWa ! fraction of the absorbed shortwave that is - ! moved to layers above with adjustAbsorptionProfile (non-dim) + ! moved to layers above with adjustAbsorptionProfile [nondim] real :: coSWa_frac ! The fraction of SWa that is actually moved upward. - real :: min_SW_heating ! A minimum remaining shortwave heating rate that will be - ! simply absorbed in the next layer for computational - ! efficiency, instead of continuing to penetrate, in units - ! of K H s-1. The default, 2.5e-11, is about 0.08 K m / century. + real :: min_SW_heating ! A minimum remaining shortwave heating rate that will be simply + ! absorbed in the next layer for computational efficiency, instead of + ! continuing to penetrate [degC H s-1 ~> degC m s-1 or degC kg m-2 s-1]. + ! The default, 2.5e-11, is about 0.08 degC m / century. real :: epsilon ! A small thickness that must remain in each - ! layer, and which will not be subject to heating (units of H) + ! layer, and which will not be subject to heating [H ~> m or kg m-2] real :: I_G_Earth real :: g_Hconv2 logical :: SW_Remains ! If true, some column has shortwave radiation that @@ -304,44 +303,45 @@ subroutine sumSWoverBands(G, GV, h, opacity_band, nsw, j, dt, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(:,:,:), intent(in) :: opacity_band !< opacity in each band of - !! penetrating shortwave radiation, - !! in m-1. The indicies are band, i, k. + !! penetrating shortwave radiation [m-1]. + !! The indicies are band, i, k. integer, intent(in) :: nsw !< number of bands of penetrating !! shortwave radiation. integer, intent(in) :: j !< j-index to work on. - real, intent(in) :: dt !< Time step (seconds). + real, intent(in) :: dt !< Time step [s]. real, intent(in) :: H_limit_fluxes !< the total depth at which the !! surface fluxes start to be limited to avoid - !! excessive heating of a thin ocean (H units) + !! excessive heating of a thin ocean [H ~> m or kg m-2] logical, intent(in) :: absorbAllSW !< If true, ensure that all shortwave !! radiation is absorbed in the ocean water column. real, dimension(:,:), intent(in) :: iPen_SW_bnd !< The incident penetrating shortwave !! heating in each band that hits the bottom and !! will be redistributed through the water column - !! (K H units); size nsw x SZI_(G). + !! [degC H ~> degC m or degC kg m-2]; size nsw x SZI_(G). real, dimension(SZI_(G),SZK_(G)+1), & intent(inout) :: netPen !< Net penetrating shortwave heat flux at each - !! interface, summed across all bands, in K H. + !! interface, summed across all bands + !! [degC H ~> degC m or degC kg m-2]. ! Local variables real :: h_heat(SZI_(G)) ! thickness of the water column that receives - ! remaining shortwave radiation, in H. + ! remaining shortwave radiation [H ~> m or kg m-2]. real :: Pen_SW_rem(SZI_(G)) ! sum across all wavelength bands of the ! penetrating shortwave heating that hits the bottom ! and will be redistributed through the water column - ! (K H units) + ! [degC H ~> degC m or degC kg m-2] real, dimension(size(iPen_SW_bnd,1),size(iPen_SW_bnd,2)) :: Pen_SW_bnd real :: SW_trans ! fraction of shortwave radiation not - ! absorbed in a layer (nondimensional) + ! absorbed in a layer [nondim] real :: unabsorbed ! fraction of the shortwave radiation ! not absorbed because the layers are too thin. real :: Ih_limit ! inverse of the total depth at which the - ! surface fluxes start to be limited (1/H units) - real :: h_min_heat ! minimum thickness layer that should get heated (H units) - real :: opt_depth ! optical depth of a layer (non-dim) - real :: exp_OD ! exp(-opt_depth) (non-dim) + ! surface fluxes start to be limited [H-1 ~> m-1 or m2 kg-1] + real :: h_min_heat ! minimum thickness layer that should get heated [H ~> m or kg m-2] + real :: opt_depth ! optical depth of a layer [nondim] + real :: exp_OD ! exp(-opt_depth) [nondim] logical :: SW_Remains ! If true, some column has shortwave radiation that ! was not entirely absorbed. diff --git a/src/parameterizations/vertical/MOM_sponge.F90 b/src/parameterizations/vertical/MOM_sponge.F90 index 8bb8fa3ef3..eaa2faf765 100644 --- a/src/parameterizations/vertical/MOM_sponge.F90 +++ b/src/parameterizations/vertical/MOM_sponge.F90 @@ -22,6 +22,11 @@ module MOM_sponge public set_up_sponge_field, set_up_sponge_ML_density public initialize_sponge, apply_sponge, sponge_end, init_sponge_diags +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> A structure for creating arrays of pointers to 3D arrays type, public :: p3d real, dimension(:,:,:), pointer :: p => NULL() !< A pointer to a 3D array @@ -51,9 +56,9 @@ module MOM_sponge integer, pointer :: col_j(:) => NULL() !< Array of the j-indicies of each of the columns being damped. real, pointer :: Iresttime_col(:) => NULL() !< The inverse restoring time of each column. real, pointer :: Rcv_ml_ref(:) => NULL() !< The value toward which the mixed layer - !! coordinate-density is being damped, in kg m-3. + !! coordinate-density is being damped [kg m-3]. real, pointer :: Ref_eta(:,:) => NULL() !< The value toward which the interface - !! heights are being damped, in depth units (Z). + !! heights are being damped [Z ~> m]. type(p3d) :: var(MAX_FIELDS_) !< Pointers to the fields that are being damped. type(p2d) :: Ref_val(MAX_FIELDS_) !< The values to which the fields are damped. @@ -61,9 +66,9 @@ module MOM_sponge real, pointer :: Iresttime_im(:) => NULL() !< The inverse restoring time of !! each row for i-mean sponges. real, pointer :: Rcv_ml_ref_im(:) => NULL() !! The value toward which the i-mean - !< mixed layer coordinate-density is being damped, in kg m-3. + !< mixed layer coordinate-density is being damped [kg m-3]. real, pointer :: Ref_eta_im(:,:) => NULL() !< The value toward which the i-mean - !! interface heights are being damped, in depth units (Z). + !! interface heights are being damped [Z ~> m]. type(p2d) :: Ref_val_im(MAX_FIELDS_) !< The values toward which the i-means of !! fields are damped. @@ -83,19 +88,19 @@ subroutine initialize_sponge(Iresttime, int_height, G, param_file, CS, GV, & Iresttime_i_mean, int_height_i_mean) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: Iresttime !< The inverse of the restoring time, in s-1. + intent(in) :: Iresttime !< The inverse of the restoring time [s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - intent(in) :: int_height !< The interface heights to damp back toward, in depth units (Z). + intent(in) :: int_height !< The interface heights to damp back toward [Z ~> m]. type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters type(sponge_CS), pointer :: CS !< A pointer that is set to point to the control !! structure for this module type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZJ_(G)), & optional, intent(in) :: Iresttime_i_mean !< The inverse of the restoring time for - !! the zonal mean properties, in s-1. + !! the zonal mean properties [s-1]. real, dimension(SZJ_(G),SZK_(G)+1), & optional, intent(in) :: int_height_i_mean !< The interface heights toward which to - !! damp the zonal mean heights, in depth units (Z). + !! damp the zonal mean heights [Z ~> m]. ! This include declares and sets the variable "version". @@ -268,12 +273,12 @@ end subroutine set_up_sponge_field subroutine set_up_sponge_ML_density(sp_val, G, CS, sp_val_i_mean) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: sp_val !< The reference values of the mixed layer density, in kg m-3 + intent(in) :: sp_val !< The reference values of the mixed layer density [kg m-3] type(sponge_CS), pointer :: CS !< A pointer to the control structure for this module that is !! set by a previous call to initialize_sponge. real, dimension(SZJ_(G)), & optional, intent(in) :: sp_val_i_mean !< the reference values of the zonal mean mixed - !! layer density in kg m-3, for use if Iresttime_i_mean > 0. + !! layer density [kg m-3], for use if Iresttime_i_mean > 0. ! This subroutine stores the reference value for mixed layer density. It is ! handled differently from other values because it is only used in determining ! which layers can be inflated. @@ -316,20 +321,20 @@ subroutine apply_sponge(h, dt, G, GV, ea, eb, CS, Rcv_ml) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2) - real, intent(in) :: dt !< The amount of time covered by this call, in s. + intent(inout) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, intent(in) :: dt !< The amount of time covered by this call [s]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: ea !< An array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in H. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: eb !< An array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in H. + !! added [H ~> m or kg m-2]. type(sponge_CS), pointer :: CS !< A pointer to the control structure for this module !! that is set by a previous call to initialize_sponge. real, dimension(SZI_(G),SZJ_(G)), & - optional, intent(inout) :: Rcv_ml !< The coordinate density of the mixed layer in kg m-2. + optional, intent(inout) :: Rcv_ml !< The coordinate density of the mixed layer [kg m-3]. ! This subroutine applies damping to the layers thicknesses, mixed ! layer buoyancy, and a variety of tracers for every column where @@ -338,40 +343,40 @@ subroutine apply_sponge(h, dt, G, GV, ea, eb, CS, Rcv_ml) ! Local variables real, dimension(SZI_(G), SZJ_(G), SZK_(G)+1) :: & w_int, & ! Water moved upward across an interface within a timestep, - ! in H. + ! [H ~> m or kg m-2]. e_D ! Interface heights that are dilated to have a value of 0 - ! at the surface, in the same units as G%bathyT (m or Z). + ! at the surface [Z ~> m]. real, dimension(SZI_(G), SZJ_(G)) :: & eta_anom, & ! Anomalies in the interface height, relative to the i-mean - ! target value, in depth units (Z). + ! target value [Z ~> m]. fld_anom ! Anomalies in a tracer concentration, relative to the ! i-mean target value. real, dimension(SZJ_(G), SZK_(G)+1) :: & - eta_mean_anom ! The i-mean interface height anomalies, in Z. + eta_mean_anom ! The i-mean interface height anomalies [Z ~> m]. real, allocatable, dimension(:,:,:) :: & fld_mean_anom ! THe i-mean tracer concentration anomalies. real, dimension(SZI_(G), SZK_(G)+1) :: & - h_above, & ! The total thickness above an interface, in H. - h_below ! The total thickness below an interface, in H. + h_above, & ! The total thickness above an interface [H ~> m or kg m-2]. + h_below ! The total thickness below an interface [H ~> m or kg m-2]. real, dimension(SZI_(G)) :: & dilate ! A nondimensional factor by which to dilate layers to - ! give 0 at the surface. + ! give 0 at the surface [nondim]. - real :: e(SZK_(G)+1) ! The interface heights, in Z, usually negative. - real :: e0 ! The height of the free surface in Z. + real :: e(SZK_(G)+1) ! The interface heights [Z ~> m], usually negative. + real :: e0 ! The height of the free surface [Z ~> m]. real :: e_str ! A nondimensional amount by which the reference ! profile must be stretched for the free surfaces ! heights in the two profiles to agree. real :: w ! The thickness of water moving upward through an - ! interface within 1 timestep, in H. - real :: wm ! wm is w if w is negative and 0 otherwise, in H. - real :: wb ! w at the interface below a layer, in H. - real :: wpb ! wpb is wb if wb is positive and 0 otherwise, in H. - real :: ea_k, eb_k ! in H - real :: damp ! The timestep times the local damping coefficient. ND. - real :: I1pdamp ! I1pdamp is 1/(1 + damp). Nondimensional. - real :: damp_1pdamp ! damp_1pdamp is damp/(1 + damp). Nondimensional. - real :: Idt ! 1.0/dt, in s-1. + ! interface within 1 timestep [H ~> m or kg m-2]. + real :: wm ! wm is w if w is negative and 0 otherwise [H ~> m or kg m-2]. + real :: wb ! w at the interface below a layer [H ~> m or kg m-2]. + real :: wpb ! wpb is wb if wb is positive and 0 otherwise [H ~> m or kg m-2]. + real :: ea_k, eb_k ! [H ~> m or kg m-2] + real :: damp ! The timestep times the local damping coefficient [nondim]. + real :: I1pdamp ! I1pdamp is 1/(1 + damp). [nondim] + real :: damp_1pdamp ! damp_1pdamp is damp/(1 + damp). [nondim] + real :: Idt ! 1.0/dt [s-1]. integer :: c, m, nkmb, i, j, k, is, ie, js, je, nz is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke diff --git a/src/parameterizations/vertical/MOM_tidal_mixing.F90 b/src/parameterizations/vertical/MOM_tidal_mixing.F90 index 05c377ab9c..6f85bc5dbe 100644 --- a/src/parameterizations/vertical/MOM_tidal_mixing.F90 +++ b/src/parameterizations/vertical/MOM_tidal_mixing.F90 @@ -36,30 +36,35 @@ module MOM_tidal_mixing public post_tidal_diagnostics public tidal_mixing_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Containers for tidal mixing diagnostics type, public :: tidal_mixing_diags ; private real, pointer, dimension(:,:,:) :: & - Kd_itidal => NULL(),& !< internal tide diffusivity at interfaces (Z2 s-1) - Fl_itidal => NULL(),& !< vertical flux of tidal turbulent dissipation (m3 s-3) - Kd_Niku => NULL(),& !< lee-wave diffusivity at interfaces (Z2 s-1) - Kd_Niku_work => NULL(),& !< layer integrated work by lee-wave driven mixing (W m-2) - Kd_Itidal_Work => NULL(),& !< layer integrated work by int tide driven mixing (W m-2) - Kd_Lowmode_Work => NULL(),& !< layer integrated work by low mode driven mixing (W m-2) - N2_int => NULL(),& !< Bouyancy frequency squared at interfaces (s-2) - vert_dep_3d => NULL(),& !< The 3-d mixing energy deposition (W m-3) + Kd_itidal => NULL(),& !< internal tide diffusivity at interfaces [Z2 s-1 ~> m2 s-1]. + Fl_itidal => NULL(),& !< vertical flux of tidal turbulent dissipation [m3 s-3] + Kd_Niku => NULL(),& !< lee-wave diffusivity at interfaces [Z2 s-1 ~> m2 s-1]. + Kd_Niku_work => NULL(),& !< layer integrated work by lee-wave driven mixing [W m-2] + Kd_Itidal_Work => NULL(),& !< layer integrated work by int tide driven mixing [W m-2] + Kd_Lowmode_Work => NULL(),& !< layer integrated work by low mode driven mixing [W m-2] + N2_int => NULL(),& !< Bouyancy frequency squared at interfaces [s-2] + vert_dep_3d => NULL(),& !< The 3-d mixing energy deposition [W m-3] Schmittner_coeff_3d => NULL() !< The coefficient in the Schmittner et al mixing scheme, in UNITS? real, pointer, dimension(:,:,:) :: tidal_qe_md => NULL() !< Input tidal energy dissipated locally, - !! interpolated to model vertical coordinate (W m-3?) + !! interpolated to model vertical coordinate [W m-3?] real, pointer, dimension(:,:,:) :: Kd_lowmode => NULL() !< internal tide diffusivity at interfaces - !! due to propagating low modes (Z2/s) + !! due to propagating low modes [Z2 s-1 ~> m2 s-1]. real, pointer, dimension(:,:,:) :: Fl_lowmode => NULL() !< vertical flux of tidal turbulent - !! dissipation due to propagating low modes (m3/s3) + !! dissipation due to propagating low modes [m3 s-3] real, pointer, dimension(:,:) :: & - TKE_itidal_used => NULL(),& !< internal tide TKE input at ocean bottom (W/m2) - N2_bot => NULL(),& !< bottom squared buoyancy frequency (1/s2) - N2_meanz => NULL(),& !< vertically averaged buoyancy frequency (1/s2) + TKE_itidal_used => NULL(),& !< internal tide TKE input at ocean bottom [W m-2] + N2_bot => NULL(),& !< bottom squared buoyancy frequency [s-2] + N2_meanz => NULL(),& !< vertically averaged buoyancy frequency [s-2] Polzin_decay_scale_scaled => NULL(),& !< vertical scale of decay for tidal dissipation - Polzin_decay_scale => NULL(),& !< vertical decay scale for tidal diss with Polzin (meter) + Polzin_decay_scale => NULL(),& !< vertical decay scale for tidal diss with Polzin [m] Simmons_coeff_2d => NULL() !< The Simmons et al mixing coefficient end type @@ -85,19 +90,19 @@ module MOM_tidal_mixing !! for dissipation of the lee waves. Schemes that are !! currently encoded are St Laurent et al (2002) and !! Polzin (2009). - real :: Int_tide_decay_scale !< decay scale for internal wave TKE (Z) + real :: Int_tide_decay_scale !< decay scale for internal wave TKE [Z ~> m]. real :: Mu_itides !< efficiency for conversion of dissipation - !! to potential energy (nondimensional) + !! to potential energy [nondim] - real :: Gamma_itides !< fraction of local dissipation (nondimensional) + real :: Gamma_itides !< fraction of local dissipation [nondim] real :: Gamma_lee !< fraction of local dissipation for lee waves - !! (Nikurashin's energy input) (nondimensional) + !! (Nikurashin's energy input) [nondim] real :: Decay_scale_factor_lee !< Scaling factor for the decay scale of lee - !! wave energy dissipation (nondimensional) + !! wave energy dissipation [nondim] - real :: min_zbot_itides !< minimum depth for internal tide conversion (Z) + real :: min_zbot_itides !< minimum depth for internal tide conversion [Z ~> m]. logical :: Lowmode_itidal_dissipation = .false. !< If true, consider mixing due to breaking low !! modes that have been remotely generated using an internal tidal !! dissipation scheme to specify the vertical profile of the energy @@ -109,20 +114,20 @@ module MOM_tidal_mixing real :: Nbotref_Polzin !< Reference value for the buoyancy frequency at the !! ocean bottom used in Polzin formulation of the - !! vertical scale of decay of tidal dissipation (1/s) + !! vertical scale of decay of tidal dissipation [s-1] real :: Polzin_decay_scale_factor !< Scaling factor for the decay length scale - !! of the tidal dissipation profile in Polzin (nondimensional) + !! of the tidal dissipation profile in Polzin [nondim] real :: Polzin_decay_scale_max_factor !< The decay length scale of tidal dissipation !! profile in Polzin formulation should not exceed - !! Polzin_decay_scale_max_factor * depth of the ocean (nondimensional). + !! Polzin_decay_scale_max_factor * depth of the ocean [nondim]. real :: Polzin_min_decay_scale !< minimum decay scale of the tidal dissipation - !! profile in Polzin formulation (Z) + !! profile in Polzin formulation [Z ~> m]. - real :: TKE_itide_max !< maximum internal tide conversion (W m-2) + real :: TKE_itide_max !< maximum internal tide conversion [W m-2] !! available to mix above the BBL - real :: utide !< constant tidal amplitude (m s-1) used if - real :: kappa_itides !< topographic wavenumber and non-dimensional scaling, in Z-1 + real :: utide !< constant tidal amplitude [m s-1] used if + real :: kappa_itides !< topographic wavenumber and non-dimensional scaling [Z-1 ~> m-1]. real :: kappa_h2_factor !< factor for the product of wavenumber * rms sgs height character(len=200) :: inputdir !< The directory in which to find input files @@ -137,24 +142,23 @@ module MOM_tidal_mixing type(CVMix_global_params_type) :: CVMix_glb_params !< CVMix-specific for Prandtl number only real :: tidal_max_coef !< CVMix-specific maximum allowable tidal diffusivity. [m^2/s] real :: tidal_diss_lim_tc !< CVMix-specific dissipation limit depth for - !! tidal-energy-constituent data, in Z. + !! tidal-energy-constituent data [Z ~> m]. type(remapping_CS) :: remap_CS !< The control structure for remapping ! Data containers - real, pointer, dimension(:,:) :: TKE_Niku => NULL() !< Lee wave driven Turbulent Kinetic Energy input, - !! in W m-2 + real, pointer, dimension(:,:) :: TKE_Niku => NULL() !< Lee wave driven Turbulent Kinetic Energy input [W m-2] real, pointer, dimension(:,:) :: TKE_itidal => NULL() !< The internal Turbulent Kinetic Energy input divided - !! by the bottom stratfication, in J m-2. - real, pointer, dimension(:,:) :: Nb => NULL() !< The near bottom buoyancy frequency, in s-1. + !! by the bottom stratfication [J m-2]. + real, pointer, dimension(:,:) :: Nb => NULL() !< The near bottom buoyancy frequency [s-1]. real, pointer, dimension(:,:) :: mask_itidal => NULL() !< A mask of where internal tide energy is input - real, pointer, dimension(:,:) :: h2 => NULL() !< Squared bottom depth variance, in m2. - real, pointer, dimension(:,:) :: tideamp => NULL() !< RMS tidal amplitude [m/s] + real, pointer, dimension(:,:) :: h2 => NULL() !< Squared bottom depth variance [m2]. + real, pointer, dimension(:,:) :: tideamp => NULL() !< RMS tidal amplitude [m s-1] real, allocatable, dimension(:) :: h_src !< tidal constituent input layer thickness [m] real, allocatable, dimension(:,:) :: tidal_qe_2d !< Tidal energy input times the local dissipation !! fraction, q*E(x,y), with the CVMix implementation - !! of Jayne et al tidal mixing, in W m-2. + !! of Jayne et al tidal mixing [W m-2]. !! TODO: make this E(x,y) only - real, allocatable, dimension(:,:,:) :: tidal_qe_3d_in !< q*E(x,y,z) with the Schmittner parameterization, in W m-3? + real, allocatable, dimension(:,:,:) :: tidal_qe_3d_in !< q*E(x,y,z) with the Schmittner parameterization [W m-3?] ! Diagnostics type(diag_ctrl), pointer :: diag => NULL() !< structure to regulate diagnostic output timing @@ -462,7 +466,7 @@ logical function tidal_mixing_init(Time, G, GV, US, param_file, diag, diag_to_Z_ CS%h2(i,j) = hamp*hamp utide = CS%tideamp(i,j) - ! Compute the fixed part of internal tidal forcing; units are [kg s-2] here. + ! Compute the fixed part of internal tidal forcing; units are [J m-2 = kg s-2] here. CS%TKE_itidal(i,j) = 0.5*US%Z_to_m * CS%kappa_h2_factor*GV%Rho0*& CS%kappa_itides * CS%h2(i,j) * utide*utide enddo ; enddo @@ -653,31 +657,33 @@ subroutine calculate_tidal_mixing(h, N2_bot, j, TKE_to_Kd, max_TKE, G, GV, US, C type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G)), intent(in) :: N2_bot !< The near-bottom squared buoyancy - !! frequency, in s-2. + !! frequency [s-2]. real, dimension(SZI_(G),SZK_(G)), intent(in) :: N2_lay !< The squared buoyancy frequency of the - !! layers, in s-2. + !! layers [s-2]. real, dimension(SZI_(G),SZK_(G)+1), intent(in) :: N2_int !< The squared buoyancy frequency at the - !! interfaces, in s-2. + !! interfaces [s-2]. integer, intent(in) :: j !< The j-index to work on real, dimension(SZI_(G),SZK_(G)), intent(in) :: TKE_to_Kd !< The conversion rate between the TKE !! TKE dissipated within a layer and the !! diapycnal diffusivity witin that layer, - !! usually (~Rho_0 / (G_Earth * dRho_lay)), - !! in Z2 s-1 / m3 s-3 = Z2 s2 m-3 + !! usually (~Rho_0 / (G_Earth * dRho_lay)) + !! [Z2 s-1 / m3 s-3 = Z2 s2 m-3 ~> s2 m-1] real, dimension(SZI_(G),SZK_(G)), intent(in) :: max_TKE !< The energy required to for a layer to entrain - !! to its maximum realizable thickness, in m3 s-3 + !! to its maximum realizable thickness [m3 s-3] type(tidal_mixing_cs), pointer :: CS !< The control structure for this module real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers, in Z2 s-1. + intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - optional, intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces, in Z2 s-1. + optional, intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces, + !! [Z2 s-1 ~> m2 s-1]. real, intent(in) :: Kd_max !< The maximum increment for diapycnal - !! diffusivity due to TKE-based processes, in Z2 s-1. + !! diffusivity due to TKE-based processes, + !! [Z2 s-1 ~> m2 s-1]. !! Set this to a negative value to have no limit. real, dimension(:,:,:), pointer :: Kv !< The "slow" vertical viscosity at each interface - !! (not layer!) in Z2 s-1. + !! (not layer!) [Z2 s-1 ~> m2 s-1]. if (CS%Int_tide_dissipation .or. CS%Lee_wave_dissipation .or. CS%Lowmode_itidal_dissipation) then if (CS%use_CVMix_tidal) then @@ -699,20 +705,20 @@ subroutine calculate_CVMix_tidal(h, j, G, GV, US, CS, N2_int, Kd_lay, Kv) type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(tidal_mixing_cs), pointer :: CS !< This module's control structure. real, dimension(SZI_(G),SZK_(G)+1), intent(in) :: N2_int !< The squared buoyancy - !! frequency at the interfaces, in s-2. + !! frequency at the interfaces [s-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: Kd_lay!< The diapycnal diffusivities in the layers, in Z2 s-1 + intent(inout) :: Kd_lay!< The diapycnal diffusivities in the layers [Z2 s-1 ~> m2 s-1]. real, dimension(:,:,:), pointer :: Kv !< The "slow" vertical viscosity at each interface - !! (not layer!) in Z2 s-1. + !! (not layer!) [Z2 s-1 ~> m2 s-1]. ! Local variables real, dimension(SZK_(G)+1) :: Kd_tidal ! tidal diffusivity [m2/s] real, dimension(SZK_(G)+1) :: Kv_tidal ! tidal viscosity [m2/s] real, dimension(SZK_(G)+1) :: vert_dep ! vertical deposition - real, dimension(SZK_(G)+1) :: iFaceHeight ! Height of interfaces (m) + real, dimension(SZK_(G)+1) :: iFaceHeight ! Height of interfaces [m] real, dimension(SZK_(G)+1) :: SchmittnerSocn - real, dimension(SZK_(G)) :: cellHeight ! Height of cell centers (m) + real, dimension(SZK_(G)) :: cellHeight ! Height of cell centers [m] real, dimension(SZK_(G)) :: tidal_qe_md ! Tidal dissipation energy interpolated from 3d input ! to model coordinates real, dimension(SZK_(G)) :: Schmittner_coeff @@ -781,7 +787,7 @@ subroutine calculate_CVMix_tidal(h, j, G, GV, US, CS, N2_int, Kd_lay, Kv) ! Update viscosity with the proper unit conversion. if (associated(Kv)) then do k=1,G%ke+1 - Kv(i,j,k) = Kv(i,j,k) + US%m_to_Z**2 * Kv_tidal(k) ! Rescale from m2 s-1 to Z2 s-1. + Kv(i,j,k) = Kv(i,j,k) + US%m_to_Z**2 * Kv_tidal(k) ! Rescale from m2 s-1 to Z2 s-1. enddo endif @@ -923,66 +929,68 @@ subroutine add_int_tide_diffusivity(h, N2_bot, j, TKE_to_Kd, max_TKE, G, GV, US, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G)), intent(in) :: N2_bot !< The near-bottom squared buoyancy frequency - !! frequency, in s-2. + !! frequency [s-2]. real, dimension(SZI_(G),SZK_(G)), intent(in) :: N2_lay !< The squared buoyancy frequency of the - !! layers, in s-2. + !! layers [s-2]. integer, intent(in) :: j !< The j-index to work on real, dimension(SZI_(G),SZK_(G)), intent(in) :: TKE_to_Kd !< The conversion rate between the TKE !! TKE dissipated within a layer and the !! diapycnal diffusivity witin that layer, - !! usually (~Rho_0 / (G_Earth * dRho_lay)), - !! in Z2 s-1 / m3 s-3 = Z2 s2 m-3 + !! usually (~Rho_0 / (G_Earth * dRho_lay)) + !! [Z2 s-1 / m3 s-3 = Z2 s2 m-3 ~> s2 m-1] real, dimension(SZI_(G),SZK_(G)), intent(in) :: max_TKE !< The energy required to for a layer to entrain - !! to its maximum realizable thickness, in m3 s-3 + !! to its maximum realizable thickness [m3 s-3] type(tidal_mixing_cs), pointer :: CS !< The control structure for this module real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers, in Z2 s-1. + intent(inout) :: Kd_lay !< The diapycnal diffusvity in layers [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), & - optional, intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces, in Z2 s-1. + optional, intent(inout) :: Kd_int !< The diapycnal diffusvity at interfaces + !! [Z2 s-1 ~> m2 s-1]. real, intent(in) :: Kd_max !< The maximum increment for diapycnal - !! diffusivity due to TKE-based processes, in Z2 s-1. + !! diffusivity due to TKE-based processes + !! [Z2 s-1 ~> m2 s-1]. !! Set this to a negative value to have no limit. ! local real, dimension(SZI_(G)) :: & htot, & ! total thickness above or below a layer, or the - ! integrated thickness in the BBL (Z) - htot_WKB, & ! distance from top to bottom (Z) WKB scaled - TKE_itidal_bot, & ! internal tide TKE at ocean bottom (m3/s3) - TKE_Niku_bot, & ! lee-wave TKE at ocean bottom (m3/s3) - TKE_lowmode_bot, & ! internal tide TKE at ocean bottom lost from all remote low modes (m3/s3) (BDM) - Inv_int, & ! inverse of TKE decay for int tide over the depth of the ocean (nondim) - Inv_int_lee, & ! inverse of TKE decay for lee waves over the depth of the ocean (nondim) - Inv_int_low, & ! inverse of TKE decay for low modes over the depth of the ocean (nondim) (BDM) - z0_Polzin, & ! TKE decay scale in Polzin formulation (Z) - z0_Polzin_scaled, & ! TKE decay scale in Polzin formulation (Z) + ! integrated thickness in the BBL [Z ~> m]. + htot_WKB, & ! WKB scaled distance from top to bottom [Z ~> m]. + TKE_itidal_bot, & ! internal tide TKE at ocean bottom [m3 s-3] + TKE_Niku_bot, & ! lee-wave TKE at ocean bottom [m3 s-3] + TKE_lowmode_bot, & ! internal tide TKE at ocean bottom lost from all remote low modes [m3 s-3] (BDM) + Inv_int, & ! inverse of TKE decay for int tide over the depth of the ocean [nondim] + Inv_int_lee, & ! inverse of TKE decay for lee waves over the depth of the ocean [nondim] + Inv_int_low, & ! inverse of TKE decay for low modes over the depth of the ocean [nondim] (BDM) + z0_Polzin, & ! TKE decay scale in Polzin formulation [Z ~> m]. + z0_Polzin_scaled, & ! TKE decay scale in Polzin formulation [Z ~> m]. ! multiplied by N2_bot/N2_meanz to be coherent with the WKB scaled z ! z*=int(N2/N2_bot) * N2_bot/N2_meanz = int(N2/N2_meanz) ! z0_Polzin_scaled = z0_Polzin * N2_bot/N2_meanz - N2_meanz, & ! vertically averaged squared buoyancy frequency (1/s2) for WKB scaling + N2_meanz, & ! vertically averaged squared buoyancy frequency [s-2] for WKB scaling TKE_itidal_rem, & ! remaining internal tide TKE (from barotropic source) TKE_Niku_rem, & ! remaining lee-wave TKE TKE_lowmode_rem, & ! remaining internal tide TKE (from propagating low mode source) (BDM) - TKE_frac_top, & ! fraction of bottom TKE that should appear at top of a layer (nondim) - TKE_frac_top_lee, & ! fraction of bottom TKE that should appear at top of a layer (nondim) + TKE_frac_top, & ! fraction of bottom TKE that should appear at top of a layer [nondim] + TKE_frac_top_lee, & ! fraction of bottom TKE that should appear at top of a layer [nondim] TKE_frac_top_lowmode, & - ! fraction of bottom TKE that should appear at top of a layer (nondim) (BDM) - z_from_bot, & ! distance from bottom (Z) - z_from_bot_WKB ! distance from bottom (Z), WKB scaled - - real :: I_rho0 ! 1 / RHO0, (m3/kg) - real :: Kd_add ! diffusivity to add in a layer (Z2/sec) - real :: TKE_itide_lay ! internal tide TKE imparted to a layer (from barotropic) (m3/s3) - real :: TKE_Niku_lay ! lee-wave TKE imparted to a layer (m3/s3) - real :: TKE_lowmode_lay ! internal tide TKE imparted to a layer (from low mode) (m3/s3) (BDM) - real :: frac_used ! fraction of TKE that can be used in a layer (nondim) - real :: Izeta ! inverse of TKE decay scale (1/Z) - real :: Izeta_lee ! inverse of TKE decay scale for lee waves (1/Z) - real :: z0_psl ! temporary variable with units of Z - real :: TKE_lowmode_tot ! TKE from all low modes (W/m2) (BDM) + ! fraction of bottom TKE that should appear at top of a layer [nondim] (BDM) + z_from_bot, & ! distance from bottom [Z ~> m]. + z_from_bot_WKB ! WKB scaled distance from bottom [Z ~> m]. + + real :: I_rho0 ! 1 / RHO0 [m3 kg-1] + real :: Kd_add ! diffusivity to add in a layer [Z2 s-1 ~> m2 s-1]. + real :: TKE_itide_lay ! internal tide TKE imparted to a layer (from barotropic) [m3 s-3] + real :: TKE_Niku_lay ! lee-wave TKE imparted to a layer [m3 s-3] + real :: TKE_lowmode_lay ! internal tide TKE imparted to a layer (from low mode) [m3 s-3] (BDM) + real :: frac_used ! fraction of TKE that can be used in a layer [nondim] + real :: Izeta ! inverse of TKE decay scale [Z-1 ~> m-1]. + real :: Izeta_lee ! inverse of TKE decay scale for lee waves [Z-1 ~> m-1]. + real :: z0_psl ! temporary variable [Z ~> m]. + real :: TKE_lowmode_tot ! TKE from all low modes [W m-2] (BDM) logical :: use_Polzin, use_Simmons character(len=160) :: mesg ! The text of an error message @@ -1059,7 +1067,7 @@ subroutine add_int_tide_diffusivity(h, N2_bot, j, TKE_to_Kd, max_TKE, G, GV, US, do i=is,ie CS%Nb(i,j) = sqrt(N2_bot(i)) - !### In the code below 1.0e-14 is a dimensional constant in s-3 + !### In the code below 1.0e-14 is a dimensional constant in [s-3] if ((CS%tideamp(i,j) > 0.0) .and. & (CS%kappa_itides**2 * CS%h2(i,j) * CS%Nb(i,j)**3 > 1.0e-14) ) then z0_polzin(i) = US%m_to_Z * CS%Polzin_decay_scale_factor * CS%Nu_Polzin * & @@ -1412,7 +1420,7 @@ subroutine post_tidal_diagnostics(G, GV, h ,CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(tidal_mixing_cs), pointer :: CS !< The control structure for this module ! local @@ -1508,7 +1516,7 @@ subroutine read_tidal_energy(G, US, tidal_energy_type, tidal_energy_file, CS) type(tidal_mixing_cs), pointer :: CS !< The control structure for this module ! local integer :: i, j, isd, ied, jsd, jed, nz - real, allocatable, dimension(:,:) :: tidal_energy_flux_2d ! input tidal energy flux at T-grid points (W/m^2) + real, allocatable, dimension(:,:) :: tidal_energy_flux_2d ! input tidal energy flux at T-grid points [W m-2] isd = G%isd ; ied = G%ied ; jsd = G%jsd ; jed = G%jed ; nz = G%ke diff --git a/src/parameterizations/vertical/MOM_vert_friction.F90 b/src/parameterizations/vertical/MOM_vert_friction.F90 index 3bcc287058..5400f8c1df 100644 --- a/src/parameterizations/vertical/MOM_vert_friction.F90 +++ b/src/parameterizations/vertical/MOM_vert_friction.F90 @@ -30,21 +30,25 @@ module MOM_vert_friction public vertvisc_limit_vel, vertvisc_init, vertvisc_end public updateCFLtruncationValue +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> The control structure with parameters and memory for the MOM_vert_friction module type, public :: vertvisc_CS ; private - real :: Hmix !< The mixed layer thickness in thickness units (H). + real :: Hmix !< The mixed layer thickness in thickness units [H ~> m or kg m-2]. real :: Hmix_stress !< The mixed layer thickness over which the wind - !! stress is applied with direct_stress, in H. - real :: Kvml !< The mixed layer vertical viscosity in m2 s-1. - real :: Kv !< The interior vertical viscosity in m2 s-1. - real :: Hbbl !< The static bottom boundary layer thickness, in m. + !! stress is applied with direct_stress [H ~> m or kg m-2]. + real :: Kvml !< The mixed layer vertical viscosity [Z2 s-1 ~> m2 s-1]. + real :: Kv !< The interior vertical viscosity [Z2 s-1 ~> m2 s-1]. + real :: Hbbl !< The static bottom boundary layer thickness [H ~> m or kg m-2]. real :: Kvbbl !< The vertical viscosity in the bottom boundary - !! layer, in m2 s-1. + !! layer [Z2 s-1 ~> m2 s-1]. - real :: maxvel !< Velocity components greater than maxvel, - !! in m s-1, are truncated. + real :: maxvel !< Velocity components greater than maxvel are truncated [m s-1]. real :: vel_underflow !< Velocity components smaller than vel_underflow - !! are set to 0, in m s-1. + !! are set to 0 [m s-1]. logical :: CFL_based_trunc !< If true, base truncations on CFL numbers, not !! absolute velocities. real :: CFL_trunc !< Velocity components will be truncated when they @@ -61,17 +65,17 @@ module MOM_vert_friction type(time_type) :: rampStartTime !< The time at which the ramping of CFL_trunc starts real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NK_INTERFACE_) :: & - a_u !< The u-drag coefficient across an interface, in Z s-1. + a_u !< The u-drag coefficient across an interface [Z s-1 ~> m s-1]. real ALLOCABLE_, dimension(NIMEMB_PTR_,NJMEM_,NKMEM_) :: & - h_u !< The effective layer thickness at u-points, m or kg m-2. + h_u !< The effective layer thickness at u-points [H ~> m or kg m-2]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NK_INTERFACE_) :: & - a_v !< The v-drag coefficient across an interface, in Z s-1. + a_v !< The v-drag coefficient across an interface [Z s-1 ~> m s-1]. real ALLOCABLE_, dimension(NIMEM_,NJMEMB_PTR_,NKMEM_) :: & - h_v !< The effective layer thickness at v-points, m or kg m-2. + h_v !< The effective layer thickness at v-points [H ~> m or kg m-2]. real, pointer, dimension(:,:) :: a1_shelf_u => NULL() !< The u-momentum coupling coefficient under - !! ice shelves in m s-1. Retained to determine stress under shelves. + !! ice shelves [Z s-1 ~> m s-1]. Retained to determine stress under shelves. real, pointer, dimension(:,:) :: a1_shelf_v => NULL() !< The v-momentum coupling coefficient under - !! ice shelves in m s-1. Retained to determine stress under shelves. + !! ice shelves [Z s-1 ~> m s-1]. Retained to determine stress under shelves. logical :: split !< If true, use the split time stepping scheme. logical :: bottomdraglaw !< If true, the bottom stress is calculated with a @@ -144,59 +148,54 @@ subroutine vertvisc(u, v, h, forces, visc, dt, OBC, ADp, CDp, G, GV, US, CS, & type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: u !< Zonal velocity in m s-1 + intent(inout) :: u !< Zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(inout) :: v !< Meridional velocity in m s-1 + intent(inout) :: v !< Meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thickness in H + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces type(vertvisc_type), intent(inout) :: visc !< Viscosities and bottom drag - real, intent(in) :: dt !< Time increment in s + real, intent(in) :: dt !< Time increment [s] type(ocean_OBC_type), pointer :: OBC !< Open boundary condition structure type(accel_diag_ptrs), intent(inout) :: ADp !< Accelerations in the momentum !! equations for diagnostics type(cont_diag_ptrs), intent(inout) :: CDp !< Continuity equation terms type(vertvisc_CS), pointer :: CS !< Vertical viscosity control structure real, dimension(SZIB_(G),SZJ_(G)), & - optional, intent(out) :: taux_bot !< Zonal bottom stress from ocean to rock in Pa + optional, intent(out) :: taux_bot !< Zonal bottom stress from ocean to rock [Pa] real, dimension(SZI_(G),SZJB_(G)), & - optional, intent(out) :: tauy_bot !< Meridional bottom stress from ocean to rock in Pa + optional, intent(out) :: tauy_bot !< Meridional bottom stress from ocean to rock [Pa] type(wave_parameters_CS), & optional, pointer :: Waves !< Container for wave/Stokes information ! Fields from forces used in this subroutine: - ! taux: Zonal wind stress in Pa. - ! tauy: Meridional wind stress in Pa. + ! taux: Zonal wind stress [Pa]. + ! tauy: Meridional wind stress [Pa]. ! Local variables - real :: b1(SZIB_(G)) ! b1 and c1 are variables used by the - real :: c1(SZIB_(G),SZK_(G)) ! tridiagonal solver. c1 is nondimensional, - ! while b1 has units of inverse thickness. - real :: d1(SZIB_(G)) ! d1=1-c1 is used by the tridiagonal solver, ND. - real :: Ray(SZIB_(G),SZK_(G)) ! Ray is the Rayleigh-drag velocity in Z s-1 - real :: b_denom_1 ! The first term in the denominator of b1, in H. + real :: b1(SZIB_(G)) ! A variable used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. + real :: c1(SZIB_(G),SZK_(G)) ! A variable used by the tridiagonal solver [nondim]. + real :: d1(SZIB_(G)) ! d1=1-c1 is used by the tridiagonal solver [nondim]. + real :: Ray(SZIB_(G),SZK_(G)) ! Ray is the Rayleigh-drag velocity [Z s-1 ~> m s-1]. + real :: b_denom_1 ! The first term in the denominator of b1 [H ~> m or kg m-2]. real :: Hmix ! The mixed layer thickness over which stress - ! is applied with direct_stress, translated into - ! thickness units - either m or kg m-2. - real :: I_Hmix ! The inverse of Hmix, in m-1 or m2 kg-1. - real :: Idt ! The inverse of the time step, in s-1. - real :: dt_Rho0 ! The time step divided by the mean - ! density, in s m3 kg-1. - real :: Rho0 ! A density used to convert drag laws into stress in - ! Pa, in kg m-3. + ! is applied with direct_stress [H ~> m or kg m-2]. + real :: I_Hmix ! The inverse of Hmix [H-1 ~> m-1 or m2 kg-1]. + real :: Idt ! The inverse of the time step [s-1]. + real :: dt_Rho0 ! The time step divided by the mean density [s m3 kg-1]. + real :: Rho0 ! A density used to convert drag laws into stress in Pa [kg m-3]. real :: dt_Z_to_H ! The time step times the conversion from Z to the - ! units of thickness - either s or s m3 kg-1. + ! units of thickness - [s H Z-1 ~> s or s kg m-3]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m or kg m-2. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: stress ! The surface stress times the time step, divided - ! by the density, in units of m2 s-1. + ! by the density [m2 s-1]. real :: zDS, hfr, h_a ! Temporary variables used with direct_stress. - real :: surface_stress(SZIB_(G))! The same as stress, unless the wind - ! stress is applied as a body force, in - ! units of m2 s-1. + real :: surface_stress(SZIB_(G))! The same as stress, unless the wind stress + ! stress is applied as a body force [m2 s-1]. logical :: do_i(SZIB_(G)) logical :: DoStokesMixing @@ -462,26 +461,24 @@ subroutine vertvisc_remnant(visc, visc_rem_u, visc_rem_v, dt, G, GV, CS) type(vertvisc_type), intent(in) :: visc !< Viscosities and bottom drag real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & intent(inout) :: visc_rem_u !< Fraction of a time-step's worth of a - !! barotopic acceleration that a layer experiences - !! after viscosity is applied in the zonal direction + !! barotopic acceleration that a layer experiences after + !! viscosity is applied in the zonal direction [nondim] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & intent(inout) :: visc_rem_v !< Fraction of a time-step's worth of a - !! barotopic acceleration that a layer experiences - !! after viscosity is applied in the meridional direction - real, intent(in) :: dt !< Time increment in s + !! barotopic acceleration that a layer experiences after + !! viscosity is applied in the meridional direction [nondim] + real, intent(in) :: dt !< Time increment [s] type(vertvisc_CS), pointer :: CS !< Vertical viscosity control structure ! Local variables - real :: b1(SZIB_(G)) ! b1 and c1 are variables used by the - real :: c1(SZIB_(G),SZK_(G)) ! tridiagonal solver. c1 is nondimensional, - ! while b1 has units of inverse thickness. - real :: d1(SZIB_(G)) ! d1=1-c1 is used by the tridiagonal solver, ND. - real :: Ray(SZIB_(G),SZK_(G)) ! Ray is the Rayleigh-drag velocity times the - ! time step, in m. - real :: b_denom_1 ! The first term in the denominator of b1, in m or kg m-2. + real :: b1(SZIB_(G)) ! A variable used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. + real :: c1(SZIB_(G),SZK_(G)) ! A variable used by the tridiagonal solver [nondim]. + real :: d1(SZIB_(G)) ! d1=1-c1 is used by the tridiagonal solver [nondim]. + real :: Ray(SZIB_(G),SZK_(G)) ! Ray is the Rayleigh-drag velocity times the time step [m]. + real :: b_denom_1 ! The first term in the denominator of b1 [H ~> m or kg m-2]. real :: dt_Z_to_H ! The time step times the conversion from Z to the - ! units of thickness - either s or s m3 kg-1. + ! units of thickness [s H Z-1 ~> s or s kg m-3]. logical :: do_i(SZIB_(G)) integer :: i, j, k, is, ie, Isq, Ieq, Jsq, Jeq, nz @@ -570,66 +567,64 @@ subroutine vertvisc_coef(u, v, h, forces, visc, dt, G, GV, US, CS, OBC) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: u !< Zonal velocity in m s-1 + intent(in) :: u !< Zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(in) :: v !< Meridional velocity in m s-1 + intent(in) :: v !< Meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thickness in H + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces type(vertvisc_type), intent(in) :: visc !< Viscosities and bottom drag - real, intent(in) :: dt !< Time increment in s + real, intent(in) :: dt !< Time increment [s] type(vertvisc_CS), pointer :: CS !< Vertical viscosity control structure type(ocean_OBC_type), pointer :: OBC !< Open boundary condition structure ! Field from forces used in this subroutine: - ! ustar: the friction velocity in m s-1, used here as the mixing + ! ustar: the friction velocity [m s-1], used here as the mixing ! velocity in the mixed layer if NKML > 1 in a bulk mixed layer. ! Local variables real, dimension(SZIB_(G),SZK_(G)) :: & h_harm, & ! Harmonic mean of the thicknesses around a velocity grid point, - ! given by 2*(h+ * h-)/(h+ + h-), in m or kg m-2 (H for short). - h_arith, & ! The arithmetic mean thickness, in m or kg m-2. - h_delta, & ! The lateral difference of thickness, in m or kg m-2. - hvel, & ! hvel is the thickness used at a velocity grid point, in H. - hvel_shelf ! The equivalent of hvel under shelves, in H. + ! given by 2*(h+ * h-)/(h+ + h-) [H ~> m or kg m-2]. + h_arith, & ! The arithmetic mean thickness [H ~> m or kg m-2]. + h_delta, & ! The lateral difference of thickness [H ~> m or kg m-2]. + hvel, & ! hvel is the thickness used at a velocity grid point [H ~> m or kg m-2]. + hvel_shelf ! The equivalent of hvel under shelves [H ~> m or kg m-2]. real, dimension(SZIB_(G),SZK_(G)+1) :: & - a_cpl, & ! The drag coefficients across interfaces, in Z s-1. a_cpl times + a_cpl, & ! The drag coefficients across interfaces [Z s-1 ~> m s-1]. a_cpl times ! the velocity difference gives the stress across an interface. a_shelf, & ! The drag coefficients across interfaces in water columns under - ! ice shelves, in Z s-1. + ! ice shelves [Z s-1 ~> m s-1]. z_i ! An estimate of each interface's height above the bottom, ! normalized by the bottom boundary layer thickness, nondim. real, dimension(SZIB_(G)) :: & - kv_bbl, & ! The bottom boundary layer viscosity in Z2 s-1. - bbl_thick, & ! The bottom boundary layer thickness in m or kg m-2. - I_Hbbl, & ! The inverse of the bottom boundary layer thickness, in units - ! of H-1 (i.e., m-1 or m2 kg-1). - I_Htbl, & ! The inverse of the top boundary layer thickness, in units - ! of H-1 (i.e., m-1 or m2 kg-1). + kv_bbl, & ! The bottom boundary layer viscosity [Z2 s-1 ~> m2 s-1]. + bbl_thick, & ! The bottom boundary layer thickness [H ~> m or kg m-2]. + I_Hbbl, & ! The inverse of the bottom boundary layer thickness [H-1 ~> m-1 or m2 kg-1]. + I_Htbl, & ! The inverse of the top boundary layer thickness [H-1 ~> m-1 or m2 kg-1]. zcol1, & ! The height of the interfaces to the north and south of a - zcol2, & ! v-point, in m or kg m-2. - Ztop_min, & ! The deeper of the two adjacent surface heights, in H. + zcol2, & ! v-point [H ~> m or kg m-2]. + Ztop_min, & ! The deeper of the two adjacent surface heights [H ~> m or kg m-2]. Dmin, & ! The shallower of the two adjacent bottom depths converted to - ! thickness units, in m or kg m-2. + ! thickness units [H ~> m or kg m-2]. zh, & ! An estimate of the interface's distance from the bottom - ! based on harmonic mean thicknesses, in m or kg m-2. - h_ml ! The mixed layer depth, in m or kg m-2. - real, allocatable, dimension(:,:) :: hML_u ! Diagnostic of the mixed layer depth at u points, in m. - real, allocatable, dimension(:,:) :: hML_v ! Diagnostic of the mixed layer depth at v points, in m. - real, allocatable, dimension(:,:,:) :: Kv_u !< Total vertical viscosity at u-points, in m2 s-1. - real, allocatable, dimension(:,:,:) :: Kv_v !< Total vertical viscosity at v-points, in m2 s-1. - real :: zcol(SZI_(G)) ! The height of an interface at h-points, in H (m or kg m-2). + ! based on harmonic mean thicknesses [H ~> m or kg m-2]. + h_ml ! The mixed layer depth [H ~> m or kg m-2]. + real, allocatable, dimension(:,:) :: hML_u ! Diagnostic of the mixed layer depth at u points [H ~> m or kg m-2]. + real, allocatable, dimension(:,:) :: hML_v ! Diagnostic of the mixed layer depth at v points [H ~> m or kg m-2]. + real, allocatable, dimension(:,:,:) :: Kv_u !< Total vertical viscosity at u-points [Z2 s-1 ~> m2 s-1]. + real, allocatable, dimension(:,:,:) :: Kv_v !< Total vertical viscosity at v-points [Z2 s-1 ~> m2 s-1]. + real :: zcol(SZI_(G)) ! The height of an interface at h-points [H ~> m or kg m-2]. real :: botfn ! A function which goes from 1 at the bottom to 0 much more ! than Hbbl into the interior. real :: topfn ! A function which goes from 1 at the top to 0 much more ! than Htbl into the interior. real :: z2 ! The distance from the bottom, normalized by Hbbl, nondim. real :: z2_wt ! A nondimensional (0-1) weight used when calculating z2. - real :: z_clear ! The clearance of an interface above the surrounding topography, in H. + real :: z_clear ! The clearance of an interface above the surrounding topography [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: I_valBL ! The inverse of a scaling factor determining when water is ! still within the boundary layer, as determined by the sum @@ -712,7 +707,7 @@ subroutine vertvisc_coef(u, v, h, forces, visc, dt, G, GV, US, CS, OBC) endif ; endif ! The following block calculates the thicknesses at velocity -! grid points for the vertical viscosity (hvel[k]). Near the +! grid points for the vertical viscosity (hvel). Near the ! bottom an upwind biased thickness is used to control the effect ! of spurious Montgomery potential gradients at the bottom where ! nearly massless layers layers ride over the topography. @@ -879,7 +874,7 @@ subroutine vertvisc_coef(u, v, h, forces, visc, dt, G, GV, US, CS, OBC) endif ; endif ! The following block calculates the thicknesses at velocity -! grid points for the vertical viscosity (hvel[k]). Near the +! grid points for the vertical viscosity (hvel). Near the ! bottom an upwind biased thickness is used to control the effect ! of spurious Montgomery potential gradients at the bottom where ! nearly massless layers layers ride over the topography. @@ -1033,31 +1028,31 @@ subroutine vertvisc_coef(u, v, h, forces, visc, dt, G, GV, US, CS, OBC) end subroutine vertvisc_coef -!> Calculate the 'coupling coefficient' (a[k]) at the -!! interfaces. If BOTTOMDRAGLAW is defined, the minimum of Hbbl and half the -!! adjacent layer thicknesses are used to calculate a[k] near the bottom. +!> Calculate the 'coupling coefficient' (a_cpl) at the interfaces. +!! If BOTTOMDRAGLAW is defined, the minimum of Hbbl and half the adjacent +!! layer thicknesses are used to calculate a_cpl near the bottom. subroutine find_coupling_coef(a_cpl, hvel, do_i, h_harm, bbl_thick, kv_bbl, z_i, h_ml, & dt, j, G, GV, US, CS, visc, forces, work_on_u, OBC, shelf) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZK_(GV)+1), & - intent(out) :: a_cpl !< Coupling coefficient across interfaces, in Z s-1 + intent(out) :: a_cpl !< Coupling coefficient across interfaces [Z s-1 ~> m s-1]. real, dimension(SZIB_(G),SZK_(GV)), & - intent(in) :: hvel !< Thickness at velocity points, in H + intent(in) :: hvel !< Thickness at velocity points [H ~> m or kg m-2] logical, dimension(SZIB_(G)), & intent(in) :: do_i !< If true, determine coupling coefficient for a column real, dimension(SZIB_(G),SZK_(GV)), & intent(in) :: h_harm !< Harmonic mean of thicknesses around a velocity - !! grid point, in H - real, dimension(SZIB_(G)), intent(in) :: bbl_thick !< Bottom boundary layer thickness, in H - real, dimension(SZIB_(G)), intent(in) :: kv_bbl !< Bottom boundary layer viscosity, in Z2 s-1 + !! grid point [H ~> m or kg m-2] + real, dimension(SZIB_(G)), intent(in) :: bbl_thick !< Bottom boundary layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G)), intent(in) :: kv_bbl !< Bottom boundary layer viscosity [Z2 s-1 ~> m2 s-1]. real, dimension(SZIB_(G),SZK_(GV)+1), & intent(in) :: z_i !< Estimate of interface heights above the bottom, !! normalized by the bottom boundary layer thickness - real, dimension(SZIB_(G)), intent(out) :: h_ml !< Mixed layer depth, in H + real, dimension(SZIB_(G)), intent(out) :: h_ml !< Mixed layer depth [H ~> m or kg m-2] integer, intent(in) :: j !< j-index to find coupling coefficient for - real, intent(in) :: dt !< Time increment, in s + real, intent(in) :: dt !< Time increment [s] type(vertvisc_CS), pointer :: CS !< Vertical viscosity control structure type(vertvisc_type), intent(in) :: visc !< Structure containing viscosities and bottom drag type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces @@ -1070,26 +1065,26 @@ subroutine find_coupling_coef(a_cpl, hvel, do_i, h_harm, bbl_thick, kv_bbl, z_i, ! Local variables real, dimension(SZIB_(G)) :: & - u_star, & ! ustar at a velocity point, in Z s-1. - absf, & ! The average of the neighboring absolute values of f, in s-1. -! h_ml, & ! The mixed layer depth, in m or kg m-2. + u_star, & ! ustar at a velocity point [Z s-1 ~> m s-1]. + absf, & ! The average of the neighboring absolute values of f [s-1]. +! h_ml, & ! The mixed layer depth [H ~> m or kg m-2]. nk_visc, & ! The (real) interface index of the base of mixed layer. z_t, & ! The distance from the top, sometimes normalized - ! by Hmix, in H or nondimensional. - kv_tbl, & ! The viscosity in a top boundary layer under ice, in Z2 s-1. + ! by Hmix, [H ~> m or kg m-2] or [nondim]. + kv_tbl, & ! The viscosity in a top boundary layer under ice [Z2 s-1 ~> m2 s-1]. tbl_thick real, dimension(SZIB_(G),SZK_(GV)) :: & - Kv_add ! A viscosity to add, in Z2 s-1. - real :: h_shear ! The distance over which shears occur, H. - real :: r ! A thickness to compare with Hbbl, in H. - real :: visc_ml ! The mixed layer viscosity, in Z2 s-1. - real :: I_Hmix ! The inverse of the mixed layer thickness, in H-1. + Kv_add ! A viscosity to add [Z2 s-1 ~> m2 s-1]. + real :: h_shear ! The distance over which shears occur [H ~> m or kg m-2]. + real :: r ! A thickness to compare with Hbbl [H ~> m or kg m-2]. + real :: visc_ml ! The mixed layer viscosity [Z2 s-1 ~> m2 s-1]. + real :: I_Hmix ! The inverse of the mixed layer thickness [H-1 ~> m-1 or m2 kg-1]. real :: a_ml ! The layer coupling coefficient across an interface in - ! the mixed layer, in m s-1. - real :: I_amax ! The inverse of the maximum coupling coefficient, in Z-1.??? - real :: temp1 ! A temporary variable in H Z + ! the mixed layer [m s-1]. + real :: I_amax ! The inverse of the maximum coupling coefficient [Z-1 ~> m-1].??? + real :: temp1 ! A temporary variable [H Z ~> m2 or kg m-1] real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: z2 ! A copy of z_i, nondim. real :: topfn real :: a_top @@ -1357,25 +1352,25 @@ subroutine vertvisc_limit_vel(u, v, h, ADp, CDp, forces, visc, dt, G, GV, US, CS type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(GV)), & - intent(inout) :: u !< Zonal velocity in m s-1 + intent(inout) :: u !< Zonal velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(GV)), & - intent(inout) :: v !< Meridional velocity in m s-1 + intent(inout) :: v !< Meridional velocity [m s-1] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thickness in H + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(accel_diag_ptrs), intent(in) :: ADp !< Acceleration diagnostic pointers type(cont_diag_ptrs), intent(in) :: CDp !< Continuity diagnostic pointers type(mech_forcing), intent(in) :: forces !< A structure with the driving mechanical forces type(vertvisc_type), intent(in) :: visc !< Viscosities and bottom drag - real, intent(in) :: dt !< Time increment in s + real, intent(in) :: dt !< Time increment [s] type(vertvisc_CS), pointer :: CS !< Vertical viscosity control structure ! Local variables real :: maxvel ! Velocities components greater than maxvel - real :: truncvel ! are truncated to truncvel, both in m s-1. + real :: truncvel ! are truncated to truncvel, both [m s-1]. real :: CFL ! The local CFL number. real :: H_report ! A thickness below which not to report truncations. - real :: dt_Rho0 ! The timestep divided by the Boussinesq density, in dt m3 kg-1. + real :: dt_Rho0 ! The timestep divided by the Boussinesq density [s m3 kg-1]. real :: vel_report(SZIB_(G),SZJB_(G)) real :: u_old(SZIB_(G),SZJ_(G),SZK_(G)) real :: v_old(SZI_(G),SZJB_(G),SZK_(G)) @@ -1582,8 +1577,8 @@ subroutine vertvisc_init(MIS, Time, G, GV, US, param_file, diag, ADp, dirs, & ! Local variables real :: hmix_str_dflt - real :: Kv_dflt ! A default viscosity in m2 s-1. - real :: Hmix_m ! A boundary layer thickness, in m. + real :: Kv_dflt ! A default viscosity [m2 s-1]. + real :: Hmix_m ! A boundary layer thickness [m]. integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB, nz ! This include declares and sets the variable "version". #include "version_variable.h" diff --git a/src/tracer/DOME_tracer.F90 b/src/tracer/DOME_tracer.F90 index 795d49694b..45eebb983e 100644 --- a/src/tracer/DOME_tracer.F90 +++ b/src/tracer/DOME_tracer.F90 @@ -32,6 +32,11 @@ module DOME_tracer public register_DOME_tracer, initialize_DOME_tracer public DOME_tracer_column_physics, DOME_tracer_surface_state, DOME_tracer_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + integer, parameter :: ntr = 11 !< The number of tracers in this module. !> The DOME_tracer control structure @@ -143,7 +148,7 @@ subroutine initialize_DOME_tracer(restart, day, G, GV, US, h, diag, OBC, CS, & logical, intent(in) :: restart !< .true. if the fields have already !! been read from a restart file. type(time_type), target, intent(in) :: day !< Time of the start of the run. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< Structure used to regulate diagnostic output. type(ocean_OBC_type), pointer :: OBC !< Structure specifying open boundary options. type(DOME_tracer_CS), pointer :: CS !< The control structure returned by a previous @@ -169,10 +174,10 @@ subroutine initialize_DOME_tracer(restart, day, G, GV, US, h, diag, OBC, CS, & real, pointer :: tr_ptr(:,:,:) => NULL() real :: PI ! 3.1415926... calculated as 4*atan(1) real :: tr_y ! Initial zonally uniform tracer concentrations. - real :: dist2 ! The distance squared from a line, in m2. + real :: dist2 ! The distance squared from a line [m2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in H. - real :: e(SZK_(G)+1), e_top, e_bot ! Heights in Z. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: e(SZK_(G)+1), e_top, e_bot ! Heights [Z ~> m]. real :: d_tr ! A change in tracer concentraions, in tracer units. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m integer :: IsdB, IedB, JsdB, JedB @@ -280,32 +285,32 @@ end subroutine initialize_DOME_tracer !! This is a simple example of a set of advected passive tracers. !! !! The arguments to this subroutine are redundant in that -!! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +!! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) subroutine DOME_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, & evap_CFL_limit, minimum_forcing_depth) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(DOME_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to DOME_register_tracer. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! Local variables real :: b1(SZI_(G)) ! b1 and c1 are variables used by the @@ -341,7 +346,7 @@ subroutine DOME_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(DOME_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to DOME_register_tracer. diff --git a/src/tracer/ISOMIP_tracer.F90 b/src/tracer/ISOMIP_tracer.F90 index 0707b54fb3..36bc3edb65 100644 --- a/src/tracer/ISOMIP_tracer.F90 +++ b/src/tracer/ISOMIP_tracer.F90 @@ -153,7 +153,7 @@ subroutine initialize_ISOMIP_tracer(restart, day, G, GV, h, diag, OBC, CS, & logical, intent(in) :: restart !< .true. if the fields have already !! been read from a restart file. type(time_type), target, intent(in) :: day !< Time of the start of the run. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in m or kg m-2. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -181,9 +181,9 @@ subroutine initialize_ISOMIP_tracer(restart, day, G, GV, h, diag, OBC, CS, & real, pointer :: tr_ptr(:,:,:) => NULL() real :: PI ! 3.1415926... calculated as 4*atan(1) real :: tr_y ! Initial zonally uniform tracer concentrations. - real :: dist2 ! The distance squared from a line, in m2. + real :: dist2 ! The distance squared from a line [m2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: e(SZK_(G)+1), e_top, e_bot, d_tr integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m integer :: IsdB, IedB, JsdB, JedB @@ -255,29 +255,29 @@ subroutine ISOMIP_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, G type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(ISOMIP_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to ISOMIP_register_tracer. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real :: mmax @@ -335,7 +335,7 @@ subroutine ISOMIP_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(ISOMIP_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to ISOMIP_register_tracer. diff --git a/src/tracer/MOM_OCMIP2_CFC.F90 b/src/tracer/MOM_OCMIP2_CFC.F90 index 6712088988..805409c16b 100644 --- a/src/tracer/MOM_OCMIP2_CFC.F90 +++ b/src/tracer/MOM_OCMIP2_CFC.F90 @@ -45,24 +45,28 @@ module MOM_OCMIP2_CFC type(time_type), pointer :: Time => NULL() !< A pointer to the ocean model's clock. type(tracer_registry_type), pointer :: tr_Reg => NULL() !< A pointer to the MOM6 tracer registry real, pointer, dimension(:,:,:) :: & - CFC11 => NULL(), & !< The CFC11 concentration in mol m-3. - CFC12 => NULL() !< The CFC12 concentration in mol m-3. + CFC11 => NULL(), & !< The CFC11 concentration [mol m-3]. + CFC12 => NULL() !< The CFC12 concentration [mol m-3]. ! In the following variables a suffix of _11 refers to CFC11 and _12 to CFC12. !>@{ Coefficients used in the CFC11 and CFC12 solubility calculation - real :: a1_11, a2_11, a3_11, a4_11 ! Coefficients in the calculation of the - real :: a1_12, a2_12, a3_12, a4_12 ! CFC11 and CFC12 Schmidt numbers, in - ! units of ND, degC-1, degC-2, degC-3. - real :: d1_11, d2_11, d3_11, d4_11 ! Coefficients in the calculation of the - real :: d1_12, d2_12, d3_12, d4_12 ! CFC11 and CFC12 solubilities, in units - ! of ND, K-1, log(K)^-1, K-2. - real :: e1_11, e2_11, e3_11 ! More coefficients in the calculation of - real :: e1_12, e2_12, e3_12 ! the CFC11 and CFC12 solubilities, in - ! units of PSU-1, PSU-1 K-1, PSU-1 K-2. + real :: a1_11, a1_12 ! Coefficients for calculating CFC11 and CFC12 Schmidt numbers [nondim] + real :: a2_11, a2_12 ! Coefficients for calculating CFC11 and CFC12 Schmidt numbers [degC-1] + real :: a3_11, a3_12 ! Coefficients for calculating CFC11 and CFC12 Schmidt numbers [degC-2] + real :: a4_11, a4_12 ! Coefficients for calculating CFC11 and CFC12 Schmidt numbers [degC-3] + + real :: d1_11, d1_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [nondim] + real :: d2_11, d2_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [hectoKelvin-1] + real :: d3_11, d3_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [log(hectoKelvin)-1] + real :: d4_11, d4_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [hectoKelvin-2] + + real :: e1_11, e1_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [PSU-1] + real :: e2_11, e2_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [PSU-1 hectoKelvin-1] + real :: e3_11, e3_12 ! Coefficients for calculating CFC11 and CFC12 solubilities [PSU-2 hectoKelvin-2] !!@} - real :: CFC11_IC_val = 0.0 !< The initial value assigned to CFC11. - real :: CFC12_IC_val = 0.0 !< The initial value assigned to CFC12. - real :: CFC11_land_val = -1.0 !< The value of CFC11 used where land is masked out. - real :: CFC12_land_val = -1.0 !< The value of CFC12 used where land is masked out. + real :: CFC11_IC_val = 0.0 !< The initial value assigned to CFC11 [mol m-3]. + real :: CFC12_IC_val = 0.0 !< The initial value assigned to CFC12 [mol m-3]. + real :: CFC11_land_val = -1.0 !< The value of CFC11 used where land is masked out [mol m-3]. + real :: CFC12_land_val = -1.0 !< The value of CFC12 used where land is masked out [mol m-3]. logical :: tracers_may_reinit !< If true, tracers may be reset via the initialization code !! if they are not found in the restart files. character(len=16) :: CFC11_name !< CFC11 variable name @@ -318,8 +322,7 @@ subroutine initialize_OCMIP2_CFC(restart, day, G, GV, US, h, diag, OBC, CS, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type @@ -362,7 +365,7 @@ end subroutine initialize_OCMIP2_CFC subroutine init_tracer_CFC(h, tr, name, land_val, IC_val, G, US, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(out) :: tr !< The tracer concentration array character(len=*), intent(in) :: name !< The tracer name real, intent(in) :: land_val !< A value the tracer takes over land @@ -411,33 +414,33 @@ subroutine OCMIP2_CFC_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(OCMIP2_CFC_CS), pointer :: CS !< The control structure returned by a !! previous call to register_OCMIP2_CFC. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! This subroutine applies diapycnal diffusion and any other column ! tracer physics or chemistry to the tracers from this file. ! CFCs are relatively simple, as they are passive tracers. with only a surface ! flux as a source. ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real :: b1(SZI_(G)) ! b1 and c1 are variables used by the @@ -496,11 +499,9 @@ function OCMIP2_CFC_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). - real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount - !! of each tracer, in kg times - !! concentration units. + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. + real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each + !! tracer, in kg times concentration units [kg conc]. type(OCMIP2_CFC_CS), pointer :: CS !< The control structure returned by a !! previous call to register_OCMIP2_CFC. character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated. @@ -548,21 +549,21 @@ subroutine OCMIP2_CFC_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(OCMIP2_CFC_CS), pointer :: CS !< The control structure returned by a previous !! call to register_OCMIP2_CFC. ! Local variables real, dimension(SZI_(G),SZJ_(G)) :: & - CFC11_Csurf, & ! The CFC-11 and CFC-12 surface concentrations times the - CFC12_Csurf, & ! Schmidt number term, both in mol m-3. - CFC11_alpha, & ! The CFC-11 solubility in mol m-3 pptv-1. - CFC12_alpha ! The CFC-12 solubility in mol m-3 pptv-1. - real :: ta ! Absolute sea surface temperature in units of dekaKelvin!?! - real :: sal ! Surface salinity in PSU. - real :: SST ! Sea surface temperature in degrees Celsius. - real :: alpha_11 ! The solubility of CFC 11 in mol m-3 pptv-1. - real :: alpha_12 ! The solubility of CFC 12 in mol m-3 pptv-1. + CFC11_Csurf, & ! The CFC-11 surface concentrations times the Schmidt number term [mol m-3]. + CFC12_Csurf, & ! The CFC-12 surface concentrations times the Schmidt number term [mol m-3]. + CFC11_alpha, & ! The CFC-11 solubility [mol m-3 pptv-1]. + CFC12_alpha ! The CFC-12 solubility [mol m-3 pptv-1]. + real :: ta ! Absolute sea surface temperature [hectoKelvin] (Why use such bizzare units?) + real :: sal ! Surface salinity [PSU]. + real :: SST ! Sea surface temperature [degC]. + real :: alpha_11 ! The solubility of CFC 11 [mol m-3 pptv-1]. + real :: alpha_12 ! The solubility of CFC 12 [mol m-3 pptv-1]. real :: sc_11, sc_12 ! The Schmidt numbers of CFC 11 and CFC 12. real :: sc_no_term ! A term related to the Schmidt number. integer :: i, j, m, is, ie, js, je, idim(4), jdim(4) diff --git a/src/tracer/MOM_generic_tracer.F90 b/src/tracer/MOM_generic_tracer.F90 index edcc636996..93f72b239d 100644 --- a/src/tracer/MOM_generic_tracer.F90 +++ b/src/tracer/MOM_generic_tracer.F90 @@ -231,7 +231,7 @@ subroutine initialize_MOM_generic_tracer(restart, day, G, GV, US, h, param_file, type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters type(diag_ctrl), target, intent(in) :: diag !< Regulates diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies whether, @@ -440,19 +440,19 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< The amount of fluid entrained from the layer - !! above during this call, in m or kg m-2. + !! above during this call [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< The amount of fluid entrained from the layer - !! below during this call, in m or kg m-2. + !! below during this call [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. - real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Hml !< Mixed layer depth - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, dimension(SZI_(G),SZJ_(G)), intent(in) :: Hml !< Mixed layer depth [H ~> m or kg m-2] + real, intent(in) :: dt !< The amount of time covered by this call [s] type(MOM_generic_tracer_CS), pointer :: CS !< Pointer to the control structure for this module. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables type(optics_type), intent(in) :: optics !< The structure containing optical properties. @@ -461,9 +461,9 @@ subroutine MOM_generic_tracer_column_physics(h_old, h_new, ea, eb, fluxes, Hml, real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which fluxes !! can be applied Stored previously in diabatic CS. ! The arguments to this subroutine are redundant in that - ! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] + ! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) -! Local variables + ! Local variables character(len=fm_string_len), parameter :: sub_name = 'MOM_generic_tracer_column_physics' type(g_tracer_type), pointer :: g_tracer, g_tracer_next @@ -600,9 +600,9 @@ end subroutine MOM_generic_tracer_column_physics function MOM_generic_tracer_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< The mass-weighted integrated amount of each - !! tracer, in kg times concentration units. + !! tracer, in kg times concentration units [kg conc]. type(MOM_generic_tracer_CS), pointer :: CS !< Pointer to the control structure for this module. character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated. character(len=*), dimension(:), intent(out) :: units !< The units of the stocks calculated. @@ -750,7 +750,7 @@ subroutine MOM_generic_tracer_surface_state(state, h, G, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(MOM_generic_tracer_CS), pointer :: CS !< Pointer to the control structure for this module. ! Local variables diff --git a/src/tracer/MOM_neutral_diffusion.F90 b/src/tracer/MOM_neutral_diffusion.F90 index b7d9dba592..d5a6f45c5f 100644 --- a/src/tracer/MOM_neutral_diffusion.F90 +++ b/src/tracer/MOM_neutral_diffusion.F90 @@ -55,28 +55,28 @@ module MOM_neutral_diffusion !! at a u-point integer, allocatable, dimension(:,:,:) :: uKoR !< Index of right interface corresponding to neutral surface, !! at a u-point - real, allocatable, dimension(:,:,:) :: uHeff !< Effective thickness at u-point (H units) + real, allocatable, dimension(:,:,:) :: uHeff !< Effective thickness at u-point [H ~> m or kg m-2] real, allocatable, dimension(:,:,:) :: vPoL !< Non-dimensional position with left layer uKoL-1, v-point real, allocatable, dimension(:,:,:) :: vPoR !< Non-dimensional position with right layer uKoR-1, v-point integer, allocatable, dimension(:,:,:) :: vKoL !< Index of left interface corresponding to neutral surface, !! at a v-point integer, allocatable, dimension(:,:,:) :: vKoR !< Index of right interface corresponding to neutral surface, !! at a v-point - real, allocatable, dimension(:,:,:) :: vHeff !< Effective thickness at v-point (H units) + real, allocatable, dimension(:,:,:) :: vHeff !< Effective thickness at v-point [H ~> m or kg m-2] ! Coefficients of polynomial reconstructions for temperature and salinity real, allocatable, dimension(:,:,:,:) :: ppoly_coeffs_T !< Polynomial coefficients for temperature real, allocatable, dimension(:,:,:,:) :: ppoly_coeffs_S !< Polynomial coefficients for salinity ! Variables needed for continuous reconstructions - real, allocatable, dimension(:,:,:) :: dRdT !< dRho/dT (kg/m3/degC) at interfaces - real, allocatable, dimension(:,:,:) :: dRdS !< dRho/dS (kg/m3/ppt) at interfaces - real, allocatable, dimension(:,:,:) :: Tint !< Interface T (degC) - real, allocatable, dimension(:,:,:) :: Sint !< Interface S (ppt) - real, allocatable, dimension(:,:,:) :: Pint !< Interface pressure (Pa) + real, allocatable, dimension(:,:,:) :: dRdT !< dRho/dT [kg m-3 degC-1] at interfaces + real, allocatable, dimension(:,:,:) :: dRdS !< dRho/dS [kg m-3 ppt-1] at interfaces + real, allocatable, dimension(:,:,:) :: Tint !< Interface T [degC] + real, allocatable, dimension(:,:,:) :: Sint !< Interface S [ppt] + real, allocatable, dimension(:,:,:) :: Pint !< Interface pressure [Pa] ! Variables needed for discontinuous reconstructions - real, allocatable, dimension(:,:,:,:) :: T_i !< Top edge reconstruction of temperature (degC) - real, allocatable, dimension(:,:,:,:) :: S_i !< Top edge reconstruction of salinity (ppt) - real, allocatable, dimension(:,:,:,:) :: dRdT_i !< dRho/dT (kg/m3/degC) at top edge - real, allocatable, dimension(:,:,:,:) :: dRdS_i !< dRho/dS (kg/m3/ppt) at top edge + real, allocatable, dimension(:,:,:,:) :: T_i !< Top edge reconstruction of temperature [degC] + real, allocatable, dimension(:,:,:,:) :: S_i !< Top edge reconstruction of salinity [ppt] + real, allocatable, dimension(:,:,:,:) :: dRdT_i !< dRho/dT [kg m-3 degC-1] at top edge + real, allocatable, dimension(:,:,:,:) :: dRdS_i !< dRho/dS [kg m-3 ppt-1] at top edge integer, allocatable, dimension(:,:) :: ns !< Number of interfacs in a column logical, allocatable, dimension(:,:,:) :: stable_cell !< True if the cell is stably stratified wrt to the next cell type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to @@ -233,9 +233,9 @@ end function neutral_diffusion_init subroutine neutral_diffusion_calc_coeffs(G, GV, h, T, S, CS) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (H units) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T !< Potential temperature (degC) - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S !< Salinity (ppt) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: T !< Potential temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: S !< Salinity [ppt] type(neutral_diffusion_CS), pointer :: CS !< Neutral diffusion control structure ! Local variables @@ -410,17 +410,18 @@ end subroutine neutral_diffusion_calc_coeffs subroutine neutral_diffusion(G, GV, h, Coef_x, Coef_y, dt, Reg, CS) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness (H units) - real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: Coef_x !< dt * Kh * dy / dx at u-points (m^2) - real, dimension(SZI_(G),SZJB_(G)), intent(in) :: Coef_y !< dt * Kh * dx / dy at v-points (m^2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, dimension(SZIB_(G),SZJ_(G)), intent(in) :: Coef_x !< dt * Kh * dy / dx at u-points [m2] + real, dimension(SZI_(G),SZJB_(G)), intent(in) :: Coef_y !< dt * Kh * dx / dy at v-points [m2] real, intent(in) :: dt !< Tracer time step * I_numitts !! (I_numitts in tracer_hordiff) type(tracer_registry_type), pointer :: Reg !< Tracer registry type(neutral_diffusion_CS), pointer :: CS !< Neutral diffusion control structure ! Local variables - real, dimension(SZIB_(G),SZJ_(G),CS%nsurf-1) :: uFlx ! Zonal flux of tracer (concentration * H) - real, dimension(SZI_(G),SZJB_(G),CS%nsurf-1) :: vFlx ! Meridional flux of tracer (concentration * H) + real, dimension(SZIB_(G),SZJ_(G),CS%nsurf-1) :: uFlx ! Zonal flux of tracer [H conc ~> m conc or conc kg m-2] + real, dimension(SZI_(G),SZJB_(G),CS%nsurf-1) :: vFlx ! Meridional flux of tracer + ! [H conc ~> m conc or conc kg m-2] real, dimension(SZI_(G),SZJ_(G),G%ke) :: tendency ! tendency array for diagn real, dimension(SZI_(G),SZJ_(G)) :: tendency_2d ! depth integrated content tendency for diagn real, dimension(SZIB_(G),SZJ_(G)) :: trans_x_2d ! depth integrated diffusive tracer x-transport diagn @@ -568,12 +569,12 @@ end subroutine neutral_diffusion !> Returns interface scalar, Si, for a column of layer values, S. subroutine interface_scalar(nk, h, S, Si, i_method, h_neglect) integer, intent(in) :: nk !< Number of levels - real, dimension(nk), intent(in) :: h !< Layer thickness (H units) + real, dimension(nk), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] real, dimension(nk), intent(in) :: S !< Layer scalar (conc, e.g. ppt) real, dimension(nk+1), intent(inout) :: Si !< Interface scalar (conc, e.g. ppt) integer, intent(in) :: i_method !< =1 use average of PLM edges !! =2 use continuous PPM edge interpolation - real, intent(in) :: h_neglect !< A negligibly small thickness (H units) + real, intent(in) :: h_neglect !< A negligibly small thickness [H ~> m or kg m-2] ! Local variables integer :: k, km2, kp1 real, dimension(nk) :: diff @@ -613,7 +614,7 @@ real function ppm_edge(hkm1, hk, hkp1, hkp2, Ak, Akp1, Pk, Pkp1, h_neglect) real, intent(in) :: Akp1 !< Average scalar value of cell k+1 real, intent(in) :: Pk !< PLM slope for cell k real, intent(in) :: Pkp1 !< PLM slope for cell k+1 - real, intent(in) :: h_neglect !< A negligibly small thickness (H units) + real, intent(in) :: h_neglect !< A negligibly small thickness [H ~> m or kg m-2] ! Local variables real :: R_hk_hkp1, R_2hk_hkp1, R_hk_2hkp1, f1, f2, f3, f4 @@ -684,7 +685,7 @@ end function signum !! The limiting follows equation 1.8 in Colella & Woodward, 1984: JCP 54, 174-201. subroutine PLM_diff(nk, h, S, c_method, b_method, diff) integer, intent(in) :: nk !< Number of levels - real, dimension(nk), intent(in) :: h !< Layer thickness (H units) + real, dimension(nk), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] real, dimension(nk), intent(in) :: S !< Layer salinity (conc, e.g. ppt) integer, intent(in) :: c_method !< Method to use for the centered difference integer, intent(in) :: b_method !< =1, use PCM in first/last cell, =2 uses linear extrapolation @@ -808,23 +809,23 @@ end function fvlsq_slope subroutine find_neutral_surface_positions_continuous(nk, Pl, Tl, Sl, dRdTl, dRdSl, Pr, Tr, Sr, & dRdTr, dRdSr, PoL, PoR, KoL, KoR, hEff) integer, intent(in) :: nk !< Number of levels - real, dimension(nk+1), intent(in) :: Pl !< Left-column interface pressure (Pa) - real, dimension(nk+1), intent(in) :: Tl !< Left-column interface potential temperature (degC) - real, dimension(nk+1), intent(in) :: Sl !< Left-column interface salinity (ppt) - real, dimension(nk+1), intent(in) :: dRdTl !< Left-column dRho/dT (kg/m3/degC) - real, dimension(nk+1), intent(in) :: dRdSl !< Left-column dRho/dS (kg/m3/ppt) - real, dimension(nk+1), intent(in) :: Pr !< Right-column interface pressure (Pa) - real, dimension(nk+1), intent(in) :: Tr !< Right-column interface potential temperature (degC) - real, dimension(nk+1), intent(in) :: Sr !< Right-column interface salinity (ppt) - real, dimension(nk+1), intent(in) :: dRdTr !< Left-column dRho/dT (kg/m3/degC) - real, dimension(nk+1), intent(in) :: dRdSr !< Left-column dRho/dS (kg/m3/ppt) + real, dimension(nk+1), intent(in) :: Pl !< Left-column interface pressure [Pa] + real, dimension(nk+1), intent(in) :: Tl !< Left-column interface potential temperature [degC] + real, dimension(nk+1), intent(in) :: Sl !< Left-column interface salinity [ppt] + real, dimension(nk+1), intent(in) :: dRdTl !< Left-column dRho/dT [kg m-3 degC-1] + real, dimension(nk+1), intent(in) :: dRdSl !< Left-column dRho/dS [kg m-3 ppt-1] + real, dimension(nk+1), intent(in) :: Pr !< Right-column interface pressure [Pa] + real, dimension(nk+1), intent(in) :: Tr !< Right-column interface potential temperature [degC] + real, dimension(nk+1), intent(in) :: Sr !< Right-column interface salinity [ppt] + real, dimension(nk+1), intent(in) :: dRdTr !< Left-column dRho/dT [kg m-3 degC-1] + real, dimension(nk+1), intent(in) :: dRdSr !< Left-column dRho/dS [kg m-3 ppt-1] real, dimension(2*nk+2), intent(inout) :: PoL !< Fractional position of neutral surface within !! layer KoL of left column real, dimension(2*nk+2), intent(inout) :: PoR !< Fractional position of neutral surface within !! layer KoR of right column integer, dimension(2*nk+2), intent(inout) :: KoL !< Index of first left interface above neutral surface integer, dimension(2*nk+2), intent(inout) :: KoR !< Index of first right interface above neutral surface - real, dimension(2*nk+1), intent(inout) :: hEff !< Effective thickness between two neutral surfaces (Pa) + real, dimension(2*nk+1), intent(inout) :: hEff !< Effective thickness between two neutral surfaces [Pa] ! Local variables integer :: ns ! Number of neutral surfaces @@ -993,27 +994,27 @@ subroutine find_neutral_surface_positions_discontinuous(CS, nk, ns, Pres_l, hcol type(neutral_diffusion_CS), intent(inout) :: CS !< Neutral diffusion control structure integer, intent(in) :: nk !< Number of levels integer, intent(in) :: ns !< Number of neutral surfaces - real, dimension(nk+1), intent(in) :: Pres_l !< Left-column interface pressure (Pa) + real, dimension(nk+1), intent(in) :: Pres_l !< Left-column interface pressure [Pa] real, dimension(nk), intent(in) :: hcol_l !< Left-column layer thicknesses - real, dimension(nk,2), intent(in) :: Tl !< Left-column top interface potential temperature (degC) - real, dimension(nk,2), intent(in) :: Sl !< Left-column top interface salinity (ppt) - real, dimension(nk,2), intent(in) :: dRdT_l !< Left-column, top interface dRho/dT (kg/m3/degC) - real, dimension(nk,2), intent(in) :: dRdS_l !< Left-column, top interface dRho/dS (kg/m3/ppt) - logical, dimension(nk), intent(in) :: stable_l !< Left-column, top interface dRho/dS (kg/m3/ppt) - real, dimension(nk+1), intent(in) :: Pres_r !< Right-column interface pressure (Pa) + real, dimension(nk,2), intent(in) :: Tl !< Left-column top interface potential temperature [degC] + real, dimension(nk,2), intent(in) :: Sl !< Left-column top interface salinity [ppt] + real, dimension(nk,2), intent(in) :: dRdT_l !< Left-column, top interface dRho/dT [kg m-3 degC-1] + real, dimension(nk,2), intent(in) :: dRdS_l !< Left-column, top interface dRho/dS [kg m-3 ppt-1] + logical, dimension(nk), intent(in) :: stable_l !< Left-column, top interface is stable + real, dimension(nk+1), intent(in) :: Pres_r !< Right-column interface pressure [Pa] real, dimension(nk), intent(in) :: hcol_r !< Left-column layer thicknesses - real, dimension(nk,2), intent(in) :: Tr !< Right-column top interface potential temperature (degC) - real, dimension(nk,2), intent(in) :: Sr !< Right-column top interface salinity (ppt) - real, dimension(nk,2), intent(in) :: dRdT_r !< Right-column, top interface dRho/dT (kg/m3/degC) - real, dimension(nk,2), intent(in) :: dRdS_r !< Right-column, top interface dRho/dS (kg/m3/ppt) - logical, dimension(nk), intent(in) :: stable_r !< Left-column, top interface dRho/dS (kg/m3/ppt) + real, dimension(nk,2), intent(in) :: Tr !< Right-column top interface potential temperature [degC] + real, dimension(nk,2), intent(in) :: Sr !< Right-column top interface salinity [ppt] + real, dimension(nk,2), intent(in) :: dRdT_r !< Right-column, top interface dRho/dT [kg m-3 degC-1] + real, dimension(nk,2), intent(in) :: dRdS_r !< Right-column, top interface dRho/dS [kg m-3 ppt-1] + logical, dimension(nk), intent(in) :: stable_r !< Right-column, top interface is stable real, dimension(4*nk), intent(inout) :: PoL !< Fractional position of neutral surface within !! layer KoL of left column real, dimension(4*nk), intent(inout) :: PoR !< Fractional position of neutral surface within !! layer KoR of right column integer, dimension(4*nk), intent(inout) :: KoL !< Index of first left interface above neutral surface integer, dimension(4*nk), intent(inout) :: KoR !< Index of first right interface above neutral surface - real, dimension(4*nk-1), intent(inout) :: hEff !< Effective thickness between two neutral surfaces (Pa) + real, dimension(4*nk-1), intent(inout) :: hEff !< Effective thickness between two neutral surfaces [Pa] real, dimension(nk,CS%deg+1), & optional, intent(in) :: ppoly_T_l !< Left-column coefficients of T reconstruction real, dimension(nk,CS%deg+1), & @@ -1264,7 +1265,7 @@ end subroutine find_neutral_surface_positions_discontinuous real function absolute_position(n,ns,Pint,Karr,NParr,k_surface) integer, intent(in) :: n !< Number of levels integer, intent(in) :: ns !< Number of neutral surfaces - real, intent(in) :: Pint(n+1) !< Position of interfaces (Pa) + real, intent(in) :: Pint(n+1) !< Position of interfaces [Pa] integer, intent(in) :: Karr(ns) !< Index of interface above position real, intent(in) :: NParr(ns) !< Non-dimensional position within layer Karr(:) integer, intent(in) :: k_surface !< k-interface to query @@ -1281,11 +1282,11 @@ end function absolute_position function absolute_positions(n,ns,Pint,Karr,NParr) integer, intent(in) :: n !< Number of levels integer, intent(in) :: ns !< Number of neutral surfaces - real, intent(in) :: Pint(n+1) !< Position of interface (Pa) + real, intent(in) :: Pint(n+1) !< Position of interface [Pa] integer, intent(in) :: Karr(ns) !< Indexes of interfaces about positions real, intent(in) :: NParr(ns) !< Non-dimensional positions within layers Karr(:) - real, dimension(ns) :: absolute_positions ! Absolute positions (Pa) + real, dimension(ns) :: absolute_positions ! Absolute positions [Pa] ! Local variables integer :: k_surface, k @@ -1302,8 +1303,8 @@ subroutine neutral_surface_flux(nk, nsurf, deg, hl, hr, Tl, Tr, PiL, PiR, KoL, K integer, intent(in) :: nk !< Number of levels integer, intent(in) :: nsurf !< Number of neutral surfaces integer, intent(in) :: deg !< Degree of polynomial reconstructions - real, dimension(nk), intent(in) :: hl !< Left-column layer thickness (Pa) - real, dimension(nk), intent(in) :: hr !< Right-column layer thickness (Pa) + real, dimension(nk), intent(in) :: hl !< Left-column layer thickness [Pa] + real, dimension(nk), intent(in) :: hr !< Right-column layer thickness [Pa] real, dimension(nk), intent(in) :: Tl !< Left-column layer tracer (conc, e.g. degC) real, dimension(nk), intent(in) :: Tr !< Right-column layer tracer (conc, e.g. degC) real, dimension(nsurf), intent(in) :: PiL !< Fractional position of neutral surface @@ -1312,7 +1313,7 @@ subroutine neutral_surface_flux(nk, nsurf, deg, hl, hr, Tl, Tr, PiL, PiR, KoL, K !! within layer KoR of right column integer, dimension(nsurf), intent(in) :: KoL !< Index of first left interface above neutral surface integer, dimension(nsurf), intent(in) :: KoR !< Index of first right interface above neutral surface - real, dimension(nsurf-1), intent(in) :: hEff !< Effective thickness between two neutral surfaces (Pa) + real, dimension(nsurf-1), intent(in) :: hEff !< Effective thickness between two neutral surfaces [Pa] real, dimension(nsurf-1), intent(inout) :: Flx !< Flux of tracer between pairs of neutral layers (conc H) logical, intent(in) :: continuous !< True if using continuous reconstruction real, intent(in) :: h_neglect !< A negligibly small width for the @@ -1992,7 +1993,7 @@ logical function test_fv_diff(verbose, hkm1, hk, hkp1, Skm1, Sk, Skp1, Ptrue, ti real, intent(in) :: Skm1 !< Left cell average value real, intent(in) :: Sk !< Center cell average value real, intent(in) :: Skp1 !< Right cell average value - real, intent(in) :: Ptrue !< True answer (Pa) + real, intent(in) :: Ptrue !< True answer [Pa] character(len=*), intent(in) :: title !< Title for messages ! Local variables @@ -2024,7 +2025,7 @@ logical function test_fvlsq_slope(verbose, hkm1, hk, hkp1, Skm1, Sk, Skp1, Ptrue real, intent(in) :: Skm1 !< Left cell average value real, intent(in) :: Sk !< Center cell average value real, intent(in) :: Skp1 !< Right cell average value - real, intent(in) :: Ptrue !< True answer (Pa) + real, intent(in) :: Ptrue !< True answer [Pa] character(len=*), intent(in) :: title !< Title for messages ! Local variables @@ -2050,11 +2051,11 @@ end function test_fvlsq_slope !> Returns true if a test of interpolate_for_nondim_position() fails, and conditionally writes results to stream logical function test_ifndp(verbose, rhoNeg, Pneg, rhoPos, Ppos, Ptrue, title) logical, intent(in) :: verbose !< If true, write results to stdout - real, intent(in) :: rhoNeg !< Lighter density (kg/m3) - real, intent(in) :: Pneg !< Interface position of lighter density (Pa) - real, intent(in) :: rhoPos !< Heavier density (kg/m3) - real, intent(in) :: Ppos !< Interface position of heavier density (Pa) - real, intent(in) :: Ptrue !< True answer (Pa) + real, intent(in) :: rhoNeg !< Lighter density [kg m-3] + real, intent(in) :: Pneg !< Interface position of lighter density [Pa] + real, intent(in) :: rhoPos !< Heavier density [kg m-3] + real, intent(in) :: Ppos !< Interface position of heavier density [Pa] + real, intent(in) :: Ptrue !< True answer [Pa] character(len=*), intent(in) :: title !< Title for messages ! Local variables @@ -2156,7 +2157,7 @@ logical function test_nsp(verbose, ns, KoL, KoR, pL, pR, hEff, KoL0, KoR0, pL0, integer, dimension(ns), intent(in) :: KoR !< Index of first right interface above neutral surface real, dimension(ns), intent(in) :: pL !< Fractional position of neutral surface within layer KoL of left column real, dimension(ns), intent(in) :: pR !< Fractional position of neutral surface within layer KoR of right column - real, dimension(ns-1), intent(in) :: hEff !< Effective thickness between two neutral surfaces (Pa) + real, dimension(ns-1), intent(in) :: hEff !< Effective thickness between two neutral surfaces [Pa] integer, dimension(ns), intent(in) :: KoL0 !< Correct value for KoL integer, dimension(ns), intent(in) :: KoR0 !< Correct value for KoR real, dimension(ns), intent(in) :: pL0 !< Correct value for pL diff --git a/src/tracer/MOM_neutral_diffusion_aux.F90 b/src/tracer/MOM_neutral_diffusion_aux.F90 index c25564b8da..88df1ddbc5 100644 --- a/src/tracer/MOM_neutral_diffusion_aux.F90 +++ b/src/tracer/MOM_neutral_diffusion_aux.F90 @@ -24,8 +24,8 @@ module MOM_neutral_diffusion_aux type, public :: ndiff_aux_CS_type ; private integer :: nterm !< Number of terms in polynomial (deg+1) integer :: max_iter !< Maximum number of iterations - real :: drho_tol !< Tolerance criterion for difference in density (kg/m3) - real :: xtol !< Criterion for how much position changes (nondim) + real :: drho_tol !< Tolerance criterion for difference in density [kg m-3] + real :: xtol !< Criterion for how much position changes [nondim] real :: ref_pres !< Determines whether a constant reference pressure is used everywhere or locally referenced !< density is done. ref_pres <-1 is the latter, ref_pres >= 0. otherwise logical :: force_brent = .false. !< Use Brent's method instead of Newton even when second derivatives are available @@ -62,10 +62,10 @@ end subroutine set_ndiff_aux_params !! For an layer to be unstable the top interface must be denser than the bottom or the bottom interface of the layer subroutine mark_unstable_cells(nk, dRdT, dRdS,T, S, stable_cell, ns) integer, intent(in) :: nk !< Number of levels in a column - real, dimension(nk,2), intent(in) :: dRdT !< drho/dT (kg/m3/degC) at interfaces - real, dimension(nk,2), intent(in) :: dRdS !< drho/dS (kg/m3/ppt) at interfaces - real, dimension(nk,2), intent(in) :: T !< drho/dS (kg/m3/ppt) at interfaces - real, dimension(nk,2), intent(in) :: S !< drho/dS (kg/m3/ppt) at interfaces + real, dimension(nk,2), intent(in) :: dRdT !< drho/dT [kg m-3 degC-1] at interfaces + real, dimension(nk,2), intent(in) :: dRdS !< drho/dS [kg m-3 ppt-1] at interfaces + real, dimension(nk,2), intent(in) :: T !< Temperature [degC] at interfaces + real, dimension(nk,2), intent(in) :: S !< Salinity [ppt] at interfaces logical, dimension(nk), intent( out) :: stable_cell !< True if this cell is unstably stratified integer, intent( out) :: ns !< Number of neutral surfaces in unmasked part of the column diff --git a/src/tracer/MOM_offline_aux.F90 b/src/tracer/MOM_offline_aux.F90 index dc616e8a49..89f4a6eef4 100644 --- a/src/tracer/MOM_offline_aux.F90 +++ b/src/tracer/MOM_offline_aux.F90 @@ -47,13 +47,13 @@ subroutine update_h_horizontal_flux(G, GV, uhtr, vhtr, h_pre, h_new) type(ocean_grid_type), pointer :: G !< ocean grid structure type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: uhtr !< Accumulated mass flux through zonal face, in kg + intent(in) :: uhtr !< Accumulated mass flux through zonal face [kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: vhtr !< Accumulated mass flux through meridional face, in kg + intent(in) :: vhtr !< Accumulated mass flux through meridional face [kg] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_pre !< Previous layer thicknesses, in kg m-2. + intent(in) :: h_pre !< Previous layer thicknesses [kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h_new !< Updated layer thicknesses, in kg m-2. + intent(inout) :: h_new !< Updated layer thicknesses [kg m-2]. ! Local variables integer :: i, j, k, m, is, ie, js, je, nz @@ -86,15 +86,15 @@ subroutine update_h_vertical_flux(G, GV, ea, eb, h_pre, h_new) type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< Mass of fluid entrained from the layer - !! above within this timestep, in kg m-2 + !! above within this timestep [kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< Mass of fluid entrained from the layer - !! below within this timestep, in kg m-2 + !! below within this timestep [kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: h_pre !< Layer thicknesses at the end of the previous - !! step, in kg m-2. + !! step [kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h_new !< Updated layer thicknesses, in kg m-2. + intent(inout) :: h_new !< Updated layer thicknesses [kg m-2]. ! Local variables integer :: i, j, k, m, is, ie, js, je, nz @@ -138,18 +138,18 @@ subroutine limit_mass_flux_3d(G, GV, uh, vh, ea, eb, h_pre) type(ocean_grid_type), pointer :: G !< ocean grid structure type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: uh !< Mass flux through zonal face, in kg + intent(inout) :: uh !< Mass flux through zonal face [kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: vh !< Mass flux through meridional face, in kg + intent(inout) :: vh !< Mass flux through meridional face [kg] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: ea !< Mass of fluid entrained from the layer - !! above within this timestep, in kg m-2 + !! above within this timestep [kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: eb !< Mass of fluid entrained from the layer - !! below within this timestep, in kg m-2 + !! below within this timestep [kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: h_pre !< Layer thicknesses at the end of the previous - !! step, in kg m-2. + !! step [kg m-2]. ! Local variables integer :: i, j, k, m, is, ie, js, je, nz @@ -242,9 +242,9 @@ subroutine distribute_residual_uh_barotropic(G, GV, hvol, uh) type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in ) :: hvol !< Mass of water in the cells at the end - !! of the previous timestep, in kg + !! of the previous timestep [kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: uh !< Zonal mass transport within a timestep, in kg + intent(inout) :: uh !< Zonal mass transport within a timestep [kg] real, dimension(SZIB_(G),SZK_(G)) :: uh2d real, dimension(SZIB_(G)) :: uh2d_sum @@ -313,9 +313,9 @@ subroutine distribute_residual_vh_barotropic(G, GV, hvol, vh) type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in ) :: hvol !< Mass of water in the cells at the end - !! of the previous timestep, in kg + !! of the previous timestep [kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: vh !< Meridional mass transport within a timestep, in kg + intent(inout) :: vh !< Meridional mass transport within a timestep [kg] real, dimension(SZJB_(G),SZK_(G)) :: vh2d real, dimension(SZJB_(G)) :: vh2d_sum @@ -386,9 +386,9 @@ subroutine distribute_residual_uh_upwards(G, GV, hvol, uh) type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in ) :: hvol !< Mass of water in the cells at the end - !! of the previous timestep, in kg + !! of the previous timestep [kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: uh !< Zonal mass transport within a timestep, in kg + intent(inout) :: uh !< Zonal mass transport within a timestep [kg] real, dimension(SZIB_(G),SZK_(G)) :: uh2d real, dimension(SZI_(G),SZK_(G)) :: h2d @@ -482,9 +482,9 @@ subroutine distribute_residual_vh_upwards(G, GV, hvol, vh) type(verticalGrid_type), pointer :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in ) :: hvol !< Mass of water in the cells at the end - !! of the previous timestep, in kg + !! of the previous timestep [kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: vh !< Meridional mass transport within a timestep, in kg + intent(inout) :: vh !< Meridional mass transport within a timestep [kg] real, dimension(SZJB_(G),SZK_(G)) :: vh2d real, dimension(SZJB_(G)) :: vh2d_sum @@ -637,9 +637,9 @@ subroutine update_offline_from_files(G, GV, nk_input, mean_file, sum_file, snap_ character(len=*), intent(in ) :: snap_file !< Name of file with snapshot fields character(len=*), intent(in ) :: surf_file !< Name of file with surface fields real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: uhtr !< Zonal mass fluxes in kg + intent(inout) :: uhtr !< Zonal mass fluxes [kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: vhtr !< Meridional mass fluxes in kg + intent(inout) :: vhtr !< Meridional mass fluxes [kg] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(inout) :: h_end !< End of timestep layer thickness real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & @@ -770,12 +770,12 @@ subroutine update_offline_from_arrays(G, GV, nk_input, ridx_sum, mean_file, sum_ character(len=200), intent(in ) :: mean_file !< Name of file with averages fields character(len=200), intent(in ) :: sum_file !< Name of file with summed fields character(len=200), intent(in ) :: snap_file !< Name of file with snapshot fields - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Zonal mass fluxes in kg - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Meridional mass fluxes in kg - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: hend !< End of timestep layer thickness in kg m-2 - real, dimension(:,:,:,:), allocatable, intent(inout) :: uhtr_all !< Zonal mass fluxes in kg - real, dimension(:,:,:,:), allocatable, intent(inout) :: vhtr_all !< Meridional mass fluxes in kg - real, dimension(:,:,:,:), allocatable, intent(inout) :: hend_all !< End of timestep layer thickness in kg m-2 + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhtr !< Zonal mass fluxes [kg] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhtr !< Meridional mass fluxes [kg] + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: hend !< End of timestep layer thickness [kg m-2] + real, dimension(:,:,:,:), allocatable, intent(inout) :: uhtr_all !< Zonal mass fluxes [kg] + real, dimension(:,:,:,:), allocatable, intent(inout) :: vhtr_all !< Meridional mass fluxes [kg] + real, dimension(:,:,:,:), allocatable, intent(inout) :: hend_all !< End of timestep layer thickness [kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: temp !< Temperature array real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: salt !< Salinity array real, dimension(:,:,:,:), allocatable, intent(inout) :: temp_all !< Temperature array diff --git a/src/tracer/MOM_offline_main.F90 b/src/tracer/MOM_offline_main.F90 index 8a59f69a61..a4676583bd 100644 --- a/src/tracer/MOM_offline_main.F90 +++ b/src/tracer/MOM_offline_main.F90 @@ -112,8 +112,8 @@ module MOM_offline_main integer :: num_off_iter !< Number of advection iterations per offline step integer :: num_vert_iter !< Number of vertical iterations per offline step integer :: off_ale_mod !< Sets how frequently the ALE step is done during the advection - real :: dt_offline !< Timestep used for offline tracers - real :: dt_offline_vertical !< Timestep used for calls to tracer vertical physics + real :: dt_offline !< Timestep used for offline tracers [s] + real :: dt_offline_vertical !< Timestep used for calls to tracer vertical physics [s] real :: evap_CFL_limit !< Copied from diabatic_CS controlling how tracers follow freshwater fluxes real :: minimum_forcing_depth !< Copied from diabatic_CS controlling how tracers follow freshwater fluxes real :: Kd_max !< Runtime parameter specifying the maximum value of vertical diffusivity @@ -158,17 +158,17 @@ module MOM_offline_main ! Fields at T-point real, allocatable, dimension(:,:,:) :: eatr !< Amount of fluid entrained from the layer above within - !! one time step (m for Bouss, kg/m^2 for non-Bouss) + !! one time step [H ~> m or kg m-2] real, allocatable, dimension(:,:,:) :: ebtr !< Amount of fluid entrained from the layer below within - !! one time step (m for Bouss, kg/m^2 for non-Bouss) + !! one time step [H ~> m or kg m-2] ! Fields at T-points on interfaces real, allocatable, dimension(:,:,:) :: Kd !< Vertical diffusivity real, allocatable, dimension(:,:,:) :: h_end !< Thicknesses at the end of offline timestep real, allocatable, dimension(:,:) :: netMassIn !< Freshwater fluxes into the ocean real, allocatable, dimension(:,:) :: netMassOut !< Freshwater fluxes out of the ocean - real, allocatable, dimension(:,:) :: mld !< Mixed layer depths at thickness points, in H. + real, allocatable, dimension(:,:) :: mld !< Mixed layer depths at thickness points [H ~> m or kg m-2]. ! Allocatable arrays to read in entire fields during initialization real, allocatable, dimension(:,:,:,:) :: uhtr_all !< Entire field of zonal transport @@ -205,11 +205,12 @@ subroutine offline_advection_ale(fluxes, Time_start, time_interval, CS, id_clock type(offline_transport_CS), pointer :: CS !< control structure for offline module integer, intent(in) :: id_clock_ALE !< Clock for ALE routines real, dimension(SZI_(CS%G),SZJ_(CS%G),SZK_(CS%G)), & - intent(inout) :: h_pre !< layer thicknesses before advection in m or kg m-2 + intent(inout) :: h_pre !< layer thicknesses before advection + !! [H ~> m or kg m-2] real, dimension(SZIB_(CS%G),SZJ_(CS%G),SZK_(CS%G)), & - intent(inout) :: uhtr !< Zonal mass transport in m3 or kg + intent(inout) :: uhtr !< Zonal mass transport [H m2 ~> m3 or kg] real, dimension(SZI_(CS%G),SZJB_(CS%G),SZK_(CS%G)), & - intent(inout) :: vhtr !< Meridional mass transport in m3 or kg + intent(inout) :: vhtr !< Meridional mass transport [H m2 ~> m3 or kg] logical, intent( out) :: converged !< True if the iterations have converged ! Local pointers @@ -646,11 +647,11 @@ subroutine offline_diabatic_ale(fluxes, Time_start, Time_end, CS, h_pre, eatr, e type(time_type), intent(in) :: Time_end !< time interval type(offline_transport_CS), pointer :: CS !< control structure from initialize_MOM real, dimension(SZI_(CS%G),SZJ_(CS%G),SZK_(CS%G)), & - intent(inout) :: h_pre !< layer thicknesses before advection in m or kg m-2 + intent(inout) :: h_pre !< layer thicknesses before advection [H ~> m or kg m-2] real, dimension(SZI_(CS%G),SZJ_(CS%G),SZK_(CS%G)), & - intent(inout) :: eatr !< Entrainment from layer above in m or kg-2 + intent(inout) :: eatr !< Entrainment from layer above [H ~> m or kg m-2] real, dimension(SZI_(CS%G),SZJ_(CS%G),SZK_(CS%G)), & - intent(inout) :: ebtr !< Entrainment from layer below in m or kg-2 + intent(inout) :: ebtr !< Entrainment from layer below [H ~> m or kg m-2] real, dimension(SZI_(CS%G),SZJ_(CS%G)) :: sw, sw_vis, sw_nir !< Save old value of shortwave radiation real :: hval @@ -749,7 +750,7 @@ subroutine offline_fw_fluxes_into_ocean(G, GV, CS, fluxes, h, in_flux_optional) type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(forcing), intent(inout) :: fluxes !< Surface fluxes container real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thickness in H units + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G)), & optional, intent(in) :: in_flux_optional !< The total time-integrated amount !! of tracer that leaves with freshwater @@ -799,7 +800,7 @@ subroutine offline_fw_fluxes_out_ocean(G, GV, CS, fluxes, h, out_flux_optional) type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure type(forcing), intent(inout) :: fluxes !< Surface fluxes container real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: h !< Layer thickness in H units + intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G)), & optional, intent(in) :: out_flux_optional !< The total time-integrated amount !! of tracer that leaves with freshwater @@ -1186,18 +1187,20 @@ subroutine extract_offline_main(CS, uhtr, vhtr, eatr, ebtr, h_end, accumulated_t dt_offline, dt_offline_vertical, skip_diffusion) type(offline_transport_CS), target, intent(in ) :: CS !< Offline control structure ! Returned optional arguments - real, dimension(:,:,:), optional, pointer :: uhtr !< Remaining zonal mass transport - real, dimension(:,:,:), optional, pointer :: vhtr !< Remaining meridional mass transport + real, dimension(:,:,:), optional, pointer :: uhtr !< Remaining zonal mass transport [H m2 ~> m3 or kg] + real, dimension(:,:,:), optional, pointer :: vhtr !< Remaining meridional mass transport [H m2 ~> m3 or kg] real, dimension(:,:,:), optional, pointer :: eatr !< Amount of fluid entrained from the layer above within - !! one time step (m for Bouss, kg/m^2 for non-Bouss) + !! one time step [H ~> m or kg m-2] real, dimension(:,:,:), optional, pointer :: ebtr !< Amount of fluid entrained from the layer below within - !! one time step (m for Bouss, kg/m^2 for non-Bouss) - real, dimension(:,:,:), optional, pointer :: h_end !< Thicknesses at the end of offline timestep in m or kg m-2 + !! one time step [H ~> m or kg m-2] + real, dimension(:,:,:), optional, pointer :: h_end !< Thicknesses at the end of offline timestep + !! [H ~> m or kg m-2] + !### Why are the following variables integers? integer, optional, pointer :: accumulated_time !< Length of time accumulated in the - !! current offline interval - integer, optional, intent( out) :: dt_offline !< Timestep used for offline tracers + !! current offline interval [s] + integer, optional, intent( out) :: dt_offline !< Timestep used for offline tracers [s] integer, optional, intent( out) :: dt_offline_vertical !< Timestep used for calls to tracer - !! vertical physics + !! vertical physics [s] logical, optional, intent( out) :: skip_diffusion !< Skips horizontal diffusion of tracers ! Pointers to 3d members diff --git a/src/tracer/MOM_tracer_Z_init.F90 b/src/tracer/MOM_tracer_Z_init.F90 index d78821cd46..dd44fb15b2 100644 --- a/src/tracer/MOM_tracer_Z_init.F90 +++ b/src/tracer/MOM_tracer_Z_init.F90 @@ -18,6 +18,11 @@ module MOM_tracer_Z_init public tracer_Z_init +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> This function initializes a tracer by reading a Z-space file, returning @@ -29,7 +34,7 @@ function tracer_Z_init(tr, h, filename, tr_name, G, US, missing_val, land_val) real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(out) :: tr !< The tracer to initialize real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] character(len=*), intent(in) :: filename !< The name of the file to read from character(len=*), intent(in) :: tr_name !< The name of the tracer in the file ! type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters @@ -49,7 +54,7 @@ function tracer_Z_init(tr, h, filename, tr_name, G, US, missing_val, land_val) tr_in ! The z-space array of tracer concentrations that is read in. real, allocatable, dimension(:) :: & z_edges, & ! The depths of the cell edges or cell centers (depending on - ! the value of has_edges) in the input z* data, in depth units (Z). + ! the value of has_edges) in the input z* data [Z ~> m]. tr_1d, & ! A copy of the input tracer concentrations in a column. wt, & ! The fractional weight for each layer in the range between ! k_top and k_bot, nondim. @@ -57,11 +62,11 @@ function tracer_Z_init(tr, h, filename, tr_name, G, US, missing_val, land_val) z2 ! of a z-cell that contributes to a layer, relative to the cell ! center and normalized by the cell thickness, nondim. ! Note that -1/2 <= z1 <= z2 <= 1/2. - real :: e(SZK_(G)+1) ! The z-star interface heights in Z. + real :: e(SZK_(G)+1) ! The z-star interface heights [Z ~> m]. real :: landval ! The tracer value to use in land points. real :: sl_tr ! The normalized slope of the tracer ! within the cell, in tracer units. - real :: htot(SZI_(G)) ! The vertical sum of h, in m or kg m-2. + real :: htot(SZI_(G)) ! The vertical sum of h [H ~> m or kg m-2]. real :: dilate ! The amount by which the thicknesses are dilated to ! create a z-star coordinate, nondim or in m3 kg-1. real :: missing ! The missing value for the tracer. diff --git a/src/tracer/MOM_tracer_advect.F90 b/src/tracer/MOM_tracer_advect.F90 index 589ad07e19..201f8aeb6f 100644 --- a/src/tracer/MOM_tracer_advect.F90 +++ b/src/tracer/MOM_tracer_advect.F90 @@ -28,7 +28,7 @@ module MOM_tracer_advect !> Control structure for this module type, public :: tracer_advect_CS ; private - real :: dt !< The baroclinic dynamics time step, in s. + real :: dt !< The baroclinic dynamics time step [s]. type(diag_ctrl), pointer :: diag !< A structure that is used to regulate the !< timing of diagnostic output. logical :: debug !< If true, write verbose checksums for debugging purposes. @@ -52,40 +52,42 @@ subroutine advect_tracer(h_end, uhtr, vhtr, OBC, dt, G, GV, CS, Reg, & type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_end !< layer thickness after advection (m or kg m-2) + intent(in) :: h_end !< layer thickness after advection [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(in) :: uhtr !< accumulated volume/mass flux through zonal face (m3 or kg) + intent(in) :: uhtr !< accumulated volume/mass flux through zonal face [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(in) :: vhtr !< accumulated volume/mass flux through merid face (m3 or kg) + intent(in) :: vhtr !< accumulated volume/mass flux through merid face [H m2 ~> m3 or kg] type(ocean_OBC_type), pointer :: OBC !< specifies whether, where, and what OBCs are used - real, intent(in) :: dt !< time increment (seconds) + real, intent(in) :: dt !< time increment [s] type(tracer_advect_CS), pointer :: CS !< control structure for module type(tracer_registry_type), pointer :: Reg !< pointer to tracer registry real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - optional, intent(in) :: h_prev_opt !< layer thickness before advection (m or kg m-2) + optional, intent(in) :: h_prev_opt !< layer thickness before advection [H ~> m or kg m-2] integer, optional, intent(in) :: max_iter_in !< The maximum number of iterations logical, optional, intent(in) :: x_first_in !< If present, indicate whether to update !! first in the x- or y-direction. real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - optional, intent(out) :: uhr_out !< accumulated volume/mass flux through zonal face (m3 or kg) + optional, intent(out) :: uhr_out !< accumulated volume/mass flux through zonal face + !! [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - optional, intent(out) :: vhr_out !< accumulated volume/mass flux through merid face (m3 or kg) + optional, intent(out) :: vhr_out !< accumulated volume/mass flux through merid face + !! [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - optional, intent(out) :: h_out !< layer thickness before advection (m or kg m-2) + optional, intent(out) :: h_out !< layer thickness before advection [H ~> m or kg m-2] type(tracer_type) :: Tr(MAX_FIELDS_) ! The array of registered tracers real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: & - hprev ! cell volume at the end of previous tracer change (m3) + hprev ! cell volume at the end of previous tracer change [H m2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: & - uhr ! The remaining zonal thickness flux (m3) + uhr ! The remaining zonal thickness flux [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: & - vhr ! The remaining meridional thickness fluxes (m3) + vhr ! The remaining meridional thickness fluxes [H m2 ~> m3 or kg] real :: uh_neglect(SZIB_(G),SZJ_(G)) ! uh_neglect and vh_neglect are the real :: vh_neglect(SZI_(G),SZJB_(G)) ! magnitude of remaining transports that - ! can be simply discarded (m3 or kg). + ! can be simply discarded [H m2 ~> m3 or kg]. - real :: landvolfill ! An arbitrary? nonzero cell volume, m3. - real :: Idt ! 1/dt in s-1. + real :: landvolfill ! An arbitrary? nonzero cell volume [H m2 ~> m3 or kg]. + real :: Idt ! 1/dt [s-1]. logical :: domore_u(SZJ_(G),SZK_(G)) ! domore__ indicate whether there is more logical :: domore_v(SZJB_(G),SZK_(G)) ! advection to be done in the corresponding ! row or column. @@ -328,15 +330,15 @@ subroutine advect_x(Tr, hprev, uhr, uh_neglect, OBC, domore_u, ntr, Idt, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_type), dimension(ntr), intent(inout) :: Tr !< The array of registered tracers to work on real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: hprev !< cell volume at the end of previous - !! tracer change, in H m2 (m3 or kg) + !! tracer change [H m2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: uhr !< accumulated volume/mass flux through - !! the zonal face, in H m2 (m3 or kg) + !! the zonal face [H m2 ~> m3 or kg] real, dimension(SZIB_(G),SZJ_(G)), intent(inout) :: uh_neglect !< A tiny zonal mass flux that can - !! be neglected, in H m2 (m3 or kg) + !! be neglected [H m2 ~> m3 or kg] type(ocean_OBC_type), pointer :: OBC !< specifies whether, where, and what OBCs are used logical, dimension(SZJ_(G),SZK_(G)), intent(inout) :: domore_u !< If true, there is more advection to be !! done in this u-row - real, intent(in) :: Idt !< The inverse of dt, in s-1 + real, intent(in) :: Idt !< The inverse of dt [s-1] integer, intent(in) :: ntr !< The number of tracers integer, intent(in) :: is !< The starting tracer i-index to work on integer, intent(in) :: ie !< The ending tracer i-index to work on @@ -348,25 +350,25 @@ subroutine advect_x(Tr, hprev, uhr, uh_neglect, OBC, domore_u, ntr, Idt, & !! for PPM interface values real, dimension(SZI_(G),ntr) :: & - slope_x ! The concentration slope per grid point in units of - ! concentration (nondim.). + slope_x ! The concentration slope per grid point [conc]. real, dimension(SZIB_(G),ntr) :: & - flux_x ! The tracer flux across a boundary in m3*conc or kg*conc. + flux_x ! The tracer flux across a boundary [H m2 conc ~> m3 conc or kg conc]. real :: maxslope ! The maximum concentration slope per grid point - ! consistent with monotonicity, in conc. (nondim.). + ! consistent with monotonicity [conc]. real :: hup, hlos ! hup is the upwind volume, hlos is the ! part of that volume that might be lost ! due to advection out the other side of - ! the grid box, both in m3 or kg. + ! the grid box, both in [H m2 ~> m3 or kg]. real :: uhh(SZIB_(G)) ! The zonal flux that occurs during the - ! current iteration, in m3 or kg. + ! current iteration [H m2 ~> m3 or kg]. real, dimension(SZIB_(G)) :: & - hlst, Ihnew, & ! Work variables with units of m3 or kg and m-3 or kg-1. - CFL ! A nondimensional work variable. + hlst, & ! Work variable [H m2 ~> m3 or kg]. + Ihnew, & ! Work variable [H-1 m-2 ~> m-3 or kg-1]. + CFL ! A nondimensional work variable [nondim]. real :: min_h ! The minimum thickness that can be realized during - ! any of the passes, in m or kg m-2. + ! any of the passes [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. + ! in roundoff and can be neglected [H ~> m or kg m-2]. logical :: do_i(SZIB_(G)) ! If true, work on given points. logical :: do_any_i integer :: i, j, m, n, i_up, stencil @@ -656,15 +658,15 @@ subroutine advect_y(Tr, hprev, vhr, vh_neglect, OBC, domore_v, ntr, Idt, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(tracer_type), dimension(ntr), intent(inout) :: Tr !< The array of registered tracers to work on real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: hprev !< cell volume at the end of previous - !! tracer change, in H m2 (m3 or kg) + !! tracer change [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: vhr !< accumulated volume/mass flux through - !! the meridional face, in H m2 (m3 or kg) + !! the meridional face [H m2 ~> m3 or kg] real, dimension(SZI_(G),SZJB_(G)), intent(inout) :: vh_neglect !< A tiny meridional mass flux that can - !! be neglected, in H m2 (m3 or kg) + !! be neglected [H m2 ~> m3 or kg] type(ocean_OBC_type), pointer :: OBC !< specifies whether, where, and what OBCs are used logical, dimension(SZJB_(G),SZK_(G)), intent(inout) :: domore_v !< If true, there is more advection to be !! done in this v-row - real, intent(in) :: Idt !< The inverse of dt, in s-1 + real, intent(in) :: Idt !< The inverse of dt [s-1] integer, intent(in) :: ntr !< The number of tracers integer, intent(in) :: is !< The starting tracer i-index to work on integer, intent(in) :: ie !< The ending tracer i-index to work on @@ -676,25 +678,25 @@ subroutine advect_y(Tr, hprev, vhr, vh_neglect, OBC, domore_v, ntr, Idt, & !! for PPM interface values real, dimension(SZI_(G),ntr,SZJ_(G)) :: & - slope_y ! The concentration slope per grid point in units of - ! concentration (nondim.). + slope_y ! The concentration slope per grid point [conc]. real, dimension(SZI_(G),ntr,SZJB_(G)) :: & - flux_y ! The tracer flux across a boundary in m3 * conc or kg*conc. + flux_y ! The tracer flux across a boundary [H m2 conc ~> m3 conc or kg conc]. real :: maxslope ! The maximum concentration slope per grid point - ! consistent with monotonicity, in conc. (nondim.). + ! consistent with monotonicity [conc]. real :: vhh(SZI_(G),SZJB_(G)) ! The meridional flux that occurs during the - ! current iteration, in m3 or kg. + ! current iteration [H m2 ~> m3 or kg]. real :: hup, hlos ! hup is the upwind volume, hlos is the ! part of that volume that might be lost ! due to advection out the other side of - ! the grid box, both in m3 or kg. + ! the grid box, both in [H m2 ~> m3 or kg]. real, dimension(SZIB_(G)) :: & - hlst, Ihnew, & ! Work variables with units of m3 or kg and m-3 or kg-1. + hlst, & ! Work variable [H m2 ~> m3 or kg]. + Ihnew, & ! Work variable [H-1 m-2 ~> m-3 or kg-1]. CFL ! A nondimensional work variable. real :: min_h ! The minimum thickness that can be realized during - ! any of the passes, in m or kg m-2. + ! any of the passes [H ~> m or kg m-2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. + ! in roundoff and can be neglected [H ~> m or kg m-2]. logical :: do_j_tr(SZJ_(G)) ! If true, calculate the tracer profiles. logical :: do_i(SZIB_(G)) ! If true, work on given points. logical :: do_any_i diff --git a/src/tracer/MOM_tracer_diabatic.F90 b/src/tracer/MOM_tracer_diabatic.F90 index c8ce7700db..f7f8028d91 100644 --- a/src/tracer/MOM_tracer_diabatic.F90 +++ b/src/tracer/MOM_tracer_diabatic.F90 @@ -26,45 +26,43 @@ subroutine tracer_vertdiff(h_old, ea, eb, dt, tr, G, GV, & sfc_flux, btm_flux, btm_reservoir, sink_rate, convert_flux_in) type(ocean_grid_type), intent(in) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_old !< layer thickness before entrainment (m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h_old !< layer thickness before entrainment + !! [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: ea !< amount of fluid entrained from the layer - !! above (units of h_work) + !! above [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: eb !< amount of fluid entrained from the layer - !! below (units of h_work) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: tr !< tracer concentration (in concentration units CU) - real, intent(in) :: dt !< amount of time covered by this call (seconds) - real, dimension(SZI_(G),SZJ_(G)), optional,intent(in) :: sfc_flux !< surface flux of the tracer in units - !! of (CU * kg m-2 s-1) + !! below [H ~> m or kg m-2] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: tr !< tracer concentration in concentration units [CU] + real, intent(in) :: dt !< amount of time covered by this call [s] + real, dimension(SZI_(G),SZJ_(G)), optional,intent(in) :: sfc_flux !< surface flux of the tracer [CU kg m-2 s-1] real, dimension(SZI_(G),SZJ_(G)), optional,intent(in) :: btm_flux !< The (negative upward) bottom flux of the - !! tracer, in units of (CU * kg m-2 s-1) + !! tracer [CU kg m-2 s-1] real, dimension(SZI_(G),SZJ_(G)), optional,intent(inout) :: btm_reservoir !< amount of tracer in a bottom reservoir - !! (units of CU kg m-2; formerly CU m) - real, optional,intent(in) :: sink_rate !< rate at which the tracer sinks, in m s-1 + !! [CU kg m-2]; formerly [CU m] + real, optional,intent(in) :: sink_rate !< rate at which the tracer sinks [m s-1] logical, optional,intent(in) :: convert_flux_in !< True if the specified sfc_flux needs !! to be integrated in time ! local variables - real :: sink_dist !< The distance the tracer sinks in a time step, in m or kg m-2. + real :: sink_dist !< The distance the tracer sinks in a time step [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G)) :: & - sfc_src, & !< The time-integrated surface source of the tracer, in - !! units of m or kg m-2 times a concentration. - btm_src !< The time-integrated bottom source of the tracer, in - !! units of m or kg m-2 times a concentration. + sfc_src, & !< The time-integrated surface source of the tracer [CU H ~> CU m or CU kg m-2]. + btm_src !< The time-integrated bottom source of the tracer [CU H ~> CU m or CU kg m-2]. real, dimension(SZI_(G)) :: & - b1, & !< b1 is used by the tridiagonal solver, in m-1 or m2 kg-1. + b1, & !< b1 is used by the tridiagonal solver [H-1 ~> m-1 or m2 kg-1]. d1 !! d1=1-c1 is used by the tridiagonal solver, nondimensional. - real :: c1(SZI_(G),SZK_(GV)) !< c1 is used by the tridiagonal solver, ND. + real :: c1(SZI_(G),SZK_(GV)) !< c1 is used by the tridiagonal solver [nondim]. real :: h_minus_dsink(SZI_(G),SZK_(GV)) !< The layer thickness minus the - !! difference in sinking rates across the layer, in m or kg m-2. + !! difference in sinking rates across the layer [H ~> m or kg m-2]. !! By construction, 0 <= h_minus_dsink < h_work. real :: sink(SZI_(G),SZK_(GV)+1) !< The tracer's sinking distances at the !! interfaces, limited to prevent characteristics from - !! crossing within a single timestep, in m or kg m-2. - real :: b_denom_1 !< The first term in the denominator of b1, in m or kg m-2. + !! crossing within a single timestep [H ~> m or kg m-2]. + real :: b_denom_1 !< The first term in the denominator of b1 [H ~> m or kg m-2]. real :: h_tr !< h_tr is h at tracer points with a h_neglect added to - !! ensure positive definiteness, in m or kg m-2. + !! ensure positive definiteness [H ~> m or kg m-2]. real :: h_neglect !< A thickness that is so small it is usually lost - !! in roundoff and can be neglected, in m. + !! in roundoff and can be neglected [H ~> m or kg m-2]. logical :: convert_flux = .true. @@ -228,14 +226,14 @@ subroutine applyTracerBoundaryFluxesInOut(G, GV, Tr, dt, fluxes, h, evap_CFL_lim type(ocean_grid_type), intent(in ) :: G !< Grid structure type(verticalGrid_type), intent(in ) :: GV !< ocean vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: Tr !< Tracer concentration on T-cell - real, intent(in ) :: dt !< Time-step over which forcing is applied (s) + real, intent(in ) :: dt !< Time-step over which forcing is applied [s] type(forcing), intent(in ) :: fluxes !< Surface fluxes container - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness in H units + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(inout) :: h !< Layer thickness [H ~> m or kg m-2] real, intent(in ) :: evap_CFL_limit !< Limit on the fraction of the !! water that can be fluxed out of the top - !! layer in a timestep (nondim) + !! layer in a timestep [nondim] real, intent(in ) :: minimum_forcing_depth !< The smallest depth over - !! which fluxes can be applied, in m + !! which fluxes can be applied [m] real, dimension(SZI_(G),SZJ_(G)), optional, intent(in ) :: in_flux_optional !< The total time-integrated !! amount of tracer that enters with freshwater real, dimension(SZI_(G),SZJ_(G)), optional, intent(in) :: out_flux_optional !< The total time-integrated @@ -248,11 +246,11 @@ subroutine applyTracerBoundaryFluxesInOut(G, GV, Tr, dt, fluxes, h, evap_CFL_lim real :: H_limit_fluxes, IforcingDepthScale, Idt real :: dThickness, dTracer real :: fractionOfForcing, hOld, Ithickness - real :: RivermixConst ! A constant used in implementing river mixing, in Pa s. + real :: RivermixConst ! A constant used in implementing river mixing [Pa s]. real, dimension(SZI_(G)) :: & - netMassInOut, & ! surface water fluxes (H units) over time step - netMassIn, & ! mass entering ocean surface (H units) over a time step - netMassOut ! mass leaving ocean surface (H units) over a time step + netMassInOut, & ! surface water fluxes [H ~> m or kg m-2] over time step + netMassIn, & ! mass entering ocean surface [H ~> m or kg m-2] over a time step + netMassOut ! mass leaving ocean surface [H ~> m or kg m-2] over a time step real, dimension(SZI_(G), SZK_(G)) :: h2d, Tr2d real, dimension(SZI_(G),SZJ_(G)) :: in_flux ! The total time-integrated amount of tracer! @@ -318,7 +316,7 @@ subroutine applyTracerBoundaryFluxesInOut(G, GV, Tr, dt, fluxes, h, evap_CFL_lim ! We aggregate the thermodynamic forcing for a time step into the following: ! These should have been set and stored during a call to applyBoundaryFluxesInOut ! netMassIn = net mass entering at ocean surface over a timestep - ! netMassOut = net mass leaving ocean surface (H units) over a time step. + ! netMassOut = net mass leaving ocean surface [H ~> m or kg m-2] over a time step. ! netMassOut < 0 means mass leaves ocean. ! Note here that the aggregateFW flag has already been taken care of in the call to diff --git a/src/tracer/MOM_tracer_flow_control.F90 b/src/tracer/MOM_tracer_flow_control.F90 index 6438a55ed2..a3c75bd7fd 100644 --- a/src/tracer/MOM_tracer_flow_control.F90 +++ b/src/tracer/MOM_tracer_flow_control.F90 @@ -279,8 +279,7 @@ subroutine tracer_flow_control_init(restart, day, G, GV, US, h, param_file, diag type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid !! structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2) + real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< A structure to parse for !! run-time parameters type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to @@ -391,19 +390,6 @@ subroutine call_tracer_set_forcing(state, fluxes, day_start, day_interval, G, CS type(tracer_flow_control_CS), pointer :: CS !< The control structure returned by a !! previous call to call_tracer_register. -! This subroutine calls the individual tracer modules' subroutines to -! specify or read quantities related to their surface forcing. -! Arguments: state - A structure containing fields that describe the -! surface state of the ocean. -! (out) fluxes - A structure containing pointers to any possible -! forcing fields. Unused fields have NULL ptrs. -! (in) day_start - Start time of the fluxes. -! (in) day_interval - Length of time over which these fluxes -! will be applied. -! (in) G - The ocean's grid structure. -! (in) CS - The control structure returned by a previous call to -! call_tracer_register. - if (.not. associated(CS)) call MOM_error(FATAL, "call_tracer_set_forcing"// & "Module must be initialized via call_tracer_register before it is used.") ! if (CS%use_ideal_age) & @@ -412,27 +398,25 @@ subroutine call_tracer_set_forcing(state, fluxes, day_start, day_interval, G, CS end subroutine call_tracer_set_forcing -!> This subroutine calls all registered tracer column physics -!! subroutines. +!> This subroutine calls all registered tracer column physics subroutines. subroutine call_tracer_column_fns(h_old, h_new, ea, eb, fluxes, Hml, dt, G, GV, tv, optics, CS, & debug, evap_CFL_limit, minimum_forcing_depth) - real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h_old !< Layer thickness before entrainment, - !! in m (Boussinesq) or kg m-2 - !! (non-Boussinesq). - real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h_new !< Layer thickness after entrainment, - !! in m or kg m-2. + real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h_old !< Layer thickness before entrainment + !! [H ~> m or kg m-2]. + real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h_new !< Layer thickness after entrainment + !! [H ~> m or kg m-2]. real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: ea !< an array to which the amount of !! fluid entrained from the layer above during this call - !! will be added, in m or kg m-2, the same as h_old. + !! will be added [H ~> m or kg m-2]. real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: eb !< an array to which the amount of !! fluid entrained from the layer below during this call - !! will be added, in m or kg m-2, the same as h_old. + !! will be added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to !! any possible forcing fields. !! Unused fields have NULL ptrs. - real, dimension(NIMEM_,NJMEM_), intent(in) :: Hml !< Mixed layer depth (m) + real, dimension(NIMEM_,NJMEM_), intent(in) :: Hml !< Mixed layer depth [H ~> m or kg m-2] real, intent(in) :: dt !< The amount of time covered by this - !! call, in s + !! call [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid !! structure. @@ -446,36 +430,9 @@ subroutine call_tracer_column_fns(h_old, h_new, ea, eb, fluxes, Hml, dt, G, GV, logical, intent(in) :: debug !< If true calculate checksums real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of !! the water that can be fluxed out - !! of the top layer in a timestep (nondim) + !! of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over - !! which fluxes can be applied, in m - -! This subroutine calls all registered tracer column physics -! subroutines. - -! Arguments: h_old - Layer thickness before entrainment, in m (Boussinesq) -! or kg m-2 (non-Boussinesq). -! (in) h_new - Layer thickness after entrainment, in m or kg m-2. -! (in) ea - an array to which the amount of fluid entrained -! from the layer above during this call will be -! added, in m or kg m-2, the same as h_old. -! (in) eb - an array to which the amount of fluid entrained -! from the layer below during this call will be -! added, in m or kg m-2, the same as h_old. -! (in) fluxes - A structure containing pointers to any possible -! forcing fields. Unused fields have NULL ptrs. -! (in) dt - The amount of time covered by this call, in s. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) tv - The structure containing thermodynamic variables. -! (in) optics - The structure containing optical properties. -! (in) CS - The control structure returned by a previous call to -! call_tracer_register. -! (in) evap_CFL_limit - Limits how much water can be fluxed out of the top layer -! Stored previously in diabatic CS. -! (in) minimum_forcing_depth - The smallest depth over which fluxes can be applied -! Stored previously in diabatic CS. -! (in) debug - Calculates checksums + !! which fluxes can be applied [H ~> m or kg m-2] if (.not. associated(CS)) call MOM_error(FATAL, "call_tracer_column_fns: "// & "Module must be initialized via call_tracer_register before it is used.") @@ -598,10 +555,9 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, CS, stock_names, stock_uni num_stocks, stock_index, got_min_max, global_min, global_max, & xgmin, ygmin, zgmin, xgmax, ygmax, zgmax) real, dimension(NIMEM_,NJMEM_,NKMEM_), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stock_values !< The integrated amounts of a tracer - !! on the current PE, usually in kg x concentration. + !! on the current PE, usually in kg x concentration [kg conc]. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(tracer_flow_control_CS), pointer :: CS !< The control structure returned by a @@ -626,22 +582,8 @@ subroutine call_tracer_stocks(h, stock_values, G, GV, CS, stock_names, stock_uni real, dimension(:), optional, intent(out) :: xgmax !< The x-position of the global maximum real, dimension(:), optional, intent(out) :: ygmax !< The y-position of the global maximum real, dimension(:), optional, intent(out) :: zgmax !< The z-position of the global maximum -! This subroutine calls all registered tracer packages to enable them to -! add to the surface state returned to the coupler. These routines are optional. -! Arguments: h - Layer thickness, in m (Boussinesq) or kg m-2 (non-Boussinesq). -! (out) stock_values - The integrated amounts of a tracer on the current -! PE, usually in kg x concentration. -! (in) G - The ocean's grid structure. -! (in) GV - The ocean's vertical grid structure. -! (in) CS - The control structure returned by a previous call to -! call_tracer_register. -! (out,opt) stock_names - Diagnostic names to use for each stock. -! (out,opt) stock_units - Units to use in the metadata for each stock. -! (out,opt) num_stocks - The number of tracer stocks being returned. -! (in,opt) stock_index - The integer stock index from stocks_constans_mod of -! the stock to be returned. If this is present and -! greater than 0, only a single stock can be returned. + ! Local variables character(len=200), dimension(MAX_FIELDS_) :: names, units character(len=200) :: set_pkg_name real, dimension(MAX_FIELDS_) :: values @@ -798,20 +740,10 @@ subroutine call_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(NIMEM_,NJMEM_,NKMEM_), & - intent(in) :: h !< Layer thicknesses, in H - !! (usually m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(tracer_flow_control_CS), pointer :: CS !< The control structure returned by a !! previous call to call_tracer_register. -! This subroutine calls all registered tracer packages to enable them to -! add to the surface state returned to the coupler. These routines are optional. - -! Arguments: state - A structure containing fields that describe the -! surface state of the ocean. -! (in) h - Layer thickness, in m (Boussinesq) or kg m-2 (non-Boussinesq). -! (in) G - The ocean's grid structure. -! (in) CS - The control structure returned by a previous call to -! call_tracer_register. if (.not. associated(CS)) call MOM_error(FATAL, "call_tracer_surface_state: "// & "Module must be initialized via call_tracer_register before it is used.") diff --git a/src/tracer/MOM_tracer_hor_diff.F90 b/src/tracer/MOM_tracer_hor_diff.F90 index 597b0fc822..48ec698696 100644 --- a/src/tracer/MOM_tracer_hor_diff.F90 +++ b/src/tracer/MOM_tracer_hor_diff.F90 @@ -34,21 +34,21 @@ module MOM_tracer_hor_diff !> The ocntrol structure for along-layer and epineutral tracer diffusion type, public :: tracer_hor_diff_CS ; private - real :: dt !< The baroclinic dynamics time step, in s. - real :: KhTr !< The along-isopycnal tracer diffusivity in m2/s. + real :: dt !< The baroclinic dynamics time step [s]. + real :: KhTr !< The along-isopycnal tracer diffusivity [m2 s-1]. real :: KhTr_Slope_Cff !< The non-dimensional coefficient in KhTr formula - real :: KhTr_min !< Minimum along-isopycnal tracer diffusivity in m2/s. - real :: KhTr_max !< Maximum along-isopycnal tracer diffusivity in m2/s. + real :: KhTr_min !< Minimum along-isopycnal tracer diffusivity [m2 s-1]. + real :: KhTr_max !< Maximum along-isopycnal tracer diffusivity [m2 s-1]. real :: KhTr_passivity_coeff !< Passivity coefficient that scales Rd/dx (default = 0) !! where passivity is the ratio between along-isopycnal - !! tracer mixing and thickness mixing - real :: KhTr_passivity_min !< Passivity minimum (default = 1/2) + !! tracer mixing and thickness mixing [nondim] + real :: KhTr_passivity_min !< Passivity minimum (default = 1/2) [nondim] real :: ML_KhTR_scale !< With Diffuse_ML_interior, the ratio of the !! truly horizontal diffusivity in the mixed - !! layer to the epipycnal diffusivity. Nondim. + !! layer to the epipycnal diffusivity [nondim]. real :: max_diff_CFL !< If positive, locally limit the along-isopycnal !! tracer diffusivity to keep the diffusive CFL - !! locally at or below this value. Nondim. + !! locally at or below this value [nondim]. logical :: Diffuse_ML_interior !< If true, diffuse along isopycnals between !! the mixed layer and the interior. logical :: check_diffusive_CFL !< If true, automatically iterate the diffusion @@ -97,8 +97,8 @@ module MOM_tracer_hor_diff subroutine tracer_hordiff(h, dt, MEKE, VarMix, G, GV, CS, Reg, tv, do_online_flag, read_khdt_x, read_khdt_y) type(ocean_grid_type), intent(inout) :: G !< Grid type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness (m or kg m-2) - real, intent(in) :: dt !< time step (seconds) + intent(in) :: h !< Layer thickness [H ~> m or kg m-2] + real, intent(in) :: dt !< time step [s] type(MEKE_type), pointer :: MEKE !< MEKE type type(VarMix_CS), pointer :: VarMix !< Variable mixing type type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure @@ -123,39 +123,38 @@ subroutine tracer_hordiff(h, dt, MEKE, VarMix, G, GV, CS, Reg, tv, do_online_fla real, dimension(SZI_(G),SZJ_(G)) :: & Ihdxdy, & ! The inverse of the volume or mass of fluid in a layer in a - ! grid cell, in m-3 or kg-1. - Kh_h, & ! The tracer diffusivity averaged to tracer points, in m2 s-1. - CFL, & ! A diffusive CFL number for each cell, nondim. - dTr ! The change in a tracer's concentration, in units of - ! concentration. + ! grid cell [H-1 m-2 ~> m-3 or kg-1]. + Kh_h, & ! The tracer diffusivity averaged to tracer points [m2 s-1]. + CFL, & ! A diffusive CFL number for each cell [nondim]. + dTr ! The change in a tracer's concentration, in units of concentration [Conc]. real, dimension(SZIB_(G),SZJ_(G)) :: & khdt_x, & ! The value of Khtr*dt times the open face width divided by - ! the distance between adjacent tracer points, in m2. + ! the distance between adjacent tracer points [m2]. Coef_x, & ! The coefficients relating zonal tracer differences - ! to time-integrated fluxes, in m3 or kg. - Kh_u ! Tracer mixing coefficient at u-points, in m2 s-1. + ! to time-integrated fluxes [H m2 ~> m3 or kg]. + Kh_u ! Tracer mixing coefficient at u-points [m2 s-1]. real, dimension(SZI_(G),SZJB_(G)) :: & khdt_y, & ! The value of Khtr*dt times the open face width divided by - ! the distance between adjacent tracer points, in m2. + ! the distance between adjacent tracer points [m2]. Coef_y, & ! The coefficients relating meridional tracer differences - ! to time-integrated fluxes, in m3 or kg. - Kh_v ! Tracer mixing coefficient at u-points, in m2 s-1. + ! to time-integrated fluxes [H m2 ~> m3 or kg]. + Kh_v ! Tracer mixing coefficient at u-points [m2 s-1]. - real :: khdt_max ! The local limiting value of khdt_x or khdt_y, in m2. + real :: khdt_max ! The local limiting value of khdt_x or khdt_y [m2]. real :: max_CFL ! The global maximum of the diffusive CFL number. logical :: use_VarMix, Resoln_scaled, do_online, use_Eady integer :: S_idx, T_idx ! Indices for temperature and salinity if needed integer :: i, j, k, m, is, ie, js, je, nz, ntr, itt, num_itts real :: I_numitts ! The inverse of the number of iterations, num_itts. real :: scale ! The fraction of khdt_x or khdt_y that is applied in this - ! layer for this iteration, nondim. - real :: Idt ! The inverse of the time step, in s-1. + ! layer for this iteration [nondim]. + real :: Idt ! The inverse of the time step [s-1]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. - real :: Kh_loc ! The local value of Kh, in m2 s-1. - real :: Res_Fn ! The local value of the resolution function, nondim. - real :: Rd_dx ! The local value of deformation radius over grid-spacing, nondim. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: Kh_loc ! The local value of Kh [m2 s-1]. + real :: Res_Fn ! The local value of the resolution function [nondim]. + real :: Rd_dx ! The local value of deformation radius over grid-spacing [nondim]. real :: normalize ! normalization used for diagnostic Kh_h; diffusivity averaged to h-points. is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = GV%ke @@ -541,7 +540,7 @@ subroutine tracer_epipycnal_ML_diff(h, dt, Tr, ntr, khdt_epi_x, khdt_epi_y, G, & GV, CS, tv, num_itts) type(ocean_grid_type), intent(inout) :: G !< ocean grid structure type(verticalGrid_type), intent(in) :: GV !< ocean vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness (m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness [H ~> m or kg m-2] real, intent(in) :: dt !< time step type(tracer_type), intent(inout) :: Tr(:) !< tracer array integer, intent(in) :: ntr !< number of tracers @@ -553,19 +552,19 @@ subroutine tracer_epipycnal_ML_diff(h, dt, Tr, ntr, khdt_epi_x, khdt_epi_y, G, & real, dimension(SZI_(G), SZJ_(G)) :: & - Rml_max ! The maximum coordinate density within the mixed layer, in kg m-3. + Rml_max ! The maximum coordinate density within the mixed layer [kg m-3]. real, dimension(SZI_(G), SZJ_(G), max(1,GV%nk_rho_varies)) :: & - rho_coord ! The coordinate density that is used to mix along, in kg m-3. + rho_coord ! The coordinate density that is used to mix along [kg m-3]. ! The naming mnemnonic is a=above,b=below,L=Left,R=Right,u=u-point,v=v-point. ! These are 1-D arrays of pointers to 2-d arrays to minimize memory usage. type(p2d), dimension(SZJ_(G)) :: & - deep_wt_Lu, deep_wt_Ru, & ! The relative weighting of the deeper of a pair, ND. - hP_Lu, hP_Ru ! The total thickness on each side for each pair, in m or kg m-2. + deep_wt_Lu, deep_wt_Ru, & ! The relative weighting of the deeper of a pair [nondim]. + hP_Lu, hP_Ru ! The total thickness on each side for each pair [H ~> m or kg m-2]. type(p2d), dimension(SZJB_(G)) :: & - deep_wt_Lv, deep_wt_Rv, & ! The relative weighting of the deeper of a pair, ND. - hP_Lv, hP_Rv ! The total thickness on each side for each pair, in m or kg m-2. + deep_wt_Lv, deep_wt_Rv, & ! The relative weighting of the deeper of a pair [nondim]. + hP_Lv, hP_Rv ! The total thickness on each side for each pair [H ~> m or kg m-2]. type(p2di), dimension(SZJ_(G)) :: & k0b_Lu, k0a_Lu, & ! The original k-indices of the layers that participate @@ -575,21 +574,21 @@ subroutine tracer_epipycnal_ML_diff(h, dt, Tr, ntr, khdt_epi_x, khdt_epi_y, G, & k0b_Rv, k0a_Rv ! in each pair of mixing at v-faces. real, dimension(SZI_(G), SZJ_(G), SZK_(G)) :: & - tr_flux_conv ! The flux convergence of tracers, in TR m3 or TR kg. + tr_flux_conv ! The flux convergence of tracers [conc H m2 ~> conc m3 or conc kg] real, dimension(SZI_(G), SZJ_(G), SZK_(G)) :: Tr_flux_3d, Tr_adj_vert_L, Tr_adj_vert_R real, dimension(SZI_(G), SZK_(G), SZJ_(G)) :: & - rho_srt, & ! The density of each layer of the sorted columns, in kg m-3. - h_srt ! The thickness of each layer of the sorted columns, in m or kg m-2. + rho_srt, & ! The density of each layer of the sorted columns [kg m-3]. + h_srt ! The thickness of each layer of the sorted columns [H ~> m or kg m-2]. integer, dimension(SZI_(G), SZK_(G), SZJ_(G)) :: & k0_srt ! The original k-index that each layer of the sorted column ! corresponds to. real, dimension(SZK_(G)) :: & h_demand_L, & ! The thickness in the left (_L) or right (_R) column that - h_demand_R, & ! is demanded to match the thickness in the counterpart, in H. + h_demand_R, & ! is demanded to match the thickness in the counterpart [H ~> m or kg m-2]. h_used_L, & ! The summed thickness from the left or right columns that - h_used_R, & ! have actually been used, in m or kg m-2 (H). + h_used_R, & ! have actually been used [H ~> m or kg m-2]. h_supply_frac_L, & ! The fraction of the demanded thickness that can h_supply_frac_R ! actually be supplied from a layer. integer, dimension(SZK_(G)) :: & @@ -609,22 +608,22 @@ subroutine tracer_epipycnal_ML_diff(h, dt, Tr, ntr, khdt_epi_x, khdt_epi_y, G, & integer, dimension(SZI_(G), SZJB_(G)) :: & nPv ! The number of epipycnal pairings at each v-point. real :: h_exclude ! A thickness that layers must attain to be considered - ! for inclusion in mixing, in m. - real :: Idt ! The inverse of the time step, in s-1. + ! for inclusion in mixing [H ~> m or kg m-2]. + real :: Idt ! The inverse of the time step [s-1]. real :: I_maxitt ! The inverse of the maximum number of iterations. - real :: rho_pair, rho_a, rho_b ! Temporary densities, in kg m-3. + real :: rho_pair, rho_a, rho_b ! Temporary densities [kg m-3]. real :: Tr_min_face ! The minimum and maximum tracer concentrations - real :: Tr_max_face ! associated with a pairing, in conc. + real :: Tr_max_face ! associated with a pairing [Conc] real :: Tr_La, Tr_Lb ! The 4 tracer concentrations that might be - real :: Tr_Ra, Tr_Rb ! associated with a pairing, in conc. + real :: Tr_Ra, Tr_Rb ! associated with a pairing [Conc] real :: Tr_av_L ! The average tracer concentrations on the left and right - real :: Tr_av_R ! sides of a pairing, in conc. - real :: Tr_flux ! The tracer flux from left to right in a pair, in conc m3. + real :: Tr_av_R ! sides of a pairing [Conc]. + real :: Tr_flux ! The tracer flux from left to right in a pair [conc H m2 ~> conc m3 or conc kg]. real :: Tr_adj_vert ! A downward vertical adjustment to Tr_flux between the - ! two cells that make up one side of the pairing, in conc m3. - real :: h_L, h_R ! Thicknesses to the left and right, in m or kg m-2 (H). - real :: wt_a, wt_b ! Fractional weights of layers above and below, ND. - real :: vol ! A cell volume or mass, in m3 or kg (H m2). + ! two cells that make up one side of the pairing [conc H m2 ~> conc m3 or conc kg]. + real :: h_L, h_R ! Thicknesses to the left and right [H ~> m or kg m-2]. + real :: wt_a, wt_b ! Fractional weights of layers above and below [nondim]. + real :: vol ! A cell volume or mass [H m2 ~> m3 or kg]. logical, dimension(SZK_(G)) :: & left_set, & ! If true, the left or right point determines the density of right_set ! of the trio. If densities are exactly equal, both are true. diff --git a/src/tracer/MOM_tracer_registry.F90 b/src/tracer/MOM_tracer_registry.F90 index 6491006c7f..f5c7d65f03 100644 --- a/src/tracer/MOM_tracer_registry.F90 +++ b/src/tracer/MOM_tracer_registry.F90 @@ -37,42 +37,48 @@ module MOM_tracer_registry !> The tracer type type, public :: tracer_type - real, dimension(:,:,:), pointer :: t => NULL() !< tracer concentration array -! real :: OBC_inflow_conc= 0.0 !< tracer concentration for generic inflows + real, dimension(:,:,:), pointer :: t => NULL() !< tracer concentration array [conc] +! real :: OBC_inflow_conc= 0.0 !< tracer concentration for generic inflows [conc] ! real, dimension(:,:,:), pointer :: OBC_in_u => NULL() !< structured values for flow into the domain ! !! specified in OBCs through u-face of cell ! real, dimension(:,:,:), pointer :: OBC_in_v => NULL() !< structured values for flow into the domain ! !! specified in OBCs through v-face of cell real, dimension(:,:,:), pointer :: ad_x => NULL() !< diagnostic array for x-advective tracer flux + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:,:), pointer :: ad_y => NULL() !< diagnostic array for y-advective tracer flux + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:), pointer :: ad2d_x => NULL() !< diagnostic vertical sum x-advective tracer flux - !! in units of (conc * m3/s or conc * kg/s) + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:), pointer :: ad2d_y => NULL() !< diagnostic vertical sum y-advective tracer flux - !! in units of (conc * m3/s or conc * kg/s) + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:,:), pointer :: df_x => NULL() !< diagnostic array for x-diffusive tracer flux + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:,:), pointer :: df_y => NULL() !< diagnostic array for y-diffusive tracer flux + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:), pointer :: df2d_x => NULL() !< diagnostic vertical sum x-diffusive flux - !! in units of (conc * m3/s or conc * kg/s) + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:), pointer :: df2d_y => NULL() !< diagnostic vertical sum y-diffusive flux - !! in units of (conc * m3/s or conc * kg/s) + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:), pointer :: df2d_conc_x => NULL() !< diagnostic vertical sum x-diffusive content flux - !! in units of (conc * m3/s or conc * kg/s) + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:), pointer :: df2d_conc_y => NULL() !< diagnostic vertical sum y-diffusive content flux - !! in units of (conc * m3/s or conc * kg/s) + !! [conc H m2 s-1 ~> conc m3 s-1 or conc kg s-1] real, dimension(:,:,:), pointer :: advection_xy => NULL() !< convergence of lateral advective tracer fluxes + !! [conc H s-1 ~> conc m s-1 or conc kg m-2 s-1] real, dimension(:,:,:), pointer :: diff_cont_xy => NULL() !< convergence of lateral diffusive tracer fluxes + !! [conc H s-1 ~> conc m s-1 or conc kg m-2 s-1] real, dimension(:,:,:), pointer :: diff_conc_xy => NULL() !< convergence of lateral diffusive tracer fluxes - !! expressed as a change in concentration + !! expressed as a change in concentration [conc s-1] real, dimension(:,:,:), pointer :: t_prev => NULL() !< tracer concentration array at a previous - !! timestep used for diagnostics + !! timestep used for diagnostics [conc] real, dimension(:,:,:), pointer :: Trxh_prev => NULL() !< layer integrated tracer concentration array !! at a previous timestep used for diagnostics character(len=32) :: name !< tracer name used for diagnostics and error messages - character(len=64) :: units !< Physical dimensions of the variable + character(len=64) :: units !< Physical dimensions of the tracer concentration character(len=240) :: longname !< Long name of the variable ! type(vardesc), pointer :: vd => NULL() !< metadata describing the tracer logical :: registry_diags = .false. !< If true, use the registry to set up the diff --git a/src/tracer/advection_test_tracer.F90 b/src/tracer/advection_test_tracer.F90 index aeb1b3aae9..34f788c952 100644 --- a/src/tracer/advection_test_tracer.F90 +++ b/src/tracer/advection_test_tracer.F90 @@ -171,7 +171,7 @@ subroutine initialize_advection_test_tracer(restart, day, G, GV, h,diag, OBC, CS type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -198,9 +198,9 @@ subroutine initialize_advection_test_tracer(restart, day, G, GV, h,diag, OBC, CS real, pointer :: tr_ptr(:,:,:) => NULL() real :: PI ! 3.1415926... calculated as 4*atan(1) real :: tr_y ! Initial zonally uniform tracer concentrations. - real :: dist2 ! The distance squared from a line, in m2. + real :: dist2 ! The distance squared from a line [m2]. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. + ! in roundoff and can be neglected [H ~> m or kg m-2]. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m integer :: IsdB, IedB, JsdB, JedB real :: tmpx, tmpy, locx, locy @@ -265,32 +265,32 @@ subroutine advection_test_tracer_column_physics(h_old, h_new, ea, eb, fluxes, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(advection_test_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_advection_test_tracer. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! This subroutine applies diapycnal diffusion and any other column ! tracer physics or chemistry to the tracers from this file. ! This is a simple example of a set of advected passive tracers. ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified real :: b1(SZI_(G)) ! b1 and c1 are variables used by the @@ -325,7 +325,7 @@ subroutine advection_test_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(advection_test_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_advection_test_tracer. @@ -354,9 +354,9 @@ end subroutine advection_test_tracer_surface_state !! If the stock_index is present, only the stock corresponding to that coded index is returned. function advection_test_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each - !! tracer, in kg times concentration units. + !! tracer, in kg times concentration units [kg conc]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(advection_test_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_advection_test_tracer. diff --git a/src/tracer/boundary_impulse_tracer.F90 b/src/tracer/boundary_impulse_tracer.F90 index 9b785fe41d..fa95d8aa77 100644 --- a/src/tracer/boundary_impulse_tracer.F90 +++ b/src/tracer/boundary_impulse_tracer.F90 @@ -156,7 +156,7 @@ subroutine initialize_boundary_impulse_tracer(restart, day, G, GV, h, diag, OBC, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -211,36 +211,36 @@ subroutine boundary_impulse_tracer_column_physics(h_old, h_new, ea, eb, fluxes, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(boundary_impulse_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_boundary_impulse_tracer. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various !! thermodynamic variables logical, intent(in) :: debug !< If true calculate checksums real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! This subroutine applies diapycnal diffusion and any other column ! tracer physics or chemistry to the tracers from this file. ! This is a simple example of a set of advected passive tracers. ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real :: Isecs_per_year = 1.0 / (365.0*86400.0) @@ -285,17 +285,17 @@ end subroutine boundary_impulse_tracer_column_physics !> Calculate total inventory of tracer function boundary_impulse_stock(h, stocks, G, GV, CS, names, units, stock_index) - type(ocean_grid_type), intent(in ) :: G !< The ocean's grid structure - type(verticalGrid_type), intent(in ) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in ) :: h !< Layer thicknesses, in H (usually m or kg m-2) - real, dimension(:), intent( out) :: stocks !< the mass-weighted integrated amount of each - !! tracer, in kg times concentration units. - type(boundary_impulse_tracer_CS), pointer :: CS !< The control structure returned by a previous - !! call to register_boundary_impulse_tracer. - character(len=*), dimension(:), intent( out) :: names !< The names of the stocks calculated. - character(len=*), dimension(:), intent( out) :: units !< The units of the stocks calculated. - integer, optional, intent(in ) :: stock_index !< The coded index of a specific stock - !! being sought. + type(ocean_grid_type), intent(in ) :: G !< The ocean's grid structure + type(verticalGrid_type), intent(in ) :: GV !< The ocean's vertical grid structure + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in ) :: h !< Layer thicknesses [H ~> m or kg m-2] + real, dimension(:), intent( out) :: stocks !< the mass-weighted integrated amount of each + !! tracer, in kg times concentration units [kg conc]. + type(boundary_impulse_tracer_CS), pointer :: CS !< The control structure returned by a previous + !! call to register_boundary_impulse_tracer. + character(len=*), dimension(:), intent( out) :: names !< The names of the stocks calculated. + character(len=*), dimension(:), intent( out) :: units !< The units of the stocks calculated. + integer, optional, intent(in ) :: stock_index !< The coded index of a specific stock + !! being sought. integer :: boundary_impulse_stock !< Return value: the number of stocks calculated here. ! This function calculates the mass-weighted integral of all tracer stocks, @@ -340,7 +340,7 @@ subroutine boundary_impulse_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(boundary_impulse_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_boundary_impulse_tracer. diff --git a/src/tracer/dye_example.F90 b/src/tracer/dye_example.F90 index 1416fb9655..51b5ab6c08 100644 --- a/src/tracer/dye_example.F90 +++ b/src/tracer/dye_example.F90 @@ -33,6 +33,10 @@ module regional_dyes public dye_tracer_column_physics, dye_tracer_surface_state public dye_stock, regional_dyes_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. !> The control structure for the regional dyes tracer package type, public :: dye_tracer_CS ; private @@ -42,8 +46,8 @@ module regional_dyes real, allocatable, dimension(:) :: dye_source_maxlon !< Maximum longitude of region dye will be injected. real, allocatable, dimension(:) :: dye_source_minlat !< Minimum latitude of region dye will be injected. real, allocatable, dimension(:) :: dye_source_maxlat !< Maximum latitude of region dye will be injected. - real, allocatable, dimension(:) :: dye_source_mindepth !< Minimum depth of region dye will be injected, in Z. - real, allocatable, dimension(:) :: dye_source_maxdepth !< Maximum depth of region dye will be injected, in Z. + real, allocatable, dimension(:) :: dye_source_mindepth !< Minimum depth of region dye will be injected [Z ~> m]. + real, allocatable, dimension(:) :: dye_source_maxdepth !< Maximum depth of region dye will be injected [Z ~> m]. type(tracer_registry_type), pointer :: tr_Reg => NULL() !< A pointer to the tracer registry real, pointer :: tr(:,:,:,:) => NULL() !< The array of tracers used in this subroutine, in g m-3? @@ -187,7 +191,7 @@ subroutine initialize_dye_tracer(restart, day, G, GV, h, diag, OBC, CS, sponge_C type(time_type), target, intent(in) :: day !< Time of the start of the run. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< Structure used to regulate diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies !! whether, where, and what open boundary @@ -242,32 +246,32 @@ end subroutine initialize_dye_tracer !! tracer physics or chemistry to the tracers from this file. !! This is a simple example of a set of advected passive tracers. !! The arguments to this subroutine are redundant in that -!! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +!! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) subroutine dye_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, & evap_CFL_limit, minimum_forcing_depth) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(dye_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_dye_tracer. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified @@ -325,9 +329,9 @@ end subroutine dye_tracer_column_physics !! returning the number of stocks it has calculated. If the stock_index !! is present, only the stock corresponding to that coded index is returned. function dye_stock(h, stocks, G, GV, CS, names, units, stock_index) - real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(NIMEM_,NJMEM_,NKMEM_), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of - !! each tracer, in kg times concentration units. + !! each tracer, in kg times concentration units [kg conc]. type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(dye_tracer_CS), pointer :: CS !< The control structure returned by a @@ -376,7 +380,7 @@ subroutine dye_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(dye_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_dye_tracer. diff --git a/src/tracer/dyed_obc_tracer.F90 b/src/tracer/dyed_obc_tracer.F90 index af69a39c52..7abbafa5fc 100644 --- a/src/tracer/dyed_obc_tracer.F90 +++ b/src/tracer/dyed_obc_tracer.F90 @@ -138,7 +138,7 @@ subroutine initialize_dyed_obc_tracer(restart, day, G, GV, h, diag, OBC, CS, dia logical, intent(in) :: restart !< .true. if the fields have already !! been read from a restart file. type(time_type), target, intent(in) :: day !< Time of the start of the run. - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< Structure used to regulate diagnostic output. type(ocean_OBC_type), pointer :: OBC !< Structure specifying open boundary options. type(dyed_obc_tracer_CS), pointer :: CS !< The control structure returned by a previous @@ -160,7 +160,7 @@ subroutine initialize_dyed_obc_tracer(restart, day, G, GV, h, diag, OBC, CS, dia ! kg(tracer) kg(water)-1 m3 s-1 or kg(tracer) s-1. real, pointer :: tr_ptr(:,:,:) => NULL() real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. + ! in roundoff and can be neglected [H ~> m or kg m-2]. real :: e(SZK_(G)+1), e_top, e_bot, d_tr integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m integer :: IsdB, IedB, JsdB, JedB @@ -201,32 +201,32 @@ end subroutine initialize_dyed_obc_tracer !! This is a simple example of a set of advected passive tracers. !! !! The arguments to this subroutine are redundant in that -!! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +!! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) subroutine dyed_obc_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS, & evap_CFL_limit, minimum_forcing_depth) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(dyed_obc_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to dyed_obc_register_tracer. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! Local variables real :: b1(SZI_(G)) ! b1 and c1 are variables used by the diff --git a/src/tracer/ideal_age_example.F90 b/src/tracer/ideal_age_example.F90 index 750fa83021..562947a011 100644 --- a/src/tracer/ideal_age_example.F90 +++ b/src/tracer/ideal_age_example.F90 @@ -50,8 +50,7 @@ module ideal_age_example real, dimension(NTR_MAX) :: IC_val = 0.0 !< The (uniform) initial condition value. real, dimension(NTR_MAX) :: young_val = 0.0 !< The value assigned to tr at the surface. real, dimension(NTR_MAX) :: land_val = -1.0 !< The value of tr used where land is masked out. - real, dimension(NTR_MAX) :: sfc_growth_rate !< The exponential growth rate for the surface value, - !! in units of year-1. + real, dimension(NTR_MAX) :: sfc_growth_rate !< The exponential growth rate for the surface value [year-1]. real, dimension(NTR_MAX) :: tracer_start_year !< The year in which tracers start aging, or at which the !! surface value equals young_val, in years. logical :: tracers_may_reinit !< If true, these tracers be set up via the initialization code if @@ -203,7 +202,7 @@ subroutine initialize_ideal_age_tracer(restart, day, G, GV, US, h, diag, OBC, CS type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -288,32 +287,32 @@ subroutine ideal_age_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(ideal_age_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_ideal_age_tracer. real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! This subroutine applies diapycnal diffusion and any other column ! tracer physics or chemistry to the tracers from this file. ! This is a simple example of a set of advected passive tracers. ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified real :: sfc_val ! The surface value for the tracers. @@ -375,9 +374,9 @@ end subroutine ideal_age_tracer_column_physics function ideal_age_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each - !! tracer, in kg times concentration units. + !! tracer, in kg times concentration units [kg conc]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(ideal_age_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_ideal_age_tracer. @@ -426,7 +425,7 @@ subroutine ideal_age_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(ideal_age_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_ideal_age_tracer. diff --git a/src/tracer/oil_tracer.F90 b/src/tracer/oil_tracer.F90 index 3130ba3804..6156c20e24 100644 --- a/src/tracer/oil_tracer.F90 +++ b/src/tracer/oil_tracer.F90 @@ -46,7 +46,7 @@ module oil_tracer real :: oil_source_latitude !< Longitude of source location (geographic) integer :: oil_source_i=-999 !< Local i of source location (computational) integer :: oil_source_j=-999 !< Local j of source location (computational) - real :: oil_source_rate !< Rate of oil injection (kg/s) + real :: oil_source_rate !< Rate of oil injection [kg s-1] real :: oil_start_year !< The year in which tracers start aging, or at which the !! surface value equals young_val, in years. real :: oil_end_year !< The year in which tracers start aging, or at which the @@ -57,9 +57,9 @@ module oil_tracer real, dimension(NTR_MAX) :: IC_val = 0.0 !< The (uniform) initial condition value. real, dimension(NTR_MAX) :: young_val = 0.0 !< The value assigned to tr at the surface. real, dimension(NTR_MAX) :: land_val = -1.0 !< The value of tr used where land is masked out. - real, dimension(NTR_MAX) :: sfc_growth_rate !< The exponential growth rate for the surface value, in units of year-1. - real, dimension(NTR_MAX) :: oil_decay_days !< Decay time scale of oil (in days) - real, dimension(NTR_MAX) :: oil_decay_rate !< Decay rate of oil (in s^-1) calculated from oil_decay_days + real, dimension(NTR_MAX) :: sfc_growth_rate !< The exponential growth rate for the surface value [year-1]. + real, dimension(NTR_MAX) :: oil_decay_days !< Decay time scale of oil [days] + real, dimension(NTR_MAX) :: oil_decay_rate !< Decay rate of oil [s-1] calculated from oil_decay_days integer, dimension(NTR_MAX) :: oil_source_k !< Layer of source logical :: oil_may_reinit !< If true, oil tracers may be reset by the initialization code !! if they are not found in the restart files. @@ -210,7 +210,7 @@ subroutine initialize_oil_tracer(restart, day, G, GV, US, h, diag, OBC, CS, & type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -303,33 +303,33 @@ subroutine oil_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(oil_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_oil_tracer. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! This subroutine applies diapycnal diffusion and any other column ! tracer physics or chemistry to the tracers from this file. ! This is a simple example of a set of advected passive tracers. ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_work ! Used so that h can be modified @@ -366,8 +366,8 @@ subroutine oil_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS if (CS%oil_decay_rate(m)>0.) then CS%tr(i,j,k,m) = G%mask2dT(i,j)*max(1.-dt*CS%oil_decay_rate(m),0.)*CS%tr(i,j,k,m) ! Safest elseif (CS%oil_decay_rate(m)<0.) then - ldecay = 12.*(3.0**(-(tv%T(i,j,k)-20.)/10.)) ! Timescale in days - ldecay = 1./(86400.*ldecay) ! Rate in s^-1 + ldecay = 12.*(3.0**(-(tv%T(i,j,k)-20.)/10.)) ! Timescale [days] + ldecay = 1./(86400.*ldecay) ! Rate [s-1] CS%tr(i,j,k,m) = G%mask2dT(i,j)*max(1.-dt*ldecay,0.)*CS%tr(i,j,k,m) endif enddo ; enddo ; enddo @@ -408,9 +408,9 @@ end subroutine oil_tracer_column_physics function oil_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each - !! tracer, in kg times concentration units. + !! tracer, in kg times concentration units [kg conc]. type(oil_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_oil_tracer. character(len=*), dimension(:), intent(out) :: names !< the names of the stocks calculated. @@ -460,7 +460,7 @@ subroutine oil_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(oil_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_oil_tracer. diff --git a/src/tracer/pseudo_salt_tracer.F90 b/src/tracer/pseudo_salt_tracer.F90 index d9f4d3f682..e41ab90095 100644 --- a/src/tracer/pseudo_salt_tracer.F90 +++ b/src/tracer/pseudo_salt_tracer.F90 @@ -40,9 +40,9 @@ module pseudo_salt_tracer type(time_type), pointer :: Time => NULL() !< A pointer to the ocean model's clock. type(tracer_registry_type), pointer :: tr_Reg => NULL() !< A pointer to the MOM tracer registry real, pointer :: ps(:,:,:) => NULL() !< The array of pseudo-salt tracer used in this - !! subroutine, in psu + !! subroutine [ppt} real, pointer :: diff(:,:,:) => NULL() !< The difference between the pseudo-salt - !! tracer and the real salt, in psu. + !! tracer and the real salt [ppt]. logical :: pseudo_salt_may_reinit = .true. !< Hard coding since this should not matter integer :: id_psd = -1 !< A diagnostic ID @@ -121,7 +121,7 @@ subroutine initialize_pseudo_salt_tracer(restart, day, G, GV, h, diag, OBC, CS, type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -178,34 +178,34 @@ subroutine pseudo_salt_tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(pseudo_salt_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_pseudo_salt_tracer. type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables logical, intent(in) :: debug !< If true calculate checksums real, optional, intent(in) :: evap_CFL_limit !< Limit on the fraction of the water that can - !! be fluxed out of the top layer in a timestep (nondim) + !! be fluxed out of the top layer in a timestep [nondim] real, optional, intent(in) :: minimum_forcing_depth !< The smallest depth over which - !! fluxes can be applied, in m + !! fluxes can be applied [m] ! This subroutine applies diapycnal diffusion and any other column ! tracer physics or chemistry to the tracers from this file. ! The arguments to this subroutine are redundant in that -! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) ! Local variables real :: year, h_total, scale, htot, Ih_limit @@ -254,9 +254,9 @@ end subroutine pseudo_salt_tracer_column_physics function pseudo_salt_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each - !! tracer, in kg times concentration units. + !! tracer, in kg times concentration units [kg conc]. type(pseudo_salt_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_pseudo_salt_tracer. character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated. @@ -305,7 +305,7 @@ subroutine pseudo_salt_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thickness, in m or kg m-2. + intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(pseudo_salt_tracer_CS), pointer :: CS !< The control structure returned by a previous !! call to register_pseudo_salt_tracer. diff --git a/src/tracer/tracer_example.F90 b/src/tracer/tracer_example.F90 index bf6b504658..26ea3fb957 100644 --- a/src/tracer/tracer_example.F90 +++ b/src/tracer/tracer_example.F90 @@ -144,7 +144,7 @@ subroutine USER_initialize_tracer(restart, day, G, GV, h, diag, OBC, CS, & type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate !! diagnostic output. type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies @@ -167,7 +167,7 @@ subroutine USER_initialize_tracer(restart, day, G, GV, h, diag, OBC, CS, & real, pointer :: tr_ptr(:,:,:) => NULL() real :: PI ! 3.1415926... calculated as 4*atan(1) real :: tr_y ! Initial zonally uniform tracer concentrations. - real :: dist2 ! The distance squared from a line, in m2. + real :: dist2 ! The distance squared from a line [m2]. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz, m integer :: IsdB, IedB, JsdB, JedB, lntr @@ -261,25 +261,25 @@ end subroutine USER_initialize_tracer !! tracer physics or chemistry to the tracers from this file. !! This is a simple example of a set of advected passive tracers. !! The arguments to this subroutine are redundant in that -!! h_new[k] = h_old[k] + ea[k] - eb[k-1] + eb[k] - ea[k+1] +!! h_new(k) = h_old(k) + ea(k) - eb(k-1) + eb(k) - ea(k+1) subroutine tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_old !< Layer thickness before entrainment, in m or kg m-2. + intent(in) :: h_old !< Layer thickness before entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h_new !< Layer thickness after entrainment, in m or kg m-2. + intent(in) :: h_new !< Layer thickness after entrainment [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: ea !< an array to which the amount of fluid entrained !! from the layer above during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & intent(in) :: eb !< an array to which the amount of fluid entrained !! from the layer below during this call will be - !! added, in m or kg m-2. + !! added [H ~> m or kg m-2]. type(forcing), intent(in) :: fluxes !< A structure containing pointers to thermodynamic !! and tracer forcing fields. Unused fields have NULL ptrs. - real, intent(in) :: dt !< The amount of time covered by this call, in s + real, intent(in) :: dt !< The amount of time covered by this call [s] type(USER_tracer_example_CS), pointer :: CS !< The control structure returned by a previous !! call to USER_register_tracer_example. @@ -290,8 +290,8 @@ subroutine tracer_column_physics(h_old, h_new, ea, eb, fluxes, dt, G, GV, CS) real :: c1(SZI_(G),SZK_(G)) ! tridiagonal solver. real :: d1(SZI_(G)) ! d1=1-c1 is used by the tridiagonal solver. real :: h_neglect ! A thickness that is so small it is usually lost - ! in roundoff and can be neglected, in m. - real :: b_denom_1 ! The first term in the denominator of b1, in m or kg m-2. + ! in roundoff and can be neglected [H ~> m or kg m-2]. + real :: b_denom_1 ! The first term in the denominator of b1 [H ~> m or kg m-2]. integer :: i, j, k, is, ie, js, je, nz, m ! The following array (trdc) determines the behavior of the tracer @@ -364,9 +364,9 @@ function USER_tracer_stock(h, stocks, G, GV, CS, names, units, stock_index) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(:), intent(out) :: stocks !< the mass-weighted integrated amount of each - !! tracer, in kg times concentration units. + !! tracer, in kg times concentration units [kg conc]. type(USER_tracer_example_CS), pointer :: CS !< The control structure returned by a !! previous call to register_USER_tracer. character(len=*), dimension(:), intent(out) :: names !< The names of the stocks calculated. @@ -411,7 +411,7 @@ subroutine USER_tracer_surface_state(state, h, G, CS) type(surface), intent(inout) :: state !< A structure containing fields that !! describe the surface state of the ocean. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] type(USER_tracer_example_CS), pointer :: CS !< The control structure returned by a previous !! call to register_USER_tracer. diff --git a/src/user/BFB_initialization.F90 b/src/user/BFB_initialization.F90 index 7c16ade9b5..31223d5686 100644 --- a/src/user/BFB_initialization.F90 +++ b/src/user/BFB_initialization.F90 @@ -20,6 +20,11 @@ module BFB_initialization public BFB_set_coord public BFB_initialize_sponges_southonly +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Unsafe model variable !! \todo Remove this module variable logical :: first_call = .true. @@ -33,7 +38,7 @@ module BFB_initialization subroutine BFB_set_coord(Rlay, g_prime, GV, param_file, eqn_of_state) real, dimension(NKMEM_), intent(out) :: Rlay !< Layer potential density. real, dimension(NKMEM_), intent(out) :: g_prime !< The reduced gravity at - !! each interface, in m2 Z-1 s-2. + !! each interface [m2 Z-1 s-2 ~> m s-2]. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters type(EOS_type), pointer :: eqn_of_state !< Integer that selects the @@ -81,13 +86,13 @@ subroutine BFB_initialize_sponges_southonly(G, GV, US, use_temperature, tv, para type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters type(sponge_CS), pointer :: CSp !< A pointer to the sponge control structure real, dimension(NIMEM_, NJMEM_, NKMEM_), & - intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] ! Local variables - real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta, in depth units (Z). - real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate, in s-1. - real :: H0(SZK_(G)) ! Resting layer thickesses in depth units (Z). - real :: min_depth ! The minimum ocean depth in depth units (Z). + real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta, in depth units [Z ~> m]. + real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1]. + real :: H0(SZK_(G)) ! Resting layer thicknesses in depth units [Z ~> m]. + real :: min_depth ! The minimum ocean depth in depth units [Z ~> m]. real :: damp, e_dense, damp_new, slat, wlon, lenlat, lenlon, nlat character(len=40) :: mdl = "BFB_initialize_sponges_southonly" ! This subroutine's name. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz @@ -97,7 +102,7 @@ subroutine BFB_initialize_sponges_southonly(G, GV, US, use_temperature, tv, para eta(:,:,:) = 0.0 ; Idamp(:,:) = 0.0 -! Here the inverse damping time, in s-1, is set. Set Idamp to 0 ! +! Here the inverse damping time [s-1], is set. Set Idamp to 0 ! ! wherever there is no sponge, and the subroutines that are called ! ! will automatically set up the sponges only where Idamp is positive! ! and mask2dT is 1. ! diff --git a/src/user/BFB_surface_forcing.F90 b/src/user/BFB_surface_forcing.F90 index edcdb002cf..3d54df5955 100644 --- a/src/user/BFB_surface_forcing.F90 +++ b/src/user/BFB_surface_forcing.F90 @@ -24,27 +24,20 @@ module BFB_surface_forcing !> Control structure for BFB_surface_forcing type, public :: BFB_surface_forcing_CS ; private - logical :: use_temperature !< If true, temperature and salinity are used as - !! state variables. + logical :: use_temperature !< If true, temperature and salinity are used as state variables. logical :: restorebuoy !< If true, use restoring surface buoyancy forcing. - real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. - real :: G_Earth !< The gravitational acceleration in m s-2. - real :: Flux_const !< The restoring rate at the surface, in m s-1. - real :: gust_const !< A constant unresolved background gustiness - !! that contributes to ustar, in Pa. - real :: SST_s !< SST at the southern edge of the linear - !! forcing ramp - real :: SST_n !< SST at the northern edge of the linear - !! forcing ramp - real :: lfrslat !< Southern latitude where the linear forcing ramp - !! begins - real :: lfrnlat !< Northern latitude where the linear forcing ramp - !! ends - real :: drho_dt !< Rate of change of density with temperature. - !! Note that temperature is being used as a dummy - !! variable here. All temperatures are converted - !! into density. + real :: Rho0 !< The density used in the Boussinesq approximation [kg m-3]. + real :: G_Earth !< The gravitational acceleration [m s-2] + real :: Flux_const !< The restoring rate at the surface [m s-1]. + real :: gust_const !< A constant unresolved background gustiness + !! that contributes to ustar [Pa]. + real :: SST_s !< SST at the southern edge of the linear forcing ramp [degC] + real :: SST_n !< SST at the northern edge of the linear forcing ramp [degC] + real :: lfrslat !< Southern latitude where the linear forcing ramp begins [degLat] + real :: lfrnlat !< Northern latitude where the linear forcing ramp ends [degLat] + real :: drho_dt !< Rate of change of density with temperature [kg m-3 degC-1]. + !! Note that temperature is being used as a dummy variable here. + !! All temperatures are converted into density. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to !! regulate the timing of diagnostic output. @@ -61,19 +54,19 @@ subroutine BFB_buoyancy_forcing(state, fluxes, day, dt, G, CS) !! have NULL ptrs. type(time_type), intent(in) :: day !< Time of the fluxes. real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(BFB_surface_forcing_CS), pointer :: CS !< A pointer to the control structure !! returned by a previous call to !! BFB_surface_forcing_init. ! Local variables - real :: Temp_restore ! The temperature that is being restored toward, in C. - real :: Salin_restore ! The salinity that is being restored toward, in PSU. + real :: Temp_restore ! The temperature that is being restored toward [degC]. + real :: Salin_restore ! The salinity that is being restored toward [ppt]. real :: density_restore ! The potential density that is being restored - ! toward, in kg m-3. - real :: rhoXcp ! The mean density times the heat capacity, in J m-3 K-1. + ! toward [kg m-3]. + real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1]. real :: buoy_rest_const ! A constant relating density anomalies to the - ! restoring buoyancy flux, in m5 s-3 kg-1. + ! restoring buoyancy flux [m5 s-3 kg-1]. integer :: i, j, is, ie, js, je integer :: isd, ied, jsd, jed @@ -102,7 +95,7 @@ subroutine BFB_buoyancy_forcing(state, fluxes, day, dt, G, CS) ! Set whichever fluxes are to be used here. Any fluxes that ! are always zero do not need to be changed here. do j=js,je ; do i=is,ie - ! Fluxes of fresh water through the surface are in units of kg m-2 s-1 + ! Fluxes of fresh water through the surface are in units of [kg m-2 s-1] ! and are positive downward - i.e. evaporation should be negative. fluxes%evap(i,j) = -0.0 * G%mask2dT(i,j) fluxes%lprec(i,j) = 0.0 * G%mask2dT(i,j) @@ -110,7 +103,7 @@ subroutine BFB_buoyancy_forcing(state, fluxes, day, dt, G, CS) ! vprec will be set later, if it is needed for salinity restoring. fluxes%vprec(i,j) = 0.0 - ! Heat fluxes are in units of W m-2 and are positive into the ocean. + ! Heat fluxes are in units of [W m-2] and are positive into the ocean. fluxes%lw(i,j) = 0.0 * G%mask2dT(i,j) fluxes%latent(i,j) = 0.0 * G%mask2dT(i,j) fluxes%sens(i,j) = 0.0 * G%mask2dT(i,j) @@ -118,7 +111,7 @@ subroutine BFB_buoyancy_forcing(state, fluxes, day, dt, G, CS) enddo ; enddo else ! This is the buoyancy only mode. do j=js,je ; do i=is,ie - ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive + ! fluxes%buoy is the buoyancy flux into the ocean [m2 s-3]. A positive ! buoyancy flux is of the same sign as heating the ocean. fluxes%buoy(i,j) = 0.0 * G%mask2dT(i,j) enddo ; enddo @@ -134,8 +127,8 @@ subroutine BFB_buoyancy_forcing(state, fluxes, day, dt, G, CS) rhoXcp = CS%Rho0 * fluxes%C_p do j=js,je ; do i=is,ie - ! Set Temp_restore and Salin_restore to the temperature (in C) and - ! salinity (in PSU) that are being restored toward. + ! Set Temp_restore and Salin_restore to the temperature (in degC) and + ! salinity (in ppt) that are being restored toward. Temp_restore = 0.0 Salin_restore = 0.0 @@ -156,7 +149,7 @@ subroutine BFB_buoyancy_forcing(state, fluxes, day, dt, G, CS) Temp_restore = 0.0 do j=js,je ; do i=is,ie ! Set density_restore to an expression for the surface potential - ! density in kg m-3 that is being restored toward. + ! density [kg m-3] that is being restored toward. if (G%geoLatT(i,j) < CS%lfrslat) then Temp_restore = CS%SST_s elseif (G%geoLatT(i,j) > CS%lfrnlat) then diff --git a/src/user/DOME2d_initialization.F90 b/src/user/DOME2d_initialization.F90 index f20e4466bd..b81061ab29 100644 --- a/src/user/DOME2d_initialization.F90 +++ b/src/user/DOME2d_initialization.F90 @@ -28,6 +28,11 @@ module DOME2d_initialization public DOME2d_initialize_temperature_salinity public DOME2d_initialize_sponges +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + character(len=40) :: mdl = "DOME2D_initialization" !< This module's name. contains @@ -90,17 +95,17 @@ subroutine DOME2d_initialize_thickness ( h, G, GV, US, param_file, just_read_par type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables - real :: e0(SZK_(GV)) ! The resting interface heights, in depth units (Z), usually + real :: e0(SZK_(GV)) ! The resting interface heights, in depth units [Z ~> m], usually ! negative because it is positive upward. real :: eta1D(SZK_(GV)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). + ! positive upward, in depth units [Z ~> m]. integer :: i, j, k, is, ie, js, je, nz real :: x real :: delta_h @@ -220,9 +225,9 @@ subroutine DOME2d_initialize_temperature_salinity ( T, S, h, G, GV, param_file, eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (ppt) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness in units of H (m or kg m-2) + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< Parameter file structure type(EOS_type), pointer :: eqn_of_state !< Equation of state structure logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -357,19 +362,19 @@ subroutine DOME2d_initialize_sponges(G, GV, tv, param_file, use_ALE, CSp, ACSp) type(sponge_CS), pointer :: CSp !< Layer-mode sponge structure type(ALE_sponge_CS), pointer :: ACSp !< ALE-mode sponge structure ! Local variables - real :: T(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for temp - real :: S(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for salt - real :: RHO(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for RHO - real :: h(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for thickness, in m. - real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for thickness - real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate, in s-1. + real :: T(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for temp [degC] + real :: S(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for salt [ppt] + real :: RHO(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for RHO [kg m-3] + real :: h(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for thickness [H ~> m or kg m-2]. + real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for thickness [Z ~> m] + real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1]. real :: S_ref, T_ref ! Reference salinity and temerature within surface layer real :: S_range, T_range ! Range of salinities and temperatures over the vertical - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), + real :: e0(SZK_(G)+1) ! The resting interface heights [Z ~> m], ! usually negative because it is positive upward. real :: eta1D(SZK_(G)+1) ! Interface height relative to the sea surface - ! positive upward, in Z. - real :: d_eta(SZK_(G)) ! The layer thickness in a column, in Z. + ! positive upward [Z ~> m]. + real :: d_eta(SZK_(G)) ! The layer thickness in a column [Z ~> m]. real :: dome2d_width_bay, dome2d_width_bottom, dome2d_depth_bay real :: dome2d_west_sponge_time_scale, dome2d_east_sponge_time_scale real :: dome2d_west_sponge_width, dome2d_east_sponge_width diff --git a/src/user/DOME_initialization.F90 b/src/user/DOME_initialization.F90 index 101e52eb30..e3685ae16f 100644 --- a/src/user/DOME_initialization.F90 +++ b/src/user/DOME_initialization.F90 @@ -28,6 +28,11 @@ module DOME_initialization public DOME_initialize_sponges public DOME_set_OBC_data +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains ! ----------------------------------------------------------------------------- @@ -42,7 +47,7 @@ subroutine DOME_initialize_topography(D, G, param_file, max_depth, US) ! Local variables real :: m_to_Z ! A dimensional rescaling factor. - real :: min_depth ! The minimum and maximum depths in Z. + real :: min_depth ! The minimum and maximum depths [Z ~> m]. ! This include declares and sets the variable "version". # include "version_variable.h" character(len=40) :: mdl = "DOME_initialize_topography" ! This subroutine's name. @@ -86,16 +91,16 @@ subroutine DOME_initialize_thickness(h, G, GV, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: e0(SZK_(GV)+1) ! The resting interface heights, in m, usually - ! negative because it is positive upward, in depth units (Z). + real :: e0(SZK_(GV)+1) ! The resting interface heights [Z ~> m], usually + ! negative because it is positive upward [Z ~> m]. real :: eta1D(SZK_(GV)+1) ! Interface height relative to the sea surface - ! positive upward, in depth units (Z). + ! positive upward [Z ~> m]. logical :: just_read ! If true, just read parameters but set nothing. character(len=40) :: mdl = "DOME_initialize_thickness" ! This subroutine's name. integer :: i, j, k, is, ie, js, je, nz @@ -154,9 +159,9 @@ subroutine DOME_initialize_sponges(G, GV, US, tv, PF, CSp) real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta. real :: temp(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for other variables. ! - real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate, in s-1. + real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1]. - real :: H0(SZK_(G)) ! Interface heights in depth units (Z) + real :: H0(SZK_(G)) ! Interface heights [Z ~> m]. real :: min_depth real :: damp, e_dense, damp_new character(len=40) :: mdl = "DOME_initialize_sponges" ! This subroutine's name. @@ -167,7 +172,7 @@ subroutine DOME_initialize_sponges(G, GV, US, tv, PF, CSp) eta(:,:,:) = 0.0 ; temp(:,:,:) = 0.0 ; Idamp(:,:) = 0.0 -! Here the inverse damping time, in s-1, is set. Set Idamp to 0 ! +! Here the inverse damping time [s-1], is set. Set Idamp to 0 ! ! wherever there is no sponge, and the subroutines that are called ! ! will automatically set up the sponges only where Idamp is positive! ! and mask2dT is 1. ! @@ -254,15 +259,15 @@ subroutine DOME_set_OBC_data(OBC, tv, G, GV, US, param_file, tr_Reg) ! Local variables ! The following variables are used to set the target temperature and salinity. real :: T0(SZK_(G)), S0(SZK_(G)) - real :: pres(SZK_(G)) ! An array of the reference pressure in Pa. - real :: drho_dT(SZK_(G)) ! Derivative of density with temperature in kg m-3 K-1. ! - real :: drho_dS(SZK_(G)) ! Derivative of density with salinity in kg m-3 PSU-1. ! - real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 in kg m-3. + real :: pres(SZK_(G)) ! An array of the reference pressure [Pa]. + real :: drho_dT(SZK_(G)) ! Derivative of density with temperature [kg m-3 degC-1]. + real :: drho_dS(SZK_(G)) ! Derivative of density with salinity [kg m-3 ppt-1]. + real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 [kg m-3]. ! The following variables are used to set up the transport in the DOME example. real :: tr_0, y1, y2, tr_k, rst, rsb, rc, v_k, lon_im1 - real :: D_edge ! The thickness in Z of the dense fluid at the + real :: D_edge ! The thickness [Z ~> m], of the dense fluid at the ! inner edge of the inflow. - real :: g_prime_tot ! The reduced gravity across all layers, m2 Z-1 s-2. + real :: g_prime_tot ! The reduced gravity across all layers [m2 Z-1 s-2 ~> m s-2]. real :: Def_Rad ! The deformation radius, based on fluid of ! thickness D_edge, in the same units as lat. real :: Ri_trans ! The shear Richardson number in the transition diff --git a/src/user/ISOMIP_initialization.F90 b/src/user/ISOMIP_initialization.F90 index 6a3bf8007e..39c9321111 100644 --- a/src/user/ISOMIP_initialization.F90 +++ b/src/user/ISOMIP_initialization.F90 @@ -33,6 +33,11 @@ module ISOMIP_initialization public ISOMIP_initialize_temperature_salinity public ISOMIP_initialize_sponges +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Initialization of topography for the ISOMIP configuration @@ -45,17 +50,17 @@ subroutine ISOMIP_initialize_topography(D, G, param_file, max_depth, US) type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type ! Local variables - real :: min_depth ! The minimum and maximum depths in Z. + real :: min_depth ! The minimum and maximum depths [Z ~> m]. real :: m_to_Z ! A dimensional rescaling factor. ! The following variables are used to set up the bathymetry in the ISOMIP example. real :: bmax ! max depth of bedrock topography real :: b0,b2,b4,b6 ! first, second, third and fourth bedrock topography coeff real :: xbar ! characteristic along-flow lenght scale of the bedrock - real :: dc ! depth of the trough compared with side walls in Z + real :: dc ! depth of the trough compared with side walls [Z ~> m]. real :: fc ! characteristic width of the side walls of the channel real :: wc ! half-width of the trough real :: ly ! domain width (across ice flow) - real :: bx, by ! dummy vatiables in Z + real :: bx, by ! dummy vatiables [Z ~> m]. real :: xtil ! dummy vatiable logical :: is_2D ! If true, use 2D setup ! This include declares and sets the variable "version". @@ -130,7 +135,7 @@ subroutine ISOMIP_initialize_thickness ( h, G, GV, US, param_file, tv, just_read type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any @@ -139,10 +144,10 @@ subroutine ISOMIP_initialize_thickness ( h, G, GV, US, param_file, tv, just_read logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), + real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units [Z ~> m], ! usually negative because it is positive upward. real :: eta1D(SZK_(G)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). + ! positive upward, in depth units [Z ~> m]. integer :: i, j, k, is, ie, js, je, nz, tmp1 real :: x real :: rho_range @@ -247,9 +252,9 @@ subroutine ISOMIP_initialize_temperature_salinity ( T, S, h, G, GV, param_file, eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (ppt) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness in H (m or kg m-2) + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< Parameter file structure type(EOS_type), pointer :: eqn_of_state !< Equation of state structure logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -257,20 +262,22 @@ subroutine ISOMIP_initialize_temperature_salinity ( T, S, h, G, GV, param_file, ! Local variables integer :: i, j, k, is, ie, js, je, nz, itt real :: x, ds, dt, rho_sur, rho_bot - real :: xi0, xi1 ! Heights in depth units (Z). - real :: S_sur, T_sur, S_bot, T_bot - real :: dT_dz, dS_dz ! Gradients of T and S in degC/Z and PPT/Z. - real :: z ! vertical position in z space - character(len=256) :: mesg ! The text of an error message + real :: xi0, xi1 ! Heights in depth units [Z ~> m]. + real :: S_sur, S_bot ! Salinity at the surface and bottom [ppt] + real :: T_sur, T_bot ! Temperature at the bottom [degC] + real :: dT_dz ! Vertical gradient of temperature [degC Z-1 ~> degC m-1]. + real :: dS_dz ! Vertical gradient of salinity [ppt Z-1 ~> ppt m-1]. + real :: z ! vertical position in z space [Z ~> m] + character(len=256) :: mesg ! The text of an error message character(len=40) :: verticalCoordinate, density_profile real :: rho_tmp - logical :: just_read ! If true, just read parameters but set nothing. + logical :: just_read ! If true, just read parameters but set nothing. logical :: fit_salin ! If true, accept the prescribed temperature and fit the salinity. real :: T0(SZK_(G)), S0(SZK_(G)) - real :: drho_dT(SZK_(G)) ! Derivative of density with temperature in kg m-3 K-1. ! - real :: drho_dS(SZK_(G)) ! Derivative of density with salinity in kg m-3 PSU-1. ! - real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 in kg m-3. - real :: pres(SZK_(G)) ! An array of the reference pressure in Pa. (zero here) + real :: drho_dT(SZK_(G)) ! Derivative of density with temperature [kg m-3 degC-1]. + real :: drho_dS(SZK_(G)) ! Derivative of density with salinity [kg m-3 ppt-1]. + real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 [kg m-3]. + real :: pres(SZK_(G)) ! An array of the reference pressure [Pa]. (zero here) real :: drho_dT1, drho_dS1, T_Ref, S_Ref is = G%isc ; ie = G%iec ; js = G%jsc ; je = G%jec ; nz = G%ke pres(:) = 0.0 @@ -428,7 +435,7 @@ subroutine ISOMIP_initialize_sponges(G, GV, US, tv, PF, use_ALE, CSp, ACSp) real :: S(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for salt real :: RHO(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for RHO real :: h(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for thickness - real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate, in s-1. + real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1]. real :: TNUDG ! Nudging time scale, days real :: S_sur, T_sur ! Surface salinity and temerature in sponge real :: S_bot, T_bot ! Bottom salinity and temerature in sponge @@ -436,10 +443,10 @@ subroutine ISOMIP_initialize_sponges(G, GV, US, tv, PF, use_ALE, CSp, ACSp) real :: rho_sur, rho_bot, rho_range real :: dT_dz, dS_dz ! Gradients of T and S in degC/Z and PPT/Z. - real :: e0(SZK_(G)+1) ! The resting interface heights, in Z, usually + real :: e0(SZK_(G)+1) ! The resting interface heights [Z ~> m], usually ! negative because it is positive upward. - real :: eta1D(SZK_(G)+1) ! Interface height relative to the sea surface, positive upward, in Z. - real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta, in Z. + real :: eta1D(SZK_(G)+1) ! Interface height relative to the sea surface, positive upward [Z ~> m]. + real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta [Z ~> m]. real :: min_depth, dummy1, z real :: damp, rho_dummy, min_thickness, rho_tmp, xi0 character(len=40) :: verticalCoordinate, filename, state_file @@ -466,10 +473,10 @@ subroutine ISOMIP_initialize_sponges(G, GV, US, tv, PF, use_ALE, CSp, ACSp) do_not_log=.true.) call get_param(PF, mdl, "ISOMIP_S_SUR_SPONGE", s_sur, & - 'Surface salinity in sponge layer.', default=s_ref) ! units="PSU") + 'Surface salinity in sponge layer.', default=s_ref) ! units="ppt") call get_param(PF, mdl, "ISOMIP_S_BOT_SPONGE", s_bot, & - 'Bottom salinity in sponge layer.', default=s_ref) ! units="PSU") + 'Bottom salinity in sponge layer.', default=s_ref) ! units="ppt") call get_param(PF, mdl, "ISOMIP_T_SUR_SPONGE", t_sur, & 'Surface temperature in sponge layer.', default=t_ref) ! units="degC") @@ -488,7 +495,7 @@ subroutine ISOMIP_initialize_sponges(G, GV, US, tv, PF, use_ALE, CSp, ACSp) if (associated(ACSp)) call MOM_error(FATAL, & "ISOMIP_initialize_sponges called with an associated ALE-sponge control structure.") - ! Here the inverse damping time, in s-1, is set. Set Idamp to 0 ! + ! Here the inverse damping time [s-1], is set. Set Idamp to 0 ! ! wherever there is no sponge, and the subroutines that are called ! ! will automatically set up the sponges only where Idamp is positive! ! and mask2dT is 1. diff --git a/src/user/Idealized_Hurricane.F90 b/src/user/Idealized_Hurricane.F90 index 36aef6df6c..c29e3beded 100644 --- a/src/user/Idealized_Hurricane.F90 +++ b/src/user/Idealized_Hurricane.F90 @@ -45,15 +45,15 @@ module Idealized_hurricane type, public :: idealized_hurricane_CS ; private ! Parameters used to compute Holland radial wind profile - real :: rho_a !< Mean air density [kg/m3] + real :: rho_a !< Mean air density [kg m-3] real :: pressure_ambient !< Pressure at surface of ambient air [Pa] real :: pressure_central !< Pressure at surface at hurricane center [Pa] real :: rad_max_wind !< Radius of maximum winds [m] - real :: max_windspeed !< Maximum wind speeds [m/s] - real :: hurr_translation_spd !< Hurricane translation speed [m/s] - real :: hurr_translation_dir !< Hurricane translation speed [m/s] - real :: gustiness !< Gustiness (optional, used in u*) [m/s] - real :: Rho0 !< A reference ocean density [kg/m3] + real :: max_windspeed !< Maximum wind speeds [m s-1] + real :: hurr_translation_spd !< Hurricane translation speed [m s-1] + real :: hurr_translation_dir !< Hurricane translation speed [m s-1] + real :: gustiness !< Gustiness (optional, used in u*) [m s-1] + real :: Rho0 !< A reference ocean density [kg m-3] real :: Hurr_cen_Y0 !< The initial y position of the hurricane !! This experiment is conducted in a Cartesian !! grid and this is assumed to be in meters [m] @@ -69,7 +69,7 @@ module Idealized_hurricane ! Parameters used if in SCM (single column model) mode - logical :: SCM_mode !< Single Column Model Mode [nd] + logical :: SCM_mode !< If true this being used in Single Column Model mode logical :: BR_BENCH !< A "benchmark" configuration (which is meant to !! provide identical wind to reproduce a previous !! experiment, where that wind formula contained @@ -198,10 +198,10 @@ end subroutine idealized_hurricane_wind_init !> Computes the surface wind for the idealized hurricane test cases subroutine idealized_hurricane_wind_forcing(state, forces, day, G, US, CS) - type(surface), intent(in) :: state !< Surface state structure - type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces - type(time_type), intent(in) :: day !< Time in days - type(ocean_grid_type), intent(inout) :: G !< Grid structure + type(surface), intent(in) :: state !< Surface state structure + type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces + type(time_type), intent(in) :: day !< Time in days + type(ocean_grid_type), intent(inout) :: G !< Grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(idealized_hurricane_CS), pointer :: CS !< Container for idealized hurricane parameters @@ -553,7 +553,7 @@ subroutine SCM_idealized_hurricane_wind_forcing(state, forces, day, G, US, CS) U_TS = CS%hurr_translation_spd/2.*cos(transdir) V_TS = CS%hurr_translation_spd/2.*sin(transdir) - ! Set the surface wind stresses, in units of Pa. A positive taux + ! Set the surface wind stresses, in [Pa]. A positive taux ! accelerates the ocean to the (pseudo-)east. ! The i-loop extends to is-1 so that taux can be used later in the ! calculation of ustar - otherwise the lower bound would be Isq. @@ -601,7 +601,7 @@ subroutine SCM_idealized_hurricane_wind_forcing(state, forces, day, G, US, CS) endif forces%tauy(I,j) = CS%rho_a * G%mask2dCv(I,j) * Cd*du10*dV enddo ; enddo - ! Set the surface friction velocity, in units of m s-1. ustar is always positive. + ! Set the surface friction velocity [m s-1]. ustar is always positive. do j=js,je ; do i=is,ie ! This expression can be changed if desired, but need not be. forces%ustar(i,j) = US%m_to_Z * G%mask2dT(i,j) * sqrt(CS%gustiness/CS%Rho0 + & diff --git a/src/user/Kelvin_initialization.F90 b/src/user/Kelvin_initialization.F90 index 1fd9edb3ea..85e11435dc 100644 --- a/src/user/Kelvin_initialization.F90 +++ b/src/user/Kelvin_initialization.F90 @@ -27,6 +27,11 @@ module Kelvin_initialization public Kelvin_set_OBC_data, Kelvin_initialize_topography public register_Kelvin_OBC, Kelvin_OBC_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for Kelvin wave open boundaries. type, public :: Kelvin_OBC_CS ; private integer :: mode = 0 !< Vertical mode @@ -121,7 +126,7 @@ subroutine Kelvin_initialize_topography(D, G, param_file, max_depth, US) ! Local variables character(len=40) :: mdl = "Kelvin_initialize_topography" ! This subroutine's name. real :: m_to_Z ! A dimensional rescaling factor. - real :: min_depth ! The minimum and maximum depths in Z. + real :: min_depth ! The minimum and maximum depths [Z ~> m]. real :: PI ! 3.1415... real :: coast_offset1, coast_offset2, coast_angle, right_angle integer :: i, j @@ -170,16 +175,16 @@ subroutine Kelvin_set_OBC_data(OBC, CS, G, GV, US, h, Time) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness, in H. + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< layer thickness [H ~> m or kg m-2]. type(time_type), intent(in) :: Time !< model time. ! The following variables are used to set up the transport in the Kelvin example. real :: time_sec, cff - real :: N0 ! Brunt-Vaisala frequency in s-1 + real :: N0 ! Brunt-Vaisala frequency [s-1] real :: plx !< Longshore wave parameter real :: pmz !< Vertical wave parameter real :: lambda !< Offshore decay scale - real :: omega !< Wave frequency in s-1 + real :: omega !< Wave frequency [s-1] real :: PI integer :: i, j, k, n, is, ie, js, je, isd, ied, jsd, jed, nz integer :: IsdB, IedB, JsdB, JedB diff --git a/src/user/MOM_controlled_forcing.F90 b/src/user/MOM_controlled_forcing.F90 index 2034a16bb4..a061fcb3eb 100644 --- a/src/user/MOM_controlled_forcing.F90 +++ b/src/user/MOM_controlled_forcing.F90 @@ -36,23 +36,23 @@ module MOM_controlled_forcing logical :: do_integrated !< If true, use time-integrated anomalies to control !! the surface state. integer :: num_cycle !< The number of elements in the forcing cycle. - real :: heat_int_rate !< The rate at which heating anomalies accumulate, in s-1. - real :: prec_int_rate !< The rate at which precipitation anomalies accumulate, in s-1. + real :: heat_int_rate !< The rate at which heating anomalies accumulate [s-1]. + real :: prec_int_rate !< The rate at which precipitation anomalies accumulate [s-1]. real :: heat_cyc_rate !< The rate at which cyclical heating anomaliess - !! accumulate, in s-1. + !! accumulate [s-1]. real :: prec_cyc_rate !< The rate at which cyclical precipitation anomaliess - !! accumulate, in s-1. + !! accumulate [s-1]. real :: Len2 !< The square of the length scale over which the anomalies - !! are smoothed via a Laplacian filter, in m2. + !! are smoothed via a Laplacian filter [m2]. real :: lam_heat !< A constant of proportionality between SST anomalies - !! and heat fluxes, in W m-2 K-1. + !! and heat fluxes [W m-2 degC-1]. real :: lam_prec !< A constant of proportionality between SSS anomalies - !! (normalised by mean SSS) and precipitation, in kg m-2. + !! (normalised by mean SSS) and precipitation [kg m-2]. real :: lam_cyc_heat !< A constant of proportionality between cyclical SST - !! anomalies and corrective heat fluxes, in W m-2 K-1. + !! anomalies and corrective heat fluxes [W m-2 degC-1]. real :: lam_cyc_prec !< A constant of proportionality between cyclical SSS !! anomalies (normalised by mean SSS) and corrective - !! precipitation, in kg m-2. + !! precipitation [kg m-2]. !>@{ Pointers for data. !! \todo Needs more complete documentation. @@ -81,21 +81,21 @@ subroutine apply_ctrl_forcing(SST_anom, SSS_anom, SSS_mean, virt_heat, virt_prec day_start, dt, G, CS) type(ocean_grid_type), intent(inout) :: G !< The ocean's grid structure. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: SST_anom !< The sea surface temperature - !! anomalies, in deg C. + !! anomalies [degC]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: SSS_anom !< The sea surface salinity - !! anomlies, in g kg-1. + !! anomlies [ppt]. real, dimension(SZI_(G),SZJ_(G)), intent(in) :: SSS_mean !< The mean sea surface - !! salinity, in g kg-1. + !! salinity [ppt]. real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: virt_heat !< Virtual (corrective) heat !! fluxes that are augmented - !! in this subroutine, in W m-2. + !! in this subroutine [W m-2]. real, dimension(SZI_(G),SZJ_(G)), intent(inout) :: virt_precip !< Virtual (corrective) !! precipitation fluxes that !! are augmented in this - !! subroutine, in kg m-2 s-1. + !! subroutine [kg m-2 s-1]. type(time_type), intent(in) :: day_start !< Start time of the fluxes. real, intent(in) :: dt !< Length of time over which these - !! fluxes will be applied, in s. + !! fluxes will be applied [s]. type(ctrl_forcing_CS), pointer :: CS !< A pointer to the control structure !! returned by a previous call to !! ctrl_forcing_init. @@ -107,7 +107,7 @@ subroutine apply_ctrl_forcing(SST_anom, SSS_anom, SSS_mean, virt_heat, virt_prec flux_heat_y, & flux_prec_y type(time_type) :: day_end - real :: coef ! A heat-flux coefficient with units of m2. + real :: coef ! A heat-flux coefficient [m2]. real :: mr_st, mr_end, mr_mid, mr_prev, mr_next real :: dt_wt, dt_heat_rate, dt_prec_rate real :: dt1_heat_rate, dt1_prec_rate, dt2_heat_rate, dt2_prec_rate diff --git a/src/user/MOM_wave_interface.F90 b/src/user/MOM_wave_interface.F90 index f9934615dc..fedd46ab03 100644 --- a/src/user/MOM_wave_interface.F90 +++ b/src/user/MOM_wave_interface.F90 @@ -17,9 +17,7 @@ module MOM_wave_interface use MOM_verticalgrid, only : verticalGrid_type use data_override_mod, only : data_override_init, data_override -implicit none - -private +implicit none ; private #include @@ -40,6 +38,10 @@ module MOM_wave_interface ! CL2 effects. public Waves_end ! public interface to deallocate and free wave related memory. +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. !> Container for all surface wave related parameters type, public :: wave_parameters_CS ; private @@ -67,19 +69,19 @@ module MOM_wave_interface ! Surface Wave Dependent 1d/2d/3d vars real, allocatable, dimension(:), public :: & - WaveNum_Cen !< Wavenumber bands for read/coupled (1/m) + WaveNum_Cen !< Wavenumber bands for read/coupled [m-1] real, allocatable, dimension(:), public :: & - Freq_Cen !< Frequency bands for read/coupled (1/s) + Freq_Cen !< Frequency bands for read/coupled [s-1] real, allocatable, dimension(:), public :: & - PrescribedSurfStkX !< Surface Stokes drift if prescribed (m/s) + PrescribedSurfStkX !< Surface Stokes drift if prescribed [m s-1] real, allocatable, dimension(:), public :: & - PrescribedSurfStkY !< Surface Stokes drift if prescribed (m/s) + PrescribedSurfStkY !< Surface Stokes drift if prescribed [m s-1] real, allocatable, dimension(:,:,:), public :: & - Us_x !< 3d Stokes drift profile (zonal, m/s) + Us_x !< 3d zonal Stokes drift profile [m s-1] !! Horizontal -> U points !! Vertical -> Mid-points real, allocatable, dimension(:,:,:), public :: & - Us_y !< 3d Stokes drift profile (meridional, m/s) + Us_y !< 3d meridional Stokes drift profile [m s-1] !! Horizontal -> V points !! Vertical -> Mid-points real, allocatable, dimension(:,:), public :: & @@ -102,7 +104,7 @@ module MOM_wave_interface !! Horizontal -> V points !! 3rd dimension -> Freq/Wavenumber real, allocatable, dimension(:,:,:), public :: & - KvS !< Viscosity for Stokes Drift shear (Z2/s) + KvS !< Viscosity for Stokes Drift shear [Z2/s ~> m2 s-1] ! Pointers to auxiliary fields type(time_type), pointer, public :: Time !< A pointer to the ocean model's clock. @@ -187,7 +189,7 @@ module MOM_wave_interface !> Initializes parameters related to MOM_wave_interface subroutine MOM_wave_interface_init(time, G, GV, US, param_file, CS, diag ) - type(time_type), target, intent(in) :: Time !< Time (s) + type(time_type), target, intent(in) :: Time !< Model time type(ocean_grid_type), intent(inout) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type @@ -424,8 +426,8 @@ subroutine Update_Surface_Waves(G, GV, US, Day, dt, CS) type(ocean_grid_type), intent(inout) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - type(time_type), intent(in) :: Day !< Time (s) - type(time_type), intent(in) :: dt !< Timestep (s) + type(time_type), intent(in) :: Day !< Current model time + type(time_type), intent(in) :: dt !< Timestep as a time-type ! Local variables integer :: ii, jj, kk, b type(time_type) :: Day_Center @@ -467,9 +469,9 @@ subroutine Update_Stokes_Drift(G, GV, US, CS, h, ustar) type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Thickness (m or kg/m2) + intent(in) :: h !< Thickness [H ~> m or kg m-2] real, dimension(SZI_(G),SZJ_(G)), & - intent(in) :: ustar !< Wind friction velocity (Z/s) + intent(in) :: ustar !< Wind friction velocity [Z s-1 ~> m s-1]. ! Local Variables real :: Top, MidPoint, Bottom, one_cm real :: DecayScale @@ -690,14 +692,14 @@ end subroutine Update_Stokes_Drift !! using the data_override procedures. subroutine Surface_Bands_by_data_override(day_center, G, GV, US, CS) use NETCDF - type(time_type), intent(in) :: day_center !< Center of timestep (s) + type(time_type), intent(in) :: day_center !< Center of timestep type(wave_parameters_CS), pointer :: CS !< Wave structure type(ocean_grid_type), intent(inout) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type ! Local variables - real :: temp_x(SZI_(G),SZJ_(G)) ! Pseudo-zonal and psuedo-meridional - real :: temp_y(SZI_(G),SZJ_(G)) ! Stokes drift of band at h-points, in m/s + real :: temp_x(SZI_(G),SZJ_(G)) ! Pseudo-zonal Stokes drift of band at h-points [m s-1] + real :: temp_y(SZI_(G),SZJ_(G)) ! Psuedo-meridional Stokes drift of band at h-points [m s-1] real :: Top, MidPoint integer :: b integer :: i, j @@ -864,18 +866,18 @@ subroutine get_Langmuir_Number( LA, G, GV, US, HBL, ustar, i, j, & type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type integer, intent(in) :: i !< Meridional index of h-point integer, intent(in) :: j !< Zonal index of h-point - real, intent(in) :: ustar !< Friction velocity (Z/s) - real, intent(in) :: HBL !< (Positive) thickness of boundary layer (Z) + real, intent(in) :: ustar !< Friction velocity [Z s-1 ~> m s-1]. + real, intent(in) :: HBL !< (Positive) thickness of boundary layer [Z ~> m]. logical, optional, intent(in) :: Override_MA !< Override to use misalignment in LA !! calculation. This can be used if diagnostic !! LA outputs are desired that are different than !! those used by the dynamical model. real, dimension(SZK_(GV)), optional, & - intent(in) :: H !< Grid layer thickness in H (m or kg/m2) + intent(in) :: H !< Grid layer thickness [H ~> m or kg m-2] real, dimension(SZK_(GV)), optional, & - intent(in) :: U_H !< Zonal velocity at H point (m/s) + intent(in) :: U_H !< Zonal velocity at H point [m s-1] real, dimension(SZK_(GV)), optional, & - intent(in) :: V_H !< Meridional velocity at H point (m/s) + intent(in) :: V_H !< Meridional velocity at H point [m s-1] type(Wave_parameters_CS), & pointer :: Waves !< Surface wave control structure. @@ -964,7 +966,7 @@ end subroutine get_Langmuir_Number !! !! Original description: !! - This function returns the enhancement factor, given the 10-meter -!! wind (m/s), friction velocity (m/s) and the boundary layer depth (m). +!! wind [m s-1], friction velocity [m s-1] and the boundary layer depth [m]. !! !! Update (Jan/25): !! - Converted from function to subroutine, now returns Langmuir number. @@ -977,11 +979,11 @@ end subroutine get_Langmuir_Number !! - BGR remove u10 input !! - BGR note: fixed parameter values should be changed to "get_params" subroutine get_StokesSL_LiFoxKemper(ustar, hbl, GV, US, UStokes_SL, LA) - real, intent(in) :: ustar !< water-side surface friction velocity (Z/s) - real, intent(in) :: hbl !< boundary layer depth (Z) + real, intent(in) :: ustar !< water-side surface friction velocity [Z s-1 ~> m s-1]. + real, intent(in) :: hbl !< boundary layer depth [Z ~> m]. type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(out) :: UStokes_SL !< Surface layer averaged Stokes drift (m/s) + real, intent(out) :: UStokes_SL !< Surface layer averaged Stokes drift [m s-1] real, intent(out) :: LA !< Langmuir number ! Local variables ! parameters @@ -1058,16 +1060,16 @@ end subroutine Get_StokesSL_LiFoxKemper subroutine Get_SL_Average_Prof( GV, AvgDepth, H, Profile, Average ) type(verticalGrid_type), & intent(in) :: GV !< Ocean vertical grid structure - real, intent(in) :: AvgDepth !< Depth to average over (Z) + real, intent(in) :: AvgDepth !< Depth to average over [Z ~> m]. real, dimension(SZK_(GV)), & - intent(in) :: H !< Grid thickness (H) + intent(in) :: H !< Grid thickness [H ~> m or kg m-2] real, dimension(SZK_(GV)), & - intent(in) :: Profile !< Profile of quantity to be averaged - !! (used here for Stokes drift, m/s) - real, intent(out) :: Average !< Output quantity averaged over depth AvgDepth - !! (used here for Stokes drift, m/s) + intent(in) :: Profile !< Profile of quantity to be averaged [arbitrary] + !! (used here for Stokes drift) + real, intent(out) :: Average !< Output quantity averaged over depth AvgDepth [arbitrary] + !! (used here for Stokes drift) !Local variables - real :: top, midpoint, bottom ! Depths in Z + real :: top, midpoint, bottom ! Depths [Z ~> m]. real :: Sum integer :: kk @@ -1097,13 +1099,13 @@ end subroutine Get_SL_Average_Prof subroutine Get_SL_Average_Band( GV, AvgDepth, NB, WaveNumbers, SurfStokes, Average ) type(verticalGrid_type), & intent(in) :: GV !< Ocean vertical grid - real, intent(in) :: AvgDepth !< Depth to average over (Z) + real, intent(in) :: AvgDepth !< Depth to average over [Z ~> m]. integer, intent(in) :: NB !< Number of bands used real, dimension(NB), & - intent(in) :: WaveNumbers !< Wavenumber corresponding to each band (1/Z) + intent(in) :: WaveNumbers !< Wavenumber corresponding to each band [Z-1 ~> m-1] real, dimension(NB), & - intent(in) :: SurfStokes !< Surface Stokes drift for each band (m/s) - real, intent(out) :: Average !< Output average Stokes drift over depth AvgDepth (m/s) + intent(in) :: SurfStokes !< Surface Stokes drift for each band [m s-1] + real, intent(out) :: Average !< Output average Stokes drift over depth AvgDepth [m s-1] ! Local variables integer :: bb @@ -1130,8 +1132,8 @@ end subroutine Get_SL_Average_Band subroutine DHH85_mid(GV, US, zpt, UStokes) type(verticalGrid_type), intent(in) :: GV !< Ocean vertical grid type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, intent(in) :: ZPT !< Depth to get Stokes drift (Z) !### THIS IS NOT USED YET. - real, intent(out) :: UStokes !< Stokes drift (m/s) + real, intent(in) :: ZPT !< Depth to get Stokes drift [Z ~> m]. !### THIS IS NOT USED YET. + real, intent(out) :: UStokes !< Stokes drift [m s-1] ! real :: ann, Bnn, Snn, Cnn, Dnn real :: omega_peak, omega, u10, WA, domega @@ -1188,16 +1190,16 @@ subroutine StokesMixing(G, GV, DT, h, u, v, Waves ) intent(in) :: GV !< Ocean vertical grid real, intent(in) :: Dt !< Time step of MOM6 [s] for explicit solver real, dimension(SZI_(G),SZJ_(G),SZK_(G)),& - intent(in) :: h !< Layer/level thicknesses (units of H) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: u !< Velocity i-component (m/s) + intent(inout) :: u !< Velocity i-component [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: v !< Velocity j-component (m/s) + intent(inout) :: v !< Velocity j-component [m s-1] type(Wave_parameters_CS), & pointer :: Waves !< Surface wave related control structure. ! Local variables real :: dTauUp, dTauDn - real :: h_Lay ! The layer thickness at a velocity point, in Z. + real :: h_Lay ! The layer thickness at a velocity point [Z ~> m]. integer :: i,j,k ! This is a template to think about down-Stokes mixing. @@ -1256,11 +1258,11 @@ subroutine CoriolisStokes(G, GV, DT, h, u, v, WAVES) intent(in) :: GV !< Ocean vertical grid real, intent(in) :: Dt !< Time step of MOM6 [s] CHECK IF PASSING RIGHT TIMESTEP real, dimension(SZI_(G),SZJ_(G),SZK_(G)), & - intent(in) :: h !< Layer/level thicknesses (units of H) + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(inout) :: u !< Velocity i-component (m/s) + intent(inout) :: u !< Velocity i-component [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(inout) :: v !< Velocity j-component (m/s) + intent(inout) :: v !< Velocity j-component [m s-1] type(Wave_parameters_CS), & pointer :: Waves !< Surface wave related control structure. ! Local variables @@ -1293,8 +1295,8 @@ end subroutine CoriolisStokes !! wind speed for wind-wave relationships. Should be a fine way to estimate !! the neutral wind-speed as written here. subroutine ust_2_u10_coare3p5(USTair, U10, GV, US) - real, intent(in) :: USTair !< Wind friction velocity (m/s) - real, intent(out) :: U10 !< 10-m neutral wind speed (m/s) + real, intent(in) :: USTair !< Wind friction velocity [m s-1] + real, intent(out) :: U10 !< 10-m neutral wind speed [m s-1] type(verticalGrid_type), intent(in) :: GV !< vertical grid type type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type diff --git a/src/user/Neverland_initialization.F90 b/src/user/Neverland_initialization.F90 index 131b77ab31..949530e773 100644 --- a/src/user/Neverland_initialization.F90 +++ b/src/user/Neverland_initialization.F90 @@ -24,6 +24,11 @@ module Neverland_initialization public Neverland_initialize_topography public Neverland_initialize_thickness +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> This subroutine sets up the Neverland test case topography. @@ -110,19 +115,19 @@ subroutine Neverland_initialize_thickness(h, G, GV, US, param_file, eqn_of_state type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, intent(out), dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h !< The thickness that is being - !! initialized, in H. + !! initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open !! file to parse for model !! parameter values. type(EOS_type), pointer :: eqn_of_state !< integer that selects the !! equation of state. real, intent(in) :: P_Ref !< The coordinate-density - !! reference pressure in Pa. + !! reference pressure [Pa]. ! Local variables - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), + real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units [Z ~> m], ! usually negative because it is positive upward. - real, dimension(SZK_(G)) :: h_profile ! Vector of initial thickness profile (Z) - real :: e_interface ! Current interface position (m) + real, dimension(SZK_(G)) :: h_profile ! Vector of initial thickness profile [Z ~> m]. + real :: e_interface ! Current interface position [Z ~> m]. real :: x,y,r1,r2 ! x,y and radial coordinates for computation of initial pert. real :: pert_amp ! Amplitude of perturbations measured in Angstrom_H real :: h_noise ! Amplitude of noise to scale h by @@ -157,7 +162,8 @@ subroutine Neverland_initialize_thickness(h, G, GV, US, param_file, eqn_of_state y=(G%geoLatT(i,j)-G%south_lat)/G%len_lat r1=sqrt((x-0.7)**2+(y-0.2)**2) r2=sqrt((x-0.3)**2+(y-0.25)**2) - h(i,j,k) = h(i,j,k) + pert_amp*(e0(k) - e0(nz+1))*GV%Z_to_H*(spike(r1,0.15)-spike(r2,0.15)) ! Prescribed perturbation + h(i,j,k) = h(i,j,k) + pert_amp * (e0(k) - e0(nz+1)) * GV%Z_to_H * & + (spike(r1,0.15)-spike(r2,0.15)) ! Prescribed perturbation if (h_noise /= 0.) then rns = initializeRandomNumberStream( int( 4096*(x + (y+1.)) ) ) call getRandomNumbers(rns, noise) ! x will be in (0,1) diff --git a/src/user/Phillips_initialization.F90 b/src/user/Phillips_initialization.F90 index 1e513460b5..357396b794 100644 --- a/src/user/Phillips_initialization.F90 +++ b/src/user/Phillips_initialization.F90 @@ -24,6 +24,11 @@ module Phillips_initialization public Phillips_initialize_sponges public Phillips_initialize_topography +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + ! This include declares and sets the variable "version". #include "version_variable.h" @@ -35,18 +40,20 @@ subroutine Phillips_initialize_thickness(h, G, GV, US, param_file, just_read_par type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: eta0(SZK_(G)+1) ! The 1-d nominal positions of the interfaces, in depth units (Z). - real :: eta_im(SZJ_(G),SZK_(G)+1) ! A temporary array for zonal-mean eta, in depth units (Z). - real :: eta1D(SZK_(G)+1) ! Interface height relative to the sea surface - ! positive upward, in in depth units (Z). - real :: damp_rate, jet_width, jet_height, y_2 - real :: half_strat, half_depth + real :: eta0(SZK_(G)+1) ! The 1-d nominal positions of the interfaces [Z ~> m] + real :: eta_im(SZJ_(G),SZK_(G)+1) ! A temporary array for zonal-mean eta [Z ~> m] + real :: eta1D(SZK_(G)+1) ! Interface height relative to the sea surface, positive upward [Z ~> m] + real :: jet_width ! The width of the zonal-mean jet [km] + real :: jet_height ! The interface height scale associated with the zonal-mean jet [Z ~> m] + real :: y_2 + real :: half_strat ! The fractional depth where the stratification is centered [nondim] + real :: half_depth ! The depth where the stratification is centered [Z ~> m] logical :: just_read ! If true, just read parameters but set nothing. character(len=40) :: mdl = "Phillips_initialize_thickness" ! This subroutine's name. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz @@ -60,8 +67,9 @@ subroutine Phillips_initialize_thickness(h, G, GV, US, param_file, just_read_par if (.not.just_read) call log_version(param_file, mdl, version) call get_param(param_file, mdl, "HALF_STRAT_DEPTH", half_strat, & - "The maximum depth of the ocean.", units="nondim", & - default = 0.5, do_not_log=just_read) +!### UNCOMMENT TO FIX THIS "The fractional depth where the stratification is centered.", & + "The maximum depth of the ocean.", & + units="nondim", default = 0.5, do_not_log=just_read) call get_param(param_file, mdl, "JET_WIDTH", jet_width, & "The width of the zonal-mean jet.", units="km", & fail_if_missing=.not.just_read, do_not_log=just_read) @@ -91,11 +99,10 @@ subroutine Phillips_initialize_thickness(h, G, GV, US, param_file, just_read_par enddo ; enddo do j=js,je ; do i=is,ie -! This sets the initial thickness (in H) of the layers. The ! -! thicknesses are set to insure that: 1. each layer is at least an ! -! Angstrom thick, and 2. the interfaces are where they should be ! -! based on the resting depths and interface height perturbations, ! -! as long at this doesn't interfere with 1. ! + ! This sets the initial thickness in [H ~> m or kg m-2] of the layers. The + ! thicknesses are set to insure that: 1. each layer is at least an Angstrom thick, and + ! 2. the interfaces are where they should be based on the resting depths and interface + ! height perturbations, as long at this doesn't interfere with 1. eta1D(nz+1) = -G%bathyT(i,j) do k=nz,1,-1 eta1D(K) = eta_im(j,K) @@ -116,15 +123,15 @@ subroutine Phillips_initialize_velocity(u, v, G, GV, US, param_file, just_read_p type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< i-component of velocity [m/s] + intent(out) :: u !< i-component of velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: v !< j-component of velocity [m/s] + intent(out) :: v !< j-component of velocity [m s-1] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to !! parse for modelparameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: damp_rate, jet_width, jet_height, x_2, y_2 + real :: jet_width, jet_height, x_2, y_2 real :: velocity_amplitude, pi integer :: i, j, k, is, ie, js, je, nz, m logical :: just_read ! If true, just read parameters but set nothing. @@ -203,21 +210,21 @@ subroutine Phillips_initialize_sponges(G, GV, US, tv, param_file, CSp, h) type(sponge_CS), pointer :: CSp !< A pointer that is set to point to !! the control structure for the !! sponge module. - real, intent(in), dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h !< Thickness field, in units of H. + real, intent(in), dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h !< Thickness field [H ~> m or kg m-2]. ! Local variables real :: eta0(SZK_(G)+1) ! The 1-d nominal positions of the interfaces. - real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta, in depth units (Z). + real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta [Z ~> m]. real :: temp(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for other variables. - real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate, in s-1. - real :: eta_im(SZJ_(G),SZK_(G)+1) ! A temporary array for zonal-mean eta, in Z. - real :: Idamp_im(SZJ_(G)) ! The inverse zonal-mean damping rate, in s-1. - real :: damp_rate ! The inverse zonal-mean damping rate, in s-1. + real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1]. + real :: eta_im(SZJ_(G),SZK_(G)+1) ! A temporary array for zonal-mean eta [Z ~> m]. + real :: Idamp_im(SZJ_(G)) ! The inverse zonal-mean damping rate [s-1]. + real :: damp_rate ! The inverse zonal-mean damping rate [s-1]. real :: jet_width ! The width of the zonal mean jet, in km. - real :: jet_height ! The interface height scale associated with the zonal-mean jet, in Z. + real :: jet_height ! The interface height scale associated with the zonal-mean jet [Z ~> m]. real :: y_2 ! The y-position relative to the channel center, in km. - real :: half_strat ! The fractional depth where the straficiation is centered, ND. - real :: half_depth ! The depth where the stratification is centered, in Z. + real :: half_strat ! The fractional depth where the straficiation is centered [nondim]. + real :: half_depth ! The depth where the stratification is centered [Z ~> m]. character(len=40) :: mdl = "Phillips_initialize_sponges" ! This subroutine's name. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz @@ -341,16 +348,16 @@ end subroutine Phillips_initialize_topography !! The one argument passed to initialize, Time, is set to the !! current time of the simulation. The fields which are initialized !! here are: -!! u - Zonal velocity in m s-1. -!! v - Meridional velocity in m s-1. +!! u - Zonal velocity [m s-1]. +!! v - Meridional velocity [m s-1]. !! h - Layer thickness in m. (Must be positive.) !! D - Basin depth in m. (Must be positive.) -!! f - The Coriolis parameter, in s-1. -!! g - The reduced gravity at each interface, in m s-2. -!! Rlay - Layer potential density (coordinate variable) in kg m-3. +!! f - The Coriolis parameter [s-1]. +!! g - The reduced gravity at each interface [m s-2] +!! Rlay - Layer potential density (coordinate variable) [kg m-3]. !! If ENABLE_THERMODYNAMICS is defined: -!! T - Temperature in C. -!! S - Salinity in psu. +!! T - Temperature [degC]. +!! S - Salinity [ppt]. !! If SPONGE is defined: !! A series of subroutine calls are made to set up the damping !! rates and reference profiles for all variables that are damped diff --git a/src/user/Rossby_front_2d_initialization.F90 b/src/user/Rossby_front_2d_initialization.F90 index 975b96e866..a3f23361f7 100644 --- a/src/user/Rossby_front_2d_initialization.F90 +++ b/src/user/Rossby_front_2d_initialization.F90 @@ -28,9 +28,9 @@ module Rossby_front_2d_initialization public Rossby_front_initialize_velocity ! Parameters defining the initial conditions of this test case -real, parameter :: frontFractionalWidth = 0.5 !< Width of front as fraction of domain -real, parameter :: HMLmin = 0.25 !< Shallowest ML as fractional depth of ocean -real, parameter :: HMLmax = 0.75 !< Deepest ML as fractional depth of ocean +real, parameter :: frontFractionalWidth = 0.5 !< Width of front as fraction of domain [nondim] +real, parameter :: HMLmin = 0.25 !< Shallowest ML as fractional depth of ocean [nondim] +real, parameter :: HMLmax = 0.75 !< Deepest ML as fractional depth of ocean [nondim] contains @@ -39,7 +39,7 @@ subroutine Rossby_front_initialize_thickness(h, G, GV, param_file, just_read_par type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -110,9 +110,9 @@ subroutine Rossby_front_initialize_temperature_salinity(T, S, h, G, GV, & param_file, eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [deg C] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC] real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt] - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Thickness in H + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Thickness [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< Parameter file handle type(EOS_type), pointer :: eqn_of_state !< Equation of state structure logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -163,11 +163,11 @@ subroutine Rossby_front_initialize_velocity(u, v, h, G, GV, param_file, just_rea type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), & - intent(out) :: u !< i-component of velocity [m/s] + intent(out) :: u !< i-component of velocity [m s-1] real, dimension(SZI_(G),SZJB_(G),SZK_(G)), & - intent(out) :: v !< j-component of velocity [m/s] + intent(out) :: v !< j-component of velocity [m s-1] real, dimension(SZI_(G),SZJ_(G), SZK_(G)), & - intent(in) :: h !< Thickness [H] + intent(in) :: h !< Thickness [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call @@ -177,9 +177,9 @@ subroutine Rossby_front_initialize_velocity(u, v, h, G, GV, param_file, just_rea real :: T_range ! Range of salinities and temperatures over the vertical real :: dUdT ! Factor to convert dT/dy into dU/dz, g*alpha/f real :: dRho_dT - real :: Dml, zi, zc, zm ! Depths in units of Z. + real :: Dml, zi, zc, zm ! Depths [Z ~> m]. real :: f, Ty - real :: hAtU ! Interpolated layer thickness in units of Z. + real :: hAtU ! Interpolated layer thickness [Z ~> m]. integer :: i, j, k, is, ie, js, je, nz logical :: just_read ! If true, just read parameters but set nothing. character(len=40) :: verticalCoordinate diff --git a/src/user/SCM_CVMix_tests.F90 b/src/user/SCM_CVMix_tests.F90 index 303dbb54ea..e24db1bcda 100644 --- a/src/user/SCM_CVMix_tests.F90 +++ b/src/user/SCM_CVMix_tests.F90 @@ -14,6 +14,7 @@ module SCM_CVMix_tests use MOM_time_manager, only : time_type, operator(+), operator(/), time_type_to_real use MOM_unit_scaling, only : unit_scale_type use MOM_variables, only : thermo_var_ptrs, surface + implicit none ; private #include @@ -24,19 +25,23 @@ module SCM_CVMix_tests public SCM_CVMix_tests_buoyancy_forcing public SCM_CVMix_tests_CS +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Container for surface forcing parameters -type SCM_CVMix_tests_CS -private +type SCM_CVMix_tests_CS ; private logical :: UseWindStress !< True to use wind stress - logical :: UseHeatFlux !< True to use heat flux + logical :: UseHeatFlux !< True to use heat flux logical :: UseEvaporation !< True to use evaporation logical :: UseDiurnalSW !< True to use diurnal sw radiation - real :: tau_x !< (Constant) Wind stress, X (Pa) - real :: tau_y !< (Constant) Wind stress, Y (Pa) - real :: surf_HF !< (Constant) Heat flux (m K s^{-1}) - real :: surf_evap !< (Constant) Evaporation rate (m/s) - real :: Max_sw !< maximum of diurnal sw radiation (m K s^{-1}) - real,public :: Rho0 !< reference density copied for easy passing + real :: tau_x !< (Constant) Wind stress, X [Pa] + real :: tau_y !< (Constant) Wind stress, Y [Pa] + real :: surf_HF !< (Constant) Heat flux [m degC s-1] + real :: surf_evap !< (Constant) Evaporation rate [m s-1] + real :: Max_sw !< maximum of diurnal sw radiation [m degC s-1] + real,public :: Rho0 !< reference density copied for easy passing [kg m-3] end type ! This include declares and sets the variable "version". @@ -48,9 +53,9 @@ module SCM_CVMix_tests !> Initializes temperature and salinity for the SCM CVMix test example subroutine SCM_CVMix_tests_TS_init(T, S, h, G, GV, US, param_file, just_read_params) - real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(out) :: T !< Potential temperature (degC) - real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(out) :: S !< Salinity (psu) - real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(in) :: h !< Layer thickness in H (often m or Pa) + real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(out) :: T !< Potential temperature [degC] + real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(out) :: S !< Salinity [psu] + real, dimension(NIMEM_,NJMEM_, NKMEM_), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type @@ -58,16 +63,16 @@ subroutine SCM_CVMix_tests_TS_init(T, S, h, G, GV, US, param_file, just_read_par logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables - real :: UpperLayerTempMLD !< Upper layer Temp MLD thickness (Z) - real :: UpperLayerSaltMLD !< Upper layer Salt MLD thickness (Z) - real :: UpperLayerTemp !< Upper layer temperature (SST if thickness 0) (deg C) - real :: UpperLayerSalt !< Upper layer salinity (SSS if thickness 0) (PPT) - real :: LowerLayerTemp !< Temp at top of lower layer (deg C) - real :: LowerLayerSalt !< Salt at top of lower layer (PPT) - real :: LowerLayerdTdz !< Temp gradient in lower layer (deg C / Z) - real :: LowerLayerdSdz !< Salt gradient in lower layer (PPT / Z) - real :: LowerLayerMinTemp !< Minimum temperature in lower layer - real :: zC, DZ, top, bottom ! Depths and thicknesses in Z. + real :: UpperLayerTempMLD !< Upper layer Temp MLD thickness [Z ~> m]. + real :: UpperLayerSaltMLD !< Upper layer Salt MLD thickness [Z ~> m]. + real :: UpperLayerTemp !< Upper layer temperature (SST if thickness 0) [degC] + real :: UpperLayerSalt !< Upper layer salinity (SSS if thickness 0) [ppt] + real :: LowerLayerTemp !< Temp at top of lower layer [degC] + real :: LowerLayerSalt !< Salt at top of lower layer [ppt] + real :: LowerLayerdTdz !< Temp gradient in lower layer [degC / Z ~> degC m-1]. + real :: LowerLayerdSdz !< Salt gradient in lower layer [ppt / Z ~> ppt m-1]. + real :: LowerLayerMinTemp !< Minimum temperature in lower layer [degC] + real :: zC, DZ, top, bottom ! Depths and thicknesses [Z ~> m]. logical :: just_read ! If true, just read parameters but set nothing. integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz @@ -107,8 +112,8 @@ subroutine SCM_CVMix_tests_TS_init(T, S, h, G, GV, US, param_file, just_read_par top = 0. ! Reference to surface bottom = 0. do k=1,nz - bottom = bottom - h(i,j,k)*GV%H_to_Z ! Interface below layer (in m) - zC = 0.5*( top + bottom ) ! Z of middle of layer (in m) + bottom = bottom - h(i,j,k)*GV%H_to_Z ! Interface below layer [Z ~> m] + zC = 0.5*( top + bottom ) ! Z of middle of layer [Z ~> m] DZ = min(0., zC + UpperLayerTempMLD) T(i,j,k) = max(LowerLayerMinTemp,LowerLayerTemp + LowerLayerdTdZ * DZ) DZ = min(0., zC + UpperLayerSaltMLD) @@ -220,10 +225,10 @@ end subroutine SCM_CVMix_tests_wind_forcing subroutine SCM_CVMix_tests_buoyancy_forcing(state, fluxes, day, G, CS) - type(surface), intent(in) :: state !< Surface state structure - type(forcing), intent(inout) :: fluxes !< Surface fluxes structure - type(time_type), intent(in) :: day !< Time in days (seconds?) - type(ocean_grid_type), intent(inout) :: G !< Grid structure + type(surface), intent(in) :: state !< Surface state structure + type(forcing), intent(inout) :: fluxes !< Surface fluxes structure + type(time_type), intent(in) :: day !< Current model time + type(ocean_grid_type), intent(inout) :: G !< Grid structure type(SCM_CVMix_tests_CS), pointer :: CS !< Container for SCM parameters ! Local variables @@ -250,7 +255,7 @@ subroutine SCM_CVMix_tests_buoyancy_forcing(state, fluxes, day, G, CS) if (CS%UseEvaporation) then do J=Jsq,Jeq ; do i=is,ie - ! Note CVMix test inputs give evaporation in m/s + ! Note CVMix test inputs give evaporation in [m s-1] ! This therefore must be converted to mass flux ! by multiplying by density fluxes%evap(i,J) = CS%surf_evap * CS%Rho0 diff --git a/src/user/adjustment_initialization.F90 b/src/user/adjustment_initialization.F90 index fbf1a0df97..28033d8799 100644 --- a/src/user/adjustment_initialization.F90 +++ b/src/user/adjustment_initialization.F90 @@ -24,6 +24,11 @@ module adjustment_initialization public adjustment_initialize_thickness public adjustment_initialize_temperature_salinity +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Initializes the layer thicknesses in the adjustment test case @@ -32,16 +37,16 @@ subroutine adjustment_initialize_thickness ( h, G, GV, US, param_file, just_read type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), usually + real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units [Z ~> m], usually ! negative because it is positive upward. real :: eta1D(SZK_(G)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). + ! positive upward, in depth units [Z ~> m]. real :: x, y, yy, delta_S_strat, dSdz, delta_S, S_ref real :: min_thickness, adjustment_width, adjustment_delta, adjustment_deltaS real :: front_wave_amp, front_wave_length, front_wave_asym @@ -183,7 +188,7 @@ subroutine adjustment_initialize_temperature_salinity(T, S, h, G, GV, param_file type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< The temperature that is being initialized. real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< The salinity that is being initialized. - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< The model thicknesses in H (m or kg m-2). + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< The model thicknesses [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to !! parse for model parameter values. type(EOS_type), pointer :: eqn_of_state !< Equation of state. diff --git a/src/user/baroclinic_zone_initialization.F90 b/src/user/baroclinic_zone_initialization.F90 index b9bab35f59..8f3ad67ca9 100644 --- a/src/user/baroclinic_zone_initialization.F90 +++ b/src/user/baroclinic_zone_initialization.F90 @@ -19,6 +19,11 @@ module baroclinic_zone_initialization public baroclinic_zone_init_temperature_salinity +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Reads the parameters unique to this module @@ -28,15 +33,15 @@ subroutine bcz_params(G, GV, US, param_file, S_ref, dSdz, delta_S, dSdx, T_ref, type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type type(param_file_type), intent(in) :: param_file !< Parameter file handle - real, intent(out) :: S_ref !< Reference salinity (ppt) - real, intent(out) :: dSdz !< Salinity stratification (ppt/Z) - real, intent(out) :: delta_S !< Salinity difference across baroclinic zone (ppt) - real, intent(out) :: dSdx !< Linear salinity gradient (ppt/m) - real, intent(out) :: T_ref !< Reference temperature (ppt) - real, intent(out) :: dTdz !< Temperature stratification (ppt/Z) - real, intent(out) :: delta_T !< Temperature difference across baroclinic zone (ppt) - real, intent(out) :: dTdx !< Linear temperature gradient (ppt/m) - real, intent(out) :: L_zone !< Width of baroclinic zone (m) + real, intent(out) :: S_ref !< Reference salinity [ppt] + real, intent(out) :: dSdz !< Salinity stratification [ppt Z-1 ~> ppt m-1] + real, intent(out) :: delta_S !< Salinity difference across baroclinic zone [ppt] + real, intent(out) :: dSdx !< Linear salinity gradient [ppt m-1] + real, intent(out) :: T_ref !< Reference temperature [degC] + real, intent(out) :: dTdz !< Temperature stratification [degC Z-1 ~> degC m-1] + real, intent(out) :: delta_T !< Temperature difference across baroclinic zone [degC] + real, intent(out) :: dTdx !< Linear temperature gradient [degC m-1] + real, intent(out) :: L_zone !< Width of baroclinic zone [m] logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. @@ -75,9 +80,9 @@ subroutine baroclinic_zone_init_temperature_salinity(T, S, h, G, GV, US, param_f type(ocean_grid_type), intent(in) :: G !< Grid structure type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [deg C] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC] real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt] - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< The model thicknesses in H (m or kg m-2) + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< The model thicknesses [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< Parameter file handle logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing T & S. @@ -86,7 +91,7 @@ subroutine baroclinic_zone_init_temperature_salinity(T, S, h, G, GV, US, param_f real :: T_ref, dTdz, dTdx, delta_T ! Parameters describing temperature distribution real :: S_ref, dSdz, dSdx, delta_S ! Parameters describing salinity distribution real :: L_zone ! Width of baroclinic zone - real :: zc, zi ! Depths in depth units (Z). + real :: zc, zi ! Depths in depth units [Z ~> m] real :: x, xd, xs, y, yd, fn real :: PI ! 3.1415926... calculated as 4*atan(1) logical :: just_read ! If true, just read parameters but set nothing. diff --git a/src/user/benchmark_initialization.F90 b/src/user/benchmark_initialization.F90 index 0a5589a0b6..859a878446 100644 --- a/src/user/benchmark_initialization.F90 +++ b/src/user/benchmark_initialization.F90 @@ -23,19 +23,24 @@ module benchmark_initialization public benchmark_initialize_thickness public benchmark_init_temperature_salinity +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> This subroutine sets up the benchmark test case topography. subroutine benchmark_initialize_topography(D, G, param_file, max_depth, US) type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type real, dimension(G%isd:G%ied,G%jsd:G%jed), & - intent(out) :: D !< Ocean bottom depth in m or Z if US is present + intent(out) :: D !< Ocean bottom depth in m or [Z ~> m] if US is present type(param_file_type), intent(in) :: param_file !< Parameter file structure real, intent(in) :: max_depth !< Maximum model depth in the units of D type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type ! Local variables - real :: min_depth ! The minimum and maximum depths in Z. + real :: min_depth ! The minimum and maximum depths [Z ~> m]. real :: PI ! 3.1415926... calculated as 4*atan(1) real :: D0 ! A constant to make the maximum ! ! basin depth MAXIMUM_DEPTH. ! @@ -83,29 +88,29 @@ subroutine benchmark_initialize_thickness(h, G, GV, US, param_file, eqn_of_state type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. type(EOS_type), pointer :: eqn_of_state !< integer that selects the !! equation of state. real, intent(in) :: P_Ref !< The coordinate-density - !! reference pressure in Pa. + !! reference pressure [Pa]. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables - real :: e0(SZK_(GV)+1) ! The resting interface heights, in depth units (Z), + real :: e0(SZK_(GV)+1) ! The resting interface heights, in depth units [Z ~> m], ! usually negative because it is positive upward. real :: e_pert(SZK_(GV)+1) ! Interface height perturbations, positive upward, - ! in depth units (Z). + ! in depth units [Z ~> m]. real :: eta1D(SZK_(GV)+1) ! Interface height relative to the sea surface - ! positive upward, in depth units (Z). - real :: SST ! The initial sea surface temperature, in deg C. - real :: T_int ! The initial temperature of an interface, in deg C. - real :: ML_depth ! The specified initial mixed layer depth, in depth units (Z). - real :: thermocline_scale ! The e-folding scale of the thermocline, in depth units (Z). + ! positive upward, in depth units [Z ~> m]. + real :: SST ! The initial sea surface temperature [degC]. + real :: T_int ! The initial temperature of an interface [degC]. + real :: ML_depth ! The specified initial mixed layer depth, in depth units [Z ~> m]. + real :: thermocline_scale ! The e-folding scale of the thermocline, in depth units [Z ~> m]. real, dimension(SZK_(GV)) :: T0, pres, S0, rho_guess, drho, drho_dT, drho_dS real :: a_exp ! The fraction of the overall stratification that is exponential. - real :: I_ts, I_md ! Inverse lengthscales in Z-1. + real :: I_ts, I_md ! Inverse lengthscales [Z-1 ~> m-1]. real :: T_frac ! A ratio of the interface temperature to the range ! between SST and the bottom temperature. real :: err, derr_dz ! The error between the profile's temperature and the @@ -168,13 +173,10 @@ subroutine benchmark_initialize_thickness(h, G, GV, US, param_file, eqn_of_state do k=1,nz ; e_pert(K) = 0.0 ; enddo -! The remainder of this subroutine should not be changed. ! - -! This sets the initial thickness (in H) of the layers. The ! -! thicknesses are set to insure that: 1. each layer is at least ! -! Gv%Angstrom_m thick, and 2. the interfaces are where they should be ! -! based on the resting depths and interface height perturbations, ! -! as long at this doesn't interfere with 1. ! + ! This sets the initial thickness (in [H ~> m or kg m-2]) of the layers. The thicknesses + ! are set to insure that: 1. each layer is at least Gv%Angstrom_m thick, and + ! 2. the interfaces are where they should be based on the resting depths and interface + ! height perturbations, as long at this doesn't interfere with 1. eta1D(nz+1) = -G%bathyT(i,j) do k=nz,2,-1 @@ -220,19 +222,17 @@ subroutine benchmark_init_temperature_salinity(T, S, G, GV, param_file, & type(EOS_type), pointer :: eqn_of_state !< integer that selects the !! equation of state. real, intent(in) :: P_Ref !< The coordinate-density - !! reference pressure in Pa. + !! reference pressure [Pa]. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables real :: T0(SZK_(G)), S0(SZK_(G)) - real :: pres(SZK_(G)) ! Reference pressure in kg m-3. ! - real :: drho_dT(SZK_(G)) ! Derivative of density with temperature in ! - ! kg m-3 K-1. ! - real :: drho_dS(SZK_(G)) ! Derivative of density with salinity in ! - ! kg m-3 PSU-1. ! - real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 in kg m-3. ! + real :: pres(SZK_(G)) ! Reference pressure [kg m-3]. + real :: drho_dT(SZK_(G)) ! Derivative of density with temperature [kg m-3 degC-1]. + real :: drho_dS(SZK_(G)) ! Derivative of density with salinity [kg m-3 ppt-1]. + real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 [kg m-3]. real :: PI ! 3.1415926... calculated as 4*atan(1) - real :: SST ! The initial sea surface temperature, in deg C. + real :: SST ! The initial sea surface temperature [degC]. real :: lat logical :: just_read ! If true, just read parameters but set nothing. character(len=40) :: mdl = "benchmark_init_temperature_salinity" ! This subroutine's name. diff --git a/src/user/circle_obcs_initialization.F90 b/src/user/circle_obcs_initialization.F90 index 7ba02a7acc..4372586820 100644 --- a/src/user/circle_obcs_initialization.F90 +++ b/src/user/circle_obcs_initialization.F90 @@ -20,6 +20,11 @@ module circle_obcs_initialization public circle_obcs_initialize_thickness +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> This subroutine initializes layer thicknesses for the circle_obcs experiment. @@ -27,17 +32,17 @@ subroutine circle_obcs_initialize_thickness(h, G, GV, param_file, just_read_para type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: e0(SZK_(GV)+1) ! The resting interface heights, in depth units (Z), usually + real :: e0(SZK_(GV)+1) ! The resting interface heights, in depth units [Z ~> m], usually ! negative because it is positive upward. real :: eta1D(SZK_(GV)+1)! Interface height relative to the sea surface - ! positive upward, in in depth units (Z). - real :: IC_amp ! The amplitude of the initial height displacement, in H. + ! positive upward, in depth units [Z ~> m]. + real :: IC_amp ! The amplitude of the initial height displacement [H ~> m or kg m-2]. real :: diskrad, rad, xCenter, xRadius, lonC, latC, xOffset logical :: just_read ! This include declares and sets the variable "version". diff --git a/src/user/dense_water_initialization.F90 b/src/user/dense_water_initialization.F90 index f857978c8e..2233adb1a3 100644 --- a/src/user/dense_water_initialization.F90 +++ b/src/user/dense_water_initialization.F90 @@ -25,8 +25,8 @@ module dense_water_initialization character(len=40) :: mdl = "dense_water_initialization" !< Module name -real, parameter :: default_sill = 0.2 !< Default depth of the sill [nondim] -real, parameter :: default_shelf = 0.4 !< Default depth of the shelf [nondim] +real, parameter :: default_sill = 0.2 !< Default depth of the sill [nondim] +real, parameter :: default_shelf = 0.4 !< Default depth of the shelf [nondim] real, parameter :: default_mld = 0.25 !< Default depth of the mixed layer [nondim] contains @@ -100,9 +100,9 @@ subroutine dense_water_initialize_TS(G, GV, param_file, eqn_of_state, T, S, h, j type(verticalGrid_type), intent(in) :: GV !< Vertical grid control structure type(param_file_type), intent(in) :: param_file !< Parameter file structure type(EOS_type), pointer :: eqn_of_state !< EOS structure - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: T !< Output temperature (degC) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: S !< Output salinity (ppt) - real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: T !< Output temperature [degC] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(out) :: S !< Output salinity [ppt] + real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2] logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables diff --git a/src/user/dumbbell_initialization.F90 b/src/user/dumbbell_initialization.F90 index 02222c9865..c6e6354ef3 100644 --- a/src/user/dumbbell_initialization.F90 +++ b/src/user/dumbbell_initialization.F90 @@ -31,6 +31,11 @@ module dumbbell_initialization public dumbbell_initialize_temperature_salinity public dumbbell_initialize_sponges +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Initialization of topography. @@ -74,19 +79,19 @@ subroutine dumbbell_initialize_thickness ( h, G, GV, US, param_file, just_read_p type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in m. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), usually + real :: e0(SZK_(G)+1) ! The resting interface heights [Z ~> m], usually ! negative because it is positive upward. real :: eta1D(SZK_(G)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). - real :: min_thickness ! The minimum layer thicknesses, in Z. - real :: S_surf, S_range, S_ref, S_light, S_dense ! Various salinities, in ppt. - real :: eta_IC_quanta ! The granularity of quantization of intial interface heights, in Z-1. + ! positive upward [Z ~> m]. + real :: min_thickness ! The minimum layer thicknesses [Z ~> m]. + real :: S_surf, S_range, S_ref, S_light, S_dense ! Various salinities [ppt]. + real :: eta_IC_quanta ! The granularity of quantization of intial interface heights [Z-1 ~> m-1]. ! This include declares and sets the variable "version". # include "version_variable.h" character(len=20) :: verticalCoordinate @@ -190,9 +195,9 @@ subroutine dumbbell_initialize_temperature_salinity ( T, S, h, G, GV, param_file eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (ppt) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness (m or Pa) + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< Parameter file structure type(EOS_type), pointer :: eqn_of_state !< Equation of state structure logical, optional, intent(in) :: just_read_params !< If present and true, this call will diff --git a/src/user/dumbbell_surface_forcing.F90 b/src/user/dumbbell_surface_forcing.F90 index d206914e2a..7a2360fc7a 100644 --- a/src/user/dumbbell_surface_forcing.F90 +++ b/src/user/dumbbell_surface_forcing.F90 @@ -26,20 +26,19 @@ module dumbbell_surface_forcing logical :: use_temperature !< If true, temperature and salinity are used as !! state variables. logical :: restorebuoy !< If true, use restoring surface buoyancy forcing. - real :: Rho0 !< The density used in the Boussinesq - !! approximation, in kg m-3. - real :: G_Earth !< The gravitational acceleration in m s-2. - real :: Flux_const !< The restoring rate at the surface, in m s-1. - real :: gust_const !< A constant unresolved background gustiness - !! that contributes to ustar, in Pa. - real :: slp_amplitude !< The amplitude of pressure loading (in Pa) applied + real :: Rho0 !< The density used in the Boussinesq approximation [kg m-3]. + real :: G_Earth !< The gravitational acceleration [m s-2] + real :: Flux_const !< The restoring rate at the surface [m s-1]. + real :: gust_const !< A constant unresolved background gustiness + !! that contributes to ustar [Pa]. + real :: slp_amplitude !< The amplitude of pressure loading [Pa] applied !! to the reservoirs real :: slp_period !< Period of sinusoidal pressure wave real, dimension(:,:), allocatable :: & forcing_mask !< A mask regulating where forcing occurs real, dimension(:,:), allocatable :: & S_restore !< The surface salinity field toward which to - !! restore, in PSU. + !! restore [ppt]. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to regulate the !! timing of diagnostic output. end type dumbbell_surface_forcing_CS @@ -55,18 +54,18 @@ subroutine dumbbell_buoyancy_forcing(state, fluxes, day, dt, G, CS) !! have NULL ptrs. type(time_type), intent(in) :: day !< Time of the fluxes. real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(dumbbell_surface_forcing_CS), pointer :: CS !< A control structure returned by a previous !! call to dumbbell_surface_forcing_init ! Local variables - real :: Temp_restore ! The temperature that is being restored toward, in C. - real :: Salin_restore ! The salinity that is being restored toward, in PSU. + real :: Temp_restore ! The temperature that is being restored toward [degC]. + real :: Salin_restore ! The salinity that is being restored toward [ppt]. real :: density_restore ! The potential density that is being restored - ! toward, in kg m-3. - real :: rhoXcp ! The mean density times the heat capacity, in J m-3 K-1. + ! toward [kg m-3]. + real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1]. real :: buoy_rest_const ! A constant relating density anomalies to the - ! restoring buoyancy flux, in m5 s-3 kg-1. + ! restoring buoyancy flux [m5 s-3 kg-1]. integer :: i, j, is, ie, js, je integer :: isd, ied, jsd, jed @@ -98,7 +97,7 @@ subroutine dumbbell_buoyancy_forcing(state, fluxes, day, dt, G, CS) ! Set whichever fluxes are to be used here. Any fluxes that ! are always zero do not need to be changed here. do j=js,je ; do i=is,ie - ! Fluxes of fresh water through the surface are in units of kg m-2 s-1 + ! Fluxes of fresh water through the surface are in units of [kg m-2 s-1] ! and are positive downward - i.e. evaporation should be negative. fluxes%evap(i,j) = -0.0 * G%mask2dT(i,j) fluxes%lprec(i,j) = 0.0 * G%mask2dT(i,j) @@ -106,7 +105,7 @@ subroutine dumbbell_buoyancy_forcing(state, fluxes, day, dt, G, CS) ! vprec will be set later, if it is needed for salinity restoring. fluxes%vprec(i,j) = 0.0 - ! Heat fluxes are in units of W m-2 and are positive into the ocean. + ! Heat fluxes are in units of [W m-2] and are positive into the ocean. fluxes%lw(i,j) = 0.0 * G%mask2dT(i,j) fluxes%latent(i,j) = 0.0 * G%mask2dT(i,j) fluxes%sens(i,j) = 0.0 * G%mask2dT(i,j) @@ -114,7 +113,7 @@ subroutine dumbbell_buoyancy_forcing(state, fluxes, day, dt, G, CS) enddo ; enddo else ! This is the buoyancy only mode. do j=js,je ; do i=is,ie - ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive + ! fluxes%buoy is the buoyancy flux into the ocean [m2 s-3]. A positive ! buoyancy flux is of the same sign as heating the ocean. fluxes%buoy(i,j) = 0.0 * G%mask2dT(i,j) enddo ; enddo @@ -123,7 +122,7 @@ subroutine dumbbell_buoyancy_forcing(state, fluxes, day, dt, G, CS) if (CS%use_temperature .and. CS%restorebuoy) then do j=js,je ; do i=is,ie ! Set density_restore to an expression for the surface potential - ! density in kg m-3 that is being restored toward. + ! density [kg m-3] that is being restored toward. if (CS%forcing_mask(i,j)>0.) then fluxes%vprec(i,j) = - (G%mask2dT(i,j) * (CS%Rho0*CS%Flux_const)) * & ((CS%S_restore(i,j) - state%SSS(i,j)) / & @@ -144,7 +143,7 @@ subroutine dumbbell_dynamic_forcing(state, fluxes, day, dt, G, CS) !! have NULL ptrs. type(time_type), intent(in) :: day !< Time of the fluxes. real, intent(in) :: dt !< The amount of time over which - !! the fluxes apply, in s + !! the fluxes apply [s] type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure type(dumbbell_surface_forcing_CS), pointer :: CS !< A control structure returned by a previous !! call to dumbbell_surface_forcing_init diff --git a/src/user/external_gwave_initialization.F90 b/src/user/external_gwave_initialization.F90 index 153ec00b42..2ef3ca2fb7 100644 --- a/src/user/external_gwave_initialization.F90 +++ b/src/user/external_gwave_initialization.F90 @@ -17,6 +17,11 @@ module external_gwave_initialization public external_gwave_initialize_thickness +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> This subroutine initializes layer thicknesses for the external_gwave experiment. @@ -25,14 +30,14 @@ subroutine external_gwave_initialize_thickness(h, G, GV, US, param_file, just_re type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. ! Local variables real :: eta1D(SZK_(G)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). + ! positive upward [Z ~> m]. real :: ssh_anomaly_height ! Vertical height of ssh anomaly real :: ssh_anomaly_width ! Lateral width of anomaly logical :: just_read ! If true, just read parameters but set nothing. diff --git a/src/user/lock_exchange_initialization.F90 b/src/user/lock_exchange_initialization.F90 index 4114b709c8..c442f63891 100644 --- a/src/user/lock_exchange_initialization.F90 +++ b/src/user/lock_exchange_initialization.F90 @@ -28,18 +28,17 @@ subroutine lock_exchange_initialize_thickness(h, G, GV, US, param_file, just_rea type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: e0(SZK_(GV)) ! The resting interface heights, in m, usually ! - ! negative because it is positive upward. ! - real :: e_pert(SZK_(GV)) ! Interface height perturbations, positive ! - ! upward, in m. ! - real :: eta1D(SZK_(GV)+1)! Interface height relative to the sea surface ! - ! positive upward, in m. ! + real :: e0(SZK_(GV)) ! The resting interface heights [Z ~> m], usually + ! negative because it is positive upward. + real :: e_pert(SZK_(GV)) ! Interface height perturbations, positive upward [Z ~> m]. + real :: eta1D(SZK_(GV)+1)! Interface height relative to the sea surface + ! positive upward [Z ~> m]. real :: front_displacement ! Vertical displacement acrodd front real :: thermocline_thickness ! Thickness of stratified region logical :: just_read ! If true, just read parameters but set nothing. diff --git a/src/user/seamount_initialization.F90 b/src/user/seamount_initialization.F90 index 8f1ed97b06..6180ff2e00 100644 --- a/src/user/seamount_initialization.F90 +++ b/src/user/seamount_initialization.F90 @@ -30,6 +30,11 @@ module seamount_initialization public seamount_initialize_thickness public seamount_initialize_temperature_salinity +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + contains !> Initialization of topography. @@ -77,19 +82,19 @@ subroutine seamount_initialize_thickness ( h, G, GV, US, param_file, just_read_p type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. - real :: e0(SZK_(G)+1) ! The resting interface heights, in depth units (Z), usually + real :: e0(SZK_(G)+1) ! The resting interface heights [Z ~> m], usually ! negative because it is positive upward. real :: eta1D(SZK_(G)+1)! Interface height relative to the sea surface - ! positive upward, in depth units (Z). - real :: min_thickness ! The minimum layer thicknesses, in Z. - real :: S_surf, S_range, S_ref, S_light, S_dense ! Various salinities, in ppt. - real :: eta_IC_quanta ! The granularity of quantization of intial interface heights, in Z-1. + ! positive upward [Z ~> m]. + real :: min_thickness ! The minimum layer thicknesses [Z ~> m]. + real :: S_surf, S_range, S_ref, S_light, S_dense ! Various salinities [ppt]. + real :: eta_IC_quanta ! The granularity of quantization of intial interface heights [Z-1 ~> m-1]. character(len=20) :: verticalCoordinate logical :: just_read ! If true, just read parameters but set nothing. integer :: i, j, k, is, ie, js, je, nz @@ -189,10 +194,10 @@ end subroutine seamount_initialize_thickness subroutine seamount_initialize_temperature_salinity ( T, S, h, G, GV, param_file, & eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure - type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (ppt) - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness in H (m or Pa) + type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2] type(param_file_type), intent(in) :: param_file !< Parameter file structure type(EOS_type), pointer :: eqn_of_state !< Equation of state structure logical, optional, intent(in) :: just_read_params !< If present and true, this call will diff --git a/src/user/sloshing_initialization.F90 b/src/user/sloshing_initialization.F90 index f192af804d..990d43fda4 100644 --- a/src/user/sloshing_initialization.F90 +++ b/src/user/sloshing_initialization.F90 @@ -58,14 +58,14 @@ subroutine sloshing_initialize_thickness ( h, G, GV, US, param_file, just_read_p type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open file !! to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will !! only read parameters without changing h. real :: displ(SZK_(G)+1) ! The interface displacement in depth units. - real :: z_unif(SZK_(G)+1) ! Fractional uniform interface heights, nondim. + real :: z_unif(SZK_(G)+1) ! Fractional uniform interface heights [nondim]. real :: z_inter(SZK_(G)+1) ! Interface heights, in depth units. real :: a0 ! The displacement amplitude in depth units. real :: weight_z ! A (misused?) depth-space weighting, in inconsistent units. @@ -180,9 +180,9 @@ subroutine sloshing_initialize_temperature_salinity ( T, S, h, G, GV, param_file eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC). - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (ppt). - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness in H (m or Pa). + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC]. + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt]. + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the !! open file to parse for model !! parameter values. diff --git a/src/user/soliton_initialization.F90 b/src/user/soliton_initialization.F90 index 668497fe11..033a8f0e52 100644 --- a/src/user/soliton_initialization.F90 +++ b/src/user/soliton_initialization.F90 @@ -33,7 +33,7 @@ subroutine soliton_initialize_thickness(h, G, GV, US) type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thickness that is being initialized, in H. + intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]. integer :: i, j, k, is, ie, js, je, nz real :: x, y, x0, y0 @@ -65,9 +65,9 @@ end subroutine soliton_initialize_thickness !> Initialization of u and v in the equatorial Rossby soliton test subroutine soliton_initialize_velocity(u, v, h, G) type(ocean_grid_type), intent(in) :: G !< Grid structure - real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: u !< i-component of velocity [m/s] - real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: v !< j-component of velocity [m/s] - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Thickness [H] + real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(out) :: u !< i-component of velocity [m s-1] + real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(out) :: v !< j-component of velocity [m s-1] + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Thickness [H ~> m or kg m-2] real :: x, y, x0, y0 real :: val1, val2, val3, val4 diff --git a/src/user/user_change_diffusivity.F90 b/src/user/user_change_diffusivity.F90 index 4cef242cb1..5a29614506 100644 --- a/src/user/user_change_diffusivity.F90 +++ b/src/user/user_change_diffusivity.F90 @@ -18,15 +18,20 @@ module user_change_diffusivity public user_change_diff, user_change_diff_init, user_change_diff_end +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> Control structure for user_change_diffusivity type, public :: user_change_diff_CS ; private real :: Kd_add !< The scale of a diffusivity that is added everywhere - !! without any filtering or scaling, in m2 s-1. + !! without any filtering or scaling [Z2 s-1 ~> m2 s-1]. real :: lat_range(4) !< 4 values that define the latitude range over which - !! a diffusivity scaled by Kd_add is added, in deg. + !! a diffusivity scaled by Kd_add is added [degLat]. real :: rho_range(4) !< 4 values that define the coordinate potential !! density range over which a diffusivity scaled by - !! Kd_add is added, in kg m-3. + !! Kd_add is added [kg m-3]. logical :: use_abs_lat !< If true, use the absolute value of latitude when !! setting lat_range. type(diag_ctrl), pointer :: diag => NULL() !< A structure that is used to @@ -42,27 +47,27 @@ module user_change_diffusivity subroutine user_change_diff(h, tv, G, GV, CS, Kd_lay, Kd_int, T_f, S_f, Kd_int_add) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure - real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness, in Z (often m or kg m-2). + real, dimension(SZI_(G),SZJ_(G),SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]. type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers !! to any available thermodynamic !! fields. Absent fields have NULL ptrs. type(user_change_diff_CS), pointer :: CS !< This module's control structure. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(inout) :: Kd_lay !< The diapycnal diffusivity of - !! each layer in Z2 s-1. + !! each layer [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)+1), optional, intent(inout) :: Kd_int !< The diapycnal diffusivity - !! at each interface in Z2 s-1. + !! at each interface [Z2 s-1 ~> m2 s-1]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(in) :: T_f !< Temperature with massless - !! layers filled in vertically. + !! layers filled in vertically [degC]. real, dimension(SZI_(G),SZJ_(G),SZK_(G)), optional, intent(in) :: S_f !< Salinity with massless - !! layers filled in vertically. + !! layers filled in vertically [ppt]. real, dimension(:,:,:), optional, pointer :: Kd_int_add !< The diapycnal !! diffusivity that is being added at - !! each interface in Z2 s-1. + !! each interface [Z2 s-1 ~> m2 s-1]. ! Local variables - real :: Rcv(SZI_(G),SZK_(G)) ! The coordinate density in layers in kg m-3. + real :: Rcv(SZI_(G),SZK_(G)) ! The coordinate density in layers [kg m-3]. real :: p_ref(SZI_(G)) ! An array of tv%P_Ref pressures. - real :: rho_fn ! The density dependence of the input function, 0-1, ND. - real :: lat_fn ! The latitude dependence of the input function, 0-1, ND. + real :: rho_fn ! The density dependence of the input function, 0-1 [nondim]. + real :: lat_fn ! The latitude dependence of the input function, 0-1 [nondim]. logical :: use_EOS ! If true, density is calculated from T & S using an ! equation of state. logical :: store_Kd_add ! Save the added diffusivity as a diagnostic if true. diff --git a/src/user/user_initialization.F90 b/src/user/user_initialization.F90 index c94613117a..1de9c3664a 100644 --- a/src/user/user_initialization.F90 +++ b/src/user/user_initialization.F90 @@ -25,6 +25,11 @@ module user_initialization public USER_initialize_velocity, USER_init_temperature_salinity public USER_initialize_sponges, USER_set_OBC_data, USER_set_rotation +! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional +! consistency testing. These are noted in comments with units like Z, H, L, and T, along with +! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units +! vary with the Boussinesq approximation, the Boussinesq variant is given first. + !> A module variable that should not be used. !! \todo Move this module variable into a control structure. logical :: first_call = .true. @@ -37,7 +42,7 @@ subroutine USER_set_coord(Rlay, g_prime, GV, param_file, eqn_of_state) !! structure. real, dimension(:), intent(out) :: Rlay !< Layer potential density. real, dimension(:), intent(out) :: g_prime !< The reduced gravity at - !! each interface, in m2 Z-1 s-2. + !! each interface [m2 Z-1 s-2 ~> m s-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the !! open file to parse for model !! parameter values. @@ -78,7 +83,7 @@ subroutine USER_initialize_thickness(h, G, GV, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure. type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(out) :: h !< The thicknesses being initialized, in H. + intent(out) :: h !< The thicknesses being initialized [H ~> m or kg m-2]. type(param_file_type), intent(in) :: param_file !< A structure indicating the open !! file to parse for model parameter values. logical, optional, intent(in) :: just_read_params !< If present and true, this call will @@ -94,7 +99,7 @@ subroutine USER_initialize_thickness(h, G, GV, param_file, just_read_params) if (just_read) return ! All run-time parameters have been read, so return. - h(:,:,1) = 0.0 ! h should be set in units of H. + h(:,:,1) = 0.0 ! h should be set [H ~> m or kg m-2]. if (first_call) call write_user_log(param_file) @@ -103,7 +108,7 @@ end subroutine USER_initialize_thickness !> initialize velocities. subroutine USER_initialize_velocity(u, v, G, param_file, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure. - real, dimension(SZIB_(G), SZJ_(G), SZK_(G)), intent(out) :: u !< i-component of velocity [m/s] + real, dimension(SZIB_(G), SZJ_(G), SZK_(G)), intent(out) :: u !< i-component of velocity [m s-1] real, dimension(SZI_(G), SZJB_(G), SZK_(G)), intent(out) :: v !< j-component of velocity [m/s] type(param_file_type), intent(in) :: param_file !< A structure indicating the !! open file to parse for model @@ -132,8 +137,8 @@ end subroutine USER_initialize_velocity !! into T(:,:,:) and S(:,:,:). subroutine USER_init_temperature_salinity(T, S, G, param_file, eqn_of_state, just_read_params) type(ocean_grid_type), intent(in) :: G !< Ocean grid structure. - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature (degC). - real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity (ppt). + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< Potential temperature [degC]. + real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< Salinity [ppt]. type(param_file_type), intent(in) :: param_file !< A structure indicating the !! open file to parse for model !! parameter values. @@ -174,7 +179,7 @@ subroutine USER_initialize_sponges(G, GV, use_temp, tv, param_file, CSp, h) !! parameter values. type(sponge_CS), pointer :: CSp !< A pointer to the sponge control structure. real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), & - intent(in) :: h !< Layer thicknesses, in units of H (m or kg m-2). + intent(in) :: h !< Layer thicknesses [H ~> m or kg m-2]. call MOM_error(FATAL, & "USER_initialization.F90, USER_initialize_sponges: " // & "Unmodified user routine called - you must edit the routine to use it") @@ -237,19 +242,18 @@ end subroutine write_user_log !! The one argument passed to initialize, Time, is set to the !! current time of the simulation. The fields which are initialized !! here are: -!! - u - Zonal velocity in m s-1. -!! - v - Meridional velocity in m s-1. -!! - h - Layer thickness in H. (Must be positive.) -!! - G%bathyT - Basin depth in Z. (Must be positive.) -!! - G%CoriolisBu - The Coriolis parameter, in s-1. -!! - GV%g_prime - The reduced gravity at each interface, in m2 Z-1 s-2. -!! - GV%Rlay - Layer potential density (coordinate variable), kg m-3. +!! - u - Zonal velocity [m s-1]. +!! - v - Meridional velocity [m s-1]. +!! - h - Layer thickness [H ~> m or kg m-2]. (Must be positive.) +!! - G%bathyT - Basin depth [Z ~> m]. (Must be positive.) +!! - G%CoriolisBu - The Coriolis parameter [s-1]. +!! - GV%g_prime - The reduced gravity at each interface [m2 Z-1 s-2 ~> m s-2]. +!! - GV%Rlay - Layer potential density (coordinate variable) [kg m-3]. !! If ENABLE_THERMODYNAMICS is defined: -!! - T - Temperature in C. -!! - S - Salinity in psu. +!! - T - Temperature [degC]. +!! - S - Salinity [psu]. !! If BULKMIXEDLAYER is defined: -!! - Rml - Mixed layer and buffer layer potential densities in -!! units of kg m-3. +!! - Rml - Mixed layer and buffer layer potential densities [kg m-3]. !! If SPONGE is defined: !! - A series of subroutine calls are made to set up the damping !! rates and reference profiles for all variables that are damped