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

Flexible restart write times (restart_fh) #125

Open
wants to merge 8 commits into
base: emc/develop
Choose a base branch
from
69 changes: 63 additions & 6 deletions mediator/med_phases_restart_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module med_phases_restart_mod
use med_phases_prep_glc_mod , only : FBocnAccum2glc_o, ocnAccum2glc_cnt
use med_phases_prep_rof_mod , only : FBlndAccum2rof_l, lndAccum2rof_cnt
use pio , only : file_desc_t
use ESMF , only : ESMF_Time
implicit none
private

Expand All @@ -23,6 +24,8 @@ module med_phases_restart_mod
private :: med_phases_restart_alarm_init

logical :: write_restart_at_endofrun = .false.
logical :: write_restartfh = .false.
type(ESMF_Time), allocatable :: restartFhTimes(:)
logical :: whead(2) = (/.true. , .false./)
logical :: wdata(2) = (/.false., .true. /)

Expand All @@ -41,10 +44,14 @@ subroutine med_phases_restart_alarm_init(gcomp, rc)

use ESMF , only : ESMF_GridComp, ESMF_GridCompGet
use ESMF , only : ESMF_Clock, ESMF_ClockGet, ESMF_ClockAdvance, ESMF_ClockSet
use ESMF , only : ESMF_Time, ESMF_TimeInterval, ESMF_TimeIntervalGet
use ESMF , only : ESMF_Alarm, ESMF_AlarmSet
use ESMF , only : ESMF_Time, ESMF_TimeInterval, ESMF_TimeIntervalGet, ESMF_TimeIntervalSet
use ESMF , only : ESMF_Alarm, ESMF_AlarmSet, ESMF_TimePrint
use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_LOGMSG_ERROR
use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE
use ESMF , only : operator(==), operator(+)
use ESMF , only : ESMF_KIND_R8, ESMF_ConfigCreate, ESMF_ConfigDestroy, ESMF_ConfigLoadFile, &
ESMF_ConfigGetLen, ESMF_ConfigGetAttribute, ESMF_Config, &
ESMF_LogFoundError, ESMF_LOGERR_PASSTHRU
use NUOPC , only : NUOPC_CompAttributeGet
use NUOPC_Model , only : NUOPC_ModelGet
use med_time_mod , only : med_time_AlarmInit
Expand All @@ -56,14 +63,18 @@ subroutine med_phases_restart_alarm_init(gcomp, rc)
! local variables
type(ESMF_Alarm) :: alarm
type(ESMF_Clock) :: mclock
type(ESMF_TimeInterval) :: mtimestep
type(ESMF_TimeInterval) :: mtimestep, fhInterval
type(ESMF_Time) :: mCurrTime
integer :: timestep_length
character(CL) :: cvalue ! attribute string
character(CL) :: restart_option ! freq_option setting (ndays, nsteps, etc)
integer :: restart_n ! freq_n setting relative to freq_option
logical :: isPresent
logical :: isSet
integer :: n, nfh, fh_s
character(len=256) :: timestr
real(kind=ESMF_KIND_R8), allocatable :: restart_fh(:)
type(ESMF_Config) :: CF_mc
character(len=*), parameter :: subname='(med_phases_restart_alarm_init)'
!---------------------------------------

Expand Down Expand Up @@ -95,7 +106,7 @@ subroutine med_phases_restart_alarm_init(gcomp, rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_ClockAdvance(mclock,rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_ClockSet(mclock, currTime=mcurrtime, rc=rc)
call ESMF_ClockSet(mclock, currTime=mCurrTime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! Handle end of run restart
Expand All @@ -105,6 +116,42 @@ subroutine med_phases_restart_alarm_init(gcomp, rc)
if (trim(cvalue) .eq. '.true.') write_restart_at_endofrun = .true.
end if

! Set up times to write non-interval restarts
inquire(FILE='model_configure', EXIST=isPresent)
if (isPresent) then !model_configure exists. this is ufs run
CF_mc = ESMF_ConfigCreate(rc=rc)
call ESMF_ConfigLoadFile(config=CF_mc,filename='model_configure' ,rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return

nfh = ESMF_ConfigGetLen(config=CF_mc, label ='restart_fh:',rc=rc)
if (nfh .gt. 0) then
allocate(restart_fh(1:nfh))
allocate(restartFhTimes(1:nfh)) !not deallocated

call ESMF_ConfigGetAttribute(CF_mc,valueList=restart_fh,label='restart_fh:', rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
! create a list of times at each restart_fh
do n = 1,nfh
fh_s = NINT(3600*restart_fh(n))
call ESMF_TimeIntervalSet(fhInterval, s=fh_s, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
restartFhTimes(n) = mCurrTime + fhInterval
call ESMF_TimePrint(restartFhTimes(n), options="string", preString="restart_fh at ", unit=timestr, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (maintask) then
if (mod(fh_s, timestep_length) /= 0) then
write(logunit,'(A)')trim(subname)//trim(timestr)//' will not be written'
else
write(logunit,'(A)')trim(subname)//trim(timestr)//' will be written'
end if
end if
end do
deallocate(restart_fh)
end if !nfh>0
call ESMF_ConfigDestroy(CF_mc, rc=rc)
if (ESMF_LogFoundError(rcToCheck=rc, msg=ESMF_LOGERR_PASSTHRU, line=__LINE__, file=__FILE__)) return
end if !model_configure

! Write mediator diagnostic output
if (maintask) then
write(logunit,*)
Expand All @@ -125,7 +172,7 @@ subroutine med_phases_restart_write(gcomp, rc)
use ESMF , only : ESMF_GridComp, ESMF_VM, ESMF_Clock, ESMF_Time, ESMF_Alarm
use ESMF , only : ESMF_TimeInterval, ESMF_CalKind_Flag, ESMF_MAXSTR
use ESMF , only : ESMF_LogWrite, ESMF_LOGMSG_INFO, ESMF_SUCCESS, ESMF_FAILURE
use ESMF , only : ESMF_LOGMSG_ERROR, operator(==), operator(-)
use ESMF , only : ESMF_LOGMSG_ERROR, operator(==), operator(+), operator(-)
use ESMF , only : ESMF_GridCompGet, ESMF_ClockGet, ESMF_ClockGetNextTime
use ESMF , only : ESMF_TimeGet, ESMF_ClockGetAlarm, ESMF_ClockPrint, ESMF_TimeIntervalGet
use ESMF , only : ESMF_AlarmIsRinging, ESMF_AlarmRingerOff, ESMF_FieldBundleIsCreated
Expand Down Expand Up @@ -244,7 +291,17 @@ subroutine med_phases_restart_write(gcomp, rc)
endif
endif

if (alarmIsOn) then
if (allocated(restartFhTimes)) then
write_restartfh = .false.
! check if next time is == to any restartfhtime
do n = 1,size(restartFhTimes)
call ESMF_ClockGetNextTime(clock, nextTime=nexttime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (nextTime == restartFhTimes(n)) write_restartfh = .true.
end do
end if

if (alarmIsOn .or. write_restartfh) then
call ESMF_ClockGet(clock, currtime=currtime, starttime=starttime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_ClockGetNextTime(clock, nextTime=nexttime, rc=rc)
Expand Down