MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
sfrmodule Module Reference

This module contains the SFR package methods. More...

Data Types

type  sfrtype
 

Functions/Subroutines

subroutine, public sfr_create (packobj, id, ibcnum, inunit, iout, namemodel, pakname)
 @ brief Create a new package object More...
 
subroutine sfr_allocate_scalars (this)
 @ brief Allocate scalars More...
 
subroutine sfr_allocate_arrays (this)
 @ brief Allocate arrays More...
 
subroutine sfr_read_dimensions (this)
 @ brief Read dimensions for package More...
 
subroutine sfr_options (this, option, found)
 @ brief Read additional options for package More...
 
subroutine sfr_ar (this)
 @ brief Allocate and read method for package More...
 
subroutine sfr_read_packagedata (this)
 @ brief Read packagedata for the package More...
 
subroutine sfr_read_crossection (this)
 @ brief Read crosssection block for the package More...
 
subroutine sfr_read_connectiondata (this)
 @ brief Read connectiondata for the package More...
 
subroutine sfr_read_diversions (this)
 @ brief Read diversions for the package More...
 
subroutine sfr_read_initial_stages (this)
 @ brief Read initialstages data for the package More...
 
subroutine sfr_rp (this)
 @ brief Read and prepare period data for package More...
 
subroutine sfr_ad (this)
 @ brief Advance the package More...
 
subroutine sfr_cf (this)
 @ brief Formulate the package hcof and rhs terms. More...
 
subroutine sfr_fc (this, rhs, ia, idxglo, matrix_sln)
 @ brief Copy hcof and rhs terms into solution. More...
 
subroutine sfr_fn (this, rhs, ia, idxglo, matrix_sln)
 @ brief Add Newton-Raphson terms for package into solution. More...
 
subroutine sfr_cc (this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
 @ brief Convergence check for package. More...
 
subroutine sfr_cq (this, x, flowja, iadv)
 @ brief Calculate package flows. More...
 
subroutine sfr_ot_package_flows (this, icbcfl, ibudfl)
 @ brief Output package flow terms. More...
 
subroutine sfr_ot_dv (this, idvsave, idvprint)
 @ brief Output package dependent-variable terms. More...
 
subroutine sfr_ot_bdsummary (this, kstp, kper, iout, ibudfl)
 @ brief Output advanced package budget summary. More...
 
subroutine sfr_fp (this)
 Write the Courant-number summary table to the listing file. More...
 
subroutine sfr_dt (this)
 Submit the ATS time step for the most Courant-constraining reach. More...
 
subroutine sfr_calc_celerity (this, n, q, celerity)
 Kinematic-wave celerity from a flow perturbation (0 if dry) More...
 
subroutine sfr_da (this)
 @ brief Deallocate package memory More...
 
subroutine sfr_precompute_tvd (this)
 Pre-compute the single upstream reach index for the TVD limiter. More...
 
subroutine define_listlabel (this)
 @ brief Define the list label for the package More...
 
logical function sfr_obs_supported (this)
 Determine if observations are supported. More...
 
subroutine sfr_df_obs (this)
 Define the observation types available in the package. More...
 
subroutine sfr_bd_obs (this)
 Save observations for the package. More...
 
subroutine sfr_rp_obs (this)
 Read and prepare observations for a package. More...
 
subroutine sfr_process_obsid (obsrv, dis, inunitobs, iout)
 Process observation IDs for a package. More...
 
subroutine sfr_set_stressperiod (this, n, ichkustrm, crossfile)
 Set period data. More...
 
subroutine sfr_solve (this, n, h, hcof, rhs, update)
 Solve reach continuity equation. More...
 
subroutine sfr_update_flows (this, n, qd, qgwf)
 Update flow terms. More...
 
subroutine sfr_adjust_ro_ev (this, qc, qu, qi, qr, qro, qe, qfrommvr)
 Adjust runoff and evaporation. More...
 
subroutine sfr_calc_qd (this, n, depth, hgwf, qgwf, qd)
 Calculate downstream flow term. More...
 
subroutine sfr_calc_qsource (this, n, depth, qsrc)
 Calculate sum of sources. More...
 
subroutine sfr_calc_qman (this, n, depth, qman)
 Calculate streamflow. More...
 
subroutine sfr_calc_qgwf (this, n, depth, hgwf, qgwf, gwfhcof, gwfrhs)
 Calculate reach-aquifer exchange. More...
 
integer(i4b) function sfr_gwf_conn (this, n)
 Determine if a reach is connected to a gwf cell. More...
 
subroutine sfr_calc_cond (this, n, depth, cond, hsfr, h_temp)
 Calculate reach-aquifer conductance. More...
 
subroutine sfr_calc_div (this, n, i, qd, qdiv)
 Calculate diversion flow. More...
 
subroutine sfr_calc_reach_depth (this, n, q1, d1)
 Calculate the depth at the midpoint. More...
 
subroutine sfr_calc_xs_depth (this, n, qrch, d)
 Calculate the depth at the midpoint of a irregular cross-section. More...
 
subroutine sfr_check_conversion (this)
 Check unit conversion data. More...
 
subroutine sfr_check_storage_weight (this)
 Check storage weight. More...
 
subroutine sfr_check_reaches (this)
 Check reach data. More...
 
subroutine sfr_check_connections (this)
 Check connection data. More...
 
subroutine sfr_check_diversions (this)
 Check diversions data. More...
 
subroutine sfr_check_initialstages (this)
 Check initial stage data. More...
 
subroutine sfr_check_ustrf (this)
 Check upstream fraction data. More...
 
subroutine sfr_setup_budobj (this)
 Setup budget object for package. More...
 
subroutine sfr_fill_budobj (this)
 Copy flow terms into budget object for package. More...
 
subroutine sfr_setup_tableobj (this)
 Setup stage table object for package. More...
 
real(dp) function calc_area_wet (this, n, depth)
 Calculate wetted area. More...
 
real(dp) function calc_perimeter_wet (this, n, depth)
 Calculate wetted perimeter. More...
 
real(dp) function calc_surface_area (this, n)
 Calculate maximum surface area. More...
 
real(dp) function calc_surface_area_wet (this, n, depth)
 Calculate wetted surface area. More...
 
real(dp) function calc_top_width_wet (this, n, depth)
 Calculate wetted top width. More...
 
subroutine sfr_activate_density (this)
 Activate density terms. More...
 
subroutine sfr_activate_viscosity (this)
 Activate viscosity terms. More...
 
subroutine sfr_calculate_density_exchange (this, n, stage, head, cond, tops, flow, gwfhcof, gwfrhs)
 Calculate density terms. More...
 

Variables

character(len=lenftype) ftype = 'SFR'
 package ftype string More...
 
character(len=lenpackagename) text = ' SFR'
 package budget string More...
 

Detailed Description

This module contains the overridden methods for the streamflow routing (SFR) package. Most of the methods in the base Boundary Package are overridden.

Function/Subroutine Documentation

◆ calc_area_wet()

real(dp) function sfrmodule::calc_area_wet ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth 
)
private

Function to calculate the wetted area for a SFR package reach.

Returns
wetted area
Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth

Definition at line 5835 of file gwf-sfr.f90.

5836  ! -- return variable
5837  real(DP) :: calc_area_wet !< wetted area
5838  ! -- dummy
5839  class(SfrType) :: this !< SfrType object
5840  integer(I4B), intent(in) :: n !< reach number
5841  real(DP), intent(in) :: depth !< reach depth
5842  ! -- local
5843  integer(I4B) :: npts
5844  integer(I4B) :: i0
5845  integer(I4B) :: i1
5846  !
5847  ! -- Calculate wetted area
5848  npts = this%ncrosspts(n)
5849  i0 = this%iacross(n)
5850  i1 = this%iacross(n + 1) - 1
5851  if (npts > 1) then
5852  calc_area_wet = get_cross_section_area(npts, this%station(i0:i1), &
5853  this%xsheight(i0:i1), depth)
5854  else
5855  calc_area_wet = this%station(i0) * depth
5856  end if
Here is the call graph for this function:

◆ calc_perimeter_wet()

real(dp) function sfrmodule::calc_perimeter_wet ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth 
)
private

Function to calculate the wetted perimeter for a SFR package reach.

Returns
wetted perimeter
Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth

Definition at line 5863 of file gwf-sfr.f90.

5864  ! -- return variable
5865  real(DP) :: calc_perimeter_wet !< wetted perimeter
5866  ! -- dummy
5867  class(SfrType) :: this !< SfrType object
5868  integer(I4B), intent(in) :: n !< reach number
5869  real(DP), intent(in) :: depth !< reach depth
5870  ! -- local
5871  integer(I4B) :: npts
5872  integer(I4B) :: i0
5873  integer(I4B) :: i1
5874  !
5875  ! -- Calculate wetted perimeter
5876  npts = this%ncrosspts(n)
5877  i0 = this%iacross(n)
5878  i1 = this%iacross(n + 1) - 1
5879  if (npts > 1) then
5880  calc_perimeter_wet = get_wetted_perimeter(npts, this%station(i0:i1), &
5881  this%xsheight(i0:i1), depth)
5882  else
5883  calc_perimeter_wet = this%station(i0) ! no depth dependence in original implementation
5884  end if
Here is the call graph for this function:

◆ calc_surface_area()

real(dp) function sfrmodule::calc_surface_area ( class(sfrtype this,
integer(i4b), intent(in)  n 
)
private

Function to calculate the maximum surface area for a SFR package reach.

Returns
surface area
Parameters
thisSfrType object
[in]nreach number

Definition at line 5891 of file gwf-sfr.f90.

5892  ! -- return variable
5893  real(DP) :: calc_surface_area !< surface area
5894  ! -- dummy
5895  class(SfrType) :: this !< SfrType object
5896  integer(I4B), intent(in) :: n !< reach number
5897  ! -- local
5898  integer(I4B) :: npts
5899  integer(I4B) :: i0
5900  integer(I4B) :: i1
5901  real(DP) :: top_width
5902  !
5903  ! -- Calculate surface area
5904  npts = this%ncrosspts(n)
5905  i0 = this%iacross(n)
5906  i1 = this%iacross(n + 1) - 1
5907  if (npts > 1) then
5908  top_width = get_saturated_topwidth(npts, this%station(i0:i1))
5909  else
5910  top_width = this%station(i0)
5911  end if
5912  calc_surface_area = top_width * this%length(n)
Here is the call graph for this function:

◆ calc_surface_area_wet()

real(dp) function sfrmodule::calc_surface_area_wet ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth 
)
private

Function to calculate the wetted surface area for a SFR package reach.

Returns
wetted surface area
Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth

Definition at line 5919 of file gwf-sfr.f90.

5920  ! -- return variable
5921  real(DP) :: calc_surface_area_wet !< wetted surface area
5922  ! -- dummy
5923  class(SfrType) :: this !< SfrType object
5924  integer(I4B), intent(in) :: n !< reach number
5925  real(DP), intent(in) :: depth !< reach depth
5926  ! -- local
5927  real(DP) :: top_width
5928  !
5929  ! -- Calculate wetted surface area
5930  top_width = this%calc_top_width_wet(n, depth)
5931  calc_surface_area_wet = top_width * this%length(n)

◆ calc_top_width_wet()

real(dp) function sfrmodule::calc_top_width_wet ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth 
)
private

Function to calculate the wetted top width for a SFR package reach.

Returns
wetted top width
Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth

Definition at line 5938 of file gwf-sfr.f90.

5939  ! -- return variable
5940  real(DP) :: calc_top_width_wet !< wetted top width
5941  ! -- dummy
5942  class(SfrType) :: this !< SfrType object
5943  integer(I4B), intent(in) :: n !< reach number
5944  real(DP), intent(in) :: depth !< reach depth
5945  ! -- local
5946  integer(I4B) :: npts
5947  integer(I4B) :: i0
5948  integer(I4B) :: i1
5949  real(DP) :: sat
5950  !
5951  ! -- Calculate wetted top width
5952  npts = this%ncrosspts(n)
5953  i0 = this%iacross(n)
5954  i1 = this%iacross(n + 1) - 1
5955  sat = scubicsaturation(dem5, dzero, depth, dem5)
5956  if (npts > 1) then
5957  calc_top_width_wet = sat * get_wetted_topwidth(npts, &
5958  this%station(i0:i1), &
5959  this%xsheight(i0:i1), &
5960  depth)
5961  else
5962  calc_top_width_wet = sat * this%station(i0)
5963  end if
Here is the call graph for this function:

◆ define_listlabel()

subroutine sfrmodule::define_listlabel ( class(sfrtype), intent(inout)  this)
private

Method defined the list label for the SFR package. The list label is the heading that is written to iout when PRINT_INPUT option is used.

Parameters
[in,out]thisSfrType object

Definition at line 3160 of file gwf-sfr.f90.

3161  ! -- dummy
3162  class(SfrType), intent(inout) :: this !< SfrType object
3163  !
3164  ! -- create the header list label
3165  this%listlabel = trim(this%filtyp)//' NO.'
3166  if (this%dis%ndim == 3) then
3167  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
3168  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
3169  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
3170  elseif (this%dis%ndim == 2) then
3171  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
3172  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
3173  else
3174  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
3175  end if
3176  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
3177  if (this%inamedbound == 1) then
3178  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
3179  end if

◆ sfr_activate_density()

subroutine sfrmodule::sfr_activate_density ( class(sfrtype), intent(inout)  this)
private

Method to activate addition of density terms for a SFR package reach.

Parameters
[in,out]thisSfrType object

Definition at line 5970 of file gwf-sfr.f90.

5971  ! -- modules
5973  ! -- dummy
5974  class(SfrType), intent(inout) :: this !< SfrType object
5975  ! -- local
5976  integer(I4B) :: i
5977  integer(I4B) :: j
5978  !
5979  ! -- Set idense and reallocate denseterms to be of size MAXBOUND
5980  this%idense = 1
5981  call mem_reallocate(this%denseterms, 3, this%MAXBOUND, 'DENSETERMS', &
5982  this%memoryPath)
5983  do i = 1, this%maxbound
5984  do j = 1, 3
5985  this%denseterms(j, i) = dzero
5986  end do
5987  end do
5988  write (this%iout, '(/1x,a)') 'DENSITY TERMS HAVE BEEN ACTIVATED FOR SFR &
5989  &PACKAGE: '//trim(adjustl(this%packName))

◆ sfr_activate_viscosity()

subroutine sfrmodule::sfr_activate_viscosity ( class(sfrtype), intent(inout)  this)

Method to activate addition of viscosity terms for exchange with groundwater along a SFR package reach.

Parameters
[in,out]thisSfrType object

Definition at line 5997 of file gwf-sfr.f90.

5998  ! -- modules
6000  ! -- dummy
6001  class(SfrType), intent(inout) :: this !< SfrType object
6002  ! -- local
6003  integer(I4B) :: i
6004  integer(I4B) :: j
6005  !
6006  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
6007  this%ivsc = 1
6008  call mem_reallocate(this%viscratios, 2, this%MAXBOUND, 'VISCRATIOS', &
6009  this%memoryPath)
6010  do i = 1, this%maxbound
6011  do j = 1, 2
6012  this%viscratios(j, i) = done
6013  end do
6014  end do
6015  write (this%iout, '(/1x,a)') 'VISCOSITY HAS BEEN ACTIVATED FOR SFR &
6016  &PACKAGE: '//trim(adjustl(this%packName))

◆ sfr_ad()

subroutine sfrmodule::sfr_ad ( class(sfrtype this)

Advance data in the SFR package. The method sets advances time series, time array series, and observation data.

Parameters
thisSfrType object

Definition at line 2173 of file gwf-sfr.f90.

2174  ! -- modules
2176  ! -- dummy
2177  class(SfrType) :: this !< SfrType object
2178  ! -- local
2179  integer(I4B) :: n
2180  integer(I4B) :: iaux
2181 
2182  ! -- update previous values
2183  if (this%istorage == 1) then
2184  do n = 1, this%maxbound
2185  this%stageold(n) = this%stage(n)
2186  this%usinflowold(n) = this%usinflow(n)
2187  this%dsflowold(n) = this%dsflow(n)
2188  end do
2189  end if
2190  !
2191  ! -- Most advanced package AD routines have to restore state if
2192  ! the solution failed and the time step is being retried with a smaller
2193  ! step size. This is not needed here because there is no old stage
2194  ! or storage effects in the stream.
2195  !
2196  ! -- Advance the time series manager
2197  call this%TsManager%ad()
2198  !
2199  ! -- check upstream fractions if time series are being used to
2200  ! define this variable
2201  if (var_timeseries(this%tsManager, this%packName, 'USTRF')) then
2202  call this%sfr_check_ustrf()
2203  end if
2204  !
2205  ! -- update auxiliary variables by copying from the derived-type time
2206  ! series variable into the bndpackage auxvar variable so that this
2207  ! information is properly written to the GWF budget file
2208  if (this%naux > 0) then
2209  do n = 1, this%maxbound
2210  do iaux = 1, this%naux
2211  if (this%noupdateauxvar(iaux) /= 0) cycle
2212  this%auxvar(iaux, n) = this%rauxvar(iaux, n)
2213  end do
2214  end do
2215  end if
2216  !
2217  ! -- reset upstream flow to zero and set specified stage
2218  do n = 1, this%maxbound
2219  this%usflow(n) = dzero
2220  if (this%iboundpak(n) < 0) then
2221  this%stage(n) = this%sstage(n)
2222  end if
2223  end do
2224  !
2225  ! -- pakmvrobj ad
2226  if (this%imover == 1) then
2227  call this%pakmvrobj%ad()
2228  end if
2229  !
2230  ! -- For each observation, push simulated value and corresponding
2231  ! simulation time from "current" to "preceding" and reset
2232  ! "current" value.
2233  call this%obs%obs_ad()
logical function, public var_timeseries(tsManager, pkgName, varName, auxOrBnd)
Determine if a timeseries link with varName is defined.
Here is the call graph for this function:

◆ sfr_adjust_ro_ev()

subroutine sfrmodule::sfr_adjust_ro_ev ( class(sfrtype this,
real(dp), intent(inout)  qc,
real(dp), intent(in)  qu,
real(dp), intent(in)  qi,
real(dp), intent(in)  qr,
real(dp), intent(inout)  qro,
real(dp), intent(inout)  qe,
real(dp), intent(in)  qfrommvr 
)
private

Method to adjust runoff and evaporation for a SFR package reach based on the total reach flow.

Parameters
thisSfrType object
[in,out]qctotal reach volumetric flow
[in]quupstream reach volumetric flow
[in]qireach volumetric inflow
[in]qrreach volumetric rainfall
[in,out]qroreach volumetric runoff
[in,out]qereach volumetric evaporation
[in]qfrommvrreach volumetric flow from mover

Definition at line 3991 of file gwf-sfr.f90.

3992  ! -- dummy
3993  class(SfrType) :: this !< SfrType object
3994  real(DP), intent(inout) :: qc !< total reach volumetric flow
3995  real(DP), intent(in) :: qu !< upstream reach volumetric flow
3996  real(DP), intent(in) :: qi !< reach volumetric inflow
3997  real(DP), intent(in) :: qr !< reach volumetric rainfall
3998  real(DP), intent(inout) :: qro !< reach volumetric runoff
3999  real(DP), intent(inout) :: qe !< reach volumetric evaporation
4000  real(DP), intent(in) :: qfrommvr !< reach volumetric flow from mover
4001  ! -- local
4002  real(DP) :: qt
4003  !
4004  ! -- adjust runoff or evaporation if sum of sources is negative
4005  if (qc < dzero) then
4006  !
4007  ! -- calculate sources without evaporation
4008  qt = qu + qi + qr + qro + qfrommvr
4009  !
4010  ! -- runoff exceeds sources of water for reach
4011  if (qt < dzero) then
4012  if (qro < dzero) then
4013  qro = -(qu + qi + qr + qfrommvr)
4014  qe = dzero
4015  end if
4016  !
4017  ! -- evaporation exceeds sources of water for reach
4018  else
4019  if (qe > dzero) then
4020  qe = qu + qi + qr + qro + qfrommvr
4021  end if
4022  end if
4023  qc = qu + qi + qr - qe + qro + qfrommvr
4024  end if

◆ sfr_allocate_arrays()

subroutine sfrmodule::sfr_allocate_arrays ( class(sfrtype), intent(inout)  this)

Allocate and initialize array for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 439 of file gwf-sfr.f90.

440  ! -- modules
442  ! -- dummy
443  class(SfrType), intent(inout) :: this !< SfrType object
444  ! -- local
445  integer(I4B) :: i
446  integer(I4B) :: j
447  !
448  ! -- allocate character array for budget text
449  allocate (this%csfrbudget(this%bditems))
450  call mem_allocate(this%sfrname, lenboundname, this%maxbound, &
451  'SFRNAME', this%memoryPath)
452  !
453  ! -- variables originally in SfrDataType
454  call mem_allocate(this%iboundpak, this%maxbound, 'IBOUNDPAK', &
455  this%memoryPath)
456  call mem_allocate(this%igwfnode, this%maxbound, 'IGWFNODE', this%memoryPath)
457  call mem_allocate(this%igwftopnode, this%maxbound, 'IGWFTOPNODE', &
458  this%memoryPath)
459  call mem_allocate(this%length, this%maxbound, 'LENGTH', this%memoryPath)
460  call mem_allocate(this%width, this%maxbound, 'WIDTH', this%memoryPath)
461  call mem_allocate(this%strtop, this%maxbound, 'STRTOP', this%memoryPath)
462  call mem_allocate(this%bthick, this%maxbound, 'BTHICK', this%memoryPath)
463  call mem_allocate(this%hk, this%maxbound, 'HK', this%memoryPath)
464  call mem_allocate(this%slope, this%maxbound, 'SLOPE', this%memoryPath)
465  call mem_allocate(this%nconnreach, this%maxbound, 'NCONNREACH', &
466  this%memoryPath)
467  call mem_allocate(this%ustrf, this%maxbound, 'USTRF', this%memoryPath)
468  call mem_allocate(this%ftotnd, this%maxbound, 'FTOTND', this%memoryPath)
469  call mem_allocate(this%ndiv, this%maxbound, 'NDIV', this%memoryPath)
470  call mem_allocate(this%usflow, this%maxbound, 'USFLOW', this%memoryPath)
471  call mem_allocate(this%dsflow, this%maxbound, 'DSFLOW', this%memoryPath)
472  call mem_allocate(this%depth, this%maxbound, 'DEPTH', this%memoryPath)
473  call mem_allocate(this%stage, this%maxbound, 'STAGE', this%memoryPath)
474  call mem_allocate(this%gwflow, this%maxbound, 'GWFLOW', this%memoryPath)
475  call mem_allocate(this%simevap, this%maxbound, 'SIMEVAP', this%memoryPath)
476  call mem_allocate(this%simrunoff, this%maxbound, 'SIMRUNOFF', &
477  this%memoryPath)
478  call mem_allocate(this%stage0, this%maxbound, 'STAGE0', this%memoryPath)
479  call mem_allocate(this%usflow0, this%maxbound, 'USFLOW0', this%memoryPath)
480  !
481  ! -- stage, usflow, inflow, and dsflow for previous timestep
482  if (this%istorage == 1) then
483  call mem_allocate(this%stageold, this%maxbound, 'STAGEOLD', &
484  this%memoryPath)
485  call mem_allocate(this%usinflow, this%maxbound, 'USINFLOW', &
486  this%memoryPath)
487  call mem_allocate(this%usinflowold, this%maxbound, 'USINFLOWOLD', &
488  this%memoryPath)
489  call mem_allocate(this%dsflowold, this%maxbound, 'DSFLOWOLD', &
490  this%memoryPath)
491  call mem_allocate(this%storage, this%maxbound, 'STORAGE', &
492  this%memoryPath)
493  call mem_allocate(this%crmin, this%maxbound, 'CRMIN', this%memoryPath)
494  call mem_allocate(this%crmax, this%maxbound, 'CRMAX', this%memoryPath)
495  call mem_allocate(this%crsum, this%maxbound, 'CRSUM', this%memoryPath)
496  call mem_allocate(this%crcnt, this%maxbound, 'CRCNT', this%memoryPath)
497  if (this%ats_courant /= dnodata) then
498  call mem_allocate(this%itvd_upstream, this%maxbound, &
499  'ITVD_UPSTREAM', this%memoryPath)
500  else
501  call mem_allocate(this%itvd_upstream, 0, 'ITVD_UPSTREAM', this%memoryPath)
502  end if
503  end if
504  !
505  ! -- reach order and connection data
506  call mem_allocate(this%isfrorder, this%maxbound, 'ISFRORDER', &
507  this%memoryPath)
508  call mem_allocate(this%ia, this%maxbound + 1, 'IA', this%memoryPath)
509  call mem_allocate(this%ja, 0, 'JA', this%memoryPath)
510  call mem_allocate(this%idir, 0, 'IDIR', this%memoryPath)
511  call mem_allocate(this%idiv, 0, 'IDIV', this%memoryPath)
512  call mem_allocate(this%qconn, 0, 'QCONN', this%memoryPath)
513  !
514  ! -- boundary data
515  call mem_allocate(this%rough, this%maxbound, 'ROUGH', this%memoryPath)
516  call mem_allocate(this%rain, this%maxbound, 'RAIN', this%memoryPath)
517  call mem_allocate(this%evap, this%maxbound, 'EVAP', this%memoryPath)
518  call mem_allocate(this%inflow, this%maxbound, 'INFLOW', this%memoryPath)
519  call mem_allocate(this%runoff, this%maxbound, 'RUNOFF', this%memoryPath)
520  call mem_allocate(this%sstage, this%maxbound, 'SSTAGE', this%memoryPath)
521  !
522  ! -- aux variables
523  call mem_allocate(this%rauxvar, this%naux, this%maxbound, &
524  'RAUXVAR', this%memoryPath)
525  !
526  ! -- diversion variables
527  call mem_allocate(this%iadiv, this%maxbound + 1, 'IADIV', this%memoryPath)
528  call mem_allocate(this%divreach, 0, 'DIVREACH', this%memoryPath)
529  call mem_allocate(this%divflow, 0, 'DIVFLOW', this%memoryPath)
530  call mem_allocate(this%divq, 0, 'DIVQ', this%memoryPath)
531  !
532  ! -- cross-section data
533  call mem_allocate(this%ncrosspts, this%maxbound, 'NCROSSPTS', &
534  this%memoryPath)
535  call mem_allocate(this%iacross, this%maxbound + 1, 'IACROSS', &
536  this%memoryPath)
537  call mem_allocate(this%station, this%ncrossptstot, 'STATION', &
538  this%memoryPath)
539  call mem_allocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
540  this%memoryPath)
541  call mem_allocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
542  this%memoryPath)
543  !
544  ! -- initialize variables
545  this%iacross(1) = 0
546  do i = 1, this%maxbound
547  this%iboundpak(i) = 1
548  this%igwfnode(i) = 0
549  this%igwftopnode(i) = 0
550  this%length(i) = dzero
551  this%width(i) = dzero
552  this%strtop(i) = dzero
553  this%bthick(i) = dzero
554  this%hk(i) = dzero
555  this%slope(i) = dzero
556  this%nconnreach(i) = 0
557  this%ustrf(i) = dzero
558  this%ftotnd(i) = dzero
559  this%ndiv(i) = 0
560  this%usflow(i) = dzero
561  this%dsflow(i) = dzero
562  this%depth(i) = dzero
563  this%stage(i) = dzero
564  this%gwflow(i) = dzero
565  this%simevap(i) = dzero
566  this%simrunoff(i) = dzero
567  this%stage0(i) = dzero
568  this%usflow0(i) = dzero
569  !
570  ! -- stage
571  if (this%istorage == 1) then
572  this%stageold(i) = dzero
573  this%usinflow(i) = dzero
574  this%usinflowold(i) = dzero
575  this%dsflowold(i) = dzero
576  this%storage(i) = dzero
577  this%crmin(i) = dep20
578  this%crmax(i) = -dep20
579  this%crsum(i) = dzero
580  this%crcnt(i) = 0
581  if (this%ats_courant /= dnodata) then
582  this%itvd_upstream(i) = 0
583  end if
584  end if
585  !
586  ! -- boundary data
587  this%rough(i) = dzero
588  this%rain(i) = dzero
589  this%evap(i) = dzero
590  this%inflow(i) = dzero
591  this%runoff(i) = dzero
592  this%sstage(i) = dzero
593  !
594  ! -- aux variables
595  do j = 1, this%naux
596  this%rauxvar(j, i) = dzero
597  end do
598  !
599  ! -- cross-section data
600  this%ncrosspts(i) = 0
601  this%iacross(i + 1) = 0
602  end do
603  !
604  ! -- initialize additional cross-section data
605  do i = 1, this%ncrossptstot
606  this%station(i) = dzero
607  this%xsheight(i) = dzero
608  this%xsrough(i) = dzero
609  end do
610  !
611  !-- fill csfrbudget
612  this%csfrbudget(1) = ' RAINFALL'
613  this%csfrbudget(2) = ' EVAPORATION'
614  this%csfrbudget(3) = ' RUNOFF'
615  this%csfrbudget(4) = ' EXT-INFLOW'
616  this%csfrbudget(5) = ' GWF'
617  this%csfrbudget(6) = ' EXT-OUTFLOW'
618  this%csfrbudget(7) = ' FROM-MVR'
619  this%csfrbudget(8) = ' TO-MVR'
620  !
621  ! -- allocate and initialize budget output data
622  call mem_allocate(this%qoutflow, this%maxbound, 'QOUTFLOW', this%memoryPath)
623  call mem_allocate(this%qextoutflow, this%maxbound, 'QEXTOUTFLOW', &
624  this%memoryPath)
625  do i = 1, this%maxbound
626  this%qoutflow(i) = dzero
627  this%qextoutflow(i) = dzero
628  end do
629  !
630  ! -- allocate and initialize dbuff
631  if (this%istageout > 0) then
632  call mem_allocate(this%dbuff, this%maxbound, 'DBUFF', this%memoryPath)
633  do i = 1, this%maxbound
634  this%dbuff(i) = dzero
635  end do
636  else
637  call mem_allocate(this%dbuff, 0, 'DBUFF', this%memoryPath)
638  end if
639  !
640  ! -- allocate character array for budget text
641  allocate (this%cauxcbc(this%cbcauxitems))
642  !
643  ! -- allocate and initialize qauxcbc
644  call mem_allocate(this%qauxcbc, this%cbcauxitems, 'QAUXCBC', &
645  this%memoryPath)
646  do i = 1, this%cbcauxitems
647  this%qauxcbc(i) = dzero
648  end do
649  !
650  ! -- fill cauxcbc
651  this%cauxcbc(1) = 'FLOW-AREA '
652  !
653  ! -- allocate denseterms to size 0
654  call mem_allocate(this%denseterms, 3, 0, 'DENSETERMS', this%memoryPath)
655  !
656  ! -- allocate viscratios to size 0
657  call mem_allocate(this%viscratios, 2, 0, 'VISCRATIOS', this%memoryPath)

