📄 time_manager.f90
字号:
start_date = esmf_dateinit(rst_type, rst_start_ymd, rst_start_tod, rc) call chkrc(rc, sub//': error return from esmf_dateinit: setting start_date')! Initialize current date. curr_date = esmf_dateinit(rst_type, rst_curr_ymd, rst_curr_tod, rc) call chkrc(rc, sub//': error return from esmf_dateinit: setting curr_date')! Initialize stop date. if ( stop_ymd /= uninit_int ) then stop_date = esmf_dateinit(rst_type, stop_ymd, stop_tod, rc) else if ( nestep /= uninit_int ) then if ( nestep >= 0 ) then stop_date = esmf_dateincrementsec(start_date, dtime*nestep, rc) else stop_date = esmf_dateincrementday(start_date, -nestep, rc) end if else if ( nelapse /= uninit_int ) then if ( nelapse >= 0 ) then stop_date = esmf_dateincrementsec(curr_date, dtime*nelapse, rc) else stop_date = esmf_dateincrementday(curr_date, -nelapse, rc) end if else stop_date = esmf_dateinit(rst_type, rst_stop_ymd, rst_stop_tod, rc) end if call chkrc(rc, sub//': error return setting stop_date')! Check that stop date is later than current date. call esmf_dateislater(curr_date, stop_date, islater, rc) call chkrc(rc, sub//': error return from esmf_dateislater: comparing start and stop dates') if ( .not. islater ) then write(6,*)sub,': stop date must be specified later than current date: ' call esmf_dateget(curr_date, ymd, tod) write(6,*)' Current date (ymd tod): ', ymd, tod call esmf_dateget(stop_date, ymd, tod) write(6,*)' Stop date (ymd tod): ', ymd, tod call endrun end if call esmf_dateget(stop_date, rst_stop_ymd, rst_stop_tod)! Restart a time manager. tm_id = esmf_timemgrrestartread(rst_type, rst_nstep, rst_step_days, rst_step_sec, rst_start_ymd, & rst_start_tod, rst_stop_ymd, rst_stop_tod, rst_ref_ymd, rst_ref_tod, & rst_curr_ymd, rst_curr_tod, rc) call chkrc(rc, sub//': error return from esmf_timemgrrestartread')! Advance the timestep. Data from the restart file corresponds to the! last timestep of the previous run. call advance_timestep()! Set flag that this is the first timestep of the restart run. tm_first_restart_step = .true.! Initialize date used for perpetual calendar day calculation. if ( rst_perp_cal ) then tm_perp_date = esmf_dateinit(rst_type, rst_perp_ymd, 0, rc) call chkrc(rc, sub//': error return from esmf_dateinit: setting tm_perp_date') tm_perp_calendar = .true. end if! Set variables from "comtim.h interface" for backwards compatibility.! Calculation of ending timestep number (nestep) assumes a constant stepsize. ntspday = 86400/dtime diff = esmf_timeinit() call esmf_datediff(start_date, stop_date, diff, islater, rc) call chkrc(rc, sub//': error return from esmf_datediff calculating nestep') call esmf_timeget(diff, ndays, nsecs, rc) call chkrc(rc, sub//': error return from esmf_timeget calculating nestep') nestep = ntspday*ndays + nsecs/dtime if ( mod(nsecs,dtime) /= 0 ) nestep = nestep + 1! Print configuration summary to log file (stdout). if (masterproc) then call timemgr_print() end ifend subroutine timemgr_restart!=========================================================================================subroutine timemgr_print() implicit none! Local variables character(len=*), parameter :: sub = 'timemgr_print' integer :: rc integer :: day, sec, ymd, tod character(len=32) :: cal ! Calendar to use in date calculations. integer ::& ! Data required to restart time manager: type = uninit_int, &! calendar type nstep = uninit_int, &! current step number step_days = uninit_int, &! days component of timestep size step_sec = uninit_int, &! seconds component of timestep size start_ymd = uninit_int, &! start date start_tod = uninit_int, &! start time of day stop_ymd = uninit_int, &! stop date stop_tod = uninit_int, &! stop time of day ref_ymd = uninit_int, &! reference date ref_tod = uninit_int, &! reference time of day curr_ymd = uninit_int, &! current date curr_tod = uninit_int ! current time of day!----------------------------------------------------------------------------------------- call esmf_timemgrrestartwrite(tm_id, type, nstep, step_days, step_sec, & start_ymd, start_tod, stop_ymd, stop_tod, ref_ymd, & ref_tod, curr_ymd, curr_tod, rc) call chkrc(rc, sub//': error return from esmf_timemgrrestartwrite') write(6,*)' ********** Time Manager Configuration **********' if ( type == esmf_no_leap ) then cal = 'NO_LEAP' else if ( type == esmf_gregorian ) then cal = 'GREGORIAN' end if write(6,*)' Calendar type: ',trim(cal) write(6,*)' Timestep size (seconds): ', (step_days*86400 + step_sec) write(6,*)' Start date (ymd tod): ', start_ymd, start_tod write(6,*)' Stop date (ymd tod): ', stop_ymd, stop_tod write(6,*)' Reference date (ymd tod): ', ref_ymd, ref_tod write(6,*)' Current step number: ', nstep write(6,*)' Ending step number: ', nestep write(6,*)' Current date (ymd tod): ', curr_ymd, curr_tod if ( tm_perp_calendar ) then call esmf_dateget(tm_perp_date, ymd, tod) write(6,*)' Use perpetual diurnal cycle date (ymd): ', ymd end if write(6,*)' ************************************************'end subroutine timemgr_print!=========================================================================================subroutine advance_timestep()! Increment the timestep number. implicit none ! Local variables character(len=*), parameter :: sub = 'advance_timestep' integer :: rc!----------------------------------------------------------------------------------------- call esmf_timemgradvance(tm_id, rc) call chkrc(rc, sub//': error return from esmf_timemgradvance')! Set first step flag off. tm_first_restart_step = .false.end subroutine advance_timestep!=========================================================================================function get_step_size()! Return the step size in seconds. implicit none ! Return value integer :: get_step_size! Local variables character(len=*), parameter :: sub = 'get_step_size' integer :: days, seconds integer :: rc!----------------------------------------------------------------------------------------- call esmf_timemgrgetstepsize(tm_id, days, seconds, rc) call chkrc(rc, sub//': error return from esmf_timemgrgetstepsize') get_step_size = 86400*days + secondsend function get_step_size!=========================================================================================function get_nstep()! Return the timestep number. implicit none ! Return value integer :: get_nstep! Local variables character(len=*), parameter :: sub = 'get_nstep' integer :: rc!----------------------------------------------------------------------------------------- get_nstep = esmf_timemgrgetnstep(tm_id, rc) call chkrc(rc, sub//': error return from esmf_timemgrgetnstep')end function get_nstep!=========================================================================================subroutine get_curr_date(yr, mon, day, tod, offset)! Return date components valid at end of current timestep with an optional! offset (positive or negative) in seconds. implicit none ! Arguments integer, intent(out) ::& yr, &! year mon, &! month day, &! day of month tod ! time of day (seconds past 0Z) integer, optional, intent(in) :: offset ! Offset from current time in seconds. ! Positive for future times, negative ! for previous times.! Local variables character(len=*), parameter :: sub = 'get_curr_date' integer :: rc type(esmf_date) :: date type(esmf_time) :: off integer :: ymd!----------------------------------------------------------------------------------------- date = esmf_timemgrgetcurrdate(tm_id, rc) call chkrc(rc, sub//': error return from esmf_timemgrgetcurrdate') if (present(offset)) then if (offset > 0) then date = esmf_dateincrementsec(date, offset, rc) call chkrc(rc, sub//': error incrementing current date') else if (offset < 0) then off = esmf_timeinit(0, -offset, rc) call chkrc(rc, sub//': error setting offset time type') date = esmf_datedecrement(date, off, rc) call chkrc(rc, sub//': error decrementing current date') end if end if call esmf_dateget(date, ymd, tod, rc) call chkrc(rc, sub//': error return from esmf_dateget') yr = ymd/10000 mon = mod(ymd, 10000) / 100 day = mod(ymd, 100)end subroutine get_curr_date!=========================================================================================subroutine get_perp_date(yr, mon, day, tod)! Return time of day valid at end of current timestep and the components! of the perpetual date. implicit none ! Arguments integer, intent(out) ::& yr, &! year mon, &! month day, &! day of month tod ! time of day (seconds past 0Z)! Local variables character(len=*), parameter :: sub = 'get_perp_date' integer :: rc type(esmf_date) :: date integer :: ymd, idum!----------------------------------------------------------------------------------------- date = esmf_timemgrgetcurrdate(tm_id, rc) call chkrc(rc, sub//': error return from esmf_timemgrgetcurrdate') call esmf_dateget(date, idum, tod, rc) call chkrc(rc, sub//': error return from esmf_dateget') call esmf_dateget(tm_perp_date, ymd, idum, rc) call chkrc(rc, sub//': error return from esmf_dateget') yr = ymd/10000 mon = mod(ymd, 10000) / 100 day = mod(ymd, 100)end subroutine get_perp_date!=========================================================================================subroutine get_prev_date(yr, mon, day, tod)! Return date components valid at beginning of current timestep. implicit none ! Arguments integer, intent(out) ::& yr, &! year mon, &! month day, &! day of month tod ! time of day (seconds past 0Z)! Local variables character(len=*), parameter :: sub = 'get_prev_date' integer :: rc type(esmf_date) :: date integer :: ymd!----------------------------------------------------------------------------------------- date = esmf_timemgrgetprevdate(tm_id, rc) call chkrc(rc, sub//': error return from esmf_timemgrgetprevdate') call esmf_dateget(date, ymd, tod, rc) call chkrc(rc, sub//': error return from esmf_dateget') yr = ymd/10000 mon = mod(ymd, 10000) / 100 day = mod(ymd, 100)end subroutine get_prev_date!=========================================================================================subroutine get_start_date(yr, mon, day, tod)! Return date components valid at beginning of initial run. implicit none ! Arguments integer, intent(out) ::& yr, &! year mon, &! month
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -