Skip to content

Commit

Permalink
Merge branch 'framework/interval_in-interval_out-support-for-streams'…
Browse files Browse the repository at this point in the history
… into develop

This merge adds new functionality at the mpas_timekeeping and mpas_stream_manager
levels to query the minimum interval among a list of alarms; at the stream manager
level, this list represents the minimum input or output interval for a specified
stream. For non-recurring alarms, a zero-length interval is returned.

* framework/interval_in-interval_out-support-for-streams:
  New function to query the minimum input or output interval of a stream
  New function to return the minimum alarm interval in an alarm list
  • Loading branch information
mgduda committed Sep 21, 2017
2 parents 30dc955 + 43f7f2b commit e466b46
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
85 changes: 85 additions & 0 deletions src/framework/mpas_stream_manager.F
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module mpas_stream_manager
MPAS_stream_mgr_get_next_stream, &
MPAS_stream_mgr_get_next_field, &
MPAS_stream_mgr_stream_exists, &
MPAS_stream_mgr_get_stream_interval, &
MPAS_get_stream_filename, &
MPAS_build_stream_filename

Expand Down Expand Up @@ -1506,6 +1507,90 @@ logical function MPAS_stream_mgr_ringing_alarms(manager, streamID, direction, ie
end function MPAS_stream_mgr_ringing_alarms !}}}
!-----------------------------------------------------------------------
! routine MPAS_stream_mgr_get_stream_interval
!
!> \brief Returns the minimum input/output interval for a stream
!> \author Dom Heinzeller
!> \date 28 August 2017
!> \details
!> Returns the minimum input or output interval for a given stream attached
!> to a stream manager. The mandatory input argument direction can take
!> values of MPAS_STREAM_INPUT (return minimum input interval) or
!> MPAS_STREAM_OUTPUT (return minimum output interval). If an error occurs,
!> a time interval of length zero and an error flag != MPAS_STREAM_MGR_NOERR
!> are returned.
!> Note: This function doesn't support streamID regular expressions
!
!-----------------------------------------------------------------------
function MPAS_stream_mgr_get_stream_interval(manager, streamID, direction, ierr) result(interval)

implicit none

type (MPAS_TimeInterval_type) :: interval

type (MPAS_streamManager_type), intent(in) :: manager
character(len=*), intent(in) :: streamID
integer, intent(in) :: direction
integer, intent(out) :: ierr

type (mpas_stream_list_type), pointer :: streamCursor, alarmCursor

ierr = MPAS_STREAM_MGR_NOERR
nullify(streamCursor)
call mpas_set_timeInterval(interval, dt = 0.0)

if ( mpas_stream_list_query(manager % streams, streamID, streamCursor) ) then

if (direction == MPAS_STREAM_INPUT) then

if (streamCursor % direction == MPAS_STREAM_INPUT .or. streamCursor % direction == MPAS_STREAM_INPUT_OUTPUT) then
alarmCursor => streamCursor % alarmList_in % head
call mpas_minimum_alarm_interval(manager % streamClock, alarmCursor, interval)
else if (streamCursor % direction == MPAS_STREAM_OUTPUT) then
ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Requested an input interval for output-only stream '// trim(streamID))
else if (streamCursor % direction == MPAS_STREAM_NONE) then
ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Requested an input interval for inactive stream '// trim(streamID))
else
ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Requested an input interval for stream '// trim(streamID) // ' with unknown direction')
end if

else if (direction == MPAS_STREAM_OUTPUT) then

if (streamCursor % direction == MPAS_STREAM_OUTPUT .or. streamCursor % direction == MPAS_STREAM_INPUT_OUTPUT) then
alarmCursor => streamCursor % alarmList_out % head
call mpas_minimum_alarm_interval(manager % streamClock, alarmCursor, interval)
else if (streamCursor % direction == MPAS_STREAM_INPUT) then
ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Requested an output interval for input-only stream '// trim(streamID))
else if (streamCursor % direction == MPAS_STREAM_NONE) then
ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Requested an output interval for inactive stream '// trim(streamID))
else
ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Requested an output interval for stream '// trim(streamID) // ' with unknown direction')
end if

else

ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Invalid direction encountered in MPAS_stream_mgr_get_stream_interval')

end if

else

ierr = MPAS_STREAM_MGR_ERROR
call MPAS_stream_mesg(manager % errorLevel, 'Stream ''' // trim(streamID) // ''' does not exist. Cannot retrieve stream input/output intervals')

end if

end function MPAS_stream_mgr_get_stream_interval


!-----------------------------------------------------------------------
! routine MPAS_stream_mgr_set_property_int
!
Expand Down
48 changes: 47 additions & 1 deletion src/framework/mpas_timekeeping.F
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,53 @@ type (MPAS_TimeInterval_type) function mpas_alarm_interval(clock, alarmID, ierr)
end function mpas_alarm_interval


!-----------------------------------------------------------------------
! routine mpas_minimum_alarm_interval
!
!> \brief This function returns the shortest alarm interval in an alarm list
!> \author Dom Heinzeller
!> \date 08/23/2017
!> \details This function returns the shortest alarm interval in an alarm list.
!> If the alarm list is empty or contains contains only one-off events (e.g.
!> initial_only, final_only), the resulting interval is set to zero. This
!> routine modifies the alarmListPtr and potentially leaves it in an
!> undefined status upon exit.
!-----------------------------------------------------------------------
subroutine mpas_minimum_alarm_interval(clock, alarmListPtr, interval)

implicit none

type (MPAS_Clock_type), intent(in) :: clock
type (MPAS_stream_list_type), pointer :: alarmListPtr
type (MPAS_TimeInterval_type), intent(out) :: interval

type (MPAS_Alarm_type), pointer :: alarmPtr
type (MPAS_TimeInterval_type) :: zero_interval

call mpas_set_timeInterval(zero_interval, dt = 0.0)
call mpas_set_timeInterval(interval, dt = 0.0)

do while(associated(alarmListPtr))
alarmPtr => clock % alarmListHead
do while (associated(alarmPtr))
if (trim(alarmPtr % alarmID) == trim(alarmListPtr % name)) then
if (alarmPtr % isRecurring) then
if (interval .eq. zero_interval) then
interval = alarmPtr % ringTimeInterval
else if (alarmPtr % ringTimeInterval .lt. interval) then
interval = alarmPtr % ringTimeInterval
end if
end if
exit
end if
alarmPtr => alarmPtr % next
end do
alarmListPtr => alarmListPtr % next
end do

end subroutine mpas_minimum_alarm_interval


!-----------------------------------------------------------------------
! routine mpas_alarm_get_next_ring_time
!
Expand Down Expand Up @@ -748,7 +795,6 @@ subroutine mpas_print_alarm(clock, alarmID, ierr)
end subroutine mpas_print_alarm



logical function mpas_is_alarm_ringing(clock, alarmID, interval, ierr)

implicit none
Expand Down

0 comments on commit e466b46

Please sign in to comment.