diff --git a/cesm/driver/esm_time_mod.F90 b/cesm/driver/esm_time_mod.F90 index 6650a4ab..d4d0e81c 100644 --- a/cesm/driver/esm_time_mod.F90 +++ b/cesm/driver/esm_time_mod.F90 @@ -18,6 +18,7 @@ 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 @@ -25,7 +26,7 @@ module esm_time_mod 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 @@ -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, & @@ -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 diff --git a/mediator/CMakeLists.txt b/mediator/CMakeLists.txt index 9630b5e2..80be3d2e 100644 --- a/mediator/CMakeLists.txt +++ b/mediator/CMakeLists.txt @@ -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 diff --git a/mediator/Makefile b/mediator/Makefile index 990fe58e..a353ff9a 100644 --- a/mediator/Makefile +++ b/mediator/Makefile @@ -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 @@ -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 @@ -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 diff --git a/mediator/med.F90 b/mediator/med.F90 index c9f1328c..f11a34fd 100644 --- a/mediator/med.F90 +++ b/mediator/med.F90 @@ -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 @@ -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 @@ -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 diff --git a/mediator/med_diag_mod.F90 b/mediator/med_diag_mod.F90 index 8ea6651e..0416e469 100644 --- a/mediator/med_diag_mod.F90 +++ b/mediator/med_diag_mod.F90 @@ -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 diff --git a/mediator/med_phases_history_mod.F90 b/mediator/med_phases_history_mod.F90 index f1157805..2da08cc6 100644 --- a/mediator/med_phases_history_mod.F90 +++ b/mediator/med_phases_history_mod.F90 @@ -154,8 +154,8 @@ subroutine med_phases_history_write(gcomp, rc) use ESMF , only : ESMF_Alarm, ESMF_AlarmSet use ESMF , only : ESMF_FieldBundleIsCreated use med_internalstate_mod, only : compocn, compatm - use med_time_mod , only : med_time_alarmInit - + use nuopc_shr_methods , only : alarmInit + ! input/output variables type(ESMF_GridComp) :: gcomp integer, intent(out) :: rc @@ -228,8 +228,8 @@ subroutine med_phases_history_write(gcomp, rc) if (hist_option_all_inst(1:len(optnsteps)) == optnsteps) then min_timestep = get_minimum_timestep(gcomp, rc=rc) endif - call med_time_alarmInit(mclock, alarm, option=hist_option_all_inst, opt_n=hist_n_all_inst, & - reftime=starttime, alarmname=alarmname, min_timestep=min_timestep, rc=rc) + call alarmInit(mclock, alarm, option=hist_option_all_inst, opt_n=hist_n_all_inst, & + reftime=starttime, alarmname=alarmname, rc=rc) call ESMF_AlarmSet(alarm, clock=mclock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return @@ -1536,8 +1536,7 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi use NUOPC_Mediator, only : NUOPC_MediatorGet use ESMF , only : ESMF_ClockCreate, ESMF_ClockGet, ESMF_ClockSet - use med_time_mod , only : med_time_alarmInit - use nuopc_shr_methods, only: get_minimum_timestep + use nuopc_shr_methods, only: AlarmInit ! input/output variables type(ESMF_GridComp) , intent(in) :: gcomp @@ -1547,7 +1546,7 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi character(len=*) , intent(in) :: hist_option ! freq_option setting (ndays, nsteps, etc) integer , intent(in) :: hist_n ! freq_n setting relative to freq_option integer , intent(out) :: rc - + ! local variables type(ESMF_Clock) :: mclock, dclock type(ESMF_Time) :: StartTime @@ -1581,13 +1580,8 @@ subroutine med_phases_history_init_histclock(gcomp, hclock, alarm, alarmname, hi hclock = ESMF_ClockCreate(mclock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - ! Initialize history alarm and advance history clock to trigger - ! alarms then reset history clock back to mcurrtime - if (hist_option(1:len(optnsteps)) == optnsteps) then - min_timestep = get_minimum_timestep(gcomp, rc=rc) - endif - call med_time_alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, & - reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., min_timestep=min_timestep, rc=rc) + call alarmInit(hclock, alarm, option=hist_option, opt_n=hist_n, & + reftime=StartTime, alarmname=trim(alarmname), advance_clock=.true., rc=rc) ! Write diagnostic info if (maintask) then diff --git a/mediator/med_phases_prep_glc_mod.F90 b/mediator/med_phases_prep_glc_mod.F90 index 920fb415..19ac47e7 100644 --- a/mediator/med_phases_prep_glc_mod.F90 +++ b/mediator/med_phases_prep_glc_mod.F90 @@ -38,7 +38,7 @@ module med_phases_prep_glc_mod use med_methods_mod , only : field_getdata2d => med_methods_Field_getdata2d use med_methods_mod , only : field_getdata1d => med_methods_Field_getdata1d use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_time_mod , only : med_time_alarmInit + use nuopc_shr_methods , only : alarmInit use glc_elevclass_mod , only : glc_get_num_elevation_classes use glc_elevclass_mod , only : glc_get_elevation_classes use glc_elevclass_mod , only : glc_get_fractional_icecov @@ -545,7 +545,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) call NUOPC_CompAttributeGet(gcomp, name="glc_avg_period", value=glc_avg_period, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (trim(glc_avg_period) == 'yearly') then - call med_time_alarmInit(prepglc_clock, glc_avg_alarm, 'yearly', alarmname='alarm_glc_avg', rc=rc) + call alarmInit(prepglc_clock, glc_avg_alarm, 'yearly', alarmname='alarm_glc_avg', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (maintask) then write(logunit,'(a,i10)') trim(subname)//& @@ -555,7 +555,7 @@ subroutine med_phases_prep_glc_avg(gcomp, rc) call NUOPC_CompAttributeGet(gcomp, name="glc_cpl_dt", value=cvalue, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return read(cvalue,*) glc_cpl_dt - call med_time_alarmInit(prepglc_clock, glc_avg_alarm, 'nseconds', opt_n=glc_cpl_dt, alarmname='alarm_glc_avg', rc=rc) + call alarmInit(prepglc_clock, glc_avg_alarm, 'nseconds', opt_n=glc_cpl_dt, alarmname='alarm_glc_avg', rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return if (maintask) then write(logunit,'(a,i10)') trim(subname)//& diff --git a/mediator/med_phases_profile_mod.F90 b/mediator/med_phases_profile_mod.F90 index 5c28eca3..76a630cb 100644 --- a/mediator/med_phases_profile_mod.F90 +++ b/mediator/med_phases_profile_mod.F90 @@ -9,7 +9,7 @@ module med_phases_profile_mod use med_utils_mod , only : med_utils_chkerr, med_memcheck use med_internalstate_mod , only : maintask, logunit use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_time_mod , only : alarmInit => med_time_alarmInit + use nuopc_shr_methods , only : alarmInit use perf_mod , only : t_startf, t_stopf #ifdef CESMCOUPLED use shr_mem_mod , only : shr_mem_getusage diff --git a/mediator/med_phases_restart_mod.F90 b/mediator/med_phases_restart_mod.F90 index 70d80f7e..54684cf8 100644 --- a/mediator/med_phases_restart_mod.F90 +++ b/mediator/med_phases_restart_mod.F90 @@ -47,8 +47,7 @@ subroutine med_phases_restart_alarm_init(gcomp, rc) use ESMF , only : ESMF_SUCCESS, ESMF_FAILURE use NUOPC , only : NUOPC_CompAttributeGet use NUOPC_Model , only : NUOPC_ModelGet - use med_time_mod , only : med_time_AlarmInit - use nuopc_shr_methods, only : get_minimum_timestep + use nuopc_shr_methods, only : AlarmInit ! input/output variables type(ESMF_GridComp) :: gcomp @@ -65,8 +64,6 @@ subroutine med_phases_restart_alarm_init(gcomp, rc) integer :: restart_n ! freq_n setting relative to freq_option logical :: isPresent logical :: isSet - integer :: min_timestep = 0 ! used for nsteps option - character(len=*), parameter :: optNsteps = "nstep" character(len=*), parameter :: subname='(med_phases_restart_alarm_init)' !--------------------------------------- @@ -86,13 +83,9 @@ subroutine med_phases_restart_alarm_init(gcomp, rc) ! Set alarm for instantaneous mediator restart output call ESMF_ClockGet(mclock, currTime=mCurrTime, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return - if (restart_option(1:len(optNsteps)) .eq. optNSteps) then - min_timestep = get_minimum_timestep(gcomp, rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - endif - - call med_time_alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, & - reftime=mcurrTime, alarmname='alarm_restart', min_timestep=min_timestep, rc=rc) + + call alarmInit(mclock, alarm, option=restart_option, opt_n=restart_n, & + reftime=mcurrTime, alarmname='alarm_restart', rc=rc) call ESMF_AlarmSet(alarm, clock=mclock, rc=rc) if (ChkErr(rc,__LINE__,u_FILE_u)) return diff --git a/mediator/med_time_mod.F90 b/mediator/med_time_mod.F90 deleted file mode 100644 index 6e513155..00000000 --- a/mediator/med_time_mod.F90 +++ /dev/null @@ -1,334 +0,0 @@ -module med_time_mod - - use med_kind_mod , only : CX=>SHR_KIND_CX, CS=>SHR_KIND_CS, CL=>SHR_KIND_CL, R8=>SHR_KIND_R8 - use ESMF , only : ESMF_GridComp, ESMF_GridCompGet, ESMF_GridCompSet - use ESMF , only : ESMF_Clock, ESMF_ClockCreate, ESMF_ClockGet, ESMF_ClockSet - use ESMF , only : ESMF_ClockAdvance - use ESMF , only : ESMF_Alarm, ESMF_AlarmCreate, ESMF_AlarmGet, ESMF_AlarmSet - use ESMF , only : ESMF_Calendar, ESMF_CalKind_Flag, ESMF_CalendarCreate - use ESMF , only : ESMF_CALKIND_NOLEAP, ESMF_CALKIND_GREGORIAN - use ESMF , only : ESMF_Time, ESMF_TimeGet, ESMF_TimeSet - use ESMF , only : ESMF_TimeInterval, ESMF_TimeIntervalSet, ESMF_TimeIntervalGet - use ESMF , only : ESMF_SUCCESS, ESMF_LogWrite, ESMF_FAILURE - use ESMF , only : ESMF_VM, ESMF_VMGet, ESMF_VMBroadcast, ESMF_ClockGetAlarm - use ESMF , only : ESMF_LOGMSG_INFO, ESMF_FAILURE, ESMF_LOGMSG_ERROR - use ESMF , only : operator(<), operator(/=), operator(+), mod - use ESMF , only : operator(-), operator(*) , operator(>=) - use ESMF , only : operator(<=), operator(>), operator(==) - use med_constants_mod , only : dbug_flag => med_constants_dbug_flag - use med_utils_mod , only : chkerr => med_utils_ChkErr - use med_internalstate_mod, only : maintask, logunit - - implicit none - private ! default private - - public :: med_time_alarmInit ! initialize an alarm - - ! Clock and alarm options - character(len=*), private, parameter :: & - optNONE = "none" , & - optNever = "never" , & - optNSteps = "nstep" , & - optNSeconds = "nsecond" , & - optNMinutes = "nminute" , & - optNHours = "nhour" , & - optNDays = "nday" , & - optNMonths = "nmonth" , & - optNYears = "nyear" , & - optMonthly = "monthly" , & - optYearly = "yearly" , & - optDate = "date" , & - optEnd = "end" , & - optGLCCouplingPeriod = "glc_coupling_period" - - ! Module data - integer, parameter :: SecPerDay = 86400 ! Seconds per day - character(len=*), parameter :: u_FILE_u = & - __FILE__ - -!=============================================================================== -contains -!=============================================================================== - - subroutine med_time_alarmInit( clock, alarm, option, & - opt_n, opt_ymd, opt_tod, reftime, alarmname, advance_clock, min_timestep, 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 ! reference time - character(len=*) , optional , intent(in) :: alarmname ! alarm name - logical , optional , intent(in) :: advance_clock ! advance clock to trigger alarm - integer , optional , intent(in) :: min_timestep ! used for nsteps option only - integer , intent(out) :: 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 alarm time - type(ESMF_TimeInterval) :: TimeStepInterval ! Timestep interval - 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) - - ! 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(trim(option) == optNSteps .or. trim(option) == trim(optNSteps)//'s') then - if(present(min_timestep)) then - if(min_timestep <= 0) then - call ESMF_LogWrite(subname//trim(option)//' min_timestep <= 0', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - else - call ESMF_LogWrite(subname//trim(option)//' requires min_timestep', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - end if - endif - 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 (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 (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 (optDate) - call ESMF_TimeIntervalSet(AlarmInterval, yy=9999, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call med_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 (optNSteps,trim(optNSteps)//'s') - call ESMF_ClockGet(clock, TimeStep=TimestepInterval, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_TimeIntervalSet(AlarmInterval, s=min_timestep, rc=rc ) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - AlarmInterval = AlarmInterval * opt_n - ! timestepinterval*0 is 0 of kind ESMF_TimeStepInterval - if (mod(AlarmInterval, TimestepInterval) /= (timestepinterval*0)) then - call ESMF_LogWrite(subname//'illegal Alarm setting for '//trim(alarmname), ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - 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 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 - ! AlarmInterval*0 is 0 of kind ESMF_TimeStepInterval - if (AlarmInterval <= AlarmInterval*0) then - call ESMF_LogWrite(subname//'AlarmInterval ERROR ', ESMF_LOGMSG_ERROR) - rc = ESMF_FAILURE - return - endif - do while (NextAlarm <= CurrTime) - NextAlarm = NextAlarm + AlarmInterval - enddo - endif - - if (maintask) then - write(logunit,*) - write(logunit,'(a)') trim(subname) //' creating alarm '// trim(lalarmname) - end if - - alarm = ESMF_AlarmCreate( name=lalarmname, clock=clock, ringTime=NextAlarm, & - ringInterval=AlarmInterval, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - - ! Advance model clock to trigger alarm then reset model clock back to currtime - if (present(advance_clock)) then - if (advance_clock) then - call ESMF_AlarmSet(alarm, clock=clock, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockGet(clock, currTime=CurrTime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockAdvance(clock,rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - call ESMF_ClockSet(clock, currTime=currtime, rc=rc) - if (ChkErr(rc,__LINE__,u_FILE_u)) return - end if - end if - - end subroutine med_time_alarmInit - - !=============================================================================== - subroutine med_time_date2ymd (date, year, month, day) - - ! input/output variables - integer, intent(in) :: date ! coded-date (yyyymmdd) - integer, intent(out) :: year,month,day ! calendar year,month,day - - ! local variables - integer :: tdate ! temporary date - character(*),parameter :: subName = "(med_time_date2ymd)" - !------------------------------------------------------------------------------- - tdate = abs(date) - year = int(tdate/10000) - if (date < 0) then - year = -year - end if - month = int( mod(tdate,10000)/ 100) - day = mod(tdate, 100) - end subroutine med_time_date2ymd - -end module med_time_mod