Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User specified history write frequency #353

Merged
Merged
Show file tree
Hide file tree
Changes from 2 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
7 changes: 4 additions & 3 deletions route/build/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,9 @@ DATATYPES = \
datetime_data.f90 \
csv_data.f90 \
globalData.f90 \
historyFile.f90 \
popMetadat.f90 \
histVars_data.f90 \
historyFile.f90 \
allocation.f90
# define utilities
UTILS = \
Expand Down Expand Up @@ -177,8 +178,8 @@ IO = \
standalone/read_remap.f90 \
io_rpointfile.f90 \
read_restart.f90 \
write_restart_pio.f90 \
write_simoutput_pio.f90
write_simoutput_pio.f90 \
write_restart_pio.f90
# CORE
CORE = \
accum_runoff.f90 \
Expand Down
1 change: 1 addition & 0 deletions route/build/cpl/RtmTimeManager.F90
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ SUBROUTINE init_time(ierr, message)
iTime = 1
simDatetime(0) = datetime(integerMissing, integerMissing, integerMissing, integerMissing, integerMissing, realMissing)
simDatetime(1) = begDatetime
simDatetime(2) = simDatetime(1)%add_sec(dt, calendar, ierr, cmessage)

if (masterproc .and. debug_write) then
write(iulog,*) 'simStart datetime = ', trim(simStart)
Expand Down
10 changes: 5 additions & 5 deletions route/build/src/globalData.f90
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ MODULE globalData
integer(i4b), public :: iTime ! time index at simulation time step
real(dp), public :: timeVar ! time variables (unit given by time variable)
real(dp), public :: TSEC(0:1) ! begning and end of time step since simulation started (sec)
type(datetime), public :: simDatetime(0:1) ! previous and current simulation time (yyyy:mm:dd:hh:mm:ss)
type(datetime), public :: simDatetime(0:2) ! previous, current and next simulation time (yyyy:mm:dd:hh:mm:ss)
type(datetime), public :: begDatetime ! simulation start date/time (yyyy:mm:dd:hh:mm:ss)
type(datetime), public :: endDatetime ! simulation end date/time (yyyy:mm:dd:hh:mm:ss)
type(datetime), public :: restDatetime ! desired restart date/time (yyyy:mm:dd:hh:mm:ss)
Expand All @@ -104,13 +104,13 @@ MODULE globalData

! ---------- Misc. data -------------------------------------------------------------------------
character(len=strLen), public :: runMode='standalone' ! run options: standalone or cesm-coupling
logical(lgt), public :: isHistFileOpen=.false. ! flag to indicate history output netcdf is open
integer(i4b), public :: ixPrint(1:2)=integerMissing ! index of desired reach to be on-screen print
integer(i4b), public :: nEns=1 ! number of ensemble
integer(i4b), public :: maxtdh ! maximum unit-hydrograph future time steps
type(cMolecule), public :: nMolecule ! number of computational molecule (used for KW, MC, DW)
character(300), public :: hfileout=charMissing ! name of the history output file
character(300), public :: hfileout_gage=charMissing ! name of the gage-only history output file
character(300), public :: rfileout=charMissing ! name of the restart output file
character(300), public :: hfileout=charMissing ! history output file name
character(300), public :: hfileout_gage=charMissing ! gage-only history output file name
character(300), public :: rfileout=charMissing ! restart output file name

! ---------- MPI/OMP/PIO variables ----------------------------------------------------------------

Expand Down
259 changes: 259 additions & 0 deletions route/build/src/histVars_data.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,259 @@
MODULE histVars_data

! history file variable data

USE nrtype
USE dataTypes, ONLY: STRFLX
USE var_lookup, ONLY: ixRFLX, nVarsRFLX
USE var_lookup, ONLY: ixHFLX, nVarsHFLX
USE public_var, ONLY: accumRunoff ! accum runoff ID = 0
USE public_var, ONLY: impulseResponseFunc ! IRF routing ID = 1
USE public_var, ONLY: kinematicWaveTracking ! KWT routing ID = 2
USE public_var, ONLY: kinematicWave ! KW routing ID = 3
USE public_var, ONLY: muskingumCunge ! MC routing ID = 4
USE public_var, ONLY: diffusiveWave ! DW routing ID = 5
USE globalData, ONLY: nRoutes
USE globalData, ONLY: routeMethods
USE globalData, ONLY: meta_rflx, meta_hflx
USE globalData, ONLY: idxSUM,idxIRF,idxKWT, &
idxKW,idxMC,idxDW

implicit none

public:: histVars

