Skip to content

Commit

Permalink
Minor code cleanup in drivers/FMS_cap
Browse files Browse the repository at this point in the history
Various minor code cleanup in the drivers/FMS_cap directory, including:
  o Rescaled the internal latent_heat variables in the control structure for
    MOM_surface_forcing_gfdl for improved dimensional consistency testing.
  o Removed the unused local variable PmE_adj in convert_IOB_to_fluxes().
  o Corrected the documented units or fixed spelling errors in several comments.
All answers and output are bitwise identical.
  • Loading branch information
Hallberg-NOAA authored and marshallward committed Nov 30, 2021
1 parent e218478 commit a0248ef
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 37 deletions.
58 changes: 28 additions & 30 deletions config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ module MOM_surface_forcing_gfdl

real :: Rho0 !< Boussinesq reference density [R ~> 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 :: latent_heat_fusion !< Latent heat of fusion [Q ~> J kg-1]
real :: latent_heat_vapor !< Latent heat of vaporization [Q ~> J kg-1]

real :: max_p_surf !< The maximum surface pressure that can be exerted by
!! the atmosphere and floating sea-ice [R L2 T-2 ~> Pa].
Expand Down Expand Up @@ -231,8 +231,6 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
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 [ppt]
PmE_adj, & ! The adjustment to PminusE that will cause the salinity
! 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 net freshwater flux into the ocean [kg m-2 s-1]
work_sum, & ! A 2-d array that is used as the work space for global sums [m2] or [kg s-1]
Expand All @@ -245,7 +243,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
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 :: kg_m2_s_conversion ! A combination of unit conversion factors for rescaling
real :: kg_m2_s_conversion ! A combination of unit conversion factors for rescaling
! mass fluxes [R Z s m2 kg-1 T-1 ~> 1].
real :: rhoXcp ! Reference density times heat capacity times unit scaling
! factors [Q R degC-1 ~> J m-3 degC-1]
Expand All @@ -264,7 +262,6 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
kg_m2_s_conversion = US%kg_m2s_to_RZ_T
if (CS%restore_temp) rhoXcp = CS%Rho0 * fluxes%C_p
open_ocn_mask(:,:) = 1.0
pme_adj(:,:) = 0.0
fluxes%vPrecGlobalAdj = 0.0
fluxes%vPrecGlobalScl = 0.0
fluxes%saltFluxGlobalAdj = 0.0
Expand Down Expand Up @@ -490,19 +487,17 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,

fluxes%latent(i,j) = 0.0
if (associated(IOB%fprec)) then
fluxes%latent(i,j) = fluxes%latent(i,j) - &
IOB%fprec(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_fusion
fluxes%latent_fprec_diag(i,j) = -G%mask2dT(i,j) * IOB%fprec(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_fusion
fluxes%latent(i,j) = fluxes%latent(i,j) - IOB%fprec(i-i0,j-j0)*kg_m2_s_conversion * CS%latent_heat_fusion
fluxes%latent_fprec_diag(i,j) = -G%mask2dT(i,j) * IOB%fprec(i-i0,j-j0)*kg_m2_s_conversion * CS%latent_heat_fusion
endif
if (associated(IOB%calving)) then
fluxes%latent(i,j) = fluxes%latent(i,j) - &
IOB%calving(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_fusion
fluxes%latent_frunoff_diag(i,j) = -G%mask2dT(i,j) * IOB%calving(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_fusion
fluxes%latent(i,j) = fluxes%latent(i,j) - IOB%calving(i-i0,j-j0)*kg_m2_s_conversion * CS%latent_heat_fusion
fluxes%latent_frunoff_diag(i,j) = -G%mask2dT(i,j) * IOB%calving(i-i0,j-j0)*kg_m2_s_conversion * &
CS%latent_heat_fusion
endif
if (associated(IOB%q_flux)) then
fluxes%latent(i,j) = fluxes%latent(i,j) - &
IOB%q_flux(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_vapor
fluxes%latent_evap_diag(i,j) = -G%mask2dT(i,j) * IOB%q_flux(i-i0,j-j0)*US%W_m2_to_QRZ_T*CS%latent_heat_vapor
fluxes%latent(i,j) = fluxes%latent(i,j) - IOB%q_flux(i-i0,j-j0)*kg_m2_s_conversion * CS%latent_heat_vapor
fluxes%latent_evap_diag(i,j) = -G%mask2dT(i,j) * IOB%q_flux(i-i0,j-j0)*kg_m2_s_conversion * CS%latent_heat_vapor
endif

fluxes%latent(i,j) = G%mask2dT(i,j) * fluxes%latent(i,j)
Expand Down Expand Up @@ -601,7 +596,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
if (CS%adjust_net_fresh_water_by_scaling) then
call adjust_area_mean_to_zero(net_FW2, G, fluxes%netFWGlobalScl)
do j=js,je ; do i=is,ie
fluxes%vprec(i,j) = fluxes%vprec(i,j) + US%kg_m2s_to_RZ_T * &
fluxes%vprec(i,j) = fluxes%vprec(i,j) + kg_m2_s_conversion * &
(net_FW2(i,j) - net_FW(i,j)/(US%L_to_m**2*G%areaT(i,j))) * G%mask2dT(i,j)
enddo ; enddo
else
Expand Down Expand Up @@ -670,7 +665,7 @@ subroutine convert_IOB_to_forces(IOB, forces, index_bounds, Time, G, US, CS, dt_
real :: Kv_rho_ice ! (CS%Kv_sea_ice / CS%density_sea_ice) [L4 Z-2 T-1 R-1 ~> m5 s-1 kg-1]
real :: mass_ice ! mass of sea ice at a face [R Z ~> kg m-2]
real :: mass_eff ! effective mass of sea ice for rigidity [R Z ~> kg m-2]
real :: wt1, wt2 ! Relative weights of previous and current values of ustar, ND.
real :: wt1, wt2 ! Relative weights of previous and current values of ustar [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
Expand Down Expand Up @@ -891,9 +886,9 @@ subroutine extract_IOB_stresses(IOB, index_bounds, Time, G, US, CS, taux, tauy,
! Local variables
real, dimension(SZI_(G),SZJ_(G)) :: taux_in_A ! Zonal wind stresses [R Z L T-2 ~> Pa] at h points
real, dimension(SZI_(G),SZJ_(G)) :: tauy_in_A ! Meridional wind stresses [R Z L T-2 ~> Pa] at h points
real, dimension(SZIB_(G),SZJ_(G)) :: taux_in_C ! Zonal wind stresses [Pa] at u points
real, dimension(SZIB_(G),SZJ_(G)) :: taux_in_C ! Zonal wind stresses [R Z L T-2 ~> Pa] at u points
real, dimension(SZI_(G),SZJB_(G)) :: tauy_in_C ! Meridional wind stresses [R Z L T-2 ~> 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)) :: taux_in_B ! Zonal wind stresses [R Z L T-2 ~> Pa] at q points
real, dimension(SZIB_(G),SZJB_(G)) :: tauy_in_B ! Meridional wind stresses [R Z L T-2 ~> Pa] at q points

real :: gustiness ! unresolved gustiness that contributes to ustar [R Z L T-2 ~> Pa]
Expand Down Expand Up @@ -1109,7 +1104,8 @@ subroutine apply_flux_adjustments(G, US, CS, Time, fluxes)
type(forcing), intent(inout) :: fluxes !< Surface fluxes structure

! Local variables
real, dimension(G%isc:G%iec,G%jsc:G%jec) :: temp_at_h ! Various fluxes at h points [W m-2] or [kg m-2 s-1]
real, dimension(G%isc:G%iec,G%jsc:G%jec) :: temp_at_h ! Various fluxes at h points
! [Q R Z T-1 ~> W m-2] or [R Z T-1 ~> kg m-2 s-1]

integer :: isc, iec, jsc, jec, i, j
logical :: overrode_h
Expand All @@ -1120,7 +1116,7 @@ subroutine apply_flux_adjustments(G, US, CS, Time, fluxes)
scale=US%W_m2_to_QRZ_T)

if (overrode_h) then ; do j=jsc,jec ; do i=isc,iec
fluxes%heat_added(i,j) = fluxes%heat_added(i,j) + temp_at_h(i,j)* G%mask2dT(i,j)
fluxes%heat_added(i,j) = fluxes%heat_added(i,j) + temp_at_h(i,j) * G%mask2dT(i,j)
enddo ; enddo ; endif
! Not needed? ! if (overrode_h) call pass_var(fluxes%heat_added, G%Domain)

Expand Down Expand Up @@ -1283,9 +1279,9 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
"parameters from vertical units of m to kg m-2.", &
units="kg m-3", default=1035.0, scale=US%kg_m3_to_R)
call get_param(param_file, mdl, "LATENT_HEAT_FUSION", CS%latent_heat_fusion, &
"The latent heat of fusion.", units="J/kg", default=hlf)
"The latent heat of fusion.", units="J/kg", default=hlf, scale=US%J_kg_to_Q)
call get_param(param_file, mdl, "LATENT_HEAT_VAPORIZATION", CS%latent_heat_vapor, &
"The latent heat of fusion.", units="J/kg", default=hlv)
"The latent heat of fusion.", units="J/kg", default=hlv, scale=US%J_kg_to_Q)
call get_param(param_file, mdl, "MAX_P_SURF", CS%max_p_surf, &
"The maximum surface pressure that can be exerted by the "//&
"atmosphere and floating sea-ice or ice shelves. This is "//&
Expand Down Expand Up @@ -1373,12 +1369,12 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
call get_param(param_file, mdl, "FLUXCONST", CS%Flux_const, &
"The constant that relates the restoring surface fluxes to the relative "//&
"surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
default=0.0, units="m day-1", scale=US%m_to_Z*US%T_to_s,unscaled=unscaled_fluxconst)
default=0.0, units="m day-1", scale=US%m_to_Z*US%T_to_s, unscaled=unscaled_fluxconst)
call get_param(param_file, mdl, "FLUXCONST_SALT", CS%Flux_const_salt, &
"The constant that relates the restoring surface salt fluxes to the relative "//&
"surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
fail_if_missing=.false.,default=unscaled_fluxconst, units="m day-1", scale=US%m_to_Z*US%T_to_s)
! Convert CS%Flux_const from m day-1 to m s-1.
! Finish converting CS%Flux_const from m day-1 to [Z T-1 ~> m s-1].
CS%Flux_const = CS%Flux_const / 86400.0
CS%Flux_const_salt = CS%Flux_const_salt / 86400.0
call get_param(param_file, mdl, "SALT_RESTORE_FILE", CS%salt_restore_file, &
Expand Down Expand Up @@ -1450,10 +1446,12 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)

endif

! 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.
! Optionally read tidal amplitude from input file [Z T-1 ~> 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.
! Note that the slightly unusual length scaling is deliberate, because the tidal
! amplitudes are used to set the friction velocity.
call get_param(param_file, mdl, "CD_TIDES", CS%cd_tides, &
"The drag coefficient that applies to the tides.", &
units="nondim", default=1.0e-4)
Expand Down Expand Up @@ -1624,7 +1622,7 @@ subroutine surface_forcing_end(CS, fluxes)

end subroutine surface_forcing_end

!> Write out a set of messages with checksums of the fields in an ice_ocen_boundary type
!> Write out a set of messages with checksums of the fields in an ice_ocean_boundary type
subroutine ice_ocn_bnd_type_chksum(id, timestep, iobt)

character(len=*), intent(in) :: id !< An identifying string for this call
Expand Down
14 changes: 7 additions & 7 deletions config_src/drivers/FMS_cap/ocean_model_MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ module ocean_model_mod

!> This type is used for communication with other components via the FMS coupler.
!! The element names and types can be changed only with great deliberation, hence
!! the persistnce of things like the cutsy element name "avg_kount".
!! the persistence of things like the cutesy element name "avg_kount".
type, public :: ocean_public_type
type(domain2d) :: Domain !< The domain for the surface fields.
logical :: is_ocean_pe !< .true. on processors that run the ocean model.
Expand All @@ -110,8 +110,8 @@ module ocean_model_mod
!! a global max across ocean and non-ocean processors can be
!! used to determine its value.
real, pointer, dimension(:,:) :: &
t_surf => NULL(), & !< SST on t-cell (degrees Kelvin)
s_surf => NULL(), & !< SSS on t-cell (psu)
t_surf => NULL(), & !< SST on t-cell [degrees Kelvin]
s_surf => NULL(), & !< SSS on t-cell [ppt]
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,
Expand Down Expand Up @@ -221,7 +221,7 @@ module ocean_model_mod
!! for restarts and reading restart files if appropriate.
!!
!! This subroutine initializes both the ocean state and the ocean surface type.
!! Because of the way that indicies and domains are handled, Ocean_sfc must have
!! Because of the way that indices and domains are handled, Ocean_sfc must have
!! been used in a previous call to initialize_ocean_type.
subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, wind_stagger, gas_fields_ocn)
type(ocean_public_type), target, &
Expand Down Expand Up @@ -766,7 +766,7 @@ subroutine initialize_ocean_public_type(input_domain, Ocean_sfc, diag, gas_field
!! tracer fluxes.

integer :: xsz, ysz, layout(2)
! ice-ocean-boundary fields are always allocated using absolute indicies
! ice-ocean-boundary fields are always allocated using absolute indices
! and have no halos.
integer :: isc, iec, jsc, jec

Expand Down Expand Up @@ -806,7 +806,7 @@ end subroutine initialize_ocean_public_type
!! surface state variable. This may eventually be folded into the MOM
!! code that calculates the surface state in the first place.
!! Note the offset in the arrays because the ocean_data_type has no
!! halo points in its arrays and always uses absolute indicies.
!! halo points in its arrays and always uses absolute indices.
subroutine convert_state_to_ocean_type(sfc_state, Ocean_sfc, G, US, patm, press_to_z)
type(surface), intent(inout) :: sfc_state !< A structure containing fields that
!! describe the surface state of the ocean.
Expand Down Expand Up @@ -946,7 +946,7 @@ end subroutine ocean_model_init_sfc

!> ocean_model_flux_init is used to initialize properties of the air-sea fluxes
!! as determined by various run-time parameters. It can be called from
!! non-ocean PEs, or PEs that have not yet been initialzed, and it can safely
!! non-ocean PEs, or PEs that have not yet been initialized, and it can safely
!! be called multiple times.
subroutine ocean_model_flux_init(OS, verbosity)
type(ocean_state_type), optional, pointer :: OS !< An optional pointer to the ocean state,
Expand Down

0 comments on commit a0248ef

Please sign in to comment.