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

+Rescale driver timestep variables and step_MOM args #260

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions config_src/drivers/FMS_cap/MOM_surface_forcing_gfdl.F90
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
type(time_type), intent(in) :: Time !< The time of the fluxes, used for interpolating the
!! salinity to the right time, when it is being restored.
real, intent(in) :: valid_time !< The amount of time over which these fluxes
!! should be applied [s].
!! should be applied [T ~> s].
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 !< A pointer to the control structure returned by a
Expand Down Expand Up @@ -333,7 +333,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,

! Indicate that there are new unused fluxes.
fluxes%fluxes_used = .false.
fluxes%dt_buoy_accum = US%s_to_T*valid_time
fluxes%dt_buoy_accum = valid_time

fluxes%heat_added(:,:) = 0.0
fluxes%salt_flux_added(:,:) = 0.0
Expand Down Expand Up @@ -581,7 +581,7 @@ subroutine convert_IOB_to_fluxes(IOB, fluxes, index_bounds, Time, valid_time, G,
!#CTRL# SSS_mean(i,j) = 0.5*(sfc_state%SSS(i,j) + CS%S_Restore(i,j))
!#CTRL# enddo ; enddo
!#CTRL# call apply_ctrl_forcing(SST_anom, SSS_anom, SSS_mean, fluxes%heat_added, &
!#CTRL# fluxes%vprec, day, US%s_to_T*valid_time, G, US, CS%ctrl_forcing_CSp)
!#CTRL# fluxes%vprec, day, valid_time, G, US, CS%ctrl_forcing_CSp)
!#CTRL# endif

! adjust the NET fresh-water flux to zero, if flagged
Expand Down Expand Up @@ -663,7 +663,7 @@ 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 [s], or if 0 do not average ustar.
!! average [T ~> 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.

Expand Down
45 changes: 26 additions & 19 deletions config_src/drivers/FMS_cap/ocean_model_MOM.F90
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module ocean_model_mod
use MOM_coupler_types, only : coupler_type_spawn, coupler_type_write_chksums
use MOM_coupler_types, only : coupler_type_initialized, coupler_type_copy_data
use MOM_coupler_types, only : coupler_type_set_diags, coupler_type_send_data
use MOM_diag_mediator, only : diag_ctrl, enable_averaging, disable_averaging
use MOM_diag_mediator, only : diag_ctrl, enable_averages, disable_averaging
use MOM_diag_mediator, only : diag_mediator_close_registration, diag_mediator_end
use MOM_domains, only : MOM_domain_type, domain2d, clone_MOM_domain, get_domain_extent
use MOM_domains, only : pass_var, pass_vector, AGRID, BGRID_NE, CGRID_NE, TO_ALL, Omit_Corners
Expand Down Expand Up @@ -171,8 +171,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 [s]
real :: dt_therm !< thermodynamics time step [s]
real :: dt !< (baroclinic) dynamics time step [T ~> s]
real :: dt_therm !< thermodynamics time step [T ~> 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
Expand Down Expand Up @@ -293,16 +293,17 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, wind_stagger, gas
"including both dynamics and thermodynamics. If false, "//&
"the two phases are advanced with separate calls.", default=.true.)
call get_param(param_file, mdl, "DT", OS%dt, &
"The (baroclinic) dynamics time step. The time-step that "//&
"is actually used will be an integer fraction of the "//&
"forcing time-step.", units="s", fail_if_missing=.true.)
"The (baroclinic) dynamics time step. The time-step that is actually "//&
"used will be an integer fraction of the forcing time-step.", &
units="s", scale=OS%US%s_to_T, fail_if_missing=.true.)
call get_param(param_file, mdl, "DT_THERM", OS%dt_therm, &
"The thermodynamic and tracer advection time step. "//&
"Ideally DT_THERM should be an integer multiple of DT "//&
"and less than the forcing or coupling time-step, unless "//&
"THERMO_SPANS_COUPLING is true, in which case DT_THERM "//&
"can be an integer multiple of the coupling timestep. By "//&
"default DT_THERM is set to DT.", units="s", default=OS%dt)
"default DT_THERM is set to DT.", &
units="s", scale=OS%US%s_to_T, default=OS%US%T_to_s*OS%dt)
call get_param(param_file, "MOM", "THERMO_SPANS_COUPLING", OS%thermo_spans_coupling, &
"If true, the MOM will take thermodynamic and tracer "//&
"timesteps that can be longer than the coupling timestep. "//&
Expand Down Expand Up @@ -462,11 +463,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 [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].
real :: dt_coupling ! The coupling time step [T ~> s].
real :: dt_therm ! A limited and quantized version of OS%dt_therm [T ~> s].
real :: dt_dyn ! The dynamics time step [T ~> s].
real :: dtdia ! The diabatic time step [T ~> s].
real :: t_elapsed_seg ! The elapsed time in this update segment [T ~> 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.
Expand All @@ -478,7 +479,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda
integer :: is, ie, js, je

call callTree_enter("update_ocean_model(), ocean_model_MOM.F90")
dt_coupling = time_type_to_real(Ocean_coupling_time_step)
dt_coupling = OS%US%s_to_T*time_type_to_real(Ocean_coupling_time_step)

if (.not.associated(OS)) then
call MOM_error(FATAL, "update_ocean_model called with an unassociated "// &
Expand Down Expand Up @@ -534,7 +535,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda
OS%sfc_state, dt_coupling, OS%marine_ice_CSp)

#ifdef _USE_GENERIC_TRACER
call enable_averaging(dt_coupling, OS%Time + Ocean_coupling_time_step, OS%diag) !Is this needed?
call enable_averages(dt_coupling, OS%Time + Ocean_coupling_time_step, OS%diag) !Is this needed?
call MOM_generic_tracer_fluxes_accumulate(OS%fluxes, 1.0) ! Here weight=1, so just store the current fluxes
call disable_averaging(OS%diag)
#endif
Expand All @@ -546,7 +547,7 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda
OS%grid, OS%US, OS%forcing_CSp, OS%sfc_state)

if (OS%use_ice_shelf) &
call shelf_calc_flux(OS%sfc_state, OS%flux_tmp, OS%Time, dt_coupling, OS%Ice_shelf_CSp)
call shelf_calc_flux(OS%sfc_state, OS%flux_tmp, OS%Time,dt_coupling, OS%Ice_shelf_CSp)
if (OS%icebergs_alter_ocean) &
call iceberg_fluxes(OS%grid, OS%US, OS%flux_tmp, OS%use_ice_shelf, &
OS%sfc_state, dt_coupling, OS%marine_ice_CSp)
Expand Down Expand Up @@ -582,10 +583,16 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda
call step_offline(OS%forces, OS%fluxes, OS%sfc_state, Time1, dt_coupling, OS%MOM_CSp)
elseif ((.not.do_thermo) .or. (.not.do_dyn)) then
! The call sequence is being orchestrated from outside of update_ocean_model.
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, dt_coupling, OS%MOM_CSp, &
if (present(cycle_length)) then
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, dt_coupling, OS%MOM_CSp, &
Waves=OS%Waves, do_dynamics=do_dyn, do_thermodynamics=do_thermo, &
start_cycle=start_cycle, end_cycle=end_cycle, cycle_length=cycle_length, &
start_cycle=start_cycle, end_cycle=end_cycle, cycle_length=OS%US%s_to_T*cycle_length, &
reset_therm=Ocn_fluxes_used)
else
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, dt_coupling, OS%MOM_CSp, &
Waves=OS%Waves, do_dynamics=do_dyn, do_thermodynamics=do_thermo, &
start_cycle=start_cycle, end_cycle=end_cycle, reset_therm=Ocn_fluxes_used)
endif
elseif (OS%single_step_call) then
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, dt_coupling, OS%MOM_CSp, Waves=OS%Waves)
else ! Step both the dynamics and thermodynamics with separate calls.
Expand Down Expand Up @@ -634,15 +641,15 @@ subroutine update_ocean_model(Ice_ocean_boundary, OS, Ocean_sfc, time_start_upda

if (step_thermo) then
! Back up Time1 to the start of the thermodynamic segment.
Time1 = Time1 - real_to_time(dtdia - dt_dyn)
Time1 = Time1 - real_to_time(OS%US%T_to_s*(dtdia - dt_dyn))
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, dtdia, OS%MOM_CSp, &
Waves=OS%Waves, do_dynamics=.false., do_thermodynamics=.true., &
start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_coupling)
endif
endif

