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

Commit

Permalink
Merge PR #1347 'akturner/framework/forcing_restart_timestamp' into de…
Browse files Browse the repository at this point in the history
…velop

These changes remove the need for the forcing system to write a text
file with restart timestamps for a forcing groups clock. Instead the
times are stored in the regular restart file. This requires a core to
define a nForcingGroupsMax dimension (larger than the number of forcing
groups on a domain) and a new "forcing" pool with three variables:

<var_struct name="forcing" time_levs="1" packages="pkgForcing">
  <var name="nForcingGroupCounter" type="integer" dimensions="Time"/>
  <var name="forcingGroupNames" type="text" dimensions="nForcingGroupsMax Time"/>
  <var name="forcingGroupRestartTimes" type="text" dimensions="nForcingGroupsMax Time"/>
</var_struct>
The latter two variables must be included in the core restart stream.
  • Loading branch information
mark-petersen committed Oct 2, 2017
2 parents e9ce203 + 49434b6 commit 9359319
Showing 1 changed file with 136 additions and 80 deletions.
216 changes: 136 additions & 80 deletions src/framework/mpas_forcing.F
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ module mpas_forcing

!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!
! mpas_forcing_init
! mpas_forcing_init_group
!
!> \brief Add a forcing group to the forcing group list
!> \author Adrian K. Turner, LANL
Expand All @@ -59,10 +59,8 @@ module mpas_forcing
!> time of the forcing group clock. Specify 'none' for this if no forcing
!> is desired. 'forcingCycleDuration' is the
!> timestamp of duration of the forcing clock. 'restart' is true if the
!> model is restarting. 'forcingRestartFile' is the filename of the file
!> from which forcing clock time will be read when restarting.
!> 'forcingCycleStartInclusive' (default: true) is true if the start time
!> of the forcing cycle is included in the cycle.
!> model is restarting. 'forcingCycleStartInclusive' (default: true) is
!> true if the start time of the forcing cycle is included in the cycle.
!
!-----------------------------------------------------------------------