◆ sfr_allocate_scalars()

subroutine sfrmodule::sfr_allocate_scalars ( class(sfrtype), intent(inout)  this)

Allocate and initialize scalars for the SFR package. The base model allocate scalars method is also called.

Parameters
[in,out]thisSfrType object

Definition at line 368 of file gwf-sfr.f90.

369  ! -- modules
372  ! -- dummy
373  class(SfrType), intent(inout) :: this !< SfrType object
374  !
375  ! -- call standard BndType allocate scalars
376  call this%BndType%allocate_scalars()
377  !
378  ! -- allocate the object and assign values to object variables
379  call mem_allocate(this%ats_courant, 'ATS_COURANT', this%memoryPath)
380  call mem_allocate(this%istorage, 'ISTORAGE', this%memoryPath)
381  call mem_allocate(this%iprhed, 'IPRHED', this%memoryPath)
382  call mem_allocate(this%istageout, 'ISTAGEOUT', this%memoryPath)
383  call mem_allocate(this%ibudgetout, 'IBUDGETOUT', this%memoryPath)
384  call mem_allocate(this%ibudcsv, 'IBUDCSV', this%memoryPath)
385  call mem_allocate(this%ipakcsv, 'IPAKCSV', this%memoryPath)
386  call mem_allocate(this%idiversions, 'IDIVERSIONS', this%memoryPath)
387  call mem_allocate(this%maxsfrpicard, 'MAXSFRPICARD', this%memoryPath)
388  call mem_allocate(this%maxsfrit, 'MAXSFRIT', this%memoryPath)
389  call mem_allocate(this%bditems, 'BDITEMS', this%memoryPath)
390  call mem_allocate(this%cbcauxitems, 'CBCAUXITEMS', this%memoryPath)
391  call mem_allocate(this%unitconv, 'UNITCONV', this%memoryPath)
392  call mem_allocate(this%lengthconv, 'LENGTHCONV', this%memoryPath)
393  call mem_allocate(this%timeconv, 'TIMECONV', this%memoryPath)
394  call mem_allocate(this%dmaxchg, 'DMAXCHG', this%memoryPath)
395  call mem_allocate(this%deps, 'DEPS', this%memoryPath)
396  call mem_allocate(this%storage_weight, 'STORAGE_WEIGHT', this%memoryPath)
397  call mem_allocate(this%nconn, 'NCONN', this%memoryPath)
398  call mem_allocate(this%icheck, 'ICHECK', this%memoryPath)
399  call mem_allocate(this%iconvchk, 'ICONVCHK', this%memoryPath)
400  call mem_allocate(this%idense, 'IDENSE', this%memoryPath)
401  call mem_allocate(this%ianynone, 'IANYNONE', this%memoryPath)
402  call mem_allocate(this%ncrossptstot, 'NCROSSPTSTOT', this%memoryPath)
403  !
404  ! -- set pointer to gwf iss
405  call mem_setptr(this%gwfiss, 'ISS', create_mem_path(this%name_model))
406  !
407  ! -- Set values
408  this%istorage = 0
409  this%iprhed = 0
410  this%istageout = 0
411  this%ibudgetout = 0
412  this%ibudcsv = 0
413  this%ipakcsv = 0
414  this%idiversions = 0
415  this%maxsfrpicard = 100
416  this%maxsfrit = maxadpit
417  this%bditems = 8
418  this%cbcauxitems = 1
419  this%unitconv = done
420  this%lengthconv = dnodata
421  this%timeconv = dnodata
422  this%dmaxchg = dem5
423  this%deps = dp999 * this%dmaxchg
424  this%storage_weight = dnodata
425  this%nconn = 0
426  this%ats_courant = dnodata
427  this%icheck = 1
428  this%iconvchk = 1
429  this%idense = 0
430  this%ivsc = 0
431  this%ianynone = 0
432  this%ncrossptstot = 0
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
Here is the call graph for this function:

◆ sfr_ar()

subroutine sfrmodule::sfr_ar ( class(sfrtype), intent(inout)  this)

Method to read and prepare period data for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 936 of file gwf-sfr.f90.

937  ! -- modules
938  use tdismodule, only: inats
939  ! -- dummy
940  class(SfrType), intent(inout) :: this !< SfrType object
941  ! -- local
942  integer(I4B) :: n
943  integer(I4B) :: ierr
944  !
945  ! -- allocate and read observations
946  call this%obs%obs_ar()
947  !
948  ! -- call standard BndType allocate scalars
949  call this%BndType%allocate_arrays()
950  !
951  ! -- set boundname for each connection
952  if (this%inamedbound /= 0) then
953  do n = 1, this%maxbound
954  this%boundname(n) = this%sfrname(n)
955  end do
956  end if
957  !
958  ! -- copy boundname into boundname_cst
959  call this%copy_boundname()
960  !
961  ! -- copy igwfnode into nodelist
962  do n = 1, this%maxbound
963  this%nodelist(n) = this%igwfnode(n)
964  end do
965  !
966  ! -- check the sfr unit conversion data
967  call this%sfr_check_conversion()
968  !
969  ! -- check the storage_weight
970  call this%sfr_check_storage_weight()
971  !
972  ! -- check that ATS_COURANT is only used with STORAGE
973  if (this%ats_courant /= dnodata .and. this%istorage /= 1) then
974  write (errmsg, '(a)') &
975  'ATS_COURANT OPTION REQUIRES STORAGE OPTION TO BE ACTIVE'
976  call store_error(errmsg)
977  end if
978  !
979  ! -- warn when ATS_COURANT is specified but ATS is not active in TDIS
980  if (this%ats_courant /= dnodata .and. inats == 0) then
981  write (warnmsg, '(a)') &
982  'ATS_COURANT IS SPECIFIED IN THE SFR OPTIONS BLOCK BUT THE '// &
983  'ATS PACKAGE IS NOT ACTIVE IN TDIS, SO THE TIME STEP IS NOT '// &
984  'ADAPTED TO THE COURANT NUMBER. IF THE COURANT NUMBER EXCEEDS 1 '// &
985  'THE EXPLICIT KINEMATIC-WAVE ROUTING MAY OSCILLATE WHILE STILL '// &
986  'CLOSING THE BUDGET. ACTIVATE THE ATS PACKAGE OR USE A SMALLER '// &
987  'TIME STEP.'
988  call store_warning(warnmsg)
989  end if
990  !
991  ! -- pre-compute TVD upstream connectivity when ATS_COURANT is active
992  if (this%ats_courant /= dnodata .and. this%istorage == 1) then
993  call this%sfr_precompute_tvd()
994  end if
995  !
996  ! -- check the sfr reach data
997  call this%sfr_check_reaches()
998 
999  ! -- check the connection data
1000  call this%sfr_check_connections()
1001 
1002  ! -- check the diversion data
1003  if (this%idiversions /= 0) then
1004  call this%sfr_check_diversions()
1005  end if
1006 
1007  ! -- check the diversion data
1008  if (this%istorage == 1) then
1009  call this%sfr_check_initialstages()
1010  end if
1011  !
1012  ! -- terminate if errors were detected in any of the static sfr data
1013  ierr = count_errors()
1014  if (ierr > 0) then
1015  call this%parser%StoreErrorUnit()
1016  end if
1017  !
1018  ! -- setup pakmvrobj
1019  if (this%imover /= 0) then
1020  allocate (this%pakmvrobj)
1021  call this%pakmvrobj%ar(this%maxbound, this%maxbound, this%memoryPath)
1022  end if
integer(i4b), pointer, public inats
flag indicating ats active for simulation
Definition: tdis.f90:28
Here is the call graph for this function:

◆ sfr_bd_obs()

subroutine sfrmodule::sfr_bd_obs ( class(sfrtype this)
private

Method to save simulated values for the SFR package.

Parameters
thisSfrType object

Definition at line 3300 of file gwf-sfr.f90.

3301  ! -- dummy
3302  class(SfrType) :: this !< SfrType object
3303  ! -- local
3304  integer(I4B) :: i
3305  integer(I4B) :: j
3306  integer(I4B) :: n
3307  real(DP) :: v
3308  character(len=100) :: msg
3309  type(ObserveType), pointer :: obsrv => null()
3310  !
3311  ! Write simulated values for all sfr observations
3312  if (this%obs%npakobs > 0) then
3313  call this%obs%obs_bd_clear()
3314  do i = 1, this%obs%npakobs
3315  obsrv => this%obs%pakobs(i)%obsrv
3316  do j = 1, obsrv%indxbnds_count
3317  n = obsrv%indxbnds(j)
3318  v = dzero
3319  select case (obsrv%ObsTypeId)
3320  case ('STAGE')
3321  v = this%stage(n)
3322  case ('TO-MVR')
3323  v = dnodata
3324  if (this%imover == 1) then
3325  v = this%pakmvrobj%get_qtomvr(n)
3326  if (v > dzero) then
3327  v = -v
3328  end if
3329  end if
3330  case ('FROM-MVR')
3331  v = dnodata
3332  if (this%imover == 1) then
3333  v = this%pakmvrobj%get_qfrommvr(n)
3334  end if
3335  case ('EXT-INFLOW')
3336  v = this%inflow(n)
3337  case ('INFLOW')
3338  v = this%usflow(n)
3339  case ('OUTFLOW')
3340  v = this%qoutflow(n)
3341  case ('EXT-OUTFLOW')
3342  v = this%qextoutflow(n)
3343  case ('RAINFALL')
3344  if (this%iboundpak(n) /= 0) then
3345  v = this%rain(n)
3346  else
3347  v = dzero
3348  end if
3349  case ('RUNOFF')
3350  v = this%simrunoff(n)
3351  case ('EVAPORATION')
3352  v = this%simevap(n)
3353  case ('SFR')
3354  v = this%gwflow(n)
3355  case ('UPSTREAM-FLOW')
3356  v = this%usflow(n)
3357  if (this%imover == 1) then
3358  v = v + this%pakmvrobj%get_qfrommvr(n)
3359  end if
3360  case ('DOWNSTREAM-FLOW')
3361  v = this%dsflow(n)
3362  if (v > dzero) then
3363  v = -v
3364  end if
3365  case ('DEPTH')
3366  v = this%depth(n)
3367  case ('WET-PERIMETER')
3368  v = this%calc_perimeter_wet(n, this%depth(n))
3369  case ('WET-AREA')
3370  v = this%calc_area_wet(n, this%depth(n))
3371  case ('WET-WIDTH')
3372  v = this%calc_top_width_wet(n, this%depth(n))
3373  case default
3374  msg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
3375  call store_error(msg)
3376  end select
3377  call this%obs%SaveOneSimval(obsrv, v)
3378  end do
3379  end do
3380  !
3381  ! -- write summary of package error messages
3382  if (count_errors() > 0) then
3383  call this%parser%StoreErrorUnit()
3384  end if
3385  end if
Here is the call graph for this function:

◆ sfr_calc_celerity()

subroutine sfrmodule::sfr_calc_celerity ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  q,
real(dp), intent(out)  celerity 
)
Parameters
thisSfrType object
[in]nreach number
[in]qreach flow
[out]celeritykinematic-wave celerity

Definition at line 2951 of file gwf-sfr.f90.

2952  ! -- dummy
2953  class(SfrType) :: this !< SfrType object
2954  integer(I4B), intent(in) :: n !< reach number
2955  real(DP), intent(in) :: q !< reach flow
2956  real(DP), intent(out) :: celerity !< kinematic-wave celerity
2957  ! -- local
2958  real(DP) :: d
2959  real(DP) :: a
2960  real(DP) :: a2
2961  !
2962  celerity = dzero
2963  call this%sfr_calc_reach_depth(n, q, d)
2964  if (d > dzero) then
2965  a = this%calc_area_wet(n, d)
2966  call this%sfr_calc_reach_depth(n, q + this%deps, d)
2967  a2 = this%calc_area_wet(n, d)
2968  if (a2 > a) then
2969  celerity = this%deps / (a2 - a)
2970  end if
2971  end if

◆ sfr_calc_cond()

subroutine sfrmodule::sfr_calc_cond ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth,
real(dp), intent(inout)  cond,
real(dp), intent(in), optional  hsfr,
real(dp), intent(in), optional  h_temp 
)
private

Method to calculate the reach-aquifer conductance for a SFR package reach.

Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth
[in,out]condreach-aquifer conductance
[in]hsfrstream stage
[in]h_temphead in gw cell

Definition at line 4269 of file gwf-sfr.f90.

4270  ! -- dummy
4271  class(SfrType) :: this !< SfrType object
4272  integer(I4B), intent(in) :: n !< reach number
4273  real(DP), intent(in) :: depth !< reach depth
4274  real(DP), intent(inout) :: cond !< reach-aquifer conductance
4275  real(DP), intent(in), optional :: hsfr !< stream stage
4276  real(DP), intent(in), optional :: h_temp !< head in gw cell
4277  ! -- local
4278  integer(I4B) :: node
4279  real(DP) :: wp
4280  real(DP) :: vscratio
4281  !
4282  ! -- initialize conductance
4283  cond = dzero
4284  !
4285  ! -- initial viscosity ratio to 1
4286  vscratio = done
4287  !
4288  ! -- calculate conductance if GWF cell is active
4289  ! rch-gwf flow will not occur if reach connected to an constant head cell
4290  node = this%igwfnode(n)
4291  if (node > 0) then
4292  if (this%ibound(node) > 0) then
4293  !
4294  ! -- direction of gradient across streambed determines which vsc ratio
4295  if (this%ivsc == 1) then
4296  if (hsfr > h_temp) then
4297  ! strm stg > gw head
4298  vscratio = this%viscratios(1, n)
4299  else
4300  vscratio = this%viscratios(2, n)
4301  end if
4302  end if
4303  wp = this%calc_perimeter_wet(n, depth)
4304  cond = this%hk(n) * vscratio * this%length(n) * wp / this%bthick(n)
4305  end if
4306  end if

◆ sfr_calc_div()

subroutine sfrmodule::sfr_calc_div ( class(sfrtype this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  i,
real(dp), intent(inout)  qd,
real(dp), intent(inout)  qdiv 
)
private

Method to calculate the diversion flow for a diversion connected to a SFR package reach. The downstream flow for a reach is passed in and adjusted by the diversion flow amount calculated in this method.

Parameters
thisSfrType object
[in]nreach number
[in]idiversion number in reach
[in,out]qdremaining downstream flow for reach
[in,out]qdivdiversion flow for diversion i

Definition at line 4316 of file gwf-sfr.f90.

4317  ! -- dummy
4318  class(SfrType) :: this !< SfrType object
4319  integer(I4B), intent(in) :: n !< reach number
4320  integer(I4B), intent(in) :: i !< diversion number in reach
4321  real(DP), intent(inout) :: qd !< remaining downstream flow for reach
4322  real(DP), intent(inout) :: qdiv !< diversion flow for diversion i
4323  ! -- local
4324  character(len=10) :: cp
4325  integer(I4B) :: jpos
4326  integer(I4B) :: n2
4327  real(DP) :: v
4328  !
4329  ! -- set local variables
4330  jpos = this%iadiv(n) + i - 1
4331  n2 = this%divreach(jpos)
4332  cp = this%divcprior(jpos)
4333  v = this%divflow(jpos)
4334  !
4335  ! -- calculate diversion
4336  select case (cp)
4337  ! -- flood diversion
4338  case ('EXCESS')
4339  if (qd < v) then
4340  v = dzero
4341  else
4342  v = qd - v
4343  end if
4344  ! -- diversion percentage
4345  case ('FRACTION')
4346  v = qd * v
4347  ! -- STR priority algorithm
4348  case ('THRESHOLD')
4349  if (qd < v) then
4350  v = dzero
4351  end if
4352  ! -- specified diversion
4353  case ('UPTO')
4354  if (v > qd) then
4355  v = qd
4356  end if
4357  case default
4358  v = dzero
4359  end select
4360  !
4361  ! -- update upstream from for downstream reaches
4362  qd = qd - v
4363  qdiv = v

◆ sfr_calc_qd()

subroutine sfrmodule::sfr_calc_qd ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth,
real(dp), intent(in)  hgwf,
real(dp), intent(inout)  qgwf,
real(dp), intent(inout)  qd 
)
private

Method to calculate downstream flow for a SFR package reach.

Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth
[in]hgwfgroundwater head in connected GWF cell
[in,out]qgwfgroundwater leakage for reach
[in,out]qdresidual

Definition at line 4031 of file gwf-sfr.f90.

4032  ! -- dummy
4033  class(SfrType) :: this !< SfrType object
4034  integer(I4B), intent(in) :: n !< reach number
4035  real(DP), intent(in) :: depth !< reach depth
4036  real(DP), intent(in) :: hgwf !< groundwater head in connected GWF cell
4037  real(DP), intent(inout) :: qgwf !< groundwater leakage for reach
4038  real(DP), intent(inout) :: qd !< residual
4039  ! -- local
4040  real(DP) :: qsrc
4041  !
4042  ! -- initialize residual
4043  qd = dzero
4044  !
4045  ! -- calculate total water sources excluding groundwater leakage
4046  call this%sfr_calc_qsource(n, depth, qsrc)
4047  !
4048  ! -- estimate groundwater leakage
4049  call this%sfr_calc_qgwf(n, depth, hgwf, qgwf)
4050  if (-qgwf > qsrc) qgwf = -qsrc
4051  !
4052  ! -- calculate down stream flow
4053  qd = qsrc + qgwf
4054  !
4055  ! -- limit downstream flow to a positive value
4056  if (qd < dem30) qd = dzero

◆ sfr_calc_qgwf()

subroutine sfrmodule::sfr_calc_qgwf ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth,
real(dp), intent(in)  hgwf,
real(dp), intent(inout)  qgwf,
real(dp), intent(inout), optional  gwfhcof,
real(dp), intent(inout), optional  gwfrhs 
)
private

Method to calculate the reach-aquifer exchange for a SFR package reach. The reach-aquifer exchange is relative to the reach. Calculated flow is positive if flow is from the aquifer to the reach.

Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth
[in]hgwfhead in GWF cell connected to reach
[in,out]qgwfreach-aquifer exchange
[in,out]gwfhcofdiagonal coefficient term for reach
[in,out]gwfrhsright-hand side term for reach

Definition at line 4182 of file gwf-sfr.f90.

4183  ! -- dummy
4184  class(SfrType) :: this !< SfrType object
4185  integer(I4B), intent(in) :: n !< reach number
4186  real(DP), intent(in) :: depth !< reach depth
4187  real(DP), intent(in) :: hgwf !< head in GWF cell connected to reach
4188  real(DP), intent(inout) :: qgwf !< reach-aquifer exchange
4189  real(DP), intent(inout), optional :: gwfhcof !< diagonal coefficient term for reach
4190  real(DP), intent(inout), optional :: gwfrhs !< right-hand side term for reach
4191  ! -- local
4192  integer(I4B) :: node
4193  real(DP) :: tp
4194  real(DP) :: bt
4195  real(DP) :: hsfr
4196  real(DP) :: h_temp
4197  real(DP) :: cond
4198  real(DP) :: sat
4199  real(DP) :: derv
4200  real(DP) :: gwfhcof0
4201  real(DP) :: gwfrhs0
4202  !
4203  ! -- initialize qgwf
4204  qgwf = dzero
4205  !
4206  ! -- skip sfr-aquifer exchange in external cells
4207  node = this%igwfnode(n)
4208  if (node < 1) return
4209  !
4210  ! -- skip sfr-aquifer exchange in inactive cells
4211  if (this%ibound(node) == 0) return
4212  !
4213  ! -- calculate saturation
4214  call schsmooth(depth, sat, derv)
4215  !
4216  ! -- terms for calculating direction of gradient across streambed
4217  tp = this%strtop(n)
4218  bt = tp - this%bthick(n)
4219  hsfr = tp + depth
4220  h_temp = hgwf
4221  if (h_temp < bt) then
4222  h_temp = bt
4223  end if
4224  !
4225  ! -- calculate conductance
4226  call this%sfr_calc_cond(n, depth, cond, hsfr, h_temp)
4227  !
4228  ! -- calculate groundwater leakage
4229  qgwf = sat * cond * (h_temp - hsfr)
4230  gwfrhs0 = -sat * cond * hsfr
4231  gwfhcof0 = -sat * cond
4232  !
4233  ! Add density contributions, if active
4234  if (this%idense /= 0) then
4235  call this%sfr_calculate_density_exchange(n, hsfr, hgwf, cond, tp, &
4236  qgwf, gwfhcof0, gwfrhs0)
4237  end if
4238  !
4239  ! -- Set gwfhcof and gwfrhs if present
4240  if (present(gwfhcof)) gwfhcof = gwfhcof0
4241  if (present(gwfrhs)) gwfrhs = gwfrhs0
Here is the call graph for this function:

◆ sfr_calc_qman()

subroutine sfrmodule::sfr_calc_qman ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth,
real(dp), intent(inout)  qman 
)
private

Method to calculate the streamflow using Manning's equation for a SFR package reach.

Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth
[in,out]qmanstreamflow

Definition at line 4112 of file gwf-sfr.f90.

4113  ! -- dummy
4114  class(SfrType) :: this !< SfrType object
4115  integer(I4B), intent(in) :: n !< reach number
4116  real(DP), intent(in) :: depth !< reach depth
4117  real(DP), intent(inout) :: qman !< streamflow
4118  ! -- local
4119  integer(I4B) :: npts
4120  integer(I4B) :: i0
4121  integer(I4B) :: i1
4122  real(DP) :: sat
4123  real(DP) :: derv
4124  real(DP) :: s
4125  real(DP) :: r
4126  real(DP) :: aw
4127  real(DP) :: wp
4128  real(DP) :: rh
4129  !
4130  ! -- initialize variables
4131  qman = dzero
4132  !
4133  ! -- calculate Manning's discharge for non-zero depths
4134  if (depth > dzero) then
4135  npts = this%ncrosspts(n)
4136  !
4137  ! -- set constant terms for Manning's equation
4138  call schsmooth(depth, sat, derv)
4139  s = this%slope(n)
4140  !
4141  ! -- calculate the mannings coefficient that is a
4142  ! function of depth
4143  if (npts > 1) then
4144  !
4145  ! -- get the location of the cross-section data for the reach
4146  i0 = this%iacross(n)
4147  i1 = this%iacross(n + 1) - 1
4148  !
4149  ! -- get the Manning's sum of the Manning's discharge
4150  ! for each section
4151  qman = get_mannings_section(npts, &
4152  this%station(i0:i1), &
4153  this%xsheight(i0:i1), &
4154  this%xsrough(i0:i1), &
4155  this%rough(n), &
4156  this%unitconv, &
4157  s, &
4158  depth)
4159  else
4160  r = this%rough(n)
4161  aw = this%calc_area_wet(n, depth)
4162  wp = this%calc_perimeter_wet(n, depth)
4163  if (wp > dzero) then
4164  rh = aw / wp
4165  else
4166  rh = dzero
4167  end if
4168  qman = this%unitconv * aw * (rh**dtwothirds) * sqrt(s) / r
4169  end if
4170  !
4171  ! -- calculate stream flow
4172  qman = sat * qman
4173  end if
Here is the call graph for this function:

◆ sfr_calc_qsource()

subroutine sfrmodule::sfr_calc_qsource ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  depth,
real(dp), intent(inout)  qsrc 
)
private

Method to calculate the sum of sources for reach, excluding reach leakage, for a SFR package reach.

Parameters
thisSfrType object
[in]nreach number
[in]depthreach depth
[in,out]qsrcsum of sources for reach

Definition at line 4064 of file gwf-sfr.f90.

4065  ! -- dummy
4066  class(SfrType) :: this !< SfrType object
4067  integer(I4B), intent(in) :: n !< reach number
4068  real(DP), intent(in) :: depth !< reach depth
4069  real(DP), intent(inout) :: qsrc !< sum of sources for reach
4070  ! -- local
4071  real(DP) :: qu
4072  real(DP) :: qi
4073  real(DP) :: qr
4074  real(DP) :: qe
4075  real(DP) :: qro
4076  real(DP) :: qfrommvr
4077  real(DP) :: a
4078  real(DP) :: ae
4079  !
4080  ! -- initialize residual
4081  qsrc = dzero
4082  !
4083  ! -- calculate flow terms
4084  qu = this%usflow(n)
4085  qi = this%inflow(n)
4086  qro = this%runoff(n)
4087  !
4088  ! -- calculate rainfall and evap
4089  a = this%calc_surface_area(n)
4090  ae = this%calc_surface_area_wet(n, depth)
4091  qr = this%rain(n) * a
4092  qe = this%evap(n) * ae
4093  !
4094  ! -- calculate mover term
4095  qfrommvr = dzero
4096  if (this%imover == 1) then
4097  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
4098  end if
4099  !
4100  ! -- calculate down stream flow
4101  qsrc = qu + qi + qr - qe + qro + qfrommvr
4102  !
4103  ! -- adjust runoff or evaporation if sum of sources is negative
4104  call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)

◆ sfr_calc_reach_depth()

subroutine sfrmodule::sfr_calc_reach_depth ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  q1,
real(dp), intent(inout)  d1 
)
private

Method to calculate the depth at the midpoint of a reach.

Parameters
thisSfrType object
[in]nreach number
[in]q1streamflow
[in,out]d1stream depth at midpoint of reach

Definition at line 4370 of file gwf-sfr.f90.

4371  ! -- dummy
4372  class(SfrType) :: this !< SfrType object
4373  integer(I4B), intent(in) :: n !< reach number
4374  real(DP), intent(in) :: q1 !< streamflow
4375  real(DP), intent(inout) :: d1 !< stream depth at midpoint of reach
4376  ! -- local
4377  real(DP) :: w
4378  real(DP) :: s
4379  real(DP) :: r
4380  real(DP) :: qconst
4381  !
4382  ! -- initialize slope and roughness
4383  s = this%slope(n)
4384  r = this%rough(n)
4385  !
4386  ! -- calculate stream depth at the midpoint
4387  if (q1 > dzero) then
4388  if (this%ncrosspts(n) > 1) then
4389  call this%sfr_calc_xs_depth(n, q1, d1)
4390  else
4391  w = this%station(this%iacross(n))
4392  qconst = this%unitconv * w * sqrt(s) / r
4393  d1 = (q1 / qconst)**dp6
4394  end if
4395  else
4396  d1 = dzero
4397  end if

◆ sfr_calc_xs_depth()

subroutine sfrmodule::sfr_calc_xs_depth ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  qrch,
real(dp), intent(inout)  d 
)
private

Method to calculate the depth at the midpoint of a reach with a irregular cross-section using Newton-Raphson.

Parameters
thisSfrType object
[in]nreach number
[in]qrchstreamflow
[in,out]dstream depth at midpoint of reach

Definition at line 4405 of file gwf-sfr.f90.

