diff --git a/config_src/drivers/solo_driver/MOM_surface_forcing.F90 b/config_src/drivers/solo_driver/MOM_surface_forcing.F90 index 967667d786..448b16b5e4 100644 --- a/config_src/drivers/solo_driver/MOM_surface_forcing.F90 +++ b/config_src/drivers/solo_driver/MOM_surface_forcing.F90 @@ -30,13 +30,12 @@ module MOM_surface_forcing use MOM_grid, only : ocean_grid_type use MOM_get_input, only : Get_MOM_Input, directories use MOM_io, only : file_exists, MOM_read_data, MOM_read_vector, slasher -use MOM_io, only : read_netCDF_data -use MOM_io, only : EAST_FACE, NORTH_FACE, num_timelevels +use MOM_io, only : read_netCDF_data, EAST_FACE, NORTH_FACE, num_timelevels use MOM_restart, only : register_restart_field, restart_init, MOM_restart_CS use MOM_restart, only : restart_init_end, save_restart, restore_state -use MOM_time_manager, only : time_type, operator(+), operator(/), get_time, time_type_to_real -use MOM_tracer_flow_control, only : call_tracer_set_forcing -use MOM_tracer_flow_control, only : tracer_flow_control_CS +use MOM_time_manager, only : time_type, operator(+), operator(/), operator(*) +use MOM_time_manager, only : set_time, get_time, get_date, time_type_to_real +use MOM_tracer_flow_control, only : call_tracer_set_forcing, tracer_flow_control_CS use MOM_unit_scaling, only : unit_scale_type use MOM_variables, only : surface use MESO_surface_forcing, only : MESO_buoyancy_forcing @@ -51,10 +50,10 @@ module MOM_surface_forcing use SCM_CVmix_tests, only : SCM_CVmix_tests_wind_forcing use SCM_CVmix_tests, only : SCM_CVmix_tests_buoyancy_forcing use SCM_CVmix_tests, only : SCM_CVmix_tests_CS -use BFB_surface_forcing, only : BFB_buoyancy_forcing -use BFB_surface_forcing, only : BFB_surface_forcing_init, BFB_surface_forcing_CS -use dumbbell_surface_forcing, only : dumbbell_surface_forcing_init, dumbbell_surface_forcing_CS -use dumbbell_surface_forcing, only : dumbbell_buoyancy_forcing +use BFB_surface_forcing, only : BFB_buoyancy_forcing +use BFB_surface_forcing, only : BFB_surface_forcing_init, BFB_surface_forcing_CS +use dumbbell_surface_forcing, only : dumbbell_surface_forcing_init, dumbbell_surface_forcing_CS +use dumbbell_surface_forcing, only : dumbbell_buoyancy_forcing implicit none ; private @@ -102,8 +101,6 @@ module MOM_surface_forcing real, pointer :: S_Restore(:,:) => NULL() !< salinity to damp (restore) the SSS [S ~> ppt] real, pointer :: Dens_Restore(:,:) => NULL() !< density to damp (restore) surface density [R ~> 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 [R L Z T-2 ~> Pa]. @@ -181,6 +178,38 @@ module MOM_surface_forcing character(len=80) :: SST_restore_var = '' !< target sea surface temperature variable name in the input file character(len=80) :: SSS_restore_var = '' !< target sea surface salinity variable name in the input file + ! These variables relate model times to time levels in the various forcing files. + integer :: wind_days_per_rec = 0 !< If positive the number of days of wind stress per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: SW_days_per_rec = 0 !< If positive the number of days shortwave heat flux per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: LW_days_per_rec = 0 !< If positive the number of days longwave heat flux per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: latent_days_per_rec = 0 !< If positive the number of days latent heat flux per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: sens_days_per_rec = 0 !< If positive the number of days sensible heat flux per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: evap_days_per_rec = 0 !< If positive the number of days evaporation per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: precip_days_per_rec = 0 !< If positive the number of days precipitation per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: runoff_days_per_rec = 0 !< If positive the number of days runoff per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: SST_days_per_rec = 0 !< If positive the number of days target SST per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + integer :: SSS_days_per_rec = 0 !< If positive the number of days target SSS per forcing file time level, + !! or if negative the number of time levels per day. If 31 change forcing + !! monthly, or if 0 the model will guess the right value based on the file size. + ! These variables give the number of time levels in the various forcing files. integer :: wind_nlev = -1 !< The number of time levels in the file of wind stress integer :: SW_nlev = -1 !< The number of time levels in the file of shortwave heat flux @@ -682,10 +711,7 @@ subroutine wind_forcing_from_file(sfc_state, forces, day, G, US, CS) real :: ustar_loc(SZI_(G),SZJ_(G)) ! The local value of ustar [Z T-1 ~> m s-1] real :: tau_mag ! The magnitude of the wind stress including any contributions from ! sub-gridscale variability or gustiness [R L Z T-2 ~> Pa] - integer :: time_lev_daily ! The time levels to read for fields with - integer :: time_lev_monthly ! daily and monthly cycles. integer :: time_lev ! The time level that is used for a field. - integer :: days, seconds integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq logical :: read_Ustar @@ -693,31 +719,7 @@ subroutine wind_forcing_from_file(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 - call get_time(day, seconds, days) - time_lev_daily = days - 365*floor(real(days) / 365.0) - - if (time_lev_daily < 31) then ; time_lev_monthly = 0 - elseif (time_lev_daily < 59) then ; time_lev_monthly = 1 - elseif (time_lev_daily < 90) then ; time_lev_monthly = 2 - elseif (time_lev_daily < 120) then ; time_lev_monthly = 3 - elseif (time_lev_daily < 151) then ; time_lev_monthly = 4 - elseif (time_lev_daily < 181) then ; time_lev_monthly = 5 - elseif (time_lev_daily < 212) then ; time_lev_monthly = 6 - elseif (time_lev_daily < 243) then ; time_lev_monthly = 7 - elseif (time_lev_daily < 273) then ; time_lev_monthly = 8 - elseif (time_lev_daily < 304) then ; time_lev_monthly = 9 - elseif (time_lev_daily < 334) then ; time_lev_monthly = 10 - else ; time_lev_monthly = 11 - endif - - time_lev_daily = time_lev_daily+1 - time_lev_monthly = time_lev_monthly+1 - - select case (CS%wind_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + time_lev = get_file_time_level(day, CS%wind_nlev, CS%wind_days_per_rec) if (time_lev /= CS%wind_last_lev) then filename = trim(CS%wind_file) @@ -996,11 +998,9 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) real :: rhoXcp ! reference density times heat capacity [Q R C-1 ~> J m-3 degC-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 + logical :: fluxes_changed ! True if any of the fluxes might have been altered integer :: time_lev ! time level that for a field - integer :: days, seconds integer :: i, j, is, ie, js, je call callTree_enter("buoyancy_forcing_from_files, MOM_surface_forcing.F90") @@ -1010,35 +1010,11 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) if (CS%use_temperature) rhoXcp = CS%rho_restore * fluxes%C_p ! Read the buoyancy forcing file - call get_time(day, seconds, days) - - time_lev_daily = days - 365*floor(real(days) / 365.0) - - if (time_lev_daily < 31) then ; time_lev_monthly = 0 - elseif (time_lev_daily < 59) then ; time_lev_monthly = 1 - elseif (time_lev_daily < 90) then ; time_lev_monthly = 2 - elseif (time_lev_daily < 120) then ; time_lev_monthly = 3 - elseif (time_lev_daily < 151) then ; time_lev_monthly = 4 - elseif (time_lev_daily < 181) then ; time_lev_monthly = 5 - elseif (time_lev_daily < 212) then ; time_lev_monthly = 6 - elseif (time_lev_daily < 243) then ; time_lev_monthly = 7 - elseif (time_lev_daily < 273) then ; time_lev_monthly = 8 - elseif (time_lev_daily < 304) then ; time_lev_monthly = 9 - elseif (time_lev_daily < 334) then ; time_lev_monthly = 10 - else ; time_lev_monthly = 11 - endif - - time_lev_daily = time_lev_daily +1 - time_lev_monthly = time_lev_monthly+1 + fluxes_changed = .false. - if (time_lev_daily /= CS%buoy_last_lev_read) then - - ! longwave - select case (CS%LW_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + ! longwave + time_lev = get_file_time_level(day, CS%LW_nlev, CS%LW_days_per_rec) + if (time_lev /= CS%LW_last_lev) then call MOM_read_data(CS%longwave_file, CS%LW_var, fluxes%lw(:,:), & G%Domain, timelevel=time_lev, scale=US%W_m2_to_QRZ_T) if (CS%archaic_OMIP_file) then @@ -1046,14 +1022,13 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) timelevel=time_lev, scale=US%W_m2_to_QRZ_T) do j=js,je ; do i=is,ie ; fluxes%LW(i,j) = fluxes%LW(i,j) - temp(i,j) ; enddo ; enddo endif - CS%LW_last_lev = time_lev + CS%LW_last_lev = time_lev ; fluxes_changed = .true. + endif - ! evaporation - select case (CS%evap_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + ! evaporation + if ( (CS%evap_nlev /= CS%LW_nlev) .or. (CS%evap_days_per_rec /= CS%LW_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%evap_nlev, CS%evap_days_per_rec) + if (time_lev /= CS%evap_last_lev) then if (CS%archaic_OMIP_file) then call MOM_read_data(CS%evaporation_file, CS%evap_var, fluxes%evap(:,:), & G%Domain, timelevel=time_lev, scale=-US%kg_m2s_to_RZ_T) @@ -1065,13 +1040,12 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) call MOM_read_data(CS%evaporation_file, CS%evap_var, fluxes%evap(:,:), & G%Domain, timelevel=time_lev, scale=US%kg_m2s_to_RZ_T) endif - CS%evap_last_lev = time_lev + CS%evap_last_lev = time_lev ; fluxes_changed = .true. + endif - select case (CS%latent_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + if ( (CS%latent_nlev /= CS%evap_nlev) .or. (CS%latent_days_per_rec /= CS%evap_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%latent_nlev, CS%latent_days_per_rec) + if (time_lev /= CS%latent_last_lev) then if (.not.CS%archaic_OMIP_file) then call MOM_read_data(CS%latentheat_file, CS%latent_var, fluxes%latent(:,:), & G%Domain, timelevel=time_lev, scale=US%W_m2_to_QRZ_T) @@ -1079,13 +1053,12 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) fluxes%latent_evap_diag(i,j) = fluxes%latent(i,j) enddo ; enddo endif - CS%latent_last_lev = time_lev + CS%latent_last_lev = time_lev ; fluxes_changed = .true. + endif - select case (CS%sens_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + if ( (CS%sens_nlev /= CS%latent_nlev) .or. (CS%sens_days_per_rec /= CS%latent_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%sens_nlev, CS%sens_days_per_rec) + if (time_lev /= CS%sens_last_lev) then if (CS%archaic_OMIP_file) then call MOM_read_data(CS%sensibleheat_file, CS%sens_var, fluxes%sens(:,:), & G%Domain, timelevel=time_lev, scale=-US%W_m2_to_QRZ_T) @@ -1093,13 +1066,12 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) call MOM_read_data(CS%sensibleheat_file, CS%sens_var, fluxes%sens(:,:), & G%Domain, timelevel=time_lev, scale=US%W_m2_to_QRZ_T) endif - CS%sens_last_lev = time_lev + CS%sens_last_lev = time_lev ; fluxes_changed = .true. + endif - select case (CS%SW_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + if ( (CS%SW_nlev /= CS%sens_nlev) .or. (CS%SW_days_per_rec /= CS%sens_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%SW_nlev, CS%SW_days_per_rec) + if (time_lev /= CS%SW_last_lev) then call MOM_read_data(CS%shortwave_file, CS%SW_var, fluxes%sw(:,:), G%Domain, & timelevel=time_lev, scale=US%W_m2_to_QRZ_T) if (CS%archaic_OMIP_file) then @@ -1109,13 +1081,12 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) fluxes%sw(i,j) = fluxes%sw(i,j) - temp(i,j) enddo ; enddo endif - CS%SW_last_lev = time_lev + CS%SW_last_lev = time_lev ; fluxes_changed = .true. + endif - select case (CS%precip_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + if ( (CS%precip_nlev /= CS%SW_nlev) .or. (CS%precip_days_per_rec /= CS%SW_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%precip_nlev, CS%precip_days_per_rec) + if (time_lev /= CS%precip_last_lev) then call MOM_read_data(CS%snow_file, CS%snow_var, & fluxes%fprec(:,:), G%Domain, timelevel=time_lev, scale=US%kg_m2s_to_RZ_T) call MOM_read_data(CS%rain_file, CS%rain_var, & @@ -1125,13 +1096,12 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) fluxes%lprec(i,j) = fluxes%lprec(i,j) - fluxes%fprec(i,j) enddo ; enddo endif - CS%precip_last_lev = time_lev + CS%precip_last_lev = time_lev ; fluxes_changed = .true. + endif - select case (CS%runoff_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + if ( (CS%runoff_nlev /= CS%precip_nlev) .or. (CS%runoff_days_per_rec /= CS%precip_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%runoff_nlev, CS%runoff_days_per_rec) + if (time_lev /= CS%runoff_last_lev) then if (CS%archaic_OMIP_file) then call MOM_read_data(CS%runoff_file, CS%lrunoff_var, temp(:,:), & G%Domain, timelevel=time_lev, scale=US%kg_m2s_to_RZ_T*US%m_to_L**2) @@ -1149,30 +1119,28 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) call MOM_read_data(CS%runoff_file, CS%frunoff_var, fluxes%frunoff(:,:), & G%Domain, timelevel=time_lev, scale=US%kg_m2s_to_RZ_T) endif - CS%runoff_last_lev = time_lev + CS%runoff_last_lev = time_lev ; fluxes_changed = .true. + endif -! Read the SST and SSS fields for damping. - if (CS%restorebuoy) then !#CTRL# .or. associated(CS%ctrl_forcing_CSp)) then - select case (CS%SST_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + ! Read the SST and SSS fields for damping. + if (CS%restorebuoy) then !#CTRL# .or. associated(CS%ctrl_forcing_CSp)) then + time_lev = get_file_time_level(day, CS%SST_nlev, CS%SST_days_per_rec) + if (time_lev /= CS%SST_last_lev) then call MOM_read_data(CS%SSTrestore_file, CS%SST_restore_var, & CS%T_Restore(:,:), G%Domain, timelevel=time_lev, scale=US%degC_to_C) CS%SST_last_lev = time_lev + endif - select case (CS%SSS_nlev) - case (12) ; time_lev = time_lev_monthly - case (365) ; time_lev = time_lev_daily - case default ; time_lev = 1 - end select + if ( (CS%SSS_nlev /= CS%SST_nlev) .or. (CS%SSS_days_per_rec /= CS%SST_days_per_rec) ) & + time_lev = get_file_time_level(day, CS%SSS_nlev, CS%SSS_days_per_rec) + if (time_lev /= CS%SSS_last_lev) then call MOM_read_data(CS%salinityrestore_file, CS%SSS_restore_var, & CS%S_Restore(:,:), G%Domain, timelevel=time_lev, scale=US%ppt_to_S) CS%SSS_last_lev = time_lev endif - CS%buoy_last_lev_read = time_lev_daily + endif + if (fluxes_changed) then ! mask out land points and compute heat content of water fluxes ! assume liquid precipitation enters ocean at SST ! assume frozen precipitation enters ocean at 0degC @@ -1194,8 +1162,7 @@ subroutine buoyancy_forcing_from_files(sfc_state, fluxes, day, dt, G, US, CS) fluxes%latent_fprec_diag(i,j) = -fluxes%fprec(i,j)*CS%latent_heat_fusion fluxes%latent_frunoff_diag(i,j) = -fluxes%frunoff(i,j)*CS%latent_heat_fusion enddo ; enddo - - endif ! time_lev /= CS%buoy_last_lev_read + endif ! fluxes have changed and need to be masked ! restoring surface boundary fluxes @@ -1542,6 +1509,54 @@ subroutine buoyancy_forcing_linear(sfc_state, fluxes, day, dt, G, US, CS) call callTree_leave("buoyancy_forcing_linear") end subroutine buoyancy_forcing_linear +!> Return a time record to read from a file based on the model time, the number of time records in +!! that file and the number of time records per model day. +function get_file_time_level(Time, nlev_file, days_per_rec) result (time_lev) + type(time_type), intent(in) :: Time !< The time of the fluxes + integer , intent(in) :: nlev_file !< The number of time records in a forcing file + integer , intent(in) :: days_per_rec !< If positive, the number of days spanned by each + !! time record in a file, if negative the number + !! time records per day, or if 0 determine this + !! by guessing based on the number of records in + !! the file. If this is 31, the time levels will + !! be based on the months of the calendar. + !! Setting this larger than 1000000 will always + !! cause the time level to be set to 1. + integer :: time_lev !< The time level in a file that will be read. + + ! Local variables + integer :: days, seconds ! The number of days and seconds since the start of the calendar + integer :: year, month, day, hour, minute, second ! The components of the model time + integer :: recs_per_day ! The number of file time records per day + integer :: recs ! The number of time levels into the file to read without + ! taking the periodicity of the file into account. + + if ( (days_per_rec >= 1000000) .or. & + ( (days_per_rec == 0) .and. .not.((nlev_file == 12) .or. (nlev_file == 365)) ) ) then + ! The second condition above is to recreate the existing behavior, but it should perhaps be + ! phased out. + time_lev = 1 + elseif ( (days_per_rec == 31) .or. ((days_per_rec == 0) .and. (nlev_file == 12)) ) then + call get_date(Time, year, month, day, hour, minute, second) + time_lev = month + else + call get_time(Time, seconds, days) + if ( (days_per_rec == 0) .or. (abs(days_per_rec) == 1) ) then + recs = days + elseif (days_per_rec < 0) then + recs_per_day = -days_per_rec + recs = days * recs_per_day + ( (recs_per_day*set_time(seconds, 0)) / set_time(0, 1) ) + ! When integer rounding in the time-type arithmetic is considered, the line above is equivalent to: + ! seconds_per_day = set_time(0, 1) / set_time(1, 0) + ! recs = days * recs_per_day + floor(real(recs_per_day*seconds) / real(seconds_per_day)) + else + recs = days / days_per_rec + endif + time_lev = recs - nlev_file*floor(real(recs) / real(nlev_file)) + 1 + endif + +end function get_file_time_level + !> Save a restart file for the forcing fields subroutine forcing_save_restart(CS, G, Time, directory, time_stamped, & filename_suffix) @@ -1684,12 +1699,22 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C "given by LONGWAVE_FORCING_VAR.", fail_if_missing=.true.) call get_param(param_file, mdl, "LONGWAVE_FORCING_VAR", CS%LW_var, & "The variable with the longwave forcing field.", default="LW") + call get_param(param_file, mdl, "LONGWAVE_FILE_DAYS_PER_RECORD", CS%LW_days_per_rec, & + "If positive the number of days of longwave fluxes per time level in LONGWAVE_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=0) call get_param(param_file, mdl, "SHORTWAVE_FILE", CS%shortwave_file, & "The file with the shortwave heat flux, in the variable "//& "given by SHORTWAVE_FORCING_VAR.", fail_if_missing=.true.) call get_param(param_file, mdl, "SHORTWAVE_FORCING_VAR", CS%SW_var, & "The variable with the shortwave forcing field.", default="SW") + call get_param(param_file, mdl, "SHORTWAVE_FILE_DAYS_PER_RECORD", CS%SW_days_per_rec, & + "If positive the number of days of shortwave fluxes per time level in SHORTWAVE_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%LW_days_per_rec) call get_param(param_file, mdl, "EVAPORATION_FILE", CS%evaporation_file, & "The file with the evaporative moisture flux, in the "//& @@ -1697,18 +1722,33 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C call get_param(param_file, mdl, "EVAP_FORCING_VAR", CS%evap_var, & "The variable with the evaporative moisture flux.", & default="evap") + call get_param(param_file, mdl, "EVAPORATION_FILE_DAYS_PER_RECORD", CS%evap_days_per_rec, & + "If positive the number of days of evaporation per time level in EVAPORATION_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%LW_days_per_rec) call get_param(param_file, mdl, "LATENTHEAT_FILE", CS%latentheat_file, & "The file with the latent heat flux, in the variable "//& "given by LATENT_FORCING_VAR.", fail_if_missing=.true.) call get_param(param_file, mdl, "LATENT_FORCING_VAR", CS%latent_var, & "The variable with the latent heat flux.", default="latent") + call get_param(param_file, mdl, "LATENTHEAT_FILE_DAYS_PER_RECORD", CS%latent_days_per_rec, & + "If positive the number of days of latent heat fluxes per time level in LATENTHEAT_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%LW_days_per_rec) call get_param(param_file, mdl, "SENSIBLEHEAT_FILE", CS%sensibleheat_file, & "The file with the sensible heat flux, in the variable "//& "given by SENSIBLE_FORCING_VAR.", fail_if_missing=.true.) call get_param(param_file, mdl, "SENSIBLE_FORCING_VAR", CS%sens_var, & "The variable with the sensible heat flux.", default="sensible") + call get_param(param_file, mdl, "SENSIBLEHEAT_FILE_DAYS_PER_RECORD", CS%sens_days_per_rec, & + "If positive the number of days of sensible heat fluxes per time level in SENSIBLEHEAT_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%LW_days_per_rec) call get_param(param_file, mdl, "RAIN_FILE", CS%rain_file, & "The file with the liquid precipitation flux, in the "//& @@ -1716,12 +1756,22 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C call get_param(param_file, mdl, "RAIN_FORCING_VAR", CS%rain_var, & "The variable with the liquid precipitation flux.", & default="liq_precip") + call get_param(param_file, mdl, "RAIN_FILE_DAYS_PER_RECORD", CS%precip_days_per_rec, & + "If positive the number of days of rain fluxes per time level in RAIN_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%LW_days_per_rec) call get_param(param_file, mdl, "SNOW_FILE", CS%snow_file, & "The file with the frozen precipitation flux, in the "//& "variable given by SNOW_FORCING_VAR.", fail_if_missing=.true.) call get_param(param_file, mdl, "SNOW_FORCING_VAR", CS%snow_var, & "The variable with the frozen precipitation flux.", & default="froz_precip") + call get_param(param_file, mdl, "SHORTWAVE_FILE_DAYS_PER_RECORD", CS%SW_days_per_rec, & + "If positive the number of days of shortwave fluxes per time level in SHORTWAVE_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%LW_days_per_rec) call get_param(param_file, mdl, "RUNOFF_FILE", CS%runoff_file, & "The file with the fresh and frozen runoff/calving "//& @@ -1733,6 +1783,11 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C call get_param(param_file, mdl, "FROZ_RUNOFF_FORCING_VAR", CS%frunoff_var, & "The variable with the frozen runoff flux.", & default="froz_runoff") + call get_param(param_file, mdl, "RUNOFF_FILE_DAYS_PER_RECORD", CS%SW_days_per_rec, & + "If positive the number of days of runoff per time level in RUNOFF_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=0) endif call get_param(param_file, mdl, "SSTRESTORE_FILE", CS%SSTrestore_file, & @@ -1749,9 +1804,19 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C call get_param(param_file, mdl, "SST_RESTORE_VAR", CS%SST_restore_var, & "The variable with the SST toward which to restore.", & default="SST") + call get_param(param_file, mdl, "SSTRESTORE_FILE_DAYS_PER_RECORD", CS%SST_days_per_rec, & + "If positive the number of days of SST per time level in SSTRESTORE_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=0) call get_param(param_file, mdl, "SSS_RESTORE_VAR", CS%SSS_restore_var, & "The variable with the SSS toward which to restore.", & default="SSS") + call get_param(param_file, mdl, "SALINITYRESTORE_FILE_DAYS_PER_RECORD", CS%SSS_days_per_rec, & + "If positive the number of days of salinity per time level in SALINITYRESTORE_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=CS%SST_days_per_rec) endif ! Add inputdir to the file names. @@ -1804,6 +1869,11 @@ subroutine surface_forcing_init(Time, G, US, param_file, diag, CS, tracer_flow_C "or blank to get ustar from the wind stresses plus the "//& "gustiness.", default=" ") CS%wind_file = trim(CS%inputdir) // trim(CS%wind_file) + call get_param(param_file, mdl, "WIND_FILE_DAYS_PER_RECORD", CS%wind_days_per_rec, & + "If positive the number of days of wind stress per time level in WIND_FILE, "//& + "or if negative the number of time levels per day. If 31 change forcing monthly, "//& + "or if 0 the model will guess the right value based on the file size.", & + default=0) endif if (trim(CS%wind_config) == "gyres") then call get_param(param_file, mdl, "TAUX_CONST", CS%gyres_taux_const, &