type :: histVars
integer(i4b) :: nt ! number of time steps over variables are aggregated
integer(i4b) :: nHru ! number of
integer(i4b) :: nRch ! number of
real(dp) :: timeVar ! time variable [unit] at nt = 1
real(sp), allocatable :: basRunoff(:) ! catchment average runoff [m/s] [nHru]
nmizukami marked this conversation as resolved.
Show resolved Hide resolved
real(sp), allocatable :: instRunoff(:) ! instantaneous lateral inflow into each river/lake [m3/s] [nRch]
real(sp), allocatable :: dlayRunoff(:) ! lateral inflow into river or lake [m3/s] for each reach [nRch]
real(sp), allocatable :: discharge(:,:) ! river/lake discharge [m3/s] for each reach/lake and routing method [nRch,nMethod]
real(sp), allocatable :: elev(:,:) ! river/lake surface water elevation [m] for each reach/lake and routing method [nRch,nMethod]
real(sp), allocatable :: volume(:,:) ! river/lake volume [m3] for each reach/lake and routing method [nRch,nMethod]

CONTAINS

procedure, public :: aggregate
nmizukami marked this conversation as resolved.
Show resolved Hide resolved
procedure, public :: finalize
procedure, public :: refresh
procedure, public :: clean

end type histVars

INTERFACE histVars
module procedure constructor
END INTERFACE histVars

CONTAINS

! -----------------------------------------------------
! constructor - instantiate history output data structure
! -----------------------------------------------------
FUNCTION constructor(nHru_local, nRch_local, ierr, message) RESULT(instHistVar)

implicit none
! argument variables
integer(i4b), intent(in) :: nHru_local ! number of hru in each proc
integer(i4b), intent(in) :: nRch_local ! number of Rch in each proc
integer(i4b), intent(out) :: ierr ! error code
character(*), intent(out) :: message ! error message
type(histVars) :: instHistVar
! local variables
character(strLen) :: cmessage ! error message from subroutine

ierr=0; message='initHistVars/'

instHistVar%nt = 0
instHistVar%nHru = nHRU_local
instHistVar%nRch = nRch_local

if (meta_hflx(ixHFLX%basRunoff)%varFile) then
allocate(instHistVar%basRunoff(nHRU_local), stat=ierr, errmsg=cmessage)
if(ierr/=0)then; message=trim(message)//trim(cmessage)//' [instHistVar%basRunoff]'; return; endif
instHistVar%basRunoff(1:nHRU_local) = 0._sp
end if

if (meta_rflx(ixRFLX%instRunoff)%varFile) then
allocate(instHistVar%instRunoff(nRch_local), stat=ierr, errmsg=cmessage)
if(ierr/=0)then; message=trim(message)//trim(cmessage)//' [instHistVar%instRunoff]'; return; endif
instHistVar%instRunoff(1:nRch_local) = 0._sp
end if

if (meta_rflx(ixRFLX%dlayRunoff)%varFile) then
allocate(instHistVar%dlayRunoff(nRch_local), stat=ierr, errmsg=cmessage)
if(ierr/=0)then; message=trim(message)//trim(cmessage)//' [instHistVar%instRunoff]'; return; endif
instHistVar%dlayRunoff(1:nRch_local) = 0._sp
end if

if (nRoutes>0) then ! this should be number of methods that ouput
allocate(instHistVar%discharge(nRch_local, nRoutes), stat=ierr, errmsg=cmessage)
if(ierr/=0)then; message=trim(message)//trim(cmessage)//' [instHistVar%discharge]'; return; endif
instHistVar%discharge(1:nRch_local, 1:nRoutes) = 0._sp

allocate(instHistVar%volume(nRch_local, nRoutes), stat=ierr, errmsg=cmessage)
if(ierr/=0)then; message=trim(message)//trim(cmessage)//' [instHistVar%volume]'; return; endif
instHistVar%volume(1:nRch_local, 1:nRoutes) = 0._sp
end if

END FUNCTION constructor

! ---------------------------------------------------------------
! accumulate data
! ---------------------------------------------------------------
SUBROUTINE aggregate(this, & ! inout:
timeVar_local, & ! input: time variables current
basRunoff_local, & ! input:
RCHFLX_local, & ! input:
ierr, message) ! output: error handling

implicit none
! argument variables
class(histVars), intent(inout) :: this
real(dp), intent(in) :: timeVar_local
real(dp), intent(in) :: basRunoff_local(:)
type(STRFLX), intent(in) :: RCHFLX_local(:,:)
integer(i4b), intent(out) :: ierr ! error code
character(*), intent(out) :: message ! error message
! local variables
integer(i4b) :: nHRU_input
integer(i4b) :: nRch_input
integer(i4b) :: ix, iRoute ! loop indices
integer(i4b) :: idxMethod ! temporal method index

ierr=0; message='aggregate/'

! -- increment number of sample
this%nt = this%nt + 1

if (this%nt == 1) then
this%timeVar = timeVar_local
end if

