MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
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_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_da (this)
 @ brief Deallocate package memory 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_constant (this, n, d1, hgwf, qgwf, qd)
 
subroutine sfr_calc_steady (this, n, d1, hgwf, qu, qi, qfrommvr, qr, qe, qro, qgwf, qd)
 
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_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_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, bots, 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 5747 of file gwf-sfr.f90.

5748  ! -- return variable
5749  real(DP) :: calc_area_wet !< wetted area
5750  ! -- dummy variables
5751  class(SfrType) :: this !< SfrType object
5752  integer(I4B), intent(in) :: n !< reach number
5753  real(DP), intent(in) :: depth !< reach depth
5754  ! -- local variables
5755  integer(I4B) :: npts
5756  integer(I4B) :: i0
5757  integer(I4B) :: i1
5758  !
5759  ! -- Calculate wetted area
5760  npts = this%ncrosspts(n)
5761  i0 = this%iacross(n)
5762  i1 = this%iacross(n + 1) - 1
5763  if (npts > 1) then
5764  calc_area_wet = get_cross_section_area(npts, this%station(i0:i1), &
5765  this%xsheight(i0:i1), depth)
5766  else
5767  calc_area_wet = this%station(i0) * depth
5768  end if
5769  !
5770  ! -- return
5771  return
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 5779 of file gwf-sfr.f90.

5780  ! -- return variable
5781  real(DP) :: calc_perimeter_wet !< wetted perimeter
5782  ! -- dummy variables
5783  class(SfrType) :: this !< SfrType object
5784  integer(I4B), intent(in) :: n !< reach number
5785  real(DP), intent(in) :: depth !< reach depth
5786  ! -- local variables
5787  integer(I4B) :: npts
5788  integer(I4B) :: i0
5789  integer(I4B) :: i1
5790  !
5791  ! -- Calculate wetted perimeter
5792  npts = this%ncrosspts(n)
5793  i0 = this%iacross(n)
5794  i1 = this%iacross(n + 1) - 1
5795  if (npts > 1) then
5796  calc_perimeter_wet = get_wetted_perimeter(npts, this%station(i0:i1), &
5797  this%xsheight(i0:i1), depth)
5798  else
5799  calc_perimeter_wet = this%station(i0) ! no depth dependence in original implementation
5800  end if
5801  !
5802  ! -- return
5803  return
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 5811 of file gwf-sfr.f90.

5812  ! -- return variable
5813  real(DP) :: calc_surface_area !< surface area
5814  ! -- dummy variables
5815  class(SfrType) :: this !< SfrType object
5816  integer(I4B), intent(in) :: n !< reach number
5817  ! -- local variables
5818  integer(I4B) :: npts
5819  integer(I4B) :: i0
5820  integer(I4B) :: i1
5821  real(DP) :: top_width
5822  !
5823  ! -- Calculate surface area
5824  npts = this%ncrosspts(n)
5825  i0 = this%iacross(n)
5826  i1 = this%iacross(n + 1) - 1
5827  if (npts > 1) then
5828  top_width = get_saturated_topwidth(npts, this%station(i0:i1))
5829  else
5830  top_width = this%station(i0)
5831  end if
5832  calc_surface_area = top_width * this%length(n)
5833  !
5834  ! -- return
5835  return
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 5843 of file gwf-sfr.f90.

5844  ! -- return variable
5845  real(DP) :: calc_surface_area_wet !< wetted surface area
5846  ! -- dummy variables
5847  class(SfrType) :: this !< SfrType object
5848  integer(I4B), intent(in) :: n !< reach number
5849  real(DP), intent(in) :: depth !< reach depth
5850  ! -- local variables
5851  real(DP) :: top_width
5852  !
5853  ! -- Calculate wetted surface area
5854  top_width = this%calc_top_width_wet(n, depth)
5855  calc_surface_area_wet = top_width * this%length(n)
5856  !
5857  ! -- return
5858  return

◆ 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 5866 of file gwf-sfr.f90.

5867  ! -- return variable
5868  real(DP) :: calc_top_width_wet !< wetted top width
5869  ! -- dummy variables
5870  class(SfrType) :: this !< SfrType object
5871  integer(I4B), intent(in) :: n !< reach number
5872  real(DP), intent(in) :: depth !< reach depth
5873  ! -- local variables
5874  integer(I4B) :: npts
5875  integer(I4B) :: i0
5876  integer(I4B) :: i1
5877  real(DP) :: sat
5878  !
5879  ! -- Calculate wetted top width
5880  npts = this%ncrosspts(n)
5881  i0 = this%iacross(n)
5882  i1 = this%iacross(n + 1) - 1
5883  sat = scubicsaturation(dem5, dzero, depth, dem5)
5884  if (npts > 1) then
5885  calc_top_width_wet = sat * get_wetted_topwidth(npts, &
5886  this%station(i0:i1), &
5887  this%xsheight(i0:i1), &
5888  depth)
5889  else
5890  calc_top_width_wet = sat * this%station(i0)
5891  end if
5892  !
5893  ! -- return
5894  return
Here is the call graph for this function:

◆ define_listlabel()

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

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 2774 of file gwf-sfr.f90.

2775  ! -- dummy variables
2776  class(SfrType), intent(inout) :: this !< SfrType object
2777  !
2778  ! -- create the header list label
2779  this%listlabel = trim(this%filtyp)//' NO.'
2780  if (this%dis%ndim == 3) then
2781  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
2782  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
2783  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
2784  elseif (this%dis%ndim == 2) then
2785  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
2786  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
2787  else
2788  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
2789  end if
2790  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
2791  if (this%inamedbound == 1) then
2792  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
2793  end if
2794  !
2795  ! -- return
2796  return

◆ 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 5902 of file gwf-sfr.f90.

5903  ! -- modules
5905  ! -- dummy variables
5906  class(SfrType), intent(inout) :: this !< SfrType object
5907  ! -- local variables
5908  integer(I4B) :: i
5909  integer(I4B) :: j
5910  !
5911  ! -- Set idense and reallocate denseterms to be of size MAXBOUND
5912  this%idense = 1
5913  call mem_reallocate(this%denseterms, 3, this%MAXBOUND, 'DENSETERMS', &
5914  this%memoryPath)
5915  do i = 1, this%maxbound
5916  do j = 1, 3
5917  this%denseterms(j, i) = dzero
5918  end do
5919  end do
5920  write (this%iout, '(/1x,a)') 'DENSITY TERMS HAVE BEEN ACTIVATED FOR SFR &
5921  &PACKAGE: '//trim(adjustl(this%packName))
5922  !
5923  ! -- return
5924  return

◆ 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 5933 of file gwf-sfr.f90.

5934  ! -- modules
5936  ! -- dummy variables
5937  class(SfrType), intent(inout) :: this !< SfrType object
5938  ! -- local variables
5939  integer(I4B) :: i
5940  integer(I4B) :: j
5941  !
5942  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
5943  this%ivsc = 1
5944  call mem_reallocate(this%viscratios, 2, this%MAXBOUND, 'VISCRATIOS', &
5945  this%memoryPath)
5946  do i = 1, this%maxbound
5947  do j = 1, 2
5948  this%viscratios(j, i) = done
5949  end do
5950  end do
5951  write (this%iout, '(/1x,a)') 'VISCOSITY HAS BEEN ACTIVATED FOR SFR &
5952  &PACKAGE: '//trim(adjustl(this%packName))
5953  !
5954  ! -- return
5955  return

◆ 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 1909 of file gwf-sfr.f90.

1910  ! -- modules
1912  ! -- dummy variables
1913  class(SfrType) :: this !< SfrType object
1914  ! -- local variables
1915  integer(I4B) :: n
1916  integer(I4B) :: iaux
1917  !
1918  ! -- Most advanced package AD routines have to restore state if
1919  ! the solution failed and the time step is being retried with a smaller
1920  ! step size. This is not needed here because there is no old stage
1921  ! or storage effects in the stream.
1922  !
1923  ! -- Advance the time series manager
1924  call this%TsManager%ad()
1925  !
1926  ! -- check upstream fractions if time series are being used to
1927  ! define this variable
1928  if (var_timeseries(this%tsManager, this%packName, 'USTRF')) then
1929  call this%sfr_check_ustrf()
1930  end if
1931  !
1932  ! -- update auxiliary variables by copying from the derived-type time
1933  ! series variable into the bndpackage auxvar variable so that this
1934  ! information is properly written to the GWF budget file
1935  if (this%naux > 0) then
1936  do n = 1, this%maxbound
1937  do iaux = 1, this%naux
1938  if (this%noupdateauxvar(iaux) /= 0) cycle
1939  this%auxvar(iaux, n) = this%rauxvar(iaux, n)
1940  end do
1941  end do
1942  end if
1943  !
1944  ! -- reset upstream flow to zero and set specified stage
1945  do n = 1, this%maxbound
1946  this%usflow(n) = dzero
1947  if (this%iboundpak(n) < 0) then
1948  this%stage(n) = this%sstage(n)
1949  end if
1950  end do
1951  !
1952  ! -- pakmvrobj ad
1953  if (this%imover == 1) then
1954  call this%pakmvrobj%ad()
1955  end if
1956  !
1957  ! -- For each observation, push simulated value and corresponding
1958  ! simulation time from "current" to "preceding" and reset
1959  ! "current" value.
1960  call this%obs%obs_ad()
1961  !
1962  ! -- return
1963  return
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 3625 of file gwf-sfr.f90.

3626  ! -- dummy variables
3627  class(SfrType) :: this !< SfrType object
3628  real(DP), intent(inout) :: qc !< total reach volumetric flow
3629  real(DP), intent(in) :: qu !< upstream reach volumetric flow
3630  real(DP), intent(in) :: qi !< reach volumetric inflow
3631  real(DP), intent(in) :: qr !< reach volumetric rainfall
3632  real(DP), intent(inout) :: qro !< reach volumetric runoff
3633  real(DP), intent(inout) :: qe !< reach volumetric evaporation
3634  real(DP), intent(in) :: qfrommvr !< reach volumetric flow from mover
3635  ! -- local variables
3636  real(DP) :: qt
3637  !
3638  ! -- adjust runoff or evaporation if sum of sources is negative
3639  if (qc < dzero) then
3640  !
3641  ! -- calculate sources without evaporation
3642  qt = qu + qi + qr + qro + qfrommvr
3643  !
3644  ! -- runoff exceeds sources of water for reach
3645  if (qt < dzero) then
3646  if (qro < dzero) then
3647  qro = -(qu + qi + qr + qfrommvr)
3648  qe = dzero
3649  end if
3650  !
3651  ! -- evaporation exceeds sources of water for reach
3652  else
3653  if (qe > dzero) then
3654  qe = qu + qi + qr + qro + qfrommvr
3655  end if
3656  end if
3657  qc = qu + qi + qr - qe + qro + qfrommvr
3658  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 351 of file gwf-sfr.f90.

352  ! -- modules
354  ! -- dummy variables
355  class(SfrType), intent(inout) :: this !< SfrType object
356  ! -- local variables
357  integer(I4B) :: i
358  integer(I4B) :: j
359  !
360  ! -- allocate character array for budget text
361  allocate (this%csfrbudget(this%bditems))
362  call mem_allocate(this%sfrname, lenboundname, this%maxbound, &
363  'SFRNAME', this%memoryPath)
364  !
365  ! -- variables originally in SfrDataType
366  call mem_allocate(this%iboundpak, this%maxbound, 'IBOUNDPAK', &
367  this%memoryPath)
368  call mem_allocate(this%igwfnode, this%maxbound, 'IGWFNODE', this%memoryPath)
369  call mem_allocate(this%igwftopnode, this%maxbound, 'IGWFTOPNODE', &
370  this%memoryPath)
371  call mem_allocate(this%length, this%maxbound, 'LENGTH', this%memoryPath)
372  call mem_allocate(this%width, this%maxbound, 'WIDTH', this%memoryPath)
373  call mem_allocate(this%strtop, this%maxbound, 'STRTOP', this%memoryPath)
374  call mem_allocate(this%bthick, this%maxbound, 'BTHICK', this%memoryPath)
375  call mem_allocate(this%hk, this%maxbound, 'HK', this%memoryPath)
376  call mem_allocate(this%slope, this%maxbound, 'SLOPE', this%memoryPath)
377  call mem_allocate(this%nconnreach, this%maxbound, 'NCONNREACH', &
378  this%memoryPath)
379  call mem_allocate(this%ustrf, this%maxbound, 'USTRF', this%memoryPath)
380  call mem_allocate(this%ftotnd, this%maxbound, 'FTOTND', this%memoryPath)
381  call mem_allocate(this%ndiv, this%maxbound, 'NDIV', this%memoryPath)
382  call mem_allocate(this%usflow, this%maxbound, 'USFLOW', this%memoryPath)
383  call mem_allocate(this%dsflow, this%maxbound, 'DSFLOW', this%memoryPath)
384  call mem_allocate(this%depth, this%maxbound, 'DEPTH', this%memoryPath)
385  call mem_allocate(this%stage, this%maxbound, 'STAGE', this%memoryPath)
386  call mem_allocate(this%gwflow, this%maxbound, 'GWFLOW', this%memoryPath)
387  call mem_allocate(this%simevap, this%maxbound, 'SIMEVAP', this%memoryPath)
388  call mem_allocate(this%simrunoff, this%maxbound, 'SIMRUNOFF', &
389  this%memoryPath)
390  call mem_allocate(this%stage0, this%maxbound, 'STAGE0', this%memoryPath)
391  call mem_allocate(this%usflow0, this%maxbound, 'USFLOW0', this%memoryPath)
392  !
393  ! -- reach order and connection data
394  call mem_allocate(this%isfrorder, this%maxbound, 'ISFRORDER', &
395  this%memoryPath)
396  call mem_allocate(this%ia, this%maxbound + 1, 'IA', this%memoryPath)
397  call mem_allocate(this%ja, 0, 'JA', this%memoryPath)
398  call mem_allocate(this%idir, 0, 'IDIR', this%memoryPath)
399  call mem_allocate(this%idiv, 0, 'IDIV', this%memoryPath)
400  call mem_allocate(this%qconn, 0, 'QCONN', this%memoryPath)
401  !
402  ! -- boundary data
403  call mem_allocate(this%rough, this%maxbound, 'ROUGH', this%memoryPath)
404  call mem_allocate(this%rain, this%maxbound, 'RAIN', this%memoryPath)
405  call mem_allocate(this%evap, this%maxbound, 'EVAP', this%memoryPath)
406  call mem_allocate(this%inflow, this%maxbound, 'INFLOW', this%memoryPath)
407  call mem_allocate(this%runoff, this%maxbound, 'RUNOFF', this%memoryPath)
408  call mem_allocate(this%sstage, this%maxbound, 'SSTAGE', this%memoryPath)
409  !
410  ! -- aux variables
411  call mem_allocate(this%rauxvar, this%naux, this%maxbound, &
412  'RAUXVAR', this%memoryPath)
413  !
414  ! -- diversion variables
415  call mem_allocate(this%iadiv, this%maxbound + 1, 'IADIV', this%memoryPath)
416  call mem_allocate(this%divreach, 0, 'DIVREACH', this%memoryPath)
417  call mem_allocate(this%divflow, 0, 'DIVFLOW', this%memoryPath)
418  call mem_allocate(this%divq, 0, 'DIVQ', this%memoryPath)
419  !
420  ! -- cross-section data
421  call mem_allocate(this%ncrosspts, this%maxbound, 'NCROSSPTS', &
422  this%memoryPath)
423  call mem_allocate(this%iacross, this%maxbound + 1, 'IACROSS', &
424  this%memoryPath)
425  call mem_allocate(this%station, this%ncrossptstot, 'STATION', &
426  this%memoryPath)
427  call mem_allocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
428  this%memoryPath)
429  call mem_allocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
430  this%memoryPath)
431  !
432  ! -- initialize variables
433  this%iacross(1) = 0
434  do i = 1, this%maxbound
435  this%iboundpak(i) = 1
436  this%igwfnode(i) = 0
437  this%igwftopnode(i) = 0
438  this%length(i) = dzero
439  this%width(i) = dzero
440  this%strtop(i) = dzero
441  this%bthick(i) = dzero
442  this%hk(i) = dzero
443  this%slope(i) = dzero
444  this%nconnreach(i) = 0
445  this%ustrf(i) = dzero
446  this%ftotnd(i) = dzero
447  this%ndiv(i) = 0
448  this%usflow(i) = dzero
449  this%dsflow(i) = dzero
450  this%depth(i) = dzero
451  this%stage(i) = dzero
452  this%gwflow(i) = dzero
453  this%simevap(i) = dzero
454  this%simrunoff(i) = dzero
455  this%stage0(i) = dzero
456  this%usflow0(i) = dzero
457  !
458  ! -- boundary data
459  this%rough(i) = dzero
460  this%rain(i) = dzero
461  this%evap(i) = dzero
462  this%inflow(i) = dzero
463  this%runoff(i) = dzero
464  this%sstage(i) = dzero
465  !
466  ! -- aux variables
467  do j = 1, this%naux
468  this%rauxvar(j, i) = dzero
469  end do
470  !
471  ! -- cross-section data
472  this%ncrosspts(i) = 0
473  this%iacross(i + 1) = 0
474  end do
475  !
476  ! -- initialize additional cross-section data
477  do i = 1, this%ncrossptstot
478  this%station(i) = dzero
479  this%xsheight(i) = dzero
480  this%xsrough(i) = dzero
481  end do
482  !
483  !-- fill csfrbudget
484  this%csfrbudget(1) = ' RAINFALL'
485  this%csfrbudget(2) = ' EVAPORATION'
486  this%csfrbudget(3) = ' RUNOFF'
487  this%csfrbudget(4) = ' EXT-INFLOW'
488  this%csfrbudget(5) = ' GWF'
489  this%csfrbudget(6) = ' EXT-OUTFLOW'
490  this%csfrbudget(7) = ' FROM-MVR'
491  this%csfrbudget(8) = ' TO-MVR'
492  !
493  ! -- allocate and initialize budget output data
494  call mem_allocate(this%qoutflow, this%maxbound, 'QOUTFLOW', this%memoryPath)
495  call mem_allocate(this%qextoutflow, this%maxbound, 'QEXTOUTFLOW', &
496  this%memoryPath)
497  do i = 1, this%maxbound
498  this%qoutflow(i) = dzero
499  this%qextoutflow(i) = dzero
500  end do
501  !
502  ! -- allocate and initialize dbuff
503  if (this%istageout > 0) then
504  call mem_allocate(this%dbuff, this%maxbound, 'DBUFF', this%memoryPath)
505  do i = 1, this%maxbound
506  this%dbuff(i) = dzero
507  end do
508  else
509  call mem_allocate(this%dbuff, 0, 'DBUFF', this%memoryPath)
510  end if
511  !
512  ! -- allocate character array for budget text
513  allocate (this%cauxcbc(this%cbcauxitems))
514  !
515  ! -- allocate and initialize qauxcbc
516  call mem_allocate(this%qauxcbc, this%cbcauxitems, 'QAUXCBC', &
517  this%memoryPath)
518  do i = 1, this%cbcauxitems
519  this%qauxcbc(i) = dzero
520  end do
521  !
522  ! -- fill cauxcbc
523  this%cauxcbc(1) = 'FLOW-AREA '
524  !
525  ! -- allocate denseterms to size 0
526  call mem_allocate(this%denseterms, 3, 0, 'DENSETERMS', this%memoryPath)
527  !
528  ! -- allocate viscratios to size 0
529  call mem_allocate(this%viscratios, 2, 0, 'VISCRATIOS', this%memoryPath)
530  !
531  ! -- return
532  return

◆ 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 282 of file gwf-sfr.f90.

283  ! -- modules
286  ! -- dummy variables
287  class(SfrType), intent(inout) :: this !< SfrType object
288  !
289  ! -- call standard BndType allocate scalars
290  call this%BndType%allocate_scalars()
291  !
292  ! -- allocate the object and assign values to object variables
293  call mem_allocate(this%iprhed, 'IPRHED', this%memoryPath)
294  call mem_allocate(this%istageout, 'ISTAGEOUT', this%memoryPath)
295  call mem_allocate(this%ibudgetout, 'IBUDGETOUT', this%memoryPath)
296  call mem_allocate(this%ibudcsv, 'IBUDCSV', this%memoryPath)
297  call mem_allocate(this%ipakcsv, 'IPAKCSV', this%memoryPath)
298  call mem_allocate(this%idiversions, 'IDIVERSIONS', this%memoryPath)
299  call mem_allocate(this%maxsfrpicard, 'MAXSFRPICARD', this%memoryPath)
300  call mem_allocate(this%maxsfrit, 'MAXSFRIT', this%memoryPath)
301  call mem_allocate(this%bditems, 'BDITEMS', this%memoryPath)
302  call mem_allocate(this%cbcauxitems, 'CBCAUXITEMS', this%memoryPath)
303  call mem_allocate(this%unitconv, 'UNITCONV', this%memoryPath)
304  call mem_allocate(this%lengthconv, 'LENGTHCONV', this%memoryPath)
305  call mem_allocate(this%timeconv, 'TIMECONV', this%memoryPath)
306  call mem_allocate(this%dmaxchg, 'DMAXCHG', this%memoryPath)
307  call mem_allocate(this%deps, 'DEPS', this%memoryPath)
308  call mem_allocate(this%nconn, 'NCONN', this%memoryPath)
309  call mem_allocate(this%icheck, 'ICHECK', this%memoryPath)
310  call mem_allocate(this%iconvchk, 'ICONVCHK', this%memoryPath)
311  call mem_allocate(this%idense, 'IDENSE', this%memoryPath)
312  call mem_allocate(this%ianynone, 'IANYNONE', this%memoryPath)
313  call mem_allocate(this%ncrossptstot, 'NCROSSPTSTOT', this%memoryPath)
314  !
315  ! -- set pointer to gwf iss
316  call mem_setptr(this%gwfiss, 'ISS', create_mem_path(this%name_model))
317  !
318  ! -- Set values
319  this%iprhed = 0
320  this%istageout = 0
321  this%ibudgetout = 0
322  this%ibudcsv = 0
323  this%ipakcsv = 0
324  this%idiversions = 0
325  this%maxsfrpicard = 100
326  this%maxsfrit = maxadpit
327  this%bditems = 8
328  this%cbcauxitems = 1
329  this%unitconv = done
330  this%lengthconv = dnodata
331  this%timeconv = dnodata
332  this%dmaxchg = dem5
333  this%deps = dp999 * this%dmaxchg
334  this%nconn = 0
335  this%icheck = 1
336  this%iconvchk = 1
337  this%idense = 0
338  this%ivsc = 0
339  this%ianynone = 0
340  this%ncrossptstot = 0
341  !
342  ! -- return
343  return
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 780 of file gwf-sfr.f90.

