diff --git a/src/OrchestratorLayer/config.f90 b/src/OrchestratorLayer/config.f90 index 819a72e04..a8be8e2d4 100644 --- a/src/OrchestratorLayer/config.f90 +++ b/src/OrchestratorLayer/config.f90 @@ -123,6 +123,7 @@ module config_base character(len=256) :: route_chan_f="" character(len=256) :: route_link_f="" character(len=256) :: route_lake_f="" + integer :: lake_option logical :: reservoir_persistence_usgs logical :: reservoir_persistence_usace character(len=256) :: reservoir_parameter_file="" @@ -223,168 +224,208 @@ subroutine rt_nlst_check(self) ! ! Go through and make some logical checks for each hydro.namelist option. ! ! Some of these checks will depend on specific options chosen by the user. - if( (self%sys_cpl .lt. 1) .or. (self%sys_cpl .gt. 4) ) then + if ( (self%sys_cpl .lt. 1) .or. (self%sys_cpl .gt. 4) ) then call hydro_stop("hydro.namelist ERROR: Invalid sys_cpl value specified.") - endif - if(len(trim(self%geo_static_flnm)) .eq. 0) then + endif + + if (len(trim(self%geo_static_flnm)) .eq. 0) then call hydro_stop("hydro.namelist ERROR: Please specify a GEO_STATIC_FLNM file.") else inquire(file=trim(self%geo_static_flnm),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: GEO_STATIC_FLNM not found.') endif - if(len(trim(self%geo_finegrid_flnm)) .eq. 0) then + + if (len(trim(self%geo_finegrid_flnm)) .eq. 0) then call hydro_stop("hydro.namelist ERROR: Please specify a GEO_FINEGRID_FLNM file.") else inquire(file=trim(self%geo_finegrid_flnm),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: GEO_FINEGRID_FLNM not found.') endif + !if(len(trim(self%land_spatial_meta_flnm)) .eq. 0) then ! call hydro_stop("hydro.namelist ERROR: Please specify a LAND_SPATIAL_META_FLNM file.") !else ! inquire(file=trim(self%land_spatial_meta_flnm),exist=fileExists) ! if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: LAND_SPATIAL_META_FLNM not found.') !endif - if(len(trim(self%RESTART_FILE)) .ne. 0) then + + if (len(trim(self%RESTART_FILE)) .ne. 0) then inquire(file=trim(self%RESTART_FILE),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR:= Hydro RESTART_FILE not found.') endif - if(self%igrid .le. 0) call hydro_stop('hydro.namelist ERROR: Invalid IGRID specified.') - if(self%out_dt .le. 0) call hydro_stop('hydro_namelist ERROR: Invalid out_dt specified.') - if( (self%split_output_count .lt. 0 ) .or. (self%split_output_count .gt. 1) ) then + + if (self%igrid .le. 0) call hydro_stop('hydro.namelist ERROR: Invalid IGRID specified.') + + if (self%out_dt .le. 0) call hydro_stop('hydro_namelist ERROR: Invalid out_dt specified.') + + if ((self%split_output_count .lt. 0 ) .or. (self%split_output_count .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid SPLIT_OUTPUT_COUNT specified') endif - if( (self%rst_typ .lt. 0 ) .or. (self%rst_typ .gt. 1) ) then + + if ((self%rst_typ .lt. 0 ) .or. (self%rst_typ .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid rst_typ specified') endif - if( (self%rst_bi_in .lt. 0 ) .or. (self%rst_bi_in .gt. 1) ) then + + if ((self%rst_bi_in .lt. 0 ) .or. (self%rst_bi_in .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid rst_bi_in specified') endif - if( (self%rst_bi_out .lt. 0 ) .or. (self%rst_bi_out .gt. 1) ) then + + if ((self%rst_bi_out .lt. 0 ) .or. (self%rst_bi_out .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid rst_bi_out specified') endif - if( (self%RSTRT_SWC .lt. 0 ) .or. (self%RSTRT_SWC .gt. 1) ) then + + if ((self%RSTRT_SWC .lt. 0 ) .or. (self%RSTRT_SWC .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid RSTRT_SWC specified') endif - if( (self%GW_RESTART .lt. 0 ) .or. (self%GW_RESTART .gt. 1) ) then + + if ((self%GW_RESTART .lt. 0 ) .or. (self%GW_RESTART .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid GW_RESTART specified') endif - if( (self%order_to_write .lt. 1 ) .or. (self%order_to_write .gt. 12) ) then + + if ((self%order_to_write .lt. 1 ) .or. (self%order_to_write .gt. 12) ) then call hydro_stop('hydro.namelist ERROR: Invalid order_to_write specified') endif - if( (self%io_form_outputs .lt. 0 ) .or. (self%io_form_outputs .gt. 4) ) then + + if ((self%io_form_outputs .lt. 0 ) .or. (self%io_form_outputs .gt. 4) ) then call hydro_stop('hydro.namelist ERROR: Invalid io_form_outputs specified') endif - if( (self%io_config_outputs .lt. 0 ) .or. (self%io_config_outputs .gt. 6) ) then + + if ((self%io_config_outputs .lt. 0 ) .or. (self%io_config_outputs .gt. 6) ) then call hydro_stop('hydro.namelist ERROR: Invalid io_config_outputs specified') endif - if( (self%t0OutputFlag .lt. 0 ) .or. (self%t0OutputFlag .gt. 1) ) then + + if ((self%t0OutputFlag .lt. 0 ) .or. (self%t0OutputFlag .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid t0OutputFlag specified') endif - if( (self%output_channelBucket_influx .lt. 0 ) .or. (self%output_channelBucket_influx .gt. 3) ) then + + if ((self%output_channelBucket_influx .lt. 0 ) .or. (self%output_channelBucket_influx .gt. 3) ) then call hydro_stop('hydro.namelist ERROR: Invalid output_channelBucket_influx specified') endif - if( (self%CHRTOUT_DOMAIN .lt. 0 ) .or. (self%CHRTOUT_DOMAIN .gt. 1) ) then + + if ((self%CHRTOUT_DOMAIN .lt. 0 ) .or. (self%CHRTOUT_DOMAIN .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid CHRTOUT_DOMAIN specified') endif - if( (self%CHANOBS_DOMAIN .lt. 0 ) .or. (self%CHANOBS_DOMAIN .gt. 1) ) then + + if ((self%CHANOBS_DOMAIN .lt. 0 ) .or. (self%CHANOBS_DOMAIN .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid CHANOBS_DOMAIN specified') endif - if( (self%CHRTOUT_GRID .lt. 0 ) .or. (self%CHRTOUT_GRID .gt. 1) ) then + + if ((self%CHRTOUT_GRID .lt. 0 ) .or. (self%CHRTOUT_GRID .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid CHRTOUT_GRID specified') endif - if( (self%LSMOUT_DOMAIN .lt. 0 ) .or. (self%LSMOUT_DOMAIN .gt. 1) ) then + + if ((self%LSMOUT_DOMAIN .lt. 0 ) .or. (self%LSMOUT_DOMAIN .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid LSMOUT_DOMAIN specified') endif - if( (self%RTOUT_DOMAIN .lt. 0 ) .or. (self%RTOUT_DOMAIN .gt. 1) ) then + + if ((self%RTOUT_DOMAIN .lt. 0 ) .or. (self%RTOUT_DOMAIN .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid RTOUT_DOMAIN specified') endif - if( (self%output_gw .lt. 0 ) .or. (self%output_gw .gt. 2) ) then + + if ((self%output_gw .lt. 0 ) .or. (self%output_gw .gt. 2) ) then call hydro_stop('hydro.namelist ERROR: Invalid output_gw specified') endif - if( (self%outlake .lt. 0 ) .or. (self%outlake .gt. 2) ) then + + if ((self%outlake .lt. 0 ) .or. (self%outlake .gt. 2) ) then call hydro_stop('hydro.namelist ERROR: Invalid outlake specified') endif - if( (self%frxst_pts_out .lt. 0 ) .or. (self%frxst_pts_out .gt. 1) ) then + + if ((self%frxst_pts_out .lt. 0 ) .or. (self%frxst_pts_out .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid frxst_pts_out specified') endif - if(self%TERADJ_SOLAR .ne. 0) then + + if (self%TERADJ_SOLAR .ne. 0) then call hydro_stop('hydro.namelist ERROR: Invalid TERADJ_SOLAR specified') endif ! The default value of nsoil == -999. When channel-only is used, ! nsoil == -999999. In the case of channel-only, skip following block of code. - if(self%NSOIL .le. 0 .and. self%NSOIL .ne. -999999) then + if (self%NSOIL .le. 0 .and. self%NSOIL .ne. -999999) then call hydro_stop('hydro.namelist ERROR: Invalid NSOIL specified.') endif + do i = 1,self%NSOIL - if(self%ZSOIL8(i) .gt. 0) then + if (self%ZSOIL8(i) .gt. 0) then call hydro_stop('hydro.namelist ERROR: Invalid ZSOIL layer depth specified.') endif - if(i .gt. 1) then - if(self%ZSOIL8(i) .ge. self%ZSOIL8(i-1)) then + if (i .gt. 1) then + if (self%ZSOIL8(i) .ge. self%ZSOIL8(i-1)) then call hydro_stop('hydro.namelist ERROR: Invalid ZSOIL layer depth specified.') endif endif end do - if(self%NSOIL .le. 0 .and. self%NSOIL .ne. -999999) then + if (self%NSOIL .le. 0 .and. self%NSOIL .ne. -999999) then call hydro_stop('hydro.namelist ERROR: Invalid NSOIL specified.') endif - if(self%dxrt0 .le. 0) then + if (self%dxrt0 .le. 0) then call hydro_stop('hydro.namelist ERROR: Invalid DXRT specified.') endif - if(self%AGGFACTRT .le. 0) then + + if (self%AGGFACTRT .le. 0) then call hydro_stop('hydro.namelist ERROR: Invalid AGGFACTRT specified.') endif - if(self%DTRT_CH .le. 0) then + + if (self%DTRT_CH .le. 0) then call hydro_stop('hydro.namelist ERROR: Invalid DTRT_CH specified.') endif - if(self%DTRT_TER .le. 0) then + + if (self%DTRT_TER .le. 0) then call hydro_stop('hydro.namelist ERROR: Invalid DTRT_TER specified.') endif - if( (self%SUBRTSWCRT .lt. 0 ) .or. (self%SUBRTSWCRT .gt. 1) ) then + + if ((self%SUBRTSWCRT .lt. 0 ) .or. (self%SUBRTSWCRT .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid SUBRTSWCRT specified') endif - if( (self%OVRTSWCRT .lt. 0 ) .or. (self%OVRTSWCRT .gt. 1) ) then + + if ((self%OVRTSWCRT .lt. 0 ) .or. (self%OVRTSWCRT .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid OVRTSWCRT specified') endif - if( (self%OVRTSWCRT .eq. 1 ) .or. (self%SUBRTSWCRT .eq. 1) ) then + + if ((self%OVRTSWCRT .eq. 1 ) .or. (self%SUBRTSWCRT .eq. 1) ) then if( (self%rt_option .lt. 1 ) .or. (self%rt_option .gt. 2) ) then !if(self%rt_option .ne. 1) then call hydro_stop('hydro.namelist ERROR: Invalid rt_option specified') endif endif - if( (self%CHANRTSWCRT .lt. 0 ) .or. (self%CHANRTSWCRT .gt. 1) ) then + + if ((self%CHANRTSWCRT .lt. 0 ) .or. (self%CHANRTSWCRT .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid CHANRTSWCRT specified') endif - if(self%CHANRTSWCRT .eq. 1) then - if ( self%channel_option .eq. 5 ) then + + if (self%CHANRTSWCRT .eq. 1) then + if (self%channel_option .eq. 5 ) then self%channel_option = 2 self%channel_bypass = .TRUE. endif - if( (self%channel_option .lt. 1 ) .or. (self%channel_option .gt. 3) ) then + if ((self%channel_option .lt. 1 ) .or. (self%channel_option .gt. 3) ) then call hydro_stop('hydro.namelist ERROR: Invalid channel_option specified') endif endif - if( (self%CHANRTSWCRT .eq. 1) .and. (self%channel_option .lt. 3) ) then - if(len(trim(self%route_link_f)) .eq. 0) then + + if ((self%CHANRTSWCRT .eq. 1) .and. (self%channel_option .lt. 3) ) then + if (len(trim(self%route_link_f)) .eq. 0) then call hydro_stop("hydro.namelist ERROR: Please specify a route_link_f file.") else inquire(file=trim(self%route_link_f),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: route_link_f not found.') endif endif - if( (self%bucket_loss .lt. 0 ) .or. (self%bucket_loss .gt. 1) ) then + + if ((self%bucket_loss .lt. 0 ) .or. (self%bucket_loss .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid bucket_loss specified') endif - if( (self%bucket_loss .eq. 1 ) .and. (self%UDMP_OPT .ne. 1) ) then + + if ((self%bucket_loss .eq. 1 ) .and. (self%UDMP_OPT .ne. 1) ) then call hydro_stop('hydro.namelist ERROR: Bucket loss only available when UDMP=1') endif - if( (self%GWBASESWCRT .lt. 0 ) .or. (self%GWBASESWCRT .gt. 4) ) then + + if ((self%GWBASESWCRT .lt. 0 ) .or. (self%GWBASESWCRT .gt. 4) ) then call hydro_stop('hydro.namelist ERROR: Invalid GWBASESWCRT specified') endif - if( (self%GWBASESWCRT .eq. 1 ) .or. (self%GWBASESWCRT .eq. 4) ) then + + if ((self%GWBASESWCRT .eq. 1 ) .or. (self%GWBASESWCRT .eq. 4) ) then if(len(trim(self%GWBUCKPARM_file)) .eq. 0) then call hydro_stop("hydro.namelist ERROR: Please specify a GWBUCKPARM_file file.") else @@ -392,7 +433,8 @@ subroutine rt_nlst_check(self) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: GWBUCKPARM_file not found.') endif endif - if( (self%GWBASESWCRT .gt. 0) .and. (self%UDMP_OPT .ne. 1) ) then + + if ((self%GWBASESWCRT .gt. 0) .and. (self%UDMP_OPT .ne. 1) ) then if(len(trim(self%gwbasmskfil)) .eq. 0) then call hydro_stop("hydro.namelist ERROR: Please specify a gwbasmskfil file.") else @@ -400,10 +442,12 @@ subroutine rt_nlst_check(self) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: gwbasmskfil not found.') endif endif - if( (self%UDMP_OPT .lt. 0 ) .or. (self%UDMP_OPT .gt. 1) ) then + + if ((self%UDMP_OPT .lt. 0 ) .or. (self%UDMP_OPT .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid UDMP_OPT specified') endif - if(self%UDMP_OPT .gt. 0) then + + if (self%UDMP_OPT .gt. 0) then if(len(trim(self%udmap_file)) .eq. 0) then call hydro_stop("hydro.namelist ERROR: Please specify a udmap_file file.") else @@ -411,70 +455,77 @@ subroutine rt_nlst_check(self) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: udmap_file not found.') endif endif - if( (self%UDMP_OPT .eq. 1) .and. (self%CHANRTSWCRT .eq. 0) ) then + + if ((self%UDMP_OPT .eq. 1) .and. (self%CHANRTSWCRT .eq. 0) ) then call hydro_stop('hydro.namelist ERROR: User-defined mapping requires channel routing on.') endif - if(self%outlake .ne. 0) then - if(len(trim(self%route_lake_f)) .eq. 0) then - call hydro_stop('hydro.namelist ERROR: You MUST specify a route_lake_f to ouptut and run lakes.') + + if ((self%outlake .ne. 0) .or. (self%lake_option > 0)) then + if (len(trim(self%route_lake_f)) .eq. 0) then + call hydro_stop('hydro.namelist ERROR: You MUST specify a route_lake_f to output and/or run lakes.') endif endif - if(len(trim(self%route_lake_f)) .ne. 0) then + + if (len(trim(self%route_lake_f)) .ne. 0) then inquire(file=trim(self%route_lake_f),exist=fileExists) - if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: route_lake_f not found.') + if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: specified route_lake_f ('//trim(self%route_lake_f)//') not found.') endif - if((self%channel_option .eq. 3) .and. (self%compound_channel)) then + if ((self%channel_option .eq. 3) .and. (self%compound_channel)) then call hydro_stop("Compound channel option not available for diffusive wave routing. ") end if - if(self%reservoir_type_specified) then - if(len(trim(self%reservoir_parameter_file)) .eq. 0) then + if ((self%lake_option .lt. 0) .and. (self%lake_option .gt. 3)) then + call hydro_stop("Lake Option must be 0 [lakes off], 1 [level pool], or 2 [passthrough], or 3 [reservoir DA]") + end if + + if (self%reservoir_type_specified) then + if (len(trim(self%reservoir_parameter_file)) .eq. 0) then call hydro_stop('hydro.namelist ERROR: You MUST specify a reservoir_parameter_file for & inputs to reservoirs that are not level pool type.') endif - if(len(trim(self%reservoir_parameter_file)) .ne. 0) then + if (len(trim(self%reservoir_parameter_file)) .ne. 0) then inquire(file=trim(self%reservoir_parameter_file),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: reservoir_parameter_file not found.') endif end if - if(self%reservoir_persistence_usgs) then - if(len(trim(self%reservoir_usgs_timeslice_path)) .eq. 0) then + if (self%reservoir_persistence_usgs) then + if (len(trim(self%reservoir_usgs_timeslice_path)) .eq. 0) then call hydro_stop('hydro.namelist ERROR: You MUST specify a reservoir_usgs_timeslice_path for & reservoir USGS persistence capability.') endif - if(len(trim(self%reservoir_parameter_file)) .ne. 0) then + if (len(trim(self%reservoir_parameter_file)) .ne. 0) then inquire(file=trim(self%reservoir_parameter_file),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: reservoir_parameter_file not found.') endif end if - if(self%reservoir_persistence_usace) then - if(len(trim(self%reservoir_usace_timeslice_path)) .eq. 0) then + if (self%reservoir_persistence_usace) then + if (len(trim(self%reservoir_usace_timeslice_path)) .eq. 0) then call hydro_stop('hydro.namelist ERROR: You MUST specify a reservoir_usace_timeslice_path for & reservoir USACE persistence capability.') endif - if(len(trim(self%reservoir_parameter_file)) .ne. 0) then + if (len(trim(self%reservoir_parameter_file)) .ne. 0) then inquire(file=trim(self%reservoir_parameter_file),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: reservoir_parameter_file not found.') endif end if - if(self%reservoir_rfc_forecasts) then - if(len(trim(self%reservoir_parameter_file)) .eq. 0) then + if (self%reservoir_rfc_forecasts) then + if (len(trim(self%reservoir_parameter_file)) .eq. 0) then call hydro_stop('hydro.namelist ERROR: You MUST specify a reservoir_parameter_file for inputs to rfc forecast type reservoirs.') endif - if(len(trim(self%reservoir_rfc_forecasts_time_series_path)) .eq. 0) then + if (len(trim(self%reservoir_rfc_forecasts_time_series_path)) .eq. 0) then call hydro_stop('hydro.namelist ERROR: You MUST specify a reservoir_rfc_forecasts_time_series_path for reservoir rfc forecast capability.') endif - if(len(trim(self%reservoir_parameter_file)) .ne. 0) then + if (len(trim(self%reservoir_parameter_file)) .ne. 0) then inquire(file=trim(self%reservoir_parameter_file),exist=fileExists) if (.not. fileExists) call hydro_stop('hydro.namelist ERROR: reservoir_parameter_file not found.') endif end if - if( (self%imperv_adj .lt. 0 ) .or. (self%imperv_adj .gt. 1) ) then + if ((self%imperv_adj .lt. 0 ) .or. (self%imperv_adj .gt. 1) ) then call hydro_stop('hydro.namelist ERROR: Invalid imperv_adj specified') endif @@ -486,6 +537,8 @@ subroutine init_namelist_rt_field(did) integer, intent(in) :: did integer ierr + character(len=512) :: msg + integer:: RT_OPTION, CHANRTSWCRT, channel_option, & SUBRTSWCRT,OVRTSWCRT,AGGFACTRT, & GWBASESWCRT, GW_RESTART,RSTRT_SWC,TERADJ_SOLAR, & @@ -499,6 +552,7 @@ subroutine init_namelist_rt_field(did) logical :: compound_channel integer :: channel_loss_option = 0 character(len=256) :: route_lake_f="" + integer :: lake_option !0: lakes off 1: level pool 2: passthrough, 3: reservoir da logical :: reservoir_persistence_usgs logical :: reservoir_persistence_usace character(len=256) :: reservoir_parameter_file="" @@ -573,11 +627,8 @@ subroutine init_namelist_rt_field(did) SUBRTSWCRT,OVRTSWCRT,AGGFACTRT, dtrt_ter,dtrt_ch,dxrt,& GwSpinCycles, GwPreCycles, GwSpinUp, GwPreDiag, GwPreDiagInterval, gwIhShift, & GWBASESWCRT, gwChanCondSw, gwChanCondConstIn, gwChanCondConstOut , & - route_topo_f,route_chan_f,route_link_f, compound_channel, channel_loss_option, route_lake_f, & - reservoir_persistence_usgs, reservoir_persistence_usace, reservoir_parameter_file, reservoir_usgs_timeslice_path, & - reservoir_usace_timeslice_path, reservoir_observation_lookback_hours, reservoir_observation_update_time_interval_seconds, & - reservoir_rfc_forecasts, reservoir_rfc_forecasts_time_series_path, reservoir_rfc_forecasts_lookback_hours, & - reservoir_type_specified, route_direction_f,route_order_f,gwbasmskfil, & + route_topo_f,route_chan_f,route_link_f, compound_channel, channel_loss_option, lake_option, route_lake_f, & + route_direction_f,route_order_f,gwbasmskfil, & geo_finegrid_flnm, gwstrmfil,GW_RESTART,RSTRT_SWC,TERADJ_SOLAR, sys_cpl, & order_to_write , rst_typ, rst_bi_in, rst_bi_out, gwsoilcpl, & CHRTOUT_DOMAIN,CHANOBS_DOMAIN,CHRTOUT_GRID,LSMOUT_DOMAIN,& @@ -585,6 +636,12 @@ subroutine init_namelist_rt_field(did) frxst_pts_out, udmap_file, UDMP_OPT, GWBUCKPARM_file, bucket_loss, & io_config_outputs, io_form_outputs, hydrotbl_f, t0OutputFlag, output_channelBucket_influx, imperv_adj + namelist /reservoir_nlist/ & + reservoir_persistence_usgs, reservoir_persistence_usace, reservoir_parameter_file, reservoir_usgs_timeslice_path, & + reservoir_usace_timeslice_path, reservoir_observation_lookback_hours, reservoir_observation_update_time_interval_seconds, & + reservoir_rfc_forecasts, reservoir_rfc_forecasts_time_series_path, reservoir_rfc_forecasts_lookback_hours, & + reservoir_type_specified + #ifdef WRF_HYDRO_NUDGING namelist /NUDGING_nlist/ nudgingParamFile, netwkReExFile, & readTimesliceParallel, temporalPersistence, & @@ -612,6 +669,7 @@ subroutine init_namelist_rt_field(did) compound_channel = .FALSE. channel_loss_option = 0 bucket_loss = 0 + lake_option = 1 reservoir_persistence_usgs = .FALSE. reservoir_persistence_usace = .FALSE. reservoir_observation_lookback_hours = 18 @@ -646,12 +704,17 @@ subroutine init_namelist_rt_field(did) #else open(12, form="FORMATTED") #endif - read(12, HYDRO_nlist, iostat=ierr) - if(ierr .ne. 0) call hydro_stop("HYDRO_nlst namelist error in read_rt_nlst") + read(12, HYDRO_nlist, iostat=ierr, iomsg=msg) + if(ierr .ne. 0) call hydro_stop("HYDRO_nlst namelist error in read_rt_nlst: " // trim(msg)) + + if (lake_option == 3) then + read(12, reservoir_nlist, iostat=ierr, iomsg=msg) + if (ierr /= 0) call hydro_stop("reservoir_nlist namelist error in read_rt_nlst: " // trim(msg)) + end if #ifdef WRF_HYDRO_NUDGING - read(12, NUDGING_nlist, iostat=ierr) - if(ierr .ne. 0) call hydro_stop("NUDGING_nlst namelist error in read_rt_nlst") + read(12, NUDGING_nlist, iostat=ierr, iomsg=msg) + if(ierr .ne. 0) call hydro_stop("NUDGING_nlst namelist error in read_rt_nlst: " // trim(msg)) !! Conditional default values for nuding_nlist if(maxAgePairsBiasPersist .eq. -99999) maxAgePairsBiasPersist = -1*nLastObs #endif @@ -695,6 +758,12 @@ subroutine init_namelist_rt_field(did) nlst(did)%SOLVEG_INITSWC = SOLVEG_INITSWC nlst(did)%reservoir_obs_dir = "testDirectory" + if ((lake_option == 3) .and. (reservoir_persistence_usgs .or. reservoir_persistence_usace .or. reservoir_rfc_forecasts)) then + reservoir_type_specified = .TRUE. + lake_option = 1 + end if + + nlst(did)%lake_option = lake_option nlst(did)%reservoir_persistence_usgs = reservoir_persistence_usgs nlst(did)%reservoir_persistence_usace = reservoir_persistence_usace nlst(did)%reservoir_parameter_file = reservoir_parameter_file @@ -706,10 +775,6 @@ subroutine init_namelist_rt_field(did) nlst(did)%reservoir_rfc_forecasts_time_series_path = reservoir_rfc_forecasts_time_series_path nlst(did)%reservoir_rfc_forecasts_lookback_hours = reservoir_rfc_forecasts_lookback_hours - if (reservoir_persistence_usgs .or. reservoir_persistence_usace .or. reservoir_rfc_forecasts) then - reservoir_type_specified = .TRUE. - end if - nlst(did)%reservoir_type_specified = reservoir_type_specified write(nlst(did)%hgrid,'(I1)') igrid @@ -839,6 +904,12 @@ subroutine init_namelist_rt_field(did) nlst(did)%noConstInterfBias = noConstInterfBias #endif + ! if lakes have been disabled (lake_option == 0), clear the route_lake_f and output_lakes options + if (nlst(did)%lake_option == 0) then + nlst(did)%route_lake_f = '' + nlst(did)%outlake = 0 + end if + call nlst(did)%check() ! derive rtFlag diff --git a/src/Routing/Reservoirs/Level_Pool/module_levelpool.F b/src/Routing/Reservoirs/Level_Pool/module_levelpool.F index 6e8236751..02bce4f98 100644 --- a/src/Routing/Reservoirs/Level_Pool/module_levelpool.F +++ b/src/Routing/Reservoirs/Level_Pool/module_levelpool.F @@ -56,7 +56,8 @@ module module_levelpool subroutine levelpool_init(this, water_elevation, & lake_area, weir_elevation, weir_coeffecient, & weir_length, dam_length, orifice_elevation, orifice_coefficient, & - orifice_area, max_depth, lake_number) + orifice_area, max_depth, lake_number, lake_opt) + implicit none class(levelpool), intent(inout) :: this ! object being initialized real, intent(inout) :: water_elevation ! meters AMSL @@ -69,7 +70,9 @@ subroutine levelpool_init(this, water_elevation, & real, intent(in) :: orifice_coefficient ! orifice coefficient real, intent(in) :: orifice_area ! orifice area (meters^2) real, intent(in) :: max_depth ! max depth of reservoir before overtop (meters) - integer(kind=int64), intent(in) :: lake_number ! lake number + integer(kind=int64), intent(in) :: lake_number ! lake number + integer, intent(in) :: lake_opt ! bypass lake physics (2 to use pass-through) + character(len=15) :: lake_number_string #ifdef RESERVOIR_D @@ -114,7 +117,7 @@ subroutine levelpool_init(this, water_elevation, & call this%properties%init( lake_area, & weir_elevation, weir_coeffecient, weir_length, dam_length, & orifice_elevation, orifice_coefficient, & - orifice_area, max_depth, lake_number ) + orifice_area, max_depth, lake_number, lake_opt ) end if this%pointer_allocation_guard = .true. @@ -169,6 +172,7 @@ subroutine run_levelpool_reservoir(this, previous_timestep_inflow, inflow, & this%state%water_elevation = water_elevation call LEVELPOOL_PHYSICS(this%properties%lake_number, & + this%properties%lake_opt, & previous_timestep_inflow, & this%input%inflow, & this%output%outflow, & @@ -217,7 +221,7 @@ end subroutine run_levelpool_reservoir ! SUBROUTINE LEVELPOOL ! ------------------------------------------------ - subroutine LEVELPOOL_PHYSICS(ln,qi0,qi1,qo1,ql,dt,H,ar,we,maxh,wc,wl,dl,oe,oc,oa) + subroutine LEVELPOOL_PHYSICS(ln,lake_opt,qi0,qi1,qo1,ql,dt,H,ar,we,maxh,wc,wl,dl,oe,oc,oa) !! ---------------------------- argument variables !! All elevations should be relative to a common base (often belev(k)) @@ -238,9 +242,8 @@ subroutine LEVELPOOL_PHYSICS(ln,qi0,qi1,qo1,ql,dt,H,ar,we,maxh,wc,wl,dl,oe,oc,oa real, intent(IN) :: oa ! orifice area (m^2) real, intent(IN) :: maxh ! max depth of reservoir before overtop (m) integer(kind=int64), intent(IN) :: ln ! lake number + integer, intent(in) :: lake_opt ! reservoir physics options (1: levelpool, 2: passthrough) - !!DJG Add lake option switch here...move up to namelist in future versions... - integer :: LAKE_OPT ! Lake model option (move to namelist later) real :: Htmp ! Temporary assign of incoming lake el. (m) !! ---------------------------- local variables @@ -254,22 +257,20 @@ subroutine LEVELPOOL_PHYSICS(ln,qi0,qi1,qo1,ql,dt,H,ar,we,maxh,wc,wl,dl,oe,oc,oa !! ---------------------------- subroutine body: from chow, mad mays. pg. 252 !! -- determine from inflow hydrograph - - !!DJG Set hardwire for LAKE_OPT...move specification of this to namelist in - !future versions... - LAKE_OPT = 2 Htmp = H !temporary set of incoming lake water elevation... !hdiff_vol = 0.0 !qdiff_vol = 0.0 !!DJG IF-block for lake model option 1 - outflow=inflow, 2 - Chow et al level !pool, ..... - if (LAKE_OPT == 1) then ! If-block for simple pass through scheme.... - + if (LAKE_OPT == 2) then ! If-block for simple pass through scheme.... +#ifdef RESERVOIR_D + write(6,*) "LEVELPOOL LAKE_OPT=2, using reservoir passthrough" +#endif qo1 = qi1 ! Set outflow equal to inflow at current time H = Htmp ! Set new lake water elevation to incoming lake el. - else if (LAKE_OPT == 2) then ! If-block for Chow et al level pool scheme + else if (LAKE_OPT == 1) then ! If-block for Chow et al level pool scheme It = qi0 Itdt_3 = qi0 + ((qi1 + ql - qi0) * 0.33) @@ -406,6 +407,7 @@ subroutine LEVELPOOL_PHYSICS(ln,qi0,qi1,qo1,ql,dt,H,ar,we,maxh,wc,wl,dl,oe,oc,oa else ! ELSE for LAKE_OPT.... + call hydro_stop("Invalid lake option supplied to LEVELPOOL_PHYSICS()") endif ! ENDIF for LAKE_OPT.... return diff --git a/src/Routing/Reservoirs/Level_Pool/module_levelpool_properties.F b/src/Routing/Reservoirs/Level_Pool/module_levelpool_properties.F index 0e4a9dfc0..7f6b5e0ca 100644 --- a/src/Routing/Reservoirs/Level_Pool/module_levelpool_properties.F +++ b/src/Routing/Reservoirs/Level_Pool/module_levelpool_properties.F @@ -23,6 +23,7 @@ module module_levelpool_properties real :: orifice_area ! orifice area (meters^2) real :: max_depth ! max depth of reservoir before overtop (meters) integer(kind=int64) :: lake_number ! lake number + integer :: lake_opt ! reservoir physics options (1: levelpool, 2: passthrough) contains @@ -36,7 +37,7 @@ module module_levelpool_properties !Level Pool Properties Constructor subroutine levelpool_properties_init(this, lake_area, & weir_elevation, weir_coeffecient, weir_length, dam_length, orifice_elevation, & - orifice_coefficient, orifice_area, max_depth, lake_number) + orifice_coefficient, orifice_area, max_depth, lake_number, lake_opt) implicit none class(levelpool_properties_interface), intent(inout) :: this ! the type object being initialized real, intent(in) :: lake_area ! area of lake (km^2) @@ -49,6 +50,7 @@ subroutine levelpool_properties_init(this, lake_area, & real, intent(in) :: orifice_area ! orifice area (meters^2) real, intent(in) :: max_depth ! max depth of reservoir before overtop (meters) integer(kind=int64), intent(in) :: lake_number ! lake number + integer :: lake_opt ! reservoir physics options (1: levelpool, 2: passthrough) ! Assign the values passed in to a particular level pool reservoir ! properties object's variables. @@ -62,6 +64,7 @@ subroutine levelpool_properties_init(this, lake_area, & this%max_depth = max_depth this%lake_number = lake_number this%dam_length = dam_length + this%lake_opt = lake_opt end subroutine levelpool_properties_init diff --git a/src/Routing/Reservoirs/Persistence_Level_Pool_Hybrid/module_persistence_levelpool_hybrid.F b/src/Routing/Reservoirs/Persistence_Level_Pool_Hybrid/module_persistence_levelpool_hybrid.F index 6d4b599b7..2c475333a 100644 --- a/src/Routing/Reservoirs/Persistence_Level_Pool_Hybrid/module_persistence_levelpool_hybrid.F +++ b/src/Routing/Reservoirs/Persistence_Level_Pool_Hybrid/module_persistence_levelpool_hybrid.F @@ -201,7 +201,7 @@ subroutine hybrid_init(this, water_elevation, & ! Initialize level pool reservoir call this%state%levelpool_ptr%init(water_elevation, lake_area, & weir_elevation, weir_coeffecient, weir_length, dam_length, orifice_elevation, & - orifice_coefficient, orifice_area, lake_max_water_elevation, lake_number) + orifice_coefficient, orifice_area, lake_max_water_elevation, lake_number, 1) end if end subroutine hybrid_init diff --git a/src/Routing/Reservoirs/RFC_Forecasts/module_rfc_forecasts.F b/src/Routing/Reservoirs/RFC_Forecasts/module_rfc_forecasts.F index d78d056f8..127d2badb 100644 --- a/src/Routing/Reservoirs/RFC_Forecasts/module_rfc_forecasts.F +++ b/src/Routing/Reservoirs/RFC_Forecasts/module_rfc_forecasts.F @@ -156,7 +156,7 @@ subroutine rfc_forecasts_init(this, water_elevation, & ! Initialize level pool reservoir call this%state%levelpool_ptr%init(water_elevation, lake_area, & weir_elevation, weir_coeffecient, weir_length, dam_length, orifice_elevation, & - orifice_coefficient, orifice_area, lake_max_water_elevation, lake_number) + orifice_coefficient, orifice_area, lake_max_water_elevation, lake_number, 1) ! Call to initialize time series data object call time_series_data%init(start_date, time_series_path, forecast_lookback_hours, & diff --git a/src/Routing/module_HYDRO_io.F b/src/Routing/module_HYDRO_io.F index c8dfc4388..b6e21023f 100644 --- a/src/Routing/module_HYDRO_io.F +++ b/src/Routing/module_HYDRO_io.F @@ -10358,8 +10358,8 @@ subroutine read_NSIMLAKES(NLAKES,route_lake_f) endif else !yw for IOC reach based routing, if netcdf lake file is not set from the hydro.namelist, -! we will assume that no lake will be assimulated. - write(6,*) "No lake nectdf file defined. NLAKES is set to be zero." +! we will assume that no lake will be assimilated. + write(6,*) "Lakes have been disabled -- NLAKES will be set to zero." NLAKES = 0 endif #ifdef MPP_LAND diff --git a/src/Routing/module_RT.F b/src/Routing/module_RT.F index fa3ef00c0..a58ce1bd2 100644 --- a/src/Routing/module_RT.F +++ b/src/Routing/module_RT.F @@ -853,7 +853,8 @@ subroutine LandRT_ini(did) rt_domain(did)%ORIFICEC(lake_index), & rt_domain(did)%ORIFICEA(lake_index), & rt_domain(did)%LAKEMAXH(lake_index), & - rt_domain(did)%LAKEIDM(lake_index) ) + rt_domain(did)%LAKEIDM(lake_index), & + nlst(did)%lake_option) type is (persistence_levelpool_hybrid) call reservoir%init( & diff --git a/src/hydro_namelists.json b/src/hydro_namelists.json index ce569b90e..f90073c2b 100644 --- a/src/hydro_namelists.json +++ b/src/hydro_namelists.json @@ -22,6 +22,7 @@ "igrid": 1, "io_config_outputs": 0, "io_form_outputs": 4, + "lake_option": 1, "land_spatial_meta_flnm": "NULL_specified_in_domain.json", "lsmout_domain": 1, "nsoil": 4, @@ -31,7 +32,6 @@ "output_channelbucket_influx": 0, "output_gw": 1, "ovrtswcrt": 1, - "reservoir_persistence_usgs": false, "restart_file": "NULL_specified_in_domain.json", "route_lake_f": "NULL_specified_in_domain.json", "route_link_f": "NULL_specified_in_domain.json", @@ -50,6 +50,9 @@ "udmp_opt": 1, "zsoil8": [-0.1, -0.4, -1.0, -2.0] }, + "reservoir_nlist": { + "reservoir_persistence_usgs": false + }, "nudging_nlist": { "biaswindowbeforet0": false, "invdisttimeweightbias": true, @@ -109,7 +112,9 @@ "hydro_nlist": { "lsmout_domain": 0, "output_gw": 0, - "output_channelbucket_influx": 2, + "output_channelbucket_influx": 2 + }, + "reservoir_nlist": { "reservoir_persistence_usgs": false }, "nudging_nlist": {} @@ -186,7 +191,8 @@ "channel_option": 3, "dtrt_ch": 10, "rstrt_swc": 1, - "udmp_opt": 0 + "udmp_opt": 0, + "lake_option": 0 }, "nudging_nlist": { "biaswindowbeforet0": "", @@ -211,6 +217,7 @@ "gwbasmskfil": "NULL_specified_in_domain.json", "dtrt_ch": 10, "outlake": 0, + "lake_option": 0, "rstrt_swc": 0, "t0outputflag": 0, "udmp_opt": 0 diff --git a/src/template/HYDRO/hydro.namelist b/src/template/HYDRO/hydro.namelist index 54821f10f..97683ae50 100644 --- a/src/template/HYDRO/hydro.namelist +++ b/src/template/HYDRO/hydro.namelist @@ -154,10 +154,40 @@ compound_channel = .FALSE. ! Switch to activate channel-loss option (0=no, 1=yes) [Requires Kchan in RouteLink] ! channel_loss_option = 0 +! Lake / Reservoir options (0=lakes off, 1=level pool (typical default), +! 2=passthrough, 3=reservoir DA [see &reservoir_nlist below]) +lake_option = 1 + ! Specify the lake parameter file (e.g.: "LAKEPARM.nc"). ! Note REQUIRED if lakes are on. route_lake_f = "./DOMAIN/LAKEPARM.nc" +! Switch to activate baseflow bucket model...(0=none, 1=exp. bucket, 2=pass-through, +! 4=exp. bucket with area normalized parameters) +! Option 4 is currently only supported if using reach-based routing with UDMP=1. +GWBASESWCRT = 1 + +! Switch to activate bucket model loss (0=no, 1=yes) +! This option is currently only supported if using reach-based routing with UDMP=1. +bucket_loss = 0 + +! Groundwater/baseflow 2d mask specified on land surface model grid (e.g.: "GWBASINS.nc") +! Note: Only required if baseflow model is active (1 or 2) and UDMP_OPT=0. +gwbasmskfil = "./DOMAIN/GWBASINS.nc" + +! Groundwater bucket parameter file (e.g.: "GWBUCKPARM.nc") +GWBUCKPARM_file = "./DOMAIN/GWBUCKPARM.nc" + +! User defined mapping, such as NHDPlus: 0=no (default), 1=yes +UDMP_OPT = 0 + +! If on, specify the user-defined mapping file (e.g.: "spatialweights.nc") +!udmap_file = "./DOMAIN/spatialweights.nc" + +/ + +&reservoir_nlist + ! Specify the reservoir parameter file reservoir_parameter_file = "./DOMAIN/persistence_parm.nc" @@ -190,28 +220,6 @@ reservoir_rfc_forecasts_time_series_path = "./rfc_timeseries/" ! Specify lookback hours to read reservoir RFC forecasts reservoir_rfc_forecasts_lookback_hours = 28 -! Switch to activate baseflow bucket model...(0=none, 1=exp. bucket, 2=pass-through, -! 4=exp. bucket with area normalized parameters) -! Option 4 is currently only supported if using reach-based routing with UDMP=1. -GWBASESWCRT = 1 - -! Switch to activate bucket model loss (0=no, 1=yes) -! This option is currently only supported if using reach-based routing with UDMP=1. -bucket_loss = 0 - -! Groundwater/baseflow 2d mask specified on land surface model grid (e.g.: "GWBASINS.nc") -! Note: Only required if baseflow model is active (1 or 2) and UDMP_OPT=0. -gwbasmskfil = "./DOMAIN/GWBASINS.nc" - -! Groundwater bucket parameter file (e.g.: "GWBUCKPARM.nc") -GWBUCKPARM_file = "./DOMAIN/GWBUCKPARM.nc" - -! User defined mapping, such as NHDPlus: 0=no (default), 1=yes -UDMP_OPT = 0 - -! If on, specify the user-defined mapping file (e.g.: "spatialweights.nc") -!udmap_file = "./DOMAIN/spatialweights.nc" - / &NUDGING_nlist