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) #139

Open
wants to merge 2 commits into
base: dev/emc
Choose a base branch
from
Open
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
86 changes: 19 additions & 67 deletions config_src/drivers/nuopc_cap/mom_cap.F90
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ module MOM_cap_mod
use NUOPC_Model, only: model_label_Finalize => label_Finalize
use NUOPC_Model, only: SetVM

#ifndef CESMCOUPLED
use shr_is_restart_fh_mod, only : init_is_restart_fh, is_restart_fh, write_restartfh
#endif

implicit none; private

public SetServices
Expand Down Expand Up @@ -155,8 +159,6 @@ module MOM_cap_mod
character(len=16) :: inst_suffix = ''
real(8) :: timere

type(ESMF_Time), allocatable :: restartFhTimes(:)

contains

!> NUOPC SetService method is the only public entry point.
Expand Down Expand Up @@ -625,7 +627,7 @@ subroutine InitializeAdvertise(gcomp, importState, exportState, clock, rc)
open(newunit=readunit, file=rpointer_filename, form='formatted', status='old', iostat=iostat)
if (iostat /= 0) then
call ESMF_LogSetError(ESMF_RC_FILE_OPEN, msg=subname//' ERROR opening '//rpointer_filename, &
line=__LINE__, file=u_FILE_u, rcToReturn=rc)
line=__LINE__, file=u_FILE_u, rcToReturn=rc)
return
endif
do
Expand Down Expand Up @@ -1644,10 +1646,8 @@ subroutine ModelAdvance(gcomp, rc)
integer :: num_rest_files
real(8) :: MPI_Wtime, timers
logical :: write_restart
logical :: write_restartfh
logical :: write_restart_eor


rc = ESMF_SUCCESS
if(profile_memory) call ESMF_VMLogMemInfo("Entering MOM Model_ADVANCE: ")
if(write_runtimelog) then
Expand Down Expand Up @@ -1797,16 +1797,6 @@ subroutine ModelAdvance(gcomp, rc)
call ESMF_ClockGetAlarm(clock, alarmname='restart_alarm', alarm=restart_alarm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

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

write_restart = .false.
if (ESMF_AlarmIsRinging(restart_alarm, rc=rc)) then
if (ChkErr(rc,__LINE__,u_FILE_u)) return
Expand All @@ -1827,7 +1817,12 @@ subroutine ModelAdvance(gcomp, rc)
end if
end if

if (write_restart .or. write_restartfh .or. write_restart_eor) then
#ifndef CESMCOUPLED
write_restartfh = is_restart_fh(clock)
if (write_restartfh) write_restart = .true.
#endif

if (write_restart .or. write_restart_eor) then
! determine restart filename
call ESMF_ClockGetNextTime(clock, MyTime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
Expand All @@ -1850,7 +1845,7 @@ subroutine ModelAdvance(gcomp, rc)
! write restart file(s)
call ocean_model_restart(ocean_state, restartname=restartname, num_rest_files=num_rest_files)
if (localPet == 0) then
! Write name of restart file in the rpointer file - this is currently hard-coded for the ocean
! Write name of restart file in the rpointer file - this is currently hard-coded for the ocean
open(newunit=writeunit, file=rpointer_filename, form='formatted', status='unknown', iostat=iostat)
if (iostat /= 0) then
call ESMF_LogSetError(ESMF_RC_FILE_OPEN, &
Expand Down Expand Up @@ -1927,34 +1922,26 @@ end subroutine ModelAdvance


subroutine ModelSetRunClock(gcomp, rc)

use ESMF, only : ESMF_TimeIntervalSet

type(ESMF_GridComp) :: gcomp
integer, intent(out) :: rc

! local variables
type(ESMF_VM) :: vm
type(ESMF_Clock) :: mclock, dclock
type(ESMF_Time) :: mcurrtime, dcurrtime
type(ESMF_Time) :: mstoptime, dstoptime
type(ESMF_TimeInterval) :: mtimestep, dtimestep
type(ESMF_TimeInterval) :: fhInterval
character(len=128) :: mtimestring, dtimestring
character(len=256) :: timestr
character(len=256) :: cvalue
character(len=256) :: restart_option ! Restart option units
integer :: restart_n ! Number until restart interval
integer :: restart_ymd ! Restart date (YYYYMMDD)
integer :: dt_cpl ! coupling timestep
integer :: dt_cpl
type(ESMF_Alarm) :: restart_alarm
type(ESMF_Alarm) :: stop_alarm
logical :: isPresent, isSet
logical :: first_time = .true.
integer :: localPet
integer :: n, nfh
integer, allocatable :: restart_fh(:)
character(len=*),parameter :: subname='(MOM_cap:ModelSetRunClock) '
character(len=*),parameter :: subname='MOM_cap:(ModelSetRunClock) '
character(len=256) :: timestr
!--------------------------------

rc = ESMF_SUCCESS
Expand All @@ -1970,11 +1957,6 @@ subroutine ModelSetRunClock(gcomp, rc)
call ESMF_ClockGet(mclock, currTime=mcurrtime, timeStep=mtimestep, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_GridCompGet(gcomp, vm=vm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_VMGet(vm, localPet=localPet, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

!--------------------------------
! check that the current time in the model and driver are the same
!--------------------------------
Expand Down Expand Up @@ -2073,6 +2055,9 @@ subroutine ModelSetRunClock(gcomp, rc)
call ESMF_LogWrite(subname//" Restarts will be written at finalize only", ESMF_LOGMSG_INFO)
endif
endif
call ESMF_TimeIntervalGet(dtimestep, s=dt_cpl, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call init_is_restart_fh(mcurrTime, dt_cpl, is_root_pe())
endif

if (restart_mode == 'alarms') then
Expand All @@ -2098,41 +2083,8 @@ subroutine ModelSetRunClock(gcomp, rc)
call ESMF_TimeGet(dstoptime, timestring=timestr, rc=rc)
call ESMF_LogWrite("Stop Alarm will ring at : "//trim(timestr), ESMF_LOGMSG_INFO)

! set up Times to write non-interval restarts
call NUOPC_CompAttributeGet(gcomp, name='restart_fh', isPresent=isPresent, isSet=isSet, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
if (isPresent .and. isSet) then

call ESMF_TimeIntervalGet(dtimestep, s=dt_cpl, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call NUOPC_CompAttributeGet(gcomp, name='restart_fh', value=cvalue, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! convert string to a list of integer restart_fh values
nfh = 1 + count(transfer(trim(cvalue), 'a', len(cvalue)) == ",")
allocate(restart_fh(1:nfh))
allocate(restartFhTimes(1:nfh))
read(cvalue,*)restart_fh(1:nfh)

! create a list of times at each restart_fh
do n = 1,nfh
call ESMF_TimeIntervalSet(fhInterval, h=restart_fh(n), 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 (localPet == 0) then
if (mod(3600*restart_fh(n),dt_cpl) /= 0) then
write(stdout,'(A)')trim(subname)//trim(timestr)//' will not be written'
else
write(stdout,'(A)')trim(subname)//trim(timestr)//' will be written'
end if
end if
end do
deallocate(restart_fh)
end if

first_time = .false.

endif

!--------------------------------
Expand Down
Loading