Skip to content

Commit

Permalink
Merge pull request #42 from gustavo-marques/merge-dev-master-2018-02-28
Browse files Browse the repository at this point in the history
Merging latest dev/master Feb 28 2018
  • Loading branch information
alperaltuntas authored Mar 2, 2018
2 parents 2f79ffc + bd80a20 commit 8095e8f
Show file tree
Hide file tree
Showing 46 changed files with 2,373 additions and 1,798 deletions.
239 changes: 162 additions & 77 deletions config_src/coupled_driver/ocean_model_MOM.F90

Large diffs are not rendered by default.

31 changes: 13 additions & 18 deletions config_src/mct_driver/ocn_comp_mct.F90
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ module ocn_comp_mct
use MOM_coms, only : reproducing_sum
use MOM_cpu_clock, only : cpu_clock_id, cpu_clock_begin, cpu_clock_end
use MOM_cpu_clock, only : CLOCK_SUBCOMPONENT
use MOM, only: initialize_MOM, step_MOM, MOM_control_struct, MOM_state_type, MOM_end
use MOM, only: calculate_surface_state, allocate_surface_state
use MOM, only: initialize_MOM, step_MOM, MOM_control_struct, MOM_end
use MOM, only: extract_surface_state, allocate_surface_state
use MOM, only: finish_MOM_initialization, step_offline
use MOM, only: get_MOM_state_elements, MOM_state_is_synchronized
use MOM_forcing_type, only: forcing, forcing_diags, register_forcing_type_diags
use MOM_forcing_type, only: allocate_forcing_type, deallocate_forcing_type
use MOM_forcing_type, only: mech_forcing_diags, forcing_accumulate, forcing_diagnostics
Expand Down Expand Up @@ -337,7 +338,6 @@ module ocn_comp_mct
type(verticalGrid_type), pointer :: GV => NULL() !< A pointer to a vertical grid
!! structure containing metrics and related information.
type(MOM_control_struct), pointer :: MOM_CSp => NULL()
type(MOM_state_type), pointer :: MSp => NULL()
type(surface_forcing_CS), pointer :: forcing_CSp => NULL()
type(MOM_restart_CS), pointer :: &
restart_CSp => NULL() !< A pointer set to the restart control structure
Expand Down Expand Up @@ -806,14 +806,13 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, i
if (.not.OS%is_ocean_pe) return