4406  ! -- dummy
4407  class(SfrType) :: this !< SfrType object
4408  integer(I4B), intent(in) :: n !< reach number
4409  real(DP), intent(in) :: qrch !< streamflow
4410  real(DP), intent(inout) :: d !< stream depth at midpoint of reach
4411  ! -- local
4412  integer(I4B) :: iter
4413  real(DP) :: perturbation
4414  real(DP) :: q0
4415  real(DP) :: q1
4416  real(DP) :: dq
4417  real(DP) :: derv
4418  real(DP) :: dd
4419  real(DP) :: residual
4420  !
4421  ! -- initialize variables
4422  perturbation = this%deps * dtwo
4423  d = dzero
4424  q0 = dzero
4425  residual = q0 - qrch
4426  !
4427  ! -- Newton-Raphson iteration
4428  nriter: do iter = 1, this%maxsfrit
4429  call this%sfr_calc_qman(n, d + perturbation, q1)
4430  dq = (q1 - q0)
4431  if (dq /= dzero) then
4432  derv = perturbation / (q1 - q0)
4433  else
4434  derv = dzero
4435  end if
4436  dd = derv * residual
4437  d = d - dd
4438  call this%sfr_calc_qman(n, d, q0)
4439  residual = q0 - qrch
4440  !
4441  ! -- check for convergence
4442  if (abs(dd) < this%dmaxchg) then
4443  exit nriter
4444  end if
4445  end do nriter

◆ sfr_calculate_density_exchange()

subroutine sfrmodule::sfr_calculate_density_exchange ( class(sfrtype), intent(inout)  this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(in)  cond,
real(dp), intent(in)  tops,
real(dp), intent(inout)  flow,
real(dp), intent(inout)  gwfhcof,
real(dp), intent(inout)  gwfrhs 
)

Method to calculate groundwater-reach density exchange terms for a SFR package reach.

Member variable used here denseterms : shape (3, MAXBOUND), filled by buoyancy package col 1 is relative density of sfr (densesfr / denseref) col 2 is relative density of gwf cell (densegwf / denseref) col 3 is elevation of gwf cell

Parameters
[in,out]thisSfrType object
[in]nreach number
[in]stagereach stage
[in]headhead in connected GWF cell
[in]condreach conductance
[in]topstop elevation of streambed
[in,out]flowcalculated flow, updated here with density terms
[in,out]gwfhcofGWF diagonal coefficient, updated here with density terms
[in,out]gwfrhsGWF right-hand-side value, updated here with density terms

Definition at line 6030 of file gwf-sfr.f90.

6032  ! -- dummy
6033  class(SfrType), intent(inout) :: this !< SfrType object
6034  integer(I4B), intent(in) :: n !< reach number
6035  real(DP), intent(in) :: stage !< reach stage
6036  real(DP), intent(in) :: head !< head in connected GWF cell
6037  real(DP), intent(in) :: cond !< reach conductance
6038  real(DP), intent(in) :: tops !< top elevation of streambed
6039  real(DP), intent(inout) :: flow !< calculated flow, updated here with density terms
6040  real(DP), intent(inout) :: gwfhcof !< GWF diagonal coefficient, updated here with density terms
6041  real(DP), intent(inout) :: gwfrhs !< GWF right-hand-side value, updated here with density terms
6042  ! -- local
6043  real(DP) :: ss
6044  real(DP) :: hh
6045  real(DP) :: havg
6046  real(DP) :: rdensesfr
6047  real(DP) :: rdensegwf
6048  real(DP) :: rdenseavg
6049  real(DP) :: elevsfr
6050  real(DP) :: elevgwf
6051  real(DP) :: elevavg
6052  real(DP) :: d1
6053  real(DP) :: d2
6054  logical(LGP) :: stage_below_bot
6055  logical(LGP) :: head_below_bot
6056  !
6057  ! -- Set sfr density to sfr density or gwf density
6058  if (stage >= tops) then
6059  ss = stage
6060  stage_below_bot = .false.
6061  rdensesfr = this%denseterms(1, n) ! sfr rel density
6062  else
6063  ss = tops
6064  stage_below_bot = .true.
6065  rdensesfr = this%denseterms(2, n) ! gwf rel density
6066  end if
6067  !
6068  ! -- set hh to head or tops (top elev of streambed)
6069  if (head >= tops) then
6070  hh = head
6071  head_below_bot = .false.
6072  rdensegwf = this%denseterms(2, n) ! gwf rel density
6073  else
6074  hh = tops
6075  head_below_bot = .true.
6076  rdensegwf = this%denseterms(1, n) ! sfr rel density
6077  end if
6078  !
6079  ! -- todo: hack because denseterms not updated in a cf calculation
6080  if (rdensegwf == dzero) return
6081  !
6082  ! -- Update flow
6083  if (stage_below_bot .and. head_below_bot) then
6084  !
6085  ! -- flow is zero, so no terms are updated
6086  !
6087  else
6088  !
6089  ! -- calculate average relative density
6090  rdenseavg = dhalf * (rdensesfr + rdensegwf)
6091  !
6092  ! -- Add contribution of first density term:
6093  ! cond * (denseavg/denseref - 1) * (hgwf - hsfr)
6094  d1 = cond * (rdenseavg - done)
6095  gwfhcof = gwfhcof - d1
6096  gwfrhs = gwfrhs - d1 * ss
6097  d1 = d1 * (hh - ss)
6098  flow = flow + d1
6099  !
6100  ! -- Add second density term if stage and head not below bottom
6101  if (.not. stage_below_bot .and. .not. head_below_bot) then
6102  !
6103  ! -- Add contribution of second density term:
6104  ! cond * (havg - elevavg) * (densegwf - densesfr) / denseref
6105  elevgwf = this%denseterms(3, n)
6106  elevsfr = tops
6107  elevavg = dhalf * (elevsfr + elevgwf)
6108  havg = dhalf * (hh + ss)
6109  d2 = cond * (havg - elevavg) * (rdensegwf - rdensesfr)
6110  gwfrhs = gwfrhs + d2
6111  flow = flow + d2
6112  end if
6113  end if

◆ sfr_cc()

subroutine sfrmodule::sfr_cc ( class(sfrtype), intent(inout)  this,
integer(i4b), intent(in)  innertot,
integer(i4b), intent(in)  kiter,
integer(i4b), intent(in)  iend,
integer(i4b), intent(in)  icnvgmod,
character(len=lenpakloc), intent(inout)  cpak,
integer(i4b), intent(inout)  ipak,
real(dp), intent(inout)  dpak 
)
private

Perform additional convergence checks on the flow between the SFR package and the model it is attached to.

Parameters
[in,out]thisSfrType object
[in]innertottotal number of inner iterations
[in]kiterPicard iteration number
[in]iendflag indicating if this is the last Picard iteration
[in]icnvgmodflag inficating if the model has met specific convergence criteria
[in,out]cpakstring for user node
[in,out]ipaklocation of the maximum dependent variable change
[in,out]dpakmaximum dependent variable change

Definition at line 2419 of file gwf-sfr.f90.

2420  ! -- modules
2421  use tdismodule, only: totim, kstp, kper, delt
2422  ! -- dummy
2423  class(SfrType), intent(inout) :: this !< SfrType object
2424  integer(I4B), intent(in) :: innertot !< total number of inner iterations
2425  integer(I4B), intent(in) :: kiter !< Picard iteration number
2426  integer(I4B), intent(in) :: iend !< flag indicating if this is the last Picard iteration
2427  integer(I4B), intent(in) :: icnvgmod !< flag inficating if the model has met specific convergence criteria
2428  character(len=LENPAKLOC), intent(inout) :: cpak !< string for user node
2429  integer(I4B), intent(inout) :: ipak !< location of the maximum dependent variable change
2430  real(DP), intent(inout) :: dpak !< maximum dependent variable change
2431  ! -- local
2432  character(len=LENPAKLOC) :: cloc
2433  character(len=LINELENGTH) :: tag
2434  integer(I4B) :: icheck
2435  integer(I4B) :: ipakfail
2436  integer(I4B) :: locdhmax
2437  integer(I4B) :: locrmax
2438  integer(I4B) :: locdqfrommvrmax
2439  integer(I4B) :: ntabrows
2440  integer(I4B) :: ntabcols
2441  integer(I4B) :: n
2442  real(DP) :: q
2443  real(DP) :: q0
2444  real(DP) :: qtolfact
2445  real(DP) :: dh
2446  real(DP) :: r
2447  real(DP) :: dhmax
2448  real(DP) :: rmax
2449  real(DP) :: dqfrommvr
2450  real(DP) :: dqfrommvrmax
2451  !
2452  ! -- initialize local variables
2453  icheck = this%iconvchk
2454  ipakfail = 0
2455  locdhmax = 0
2456  locrmax = 0
2457  r = dzero
2458  dhmax = dzero
2459  rmax = dzero
2460  locdqfrommvrmax = 0
2461  dqfrommvrmax = dzero
2462  !
2463  ! -- if not saving package convergence data on check convergence if
2464  ! the model is considered converged
2465  if (this%ipakcsv == 0) then
2466  if (icnvgmod == 0) then
2467  icheck = 0
2468  end if
2469  !
2470  ! -- saving package convergence data
2471  else
2472  !
2473  ! -- header for package csv
2474  if (.not. associated(this%pakcsvtab)) then
2475  !
2476  ! -- determine the number of columns and rows
2477  ntabrows = 1
2478  ntabcols = 9
2479  if (this%imover == 1) then
2480  ntabcols = ntabcols + 2
2481  end if
2482  !
2483  ! -- setup table
2484  call table_cr(this%pakcsvtab, this%packName, '')
2485  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
2486  lineseparator=.false., separator=',', &
2487  finalize=.false.)
2488  !
2489  ! -- add columns to package csv
2490  tag = 'total_inner_iterations'
2491  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2492  tag = 'totim'
2493  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2494  tag = 'kper'
2495  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2496  tag = 'kstp'
2497  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2498  tag = 'nouter'
2499  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2500  tag = 'dvmax'
2501  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2502  tag = 'dvmax_loc'
2503  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2504  tag = 'dinflowmax'
2505  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2506  tag = 'dinflowmax_loc'
2507  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2508  if (this%imover == 1) then
2509  tag = 'dqfrommvrmax'
2510  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2511  tag = 'dqfrommvrmax_loc'
2512  call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
2513  end if
2514  end if
2515  end if
2516  !
2517  ! -- perform package convergence check
2518  if (icheck /= 0) then
2519  final_check: do n = 1, this%maxbound
2520  if (this%iboundpak(n) == 0) cycle
2521  !
2522  ! -- set the Q to length factor
2523  qtolfact = delt / this%calc_surface_area(n)
2524  !
2525  ! -- calculate stage change
2526  dh = this%stage0(n) - this%stage(n)
2527  !
2528  ! -- evaluate flow difference if the time step is transient
2529  if (this%gwfiss == 0) then
2530  r = this%usflow0(n) - this%usflow(n)
2531  !
2532  ! -- normalize flow difference and convert to a depth
2533  r = r * qtolfact
2534  end if
2535  !
2536  ! -- q from mvr
2537  dqfrommvr = dzero
2538  if (this%imover == 1) then
2539  q = this%pakmvrobj%get_qfrommvr(n)
2540  q0 = this%pakmvrobj%get_qfrommvr0(n)
2541  dqfrommvr = qtolfact * (q0 - q)
2542  end if
2543  !
2544  ! -- evaluate magnitude of differences
2545  if (n == 1) then
2546  locdhmax = n
2547  dhmax = dh
2548  locrmax = n
2549  rmax = r
2550  dqfrommvrmax = dqfrommvr
2551  locdqfrommvrmax = n
2552  else
2553  if (abs(dh) > abs(dhmax)) then
2554  locdhmax = n
2555  dhmax = dh
2556  end if
2557  if (abs(r) > abs(rmax)) then
2558  locrmax = n
2559  rmax = r
2560  end if
2561  if (abs(dqfrommvr) > abs(dqfrommvrmax)) then
2562  dqfrommvrmax = dqfrommvr
2563  locdqfrommvrmax = n
2564  end if
2565  end if
2566  end do final_check
2567  !
2568  ! -- set dpak and cpak
2569  if (abs(dhmax) > abs(dpak)) then
2570  ipak = locdhmax
2571  dpak = dhmax
2572  write (cloc, "(a,'-',a)") trim(this%packName), 'stage'
2573  cpak = trim(cloc)
2574  end if
2575  if (abs(rmax) > abs(dpak)) then
2576  ipak = locrmax
2577  dpak = rmax
2578  write (cloc, "(a,'-',a)") trim(this%packName), 'inflow'
2579  cpak = trim(cloc)
2580  end if
2581  if (this%imover == 1) then
2582  if (abs(dqfrommvrmax) > abs(dpak)) then
2583  ipak = locdqfrommvrmax
2584  dpak = dqfrommvrmax
2585  write (cloc, "(a,'-',a)") trim(this%packName), 'qfrommvr'
2586  cpak = trim(cloc)
2587  end if
2588  end if
2589  !
2590  ! -- write convergence data to package csv
2591  if (this%ipakcsv /= 0) then
2592  !
2593  ! -- write the data
2594  call this%pakcsvtab%add_term(innertot)
2595  call this%pakcsvtab%add_term(totim)
2596  call this%pakcsvtab%add_term(kper)
2597  call this%pakcsvtab%add_term(kstp)
2598  call this%pakcsvtab%add_term(kiter)
2599  call this%pakcsvtab%add_term(dhmax)
2600  call this%pakcsvtab%add_term(locdhmax)
2601  call this%pakcsvtab%add_term(rmax)
2602  call this%pakcsvtab%add_term(locrmax)
2603  if (this%imover == 1) then
2604  call this%pakcsvtab%add_term(dqfrommvrmax)
2605  call this%pakcsvtab%add_term(locdqfrommvrmax)
2606  end if
2607  !
2608  ! -- finalize the package csv
2609  if (iend == 1) then
2610  call this%pakcsvtab%finalize_table()
2611  end if
2612  end if
2613  end if
2614  !
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:35
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:27
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:26
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:32
Here is the call graph for this function:

◆ sfr_cf()