781  ! -- dummy variables
782  class(SfrType), intent(inout) :: this !< SfrType object
783  ! -- local variables
784  integer(I4B) :: n
785  integer(I4B) :: ierr
786  !
787  ! -- allocate and read observations
788  call this%obs%obs_ar()
789  !
790  ! -- call standard BndType allocate scalars
791  call this%BndType%allocate_arrays()
792  !
793  ! -- set boundname for each connection
794  if (this%inamedbound /= 0) then
795  do n = 1, this%maxbound
796  this%boundname(n) = this%sfrname(n)
797  end do
798  end if
799  !
800  ! -- copy boundname into boundname_cst
801  call this%copy_boundname()
802  !
803  ! -- copy igwfnode into nodelist
804  do n = 1, this%maxbound
805  this%nodelist(n) = this%igwfnode(n)
806  end do
807  !
808  ! -- check the sfr unit conversion data
809  call this%sfr_check_conversion()
810  !
811  ! -- check the sfr reach data
812  call this%sfr_check_reaches()
813 
814  ! -- check the connection data
815  call this%sfr_check_connections()
816 
817  ! -- check the diversion data
818  if (this%idiversions /= 0) then
819  call this%sfr_check_diversions()
820  end if
821  !
822  ! -- terminate if errors were detected in any of the static sfr data
823  ierr = count_errors()
824  if (ierr > 0) then
825  call this%parser%StoreErrorUnit()
826  end if
827  !
828  ! -- setup pakmvrobj
829  if (this%imover /= 0) then
830  allocate (this%pakmvrobj)
831  call this%pakmvrobj%ar(this%maxbound, this%maxbound, this%memoryPath)
832  end if
833  !
834  ! -- return
835  return
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 2926 of file gwf-sfr.f90.

2927  ! -- dummy variables
2928  class(SfrType) :: this !< SfrType object
2929  ! -- local variables
2930  integer(I4B) :: i
2931  integer(I4B) :: j
2932  integer(I4B) :: n
2933  real(DP) :: v
2934  character(len=100) :: msg
2935  type(ObserveType), pointer :: obsrv => null()
2936  !
2937  ! Write simulated values for all sfr observations
2938  if (this%obs%npakobs > 0) then
2939  call this%obs%obs_bd_clear()
2940  do i = 1, this%obs%npakobs
2941  obsrv => this%obs%pakobs(i)%obsrv
2942  do j = 1, obsrv%indxbnds_count
2943  n = obsrv%indxbnds(j)
2944  v = dzero
2945  select case (obsrv%ObsTypeId)
2946  case ('STAGE')
2947  v = this%stage(n)
2948  case ('TO-MVR')
2949  v = dnodata
2950  if (this%imover == 1) then
2951  v = this%pakmvrobj%get_qtomvr(n)
2952  if (v > dzero) then
2953  v = -v
2954  end if
2955  end if
2956  case ('FROM-MVR')
2957  v = dnodata
2958  if (this%imover == 1) then
2959  v = this%pakmvrobj%get_qfrommvr(n)
2960  end if
2961  case ('EXT-INFLOW')
2962  v = this%inflow(n)
2963  case ('INFLOW')
2964  v = this%usflow(n)
2965  case ('OUTFLOW')
2966  v = this%qoutflow(n)
2967  case ('EXT-OUTFLOW')
2968  v = this%qextoutflow(n)
2969  case ('RAINFALL')
2970  if (this%iboundpak(n) /= 0) then
2971  v = this%rain(n)
2972  else
2973  v = dzero
2974  end if
2975  case ('RUNOFF')
2976  v = this%simrunoff(n)
2977  case ('EVAPORATION')
2978  v = this%simevap(n)
2979  case ('SFR')
2980  v = this%gwflow(n)
2981  case ('UPSTREAM-FLOW')
2982  v = this%usflow(n)
2983  if (this%imover == 1) then
2984  v = v + this%pakmvrobj%get_qfrommvr(n)
2985  end if
2986  case ('DOWNSTREAM-FLOW')
2987  v = this%dsflow(n)
2988  if (v > dzero) then
2989  v = -v
2990  end if
2991  case ('DEPTH')
2992  v = this%depth(n)
2993  case ('WET-PERIMETER')
2994  v = this%calc_perimeter_wet(n, this%depth(n))
2995  case ('WET-AREA')
2996  v = this%calc_area_wet(n, this%depth(n))
2997  case ('WET-WIDTH')
2998  v = this%calc_top_width_wet(n, this%depth(n))
2999  case default
3000  msg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
3001  call store_error(msg)
3002  end select
3003  call this%obs%SaveOneSimval(obsrv, v)
3004  end do
3005  end do
3006  !
3007  ! -- write summary of package error messages
3008  if (count_errors() > 0) then
3009  call this%parser%StoreErrorUnit()
3010  end if
3011  end if
3012  !
3013  ! -- return
3014  return
Here is the call graph for this function:

◆ 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 3921 of file gwf-sfr.f90.

3922  ! -- dummy variables
3923  class(SfrType) :: this !< SfrType object
3924  integer(I4B), intent(in) :: n !< reach number
3925  real(DP), intent(in) :: depth !< reach depth
3926  real(DP), intent(inout) :: cond !< reach-aquifer conductance
3927  real(DP), intent(in), optional :: hsfr !< stream stage
3928  real(DP), intent(in), optional :: h_temp !< head in gw cell
3929  ! -- local variables
3930  integer(I4B) :: node
3931  real(DP) :: wp
3932  real(DP) :: vscratio
3933  !
3934  ! -- initialize conductance
3935  cond = dzero
3936  !
3937  ! -- initial viscosity ratio to 1
3938  vscratio = done
3939  !
3940  ! -- calculate conductance if GWF cell is active
3941  ! rch-gwf flow will not occur if reach connected to an constant head cell
3942  node = this%igwfnode(n)
3943  if (node > 0) then
3944  if (this%ibound(node) > 0) then
3945  !
3946  ! -- direction of gradient across streambed determines which vsc ratio
3947  if (this%ivsc == 1) then
3948  if (hsfr > h_temp) then
3949  ! strm stg > gw head
3950  vscratio = this%viscratios(1, n)
3951  else
3952  vscratio = this%viscratios(2, n)
3953  end if
3954  end if
3955  wp = this%calc_perimeter_wet(n, depth)
3956  cond = this%hk(n) * vscratio * this%length(n) * wp / this%bthick(n)
3957  end if
3958  end if
3959  !
3960  ! -- return
3961  return

◆ sfr_calc_constant()

subroutine sfrmodule::sfr_calc_constant ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(inout)  d1,
real(dp), intent(in)  hgwf,
real(dp), intent(inout)  qgwf,
real(dp), intent(inout)  qd 
)
private
Parameters
thisSfrType object
[in]nreach number
[in,out]d1current reach depth estimate
[in]hgwfhead in gw cell
[in,out]qgwfreach-aquifer exchange
[in,out]qdreach outflow

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

3965  ! -- dummy variables
3966  class(SfrType) :: this !< SfrType object
3967  integer(I4B), intent(in) :: n !< reach number
3968  real(DP), intent(inout) :: d1 !< current reach depth estimate
3969  real(DP), intent(in) :: hgwf !< head in gw cell
3970  real(DP), intent(inout) :: qgwf !< reach-aquifer exchange
3971  real(DP), intent(inout) :: qd !< reach outflow
3972  ! -- local variables
3973  real(DP) :: qsrc
3974 
3975  this%stage(n) = this%sstage(n)
3976  d1 = max(dzero, this%stage(n) - this%strtop(n))
3977 
3978  call this%sfr_calc_qsource(n, d1, qsrc)
3979 
3980  if (this%sfr_gwf_conn(n) == 1) then
3981  call this%sfr_calc_qgwf(n, d1, hgwf, qgwf)
3982  qgwf = -qgwf
3983  else
3984  qgwf = dzero
3985  end if
3986 
3987  ! -- leakage exceeds inflow
3988  if (qgwf > qsrc) then
3989  d1 = dzero
3990  call this%sfr_calc_qsource(n, d1, qsrc)
3991  qgwf = qsrc
3992  end if
3993 
3994  ! -- set qd
3995  qd = qsrc - qgwf
3996 

◆ 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 4303 of file gwf-sfr.f90.

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

◆ 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 3666 of file gwf-sfr.f90.

3667  ! -- dummy variables
3668  class(SfrType) :: this !< SfrType object
3669  integer(I4B), intent(in) :: n !< reach number
3670  real(DP), intent(in) :: depth !< reach depth
3671  real(DP), intent(in) :: hgwf !< groundwater head in connected GWF cell
3672  real(DP), intent(inout) :: qgwf !< groundwater leakage for reach
3673  real(DP), intent(inout) :: qd !< residual
3674  ! -- local variables
3675  real(DP) :: qsrc
3676  !
3677  ! -- initialize residual
3678  qd = dzero
3679  !
3680  ! -- calculate total water sources excluding groundwater leakage
3681  call this%sfr_calc_qsource(n, depth, qsrc)
3682  !
3683  ! -- estimate groundwater leakage
3684  call this%sfr_calc_qgwf(n, depth, hgwf, qgwf)
3685  if (-qgwf > qsrc) qgwf = -qsrc
3686  !
3687  ! -- calculate down stream flow
3688  qd = qsrc + qgwf
3689  !
3690  ! -- limit downstream flow to a positive value
3691  if (qd < dem30) qd = dzero
3692  !
3693  ! -- return
3694  return

◆ 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 3829 of file gwf-sfr.f90.

3830  ! -- dummy variables
3831  class(SfrType) :: this !< SfrType object
3832  integer(I4B), intent(in) :: n !< reach number
3833  real(DP), intent(in) :: depth !< reach depth
3834  real(DP), intent(in) :: hgwf !< head in GWF cell connected to reach
3835  real(DP), intent(inout) :: qgwf !< reach-aquifer exchange
3836  real(DP), intent(inout), optional :: gwfhcof !< diagonal coefficient term for reach
3837  real(DP), intent(inout), optional :: gwfrhs !< right-hand side term for reach
3838  ! -- local variables
3839  integer(I4B) :: node
3840  real(DP) :: tp
3841  real(DP) :: bt
3842  real(DP) :: hsfr
3843  real(DP) :: h_temp
3844  real(DP) :: cond
3845  real(DP) :: sat
3846  real(DP) :: derv
3847  real(DP) :: gwfhcof0
3848  real(DP) :: gwfrhs0
3849  !
3850  ! -- initialize qgwf
3851  qgwf = dzero
3852  !
3853  ! -- skip sfr-aquifer exchange in external cells
3854  node = this%igwfnode(n)
3855  if (node < 1) return
3856  !
3857  ! -- skip sfr-aquifer exchange in inactive cells
3858  if (this%ibound(node) == 0) return
3859  !
3860  ! -- calculate saturation
3861  call schsmooth(depth, sat, derv)
3862  !
3863  ! -- terms for calculating direction of gradient across streambed
3864  tp = this%strtop(n)
3865  bt = tp - this%bthick(n)
3866  hsfr = tp + depth
3867  h_temp = hgwf
3868  if (h_temp < bt) then
3869  h_temp = bt
3870  end if
3871  !
3872  ! -- calculate conductance
3873  call this%sfr_calc_cond(n, depth, cond, hsfr, h_temp)
3874  !
3875  ! -- calculate groundwater leakage
3876  qgwf = sat * cond * (h_temp - hsfr)
3877  gwfrhs0 = -sat * cond * hsfr
3878  gwfhcof0 = -sat * cond
3879  !
3880  ! Add density contributions, if active
3881  if (this%idense /= 0) then
3882  call this%sfr_calculate_density_exchange(n, hsfr, hgwf, cond, tp, &
3883  qgwf, gwfhcof0, gwfrhs0)
3884  end if
3885  !
3886  ! -- Set gwfhcof and gwfrhs if present
3887  if (present(gwfhcof)) gwfhcof = gwfhcof0
3888  if (present(gwfrhs)) gwfrhs = gwfrhs0
3889  !
3890  ! -- return
3891  return
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 3755 of file gwf-sfr.f90.

3756  ! -- dummy variables
3757  class(SfrType) :: this !< SfrType object
3758  integer(I4B), intent(in) :: n !< reach number
3759  real(DP), intent(in) :: depth !< reach depth
3760  real(DP), intent(inout) :: qman !< streamflow
3761  ! -- local variables
3762  integer(I4B) :: npts
3763  integer(I4B) :: i0
3764  integer(I4B) :: i1
3765  real(DP) :: sat
3766  real(DP) :: derv
3767  real(DP) :: s
3768  real(DP) :: r
3769  real(DP) :: aw
3770  real(DP) :: wp
3771  real(DP) :: rh
3772  !
3773  ! -- initialize variables
3774  qman = dzero
3775  !
3776  ! -- calculate Manning's discharge for non-zero depths
3777  if (depth > dzero) then
3778  npts = this%ncrosspts(n)
3779  !
3780  ! -- set constant terms for Manning's equation
3781  call schsmooth(depth, sat, derv)
3782  s = this%slope(n)
3783  !
3784  ! -- calculate the mannings coefficient that is a
3785  ! function of depth
3786  if (npts > 1) then
3787  !
3788  ! -- get the location of the cross-section data for the reach
3789  i0 = this%iacross(n)
3790  i1 = this%iacross(n + 1) - 1
3791  !
3792  ! -- get the Manning's sum of the Manning's discharge
3793  ! for each section
3794  qman = get_mannings_section(npts, &
3795  this%station(i0:i1), &
3796  this%xsheight(i0:i1), &
3797  this%xsrough(i0:i1), &
3798  this%rough(n), &
3799  this%unitconv, &
3800  s, &
3801  depth)
3802  else
3803  r = this%rough(n)
3804  aw = this%calc_area_wet(n, depth)
3805  wp = this%calc_perimeter_wet(n, depth)
3806  if (wp > dzero) then
3807  rh = aw / wp
3808  else
3809  rh = dzero
3810  end if
3811  qman = this%unitconv * aw * (rh**dtwothirds) * sqrt(s) / r
3812  end if
3813  !
3814  ! -- calculate stream flow
3815  qman = sat * qman
3816  end if
3817  !
3818  ! -- return
3819  return
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 3703 of file gwf-sfr.f90.

3704  ! -- dummy variables
3705  class(SfrType) :: this !< SfrType object
3706  integer(I4B), intent(in) :: n !< reach number
3707  real(DP), intent(in) :: depth !< reach depth
3708  real(DP), intent(inout) :: qsrc !< sum of sources for reach
3709  ! -- local variables
3710  real(DP) :: qu
3711  real(DP) :: qi
3712  real(DP) :: qr
3713  real(DP) :: qe
3714  real(DP) :: qro
3715  real(DP) :: qfrommvr
3716  real(DP) :: a
3717  real(DP) :: ae
3718  !
3719  ! -- initialize residual
3720  qsrc = dzero
3721  !
3722  ! -- calculate flow terms
3723  qu = this%usflow(n)
3724  qi = this%inflow(n)
3725  qro = this%runoff(n)
3726  !
3727  ! -- calculate rainfall and evap
3728  a = this%calc_surface_area(n)
3729  ae = this%calc_surface_area_wet(n, depth)
3730  qr = this%rain(n) * a
3731  qe = this%evap(n) * ae
3732  !
3733  ! -- calculate mover term
3734  qfrommvr = dzero
3735  if (this%imover == 1) then
3736  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3737  end if
3738  !
3739  ! -- calculate down stream flow
3740  qsrc = qu + qi + qr - qe + qro + qfrommvr
3741  !
3742  ! -- adjust runoff or evaporation if sum of sources is negative
3743  call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)
3744  !
3745  ! -- return
3746  return

◆ 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 4361 of file gwf-sfr.f90.

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

◆ sfr_calc_steady()