OS%Time = Time_in
call initialize_MOM(OS%Time, Time_init, param_file, OS%dirs, OS%MSp, OS%MOM_CSp, &
call initialize_MOM(OS%Time, Time_init, param_file, OS%dirs, OS%MOM_CSp, &
OS%restart_CSp, Time_in, offline_tracer_mode=OS%offline_tracer_mode, &
input_restart_file=input_restart_file, diag_ptr=OS%diag, &
count_calls=.true.)
OS%grid => OS%MSp%G ; OS%GV => OS%MSp%GV
OS%C_p = OS%MSp%tv%C_p
OS%fluxes%C_p = OS%MSp%tv%C_p
use_temperature = ASSOCIATED(OS%MSp%tv%T)
call get_MOM_state_elements(OS%MOM_CSp, G=OS%grid, GV=OS%GV, C_p=OS%fluxes%C_p, &
use_temp=use_temperature)
OS%C_p = OS%fluxes%C_p

! Read all relevant parameters and write them to the model log.
call log_version(param_file, mdl, version, "")
Expand Down Expand Up @@ -903,9 +902,7 @@ subroutine ocean_model_init(Ocean_sfc, OS, Time_init, Time_in, gas_fields_ocn, i
! This call can only occur here if the coupler_bc_type variables have been
! initialized already using the information from gas_fields_ocn.
if (present(gas_fields_ocn)) then
call calculate_surface_state(OS%sfc_state, OS%MSp%u, &
OS%MSp%v, OS%MSp%h, OS%MSp%ave_ssh,&
OS%grid, OS%GV, OS%MSp, OS%MOM_CSp)
call extract_surface_state(OS%MOM_CSp, OS%sfc_state)

call convert_state_to_ocean_type(OS%sfc_state, Ocean_sfc, OS%grid)
endif
Expand Down Expand Up @@ -933,9 +930,7 @@ subroutine ocean_model_init_sfc(OS, Ocean_sfc)
call coupler_type_spawn(Ocean_sfc%fields, OS%sfc_state%tr_fields, &
(/is,is,ie,ie/), (/js,js,je,je/), as_needed=.true.)

call calculate_surface_state(OS%sfc_state, OS%MSp%u, &
OS%MSp%v, OS%MSp%h, OS%MSp%ave_ssh,&
OS%grid, OS%GV, OS%Msp, OS%MOM_CSp)
call extract_surface_state(OS%MOM_CSp, OS%sfc_state)

call convert_state_to_ocean_type(OS%sfc_state, Ocean_sfc, OS%grid)

Expand Down Expand Up @@ -1774,17 +1769,17 @@ subroutine update_ocean_model(OS, Ocean_sfc, time_start_update, &
call set_net_mass_forcing(OS%fluxes, OS%forces, OS%grid)

if (OS%nstep==0) then
call finish_MOM_initialization(OS%Time, OS%dirs, OS%MSp, OS%MOM_CSp, OS%fluxes, &
call finish_MOM_initialization(OS%Time, OS%dirs, OS%MOM_CSp, OS%fluxes, &
OS%restart_CSp)
endif

call disable_averaging(OS%diag)
Master_time = OS%Time ; Time1 = OS%Time

if(OS%offline_tracer_mode) then
call step_offline(OS%forces, OS%fluxes, OS%sfc_state, Time1, time_step, OS%MSp, OS%MOM_CSp)
call step_offline(OS%forces, OS%fluxes, OS%sfc_state, Time1, time_step, OS%MOM_CSp)
else
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, time_step, OS%MSp, OS%MOM_CSp)
call step_MOM(OS%forces, OS%fluxes, OS%sfc_state, Time1, time_step, OS%MOM_CSp)
endif

OS%Time = Master_time + Ocean_coupling_time_step
Expand Down Expand Up @@ -2443,7 +2438,7 @@ subroutine ocean_model_end(Ocean_sfc, Ocean_state, Time)
call diag_mediator_end(Time, Ocean_state%diag, end_diag_manager=.true.)
! print time stats
call MOM_infra_end
call MOM_end(Ocean_state%MSp, Ocean_state%MOM_CSp)
call MOM_end(Ocean_state%MOM_CSp)
if (Ocean_state%use_ice_shelf) call ice_shelf_end(Ocean_state%Ice_shelf_CSp)

end subroutine ocean_model_end
Expand Down
137 changes: 99 additions & 38 deletions config_src/solo_driver/MOM_driver.F90
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,9 @@ program MOM_main
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, only : initialize_MOM, step_MOM, MOM_control_struct, MOM_end
use MOM, only : calculate_surface_state, finish_MOM_initialization
use MOM, only : MOM_state_type, step_offline
use MOM, only : extract_surface_state, finish_MOM_initialization
use MOM, only : get_MOM_state_elements, MOM_state_is_synchronized
use MOM, only : step_offline
use MOM_domains, only : MOM_infra_init, MOM_infra_end
use MOM_error_handler, only : MOM_error, MOM_mesg, WARNING, FATAL, is_root_pe
use MOM_error_handler, only : callTree_enter, callTree_leave, callTree_waypoint
Expand Down Expand Up @@ -113,18 +114,23 @@ program MOM_main
type(time_type) :: segment_start_time ! The start time of this run segment.
type(time_type) :: Time_end ! End time for the segment or experiment.
type(time_type) :: restart_time ! The next time to write restart files.
type(time_type) :: Time_step_ocean ! A time_type version of time_step.
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.
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 time_step.
real :: time_step ! The time step of a call to step_MOM in seconds.
! 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
integer :: ntstep ! The number of baroclinic dynamics time steps
! within time_step.
! within dt_forcing.
real :: dt_therm
real :: dt_dyn, dtdia, t_elapsed_seg
integer :: n, n_max, nts, n_last_thermo
logical :: diabatic_first, single_step_call
type(time_type) :: Time2

integer :: Restart_control ! An integer that is bit-tested to determine whether
! incremental restart files are saved and whether they
Expand All @@ -142,7 +148,7 @@ program MOM_main
integer :: date(6)=-1 ! Possibly the start date of this run segment.
integer :: years=0, months=0, days=0 ! These may determine the segment run
integer :: hours=0, minutes=0, seconds=0 ! length, if read from a namelist.
integer :: yr, mon, day, hr, min, sec ! Temp variables for writing the date.
integer :: yr, mon, day, hr, mins, sec ! Temp variables for writing the date.
type(param_file_type) :: param_file ! The structure indicating the file(s)
! containing all run-time parameters.
character(len=9) :: month
Expand All @@ -167,7 +173,6 @@ program MOM_main
! a previous integration of the prognostic model

type(MOM_control_struct), pointer :: MOM_CSp => NULL()
type(MOM_state_type), pointer :: MSp => NULL()
!> A pointer to the tracer flow control structure.
type(tracer_flow_control_CS), pointer :: &
tracer_flow_CSp => NULL() !< A pointer to the tracer flow control structure
Expand Down Expand Up @@ -284,26 +289,24 @@ program MOM_main
! In this case, the segment starts at a time fixed by ocean_solo.res
segment_start_time = set_date(date(1),date(2),date(3),date(4),date(5),date(6))
Time = segment_start_time
call initialize_MOM(Time, Start_time, param_file, dirs, MSp, MOM_CSp, restart_CSp, &
call initialize_MOM(Time, Start_time, param_file, dirs, MOM_CSp, restart_CSp, &
segment_start_time, offline_tracer_mode=offline_tracer_mode, &
diag_ptr=diag, tracer_flow_CSp=tracer_flow_CSp)
else
! In this case, the segment starts at a time read from the MOM restart file
! or left as Start_time by MOM_initialize.
Time = Start_time
call initialize_MOM(Time, Start_time, param_file, dirs, MSp, MOM_CSp, restart_CSp, &
call initialize_MOM(Time, Start_time, param_file, dirs, MOM_CSp, restart_CSp, &
offline_tracer_mode=offline_tracer_mode, diag_ptr=diag, &
tracer_flow_CSp=tracer_flow_CSp)
endif
fluxes%C_p = MSp%tv%C_p ! Copy the heat capacity for consistency.

call get_MOM_state_elements(MOM_CSp, G=grid, GV=GV, C_p=fluxes%C_p)
Master_Time = Time
grid => MSp%G
GV => MSp%GV

call callTree_waypoint("done initialize_MOM")

call calculate_surface_state(sfc_state, MSp%u, MSp%v, MSp%h, &
MSp%ave_ssh, grid, GV, MSp, MOM_CSp)
call extract_surface_state(MOM_CSp, sfc_state)

call surface_forcing_init(Time, grid, param_file, diag, &
surface_forcing_CSp, tracer_flow_CSp)
Expand All @@ -324,19 +327,19 @@ program MOM_main
! Read all relevant parameters and write them to the model log.
call log_version(param_file, mod_name, version, "")
call get_param(param_file, mod_name, "DT", dt, fail_if_missing=.true.)
call get_param(param_file, mod_name, "DT_FORCING", time_step, &
call get_param(param_file, mod_name, "DT_FORCING", dt_forcing, &
"The time step for changing forcing, coupling with other \n"//&
"components, or potentially writing certain diagnostics. \n"//&
"The default value is given by DT.", units="s", default=dt)
if (offline_tracer_mode) then
call get_param(param_file, mod_name, "DT_OFFLINE", time_step, &
call get_param(param_file, mod_name, "DT_OFFLINE", dt_forcing, &
"Time step for the offline time step")
dt = time_step
dt = dt_forcing
endif
ntstep = MAX(1,ceiling(time_step/dt - 0.001))
ntstep = MAX(1,ceiling(dt_forcing/dt - 0.001))

Time_step_ocean = set_time(int(floor(time_step+0.5)))
elapsed_time_master = (abs(time_step - time_type_to_real(Time_step_ocean)) > 1.0e-12*time_step)
Time_step_ocean = set_time(int(floor(dt_forcing+0.5)))
elapsed_time_master = (abs(dt_forcing - time_type_to_real(Time_step_ocean)) > 1.0e-12*dt_forcing)
if (elapsed_time_master) &
call MOM_mesg("Using real elapsed time for the master clock.", 2)

Expand Down Expand Up @@ -365,6 +368,23 @@ program MOM_main
Time_end = daymax
endif

call get_param(param_file, mod_name, "SINGLE_STEPPING_CALL", single_step_call, &
"If true, advance the state of MOM with a single step \n"//&
"including both dynamics and thermodynamics. If false \n"//&
"the two phases are advanced with separate calls.", default=.true.)
call get_param(param_file, mod_name, "DT_THERM", dt_therm, &
"The thermodynamic and tracer advection time step. \n"//&
"Ideally DT_THERM should be an integer multiple of DT \n"//&
"and less than the forcing or coupling time-step, unless \n"//&
"THERMO_SPANS_COUPLING is true, in which case DT_THERM \n"//&
"can be an integer multiple of the coupling timestep. By \n"//&
"default DT_THERM is set to DT.", units="s", default=dt)
call get_param(param_file, mod_name, "DIABATIC_FIRST", diabatic_first, &
"If true, apply diabatic and thermodynamic processes, \n"//&
"including buoyancy forcing and mass gain or loss, \n"//&
"before stepping the dynamics forward.", default=.false.)


if (Time >= Time_end) call MOM_error(FATAL, &
"MOM_driver: The run has been started at or after the end time of the run.")

Expand Down Expand Up @@ -444,29 +464,69 @@ program MOM_main
endif

if (use_ice_shelf) then
call shelf_calc_flux(sfc_state, forces, fluxes, Time, time_step, ice_shelf_CSp)
call shelf_calc_flux(sfc_state, forces, fluxes, Time, dt_forcing, ice_shelf_CSp)
!###IS call add_shelf_flux_forcing(fluxes, ice_shelf_CSp)
!###IS ! With a coupled ice/ocean run, use the following call.
!###IS call add_shelf_flux_IOB(ice_ocean_bdry_type, ice_shelf_CSp)
endif
fluxes%fluxes_used = .false.
fluxes%dt_buoy_accum = time_step
fluxes%dt_buoy_accum = dt_forcing

if (ns==1) then
call finish_MOM_initialization(Time, dirs, MSp, MOM_CSp, fluxes, restart_CSp)
call finish_MOM_initialization(Time, dirs, MOM_CSp, fluxes, restart_CSp)
endif

! This call steps the model over a time time_step.
! This call steps the model over a time dt_forcing.
Time1 = Master_Time ; Time = Master_Time
if (offline_tracer_mode) then
call step_offline(forces, fluxes, sfc_state, Time1, time_step, MSp, MOM_CSp)
call step_offline(forces, fluxes, sfc_state, Time1, dt_forcing, MOM_CSp)
elseif (single_step_call) then
call step_MOM(forces, fluxes, sfc_state, Time1, dt_forcing, MOM_CSp)
else
call step_MOM(forces, fluxes, sfc_state, Time1, time_step, MSp, MOM_CSp)
n_max = 1 ; if (dt_forcing > dt) n_max = ceiling(dt_forcing/dt - 0.001)
dt_dyn = dt_forcing / real(n_max)

nts = MAX(1,MIN(n_max,floor(dt_therm/dt_dyn + 0.001)))
n_last_thermo = 0

Time2 = Time1 ; t_elapsed_seg = 0.0
do n=1,n_max
if (diabatic_first) then
if (modulo(n-1,nts)==0) then
dtdia = dt_dyn*min(ntstep,n_max-(n-1))
call step_MOM(forces, fluxes, sfc_state, Time2, dtdia, MOM_CSp, &
do_dynamics=.false., do_thermodynamics=.true., &
start_cycle=(n==1), end_cycle=.false., cycle_length=dt_forcing)
endif

call step_MOM(forces, fluxes, sfc_state, Time2, dt_dyn, MOM_CSp, &
do_dynamics=.true., do_thermodynamics=.false., &
start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_forcing)
else
call step_MOM(forces, fluxes, sfc_state, Time2, dt_dyn, MOM_CSp, &
do_dynamics=.true., do_thermodynamics=.false., &
start_cycle=(n==1), end_cycle=.false., cycle_length=dt_forcing)

if ((modulo(n,nts)==0) .or. (n==n_max)) then
dtdia = dt_dyn*(n - n_last_thermo)
! Back up Time2 to the start of the thermodynamic segment.
if (n > n_last_thermo+1) &
Time2 = Time2 - set_time(int(floor((dtdia - dt_dyn) + 0.5)))
call step_MOM(forces, fluxes, sfc_state, Time2, dtdia, MOM_CSp, &
do_dynamics=.false., do_thermodynamics=.true., &
start_cycle=.false., end_cycle=(n==n_max), cycle_length=dt_forcing)
n_last_thermo = n
endif
endif

t_elapsed_seg = t_elapsed_seg + dt_dyn
Time2 = Time1 + set_time(int(floor(t_elapsed_seg + 0.5)))
enddo
endif

! Time = Time + Time_step_ocean
! This is here to enable fractional-second time steps.
elapsed_time = elapsed_time + time_step
elapsed_time = elapsed_time + dt_forcing
if (elapsed_time > 2e9) 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).
Expand All @@ -488,8 +548,8 @@ program MOM_main
call write_cputime(Time, ns+ntstep-1, nmax, write_CPU_CSp)
endif ; endif

call enable_averaging(time_step, Time, diag)
call mech_forcing_diags(forces, fluxes, time_step, grid, diag, &
call enable_averaging(dt_forcing, Time, diag)
call mech_forcing_diags(forces, fluxes, dt_forcing, grid, diag, &
surface_forcing_CSp%handles)
call disable_averaging(diag)

Expand Down Expand Up @@ -534,10 +594,11 @@ program MOM_main
call cpu_clock_end(mainClock)
call cpu_clock_begin(termClock)
if (Restart_control>=0) then
if (MSp%t_dyn_rel_adv > 0.0) call MOM_error(WARNING, "End of MOM_main reached "//&
"with inconsistent dynamics and advective times. Additional restart fields "//&
if (.not.MOM_state_is_synchronized(MOM_CSp)) &
call MOM_error(WARNING, "End of MOM_main reached with inconsistent "//&
"dynamics and advective times. Additional restart fields "//&
"that have not been coded yet would be required for reproducibility.")
if (.not.fluxes%fluxes_used .and. .not.offline_tracer_mode) call MOM_error(FATAL, &
if (.not.fluxes%fluxes_used .and. .not.offline_tracer_mode) call MOM_error(FATAL, &
"End of MOM_main reached with unused buoyancy fluxes. "//&
"For conservation, the ocean restart files can only be "//&
"created after the buoyancy forcing is applied.")
Expand All @@ -551,11 +612,11 @@ program MOM_main
write(unit, '(i6,8x,a)') calendar_type, &
'(Calendar: no_calendar=0, thirty_day_months=1, julian=2, gregorian=3, noleap=4)'

call get_date(Start_time, yr, mon, day, hr, min, sec)
write(unit, '(6i6,8x,a)') yr, mon, day, hr, min, sec, &
call get_date(Start_time, yr, mon, day, hr, mins, sec)
write(unit, '(6i6,8x,a)') yr, mon, day, hr, mins, sec, &
'Model start time: year, month, day, hour, minute, second'
call get_date(Time, yr, mon, day, hr, min, sec)
write(unit, '(6i6,8x,a)') yr, mon, day, hr, min, sec, &
call get_date(Time, yr, mon, day, hr, mins, sec)
write(unit, '(6i6,8x,a)') yr, mon, day, hr, mins, sec, &
'Current model time: year, month, day, hour, minute, second'
end if
call close_file(unit)
Expand All @@ -581,7 +642,7 @@ program MOM_main

call io_infra_end ; call MOM_infra_end

call MOM_end(MSp, MOM_CSp)
call MOM_end(MOM_CSp)
if (use_ice_shelf) call ice_shelf_end(ice_shelf_CSp)

end program MOM_main
Loading

0 comments on commit 8095e8f

Please sign in to comment.