Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

+Add ANSWER_DATE runtime parameters #179

Merged
merged 11 commits into from
Aug 4, 2022
40 changes: 29 additions & 11 deletions config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,10 @@ module MOM_surface_forcing_gfdl
real :: max_delta_srestore !< Maximum delta salinity used for restoring [S ~> ppt]
real :: max_delta_trestore !< Maximum delta sst used for restoring [C ~> degC]
real, pointer, dimension(:,:) :: basin_mask => NULL() !< Mask for surface salinity restoring by basin
logical :: answers_2018 !< If true, use the order of arithmetic and expressions that recover
!! the answers from the end of 2018. Otherwise, use a simpler
!! expression to calculate gustiness.
integer :: answer_date !< The vintage of the order of arithmetic and expressions in the
!! gustiness calculations. Values below 20190101 recover the answers
!! from the end of 2018, while higher values use a simpler expression
!! to calculate gustiness.
logical :: fix_ustar_gustless_bug !< If true correct a bug in the time-averaging of the
!! gustless wind friction velocity.
logical :: check_no_land_fluxes !< Return warning if IOB flux over land is non-zero
Expand Down Expand Up @@ -533,7 +534,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
if (CS%check_no_land_fluxes) &
call check_mask_val_consistency(IOB%sw_flux_nir_dif(i-i0,j-j0), G%mask2dT(i,j), i, j, 'sw_flux_nir_dif', G)
endif
if (CS%answers_2018) then
if (CS%answer_date < 20190101) then
fluxes%sw(i,j) = fluxes%sw_vis_dir(i,j) + fluxes%sw_vis_dif(i,j) + &
fluxes%sw_nir_dir(i,j) + fluxes%sw_nir_dif(i,j)
else
Expand Down Expand Up @@ -1038,7 +1039,7 @@ subroutine extract_IOB_stresses(IOB, index_bounds, Time, G, US, CS, taux, tauy,
endif
ustar(i,j) = sqrt(gustiness*IRho0 + IRho0*Pa_conversion*IOB%stress_mag(i-i0,j-j0))
enddo ; enddo ; endif
if (CS%answers_2018) then
if (CS%answer_date < 20190101) then
if (do_gustless) then ; do j=js,je ; do i=is,ie
gustless_ustar(i,j) = sqrt(Pa_conversion*US%L_to_Z*IOB%stress_mag(i-i0,j-j0) / CS%Rho0)
enddo ; enddo ; endif
Expand All @@ -1060,7 +1061,7 @@ subroutine extract_IOB_stresses(IOB, index_bounds, Time, G, US, CS, taux, tauy,
if (CS%read_gust_2d) gustiness = CS%gust(i,j)
endif
if (do_ustar) ustar(i,j) = sqrt(gustiness*IRho0 + IRho0 * tau_mag)
if (CS%answers_2018) then
if (CS%answer_date < 20190101) then
if (do_gustless) gustless_ustar(i,j) = sqrt(US%L_to_Z*tau_mag / CS%Rho0)
else
if (do_gustless) gustless_ustar(i,j) = sqrt(IRho0 * tau_mag)
Expand All @@ -1072,7 +1073,7 @@ subroutine extract_IOB_stresses(IOB, index_bounds, Time, G, US, CS, taux, tauy,
gustiness = CS%gust_const
if (CS%read_gust_2d .and. (G%mask2dT(i,j) > 0.0)) gustiness = CS%gust(i,j)
if (do_ustar) ustar(i,j) = sqrt(gustiness*IRho0 + IRho0 * tau_mag)
if (CS%answers_2018) then
if (CS%answer_date < 20190101) then
if (do_gustless) gustless_ustar(i,j) = sqrt(US%L_to_Z*tau_mag / CS%Rho0)
else
if (do_gustless) gustless_ustar(i,j) = sqrt(IRho0 * tau_mag)
Expand All @@ -1093,7 +1094,7 @@ subroutine extract_IOB_stresses(IOB, index_bounds, Time, G, US, CS, taux, tauy,
if (CS%read_gust_2d) gustiness = CS%gust(i,j)

if (do_ustar) ustar(i,j) = sqrt(gustiness*IRho0 + IRho0 * tau_mag)
if (CS%answers_2018) then
if (CS%answer_date < 20190101) then
if (do_gustless) gustless_ustar(i,j) = sqrt(US%L_to_Z*tau_mag / CS%Rho0)
else
if (do_gustless) gustless_ustar(i,j) = sqrt(IRho0 * tau_mag)
Expand Down Expand Up @@ -1250,7 +1251,11 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
real :: utide ! The RMS tidal velocity [Z T-1 ~> m s-1].
type(directories) :: dirs
logical :: new_sim, iceberg_flux_diags
logical :: default_2018_answers
integer :: default_answer_date ! The default setting for the various ANSWER_DATE flags.
logical :: default_2018_answers ! The default setting for the various 2018_ANSWERS flags.
logical :: answers_2018 ! If true, use the order of arithmetic and expressions that recover
! the answers from the end of 2018. Otherwise, use a simpler
! expression to calculate gustiness.
type(time_type) :: Time_frc
character(len=200) :: TideAmp_file, gust_file, salt_file, temp_file ! Input file names.
! This include declares and sets the variable "version".
Expand Down Expand Up @@ -1531,13 +1536,26 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, wind_stagger)
call MOM_read_data(gust_file, 'gustiness', CS%gust, G%domain, timelevel=1, &
scale=US%kg_m3_to_R*US%m_s_to_L_T**2*US%L_to_Z) ! units in file should be Pa
endif
call get_param(param_file, mdl, "DEFAULT_ANSWER_DATE", default_answer_date, &
"This sets the default value for the various _ANSWER_DATE parameters.", &
default=99991231)
call get_param(param_file, mdl, "DEFAULT_2018_ANSWERS", default_2018_answers, &
"This sets the default value for the various _2018_ANSWERS parameters.", &
default=.false.)
call get_param(param_file, mdl, "SURFACE_FORCING_2018_ANSWERS", CS%answers_2018, &
default=(default_answer_date<20190101))
call get_param(param_file, mdl, "SURFACE_FORCING_2018_ANSWERS", answers_2018, &
"If true, use the order of arithmetic and expressions that recover the answers "//&
"from the end of 2018. Otherwise, use a simpler expression to calculate gustiness.", &
default=default_2018_answers)
! Revise inconsistent default answer dates.
if (answers_2018 .and. (default_answer_date >= 20190101)) default_answer_date = 20181231
if (.not.answers_2018 .and. (default_answer_date < 20190101)) default_answer_date = 20190101
call get_param(param_file, mdl, "SURFACE_FORCING_ANSWER_DATE", CS%answer_date, &
"The vintage of the order of arithmetic and expressions in the gustiness "//&
"calculations. Values below 20190101 recover the answers from the end "//&
"of 2018, while higher values use a simpler expression to calculate gustiness. "//&
"If both SURFACE_FORCING_2018_ANSWERS and SURFACE_FORCING_ANSWER_DATE are "//&
"specified, the latter takes precedence.", default=default_answer_date)

call get_param(param_file, mdl, "FIX_USTAR_GUSTLESS_BUG", CS%fix_ustar_gustless_bug, &
"If true correct a bug in the time-averaging of the gustless wind friction velocity", &
default=.true.)
Expand Down
37 changes: 28 additions & 9 deletions config_src/drivers/solo_driver/MOM_surface_forcing.F90
Original file line number Diff line number Diff line change
Expand Up @@ -105,10 +105,11 @@ module MOM_surface_forcing
real :: gyres_taux_sin_amp !< The amplitude of cosine wind stress gyres [R L Z T-1 ~> Pa], if WIND_CONFIG=='gyres'
real :: gyres_taux_cos_amp !< The amplitude of cosine wind stress gyres [R L Z T-1 ~> Pa], if WIND_CONFIG=='gyres'
real :: gyres_taux_n_pis !< The number of sine lobes in the basin if WIND_CONFIG=='gyres'
logical :: answers_2018 !< If true, use the order of arithmetic and expressions that recover
!! the answers from the end of 2018. Otherwise, use a form of the gyre
!! wind stresses that are rotationally invariant and more likely to be
!! the same between compilers.
integer :: answer_date !< This 8-digit integer gives the approximate date with which the order
!! of arithmetic and and expressions were added to the code.
!! Dates before 20190101 use original answers.
!! Dates after 20190101 use a form of the gyre wind stresses that are
!! rotationally invariant and more likely to be the same between compilers.
logical :: fix_ustar_gustless_bug !< If true correct a bug in the time-averaging of the
!! gustless wind friction velocity.
! if WIND_CONFIG=='scurves' then use the following to define a piecewise scurve profile
Expand Down Expand Up @@ -522,7 +523,7 @@ subroutine wind_forcing_gyres(sfc_state, forces, day, G, US, CS)
enddo ; enddo

! set the friction velocity
if (CS%answers_2018) then
if (CS%answer_date < 20190101) then
do j=js,je ; do i=is,ie
forces%ustar(i,j) = sqrt(US%L_to_Z * ((CS%gust_const/CS%Rho0) + &
sqrt(0.5*(forces%tauy(i,j-1)*forces%tauy(i,j-1) + forces%tauy(i,j)*forces%tauy(i,j) + &
Expand Down Expand Up @@ -1504,7 +1505,12 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C
real :: flux_const_default ! The unscaled value of FLUXCONST [m day-1]
real :: Pa_to_RLZ_T2 ! A unit conversion factor from Pa to the internal units
! for wind stresses [R Z L T-2 Pa-1 ~> 1]
logical :: default_2018_answers
integer :: default_answer_date ! The default setting for the various ANSWER_DATE flags.
logical :: default_2018_answers ! The default setting for the various 2018_ANSWERS flags.
logical :: answers_2018 ! If true, use the order of arithmetic and expressions that recover
! the answers from the end of 2018. Otherwise, use a form of the gyre
! wind stresses that are rotationally invariant and more likely to be
! the same between compilers.
character(len=40) :: mdl = "MOM_surface_forcing" ! This module's name.
character(len=200) :: filename, gust_file ! The name of the gustiness input file.

Expand Down Expand Up @@ -1736,16 +1742,29 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C
"the zonal wind stress profile: "//&
" n in taux = A + B*sin(n*pi*y/L) + C*cos(n*pi*y/L).", &
units="nondim", default=0.0)
call get_param(param_file, mdl, "DEFAULT_ANSWER_DATE", default_answer_date, &
"This sets the default value for the various _ANSWER_DATE parameters.", &
default=99991231)
call get_param(param_file, mdl, "DEFAULT_2018_ANSWERS", default_2018_answers, &
"This sets the default value for the various _2018_ANSWERS parameters.", &
default=.false.)
call get_param(param_file, mdl, "WIND_GYRES_2018_ANSWERS", CS%answers_2018, &
default=(default_answer_date<20190101))
call get_param(param_file, mdl, "WIND_GYRES_2018_ANSWERS", answers_2018, &
"If true, use the order of arithmetic and expressions that recover the answers "//&
"from the end of 2018. Otherwise, use expressions for the gyre friction velocities "//&
"that are rotationally invariant and more likely to be the same between compilers.", &
default=default_2018_answers)
! Revise inconsistent default answer dates.
if (answers_2018 .and. (default_answer_date >= 20190101)) default_answer_date = 20181231
if (.not.answers_2018 .and. (default_answer_date < 20190101)) default_answer_date = 20190101
call get_param(param_file, mdl, "WIND_GYRES_ANSWER_DATE", CS%answer_date, &
"The vintage of the expressions used to set gyre wind stresses. "//&
"Values below 20190101 recover the answers from the end of 2018, "//&
"while higher values use a form of the gyre wind stresses that are "//&
"rotationally invariant and more likely to be the same between compilers. "//&
"If both WIND_GYRES_2018_ANSWERS and WIND_GYRES_ANSWER_DATE are specified, "//&
"the latter takes precedence.", default=default_answer_date)
else
CS%answers_2018 = .false.
CS%answer_date = 20190101
endif
if (trim(CS%wind_config) == "scurves") then
call get_param(param_file, mdl, "WIND_SCURVES_LATS", CS%scurves_ydata, &
Expand Down
Loading