subroutine sfrmodule::sfr_calc_steady ( class(sfrtype this,
integer(i4b), intent(in)  n,
real(dp), intent(inout)  d1,
real(dp), intent(in)  hgwf,
real(dp), intent(in)  qu,
real(dp), intent(in)  qi,
real(dp), intent(in)  qfrommvr,
real(dp), intent(in)  qr,
real(dp), intent(in)  qe,
real(dp), intent(in)  qro,
real(dp), intent(inout)  qgwf,
real(dp), intent(inout)  qd 
)
private
Parameters
thisSfrType object
[in]nreach number
[in,out]d1current reach depth estimate
[in]hgwfhead in gw cell
[in]qureach upstream flow
[in]qireach specified inflow
[in]qfrommvrreach flow from mover
[in]qrreach rainfall
[in]qereach evaporation
[in]qroreach runoff flow
[in,out]qgwfreach-aquifer exchange
[in,out]qdreach outflow

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

4002  ! -- dummy variables
4003  class(SfrType) :: this !< SfrType object
4004  integer(I4B), intent(in) :: n !< reach number
4005  real(DP), intent(inout) :: d1 !< current reach depth estimate
4006  real(DP), intent(in) :: hgwf !< head in gw cell
4007  real(DP), intent(in) :: qu !< reach upstream flow
4008  real(DP), intent(in) :: qi !< reach specified inflow
4009  real(DP), intent(in) :: qfrommvr !< reach flow from mover
4010  real(DP), intent(in) :: qr !< reach rainfall
4011  real(DP), intent(in) :: qe !< reach evaporation
4012  real(DP), intent(in) :: qro !< reach runoff flow
4013  real(DP), intent(inout) :: qgwf !< reach-aquifer exchange
4014  real(DP), intent(inout) :: qd !< reach outflow
4015  ! -- local variables
4016  integer(I4B) :: i
4017  integer(I4B) :: isolve
4018  integer(I4B) :: iic
4019  integer(I4B) :: iic2
4020  integer(I4B) :: iic3
4021  integer(I4B) :: iic4
4022  integer(I4B) :: ibflg
4023  real(DP) :: qmp
4024  real(DP) :: qsrc
4025  real(DP) :: qsrcmp
4026  real(DP) :: tp
4027  real(DP) :: bt
4028  real(DP) :: hsfr
4029  real(DP) :: qc
4030  real(DP) :: en1
4031  real(DP) :: en2
4032  real(DP) :: qen1
4033  real(DP) :: f1
4034  real(DP) :: f2
4035  real(DP) :: qgwf1
4036  real(DP) :: qgwf2
4037  real(DP) :: qgwfp
4038  real(DP) :: qgwfold
4039  real(DP) :: fhstr1
4040  real(DP) :: fhstr2
4041  real(DP) :: d2
4042  real(DP) :: dpp
4043  real(DP) :: dx
4044  real(DP) :: q1
4045  real(DP) :: q2
4046  real(DP) :: derv
4047  real(DP) :: dlh
4048  real(DP) :: dlhold
4049  real(DP) :: fp
4050  real(DP) :: err
4051  real(DP) :: errold
4052  !
4053  ! -- initialize local variables
4054  d2 = dzero
4055  q1 = dzero
4056  q2 = dzero
4057  qsrc = dzero
4058  qgwf = dzero
4059  qgwfold = dzero
4060  !
4061  ! -- calculate the flow at end of the reach
4062  ! excluding groundwater leakage
4063  qc = qu + qi + qr - qe + qro + qfrommvr
4064  !
4065  ! -- calculate flow at the middle of the reach
4066  ! excluding groundwater leakage
4067  qsrcmp = qu + qi + qfrommvr + dhalf * (qr - qe + qro)
4068  qmp = qsrcmp ! initial estimate flow at the midpoint
4069  !
4070  ! -- calculate stream depth at the midpoint
4071  call this%sfr_calc_reach_depth(n, qmp, d1)
4072  !
4073  ! -- calculate sources/sinks for reach
4074  ! excluding groundwater leakage
4075  call this%sfr_calc_qsource(n, d1, qsrc)
4076  !
4077  ! -- calculate initial reach stage, downstream flow,
4078  ! and groundwater leakage
4079  tp = this%strtop(n)
4080  bt = tp - this%bthick(n)
4081  hsfr = d1 + tp
4082  qd = max(qsrc, dzero)
4083  qgwf = dzero
4084  !
4085  ! -- set flag to skip iterations
4086  isolve = 1
4087  if (hsfr <= tp .and. hgwf <= tp) isolve = 0
4088  if (hgwf <= tp .and. qc < dem30) isolve = 0
4089  if (this%sfr_gwf_conn(n) == 0) isolve = 0
4090  !
4091  ! -- iterate to achieve solution
4092  calc_solution: if (isolve /= 0) then
4093  !
4094  ! -- estimate initial end points
4095  en1 = dzero
4096  if (d1 > dem30) then
4097  if ((tp - hgwf) > dem30) then
4098  en2 = dp9 * d1
4099  else
4100  en2 = d1p1 * d1 - (tp - hgwf)
4101  end if
4102  else if ((tp - hgwf) > dem30) then
4103  en2 = done
4104  else
4105  en2 = dp99 * (hgwf - tp)
4106  end if
4107  !
4108  ! -- estimate flow at end points
4109  ! -- end point 1
4110  if (hgwf > tp) then
4111  call this%sfr_calc_qgwf(n, dzero, hgwf, qgwf1)
4112  qgwf1 = -qgwf1
4113  qen1 = qmp - dhalf * qgwf1
4114  else
4115  qgwf1 = dzero
4116  qen1 = qsrcmp
4117  end if
4118  if (hgwf > bt) then
4119  call this%sfr_calc_qgwf(n, en2, hgwf, qgwf2)
4120  qgwf2 = -qgwf2
4121  else
4122  call this%sfr_calc_qgwf(n, en2, bt, qgwf2)
4123  qgwf2 = -qgwf2
4124  end if
4125  if (qgwf2 > qsrc) qgwf2 = qsrc
4126  ! -- calculate two depths
4127  call this%sfr_calc_reach_depth(n, (qsrcmp - dhalf * qgwf1), d1)
4128  call this%sfr_calc_reach_depth(n, (qsrcmp - dhalf * qgwf2), d2)
4129  ! -- determine roots
4130  if (d1 > dem30) then
4131  f1 = en1 - d1
4132  else
4133  en1 = dzero
4134  f1 = en1 - dzero
4135  end if
4136  if (d2 > dem30) then
4137  f2 = en2 - d2
4138  if (f2 < dem30) en2 = d2
4139  else
4140  d2 = dzero
4141  f2 = en2 - dzero
4142  end if
4143  !
4144  ! -- iterate to find a solution
4145  dpp = dhalf * (en1 + en2)
4146  dx = dpp
4147  iic = 0
4148  iic2 = 0
4149  iic3 = 0
4150  fhstr1 = dzero
4151  fhstr2 = dzero
4152  qgwfp = dzero
4153  dlhold = dzero
4154  do i = 1, this%maxsfrit
4155  ibflg = 0
4156  d1 = dpp
4157  d2 = d1 + dtwo * this%deps
4158  ! -- calculate q at midpoint at both end points
4159  call this%sfr_calc_qman(n, d1, q1)
4160  call this%sfr_calc_qman(n, d2, q2)
4161  ! -- calculate groundwater leakage at both end points
4162  call this%sfr_calc_qgwf(n, d1, hgwf, qgwf1)
4163  qgwf1 = -qgwf1
4164  call this%sfr_calc_qgwf(n, d2, hgwf, qgwf2)
4165  qgwf2 = -qgwf2
4166  !
4167  if (qgwf1 >= qsrc) then
4168  en2 = dpp
4169  dpp = dhalf * (en1 + en2)
4170  call this%sfr_calc_qgwf(n, dpp, hgwf, qgwfp)
4171  qgwfp = -qgwfp
4172  if (qgwfp > qsrc) qgwfp = qsrc
4173  call this%sfr_calc_reach_depth(n, (qsrcmp - dhalf * qgwfp), dx)
4174  ibflg = 1
4175  else
4176  fhstr1 = (qsrcmp - dhalf * qgwf1) - q1
4177  fhstr2 = (qsrcmp - dhalf * qgwf2) - q2
4178  end if
4179  !
4180  if (ibflg == 0) then
4181  derv = dzero
4182  if (abs(d1 - d2) > dzero) then
4183  derv = (fhstr1 - fhstr2) / (d1 - d2)
4184  end if
4185  if (abs(derv) > dem30) then
4186  dlh = -fhstr1 / derv
4187  else
4188  dlh = dzero
4189  end if
4190  dpp = d1 + dlh
4191  !
4192  ! -- updated depth outside of endpoints - use bisection instead
4193  if ((dpp >= en2) .or. (dpp <= en1)) then
4194  if (abs(dlh) > abs(dlhold) .or. dpp < dem30) then
4195  ibflg = 1
4196  dpp = dhalf * (en1 + en2)
4197  end if
4198  end if
4199  !
4200  ! -- check for slow convergence
4201  ! -- set flags to determine if the Newton-Raphson method oscillates
4202  ! or if convergence is slow
4203  if (qgwf1 * qgwfold < dem30) then
4204  iic2 = iic2 + 1
4205  else
4206  iic2 = 0
4207  end if
4208  if (qgwf1 < dem30) then
4209  iic3 = iic3 + 1
4210  else
4211  iic3 = 0
4212  end if
4213  if (dlh * dlhold < dem30 .or. abs(dlh) > abs(dlhold)) then
4214  iic = iic + 1
4215  end if
4216  iic4 = 0
4217  if (iic3 > 7 .and. iic > 12) then
4218  iic4 = 1
4219  end if
4220  !
4221  ! -- switch to bisection when the Newton-Raphson method oscillates
4222  ! or when convergence is slow
4223  if (iic2 > 7 .or. iic > 12 .or. iic4 == 1) then
4224  ibflg = 1
4225  dpp = dhalf * (en1 + en2)
4226  end if
4227  !
4228  ! -- Calculate perturbed gwf flow
4229  call this%sfr_calc_qgwf(n, dpp, hgwf, qgwfp)
4230  qgwfp = -qgwfp
4231  if (qgwfp > qsrc) then
4232  qgwfp = qsrc
4233  if (abs(en1 - en2) < this%dmaxchg * dem6) then
4234  call this%sfr_calc_reach_depth(n, (qsrcmp - dhalf * qgwfp), dpp)
4235  end if
4236  end if
4237  call this%sfr_calc_reach_depth(n, (qsrcmp - dhalf * qgwfp), dx)
4238  end if
4239  !
4240  ! -- bisection to update end points
4241  fp = dpp - dx
4242  if (ibflg == 1) then
4243  dlh = fp
4244  ! -- change end points
4245  ! -- root is between f1 and fp
4246  if (f1 * fp < dzero) then
4247  en2 = dpp
4248  f2 = fp
4249  ! -- root is between fp and f2
4250  else
4251  en1 = dpp
4252  f1 = fp
4253  end if
4254  err = min(abs(fp), abs(en2 - en1))
4255  else
4256  err = abs(dlh)
4257  end if
4258  !
4259  ! -- check for convergence and exit if converged
4260  if (err < this%dmaxchg) then
4261  d1 = dpp
4262  qgwf = qgwfp
4263  qd = qsrc - qgwf
4264  exit
4265  end if
4266  !
4267  ! -- save iterates
4268  errold = err
4269  dlhold = dlh
4270  if (ibflg == 1) then
4271  qgwfold = qgwfp
4272  else
4273  qgwfold = qgwf1
4274  end if
4275  !
4276  ! -- end of iteration
4277  end do
4278  ! -- depth = 0 and hgwf < bt
4279  else
4280  call this%sfr_calc_qgwf(n, d1, hgwf, qgwf)
4281  qgwf = -qgwf
4282  !
4283  ! -- leakage exceeds inflow
4284  if (qgwf > qsrc) then
4285  d1 = dzero
4286  call this%sfr_calc_qsource(n, d1, qsrc)
4287  qgwf = qsrc
4288  end if
4289  ! -- set qd
4290  qd = qsrc - qgwf
4291  end if calc_solution
4292 

◆ 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 4400 of file gwf-sfr.f90.

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

◆ 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)  bots,
real(dp), intent(inout)  flow,
real(dp), intent(inout)  gwfhcof,
real(dp), intent(inout)  gwfrhs 
)

Method to galculate 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]botsbottom elevation of reach
[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 5970 of file gwf-sfr.f90.

5972  ! -- dummy variables
5973  class(SfrType), intent(inout) :: this !< SfrType object
5974  integer(I4B), intent(in) :: n !< reach number
5975  real(DP), intent(in) :: stage !< reach stage
5976  real(DP), intent(in) :: head !< head in connected GWF cell
5977  real(DP), intent(in) :: cond !< reach conductance
5978  real(DP), intent(in) :: bots !< bottom elevation of reach
5979  real(DP), intent(inout) :: flow !< calculated flow, updated here with density terms
5980  real(DP), intent(inout) :: gwfhcof !< GWF diagonal coefficient, updated here with density terms
5981  real(DP), intent(inout) :: gwfrhs !< GWF right-hand-side value, updated here with density terms
5982  ! -- local variables
5983  real(DP) :: ss
5984  real(DP) :: hh
5985  real(DP) :: havg
5986  real(DP) :: rdensesfr
5987  real(DP) :: rdensegwf
5988  real(DP) :: rdenseavg
5989  real(DP) :: elevsfr
5990  real(DP) :: elevgwf
5991  real(DP) :: elevavg
5992  real(DP) :: d1
5993  real(DP) :: d2
5994  logical(LGP) :: stage_below_bot
5995  logical(LGP) :: head_below_bot
5996  !
5997  ! -- Set sfr density to sfr density or gwf density
5998  if (stage >= bots) then
5999  ss = stage
6000  stage_below_bot = .false.
6001  rdensesfr = this%denseterms(1, n) ! sfr rel density
6002  else
6003  ss = bots
6004  stage_below_bot = .true.
6005  rdensesfr = this%denseterms(2, n) ! gwf rel density
6006  end if
6007  !
6008  ! -- set hh to head or bots
6009  if (head >= bots) then
6010  hh = head
6011  head_below_bot = .false.
6012  rdensegwf = this%denseterms(2, n) ! gwf rel density
6013  else
6014  hh = bots
6015  head_below_bot = .true.
6016  rdensegwf = this%denseterms(1, n) ! sfr rel density
6017  end if
6018  !
6019  ! -- todo: hack because denseterms not updated in a cf calculation
6020  if (rdensegwf == dzero) return
6021  !
6022  ! -- Update flow
6023  if (stage_below_bot .and. head_below_bot) then
6024  !
6025  ! -- flow is zero, so no terms are updated
6026  !
6027  else
6028  !
6029  ! -- calculate average relative density
6030  rdenseavg = dhalf * (rdensesfr + rdensegwf)
6031  !
6032  ! -- Add contribution of first density term:
6033  ! cond * (denseavg/denseref - 1) * (hgwf - hsfr)
6034  d1 = cond * (rdenseavg - done)
6035  gwfhcof = gwfhcof - d1
6036  gwfrhs = gwfrhs - d1 * ss
6037  d1 = d1 * (hh - ss)
6038  flow = flow + d1
6039  !
6040  ! -- Add second density term if stage and head not below bottom
6041  if (.not. stage_below_bot .and. .not. head_below_bot) then
6042  !
6043  ! -- Add contribution of second density term:
6044  ! cond * (havg - elevavg) * (densegwf - densesfr) / denseref
6045  elevgwf = this%denseterms(3, n)
6046  elevsfr = bots
6047  elevavg = dhalf * (elevsfr + elevgwf)
6048  havg = dhalf * (hh + ss)
6049  d2 = cond * (havg - elevavg) * (rdensegwf - rdensesfr)
6050  gwfrhs = gwfrhs + d2
6051  flow = flow + d2
6052  end if
6053  end if
6054  !
6055  ! -- return
6056  return

◆ 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 2162 of file gwf-sfr.f90.

2163  ! -- modules
2164  use tdismodule, only: totim, kstp, kper, delt
2165  ! -- dummy variables
2166  class(SfrType), intent(inout) :: this !< SfrType object
2167  integer(I4B), intent(in) :: innertot !< total number of inner iterations
2168  integer(I4B), intent(in) :: kiter !< Picard iteration number
2169  integer(I4B), intent(in) :: iend !< flag indicating if this is the last Picard iteration
2170  integer(I4B), intent(in) :: icnvgmod !< flag inficating if the model has met specific convergence criteria
2171  character(len=LENPAKLOC), intent(inout) :: cpak !< string for user node
2172  integer(I4B), intent(inout) :: ipak !< location of the maximum dependent variable change
2173  real(DP), intent(inout) :: dpak !< maximum dependent variable change
2174  ! -- local variables
2175  character(len=LENPAKLOC) :: cloc
2176  character(len=LINELENGTH) :: tag
2177  integer(I4B) :: icheck
2178  integer(I4B) :: ipakfail
2179  integer(I4B) :: locdhmax
2180  integer(I4B) :: locrmax
2181  integer(I4B) :: locdqfrommvrmax
2182  integer(I4B) :: ntabrows
2183  integer(I4B) :: ntabcols
2184  integer(I4B) :: n
2185  real(DP) :: q
2186  real(DP) :: q0
2187  real(DP) :: qtolfact
2188  real(DP) :: dh
2189  real(DP) :: r
2190  real(DP) :: dhmax
2191  real(DP) :: rmax
2192  real(DP) :: dqfrommvr
2193  real(DP) :: dqfrommvrmax
2194  !
2195  ! -- initialize local variables
2196  icheck = this%iconvchk
2197  ipakfail = 0
2198  locdhmax = 0
2199  locrmax = 0
2200  r = dzero
2201  dhmax = dzero
2202  rmax = dzero
2203  locdqfrommvrmax = 0
2204  dqfrommvrmax = dzero
2205  !
2206  ! -- if not saving package convergence data on check convergence if
2207  ! the model is considered converged
2208  if (this%ipakcsv == 0) then
2209  if (icnvgmod == 0) then
2210  icheck = 0
2211  end if
2212  !
2213  ! -- saving package convergence data
2214  else
2215  !
2216  ! -- header for package csv
2217  if (.not. associated(this%pakcsvtab)) then
2218  !
2219  ! -- determine the number of columns and rows
2220  ntabrows = 1
2221  ntabcols = 9
2222  if (this%imover == 1) then
2223  ntabcols = ntabcols + 2
2224  end if
2225  !
2226  ! -- setup table
2227  call table_cr(this%pakcsvtab, this%packName, '')
2228  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
2229  lineseparator=.false., separator=',', &
2230  finalize=.false.)
2231  !
2232  ! -- add columns to package csv
2233  tag = 'total_inner_iterations'
2234  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2235  tag = 'totim'
2236  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2237  tag = 'kper'
2238  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2239  tag = 'kstp'
2240  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2241  tag = 'nouter'
2242  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2243  tag = 'dvmax'
2244  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2245  tag = 'dvmax_loc'
2246  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2247  tag = 'dinflowmax'
2248  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2249  tag = 'dinflowmax_loc'
2250  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2251  if (this%imover == 1) then
2252  tag = 'dqfrommvrmax'
2253  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2254  tag = 'dqfrommvrmax_loc'
2255  call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
2256  end if
2257  end if
2258  end if
2259  !
2260  ! -- perform package convergence check
2261  if (icheck /= 0) then
2262  final_check: do n = 1, this%maxbound
2263  if (this%iboundpak(n) == 0) cycle
2264  !
2265  ! -- set the Q to length factor
2266  qtolfact = delt / this%calc_surface_area(n)
2267  !
2268  ! -- calculate stage change
2269  dh = this%stage0(n) - this%stage(n)
2270  !
2271  ! -- evaluate flow difference if the time step is transient
2272  if (this%gwfiss == 0) then
2273  r = this%usflow0(n) - this%usflow(n)
2274  !
2275  ! -- normalize flow difference and convert to a depth
2276  r = r * qtolfact
2277  end if
2278  !
2279  ! -- q from mvr
2280  dqfrommvr = dzero
2281  if (this%imover == 1) then
2282  q = this%pakmvrobj%get_qfrommvr(n)
2283  q0 = this%pakmvrobj%get_qfrommvr0(n)
2284  dqfrommvr = qtolfact * (q0 - q)
2285  end if
2286  !
2287  ! -- evaluate magnitude of differences
2288  if (n == 1) then
2289  locdhmax = n
2290  dhmax = dh
2291  locrmax = n
2292  rmax = r
2293  dqfrommvrmax = dqfrommvr
2294  locdqfrommvrmax = n
2295  else
2296  if (abs(dh) > abs(dhmax)) then
2297  locdhmax = n
2298  dhmax = dh
2299  end if
2300  if (abs(r) > abs(rmax)) then
2301  locrmax = n
2302  rmax = r
2303  end if
2304  if (abs(dqfrommvr) > abs(dqfrommvrmax)) then
2305  dqfrommvrmax = dqfrommvr
2306  locdqfrommvrmax = n
2307  end if
2308  end if
2309  end do final_check
2310  !
2311  ! -- set dpak and cpak
2312  if (abs(dhmax) > abs(dpak)) then
2313  ipak = locdhmax
2314  dpak = dhmax
2315  write (cloc, "(a,'-',a)") trim(this%packName), 'stage'
2316  cpak = trim(cloc)
2317  end if
2318  if (abs(rmax) > abs(dpak)) then
2319  ipak = locrmax
2320  dpak = rmax
2321  write (cloc, "(a,'-',a)") trim(this%packName), 'inflow'
2322  cpak = trim(cloc)
2323  end if
2324  if (this%imover == 1) then
2325  if (abs(dqfrommvrmax) > abs(dpak)) then
2326  ipak = locdqfrommvrmax
2327  dpak = dqfrommvrmax
2328  write (cloc, "(a,'-',a)") trim(this%packName), 'qfrommvr'
2329  cpak = trim(cloc)
2330  end if
2331  end if
2332  !
2333  ! -- write convergence data to package csv
2334  if (this%ipakcsv /= 0) then
2335  !
2336  ! -- write the data
2337  call this%pakcsvtab%add_term(innertot)
2338  call this%pakcsvtab%add_term(totim)
2339  call this%pakcsvtab%add_term(kper)
2340  call this%pakcsvtab%add_term(kstp)
2341  call this%pakcsvtab%add_term(kiter)
2342  call this%pakcsvtab%add_term(dhmax)
2343  call this%pakcsvtab%add_term(locdhmax)
2344  call this%pakcsvtab%add_term(rmax)
2345  call this%pakcsvtab%add_term(locrmax)
2346  if (this%imover == 1) then
2347  call this%pakcsvtab%add_term(dqfrommvrmax)
2348  call this%pakcsvtab%add_term(locdqfrommvrmax)
2349  end if
2350  !
2351  ! -- finalize the package csv
2352  if (iend == 1) then
2353  call this%pakcsvtab%finalize_table()
2354  end if
2355  end if
2356  end if
2357  !
2358  ! -- return
2359  return
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:32
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
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 1972 of file gwf-sfr.f90.

1973  ! -- dummy variables
1974  class(SfrType) :: this !< SfrType object
1975  ! -- local variables
1976  integer(I4B) :: n
1977  integer(I4B) :: igwfnode
1978  !
1979  ! -- return if no sfr reaches
1980  if (this%nbound == 0) return
1981  !
1982  ! -- find highest active cell
1983  do n = 1, this%nbound
1984  igwfnode = this%igwftopnode(n)
1985  if (igwfnode > 0) then
1986  if (this%ibound(igwfnode) == 0) then
1987  call this%dis%highest_active(igwfnode, this%ibound)
1988  end if
1989  end if
1990  this%igwfnode(n) = igwfnode
1991  this%nodelist(n) = igwfnode
1992  end do
1993  !
1994  ! -- return
1995  return

◆ 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 4617 of file gwf-sfr.f90.

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

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

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

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

◆ 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 5008 of file gwf-sfr.f90.

5009  ! -- dummy variables
5010  class(SfrType) :: this !< SfrType object
5011  ! -- local variables
5012  character(len=LINELENGTH) :: title
5013  character(len=LINELENGTH) :: text
5014  logical(LGP) :: lcycle
5015  logical(LGP) :: ladd
5016  character(len=5) :: crch
5017  character(len=5) :: crch2
5018  character(len=10) :: cval
5019  integer(I4B) :: maxcols
5020  integer(I4B) :: npairs
5021  integer(I4B) :: ipair
5022  integer(I4B) :: i
5023  integer(I4B) :: n
5024  integer(I4B) :: n2
5025  integer(I4B) :: idiv
5026  integer(I4B) :: i0
5027  integer(I4B) :: i1
5028  integer(I4B) :: jpos
5029  integer(I4B) :: ids
5030  real(DP) :: f
5031  real(DP) :: rval
5032  !
5033  ! -- write table header
5034  if (this%iprpak /= 0) then
5035  !
5036  ! -- determine the maximum number of columns
5037  npairs = 0
5038  do n = 1, this%maxbound
5039  ipair = 0
5040  ec: do i = this%ia(n) + 1, this%ia(n + 1) - 1
5041  !
5042  ! -- skip upstream connections
5043  if (this%idir(i) > 0) cycle ec
5044  n2 = this%ja(i)
5045  !
5046  ! -- skip inactive downstream reaches
5047  if (this%iboundpak(n2) == 0) cycle ec
5048  !
5049  ! -- increment ipair and see if it exceeds npairs
5050  ipair = ipair + 1
5051  npairs = max(npairs, ipair)
5052  end do ec
5053  end do
5054  maxcols = 1 + npairs * 2
5055  !
5056  ! -- reset the input table object
5057  title = trim(adjustl(this%text))//' PACKAGE ('// &
5058  trim(adjustl(this%packName))//') CONNECTED REACH UPSTREAM '// &
5059  'FRACTION DATA'
5060  call table_cr(this%inputtab, this%packName, title)
5061  call this%inputtab%table_df(this%maxbound, maxcols, this%iout)
5062  text = 'REACH'
5063  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5064  do i = 1, npairs
5065  write (cval, '(i10)') i
5066  text = 'DOWNSTREAM REACH '//trim(adjustl(cval))
5067  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
5068  text = 'FRACTION '//trim(adjustl(cval))
5069  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
5070  end do
5071  end if
5072  !
5073  ! -- fill diversion number for each connection
5074  do n = 1, this%maxbound
5075  do idiv = 1, this%ndiv(n)
5076  i0 = this%iadiv(n)
5077  i1 = this%iadiv(n + 1) - 1
5078  do jpos = i0, i1
5079  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5080  n2 = this%ja(i)
5081  if (this%divreach(jpos) == n2) then
5082  this%idiv(i) = jpos - i0 + 1
5083  exit
5084  end if
5085  end do
5086  end do
5087  end do
5088  end do
5089  !
5090  ! -- check that the upstream fraction for reach connected by
5091  ! a diversion is zero
5092  do n = 1, this%maxbound
5093  !
5094  ! -- determine the number of downstream reaches
5095  ids = 0
5096  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5097  if (this%idir(i) < 0) then
5098  ids = ids + 1
5099  end if
5100  end do
5101  !
5102  ! -- evaluate the diversions
5103  do idiv = 1, this%ndiv(n)
5104  jpos = this%iadiv(n) + idiv - 1
5105  n2 = this%divreach(jpos)
5106  f = this%ustrf(n2)
5107  if (f /= dzero) then
5108  write (errmsg, '(a,2(1x,i0,1x,a),1x,a,g0,a,2(1x,a))') &
5109  'Reach', n, 'is connected to reach', n2, 'by a diversion', &
5110  'but the upstream fraction is not equal to zero (', f, '). Check', &
5111  trim(this%packName), 'package diversion and package data.'
5112  if (ids > 1) then
5113  call store_error(errmsg)
5114  else
5115  write (warnmsg, '(a,3(1x,a))') &
5116  trim(warnmsg), &
5117  'A warning instead of an error is issued because', &
5118  'the reach is only connected to the diversion reach in the ', &
5119  'downstream direction.'
5120  call store_warning(warnmsg)
5121  end if
5122  end if
5123  end do
5124  end do
5125  !
5126  ! -- calculate the total fraction of connected reaches that are
5127  ! not diversions and check that the sum of upstream fractions
5128  ! is equal to 1 for each reach
5129  do n = 1, this%maxbound
5130  ids = 0
5131  rval = dzero
5132  f = dzero
5133  write (crch, '(i5)') n
5134  if (this%iprpak /= 0) then
5135  call this%inputtab%add_term(n)
5136  end if
5137  ipair = 0
5138  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
5139  lcycle = .false.
5140  !
5141  ! -- initialize downstream connection q
5142  this%qconn(i) = dzero
5143  !
5144  ! -- skip upstream connections
5145  if (this%idir(i) > 0) then
5146  lcycle = .true.
5147  end if
5148  n2 = this%ja(i)
5149  !
5150  ! -- skip inactive downstream reaches
5151  if (this%iboundpak(n2) == 0) then
5152  lcycle = .true.
5153  end if
5154  if (lcycle) then
5155  cycle eachconn
5156  end if
5157  ipair = ipair + 1
5158  write (crch2, '(i5)') n2
5159  ids = ids + 1
5160  ladd = .true.
5161  f = f + this%ustrf(n2)
5162  write (cval, '(f10.4)') this%ustrf(n2)
5163  !
5164  ! -- write upstream fractions
5165  if (this%iprpak /= 0) then
5166  call this%inputtab%add_term(n2)
5167  call this%inputtab%add_term(this%ustrf(n2))
5168  end if
5169  eachdiv: do idiv = 1, this%ndiv(n)
5170  jpos = this%iadiv(n) + idiv - 1
5171  if (this%divreach(jpos) == n2) then
5172  ladd = .false.
5173  exit eachdiv
5174  end if
5175  end do eachdiv
5176  if (ladd) then
5177  rval = rval + this%ustrf(n2)
5178  end if
5179  end do eachconn
5180  this%ftotnd(n) = rval
5181  !
5182  ! -- write remaining table columns
5183  if (this%iprpak /= 0) then
5184  ipair = ipair + 1
5185  do i = ipair, npairs
5186  call this%inputtab%add_term(' ')
5187  call this%inputtab%add_term(' ')
5188  end do
5189  end if
5190  !
5191  ! -- evaluate if an error condition has occurred
5192  ! the sum of fractions is not equal to 1
5193  if (ids /= 0) then
5194  if (abs(f - done) > dem6) then
5195  write (errmsg, '(a,1x,i0,1x,a,g0,a,3(1x,a))') &
5196  'Upstream fractions for reach ', n, 'is not equal to one (', f, &
5197  '). Check', trim(this%packName), 'package reach connectivity and', &
5198  'package data.'
5199  call store_error(errmsg)
5200  end if
5201  end if
5202  end do
5203  !
5204  ! -- return
5205  return
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 2367 of file gwf-sfr.f90.

