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

Fixed clock and timing #21

Merged
merged 1 commit into from
Aug 10, 2017
Merged
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
62 changes: 39 additions & 23 deletions config_src/mct_driver/ocn_comp_mct.F90
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module ocn_comp_mct
! This file is part of MOM6. See LICENSE.md for the license.

! mct modules
use ESMF, only: ESMF_clock, ESMF_time, ESMF_timeInterval
use ESMF, only: ESMF_clock, ESMF_time, ESMF_timeInterval, ESMF_TimeInc
use ESMF, only: ESMF_ClockGet, ESMF_TimeGet, ESMF_TimeIntervalGet
use seq_cdata_mod, only: seq_cdata
use seq_cdata_mod, only: seq_cdata_setptrs
Expand Down Expand Up @@ -73,9 +73,10 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )

! local variables
type(time_type) :: time_init !< Start time of coupled model's calendar
type(time_type) :: time_in !< Start time for ocean model at initialization
type(time_type) :: time_in !< Time at the beginning of the first ocn coupling interval
type(ESMF_time) :: current_time !< Current time
type(ESMF_timeInterval) :: time_interval !< Time interval
type(ESMF_time) :: time_in_ESMF !< Time after first ocean coupling interval (of type ESMF_time)
type(ESMF_timeInterval) :: ocn_cpl_interval !< Ocean coupling interval
integer :: year, month, day, hour, minute, seconds, seconds_n, seconds_d, rc
character(len=384) :: runid !< Run ID
character(len=384) :: runtype !< Run type
Expand All @@ -95,8 +96,8 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )
type(mct_gGrid) :: MOM_MCT_dom3d !< for 3d streams, local

! time management
integer :: ocn_cpl_dt
real (kind=8) :: mom_cpl_dt
integer :: ocn_cpl_dt !< one ocn coupling interval in seconds. (to be received from cesm)
real (kind=8) :: mom_cpl_dt !< one ocn coupling interval in seconds. (internal)
real (kind=8), parameter :: &
seconds_in_minute = 60.0d0, &
seconds_in_hour = 3600.0d0, &
Expand All @@ -113,7 +114,7 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )
integer :: km=1 !< Number of vertical levels
integer :: nx_block=0, ny_block=0 !< Size of block domain in x,y dir including ghost cells
integer :: max_blocks_clinic=0 !< Max. number of blocks per processor in each distribution
integer :: ncouple_per_day = 48
integer :: ncouple_per_day
logical :: lsend_precip_fact !< If T,send precip_fact to cpl for use in fw balance
!! (partially-coupled option)
character(len=128) :: err_msg !< Error message
Expand Down Expand Up @@ -145,14 +146,26 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )
inst_index = seq_comm_inst(MOM_MCT_ID)
inst_suffix = seq_comm_suffix(MOM_MCT_ID)

! Initialize MOM6
call t_startf('MOM_init')

! Initialize MOM6 comm
call MOM_infra_init(mpicom_ocn)
call ESMF_ClockGet(EClock, currTime=current_time, rc=rc)
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)

call set_calendar_type(NOLEAP) !TODO: confirm this

! Get the ESMF clock instance (assigned by CESM for MOM6)
call ESMF_ClockGet(EClock, currTime=current_time, rc=rc)

! Get the initial CESM time
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
time_init = set_date(year, month, day, hour, minute, seconds, err_msg=err_msg)

! Compute time_in: time at the beginning of the first ocn coupling interval
! (In CESM, ocean component is lagged by one ocean coupling interval, so:
! time_in = time_init + ocn_cpl_interval )
call ESMF_ClockGet(EClock, TimeStep=ocn_cpl_interval, rc=rc)
time_in_ESMF = ESMF_TimeInc(current_time, ocn_cpl_interval)
call ESMF_TimeGet(time_in_ESMF, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
time_in = set_date(year, month, day, hour, minute, seconds, err_msg=err_msg)

! Debugging clocks
Expand All @@ -167,8 +180,8 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )
call ESMF_ClockGet(EClock, PrevTime=current_time, rc=rc)
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
write(6,*) 'ocn_init_mct, previous time: y,m,d-',year,month,day,'h,m,s=',hour,minute,seconds
call ESMF_ClockGet(EClock, TimeStep=time_interval, rc=rc)
call ESMF_TimeIntervalGet(time_interval, yy=year, mm=month, d=day, s=seconds, sn=seconds_n, sd=seconds_d, rc=rc)
call ESMF_ClockGet(EClock, TimeStep=ocn_cpl_interval, rc=rc)
call ESMF_TimeIntervalGet(ocn_cpl_interval, yy=year, mm=month, d=day, s=seconds, sn=seconds_n, sd=seconds_d, rc=rc)
write(6,*) 'ocn_init_mct, time step: y,m,d-',year,month,day,'s,sn,sd=',seconds,seconds_n,seconds_d
endif