subroutine sfrmodule::sfr_cf ( class(sfrtype this)

Formulate the hcof and rhs terms for the WEL package that will be added to the coefficient matrix and right-hand side vector.

Parameters
thisSfrType object

Definition at line 2241 of file gwf-sfr.f90.

2242  ! -- dummy
2243  class(SfrType) :: this !< SfrType object
2244  ! -- local
2245  integer(I4B) :: n
2246  integer(I4B) :: igwfnode
2247  !
2248  ! -- return if no sfr reaches
2249  if (this%nbound == 0) return
2250  !
2251  ! -- find highest active cell
2252  do n = 1, this%nbound
2253  igwfnode = this%igwftopnode(n)
2254  if (igwfnode > 0) then
2255  if (this%ibound(igwfnode) == 0) then
2256  call this%dis%highest_active(igwfnode, this%ibound)
2257  end if
2258  end if
2259  this%igwfnode(n) = igwfnode
2260  this%nodelist(n) = igwfnode
2261  end do

◆ sfr_check_connections()

subroutine sfrmodule::sfr_check_connections ( class(sfrtype this)
private

Method to check connection data for a SFR package. This method also creates the tables used to print input data, if this option in enabled in the SFR package.

Parameters
thisSfrType object

Definition at line 4632 of file gwf-sfr.f90.

4633  ! -- dummy
4634  class(SfrType) :: this !< SfrType object
4635  ! -- local
4636  logical(LGP) :: lreorder
4637  character(len=5) :: crch
4638  character(len=5) :: crch2
4639  character(len=LINELENGTH) :: text
4640  character(len=LINELENGTH) :: title
4641  integer(I4B) :: n
4642  integer(I4B) :: nn
4643  integer(I4B) :: nc
4644  integer(I4B) :: i
4645  integer(I4B) :: ii
4646  integer(I4B) :: j
4647  integer(I4B) :: ifound
4648  integer(I4B) :: ierr
4649  integer(I4B) :: maxconn
4650  integer(I4B) :: ntabcol
4651  !
4652  ! -- determine if the reaches have been reordered
4653  lreorder = .false.
4654  do j = 1, this%MAXBOUND
4655  n = this%isfrorder(j)
4656  if (n /= j) then
4657  lreorder = .true.
4658  exit
4659  end if
4660  end do
4661  !
4662  ! -- write message that the solution order h
4663  if (lreorder) then
4664  write (this%iout, '(/,1x,a)') &
4665  trim(adjustl(this%text))//' PACKAGE ('// &
4666  trim(adjustl(this%packName))//') REACH SOLUTION HAS BEEN '// &
4667  'REORDERED USING A DAG'
4668  !
4669  ! -- print table
4670  if (this%iprpak /= 0) then
4671  !
4672  ! -- reset the input table object
4673  ntabcol = 2
4674  title = trim(adjustl(this%text))//' PACKAGE ('// &
4675  trim(adjustl(this%packName))//') REACH SOLUTION ORDER'
4676  call table_cr(this%inputtab, this%packName, title)
4677  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4678  text = 'ORDER'
4679  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4680  text = 'REACH'
4681  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4682  !
4683  ! -- upstream connection data
4684  do j = 1, this%maxbound
4685  n = this%isfrorder(j)
4686  call this%inputtab%add_term(j)
4687  call this%inputtab%add_term(n)
4688  end do
4689  end if
4690  end if
4691  !
4692  ! -- create input table for reach connections data
4693  if (this%iprpak /= 0) then
4694  !
4695  ! -- calculate the maximum number of connections
4696  maxconn = 0
4697  do n = 1, this%maxbound
4698  maxconn = max(maxconn, this%nconnreach(n))
4699  end do
4700  ntabcol = 1 + maxconn
4701  !
4702  ! -- reset the input table object
4703  title = trim(adjustl(this%text))//' PACKAGE ('// &
4704  trim(adjustl(this%packName))//') STATIC REACH CONNECTION DATA'
4705  call table_cr(this%inputtab, this%packName, title)
4706  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4707  text = 'REACH'
4708  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4709  do n = 1, maxconn
4710  write (text, '(a,1x,i6)') 'CONN', n
4711  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4712  end do
4713  end if
4714  !
4715  ! -- check the reach connections for simple errors
4716  ! -- connection check
4717  do n = 1, this%MAXBOUND
4718  write (crch, '(i5)') n
4719  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4720  nn = this%ja(i)
4721  write (crch2, '(i5)') nn
4722  ifound = 0
4723  connreach: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4724  nc = this%ja(ii)
4725  if (nc == n) then
4726  ifound = 1
4727  exit connreach
4728  end if
4729  end do connreach
4730  if (ifound /= 1) then
4731  errmsg = 'Reach '//crch//' is connected to '// &
4732  'reach '//crch2//' but reach '//crch2// &
4733  ' is not connected to reach '//crch//'.'
4734  call store_error(errmsg)
4735  end if
4736  end do eachconn
4737  !
4738  ! -- write connection data to the table
4739  if (this%iprpak /= 0) then
4740  call this%inputtab%add_term(n)
4741  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4742  call this%inputtab%add_term(this%ja(i))
4743  end do
4744  nn = maxconn - this%nconnreach(n)
4745  do i = 1, nn
4746  call this%inputtab%add_term(' ')
4747  end do
4748  end if
4749  end do
4750  !
4751  ! -- check for incorrect connections between upstream connections
4752  !
4753  ! -- check upstream connections for each reach
4754  ierr = 0
4755  do n = 1, this%maxbound
4756  write (crch, '(i5)') n
4757  eachconnv: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4758  !
4759  ! -- skip downstream connections
4760  if (this%idir(i) < 0) cycle eachconnv
4761  nn = this%ja(i)
4762  write (crch2, '(i5)') nn
4763  connreachv: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4764  ! -- skip downstream connections
4765  if (this%idir(ii) < 0) cycle connreachv
4766  nc = this%ja(ii)
4767  !
4768  ! -- if nc == n then that means reach n is an upstream connection for
4769  ! reach nn and reach nn is an upstream connection for reach n
4770  if (nc == n) then
4771  ierr = ierr + 1
4772  errmsg = 'Reach '//crch//' is connected to '// &
4773  'reach '//crch2//' but streamflow from reach '// &
4774  crch//' to reach '//crch2//' is not permitted.'
4775  call store_error(errmsg)
4776  exit connreachv
4777  end if
4778  end do connreachv
4779  end do eachconnv
4780  end do
4781  !
4782  ! -- terminate if connectivity errors
4783  if (count_errors() > 0) then
4784  call this%parser%StoreErrorUnit()
4785  end if
4786  !
4787  ! -- check that downstream reaches for a reach are
4788  ! the upstream reaches for the reach
4789  do n = 1, this%maxbound
4790  write (crch, '(i5)') n
4791  eachconnds: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4792  nn = this%ja(i)
4793  if (this%idir(i) > 0) cycle eachconnds
4794  write (crch2, '(i5)') nn
4795  ifound = 0
4796  connreachds: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4797  nc = this%ja(ii)
4798  if (nc == n) then
4799  if (this%idir(i) /= this%idir(ii)) then
4800  ifound = 1
4801  end if
4802  exit connreachds
4803  end if
4804  end do connreachds
4805  if (ifound /= 1) then
4806  errmsg = 'Reach '//crch//' downstream connected reach '// &
4807  'is reach '//crch2//' but reach '//crch//' is not'// &
4808  ' the upstream connected reach for reach '//crch2//'.'
4809  call store_error(errmsg)
4810  end if
4811  end do eachconnds
4812  end do
4813  !
4814  ! -- create input table for upstream and downstream connections
4815  if (this%iprpak /= 0) then
4816  !
4817  ! -- calculate the maximum number of upstream connections
4818  maxconn = 0
4819  do n = 1, this%maxbound
4820  ii = 0
4821  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4822  if (this%idir(i) > 0) then
4823  ii = ii + 1
4824  end if
4825  end do
4826  maxconn = max(maxconn, ii)
4827  end do
4828  ntabcol = 1 + maxconn
4829  !
4830  ! -- reset the input table object
4831  title = trim(adjustl(this%text))//' PACKAGE ('// &
4832  trim(adjustl(this%packName))//') STATIC UPSTREAM REACH '// &
4833  'CONNECTION DATA'
4834  call table_cr(this%inputtab, this%packName, title)
4835  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4836  text = 'REACH'
4837  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4838  do n = 1, maxconn
4839  write (text, '(a,1x,i6)') 'UPSTREAM CONN', n
4840  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4841  end do
4842  !
4843  ! -- upstream connection data
4844  do n = 1, this%maxbound
4845  call this%inputtab%add_term(n)
4846  ii = 0
4847  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4848  if (this%idir(i) > 0) then
4849  call this%inputtab%add_term(this%ja(i))
4850  ii = ii + 1
4851  end if
4852  end do
4853  nn = maxconn - ii
4854  do i = 1, nn
4855  call this%inputtab%add_term(' ')
4856  end do
4857  end do
4858  !
4859  ! -- calculate the maximum number of downstream connections
4860  maxconn = 0
4861  do n = 1, this%maxbound
4862  ii = 0
4863  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4864  if (this%idir(i) < 0) then
4865  ii = ii + 1
4866  end if
4867  end do
4868  maxconn = max(maxconn, ii)
4869  end do
4870  ntabcol = 1 + maxconn
4871  !
4872  ! -- reset the input table object
4873  title = trim(adjustl(this%text))//' PACKAGE ('// &
4874  trim(adjustl(this%packName))//') STATIC DOWNSTREAM '// &
4875  'REACH CONNECTION DATA'
4876  call table_cr(this%inputtab, this%packName, title)
4877  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4878  text = 'REACH'
4879  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4880  do n = 1, maxconn
4881  write (text, '(a,1x,i6)') 'DOWNSTREAM CONN', n
4882  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4883  end do
4884  !
4885  ! -- downstream connection data
4886  do n = 1, this%maxbound
4887  call this%inputtab%add_term(n)
4888  ii = 0
4889  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4890  if (this%idir(i) < 0) then
4891  call this%inputtab%add_term(this%ja(i))
4892  ii = ii + 1
4893  end if
4894  end do
4895  nn = maxconn - ii
4896  do i = 1, nn
4897  call this%inputtab%add_term(' ')
4898  end do
4899  end do
4900  end if
Here is the call graph for this function:

◆ sfr_check_conversion()

subroutine sfrmodule::sfr_check_conversion ( class(sfrtype this)
private

Method to check unit conversion data for a SFR package. This method also calculates unitconv that is used in the Manning's equation.

Parameters
thisSfrType object

Definition at line 4453 of file gwf-sfr.f90.

4454  ! -- dummy
4455  class(SfrType) :: this !< SfrType object
4456  ! -- local
4457  ! -- formats
4458  character(len=*), parameter :: fmtunitconv_error = &
4459  &"('SFR (',a,') UNIT_CONVERSION SPECIFIED VALUE (',g0,') AND', &
4460  &1x,'LENGTH_CONVERSION OR TIME_CONVERSION SPECIFIED.')"
4461  character(len=*), parameter :: fmtunitconv = &
4462  &"(1x,'SFR PACKAGE (',a,') CONVERSION DATA',&
4463  &/4x,'UNIT CONVERSION VALUE (',g0,').',/)"
4464  !
4465  ! -- check the reach data for simple errors
4466  if (this%lengthconv /= dnodata .or. this%timeconv /= dnodata) then
4467  if (this%unitconv /= done) then
4468  write (errmsg, fmtunitconv_error) &
4469  trim(adjustl(this%packName)), this%unitconv
4470  call store_error(errmsg)
4471  else
4472  if (this%lengthconv /= dnodata) then
4473  this%unitconv = this%unitconv * this%lengthconv**donethird
4474  end if
4475  if (this%timeconv /= dnodata) then
4476  this%unitconv = this%unitconv * this%timeconv
4477  end if
4478  write (this%iout, fmtunitconv) &
4479  trim(adjustl(this%packName)), this%unitconv
4480  end if
4481  end if
Here is the call graph for this function:

◆ sfr_check_diversions()

subroutine sfrmodule::sfr_check_diversions ( class(sfrtype this)
private

Method to check diversion data for a SFR package. This method also creates the tables used to print input data, if this option in enabled in the SFR package.

Parameters
thisSfrType object

Definition at line 4909 of file gwf-sfr.f90.

4910  ! -- dummy
4911  class(SfrType) :: this !< SfrType object
4912  ! -- local
4913  character(len=LINELENGTH) :: title
4914  character(len=LINELENGTH) :: text
4915  character(len=5) :: crch
4916  character(len=5) :: cdiv
4917  character(len=5) :: crch2
4918  character(len=10) :: cprior
4919  integer(I4B) :: maxdiv
4920  integer(I4B) :: n
4921  integer(I4B) :: nn
4922  integer(I4B) :: nc
4923  integer(I4B) :: ii
4924  integer(I4B) :: idiv
4925  integer(I4B) :: ifound
4926  integer(I4B) :: jpos
4927  ! -- format
4928 10 format('Diversion ', i0, ' of reach ', i0, &
4929  ' is invalid or has not been defined.')
4930  !
4931  ! -- write header
4932  if (this%iprpak /= 0) then
4933  !
4934  ! -- determine the maximum number of diversions
4935  maxdiv = 0
4936  do n = 1, this%maxbound
4937  maxdiv = maxdiv + this%ndiv(n)
4938  end do
4939  !
4940  ! -- reset the input table object
4941  title = trim(adjustl(this%text))//' PACKAGE ('// &
4942  trim(adjustl(this%packName))//') REACH DIVERSION DATA'
4943  call table_cr(this%inputtab, this%packName, title)
4944  call this%inputtab%table_df(maxdiv, 4, this%iout)
4945  text = 'REACH'
4946  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4947  text = 'DIVERSION'
4948  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4949  text = 'REACH 2'
4950  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4951  text = 'CPRIOR'
4952  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4953  end if
4954  !
4955  ! -- check that diversion data are correct
4956  do n = 1, this%maxbound
4957  if (this%ndiv(n) < 1) cycle
4958  write (crch, '(i5)') n
4959 
4960  do idiv = 1, this%ndiv(n)
4961  !
4962  ! -- determine diversion index
4963  jpos = this%iadiv(n) + idiv - 1
4964  !
4965  ! -- write idiv to cdiv
4966  write (cdiv, '(i5)') idiv
4967  !
4968  !
4969  nn = this%divreach(jpos)
4970  write (crch2, '(i5)') nn
4971  !
4972  ! -- make sure diversion reach is connected to current reach
4973  ifound = 0
4974  if (nn < 1 .or. nn > this%maxbound) then
4975  write (errmsg, 10) idiv, n
4976  call store_error(errmsg)
4977  cycle
4978  end if
4979  connreach: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4980  nc = this%ja(ii)
4981  if (nc == n) then
4982  if (this%idir(ii) > 0) then
4983  ifound = 1
4984  end if
4985  exit connreach
4986  end if
4987  end do connreach
4988  if (ifound /= 1) then
4989  errmsg = 'Reach '//crch//' is not a upstream reach for '// &
4990  'reach '//crch2//' as a result diversion '//cdiv// &
4991  ' from reach '//crch//' to reach '//crch2// &
4992  ' is not possible. Check reach connectivity.'
4993  call store_error(errmsg)
4994  end if
4995  ! -- iprior
4996  cprior = this%divcprior(jpos)
4997  !
4998  ! -- add terms to the table
4999  if (this%iprpak /= 0) then
5000  call this%inputtab%add_term(n)
5001  call this%inputtab%add_term(idiv)
5002  call this%inputtab%add_term(nn)
5003  call this%inputtab%add_term(cprior)
5004  end if
5005  end do
5006  end do
Here is the call graph for this function:

◆ sfr_check_initialstages()

subroutine sfrmodule::sfr_check_initialstages ( class(sfrtype this)
private

Method to check initial data for a SFR package and calculates the initial upstream and downstream flows for the reach based on the initial staalso creates the tables used to print input data, if this option in enabled in the SFR package.

Parameters
thisSfrType object

Definition at line 5016 of file gwf-sfr.f90.

5017  class(SfrType) :: this !< SfrType object
5018 
5019  character(len=LINELENGTH) :: title
5020  character(len=LINELENGTH) :: text
5021  character(len=5) :: crch
5022  integer(I4B) :: n
5023  real(DP) :: qman
5024 
5025  ! skip check if storage is not activated
5026  if (this%istorage == 0) return
5027 
5028  ! write header
5029  if (this%iprpak /= 0) then
5030  !
5031  ! -- reset the input table object
5032  title = trim(adjustl(this%text))//' PACKAGE ('// &
5033  trim(adjustl(this%packName))//') REACH INITIAL STAGE DATA'
5034  call table_cr(this%inputtab, this%packName, title)
5035  call this%inputtab%table_df(this%maxbound, 4, this%iout)
5036  text = 'REACH'
5037  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5038  text = 'INITIAL STAGE'
5039  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5040  text = 'INITIAL DEPTH'
5041  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5042  text = 'INITIAL FLOW'
5043  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5044  end if
5045  !
5046  ! -- check that data are correct
5047  do n = 1, this%maxbound
5048  write (crch, '(i5)') n
5049 
5050  ! calculate the initial flows
5051  call this%sfr_calc_qman(n, this%depth(n), qman)
5052  this%usinflow(n) = qman
5053  this%dsflow(n) = qman
5054 
5055  ! add terms to the table
5056  if (this%iprpak /= 0) then
5057  call this%inputtab%add_term(n)
5058  call this%inputtab%add_term(this%stage(n))
5059  call this%inputtab%add_term(this%depth(n))
5060  call this%inputtab%add_term(qman)
5061  end if
5062  end do
Here is the call graph for this function:

◆ sfr_check_reaches()

subroutine sfrmodule::sfr_check_reaches ( class(sfrtype this)
private

Method to check specified data for a SFR package. This method also creates the tables used to print input data, if this option in enabled in the SFR package.

Parameters
thisSfrType object

Definition at line 4514 of file gwf-sfr.f90.

4515  ! -- dummy
4516  class(SfrType) :: this !< SfrType object
4517  ! -- local
4518  character(len=5) :: crch
4519  character(len=10) :: cval
4520  character(len=30) :: nodestr
4521  character(len=LINELENGTH) :: title
4522  character(len=LINELENGTH) :: text
4523  integer(I4B) :: n
4524  integer(I4B) :: nn
4525  real(DP) :: btgwf
4526  real(DP) :: bt
4527  !
4528  ! -- setup inputtab tableobj
4529  if (this%iprpak /= 0) then
4530  title = trim(adjustl(this%text))//' PACKAGE ('// &
4531  trim(adjustl(this%packName))//') STATIC REACH DATA'
4532  call table_cr(this%inputtab, this%packName, title)
4533  call this%inputtab%table_df(this%maxbound, 10, this%iout)
4534  text = 'NUMBER'
4535  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4536  text = 'CELLID'
4537  call this%inputtab%initialize_column(text, 20, alignment=tableft)
4538  text = 'LENGTH'
4539  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4540  text = 'WIDTH'
4541  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4542  text = 'SLOPE'
4543  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4544  text = 'TOP'
4545  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4546  text = 'THICKNESS'
4547  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4548  text = 'HK'
4549  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4550  text = 'ROUGHNESS'
4551  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4552  text = 'UPSTREAM FRACTION'
4553  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4554  end if
4555  !
4556  ! -- check the reach data for simple errors
4557  do n = 1, this%maxbound
4558  write (crch, '(i5)') n
4559  nn = this%igwfnode(n)
4560  if (nn > 0) then
4561  btgwf = this%dis%bot(nn)
4562  call this%dis%noder_to_string(nn, nodestr)
4563  else
4564  nodestr = 'none'
4565  end if
4566  ! -- check reach length
4567  if (this%length(n) <= dzero) then
4568  errmsg = 'Reach '//crch//' length must be greater than 0.0.'
4569  call store_error(errmsg)
4570  end if
4571  ! -- check reach width
4572  if (this%width(n) <= dzero) then
4573  errmsg = 'Reach '//crch//' width must be greater than 0.0.'
4574  call store_error(errmsg)
4575  end if
4576  ! -- check reach slope
4577  if (this%slope(n) <= dzero) then
4578  errmsg = 'Reach '//crch//' slope must be greater than 0.0.'
4579  call store_error(errmsg)
4580  end if
4581  ! -- check bed thickness and bed hk for reaches connected to GWF
4582  if (nn > 0) then
4583  bt = this%strtop(n) - this%bthick(n)
4584  if (bt <= btgwf .and. this%icheck /= 0) then
4585  write (cval, '(f10.4)') bt
4586  errmsg = 'Reach '//crch//' bed bottom (rtp-rbth ='// &
4587  cval//') must be greater than the bottom of cell ('// &
4588  nodestr
4589  write (cval, '(f10.4)') btgwf
4590  errmsg = trim(adjustl(errmsg))//'='//cval//').'
4591  call store_error(errmsg)
4592  end if
4593  if (this%hk(n) < dzero) then
4594  errmsg = 'Reach '//crch//' hk must be greater than or equal to 0.0.'
4595  call store_error(errmsg)
4596  end if
4597  end if
4598  ! -- check reach roughness
4599  if (this%rough(n) <= dzero) then
4600  errmsg = 'Reach '//crch//" Manning's roughness "// &
4601  'coefficient must be greater than 0.0.'
4602  call store_error(errmsg)
4603  end if
4604  ! -- check reach upstream fraction
4605  if (this%ustrf(n) < dzero) then
4606  errmsg = 'Reach '//crch//' upstream fraction must be greater '// &
4607  'than or equal to 0.0.'
4608  call store_error(errmsg)
4609  end if
4610  ! -- write summary of reach information
4611  if (this%iprpak /= 0) then
4612  call this%inputtab%add_term(n)
4613  call this%inputtab%add_term(nodestr)
4614  call this%inputtab%add_term(this%length(n))
4615  call this%inputtab%add_term(this%width(n))
4616  call this%inputtab%add_term(this%slope(n))
4617  call this%inputtab%add_term(this%strtop(n))
4618  call this%inputtab%add_term(this%bthick(n))
4619  call this%inputtab%add_term(this%hk(n))
4620  call this%inputtab%add_term(this%rough(n))
4621  call this%inputtab%add_term(this%ustrf(n))
4622  end if
4623  end do
Here is the call graph for this function:

◆ sfr_check_storage_weight()

subroutine sfrmodule::sfr_check_storage_weight ( class(sfrtype this)
private

Method to check the kinematic storage weight for a SFR package. If the kinematic storage weight has not been set it is set to the default value.

Parameters
thisSfrType object

Definition at line 4490 of file gwf-sfr.f90.

4491  ! -- dummy
4492  class(SfrType) :: this !< SfrType object
4493  ! -- formats
4494  character(len=*), parameter :: fmtweight = &
4495  &"(1x,'SFR PACKAGE (',a,') SETTING DEFAULT',&
4496  &/4x,'STORAGE_WEIGHT VALUE (',g0,').',/)"
4497  !
4498  ! -- set storage weight if it has not been defined yet
4499  if (this%istorage == 1) then
4500  if (this%storage_weight == dnodata) then
4501  this%storage_weight = done
4502  write (this%iout, fmtweight) &
4503  trim(adjustl(this%packName)), this%storage_weight
4504  end if
4505  end if

◆ sfr_check_ustrf()

subroutine sfrmodule::sfr_check_ustrf ( class(sfrtype this)
private

Method to check upstream fraction data for a SFR package. This method also creates the tables used to print input data, if this option in enabled in the SFR package.

Parameters
thisSfrType object

Definition at line 5071 of file gwf-sfr.f90.

5072  ! -- dummy
5073  class(SfrType) :: this !< SfrType object
5074  ! -- local
5075  character(len=LINELENGTH) :: title
5076  character(len=LINELENGTH) :: text
5077  logical(LGP) :: lcycle
5078  logical(LGP) :: ladd
5079  character(len=5) :: crch
5080  character(len=5) :: crch2
5081  character(len=10) :: cval
5082  integer(I4B) :: maxcols
5083  integer(I4B) :: npairs
5084  integer(I4B) :: ipair
5085  integer(I4B) :: i
5086  integer(I4B) :: n
5087  integer(I4B) :: n2
5088  integer(I4B) :: idiv
5089  integer(I4B) :: i0
5090  integer(I4B) :: i1
5091  integer(I4B) :: jpos
5092  integer(I4B) :: ids
5093  real(DP) :: f
5094  real(DP) :: rval
5095  !
5096  ! -- write table header
5097  if (this%iprpak /= 0) then
5098  !
5099  ! -- determine the maximum number of columns
5100  npairs = 0
5101  do n = 1, this%maxbound
5102  ipair = 0
5103  ec: do i = this%ia(n) + 1, this%ia(n + 1) - 1
5104  !
5105  ! -- skip upstream connections
5106  if (this%idir(i) > 0) cycle ec
5107  n2 = this%ja(i)
5108  !
5109  ! -- skip inactive downstream reaches
5110  if (this%iboundpak(n2) == 0) cycle ec
5111  !
5112  ! -- increment ipair and see if it exceeds npairs
5113  ipair = ipair + 1
5114  npairs = max(npairs, ipair)
5115  end do ec
5116  end do
5117  maxcols = 1 + npairs * 2
5118  !
5119  ! -- reset the input table object
5120  title = trim(adjustl(this%text))//' PACKAGE ('// &
5121  trim(adjustl(this%packName))//') CONNECTED REACH UPSTREAM '// &
5122  'FRACTION DATA'
5123  call table_cr(this%inputtab, this%packName, title)
5124  call this%inputtab%table_df(this%maxbound, maxcols, this%iout)
5125  text = 'REACH'
5126  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5127  do i = 1, npairs
5128  write (cval, '(i10)') i
5129  text = 'DOWNSTREAM REACH '//trim(adjustl(cval))
5130  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5131  text = 'FRACTION '//trim(adjustl(cval))
5132  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
5133  end do
5134  end if
5135  !
5136  ! -- fill diversion number for each connection
5137  do n = 1, this%maxbound
5138  do idiv = 1, this%ndiv(n)
5139  i0 = this%iadiv(n)
5140  i1 = this%iadiv(n + 1) - 1
5141  do jpos = i0, i1
5142  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5143  n2 = this%ja(i)
5144  if (this%divreach(jpos) == n2) then
5145  this%idiv(i) = jpos - i0 + 1
5146  exit
5147  end if
5148  end do
5149  end do
5150  end do
5151  end do
5152  !
5153  ! -- check that the upstream fraction for reach connected by
5154  ! a diversion is zero
5155  do n = 1, this%maxbound
5156  !
5157  ! -- determine the number of downstream reaches
5158  ids = 0
5159  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5160  if (this%idir(i) < 0) then
5161  ids = ids + 1
5162  end if
5163  end do
5164  !
5165  ! -- evaluate the diversions
5166  do idiv = 1, this%ndiv(n)
5167  jpos = this%iadiv(n) + idiv - 1
5168  n2 = this%divreach(jpos)
5169  f = this%ustrf(n2)
5170  if (f /= dzero) then
5171  write (errmsg, '(a,2(1x,i0,1x,a),1x,a,g0,a,2(1x,a))') &
5172  'Reach', n, 'is connected to reach', n2, 'by a diversion', &
5173  'but the upstream fraction is not equal to zero (', f, '). Check', &
5174  trim(this%packName), 'package diversion and package data.'
5175  if (ids > 1) then
5176  call store_error(errmsg)
5177  else
5178  write (warnmsg, '(a,3(1x,a))') &
5179  trim(warnmsg), &
5180  'A warning instead of an error is issued because', &
5181  'the reach is only connected to the diversion reach in the ', &
5182  'downstream direction.'
5183  call store_warning(warnmsg)
5184  end if
5185  end if
5186  end do
5187  end do
5188  !
5189  ! -- calculate the total fraction of connected reaches that are
5190  ! not diversions and check that the sum of upstream fractions
5191  ! is equal to 1 for each reach
5192  do n = 1, this%maxbound
5193  ids = 0
5194  rval = dzero
5195  f = dzero
5196  write (crch, '(i5)') n
5197  if (this%iprpak /= 0) then
5198  call this%inputtab%add_term(n)
5199  end if
5200  ipair = 0
5201  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
5202  lcycle = .false.
5203  !
5204  ! -- initialize downstream connection q
5205  this%qconn(i) = dzero
5206  !
5207  ! -- skip upstream connections
5208  if (this%idir(i) > 0) then
5209  lcycle = .true.
5210  end if
5211  n2 = this%ja(i)
5212  !
5213  ! -- skip inactive downstream reaches
5214  if (this%iboundpak(n2) == 0) then
5215  lcycle = .true.
5216  end if
5217  if (lcycle) then
5218  cycle eachconn
5219  end if
5220  ipair = ipair + 1
5221  write (crch2, '(i5)') n2
5222  ids = ids + 1
5223  ladd = .true.
5224  f = f + this%ustrf(n2)
5225  write (cval, '(f10.4)') this%ustrf(n2)
5226  !
5227  ! -- write upstream fractions
5228  if (this%iprpak /= 0) then
5229  call this%inputtab%add_term(n2)
5230  call this%inputtab%add_term(this%ustrf(n2))
5231  end if
5232  eachdiv: do idiv = 1, this%ndiv(n)
5233  jpos = this%iadiv(n) + idiv - 1
5234  if (this%divreach(jpos) == n2) then
5235  ladd = .false.
5236  exit eachdiv
5237  end if
5238  end do eachdiv
5239  if (ladd) then
5240  rval = rval + this%ustrf(n2)
5241  end if
5242  end do eachconn
5243  this%ftotnd(n) = rval
5244  !
5245  ! -- write remaining table columns
5246  if (this%iprpak /= 0) then
5247  ipair = ipair + 1
5248  do i = ipair, npairs
5249  call this%inputtab%add_term(' ')
5250  call this%inputtab%add_term(' ')
5251  end do
5252  end if
5253  !
5254  ! -- evaluate if an error condition has occurred
5255  ! the sum of fractions is not equal to 1
5256  if (ids /= 0) then
5257  if (abs(f - done) > dem6) then
5258  write (errmsg, '(a,1x,i0,1x,a,g0,a,3(1x,a))') &
5259  'Upstream fractions for reach ', n, 'is not equal to one (', f, &
5260  '). Check', trim(this%packName), 'package reach connectivity and', &
5261  'package data.'
5262  call store_error(errmsg)
5263  end if
5264  end if
5265  end do
Here is the call graph for this function:

◆ sfr_cq()

subroutine sfrmodule::sfr_cq ( class(sfrtype), intent(inout)  this,
real(dp), dimension(:), intent(in)  x,
real(dp), dimension(:), intent(inout), contiguous  flowja,
integer(i4b), intent(in), optional  iadv 
)

Calculate the flow between connected SFR package control volumes.

Parameters
[in,out]thisSfrType object
[in]xcurrent dependent-variable value
[in,out]flowjaflow between two connected control volumes
[in]iadvflag that indicates if this is an advance package

Definition at line 2621 of file gwf-sfr.f90.

2622  ! -- modules
2623  use budgetmodule, only: budgettype
2624  ! -- dummy
2625  class(SfrType), intent(inout) :: this !< SfrType object
2626  real(DP), dimension(:), intent(in) :: x !< current dependent-variable value
2627  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
2628  integer(I4B), optional, intent(in) :: iadv !< flag that indicates if this is an advance package
2629  ! -- local
2630  integer(I4B) :: i
2631  real(DP) :: qext
2632  ! -- for budget
2633  integer(I4B) :: n
2634  integer(I4B) :: n2
2635  real(DP) :: qoutflow
2636  real(DP) :: qfrommvr
2637  real(DP) :: qtomvr
2638  !
2639  ! -- call base functionality in bnd_cq. This will calculate sfr-gwf flows
2640  ! and put them into this%simvals
2641  call this%BndType%bnd_cq(x, flowja, iadv=1)
2642  !
2643  ! -- Calculate qextoutflow and qoutflow for subsequent budgets
2644  do n = 1, this%maxbound
2645  !
2646  ! -- mover
2647  qfrommvr = dzero
2648  qtomvr = dzero
2649  if (this%imover == 1) then
2650  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
2651  qtomvr = this%pakmvrobj%get_qtomvr(n)
2652  if (qtomvr > dzero) then
2653  qtomvr = -qtomvr
2654  end if
2655  end if
2656  !
2657  ! -- external downstream stream flow
2658  qext = this%dsflow(n)
2659  qoutflow = dzero
2660  if (qext > dzero) then
2661  qext = -qext
2662  end if
2663  do i = this%ia(n) + 1, this%ia(n + 1) - 1
2664  if (this%idir(i) > 0) cycle
2665  n2 = this%ja(i)
2666  if (this%iboundpak(n2) == 0) cycle
2667  qext = dzero
2668  exit
2669  end do
2670  !
2671  ! -- adjust external downstream stream flow using qtomvr
2672  if (qext < dzero) then
2673  if (qtomvr < dzero) then
2674  qext = qext - qtomvr
2675  end if
2676  else
2677  qoutflow = this%dsflow(n)
2678  if (qoutflow > dzero) then
2679  qoutflow = -qoutflow
2680  end if
2681  end if
2682  !
2683  ! -- set qextoutflow and qoutflow for cell by cell budget
2684  ! output and observations
2685  this%qextoutflow(n) = qext
2686  this%qoutflow(n) = qoutflow
2687  !
2688  end do
2689  !
2690  ! -- fill the budget object
2691  call this%sfr_fill_budobj()
This module contains the BudgetModule.
Definition: Budget.f90:20
Derived type for the Budget object.
Definition: Budget.f90:39

◆ sfr_create()

subroutine, public sfrmodule::sfr_create ( class(bndtype), pointer  packobj,
integer(i4b), intent(in)  id,
integer(i4b), intent(in)  ibcnum,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout,
character(len=*), intent(in)  namemodel,
character(len=*), intent(in)  pakname 
)

Create a new SFR Package object

Parameters
packobjpointer to default package type
[in]idpackage id
[in]ibcnumboundary condition number
[in]inunitunit number of SFR package input file
[in]ioutunit number of model listing file
[in]namemodelmodel name
[in]paknamepackage name

Definition at line 325 of file gwf-sfr.f90.

326  ! -- modules
328  ! -- dummy
329  class(BndType), pointer :: packobj !< pointer to default package type
330  integer(I4B), intent(in) :: id !< package id
331  integer(I4B), intent(in) :: ibcnum !< boundary condition number
332  integer(I4B), intent(in) :: inunit !< unit number of SFR package input file
333  integer(I4B), intent(in) :: iout !< unit number of model listing file
334  character(len=*), intent(in) :: namemodel !< model name
335  character(len=*), intent(in) :: pakname !< package name
336  ! -- local
337  type(SfrType), pointer :: sfrobj
338  !
339  ! -- allocate the object and assign values to object variables
340  allocate (sfrobj)
341  packobj => sfrobj
342  !
343  ! -- create name and memory path
344  call packobj%set_names(ibcnum, namemodel, pakname, ftype)
345  packobj%text = text
346  !
347  ! -- allocate scalars
348  call sfrobj%sfr_allocate_scalars()
349  !
350  ! -- initialize package
351  call packobj%pack_initialize()
352 
353  packobj%inunit = inunit
354  packobj%iout = iout
355  packobj%id = id
356  packobj%ibcnum = ibcnum
357  packobj%ncolbnd = 4
358  packobj%iscloc = 0 ! not supported
359  packobj%isadvpak = 1
360  packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sfr_da()

subroutine sfrmodule::sfr_da ( class(sfrtype this)
private

Deallocate SFR package scalars and arrays.

Parameters
thisSfrType object

Definition at line 2978 of file gwf-sfr.f90.

2979  ! -- modules
2981  ! -- dummy
2982  class(SfrType) :: this !< SfrType object
2983  !
2984  ! -- deallocate arrays
2985  call mem_deallocate(this%qoutflow)
2986  call mem_deallocate(this%qextoutflow)
2987  deallocate (this%csfrbudget)
2988  call mem_deallocate(this%sfrname, 'SFRNAME', this%memoryPath)
2989  call mem_deallocate(this%dbuff)
2990  deallocate (this%cauxcbc)
2991  call mem_deallocate(this%qauxcbc)
2992  call mem_deallocate(this%iboundpak)
2993  call mem_deallocate(this%igwfnode)
2994  call mem_deallocate(this%igwftopnode)
2995  call mem_deallocate(this%length)
2996  call mem_deallocate(this%width)
2997  call mem_deallocate(this%strtop)
2998  call mem_deallocate(this%bthick)
2999  call mem_deallocate(this%hk)
3000  call mem_deallocate(this%slope)
3001  call mem_deallocate(this%nconnreach)
3002  call mem_deallocate(this%ustrf)
3003  call mem_deallocate(this%ftotnd)
3004  call mem_deallocate(this%usflow)
3005  call mem_deallocate(this%dsflow)
3006  call mem_deallocate(this%depth)
3007  call mem_deallocate(this%stage)
3008  call mem_deallocate(this%gwflow)
3009  call mem_deallocate(this%simevap)
3010  call mem_deallocate(this%simrunoff)
3011  call mem_deallocate(this%stage0)
3012  call mem_deallocate(this%usflow0)
3013  call mem_deallocate(this%denseterms)
3014  call mem_deallocate(this%viscratios)
3015  !
3016  ! -- stage, usflow, and dsflow for previous timestep
3017  if (this%istorage == 1) then
3018  call mem_deallocate(this%stageold)
3019  call mem_deallocate(this%dsflowold)
3020  call mem_deallocate(this%storage)
3021  call mem_deallocate(this%usinflow)
3022  call mem_deallocate(this%usinflowold)
3023  call mem_deallocate(this%crmin)
3024  call mem_deallocate(this%crmax)
3025  call mem_deallocate(this%crsum)
3026  call mem_deallocate(this%crcnt)
3027  call mem_deallocate(this%itvd_upstream)
3028  end if
3029  !
3030  ! -- deallocate reach order and connection data
3031  call mem_deallocate(this%isfrorder)
3032  call mem_deallocate(this%ia)
3033  call mem_deallocate(this%ja)
3034  call mem_deallocate(this%idir)
3035  call mem_deallocate(this%idiv)
3036  call mem_deallocate(this%qconn)
3037  !
3038  ! -- deallocate boundary data
3039  call mem_deallocate(this%rough)
3040  call mem_deallocate(this%rain)
3041  call mem_deallocate(this%evap)
3042  call mem_deallocate(this%inflow)
3043  call mem_deallocate(this%runoff)
3044  call mem_deallocate(this%sstage)
3045  !
3046  ! -- deallocate aux variables
3047  call mem_deallocate(this%rauxvar)
3048  !
3049  ! -- deallocate diversion variables
3050  call mem_deallocate(this%iadiv)
3051  call mem_deallocate(this%divreach)
3052  if (associated(this%divcprior)) then
3053  deallocate (this%divcprior)
3054  end if
3055  call mem_deallocate(this%divflow)
3056  call mem_deallocate(this%divq)
3057  call mem_deallocate(this%ndiv)
3058  !
3059  ! -- deallocate cross-section data
3060  call mem_deallocate(this%ncrosspts)
3061  call mem_deallocate(this%iacross)
3062  call mem_deallocate(this%station)
3063  call mem_deallocate(this%xsheight)
3064  call mem_deallocate(this%xsrough)
3065  !
3066  ! -- deallocate budobj
3067  call this%budobj%budgetobject_da()
3068  deallocate (this%budobj)
3069  nullify (this%budobj)
3070  !
3071  ! -- deallocate stage table
3072  if (this%iprhed > 0) then
3073  call this%stagetab%table_da()
3074  deallocate (this%stagetab)
3075  nullify (this%stagetab)
3076  end if
3077  !
3078  ! -- deallocate Courant number table
3079  if (associated(this%couranttab)) then
3080  call this%couranttab%table_da()
3081  deallocate (this%couranttab)
3082  nullify (this%couranttab)
3083  end if
3084  !
3085  ! -- deallocate package csv table
3086  if (this%ipakcsv > 0) then
3087  if (associated(this%pakcsvtab)) then
3088  call this%pakcsvtab%table_da()
3089  deallocate (this%pakcsvtab)
3090  nullify (this%pakcsvtab)
3091  end if
3092  end if
3093  !
3094  ! -- deallocate scalars
3095  call mem_deallocate(this%ats_courant)
3096  call mem_deallocate(this%istorage)
3097  call mem_deallocate(this%storage_weight)
3098  call mem_deallocate(this%iprhed)
3099  call mem_deallocate(this%istageout)
3100  call mem_deallocate(this%ibudgetout)
3101  call mem_deallocate(this%ibudcsv)
3102  call mem_deallocate(this%ipakcsv)
3103  call mem_deallocate(this%idiversions)
3104  call mem_deallocate(this%maxsfrpicard)
3105  call mem_deallocate(this%maxsfrit)
3106  call mem_deallocate(this%bditems)
3107  call mem_deallocate(this%cbcauxitems)
3108  call mem_deallocate(this%unitconv)
3109  call mem_deallocate(this%lengthconv)
3110  call mem_deallocate(this%timeconv)
3111  call mem_deallocate(this%dmaxchg)
3112  call mem_deallocate(this%deps)
3113  call mem_deallocate(this%nconn)
3114  call mem_deallocate(this%icheck)
3115  call mem_deallocate(this%iconvchk)
3116  call mem_deallocate(this%idense)
3117  call mem_deallocate(this%ianynone)
3118  call mem_deallocate(this%ncrossptstot)
3119  nullify (this%gwfiss)
3120  !
3121  ! -- call base BndType deallocate
3122  call this%BndType%bnd_da()

◆ sfr_df_obs()

subroutine sfrmodule::sfr_df_obs ( class(sfrtype this)
private

Method to define the observation types available in the SFR package.

Parameters
thisSfrType object

Definition at line 3204 of file gwf-sfr.f90.

3205  ! -- dummy
3206  class(SfrType) :: this !< SfrType object
3207  ! -- local
3208  integer(I4B) :: indx
3209  !
3210  ! -- Store obs type and assign procedure pointer
3211  ! for stage observation type.
3212  call this%obs%StoreObsType('stage', .false., indx)
3213  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3214  !
3215  ! -- Store obs type and assign procedure pointer
3216  ! for inflow observation type.
3217  call this%obs%StoreObsType('inflow', .true., indx)
3218  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3219  !
3220  ! -- Store obs type and assign procedure pointer
3221  ! for inflow observation type.
3222  call this%obs%StoreObsType('ext-inflow', .true., indx)
3223  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3224  !
3225  ! -- Store obs type and assign procedure pointer
3226  ! for rainfall observation type.
3227  call this%obs%StoreObsType('rainfall', .true., indx)
3228  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3229  !
3230  ! -- Store obs type and assign procedure pointer
3231  ! for runoff observation type.
3232  call this%obs%StoreObsType('runoff', .true., indx)
3233  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3234  !
3235  ! -- Store obs type and assign procedure pointer
3236  ! for evaporation observation type.
3237  call this%obs%StoreObsType('evaporation', .true., indx)
3238  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3239  !
3240  ! -- Store obs type and assign procedure pointer
3241  ! for outflow observation type.
3242  call this%obs%StoreObsType('outflow', .true., indx)
3243  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3244  !
3245  ! -- Store obs type and assign procedure pointer
3246  ! for ext-outflow observation type.
3247  call this%obs%StoreObsType('ext-outflow', .true., indx)
3248  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3249  !
3250  ! -- Store obs type and assign procedure pointer
3251  ! for to-mvr observation type.
3252  call this%obs%StoreObsType('to-mvr', .true., indx)
3253  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3254  !
3255  ! -- Store obs type and assign procedure pointer
3256  ! for sfr-frommvr observation type.
3257  call this%obs%StoreObsType('from-mvr', .true., indx)
3258  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3259  !
3260  ! -- Store obs type and assign procedure pointer
3261  ! for sfr observation type.
3262  call this%obs%StoreObsType('sfr', .true., indx)
3263  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3264  !
3265  ! -- Store obs type and assign procedure pointer
3266  ! for upstream flow observation type.
3267  call this%obs%StoreObsType('upstream-flow', .true., indx)
3268  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3269  !
3270  ! -- Store obs type and assign procedure pointer
3271  ! for downstream flow observation type.
3272  call this%obs%StoreObsType('downstream-flow', .true., indx)
3273  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3274  !
3275  ! -- Store obs type and assign procedure pointer
3276  ! for depth observation type.
3277  call this%obs%StoreObsType('depth', .false., indx)
3278  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3279  !
3280  ! -- Store obs type and assign procedure pointer
3281  ! for wetted-perimeter observation type.
3282  call this%obs%StoreObsType('wet-perimeter', .false., indx)
3283  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3284  !
3285  ! -- Store obs type and assign procedure pointer
3286  ! for wetted-area observation type.
3287  call this%obs%StoreObsType('wet-area', .false., indx)
3288  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3289  !
3290  ! -- Store obs type and assign procedure pointer
3291  ! for wetted-width observation type.
3292  call this%obs%StoreObsType('wet-width', .false., indx)
3293  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid

◆ sfr_dt()

subroutine sfrmodule::sfr_dt ( class(sfrtype this)
private
Parameters
thisSfrType object

Definition at line 2913 of file gwf-sfr.f90.

2914  ! -- modules
2915  use tdismodule, only: kstp, kper, ats
2916  ! -- dummy
2917  class(SfrType) :: this !< SfrType object
2918  ! -- local
2919  integer(I4B) :: n
2920  integer(I4B) :: nrmin
2921  real(DP) :: celerity
2922  real(DP) :: dt_n
2923  real(DP) :: dtmin
2924  character(len=LINELENGTH) :: msg
2925  !
2926  if (this%ats_courant == dnodata) return
2927  if (this%istorage /= 1) return
2928  !
2929  dtmin = dnodata
2930  nrmin = 0
2931  !
2932  do n = 1, this%maxbound
2933  call this%sfr_calc_celerity(n, this%dsflow(n), celerity)
2934  if (celerity > dzero) then
2935  dt_n = this%ats_courant * this%length(n) / celerity
2936  if (dt_n < dtmin) then
2937  dtmin = dt_n
2938  nrmin = n
2939  end if
2940  end if
2941  end do
2942  !
2943  if (nrmin > 0) then
2944  write (msg, '(a,i0)') trim(this%packName)//'-REACH-', nrmin
2945  call ats%ats_submit_delt(kstp, kper, dtmin, trim(msg))
2946  end if
class(atstype), pointer, public ats
Definition: tdis.f90:48

◆ sfr_fc()

subroutine sfrmodule::sfr_fc ( class(sfrtype this,
real(dp), dimension(:), intent(inout)  rhs,
integer(i4b), dimension(:), intent(in)  ia,
integer(i4b), dimension(:), intent(in)  idxglo,
class(matrixbasetype), pointer  matrix_sln 
)
private

Add the hcof and rhs terms for the SFR package to the coefficient matrix and right-hand side vector.

Parameters
thisSfrType object
[in,out]rhsright-hand side vector for model
[in]iasolution CRS row pointers
[in]idxglomapping vector for model (local) to solution (global)
matrix_slnsolution coefficient matrix

Definition at line 2269 of file gwf-sfr.f90.

2270  ! -- dummy
2271  class(SfrType) :: this !< SfrType object
2272  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2273  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2274  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2275  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2276  ! -- local
2277  integer(I4B) :: i
2278  integer(I4B) :: j
2279  integer(I4B) :: n
2280  integer(I4B) :: ipos
2281  integer(I4B) :: node
2282  real(DP) :: s0
2283  real(DP) :: ds
2284  real(DP) :: dsmax
2285  real(DP) :: hgwf
2286  real(DP) :: v
2287  real(DP) :: hhcof
2288  real(DP) :: rrhs
2289  !
2290  ! -- picard iterations for sfr to achieve good solution regardless
2291  ! of reach order
2292  sfrpicard: do i = 1, this%maxsfrpicard
2293  !
2294  ! -- initialize maximum stage change for iteration to zero
2295  dsmax = dzero
2296  !
2297  ! -- pakmvrobj fc - reset qformvr to zero
2298  if (this%imover == 1) then
2299  call this%pakmvrobj%fc()
2300  end if
2301  !
2302  ! -- solve for each sfr reach
2303  reachsolve: do j = 1, this%nbound
2304  n = this%isfrorder(j)
2305  node = this%igwfnode(n)
2306  if (node > 0) then
2307  hgwf = this%xnew(node)
2308  else
2309  hgwf = dep20
2310  end if
2311  !
2312  ! -- save previous stage and upstream flow
2313  if (i == 1) then
2314  this%stage0(n) = this%stage(n)
2315  this%usflow0(n) = this%usflow(n)
2316  end if
2317  !
2318  ! -- set initial stage to calculate stage change
2319  s0 = this%stage(n)
2320  !
2321  ! -- solve for flow in swr
2322  if (this%iboundpak(n) /= 0) then
2323  call this%sfr_solve(n, hgwf, hhcof, rrhs)
2324  else
2325  this%depth(n) = dzero
2326  this%stage(n) = this%strtop(n)
2327  v = dzero
2328  call this%sfr_update_flows(n, v, v)
2329  hhcof = dzero
2330  rrhs = dzero
2331  end if
2332  !
2333  ! -- set package hcof and rhs
2334  this%hcof(n) = hhcof
2335  this%rhs(n) = rrhs
2336  !
2337  ! -- calculate stage change
2338  ds = s0 - this%stage(n)
2339  !
2340  ! -- evaluate if stage change exceeds dsmax
2341  if (abs(ds) > abs(dsmax)) then
2342  dsmax = ds
2343  end if
2344 
2345  end do reachsolve
2346  !
2347  ! -- evaluate if the sfr picard iterations should be terminated
2348  if (abs(dsmax) <= this%dmaxchg) then
2349  exit sfrpicard
2350  end if
2351 
2352  end do sfrpicard
2353  !
2354  ! -- Copy package rhs and hcof into solution rhs and amat
2355  do n = 1, this%nbound
2356  node = this%nodelist(n)
2357  if (node < 1) cycle
2358  rhs(node) = rhs(node) + this%rhs(n)
2359  ipos = ia(node)
2360  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(n))
2361  end do

◆ sfr_fill_budobj()

subroutine sfrmodule::sfr_fill_budobj ( class(sfrtype this)
private

Method to copy flows into the budget object that stores all the sfr flows The terms listed here must correspond in number and order to the ones added in the sfr_setup_budobj method.

Parameters
thisSfrType object

Definition at line 5489 of file gwf-sfr.f90.

5490  ! -- dummy
5491  class(SfrType) :: this !< SfrType object
5492  ! -- local
5493  integer(I4B) :: naux
5494  integer(I4B) :: i
5495  integer(I4B) :: n
5496  integer(I4B) :: n1
5497  integer(I4B) :: n2
5498  integer(I4B) :: ii
5499  integer(I4B) :: idx
5500  integer(I4B) :: idiv
5501  integer(I4B) :: jpos
5502  real(DP) :: q
5503  real(DP) :: qt
5504  real(DP) :: d
5505  real(DP) :: ca
5506  real(DP) :: a
5507  real(DP) :: wp
5508  real(DP) :: l
5509  !
5510  ! -- initialize counter
5511  idx = 0
5512  !
5513  ! -- FLOW JA FACE
5514  idx = idx + 1
5515  call this%budobj%budterm(idx)%reset(this%nconn)
5516  do n = 1, this%maxbound
5517  n1 = n
5518  q = dzero
5519  ca = dzero
5520  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5521  n2 = this%ja(i)
5522  if (this%iboundpak(n) /= 0) then
5523  ! flow to downstream reaches
5524  if (this%idir(i) < 0) then
5525  qt = this%dsflow(n)
5526  q = -this%qconn(i)
5527  ! flow from upstream reaches
5528  else
5529  qt = this%usflow(n)
5530  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
5531  if (this%idir(ii) > 0) cycle
5532  if (this%ja(ii) /= n) cycle
5533  q = this%qconn(ii)
5534  exit
5535  end do
5536  end if
5537  ! calculate flow area
5538  call this%sfr_calc_reach_depth(n, qt, d)
5539  ca = this%calc_area_wet(n, d)
5540  else
5541  q = dzero
5542  ca = dzero
5543  end if
5544  this%qauxcbc(1) = ca
5545  call this%budobj%budterm(idx)%update_term(n1, n2, q, this%qauxcbc)
5546  end do
5547  end do
5548  !
5549  ! -- GWF (LEAKAGE)
5550  idx = idx + 1
5551  call this%budobj%budterm(idx)%reset(this%maxbound - this%ianynone)
5552  do n = 1, this%maxbound
5553  n2 = this%igwfnode(n)
5554  if (n2 > 0) then
5555  if (this%iboundpak(n) /= 0) then
5556  ! -- calc_perimeter_wet() does not enforce depth dependence
5557  if (this%depth(n) > dzero) then
5558  wp = this%calc_perimeter_wet(n, this%depth(n))
5559  else
5560  wp = dzero
5561  end if
5562  l = this%length(n)
5563  a = wp * l
5564  this%qauxcbc(1) = a
5565  q = -this%gwflow(n)
5566  else
5567  this%qauxcbc(1) = dzero
5568  q = dzero
5569  end if
5570  call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
5571  end if
5572  end do
5573  !
5574  ! -- RAIN
5575  idx = idx + 1
5576  call this%budobj%budterm(idx)%reset(this%maxbound)
5577  do n = 1, this%maxbound
5578  if (this%iboundpak(n) /= 0) then
5579  a = this%calc_surface_area(n)
5580  q = this%rain(n) * a
5581  else
5582  q = dzero
5583  end if
5584  call this%budobj%budterm(idx)%update_term(n, n, q)
5585  end do
5586  !
5587  ! -- EVAPORATION
5588  idx = idx + 1
5589  call this%budobj%budterm(idx)%reset(this%maxbound)
5590  do n = 1, this%maxbound
5591  if (this%iboundpak(n) /= 0) then
5592  q = -this%simevap(n)
5593  else
5594  q = dzero
5595  end if
5596  call this%budobj%budterm(idx)%update_term(n, n, q)
5597  end do
5598  !
5599  ! -- RUNOFF
5600  idx = idx + 1
5601  call this%budobj%budterm(idx)%reset(this%maxbound)
5602  do n = 1, this%maxbound
5603  if (this%iboundpak(n) /= 0) then
5604  q = this%simrunoff(n)
5605  else
5606  q = dzero
5607  end if
5608  call this%budobj%budterm(idx)%update_term(n, n, q)
5609  end do
5610  !
5611  ! -- INFLOW
5612  idx = idx + 1
5613  call this%budobj%budterm(idx)%reset(this%maxbound)
5614  do n = 1, this%maxbound
5615  if (this%iboundpak(n) /= 0) then
5616  q = this%inflow(n)
5617  else
5618  q = dzero
5619  end if
5620  call this%budobj%budterm(idx)%update_term(n, n, q)
5621  end do
5622  !
5623  ! -- EXTERNAL OUTFLOW
5624  idx = idx + 1
5625  call this%budobj%budterm(idx)%reset(this%maxbound)
5626  do n = 1, this%maxbound
5627  q = dzero
5628  if (this%iboundpak(n) /= 0) then
5629  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5630  if (this%idir(i) > 0) cycle
5631  idiv = this%idiv(i)
5632  if (idiv > 0) then
5633  jpos = this%iadiv(n) + idiv - 1
5634  q = q + this%divq(jpos)
5635  else
5636  q = q + this%qconn(i)
5637  end if
5638  end do
5639  q = q - this%dsflow(n)
5640  if (this%imover == 1) then
5641  q = q + this%pakmvrobj%get_qtomvr(n)
5642  end if
5643  else
5644  if (this%imover == 1) then
5645  q = this%pakmvrobj%get_qfrommvr(n)
5646  end if
5647  end if
5648  call this%budobj%budterm(idx)%update_term(n, n, q)
5649  end do
5650  !
5651  ! -- STORAGE
5652  idx = idx + 1
5653  call this%budobj%budterm(idx)%reset(this%maxbound)
5654  do n = 1, this%maxbound
5655  q = dzero
5656  if (this%iboundpak(n) /= 0) then
5657  d = this%depth(n)
5658  a = this%calc_surface_area_wet(n, d)
5659  this%qauxcbc(1) = a * d
5660  if (this%gwfiss == 0 .and. this%istorage == 1) then
5661  q = this%storage(n)
5662  end if
5663  else
5664  q = dzero
5665  this%qauxcbc(1) = dzero
5666  end if
5667  call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
5668  end do
5669  !
5670  ! -- MOVER
5671  if (this%imover == 1) then
5672  !
5673  ! -- FROM MOVER
5674  idx = idx + 1
5675  call this%budobj%budterm(idx)%reset(this%maxbound)
5676  do n = 1, this%maxbound
5677  q = dzero
5678  if (this%iboundpak(n) /= 0) then
5679  q = this%pakmvrobj%get_qfrommvr(n)
5680  end if
5681  call this%budobj%budterm(idx)%update_term(n, n, q)
5682  end do
5683  !
5684  ! -- TO MOVER
5685  idx = idx + 1
5686  call this%budobj%budterm(idx)%reset(this%maxbound)
5687  do n = 1, this%maxbound
5688  if (this%iboundpak(n) /= 0) then
5689  q = this%pakmvrobj%get_qtomvr(n)
5690  if (q > dzero) then
5691  q = -q
5692  end if
5693  else
5694  q = dzero
5695  end if
5696  call this%budobj%budterm(idx)%update_term(n, n, q)
5697  end do
5698  end if
5699  !
5700  ! -- AUXILIARY VARIABLES
5701  naux = this%naux
5702  if (naux > 0) then
5703  idx = idx + 1
5704  call this%budobj%budterm(idx)%reset(this%maxbound)
5705  do n = 1, this%maxbound
5706  q = dzero
5707  call this%budobj%budterm(idx)%update_term(n, n, q, this%auxvar(:, n))
5708  end do
5709  end if
5710  !
5711  ! --Terms are filled, now accumulate them for this time step
5712  call this%budobj%accumulate_terms()

◆ sfr_fn()

subroutine sfrmodule::sfr_fn ( class(sfrtype this,
real(dp), dimension(:), intent(inout)  rhs,
integer(i4b), dimension(:), intent(in)  ia,
integer(i4b), dimension(:), intent(in)  idxglo,
class(matrixbasetype), pointer  matrix_sln 
)
private

Calculate and add the Newton-Raphson terms for the SFR package to the coefficient matrix and right-hand side vector.

Parameters
thisSfrType object
[in,out]rhsright-hand side vector for model
[in]iasolution CRS row pointers
[in]idxglomapping vector for model (local) to solution (global)
matrix_slnsolution coefficient matrix

Definition at line 2369 of file gwf-sfr.f90.

2370  ! -- dummy
2371  class(SfrType) :: this !< SfrType object
2372  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2373  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2374  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2375  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2376  ! -- local
2377  integer(I4B) :: i
2378  integer(I4B) :: j
2379  integer(I4B) :: n
2380  integer(I4B) :: ipos
2381  real(DP) :: rterm
2382  real(DP) :: drterm
2383  real(DP) :: rhs1
2384  real(DP) :: hcof1
2385  real(DP) :: q1
2386  real(DP) :: q2
2387  real(DP) :: hgwf
2388  !
2389  ! -- Copy package rhs and hcof into solution rhs and amat
2390  do j = 1, this%nbound
2391  i = this%isfrorder(j)
2392  ! -- skip inactive reaches
2393  if (this%iboundpak(i) < 1) cycle
2394  ! -- skip if reach is not connected to gwf
2395  n = this%nodelist(i)
2396  if (n < 1) cycle
2397  ipos = ia(n)
2398  rterm = this%hcof(i) * this%xnew(n)
2399  ! -- calculate perturbed head
2400  hgwf = this%xnew(n) + dem4
2401  call this%sfr_solve(i, hgwf, hcof1, rhs1, update=.false.)
2402  q1 = rhs1 - hcof1 * hgwf
2403  ! -- calculate unperturbed head
2404  q2 = this%rhs(i) - this%hcof(i) * this%xnew(n)
2405  ! -- calculate derivative
2406  drterm = (q2 - q1) / dem4
2407  ! -- add terms to convert conductance formulation into
2408  ! newton-raphson formulation
2409  call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(i))
2410  rhs(n) = rhs(n) - rterm + drterm * this%xnew(n)
2411  end do

◆ sfr_fp()

subroutine sfrmodule::sfr_fp ( class(sfrtype this)
Parameters
thisSfrType object

Definition at line 2878 of file gwf-sfr.f90.

2879  ! -- dummy
2880  class(SfrType) :: this !< SfrType object
2881  ! -- local
2882  integer(I4B) :: n
2883  real(DP) :: crmean
2884  !
2885  if (this%istorage == 1) then
2886  do n = 1, this%maxbound
2887  if (this%inamedbound == 1) then
2888  call this%couranttab%add_term(this%boundname(n))
2889  end if
2890  call this%couranttab%add_term(n)
2891  if (this%crmin(n) == dep20) then
2892  call this%couranttab%add_term('--')
2893  else
2894  call this%couranttab%add_term(this%crmin(n))
2895  end if
2896  if (this%crmax(n) < dzero) then
2897  call this%couranttab%add_term('--')
2898  else
2899  call this%couranttab%add_term(this%crmax(n))
2900  end if
2901  if (this%crcnt(n) > 0) then
2902  crmean = this%crsum(n) / real(this%crcnt(n), dp)
2903  call this%couranttab%add_term(crmean)
2904  else
2905  call this%couranttab%add_term('--')
2906  end if
2907  end do
2908  end if

◆ sfr_gwf_conn()

integer(i4b) function sfrmodule::sfr_gwf_conn ( class(sfrtype this,
integer(i4b), intent(in)  n 
)
private

Function to determine if a reach is connected to a gwf cell. If connected, the return value is 1. Otherwise, the return value is 0.

Returns
flag indicating if reach is connected to a gwf cell
Parameters
thisSfrType object
[in]nreach number

Definition at line 4249 of file gwf-sfr.f90.

4250  ! -- return variable
4251  integer(I4B) :: sfr_gwf_conn !< flag indicating if reach is connected to a gwf cell
4252  ! -- dummy
4253  class(SfrType) :: this !< SfrType object
4254  integer(I4B), intent(in) :: n !< reach number
4255  ! -- local
4256  integer(I4B) :: node
4257 
4258  sfr_gwf_conn = 0
4259  node = this%igwfnode(n)
4260  if (node > 0 .and. this%hk(n) > dzero) then
4261  sfr_gwf_conn = 1
4262  end if

◆ sfr_obs_supported()

logical function sfrmodule::sfr_obs_supported ( class(sfrtype this)
private

Function to determine if observations are supported by the SFR package. Observations are supported by the SFR package.

Returns
sfr_obs_supported boolean indicating if observations are supported
Parameters
thisSfrType object

Definition at line 3192 of file gwf-sfr.f90.

3193  ! -- dummy
3194  class(SfrType) :: this !< SfrType object
3195  !
3196  ! -- set boolean
3197  sfr_obs_supported = .true.

◆ sfr_options()

subroutine sfrmodule::sfr_options ( class(sfrtype), intent(inout)  this,
character(len=*), intent(inout)  option,
logical(lgp), intent(inout)  found 
)
private

Read additional options for SFR package.

Parameters
[in,out]thisSfrType object
[in,out]optionoption keyword string
[in,out]foundboolean indicating if option found

Definition at line 752 of file gwf-sfr.f90.

753  ! -- modules
754  use openspecmodule, only: access, form
756  ! -- dummy
757  class(SfrType), intent(inout) :: this !< SfrType object
758  character(len=*), intent(inout) :: option !< option keyword string
759  logical(LGP), intent(inout) :: found !< boolean indicating if option found
760  ! -- local
761  integer(I4B) :: istat
762  real(DP) :: r
763  character(len=MAXCHARLEN) :: fname
764  character(len=MAXCHARLEN) :: keyword
765  character(len=:), allocatable :: remaining_line
766  ! -- formats
767  character(len=*), parameter :: fmttimeconv = &
768  &"(4x, 'TIME CONVERSION VALUE (',g0,') SPECIFIED.')"
769  character(len=*), parameter :: fmtlengthconv = &
770  &"(4x, 'LENGTH CONVERSION VALUE (',g0,') SPECIFIED.')"
771  character(len=*), parameter :: fmtpicard = &
772  &"(4x, 'MAXIMUM SFR PICARD ITERATION VALUE (',i0,') SPECIFIED.')"
773  character(len=*), parameter :: fmtiter = &
774  &"(4x, 'MAXIMUM SFR ITERATION VALUE (',i0,') SPECIFIED.')"
775  character(len=*), parameter :: fmtdmaxchg = &
776  &"(4x, 'MAXIMUM DEPTH CHANGE VALUE (',g0,') SPECIFIED.')"
777  character(len=*), parameter :: fmtsfrbin = &
778  "(4x, 'SFR ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', a, /4x, &
779  &'OPENED ON UNIT: ', I0)"
780  character(len=*), parameter :: fmtstoweight = &
781  &"(4x, 'KINEMATIC STORAGE WEIGHT (',g0,') SPECIFIED.')"
782  !
783  ! -- Check for SFR options
784  found = .true.
785  select case (option)
786  case ('STORAGE')
787  this%istorage = 1
788  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
789  ' REACH STORAGE IS ACTIVE.'
790  case ('PRINT_STAGE')
791  this%iprhed = 1
792  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
793  ' STAGES WILL BE PRINTED TO LISTING FILE.'
794  case ('STAGE')
795  call this%parser%GetStringCaps(keyword)
796  if (keyword == 'FILEOUT') then
797  call this%parser%GetString(fname)
798  this%istageout = getunit()
799  call openfile(this%istageout, this%iout, fname, 'DATA(BINARY)', &
800  form, access, 'REPLACE', mnormal)
801  write (this%iout, fmtsfrbin) &
802  'STAGE', trim(adjustl(fname)), this%istageout
803  else
804  call store_error('Optional stage keyword must &
805  &be followed by fileout.')
806  end if
807  case ('BUDGET')
808  call this%parser%GetStringCaps(keyword)
809  if (keyword == 'FILEOUT') then
810  call this%parser%GetString(fname)
811  call assign_iounit(this%ibudgetout, this%inunit, "BUDGET fileout")
812  call openfile(this%ibudgetout, this%iout, fname, 'DATA(BINARY)', &
813  form, access, 'REPLACE', mnormal)
814  write (this%iout, fmtsfrbin) &
815  'BUDGET', trim(adjustl(fname)), this%ibudgetout
816  else
817  call store_error('Optional budget keyword must be '// &
818  'followed by fileout.')
819  end if
820  case ('BUDGETCSV')
821  call this%parser%GetStringCaps(keyword)
822  if (keyword == 'FILEOUT') then
823  call this%parser%GetString(fname)
824  call assign_iounit(this%ibudcsv, this%inunit, "BUDGETCSV fileout")
825  call openfile(this%ibudcsv, this%iout, fname, 'CSV', &
826  filstat_opt='REPLACE')
827  write (this%iout, fmtsfrbin) &
828  'BUDGET CSV', trim(adjustl(fname)), this%ibudcsv
829  else
830  call store_error('OPTIONAL BUDGETCSV KEYWORD MUST BE FOLLOWED BY &
831  &FILEOUT')
832  end if
833  case ('PACKAGE_CONVERGENCE')
834  call this%parser%GetStringCaps(keyword)
835  if (keyword == 'FILEOUT') then
836  call this%parser%GetString(fname)
837  this%ipakcsv = getunit()
838  call openfile(this%ipakcsv, this%iout, fname, 'CSV', &
839  filstat_opt='REPLACE', mode_opt=mnormal)
840  write (this%iout, fmtsfrbin) &
841  'PACKAGE_CONVERGENCE', trim(adjustl(fname)), this%ipakcsv
842  else
843  call store_error('Optional package_convergence keyword must be '// &
844  'followed by fileout.')
845  end if
846  case ('UNIT_CONVERSION')
847  this%unitconv = this%parser%GetDouble()
848  !
849  ! -- create warning message
850  write (warnmsg, '(a)') &
851  'SETTING UNIT_CONVERSION DIRECTLY'
852  !
853  ! -- create deprecation warning
854  call deprecation_warning('OPTIONS', 'UNIT_CONVERSION', '6.4.2', &
855  warnmsg, this%parser%GetUnit())
856  case ('LENGTH_CONVERSION')
857  this%lengthconv = this%parser%GetDouble()
858  write (this%iout, fmtlengthconv) this%lengthconv
859  case ('TIME_CONVERSION')
860  this%timeconv = this%parser%GetDouble()
861  write (this%iout, fmttimeconv) this%timeconv
862  case ('MAXIMUM_PICARD_ITERATIONS')
863  this%maxsfrpicard = this%parser%GetInteger()
864  write (this%iout, fmtpicard) this%maxsfrpicard
865  case ('MAXIMUM_ITERATIONS')
866  this%maxsfrit = this%parser%GetInteger()
867  write (this%iout, fmtiter) this%maxsfrit
868  case ('MAXIMUM_DEPTH_CHANGE')
869  r = this%parser%GetDouble()
870  this%dmaxchg = r
871  this%deps = dp999 * r
872  write (this%iout, fmtdmaxchg) this%dmaxchg
873  case ('MOVER')
874  this%imover = 1
875  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
876  !
877  ! -- right now these are options that are only available in the
878  ! development version and are not included in the documentation.
879  ! These options are only available when IDEVELOPMODE in
880  ! constants module is set to 1
881  case ('ATS_COURANT')
882  call this%parser%GetRemainingLine(remaining_line)
883  keyword = trim(adjustl(remaining_line))
884  if (len_trim(keyword) == 0) then
885  this%ats_courant = done
886  else
887  read (keyword, *, iostat=istat) this%ats_courant
888  if (istat /= 0 .or. this%ats_courant <= dzero) then
889  write (errmsg, '(a,g0,a)') &
890  "ATS_COURANT SPECIFIED TO BE '", this%ats_courant, &
891  "' BUT MUST BE GREATER THAN ZERO"
892  call store_error(errmsg)
893  end if
894  end if
895  write (this%iout, '(4x,a,1pg15.6)') &
896  'TARGET COURANT NUMBER FOR ADAPTIVE TIME STEPS: ', &
897  this%ats_courant
898  case ('DEV_NO_CHECK')
899  call this%parser%DevOpt()
900  this%icheck = 0
901  write (this%iout, '(4x,A)') 'SFR CHECKS OF REACH GEOMETRY '// &
902  'RELATIVE TO MODEL GRID AND '// &
903  'REASONABLE PARAMETERS WILL NOT '// &
904  'BE PERFORMED.'
905  case ('DEV_NO_FINAL_CHECK')
906  call this%parser%DevOpt()
907  this%iconvchk = 0
908  write (this%iout, '(4x,a)') &
909  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN STREAM FLOW ROUTING &
910  &STAGES AND FLOWS WILL NOT BE MADE'
911  case ('DEV_STORAGE_WEIGHT')
912  call this%parser%DevOpt()
913  r = this%parser%GetDouble()
914  if (r < dhalf .or. r > done) then
915  write (errmsg, '(a,g0,a)') &
916  "STORAGE_WEIGHT SPECIFIED TO BE '", r, &
917  "' BUT CANNOT BE LESS THAN 0.5 OR GREATER THAN 1.0"
918  call store_error(errmsg)
919  else
920  this%storage_weight = r
921  write (this%iout, fmtstoweight) this%storage_weight
922  end if
923  !
924  ! -- no valid options found
925  case default
926  !
927  ! -- No options found
928  found = .false.
929  end select
subroutine, public assign_iounit(iounit, errunit, description)
@ brief assign io unit number
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
Here is the call graph for this function:

◆ sfr_ot_bdsummary()

subroutine sfrmodule::sfr_ot_bdsummary ( class(sfrtype this,
integer(i4b), intent(in)  kstp,
integer(i4b), intent(in)  kper,
integer(i4b), intent(in)  iout,
integer(i4b), intent(in)  ibudfl 
)

Output SFR package budget summary.

Parameters
thisSfrType object
[in]kstptime step number
[in]kperperiod number
[in]ioutflag and unit number for the model listing file
[in]ibudflflag indicating budget should be written

Definition at line 2863 of file gwf-sfr.f90.

2864  ! -- module
2865  use tdismodule, only: totim, delt
2866  ! -- dummy
2867  class(SfrType) :: this !< SfrType object
2868  integer(I4B), intent(in) :: kstp !< time step number
2869  integer(I4B), intent(in) :: kper !< period number
2870  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
2871  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
2872  !
2873  call this%budobj%write_budtable(kstp, kper, iout, ibudfl, totim, delt)

◆ sfr_ot_dv()

subroutine sfrmodule::sfr_ot_dv ( class(sfrtype this,
integer(i4b), intent(in)  idvsave,
integer(i4b), intent(in)  idvprint 
)

Output SFR boundary package dependent-variable terms.

Parameters
thisSfrType object
[in]idvsaveflag and unit number for dependent-variable output
[in]idvprintflag indicating if dependent-variable should be written to the model listing file

Definition at line 2751 of file gwf-sfr.f90.

2752  ! -- modules
2753  use tdismodule, only: kstp, kper, pertim, totim
2754  use inputoutputmodule, only: ulasav
2755  ! -- dummy
2756  class(SfrType) :: this !< SfrType object
2757  integer(I4B), intent(in) :: idvsave !< flag and unit number for dependent-variable output
2758  integer(I4B), intent(in) :: idvprint !< flag indicating if dependent-variable should be written to the model listing file
2759  ! -- local
2760  character(len=20) :: cellid
2761  integer(I4B) :: ibinun
2762  integer(I4B) :: n
2763  integer(I4B) :: node
2764  real(DP) :: d
2765  real(DP) :: v
2766  real(DP) :: hgwf
2767  real(DP) :: sbot
2768  real(DP) :: depth
2769  real(DP) :: stage
2770  real(DP) :: w
2771  real(DP) :: cond
2772  real(DP) :: grad
2773  !
2774  ! -- set unit number for binary dependent variable output
2775  ibinun = 0
2776  if (this%istageout /= 0) then
2777  ibinun = this%istageout
2778  end if
2779  if (idvsave == 0) ibinun = 0
2780  !
2781  ! -- write sfr binary output
2782  if (ibinun > 0) then
2783  do n = 1, this%maxbound
2784  d = this%depth(n)
2785  v = this%stage(n)
2786  if (this%iboundpak(n) == 0) then
2787  v = dhnoflo
2788  else if (d == dzero) then
2789  v = dhdry
2790  end if
2791  this%dbuff(n) = v
2792  end do
2793  call ulasav(this%dbuff, ' STAGE', kstp, kper, pertim, totim, &
2794  this%maxbound, 1, 1, ibinun)
2795  end if
2796  !
2797  ! -- print sfr stage and depth table
2798  if (idvprint /= 0 .and. this%iprhed /= 0) then
2799  !
2800  ! -- set table kstp and kper
2801  call this%stagetab%set_kstpkper(kstp, kper)
2802  !
2803  ! -- fill stage data
2804  do n = 1, this%maxbound
2805  node = this%igwfnode(n)
2806  if (node > 0) then
2807  call this%dis%noder_to_string(node, cellid)
2808  hgwf = this%xnew(node)
2809  else
2810  cellid = 'NONE'
2811  end if
2812  if (this%inamedbound == 1) then
2813  call this%stagetab%add_term(this%boundname(n))
2814  end if
2815  call this%stagetab%add_term(n)
2816  call this%stagetab%add_term(cellid)
2817  if (this%iboundpak(n) /= 0) then
2818  depth = this%depth(n)
2819  stage = this%stage(n)
2820  w = this%calc_top_width_wet(n, depth)
2821  call this%sfr_calc_cond(n, depth, cond, stage, hgwf)
2822  else
2823  depth = dhnoflo
2824  stage = dhnoflo
2825  w = dhnoflo
2826  cond = dhnoflo
2827  end if
2828  if (depth == dzero) then
2829  call this%stagetab%add_term(dhdry)
2830  else
2831  call this%stagetab%add_term(stage)
2832  end if
2833  call this%stagetab%add_term(depth)
2834  call this%stagetab%add_term(w)
2835  if (node > 0) then
2836  if (this%iboundpak(n) /= 0) then
2837  sbot = this%strtop(n) - this%bthick(n)
2838  if (hgwf < sbot) then
2839  grad = stage - sbot
2840  else
2841  grad = stage - hgwf
2842  end if
2843  grad = grad / this%bthick(n)
2844  else
2845  grad = dhnoflo
2846  end if
2847  call this%stagetab%add_term(hgwf)
2848  call this%stagetab%add_term(cond)
2849  call this%stagetab%add_term(grad)
2850  else
2851  call this%stagetab%add_term('--')
2852  call this%stagetab%add_term('--')
2853  call this%stagetab%add_term('--')
2854  end if
2855  end do
2856  end if
subroutine, public ulasav(buf, text, kstp, kper, pertim, totim, ncol, nrow, ilay, ichn)
Save 1 layer array on disk.
real(dp), pointer, public pertim
time relative to start of stress period
Definition: tdis.f90:33
Here is the call graph for this function:

◆ sfr_ot_package_flows()

subroutine sfrmodule::sfr_ot_package_flows ( class(sfrtype this,
integer(i4b), intent(in)  icbcfl,
integer(i4b), intent(in)  ibudfl 
)

Output SFR package flow terms.

Parameters
thisSfrType object
[in]icbcflflag and unit number for cell-by-cell output
[in]ibudflflag indication if cell-by-cell data should be saved

Definition at line 2698 of file gwf-sfr.f90.

2699  ! -- modules
2700  use tdismodule, only: kstp, kper, delt, pertim, totim
2701  ! -- dummy
2702  class(SfrType) :: this !< SfrType object
2703  integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output
2704  integer(I4B), intent(in) :: ibudfl !< flag indication if cell-by-cell data should be saved
2705  ! -- local
2706  integer(I4B) :: ibinun
2707  character(len=20), dimension(:), allocatable :: cellidstr
2708  integer(I4B) :: n
2709  integer(I4B) :: node
2710  !
2711  ! -- write the flows from the budobj
2712  ibinun = 0
2713  if (this%ibudgetout /= 0) then
2714  ibinun = this%ibudgetout
2715  end if
2716  if (icbcfl == 0) ibinun = 0
2717  if (ibinun > 0) then
2718  call this%budobj%save_flows(this%dis, ibinun, kstp, kper, delt, &
2719  pertim, totim, this%iout)
2720  end if
2721  !
2722  ! -- Print sfr flows table
2723  if (ibudfl /= 0 .and. this%iprflow /= 0) then
2724  !
2725  ! -- If there are any 'none' gwf connections then need to calculate
2726  ! a vector of cellids and pass that in to the budget flow table because
2727  ! the table assumes that there are maxbound gwf entries, which is not
2728  ! the case if any 'none's are specified.
2729  if (this%ianynone > 0) then
2730  allocate (cellidstr(this%maxbound))
2731  do n = 1, this%maxbound
2732  node = this%igwfnode(n)
2733  if (node > 0) then
2734  call this%dis%noder_to_string(node, cellidstr(n))
2735  else
2736  cellidstr(n) = 'NONE'
2737  end if
2738  end do
2739  call this%budobj%write_flowtable(this%dis, kstp, kper, cellidstr)
2740  deallocate (cellidstr)
2741  else
2742  call this%budobj%write_flowtable(this%dis, kstp, kper)
2743  end if
2744  end if

◆ sfr_precompute_tvd()

subroutine sfrmodule::sfr_precompute_tvd ( class(sfrtype), intent(inout)  this)

Index 0 for reaches with zero or multiple upstream connections.

Parameters
[in,out]thisSfrType object

Definition at line 3129 of file gwf-sfr.f90.

3130  ! -- dummy
3131  class(SfrType), intent(inout) :: this !< SfrType object
3132  ! -- local
3133  integer(I4B) :: n
3134  integer(I4B) :: j
3135  integer(I4B) :: iup_count
3136  integer(I4B) :: m
3137  !
3138  do n = 1, this%maxbound
3139  iup_count = 0
3140  m = 0
3141  do j = this%ia(n) + 1, this%ia(n + 1) - 1
3142  if (this%idir(j) > 0) then
3143  iup_count = iup_count + 1
3144  m = this%ja(j)
3145  end if
3146  end do
3147  if (iup_count == 1) then
3148  this%itvd_upstream(n) = m
3149  else
3150  this%itvd_upstream(n) = 0
3151  end if
3152  end do

◆ sfr_process_obsid()

subroutine sfrmodule::sfr_process_obsid ( type(observetype), intent(inout)  obsrv,
class(disbasetype), intent(in)  dis,
integer(i4b), intent(in)  inunitobs,
integer(i4b), intent(in)  iout 
)

Method to process observation ID strings for a SFR package.

Parameters
[in,out]obsrvObservation object
[in]disDiscretization object
[in]inunitobsfile unit number for the package observation file
[in]ioutmodel listing file unit number

Definition at line 3502 of file gwf-sfr.f90.

3503  ! -- dummy
3504  type(ObserveType), intent(inout) :: obsrv !< Observation object
3505  class(DisBaseType), intent(in) :: dis !< Discretization object
3506  integer(I4B), intent(in) :: inunitobs !< file unit number for the package observation file
3507  integer(I4B), intent(in) :: iout !< model listing file unit number
3508  ! -- local
3509  integer(I4B) :: nn1
3510  integer(I4B) :: icol
3511  integer(I4B) :: istart
3512  integer(I4B) :: istop
3513  character(len=LINELENGTH) :: string
3514  character(len=LENBOUNDNAME) :: bndname
3515  !
3516  ! -- initialize local variables
3517  string = obsrv%IDstring
3518  !
3519  ! -- Extract reach number from string and store it.
3520  ! If 1st item is not an integer(I4B), it should be a
3521  ! boundary name--deal with it.
3522  icol = 1
3523  !
3524  ! -- get reach number or boundary name
3525  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
3526  if (nn1 == namedboundflag) then
3527  obsrv%FeatureName = bndname
3528  end if
3529  !
3530  ! -- store reach number (NodeNumber)
3531  obsrv%NodeNumber = nn1
Here is the call graph for this function:

◆ sfr_read_connectiondata()

subroutine sfrmodule::sfr_read_connectiondata ( class(sfrtype), intent(inout)  this)

Method to read connectiondata for each reach for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 1417 of file gwf-sfr.f90.

1418  ! -- modules
1420  use sparsemodule, only: sparsematrix
1421  ! -- dummy
1422  class(SfrType), intent(inout) :: this !< SfrType object
1423  ! -- local
1424  character(len=LINELENGTH) :: line
1425  logical(LGP) :: isfound
1426  logical(LGP) :: endOfBlock
1427  integer(I4B) :: n
1428  integer(I4B) :: i
1429  integer(I4B) :: j
1430  integer(I4B) :: jj
1431  integer(I4B) :: jcol
1432  integer(I4B) :: jcol2
1433  integer(I4B) :: nja
1434  integer(I4B) :: ival
1435  integer(I4B) :: idir
1436  integer(I4B) :: ierr
1437  integer(I4B) :: nconnmax
1438  integer(I4B) :: nup
1439  integer(I4B) :: ipos
1440  integer(I4B) :: istat
1441  integer(I4B), dimension(:), pointer, contiguous :: rowmaxnnz => null()
1442  integer, allocatable, dimension(:) :: nboundchk
1443  integer, allocatable, dimension(:, :) :: iconndata
1444  type(sparsematrix), pointer :: sparse => null()
1445  integer(I4B), dimension(:), allocatable :: iup
1446  integer(I4B), dimension(:), allocatable :: order
1447  type(dag) :: sfr_dag
1448  !
1449  ! -- allocate and initialize local variables for reach connections
1450  allocate (nboundchk(this%maxbound))
1451  do n = 1, this%maxbound
1452  nboundchk(n) = 0
1453  end do
1454  !
1455  ! -- calculate the number of non-zero entries (size of ja maxtrix)
1456  nja = 0
1457  nconnmax = 0
1458  allocate (rowmaxnnz(this%maxbound))
1459  do n = 1, this%maxbound
1460  ival = this%nconnreach(n)
1461  if (ival < 0) ival = 0
1462  rowmaxnnz(n) = ival + 1
1463  nja = nja + ival + 1
1464  if (ival > nconnmax) then
1465  nconnmax = ival
1466  end if
1467  end do
1468  !
1469  ! -- reallocate connection data for package
1470  call mem_reallocate(this%ja, nja, 'JA', this%memoryPath)
1471  call mem_reallocate(this%idir, nja, 'IDIR', this%memoryPath)
1472  call mem_reallocate(this%idiv, nja, 'IDIV', this%memoryPath)
1473  call mem_reallocate(this%qconn, nja, 'QCONN', this%memoryPath)
1474  !
1475  ! -- initialize connection data
1476  do n = 1, nja
1477  this%idir(n) = 0
1478  this%idiv(n) = 0
1479  this%qconn(n) = dzero
1480  end do
1481  !
1482  ! -- allocate space for iconndata
1483  allocate (iconndata(nconnmax, this%maxbound))
1484  !
1485  ! -- initialize iconndata
1486  do n = 1, this%maxbound
1487  do j = 1, nconnmax
1488  iconndata(j, n) = 0
1489  end do
1490  end do
1491  !
1492  ! -- allocate space for connectivity
1493  allocate (sparse)
1494  !
1495  ! -- set up sparse
1496  call sparse%init(this%maxbound, this%maxbound, rowmaxnnz)
1497  !
1498  ! -- read connection data
1499  call this%parser%GetBlock('CONNECTIONDATA', isfound, ierr, &
1500  supportopenclose=.true.)
1501  !
1502  ! -- parse reach connectivity block if detected
1503  if (isfound) then
1504  write (this%iout, '(/1x,a)') &
1505  'PROCESSING '//trim(adjustl(this%text))//' CONNECTIONDATA'
1506  do
1507  call this%parser%GetNextLine(endofblock)
1508  if (endofblock) exit
1509  !
1510  ! -- get reach number
1511  n = this%parser%GetInteger()
1512  !
1513  ! -- check for error
1514  if (n < 1 .or. n > this%maxbound) then
1515  write (errmsg, '(a,1x,a,1x,i0)') &
1516  'SFR reach in connectiondata block is less than one or greater', &
1517  'than NREACHES:', n
1518  call store_error(errmsg)
1519  cycle
1520  end if
1521  !
1522  ! -- increment nboundchk
1523  nboundchk(n) = nboundchk(n) + 1
1524  !
1525  ! -- add diagonal connection for reach
1526  call sparse%addconnection(n, n, 1)
1527  !
1528  ! -- fill off diagonals
1529  do i = 1, this%nconnreach(n)
1530  !
1531  ! -- get connected reach
1532  ival = this%parser%GetInteger()
1533  !
1534  ! -- save connection data to temporary iconndata
1535  iconndata(i, n) = ival
1536  !
1537  ! -- determine idir
1538  if (ival < 0) then
1539  idir = -1
1540  ival = abs(ival)
1541  elseif (ival == 0) then
1542  call store_error('Missing or zero connection reach in line:')
1543  call store_error(line)
1544  else
1545  idir = 1
1546  end if
1547  if (ival > this%maxbound) then
1548  call store_error('Reach number exceeds NREACHES in line:')
1549  call store_error(line)
1550  end if
1551  !
1552  ! -- add connection to sparse
1553  call sparse%addconnection(n, ival, 1)
1554  end do
1555  end do
1556 
1557  write (this%iout, '(1x,a)') &
1558  'END OF '//trim(adjustl(this%text))//' CONNECTIONDATA'
1559 
1560  do n = 1, this%maxbound
1561  !
1562  ! -- check for missing or duplicate sfr connections
1563  if (nboundchk(n) == 0) then
1564  write (errmsg, '(a,1x,i0)') &
1565  'No connection data specified for reach', n
1566  call store_error(errmsg)
1567  else if (nboundchk(n) > 1) then
1568  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1569  'Connection data for reach', n, &
1570  'specified', nboundchk(n), 'times.'
1571  call store_error(errmsg)
1572  end if
1573  end do
1574  else
1575  call store_error('Required connectiondata block not found.')
1576  end if
1577  !
1578  ! -- terminate if errors encountered in connectiondata block
1579  if (count_errors() > 0) then
1580  call this%parser%StoreErrorUnit()
1581  end if
1582  !
1583  ! -- create ia and ja from sparse
1584  call sparse%filliaja(this%ia, this%ja, ierr, sort=.true.)
1585  !
1586  ! -- test for error condition
1587  if (ierr /= 0) then
1588  write (errmsg, '(a,3(1x,a))') &
1589  'Could not fill', trim(this%packName), &
1590  'package IA and JA connection data.', &
1591  'Check connectivity data in connectiondata block.'
1592  call store_error(errmsg)
1593  end if
1594  !
1595  ! -- fill flat connection storage
1596  do n = 1, this%maxbound
1597  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1598  jcol = this%ja(j)
1599  do jj = 1, this%nconnreach(n)
1600  jcol2 = iconndata(jj, n)
1601  if (abs(jcol2) == jcol) then
1602  idir = 1
1603  if (jcol2 < 0) then
1604  idir = -1
1605  end if
1606  this%idir(j) = idir
1607  exit
1608  end if
1609  end do
1610  end do
1611  end do
1612  !
1613  ! -- deallocate temporary local storage for reach connections
1614  deallocate (rowmaxnnz)
1615  deallocate (nboundchk)
1616  deallocate (iconndata)
1617  !
1618  ! -- destroy sparse
1619  call sparse%destroy()
1620  deallocate (sparse)
1621  !
1622  ! -- calculate reach order using DAG
1623  !
1624  ! -- initialize the DAG
1625  call sfr_dag%set_vertices(this%maxbound)
1626  !
1627  ! -- fill DAG
1628  fill_dag: do n = 1, this%maxbound
1629  !
1630  ! -- determine the number of upstream reaches
1631  nup = 0
1632  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1633  if (this%idir(j) > 0) then
1634  nup = nup + 1
1635  end if
1636  end do
1637  !
1638  ! -- cycle if nu upstream reacches
1639  if (nup == 0) cycle fill_dag
1640  !
1641  ! -- allocate local storage
1642  allocate (iup(nup))
1643  !
1644  ! -- fill local storage
1645  ipos = 1
1646  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1647  if (this%idir(j) > 0) then
1648  iup(ipos) = this%ja(j)
1649  ipos = ipos + 1
1650  end if
1651  end do
1652  !
1653  ! -- add upstream connections to DAG
1654  call sfr_dag%set_edges(n, iup)
1655  !
1656  ! -- clean up local storage
1657  deallocate (iup)
1658  end do fill_dag
1659  !
1660  ! -- perform toposort on DAG
1661  call sfr_dag%toposort(order, istat)
1662  !
1663  ! -- write warning if circular dependency
1664  if (istat == -1) then
1665  write (warnmsg, '(a)') &
1666  trim(adjustl(this%text))//' PACKAGE ('// &
1667  trim(adjustl(this%packName))//') cannot calculate a '// &
1668  'Directed Asyclic Graph for reach connectivity because '// &
1669  'of circular dependency. Using the reach number for '// &
1670  'solution ordering.'
1671  call store_warning(warnmsg)
1672  end if
1673  !
1674  ! -- fill isfrorder
1675  do n = 1, this%maxbound
1676  if (istat == 0) then
1677  this%isfrorder(n) = order(n)
1678  else
1679  this%isfrorder(n) = n
1680  end if
1681  end do
1682  !
1683  ! -- clean up DAG and remaining local storage
1684  call sfr_dag%destroy()
1685  if (istat == 0) then
1686  deallocate (order)
1687  end if
Here is the call graph for this function:

◆ sfr_read_crossection()

subroutine sfrmodule::sfr_read_crossection ( class(sfrtype), intent(inout)  this)

Method to read crosssection data for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 1279 of file gwf-sfr.f90.

1280  ! -- modules
1283  ! -- dummy
1284  class(SfrType), intent(inout) :: this !< SfrType object
1285  ! -- local
1286  character(len=LINELENGTH) :: keyword
1287  character(len=LINELENGTH) :: line
1288  logical(LGP) :: isfound
1289  logical(LGP) :: endOfBlock
1290  integer(I4B) :: n
1291  integer(I4B) :: ierr
1292  integer(I4B) :: ncrossptstot
1293  integer, allocatable, dimension(:) :: nboundchk
1294  type(SfrCrossSection), pointer :: cross_data => null()
1295  !
1296  ! -- read cross-section data
1297  call this%parser%GetBlock('CROSSSECTIONS', isfound, ierr, &
1298  supportopenclose=.true., &
1299  blockrequired=.false.)
1300  !
1301  ! -- parse reach connectivity block if detected
1302  if (isfound) then
1303  write (this%iout, '(/1x,a)') &
1304  'PROCESSING '//trim(adjustl(this%text))//' CROSSSECTIONS'
1305  !
1306  ! -- allocate and initialize local variables for reach cross-sections
1307  allocate (nboundchk(this%maxbound))
1308  do n = 1, this%maxbound
1309  nboundchk(n) = 0
1310  end do
1311  !
1312  ! -- create and initialize cross-section data
1313  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1314  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1315  this%iacross, &
1316  this%station, this%xsheight, &
1317  this%xsrough)
1318  !
1319  ! -- read all of the entries in the block
1320  readtable: do
1321  call this%parser%GetNextLine(endofblock)
1322  if (endofblock) exit
1323  !
1324  ! -- get reach number
1325  n = this%parser%GetInteger()
1326  !
1327  ! -- check for reach number error
1328  if (n < 1 .or. n > this%maxbound) then
1329  write (errmsg, '(a,1x,a,1x,i0)') &
1330  'SFR reach in crosssections block is less than one or greater', &
1331  'than NREACHES:', n
1332  call store_error(errmsg)
1333  cycle readtable
1334  end if
1335  !
1336  ! -- increment nboundchk
1337  nboundchk(n) = nboundchk(n) + 1
1338  !
1339  ! -- read FILE keyword
1340  call this%parser%GetStringCaps(keyword)
1341  select case (keyword)
1342  case ('TAB6')
1343  call this%parser%GetStringCaps(keyword)
1344  if (trim(adjustl(keyword)) /= 'FILEIN') then
1345  errmsg = 'TAB6 keyword must be followed by "FILEIN" '// &
1346  'then by filename.'
1347  call store_error(errmsg)
1348  cycle readtable
1349  end if
1350  call this%parser%GetString(line)
1351  call cross_data%read_table(n, this%width(n), &
1352  trim(adjustl(line)))
1353  case default
1354  write (errmsg, '(a,1x,i4,1x,a)') &
1355  'CROSS-SECTION TABLE ENTRY for REACH ', n, &
1356  'MUST INCLUDE TAB6 KEYWORD'
1357  call store_error(errmsg)
1358  cycle readtable
1359  end select
1360  end do readtable
1361 
1362  write (this%iout, '(1x,a)') &
1363  'END OF '//trim(adjustl(this%text))//' CROSSSECTIONS'
1364 
1365  !
1366  ! -- check for duplicate sfr crosssections
1367  do n = 1, this%maxbound
1368  if (nboundchk(n) > 1) then
1369  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1370  'Cross-section data for reach', n, &
1371  'specified', nboundchk(n), 'times.'
1372  call store_error(errmsg)
1373  end if
1374  end do
1375  !
1376  ! -- terminate if errors encountered in cross-sections block
1377  if (count_errors() > 0) then
1378  call this%parser%StoreErrorUnit()
1379  end if
1380  !
1381  ! -- determine the current size of cross-section data
1382  ncrossptstot = cross_data%get_ncrossptstot()
1383  !
1384  ! -- reallocate sfr package cross-section data
1385  if (ncrossptstot /= this%ncrossptstot) then
1386  this%ncrossptstot = ncrossptstot
1387  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1388  this%memoryPath)
1389  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1390  this%memoryPath)
1391  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1392  this%memoryPath)
1393  end if
1394  !
1395  ! -- write cross-section data to the model listing file
1396  call cross_data%output(this%width, this%rough)
1397  !
1398  ! -- pack cross-section data
1399  call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
1400  this%iacross, &
1401  this%station, &
1402  this%xsheight, &
1403  this%xsrough)
1404  !
1405  ! -- deallocate temporary local storage for reach cross-sections
1406  deallocate (nboundchk)
1407  call cross_data%destroy()
1408  deallocate (cross_data)
1409  nullify (cross_data)
1410  end if
subroutine, public cross_section_cr(this, iout, iprpak, nreaches)
Create a cross-section object.
Here is the call graph for this function:

◆ sfr_read_dimensions()

subroutine sfrmodule::sfr_read_dimensions ( class(sfrtype), intent(inout)  this)

Read dimensions for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 664 of file gwf-sfr.f90.

665  ! -- dummy
666  class(SfrType), intent(inout) :: this !< SfrType object
667  ! -- local
668  character(len=LINELENGTH) :: keyword
669  integer(I4B) :: ierr
670  logical(LGP) :: isfound
671  logical(LGP) :: endOfBlock
672  !
673  ! -- initialize dimensions to 0
674  this%maxbound = 0
675  !
676  ! -- get dimensions block
677  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
678  supportopenclose=.true.)
679  !
680  ! -- parse dimensions block if detected
681  if (isfound) then
682  write (this%iout, '(/1x,a)') &
683  'PROCESSING '//trim(adjustl(this%text))//' DIMENSIONS'
684  do
685  call this%parser%GetNextLine(endofblock)
686  if (endofblock) exit
687  call this%parser%GetStringCaps(keyword)
688  select case (keyword)
689  case ('NREACHES')
690  this%maxbound = this%parser%GetInteger()
691  write (this%iout, '(4x,a,i0)') 'NREACHES = ', this%maxbound
692  case default
693  write (errmsg, '(2a)') &
694  'Unknown '//trim(this%text)//' dimension: ', trim(keyword)
695  call store_error(errmsg)
696  end select
697  end do
698  write (this%iout, '(1x,a)') &
699  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
700  else
701  call store_error('Required dimensions block not found.')
702  end if
703  !
704  ! -- verify dimensions were set
705  if (this%maxbound < 1) then
706  write (errmsg, '(a)') &
707  'NREACHES was not specified or was specified incorrectly.'
708  call store_error(errmsg)
709  end if
710  !
711  ! -- write summary of error messages for block
712  if (count_errors() > 0) then
713  call this%parser%StoreErrorUnit()
714  end if
715  !
716  ! -- Call define_listlabel to construct the list label that is written
717  ! when PRINT_INPUT option is used.
718  call this%define_listlabel()
719  !
720  ! -- Define default cross-section data size
721  this%ncrossptstot = this%maxbound
722  !
723  ! -- Allocate arrays in package superclass
724  call this%sfr_allocate_arrays()
725  !
726  ! -- read package data
727  call this%sfr_read_packagedata()
728  !
729  ! -- read cross-section data
730  call this%sfr_read_crossection()
731  !
732  ! -- read connection data
733  call this%sfr_read_connectiondata()
734  !
735  ! -- read diversion data
736  call this%sfr_read_diversions()
737  !
738  ! -- read initial stage data
739  call this%sfr_read_initial_stages()
740  !
741  ! -- setup the budget object
742  call this%sfr_setup_budobj()
743  !
744  ! -- setup the stage table object
745  call this%sfr_setup_tableobj()
Here is the call graph for this function:

◆ sfr_read_diversions()

subroutine sfrmodule::sfr_read_diversions ( class(sfrtype), intent(inout)  this)

Method to read diversions for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 1694 of file gwf-sfr.f90.

1695  ! -- modules
1697  ! -- dummy
1698  class(SfrType), intent(inout) :: this !< SfrType object
1699  ! -- local
1700  character(len=10) :: cnum
1701  character(len=10) :: cval
1702  integer(I4B) :: j
1703  integer(I4B) :: n
1704  integer(I4B) :: ierr
1705  integer(I4B) :: ival
1706  integer(I4B) :: i0
1707  integer(I4B) :: ipos
1708  integer(I4B) :: jpos
1709  integer(I4B) :: ndiv
1710  integer(I4B) :: ndiversions
1711  integer(I4B) :: idivreach
1712  logical(LGP) :: isfound
1713  logical(LGP) :: endOfBlock
1714  integer(I4B) :: idiv
1715  integer, allocatable, dimension(:) :: iachk
1716  integer, allocatable, dimension(:) :: nboundchk
1717  !
1718  ! -- determine the total number of diversions and fill iadiv
1719  ndiversions = 0
1720  i0 = 1
1721  this%iadiv(1) = i0
1722  do n = 1, this%maxbound
1723  ndiversions = ndiversions + this%ndiv(n)
1724  i0 = i0 + this%ndiv(n)
1725  this%iadiv(n + 1) = i0
1726  end do
1727  !
1728  ! -- reallocate memory for diversions
1729  if (ndiversions > 0) then
1730  call mem_reallocate(this%divreach, ndiversions, 'DIVREACH', &
1731  this%memoryPath)
1732  allocate (this%divcprior(ndiversions))
1733  call mem_reallocate(this%divflow, ndiversions, 'DIVFLOW', this%memoryPath)
1734  call mem_reallocate(this%divq, ndiversions, 'DIVQ', this%memoryPath)
1735  end if
1736  !
1737  ! -- initialize diversion flow
1738  do n = 1, ndiversions
1739  this%divflow(n) = dzero
1740  this%divq(n) = dzero
1741  end do
1742  !
1743  ! -- read diversions
1744  call this%parser%GetBlock('DIVERSIONS', isfound, ierr, &
1745  supportopenclose=.true., &
1746  blockrequired=.false.)
1747  !
1748  ! -- parse reach connectivity block if detected
1749  if (isfound) then
1750  if (this%idiversions /= 0) then
1751  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1752  ' DIVERSIONS'
1753  !
1754  ! -- allocate and initialize local variables for diversions
1755  ndiv = 0
1756  do n = 1, this%maxbound
1757  ndiv = ndiv + this%ndiv(n)
1758  end do
1759  allocate (iachk(this%maxbound + 1))
1760  allocate (nboundchk(ndiv))
1761  iachk(1) = 1
1762  do n = 1, this%maxbound
1763  iachk(n + 1) = iachk(n) + this%ndiv(n)
1764  end do
1765  do n = 1, ndiv
1766  nboundchk(n) = 0
1767  end do
1768  !
1769  ! -- read diversion data
1770  do
1771  call this%parser%GetNextLine(endofblock)
1772  if (endofblock) exit
1773  !
1774  ! -- get reach number
1775  n = this%parser%GetInteger()
1776  if (n < 1 .or. n > this%maxbound) then
1777  write (cnum, '(i0)') n
1778  errmsg = 'Reach number should be between 1 and '// &
1779  trim(cnum)//'.'
1780  call store_error(errmsg)
1781  cycle
1782  end if
1783  !
1784  ! -- make sure reach has at least one diversion
1785  if (this%ndiv(n) < 1) then
1786  write (cnum, '(i0)') n
1787  errmsg = 'Diversions cannot be specified '// &
1788  'for reach '//trim(cnum)
1789  call store_error(errmsg)
1790  cycle
1791  end if
1792  !
1793  ! -- read diversion number
1794  ival = this%parser%GetInteger()
1795  if (ival < 1 .or. ival > this%ndiv(n)) then
1796  write (cnum, '(i0)') n
1797  errmsg = 'Reach '//trim(cnum)
1798  write (cnum, '(i0)') this%ndiv(n)
1799  errmsg = trim(errmsg)//' diversion number should be between '// &
1800  '1 and '//trim(cnum)//'.'
1801  call store_error(errmsg)
1802  cycle
1803  end if
1804 
1805  ! -- increment nboundchk
1806  ipos = iachk(n) + ival - 1
1807  nboundchk(ipos) = nboundchk(ipos) + 1
1808 
1809  idiv = ival
1810  !
1811  ! -- get target reach for diversion
1812  ival = this%parser%GetInteger()
1813  if (ival < 1 .or. ival > this%maxbound) then
1814  write (cnum, '(i0)') ival
1815  errmsg = 'Diversion target reach number should be '// &
1816  'between 1 and '//trim(cnum)//'.'
1817  call store_error(errmsg)
1818  cycle
1819  end if
1820  idivreach = ival
1821  jpos = this%iadiv(n) + idiv - 1
1822  this%divreach(jpos) = idivreach
1823  !
1824  ! -- get cprior
1825  call this%parser%GetStringCaps(cval)
1826  ival = -1
1827  select case (cval)
1828  case ('UPTO')
1829  ival = 0
1830  case ('THRESHOLD')
1831  ival = -1
1832  case ('FRACTION')
1833  ival = -2
1834  case ('EXCESS')
1835  ival = -3
1836  case default
1837  errmsg = 'Invalid cprior type '//trim(cval)//'.'
1838  call store_error(errmsg)
1839  end select
1840  !
1841  ! -- set cprior for diversion
1842  this%divcprior(jpos) = cval
1843  end do
1844 
1845  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))// &
1846  ' DIVERSIONS'
1847 
1848  do n = 1, this%maxbound
1849  do j = 1, this%ndiv(n)
1850  ipos = iachk(n) + j - 1
1851  !
1852  ! -- check for missing or duplicate reach diversions
1853  if (nboundchk(ipos) == 0) then
1854  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1855  'No data specified for reach', n, 'diversion', j
1856  call store_error(errmsg)
1857  else if (nboundchk(ipos) > 1) then
1858  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1859  'Data for reach', n, 'diversion', j, &
1860  'specified', nboundchk(ipos), 'times'
1861  call store_error(errmsg)
1862  end if
1863  end do
1864  end do
1865  !
1866  ! -- deallocate local variables
1867  deallocate (iachk)
1868  deallocate (nboundchk)
1869  else
1870  !
1871  ! -- error condition
1872  write (errmsg, '(a,1x,a)') &
1873  'A diversions block should not be', &
1874  'specified if diversions are not specified.'
1875  call store_error(errmsg)
1876  end if
1877  else
1878  if (this%idiversions /= 0) then
1879  call store_error('REQUIRED DIVERSIONS BLOCK NOT FOUND.')
1880  end if
1881  end if
1882  !
1883  ! -- write summary of diversion error messages
1884  if (count_errors() > 0) then
1885  call this%parser%StoreErrorUnit()
1886  end if
Here is the call graph for this function:

◆ sfr_read_initial_stages()

subroutine sfrmodule::sfr_read_initial_stages ( class(sfrtype), intent(inout)  this)

Method to read initialstages data for each reach for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 1893 of file gwf-sfr.f90.

1894  ! -- modules
1896  ! -- dummy
1897  class(SfrType), intent(inout) :: this !< SfrType object
1898  ! -- local
1899  integer(I4B) :: n
1900  integer(I4B) :: ierr
1901  logical(LGP) :: isfound
1902  logical(LGP) :: endOfBlock
1903  integer(I4B) :: i
1904  real(DP) :: rval
1905  integer, allocatable, dimension(:) :: nboundchk
1906  !
1907  ! -- read data
1908  call this%parser%GetBlock('INITIALSTAGES', isfound, ierr, &
1909  supportopenclose=.true., &
1910  blockrequired=.false.)
1911  !
1912  ! -- parse block if detected
1913  if (isfound) then
1914  write (this%iout, '(/1x,a)') &
1915  'PROCESSING '//trim(adjustl(this%text))//' INITIALSTAGES'
1916 
1917  allocate (nboundchk(this%maxbound))
1918  do n = 1, this%maxbound
1919  nboundchk(n) = 0
1920  end do
1921 
1922  do
1923  call this%parser%GetNextLine(endofblock)
1924  if (endofblock) exit
1925 
1926  ! -- read reach number
1927  n = this%parser%GetInteger()
1928 
1929  if (n < 1 .or. n > this%maxbound) then
1930  write (errmsg, '(a,i0,a,1x,i0,a)') &
1931  'Reach number (', n, ') must be greater than 0 and less &
1932  &than or equal to', this%maxbound, '.'
1933  call store_error(errmsg)
1934  cycle
1935  end if
1936 
1937  ! -- increment nboundchk
1938  nboundchk(n) = nboundchk(n) + 1
1939 
1940  rval = this%parser%GetDouble()
1941  this%stage(n) = rval
1942  this%depth(n) = rval - this%strtop(n)
1943 
1944  if (rval < this%strtop(n)) then
1945  write (errmsg, '(a,g0,a,1x,i0,1x,a,g0,a)') &
1946  'Initial stage (', rval, ') for reach', n, &
1947  'is less than the reach top (', this%strtop(n), ').'
1948  call store_error(errmsg)
1949  end if
1950  end do
1951 
1952  write (this%iout, '(1x,a)') &
1953  'END OF '//trim(adjustl(this%text))//' INITIALSTAGES'
1954 
1955  !
1956  ! -- Check to make sure that every reach is specified and that no reach
1957  ! is specified more than once.
1958  do i = 1, this%maxbound
1959  if (nboundchk(i) == 0) then
1960  write (errmsg, '(a,i0,1x,a)') &
1961  'Information for reach ', i, 'not specified in initialstages block.'
1962  call store_error(errmsg)
1963  else if (nboundchk(i) > 1) then
1964  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1965  'Initial stage information specified', &
1966  nboundchk(i), 'times for reach', i
1967  call store_error(errmsg)
1968  end if
1969  end do
1970  deallocate (nboundchk)
1971  else
1972  ! -- set default initial stage based on a zero depth
1973  if (this%istorage == 1) then
1974  do n = 1, this%maxbound
1975  rval = this%strtop(n)
1976  this%stage(n) = rval
1977  end do
1978  end if
1979  end if
1980  !
1981  ! -- terminate if errors encountered in reach block
1982  if (count_errors() > 0) then
1983  call this%parser%StoreErrorUnit()
1984  end if
subroutine, public read_value_or_time_series_adv(textInput, ii, jj, bndElem, pkgName, auxOrBnd, tsManager, iprpak, varName)
Call this subroutine from advanced packages to define timeseries link for a variable (varName).
Here is the call graph for this function:

◆ sfr_read_packagedata()

subroutine sfrmodule::sfr_read_packagedata ( class(sfrtype), intent(inout)  this)

Method to read packagedata for each reach for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 1029 of file gwf-sfr.f90.

1030  ! -- modules
1032  ! -- dummy
1033  class(SfrType), intent(inout) :: this !< SfrType object
1034  ! -- local
1035  character(len=LINELENGTH) :: text
1036  character(len=LINELENGTH) :: cellid
1037  character(len=10) :: cnum
1038  character(len=LENBOUNDNAME) :: bndName
1039  character(len=LENBOUNDNAME) :: bndNameTemp
1040  character(len=LENBOUNDNAME) :: hkname
1041  character(len=LENBOUNDNAME) :: manningname
1042  character(len=LENBOUNDNAME) :: ustrfname
1043  character(len=50), dimension(:), allocatable :: caux
1044  integer(I4B) :: n, ierr, ival
1045  logical(LGP) :: isfound
1046  logical(LGP) :: endOfBlock
1047  integer(I4B) :: i
1048  integer(I4B) :: ii
1049  integer(I4B) :: jj
1050  integer(I4B) :: iaux
1051  integer(I4B) :: nconzero
1052  integer(I4B) :: ipos
1053  integer, allocatable, dimension(:) :: nboundchk
1054  real(DP), pointer :: bndElem => null()
1055  !
1056  ! -- allocate space for checking sfr reach data
1057  allocate (nboundchk(this%maxbound))
1058  do i = 1, this%maxbound
1059  nboundchk(i) = 0
1060  end do
1061  nconzero = 0
1062  !
1063  ! -- allocate local storage for aux variables
1064  if (this%naux > 0) then
1065  allocate (caux(this%naux))
1066  end if
1067  !
1068  ! -- read reach data
1069  call this%parser%GetBlock('PACKAGEDATA', isfound, ierr, &
1070  supportopenclose=.true.)
1071  !
1072  ! -- parse reaches block if detected
1073  if (isfound) then
1074  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1075  ' PACKAGEDATA'
1076  do
1077  call this%parser%GetNextLine(endofblock)
1078  if (endofblock) exit
1079  ! -- read reach number
1080  n = this%parser%GetInteger()
1081 
1082  if (n < 1 .or. n > this%maxbound) then
1083  write (errmsg, '(a,1x,a,1x,i0)') &
1084  'Reach number (rno) must be greater than 0 and less', &
1085  'than or equal to', this%maxbound
1086  call store_error(errmsg)
1087  cycle
1088  end if
1089 
1090  ! -- increment nboundchk
1091  nboundchk(n) = nboundchk(n) + 1
1092  !
1093  ! -- get model node number
1094  call this%parser%GetCellid(this%dis%ndim, cellid, flag_string=.true.)
1095  this%igwfnode(n) = this%dis%noder_from_cellid(cellid, this%inunit, &
1096  this%iout, &
1097  flag_string=.true., &
1098  allow_zero=.true.)
1099  this%igwftopnode(n) = this%igwfnode(n)
1100  !
1101  ! -- read the cellid string and determine if 'none' is specified
1102  if (this%igwfnode(n) < 1) then
1103  this%ianynone = this%ianynone + 1
1104  call upcase(cellid)
1105  if (cellid == 'NONE') then
1106  call this%parser%GetStringCaps(cellid)
1107  !
1108  ! -- create warning message
1109  write (cnum, '(i0)') n
1110  warnmsg = 'CELLID for unconnected reach '//trim(cnum)// &
1111  ' specified to be NONE. Unconnected reaches '// &
1112  'should be specified with a zero for each grid '// &
1113  'dimension. For example, for a DIS grid a CELLID '// &
1114  'of 0 0 0 should be specified for unconnected reaches'
1115  !
1116  ! -- create deprecation warning
1117  call deprecation_warning('PACKAGEDATA', 'CELLID=NONE', '6.4.3', &
1118  warnmsg, this%parser%GetUnit())
1119  else
1120 
1121  end if
1122  end if
1123  ! -- get reach length
1124  this%length(n) = this%parser%GetDouble()
1125  ! -- get reach width
1126  this%width(n) = this%parser%GetDouble()
1127  ! -- get reach slope
1128  this%slope(n) = this%parser%GetDouble()
1129  ! -- get reach streambed top elevation
1130  this%strtop(n) = this%parser%GetDouble()
1131  ! -- get reach bed thickness
1132  this%bthick(n) = this%parser%GetDouble()
1133  ! -- get reach bed hk
1134  call this%parser%GetStringCaps(hkname)
1135  ! -- get reach roughness
1136  call this%parser%GetStringCaps(manningname)
1137  ! -- get number of connections for reach
1138  ival = this%parser%GetInteger()
1139  this%nconnreach(n) = ival
1140  this%nconn = this%nconn + ival
1141  if (ival < 0) then
1142  write (errmsg, '(a,1x,i0,1x,a,i0,a)') &
1143  'NCON for reach', n, &
1144  'must be greater than or equal to 0 (', ival, ').'
1145  call store_error(errmsg)
1146  else if (ival == 0) then
1147  nconzero = nconzero + 1
1148  end if
1149  ! -- get upstream fraction for reach
1150  call this%parser%GetString(ustrfname)
1151  ! -- get number of diversions for reach
1152  ival = this%parser%GetInteger()
1153  this%ndiv(n) = ival
1154  if (ival > 0) then
1155  this%idiversions = 1
1156  else if (ival < 0) then
1157  ival = 0
1158  end if
1159 
1160  ! -- get aux data
1161  do iaux = 1, this%naux
1162  call this%parser%GetString(caux(iaux))
1163  end do
1164 
1165  ! -- set default bndName
1166  write (cnum, '(i10.10)') n
1167  bndname = 'Reach'//cnum
1168 
1169  ! -- get reach name
1170  if (this%inamedbound /= 0) then
1171  call this%parser%GetStringCaps(bndnametemp)
1172  if (bndnametemp /= '') then
1173  bndname = bndnametemp
1174  end if
1175  !this%boundname(n) = bndName
1176  end if
1177  this%sfrname(n) = bndname
1178  !
1179  ! -- set reach hydraulic conductivity
1180  text = hkname
1181  jj = 1 !for 'BEDK'
1182  bndelem => this%hk(n)
1183  call read_value_or_time_series_adv(text, n, jj, bndelem, &
1184  this%packName, 'BND', &
1185  this%tsManager, this%iprpak, &
1186  'BEDK')
1187  !
1188  ! -- set Mannings
1189  text = manningname
1190  jj = 1 !for 'MANNING'
1191  bndelem => this%rough(n)
1192  call read_value_or_time_series_adv(text, n, jj, bndelem, &
1193  this%packName, 'BND', &
1194  this%tsManager, this%iprpak, &
1195  'MANNING')
1196  !
1197  ! -- set upstream fraction
1198  text = ustrfname
1199  jj = 1 ! For 'USTRF'
1200  bndelem => this%ustrf(n)
1201  call read_value_or_time_series_adv(text, n, jj, bndelem, &
1202  this%packName, 'BND', &
1203  this%tsManager, this%iprpak, 'USTRF')
1204  !
1205  ! -- get aux data
1206  do jj = 1, this%naux
1207  text = caux(jj)
1208  ii = n
1209  bndelem => this%rauxvar(jj, ii)
1210  call read_value_or_time_series_adv(text, ii, jj, bndelem, &
1211  this%packName, 'AUX', &
1212  this%tsManager, this%iprpak, &
1213  this%auxname(jj))
1214  end do
1215  !
1216  ! -- initialize sstage to the top of the reach
1217  ! this value would be used by simple routing reaches
1218  ! on kper = 1 and kstp = 1 if a stage is not specified
1219  ! on the status line for the reach
1220  this%sstage(n) = this%strtop(n)
1221 
1222  end do
1223  write (this%iout, '(1x,a)') &
1224  'END OF '//trim(adjustl(this%text))//' PACKAGEDATA'
1225  else
1226  call store_error('REQUIRED PACKAGEDATA BLOCK NOT FOUND.')
1227  end if
1228  !
1229  ! -- Check to make sure that every reach is specified and that no reach
1230  ! is specified more than once.
1231  do i = 1, this%maxbound
1232  if (nboundchk(i) == 0) then
1233  write (errmsg, '(a,i0,1x,a)') &
1234  'Information for reach ', i, 'not specified in packagedata block.'
1235  call store_error(errmsg)
1236  else if (nboundchk(i) > 1) then
1237  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1238  'Reach information specified', nboundchk(i), 'times for reach', i
1239  call store_error(errmsg)
1240  end if
1241  end do
1242  deallocate (nboundchk)
1243  !
1244  ! -- Submit warning message if any reach has zero connections
1245  if (nconzero > 0) then
1246  write (warnmsg, '(a,1x,a,1x,a,1x,i0,1x, a)') &
1247  'SFR Package', trim(this%packName), &
1248  'has', nconzero, 'reach(es) with zero connections.'
1249  call store_warning(warnmsg)
1250  end if
1251  !
1252  ! -- terminate if errors encountered in reach block
1253  if (count_errors() > 0) then
1254  call this%parser%StoreErrorUnit()
1255  end if
1256  !
1257  ! -- initialize the cross-section data
1258  ipos = 1
1259  this%iacross(1) = ipos
1260  do i = 1, this%maxbound
1261  this%ncrosspts(i) = 1
1262  this%station(ipos) = this%width(i)
1263  this%xsheight(ipos) = dzero
1264  this%xsrough(ipos) = done
1265  ipos = ipos + 1
1266  this%iacross(i + 1) = ipos
1267  end do
1268  !
1269  ! -- deallocate local storage for aux variables
1270  if (this%naux > 0) then
1271  deallocate (caux)
1272  end if
Here is the call graph for this function:

◆ sfr_rp()

subroutine sfrmodule::sfr_rp ( class(sfrtype), intent(inout)  this)

Method to read and prepare period data for the SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 1991 of file gwf-sfr.f90.

1992  ! -- modules
1993  use tdismodule, only: kper, nper
1996  ! -- dummy
1997  class(SfrType), intent(inout) :: this !< SfrType object
1998  ! -- local
1999  character(len=LINELENGTH) :: title
2000  character(len=LINELENGTH) :: line
2001  character(len=LINELENGTH) :: crossfile
2002  integer(I4B) :: ierr
2003  integer(I4B) :: n
2004  integer(I4B) :: ichkustrm
2005  integer(I4B) :: ichkcross
2006  integer(I4B) :: ncrossptstot
2007  logical(LGP) :: isfound
2008  logical(LGP) :: endOfBlock
2009  type(SfrCrossSection), pointer :: cross_data => null()
2010  ! -- formats
2011  character(len=*), parameter :: fmtblkerr = &
2012  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
2013  character(len=*), parameter :: fmtlsp = &
2014  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
2015  character(len=*), parameter :: fmtnbd = &
2016  "(1X,/1X,'The number of active ',A,'S (',I6, &
2017  &') is greater than maximum (',I6,')')"
2018  !
2019  ! -- initialize flags
2020  ichkustrm = 0
2021  ichkcross = 0
2022  if (kper == 1) then
2023  ichkustrm = 1
2024  end if
2025  !
2026  ! -- set nbound to maxbound
2027  this%nbound = this%maxbound
2028  !
2029  ! -- Set ionper to the stress period number for which a new block of data
2030  ! will be read.
2031  if (this%ionper < kper) then
2032  !
2033  ! -- get period block
2034  call this%parser%GetBlock('PERIOD', isfound, ierr, &
2035  supportopenclose=.true., &
2036  blockrequired=.false.)
2037  if (isfound) then
2038  !
2039  ! -- read ionper and check for increasing period numbers
2040  call this%read_check_ionper()
2041  else
2042  !
2043  ! -- PERIOD block not found
2044  if (ierr < 0) then
2045  ! -- End of file found; data applies for remainder of simulation.
2046  this%ionper = nper + 1
2047  else
2048  ! -- Found invalid block
2049  call this%parser%GetCurrentLine(line)
2050  write (errmsg, fmtblkerr) adjustl(trim(line))
2051  call store_error(errmsg)
2052  call this%parser%StoreErrorUnit()
2053  end if
2054  end if
2055  end if
2056  !
2057  ! -- Read data if ionper == kper
2058  if (this%ionper == kper) then
2059  !
2060  ! -- create and initialize cross-section data
2061  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
2062  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
2063  this%iacross, &
2064  this%station, this%xsheight, &
2065  this%xsrough)
2066  !
2067  ! -- setup table for period data
2068  if (this%iprpak /= 0) then
2069  !
2070  ! -- reset the input table object
2071  title = trim(adjustl(this%text))//' PACKAGE ('// &
2072  trim(adjustl(this%packName))//') DATA FOR PERIOD'
2073  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
2074  call table_cr(this%inputtab, this%packName, title)
2075  call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
2076  text = 'NUMBER'
2077  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
2078  text = 'KEYWORD'
2079  call this%inputtab%initialize_column(text, 20, alignment=tableft)
2080  do n = 1, 2
2081  write (text, '(a,1x,i6)') 'VALUE', n
2082  call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
2083  end do
2084  end if
2085  !
2086  ! -- read data
2087  do
2088  call this%parser%GetNextLine(endofblock)
2089  if (endofblock) exit
2090  n = this%parser%GetInteger()
2091  if (n < 1 .or. n > this%maxbound) then
2092  write (errmsg, '(a,1x,a,1x,i0,a)') &
2093  'Reach number (RNO) must be greater than 0 and', &
2094  'less than or equal to', this%maxbound, '.'
2095  call store_error(errmsg)
2096  cycle
2097  end if
2098  !
2099  ! -- read data from the rest of the line
2100  call this%sfr_set_stressperiod(n, ichkustrm, crossfile)
2101  !
2102  ! -- write line to table
2103  if (this%iprpak /= 0) then
2104  call this%parser%GetCurrentLine(line)
2105  call this%inputtab%line_to_columns(line)
2106  end if
2107  !
2108  ! -- process cross-section file
2109  if (trim(adjustl(crossfile)) /= 'NONE') then
2110  call cross_data%read_table(n, this%width(n), &
2111  trim(adjustl(crossfile)))
2112  end if
2113  end do
2114  !
2115  ! -- write raw period data
2116  if (this%iprpak /= 0) then
2117  call this%inputtab%finalize_table()
2118  end if
2119  !
2120  ! -- finalize cross-sections
2121 
2122  !
2123  ! -- determine the current size of cross-section data
2124  ncrossptstot = cross_data%get_ncrossptstot()
2125  !
2126  ! -- reallocate sfr package cross-section data
2127  if (ncrossptstot /= this%ncrossptstot) then
2128  this%ncrossptstot = ncrossptstot
2129  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
2130  this%memoryPath)
2131  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
2132  this%memoryPath)
2133  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
2134  this%memoryPath)
2135  end if
2136  !
2137  ! -- write cross-section data to the model listing file
2138  call cross_data%output(this%width, this%rough, kstp=1, kper=kper)
2139  !
2140  ! -- pack cross-section data
2141  call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
2142  this%iacross, &
2143  this%station, &
2144  this%xsheight, &
2145  this%xsrough)
2146  !
2147  ! -- deallocate temporary local storage for reach cross-sections
2148  call cross_data%destroy()
2149  deallocate (cross_data)
2150  nullify (cross_data)
2151  !
2152  ! -- Reuse data from last stress period
2153  else
2154  write (this%iout, fmtlsp) trim(this%filtyp)
2155  end if
2156  !
2157  ! -- check upstream fraction values
2158  if (ichkustrm /= 0) then
2159  call this%sfr_check_ustrf()
2160  end if
2161  !
2162  ! -- write summary of package block error messages
2163  if (count_errors() > 0) then
2164  call this%parser%StoreErrorUnit()
2165  end if
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:24
Here is the call graph for this function:

◆ sfr_rp_obs()

subroutine sfrmodule::sfr_rp_obs ( class(sfrtype), intent(inout)  this)
private

Method to read and prepare observations for a SFR package.

Parameters
[in,out]thisSfrType object

Definition at line 3392 of file gwf-sfr.f90.

3393  ! -- modules
3394  use tdismodule, only: kper
3395  ! -- dummy
3396  class(SfrType), intent(inout) :: this !< SfrType object
3397  ! -- local
3398  integer(I4B) :: i
3399  integer(I4B) :: j
3400  integer(I4B) :: nn1
3401  character(len=LENBOUNDNAME) :: bname
3402  logical(LGP) :: jfound
3403  class(ObserveType), pointer :: obsrv => null()
3404  ! -- formats
3405 10 format('Boundary "', a, '" for observation "', a, &
3406  '" is invalid in package "', a, '"')
3407 30 format('Boundary name not provided for observation "', a, &
3408  '" in package "', a, '"')
3409  !
3410  ! -- process each package observation
3411  ! only done the first stress period since boundaries are fixed
3412  ! for the simulation
3413  if (kper == 1) then
3414  do i = 1, this%obs%npakobs
3415  obsrv => this%obs%pakobs(i)%obsrv
3416  !
3417  ! -- get node number 1
3418  nn1 = obsrv%NodeNumber
3419  if (nn1 == namedboundflag) then
3420  bname = obsrv%FeatureName
3421  if (bname /= '') then
3422  ! -- Observation location(s) is(are) based on a boundary name.
3423  ! Iterate through all boundaries to identify and store
3424  ! corresponding index(indices) in bound array.
3425  jfound = .false.
3426  do j = 1, this%maxbound
3427  if (this%boundname(j) == bname) then
3428  jfound = .true.
3429  call obsrv%AddObsIndex(j)
3430  end if
3431  end do
3432  if (.not. jfound) then
3433  write (errmsg, 10) &
3434  trim(bname), trim(obsrv%name), trim(this%packName)
3435  call store_error(errmsg)
3436  end if
3437  else
3438  write (errmsg, 30) trim(obsrv%name), trim(this%packName)
3439  call store_error(errmsg)
3440  end if
3441  else if (nn1 < 1 .or. nn1 > this%maxbound) then
3442  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3443  trim(adjustl(obsrv%ObsTypeId)), &
3444  'reach must be greater than 0 and less than or equal to', &
3445  this%maxbound, '(specified value is ', nn1, ')'
3446  call store_error(errmsg)
3447  else
3448  if (obsrv%indxbnds_count == 0) then
3449  call obsrv%AddObsIndex(nn1)
3450  else
3451  errmsg = 'Programming error in sfr_rp_obs'
3452  call store_error(errmsg)
3453  end if
3454  end if
3455  !
3456  ! -- catch non-cumulative observation assigned to observation defined
3457  ! by a boundname that is assigned to more than one element
3458  if (obsrv%ObsTypeId == 'STAGE' .or. &
3459  obsrv%ObsTypeId == 'DEPTH' .or. &
3460  obsrv%ObsTypeId == 'WET-PERIMETER' .or. &
3461  obsrv%ObsTypeId == 'WET-AREA' .or. &
3462  obsrv%ObsTypeId == 'WET-WIDTH') then
3463  nn1 = obsrv%NodeNumber
3464  if (nn1 == namedboundflag) then
3465  if (obsrv%indxbnds_count > 1) then
3466  write (errmsg, '(a,3(1x,a))') &
3467  trim(adjustl(obsrv%ObsTypeId)), &
3468  'for observation', trim(adjustl(obsrv%Name)), &
3469  ' must be assigned to a reach with a unique boundname.'
3470  call store_error(errmsg)
3471  end if
3472  end if
3473  end if
3474  !
3475  ! -- check that node number 1 is valid; call store_error if not
3476  do j = 1, obsrv%indxbnds_count
3477  nn1 = obsrv%indxbnds(j)
3478  if (nn1 < 1 .or. nn1 > this%maxbound) then
3479  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3480  trim(adjustl(obsrv%ObsTypeId)), &
3481  'reach must be greater than 0 and less than or equal to', &
3482  this%maxbound, '(specified value is ', nn1, ')'
3483  call store_error(errmsg)
3484  end if
3485  end do
3486  end do
3487  !
3488  ! -- evaluate if there are any observation errors
3489  if (count_errors() > 0) then
3490  call this%parser%StoreErrorUnit()
3491  end if
3492  end if
Here is the call graph for this function:

◆ sfr_set_stressperiod()

subroutine sfrmodule::sfr_set_stressperiod ( class(sfrtype), intent(inout)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(inout)  ichkustrm,
character(len=linelength), intent(inout)  crossfile 
)
private

Method to read and set period data for a SFR package reach.

Parameters
[in,out]thisSfrType object
[in]nreach number
[in,out]ichkustrmflag indicating if upstream fraction data specified
[in,out]crossfilecross-section file name

Definition at line 3542 of file gwf-sfr.f90.

3543  ! -- modules
3545  ! -- dummy
3546  class(SfrType), intent(inout) :: this !< SfrType object
3547  integer(I4B), intent(in) :: n !< reach number
3548  integer(I4B), intent(inout) :: ichkustrm !< flag indicating if upstream fraction data specified
3549  character(len=LINELENGTH), intent(inout) :: crossfile !< cross-section file name
3550  ! -- local
3551  character(len=10) :: cnum
3552  character(len=LINELENGTH) :: text
3553  character(len=LINELENGTH) :: caux
3554  character(len=LINELENGTH) :: keyword
3555  integer(I4B) :: ival
3556  integer(I4B) :: ii
3557  integer(I4B) :: jj
3558  integer(I4B) :: idiv
3559  integer(I4B) :: ixserror
3560  character(len=10) :: cp
3561  real(DP) :: divq
3562  real(DP), pointer :: bndElem => null()
3563  !
3564  ! -- initialize variables
3565  crossfile = 'NONE'
3566  !
3567  ! -- read line
3568  call this%parser%GetStringCaps(keyword)
3569  select case (keyword)
3570  case ('STATUS')
3571  ichkustrm = 1
3572  call this%parser%GetStringCaps(text)
3573  if (text == 'INACTIVE') then
3574  this%iboundpak(n) = 0
3575  else if (text == 'ACTIVE') then
3576  this%iboundpak(n) = 1
3577  else if (text == 'SIMPLE') then
3578  this%iboundpak(n) = -1
3579  else
3580  write (errmsg, '(2a)') &
3581  'Unknown '//trim(this%text)//' sfr status keyword: ', trim(text)
3582  call store_error(errmsg)
3583  end if
3584  case ('BEDK')
3585  call this%parser%GetString(text)
3586  jj = 1 ! For 'BEDK'
3587  bndelem => this%hk(n)
3588  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3589  this%packName, 'BND', &
3590  this%tsManager, this%iprpak, &
3591  'BEDK')
3592  case ('MANNING')
3593  call this%parser%GetString(text)
3594  jj = 1 ! For 'MANNING'
3595  bndelem => this%rough(n)
3596  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3597  this%packName, 'BND', &
3598  this%tsManager, this%iprpak, &
3599  'MANNING')
3600  case ('STAGE')
3601  call this%parser%GetString(text)
3602  jj = 1 ! For 'STAGE'
3603  bndelem => this%sstage(n)
3604  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3605  this%packName, 'BND', &
3606  this%tsManager, this%iprpak, 'STAGE')
3607  case ('RAINFALL')
3608  call this%parser%GetString(text)
3609  jj = 1 ! For 'RAIN'
3610  bndelem => this%rain(n)
3611  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3612  this%packName, 'BND', &
3613  this%tsManager, this%iprpak, 'RAIN')
3614  case ('EVAPORATION')
3615  call this%parser%GetString(text)
3616  jj = 1 ! For 'EVAP'
3617  bndelem => this%evap(n)
3618  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3619  this%packName, 'BND', &
3620  this%tsManager, this%iprpak, &
3621  'EVAP')
3622  case ('RUNOFF')
3623  call this%parser%GetString(text)
3624  jj = 1 ! For 'RUNOFF'
3625  bndelem => this%runoff(n)
3626  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3627  this%packName, 'BND', &
3628  this%tsManager, this%iprpak, &
3629  'RUNOFF')
3630  case ('INFLOW')
3631  call this%parser%GetString(text)
3632  jj = 1 ! For 'INFLOW'
3633  bndelem => this%inflow(n)
3634  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3635  this%packName, 'BND', &
3636  this%tsManager, this%iprpak, &
3637  'INFLOW')
3638  case ('DIVERSION')
3639  !
3640  ! -- make sure reach has at least one diversion
3641  if (this%ndiv(n) < 1) then
3642  write (cnum, '(i0)') n
3643  errmsg = 'diversions cannot be specified for reach '//trim(cnum)
3644  call store_error(errmsg)
3645  end if
3646  !
3647  ! -- read diversion number
3648  ival = this%parser%GetInteger()
3649  if (ival < 1 .or. ival > this%ndiv(n)) then
3650  write (cnum, '(i0)') n
3651  errmsg = 'Reach '//trim(cnum)
3652  write (cnum, '(i0)') this%ndiv(n)
3653  errmsg = trim(errmsg)//' diversion number should be between 1 '// &
3654  'and '//trim(cnum)//'.'
3655  call store_error(errmsg)
3656  end if
3657  idiv = ival
3658  !
3659  ! -- read value
3660  call this%parser%GetString(text)
3661  ii = this%iadiv(n) + idiv - 1
3662  jj = 1 ! For 'DIVERSION'
3663  bndelem => this%divflow(ii)
3664  call read_value_or_time_series_adv(text, ii, jj, bndelem, &
3665  this%packName, 'BND', &
3666  this%tsManager, this%iprpak, &
3667  'DIVFLOW')
3668  !
3669  ! -- if diversion cprior is 'fraction', ensure that 0.0 <= fraction <= 1.0
3670  cp = this%divcprior(ii)
3671  divq = this%divflow(ii)
3672  if (cp == 'FRACTION' .and. (divq < dzero .or. divq > done)) then
3673  write (errmsg, '(a,1x,i0,a)') &
3674  'cprior is type FRACTION for diversion no.', ii, &
3675  ', but divflow not within the range 0.0 to 1.0'
3676  call store_error(errmsg)
3677  end if
3678  case ('UPSTREAM_FRACTION')
3679  ichkustrm = 1
3680  call this%parser%GetString(text)
3681  jj = 1 ! For 'USTRF'
3682  bndelem => this%ustrf(n)
3683  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3684  this%packName, 'BND', &
3685  this%tsManager, this%iprpak, 'USTRF')
3686 
3687  case ('CROSS_SECTION')
3688  ixserror = 0
3689  !
3690  ! -- read FILE keyword
3691  call this%parser%GetStringCaps(keyword)
3692  select case (keyword)
3693  case ('TAB6')
3694  call this%parser%GetStringCaps(keyword)
3695  if (trim(adjustl(keyword)) /= 'FILEIN') then
3696  errmsg = 'TAB6 keyword must be followed by "FILEIN" '// &
3697  'then by filename.'
3698  call store_error(errmsg)
3699  ixserror = 1
3700  end if
3701  if (ixserror == 0) then
3702  call this%parser%GetString(crossfile)
3703  end if
3704  case default
3705  write (errmsg, '(a,1x,i4,1x,a)') &
3706  'CROSS-SECTION TABLE ENTRY for REACH ', n, &
3707  'MUST INCLUDE TAB6 KEYWORD'
3708  call store_error(errmsg)
3709  end select
3710 
3711  case ('AUXILIARY')
3712  call this%parser%GetStringCaps(caux)
3713  do jj = 1, this%naux
3714  if (trim(adjustl(caux)) /= trim(adjustl(this%auxname(jj)))) cycle
3715  call this%parser%GetString(text)
3716  ii = n
3717  bndelem => this%rauxvar(jj, ii)
3718  call read_value_or_time_series_adv(text, ii, jj, bndelem, &
3719  this%packName, 'AUX', &
3720  this%tsManager, this%iprpak, &
3721  this%auxname(jj))
3722  exit
3723  end do
3724 
3725  case default
3726  write (errmsg, '(a,a)') &
3727  'Unknown '//trim(this%text)//' sfr data keyword: ', &
3728  trim(keyword)//'.'
3729  call store_error(errmsg)
3730  end select
Here is the call graph for this function:

◆ sfr_setup_budobj()

subroutine sfrmodule::sfr_setup_budobj ( class(sfrtype this)
private

Method to set up the budget object that stores all the sfr flows The terms listed here must correspond in number and order to the ones listed in the sfr_fill_budobj method.

Parameters
thisSfrType object

Definition at line 5274 of file gwf-sfr.f90.

5275  ! -- dummy
5276  class(SfrType) :: this !< SfrType object
5277  ! -- local
5278  integer(I4B) :: nbudterm
5279  integer(I4B) :: i
5280  integer(I4B) :: n
5281  integer(I4B) :: n1
5282  integer(I4B) :: n2
5283  integer(I4B) :: maxlist
5284  integer(I4B) :: naux
5285  integer(I4B) :: idx
5286  real(DP) :: q
5287  character(len=LENBUDTXT) :: text
5288  character(len=LENBUDTXT), dimension(1) :: auxtxt
5289  !
5290  ! -- Determine the number of sfr budget terms. These are fixed for
5291  ! the simulation and cannot change. This includes FLOW-JA-FACE
5292  ! so they can be written to the binary budget files, but these internal
5293  ! flows are not included as part of the budget table.
5294  nbudterm = 8
5295  if (this%imover == 1) nbudterm = nbudterm + 2
5296  if (this%naux > 0) nbudterm = nbudterm + 1
5297  !
5298  ! -- set up budobj
5299  call budgetobject_cr(this%budobj, this%packName)
5300  call this%budobj%budgetobject_df(this%maxbound, nbudterm, 0, 0, &
5301  ibudcsv=this%ibudcsv)
5302  idx = 0
5303  !
5304  ! -- Go through and set up each budget term
5305  text = ' FLOW-JA-FACE'
5306  idx = idx + 1
5307  maxlist = this%nconn
5308  naux = 1
5309  auxtxt(1) = ' FLOW-AREA'
5310  call this%budobj%budterm(idx)%initialize(text, &
5311  this%name_model, &
5312  this%packName, &
5313  this%name_model, &
5314  this%packName, &
5315  maxlist, .false., .false., &
5316  naux, auxtxt)
5317  !
5318  ! -- store connectivity
5319  call this%budobj%budterm(idx)%reset(this%nconn)
5320  q = dzero
5321  do n = 1, this%maxbound
5322  n1 = n
5323  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5324  n2 = this%ja(i)
5325  call this%budobj%budterm(idx)%update_term(n1, n2, q)
5326  end do
5327  end do
5328  !
5329  ! --
5330  text = ' GWF'
5331  idx = idx + 1
5332  maxlist = this%maxbound - this%ianynone
5333  naux = 1
5334  auxtxt(1) = ' FLOW-AREA'
5335  call this%budobj%budterm(idx)%initialize(text, &
5336  this%name_model, &
5337  this%packName, &
5338  this%name_model, &
5339  this%name_model, &
5340  maxlist, .false., .true., &
5341  naux, auxtxt)
5342  call this%budobj%budterm(idx)%reset(maxlist)
5343  q = dzero
5344  do n = 1, this%maxbound
5345  n2 = this%igwfnode(n)
5346  if (n2 > 0) then
5347  call this%budobj%budterm(idx)%update_term(n, n2, q)
5348  end if
5349  end do
5350  !
5351  ! --
5352  text = ' RAINFALL'
5353  idx = idx + 1
5354  maxlist = this%maxbound
5355  naux = 0
5356  call this%budobj%budterm(idx)%initialize(text, &
5357  this%name_model, &
5358  this%packName, &
5359  this%name_model, &
5360  this%packName, &
5361  maxlist, .false., .false., &
5362  naux)
5363  !
5364  ! --
5365  text = ' EVAPORATION'
5366  idx = idx + 1
5367  maxlist = this%maxbound
5368  naux = 0
5369  call this%budobj%budterm(idx)%initialize(text, &
5370  this%name_model, &
5371  this%packName, &
5372  this%name_model, &
5373  this%packName, &
5374  maxlist, .false., .false., &
5375  naux)
5376  !
5377  ! --
5378  text = ' RUNOFF'
5379  idx = idx + 1
5380  maxlist = this%maxbound
5381  naux = 0
5382  call this%budobj%budterm(idx)%initialize(text, &
5383  this%name_model, &
5384  this%packName, &
5385  this%name_model, &
5386  this%packName, &
5387  maxlist, .false., .false., &
5388  naux)
5389  !
5390  ! --
5391  text = ' EXT-INFLOW'
5392  idx = idx + 1
5393  maxlist = this%maxbound
5394  naux = 0
5395  call this%budobj%budterm(idx)%initialize(text, &
5396  this%name_model, &
5397  this%packName, &
5398  this%name_model, &
5399  this%packName, &
5400  maxlist, .false., .false., &
5401  naux)
5402  !
5403  ! --
5404  text = ' EXT-OUTFLOW'
5405  idx = idx + 1
5406  maxlist = this%maxbound
5407  naux = 0
5408  call this%budobj%budterm(idx)%initialize(text, &
5409  this%name_model, &
5410  this%packName, &
5411  this%name_model, &
5412  this%packName, &
5413  maxlist, .false., .false., &
5414  naux)
5415  !
5416  ! --
5417  text = ' STORAGE'
5418  idx = idx + 1
5419  maxlist = this%maxbound
5420  naux = 1
5421  auxtxt(1) = ' VOLUME'
5422  call this%budobj%budterm(idx)%initialize(text, &
5423  this%name_model, &
5424  this%packName, &
5425  this%name_model, &
5426  this%packName, &
5427  maxlist, .false., .false., &
5428  naux, auxtxt)
5429  !
5430  ! --
5431  if (this%imover == 1) then
5432  !
5433  ! --
5434  text = ' FROM-MVR'
5435  idx = idx + 1
5436  maxlist = this%maxbound
5437  naux = 0
5438  call this%budobj%budterm(idx)%initialize(text, &
5439  this%name_model, &
5440  this%packName, &
5441  this%name_model, &
5442  this%packName, &
5443  maxlist, .false., .false., &
5444  naux)
5445  !
5446  ! --
5447  text = ' TO-MVR'
5448  idx = idx + 1
5449  maxlist = this%maxbound
5450  naux = 0
5451  call this%budobj%budterm(idx)%initialize(text, &
5452  this%name_model, &
5453  this%packName, &
5454  this%name_model, &
5455  this%packName, &
5456  maxlist, .false., .false., &
5457  naux)
5458  end if
5459  !
5460  ! --
5461  naux = this%naux
5462  if (naux > 0) then
5463  !
5464  ! --
5465  text = ' AUXILIARY'
5466  idx = idx + 1
5467  maxlist = this%maxbound
5468  call this%budobj%budterm(idx)%initialize(text, &
5469  this%name_model, &
5470  this%packName, &
5471  this%name_model, &
5472  this%packName, &
5473  maxlist, .false., .false., &
5474  naux, this%auxname)
5475  end if
5476  !
5477  ! -- if sfr flow for each reach are written to the listing file
5478  if (this%iprflow /= 0) then
5479  call this%budobj%flowtable_df(this%iout, cellids='GWF')
5480  end if
Here is the call graph for this function:

◆ sfr_setup_tableobj()

subroutine sfrmodule::sfr_setup_tableobj ( class(sfrtype this)
private

Method to set up the table object that is used to write the sfr stage data. The terms listed here must correspond in number and order to the ones written to the stage table in the sfr_ot method.

Parameters
thisSfrType object

Definition at line 5721 of file gwf-sfr.f90.

5722  ! -- dummy
5723  class(SfrType) :: this !< SfrType object
5724  ! -- local
5725  integer(I4B) :: nterms
5726  character(len=LINELENGTH) :: title
5727  character(len=LINELENGTH) :: text
5728  !
5729  ! -- setup stage table
5730  if (this%iprhed > 0) then
5731  !
5732  ! -- Determine the number of sfr budget terms. These are fixed for
5733  ! the simulation and cannot change. This includes FLOW-JA-FACE
5734  ! so they can be written to the binary budget files, but these internal
5735  ! flows are not included as part of the budget table.
5736  nterms = 8
5737  if (this%inamedbound == 1) then
5738  nterms = nterms + 1
5739  end if
5740  !
5741  ! -- set up table title
5742  title = trim(adjustl(this%text))//' PACKAGE ('// &
5743  trim(adjustl(this%packName))//') STAGES FOR EACH CONTROL VOLUME'
5744  !
5745  ! -- set up stage tableobj
5746  call table_cr(this%stagetab, this%packName, title)
5747  call this%stagetab%table_df(this%maxbound, nterms, this%iout, &
5748  transient=.true.)
5749  !
5750  ! -- Go through and set up table budget term
5751  if (this%inamedbound == 1) then
5752  text = 'NAME'
5753  call this%stagetab%initialize_column(text, lenboundname, &
5754  alignment=tableft)
5755  end if
5756  !
5757  ! -- reach number
5758  text = 'NUMBER'
5759  call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
5760  !
5761  ! -- cellids
5762  text = 'CELLID'
5763  call this%stagetab%initialize_column(text, 20, alignment=tableft)
5764  !
5765  ! -- reach stage
5766  text = 'STAGE'
5767  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5768  !
5769  ! -- reach depth
5770  text = 'DEPTH'
5771  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5772  !
5773  ! -- reach width
5774  text = 'WIDTH'
5775  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5776  !
5777  ! -- gwf head
5778  text = 'GWF HEAD'
5779  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5780  !
5781  ! -- streambed conductance
5782  text = 'STREAMBED CONDUCTANCE'
5783  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5784  !
5785  ! -- streambed gradient
5786  text = 'STREAMBED GRADIENT'
5787  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5788  end if
5789  !
5790  ! -- setup Courant number table
5791  if (this%istorage == 1) then
5792  nterms = 4
5793  if (this%inamedbound == 1) then
5794  nterms = nterms + 1
5795  end if
5796  !
5797  ! -- set up table title
5798  title = trim(adjustl(this%text))//' PACKAGE ('// &
5799  trim(adjustl(this%packName))//') COURANT NUMBER FOR EACH REACH'
5800  !
5801  ! -- set up Courant tableobj
5802  call table_cr(this%couranttab, this%packName, title)
5803  call this%couranttab%table_df(this%maxbound, nterms, this%iout)
5804  !
5805  if (this%inamedbound == 1) then
5806  text = 'NAME'
5807  call this%couranttab%initialize_column(text, lenboundname, &
5808  alignment=tableft)
5809  end if
5810  !
5811  ! -- reach number
5812  text = 'NUMBER'
5813  call this%couranttab%initialize_column(text, 10, alignment=tabcenter)
5814  !
5815  ! -- minimum Courant number
5816  text = 'MINIMUM'
5817  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5818  !
5819  ! -- maximum Courant number
5820  text = 'MAXIMUM'
5821  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5822  !
5823  ! -- mean Courant number
5824  text = 'MEAN'
5825  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5826  end if
Here is the call graph for this function:

◆ sfr_solve()

subroutine sfrmodule::sfr_solve ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  h,
real(dp), intent(inout)  hcof,
real(dp), intent(inout)  rhs,
logical(lgp), intent(in), optional  update 
)

Method to solve the continuity equation for a SFR package reach.

Parameters
thisSfrType object
[in]nreach number
[in]hgroundwater head in cell connected to reach
[in,out]hcofcoefficient term added to the diagonal
[in,out]rhsright-hand side term
[in]updateboolean indicating if the reach depth and stage variables should be updated to current iterate

Definition at line 3737 of file gwf-sfr.f90.

3738  ! -- dummy
3739  class(SfrType) :: this !< SfrType object
3740  integer(I4B), intent(in) :: n !< reach number
3741  real(DP), intent(in) :: h !< groundwater head in cell connected to reach
3742  real(DP), intent(inout) :: hcof !< coefficient term added to the diagonal
3743  real(DP), intent(inout) :: rhs !< right-hand side term
3744  logical(LGP), intent(in), optional :: update !< boolean indicating if the reach depth and stage variables should be updated to current iterate
3745  ! -- local
3746  logical(LGP) :: lupdate
3747  integer(I4B) :: i
3748  integer(I4B) :: ii
3749  integer(I4B) :: n2
3750  real(DP) :: hgwf
3751  real(DP) :: sa
3752  real(DP) :: sa_wet
3753  real(DP) :: qu
3754  real(DP) :: qi
3755  real(DP) :: qr
3756  real(DP) :: qe
3757  real(DP) :: qro
3758  real(DP) :: qsrc
3759  real(DP) :: qfrommvr
3760  real(DP) :: qgwf
3761  real(DP) :: tp
3762  real(DP) :: bt
3763  real(DP) :: hsfr
3764  real(DP) :: qd
3765  real(DP) :: d1
3766  real(DP) :: sumleak
3767  real(DP) :: sumrch
3768  real(DP) :: gwfhcof
3769  real(DP) :: gwfrhs
3770  !
3771  ! -- Process optional dummy variables
3772  if (present(update)) then
3773  lupdate = update
3774  else
3775  lupdate = .true.
3776  end if
3777 
3778  ! -- initialize variables
3779  hcof = dzero
3780  rhs = dzero
3781  !
3782  if (this%iboundpak(n) == 0) then
3783  this%depth(n) = dzero
3784  this%stage(n) = dhnoflo
3785  this%usflow(n) = dzero
3786  this%simevap(n) = dzero
3787  this%simrunoff(n) = dzero
3788  this%dsflow(n) = dzero
3789  this%gwflow(n) = dzero
3790  else
3791  hgwf = h
3792  d1 = dzero
3793  qsrc = dzero
3794  qgwf = dzero
3795  qd = this%dsflow(n)
3796 
3797  ! -- calculate initial depth assuming a wide cross-section and
3798  ! ignore groundwater leakage
3799  ! -- calculate upstream flow
3800  qu = dzero
3801  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3802  if (this%idir(i) < 0) cycle
3803  n2 = this%ja(i)
3804  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
3805  if (this%idir(ii) > 0) cycle
3806  if (this%ja(ii) /= n) cycle
3807  qu = qu + this%qconn(ii)
3808  end do
3809  end do
3810  this%usflow(n) = qu
3811 
3812  ! -- calculate remaining terms
3813  sa = this%calc_surface_area(n)
3814  sa_wet = this%calc_surface_area_wet(n, this%depth(n))
3815  qi = this%inflow(n)
3816  qr = this%rain(n) * sa
3817  qe = this%evap(n) * sa_wet
3818  qro = this%runoff(n)
3819 
3820  ! -- Water mover term; assume that it goes in at the upstream end of the reach
3821  qfrommvr = dzero
3822  if (this%imover == 1) then
3823  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3824  end if
3825 
3826  ! -- calculate downstream flow ignoring groundwater leakage
3827  qsrc = qu + qi + qr - qe + qro + qfrommvr
3828 
3829  ! -- adjust runoff or evaporation if sum of sources is negative
3830  call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)
3831 
3832  ! -- set simulated evaporation and runoff
3833  this%simevap(n) = qe
3834  this%simrunoff(n) = qro
3835 
3836  ! -- calculate reach flow using appropriate method
3837  if (this%iboundpak(n) < 0) then
3838  call this%sfr_calc_constant(n, d1, hgwf, qgwf, qd)
3839  else
3840  if (this%gwfiss == 0 .and. this%istorage == 1) then
3841  if (this%ats_courant /= dnodata) then
3842  call this%sfr_calc_tvd(n, d1, hgwf, qu, qi, &
3843  qfrommvr, qr, qe, qro, &
3844  qgwf, qd)
3845  else
3846  call this%sfr_calc_transient(n, d1, hgwf, qu, qi, &
3847  qfrommvr, qr, qe, qro, &
3848  qgwf, qd)
3849  end if
3850  else
3851  call this%sfr_calc_steady(n, d1, hgwf, qu, qi, &
3852  qfrommvr, qr, qe, qro, &
3853  qgwf, qd)
3854  end if
3855  end if
3856 
3857  ! -- update sfr stage
3858  tp = this%strtop(n)
3859  bt = tp - this%bthick(n)
3860  hsfr = tp + d1
3861 
3862  ! -- update stored values
3863  if (lupdate) then
3864  ! -- save depth and calculate stage
3865  this%depth(n) = d1
3866  this%stage(n) = hsfr
3867  ! -- update flows
3868  call this%sfr_update_flows(n, qd, qgwf)
3869  end if
3870 
3871  ! -- calculate sumleak and sumrch
3872  sumleak = dzero
3873  sumrch = dzero
3874  if (this%gwfiss == 0) then
3875  sumleak = qgwf
3876  else
3877  sumleak = qgwf
3878  end if
3879  if (hgwf < bt) then
3880  sumrch = qgwf
3881  end if
3882 
3883  ! -- make final qgwf calculation and obtain
3884  ! gwfhcof and gwfrhs values
3885  call this%sfr_calc_qgwf(n, d1, hgwf, qgwf, gwfhcof, gwfrhs)
3886 
3887  ! -- update hcof and rhs terms
3888  if (abs(sumleak) > dzero) then
3889  ! -- stream leakage is not head dependent
3890  if (hgwf < bt) then
3891  rhs = rhs - sumrch
3892  ! -- stream leakage is head dependent
3893  else if ((sumleak - qsrc) < -dem30) then
3894  if (this%gwfiss == 0) then
3895  rhs = rhs + gwfrhs - sumrch
3896  else
3897  rhs = rhs + gwfrhs
3898  end if
3899  hcof = gwfhcof
3900  ! -- place holder for UZF
3901  else
3902  if (this%gwfiss == 0) then
3903  rhs = rhs - sumleak - sumrch
3904  else
3905  rhs = rhs - sumleak
3906  end if
3907  end if
3908 
3909  ! -- add groundwater leakage
3910  else if (hgwf < bt) then
3911  rhs = rhs - sumrch
3912  end if
3913  end if

