Skip to content
This repository has been archived by the owner on Oct 23, 2020. It is now read-only.

Apply stream reference_time to individual output records #1418

Merged
Show file tree
Hide file tree
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
36 changes: 27 additions & 9 deletions src/framework/mpas_stream_manager.F
Original file line number Diff line number Diff line change
Expand Up @@ -5909,9 +5909,11 @@ subroutine stream_mgr_add_alarm_c(manager_c, streamID_c, direction_c, alarmTime_
use mpas_derived_types, only : MPAS_streamManager_type, MPAS_Clock_type, MPAS_Time_type, MPAS_TimeInterval_type, &
MPAS_STREAM_MGR_NOERR, MPAS_STREAM_INPUT, MPAS_STREAM_OUTPUT, MPAS_START_TIME, &
MPAS_STOP_TIME, MPAS_STREAM_PROPERTY_REF_TIME
use mpas_stream_manager, only : MPAS_stream_mgr_get_clock, MPAS_stream_mgr_add_alarm, MPAS_stream_mgr_set_property
use mpas_stream_manager, only : MPAS_stream_mgr_get_clock, MPAS_stream_mgr_add_alarm, MPAS_stream_mgr_set_property, &
MPAS_stream_mgr_get_property
use mpas_kind_types, only : StrKIND
use mpas_timekeeping, only : mpas_add_clock_alarm, mpas_set_time, mpas_get_time, mpas_set_timeInterval, mpas_get_clock_time
use mpas_timekeeping, only : mpas_add_clock_alarm, mpas_set_time, mpas_get_time, mpas_set_timeInterval, mpas_get_clock_time, &
mpas_adjust_alarm_to_reference_time

implicit none

Expand All @@ -5927,11 +5929,14 @@ subroutine stream_mgr_add_alarm_c(manager_c, streamID_c, direction_c, alarmTime_
character(len=StrKIND) :: streamID, direction, alarmID, alarmTime, alarmInterval, alarmString
type (MPAS_Time_type) :: alarmTime_local
type (MPAS_TimeInterval_type) :: alarmInterval_local
character(len=StrKIND) :: streamReferenceTimeString
type (MPAS_Time_type) :: streamReferenceTime
integer :: idirection
integer :: ierr
integer :: ierr, ierr_tmp


ierr = 0
ierr_tmp = 0

call c_f_pointer(manager_c, manager)
call mpas_c_to_f_string(streamID_c, streamID)
Expand All @@ -5954,23 +5959,36 @@ subroutine stream_mgr_add_alarm_c(manager_c, streamID_c, direction_c, alarmTime_
call MPAS_stream_mgr_get_clock(manager, clock)

if (trim(alarmTime) == 'start' .and. trim(alarmInterval) == 'final_only') then
alarmTime_local = mpas_get_clock_time(clock, MPAS_STOP_TIME, ierr=ierr)
alarmTime_local = mpas_get_clock_time(clock, MPAS_STOP_TIME, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
call mpas_get_time(alarmTime_local, dateTimeString=alarmString)
call MPAS_stream_mgr_set_property(manager, streamID, MPAS_STREAM_PROPERTY_REF_TIME, alarmString, ierr=ierr)
call MPAS_stream_mgr_set_property(manager, streamID, MPAS_STREAM_PROPERTY_REF_TIME, alarmString, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
else if (trim(alarmTime) == 'start') then
alarmTime_local = mpas_get_clock_time(clock, MPAS_START_TIME, ierr=ierr)
alarmTime_local = mpas_get_clock_time(clock, MPAS_START_TIME, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
else
call mpas_set_time(alarmTime_local, dateTimeString=alarmTime)
end if

if (trim(alarmInterval) == 'initial_only' .or. trim(alarmInterval) == 'final_only') then
call mpas_add_clock_alarm(clock, alarmID, alarmTime_local, ierr=ierr)
call mpas_add_clock_alarm(clock, alarmID, alarmTime_local, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
else
call mpas_set_timeInterval(alarmInterval_local, timeString=alarmInterval)
call mpas_add_clock_alarm(clock, alarmID, alarmTime_local, alarmTimeInterval=alarmInterval_local, ierr=ierr)
call mpas_add_clock_alarm(clock, alarmID, alarmTime_local, alarmTimeInterval=alarmInterval_local, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
! Now calibrate alarm to use the stream's reference time as the time coordinate origin for the stream's output alarm.
call MPAS_stream_mgr_get_property(manager, streamID, MPAS_STREAM_PROPERTY_REF_TIME, streamReferenceTimeString, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
call mpas_set_time(streamReferenceTime, dateTimeString=streamReferenceTimeString, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)
call mpas_adjust_alarm_to_reference_time(clock, alarmID, streamReferenceTime, ierr)
ierr = ior(ierr, ierr_tmp)
end if

call MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, idirection, ierr=ierr)
call MPAS_stream_mgr_add_alarm(manager, streamID, alarmID, idirection, ierr=ierr_tmp)
ierr = ior(ierr, ierr_tmp)

if (ierr == MPAS_STREAM_MGR_NOERR) then
ierr_c = 0
Expand Down
69 changes: 69 additions & 0 deletions src/framework/mpas_timekeeping.F
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,75 @@ subroutine mpas_reset_clock_alarm(clock, alarmID, interval, ierr)
end subroutine mpas_reset_clock_alarm


! Adjust the previous ring time of a recurring alarm to be away from a provided reference time
! by an integer multiple of the alarm's interval.
! This is useful if the alarm's default prevRingTime, which is the current time when the alarm
! is created, is not desired.
subroutine mpas_adjust_alarm_to_reference_time(clock, alarmID, referenceTime, ierr)

implicit none

type (MPAS_Clock_type), intent(inout) :: clock
character (len=*), intent(in) :: alarmID
type (MPAS_Time_type) :: referenceTime
type (MPAS_Time_type) :: now
integer, intent(out) :: ierr

! Local variables
type (MPAS_Alarm_type), pointer :: alarmPtr
type (MPAS_TimeInterval_type) :: searchInterval, searchRemainder
integer (kind=I8KIND) :: nDivs
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewhoffman I added this I8 kind in an extra commit to get it to compile.

integer :: threadNum
integer :: ierr_tmp

ierr = 0
ierr_tmp = 0

threadNum = mpas_threading_get_thread_num()

if ( threadNum == 0 ) then
alarmPtr => clock % alarmListHead
do while (associated(alarmPtr))

if (trim(alarmPtr % alarmID) == trim(alarmID)) then

if (alarmPtr % isRecurring) then
!call mpas_print_alarm(clock, alarmID, ierr_tmp)
now = mpas_get_clock_time(clock, MPAS_NOW, ierr_tmp)
ierr = ior(ierr, ierr_tmp)
if(clock % direction == MPAS_FORWARD) then
if (now > referenceTime) then
searchInterval = now - referenceTime
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
alarmPtr % prevRingTime = now - searchRemainder
else
searchInterval = referenceTime - now
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
alarmPtr % prevRingTime = now - (alarmPtr % ringTimeInterval - searchRemainder)
endif
else ! MPAS_REVERSE
if (now < referenceTime) then
searchInterval = now - referenceTime
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
alarmPtr % prevRingTime = now - searchRemainder
else
searchInterval = referenceTime - now
call mpas_interval_division(referenceTime, searchInterval, alarmPtr % ringTimeInterval, nDivs, searchRemainder)
alarmPtr % prevRingTime = now - (alarmPtr % ringTimeInterval - searchRemainder)
endif
end if ! forward direction
!call mpas_print_alarm(clock, alarmID, ierr_tmp)
end if ! isRecurring
exit ! exit after we found the alarm we were looking for
end if ! if this alarm we were looking for
alarmPtr => alarmPtr % next
end do
end if ! thread check

!$omp barrier
end subroutine mpas_adjust_alarm_to_reference_time



! specify a valid previousRingTime for each alarm
subroutine mpas_calibrate_alarms(clock, ierr)
Expand Down