Expand All @@ -74,7 +72,6 @@ subroutine mpas_forcing_init_group(&!{{{
forcingCycleStart, &
forcingCycleDuration, &
restart, &
forcingRestartFile, &
forcingCycleStartInclusive)

type(mpas_forcing_group_type), pointer :: &
Expand All @@ -87,10 +84,9 @@ subroutine mpas_forcing_init_group(&!{{{
domain !< Input: the domain to which data will be put

character(len=*), intent(in) :: &
startTimeStr, & !< Input: the forcing start time
forcingCycleStart, & !< Input: the forcing cycle start time string
forcingCycleDuration, & !< Input: the forcing cycle duration time string
forcingRestartFile !< Input: restart filename with forcing clock times
startTimeStr, & !< Input: the forcing start time
forcingCycleStart, & !< Input: the forcing cycle start time string
forcingCycleDuration !< Input: the forcing cycle duration time string

logical, intent(in) :: &
restart !< Input: whether this is a restarted run
Expand Down Expand Up @@ -139,11 +135,14 @@ subroutine mpas_forcing_init_group(&!{{{
! set the forcing group domain
forcingGroupNew % domain_ptr => domain

! add forcing group to restart counter
call add_forcing_group_to_restart_counter(forcingGroupNew)

! create the forcing clock
call mpas_set_timeInterval(timeStep, dt=0.0_RKIND)
call mpas_set_time(stopTime, dateTimeString="9999-12-31_23:59:59") ! shouldnt need to do this!
if (restart) then
call read_restart_times(forcingGroupNew, forcingRestartFile, timeStep, stopTime)
call get_restart_times(forcingGroupNew, timeStep, stopTime)
else
call mpas_set_time(startTime, dateTimeString=startTimeStr)
call mpas_create_clock(forcingGroupNew % forcingClock, startTime=startTime, timeStep=timeStep, stopTime=stopTime)
Expand Down Expand Up @@ -2494,154 +2493,211 @@ end subroutine forcing_shift_data!}}}
!
! mpas_forcing_write_restart_times
!
!> \brief write out forcing restart times
!> \brief set forcing restart times registry variables
!> \author Adrian K. Turner, LANL
!> \date 9th December 2014
!> \details
!> loop over the forcing groups in the forcing group object and write
!> out the forcing clock times to a restart file. 'forcingGroupHead'
!> is the forcing group object and 'forcingTimeRestartFilename' is the
!> filename of the file to write the restart times to.
!> out the forcing clock times to registry variables that are included
!> in the restart stream. 'forcingGroupHead' is the forcing group
!> object
!
!-----------------------------------------------------------------------

subroutine mpas_forcing_write_restart_times(forcingGroupHead, forcingTimeRestartFilename)!{{{
subroutine mpas_forcing_write_restart_times(forcingGroupHead)!{{{

type(mpas_forcing_group_type), pointer :: &
forcingGroupHead ! forcing group linked list head pointer

character(len=*), intent(in) :: &
forcingTimeRestartFilename ! name of the file containing the restart times

type(mpas_forcing_group_type), pointer :: &
forcingGroup ! forcing group iterator

type(MPAS_time_type) :: forcingClockTime
type(MPAS_time_type) :: &
forcingClockTime

character(len=strKIND) :: forcingClockTimeStr
character(len=strKIND) :: &
forcingClockTimeStr

integer :: restartTimestampUnit
type(block_type), pointer :: &
block

! open restart time file
type(mpas_pool_type), pointer :: &
forcingPool

integer, pointer :: &
nForcingGroupCounter

character(len=strKIND), dimension(:), pointer :: &
forcingGroupNames, &
forcingGroupRestartTimes

! loop over forcing groups
forcingGroup => forcingGroupHead
do while (associated(forcingGroup))

if (forcingGroup % domain_ptr % dminfo % my_proc_id == IO_NODE) then
block => forcingGroup % domain_ptr % blocklist
do while (associated(block))

call mpas_new_unit(restartTimestampUnit)
open(restartTimestampUnit,file=trim(forcingTimeRestartFilename), form='formatted', status='replace')
exit
call MPAS_pool_get_subpool(block % structs, "forcing", forcingPool)

endif
call MPAS_pool_get_array(forcingPool, "nForcingGroupCounter", nforcingGroupCounter)

nforcingGroupCounter = 0

block => block % next
end do

forcingGroup => forcingGroup % next
enddo
end do

! loop over forcing groups
forcingGroup => forcingGroupHead
do while (associated(forcingGroup))

if (forcingGroup % domain_ptr % dminfo % my_proc_id == IO_NODE) then
! get the forcing clock time
forcingClockTime = MPAS_get_clock_time(forcingGroup % forcingClock, MPAS_NOW)

! get the forcing clock time
forcingClockTime = MPAS_get_clock_time(forcingGroup % forcingClock, MPAS_NOW)
call MPAS_get_time(forcingClockTime, dateTimeString=forcingClockTimeStr)

call MPAS_get_time(forcingClockTime, dateTimeString=forcingClockTimeStr)
block => forcingGroup % domain_ptr % blocklist
do while (associated(block))

! write the forcing time to the restart file
write(restartTimestampUnit,*) trim(forcingGroup % forcingGroupName), " ", trim(forcingClockTimeStr)
call MPAS_pool_get_subpool(block % structs, "forcing", forcingPool)

endif
call MPAS_pool_get_array(forcingPool, "nForcingGroupCounter", nForcingGroupCounter)
call MPAS_pool_get_array(forcingPool, "forcingGroupNames", forcingGroupNames)
call MPAS_pool_get_array(forcingPool, "forcingGroupRestartTimes", forcingGroupRestartTimes)

nForcingGroupCounter = nForcingGroupCounter + 1
forcingGroupNames (nforcingGroupCounter) = trim(forcingGroup % forcingGroupName)
forcingGroupRestartTimes(nforcingGroupCounter) = trim(forcingClockTimeStr)

block => block % next
end do

forcingGroup => forcingGroup % next
end do

! close the file
forcingGroup => forcingGroupHead
do while (associated(forcingGroup))
end subroutine mpas_forcing_write_restart_times!}}}

!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!
! add_forcing_group_to_restart_counter
!
!> \brief checks number of forcing groups
!> \author Adrian K. Turner, LANL
!> \date 16th May 2017
!> \details
!> This routine checks that the number of forcing groups per domain
!> does not exceed the maximum allowed.
!
!-----------------------------------------------------------------------

subroutine add_forcing_group_to_restart_counter(forcingGroup)

type(mpas_forcing_group_type), pointer :: &
forcingGroup ! forcing group

type(block_type), pointer :: &
block

integer, pointer :: &
nForcingGroupsMax, &
nforcingGroupCounter

type(mpas_pool_type), pointer :: &
forcingPool

block => forcingGroup % domain_ptr % blocklist
do while (associated(block))

call MPAS_pool_get_dimension(block % dimensions, "nForcingGroupsMax", nForcingGroupsMax)

call MPAS_pool_get_subpool(block % structs, "forcing", forcingPool)

call MPAS_pool_get_array(forcingPool, "nForcingGroupCounter", nforcingGroupCounter)

nforcingGroupCounter = nforcingGroupCounter + 1

if (nforcingGroupCounter > nForcingGroupsMax) then

call mpas_log_write(&
"Init forcing group: "//trim(forcingGroup % forcingGroupName)//&
", nForcingGroupsMax too small, nForcingGroupsMax: $i, nforcingGroupCounter: $i", &
MPAS_LOG_CRIT, &
intArgs=(/nForcingGroupsMax,nforcingGroupCounter/))

if (forcingGroup % domain_ptr % dminfo % my_proc_id == IO_NODE) then
close(restartTimestampUnit)
call mpas_release_unit(restartTimestampUnit)
exit
endif

forcingGroup => forcingGroup % next
block => block % next
end do

end subroutine mpas_forcing_write_restart_times!}}}
end subroutine add_forcing_group_to_restart_counter

!|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
!
! read_restart_times
! get_restart_times
!
!> \brief read in forcing restart times
!> \brief get forcing restart times and create forcing clocks.
!> \author Adrian K. Turner, LANL
!> \date 9th December 2014
!> \details
!> read in the forcing group restart times from an external file and
!> set the correct forcing group clock to this time
!> The forcing clock restart times have been read in from the restart
!> file. This routine sets the forcing group clock from those times.
!
!-----------------------------------------------------------------------

subroutine read_restart_times(&!{{{
subroutine get_restart_times(&!{{{
forcingGroup, &
forcingTimeRestartFilename, &
timeStep, &
stopTime)

type(mpas_forcing_group_type), pointer :: &
forcingGroup ! forcing group to restart

character(len=*), intent(in) :: &
forcingTimeRestartFilename ! name of the file containing the restart times

type(MPAS_TimeInterval_type), intent(in) :: &
timeStep ! simulation time step

type(MPAS_Time_type), intent(in) :: &
stopTime ! stop time of forcing clock - !!!! SHOULDNT BE NEEDED

type(MPAS_time_type) :: forcingClockTime
type(MPAS_time_type) :: &
forcingClockTime

character(len=strKIND) :: &
forcingClockTimeStr, &
forcingGroupName
type(mpas_pool_type), pointer :: &
forcingPool

integer, pointer :: &
nForcingGroupsMax

integer :: &
status
iForcingGroup

! open restart time file
open(22,file=trim(forcingTimeRestartFilename), form='formatted', action='read')
character(len=strKIND), dimension(:), pointer :: &
forcingGroupNames, &
forcingGroupRestartTimes

! loop over entries in restart file
do
call mpas_pool_get_subpool(forcingGroup % domain_ptr % blocklist % structs, "forcing", forcingPool)

! read restart entry
read(22,*,iostat=status) forcingGroupName, forcingClockTimeStr
call MPAS_pool_get_array(forcingPool, "forcingGroupNames", forcingGroupNames)
call MPAS_pool_get_array(forcingPool, "forcingGroupRestartTimes", forcingGroupRestartTimes)

FORCING_DEBUG_WRITE('-- Forcing: read_restart_times: '//trim(forcingGroup % forcingGroupName)//' '//trim(forcingGroupName)//' '//trim(forcingClockTimeStr))
call mpas_pool_get_dimension(forcingGroup % domain_ptr % blocklist % dimensions, "nForcingGroupsMax", nForcingGroupsMax)

! find the correct forcing group
if (trim(forcingGroup % forcingGroupName) == trim(forcingGroupName)) then
do iForcingGroup = 1, nForcingGroupsMax

if (trim(forcingGroup % forcingGroupName) == trim(forcingGroupNames(iForcingGroup)(1:ShortStrKind))) then

! set the forcing group time
FORCING_DEBUG_WRITE('-- Forcing: read_restart_times: set time' COMMA " " COMMA trim(forcingClockTimeStr))
call MPAS_set_time(forcingClockTime, dateTimeString=trim(forcingClockTimeStr))
FORCING_DEBUG_WRITE('-- Forcing: read_restart_times: create clock')
call mpas_create_clock(forcingGroup % forcingClock, startTime=forcingClockTime, timeStep=timeStep, stopTime=stopTime)

exit
endif
call MPAS_set_time(forcingClockTime, dateTimeString=trim(forcingGroupRestartTimes(iForcingGroup)(1:ShortStrKind)))

! stop reading if at end of file
if (status < 0) exit
call mpas_create_clock(forcingGroup % forcingClock, startTime=forcingClockTime, timeStep=timeStep, stopTime=stopTime)

end do
endif

close(22)
enddo ! iForcingGroup

end subroutine read_restart_times!}}}
end subroutine get_restart_times!}}}

!-----------------------------------------------------------------------

Expand Down

0 comments on commit 9359319

Please sign in to comment.