2368  ! -- modules
2369  use budgetmodule, only: budgettype
2370  ! -- dummy variables
2371  class(SfrType), intent(inout) :: this !< SfrType object
2372  real(DP), dimension(:), intent(in) :: x !< current dependent-variable value
2373  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
2374  integer(I4B), optional, intent(in) :: iadv !< flag that indicates if this is an advance package
2375  ! -- local variables
2376  integer(I4B) :: i
2377  real(DP) :: qext
2378  ! -- for budget
2379  integer(I4B) :: n
2380  integer(I4B) :: n2
2381  real(DP) :: qoutflow
2382  real(DP) :: qfrommvr
2383  real(DP) :: qtomvr
2384  !
2385  ! -- call base functionality in bnd_cq. This will calculate sfr-gwf flows
2386  ! and put them into this%simvals
2387  call this%BndType%bnd_cq(x, flowja, iadv=1)
2388  !
2389  ! -- Calculate qextoutflow and qoutflow for subsequent budgets
2390  do n = 1, this%maxbound
2391  !
2392  ! -- mover
2393  qfrommvr = dzero
2394  qtomvr = dzero
2395  if (this%imover == 1) then
2396  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
2397  qtomvr = this%pakmvrobj%get_qtomvr(n)
2398  if (qtomvr > dzero) then
2399  qtomvr = -qtomvr
2400  end if
2401  end if
2402  !
2403  ! -- external downstream stream flow
2404  qext = this%dsflow(n)
2405  qoutflow = dzero
2406  if (qext > dzero) then
2407  qext = -qext
2408  end if
2409  do i = this%ia(n) + 1, this%ia(n + 1) - 1
2410  if (this%idir(i) > 0) cycle
2411  n2 = this%ja(i)
2412  if (this%iboundpak(n2) == 0) cycle
2413  qext = dzero
2414  exit
2415  end do
2416  !
2417  ! -- adjust external downstream stream flow using qtomvr
2418  if (qext < dzero) then
2419  if (qtomvr < dzero) then
2420  qext = qext - qtomvr
2421  end if
2422  else
2423  qoutflow = this%dsflow(n)
2424  if (qoutflow > dzero) then
2425  qoutflow = -qoutflow
2426  end if
2427  end if
2428  !
2429  ! -- set qextoutflow and qoutflow for cell by cell budget
2430  ! output and observations
2431  this%qextoutflow(n) = qext
2432  this%qoutflow(n) = qoutflow
2433  !
2434  end do
2435  !
2436  ! -- fill the budget object
2437  call this%sfr_fill_budobj()
2438  !
2439  ! -- return
2440  return
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 235 of file gwf-sfr.f90.

236  ! -- modules
238  ! -- dummy variables
239  class(BndType), pointer :: packobj !< pointer to default package type
240  integer(I4B), intent(in) :: id !< package id
241  integer(I4B), intent(in) :: ibcnum !< boundary condition number
242  integer(I4B), intent(in) :: inunit !< unit number of SFR package input file
243  integer(I4B), intent(in) :: iout !< unit number of model listing file
244  character(len=*), intent(in) :: namemodel !< model name
245  character(len=*), intent(in) :: pakname !< package name
246  ! -- local variables
247  type(SfrType), pointer :: sfrobj
248  !
249  ! -- allocate the object and assign values to object variables
250  allocate (sfrobj)
251  packobj => sfrobj
252  !
253  ! -- create name and memory path
254  call packobj%set_names(ibcnum, namemodel, pakname, ftype)
255  packobj%text = text
256  !
257  ! -- allocate scalars
258  call sfrobj%sfr_allocate_scalars()
259  !
260  ! -- initialize package
261  call packobj%pack_initialize()
262 
263  packobj%inunit = inunit
264  packobj%iout = iout
265  packobj%id = id
266  packobj%ibcnum = ibcnum
267  packobj%ncolbnd = 4
268  packobj%iscloc = 0 ! not supported
269  packobj%isadvpak = 1
270  packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
271  !
272  ! -- return
273  return
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)

Deallocate SFR package scalars and arrays.

Parameters
thisSfrType object

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

2643  ! -- modules
2645  ! -- dummy variables
2646  class(SfrType) :: this !< SfrType object
2647  !
2648  ! -- deallocate arrays
2649  call mem_deallocate(this%qoutflow)
2650  call mem_deallocate(this%qextoutflow)
2651  deallocate (this%csfrbudget)
2652  call mem_deallocate(this%sfrname, 'SFRNAME', this%memoryPath)
2653  call mem_deallocate(this%dbuff)
2654  deallocate (this%cauxcbc)
2655  call mem_deallocate(this%qauxcbc)
2656  call mem_deallocate(this%iboundpak)
2657  call mem_deallocate(this%igwfnode)
2658  call mem_deallocate(this%igwftopnode)
2659  call mem_deallocate(this%length)
2660  call mem_deallocate(this%width)
2661  call mem_deallocate(this%strtop)
2662  call mem_deallocate(this%bthick)
2663  call mem_deallocate(this%hk)
2664  call mem_deallocate(this%slope)
2665  call mem_deallocate(this%nconnreach)
2666  call mem_deallocate(this%ustrf)
2667  call mem_deallocate(this%ftotnd)
2668  call mem_deallocate(this%usflow)
2669  call mem_deallocate(this%dsflow)
2670  call mem_deallocate(this%depth)
2671  call mem_deallocate(this%stage)
2672  call mem_deallocate(this%gwflow)
2673  call mem_deallocate(this%simevap)
2674  call mem_deallocate(this%simrunoff)
2675  call mem_deallocate(this%stage0)
2676  call mem_deallocate(this%usflow0)
2677  call mem_deallocate(this%denseterms)
2678  call mem_deallocate(this%viscratios)
2679  !
2680  ! -- deallocate reach order and connection data
2681  call mem_deallocate(this%isfrorder)
2682  call mem_deallocate(this%ia)
2683  call mem_deallocate(this%ja)
2684  call mem_deallocate(this%idir)
2685  call mem_deallocate(this%idiv)
2686  call mem_deallocate(this%qconn)
2687  !
2688  ! -- deallocate boundary data
2689  call mem_deallocate(this%rough)
2690  call mem_deallocate(this%rain)
2691  call mem_deallocate(this%evap)
2692  call mem_deallocate(this%inflow)
2693  call mem_deallocate(this%runoff)
2694  call mem_deallocate(this%sstage)
2695  !
2696  ! -- deallocate aux variables
2697  call mem_deallocate(this%rauxvar)
2698  !
2699  ! -- deallocate diversion variables
2700  call mem_deallocate(this%iadiv)
2701  call mem_deallocate(this%divreach)
2702  if (associated(this%divcprior)) then
2703  deallocate (this%divcprior)
2704  end if
2705  call mem_deallocate(this%divflow)
2706  call mem_deallocate(this%divq)
2707  call mem_deallocate(this%ndiv)
2708  !
2709  ! -- deallocate cross-section data
2710  call mem_deallocate(this%ncrosspts)
2711  call mem_deallocate(this%iacross)
2712  call mem_deallocate(this%station)
2713  call mem_deallocate(this%xsheight)
2714  call mem_deallocate(this%xsrough)
2715  !
2716  ! -- deallocate budobj
2717  call this%budobj%budgetobject_da()
2718  deallocate (this%budobj)
2719  nullify (this%budobj)
2720  !
2721  ! -- deallocate stage table
2722  if (this%iprhed > 0) then
2723  call this%stagetab%table_da()
2724  deallocate (this%stagetab)
2725  nullify (this%stagetab)
2726  end if
2727  !
2728  ! -- deallocate package csv table
2729  if (this%ipakcsv > 0) then
2730  if (associated(this%pakcsvtab)) then
2731  call this%pakcsvtab%table_da()
2732  deallocate (this%pakcsvtab)
2733  nullify (this%pakcsvtab)
2734  end if
2735  end if
2736  !
2737  ! -- deallocate scalars
2738  call mem_deallocate(this%iprhed)
2739  call mem_deallocate(this%istageout)
2740  call mem_deallocate(this%ibudgetout)
2741  call mem_deallocate(this%ibudcsv)
2742  call mem_deallocate(this%ipakcsv)
2743  call mem_deallocate(this%idiversions)
2744  call mem_deallocate(this%maxsfrpicard)
2745  call mem_deallocate(this%maxsfrit)
2746  call mem_deallocate(this%bditems)
2747  call mem_deallocate(this%cbcauxitems)
2748  call mem_deallocate(this%unitconv)
2749  call mem_deallocate(this%lengthconv)
2750  call mem_deallocate(this%timeconv)
2751  call mem_deallocate(this%dmaxchg)
2752  call mem_deallocate(this%deps)
2753  call mem_deallocate(this%nconn)
2754  call mem_deallocate(this%icheck)
2755  call mem_deallocate(this%iconvchk)
2756  call mem_deallocate(this%idense)
2757  call mem_deallocate(this%ianynone)
2758  call mem_deallocate(this%ncrossptstot)
2759  nullify (this%gwfiss)
2760  !
2761  ! -- call base BndType deallocate
2762  call this%BndType%bnd_da()
2763  !
2764  ! -- return
2765  return

◆ 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 2826 of file gwf-sfr.f90.

2827  ! -- dummy variables
2828  class(SfrType) :: this !< SfrType object
2829  ! -- local variables
2830  integer(I4B) :: indx
2831  !
2832  ! -- Store obs type and assign procedure pointer
2833  ! for stage observation type.
2834  call this%obs%StoreObsType('stage', .false., indx)
2835  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2836  !
2837  ! -- Store obs type and assign procedure pointer
2838  ! for inflow observation type.
2839  call this%obs%StoreObsType('inflow', .true., indx)
2840  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2841  !
2842  ! -- Store obs type and assign procedure pointer
2843  ! for inflow observation type.
2844  call this%obs%StoreObsType('ext-inflow', .true., indx)
2845  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2846  !
2847  ! -- Store obs type and assign procedure pointer
2848  ! for rainfall observation type.
2849  call this%obs%StoreObsType('rainfall', .true., indx)
2850  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2851  !
2852  ! -- Store obs type and assign procedure pointer
2853  ! for runoff observation type.
2854  call this%obs%StoreObsType('runoff', .true., indx)
2855  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2856  !
2857  ! -- Store obs type and assign procedure pointer
2858  ! for evaporation observation type.
2859  call this%obs%StoreObsType('evaporation', .true., indx)
2860  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2861  !
2862  ! -- Store obs type and assign procedure pointer
2863  ! for outflow observation type.
2864  call this%obs%StoreObsType('outflow', .true., indx)
2865  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2866  !
2867  ! -- Store obs type and assign procedure pointer
2868  ! for ext-outflow observation type.
2869  call this%obs%StoreObsType('ext-outflow', .true., indx)
2870  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2871  !
2872  ! -- Store obs type and assign procedure pointer
2873  ! for to-mvr observation type.
2874  call this%obs%StoreObsType('to-mvr', .true., indx)
2875  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2876  !
2877  ! -- Store obs type and assign procedure pointer
2878  ! for sfr-frommvr observation type.
2879  call this%obs%StoreObsType('from-mvr', .true., indx)
2880  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2881  !
2882  ! -- Store obs type and assign procedure pointer
2883  ! for sfr observation type.
2884  call this%obs%StoreObsType('sfr', .true., indx)
2885  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2886  !
2887  ! -- Store obs type and assign procedure pointer
2888  ! for upstream flow observation type.
2889  call this%obs%StoreObsType('upstream-flow', .true., indx)
2890  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2891  !
2892  ! -- Store obs type and assign procedure pointer
2893  ! for downstream flow observation type.
2894  call this%obs%StoreObsType('downstream-flow', .true., indx)
2895  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2896  !
2897  ! -- Store obs type and assign procedure pointer
2898  ! for depth observation type.
2899  call this%obs%StoreObsType('depth', .false., indx)
2900  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2901  !
2902  ! -- Store obs type and assign procedure pointer
2903  ! for wetted-perimeter observation type.
2904  call this%obs%StoreObsType('wet-perimeter', .false., indx)
2905  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2906  !
2907  ! -- Store obs type and assign procedure pointer
2908  ! for wetted-area observation type.
2909  call this%obs%StoreObsType('wet-area', .false., indx)
2910  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2911  !
2912  ! -- Store obs type and assign procedure pointer
2913  ! for wetted-width observation type.
2914  call this%obs%StoreObsType('wet-width', .false., indx)
2915  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
2916  !
2917  ! -- return
2918  return
Here is the call graph for this function:

◆ 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 2004 of file gwf-sfr.f90.

2005  ! -- dummy variables
2006  class(SfrType) :: this !< SfrType object
2007  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2008  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2009  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2010  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2011  ! -- local variables
2012  integer(I4B) :: i
2013  integer(I4B) :: j
2014  integer(I4B) :: n
2015  integer(I4B) :: ipos
2016  integer(I4B) :: node
2017  real(DP) :: s0
2018  real(DP) :: ds
2019  real(DP) :: dsmax
2020  real(DP) :: hgwf
2021  real(DP) :: v
2022  real(DP) :: hhcof
2023  real(DP) :: rrhs
2024  !
2025  ! -- picard iterations for sfr to achieve good solution regardless
2026  ! of reach order
2027  sfrpicard: do i = 1, this%maxsfrpicard
2028  !
2029  ! -- initialize maximum stage change for iteration to zero
2030  dsmax = dzero
2031  !
2032  ! -- pakmvrobj fc - reset qformvr to zero
2033  if (this%imover == 1) then
2034  call this%pakmvrobj%fc()
2035  end if
2036  !
2037  ! -- solve for each sfr reach
2038  reachsolve: do j = 1, this%nbound
2039  n = this%isfrorder(j)
2040  node = this%igwfnode(n)
2041  if (node > 0) then
2042  hgwf = this%xnew(node)
2043  else
2044  hgwf = dep20
2045  end if
2046  !
2047  ! -- save previous stage and upstream flow
2048  if (i == 1) then
2049  this%stage0(n) = this%stage(n)
2050  this%usflow0(n) = this%usflow(n)
2051  end if
2052  !
2053  ! -- set initial stage to calculate stage change
2054  s0 = this%stage(n)
2055  !
2056  ! -- solve for flow in swr
2057  if (this%iboundpak(n) /= 0) then
2058  call this%sfr_solve(n, hgwf, hhcof, rrhs)
2059  else
2060  this%depth(n) = dzero
2061  this%stage(n) = this%strtop(n)
2062  v = dzero
2063  call this%sfr_update_flows(n, v, v)
2064  hhcof = dzero
2065  rrhs = dzero
2066  end if
2067  !
2068  ! -- set package hcof and rhs
2069  this%hcof(n) = hhcof
2070  this%rhs(n) = rrhs
2071  !
2072  ! -- calculate stage change
2073  ds = s0 - this%stage(n)
2074  !
2075  ! -- evaluate if stage change exceeds dsmax
2076  if (abs(ds) > abs(dsmax)) then
2077  dsmax = ds
2078  end if
2079 
2080  end do reachsolve
2081  !
2082  ! -- evaluate if the sfr picard iterations should be terminated
2083  if (abs(dsmax) <= this%dmaxchg) then
2084  exit sfrpicard
2085  end if
2086 
2087  end do sfrpicard
2088  !
2089  ! -- Copy package rhs and hcof into solution rhs and amat
2090  do n = 1, this%nbound
2091  node = this%nodelist(n)
2092  if (node < 1) cycle
2093  rhs(node) = rhs(node) + this%rhs(n)
2094  ipos = ia(node)
2095  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(n))
2096  end do
2097  !
2098  ! -- return
2099  return

◆ 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 5434 of file gwf-sfr.f90.