! -- array size checks - input data vs history output buffer
! hru and reach size in input data
nHru_input = size(basRunoff_local)
nRch_input = size(RCHFLX_local(1,:))
if (nHru_input/=this%nHru) then
write(message,'(2A,I,A,I)') trim(message),'history buffer hru size:',this%nHru,'/= input data hru size:',nHru_input
ierr=81; return
end if
if (nRch_input/=this%nRch) then
write(message,'(2A,I,A,I)') trim(message),'history buffer reach size:',this%nRch,'/= input data reach size:',nRch_input
ierr=81; return
end if

! ---- aggregate
! 1. basin runoff
nmizukami marked this conversation as resolved.
Show resolved Hide resolved
if (meta_hflx(ixHFLX%basRunoff)%varFile) then
this%basRunoff(1:this%nHRU) = this%basRunoff(1:this%nHRU) + basRunoff_local(1:this%nHru)
end if

! 2. instantaneous runoff into reach
if (meta_rflx(ixRFLX%instRunoff)%varFile) then
this%instRunoff(1:this%nRch) = this%instRunoff(1:this%nRch) + RCHFLX_local(1,1:this%nRch)%BASIN_QI
end if

! 3. delayed runoff into reach
if (meta_rflx(ixRFLX%dlayRunoff)%varFile) then
this%dlayRunoff(1:this%nRch) = this%dlayRunoff(1:this%nRch) + RCHFLX_local(1,1:this%nRch)%BASIN_QR(1)
end if

! 4. discharge and volume
do iRoute = 1, nRoutes
select case(routeMethods(iRoute))
case(accumRunoff); idxMethod=idxSUM
case(impulseResponseFunc); idxMethod=idxIRF
case(kinematicWaveTracking); idxMethod=idxKWT
case(kinematicWave); idxMethod=idxKW
case(muskingumCunge); idxMethod=idxMC
case(diffusiveWave); idxMethod=idxDW
case default
write(message,'(2A,X,I,X,A)') trim(message), 'routing method index:',routeMethods(iRoute), 'must be 0-5'
ierr=81; return
end select

do ix=1,this%nRch
this%discharge(ix,iRoute) = this%discharge(ix,iRoute) + RCHFLX_local(1,ix)%ROUTE(idxMethod)%REACH_Q
this%volume(ix,iRoute) = this%volume(ix,iRoute) + RCHFLX_local(1,ix)%ROUTE(idxMethod)%REACH_VOL(1)
end do
end do

END SUBROUTINE aggregate

! ---------------------------------------------------------------
! finalize output variable (compute mean)
! ---------------------------------------------------------------
SUBROUTINE finalize(this)

implicit none
! Argument variables
class(histVars), intent(inout) :: this

! ---- aggregate
! 1. basin runoff
if (allocated(this%basRunoff)) then
this%basRunoff = this%basRunoff/real(this%nt, kind=sp)
end if

! 2. instantaneous runoff into reach
if (allocated(this%instRunoff)) then
this%instRunoff = this%instRunoff/real(this%nt, kind=sp)
end if

! 3. delayed runoff into reach
if (allocated(this%dlayRunoff)) then
this%dlayRunoff = this%dlayRunoff/real(this%nt, kind=sp)
end if

! 4. discharge
if (allocated(this%discharge)) then
this%discharge = this%discharge/real(this%nt, kind=sp)
end if

! 5. volume
if (allocated(this%volume)) then
nmizukami marked this conversation as resolved.
Show resolved Hide resolved
this%volume = this%volume/real(this%nt, kind=sp)
end if

END SUBROUTINE finalize

! ---------------------------------------------------------------
! re-initialzae intantiated data structure
! ---------------------------------------------------------------
SUBROUTINE refresh(this)

implicit none
! Argument variables
class(histVars), intent(inout) :: this

this%nt = 0

if (allocated(this%basRunoff)) this%basRunoff = 0._sp
if (allocated(this%instRunoff)) this%instRunoff = 0._sp
if (allocated(this%dlayRunoff)) this%dlayRunoff = 0._sp
if (allocated(this%discharge)) this%discharge = 0._sp
if (allocated(this%volume)) this%volume = 0._sp

END SUBROUTINE refresh

! ---------------------------------------------------------------
! Release memory (deallocate array)
! ---------------------------------------------------------------
SUBROUTINE clean(this)

implicit none
! Argument variables
class(histVars), intent(inout) :: this

if (allocated(this%basRunoff)) deallocate(this%basRunoff)
if (allocated(this%instRunoff)) deallocate(this%instRunoff)
if (allocated(this%dlayRunoff)) deallocate(this%dlayRunoff)
if (allocated(this%discharge)) deallocate(this%discharge)
if (allocated(this%volume)) deallocate(this%volume)

END SUBROUTINE clean

END MODULE histVars_data
Loading