Skip to content

Commit

Permalink
move all alarminit to nuopc_shr_methods in share code
Browse files Browse the repository at this point in the history
  • Loading branch information
jedwards4b committed Apr 4, 2024
1 parent 44cb901 commit bcaac2a
Show file tree
Hide file tree
Showing 10 changed files with 26 additions and 636 deletions.
266 changes: 3 additions & 263 deletions cesm/driver/esm_time_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,15 @@ module esm_time_mod
use ESMF , only : operator(<=), operator(>), operator(==)
use NUOPC , only : NUOPC_CompAttributeGet
use esm_utils_mod , only : chkerr
use nuopc_shr_methods , only : AlarmInit

implicit none
private ! default private

public :: esm_time_clockInit ! initialize driver clock (assumes default calendar)

! private :: esm_time_timeInit
private :: esm_time_alarmInit
! private :: esm_time_alarmInit
private :: esm_time_date2ymd

! Clock and alarm options
Expand Down Expand Up @@ -296,7 +297,7 @@ subroutine esm_time_clockInit(ensemble_driver, instance_driver, logunit, maintas
write(logunit,*) trim(subname)//': driver stop_tod: '// trim(tmpstr)
endif

call esm_time_alarmInit(clock, &
call alarmInit(clock, &
alarm = alarm_stop, &
option = stop_option, &
opt_n = stop_n, &
Expand Down Expand Up @@ -329,267 +330,6 @@ end subroutine esm_time_clockInit

!===============================================================================

subroutine esm_time_alarmInit( clock, alarm, option, &
opt_n, opt_ymd, opt_tod, RefTime, alarmname, rc)

! Setup an alarm in a clock
! Notes: The ringtime sent to AlarmCreate MUST be the next alarm
! time. If you send an arbitrary but proper ringtime from the
! past and the ring interval, the alarm will always go off on the
! next clock advance and this will cause serious problems. Even
! if it makes sense to initialize an alarm with some reference
! time and the alarm interval, that reference time has to be
! advance forward to be >= the current time. In the logic below
! we set an appropriate "NextAlarm" and then we make sure to
! advance it properly based on the ring interval.

! input/output variables
type(ESMF_Clock) , intent(inout) :: clock ! clock
type(ESMF_Alarm) , intent(inout) :: alarm ! alarm
character(len=*) , intent(in) :: option ! alarm option
integer , optional , intent(in) :: opt_n ! alarm freq
integer , optional , intent(in) :: opt_ymd ! alarm ymd
integer , optional , intent(in) :: opt_tod ! alarm tod (sec)
type(ESMF_Time) , optional , intent(in) :: RefTime ! ref time
character(len=*) , optional , intent(in) :: alarmname ! alarm name
integer , intent(inout) :: rc ! Return code

! local variables
type(ESMF_Calendar) :: cal ! calendar
integer :: lymd ! local ymd
integer :: ltod ! local tod
integer :: cyy,cmm,cdd,csec ! time info
character(len=64) :: lalarmname ! local alarm name
logical :: update_nextalarm ! update next alarm
type(ESMF_Time) :: CurrTime ! Current Time
type(ESMF_Time) :: NextAlarm ! Next restart alarm time
type(ESMF_TimeInterval) :: AlarmInterval ! Alarm interval
character(len=*), parameter :: subname = '(med_time_alarmInit): '
!-------------------------------------------------------------------------------

rc = ESMF_SUCCESS

lalarmname = 'alarm_unknown'
if (present(alarmname)) lalarmname = trim(alarmname)
ltod = 0
if (present(opt_tod)) ltod = opt_tod
lymd = -1
if (present(opt_ymd)) lymd = opt_ymd

call ESMF_ClockGet(clock, CurrTime=CurrTime, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

call ESMF_TimeGet(CurrTime, yy=cyy, mm=cmm, dd=cdd, s=csec, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! initial guess of next alarm, this will be updated below
if (present(RefTime)) then
NextAlarm = RefTime
else
NextAlarm = CurrTime
endif

! Get calendar from clock
call ESMF_ClockGet(clock, calendar=cal, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

! Error checks
if (trim(option) == optdate) then
if (.not. present(opt_ymd)) then
call ESMF_LogWrite(trim(subname)//trim(option)//' requires opt_ymd', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
if (lymd < 0 .or. ltod < 0) then
call ESMF_LogWrite(subname//trim(option)//'opt_ymd, opt_tod invalid', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
else if (&
trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s' .or. &
trim(option) == optNSeconds .or. trim(option) == trim(optNSeconds)//'s' .or. &
trim(option) == optNMinutes .or. trim(option) == trim(optNMinutes)//'s' .or. &
trim(option) == optNHours .or. trim(option) == trim(optNHours)//'s' .or. &
trim(option) == optNDays .or. trim(option) == trim(optNDays)//'s' .or. &
trim(option) == optNMonths .or. trim(option) == trim(optNMonths)//'s' .or. &
trim(option) == optNYears .or. trim(option) == trim(optNYears)//'s' ) then
if (.not.present(opt_n)) then
call ESMF_LogWrite(subname//trim(option)//' requires opt_n', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
if (opt_n <= 0) then
call ESMF_LogWrite(subname//trim(option)//' invalid opt_n', ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if
end if

! Determine inputs for call to create alarm
selectcase (trim(option))

case (optNONE)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optDate)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call esm_time_date2ymd(opt_ymd, cyy, cmm, cdd)

call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=cdd, s=ltod, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optNever)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=9999, mm=12, dd=1, s=0, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case (optNSteps,trim(optNSteps)//'s')
call ESMF_ClockGet(clock, TimeStep=AlarmInterval, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNSeconds,trim(optNSeconds)//'s')
call ESMF_TimeIntervalSet(AlarmInterval, s=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNMinutes,trim(optNMinutes)//'s')
call ESMF_TimeIntervalSet(AlarmInterval, s=60, rc=rc)
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNHours,trim(optNHours)//'s')
call ESMF_TimeIntervalSet(AlarmInterval, s=3600, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNDays,trim(optNDays)//'s')
call ESMF_TimeIntervalSet(AlarmInterval, d=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optNMonths,trim(optNMonths)//'s')
call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optMonthly)
call ESMF_TimeIntervalSet(AlarmInterval, mm=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=cyy, mm=cmm, dd=1, s=0, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .true.

case (optNYears, trim(optNYears)//'s')
call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
AlarmInterval = AlarmInterval * opt_n
update_nextalarm = .true.

case (optYearly)
call ESMF_TimeIntervalSet(AlarmInterval, yy=1, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_TimeSet( NextAlarm, yy=cyy, mm=1, dd=1, s=0, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .true.

case (optEnd)
call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_ClockGetAlarm(clock, "alarm_stop", alarm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
call ESMF_AlarmGet(alarm, ringTime=NextAlarm, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
update_nextalarm = .false.

case default
call ESMF_LogWrite(subname//'unknown option '//trim(option), ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return

end select

! --------------------------------------------------------------------------------
! --- AlarmInterval and NextAlarm should be set ---
! --------------------------------------------------------------------------------

! --- advance Next Alarm so it won't ring on first timestep for
! --- most options above. go back one alarminterval just to be careful

if (update_nextalarm) then
NextAlarm = NextAlarm - AlarmInterval
do while (NextAlarm <= CurrTime)
NextAlarm = NextAlarm + AlarmInterval
enddo
endif

alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, &
ringInterval=AlarmInterval, rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end subroutine esm_time_alarmInit

!===============================================================================
#ifdef UNUSEDFUNCTION
subroutine esm_time_timeInit( Time, ymd, cal, tod, desc, logunit )

! Create the ESMF_Time object corresponding to the given input time, given in
! YMD (Year Month Day) and TOD (Time-of-day) format.
! Set the time by an integer as YYYYMMDD and integer seconds in the day

! input/output parameters:
type(ESMF_Time) , intent(inout) :: Time ! ESMF time
integer , intent(in) :: ymd ! year, month, day YYYYMMDD
type(ESMF_Calendar) , intent(in) :: cal ! ESMF calendar
integer , intent(in), optional :: tod ! time of day in seconds
character(len=*) , intent(in), optional :: desc ! description of time to set
integer , intent(in), optional :: logunit

! local variables
integer :: yr, mon, day ! Year, month, day as integers
integer :: ltod ! local tod
character(len=256) :: ldesc ! local desc
integer :: rc ! return code
character(len=*), parameter :: subname = '(esm_time_m_ETimeInit) '
!-------------------------------------------------------------------------------

ltod = 0
if (present(tod)) ltod = tod
ldesc = ''
if (present(desc)) ldesc = desc

if ( (ymd < 0) .or. (ltod < 0) .or. (ltod > SecPerDay) )then
if (present(logunit)) then
write(logunit,*) subname//': ERROR yymmdd is a negative number or '// &
'time-of-day out of bounds', ymd, ltod
end if
call ESMF_LogWrite( subname//'ERROR: Bad input' , ESMF_LOGMSG_ERROR)
rc = ESMF_FAILURE
return
end if

call esm_time_date2ymd (ymd,yr,mon,day)

call ESMF_TimeSet( Time, yy=yr, mm=mon, dd=day, s=ltod, calendar=cal, rc=rc )
if (ChkErr(rc,__LINE__,u_FILE_u)) return

end subroutine esm_time_timeInit
#endif
!===============================================================================

subroutine esm_time_date2ymd (date, year, month, day)

! input/output variables
Expand Down
2 changes: 1 addition & 1 deletion mediator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set(SRCFILES esmFldsExchange_cesm_mod.F90 med_fraction_mod.F90
med_methods_mod.F90 med_phases_prep_ice_mod.F90
med_phases_restart_mod.F90 esmFldsExchange_hafs_mod.F90
med_internalstate_mod.F90 med_phases_aofluxes_mod.F90
med_phases_prep_lnd_mod.F90 med_time_mod.F90
med_phases_prep_lnd_mod.F90
esmFldsExchange_ufs_mod.F90 med_io_mod.F90
med_phases_history_mod.F90 med_phases_prep_ocn_mod.F90
med_utils_mod.F90 esmFlds.F90 med_kind_mod.F90
Expand Down
7 changes: 3 additions & 4 deletions mediator/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ esmFldsExchange_hafs_mod.o : med_kind_mod.o med_methods_mod.o esmFlds.o med_inte
med.o : med_kind_mod.o med_phases_profile_mod.o med_utils_mod.o med_phases_prep_rof_mod.o med_phases_aofluxes_mod.o \
med_phases_prep_ice_mod.o med_fraction_mod.o med_map_mod.o med_constants_mod.o med_phases_prep_wav_mod.o \
med_phases_prep_lnd_mod.o med_phases_history_mod.o med_phases_ocnalb_mod.o med_phases_restart_mod.o \
med_time_mod.o med_internalstate_mod.o med_phases_prep_atm_mod.o esmFldsExchange_cesm_mod.o esmFldsExchange_ufs_mod.o \
med_internalstate_mod.o med_phases_prep_atm_mod.o esmFldsExchange_cesm_mod.o esmFldsExchange_ufs_mod.o \
esmFldsExchange_hafs_mod.o med_phases_prep_glc_mod.o esmFlds.o med_io_mod.o med_methods_mod.o med_phases_prep_ocn_mod.o \
med_phases_post_atm_mod.o med_phases_post_ice_mod.o med_phases_post_lnd_mod.o med_phases_post_glc_mod.o med_phases_post_rof_mod.o \
med_phases_post_wav_mod.o
Expand All @@ -50,7 +50,7 @@ med_map_mod.o : med_kind_mod.o med_internalstate_mod.o med_constants_mod.o med_m
med_merge_mod.o : med_kind_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o med_utils_mod.o
med_methods_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o
med_phases_aofluxes_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o
med_phases_history_mod.o : med_kind_mod.o med_utils_mod.o med_time_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_io_mod.o esmFlds.o
med_phases_history_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_constants_mod.o med_map_mod.o med_methods_mod.o med_io_mod.o esmFlds.o
med_phases_ocnalb_mod.o : med_kind_mod.o med_utils_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_methods_mod.o
med_phases_prep_atm_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_merge_mod.o med_map_mod.o med_constants_mod.o med_phases_ocnalb_mod.o med_internalstate_mod.o med_utils_mod.o
med_phases_prep_glc_mod.o : med_kind_mod.o med_utils_mod.o med_internalstate_mod.o med_map_mod.o med_constants_mod.o med_methods_mod.o esmFlds.o
Expand All @@ -68,6 +68,5 @@ med_phases_post_rof_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_m
med_phases_post_wav_mod.o : med_kind_mod.o esmFlds.o med_methods_mod.o med_map_mod.o med_constants_mod.o med_internalstate_mod.o med_utils_mod.o
med_phases_profile_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o med_internalstate_mod.o med_time_mod.o
med_phases_restart_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o med_internalstate_mod.o esmFlds.o med_io_mod.o
med_time_mod.o : med_kind_mod.o med_utils_mod.o med_constants_mod.o
med_utils_mod.o : med_kind_mod.o
med_diag_mod.o : med_kind_mod.o med_time_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o
med_diag_mod.o : med_kind_mod.o med_utils_mod.o med_methods_mod.o med_internalstate_mod.o
7 changes: 3 additions & 4 deletions mediator/med.F90
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ module MED
use med_methods_mod , only : FB_getFieldN => med_methods_FB_getFieldN
use med_methods_mod , only : clock_timeprint => med_methods_clock_timeprint
use med_utils_mod , only : memcheck => med_memcheck
use med_time_mod , only : med_time_alarmInit
use med_internalstate_mod , only : InternalState, med_internalstate_init, med_internalstate_coupling
use med_internalstate_mod , only : med_internalstate_defaultmasks, logunit, maintask
use med_internalstate_mod , only : ncomps, compname
Expand Down Expand Up @@ -2257,7 +2256,7 @@ subroutine SetRunClock(gcomp, rc)
use NUOPC , only : NUOPC_CompCheckSetClock, NUOPC_CompAttributeGet
use NUOPC_Mediator , only : NUOPC_MediatorGet
! NUOPC_shr_methods is now in cesm_share and cdeps
use nuopc_shr_methods, only : get_minimum_timestep
use nuopc_shr_methods, only : get_minimum_timestep, AlarmInit

! input/output variables
type(ESMF_GridComp) :: gcomp
Expand Down Expand Up @@ -2322,8 +2321,8 @@ subroutine SetRunClock(gcomp, rc)
min_timestep = get_minimum_timestep(gcomp, rc)
endif

call med_time_alarmInit(mclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, &
alarmname='alarm_stop', min_timestep=min_timestep, rc=rc)
call AlarmInit(mclock, stop_alarm, stop_option, opt_n=stop_n, opt_ymd=stop_ymd, &
alarmname='alarm_stop', rc=rc)
if (ChkErr(rc,__LINE__,u_FILE_u)) return
stopalarmcreated = .true.
end if
Expand Down
1 change: 0 additions & 1 deletion mediator/med_diag_mod.F90
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ module med_diag_mod
use med_methods_mod , only : fldbun_getdata2d => med_methods_FB_getdata2d
use med_methods_mod , only : fldbun_getdata1d => med_methods_FB_getdata1d
use med_methods_mod , only : fldbun_fldChk => med_methods_FB_FldChk
use med_time_mod , only : alarmInit => med_time_alarmInit
use med_utils_mod , only : chkerr => med_utils_ChkErr
use perf_mod , only : t_startf, t_stopf

Expand Down
Loading

0 comments on commit bcaac2a

Please sign in to comment.