5435  ! -- dummy variables
5436  class(SfrType) :: this !< SfrType object
5437  ! -- local variables
5438  integer(I4B) :: naux
5439  integer(I4B) :: i
5440  integer(I4B) :: n
5441  integer(I4B) :: n1
5442  integer(I4B) :: n2
5443  integer(I4B) :: ii
5444  integer(I4B) :: idx
5445  integer(I4B) :: idiv
5446  integer(I4B) :: jpos
5447  real(DP) :: q
5448  real(DP) :: qt
5449  real(DP) :: d
5450  real(DP) :: ca
5451  real(DP) :: a
5452  real(DP) :: wp
5453  real(DP) :: l
5454  !
5455  ! -- initialize counter
5456  idx = 0
5457  !
5458  ! -- FLOW JA FACE
5459  idx = idx + 1
5460  call this%budobj%budterm(idx)%reset(this%nconn)
5461  do n = 1, this%maxbound
5462  n1 = n
5463  q = dzero
5464  ca = dzero
5465  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5466  n2 = this%ja(i)
5467  if (this%iboundpak(n) /= 0) then
5468  ! flow to downstream reaches
5469  if (this%idir(i) < 0) then
5470  qt = this%dsflow(n)
5471  q = -this%qconn(i)
5472  ! flow from upstream reaches
5473  else
5474  qt = this%usflow(n)
5475  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
5476  if (this%idir(ii) > 0) cycle
5477  if (this%ja(ii) /= n) cycle
5478  q = this%qconn(ii)
5479  exit
5480  end do
5481  end if
5482  ! calculate flow area
5483  call this%sfr_calc_reach_depth(n, qt, d)
5484  ca = this%calc_area_wet(n, d)
5485  else
5486  q = dzero
5487  ca = dzero
5488  end if
5489  this%qauxcbc(1) = ca
5490  call this%budobj%budterm(idx)%update_term(n1, n2, q, this%qauxcbc)
5491  end do
5492  end do
5493  !
5494  ! -- GWF (LEAKAGE)
5495  idx = idx + 1
5496  call this%budobj%budterm(idx)%reset(this%maxbound - this%ianynone)
5497  do n = 1, this%maxbound
5498  n2 = this%igwfnode(n)
5499  if (n2 > 0) then
5500  if (this%iboundpak(n) /= 0) then
5501  ! -- calc_perimeter_wet() does not enforce depth dependence
5502  if (this%depth(n) > dzero) then
5503  wp = this%calc_perimeter_wet(n, this%depth(n))
5504  else
5505  wp = dzero
5506  end if
5507  l = this%length(n)
5508  a = wp * l
5509  this%qauxcbc(1) = a
5510  q = -this%gwflow(n)
5511  else
5512  this%qauxcbc(1) = dzero
5513  q = dzero
5514  end if
5515  call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
5516  end if
5517  end do
5518  !
5519  ! -- RAIN
5520  idx = idx + 1
5521  call this%budobj%budterm(idx)%reset(this%maxbound)
5522  do n = 1, this%maxbound
5523  if (this%iboundpak(n) /= 0) then
5524  a = this%calc_surface_area(n)
5525  q = this%rain(n) * a
5526  else
5527  q = dzero
5528  end if
5529  call this%budobj%budterm(idx)%update_term(n, n, q)
5530  end do
5531  !
5532  ! -- EVAPORATION
5533  idx = idx + 1
5534  call this%budobj%budterm(idx)%reset(this%maxbound)
5535  do n = 1, this%maxbound
5536  if (this%iboundpak(n) /= 0) then
5537  q = -this%simevap(n)
5538  else
5539  q = dzero
5540  end if
5541  call this%budobj%budterm(idx)%update_term(n, n, q)
5542  end do
5543  !
5544  ! -- RUNOFF
5545  idx = idx + 1
5546  call this%budobj%budterm(idx)%reset(this%maxbound)
5547  do n = 1, this%maxbound
5548  if (this%iboundpak(n) /= 0) then
5549  q = this%simrunoff(n)
5550  else
5551  q = dzero
5552  end if
5553  call this%budobj%budterm(idx)%update_term(n, n, q)
5554  end do
5555  !
5556  ! -- INFLOW
5557  idx = idx + 1
5558  call this%budobj%budterm(idx)%reset(this%maxbound)
5559  do n = 1, this%maxbound
5560  if (this%iboundpak(n) /= 0) then
5561  q = this%inflow(n)
5562  else
5563  q = dzero
5564  end if
5565  call this%budobj%budterm(idx)%update_term(n, n, q)
5566  end do
5567  !
5568  ! -- EXTERNAL OUTFLOW
5569  idx = idx + 1
5570  call this%budobj%budterm(idx)%reset(this%maxbound)
5571  do n = 1, this%maxbound
5572  q = dzero
5573  if (this%iboundpak(n) /= 0) then
5574  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5575  if (this%idir(i) > 0) cycle
5576  idiv = this%idiv(i)
5577  if (idiv > 0) then
5578  jpos = this%iadiv(n) + idiv - 1
5579  q = q + this%divq(jpos)
5580  else
5581  q = q + this%qconn(i)
5582  end if
5583  end do
5584  q = q - this%dsflow(n)
5585  if (this%imover == 1) then
5586  q = q + this%pakmvrobj%get_qtomvr(n)
5587  end if
5588  else
5589  if (this%imover == 1) then
5590  q = this%pakmvrobj%get_qfrommvr(n)
5591  end if
5592  end if
5593  call this%budobj%budterm(idx)%update_term(n, n, q)
5594  end do
5595  !
5596  ! -- STORAGE
5597  idx = idx + 1
5598  call this%budobj%budterm(idx)%reset(this%maxbound)
5599  do n = 1, this%maxbound
5600  q = dzero
5601  if (this%iboundpak(n) /= 0) then
5602  d = this%depth(n)
5603  a = this%calc_surface_area_wet(n, d)
5604  this%qauxcbc(1) = a * d
5605  else
5606  q = dzero
5607  this%qauxcbc(1) = dzero
5608  end if
5609  call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
5610  end do
5611  !
5612  ! -- MOVER
5613  if (this%imover == 1) then
5614  !
5615  ! -- FROM MOVER
5616  idx = idx + 1
5617  call this%budobj%budterm(idx)%reset(this%maxbound)
5618  do n = 1, this%maxbound
5619  q = dzero
5620  if (this%iboundpak(n) /= 0) then
5621  q = this%pakmvrobj%get_qfrommvr(n)
5622  end if
5623  call this%budobj%budterm(idx)%update_term(n, n, q)
5624  end do
5625  !
5626  ! -- TO MOVER
5627  idx = idx + 1
5628  call this%budobj%budterm(idx)%reset(this%maxbound)
5629  do n = 1, this%maxbound
5630  if (this%iboundpak(n) /= 0) then
5631  q = this%pakmvrobj%get_qtomvr(n)
5632  if (q > dzero) then
5633  q = -q
5634  end if
5635  else
5636  q = dzero
5637  end if
5638  call this%budobj%budterm(idx)%update_term(n, n, q)
5639  end do
5640  end if
5641  !
5642  ! -- AUXILIARY VARIABLES
5643  naux = this%naux
5644  if (naux > 0) then
5645  idx = idx + 1
5646  call this%budobj%budterm(idx)%reset(this%maxbound)
5647  do n = 1, this%maxbound
5648  q = dzero
5649  call this%budobj%budterm(idx)%update_term(n, n, q, this%auxvar(:, n))
5650  end do
5651  end if
5652  !
5653  ! --Terms are filled, now accumulate them for this time step
5654  call this%budobj%accumulate_terms()
5655  !
5656  ! -- return
5657  return

◆ 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 2108 of file gwf-sfr.f90.

2109  ! -- dummy variables
2110  class(SfrType) :: this !< SfrType object
2111  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2112  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2113  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2114  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2115  ! -- local variables
2116  integer(I4B) :: i
2117  integer(I4B) :: j
2118  integer(I4B) :: n
2119  integer(I4B) :: ipos
2120  real(DP) :: rterm
2121  real(DP) :: drterm
2122  real(DP) :: rhs1
2123  real(DP) :: hcof1
2124  real(DP) :: q1
2125  real(DP) :: q2
2126  real(DP) :: hgwf
2127  !
2128  ! -- Copy package rhs and hcof into solution rhs and amat
2129  do j = 1, this%nbound
2130  i = this%isfrorder(j)
2131  ! -- skip inactive reaches
2132  if (this%iboundpak(i) < 1) cycle
2133  ! -- skip if reach is not connected to gwf
2134  n = this%nodelist(i)
2135  if (n < 1) cycle
2136  ipos = ia(n)
2137  rterm = this%hcof(i) * this%xnew(n)
2138  ! -- calculate perturbed head
2139  hgwf = this%xnew(n) + dem4
2140  call this%sfr_solve(i, hgwf, hcof1, rhs1, update=.false.)
2141  q1 = rhs1 - hcof1 * hgwf
2142  ! -- calculate unperturbed head
2143  q2 = this%rhs(i) - this%hcof(i) * this%xnew(n)
2144  ! -- calculate derivative
2145  drterm = (q2 - q1) / dem4
2146  ! -- add terms to convert conductance formulation into
2147  ! newton-raphson formulation
2148  call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(i))
2149  rhs(n) = rhs(n) - rterm + drterm * this%xnew(n)
2150  end do
2151  !
2152  ! -- return
2153  return

◆ 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 3900 of file gwf-sfr.f90.

3901  ! -- return variable
3902  integer(I4B) :: sfr_gwf_conn !< flag indicating if reach is connected to a gwf cell
3903  ! -- dummy variables
3904  class(SfrType) :: this !< SfrType object
3905  integer(I4B), intent(in) :: n !< reach number
3906  ! -- local variables
3907  integer(I4B) :: node
3908 
3909  sfr_gwf_conn = 0
3910  node = this%igwfnode(n)
3911  if (node > 0 .and. this%hk(n) > dzero) then
3912  sfr_gwf_conn = 1
3913  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 2810 of file gwf-sfr.f90.

2811  ! -- dummy variables
2812  class(SfrType) :: this !< SfrType object
2813  !
2814  ! -- set boolean
2815  sfr_obs_supported = .true.
2816  !
2817  ! -- return
2818  return

◆ 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 629 of file gwf-sfr.f90.

630  ! -- modules
631  use openspecmodule, only: access, form
633  ! -- dummy variables
634  class(SfrType), intent(inout) :: this !< SfrType object
635  character(len=*), intent(inout) :: option !< option keyword string
636  logical(LGP), intent(inout) :: found !< boolean indicating if option found
637  ! -- local variables
638  real(DP) :: r
639  character(len=MAXCHARLEN) :: fname
640  character(len=MAXCHARLEN) :: keyword
641  ! -- formats
642  character(len=*), parameter :: fmttimeconv = &
643  &"(4x, 'TIME CONVERSION VALUE (',g0,') SPECIFIED.')"
644  character(len=*), parameter :: fmtlengthconv = &
645  &"(4x, 'LENGTH CONVERSION VALUE (',g0,') SPECIFIED.')"
646  character(len=*), parameter :: fmtpicard = &
647  &"(4x, 'MAXIMUM SFR PICARD ITERATION VALUE (',i0,') SPECIFIED.')"
648  character(len=*), parameter :: fmtiter = &
649  &"(4x, 'MAXIMUM SFR ITERATION VALUE (',i0,') SPECIFIED.')"
650  character(len=*), parameter :: fmtdmaxchg = &
651  &"(4x, 'MAXIMUM DEPTH CHANGE VALUE (',g0,') SPECIFIED.')"
652  character(len=*), parameter :: fmtsfrbin = &
653  "(4x, 'SFR ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', a, /4x, &
654  &'OPENED ON UNIT: ', I0)"
655  !
656  ! -- Check for SFR options
657  found = .true.
658  select case (option)
659  case ('PRINT_STAGE')
660  this%iprhed = 1
661  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
662  ' STAGES WILL BE PRINTED TO LISTING FILE.'
663  case ('STAGE')
664  call this%parser%GetStringCaps(keyword)
665  if (keyword == 'FILEOUT') then
666  call this%parser%GetString(fname)
667  this%istageout = getunit()
668  call openfile(this%istageout, this%iout, fname, 'DATA(BINARY)', &
669  form, access, 'REPLACE', mnormal)
670  write (this%iout, fmtsfrbin) &
671  'STAGE', trim(adjustl(fname)), this%istageout
672  else
673  call store_error('Optional stage keyword must &
674  &be followed by fileout.')
675  end if
676  case ('BUDGET')
677  call this%parser%GetStringCaps(keyword)
678  if (keyword == 'FILEOUT') then
679  call this%parser%GetString(fname)
680  this%ibudgetout = getunit()
681  call openfile(this%ibudgetout, this%iout, fname, 'DATA(BINARY)', &
682  form, access, 'REPLACE', mnormal)
683  write (this%iout, fmtsfrbin) &
684  'BUDGET', trim(adjustl(fname)), this%ibudgetout
685  else
686  call store_error('Optional budget keyword must be '// &
687  'followed by fileout.')
688  end if
689  case ('BUDGETCSV')
690  call this%parser%GetStringCaps(keyword)
691  if (keyword == 'FILEOUT') then
692  call this%parser%GetString(fname)
693  this%ibudcsv = getunit()
694  call openfile(this%ibudcsv, this%iout, fname, 'CSV', &
695  filstat_opt='REPLACE')
696  write (this%iout, fmtsfrbin) &
697  'BUDGET CSV', trim(adjustl(fname)), this%ibudcsv
698  else
699  call store_error('OPTIONAL BUDGETCSV KEYWORD MUST BE FOLLOWED BY &
700  &FILEOUT')
701  end if
702  case ('PACKAGE_CONVERGENCE')
703  call this%parser%GetStringCaps(keyword)
704  if (keyword == 'FILEOUT') then
705  call this%parser%GetString(fname)
706  this%ipakcsv = getunit()
707  call openfile(this%ipakcsv, this%iout, fname, 'CSV', &
708  filstat_opt='REPLACE', mode_opt=mnormal)
709  write (this%iout, fmtsfrbin) &
710  'PACKAGE_CONVERGENCE', trim(adjustl(fname)), this%ipakcsv
711  else
712  call store_error('Optional package_convergence keyword must be '// &
713  'followed by fileout.')
714  end if
715  case ('UNIT_CONVERSION')
716  this%unitconv = this%parser%GetDouble()
717  !
718  ! -- create warning message
719  write (warnmsg, '(a)') &
720  'SETTING UNIT_CONVERSION DIRECTLY'
721  !
722  ! -- create deprecation warning
723  call deprecation_warning('OPTIONS', 'UNIT_CONVERSION', '6.4.2', &
724  warnmsg, this%parser%GetUnit())
725  case ('LENGTH_CONVERSION')
726  this%lengthconv = this%parser%GetDouble()
727  write (this%iout, fmtlengthconv) this%lengthconv
728  case ('TIME_CONVERSION')
729  this%timeconv = this%parser%GetDouble()
730  write (this%iout, fmttimeconv) this%timeconv
731  case ('MAXIMUM_PICARD_ITERATIONS')
732  this%maxsfrpicard = this%parser%GetInteger()
733  write (this%iout, fmtpicard) this%maxsfrpicard
734  case ('MAXIMUM_ITERATIONS')
735  this%maxsfrit = this%parser%GetInteger()
736  write (this%iout, fmtiter) this%maxsfrit
737  case ('MAXIMUM_DEPTH_CHANGE')
738  r = this%parser%GetDouble()
739  this%dmaxchg = r
740  this%deps = dp999 * r
741  write (this%iout, fmtdmaxchg) this%dmaxchg
742  case ('MOVER')
743  this%imover = 1
744  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
745  !
746  ! -- right now these are options that are only available in the
747  ! development version and are not included in the documentation.
748  ! These options are only available when IDEVELOPMODE in
749  ! constants module is set to 1
750  case ('DEV_NO_CHECK')
751  call this%parser%DevOpt()
752  this%icheck = 0
753  write (this%iout, '(4x,A)') 'SFR CHECKS OF REACH GEOMETRY '// &
754  'RELATIVE TO MODEL GRID AND '// &
755  'REASONABLE PARAMETERS WILL NOT '// &
756  'BE PERFORMED.'
757  case ('DEV_NO_FINAL_CHECK')
758  call this%parser%DevOpt()
759  this%iconvchk = 0
760  write (this%iout, '(4x,a)') &
761  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN STREAM FLOW ROUTING &
762  &STAGES AND FLOWS WILL NOT BE MADE'
763  !
764  ! -- no valid options found
765  case default
766  !
767  ! -- No options found
768  found = .false.
769  end select
770  !
771  ! -- return
772  return
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 2621 of file gwf-sfr.f90.

2622  ! -- module
2623  use tdismodule, only: totim, delt
2624  ! -- dummy
2625  class(SfrType) :: this !< SfrType object
2626  integer(I4B), intent(in) :: kstp !< time step number
2627  integer(I4B), intent(in) :: kper !< period number
2628  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
2629  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
2630  !
2631  call this%budobj%write_budtable(kstp, kper, iout, ibudfl, totim, delt)
2632  !
2633  ! -- return
2634  return

◆ 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 2505 of file gwf-sfr.f90.

2506  ! -- modules
2507  use tdismodule, only: kstp, kper, pertim, totim
2508  use inputoutputmodule, only: ulasav
2509  ! -- dummy variables
2510  class(SfrType) :: this !< SfrType object
2511  integer(I4B), intent(in) :: idvsave !< flag and unit number for dependent-variable output
2512  integer(I4B), intent(in) :: idvprint !< flag indicating if dependent-variable should be written to the model listing file
2513  ! -- local variables
2514  character(len=20) :: cellid
2515  integer(I4B) :: ibinun
2516  integer(I4B) :: n
2517  integer(I4B) :: node
2518  real(DP) :: d
2519  real(DP) :: v
2520  real(DP) :: hgwf
2521  real(DP) :: sbot
2522  real(DP) :: depth
2523  real(DP) :: stage
2524  real(DP) :: w
2525  real(DP) :: cond
2526  real(DP) :: grad
2527  !
2528  ! -- set unit number for binary dependent variable output
2529  ibinun = 0
2530  if (this%istageout /= 0) then
2531  ibinun = this%istageout
2532  end if
2533  if (idvsave == 0) ibinun = 0
2534  !
2535  ! -- write sfr binary output
2536  if (ibinun > 0) then
2537  do n = 1, this%maxbound
2538  d = this%depth(n)
2539  v = this%stage(n)
2540  if (this%iboundpak(n) == 0) then
2541  v = dhnoflo
2542  else if (d == dzero) then
2543  v = dhdry
2544  end if
2545  this%dbuff(n) = v
2546  end do
2547  call ulasav(this%dbuff, ' STAGE', kstp, kper, pertim, totim, &
2548  this%maxbound, 1, 1, ibinun)
2549  end if
2550  !
2551  ! -- print sfr stage and depth table
2552  if (idvprint /= 0 .and. this%iprhed /= 0) then
2553  !
2554  ! -- set table kstp and kper
2555  call this%stagetab%set_kstpkper(kstp, kper)
2556  !
2557  ! -- fill stage data
2558  do n = 1, this%maxbound
2559  node = this%igwfnode(n)
2560  if (node > 0) then
2561  call this%dis%noder_to_string(node, cellid)
2562  hgwf = this%xnew(node)
2563  else
2564  cellid = 'NONE'
2565  end if
2566  if (this%inamedbound == 1) then
2567  call this%stagetab%add_term(this%boundname(n))
2568  end if
2569  call this%stagetab%add_term(n)
2570  call this%stagetab%add_term(cellid)
2571  if (this%iboundpak(n) /= 0) then
2572  depth = this%depth(n)
2573  stage = this%stage(n)
2574  w = this%calc_top_width_wet(n, depth)
2575  call this%sfr_calc_cond(n, depth, cond, stage, hgwf)
2576  else
2577  depth = dhnoflo
2578  stage = dhnoflo
2579  w = dhnoflo
2580  cond = dhnoflo
2581  end if
2582  if (depth == dzero) then
2583  call this%stagetab%add_term(dhdry)
2584  else
2585  call this%stagetab%add_term(stage)
2586  end if
2587  call this%stagetab%add_term(depth)
2588  call this%stagetab%add_term(w)
2589  if (node > 0) then
2590  if (this%iboundpak(n) /= 0) then
2591  sbot = this%strtop(n) - this%bthick(n)
2592  if (hgwf < sbot) then
2593  grad = stage - sbot
2594  else
2595  grad = stage - hgwf
2596  end if
2597  grad = grad / this%bthick(n)
2598  else
2599  grad = dhnoflo
2600  end if
2601  call this%stagetab%add_term(hgwf)
2602  call this%stagetab%add_term(cond)
2603  call this%stagetab%add_term(grad)
2604  else
2605  call this%stagetab%add_term('--')
2606  call this%stagetab%add_term('--')
2607  call this%stagetab%add_term('--')
2608  end if
2609  end do
2610  end if
2611  !
2612  ! -- return
2613  return
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:30
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 2448 of file gwf-sfr.f90.

2449  ! -- modules
2450  use tdismodule, only: kstp, kper, delt, pertim, totim
2451  ! -- dummy variables
2452  class(SfrType) :: this !< SfrType object
2453  integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output
2454  integer(I4B), intent(in) :: ibudfl !< flag indication if cell-by-cell data should be saved
2455  ! -- local variables
2456  integer(I4B) :: ibinun
2457  character(len=20), dimension(:), allocatable :: cellidstr
2458  integer(I4B) :: n
2459  integer(I4B) :: node
2460  !
2461  ! -- write the flows from the budobj
2462  ibinun = 0
2463  if (this%ibudgetout /= 0) then
2464  ibinun = this%ibudgetout
2465  end if
2466  if (icbcfl == 0) ibinun = 0
2467  if (ibinun > 0) then
2468  call this%budobj%save_flows(this%dis, ibinun, kstp, kper, delt, &
2469  pertim, totim, this%iout)
2470  end if
2471  !
2472  ! -- Print sfr flows table
2473  if (ibudfl /= 0 .and. this%iprflow /= 0) then
2474  !
2475  ! -- If there are any 'none' gwf connections then need to calculate
2476  ! a vector of cellids and pass that in to the budget flow table because
2477  ! the table assumes that there are maxbound gwf entries, which is not
2478  ! the case if any 'none's are specified.
2479  if (this%ianynone > 0) then
2480  allocate (cellidstr(this%maxbound))
2481  do n = 1, this%maxbound
2482  node = this%igwfnode(n)
2483  if (node > 0) then
2484  call this%dis%noder_to_string(node, cellidstr(n))
2485  else
2486  cellidstr(n) = 'NONE'
2487  end if
2488  end do
2489  call this%budobj%write_flowtable(this%dis, kstp, kper, cellidstr)
2490  deallocate (cellidstr)
2491  else
2492  call this%budobj%write_flowtable(this%dis, kstp, kper)
2493  end if
2494  end if
2495  !
2496  ! -- return
2497  return

◆ 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 3136 of file gwf-sfr.f90.

3137  ! -- dummy variables
3138  type(ObserveType), intent(inout) :: obsrv !< Observation object
3139  class(DisBaseType), intent(in) :: dis !< Discretization object
3140  integer(I4B), intent(in) :: inunitobs !< file unit number for the package observation file
3141  integer(I4B), intent(in) :: iout !< model listing file unit number
3142  ! -- local variables
3143  integer(I4B) :: nn1
3144  integer(I4B) :: icol
3145  integer(I4B) :: istart
3146  integer(I4B) :: istop
3147  character(len=LINELENGTH) :: string
3148  character(len=LENBOUNDNAME) :: bndname
3149  !
3150  ! -- initialize local variables
3151  string = obsrv%IDstring
3152  !
3153  ! -- Extract reach number from string and store it.
3154  ! If 1st item is not an integer(I4B), it should be a
3155  ! boundary name--deal with it.
3156  icol = 1
3157  !
3158  ! -- get reach number or boundary name
3159  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
3160  if (nn1 == namedboundflag) then
3161  obsrv%FeatureName = bndname
3162  end if
3163  !
3164  ! -- store reach number (NodeNumber)
3165  obsrv%NodeNumber = nn1
3166  !
3167  ! -- return
3168  return
Here is the call graph for this function:
Here is the caller 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 1239 of file gwf-sfr.f90.

1240  ! -- modules
1242  use sparsemodule, only: sparsematrix
1243  ! -- dummy variables
1244  class(SfrType), intent(inout) :: this !< SfrType object
1245  ! -- local variables
1246  character(len=LINELENGTH) :: line
1247  logical(LGP) :: isfound
1248  logical(LGP) :: endOfBlock
1249  integer(I4B) :: n
1250  integer(I4B) :: i
1251  integer(I4B) :: j
1252  integer(I4B) :: jj
1253  integer(I4B) :: jcol
1254  integer(I4B) :: jcol2
1255  integer(I4B) :: nja
1256  integer(I4B) :: ival
1257  integer(I4B) :: idir
1258  integer(I4B) :: ierr
1259  integer(I4B) :: nconnmax
1260  integer(I4B) :: nup
1261  integer(I4B) :: ipos
1262  integer(I4B) :: istat
1263  integer(I4B), dimension(:), pointer, contiguous :: rowmaxnnz => null()
1264  integer, allocatable, dimension(:) :: nboundchk
1265  integer, allocatable, dimension(:, :) :: iconndata
1266  type(sparsematrix), pointer :: sparse => null()
1267  integer(I4B), dimension(:), allocatable :: iup
1268  integer(I4B), dimension(:), allocatable :: order
1269  type(dag) :: sfr_dag
1270  !
1271  ! -- allocate and initialize local variables for reach connections
1272  allocate (nboundchk(this%maxbound))
1273  do n = 1, this%maxbound
1274  nboundchk(n) = 0
1275  end do
1276  !
1277  ! -- calculate the number of non-zero entries (size of ja maxtrix)
1278  nja = 0
1279  nconnmax = 0
1280  allocate (rowmaxnnz(this%maxbound))
1281  do n = 1, this%maxbound
1282  ival = this%nconnreach(n)
1283  if (ival < 0) ival = 0
1284  rowmaxnnz(n) = ival + 1
1285  nja = nja + ival + 1
1286  if (ival > nconnmax) then
1287  nconnmax = ival
1288  end if
1289  end do
1290  !
1291  ! -- reallocate connection data for package
1292  call mem_reallocate(this%ja, nja, 'JA', this%memoryPath)
1293  call mem_reallocate(this%idir, nja, 'IDIR', this%memoryPath)
1294  call mem_reallocate(this%idiv, nja, 'IDIV', this%memoryPath)
1295  call mem_reallocate(this%qconn, nja, 'QCONN', this%memoryPath)
1296  !
1297  ! -- initialize connection data
1298  do n = 1, nja
1299  this%idir(n) = 0
1300  this%idiv(n) = 0
1301  this%qconn(n) = dzero
1302  end do
1303  !
1304  ! -- allocate space for iconndata
1305  allocate (iconndata(nconnmax, this%maxbound))
1306  !
1307  ! -- initialize iconndata
1308  do n = 1, this%maxbound
1309  do j = 1, nconnmax
1310  iconndata(j, n) = 0
1311  end do
1312  end do
1313  !
1314  ! -- allocate space for connectivity
1315  allocate (sparse)
1316  !
1317  ! -- set up sparse
1318  call sparse%init(this%maxbound, this%maxbound, rowmaxnnz)
1319  !
1320  ! -- read connection data
1321  call this%parser%GetBlock('CONNECTIONDATA', isfound, ierr, &
1322  supportopenclose=.true.)
1323  !
1324  ! -- parse reach connectivity block if detected
1325  if (isfound) then
1326  write (this%iout, '(/1x,a)') &
1327  'PROCESSING '//trim(adjustl(this%text))//' CONNECTIONDATA'
1328  do
1329  call this%parser%GetNextLine(endofblock)
1330  if (endofblock) exit
1331  !
1332  ! -- get reach number
1333  n = this%parser%GetInteger()
1334  !
1335  ! -- check for error
1336  if (n < 1 .or. n > this%maxbound) then
1337  write (errmsg, '(a,1x,a,1x,i0)') &
1338  'SFR reach in connectiondata block is less than one or greater', &
1339  'than NREACHES:', n
1340  call store_error(errmsg)
1341  cycle
1342  end if
1343  !
1344  ! -- increment nboundchk
1345  nboundchk(n) = nboundchk(n) + 1
1346  !
1347  ! -- add diagonal connection for reach
1348  call sparse%addconnection(n, n, 1)
1349  !
1350  ! -- fill off diagonals
1351  do i = 1, this%nconnreach(n)
1352  !
1353  ! -- get connected reach
1354  ival = this%parser%GetInteger()
1355  !
1356  ! -- save connection data to temporary iconndata
1357  iconndata(i, n) = ival
1358  !
1359  ! -- determine idir
1360  if (ival < 0) then
1361  idir = -1
1362  ival = abs(ival)
1363  elseif (ival == 0) then
1364  call store_error('Missing or zero connection reach in line:')
1365  call store_error(line)
1366  else
1367  idir = 1
1368  end if
1369  if (ival > this%maxbound) then
1370  call store_error('Reach number exceeds NREACHES in line:')
1371  call store_error(line)
1372  end if
1373  !
1374  ! -- add connection to sparse
1375  call sparse%addconnection(n, ival, 1)
1376  end do
1377  end do
1378 
1379  write (this%iout, '(1x,a)') &
1380  'END OF '//trim(adjustl(this%text))//' CONNECTIONDATA'
1381 
1382  do n = 1, this%maxbound
1383  !
1384  ! -- check for missing or duplicate sfr connections
1385  if (nboundchk(n) == 0) then
1386  write (errmsg, '(a,1x,i0)') &
1387  'No connection data specified for reach', n
1388  call store_error(errmsg)
1389  else if (nboundchk(n) > 1) then
1390  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1391  'Connection data for reach', n, &
1392  'specified', nboundchk(n), 'times.'
1393  call store_error(errmsg)
1394  end if
1395  end do
1396  else
1397  call store_error('Required connectiondata block not found.')
1398  end if
1399  !
1400  ! -- terminate if errors encountered in connectiondata block
1401  if (count_errors() > 0) then
1402  call this%parser%StoreErrorUnit()
1403  end if
1404  !
1405  ! -- create ia and ja from sparse
1406  call sparse%filliaja(this%ia, this%ja, ierr, sort=.true.)
1407  !
1408  ! -- test for error condition
1409  if (ierr /= 0) then
1410  write (errmsg, '(a,3(1x,a))') &
1411  'Could not fill', trim(this%packName), &
1412  'package IA and JA connection data.', &
1413  'Check connectivity data in connectiondata block.'
1414  call store_error(errmsg)
1415  end if
1416  !
1417  ! -- fill flat connection storage
1418  do n = 1, this%maxbound
1419  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1420  jcol = this%ja(j)
1421  do jj = 1, this%nconnreach(n)
1422  jcol2 = iconndata(jj, n)
1423  if (abs(jcol2) == jcol) then
1424  idir = 1
1425  if (jcol2 < 0) then
1426  idir = -1
1427  end if
1428  this%idir(j) = idir
1429  exit
1430  end if
1431  end do
1432  end do
1433  end do
1434  !
1435  ! -- deallocate temporary local storage for reach connections
1436  deallocate (rowmaxnnz)
1437  deallocate (nboundchk)
1438  deallocate (iconndata)
1439  !
1440  ! -- destroy sparse
1441  call sparse%destroy()
1442  deallocate (sparse)
1443  !
1444  ! -- calculate reach order using DAG
1445  !
1446  ! -- initialize the DAG
1447  call sfr_dag%set_vertices(this%maxbound)
1448  !
1449  ! -- fill DAG
1450  fill_dag: do n = 1, this%maxbound
1451  !
1452  ! -- determine the number of upstream reaches
1453  nup = 0
1454  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1455  if (this%idir(j) > 0) then
1456  nup = nup + 1
1457  end if
1458  end do
1459  !
1460  ! -- cycle if nu upstream reacches
1461  if (nup == 0) cycle fill_dag
1462  !
1463  ! -- allocate local storage
1464  allocate (iup(nup))
1465  !
1466  ! -- fill local storage
1467  ipos = 1
1468  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1469  if (this%idir(j) > 0) then
1470  iup(ipos) = this%ja(j)
1471  ipos = ipos + 1
1472  end if
1473  end do
1474  !
1475  ! -- add upstream connections to DAG
1476  call sfr_dag%set_edges(n, iup)
1477  !
1478  ! -- clean up local storage
1479  deallocate (iup)
1480  end do fill_dag
1481  !
1482  ! -- perform toposort on DAG
1483  call sfr_dag%toposort(order, istat)
1484  !
1485  ! -- write warning if circular dependency
1486  if (istat == -1) then
1487  write (warnmsg, '(a)') &
1488  trim(adjustl(this%text))//' PACKAGE ('// &
1489  trim(adjustl(this%packName))//') cannot calculate a '// &
1490  'Directed Asyclic Graph for reach connectivity because '// &
1491  'of circular dependency. Using the reach number for '// &
1492  'solution ordering.'
1493  call store_warning(warnmsg)
1494  end if
1495  !
1496  ! -- fill isfrorder
1497  do n = 1, this%maxbound
1498  if (istat == 0) then
1499  this%isfrorder(n) = order(n)
1500  else
1501  this%isfrorder(n) = n
1502  end if
1503  end do
1504  !
1505  ! -- clean up DAG and remaining local storage
1506  call sfr_dag%destroy()
1507  if (istat == 0) then
1508  deallocate (order)
1509  end if
1510  !
1511  ! -- return
1512  return
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 1097 of file gwf-sfr.f90.

1098  ! -- modules
1101  ! -- dummy variables
1102  class(SfrType), intent(inout) :: this !< SfrType object
1103  ! -- local variables
1104  character(len=LINELENGTH) :: keyword
1105  character(len=LINELENGTH) :: line
1106  logical(LGP) :: isfound
1107  logical(LGP) :: endOfBlock
1108  integer(I4B) :: n
1109  integer(I4B) :: ierr
1110  integer(I4B) :: ncrossptstot
1111  integer, allocatable, dimension(:) :: nboundchk
1112  type(SfrCrossSection), pointer :: cross_data => null()
1113  !
1114  ! -- read cross-section data
1115  call this%parser%GetBlock('CROSSSECTIONS', isfound, ierr, &
1116  supportopenclose=.true., &
1117  blockrequired=.false.)
1118  !
1119  ! -- parse reach connectivity block if detected
1120  if (isfound) then
1121  write (this%iout, '(/1x,a)') &
1122  'PROCESSING '//trim(adjustl(this%text))//' CROSSSECTIONS'
1123  !
1124  ! -- allocate and initialize local variables for reach cross-sections
1125  allocate (nboundchk(this%maxbound))
1126  do n = 1, this%maxbound
1127  nboundchk(n) = 0
1128  end do
1129  !
1130  ! -- create and initialize cross-section data
1131  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1132  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1133  this%iacross, &
1134  this%station, this%xsheight, &
1135  this%xsrough)
1136  !
1137  ! -- read all of the entries in the block
1138  readtable: do
1139  call this%parser%GetNextLine(endofblock)
1140  if (endofblock) exit
1141  !
1142  ! -- get reach number
1143  n = this%parser%GetInteger()
1144  !
1145  ! -- check for reach number error
1146  if (n < 1 .or. n > this%maxbound) then
1147  write (errmsg, '(a,1x,a,1x,i0)') &
1148  'SFR reach in crosssections block is less than one or greater', &
1149  'than NREACHES:', n
1150  call store_error(errmsg)
1151  cycle readtable
1152  end if
1153  !
1154  ! -- increment nboundchk
1155  nboundchk(n) = nboundchk(n) + 1
1156  !
1157  ! -- read FILE keyword
1158  call this%parser%GetStringCaps(keyword)
1159  select case (keyword)
1160  case ('TAB6')
1161  call this%parser%GetStringCaps(keyword)
1162  if (trim(adjustl(keyword)) /= 'FILEIN') then
1163  errmsg = 'TAB6 keyword must be followed by "FILEIN" '// &
1164  'then by filename.'
1165  call store_error(errmsg)
1166  cycle readtable
1167  end if
1168  call this%parser%GetString(line)
1169  call cross_data%read_table(n, this%width(n), &
1170  trim(adjustl(line)))
1171  case default
1172  write (errmsg, '(a,1x,i4,1x,a)') &
1173  'CROSS-SECTION TABLE ENTRY for REACH ', n, &
1174  'MUST INCLUDE TAB6 KEYWORD'
1175  call store_error(errmsg)
1176  cycle readtable
1177  end select
1178  end do readtable
1179 
1180  write (this%iout, '(1x,a)') &
1181  'END OF '//trim(adjustl(this%text))//' CROSSSECTIONS'
1182 
1183  !
1184  ! -- check for duplicate sfr crosssections
1185  do n = 1, this%maxbound
1186  if (nboundchk(n) > 1) then
1187  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1188  'Cross-section data for reach', n, &
1189  'specified', nboundchk(n), 'times.'
1190  call store_error(errmsg)
1191  end if
1192  end do
1193  !
1194  ! -- terminate if errors encountered in cross-sections block
1195  if (count_errors() > 0) then
1196  call this%parser%StoreErrorUnit()
1197  end if
1198  !
1199  ! -- determine the current size of cross-section data
1200  ncrossptstot = cross_data%get_ncrossptstot()
1201  !
1202  ! -- reallocate sfr package cross-section data
1203  if (ncrossptstot /= this%ncrossptstot) then
1204  this%ncrossptstot = ncrossptstot
1205  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1206  this%memoryPath)
1207  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1208  this%memoryPath)
1209  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1210  this%memoryPath)
1211  end if
1212  !
1213  ! -- write cross-section data to the model listing file
1214  call cross_data%output(this%width, this%rough)
1215  !
1216  ! -- pack cross-section data
1217  call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
1218  this%iacross, &
1219  this%station, &
1220  this%xsheight, &
1221  this%xsrough)
1222  !
1223  ! -- deallocate temporary local storage for reach cross-sections
1224  deallocate (nboundchk)
1225  call cross_data%destroy()
1226  deallocate (cross_data)
1227  nullify (cross_data)
1228  end if
1229  !
1230  ! -- return
1231  return
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 540 of file gwf-sfr.f90.