t_elapsed_seg = t_elapsed_seg + dt_dyn
Time1 = Time_seg_start + real_to_time(t_elapsed_seg)
Time1 = Time_seg_start + real_to_time(OS%US%T_to_s*t_elapsed_seg)
enddo
endif

Expand Down
21 changes: 10 additions & 11 deletions config_src/drivers/ice_solo_driver/ice_shelf_driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@ program Shelf_main
use MOM_cpu_clock, only : CLOCK_COMPONENT
use MOM_debugging, only : MOM_debugging_init
use MOM_diag_mediator, only : diag_mediator_init, diag_mediator_infrastructure_init
use MOM_diag_mediator, only : enable_averaging, disable_averaging, diag_mediator_end
use MOM_diag_mediator, only : diag_ctrl, diag_mediator_close_registration
use MOM_diag_mediator, only : diag_mediator_end, diag_ctrl, diag_mediator_close_registration
use MOM_domains, only : MOM_infra_init, MOM_infra_end
use MOM_domains, only : MOM_domains_init, clone_MOM_domain, pass_var
use MOM_dyn_horgrid, only : dyn_horgrid_type, create_dyn_horgrid, destroy_dyn_horgrid
Expand Down Expand Up @@ -96,13 +95,13 @@ program Shelf_main
type(time_type) :: time_chg ! An amount of time to adjust the segment_start_time
! and elapsed time to avoid roundoff problems.

