diff --git a/CHANGELOG.md b/CHANGELOG.md index 7956732c3d7c..74d6483ad4bd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added optional start_date and start_time to control the output window for each History collection. No output will be written before then. If not specified, these default to the beginning of the experiment. - Added utility to prepare inputs for ExtDatDriver.x so that ExtData can simulate a real GEOS run - Added loggers when writing or reading weight files - Added new option to AGCM.rc `overwrite_checkpoint` to allow checkpoint files to be overwritten. By default still will not overwrite checkpoints diff --git a/gridcomps/History/MAPL_HistoryCollection.F90 b/gridcomps/History/MAPL_HistoryCollection.F90 index 336773e0400d..1a6827e7c985 100644 --- a/gridcomps/History/MAPL_HistoryCollection.F90 +++ b/gridcomps/History/MAPL_HistoryCollection.F90 @@ -47,12 +47,15 @@ module MAPL_HistoryCollectionMod integer :: acc_offset integer :: ref_date integer :: ref_time + integer :: start_date + integer :: start_time integer :: end_date integer :: end_time integer :: duration type(ESMF_Alarm) :: his_alarm ! when to write file type(ESMF_Alarm) :: seg_alarm ! segment alarm controls when to write to new file type(ESMF_Alarm) :: mon_alarm + type(ESMF_Alarm) :: start_alarm type(ESMF_Alarm) :: end_alarm integer,pointer :: expSTATE (:) integer :: unit @@ -70,6 +73,7 @@ module MAPL_HistoryCollectionMod integer :: verbose integer :: xyoffset logical :: disabled + logical :: skipWriting logical :: subVm logical :: backwards ! Adds support for clock running in reverse direction logical :: useNewFormat diff --git a/gridcomps/History/MAPL_HistoryGridComp.F90 b/gridcomps/History/MAPL_HistoryGridComp.F90 index 17deb2db1299..c0ee057d4dd9 100644 --- a/gridcomps/History/MAPL_HistoryGridComp.F90 +++ b/gridcomps/History/MAPL_HistoryGridComp.F90 @@ -56,7 +56,7 @@ module MAPL_HistoryGridCompMod use MaskSamplerGeosatMod use MAPL_StringTemplate use regex_module - use MAPL_TimeUtilsMod, only: is_valid_time, is_valid_date + use MAPL_TimeUtilsMod, only: is_valid_time, is_valid_date, MAPL_UndefInt use gFTL_StringStringMap !use ESMF_CFIOMOD use MAPL_EpochSwathMod @@ -811,16 +811,19 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) label=trim(string) // 'ref_time:',_RC ) _ASSERT(is_valid_time(list(n)%ref_time),'Invalid ref_time') - call ESMF_ConfigGetAttribute ( cfg, list(n)%end_date, default=-999, & + call ESMF_ConfigGetAttribute ( cfg, list(n)%start_date, default=MAPL_UndefInt, & + label=trim(string) // 'start_date:',_RC ) + _ASSERT(is_valid_date(list(n)%start_date),'Invalid start_date') + call ESMF_ConfigGetAttribute ( cfg, list(n)%start_time, default=MAPL_UndefInt, & + label=trim(string) // 'start_time:',_RC ) + _ASSERT(is_valid_time(list(n)%start_time),'Invalid start_time') + + call ESMF_ConfigGetAttribute ( cfg, list(n)%end_date, default=MAPL_UndefInt, & label=trim(string) // 'end_date:',_RC ) - if (list(n)%end_date /= -999) then - _ASSERT(is_valid_date(list(n)%end_date),'Invalid end_date') - end if - call ESMF_ConfigGetAttribute ( cfg, list(n)%end_time, default=-999, & + _ASSERT(is_valid_date(list(n)%end_date),'Invalid end_date') + call ESMF_ConfigGetAttribute ( cfg, list(n)%end_time, default=MAPL_UndefInt, & label=trim(string) // 'end_time:',_RC ) - if (list(n)%end_time /= -999) then - _ASSERT(is_valid_time(list(n)%end_time),'Invalid end_time') - end if + _ASSERT(is_valid_time(list(n)%end_time),'Invalid end_time') call ESMF_ConfigGetAttribute ( cfg, list(n)%duration, default=list(n)%frequency, & label=trim(string) // 'duration:' ,_RC ) @@ -1349,9 +1352,41 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) intState%stampOffset(n) = Frequency ! we go to the beginning of the month end if +! End Alarm based on start_date and start_time +! ---------------------------------------- + if( list(n)%start_date.ne.MAPL_UndefInt .and. list(n)%start_time.ne.MAPL_UndefInt ) then + REF_TIME(1) = list(n)%start_date/10000 + REF_TIME(2) = mod(list(n)%start_date,10000)/100 + REF_TIME(3) = mod(list(n)%start_date,100) + REF_TIME(4) = list(n)%start_time/10000 + REF_TIME(5) = mod(list(n)%start_time,10000)/100 + REF_TIME(6) = mod(list(n)%start_time,100) + + call ESMF_TimeSet( RingTime, YY = REF_TIME(1), & + MM = REF_TIME(2), & + DD = REF_TIME(3), & + H = REF_TIME(4), & + M = REF_TIME(5), & + S = REF_TIME(6), calendar=cal, rc=rc ) + else + RingTime = CurrTime + end if + list(n)%start_alarm = ESMF_AlarmCreate( clock=clock, RingTime=RingTime, sticky=.false., _RC ) + + list(n)%skipWriting = .true. + if (RingTime == CurrTime) then + call ESMF_AlarmRingerOn(list(n)%start_alarm, _RC ) + list(n)%skipWriting = .false. + else + if (RingTime < CurrTime .NEQV. list(n)%backwards) then + list(n)%skipWriting = .false. + endif + end if + + ! End Alarm based on end_date and end_time ! ---------------------------------------- - if( list(n)%end_date.ne.-999 .and. list(n)%end_time.ne.-999 ) then + if( list(n)%end_date.ne.MAPL_UndefInt .and. list(n)%end_time.ne.MAPL_UndefInt ) then REF_TIME(1) = list(n)%end_date/10000 REF_TIME(2) = mod(list(n)%end_date,10000)/100 REF_TIME(3) = mod(list(n)%end_date,100) @@ -2527,9 +2562,13 @@ subroutine Initialize ( gc, import, dumexport, clock, rc ) else print *, ' Duration: ', list(n)%duration end if - if( list(n)%end_date.ne.-999 ) then - print *, ' End_Date: ', list(n)%end_date - print *, ' End_Time: ', list(n)%end_time + if( list(n)%start_date.ne.MAPL_UndefInt ) then + print *, ' Start_Date: ', list(n)%start_date + print *, ' Start_Time: ', list(n)%start_time + endif + if( list(n)%end_date.ne.MAPL_UndefInt ) then + print *, ' End_Date: ', list(n)%end_date + print *, ' End_Time: ', list(n)%end_time endif if (trim(list(n)%output_grid_label)/='') then print *, ' Regrid Mthd: ', regrid_method_int_to_string(list(n)%regrid_method) @@ -3427,6 +3466,14 @@ subroutine Run ( gc, import, export, clock, rc ) ! decide if we are writing based on alarms + do n=1,nlist + if (list(n)%skipWriting) then + if (ESMF_AlarmIsRinging(list(n)%start_alarm)) then + list(n)%skipWriting = .false. + endif + endif + end do + do n=1,nlist if (list(n)%disabled .or. ESMF_AlarmIsRinging(list(n)%end_alarm) ) then list(n)%disabled = .true. @@ -3454,6 +3501,8 @@ subroutine Run ( gc, import, export, clock, rc ) end if end if + if (list(n)%skipWriting) writing(n) = .false. + if (writing(n) .and. .not.IntState%average(n)) then ! R8 to R4 copy (if needed!) do m=1,list(n)%field_set%nfields diff --git a/shared/TimeUtils.F90 b/shared/TimeUtils.F90 index 57fe47f15301..460670adcdde 100644 --- a/shared/TimeUtils.F90 +++ b/shared/TimeUtils.F90 @@ -7,6 +7,8 @@ module MAPL_TimeUtilsMod public :: is_valid_time public :: is_valid_datetime + integer, public, parameter :: MAPL_UndefInt = -999 + contains logical function is_valid_date(date) result(is_valid) @@ -19,6 +21,11 @@ logical function is_valid_date(date) result(is_valid) integer :: year, month, day logical :: is_leap_year + if (date == MAPL_UndefInt) then + is_valid = .true. + return + end if + year = date/10000 month = mod(date,10000)/100 day = mod(date,100) @@ -66,6 +73,11 @@ logical function is_valid_time(time) result(is_valid) integer :: hours, minutes, seconds + if (time == MAPL_UndefInt) then + is_valid = .true. + return + end if + hours = time/10000 minutes = mod(time,10000)/100 seconds = mod(time,100)