541  ! -- dummy variables
542  class(SfrType), intent(inout) :: this !< SfrType object
543  ! -- local variables
544  character(len=LINELENGTH) :: keyword
545  integer(I4B) :: ierr
546  logical(LGP) :: isfound
547  logical(LGP) :: endOfBlock
548  !
549  ! -- initialize dimensions to 0
550  this%maxbound = 0
551  !
552  ! -- get dimensions block
553  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
554  supportopenclose=.true.)
555  !
556  ! -- parse dimensions block if detected
557  if (isfound) then
558  write (this%iout, '(/1x,a)') &
559  'PROCESSING '//trim(adjustl(this%text))//' DIMENSIONS'
560  do
561  call this%parser%GetNextLine(endofblock)
562  if (endofblock) exit
563  call this%parser%GetStringCaps(keyword)
564  select case (keyword)
565  case ('NREACHES')
566  this%maxbound = this%parser%GetInteger()
567  write (this%iout, '(4x,a,i0)') 'NREACHES = ', this%maxbound
568  case default
569  write (errmsg, '(2a)') &
570  'Unknown '//trim(this%text)//' dimension: ', trim(keyword)
571  call store_error(errmsg)
572  end select
573  end do
574  write (this%iout, '(1x,a)') &
575  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
576  else
577  call store_error('Required dimensions block not found.')
578  end if
579  !
580  ! -- verify dimensions were set
581  if (this%maxbound < 1) then
582  write (errmsg, '(a)') &
583  'NREACHES was not specified or was specified incorrectly.'
584  call store_error(errmsg)
585  end if
586  !
587  ! -- write summary of error messages for block
588  if (count_errors() > 0) then
589  call this%parser%StoreErrorUnit()
590  end if
591  !
592  ! -- Call define_listlabel to construct the list label that is written
593  ! when PRINT_INPUT option is used.
594  call this%define_listlabel()
595  !
596  ! -- Define default cross-section data size
597  this%ncrossptstot = this%maxbound
598  !
599  ! -- Allocate arrays in package superclass
600  call this%sfr_allocate_arrays()
601  !
602  ! -- read package data
603  call this%sfr_read_packagedata()
604  !
605  ! -- read cross-section data
606  call this%sfr_read_crossection()
607  !
608  ! -- read connection data
609  call this%sfr_read_connectiondata()
610  !
611  ! -- read diversion data
612  call this%sfr_read_diversions()
613  !
614  ! -- setup the budget object
615  call this%sfr_setup_budobj()
616  !
617  ! -- setup the stage table object
618  call this%sfr_setup_tableobj()
619  !
620  ! -- return
621  return
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 1520 of file gwf-sfr.f90.

1521  ! -- modules
1523  ! -- dummy variables
1524  class(SfrType), intent(inout) :: this !< SfrType object
1525  ! -- local variables
1526  character(len=10) :: cnum
1527  character(len=10) :: cval
1528  integer(I4B) :: j
1529  integer(I4B) :: n
1530  integer(I4B) :: ierr
1531  integer(I4B) :: ival
1532  integer(I4B) :: i0
1533  integer(I4B) :: ipos
1534  integer(I4B) :: jpos
1535  integer(I4B) :: ndiv
1536  integer(I4B) :: ndiversions
1537  integer(I4B) :: idivreach
1538  logical(LGP) :: isfound
1539  logical(LGP) :: endOfBlock
1540  integer(I4B) :: idiv
1541  integer, allocatable, dimension(:) :: iachk
1542  integer, allocatable, dimension(:) :: nboundchk
1543  !
1544  ! -- determine the total number of diversions and fill iadiv
1545  ndiversions = 0
1546  i0 = 1
1547  this%iadiv(1) = i0
1548  do n = 1, this%maxbound
1549  ndiversions = ndiversions + this%ndiv(n)
1550  i0 = i0 + this%ndiv(n)
1551  this%iadiv(n + 1) = i0
1552  end do
1553  !
1554  ! -- reallocate memory for diversions
1555  if (ndiversions > 0) then
1556  call mem_reallocate(this%divreach, ndiversions, 'DIVREACH', &
1557  this%memoryPath)
1558  allocate (this%divcprior(ndiversions))
1559  call mem_reallocate(this%divflow, ndiversions, 'DIVFLOW', this%memoryPath)
1560  call mem_reallocate(this%divq, ndiversions, 'DIVQ', this%memoryPath)
1561  end if
1562  !
1563  ! -- initialize diversion flow
1564  do n = 1, ndiversions
1565  this%divflow(n) = dzero
1566  this%divq(n) = dzero
1567  end do
1568  !
1569  ! -- read diversions
1570  call this%parser%GetBlock('DIVERSIONS', isfound, ierr, &
1571  supportopenclose=.true., &
1572  blockrequired=.false.)
1573  !
1574  ! -- parse reach connectivity block if detected
1575  if (isfound) then
1576  if (this%idiversions /= 0) then
1577  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1578  ' DIVERSIONS'
1579  !
1580  ! -- allocate and initialize local variables for diversions
1581  ndiv = 0
1582  do n = 1, this%maxbound
1583  ndiv = ndiv + this%ndiv(n)
1584  end do
1585  allocate (iachk(this%maxbound + 1))
1586  allocate (nboundchk(ndiv))
1587  iachk(1) = 1
1588  do n = 1, this%maxbound
1589  iachk(n + 1) = iachk(n) + this%ndiv(n)
1590  end do
1591  do n = 1, ndiv
1592  nboundchk(n) = 0
1593  end do
1594  !
1595  ! -- read diversion data
1596  do
1597  call this%parser%GetNextLine(endofblock)
1598  if (endofblock) exit
1599  !
1600  ! -- get reach number
1601  n = this%parser%GetInteger()
1602  if (n < 1 .or. n > this%maxbound) then
1603  write (cnum, '(i0)') n
1604  errmsg = 'Reach number should be between 1 and '// &
1605  trim(cnum)//'.'
1606  call store_error(errmsg)
1607  cycle
1608  end if
1609  !
1610  ! -- make sure reach has at least one diversion
1611  if (this%ndiv(n) < 1) then
1612  write (cnum, '(i0)') n
1613  errmsg = 'Diversions cannot be specified '// &
1614  'for reach '//trim(cnum)
1615  call store_error(errmsg)
1616  cycle
1617  end if
1618  !
1619  ! -- read diversion number
1620  ival = this%parser%GetInteger()
1621  if (ival < 1 .or. ival > this%ndiv(n)) then
1622  write (cnum, '(i0)') n
1623  errmsg = 'Reach '//trim(cnum)
1624  write (cnum, '(i0)') this%ndiv(n)
1625  errmsg = trim(errmsg)//' diversion number should be between '// &
1626  '1 and '//trim(cnum)//'.'
1627  call store_error(errmsg)
1628  cycle
1629  end if
1630 
1631  ! -- increment nboundchk
1632  ipos = iachk(n) + ival - 1
1633  nboundchk(ipos) = nboundchk(ipos) + 1
1634 
1635  idiv = ival
1636  !
1637  ! -- get target reach for diversion
1638  ival = this%parser%GetInteger()
1639  if (ival < 1 .or. ival > this%maxbound) then
1640  write (cnum, '(i0)') ival
1641  errmsg = 'Diversion target reach number should be '// &
1642  'between 1 and '//trim(cnum)//'.'
1643  call store_error(errmsg)
1644  cycle
1645  end if
1646  idivreach = ival
1647  jpos = this%iadiv(n) + idiv - 1
1648  this%divreach(jpos) = idivreach
1649  !
1650  ! -- get cprior
1651  call this%parser%GetStringCaps(cval)
1652  ival = -1
1653  select case (cval)
1654  case ('UPTO')
1655  ival = 0
1656  case ('THRESHOLD')
1657  ival = -1
1658  case ('FRACTION')
1659  ival = -2
1660  case ('EXCESS')
1661  ival = -3
1662  case default
1663  errmsg = 'Invalid cprior type '//trim(cval)//'.'
1664  call store_error(errmsg)
1665  end select
1666  !
1667  ! -- set cprior for diversion
1668  this%divcprior(jpos) = cval
1669  end do
1670 
1671  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))// &
1672  ' DIVERSIONS'
1673 
1674  do n = 1, this%maxbound
1675  do j = 1, this%ndiv(n)
1676  ipos = iachk(n) + j - 1
1677  !
1678  ! -- check for missing or duplicate reach diversions
1679  if (nboundchk(ipos) == 0) then
1680  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1681  'No data specified for reach', n, 'diversion', j
1682  call store_error(errmsg)
1683  else if (nboundchk(ipos) > 1) then
1684  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1685  'Data for reach', n, 'diversion', j, &
1686  'specified', nboundchk(ipos), 'times'
1687  call store_error(errmsg)
1688  end if
1689  end do
1690  end do
1691  !
1692  ! -- deallocate local variables
1693  deallocate (iachk)
1694  deallocate (nboundchk)
1695  else
1696  !
1697  ! -- error condition
1698  write (errmsg, '(a,1x,a)') &
1699  'A diversions block should not be', &
1700  'specified if diversions are not specified.'
1701  call store_error(errmsg)
1702  end if
1703  else
1704  if (this%idiversions /= 0) then
1705  call store_error('REQUIRED DIVERSIONS BLOCK NOT FOUND.')
1706  end if
1707  end if
1708  !
1709  ! -- write summary of diversion error messages
1710  if (count_errors() > 0) then
1711  call this%parser%StoreErrorUnit()
1712  end if
1713  !
1714  ! -- return
1715  return
Here is the call graph for this function:

◆ sfr_read_packagedata()

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

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

Parameters
[in,out]thisSfrType object

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

844  ! -- modules
846  ! -- dummy variables
847  class(SfrType), intent(inout) :: this !< SfrType object
848  ! -- local variables
849  character(len=LINELENGTH) :: text
850  character(len=LINELENGTH) :: cellid
851  character(len=10) :: cnum
852  character(len=LENBOUNDNAME) :: bndName
853  character(len=LENBOUNDNAME) :: bndNameTemp
854  character(len=LENBOUNDNAME) :: hkname
855  character(len=LENBOUNDNAME) :: manningname
856  character(len=LENBOUNDNAME) :: ustrfname
857  character(len=50), dimension(:), allocatable :: caux
858  integer(I4B) :: n, ierr, ival
859  logical(LGP) :: isfound
860  logical(LGP) :: endOfBlock
861  integer(I4B) :: i
862  integer(I4B) :: ii
863  integer(I4B) :: jj
864  integer(I4B) :: iaux
865  integer(I4B) :: nconzero
866  integer(I4B) :: ipos
867  integer, allocatable, dimension(:) :: nboundchk
868  real(DP), pointer :: bndElem => null()
869  !
870  ! -- allocate space for checking sfr reach data
871  allocate (nboundchk(this%maxbound))
872  do i = 1, this%maxbound
873  nboundchk(i) = 0
874  end do
875  nconzero = 0
876  !
877  ! -- allocate local storage for aux variables
878  if (this%naux > 0) then
879  allocate (caux(this%naux))
880  end if
881  !
882  ! -- read reach data
883  call this%parser%GetBlock('PACKAGEDATA', isfound, ierr, &
884  supportopenclose=.true.)
885  !
886  ! -- parse reaches block if detected
887  if (isfound) then
888  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
889  ' PACKAGEDATA'
890  do
891  call this%parser%GetNextLine(endofblock)
892  if (endofblock) exit
893  ! -- read reach number
894  n = this%parser%GetInteger()
895 
896  if (n < 1 .or. n > this%maxbound) then
897  write (errmsg, '(a,1x,a,1x,i0)') &
898  'Reach number (rno) must be greater than 0 and less', &
899  'than or equal to', this%maxbound
900  call store_error(errmsg)
901  cycle
902  end if
903 
904  ! -- increment nboundchk
905  nboundchk(n) = nboundchk(n) + 1
906  !
907  ! -- get model node number
908  call this%parser%GetCellid(this%dis%ndim, cellid, flag_string=.true.)
909  this%igwfnode(n) = this%dis%noder_from_cellid(cellid, this%inunit, &
910  this%iout, &
911  flag_string=.true., &
912  allow_zero=.true.)
913  this%igwftopnode(n) = this%igwfnode(n)
914  !
915  ! -- read the cellid string and determine if 'none' is specified
916  if (this%igwfnode(n) < 1) then
917  this%ianynone = this%ianynone + 1
918  call upcase(cellid)
919  if (cellid == 'NONE') then
920  call this%parser%GetStringCaps(cellid)
921  !
922  ! -- create warning message
923  write (cnum, '(i0)') n
924  warnmsg = 'CELLID for unconnected reach '//trim(cnum)// &
925  ' specified to be NONE. Unconnected reaches '// &
926  'should be specified with a zero for each grid '// &
927  'dimension. For example, for a DIS grid a CELLID '// &
928  'of 0 0 0 should be specified for unconnected reaches'
929  !
930  ! -- create deprecation warning
931  call deprecation_warning('PACKAGEDATA', 'CELLID=NONE', '6.4.3', &
932  warnmsg, this%parser%GetUnit())
933  else
934 
935  end if
936  end if
937  ! -- get reach length
938  this%length(n) = this%parser%GetDouble()
939  ! -- get reach width
940  this%width(n) = this%parser%GetDouble()
941  ! -- get reach slope
942  this%slope(n) = this%parser%GetDouble()
943  ! -- get reach stream bottom
944  this%strtop(n) = this%parser%GetDouble()
945  ! -- get reach bed thickness
946  this%bthick(n) = this%parser%GetDouble()
947  ! -- get reach bed hk
948  call this%parser%GetStringCaps(hkname)
949  ! -- get reach roughness
950  call this%parser%GetStringCaps(manningname)
951  ! -- get number of connections for reach
952  ival = this%parser%GetInteger()
953  this%nconnreach(n) = ival
954  this%nconn = this%nconn + ival
955  if (ival < 0) then
956  write (errmsg, '(a,1x,i0,1x,a,i0,a)') &
957  'NCON for reach', n, &
958  'must be greater than or equal to 0 (', ival, ').'
959  call store_error(errmsg)
960  else if (ival == 0) then
961  nconzero = nconzero + 1
962  end if
963  ! -- get upstream fraction for reach
964  call this%parser%GetString(ustrfname)
965  ! -- get number of diversions for reach
966  ival = this%parser%GetInteger()
967  this%ndiv(n) = ival
968  if (ival > 0) then
969  this%idiversions = 1
970  else if (ival < 0) then
971  ival = 0
972  end if
973 
974  ! -- get aux data
975  do iaux = 1, this%naux
976  call this%parser%GetString(caux(iaux))
977  end do
978 
979  ! -- set default bndName
980  write (cnum, '(i10.10)') n
981  bndname = 'Reach'//cnum
982 
983  ! -- get reach name
984  if (this%inamedbound /= 0) then
985  call this%parser%GetStringCaps(bndnametemp)
986  if (bndnametemp /= '') then
987  bndname = bndnametemp
988  end if
989  !this%boundname(n) = bndName
990  end if
991  this%sfrname(n) = bndname
992  !
993  ! -- set reach hydraulic conductivity
994  text = hkname
995  jj = 1 !for 'BEDK'
996  bndelem => this%hk(n)
997  call read_value_or_time_series_adv(text, n, jj, bndelem, &
998  this%packName, 'BND', &
999  this%tsManager, this%iprpak, &
1000  'BEDK')
1001  !
1002  ! -- set Mannings
1003  text = manningname
1004  jj = 1 !for 'MANNING'
1005  bndelem => this%rough(n)
1006  call read_value_or_time_series_adv(text, n, jj, bndelem, &
1007  this%packName, 'BND', &
1008  this%tsManager, this%iprpak, &
1009  'MANNING')
1010  !
1011  ! -- set upstream fraction
1012  text = ustrfname
1013  jj = 1 ! For 'USTRF'
1014  bndelem => this%ustrf(n)
1015  call read_value_or_time_series_adv(text, n, jj, bndelem, &
1016  this%packName, 'BND', &
1017  this%tsManager, this%iprpak, 'USTRF')
1018  !
1019  ! -- get aux data
1020  do jj = 1, this%naux
1021  text = caux(jj)
1022  ii = n
1023  bndelem => this%rauxvar(jj, ii)
1024  call read_value_or_time_series_adv(text, ii, jj, bndelem, &
1025  this%packName, 'AUX', &
1026  this%tsManager, this%iprpak, &
1027  this%auxname(jj))
1028  end do
1029  !
1030  ! -- initialize sstage to the top of the reach
1031  ! this value would be used by simple routing reaches
1032  ! on kper = 1 and kstp = 1 if a stage is not specified
1033  ! on the status line for the reach
1034  this%sstage(n) = this%strtop(n)
1035 
1036  end do
1037  write (this%iout, '(1x,a)') &
1038  'END OF '//trim(adjustl(this%text))//' PACKAGEDATA'
1039  else
1040  call store_error('REQUIRED PACKAGEDATA BLOCK NOT FOUND.')
1041  end if
1042  !
1043  ! -- Check to make sure that every reach is specified and that no reach
1044  ! is specified more than once.
1045  do i = 1, this%maxbound
1046  if (nboundchk(i) == 0) then
1047  write (errmsg, '(a,i0,1x,a)') &
1048  'Information for reach ', i, 'not specified in packagedata block.'
1049  call store_error(errmsg)
1050  else if (nboundchk(i) > 1) then
1051  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1052  'Reach information specified', nboundchk(i), 'times for reach', i
1053  call store_error(errmsg)
1054  end if
1055  end do
1056  deallocate (nboundchk)
1057  !
1058  ! -- Submit warning message if any reach has zero connections
1059  if (nconzero > 0) then
1060  write (warnmsg, '(a,1x,a,1x,a,1x,i0,1x, a)') &
1061  'SFR Package', trim(this%packName), &
1062  'has', nconzero, 'reach(es) with zero connections.'
1063  call store_warning(warnmsg)
1064  end if
1065  !
1066  ! -- terminate if errors encountered in reach block
1067  if (count_errors() > 0) then
1068  call this%parser%StoreErrorUnit()
1069  end if
1070  !
1071  ! -- initialize the cross-section data
1072  ipos = 1
1073  this%iacross(1) = ipos
1074  do i = 1, this%maxbound
1075  this%ncrosspts(i) = 1
1076  this%station(ipos) = this%width(i)
1077  this%xsheight(ipos) = dzero
1078  this%xsrough(ipos) = done
1079  ipos = ipos + 1
1080  this%iacross(i + 1) = ipos
1081  end do
1082  !
1083  ! -- deallocate local storage for aux variables
1084  if (this%naux > 0) then
1085  deallocate (caux)
1086  end if
1087  !
1088  ! -- return
1089  return
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_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 1723 of file gwf-sfr.f90.

1724  ! -- modules
1725  use tdismodule, only: kper, nper
1728  ! -- dummy variables
1729  class(SfrType), intent(inout) :: this !< SfrType object
1730  ! -- local variables
1731  character(len=LINELENGTH) :: title
1732  character(len=LINELENGTH) :: line
1733  character(len=LINELENGTH) :: crossfile
1734  integer(I4B) :: ierr
1735  integer(I4B) :: n
1736  integer(I4B) :: ichkustrm
1737  integer(I4B) :: ichkcross
1738  integer(I4B) :: ncrossptstot
1739  logical(LGP) :: isfound
1740  logical(LGP) :: endOfBlock
1741  type(SfrCrossSection), pointer :: cross_data => null()
1742  ! -- formats
1743  character(len=*), parameter :: fmtblkerr = &
1744  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
1745  character(len=*), parameter :: fmtlsp = &
1746  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
1747  character(len=*), parameter :: fmtnbd = &
1748  "(1X,/1X,'The number of active ',A,'S (',I6, &
1749  &') is greater than maximum (',I6,')')"
1750  !
1751  ! -- initialize flags
1752  ichkustrm = 0
1753  ichkcross = 0
1754  if (kper == 1) then
1755  ichkustrm = 1
1756  end if
1757  !
1758  ! -- set nbound to maxbound
1759  this%nbound = this%maxbound
1760  !
1761  ! -- Set ionper to the stress period number for which a new block of data
1762  ! will be read.
1763  if (this%ionper < kper) then
1764  !
1765  ! -- get period block
1766  call this%parser%GetBlock('PERIOD', isfound, ierr, &
1767  supportopenclose=.true., &
1768  blockrequired=.false.)
1769  if (isfound) then
1770  !
1771  ! -- read ionper and check for increasing period numbers
1772  call this%read_check_ionper()
1773  else
1774  !
1775  ! -- PERIOD block not found
1776  if (ierr < 0) then
1777  ! -- End of file found; data applies for remainder of simulation.
1778  this%ionper = nper + 1
1779  else
1780  ! -- Found invalid block
1781  call this%parser%GetCurrentLine(line)
1782  write (errmsg, fmtblkerr) adjustl(trim(line))
1783  call store_error(errmsg)
1784  call this%parser%StoreErrorUnit()
1785  end if
1786  end if
1787  end if
1788  !
1789  ! -- Read data if ionper == kper
1790  if (this%ionper == kper) then
1791  !
1792  ! -- create and initialize cross-section data
1793  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1794  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1795  this%iacross, &
1796  this%station, this%xsheight, &
1797  this%xsrough)
1798  !
1799  ! -- setup table for period data
1800  if (this%iprpak /= 0) then
1801  !
1802  ! -- reset the input table object
1803  title = trim(adjustl(this%text))//' PACKAGE ('// &
1804  trim(adjustl(this%packName))//') DATA FOR PERIOD'
1805  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
1806  call table_cr(this%inputtab, this%packName, title)
1807  call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
1808  text = 'NUMBER'
1809  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
1810  text = 'KEYWORD'
1811  call this%inputtab%initialize_column(text, 20, alignment=tableft)
1812  do n = 1, 2
1813  write (text, '(a,1x,i6)') 'VALUE', n
1814  call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
1815  end do
1816  end if
1817  !
1818  ! -- read data
1819  do
1820  call this%parser%GetNextLine(endofblock)
1821  if (endofblock) exit
1822  n = this%parser%GetInteger()
1823  if (n < 1 .or. n > this%maxbound) then
1824  write (errmsg, '(a,1x,a,1x,i0,a)') &
1825  'Reach number (RNO) must be greater than 0 and', &
1826  'less than or equal to', this%maxbound, '.'
1827  call store_error(errmsg)
1828  cycle
1829  end if
1830  !
1831  ! -- read data from the rest of the line
1832  call this%sfr_set_stressperiod(n, ichkustrm, crossfile)
1833  !
1834  ! -- write line to table
1835  if (this%iprpak /= 0) then
1836  call this%parser%GetCurrentLine(line)
1837  call this%inputtab%line_to_columns(line)
1838  end if
1839  !
1840  ! -- process cross-section file
1841  if (trim(adjustl(crossfile)) /= 'NONE') then
1842  call cross_data%read_table(n, this%width(n), &
1843  trim(adjustl(crossfile)))
1844  end if
1845  end do
1846  !
1847  ! -- write raw period data
1848  if (this%iprpak /= 0) then
1849  call this%inputtab%finalize_table()
1850  end if
1851  !
1852  ! -- finalize cross-sections
1853 
1854  !
1855  ! -- determine the current size of cross-section data
1856  ncrossptstot = cross_data%get_ncrossptstot()
1857  !
1858  ! -- reallocate sfr package cross-section data
1859  if (ncrossptstot /= this%ncrossptstot) then
1860  this%ncrossptstot = ncrossptstot
1861  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1862  this%memoryPath)
1863  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1864  this%memoryPath)
1865  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1866  this%memoryPath)
1867  end if
1868  !
1869  ! -- write cross-section data to the model listing file
1870  call cross_data%output(this%width, this%rough, kstp=1, kper=kper)
1871  !
1872  ! -- pack cross-section data
1873  call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
1874  this%iacross, &
1875  this%station, &
1876  this%xsheight, &
1877  this%xsrough)
1878  !
1879  ! -- deallocate temporary local storage for reach cross-sections
1880  call cross_data%destroy()
1881  deallocate (cross_data)
1882  nullify (cross_data)
1883  !
1884  ! -- Reuse data from last stress period
1885  else
1886  write (this%iout, fmtlsp) trim(this%filtyp)
1887  end if
1888  !
1889  ! -- check upstream fraction values
1890  if (ichkustrm /= 0) then
1891  call this%sfr_check_ustrf()
1892  end if
1893  !
1894  ! -- write summary of package block error messages
1895  if (count_errors() > 0) then
1896  call this%parser%StoreErrorUnit()
1897  end if
1898  !
1899  ! -- return
1900  return
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21
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 3022 of file gwf-sfr.f90.

3023  ! -- modules
3024  use tdismodule, only: kper
3025  ! -- dummy variables
3026  class(SfrType), intent(inout) :: this !< SfrType object
3027  ! -- local variables
3028  integer(I4B) :: i
3029  integer(I4B) :: j
3030  integer(I4B) :: nn1
3031  character(len=LENBOUNDNAME) :: bname
3032  logical(LGP) :: jfound
3033  class(ObserveType), pointer :: obsrv => null()
3034  ! -- formats
3035 10 format('Boundary "', a, '" for observation "', a, &
3036  '" is invalid in package "', a, '"')
3037 30 format('Boundary name not provided for observation "', a, &
3038  '" in package "', a, '"')
3039  !
3040  ! -- process each package observation
3041  ! only done the first stress period since boundaries are fixed
3042  ! for the simulation
3043  if (kper == 1) then
3044  do i = 1, this%obs%npakobs
3045  obsrv => this%obs%pakobs(i)%obsrv
3046  !
3047  ! -- get node number 1
3048  nn1 = obsrv%NodeNumber
3049  if (nn1 == namedboundflag) then
3050  bname = obsrv%FeatureName
3051  if (bname /= '') then
3052  ! -- Observation location(s) is(are) based on a boundary name.
3053  ! Iterate through all boundaries to identify and store
3054  ! corresponding index(indices) in bound array.
3055  jfound = .false.
3056  do j = 1, this%maxbound
3057  if (this%boundname(j) == bname) then
3058  jfound = .true.
3059  call obsrv%AddObsIndex(j)
3060  end if
3061  end do
3062  if (.not. jfound) then
3063  write (errmsg, 10) &
3064  trim(bname), trim(obsrv%name), trim(this%packName)
3065  call store_error(errmsg)
3066  end if
3067  else
3068  write (errmsg, 30) trim(obsrv%name), trim(this%packName)
3069  call store_error(errmsg)
3070  end if
3071  else if (nn1 < 1 .or. nn1 > this%maxbound) then
3072  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3073  trim(adjustl(obsrv%ObsTypeId)), &
3074  'reach must be greater than 0 and less than or equal to', &
3075  this%maxbound, '(specified value is ', nn1, ')'
3076  call store_error(errmsg)
3077  else
3078  if (obsrv%indxbnds_count == 0) then
3079  call obsrv%AddObsIndex(nn1)
3080  else
3081  errmsg = 'Programming error in sfr_rp_obs'
3082  call store_error(errmsg)
3083  end if
3084  end if
3085  !
3086  ! -- catch non-cumulative observation assigned to observation defined
3087  ! by a boundname that is assigned to more than one element
3088  if (obsrv%ObsTypeId == 'STAGE' .or. &
3089  obsrv%ObsTypeId == 'DEPTH' .or. &
3090  obsrv%ObsTypeId == 'WET-PERIMETER' .or. &
3091  obsrv%ObsTypeId == 'WET-AREA' .or. &
3092  obsrv%ObsTypeId == 'WET-WIDTH') then
3093  nn1 = obsrv%NodeNumber
3094  if (nn1 == namedboundflag) then
3095  if (obsrv%indxbnds_count > 1) then
3096  write (errmsg, '(a,3(1x,a))') &
3097  trim(adjustl(obsrv%ObsTypeId)), &
3098  'for observation', trim(adjustl(obsrv%Name)), &
3099  ' must be assigned to a reach with a unique boundname.'
3100  call store_error(errmsg)
3101  end if
3102  end if
3103  end if
3104  !
3105  ! -- check that node number 1 is valid; call store_error if not
3106  do j = 1, obsrv%indxbnds_count
3107  nn1 = obsrv%indxbnds(j)
3108  if (nn1 < 1 .or. nn1 > this%maxbound) then
3109  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3110  trim(adjustl(obsrv%ObsTypeId)), &
3111  'reach must be greater than 0 and less than or equal to', &
3112  this%maxbound, '(specified value is ', nn1, ')'
3113  call store_error(errmsg)
3114  end if
3115  end do
3116  end do
3117  !
3118  ! -- evaluate if there are any observation errors
3119  if (count_errors() > 0) then
3120  call this%parser%StoreErrorUnit()
3121  end if
3122  end if
3123  !
3124  ! -- return
3125  return
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 3180 of file gwf-sfr.f90.