real :: elapsed_time = 0.0 ! Elapsed time in this run [s].
real :: elapsed_time = 0.0 ! Elapsed time in this run [T ~> 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_shelf is not an exact
! representation of time_step.
real :: time_step ! The time step [s]
real :: time_step ! The time step [T ~> s]

! A pointer to a structure containing metrics and related information.
type(ocean_grid_type), pointer :: ocn_grid
Expand Down Expand Up @@ -232,7 +231,7 @@ program Shelf_main
call get_param(param_file, mod_name, "ICE_VELOCITY_TIMESTEP", time_step, &
"The time step for changing forcing, coupling with other "//&
"components, or potentially writing certain diagnostics.", &
units="s", fail_if_missing=.true.)
units="s", scale=US%s_to_T, fail_if_missing=.true.)

if (sum(date) >= 0) then
! In this case, the segment starts at a time fixed by ocean_solo.res
Expand Down Expand Up @@ -282,8 +281,8 @@ program Shelf_main
segment_start_time = Time
elapsed_time = 0.0

Time_step_shelf = real_to_time(time_step)
elapsed_time_master = (abs(time_step - time_type_to_real(Time_step_shelf)) > 1.0e-12*time_step)
Time_step_shelf = real_to_time(US%T_to_s*time_step)
elapsed_time_master = (abs(time_step - US%s_to_T*time_type_to_real(Time_step_shelf)) > 1.0e-12*time_step)
if (elapsed_time_master) &
call MOM_mesg("Using real elapsed time for the master clock.", 2)

Expand Down Expand Up @@ -384,18 +383,18 @@ program Shelf_main
! Time = Time + Time_step_shelf
! This is here to enable fractional-second time steps.
elapsed_time = elapsed_time + time_step
if (elapsed_time > 2e9) then
if (elapsed_time > 2.0e9*US%s_to_T) then
! This is here to ensure that the conversion from a real to an integer can be accurately
! represented in long runs (longer than ~63 years). It will also ensure that elapsed time
! does not lose resolution of order the timetype's resolution, provided that the timestep and
! tick are larger than 10-5 seconds. If a clock with a finer resolution is used, a smaller
! value would be required.
time_chg = real_to_time(elapsed_time)
time_chg = real_to_time(US%T_to_s*elapsed_time)
segment_start_time = segment_start_time + time_chg
elapsed_time = elapsed_time - time_type_to_real(time_chg)
elapsed_time = elapsed_time - US%s_to_T*time_type_to_real(time_chg)
endif
if (elapsed_time_master) then
Master_Time = segment_start_time + real_to_time(elapsed_time)
Master_Time = segment_start_time + real_to_time(US%T_to_s*elapsed_time)
else
Master_Time = Master_Time + Time_step_shelf
endif
Expand Down
Loading