◆ sfr_update_flows()

subroutine sfrmodule::sfr_update_flows ( class(sfrtype), intent(inout)  this,
integer(i4b), intent(in)  n,
real(dp), intent(inout)  qd,
real(dp), intent(in)  qgwf 
)
private

Method to update downstream flow and groundwater leakage terms for a SFR package reach.

Parameters
[in,out]thisSfrType object
[in]nreach number
[in,out]qddownstream reach flow
[in]qgwfgroundwater leakage for reach

Definition at line 3921 of file gwf-sfr.f90.

3922  ! -- dummy
3923  class(SfrType), intent(inout) :: this !< SfrType object
3924  integer(I4B), intent(in) :: n !< reach number
3925  real(DP), intent(inout) :: qd !< downstream reach flow
3926  real(DP), intent(in) :: qgwf !< groundwater leakage for reach
3927  ! -- local
3928  integer(I4B) :: i
3929  integer(I4B) :: n2
3930  integer(I4B) :: idiv
3931  integer(I4B) :: jpos
3932  real(DP) :: qdiv
3933  real(DP) :: f
3934  !
3935  ! -- update reach terms
3936  !
3937  ! -- save final downstream stream flow
3938  this%dsflow(n) = qd
3939  !
3940  ! -- save groundwater leakage
3941  this%gwflow(n) = qgwf
3942  !
3943  ! -- route downstream flow
3944  if (qd > dzero) then
3945  !
3946  ! -- route water to diversions
3947  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3948  if (this%idir(i) > 0) cycle
3949  idiv = this%idiv(i)
3950  if (idiv == 0) cycle
3951  jpos = this%iadiv(n) + idiv - 1
3952  call this%sfr_calc_div(n, idiv, qd, qdiv)
3953  this%qconn(i) = qdiv
3954  this%divq(jpos) = qdiv
3955  end do
3956  !
3957  ! -- Mover terms: store outflow after diversion loss
3958  ! as qformvr and reduce outflow (qd)
3959  ! by how much was actually sent to the mover
3960  if (this%imover == 1) then
3961  call this%pakmvrobj%accumulate_qformvr(n, qd)
3962  qd = max(qd - this%pakmvrobj%get_qtomvr(n), dzero)
3963  end if
3964  !
3965  ! -- route remaining water to downstream reaches
3966  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3967  if (this%idir(i) > 0) cycle
3968  if (this%idiv(i) > 0) cycle
3969  n2 = this%ja(i)
3970  if (this%iboundpak(n2) == 0) cycle
3971  f = this%ustrf(n2) / this%ftotnd(n)
3972  this%qconn(i) = qd * f
3973  end do
3974  else
3975  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3976  if (this%idir(i) > 0) cycle
3977  this%qconn(i) = dzero
3978  idiv = this%idiv(i)
3979  if (idiv == 0) cycle
3980  jpos = this%iadiv(n) + idiv - 1
3981  this%divq(jpos) = dzero
3982  end do
3983  end if

Variable Documentation

◆ ftype

character(len=lenftype) sfrmodule::ftype = 'SFR'

Definition at line 46 of file gwf-sfr.f90.

46  character(len=LENFTYPE) :: ftype = 'SFR' !< package ftype string

◆ text

character(len=lenpackagename) sfrmodule::text = ' SFR'

Definition at line 47 of file gwf-sfr.f90.

47  character(len=LENPACKAGENAME) :: text = ' SFR' !< package budget string