Expand Down Expand Up @@ -235,8 +248,9 @@ subroutine ocn_init_mct( EClock, cdata_o, x2o_o, o2x_o, NLFilename )
call seq_timemgr_EClockGetData(EClock, dtime=ocn_cpl_dt)

! \todo Need interface to get dt from MOM6
ncouple_per_day = seconds_in_day / ocn_cpl_dt
mom_cpl_dt = seconds_in_day / ncouple_per_day
if (mom_cpl_dt /= ocn_cpl_dt) then
if (mom_cpl_dt /= ocn_cpl_dt) then ! \todo this check is trivial for now.
write(*,*) 'ERROR pop_cpl_dt and ocn_cpl_dt must be identical'
call exit(0)
end if
Expand Down Expand Up @@ -303,21 +317,24 @@ subroutine ocn_run_mct( EClock, cdata_o, x2o_o, o2x_o)
type(mct_aVect), intent(inout) :: x2o_o !< Fluxes from coupler to ocean, computed by ocean
type(mct_aVect), intent(inout) :: o2x_o !< Fluxes from ocean to coupler, computed by ocean
! Local variables
type(ESMF_time) :: current_time
type(ESMF_timeInterval) :: time_interval
type(ESMF_time) :: current_time !< Time to be reached at the end of ocean cpl interval
type(ESMF_time) :: time_start_ESMF !< Time at the start of the coupling interval
type(ESMF_timeInterval) :: ocn_cpl_interval !< The length of one ocean coupling interval
integer :: year, month, day, hour, minute, seconds, seconds_n, seconds_d, rc
logical :: write_restart_at_eod
type(time_type) :: time_start !< Start of coupled time interval to pass to MOM6
type(time_type) :: coupling_timestep !< Coupled time interval to pass to MOM6
character(len=128) :: err_msg

! Translate the current time (start of coupling interval)
call ESMF_ClockGet(EClock, currTime=current_time, rc=rc)
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
! Compute the time at the start of this coupling interval
call ESMF_ClockGet(EClock, PrevTime=time_start_ESMF, rc=rc)
call ESMF_TimeGet(time_start_ESMF, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
time_start = set_date(year, month, day, hour, minute, seconds, err_msg=err_msg)

! Debugging clocks
if (debug .and. is_root_pe()) then
call ESMF_ClockGet(EClock, CurrTime=current_time, rc=rc)
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
write(6,*) 'ocn_run_mct, current time: y,m,d-',year,month,day,'h,m,s=',hour,minute,seconds
call ESMF_ClockGet(EClock, StartTime=current_time, rc=rc)
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
Expand All @@ -328,15 +345,14 @@ subroutine ocn_run_mct( EClock, cdata_o, x2o_o, o2x_o)
call ESMF_ClockGet(EClock, PrevTime=current_time, rc=rc)
call ESMF_TimeGet(current_time, yy=year, mm=month, dd=day, h=hour, m=minute, s=seconds, rc=rc)
write(6,*) 'ocn_run_mct, previous time: y,m,d-',year,month,day,'h,m,s=',hour,minute,seconds
call ESMF_ClockGet(EClock, TimeStep=ocn_cpl_interval, rc=rc)
call ESMF_TimeIntervalGet(ocn_cpl_interval, yy=year, mm=month, d=day, s=seconds, sn=seconds_n, sd=seconds_d, rc=rc)
write(6,*) 'ocn_init_mct, time step: y,m,d-',year,month,day,'s,sn,sd=',seconds,seconds_n,seconds_d
endif

! Translate the coupling time interval
call ESMF_ClockGet(EClock, TimeStep=time_interval, rc=rc)
call ESMF_TimeIntervalGet(time_interval, yy=year, mm=month, d=day, s=seconds, sn=seconds_n, sd=seconds_d, rc=rc)
time_start = set_date(year, month, day, 0, 0, seconds, err_msg=err_msg)
if (debug .and. is_root_pe()) then
write(6,*) 'ocn_run_mct, time step: y,m,d-',year,month,day,'s,sn,sd=',seconds,seconds_n,seconds_d
endif
call ESMF_ClockGet(EClock, TimeStep=ocn_cpl_interval, rc=rc)
call ESMF_TimeIntervalGet(ocn_cpl_interval, yy=year, mm=month, d=day, s=seconds, sn=seconds_n, sd=seconds_d, rc=rc)
coupling_timestep = set_time(seconds, days=day, err_msg=err_msg)

! set (actually, get from mct) the cdata pointers:
Expand Down