3181  ! -- modules
3183  ! -- dummy variables
3184  class(SfrType), intent(inout) :: this !< SfrType object
3185  integer(I4B), intent(in) :: n !< reach number
3186  integer(I4B), intent(inout) :: ichkustrm !< flag indicating if upstream fraction data specified
3187  character(len=LINELENGTH), intent(inout) :: crossfile !< cross-section file name
3188  ! -- local variables
3189  character(len=10) :: cnum
3190  character(len=LINELENGTH) :: text
3191  character(len=LINELENGTH) :: caux
3192  character(len=LINELENGTH) :: keyword
3193  integer(I4B) :: ival
3194  integer(I4B) :: ii
3195  integer(I4B) :: jj
3196  integer(I4B) :: idiv
3197  integer(I4B) :: ixserror
3198  character(len=10) :: cp
3199  real(DP) :: divq
3200  real(DP), pointer :: bndElem => null()
3201  !
3202  ! -- initialize variables
3203  crossfile = 'NONE'
3204  !
3205  ! -- read line
3206  call this%parser%GetStringCaps(keyword)
3207  select case (keyword)
3208  case ('STATUS')
3209  ichkustrm = 1
3210  call this%parser%GetStringCaps(text)
3211  if (text == 'INACTIVE') then
3212  this%iboundpak(n) = 0
3213  else if (text == 'ACTIVE') then
3214  this%iboundpak(n) = 1
3215  else if (text == 'SIMPLE') then
3216  this%iboundpak(n) = -1
3217  else
3218  write (errmsg, '(2a)') &
3219  'Unknown '//trim(this%text)//' sfr status keyword: ', trim(text)
3220  call store_error(errmsg)
3221  end if
3222  case ('BEDK')
3223  call this%parser%GetString(text)
3224  jj = 1 ! For 'BEDK'
3225  bndelem => this%hk(n)
3226  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3227  this%packName, 'BND', &
3228  this%tsManager, this%iprpak, &
3229  'BEDK')
3230  case ('MANNING')
3231  call this%parser%GetString(text)
3232  jj = 1 ! For 'MANNING'
3233  bndelem => this%rough(n)
3234  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3235  this%packName, 'BND', &
3236  this%tsManager, this%iprpak, &
3237  'MANNING')
3238  case ('STAGE')
3239  call this%parser%GetString(text)
3240  jj = 1 ! For 'STAGE'
3241  bndelem => this%sstage(n)
3242  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3243  this%packName, 'BND', &
3244  this%tsManager, this%iprpak, 'STAGE')
3245  case ('RAINFALL')
3246  call this%parser%GetString(text)
3247  jj = 1 ! For 'RAIN'
3248  bndelem => this%rain(n)
3249  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3250  this%packName, 'BND', &
3251  this%tsManager, this%iprpak, 'RAIN')
3252  case ('EVAPORATION')
3253  call this%parser%GetString(text)
3254  jj = 1 ! For 'EVAP'
3255  bndelem => this%evap(n)
3256  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3257  this%packName, 'BND', &
3258  this%tsManager, this%iprpak, &
3259  'EVAP')
3260  case ('RUNOFF')
3261  call this%parser%GetString(text)
3262  jj = 1 ! For 'RUNOFF'
3263  bndelem => this%runoff(n)
3264  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3265  this%packName, 'BND', &
3266  this%tsManager, this%iprpak, &
3267  'RUNOFF')
3268  case ('INFLOW')
3269  call this%parser%GetString(text)
3270  jj = 1 ! For 'INFLOW'
3271  bndelem => this%inflow(n)
3272  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3273  this%packName, 'BND', &
3274  this%tsManager, this%iprpak, &
3275  'INFLOW')
3276  case ('DIVERSION')
3277  !
3278  ! -- make sure reach has at least one diversion
3279  if (this%ndiv(n) < 1) then
3280  write (cnum, '(i0)') n
3281  errmsg = 'diversions cannot be specified for reach '//trim(cnum)
3282  call store_error(errmsg)
3283  end if
3284  !
3285  ! -- read diversion number
3286  ival = this%parser%GetInteger()
3287  if (ival < 1 .or. ival > this%ndiv(n)) then
3288  write (cnum, '(i0)') n
3289  errmsg = 'Reach '//trim(cnum)
3290  write (cnum, '(i0)') this%ndiv(n)
3291  errmsg = trim(errmsg)//' diversion number should be between 1 '// &
3292  'and '//trim(cnum)//'.'
3293  call store_error(errmsg)
3294  end if
3295  idiv = ival
3296  !
3297  ! -- read value
3298  call this%parser%GetString(text)
3299  ii = this%iadiv(n) + idiv - 1
3300  jj = 1 ! For 'DIVERSION'
3301  bndelem => this%divflow(ii)
3302  call read_value_or_time_series_adv(text, ii, jj, bndelem, &
3303  this%packName, 'BND', &
3304  this%tsManager, this%iprpak, &
3305  'DIVFLOW')
3306  !
3307  ! -- if diversion cprior is 'fraction', ensure that 0.0 <= fraction <= 1.0
3308  cp = this%divcprior(ii)
3309  divq = this%divflow(ii)
3310  if (cp == 'FRACTION' .and. (divq < dzero .or. divq > done)) then
3311  write (errmsg, '(a,1x,i0,a)') &
3312  'cprior is type FRACTION for diversion no.', ii, &
3313  ', but divflow not within the range 0.0 to 1.0'
3314  call store_error(errmsg)
3315  end if
3316  case ('UPSTREAM_FRACTION')
3317  ichkustrm = 1
3318  call this%parser%GetString(text)
3319  jj = 1 ! For 'USTRF'
3320  bndelem => this%ustrf(n)
3321  call read_value_or_time_series_adv(text, n, jj, bndelem, &
3322  this%packName, 'BND', &
3323  this%tsManager, this%iprpak, 'USTRF')
3324 
3325  case ('CROSS_SECTION')
3326  ixserror = 0
3327  !
3328  ! -- read FILE keyword
3329  call this%parser%GetStringCaps(keyword)
3330  select case (keyword)
3331  case ('TAB6')
3332  call this%parser%GetStringCaps(keyword)
3333  if (trim(adjustl(keyword)) /= 'FILEIN') then
3334  errmsg = 'TAB6 keyword must be followed by "FILEIN" '// &
3335  'then by filename.'
3336  call store_error(errmsg)
3337  ixserror = 1
3338  end if
3339  if (ixserror == 0) then
3340  call this%parser%GetString(crossfile)
3341  end if
3342  case default
3343  write (errmsg, '(a,1x,i4,1x,a)') &
3344  'CROSS-SECTION TABLE ENTRY for REACH ', n, &
3345  'MUST INCLUDE TAB6 KEYWORD'
3346  call store_error(errmsg)
3347  end select
3348 
3349  case ('AUXILIARY')
3350  call this%parser%GetStringCaps(caux)
3351  do jj = 1, this%naux
3352  if (trim(adjustl(caux)) /= trim(adjustl(this%auxname(jj)))) cycle
3353  call this%parser%GetString(text)
3354  ii = n
3355  bndelem => this%rauxvar(jj, ii)
3356  call read_value_or_time_series_adv(text, ii, jj, bndelem, &
3357  this%packName, 'AUX', &
3358  this%tsManager, this%iprpak, &
3359  this%auxname(jj))
3360  exit
3361  end do
3362 
3363  case default
3364  write (errmsg, '(a,a)') &
3365  'Unknown '//trim(this%text)//' sfr data keyword: ', &
3366  trim(keyword)//'.'
3367  call store_error(errmsg)
3368  end select
3369  !
3370  ! -- return
3371  return
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 5215 of file gwf-sfr.f90.

5216  ! -- dummy variables
5217  class(SfrType) :: this !< SfrType object
5218  ! -- local variables
5219  integer(I4B) :: nbudterm
5220  integer(I4B) :: i
5221  integer(I4B) :: n
5222  integer(I4B) :: n1
5223  integer(I4B) :: n2
5224  integer(I4B) :: maxlist
5225  integer(I4B) :: naux
5226  integer(I4B) :: idx
5227  real(DP) :: q
5228  character(len=LENBUDTXT) :: text
5229  character(len=LENBUDTXT), dimension(1) :: auxtxt
5230  !
5231  ! -- Determine the number of sfr budget terms. These are fixed for
5232  ! the simulation and cannot change. This includes FLOW-JA-FACE
5233  ! so they can be written to the binary budget files, but these internal
5234  ! flows are not included as part of the budget table.
5235  nbudterm = 8
5236  if (this%imover == 1) nbudterm = nbudterm + 2
5237  if (this%naux > 0) nbudterm = nbudterm + 1
5238  !
5239  ! -- set up budobj
5240  call budgetobject_cr(this%budobj, this%packName)
5241  call this%budobj%budgetobject_df(this%maxbound, nbudterm, 0, 0, &
5242  ibudcsv=this%ibudcsv)
5243  idx = 0
5244  !
5245  ! -- Go through and set up each budget term
5246  text = ' FLOW-JA-FACE'
5247  idx = idx + 1
5248  maxlist = this%nconn
5249  naux = 1
5250  auxtxt(1) = ' FLOW-AREA'
5251  call this%budobj%budterm(idx)%initialize(text, &
5252  this%name_model, &
5253  this%packName, &
5254  this%name_model, &
5255  this%packName, &
5256  maxlist, .false., .false., &
5257  naux, auxtxt)
5258  !
5259  ! -- store connectivity
5260  call this%budobj%budterm(idx)%reset(this%nconn)
5261  q = dzero
5262  do n = 1, this%maxbound
5263  n1 = n
5264  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5265  n2 = this%ja(i)
5266  call this%budobj%budterm(idx)%update_term(n1, n2, q)
5267  end do
5268  end do
5269  !
5270  ! --
5271  text = ' GWF'
5272  idx = idx + 1
5273  maxlist = this%maxbound - this%ianynone
5274  naux = 1
5275  auxtxt(1) = ' FLOW-AREA'
5276  call this%budobj%budterm(idx)%initialize(text, &
5277  this%name_model, &
5278  this%packName, &
5279  this%name_model, &
5280  this%name_model, &
5281  maxlist, .false., .true., &
5282  naux, auxtxt)
5283  call this%budobj%budterm(idx)%reset(this%maxbound)
5284  q = dzero
5285  do n = 1, this%maxbound
5286  n2 = this%igwfnode(n)
5287  if (n2 > 0) then
5288  call this%budobj%budterm(idx)%update_term(n, n2, q)
5289  end if
5290  end do
5291  !
5292  ! --
5293  text = ' RAINFALL'
5294  idx = idx + 1
5295  maxlist = this%maxbound
5296  naux = 0
5297  call this%budobj%budterm(idx)%initialize(text, &
5298  this%name_model, &
5299  this%packName, &
5300  this%name_model, &
5301  this%packName, &
5302  maxlist, .false., .false., &
5303  naux)
5304  !
5305  ! --
5306  text = ' EVAPORATION'
5307  idx = idx + 1
5308  maxlist = this%maxbound
5309  naux = 0
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)
5317  !
5318  ! --
5319  text = ' RUNOFF'
5320  idx = idx + 1
5321  maxlist = this%maxbound
5322  naux = 0
5323  call this%budobj%budterm(idx)%initialize(text, &
5324  this%name_model, &
5325  this%packName, &
5326  this%name_model, &
5327  this%packName, &
5328  maxlist, .false., .false., &
5329  naux)
5330  !
5331  ! --
5332  text = ' EXT-INFLOW'
5333  idx = idx + 1
5334  maxlist = this%maxbound
5335  naux = 0
5336  call this%budobj%budterm(idx)%initialize(text, &
5337  this%name_model, &
5338  this%packName, &
5339  this%name_model, &
5340  this%packName, &
5341  maxlist, .false., .false., &
5342  naux)
5343  !
5344  ! --
5345  text = ' EXT-OUTFLOW'
5346  idx = idx + 1
5347  maxlist = this%maxbound
5348  naux = 0
5349  call this%budobj%budterm(idx)%initialize(text, &
5350  this%name_model, &
5351  this%packName, &
5352  this%name_model, &
5353  this%packName, &
5354  maxlist, .false., .false., &
5355  naux)
5356  !
5357  ! --
5358  text = ' STORAGE'
5359  idx = idx + 1
5360  maxlist = this%maxbound
5361  naux = 1
5362  auxtxt(1) = ' VOLUME'
5363  call this%budobj%budterm(idx)%initialize(text, &
5364  this%name_model, &
5365  this%packName, &
5366  this%name_model, &
5367  this%packName, &
5368  maxlist, .false., .false., &
5369  naux, auxtxt)
5370  !
5371  ! --
5372  if (this%imover == 1) then
5373  !
5374  ! --
5375  text = ' FROM-MVR'
5376  idx = idx + 1
5377  maxlist = this%maxbound
5378  naux = 0
5379  call this%budobj%budterm(idx)%initialize(text, &
5380  this%name_model, &
5381  this%packName, &
5382  this%name_model, &
5383  this%packName, &
5384  maxlist, .false., .false., &
5385  naux)
5386  !
5387  ! --
5388  text = ' TO-MVR'
5389  idx = idx + 1
5390  maxlist = this%maxbound
5391  naux = 0
5392  call this%budobj%budterm(idx)%initialize(text, &
5393  this%name_model, &
5394  this%packName, &
5395  this%name_model, &
5396  this%packName, &
5397  maxlist, .false., .false., &
5398  naux)
5399  end if
5400  !
5401  ! --
5402  naux = this%naux
5403  if (naux > 0) then
5404  !
5405  ! --
5406  text = ' AUXILIARY'
5407  idx = idx + 1
5408  maxlist = this%maxbound
5409  call this%budobj%budterm(idx)%initialize(text, &
5410  this%name_model, &
5411  this%packName, &
5412  this%name_model, &
5413  this%packName, &
5414  maxlist, .false., .false., &
5415  naux, this%auxname)
5416  end if
5417  !
5418  ! -- if sfr flow for each reach are written to the listing file
5419  if (this%iprflow /= 0) then
5420  call this%budobj%flowtable_df(this%iout, cellids='GWF')
5421  end if
5422  !
5423  ! -- return
5424  return
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 5667 of file gwf-sfr.f90.

5668  ! -- dummy variables
5669  class(SfrType) :: this !< SfrType object
5670  ! -- local variables
5671  integer(I4B) :: nterms
5672  character(len=LINELENGTH) :: title
5673  character(len=LINELENGTH) :: text
5674  !
5675  ! -- setup stage table
5676  if (this%iprhed > 0) then
5677  !
5678  ! -- Determine the number of sfr budget terms. These are fixed for
5679  ! the simulation and cannot change. This includes FLOW-JA-FACE
5680  ! so they can be written to the binary budget files, but these internal
5681  ! flows are not included as part of the budget table.
5682  nterms = 8
5683  if (this%inamedbound == 1) then
5684  nterms = nterms + 1
5685  end if
5686  !
5687  ! -- set up table title
5688  title = trim(adjustl(this%text))//' PACKAGE ('// &
5689  trim(adjustl(this%packName))//') STAGES FOR EACH CONTROL VOLUME'
5690  !
5691  ! -- set up stage tableobj
5692  call table_cr(this%stagetab, this%packName, title)
5693  call this%stagetab%table_df(this%maxbound, nterms, this%iout, &
5694  transient=.true.)
5695  !
5696  ! -- Go through and set up table budget term
5697  if (this%inamedbound == 1) then
5698  text = 'NAME'
5699  call this%stagetab%initialize_column(text, lenboundname, &
5700  alignment=tableft)
5701  end if
5702  !
5703  ! -- reach number
5704  text = 'NUMBER'
5705  call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
5706  !
5707  ! -- cellids
5708  text = 'CELLID'
5709  call this%stagetab%initialize_column(text, 20, alignment=tableft)
5710  !
5711  ! -- reach stage
5712  text = 'STAGE'
5713  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5714  !
5715  ! -- reach depth
5716  text = 'DEPTH'
5717  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5718  !
5719  ! -- reach width
5720  text = 'WIDTH'
5721  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5722  !
5723  ! -- gwf head
5724  text = 'GWF HEAD'
5725  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5726  !
5727  ! -- streambed conductance
5728  text = 'STREAMBED CONDUCTANCE'
5729  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5730  !
5731  ! -- streambed gradient
5732  text = 'STREAMBED GRADIENT'
5733  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5734  end if
5735  !
5736  ! -- return
5737  return
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 3379 of file gwf-sfr.f90.

3380  ! -- dummy variables
3381  class(SfrType) :: this !< SfrType object
3382  integer(I4B), intent(in) :: n !< reach number
3383  real(DP), intent(in) :: h !< groundwater head in cell connected to reach
3384  real(DP), intent(inout) :: hcof !< coefficient term added to the diagonal
3385  real(DP), intent(inout) :: rhs !< right-hand side term
3386  logical(LGP), intent(in), optional :: update !< boolean indicating if the reach depth and stage variables should be updated to current iterate
3387  ! -- local variables
3388  logical(LGP) :: lupdate
3389  integer(I4B) :: i
3390  integer(I4B) :: ii
3391  integer(I4B) :: n2
3392  real(DP) :: hgwf
3393  real(DP) :: sa
3394  real(DP) :: sa_wet
3395  real(DP) :: qu
3396  real(DP) :: qi
3397  real(DP) :: qr
3398  real(DP) :: qe
3399  real(DP) :: qro
3400  real(DP) :: qsrc
3401  real(DP) :: qfrommvr
3402  real(DP) :: qgwf
3403  real(DP) :: tp
3404  real(DP) :: bt
3405  real(DP) :: hsfr
3406  real(DP) :: qd
3407  real(DP) :: d1
3408  real(DP) :: sumleak
3409  real(DP) :: sumrch
3410  real(DP) :: gwfhcof
3411  real(DP) :: gwfrhs
3412  !
3413  ! -- Process optional dummy variables
3414  if (present(update)) then
3415  lupdate = update
3416  else
3417  lupdate = .true.
3418  end if
3419 
3420  ! -- initialize variables
3421  hcof = dzero
3422  rhs = dzero
3423  !
3424  if (this%iboundpak(n) == 0) then
3425  this%depth(n) = dzero
3426  this%stage(n) = dhnoflo
3427  this%usflow(n) = dzero
3428  this%simevap(n) = dzero
3429  this%simrunoff(n) = dzero
3430  this%dsflow(n) = dzero
3431  this%gwflow(n) = dzero
3432  else
3433  hgwf = h
3434  d1 = dzero
3435  qsrc = dzero
3436  qgwf = dzero
3437 
3438  ! -- calculate initial depth assuming a wide cross-section and
3439  ! ignore groundwater leakage
3440  ! -- calculate upstream flow
3441  qu = dzero
3442  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3443  if (this%idir(i) < 0) cycle
3444  n2 = this%ja(i)
3445  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
3446  if (this%idir(ii) > 0) cycle
3447  if (this%ja(ii) /= n) cycle
3448  qu = qu + this%qconn(ii)
3449  end do
3450  end do
3451  this%usflow(n) = qu
3452 
3453  ! -- calculate remaining terms
3454  sa = this%calc_surface_area(n)
3455  sa_wet = this%calc_surface_area_wet(n, this%depth(n))
3456  qi = this%inflow(n)
3457  qr = this%rain(n) * sa
3458  qe = this%evap(n) * sa_wet
3459  qro = this%runoff(n)
3460 
3461  ! -- Water mover term; assume that it goes in at the upstream end of the reach
3462  qfrommvr = dzero
3463  if (this%imover == 1) then
3464  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3465  end if
3466 
3467  ! -- calculate downstream flow ignoring groundwater leakage
3468  qsrc = qu + qi + qr - qe + qro + qfrommvr
3469 
3470  ! -- adjust runoff or evaporation if sum of sources is negative
3471  call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)
3472 
3473  ! -- set simulated evaporation and runoff
3474  this%simevap(n) = qe
3475  this%simrunoff(n) = qro
3476 
3477  ! -- calculate reach flow using appropriate method
3478  if (this%iboundpak(n) < 0) then
3479  call this%sfr_calc_constant(n, d1, hgwf, qgwf, qd)
3480  else
3481  call this%sfr_calc_steady(n, d1, hgwf, qu, qi, &
3482  qfrommvr, qr, qe, qro, &
3483  qgwf, qd)
3484  end if
3485 
3486  ! -- update sfr stage
3487  tp = this%strtop(n)
3488  bt = tp - this%bthick(n)
3489  hsfr = tp + d1
3490 
3491  ! -- update stored values
3492  if (lupdate) then
3493  ! -- save depth and calculate stage
3494  this%depth(n) = d1
3495  this%stage(n) = hsfr
3496  ! -- update flows
3497  call this%sfr_update_flows(n, qd, qgwf)
3498  end if
3499 
3500  ! -- calculate sumleak and sumrch
3501  sumleak = dzero
3502  sumrch = dzero
3503  if (this%gwfiss == 0) then
3504  sumleak = qgwf
3505  else
3506  sumleak = qgwf
3507  end if
3508  if (hgwf < bt) then
3509  sumrch = qgwf
3510  end if
3511 
3512  ! -- make final qgwf calculation and obtain
3513  ! gwfhcof and gwfrhs values
3514  call this%sfr_calc_qgwf(n, d1, hgwf, qgwf, gwfhcof, gwfrhs)
3515 
3516  ! -- update hcof and rhs terms
3517  if (abs(sumleak) > dzero) then
3518  ! -- stream leakage is not head dependent
3519  if (hgwf < bt) then
3520  rhs = rhs - sumrch
3521  ! -- stream leakage is head dependent
3522  else if ((sumleak - qsrc) < -dem30) then
3523  if (this%gwfiss == 0) then
3524  rhs = rhs + gwfrhs - sumrch
3525  else
3526  rhs = rhs + gwfrhs
3527  end if
3528  hcof = gwfhcof
3529  ! -- place holder for UZF
3530  else
3531  if (this%gwfiss == 0) then
3532  rhs = rhs - sumleak - sumrch
3533  else
3534  rhs = rhs - sumleak
3535  end if
3536  end if
3537 
3538  ! -- add groundwater leakage
3539  else if (hgwf < bt) then
3540  rhs = rhs - sumrch
3541  end if
3542  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 3551 of file gwf-sfr.f90.

3552  ! -- dummy variables
3553  class(SfrType), intent(inout) :: this !< SfrType object
3554  integer(I4B), intent(in) :: n !< reach number
3555  real(DP), intent(inout) :: qd !< downstream reach flow
3556  real(DP), intent(in) :: qgwf !< groundwater leakage for reach
3557  ! -- local variables
3558  integer(I4B) :: i
3559  integer(I4B) :: n2
3560  integer(I4B) :: idiv
3561  integer(I4B) :: jpos
3562  real(DP) :: qdiv
3563  real(DP) :: f
3564  !
3565  ! -- update reach terms
3566  !
3567  ! -- save final downstream stream flow
3568  this%dsflow(n) = qd
3569  !
3570  ! -- save groundwater leakage
3571  this%gwflow(n) = qgwf
3572  !
3573  ! -- route downstream flow
3574  if (qd > dzero) then
3575  !
3576  ! -- route water to diversions
3577  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3578  if (this%idir(i) > 0) cycle
3579  idiv = this%idiv(i)
3580  if (idiv == 0) cycle
3581  jpos = this%iadiv(n) + idiv - 1
3582  call this%sfr_calc_div(n, idiv, qd, qdiv)
3583  this%qconn(i) = qdiv
3584  this%divq(jpos) = qdiv
3585  end do
3586  !
3587  ! -- Mover terms: store outflow after diversion loss
3588  ! as qformvr and reduce outflow (qd)
3589  ! by how much was actually sent to the mover
3590  if (this%imover == 1) then
3591  call this%pakmvrobj%accumulate_qformvr(n, qd)
3592  qd = max(qd - this%pakmvrobj%get_qtomvr(n), dzero)
3593  end if
3594  !
3595  ! -- route remaining water to downstream reaches
3596  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3597  if (this%idir(i) > 0) cycle
3598  if (this%idiv(i) > 0) cycle
3599  n2 = this%ja(i)
3600  if (this%iboundpak(n2) == 0) cycle
3601  f = this%ustrf(n2) / this%ftotnd(n)
3602  this%qconn(i) = qd * f
3603  end do
3604  else
3605  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3606  if (this%idir(i) > 0) cycle
3607  this%qconn(i) = dzero
3608  idiv = this%idiv(i)
3609  if (idiv == 0) cycle
3610  jpos = this%iadiv(n) + idiv - 1
3611  this%divq(jpos) = dzero
3612  end do
3613  end if
3614  !
3615  ! -- return
3616  return

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