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

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

Data Types

type  sfrinputtype
 Input context array pointers for SFR. More...
 
type  sfrtype
 

Functions/Subroutines

subroutine, public sfr_create (packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
 @ 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_checkin_deprecated_names (this)
 Alias deprecated SFR variable names to their current storage. More...
 
subroutine sfr_source_options (this)
 Source OPTIONS from input context. More...
 
subroutine sfr_source_dimensions (this)
 Source DIMENSIONS block from input context and load static data. More...
 
subroutine sfr_source_packagedata (this)
 Source PACKAGEDATA block from input context. More...
 
subroutine sfr_source_crosssections (this)
 Source CROSSSECTIONS block from input context. More...
 
subroutine sfr_source_connectiondata (this)
 Source CONNECTIONDATA block from input context. More...
 
subroutine sfr_source_diversions (this)
 Source DIVERSIONS block from input context. More...
 
subroutine sfr_source_initialstages (this)
 Source INITIALSTAGES block from input context. More...
 
subroutine sfr_ar (this)
 @ brief Allocate and read method for package More...
 
subroutine sfr_rp (this)
 @ brief Read and prepare period data for package More...
 
subroutine sfr_ad (this)
 @ brief Advance the package More...
 
subroutine sfr_cf (this)
 @ brief Formulate the package hcof and rhs terms. More...
 
subroutine sfr_fc (this, rhs, ia, idxglo, matrix_sln)
 @ brief Copy hcof and rhs terms into solution. More...
 
subroutine sfr_fn (this, rhs, ia, idxglo, matrix_sln)
 @ brief Add Newton-Raphson terms for package into solution. More...
 
subroutine sfr_cc (this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
 @ brief Convergence check for package. More...
 
subroutine sfr_cq (this, x, flowja, iadv)
 @ brief Calculate package flows. More...
 
subroutine sfr_ot_package_flows (this, icbcfl, ibudfl)
 @ brief Output package flow terms. More...
 
subroutine sfr_ot_dv (this, idvsave, idvprint)
 @ brief Output package dependent-variable terms. More...
 
subroutine sfr_ot_bdsummary (this, kstp, kper, iout, ibudfl)
 @ brief Output advanced package budget summary. More...
 
subroutine sfr_fp (this)
 Write the Courant-number summary table to the listing file. More...
 
subroutine sfr_dt (this)
 Submit the ATS time step for the most Courant-constraining reach. More...
 
subroutine sfr_calc_celerity (this, n, q, celerity)
 Kinematic-wave celerity from a flow perturbation (0 if dry) More...
 
subroutine sfr_da (this)
 @ brief Deallocate package memory More...
 
subroutine sfr_precompute_tvd (this)
 Pre-compute the single upstream reach index for the TVD limiter. More...
 
subroutine define_listlabel (this)
 @ brief Define the list label for the package More...
 
logical function sfr_obs_supported (this)
 Determine if observations are supported. More...
 
subroutine sfr_df_obs (this)
 Define the observation types available in the package. More...
 
subroutine sfr_bd_obs (this)
 Save observations for the package. More...
 
subroutine sfr_rp_obs (this)
 Read and prepare observations for a package. More...
 
subroutine sfr_process_obsid (obsrv, dis, inunitobs, iout)
 Process observation IDs for a package. More...
 
subroutine sfr_solve (this, n, h, hcof, rhs, update)
 Solve reach continuity equation. More...
 
subroutine sfr_update_flows (this, n, qd, qgwf)
 Update flow terms. More...
 
subroutine sfr_adjust_ro_ev (this, qc, qu, qi, qr, qro, qe, qfrommvr)
 Adjust runoff and evaporation. More...
 
subroutine sfr_calc_qd (this, n, depth, hgwf, qgwf, qd)
 Calculate downstream flow term. More...
 
subroutine sfr_calc_qsource (this, n, depth, qsrc)
 Calculate sum of sources. More...
 
subroutine sfr_calc_qman (this, n, depth, qman)
 Calculate streamflow. More...
 
subroutine sfr_calc_qgwf (this, n, depth, hgwf, qgwf, gwfhcof, gwfrhs)
 Calculate reach-aquifer exchange. More...
 
integer(i4b) function sfr_gwf_conn (this, n)
 Determine if a reach is connected to a gwf cell. More...
 
subroutine sfr_calc_cond (this, n, depth, cond, hsfr, h_temp)
 Calculate reach-aquifer conductance. More...
 
subroutine sfr_calc_div (this, n, i, qd, qdiv)
 Calculate diversion flow. More...
 
subroutine sfr_calc_reach_depth (this, n, q1, d1)
 Calculate the depth at the midpoint. More...
 
subroutine sfr_calc_xs_depth (this, n, qrch, d)
 Calculate the depth at the midpoint of a irregular cross-section. More...
 
subroutine sfr_check_conversion (this)
 Check unit conversion data. More...
 
subroutine sfr_check_storage_weight (this)
 Check storage weight. More...
 
subroutine sfr_check_reaches (this)
 Check reach data. More...
 
subroutine sfr_check_connections (this)
 Check connection data. More...
 
subroutine sfr_check_diversions (this)
 Check diversions data. More...
 
subroutine sfr_check_initialstages (this)
 Check initial stage data. More...
 
subroutine sfr_check_ustrf (this)
 Check upstream fraction data. More...
 
subroutine sfr_set_period_value (this, i, n, setting)
 Apply a PERIOD setting value to reach n. More...
 
subroutine sfr_setup_budobj (this)
 Setup budget object for package. More...
 
subroutine sfr_fill_budobj (this)
 Copy flow terms into budget object for package. More...
 
subroutine sfr_setup_tableobj (this)
 Setup stage table object for package. More...
 
real(dp) function calc_area_wet (this, n, depth)
 Calculate wetted area. More...
 
real(dp) function calc_perimeter_wet (this, n, depth)
 Calculate wetted perimeter. More...
 
real(dp) function calc_surface_area (this, n)
 Calculate maximum surface area. More...
 
real(dp) function calc_surface_area_wet (this, n, depth)
 Calculate wetted surface area. More...
 
real(dp) function calc_top_width_wet (this, n, depth)
 Calculate wetted top width. More...
 
subroutine sfr_activate_density (this)
 Activate density terms. More...
 
subroutine sfr_activate_viscosity (this)
 Activate viscosity terms. More...
 
subroutine sfr_calculate_density_exchange (this, n, stage, head, cond, tops, flow, gwfhcof, gwfrhs)
 Calculate density terms. More...
 
subroutine sfr_input_init (this, mempath, naux)
 Bind SfrInputType PERIOD pointers to input context arrays. More...
 
subroutine sfr_input_destroy (this)
 Nullify all SfrInputType pointers. 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 5556 of file gwf-sfr.f90.

5557  ! -- return variable
5558  real(DP) :: calc_area_wet !< wetted area
5559  ! -- dummy
5560  class(SfrType) :: this !< SfrType object
5561  integer(I4B), intent(in) :: n !< reach number
5562  real(DP), intent(in) :: depth !< reach depth
5563  ! -- local
5564  integer(I4B) :: npts
5565  integer(I4B) :: i0
5566  integer(I4B) :: i1
5567  !
5568  ! -- Calculate wetted area
5569  npts = this%ncrosspts(n)
5570  i0 = this%iacross(n)
5571  i1 = this%iacross(n + 1) - 1
5572  if (npts > 1) then
5573  calc_area_wet = get_cross_section_area(npts, this%station(i0:i1), &
5574  this%xsheight(i0:i1), depth)
5575  else
5576  calc_area_wet = this%station(i0) * depth
5577  end if
Here is the call graph for this function:

◆ calc_perimeter_wet()

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

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

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

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

5585  ! -- return variable
5586  real(DP) :: calc_perimeter_wet !< wetted perimeter
5587  ! -- dummy
5588  class(SfrType) :: this !< SfrType object
5589  integer(I4B), intent(in) :: n !< reach number
5590  real(DP), intent(in) :: depth !< reach depth
5591  ! -- local
5592  integer(I4B) :: npts
5593  integer(I4B) :: i0
5594  integer(I4B) :: i1
5595  !
5596  ! -- Calculate wetted perimeter
5597  npts = this%ncrosspts(n)
5598  i0 = this%iacross(n)
5599  i1 = this%iacross(n + 1) - 1
5600  if (npts > 1) then
5601  calc_perimeter_wet = get_wetted_perimeter(npts, this%station(i0:i1), &
5602  this%xsheight(i0:i1), depth)
5603  else
5604  calc_perimeter_wet = this%station(i0) ! no depth dependence in original implementation
5605  end if
Here is the call graph for this function:

◆ calc_surface_area()

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

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

Returns
surface area
Parameters
thisSfrType object
[in]nreach number

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

5613  ! -- return variable
5614  real(DP) :: calc_surface_area !< surface area
5615  ! -- dummy
5616  class(SfrType) :: this !< SfrType object
5617  integer(I4B), intent(in) :: n !< reach number
5618  ! -- local
5619  integer(I4B) :: npts
5620  integer(I4B) :: i0
5621  integer(I4B) :: i1
5622  real(DP) :: top_width
5623  !
5624  ! -- Calculate surface area
5625  npts = this%ncrosspts(n)
5626  i0 = this%iacross(n)
5627  i1 = this%iacross(n + 1) - 1
5628  if (npts > 1) then
5629  top_width = get_saturated_topwidth(npts, this%station(i0:i1))
5630  else
5631  top_width = this%station(i0)
5632  end if
5633  calc_surface_area = top_width * this%length(n)
Here is the call graph for this function:

◆ calc_surface_area_wet()

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

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

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

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

5641  ! -- return variable
5642  real(DP) :: calc_surface_area_wet !< wetted surface area
5643  ! -- dummy
5644  class(SfrType) :: this !< SfrType object
5645  integer(I4B), intent(in) :: n !< reach number
5646  real(DP), intent(in) :: depth !< reach depth
5647  ! -- local
5648  real(DP) :: top_width
5649  !
5650  ! -- Calculate wetted surface area
5651  top_width = this%calc_top_width_wet(n, depth)
5652  calc_surface_area_wet = top_width * this%length(n)

◆ calc_top_width_wet()

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

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

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

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

5660  ! -- return variable
5661  real(DP) :: calc_top_width_wet !< wetted top width
5662  ! -- dummy
5663  class(SfrType) :: this !< SfrType object
5664  integer(I4B), intent(in) :: n !< reach number
5665  real(DP), intent(in) :: depth !< reach depth
5666  ! -- local
5667  integer(I4B) :: npts
5668  integer(I4B) :: i0
5669  integer(I4B) :: i1
5670  real(DP) :: sat
5671  !
5672  ! -- Calculate wetted top width
5673  npts = this%ncrosspts(n)
5674  i0 = this%iacross(n)
5675  i1 = this%iacross(n + 1) - 1
5676  sat = scubicsaturation(dem5, dzero, depth, dem5)
5677  if (npts > 1) then
5678  calc_top_width_wet = sat * get_wetted_topwidth(npts, &
5679  this%station(i0:i1), &
5680  this%xsheight(i0:i1), &
5681  depth)
5682  else
5683  calc_top_width_wet = sat * this%station(i0)
5684  end if
Here is the call graph for this function:

◆ define_listlabel()

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

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

Parameters
[in,out]thisSfrType object

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

3060  ! -- dummy
3061  class(SfrType), intent(inout) :: this !< SfrType object
3062  !
3063  ! -- create the header list label
3064  this%listlabel = trim(this%filtyp)//' NO.'
3065  if (this%dis%ndim == 3) then
3066  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
3067  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
3068  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
3069  elseif (this%dis%ndim == 2) then
3070  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
3071  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
3072  else
3073  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
3074  end if
3075  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
3076  if (this%inamedbound == 1) then
3077  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
3078  end if

◆ sfr_activate_density()

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

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

Parameters
[in,out]thisSfrType object

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

5692  ! -- modules
5694  ! -- dummy
5695  class(SfrType), intent(inout) :: this !< SfrType object
5696  ! -- local
5697  integer(I4B) :: i
5698  integer(I4B) :: j
5699  !
5700  ! -- Set idense and reallocate denseterms to be of size MAXBOUND
5701  this%idense = 1
5702  call mem_reallocate(this%denseterms, 3, this%MAXBOUND, 'DENSETERMS', &
5703  this%memoryPath)
5704  do i = 1, this%maxbound
5705  do j = 1, 3
5706  this%denseterms(j, i) = dzero
5707  end do
5708  end do
5709  write (this%iout, '(/1x,a)') 'DENSITY TERMS HAVE BEEN ACTIVATED FOR SFR &
5710  &PACKAGE: '//trim(adjustl(this%packName))

◆ sfr_activate_viscosity()

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

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

Parameters
[in,out]thisSfrType object

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

5719  ! -- modules
5721  ! -- dummy
5722  class(SfrType), intent(inout) :: this !< SfrType object
5723  ! -- local
5724  integer(I4B) :: i
5725  integer(I4B) :: j
5726  !
5727  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
5728  this%ivsc = 1
5729  call mem_reallocate(this%viscratios, 2, this%MAXBOUND, 'VISCRATIOS', &
5730  this%memoryPath)
5731  do i = 1, this%maxbound
5732  do j = 1, 2
5733  this%viscratios(j, i) = done
5734  end do
5735  end do
5736  write (this%iout, '(/1x,a)') 'VISCOSITY HAS BEEN ACTIVATED FOR SFR &
5737  &PACKAGE: '//trim(adjustl(this%packName))

◆ sfr_ad()

subroutine sfrmodule::sfr_ad ( class(sfrtype)  this)

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

Parameters
thisSfrType object

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

2034  ! -- modules
2035  use constantsmodule, only: lenvarname
2036  ! -- dummy
2037  class(SfrType) :: this !< SfrType object
2038  ! -- local
2039  integer(I4B) :: n
2040  integer(I4B) :: i
2041  integer(I4B) :: ii
2042  integer(I4B) :: idiv
2043  integer(I4B) :: iaux
2044  character(len=LENVARNAME) :: setting
2045 
2046  ! -- sync PACKAGEDATA AUX TS and advance observations;
2047  ! -- step auxvar period block overrides
2048  call this%BndExtType%bnd_ad()
2049  !
2050  ! -- update previous values
2051  if (this%istorage == 1) then
2052  do n = 1, this%maxbound
2053  this%stageold(n) = this%stage(n)
2054  this%usinflowold(n) = this%usinflow(n)
2055  this%dsflowold(n) = this%dsflow(n)
2056  end do
2057  end if
2058  !
2059  ! -- sync PACKAGEDATA and PERIOD TS fields from input context each
2060  ! timestep; skipped when no TS6 files are configured. PACKAGEDATA
2061  ! values are synced only for rows linked to a time series
2062  if (this%ts_active) then
2063  do i = 1, this%maxbound
2064  n = this%pkg_ifno(i)
2065  if (.not. this%bedk_set(n) .and. &
2066  this%input%rhk_tslink(i) /= 0) &
2067  this%hk(n) = this%input%rhk(i)
2068  if (.not. this%manning_set(n) .and. &
2069  this%input%man_tslink(i) /= 0) &
2070  this%rough(n) = this%input%man(i)
2071  if (.not. this%ustrf_set(n) .and. &
2072  this%input%ustrf_tslink(i) /= 0) &
2073  this%ustrf(n) = this%input%ustrf(i)
2074  end do
2075  !
2076  if (this%input%nbound > 0) then
2077  do i = 1, this%input%nbound
2078  n = this%input%ifno(i)
2079  if (n < 1 .or. n > this%maxbound) cycle
2080  ! -- BEDK, MANNING, UPSTREAM_FRAC, STAGE, INFLOW, RAINFALL, EVAPORATION, RUNOFF
2081  setting = this%input%setting(i)
2082  call this%sfr_set_period_value(i, n, setting)
2083  ! -- DIVFLOW
2084  if (trim(setting) == 'DIVERSION') then
2085  if (this%ndiv(n) >= 1) then
2086  idiv = this%input%idv(i)
2087  if (idiv >= 1 .and. idiv <= this%ndiv(n)) then
2088  ii = this%iadiv(n) + idiv - 1
2089  end if
2090  end if
2091  end if
2092  end do
2093  end if
2094  end if
2095  !
2096  ! -- check upstream fractions (only needed when USTRF may be TS-updated;
2097  ! sfr_rp already validates ustrf once per period via ichkustrm)
2098  if (this%ts_active) call this%sfr_check_ustrf()
2099  !
2100  ! -- update auxiliary variables by copying from the derived-type time
2101  ! series variable into the bndpackage auxvar variable so that this
2102  ! information is properly written to the GWF budget file
2103  if (this%naux > 0) then
2104  do n = 1, this%maxbound
2105  do iaux = 1, this%naux
2106  if (this%noupdateauxvar(iaux) /= 0) cycle
2107  this%auxvar(iaux, n) = this%featureauxvar(iaux, n)
2108  end do
2109  end do
2110  end if
2111  !
2112  ! -- reset upstream flow to zero and set specified stage
2113  do n = 1, this%maxbound
2114  this%usflow(n) = dzero
2115  if (this%iboundpak(n) < 0) then
2116  this%stage(n) = this%sstage(n)
2117  end if
2118  end do
2119  !
2120  ! -- pakmvrobj ad
2121  if (this%imover == 1) then
2122  call this%pakmvrobj%ad()
2123  end if
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17

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

3692  ! -- dummy
3693  class(SfrType) :: this !< SfrType object
3694  real(DP), intent(inout) :: qc !< total reach volumetric flow
3695  real(DP), intent(in) :: qu !< upstream reach volumetric flow
3696  real(DP), intent(in) :: qi !< reach volumetric inflow
3697  real(DP), intent(in) :: qr !< reach volumetric rainfall
3698  real(DP), intent(inout) :: qro !< reach volumetric runoff
3699  real(DP), intent(inout) :: qe !< reach volumetric evaporation
3700  real(DP), intent(in) :: qfrommvr !< reach volumetric flow from mover
3701  ! -- local
3702  real(DP) :: qt
3703  !
3704  ! -- adjust runoff or evaporation if sum of sources is negative
3705  if (qc < dzero) then
3706  !
3707  ! -- calculate sources without evaporation
3708  qt = qu + qi + qr + qro + qfrommvr
3709  !
3710  ! -- runoff exceeds sources of water for reach
3711  if (qt < dzero) then
3712  if (qro < dzero) then
3713  qro = -(qu + qi + qr + qfrommvr)
3714  qe = dzero
3715  end if
3716  !
3717  ! -- evaporation exceeds sources of water for reach
3718  else
3719  if (qe > dzero) then
3720  qe = qu + qi + qr + qro + qfrommvr
3721  end if
3722  end if
3723  qc = qu + qi + qr - qe + qro + qfrommvr
3724  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 483 of file gwf-sfr.f90.

484  ! -- modules
486  ! -- dummy
487  class(SfrType), intent(inout) :: this !< SfrType object
488  ! -- local
489  integer(I4B) :: i
490  !
491  ! -- allocate character array for budget text
492  allocate (this%csfrbudget(this%bditems))
493  call mem_allocate(this%sfrname, lenboundname, this%maxbound, &
494  'SFRNAME', this%memoryPath)
495  !
496  ! -- variables originally in SfrDataType
497  call mem_allocate(this%iboundpak, this%maxbound, 'IBOUNDPAK', &
498  this%memoryPath)
499  call mem_allocate(this%igwfnode, this%maxbound, 'IGWFNODE', this%memoryPath)
500  call mem_allocate(this%igwftopnode, this%maxbound, 'IGWFTOPNODE', &
501  this%memoryPath)
502  call mem_allocate(this%length, this%maxbound, 'LENGTH', this%memoryPath)
503  call mem_allocate(this%width, this%maxbound, 'WIDTH', this%memoryPath)
504  call mem_allocate(this%strtop, this%maxbound, 'STRTOP', this%memoryPath)
505  call mem_allocate(this%bthick, this%maxbound, 'BTHICK', this%memoryPath)
506  call mem_allocate(this%slope, this%maxbound, 'SLOPE', this%memoryPath)
507  call mem_allocate(this%nconnreach, this%maxbound, 'NCONNREACH', &
508  this%memoryPath)
509  call mem_allocate(this%bedk_set, this%maxbound, 'BEDK_SET', this%memoryPath)
510  call mem_allocate(this%manning_set, this%maxbound, 'MANNING_SET', &
511  this%memoryPath)
512  call mem_allocate(this%ustrf_set, this%maxbound, 'USTRF_SET', &
513  this%memoryPath)
514  this%bedk_set = .false.
515  this%manning_set = .false.
516  this%ustrf_set = .false.
517  call mem_allocate(this%ftotnd, this%maxbound, 'FTOTND', this%memoryPath)
518  call mem_allocate(this%ndiv, this%maxbound, 'NDIV', this%memoryPath)
519  call mem_allocate(this%usflow, this%maxbound, 'USFLOW', this%memoryPath)
520  call mem_allocate(this%dsflow, this%maxbound, 'DSFLOW', this%memoryPath)
521  call mem_allocate(this%depth, this%maxbound, 'DEPTH', this%memoryPath)
522  call mem_allocate(this%stage, this%maxbound, 'STAGE', this%memoryPath)
523  call mem_allocate(this%gwflow, this%maxbound, 'GWFLOW', this%memoryPath)
524  call mem_allocate(this%simevap, this%maxbound, 'SIMEVAP', this%memoryPath)
525  call mem_allocate(this%simrunoff, this%maxbound, 'SIMRUNOFF', &
526  this%memoryPath)
527  call mem_allocate(this%stage0, this%maxbound, 'STAGE0', this%memoryPath)
528  call mem_allocate(this%usflow0, this%maxbound, 'USFLOW0', this%memoryPath)
529  !
530  ! -- stage, usflow, inflow, and dsflow for previous timestep
531  if (this%istorage == 1) then
532  call mem_allocate(this%stageold, this%maxbound, 'STAGEOLD', &
533  this%memoryPath)
534  call mem_allocate(this%usinflow, this%maxbound, 'USINFLOW', &
535  this%memoryPath)
536  call mem_allocate(this%usinflowold, this%maxbound, 'USINFLOWOLD', &
537  this%memoryPath)
538  call mem_allocate(this%dsflowold, this%maxbound, 'DSFLOWOLD', &
539  this%memoryPath)
540  call mem_allocate(this%storage, this%maxbound, 'STORAGE', &
541  this%memoryPath)
542  call mem_allocate(this%crmin, this%maxbound, 'CRMIN', this%memoryPath)
543  call mem_allocate(this%crmax, this%maxbound, 'CRMAX', this%memoryPath)
544  call mem_allocate(this%crsum, this%maxbound, 'CRSUM', this%memoryPath)
545  call mem_allocate(this%crcnt, this%maxbound, 'CRCNT', this%memoryPath)
546  if (this%ats_courant /= dnodata) then
547  call mem_allocate(this%itvd_upstream, this%maxbound, &
548  'ITVD_UPSTREAM', this%memoryPath)
549  else
550  call mem_allocate(this%itvd_upstream, 0, 'ITVD_UPSTREAM', this%memoryPath)
551  end if
552  end if
553  !
554  ! -- reach order and connection data
555  call mem_allocate(this%isfrorder, this%maxbound, 'ISFRORDER', &
556  this%memoryPath)
557  call mem_allocate(this%ia, this%maxbound + 1, 'IA', this%memoryPath)
558  call mem_allocate(this%ja, 0, 'JA', this%memoryPath)
559  call mem_allocate(this%idir, 0, 'IDIR', this%memoryPath)
560  call mem_allocate(this%idiv, 0, 'IDIV', this%memoryPath)
561  call mem_allocate(this%qconn, 0, 'QCONN', this%memoryPath)
562  !
563  ! -- alias into the input context's permanent, feature-indexed arrays
564  ! (allocated and DZERO-initialized by the loader)
565  call mem_setptr(this%rain, 'RAINFALL', this%input_mempath)
566  call mem_setptr(this%evap, 'EVAPORATION', this%input_mempath)
567  call mem_setptr(this%inflow, 'INFLOW', this%input_mempath)
568  call mem_setptr(this%runoff, 'RUNOFF', this%input_mempath)
569  call mem_setptr(this%sstage, 'STAGE', this%input_mempath)
570  call mem_setptr(this%hk, 'BEDK', this%input_mempath)
571  call mem_setptr(this%rough, 'MANNING', this%input_mempath)
572  call mem_setptr(this%ustrf, 'UPSTREAM_FRAC', this%input_mempath)
573  !
574  !
575  ! -- diversion variables
576  call mem_allocate(this%iadiv, this%maxbound + 1, 'IADIV', this%memoryPath)
577  call mem_allocate(this%divreach, 0, 'DIVREACH', this%memoryPath)
578  call mem_allocate(this%divq, 0, 'DIVQ', this%memoryPath)
579  !
580  ! -- cross-section data
581  call mem_allocate(this%ncrosspts, this%maxbound, 'NCROSSPTS', &
582  this%memoryPath)
583  call mem_allocate(this%iacross, this%maxbound + 1, 'IACROSS', &
584  this%memoryPath)
585  call mem_allocate(this%station, this%ncrossptstot, 'STATION', &
586  this%memoryPath)
587  call mem_allocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
588  this%memoryPath)
589  call mem_allocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
590  this%memoryPath)
591  !
592  ! -- initialize variables
593  this%iacross(1) = 0
594  do i = 1, this%maxbound
595  this%iboundpak(i) = 1
596  this%igwfnode(i) = 0
597  this%igwftopnode(i) = 0
598  this%length(i) = dzero
599  this%width(i) = dzero
600  this%strtop(i) = dzero
601  this%bthick(i) = dzero
602  this%hk(i) = dzero
603  this%slope(i) = dzero
604  this%nconnreach(i) = 0
605  this%ustrf(i) = dzero
606  this%ftotnd(i) = dzero
607  this%ndiv(i) = 0
608  this%usflow(i) = dzero
609  this%dsflow(i) = dzero
610  this%depth(i) = dzero
611  this%stage(i) = dzero
612  this%gwflow(i) = dzero
613  this%simevap(i) = dzero
614  this%simrunoff(i) = dzero
615  this%stage0(i) = dzero
616  this%usflow0(i) = dzero
617  !
618  ! -- stage
619  if (this%istorage == 1) then
620  this%stageold(i) = dzero
621  this%usinflow(i) = dzero
622  this%usinflowold(i) = dzero
623  this%dsflowold(i) = dzero
624  this%storage(i) = dzero
625  this%crmin(i) = dep20
626  this%crmax(i) = -dep20
627  this%crsum(i) = dzero
628  this%crcnt(i) = 0
629  if (this%ats_courant /= dnodata) then
630  this%itvd_upstream(i) = 0
631  end if
632  end if
633  !
634  ! -- boundary data
635  this%rough(i) = dzero
636  !
637  !
638  ! -- cross-section data
639  this%ncrosspts(i) = 0
640  this%iacross(i + 1) = 0
641  end do
642  !
643  ! -- initialize additional cross-section data
644  do i = 1, this%ncrossptstot
645  this%station(i) = dzero
646  this%xsheight(i) = dzero
647  this%xsrough(i) = dzero
648  end do
649  !
650  !-- fill csfrbudget
651  this%csfrbudget(1) = ' RAINFALL'
652  this%csfrbudget(2) = ' EVAPORATION'
653  this%csfrbudget(3) = ' RUNOFF'
654  this%csfrbudget(4) = ' EXT-INFLOW'
655  this%csfrbudget(5) = ' GWF'
656  this%csfrbudget(6) = ' EXT-OUTFLOW'
657  this%csfrbudget(7) = ' FROM-MVR'
658  this%csfrbudget(8) = ' TO-MVR'
659  !
660  ! -- allocate and initialize budget output data
661  call mem_allocate(this%qoutflow, this%maxbound, 'QOUTFLOW', this%memoryPath)
662  call mem_allocate(this%qextoutflow, this%maxbound, 'QEXTOUTFLOW', &
663  this%memoryPath)
664  do i = 1, this%maxbound
665  this%qoutflow(i) = dzero
666  this%qextoutflow(i) = dzero
667  end do
668  !
669  ! -- allocate and initialize dbuff
670  if (this%istageout > 0) then
671  call mem_allocate(this%dbuff, this%maxbound, 'DBUFF', this%memoryPath)
672  do i = 1, this%maxbound
673  this%dbuff(i) = dzero
674  end do
675  else
676  call mem_allocate(this%dbuff, 0, 'DBUFF', this%memoryPath)
677  end if
678  !
679  ! -- allocate character array for budget text
680  allocate (this%cauxcbc(this%cbcauxitems))
681  !
682  ! -- allocate and initialize qauxcbc
683  call mem_allocate(this%qauxcbc, this%cbcauxitems, 'QAUXCBC', &
684  this%memoryPath)
685  do i = 1, this%cbcauxitems
686  this%qauxcbc(i) = dzero
687  end do
688  !
689  ! -- fill cauxcbc
690  this%cauxcbc(1) = 'FLOW-AREA '
691  !
692  ! -- allocate denseterms to size 0
693  call mem_allocate(this%denseterms, 3, 0, 'DENSETERMS', this%memoryPath)
694  !
695  ! -- allocate viscratios to size 0
696  call mem_allocate(this%viscratios, 2, 0, 'VISCRATIOS', this%memoryPath)

◆ sfr_allocate_scalars()

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

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

Parameters
[in,out]thisSfrType object

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

413  ! -- modules
416  ! -- dummy
417  class(SfrType), intent(inout) :: this !< SfrType object
418  !
419  ! -- call standard BndExtType allocate scalars
420  call this%BndExtType%allocate_scalars()
421  !
422  ! -- allocate the object and assign values to object variables
423  call mem_allocate(this%istorage, 'ISTORAGE', this%memoryPath)
424  call mem_allocate(this%iprhed, 'IPRHED', this%memoryPath)
425  call mem_allocate(this%istageout, 'ISTAGEOUT', this%memoryPath)
426  call mem_allocate(this%ibudgetout, 'IBUDGETOUT', this%memoryPath)
427  call mem_allocate(this%ibudcsv, 'IBUDCSV', this%memoryPath)
428  call mem_allocate(this%ipakcsv, 'IPAKCSV', this%memoryPath)
429  call mem_allocate(this%idiversions, 'IDIVERSIONS', this%memoryPath)
430  call mem_allocate(this%maxsfrpicard, 'MAXSFRPICARD', this%memoryPath)
431  call mem_allocate(this%maxsfrit, 'MAXSFRIT', this%memoryPath)
432  call mem_allocate(this%bditems, 'BDITEMS', this%memoryPath)
433  call mem_allocate(this%cbcauxitems, 'CBCAUXITEMS', this%memoryPath)
434  call mem_allocate(this%unitconv, 'UNITCONV', this%memoryPath)
435  call mem_allocate(this%lengthconv, 'LENGTHCONV', this%memoryPath)
436  call mem_allocate(this%timeconv, 'TIMECONV', this%memoryPath)
437  call mem_allocate(this%dmaxchg, 'DMAXCHG', this%memoryPath)
438  call mem_allocate(this%deps, 'DEPS', this%memoryPath)
439  call mem_allocate(this%storage_weight, 'STORAGE_WEIGHT', this%memoryPath)
440  call mem_allocate(this%ats_courant, 'ATS_COURANT', this%memoryPath)
441  call mem_allocate(this%nconn, 'NCONN', this%memoryPath)
442  call mem_allocate(this%icheck, 'ICHECK', this%memoryPath)
443  call mem_allocate(this%iconvchk, 'ICONVCHK', this%memoryPath)
444  call mem_allocate(this%idense, 'IDENSE', this%memoryPath)
445  call mem_allocate(this%ianynone, 'IANYNONE', this%memoryPath)
446  call mem_allocate(this%ncrossptstot, 'NCROSSPTSTOT', this%memoryPath)
447  !
448  ! -- set pointer to gwf iss
449  call mem_setptr(this%gwfiss, 'ISS', create_mem_path(this%name_model))
450  !
451  ! -- Set values
452  this%istorage = 0
453  this%iprhed = 0
454  this%istageout = 0
455  this%ibudgetout = 0
456  this%ibudcsv = 0
457  this%ipakcsv = 0
458  this%idiversions = 0
459  this%maxsfrpicard = 100
460  this%maxsfrit = maxadpit
461  this%bditems = 8
462  this%cbcauxitems = 1
463  this%unitconv = done
464  this%lengthconv = dnodata
465  this%timeconv = dnodata
466  this%dmaxchg = dem5
467  this%deps = dp999 * this%dmaxchg
468  this%storage_weight = dnodata
469  this%ats_courant = dnodata
470  this%nconn = 0
471  this%icheck = 1
472  this%iconvchk = 1
473  this%idense = 0
474  this%ivsc = 0
475  this%ianynone = 0
476  this%ncrossptstot = 0
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
Here is the call graph for this function:

◆ sfr_ar()

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

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

Parameters
[in,out]thisSfrType object

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

1683  ! -- modules
1684  use tdismodule, only: inats
1685  ! -- dummy
1686  class(SfrType), intent(inout) :: this !< SfrType object
1687  ! -- local
1688  integer(I4B) :: n
1689  integer(I4B) :: ierr
1690  !
1691  ! -- allocate and read observations
1692  call this%obs%obs_ar()
1693  !
1694  ! -- allocate BndType connection-level arrays (nodelist, bound, auxvar, etc.)
1695  call this%BndExtType%allocate_arrays()
1696  !
1697  ! -- allocate featureauxvar and set pkg_ifno/pkg_auxvar input context
1698  ! pointers
1699  call this%BndExtType%allocate_featureauxvar()
1700  !
1701  ! -- set persistent PERIOD pointers into input context (valid for
1702  ! simulation lifetime)
1703  call this%input%init(this%input_mempath, this%naux)
1704  !
1705  ! -- set boundname for each connection
1706  if (this%inamedbound /= 0) then
1707  do n = 1, this%maxbound
1708  this%boundname(n) = this%sfrname(n)
1709  end do
1710  end if
1711  !
1712  ! -- copy boundname into boundname_cst
1713  call this%copy_boundname()
1714  !
1715  ! -- copy igwfnode into nodelist
1716  do n = 1, this%maxbound
1717  this%nodelist(n) = this%igwfnode(n)
1718  end do
1719  !
1720  ! -- check the sfr unit conversion data
1721  call this%sfr_check_conversion()
1722  !
1723  ! -- check the storage_weight
1724  call this%sfr_check_storage_weight()
1725  !
1726  ! -- check that ATS_COURANT is only used with STORAGE
1727  if (this%ats_courant /= dnodata .and. this%istorage /= 1) then
1728  write (errmsg, '(a)') &
1729  'ATS_COURANT OPTION REQUIRES STORAGE OPTION TO BE ACTIVE'
1730  call store_error(errmsg)
1731  end if
1732  !
1733  ! -- warn when ATS_COURANT is specified but ATS is not active in TDIS
1734  if (this%ats_courant /= dnodata .and. inats == 0) then
1735  write (warnmsg, '(a)') &
1736  'ATS_COURANT IS SPECIFIED IN THE SFR OPTIONS BLOCK BUT THE '// &
1737  'ATS PACKAGE IS NOT ACTIVE IN TDIS, SO THE TIME STEP IS NOT '// &
1738  'ADAPTED TO THE COURANT NUMBER. IF THE COURANT NUMBER EXCEEDS 1 '// &
1739  'THE EXPLICIT KINEMATIC-WAVE ROUTING MAY OSCILLATE WHILE STILL '// &
1740  'CLOSING THE BUDGET. ACTIVATE THE ATS PACKAGE OR USE A SMALLER '// &
1741  'TIME STEP.'
1742  call store_warning(warnmsg)
1743  end if
1744  !
1745  ! -- pre-compute TVD upstream connectivity when ATS_COURANT is active
1746  if (this%ats_courant /= dnodata .and. this%istorage == 1) then
1747  call this%sfr_precompute_tvd()
1748  end if
1749  !
1750  ! -- check the sfr reach data
1751  call this%sfr_check_reaches()
1752 
1753  ! -- check the connection data
1754  call this%sfr_check_connections()
1755 
1756  ! -- check the diversion data
1757  if (this%idiversions /= 0) then
1758  call this%sfr_check_diversions()
1759  end if
1760 
1761  ! -- check the diversion data
1762  if (this%istorage == 1) then
1763  call this%sfr_check_initialstages()
1764  end if
1765  !
1766  ! -- terminate if errors were detected in any of the static sfr data
1767  ierr = count_errors()
1768  if (ierr > 0) then
1769  call store_error_filename(this%input_fname)
1770  end if
1771  !
1772  ! -- setup pakmvrobj
1773  if (this%imover /= 0) then
1774  allocate (this%pakmvrobj)
1775  call this%pakmvrobj%ar(this%maxbound, this%maxbound, this%memoryPath)
1776  end if
integer(i4b), pointer, public inats
flag indicating ats active for simulation
Definition: tdis.f90:28
Here is the call graph for this function:

◆ sfr_bd_obs()

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

Method to save simulated values for the SFR package.

Parameters
thisSfrType object

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

3200  ! -- dummy
3201  class(SfrType) :: this !< SfrType object
3202  ! -- local
3203  integer(I4B) :: i
3204  integer(I4B) :: j
3205  integer(I4B) :: n
3206  real(DP) :: v
3207  character(len=100) :: msg
3208  type(ObserveType), pointer :: obsrv => null()
3209  !
3210  ! Write simulated values for all sfr observations
3211  if (this%obs%npakobs > 0) then
3212  call this%obs%obs_bd_clear()
3213  do i = 1, this%obs%npakobs
3214  obsrv => this%obs%pakobs(i)%obsrv
3215  do j = 1, obsrv%indxbnds_count
3216  n = obsrv%indxbnds(j)
3217  v = dzero
3218  select case (obsrv%ObsTypeId)
3219  case ('STAGE')
3220  v = this%stage(n)
3221  case ('TO-MVR')
3222  v = dnodata
3223  if (this%imover == 1) then
3224  v = this%pakmvrobj%get_qtomvr(n)
3225  if (v > dzero) then
3226  v = -v
3227  end if
3228  end if
3229  case ('FROM-MVR')
3230  v = dnodata
3231  if (this%imover == 1) then
3232  v = this%pakmvrobj%get_qfrommvr(n)
3233  end if
3234  case ('EXT-INFLOW')
3235  v = this%inflow(n)
3236  case ('INFLOW')
3237  v = this%usflow(n)
3238  case ('OUTFLOW')
3239  v = this%qoutflow(n)
3240  case ('EXT-OUTFLOW')
3241  v = this%qextoutflow(n)
3242  case ('RAINFALL')
3243  if (this%iboundpak(n) /= 0) then
3244  v = this%rain(n)
3245  else
3246  v = dzero
3247  end if
3248  case ('RUNOFF')
3249  v = this%simrunoff(n)
3250  case ('EVAPORATION')
3251  v = this%simevap(n)
3252  case ('SFR')
3253  v = this%gwflow(n)
3254  case ('UPSTREAM-FLOW')
3255  v = this%usflow(n)
3256  if (this%imover == 1) then
3257  v = v + this%pakmvrobj%get_qfrommvr(n)
3258  end if
3259  case ('DOWNSTREAM-FLOW')
3260  v = this%dsflow(n)
3261  if (v > dzero) then
3262  v = -v
3263  end if
3264  case ('DEPTH')
3265  v = this%depth(n)
3266  case ('WET-PERIMETER')
3267  v = this%calc_perimeter_wet(n, this%depth(n))
3268  case ('WET-AREA')
3269  v = this%calc_area_wet(n, this%depth(n))
3270  case ('WET-WIDTH')
3271  v = this%calc_top_width_wet(n, this%depth(n))
3272  case default
3273  msg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
3274  call store_error(msg)
3275  end select
3276  call this%obs%SaveOneSimval(obsrv, v)
3277  end do
3278  end do
3279  !
3280  ! -- write summary of package error messages
3281  if (count_errors() > 0) then
3282  call store_error_filename(this%input_fname)
3283  end if
3284  end if
Here is the call graph for this function:

◆ sfr_calc_celerity()

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

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

2841  ! -- dummy
2842  class(SfrType) :: this !< SfrType object
2843  integer(I4B), intent(in) :: n !< reach number
2844  real(DP), intent(in) :: q !< reach flow
2845  real(DP), intent(out) :: celerity !< kinematic-wave celerity
2846  ! -- local
2847  real(DP) :: d
2848  real(DP) :: a
2849  real(DP) :: a2
2850  !
2851  celerity = dzero
2852  call this%sfr_calc_reach_depth(n, q, d)
2853  if (d > dzero) then
2854  a = this%calc_area_wet(n, d)
2855  call this%sfr_calc_reach_depth(n, q + this%deps, d)
2856  a2 = this%calc_area_wet(n, d)
2857  if (a2 > a) then
2858  celerity = this%deps / (a2 - a)
2859  end if
2860  end if

◆ sfr_calc_cond()

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

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

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

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

3970  ! -- dummy
3971  class(SfrType) :: this !< SfrType object
3972  integer(I4B), intent(in) :: n !< reach number
3973  real(DP), intent(in) :: depth !< reach depth
3974  real(DP), intent(inout) :: cond !< reach-aquifer conductance
3975  real(DP), intent(in), optional :: hsfr !< stream stage
3976  real(DP), intent(in), optional :: h_temp !< head in gw cell
3977  ! -- local
3978  integer(I4B) :: node
3979  real(DP) :: wp
3980  real(DP) :: vscratio
3981  !
3982  ! -- initialize conductance
3983  cond = dzero
3984  !
3985  ! -- initial viscosity ratio to 1
3986  vscratio = done
3987  !
3988  ! -- calculate conductance if GWF cell is active
3989  ! rch-gwf flow will not occur if reach connected to an constant head cell
3990  node = this%igwfnode(n)
3991  if (node > 0) then
3992  if (this%ibound(node) > 0) then
3993  !
3994  ! -- direction of gradient across streambed determines which vsc ratio
3995  if (this%ivsc == 1) then
3996  if (hsfr > h_temp) then
3997  ! strm stg > gw head
3998  vscratio = this%viscratios(1, n)
3999  else
4000  vscratio = this%viscratios(2, n)
4001  end if
4002  end if
4003  wp = this%calc_perimeter_wet(n, depth)
4004  cond = this%hk(n) * vscratio * this%length(n) * wp / this%bthick(n)
4005  end if
4006  end if

◆ sfr_calc_div()

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

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

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

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

4017  ! -- dummy
4018  class(SfrType) :: this !< SfrType object
4019  integer(I4B), intent(in) :: n !< reach number
4020  integer(I4B), intent(in) :: i !< diversion number in reach
4021  real(DP), intent(inout) :: qd !< remaining downstream flow for reach
4022  real(DP), intent(inout) :: qdiv !< diversion flow for diversion i
4023  ! -- local
4024  character(len=10) :: cp
4025  integer(I4B) :: jpos
4026  integer(I4B) :: n2
4027  real(DP) :: v
4028  !
4029  ! -- set local variables
4030  jpos = this%iadiv(n) + i - 1
4031  n2 = this%divreach(jpos)
4032  cp = this%divcprior(jpos)
4033  v = this%divflow(jpos)
4034  !
4035  ! -- calculate diversion
4036  select case (cp)
4037  ! -- flood diversion
4038  case ('EXCESS')
4039  if (qd < v) then
4040  v = dzero
4041  else
4042  v = qd - v
4043  end if
4044  ! -- diversion percentage
4045  case ('FRACTION')
4046  v = qd * v
4047  ! -- STR priority algorithm
4048  case ('THRESHOLD')
4049  if (qd < v) then
4050  v = dzero
4051  end if
4052  ! -- specified diversion
4053  case ('UPTO')
4054  if (v > qd) then
4055  v = qd
4056  end if
4057  case default
4058  v = dzero
4059  end select
4060  !
4061  ! -- update upstream from for downstream reaches
4062  qd = qd - v
4063  qdiv = v

◆ sfr_calc_qd()

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

Method to calculate downstream flow for a SFR package reach.

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

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

3732  ! -- dummy
3733  class(SfrType) :: this !< SfrType object
3734  integer(I4B), intent(in) :: n !< reach number
3735  real(DP), intent(in) :: depth !< reach depth
3736  real(DP), intent(in) :: hgwf !< groundwater head in connected GWF cell
3737  real(DP), intent(inout) :: qgwf !< groundwater leakage for reach
3738  real(DP), intent(inout) :: qd !< residual
3739  ! -- local
3740  real(DP) :: qsrc
3741  !
3742  ! -- initialize residual
3743  qd = dzero
3744  !
3745  ! -- calculate total water sources excluding groundwater leakage
3746  call this%sfr_calc_qsource(n, depth, qsrc)
3747  !
3748  ! -- estimate groundwater leakage
3749  call this%sfr_calc_qgwf(n, depth, hgwf, qgwf)
3750  if (-qgwf > qsrc) qgwf = -qsrc
3751  !
3752  ! -- calculate down stream flow
3753  qd = qsrc + qgwf
3754  !
3755  ! -- limit downstream flow to a positive value
3756  if (qd < dem30) qd = dzero

◆ sfr_calc_qgwf()

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

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

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

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

3883  ! -- dummy
3884  class(SfrType) :: this !< SfrType object
3885  integer(I4B), intent(in) :: n !< reach number
3886  real(DP), intent(in) :: depth !< reach depth
3887  real(DP), intent(in) :: hgwf !< head in GWF cell connected to reach
3888  real(DP), intent(inout) :: qgwf !< reach-aquifer exchange
3889  real(DP), intent(inout), optional :: gwfhcof !< diagonal coefficient term for reach
3890  real(DP), intent(inout), optional :: gwfrhs !< right-hand side term for reach
3891  ! -- local
3892  integer(I4B) :: node
3893  real(DP) :: tp
3894  real(DP) :: bt
3895  real(DP) :: hsfr
3896  real(DP) :: h_temp
3897  real(DP) :: cond
3898  real(DP) :: sat
3899  real(DP) :: derv
3900  real(DP) :: gwfhcof0
3901  real(DP) :: gwfrhs0
3902  !
3903  ! -- initialize qgwf
3904  qgwf = dzero
3905  !
3906  ! -- skip sfr-aquifer exchange in external cells
3907  node = this%igwfnode(n)
3908  if (node < 1) return
3909  !
3910  ! -- skip sfr-aquifer exchange in inactive cells
3911  if (this%ibound(node) == 0) return
3912  !
3913  ! -- calculate saturation
3914  call schsmooth(depth, sat, derv)
3915  !
3916  ! -- terms for calculating direction of gradient across streambed
3917  tp = this%strtop(n)
3918  bt = tp - this%bthick(n)
3919  hsfr = tp + depth
3920  h_temp = hgwf
3921  if (h_temp < bt) then
3922  h_temp = bt
3923  end if
3924  !
3925  ! -- calculate conductance
3926  call this%sfr_calc_cond(n, depth, cond, hsfr, h_temp)
3927  !
3928  ! -- calculate groundwater leakage
3929  qgwf = sat * cond * (h_temp - hsfr)
3930  gwfrhs0 = -sat * cond * hsfr
3931  gwfhcof0 = -sat * cond
3932  !
3933  ! Add density contributions, if active
3934  if (this%idense /= 0) then
3935  call this%sfr_calculate_density_exchange(n, hsfr, hgwf, cond, tp, &
3936  qgwf, gwfhcof0, gwfrhs0)
3937  end if
3938  !
3939  ! -- Set gwfhcof and gwfrhs if present
3940  if (present(gwfhcof)) gwfhcof = gwfhcof0
3941  if (present(gwfrhs)) gwfrhs = gwfrhs0
Here is the call graph for this function:

◆ sfr_calc_qman()

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

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

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

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

3813  ! -- dummy
3814  class(SfrType) :: this !< SfrType object
3815  integer(I4B), intent(in) :: n !< reach number
3816  real(DP), intent(in) :: depth !< reach depth
3817  real(DP), intent(inout) :: qman !< streamflow
3818  ! -- local
3819  integer(I4B) :: npts
3820  integer(I4B) :: i0
3821  integer(I4B) :: i1
3822  real(DP) :: sat
3823  real(DP) :: derv
3824  real(DP) :: s
3825  real(DP) :: r
3826  real(DP) :: aw
3827  real(DP) :: wp
3828  real(DP) :: rh
3829  !
3830  ! -- initialize variables
3831  qman = dzero
3832  !
3833  ! -- calculate Manning's discharge for non-zero depths
3834  if (depth > dzero) then
3835  npts = this%ncrosspts(n)
3836  !
3837  ! -- set constant terms for Manning's equation
3838  call schsmooth(depth, sat, derv)
3839  s = this%slope(n)
3840  !
3841  ! -- calculate the mannings coefficient that is a
3842  ! function of depth
3843  if (npts > 1) then
3844  !
3845  ! -- get the location of the cross-section data for the reach
3846  i0 = this%iacross(n)
3847  i1 = this%iacross(n + 1) - 1
3848  !
3849  ! -- get the Manning's sum of the Manning's discharge
3850  ! for each section
3851  qman = get_mannings_section(npts, &
3852  this%station(i0:i1), &
3853  this%xsheight(i0:i1), &
3854  this%xsrough(i0:i1), &
3855  this%rough(n), &
3856  this%unitconv, &
3857  s, &
3858  depth)
3859  else
3860  r = this%rough(n)
3861  aw = this%calc_area_wet(n, depth)
3862  wp = this%calc_perimeter_wet(n, depth)
3863  if (wp > dzero) then
3864  rh = aw / wp
3865  else
3866  rh = dzero
3867  end if
3868  qman = this%unitconv * aw * (rh**dtwothirds) * sqrt(s) / r
3869  end if
3870  !
3871  ! -- calculate stream flow
3872  qman = sat * qman
3873  end if
Here is the call graph for this function:

◆ sfr_calc_qsource()

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

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

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

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

3765  ! -- dummy
3766  class(SfrType) :: this !< SfrType object
3767  integer(I4B), intent(in) :: n !< reach number
3768  real(DP), intent(in) :: depth !< reach depth
3769  real(DP), intent(inout) :: qsrc !< sum of sources for reach
3770  ! -- local
3771  real(DP) :: qu
3772  real(DP) :: qi
3773  real(DP) :: qr
3774  real(DP) :: qe
3775  real(DP) :: qro
3776  real(DP) :: qfrommvr
3777  real(DP) :: a
3778  real(DP) :: ae
3779  !
3780  ! -- initialize residual
3781  qsrc = dzero
3782  !
3783  ! -- calculate flow terms
3784  qu = this%usflow(n)
3785  qi = this%inflow(n)
3786  qro = this%runoff(n)
3787  !
3788  ! -- calculate rainfall and evap
3789  a = this%calc_surface_area(n)
3790  ae = this%calc_surface_area_wet(n, depth)
3791  qr = this%rain(n) * a
3792  qe = this%evap(n) * ae
3793  !
3794  ! -- calculate mover term
3795  qfrommvr = dzero
3796  if (this%imover == 1) then
3797  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3798  end if
3799  !
3800  ! -- calculate down stream flow
3801  qsrc = qu + qi + qr - qe + qro + qfrommvr
3802  !
3803  ! -- adjust runoff or evaporation if sum of sources is negative
3804  call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)

◆ sfr_calc_reach_depth()

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

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

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

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

4071  ! -- dummy
4072  class(SfrType) :: this !< SfrType object
4073  integer(I4B), intent(in) :: n !< reach number
4074  real(DP), intent(in) :: q1 !< streamflow
4075  real(DP), intent(inout) :: d1 !< stream depth at midpoint of reach
4076  ! -- local
4077  real(DP) :: w
4078  real(DP) :: s
4079  real(DP) :: r
4080  real(DP) :: qconst
4081  !
4082  ! -- initialize slope and roughness
4083  s = this%slope(n)
4084  r = this%rough(n)
4085  !
4086  ! -- calculate stream depth at the midpoint
4087  if (q1 > dzero) then
4088  if (this%ncrosspts(n) > 1) then
4089  call this%sfr_calc_xs_depth(n, q1, d1)
4090  else
4091  w = this%station(this%iacross(n))
4092  qconst = this%unitconv * w * sqrt(s) / r
4093  d1 = (q1 / qconst)**dp6
4094  end if
4095  else
4096  d1 = dzero
4097  end if

◆ sfr_calc_xs_depth()

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

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

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

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

4106  ! -- dummy
4107  class(SfrType) :: this !< SfrType object
4108  integer(I4B), intent(in) :: n !< reach number
4109  real(DP), intent(in) :: qrch !< streamflow
4110  real(DP), intent(inout) :: d !< stream depth at midpoint of reach
4111  ! -- local
4112  integer(I4B) :: iter
4113  real(DP) :: perturbation
4114  real(DP) :: q0
4115  real(DP) :: q1
4116  real(DP) :: dq
4117  real(DP) :: derv
4118  real(DP) :: dd
4119  real(DP) :: residual
4120  !
4121  ! -- initialize variables
4122  perturbation = this%deps * dtwo
4123  d = dzero
4124  q0 = dzero
4125  residual = q0 - qrch
4126  !
4127  ! -- Newton-Raphson iteration
4128  nriter: do iter = 1, this%maxsfrit
4129  call this%sfr_calc_qman(n, d + perturbation, q1)
4130  dq = (q1 - q0)
4131  if (dq /= dzero) then
4132  derv = perturbation / (q1 - q0)
4133  else
4134  derv = dzero
4135  end if
4136  dd = derv * residual
4137  d = d - dd
4138  call this%sfr_calc_qman(n, d, q0)
4139  residual = q0 - qrch
4140  !
4141  ! -- check for convergence
4142  if (abs(dd) < this%dmaxchg) then
4143  exit nriter
4144  end if
4145  end do nriter

◆ sfr_calculate_density_exchange()

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

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

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

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

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

5753  ! -- dummy
5754  class(SfrType), intent(inout) :: this !< SfrType object
5755  integer(I4B), intent(in) :: n !< reach number
5756  real(DP), intent(in) :: stage !< reach stage
5757  real(DP), intent(in) :: head !< head in connected GWF cell
5758  real(DP), intent(in) :: cond !< reach conductance
5759  real(DP), intent(in) :: tops !< top elevation of streambed
5760  real(DP), intent(inout) :: flow !< calculated flow, updated here with density terms
5761  real(DP), intent(inout) :: gwfhcof !< GWF diagonal coefficient, updated here with density terms
5762  real(DP), intent(inout) :: gwfrhs !< GWF right-hand-side value, updated here with density terms
5763  ! -- local
5764  real(DP) :: ss
5765  real(DP) :: hh
5766  real(DP) :: havg
5767  real(DP) :: rdensesfr
5768  real(DP) :: rdensegwf
5769  real(DP) :: rdenseavg
5770  real(DP) :: elevsfr
5771  real(DP) :: elevgwf
5772  real(DP) :: elevavg
5773  real(DP) :: d1
5774  real(DP) :: d2
5775  logical(LGP) :: stage_below_bot
5776  logical(LGP) :: head_below_bot
5777  !
5778  ! -- Set sfr density to sfr density or gwf density
5779  if (stage >= tops) then
5780  ss = stage
5781  stage_below_bot = .false.
5782  rdensesfr = this%denseterms(1, n) ! sfr rel density
5783  else
5784  ss = tops
5785  stage_below_bot = .true.
5786  rdensesfr = this%denseterms(2, n) ! gwf rel density
5787  end if
5788  !
5789  ! -- set hh to head or tops (top elev of streambed)
5790  if (head >= tops) then
5791  hh = head
5792  head_below_bot = .false.
5793  rdensegwf = this%denseterms(2, n) ! gwf rel density
5794  else
5795  hh = tops
5796  head_below_bot = .true.
5797  rdensegwf = this%denseterms(1, n) ! sfr rel density
5798  end if
5799  !
5800  ! -- todo: hack because denseterms not updated in a cf calculation
5801  if (rdensegwf == dzero) return
5802  !
5803  ! -- Update flow
5804  if (stage_below_bot .and. head_below_bot) then
5805  !
5806  ! -- flow is zero, so no terms are updated
5807  !
5808  else
5809  !
5810  ! -- calculate average relative density
5811  rdenseavg = dhalf * (rdensesfr + rdensegwf)
5812  !
5813  ! -- Add contribution of first density term:
5814  ! cond * (denseavg/denseref - 1) * (hgwf - hsfr)
5815  d1 = cond * (rdenseavg - done)
5816  gwfhcof = gwfhcof - d1
5817  gwfrhs = gwfrhs - d1 * ss
5818  d1 = d1 * (hh - ss)
5819  flow = flow + d1
5820  !
5821  ! -- Add second density term if stage and head not below bottom
5822  if (.not. stage_below_bot .and. .not. head_below_bot) then
5823  !
5824  ! -- Add contribution of second density term:
5825  ! cond * (havg - elevavg) * (densegwf - densesfr) / denseref
5826  elevgwf = this%denseterms(3, n)
5827  elevsfr = tops
5828  elevavg = dhalf * (elevsfr + elevgwf)
5829  havg = dhalf * (hh + ss)
5830  d2 = cond * (havg - elevavg) * (rdensegwf - rdensesfr)
5831  gwfrhs = gwfrhs + d2
5832  flow = flow + d2
5833  end if
5834  end if

◆ sfr_cc()

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

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

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

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

2310  ! -- modules
2311  use tdismodule, only: totim, kstp, kper, delt
2312  ! -- dummy
2313  class(SfrType), intent(inout) :: this !< SfrType object
2314  integer(I4B), intent(in) :: innertot !< total number of inner iterations
2315  integer(I4B), intent(in) :: kiter !< Picard iteration number
2316  integer(I4B), intent(in) :: iend !< flag indicating if this is the last Picard iteration
2317  integer(I4B), intent(in) :: icnvgmod !< flag inficating if the model has met specific convergence criteria
2318  character(len=LENPAKLOC), intent(inout) :: cpak !< string for user node
2319  integer(I4B), intent(inout) :: ipak !< location of the maximum dependent variable change
2320  real(DP), intent(inout) :: dpak !< maximum dependent variable change
2321  ! -- local
2322  character(len=LENPAKLOC) :: cloc
2323  character(len=LINELENGTH) :: tag
2324  integer(I4B) :: icheck
2325  integer(I4B) :: ipakfail
2326  integer(I4B) :: locdhmax
2327  integer(I4B) :: locrmax
2328  integer(I4B) :: locdqfrommvrmax
2329  integer(I4B) :: ntabrows
2330  integer(I4B) :: ntabcols
2331  integer(I4B) :: n
2332  real(DP) :: q
2333  real(DP) :: q0
2334  real(DP) :: qtolfact
2335  real(DP) :: dh
2336  real(DP) :: r
2337  real(DP) :: dhmax
2338  real(DP) :: rmax
2339  real(DP) :: dqfrommvr
2340  real(DP) :: dqfrommvrmax
2341  !
2342  ! -- initialize local variables
2343  icheck = this%iconvchk
2344  ipakfail = 0
2345  locdhmax = 0
2346  locrmax = 0
2347  r = dzero
2348  dhmax = dzero
2349  rmax = dzero
2350  locdqfrommvrmax = 0
2351  dqfrommvrmax = dzero
2352  !
2353  ! -- if not saving package convergence data on check convergence if
2354  ! the model is considered converged
2355  if (this%ipakcsv == 0) then
2356  if (icnvgmod == 0) then
2357  icheck = 0
2358  end if
2359  !
2360  ! -- saving package convergence data
2361  else
2362  !
2363  ! -- header for package csv
2364  if (.not. associated(this%pakcsvtab)) then
2365  !
2366  ! -- determine the number of columns and rows
2367  ntabrows = 1
2368  ntabcols = 9
2369  if (this%imover == 1) then
2370  ntabcols = ntabcols + 2
2371  end if
2372  !
2373  ! -- setup table
2374  call table_cr(this%pakcsvtab, this%packName, '')
2375  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
2376  lineseparator=.false., separator=',', &
2377  finalize=.false.)
2378  !
2379  ! -- add columns to package csv
2380  tag = 'total_inner_iterations'
2381  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2382  tag = 'totim'
2383  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2384  tag = 'kper'
2385  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2386  tag = 'kstp'
2387  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2388  tag = 'nouter'
2389  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2390  tag = 'dvmax'
2391  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2392  tag = 'dvmax_loc'
2393  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2394  tag = 'dinflowmax'
2395  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2396  tag = 'dinflowmax_loc'
2397  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2398  if (this%imover == 1) then
2399  tag = 'dqfrommvrmax'
2400  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2401  tag = 'dqfrommvrmax_loc'
2402  call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
2403  end if
2404  end if
2405  end if
2406  !
2407  ! -- perform package convergence check
2408  if (icheck /= 0) then
2409  final_check: do n = 1, this%maxbound
2410  if (this%iboundpak(n) == 0) cycle
2411  !
2412  ! -- set the Q to length factor
2413  qtolfact = delt / this%calc_surface_area(n)
2414  !
2415  ! -- calculate stage change
2416  dh = this%stage0(n) - this%stage(n)
2417  !
2418  ! -- evaluate flow difference if the time step is transient
2419  if (this%gwfiss == 0) then
2420  r = this%usflow0(n) - this%usflow(n)
2421  !
2422  ! -- normalize flow difference and convert to a depth
2423  r = r * qtolfact
2424  end if
2425  !
2426  ! -- q from mvr
2427  dqfrommvr = dzero
2428  if (this%imover == 1) then
2429  q = this%pakmvrobj%get_qfrommvr(n)
2430  q0 = this%pakmvrobj%get_qfrommvr0(n)
2431  dqfrommvr = qtolfact * (q0 - q)
2432  end if
2433  !
2434  ! -- evaluate magnitude of differences
2435  if (n == 1) then
2436  locdhmax = n
2437  dhmax = dh
2438  locrmax = n
2439  rmax = r
2440  dqfrommvrmax = dqfrommvr
2441  locdqfrommvrmax = n
2442  else
2443  if (abs(dh) > abs(dhmax)) then
2444  locdhmax = n
2445  dhmax = dh
2446  end if
2447  if (abs(r) > abs(rmax)) then
2448  locrmax = n
2449  rmax = r
2450  end if
2451  if (abs(dqfrommvr) > abs(dqfrommvrmax)) then
2452  dqfrommvrmax = dqfrommvr
2453  locdqfrommvrmax = n
2454  end if
2455  end if
2456  end do final_check
2457  !
2458  ! -- set dpak and cpak
2459  if (abs(dhmax) > abs(dpak)) then
2460  ipak = locdhmax
2461  dpak = dhmax
2462  write (cloc, "(a,'-',a)") trim(this%packName), 'stage'
2463  cpak = trim(cloc)
2464  end if
2465  if (abs(rmax) > abs(dpak)) then
2466  ipak = locrmax
2467  dpak = rmax
2468  write (cloc, "(a,'-',a)") trim(this%packName), 'inflow'
2469  cpak = trim(cloc)
2470  end if
2471  if (this%imover == 1) then
2472  if (abs(dqfrommvrmax) > abs(dpak)) then
2473  ipak = locdqfrommvrmax
2474  dpak = dqfrommvrmax
2475  write (cloc, "(a,'-',a)") trim(this%packName), 'qfrommvr'
2476  cpak = trim(cloc)
2477  end if
2478  end if
2479  !
2480  ! -- write convergence data to package csv
2481  if (this%ipakcsv /= 0) then
2482  !
2483  ! -- write the data
2484  call this%pakcsvtab%add_term(innertot)
2485  call this%pakcsvtab%add_term(totim)
2486  call this%pakcsvtab%add_term(kper)
2487  call this%pakcsvtab%add_term(kstp)
2488  call this%pakcsvtab%add_term(kiter)
2489  call this%pakcsvtab%add_term(dhmax)
2490  call this%pakcsvtab%add_term(locdhmax)
2491  call this%pakcsvtab%add_term(rmax)
2492  call this%pakcsvtab%add_term(locrmax)
2493  if (this%imover == 1) then
2494  call this%pakcsvtab%add_term(dqfrommvrmax)
2495  call this%pakcsvtab%add_term(locdqfrommvrmax)
2496  end if
2497  !
2498  ! -- finalize the package csv
2499  if (iend == 1) then
2500  call this%pakcsvtab%finalize_table()
2501  end if
2502  end if
2503  end if
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:35
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:27
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:26
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:32
Here is the call graph for this function:

◆ sfr_cf()

subroutine sfrmodule::sfr_cf ( class(sfrtype)  this)

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

Parameters
thisSfrType object

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

2132  ! -- dummy
2133  class(SfrType) :: this !< SfrType object
2134  ! -- local
2135  integer(I4B) :: n
2136  integer(I4B) :: igwfnode
2137  !
2138  ! -- return if no sfr reaches
2139  if (this%nbound == 0) return
2140  !
2141  ! -- find highest active cell
2142  do n = 1, this%nbound
2143  igwfnode = this%igwftopnode(n)
2144  if (igwfnode > 0) then
2145  if (this%ibound(igwfnode) == 0) then
2146  call this%dis%highest_active(igwfnode, this%ibound)
2147  end if
2148  end if
2149  this%igwfnode(n) = igwfnode
2150  this%nodelist(n) = igwfnode
2151  end do

◆ sfr_check_connections()

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

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

Parameters
thisSfrType object

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

4333  ! -- dummy
4334  class(SfrType) :: this !< SfrType object
4335  ! -- local
4336  logical(LGP) :: lreorder
4337  character(len=5) :: crch
4338  character(len=5) :: crch2
4339  character(len=LINELENGTH) :: text
4340  character(len=LINELENGTH) :: title
4341  integer(I4B) :: n
4342  integer(I4B) :: nn
4343  integer(I4B) :: nc
4344  integer(I4B) :: i
4345  integer(I4B) :: ii
4346  integer(I4B) :: j
4347  integer(I4B) :: ifound
4348  integer(I4B) :: ierr
4349  integer(I4B) :: maxconn
4350  integer(I4B) :: ntabcol
4351  !
4352  ! -- determine if the reaches have been reordered
4353  lreorder = .false.
4354  do j = 1, this%MAXBOUND
4355  n = this%isfrorder(j)
4356  if (n /= j) then
4357  lreorder = .true.
4358  exit
4359  end if
4360  end do
4361  !
4362  ! -- write message that the solution order h
4363  if (lreorder) then
4364  write (this%iout, '(/,1x,a)') &
4365  trim(adjustl(this%text))//' PACKAGE ('// &
4366  trim(adjustl(this%packName))//') REACH SOLUTION HAS BEEN '// &
4367  'REORDERED USING A DAG'
4368  !
4369  ! -- print table
4370  if (this%iprpak /= 0) then
4371  !
4372  ! -- reset the input table object
4373  ntabcol = 2
4374  title = trim(adjustl(this%text))//' PACKAGE ('// &
4375  trim(adjustl(this%packName))//') REACH SOLUTION ORDER'
4376  call table_cr(this%inputtab, this%packName, title)
4377  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4378  text = 'ORDER'
4379  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4380  text = 'REACH'
4381  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4382  !
4383  ! -- upstream connection data
4384  do j = 1, this%maxbound
4385  n = this%isfrorder(j)
4386  call this%inputtab%add_term(j)
4387  call this%inputtab%add_term(n)
4388  end do
4389  end if
4390  end if
4391  !
4392  ! -- create input table for reach connections data
4393  if (this%iprpak /= 0) then
4394  !
4395  ! -- calculate the maximum number of connections
4396  maxconn = 0
4397  do n = 1, this%maxbound
4398  maxconn = max(maxconn, this%nconnreach(n))
4399  end do
4400  ntabcol = 1 + maxconn
4401  !
4402  ! -- reset the input table object
4403  title = trim(adjustl(this%text))//' PACKAGE ('// &
4404  trim(adjustl(this%packName))//') STATIC REACH CONNECTION DATA'
4405  call table_cr(this%inputtab, this%packName, title)
4406  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4407  text = 'REACH'
4408  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4409  do n = 1, maxconn
4410  write (text, '(a,1x,i6)') 'CONN', n
4411  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4412  end do
4413  end if
4414  !
4415  ! -- verify every listed connection is reciprocated: if reach n lists
4416  ! -- reach nn, reach nn must list reach n back
4417  do n = 1, this%MAXBOUND
4418  write (crch, '(i5)') n
4419  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4420  nn = this%ja(i)
4421  write (crch2, '(i5)') nn
4422  ifound = 0
4423  connreach: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4424  nc = this%ja(ii)
4425  if (nc == n) then
4426  ifound = 1
4427  exit connreach
4428  end if
4429  end do connreach
4430  if (ifound /= 1) then
4431  errmsg = 'Reach '//crch//' is connected to '// &
4432  'reach '//crch2//' but reach '//crch2// &
4433  ' is not connected to reach '//crch//'.'
4434  call store_error(errmsg)
4435  end if
4436  end do eachconn
4437  !
4438  ! -- write connection data to the table
4439  if (this%iprpak /= 0) then
4440  call this%inputtab%add_term(n)
4441  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4442  call this%inputtab%add_term(this%ja(i))
4443  end do
4444  nn = maxconn - this%nconnreach(n)
4445  do i = 1, nn
4446  call this%inputtab%add_term(' ')
4447  end do
4448  end if
4449  end do
4450  !
4451  ! -- verify upstream connections don't form a mutual pair: two reaches
4452  ! -- cannot each list the other as upstream
4453  ierr = 0
4454  do n = 1, this%maxbound
4455  write (crch, '(i5)') n
4456  eachconnv: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4457  !
4458  ! -- skip downstream connections
4459  if (this%idir(i) < 0) cycle eachconnv
4460  nn = this%ja(i)
4461  write (crch2, '(i5)') nn
4462  connreachv: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4463  ! -- skip downstream connections
4464  if (this%idir(ii) < 0) cycle connreachv
4465  nc = this%ja(ii)
4466  !
4467  ! -- if nc == n then that means reach n is an upstream connection for
4468  ! reach nn and reach nn is an upstream connection for reach n
4469  if (nc == n) then
4470  ierr = ierr + 1
4471  errmsg = 'Reach '//crch//' is connected to '// &
4472  'reach '//crch2//' but streamflow from reach '// &
4473  crch//' to reach '//crch2//' is not permitted.'
4474  call store_error(errmsg)
4475  exit connreachv
4476  end if
4477  end do connreachv
4478  end do eachconnv
4479  end do
4480  !
4481  ! -- terminate if connectivity errors
4482  if (count_errors() > 0) then
4483  call store_error_filename(this%input_fname)
4484  end if
4485  !
4486  ! -- check that downstream reaches for a reach are
4487  ! the upstream reaches for the reach
4488  do n = 1, this%maxbound
4489  write (crch, '(i5)') n
4490  eachconnds: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4491  nn = this%ja(i)
4492  if (this%idir(i) > 0) cycle eachconnds
4493  write (crch2, '(i5)') nn
4494  ifound = 0
4495  connreachds: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4496  nc = this%ja(ii)
4497  if (nc == n) then
4498  if (this%idir(i) /= this%idir(ii)) then
4499  ifound = 1
4500  end if
4501  exit connreachds
4502  end if
4503  end do connreachds
4504  if (ifound /= 1) then
4505  errmsg = 'Reach '//crch//' downstream connected reach '// &
4506  'is reach '//crch2//' but reach '//crch//' is not'// &
4507  ' the upstream connected reach for reach '//crch2//'.'
4508  call store_error(errmsg)
4509  end if
4510  end do eachconnds
4511  end do
4512  !
4513  ! -- create input table for upstream and downstream connections
4514  if (this%iprpak /= 0) then
4515  !
4516  ! -- calculate the maximum number of upstream connections
4517  maxconn = 0
4518  do n = 1, this%maxbound
4519  ii = 0
4520  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4521  if (this%idir(i) > 0) then
4522  ii = ii + 1
4523  end if
4524  end do
4525  maxconn = max(maxconn, ii)
4526  end do
4527  ntabcol = 1 + maxconn
4528  !
4529  ! -- reset the input table object
4530  title = trim(adjustl(this%text))//' PACKAGE ('// &
4531  trim(adjustl(this%packName))//') STATIC UPSTREAM REACH '// &
4532  'CONNECTION DATA'
4533  call table_cr(this%inputtab, this%packName, title)
4534  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4535  text = 'REACH'
4536  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4537  do n = 1, maxconn
4538  write (text, '(a,1x,i6)') 'UPSTREAM CONN', n
4539  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4540  end do
4541  !
4542  ! -- upstream connection data
4543  do n = 1, this%maxbound
4544  call this%inputtab%add_term(n)
4545  ii = 0
4546  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4547  if (this%idir(i) > 0) then
4548  call this%inputtab%add_term(this%ja(i))
4549  ii = ii + 1
4550  end if
4551  end do
4552  nn = maxconn - ii
4553  do i = 1, nn
4554  call this%inputtab%add_term(' ')
4555  end do
4556  end do
4557  !
4558  ! -- calculate the maximum number of downstream connections
4559  maxconn = 0
4560  do n = 1, this%maxbound
4561  ii = 0
4562  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4563  if (this%idir(i) < 0) then
4564  ii = ii + 1
4565  end if
4566  end do
4567  maxconn = max(maxconn, ii)
4568  end do
4569  ntabcol = 1 + maxconn
4570  !
4571  ! -- reset the input table object
4572  title = trim(adjustl(this%text))//' PACKAGE ('// &
4573  trim(adjustl(this%packName))//') STATIC DOWNSTREAM '// &
4574  'REACH CONNECTION DATA'
4575  call table_cr(this%inputtab, this%packName, title)
4576  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4577  text = 'REACH'
4578  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4579  do n = 1, maxconn
4580  write (text, '(a,1x,i6)') 'DOWNSTREAM CONN', n
4581  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4582  end do
4583  !
4584  ! -- downstream connection data
4585  do n = 1, this%maxbound
4586  call this%inputtab%add_term(n)
4587  ii = 0
4588  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4589  if (this%idir(i) < 0) then
4590  call this%inputtab%add_term(this%ja(i))
4591  ii = ii + 1
4592  end if
4593  end do
4594  nn = maxconn - ii
4595  do i = 1, nn
4596  call this%inputtab%add_term(' ')
4597  end do
4598  end do
4599  end if
Here is the call graph for this function:

◆ sfr_check_conversion()

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

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

Parameters
thisSfrType object

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

4154  ! -- dummy
4155  class(SfrType) :: this !< SfrType object
4156  ! -- local
4157  ! -- formats
4158  character(len=*), parameter :: fmtunitconv_error = &
4159  &"('SFR (',a,') UNIT_CONVERSION SPECIFIED VALUE (',g0,') AND', &
4160  &1x,'LENGTH_CONVERSION OR TIME_CONVERSION SPECIFIED.')"
4161  character(len=*), parameter :: fmtunitconv = &
4162  &"(1x,'SFR PACKAGE (',a,') CONVERSION DATA',&
4163  &/4x,'UNIT CONVERSION VALUE (',g0,').',/)"
4164  !
4165  ! -- check the reach data for simple errors
4166  if (this%lengthconv /= dnodata .or. this%timeconv /= dnodata) then
4167  if (this%unitconv /= done) then
4168  write (errmsg, fmtunitconv_error) &
4169  trim(adjustl(this%packName)), this%unitconv
4170  call store_error(errmsg)
4171  else
4172  if (this%lengthconv /= dnodata) then
4173  this%unitconv = this%unitconv * this%lengthconv**donethird
4174  end if
4175  if (this%timeconv /= dnodata) then
4176  this%unitconv = this%unitconv * this%timeconv
4177  end if
4178  write (this%iout, fmtunitconv) &
4179  trim(adjustl(this%packName)), this%unitconv
4180  end if
4181  end if
Here is the call graph for this function:

◆ sfr_check_diversions()

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

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

Parameters
thisSfrType object

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

4609  ! -- dummy
4610  class(SfrType) :: this !< SfrType object
4611  ! -- local
4612  character(len=LINELENGTH) :: title
4613  character(len=LINELENGTH) :: text
4614  character(len=5) :: crch
4615  character(len=5) :: cdiv
4616  character(len=5) :: crch2
4617  character(len=10) :: cprior
4618  integer(I4B) :: maxdiv
4619  integer(I4B) :: n
4620  integer(I4B) :: nn
4621  integer(I4B) :: nc
4622  integer(I4B) :: ii
4623  integer(I4B) :: idiv
4624  integer(I4B) :: ifound
4625  integer(I4B) :: jpos
4626  ! -- format
4627 10 format('Diversion ', i0, ' of reach ', i0, &
4628  ' is invalid or has not been defined.')
4629  !
4630  ! -- write header
4631  if (this%iprpak /= 0) then
4632  !
4633  ! -- determine the maximum number of diversions
4634  maxdiv = 0
4635  do n = 1, this%maxbound
4636  maxdiv = maxdiv + this%ndiv(n)
4637  end do
4638  !
4639  ! -- reset the input table object
4640  title = trim(adjustl(this%text))//' PACKAGE ('// &
4641  trim(adjustl(this%packName))//') REACH DIVERSION DATA'
4642  call table_cr(this%inputtab, this%packName, title)
4643  call this%inputtab%table_df(maxdiv, 4, this%iout)
4644  text = 'REACH'
4645  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4646  text = 'DIVERSION'
4647  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4648  text = 'REACH 2'
4649  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4650  text = 'CPRIOR'
4651  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4652  end if
4653  !
4654  ! -- check that diversion data are correct
4655  do n = 1, this%maxbound
4656  if (this%ndiv(n) < 1) cycle
4657  write (crch, '(i5)') n
4658 
4659  do idiv = 1, this%ndiv(n)
4660  !
4661  ! -- determine diversion index
4662  jpos = this%iadiv(n) + idiv - 1
4663  !
4664  ! -- write idiv to cdiv
4665  write (cdiv, '(i5)') idiv
4666  !
4667  !
4668  nn = this%divreach(jpos)
4669  write (crch2, '(i5)') nn
4670  !
4671  ! -- make sure diversion reach is connected to current reach
4672  ifound = 0
4673  if (nn < 1 .or. nn > this%maxbound) then
4674  write (errmsg, 10) idiv, n
4675  call store_error(errmsg)
4676  cycle
4677  end if
4678  connreach: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4679  nc = this%ja(ii)
4680  if (nc == n) then
4681  if (this%idir(ii) > 0) then
4682  ifound = 1
4683  end if
4684  exit connreach
4685  end if
4686  end do connreach
4687  if (ifound /= 1) then
4688  errmsg = 'Reach '//crch//' is not a upstream reach for '// &
4689  'reach '//crch2//' as a result diversion '//cdiv// &
4690  ' from reach '//crch//' to reach '//crch2// &
4691  ' is not possible. Check reach connectivity.'
4692  call store_error(errmsg)
4693  end if
4694  ! -- iprior
4695  cprior = this%divcprior(jpos)
4696  !
4697  ! -- add terms to the table
4698  if (this%iprpak /= 0) then
4699  call this%inputtab%add_term(n)
4700  call this%inputtab%add_term(idiv)
4701  call this%inputtab%add_term(nn)
4702  call this%inputtab%add_term(cprior)
4703  end if
4704  end do
4705  end do
Here is the call graph for this function:

◆ sfr_check_initialstages()

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

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

Parameters
thisSfrType object

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

4716  class(SfrType) :: this !< SfrType object
4717 
4718  character(len=LINELENGTH) :: title
4719  character(len=LINELENGTH) :: text
4720  character(len=5) :: crch
4721  integer(I4B) :: n
4722  real(DP) :: qman
4723 
4724  ! skip check if storage is not activated
4725  if (this%istorage == 0) return
4726 
4727  ! write header
4728  if (this%iprpak /= 0) then
4729  !
4730  ! -- reset the input table object
4731  title = trim(adjustl(this%text))//' PACKAGE ('// &
4732  trim(adjustl(this%packName))//') REACH INITIAL STAGE DATA'
4733  call table_cr(this%inputtab, this%packName, title)
4734  call this%inputtab%table_df(this%maxbound, 4, this%iout)
4735  text = 'REACH'
4736  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4737  text = 'INITIAL STAGE'
4738  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4739  text = 'INITIAL DEPTH'
4740  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4741  text = 'INITIAL FLOW'
4742  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4743  end if
4744  !
4745  ! -- check that data are correct
4746  do n = 1, this%maxbound
4747  write (crch, '(i5)') n
4748 
4749  ! calculate the initial flows
4750  call this%sfr_calc_qman(n, this%depth(n), qman)
4751  this%usinflow(n) = qman
4752  this%dsflow(n) = qman
4753 
4754  ! add terms to the table
4755  if (this%iprpak /= 0) then
4756  call this%inputtab%add_term(n)
4757  call this%inputtab%add_term(this%stage(n))
4758  call this%inputtab%add_term(this%depth(n))
4759  call this%inputtab%add_term(qman)
4760  end if
4761  end do
Here is the call graph for this function:

◆ sfr_check_reaches()

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

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

Parameters
thisSfrType object

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

4215  ! -- dummy
4216  class(SfrType) :: this !< SfrType object
4217  ! -- local
4218  character(len=5) :: crch
4219  character(len=10) :: cval
4220  character(len=30) :: nodestr
4221  character(len=LINELENGTH) :: title
4222  character(len=LINELENGTH) :: text
4223  integer(I4B) :: n
4224  integer(I4B) :: nn
4225  real(DP) :: btgwf
4226  real(DP) :: bt
4227  !
4228  ! -- setup inputtab tableobj
4229  if (this%iprpak /= 0) then
4230  title = trim(adjustl(this%text))//' PACKAGE ('// &
4231  trim(adjustl(this%packName))//') STATIC REACH DATA'
4232  call table_cr(this%inputtab, this%packName, title)
4233  call this%inputtab%table_df(this%maxbound, 10, this%iout)
4234  text = 'NUMBER'
4235  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4236  text = 'CELLID'
4237  call this%inputtab%initialize_column(text, 20, alignment=tableft)
4238  text = 'LENGTH'
4239  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4240  text = 'WIDTH'
4241  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4242  text = 'SLOPE'
4243  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4244  text = 'TOP'
4245  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4246  text = 'THICKNESS'
4247  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4248  text = 'HK'
4249  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4250  text = 'ROUGHNESS'
4251  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4252  text = 'UPSTREAM FRACTION'
4253  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4254  end if
4255  !
4256  ! -- check the reach data for simple errors
4257  do n = 1, this%maxbound
4258  write (crch, '(i5)') n
4259  nn = this%igwfnode(n)
4260  if (nn > 0) then
4261  btgwf = this%dis%bot(nn)
4262  call this%dis%noder_to_string(nn, nodestr)
4263  else
4264  nodestr = 'none'
4265  end if
4266  ! -- check reach length
4267  if (this%length(n) <= dzero) then
4268  errmsg = 'Reach '//crch//' length must be greater than 0.0.'
4269  call store_error(errmsg)
4270  end if
4271  ! -- check reach width
4272  if (this%width(n) <= dzero) then
4273  errmsg = 'Reach '//crch//' width must be greater than 0.0.'
4274  call store_error(errmsg)
4275  end if
4276  ! -- check reach slope
4277  if (this%slope(n) <= dzero) then
4278  errmsg = 'Reach '//crch//' slope must be greater than 0.0.'
4279  call store_error(errmsg)
4280  end if
4281  ! -- check bed thickness and bed hk for reaches connected to GWF
4282  if (nn > 0) then
4283  bt = this%strtop(n) - this%bthick(n)
4284  if (bt <= btgwf .and. this%icheck /= 0) then
4285  write (cval, '(f10.4)') bt
4286  errmsg = 'Reach '//crch//' bed bottom (rtp-rbth ='// &
4287  cval//') must be greater than the bottom of cell ('// &
4288  nodestr
4289  write (cval, '(f10.4)') btgwf
4290  errmsg = trim(adjustl(errmsg))//'='//cval//').'
4291  call store_error(errmsg)
4292  end if
4293  if (this%hk(n) < dzero) then
4294  errmsg = 'Reach '//crch//' hk must be greater than or equal to 0.0.'
4295  call store_error(errmsg)
4296  end if
4297  end if
4298  ! -- check reach roughness
4299  if (this%rough(n) <= dzero) then
4300  errmsg = 'Reach '//crch//" Manning's roughness "// &
4301  'coefficient must be greater than 0.0.'
4302  call store_error(errmsg)
4303  end if
4304  ! -- check reach upstream fraction
4305  if (this%ustrf(n) < dzero) then
4306  errmsg = 'Reach '//crch//' upstream fraction must be greater '// &
4307  'than or equal to 0.0.'
4308  call store_error(errmsg)
4309  end if
4310  ! -- write summary of reach information
4311  if (this%iprpak /= 0) then
4312  call this%inputtab%add_term(n)
4313  call this%inputtab%add_term(nodestr)
4314  call this%inputtab%add_term(this%length(n))
4315  call this%inputtab%add_term(this%width(n))
4316  call this%inputtab%add_term(this%slope(n))
4317  call this%inputtab%add_term(this%strtop(n))
4318  call this%inputtab%add_term(this%bthick(n))
4319  call this%inputtab%add_term(this%hk(n))
4320  call this%inputtab%add_term(this%rough(n))
4321  call this%inputtab%add_term(this%ustrf(n))
4322  end if
4323  end do
Here is the call graph for this function:

◆ sfr_check_storage_weight()

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

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

Parameters
thisSfrType object

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

4191  ! -- dummy
4192  class(SfrType) :: this !< SfrType object
4193  ! -- formats
4194  character(len=*), parameter :: fmtweight = &
4195  &"(1x,'SFR PACKAGE (',a,') SETTING DEFAULT',&
4196  &/4x,'STORAGE_WEIGHT VALUE (',g0,').',/)"
4197  !
4198  ! -- set storage weight if it has not been defined yet
4199  if (this%istorage == 1) then
4200  if (this%storage_weight == dnodata) then
4201  this%storage_weight = done
4202  write (this%iout, fmtweight) &
4203  trim(adjustl(this%packName)), this%storage_weight
4204  end if
4205  end if

◆ sfr_check_ustrf()

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

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

Parameters
thisSfrType object

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

4771  ! -- dummy
4772  class(SfrType) :: this !< SfrType object
4773  ! -- local
4774  character(len=LINELENGTH) :: title
4775  character(len=LINELENGTH) :: text
4776  logical(LGP) :: lcycle
4777  logical(LGP) :: ladd
4778  character(len=5) :: crch
4779  character(len=5) :: crch2
4780  character(len=10) :: cval
4781  integer(I4B) :: maxcols
4782  integer(I4B) :: npairs
4783  integer(I4B) :: ipair
4784  integer(I4B) :: i
4785  integer(I4B) :: n
4786  integer(I4B) :: n2
4787  integer(I4B) :: idiv
4788  integer(I4B) :: i0
4789  integer(I4B) :: i1
4790  integer(I4B) :: jpos
4791  integer(I4B) :: ids
4792  real(DP) :: f
4793  real(DP) :: rval
4794  !
4795  ! -- write table header
4796  if (this%iprpak /= 0) then
4797  !
4798  ! -- determine the maximum number of columns
4799  npairs = 0
4800  do n = 1, this%maxbound
4801  ipair = 0
4802  ec: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4803  !
4804  ! -- skip upstream connections
4805  if (this%idir(i) > 0) cycle ec
4806  n2 = this%ja(i)
4807  !
4808  ! -- skip inactive downstream reaches
4809  if (this%iboundpak(n2) == 0) cycle ec
4810  !
4811  ! -- increment ipair and see if it exceeds npairs
4812  ipair = ipair + 1
4813  npairs = max(npairs, ipair)
4814  end do ec
4815  end do
4816  maxcols = 1 + npairs * 2
4817  !
4818  ! -- reset the input table object
4819  title = trim(adjustl(this%text))//' PACKAGE ('// &
4820  trim(adjustl(this%packName))//') CONNECTED REACH UPSTREAM '// &
4821  'FRACTION DATA'
4822  call table_cr(this%inputtab, this%packName, title)
4823  call this%inputtab%table_df(this%maxbound, maxcols, this%iout)
4824  text = 'REACH'
4825  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4826  do i = 1, npairs
4827  write (cval, '(i10)') i
4828  text = 'DOWNSTREAM REACH '//trim(adjustl(cval))
4829  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4830  text = 'FRACTION '//trim(adjustl(cval))
4831  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4832  end do
4833  end if
4834  !
4835  ! -- fill diversion number for each connection
4836  do n = 1, this%maxbound
4837  do idiv = 1, this%ndiv(n)
4838  i0 = this%iadiv(n)
4839  i1 = this%iadiv(n + 1) - 1
4840  do jpos = i0, i1
4841  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4842  n2 = this%ja(i)
4843  if (this%divreach(jpos) == n2) then
4844  this%idiv(i) = jpos - i0 + 1
4845  exit
4846  end if
4847  end do
4848  end do
4849  end do
4850  end do
4851  !
4852  ! -- check that the upstream fraction for reach connected by
4853  ! a diversion is zero
4854  do n = 1, this%maxbound
4855  !
4856  ! -- determine the number of downstream reaches
4857  ids = 0
4858  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4859  if (this%idir(i) < 0) then
4860  ids = ids + 1
4861  end if
4862  end do
4863  !
4864  ! -- evaluate the diversions
4865  do idiv = 1, this%ndiv(n)
4866  jpos = this%iadiv(n) + idiv - 1
4867  n2 = this%divreach(jpos)
4868  f = this%ustrf(n2)
4869  if (f /= dzero) then
4870  write (errmsg, '(a,2(1x,i0,1x,a),1x,a,g0,a,2(1x,a))') &
4871  'Reach', n, 'is connected to reach', n2, 'by a diversion', &
4872  'but the upstream fraction is not equal to zero (', f, '). Check', &
4873  trim(this%packName), 'package diversion and package data.'
4874  if (ids > 1) then
4875  call store_error(errmsg)
4876  else
4877  write (warnmsg, '(a,3(1x,a))') &
4878  trim(warnmsg), &
4879  'A warning instead of an error is issued because', &
4880  'the reach is only connected to the diversion reach in the ', &
4881  'downstream direction.'
4882  call store_warning(warnmsg)
4883  end if
4884  end if
4885  end do
4886  end do
4887  !
4888  ! -- calculate the total fraction of connected reaches that are
4889  ! not diversions and check that the sum of upstream fractions
4890  ! is equal to 1 for each reach
4891  do n = 1, this%maxbound
4892  ids = 0
4893  rval = dzero
4894  f = dzero
4895  write (crch, '(i5)') n
4896  if (this%iprpak /= 0) then
4897  call this%inputtab%add_term(n)
4898  end if
4899  ipair = 0
4900  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4901  lcycle = .false.
4902  !
4903  ! -- initialize downstream connection q
4904  this%qconn(i) = dzero
4905  !
4906  ! -- skip upstream connections
4907  if (this%idir(i) > 0) then
4908  lcycle = .true.
4909  end if
4910  n2 = this%ja(i)
4911  !
4912  ! -- skip inactive downstream reaches
4913  if (this%iboundpak(n2) == 0) then
4914  lcycle = .true.
4915  end if
4916  if (lcycle) then
4917  cycle eachconn
4918  end if
4919  ipair = ipair + 1
4920  write (crch2, '(i5)') n2
4921  ids = ids + 1
4922  ladd = .true.
4923  f = f + this%ustrf(n2)
4924  write (cval, '(f10.4)') this%ustrf(n2)
4925  !
4926  ! -- write upstream fractions
4927  if (this%iprpak /= 0) then
4928  call this%inputtab%add_term(n2)
4929  call this%inputtab%add_term(this%ustrf(n2))
4930  end if
4931  eachdiv: do idiv = 1, this%ndiv(n)
4932  jpos = this%iadiv(n) + idiv - 1
4933  if (this%divreach(jpos) == n2) then
4934  ladd = .false.
4935  exit eachdiv
4936  end if
4937  end do eachdiv
4938  if (ladd) then
4939  rval = rval + this%ustrf(n2)
4940  end if
4941  end do eachconn
4942  this%ftotnd(n) = rval
4943  !
4944  ! -- write remaining table columns
4945  if (this%iprpak /= 0) then
4946  ipair = ipair + 1
4947  do i = ipair, npairs
4948  call this%inputtab%add_term(' ')
4949  call this%inputtab%add_term(' ')
4950  end do
4951  end if
4952  !
4953  ! -- evaluate if an error condition has occurred
4954  ! the sum of fractions is not equal to 1
4955  if (ids /= 0) then
4956  if (abs(f - done) > dem6) then
4957  write (errmsg, '(a,1x,i0,1x,a,g0,a,3(1x,a))') &
4958  'Upstream fractions for reach ', n, 'is not equal to one (', f, &
4959  '). Check', trim(this%packName), 'package reach connectivity and', &
4960  'package data.'
4961  call store_error(errmsg)
4962  end if
4963  end if
4964  end do
Here is the call graph for this function:

◆ sfr_checkin_deprecated_names()

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

IDM integration moved several reach variables into the input context, renaming some. These aliases share memory with the relocated variables so that programs addressing them through the API by their old package-path names continue to resolve; each use is reported as deprecated. DIVFLOW is only set from the input context when diversions are present; otherwise an empty DIVFLOW is allocated at the package path, as before IDM integration.

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

709  ! -- modules
712  ! -- dummy
713  class(SfrType), intent(inout) :: this
714  ! -- local
715  real(DP), dimension(:, :), pointer, contiguous :: aux => null()
716  integer(I4B) :: isize
717  ! -- code
718  !
719  ! -- reach auxiliary values, present (possibly empty) in the input context
720  call get_isize('AUX', this%input_mempath, isize)
721  if (isize >= 0) then
722  call mem_setptr(aux, 'AUX', this%input_mempath)
723  call mem_alias_deprecated(aux, 'RAUXVAR', this%memoryPath, &
724  'AUX', this%input_mempath, '6.8.2')
725  end if
726  !
727  ! -- diversion flows
728  if (associated(this%divflow)) then
729  call mem_alias_deprecated(this%divflow, 'DIVFLOW', this%memoryPath, &
730  'DIVFLOW', this%input_mempath, '6.8.2')
731  else
732  call mem_allocate(this%divflow, 0, 'DIVFLOW', this%memoryPath)
733  end if
734  !
735  call mem_alias_deprecated(this%rain, 'RAIN', this%memoryPath, &
736  'RAINFALL', this%input_mempath, '6.8.2')
737  call mem_alias_deprecated(this%evap, 'EVAP', this%memoryPath, &
738  'EVAPORATION', this%input_mempath, '6.8.2')
739  call mem_alias_deprecated(this%inflow, 'INFLOW', this%memoryPath, &
740  'INFLOW', this%input_mempath, '6.8.2')
741  call mem_alias_deprecated(this%runoff, 'RUNOFF', this%memoryPath, &
742  'RUNOFF', this%input_mempath, '6.8.2')
743  call mem_alias_deprecated(this%sstage, 'SSTAGE', this%memoryPath, &
744  'STAGE', this%input_mempath, '6.8.2')
745  call mem_alias_deprecated(this%hk, 'HK', this%memoryPath, &
746  'BEDK', this%input_mempath, '6.8.2')
747  call mem_alias_deprecated(this%rough, 'ROUGH', this%memoryPath, &
748  'MANNING', this%input_mempath, '6.8.2')
749  call mem_alias_deprecated(this%ustrf, 'USTRF', this%memoryPath, &
750  'UPSTREAM_FRAC', this%input_mempath, '6.8.2')
Previous variable names checked in as deprecated aliases.
Definition: MemoryAlias.f90:7
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
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 2510 of file gwf-sfr.f90.

2511  ! -- modules
2512  use budgetmodule, only: budgettype
2513  ! -- dummy
2514  class(SfrType), intent(inout) :: this !< SfrType object
2515  real(DP), dimension(:), intent(in) :: x !< current dependent-variable value
2516  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
2517  integer(I4B), optional, intent(in) :: iadv !< flag that indicates if this is an advance package
2518  ! -- local
2519  integer(I4B) :: i
2520  real(DP) :: qext
2521  ! -- for budget
2522  integer(I4B) :: n
2523  integer(I4B) :: n2
2524  real(DP) :: qoutflow
2525  real(DP) :: qfrommvr
2526  real(DP) :: qtomvr
2527  !
2528  ! -- call base functionality in bnd_cq. This will calculate sfr-gwf flows
2529  ! and put them into this%simvals
2530  call this%BndType%bnd_cq(x, flowja, iadv=1)
2531  !
2532  ! -- Calculate qextoutflow and qoutflow for subsequent budgets
2533  do n = 1, this%maxbound
2534  !
2535  ! -- mover
2536  qfrommvr = dzero
2537  qtomvr = dzero
2538  if (this%imover == 1) then
2539  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
2540  qtomvr = this%pakmvrobj%get_qtomvr(n)
2541  if (qtomvr > dzero) then
2542  qtomvr = -qtomvr
2543  end if
2544  end if
2545  !
2546  ! -- external downstream stream flow
2547  qext = this%dsflow(n)
2548  qoutflow = dzero
2549  if (qext > dzero) then
2550  qext = -qext
2551  end if
2552  do i = this%ia(n) + 1, this%ia(n + 1) - 1
2553  if (this%idir(i) > 0) cycle
2554  n2 = this%ja(i)
2555  if (this%iboundpak(n2) == 0) cycle
2556  qext = dzero
2557  exit
2558  end do
2559  !
2560  ! -- adjust external downstream stream flow using qtomvr
2561  if (qext < dzero) then
2562  if (qtomvr < dzero) then
2563  qext = qext - qtomvr
2564  end if
2565  else
2566  qoutflow = this%dsflow(n)
2567  if (qoutflow > dzero) then
2568  qoutflow = -qoutflow
2569  end if
2570  end if
2571  !
2572  ! -- set qextoutflow and qoutflow for cell by cell budget
2573  ! output and observations
2574  this%qextoutflow(n) = qext
2575  this%qoutflow(n) = qoutflow
2576  !
2577  end do
2578  !
2579  ! -- fill the budget object
2580  call this%sfr_fill_budobj()
This module contains the BudgetModule.
Definition: Budget.f90:20
Derived type for the Budget object.
Definition: Budget.f90:40

◆ 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,
character(len=*), intent(in)  mempath 
)

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
[in]mempathinput mempath

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

369  ! -- modules
371  ! -- dummy
372  class(BndType), pointer :: packobj !< pointer to default package type
373  integer(I4B), intent(in) :: id !< package id
374  integer(I4B), intent(in) :: ibcnum !< boundary condition number
375  integer(I4B), intent(in) :: inunit !< unit number of SFR package input file
376  integer(I4B), intent(in) :: iout !< unit number of model listing file
377  character(len=*), intent(in) :: namemodel !< model name
378  character(len=*), intent(in) :: pakname !< package name
379  character(len=*), intent(in) :: mempath !< input mempath
380  ! -- local
381  type(SfrType), pointer :: sfrobj
382  !
383  ! -- allocate the object and assign values to object variables
384  allocate (sfrobj)
385  packobj => sfrobj
386  !
387  ! -- create name and memory path
388  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
389  packobj%text = text
390  !
391  ! -- allocate scalars
392  call sfrobj%sfr_allocate_scalars()
393  !
394  ! -- initialize package
395  call packobj%pack_initialize()
396 
397  packobj%inunit = inunit
398  packobj%iout = iout
399  packobj%id = id
400  packobj%ibcnum = ibcnum
401  packobj%ncolbnd = 4
402  packobj%iscloc = 0 ! not supported
403  packobj%isadvpak = 1
404  packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sfr_da()

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

Deallocate SFR package scalars and arrays.

Parameters
thisSfrType object

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

2868  ! -- modules
2870  ! -- dummy
2871  class(SfrType) :: this !< SfrType object
2872  !
2873  ! -- deallocate arrays
2874  call mem_deallocate(this%qoutflow)
2875  call mem_deallocate(this%qextoutflow)
2876  deallocate (this%csfrbudget)
2877  call mem_deallocate(this%sfrname, 'SFRNAME', this%memoryPath)
2878  call mem_deallocate(this%dbuff)
2879  deallocate (this%cauxcbc)
2880  call mem_deallocate(this%qauxcbc)
2881  call mem_deallocate(this%iboundpak)
2882  call mem_deallocate(this%igwfnode)
2883  call mem_deallocate(this%igwftopnode)
2884  call mem_deallocate(this%length)
2885  call mem_deallocate(this%width)
2886  call mem_deallocate(this%strtop)
2887  call mem_deallocate(this%bthick)
2888  call mem_deallocate(this%slope)
2889  call mem_deallocate(this%nconnreach)
2890  call mem_deallocate(this%bedk_set)
2891  call mem_deallocate(this%manning_set)
2892  call mem_deallocate(this%ustrf_set)
2893  call mem_deallocate(this%ftotnd)
2894  call mem_deallocate(this%usflow)
2895  call mem_deallocate(this%dsflow)
2896  call mem_deallocate(this%depth)
2897  call mem_deallocate(this%stage)
2898  call mem_deallocate(this%gwflow)
2899  call mem_deallocate(this%simevap)
2900  call mem_deallocate(this%simrunoff)
2901  call mem_deallocate(this%stage0)
2902  call mem_deallocate(this%usflow0)
2903  call mem_deallocate(this%denseterms)
2904  call mem_deallocate(this%viscratios)
2905  !
2906  ! -- stage, usflow, and dsflow for previous timestep
2907  if (this%istorage == 1) then
2908  call mem_deallocate(this%stageold)
2909  call mem_deallocate(this%dsflowold)
2910  call mem_deallocate(this%storage)
2911  call mem_deallocate(this%usinflow)
2912  call mem_deallocate(this%usinflowold)
2913  call mem_deallocate(this%crmin)
2914  call mem_deallocate(this%crmax)
2915  call mem_deallocate(this%crsum)
2916  call mem_deallocate(this%crcnt)
2917  call mem_deallocate(this%itvd_upstream)
2918  end if
2919  !
2920  ! -- deallocate reach order and connection data
2921  call mem_deallocate(this%isfrorder)
2922  call mem_deallocate(this%ia)
2923  call mem_deallocate(this%ja)
2924  call mem_deallocate(this%idir)
2925  call mem_deallocate(this%idiv)
2926  call mem_deallocate(this%qconn)
2927  !
2928  nullify (this%rain)
2929  nullify (this%evap)
2930  nullify (this%inflow)
2931  nullify (this%runoff)
2932  nullify (this%sstage)
2933  nullify (this%hk)
2934  nullify (this%rough)
2935  nullify (this%ustrf)
2936  !
2937  ! -- deallocate diversion variables
2938  call mem_deallocate(this%iadiv)
2939  call mem_deallocate(this%divreach)
2940  if (associated(this%divcprior)) then
2941  deallocate (this%divcprior)
2942  end if
2943  ! -- divflow is package-owned only when empty (no diversions); it is not
2944  ! associated if the simulation stopped before it was set
2945  if (associated(this%divflow)) then
2946  if (size(this%divflow) == 0) then
2947  call mem_deallocate(this%divflow)
2948  else
2949  nullify (this%divflow)
2950  end if
2951  end if
2952  call mem_deallocate(this%divq)
2953  call mem_deallocate(this%ndiv)
2954  !
2955  ! -- deallocate cross-section data
2956  call mem_deallocate(this%ncrosspts)
2957  call mem_deallocate(this%iacross)
2958  call mem_deallocate(this%station)
2959  call mem_deallocate(this%xsheight)
2960  call mem_deallocate(this%xsrough)
2961  !
2962  ! -- deallocate budobj
2963  call this%budobj%budgetobject_da()
2964  deallocate (this%budobj)
2965  nullify (this%budobj)
2966  !
2967  ! -- deallocate stage table
2968  if (this%iprhed > 0) then
2969  call this%stagetab%table_da()
2970  deallocate (this%stagetab)
2971  nullify (this%stagetab)
2972  end if
2973  !
2974  ! -- deallocate Courant number table
2975  if (associated(this%couranttab)) then
2976  call this%couranttab%table_da()
2977  deallocate (this%couranttab)
2978  nullify (this%couranttab)
2979  end if
2980  !
2981  ! -- deallocate package csv table
2982  if (this%ipakcsv > 0) then
2983  if (associated(this%pakcsvtab)) then
2984  call this%pakcsvtab%table_da()
2985  deallocate (this%pakcsvtab)
2986  nullify (this%pakcsvtab)
2987  end if
2988  end if
2989  !
2990  ! -- deallocate scalars
2991  call mem_deallocate(this%ats_courant)
2992  call mem_deallocate(this%istorage)
2993  call mem_deallocate(this%storage_weight)
2994  call mem_deallocate(this%iprhed)
2995  call mem_deallocate(this%istageout)
2996  call mem_deallocate(this%ibudgetout)
2997  call mem_deallocate(this%ibudcsv)
2998  call mem_deallocate(this%ipakcsv)
2999  call mem_deallocate(this%idiversions)
3000  call mem_deallocate(this%maxsfrpicard)
3001  call mem_deallocate(this%maxsfrit)
3002  call mem_deallocate(this%bditems)
3003  call mem_deallocate(this%cbcauxitems)
3004  call mem_deallocate(this%unitconv)
3005  call mem_deallocate(this%lengthconv)
3006  call mem_deallocate(this%timeconv)
3007  call mem_deallocate(this%dmaxchg)
3008  call mem_deallocate(this%deps)
3009  call mem_deallocate(this%nconn)
3010  call mem_deallocate(this%icheck)
3011  call mem_deallocate(this%iconvchk)
3012  call mem_deallocate(this%idense)
3013  call mem_deallocate(this%ianynone)
3014  call mem_deallocate(this%ncrossptstot)
3015  nullify (this%gwfiss)
3016  !
3017  ! -- nullify SFR input context pointers (input context owns the memory)
3018  call this%input%destroy()
3019  !
3020  ! -- call base BndExtType deallocate
3021  call this%BndExtType%bnd_da()

◆ sfr_df_obs()

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

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

Parameters
thisSfrType object

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

3104  ! -- dummy
3105  class(SfrType) :: this !< SfrType object
3106  ! -- local
3107  integer(I4B) :: indx
3108  !
3109  ! -- Store obs type and assign procedure pointer
3110  ! for stage observation type.
3111  call this%obs%StoreObsType('stage', .false., indx)
3112  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3113  !
3114  ! -- Store obs type and assign procedure pointer
3115  ! for inflow observation type.
3116  call this%obs%StoreObsType('inflow', .true., indx)
3117  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3118  !
3119  ! -- Store obs type and assign procedure pointer
3120  ! for inflow observation type.
3121  call this%obs%StoreObsType('ext-inflow', .true., indx)
3122  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3123  !
3124  ! -- Store obs type and assign procedure pointer
3125  ! for rainfall observation type.
3126  call this%obs%StoreObsType('rainfall', .true., indx)
3127  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3128  !
3129  ! -- Store obs type and assign procedure pointer
3130  ! for runoff observation type.
3131  call this%obs%StoreObsType('runoff', .true., indx)
3132  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3133  !
3134  ! -- Store obs type and assign procedure pointer
3135  ! for evaporation observation type.
3136  call this%obs%StoreObsType('evaporation', .true., indx)
3137  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3138  !
3139  ! -- Store obs type and assign procedure pointer
3140  ! for outflow observation type.
3141  call this%obs%StoreObsType('outflow', .true., indx)
3142  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3143  !
3144  ! -- Store obs type and assign procedure pointer
3145  ! for ext-outflow observation type.
3146  call this%obs%StoreObsType('ext-outflow', .true., indx)
3147  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3148  !
3149  ! -- Store obs type and assign procedure pointer
3150  ! for to-mvr observation type.
3151  call this%obs%StoreObsType('to-mvr', .true., indx)
3152  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3153  !
3154  ! -- Store obs type and assign procedure pointer
3155  ! for sfr-frommvr observation type.
3156  call this%obs%StoreObsType('from-mvr', .true., indx)
3157  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3158  !
3159  ! -- Store obs type and assign procedure pointer
3160  ! for sfr observation type.
3161  call this%obs%StoreObsType('sfr', .true., indx)
3162  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3163  !
3164  ! -- Store obs type and assign procedure pointer
3165  ! for upstream flow observation type.
3166  call this%obs%StoreObsType('upstream-flow', .true., indx)
3167  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3168  !
3169  ! -- Store obs type and assign procedure pointer
3170  ! for downstream flow observation type.
3171  call this%obs%StoreObsType('downstream-flow', .true., indx)
3172  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3173  !
3174  ! -- Store obs type and assign procedure pointer
3175  ! for depth observation type.
3176  call this%obs%StoreObsType('depth', .false., indx)
3177  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3178  !
3179  ! -- Store obs type and assign procedure pointer
3180  ! for wetted-perimeter observation type.
3181  call this%obs%StoreObsType('wet-perimeter', .false., indx)
3182  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3183  !
3184  ! -- Store obs type and assign procedure pointer
3185  ! for wetted-area observation type.
3186  call this%obs%StoreObsType('wet-area', .false., indx)
3187  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3188  !
3189  ! -- Store obs type and assign procedure pointer
3190  ! for wetted-width observation type.
3191  call this%obs%StoreObsType('wet-width', .false., indx)
3192  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid

◆ sfr_dt()

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

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

2803  ! -- modules
2804  use tdismodule, only: kstp, kper, ats
2805  ! -- dummy
2806  class(SfrType) :: this !< SfrType object
2807  ! -- local
2808  integer(I4B) :: n
2809  integer(I4B) :: nrmin
2810  real(DP) :: celerity
2811  real(DP) :: dt_n
2812  real(DP) :: dtmin
2813  character(len=LINELENGTH) :: msg
2814  !
2815  if (this%ats_courant == dnodata) return
2816  if (this%istorage /= 1) return
2817  !
2818  dtmin = dnodata
2819  nrmin = 0
2820  !
2821  do n = 1, this%maxbound
2822  call this%sfr_calc_celerity(n, this%dsflow(n), celerity)
2823  if (celerity > dzero) then
2824  dt_n = this%ats_courant * this%length(n) / celerity
2825  if (dt_n < dtmin) then
2826  dtmin = dt_n
2827  nrmin = n
2828  end if
2829  end if
2830  end do
2831  !
2832  if (nrmin > 0) then
2833  write (msg, '(a,i0)') trim(this%packName)//'-REACH-', nrmin
2834  call ats%ats_submit_delt(kstp, kper, dtmin, trim(msg))
2835  end if
class(atstype), pointer, public ats
Definition: tdis.f90:48

◆ sfr_fc()

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

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

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

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

2160  ! -- dummy
2161  class(SfrType) :: this !< SfrType object
2162  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2163  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2164  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2165  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2166  ! -- local
2167  integer(I4B) :: i
2168  integer(I4B) :: j
2169  integer(I4B) :: n
2170  integer(I4B) :: ipos
2171  integer(I4B) :: node
2172  real(DP) :: s0
2173  real(DP) :: ds
2174  real(DP) :: dsmax
2175  real(DP) :: hgwf
2176  real(DP) :: v
2177  real(DP) :: hhcof
2178  real(DP) :: rrhs
2179  !
2180  ! -- picard iterations for sfr to achieve good solution regardless
2181  ! of reach order
2182  sfrpicard: do i = 1, this%maxsfrpicard
2183  !
2184  ! -- initialize maximum stage change for iteration to zero
2185  dsmax = dzero
2186  !
2187  ! -- pakmvrobj fc - reset qformvr to zero
2188  if (this%imover == 1) then
2189  call this%pakmvrobj%fc()
2190  end if
2191  !
2192  ! -- solve for each sfr reach
2193  reachsolve: do j = 1, this%nbound
2194  n = this%isfrorder(j)
2195  node = this%igwfnode(n)
2196  if (node > 0) then
2197  hgwf = this%xnew(node)
2198  else
2199  hgwf = dep20
2200  end if
2201  !
2202  ! -- save previous stage and upstream flow
2203  if (i == 1) then
2204  this%stage0(n) = this%stage(n)
2205  this%usflow0(n) = this%usflow(n)
2206  end if
2207  !
2208  ! -- set initial stage to calculate stage change
2209  s0 = this%stage(n)
2210  !
2211  ! -- solve for flow in swr
2212  if (this%iboundpak(n) /= 0) then
2213  call this%sfr_solve(n, hgwf, hhcof, rrhs)
2214  else
2215  this%depth(n) = dzero
2216  this%stage(n) = this%strtop(n)
2217  v = dzero
2218  call this%sfr_update_flows(n, v, v)
2219  hhcof = dzero
2220  rrhs = dzero
2221  end if
2222  !
2223  ! -- set package hcof and rhs
2224  this%hcof(n) = hhcof
2225  this%rhs(n) = rrhs
2226  !
2227  ! -- calculate stage change
2228  ds = s0 - this%stage(n)
2229  !
2230  ! -- evaluate if stage change exceeds dsmax
2231  if (abs(ds) > abs(dsmax)) then
2232  dsmax = ds
2233  end if
2234 
2235  end do reachsolve
2236  !
2237  ! -- evaluate if the sfr picard iterations should be terminated
2238  if (abs(dsmax) <= this%dmaxchg) then
2239  exit sfrpicard
2240  end if
2241 
2242  end do sfrpicard
2243  !
2244  ! -- Copy package rhs and hcof into solution rhs and amat
2245  do n = 1, this%nbound
2246  node = this%nodelist(n)
2247  if (node < 1) cycle
2248  rhs(node) = rhs(node) + this%rhs(n)
2249  ipos = ia(node)
2250  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(n))
2251  end do

◆ sfr_fill_budobj()

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

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

Parameters
thisSfrType object

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

5211  ! -- dummy
5212  class(SfrType) :: this !< SfrType object
5213  ! -- local
5214  integer(I4B) :: naux
5215  integer(I4B) :: i
5216  integer(I4B) :: n
5217  integer(I4B) :: n1
5218  integer(I4B) :: n2
5219  integer(I4B) :: ii
5220  integer(I4B) :: idx
5221  integer(I4B) :: idiv
5222  integer(I4B) :: jpos
5223  real(DP) :: q
5224  real(DP) :: qt
5225  real(DP) :: d
5226  real(DP) :: ca
5227  real(DP) :: a
5228  real(DP) :: wp
5229  real(DP) :: l
5230  !
5231  ! -- initialize counter
5232  idx = 0
5233  !
5234  ! -- FLOW JA FACE
5235  idx = idx + 1
5236  call this%budobj%budterm(idx)%reset(this%nconn)
5237  do n = 1, this%maxbound
5238  n1 = n
5239  q = dzero
5240  ca = dzero
5241  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5242  n2 = this%ja(i)
5243  if (this%iboundpak(n) /= 0) then
5244  ! flow to downstream reaches
5245  if (this%idir(i) < 0) then
5246  qt = this%dsflow(n)
5247  q = -this%qconn(i)
5248  ! flow from upstream reaches
5249  else
5250  qt = this%usflow(n)
5251  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
5252  if (this%idir(ii) > 0) cycle
5253  if (this%ja(ii) /= n) cycle
5254  q = this%qconn(ii)
5255  exit
5256  end do
5257  end if
5258  ! calculate flow area
5259  call this%sfr_calc_reach_depth(n, qt, d)
5260  ca = this%calc_area_wet(n, d)
5261  else
5262  q = dzero
5263  ca = dzero
5264  end if
5265  this%qauxcbc(1) = ca
5266  call this%budobj%budterm(idx)%update_term(n1, n2, q, this%qauxcbc)
5267  end do
5268  end do
5269  !
5270  ! -- GWF (LEAKAGE)
5271  idx = idx + 1
5272  call this%budobj%budterm(idx)%reset(this%maxbound - this%ianynone)
5273  do n = 1, this%maxbound
5274  n2 = this%igwfnode(n)
5275  if (n2 > 0) then
5276  if (this%iboundpak(n) /= 0) then
5277  ! -- calc_perimeter_wet() does not enforce depth dependence
5278  if (this%depth(n) > dzero) then
5279  wp = this%calc_perimeter_wet(n, this%depth(n))
5280  else
5281  wp = dzero
5282  end if
5283  l = this%length(n)
5284  a = wp * l
5285  this%qauxcbc(1) = a
5286  q = -this%gwflow(n)
5287  else
5288  this%qauxcbc(1) = dzero
5289  q = dzero
5290  end if
5291  call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
5292  end if
5293  end do
5294  !
5295  ! -- RAIN
5296  idx = idx + 1
5297  call this%budobj%budterm(idx)%reset(this%maxbound)
5298  do n = 1, this%maxbound
5299  if (this%iboundpak(n) /= 0) then
5300  a = this%calc_surface_area(n)
5301  q = this%rain(n) * a
5302  else
5303  q = dzero
5304  end if
5305  call this%budobj%budterm(idx)%update_term(n, n, q)
5306  end do
5307  !
5308  ! -- EVAPORATION
5309  idx = idx + 1
5310  call this%budobj%budterm(idx)%reset(this%maxbound)
5311  do n = 1, this%maxbound
5312  if (this%iboundpak(n) /= 0) then
5313  q = -this%simevap(n)
5314  else
5315  q = dzero
5316  end if
5317  call this%budobj%budterm(idx)%update_term(n, n, q)
5318  end do
5319  !
5320  ! -- RUNOFF
5321  idx = idx + 1
5322  call this%budobj%budterm(idx)%reset(this%maxbound)
5323  do n = 1, this%maxbound
5324  if (this%iboundpak(n) /= 0) then
5325  q = this%simrunoff(n)
5326  else
5327  q = dzero
5328  end if
5329  call this%budobj%budterm(idx)%update_term(n, n, q)
5330  end do
5331  !
5332  ! -- INFLOW
5333  idx = idx + 1
5334  call this%budobj%budterm(idx)%reset(this%maxbound)
5335  do n = 1, this%maxbound
5336  if (this%iboundpak(n) /= 0) then
5337  q = this%inflow(n)
5338  else
5339  q = dzero
5340  end if
5341  call this%budobj%budterm(idx)%update_term(n, n, q)
5342  end do
5343  !
5344  ! -- EXTERNAL OUTFLOW
5345  idx = idx + 1
5346  call this%budobj%budterm(idx)%reset(this%maxbound)
5347  do n = 1, this%maxbound
5348  q = dzero
5349  if (this%iboundpak(n) /= 0) then
5350  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5351  if (this%idir(i) > 0) cycle
5352  idiv = this%idiv(i)
5353  if (idiv > 0) then
5354  jpos = this%iadiv(n) + idiv - 1
5355  q = q + this%divq(jpos)
5356  else
5357  q = q + this%qconn(i)
5358  end if
5359  end do
5360  q = q - this%dsflow(n)
5361  if (this%imover == 1) then
5362  q = q + this%pakmvrobj%get_qtomvr(n)
5363  end if
5364  else
5365  if (this%imover == 1) then
5366  q = this%pakmvrobj%get_qfrommvr(n)
5367  end if
5368  end if
5369  call this%budobj%budterm(idx)%update_term(n, n, q)
5370  end do
5371  !
5372  ! -- STORAGE
5373  idx = idx + 1
5374  call this%budobj%budterm(idx)%reset(this%maxbound)
5375  do n = 1, this%maxbound
5376  q = dzero
5377  if (this%iboundpak(n) /= 0) then
5378  d = this%depth(n)
5379  a = this%calc_surface_area_wet(n, d)
5380  this%qauxcbc(1) = a * d
5381  if (this%gwfiss == 0 .and. this%istorage == 1) then
5382  q = this%storage(n)
5383  end if
5384  else
5385  q = dzero
5386  this%qauxcbc(1) = dzero
5387  end if
5388  call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
5389  end do
5390  !
5391  ! -- MOVER
5392  if (this%imover == 1) then
5393  !
5394  ! -- FROM MOVER
5395  idx = idx + 1
5396  call this%budobj%budterm(idx)%reset(this%maxbound)
5397  do n = 1, this%maxbound
5398  q = dzero
5399  if (this%iboundpak(n) /= 0) then
5400  q = this%pakmvrobj%get_qfrommvr(n)
5401  end if
5402  call this%budobj%budterm(idx)%update_term(n, n, q)
5403  end do
5404  !
5405  ! -- TO MOVER
5406  idx = idx + 1
5407  call this%budobj%budterm(idx)%reset(this%maxbound)
5408  do n = 1, this%maxbound
5409  if (this%iboundpak(n) /= 0) then
5410  q = this%pakmvrobj%get_qtomvr(n)
5411  if (q > dzero) then
5412  q = -q
5413  end if
5414  else
5415  q = dzero
5416  end if
5417  call this%budobj%budterm(idx)%update_term(n, n, q)
5418  end do
5419  end if
5420  !
5421  ! -- AUXILIARY VARIABLES
5422  naux = this%naux
5423  if (naux > 0) then
5424  idx = idx + 1
5425  call this%budobj%budterm(idx)%reset(this%maxbound)
5426  do n = 1, this%maxbound
5427  q = dzero
5428  call this%budobj%budterm(idx)%update_term(n, n, q, this%auxvar(:, n))
5429  end do
5430  end if
5431  !
5432  ! --Terms are filled, now accumulate them for this time step
5433  call this%budobj%accumulate_terms()

◆ sfr_fn()

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

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

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

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

2260  ! -- dummy
2261  class(SfrType) :: this !< SfrType object
2262  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2263  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2264  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2265  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2266  ! -- local
2267  integer(I4B) :: i
2268  integer(I4B) :: j
2269  integer(I4B) :: n
2270  integer(I4B) :: ipos
2271  real(DP) :: rterm
2272  real(DP) :: drterm
2273  real(DP) :: rhs1
2274  real(DP) :: hcof1
2275  real(DP) :: q1
2276  real(DP) :: q2
2277  real(DP) :: hgwf
2278  !
2279  ! -- Copy package rhs and hcof into solution rhs and amat
2280  do j = 1, this%nbound
2281  i = this%isfrorder(j)
2282  ! -- skip inactive reaches
2283  if (this%iboundpak(i) < 1) cycle
2284  ! -- skip if reach is not connected to gwf
2285  n = this%nodelist(i)
2286  if (n < 1) cycle
2287  ipos = ia(n)
2288  rterm = this%hcof(i) * this%xnew(n)
2289  ! -- calculate perturbed head
2290  hgwf = this%xnew(n) + dem4
2291  call this%sfr_solve(i, hgwf, hcof1, rhs1, update=.false.)
2292  q1 = rhs1 - hcof1 * hgwf
2293  ! -- calculate unperturbed head
2294  q2 = this%rhs(i) - this%hcof(i) * this%xnew(n)
2295  ! -- calculate derivative
2296  drterm = (q2 - q1) / dem4
2297  ! -- add terms to convert conductance formulation into
2298  ! newton-raphson formulation
2299  call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(i))
2300  rhs(n) = rhs(n) - rterm + drterm * this%xnew(n)
2301  end do

◆ sfr_fp()

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

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

2768  ! -- dummy
2769  class(SfrType) :: this !< SfrType object
2770  ! -- local
2771  integer(I4B) :: n
2772  real(DP) :: crmean
2773  !
2774  if (this%istorage == 1) then
2775  do n = 1, this%maxbound
2776  if (this%inamedbound == 1) then
2777  call this%couranttab%add_term(this%boundname(n))
2778  end if
2779  call this%couranttab%add_term(n)
2780  if (this%crmin(n) == dep20) then
2781  call this%couranttab%add_term('--')
2782  else
2783  call this%couranttab%add_term(this%crmin(n))
2784  end if
2785  if (this%crmax(n) < dzero) then
2786  call this%couranttab%add_term('--')
2787  else
2788  call this%couranttab%add_term(this%crmax(n))
2789  end if
2790  if (this%crcnt(n) > 0) then
2791  crmean = this%crsum(n) / real(this%crcnt(n), dp)
2792  call this%couranttab%add_term(crmean)
2793  else
2794  call this%couranttab%add_term('--')
2795  end if
2796  end do
2797  end if

◆ sfr_gwf_conn()

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

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

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

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

3950  ! -- return variable
3951  integer(I4B) :: sfr_gwf_conn !< flag indicating if reach is connected to a gwf cell
3952  ! -- dummy
3953  class(SfrType) :: this !< SfrType object
3954  integer(I4B), intent(in) :: n !< reach number
3955  ! -- local
3956  integer(I4B) :: node
3957 
3958  sfr_gwf_conn = 0
3959  node = this%igwfnode(n)
3960  if (node > 0 .and. this%hk(n) > dzero) then
3961  sfr_gwf_conn = 1
3962  end if

◆ sfr_input_destroy()

subroutine sfrmodule::sfr_input_destroy ( class(sfrinputtype), intent(inout)  this)

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

5862  class(SfrInputType), intent(inout) :: this
5863  nullify (this%rhk)
5864  nullify (this%man)
5865  nullify (this%ustrf)
5866  nullify (this%rhk_tslink)
5867  nullify (this%man_tslink)
5868  nullify (this%ustrf_tslink)
5869  nullify (this%nbound)
5870  nullify (this%ifno)
5871  nullify (this%status)
5872  nullify (this%setting)
5873  nullify (this%idv)
5874  nullify (this%tab6_filename)
5875  nullify (this%auxname)
5876  nullify (this%auxval)

◆ sfr_input_init()

subroutine sfrmodule::sfr_input_init ( class(sfrinputtype), intent(inout)  this,
character(len=*), intent(in)  mempath,
integer(i4b), intent(in)  naux 
)
private

Called once from sfr_ar; PACKAGEDATA pointers are set separately in sfr_source_packagedata.

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

5843  use memorymanagermodule, only: mem_setptr
5844  class(SfrInputType), intent(inout) :: this
5845  character(len=*), intent(in) :: mempath
5846  integer(I4B), intent(in) :: naux
5847  call mem_setptr(this%nbound, 'NBOUND', mempath)
5848  call mem_setptr(this%ifno, 'IFNO', mempath)
5849  call mem_setptr(this%setting, 'SETTING', mempath)
5850  call mem_setptr(this%status, 'STATUS', mempath)
5851  call mem_setptr(this%idv, 'IDV', mempath)
5852  call mem_setptr(this%tab6_filename, 'TAB6_FILENAME', mempath)
5853  if (naux > 0) then
5854  call mem_setptr(this%auxname, 'AUXNAME', mempath)
5855  call mem_setptr(this%auxval, 'AUXVAL', mempath)
5856  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 3091 of file gwf-sfr.f90.

3092  ! -- dummy
3093  class(SfrType) :: this !< SfrType object
3094  !
3095  ! -- set boolean
3096  sfr_obs_supported = .true.

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

2753  ! -- module
2754  use tdismodule, only: totim, delt
2755  ! -- dummy
2756  class(SfrType) :: this !< SfrType object
2757  integer(I4B), intent(in) :: kstp !< time step number
2758  integer(I4B), intent(in) :: kper !< period number
2759  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
2760  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
2761  !
2762  call this%budobj%write_budtable(kstp, kper, iout, ibudfl, totim, delt)

◆ sfr_ot_dv()

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

Output SFR boundary package dependent-variable terms.

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

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

2641  ! -- modules
2642  use tdismodule, only: kstp, kper, pertim, totim
2643  use inputoutputmodule, only: ulasav
2644  ! -- dummy
2645  class(SfrType) :: this !< SfrType object
2646  integer(I4B), intent(in) :: idvsave !< flag and unit number for dependent-variable output
2647  integer(I4B), intent(in) :: idvprint !< flag indicating if dependent-variable should be written to the model listing file
2648  ! -- local
2649  character(len=20) :: cellid
2650  integer(I4B) :: ibinun
2651  integer(I4B) :: n
2652  integer(I4B) :: node
2653  real(DP) :: d
2654  real(DP) :: v
2655  real(DP) :: hgwf
2656  real(DP) :: sbot
2657  real(DP) :: depth
2658  real(DP) :: stage
2659  real(DP) :: w
2660  real(DP) :: cond
2661  real(DP) :: grad
2662  !
2663  ! -- set unit number for binary dependent variable output
2664  ibinun = 0
2665  if (this%istageout /= 0) then
2666  ibinun = this%istageout
2667  end if
2668  if (idvsave == 0) ibinun = 0
2669  !
2670  ! -- write sfr binary output
2671  if (ibinun > 0) then
2672  do n = 1, this%maxbound
2673  d = this%depth(n)
2674  v = this%stage(n)
2675  if (this%iboundpak(n) == 0) then
2676  v = dhnoflo
2677  else if (d == dzero) then
2678  v = dhdry
2679  end if
2680  this%dbuff(n) = v
2681  end do
2682  call ulasav(this%dbuff, ' STAGE', kstp, kper, pertim, totim, &
2683  this%maxbound, 1, 1, ibinun)
2684  end if
2685  !
2686  ! -- print sfr stage and depth table
2687  if (idvprint /= 0 .and. this%iprhed /= 0) then
2688  !
2689  ! -- set table kstp and kper
2690  call this%stagetab%set_kstpkper(kstp, kper)
2691  !
2692  ! -- fill stage data
2693  do n = 1, this%maxbound
2694  node = this%igwfnode(n)
2695  if (node > 0) then
2696  call this%dis%noder_to_string(node, cellid)
2697  hgwf = this%xnew(node)
2698  else
2699  cellid = 'NONE'
2700  end if
2701  if (this%inamedbound == 1) then
2702  call this%stagetab%add_term(this%boundname(n))
2703  end if
2704  call this%stagetab%add_term(n)
2705  call this%stagetab%add_term(cellid)
2706  if (this%iboundpak(n) /= 0) then
2707  depth = this%depth(n)
2708  stage = this%stage(n)
2709  w = this%calc_top_width_wet(n, depth)
2710  call this%sfr_calc_cond(n, depth, cond, stage, hgwf)
2711  else
2712  depth = dhnoflo
2713  stage = dhnoflo
2714  w = dhnoflo
2715  cond = dhnoflo
2716  end if
2717  if (depth == dzero) then
2718  call this%stagetab%add_term(dhdry)
2719  else
2720  call this%stagetab%add_term(stage)
2721  end if
2722  call this%stagetab%add_term(depth)
2723  call this%stagetab%add_term(w)
2724  if (node > 0) then
2725  if (this%iboundpak(n) /= 0) then
2726  sbot = this%strtop(n) - this%bthick(n)
2727  if (hgwf < sbot) then
2728  grad = stage - sbot
2729  else
2730  grad = stage - hgwf
2731  end if
2732  grad = grad / this%bthick(n)
2733  else
2734  grad = dhnoflo
2735  end if
2736  call this%stagetab%add_term(hgwf)
2737  call this%stagetab%add_term(cond)
2738  call this%stagetab%add_term(grad)
2739  else
2740  call this%stagetab%add_term('--')
2741  call this%stagetab%add_term('--')
2742  call this%stagetab%add_term('--')
2743  end if
2744  end do
2745  end if
subroutine, public ulasav(buf, text, kstp, kper, pertim, totim, ncol, nrow, ilay, ichn)
Save 1 layer array on disk.
real(dp), pointer, public pertim
time relative to start of stress period
Definition: tdis.f90:33
Here is the call graph for this function:

◆ sfr_ot_package_flows()

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

Output SFR package flow terms.

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

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

2588  ! -- modules
2589  use tdismodule, only: kstp, kper, delt, pertim, totim
2590  ! -- dummy
2591  class(SfrType) :: this !< SfrType object
2592  integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output
2593  integer(I4B), intent(in) :: ibudfl !< flag indication if cell-by-cell data should be saved
2594  ! -- local
2595  integer(I4B) :: ibinun
2596  character(len=20), dimension(:), allocatable :: cellidstr
2597  integer(I4B) :: n
2598  integer(I4B) :: node
2599  !
2600  ! -- write the flows from the budobj
2601  ibinun = 0
2602  if (this%ibudgetout /= 0) then
2603  ibinun = this%ibudgetout
2604  end if
2605  if (icbcfl == 0) ibinun = 0
2606  if (ibinun > 0) then
2607  call this%budobj%save_flows(this%dis, ibinun, kstp, kper, delt, &
2608  pertim, totim, this%iout)
2609  end if
2610  !
2611  ! -- Print sfr flows table
2612  if (ibudfl /= 0 .and. this%iprflow /= 0) then
2613  !
2614  ! -- If there are any 'none' gwf connections then need to calculate
2615  ! a vector of cellids and pass that in to the budget flow table because
2616  ! the table assumes that there are maxbound gwf entries, which is not
2617  ! the case if any 'none's are specified.
2618  if (this%ianynone > 0) then
2619  allocate (cellidstr(this%maxbound))
2620  do n = 1, this%maxbound
2621  node = this%igwfnode(n)
2622  if (node > 0) then
2623  call this%dis%noder_to_string(node, cellidstr(n))
2624  else
2625  cellidstr(n) = 'NONE'
2626  end if
2627  end do
2628  call this%budobj%write_flowtable(this%dis, kstp, kper, cellidstr)
2629  deallocate (cellidstr)
2630  else
2631  call this%budobj%write_flowtable(this%dis, kstp, kper)
2632  end if
2633  end if

◆ sfr_precompute_tvd()

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

Index 0 for reaches with zero or multiple upstream connections.

Parameters
[in,out]thisSfrType object

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

3029  ! -- dummy
3030  class(SfrType), intent(inout) :: this !< SfrType object
3031  ! -- local
3032  integer(I4B) :: n
3033  integer(I4B) :: j
3034  integer(I4B) :: iup_count
3035  integer(I4B) :: m
3036  !
3037  do n = 1, this%maxbound
3038  iup_count = 0
3039  m = 0
3040  do j = this%ia(n) + 1, this%ia(n + 1) - 1
3041  if (this%idir(j) > 0) then
3042  iup_count = iup_count + 1
3043  m = this%ja(j)
3044  end if
3045  end do
3046  if (iup_count == 1) then
3047  this%itvd_upstream(n) = m
3048  else
3049  this%itvd_upstream(n) = 0
3050  end if
3051  end do

◆ sfr_process_obsid()

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

Method to process observation ID strings for a SFR package.

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

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

3402  ! -- dummy
3403  type(ObserveType), intent(inout) :: obsrv !< Observation object
3404  class(DisBaseType), intent(in) :: dis !< Discretization object
3405  integer(I4B), intent(in) :: inunitobs !< file unit number for the package observation file
3406  integer(I4B), intent(in) :: iout !< model listing file unit number
3407  ! -- local
3408  integer(I4B) :: nn1
3409  integer(I4B) :: icol
3410  integer(I4B) :: istart
3411  integer(I4B) :: istop
3412  character(len=LINELENGTH) :: string
3413  character(len=LENBOUNDNAME) :: bndname
3414  !
3415  ! -- initialize local variables
3416  string = obsrv%IDstring
3417  !
3418  ! -- Extract reach number from string and store it.
3419  ! If 1st item is not an integer(I4B), it should be a
3420  ! boundary name--deal with it.
3421  icol = 1
3422  !
3423  ! -- get reach number or boundary name
3424  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
3425  if (nn1 == namedboundflag) then
3426  obsrv%FeatureName = bndname
3427  end if
3428  !
3429  ! -- store reach number (NodeNumber)
3430  obsrv%NodeNumber = nn1
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 1783 of file gwf-sfr.f90.

1784  ! -- modules
1785  use constantsmodule, only: lenvarname
1786  use tdismodule, only: kper
1789  ! -- dummy
1790  class(SfrType), intent(inout) :: this !< SfrType object
1791  ! -- local
1792  character(len=LINELENGTH) :: crossfile
1793  character(len=LINELENGTH) :: str
1794  real(DP) :: auxvaldbl
1795  character(len=LINELENGTH) :: title
1796  character(len=LINELENGTH) :: text
1797  character(len=LENVARNAME) :: setting
1798  character(len=10) :: cnum
1799  character(len=10) :: cp
1800  integer(I4B) :: n
1801  integer(I4B) :: i
1802  integer(I4B) :: ii
1803  integer(I4B) :: jj
1804  integer(I4B) :: idiv
1805  integer(I4B) :: ichkustrm
1806  integer(I4B) :: ncrossptstot
1807  type(SfrCrossSection), pointer :: cross_data => null()
1808  ! -- formats
1809  character(len=*), parameter :: fmtlsp = &
1810  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
1811  !
1812  ! -- initialize flags
1813  ichkustrm = 0
1814  if (kper == 1) then
1815  ichkustrm = 1
1816  end if
1817  !
1818  ! -- set nbound to maxbound
1819  this%nbound = this%maxbound
1820  !
1821  ! -- check if input context has been updated for this stress period
1822  if (this%iper == kper) then
1823  !
1824  ! -- create and initialize cross-section data
1825  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1826  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1827  this%iacross, &
1828  this%station, this%xsheight, &
1829  this%xsrough)
1830  !
1831  ! -- setup table to echo period data
1832  if (this%iprpak /= 0) then
1833  title = trim(adjustl(this%text))//' PACKAGE ('// &
1834  trim(adjustl(this%packName))//') DATA FOR PERIOD'
1835  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
1836  call table_cr(this%inputtab, this%packName, title)
1837  call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
1838  text = 'NUMBER'
1839  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
1840  text = 'KEYWORD'
1841  call this%inputtab%initialize_column(text, 20, alignment=tableft)
1842  do jj = 1, 2
1843  write (text, '(a,1x,i6)') 'VALUE', jj
1844  call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
1845  end do
1846  end if
1847  !
1848  ! -- process each period data entry
1849  do i = 1, this%input%nbound
1850  n = this%input%ifno(i)
1851  if (n < 1 .or. n > this%maxbound) then
1852  write (errmsg, '(a,1x,a,1x,i0,a)') &
1853  'Reach number (RNO) must be greater than 0 and', &
1854  'less than or equal to', this%maxbound, '.'
1855  call store_error(errmsg)
1856  cycle
1857  end if
1858  !
1859  ! -- dispatch key for this row
1860  setting = this%input%setting(i)
1861  !
1862  ! -- STATUS
1863  if (trim(setting) == 'STATUS') then
1864  str = this%input%status(i)
1865  ichkustrm = 1
1866  if (str == 'INACTIVE') then
1867  this%iboundpak(n) = 0
1868  else if (str == 'ACTIVE') then
1869  this%iboundpak(n) = 1
1870  else if (str == 'SIMPLE') then
1871  this%iboundpak(n) = -1
1872  else
1873  write (errmsg, '(2a)') &
1874  'Unknown '//trim(this%text)//' sfr status keyword: ', trim(str)
1875  call store_error(errmsg)
1876  end if
1877  end if
1878  !
1879  ! -- BEDK, MANNING, STAGE, INFLOW, RAINFALL, EVAPORATION, RUNOFF,
1880  ! UPSTREAM_FRAC; sfr_ad re-syncs these each timestep if TS-linked
1881  call this%sfr_set_period_value(i, n, setting)
1882  if (trim(setting) == 'UPSTREAM_FRAC') ichkustrm = 1
1883  !
1884  ! -- DIVERSION (compound group)
1885  if (trim(setting) == 'DIVERSION') then
1886  if (this%ndiv(n) < 1) then
1887  write (cnum, '(i0)') n
1888  errmsg = 'diversions cannot be specified for reach '//trim(cnum)
1889  call store_error(errmsg)
1890  else
1891  idiv = this%input%idv(i)
1892  if (idiv < 1 .or. idiv > this%ndiv(n)) then
1893  write (cnum, '(i0)') n
1894  errmsg = 'Reach '//trim(cnum)
1895  write (cnum, '(i0)') this%ndiv(n)
1896  errmsg = trim(errmsg)//' diversion number should be between 1 '// &
1897  'and '//trim(cnum)//'.'
1898  call store_error(errmsg)
1899  else
1900  ii = this%iadiv(n) + idiv - 1
1901  ! -- if cprior is 'FRACTION', check 0.0 <= divflow <= 1.0
1902  cp = this%divcprior(ii)
1903  if (cp == 'FRACTION' .and. &
1904  (this%divflow(ii) < dzero .or. this%divflow(ii) > done)) then
1905  write (errmsg, '(a,1x,i0,a)') &
1906  'cprior is type FRACTION for diversion no.', ii, &
1907  ', but divflow not within the range 0.0 to 1.0'
1908  call store_error(errmsg)
1909  end if
1910  end if
1911  end if
1912  end if
1913  !
1914  ! -- CROSS_SECTION (compound group)
1915  if (trim(setting) == 'CROSS_SECTION') then
1916  crossfile = this%input%tab6_filename(i)
1917  call cross_data%read_table(n, this%width(n), trim(adjustl(crossfile)))
1918  end if
1919  !
1920  ! -- AUXILIARY (compound group): featureauxvar already holds the
1921  ! -- current value; only extract auxname for echoing this row
1922  if (this%naux > 0) then
1923  if (trim(setting) == 'PERIOD_AUXILIARY') then
1924  str = this%input%auxname(i)
1925  auxvaldbl = this%input%auxval(i)
1926  end if
1927  end if
1928  !
1929  ! -- echo row to period data table
1930  if (this%iprpak /= 0) then
1931  call this%inputtab%add_term(n)
1932  if (trim(setting) == 'PERIOD_AUXILIARY') then
1933  call this%inputtab%add_term('AUXILIARY')
1934  else
1935  call this%inputtab%add_term(trim(setting))
1936  end if
1937  select case (trim(setting))
1938  case ('STATUS')
1939  call this%inputtab%add_term(trim(str))
1940  call this%inputtab%add_term(' ')
1941  case ('BEDK')
1942  call this%inputtab%add_term(this%hk(n))
1943  call this%inputtab%add_term(' ')
1944  case ('MANNING')
1945  call this%inputtab%add_term(this%rough(n))
1946  call this%inputtab%add_term(' ')
1947  case ('STAGE')
1948  call this%inputtab%add_term(this%sstage(n))
1949  call this%inputtab%add_term(' ')
1950  case ('INFLOW')
1951  call this%inputtab%add_term(this%inflow(n))
1952  call this%inputtab%add_term(' ')
1953  case ('RAINFALL')
1954  call this%inputtab%add_term(this%rain(n))
1955  call this%inputtab%add_term(' ')
1956  case ('EVAPORATION')
1957  call this%inputtab%add_term(this%evap(n))
1958  call this%inputtab%add_term(' ')
1959  case ('RUNOFF')
1960  call this%inputtab%add_term(this%runoff(n))
1961  call this%inputtab%add_term(' ')
1962  case ('UPSTREAM_FRAC')
1963  call this%inputtab%add_term(this%ustrf(n))
1964  call this%inputtab%add_term(' ')
1965  case ('DIVERSION')
1966  call this%inputtab%add_term(idiv)
1967  call this%inputtab%add_term(this%divflow(ii))
1968  case ('CROSS_SECTION')
1969  call this%inputtab%add_term(trim(crossfile))
1970  call this%inputtab%add_term(' ')
1971  case ('PERIOD_AUXILIARY')
1972  call this%inputtab%add_term(trim(str))
1973  call this%inputtab%add_term(auxvaldbl)
1974  case default
1975  call this%inputtab%add_term(' ')
1976  call this%inputtab%add_term(' ')
1977  end select
1978  end if
1979  end do
1980  if (this%iprpak /= 0) then
1981  call this%inputtab%finalize_table()
1982  end if
1983  !
1984  ! -- determine the current size of cross-section data
1985  ncrossptstot = cross_data%get_ncrossptstot()
1986  !
1987  ! -- reallocate sfr package cross-section data if size changed
1988  if (ncrossptstot /= this%ncrossptstot) then
1989  this%ncrossptstot = ncrossptstot
1990  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1991  this%memoryPath)
1992  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1993  this%memoryPath)
1994  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1995  this%memoryPath)
1996  end if
1997  !
1998  ! -- write cross-section data to the model listing file
1999  call cross_data%output(this%width, this%rough, kstp=1, kper=kper)
2000  !
2001  ! -- pack cross-section data
2002  call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
2003  this%iacross, &
2004  this%station, &
2005  this%xsheight, &
2006  this%xsrough)
2007  !
2008  ! -- deallocate temporary local storage for reach cross-sections
2009  call cross_data%destroy()
2010  deallocate (cross_data)
2011  nullify (cross_data)
2012  else
2013  write (this%iout, fmtlsp) trim(this%filtyp)
2014  end if
2015  !
2016  ! -- check upstream fraction values every period; ftotnd must be
2017  ! initialized for sfr_update_flows even when there is no period data
2018  if (ichkustrm /= 0) then
2019  call this%sfr_check_ustrf()
2020  end if
2021  !
2022  ! -- write summary of package block error messages
2023  if (count_errors() > 0) then
2024  call store_error_filename(this%input_fname)
2025  end if
subroutine, public cross_section_cr(this, iout, iprpak, nreaches)
Create a cross-section object.
Here is the call graph for this function:

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

3292  ! -- modules
3293  use tdismodule, only: kper
3294  ! -- dummy
3295  class(SfrType), intent(inout) :: this !< SfrType object
3296  ! -- local
3297  integer(I4B) :: i
3298  integer(I4B) :: j
3299  integer(I4B) :: nn1
3300  character(len=LENBOUNDNAME) :: bname
3301  logical(LGP) :: jfound
3302  class(ObserveType), pointer :: obsrv => null()
3303  ! -- formats
3304 10 format('Boundary "', a, '" for observation "', a, &
3305  '" is invalid in package "', a, '"')
3306 30 format('Boundary name not provided for observation "', a, &
3307  '" in package "', a, '"')
3308  !
3309  ! -- process each package observation
3310  ! only done the first stress period since boundaries are fixed
3311  ! for the simulation
3312  if (kper == 1) then
3313  do i = 1, this%obs%npakobs
3314  obsrv => this%obs%pakobs(i)%obsrv
3315  !
3316  ! -- get node number 1
3317  nn1 = obsrv%NodeNumber
3318  if (nn1 == namedboundflag) then
3319  bname = obsrv%FeatureName
3320  if (bname /= '') then
3321  ! -- Observation location(s) is(are) based on a boundary name.
3322  ! Iterate through all boundaries to identify and store
3323  ! corresponding index(indices) in bound array.
3324  jfound = .false.
3325  do j = 1, this%maxbound
3326  if (this%boundname(j) == bname) then
3327  jfound = .true.
3328  call obsrv%AddObsIndex(j)
3329  end if
3330  end do
3331  if (.not. jfound) then
3332  write (errmsg, 10) &
3333  trim(bname), trim(obsrv%name), trim(this%packName)
3334  call store_error(errmsg)
3335  end if
3336  else
3337  write (errmsg, 30) trim(obsrv%name), trim(this%packName)
3338  call store_error(errmsg)
3339  end if
3340  else if (nn1 < 1 .or. nn1 > this%maxbound) then
3341  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3342  trim(adjustl(obsrv%ObsTypeId)), &
3343  'reach must be greater than 0 and less than or equal to', &
3344  this%maxbound, '(specified value is ', nn1, ')'
3345  call store_error(errmsg)
3346  else
3347  if (obsrv%indxbnds_count == 0) then
3348  call obsrv%AddObsIndex(nn1)
3349  else
3350  errmsg = 'Programming error in sfr_rp_obs'
3351  call store_error(errmsg)
3352  end if
3353  end if
3354  !
3355  ! -- catch non-cumulative observation assigned to observation defined
3356  ! by a boundname that is assigned to more than one element
3357  if (obsrv%ObsTypeId == 'STAGE' .or. &
3358  obsrv%ObsTypeId == 'DEPTH' .or. &
3359  obsrv%ObsTypeId == 'WET-PERIMETER' .or. &
3360  obsrv%ObsTypeId == 'WET-AREA' .or. &
3361  obsrv%ObsTypeId == 'WET-WIDTH') then
3362  nn1 = obsrv%NodeNumber
3363  if (nn1 == namedboundflag) then
3364  if (obsrv%indxbnds_count > 1) then
3365  write (errmsg, '(a,3(1x,a))') &
3366  trim(adjustl(obsrv%ObsTypeId)), &
3367  'for observation', trim(adjustl(obsrv%Name)), &
3368  ' must be assigned to a reach with a unique boundname.'
3369  call store_error(errmsg)
3370  end if
3371  end if
3372  end if
3373  !
3374  ! -- check that node number 1 is valid; call store_error if not
3375  do j = 1, obsrv%indxbnds_count
3376  nn1 = obsrv%indxbnds(j)
3377  if (nn1 < 1 .or. nn1 > this%maxbound) then
3378  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3379  trim(adjustl(obsrv%ObsTypeId)), &
3380  'reach must be greater than 0 and less than or equal to', &
3381  this%maxbound, '(specified value is ', nn1, ')'
3382  call store_error(errmsg)
3383  end if
3384  end do
3385  end do
3386  !
3387  ! -- evaluate if there are any observation errors
3388  if (count_errors() > 0) then
3389  call store_error_filename(this%input_fname)
3390  end if
3391  end if
Here is the call graph for this function:

◆ sfr_set_period_value()

subroutine sfrmodule::sfr_set_period_value ( class(sfrtype), intent(inout)  this,
integer(i4b), intent(in)  i,
integer(i4b), intent(in)  n,
character(len=*), intent(in)  setting 
)
private

Shared by sfr_rp and sfr_ad; DIVERSION is handled separately by both callers because its target index requires its own validation.

Parameters
[in]irow index into input context arrays
[in]nreach number
[in]settinguppercase mf6varname dispatch key

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

4973  ! -- dummy
4974  class(SfrType), intent(inout) :: this
4975  integer(I4B), intent(in) :: i !< row index into input context arrays
4976  integer(I4B), intent(in) :: n !< reach number
4977  character(len=*), intent(in) :: setting !< uppercase mf6varname dispatch key
4978  !
4979  select case (trim(setting))
4980  case ('BEDK')
4981  this%bedk_set(n) = .true.
4982  case ('MANNING')
4983  this%manning_set(n) = .true.
4984  case ('UPSTREAM_FRAC')
4985  this%ustrf_set(n) = .true.
4986  end select

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

4996  ! -- dummy
4997  class(SfrType) :: this !< SfrType object
4998  ! -- local
4999  integer(I4B) :: nbudterm
5000  integer(I4B) :: i
5001  integer(I4B) :: n
5002  integer(I4B) :: n1
5003  integer(I4B) :: n2
5004  integer(I4B) :: maxlist
5005  integer(I4B) :: naux
5006  integer(I4B) :: idx
5007  real(DP) :: q
5008  character(len=LENBUDTXT) :: text
5009  character(len=LENBUDTXT), dimension(1) :: auxtxt
5010  !
5011  ! -- Determine the number of sfr budget terms. These are fixed for
5012  ! the simulation and cannot change. This includes FLOW-JA-FACE
5013  ! so they can be written to the binary budget files, but these internal
5014  ! flows are not included as part of the budget table.
5015  nbudterm = 8
5016  if (this%imover == 1) nbudterm = nbudterm + 2
5017  if (this%naux > 0) nbudterm = nbudterm + 1
5018  !
5019  ! -- set up budobj
5020  call budgetobject_cr(this%budobj, this%packName)
5021  call this%budobj%budgetobject_df(this%maxbound, nbudterm, 0, 0, &
5022  ibudcsv=this%ibudcsv)
5023  idx = 0
5024  !
5025  ! -- Go through and set up each budget term
5026  text = ' FLOW-JA-FACE'
5027  idx = idx + 1
5028  maxlist = this%nconn
5029  naux = 1
5030  auxtxt(1) = ' FLOW-AREA'
5031  call this%budobj%budterm(idx)%initialize(text, &
5032  this%name_model, &
5033  this%packName, &
5034  this%name_model, &
5035  this%packName, &
5036  maxlist, .false., .false., &
5037  naux, auxtxt)
5038  !
5039  ! -- store connectivity
5040  call this%budobj%budterm(idx)%reset(this%nconn)
5041  q = dzero
5042  do n = 1, this%maxbound
5043  n1 = n
5044  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5045  n2 = this%ja(i)
5046  call this%budobj%budterm(idx)%update_term(n1, n2, q)
5047  end do
5048  end do
5049  !
5050  ! --
5051  text = ' GWF'
5052  idx = idx + 1
5053  maxlist = this%maxbound - this%ianynone
5054  naux = 1
5055  auxtxt(1) = ' FLOW-AREA'
5056  call this%budobj%budterm(idx)%initialize(text, &
5057  this%name_model, &
5058  this%packName, &
5059  this%name_model, &
5060  this%name_model, &
5061  maxlist, .false., .true., &
5062  naux, auxtxt)
5063  call this%budobj%budterm(idx)%reset(maxlist)
5064  q = dzero
5065  do n = 1, this%maxbound
5066  n2 = this%igwfnode(n)
5067  if (n2 > 0) then
5068  call this%budobj%budterm(idx)%update_term(n, n2, q)
5069  end if
5070  end do
5071  !
5072  ! --
5073  text = ' RAINFALL'
5074  idx = idx + 1
5075  maxlist = this%maxbound
5076  naux = 0
5077  call this%budobj%budterm(idx)%initialize(text, &
5078  this%name_model, &
5079  this%packName, &
5080  this%name_model, &
5081  this%packName, &
5082  maxlist, .false., .false., &
5083  naux)
5084  !
5085  ! --
5086  text = ' EVAPORATION'
5087  idx = idx + 1
5088  maxlist = this%maxbound
5089  naux = 0
5090  call this%budobj%budterm(idx)%initialize(text, &
5091  this%name_model, &
5092  this%packName, &
5093  this%name_model, &
5094  this%packName, &
5095  maxlist, .false., .false., &
5096  naux)
5097  !
5098  ! --
5099  text = ' RUNOFF'
5100  idx = idx + 1
5101  maxlist = this%maxbound
5102  naux = 0
5103  call this%budobj%budterm(idx)%initialize(text, &
5104  this%name_model, &
5105  this%packName, &
5106  this%name_model, &
5107  this%packName, &
5108  maxlist, .false., .false., &
5109  naux)
5110  !
5111  ! --
5112  text = ' EXT-INFLOW'
5113  idx = idx + 1
5114  maxlist = this%maxbound
5115  naux = 0
5116  call this%budobj%budterm(idx)%initialize(text, &
5117  this%name_model, &
5118  this%packName, &
5119  this%name_model, &
5120  this%packName, &
5121  maxlist, .false., .false., &
5122  naux)
5123  !
5124  ! --
5125  text = ' EXT-OUTFLOW'
5126  idx = idx + 1
5127  maxlist = this%maxbound
5128  naux = 0
5129  call this%budobj%budterm(idx)%initialize(text, &
5130  this%name_model, &
5131  this%packName, &
5132  this%name_model, &
5133  this%packName, &
5134  maxlist, .false., .false., &
5135  naux)
5136  !
5137  ! --
5138  text = ' STORAGE'
5139  idx = idx + 1
5140  maxlist = this%maxbound
5141  naux = 1
5142  auxtxt(1) = ' VOLUME'
5143  call this%budobj%budterm(idx)%initialize(text, &
5144  this%name_model, &
5145  this%packName, &
5146  this%name_model, &
5147  this%packName, &
5148  maxlist, .false., .false., &
5149  naux, auxtxt)
5150  !
5151  ! --
5152  if (this%imover == 1) then
5153  !
5154  ! --
5155  text = ' FROM-MVR'
5156  idx = idx + 1
5157  maxlist = this%maxbound
5158  naux = 0
5159  call this%budobj%budterm(idx)%initialize(text, &
5160  this%name_model, &
5161  this%packName, &
5162  this%name_model, &
5163  this%packName, &
5164  maxlist, .false., .false., &
5165  naux)
5166  !
5167  ! --
5168  text = ' TO-MVR'
5169  idx = idx + 1
5170  maxlist = this%maxbound
5171  naux = 0
5172  call this%budobj%budterm(idx)%initialize(text, &
5173  this%name_model, &
5174  this%packName, &
5175  this%name_model, &
5176  this%packName, &
5177  maxlist, .false., .false., &
5178  naux)
5179  end if
5180  !
5181  ! --
5182  naux = this%naux
5183  if (naux > 0) then
5184  !
5185  ! --
5186  text = ' AUXILIARY'
5187  idx = idx + 1
5188  maxlist = this%maxbound
5189  call this%budobj%budterm(idx)%initialize(text, &
5190  this%name_model, &
5191  this%packName, &
5192  this%name_model, &
5193  this%packName, &
5194  maxlist, .false., .false., &
5195  naux, this%auxname)
5196  end if
5197  !
5198  ! -- if sfr flow for each reach are written to the listing file
5199  if (this%iprflow /= 0) then
5200  call this%budobj%flowtable_df(this%iout, cellids='GWF')
5201  end if
Here is the call graph for this function:

◆ sfr_setup_tableobj()

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

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

Parameters
thisSfrType object

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

5443  ! -- dummy
5444  class(SfrType) :: this !< SfrType object
5445  ! -- local
5446  integer(I4B) :: nterms
5447  character(len=LINELENGTH) :: title
5448  character(len=LINELENGTH) :: text
5449  !
5450  ! -- setup stage table
5451  if (this%iprhed > 0) then
5452  !
5453  ! -- Determine the number of sfr budget terms. These are fixed for
5454  ! the simulation and cannot change. This includes FLOW-JA-FACE
5455  ! so they can be written to the binary budget files, but these internal
5456  ! flows are not included as part of the budget table.
5457  nterms = 8
5458  if (this%inamedbound == 1) then
5459  nterms = nterms + 1
5460  end if
5461  !
5462  ! -- set up table title
5463  title = trim(adjustl(this%text))//' PACKAGE ('// &
5464  trim(adjustl(this%packName))//') STAGES FOR EACH CONTROL VOLUME'
5465  !
5466  ! -- set up stage tableobj
5467  call table_cr(this%stagetab, this%packName, title)
5468  call this%stagetab%table_df(this%maxbound, nterms, this%iout, &
5469  transient=.true.)
5470  !
5471  ! -- Go through and set up table budget term
5472  if (this%inamedbound == 1) then
5473  text = 'NAME'
5474  call this%stagetab%initialize_column(text, lenboundname, &
5475  alignment=tableft)
5476  end if
5477  !
5478  ! -- reach number
5479  text = 'NUMBER'
5480  call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
5481  !
5482  ! -- cellids
5483  text = 'CELLID'
5484  call this%stagetab%initialize_column(text, 20, alignment=tableft)
5485  !
5486  ! -- reach stage
5487  text = 'STAGE'
5488  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5489  !
5490  ! -- reach depth
5491  text = 'DEPTH'
5492  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5493  !
5494  ! -- reach width
5495  text = 'WIDTH'
5496  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5497  !
5498  ! -- gwf head
5499  text = 'GWF HEAD'
5500  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5501  !
5502  ! -- streambed conductance
5503  text = 'STREAMBED CONDUCTANCE'
5504  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5505  !
5506  ! -- streambed gradient
5507  text = 'STREAMBED GRADIENT'
5508  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5509  end if
5510  !
5511  ! -- setup Courant number table
5512  if (this%istorage == 1) then
5513  nterms = 4
5514  if (this%inamedbound == 1) then
5515  nterms = nterms + 1
5516  end if
5517  !
5518  ! -- set up table title
5519  title = trim(adjustl(this%text))//' PACKAGE ('// &
5520  trim(adjustl(this%packName))//') COURANT NUMBER FOR EACH REACH'
5521  !
5522  ! -- set up Courant tableobj
5523  call table_cr(this%couranttab, this%packName, title)
5524  call this%couranttab%table_df(this%maxbound, nterms, this%iout)
5525  !
5526  if (this%inamedbound == 1) then
5527  text = 'NAME'
5528  call this%couranttab%initialize_column(text, lenboundname, &
5529  alignment=tableft)
5530  end if
5531  !
5532  ! -- reach number
5533  text = 'NUMBER'
5534  call this%couranttab%initialize_column(text, 10, alignment=tabcenter)
5535  !
5536  ! -- minimum Courant number
5537  text = 'MINIMUM'
5538  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5539  !
5540  ! -- maximum Courant number
5541  text = 'MAXIMUM'
5542  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5543  !
5544  ! -- mean Courant number
5545  text = 'MEAN'
5546  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5547  end if
Here is the call graph for this function:

◆ sfr_solve()

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

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

3438  ! -- dummy
3439  class(SfrType) :: this !< SfrType object
3440  integer(I4B), intent(in) :: n !< reach number
3441  real(DP), intent(in) :: h !< groundwater head in cell connected to reach
3442  real(DP), intent(inout) :: hcof !< coefficient term added to the diagonal
3443  real(DP), intent(inout) :: rhs !< right-hand side term
3444  logical(LGP), intent(in), optional :: update !< boolean indicating if the reach depth and stage variables should be updated to current iterate
3445  ! -- local
3446  logical(LGP) :: lupdate
3447  integer(I4B) :: i
3448  integer(I4B) :: ii
3449  integer(I4B) :: n2
3450  real(DP) :: hgwf
3451  real(DP) :: sa
3452  real(DP) :: sa_wet
3453  real(DP) :: qu
3454  real(DP) :: qi
3455  real(DP) :: qr
3456  real(DP) :: qe
3457  real(DP) :: qro
3458  real(DP) :: qsrc
3459  real(DP) :: qfrommvr
3460  real(DP) :: qgwf
3461  real(DP) :: tp
3462  real(DP) :: bt
3463  real(DP) :: hsfr
3464  real(DP) :: qd
3465  real(DP) :: d1
3466  real(DP) :: sumleak
3467  real(DP) :: sumrch
3468  real(DP) :: gwfhcof
3469  real(DP) :: gwfrhs
3470  !
3471  ! -- Process optional dummy variables
3472  if (present(update)) then
3473  lupdate = update
3474  else
3475  lupdate = .true.
3476  end if
3477 
3478  ! -- initialize variables
3479  hcof = dzero
3480  rhs = dzero
3481  !
3482  if (this%iboundpak(n) == 0) then
3483  this%depth(n) = dzero
3484  this%stage(n) = dhnoflo
3485  this%usflow(n) = dzero
3486  this%simevap(n) = dzero
3487  this%simrunoff(n) = dzero
3488  this%dsflow(n) = dzero
3489  this%gwflow(n) = dzero
3490  else
3491  hgwf = h
3492  d1 = dzero
3493  qsrc = dzero
3494  qgwf = dzero
3495  qd = this%dsflow(n)
3496 
3497  ! -- calculate initial depth assuming a wide cross-section and
3498  ! ignore groundwater leakage
3499  ! -- calculate upstream flow
3500  qu = dzero
3501  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3502  if (this%idir(i) < 0) cycle
3503  n2 = this%ja(i)
3504  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
3505  if (this%idir(ii) > 0) cycle
3506  if (this%ja(ii) /= n) cycle
3507  qu = qu + this%qconn(ii)
3508  end do
3509  end do
3510  this%usflow(n) = qu
3511 
3512  ! -- calculate remaining terms
3513  sa = this%calc_surface_area(n)
3514  sa_wet = this%calc_surface_area_wet(n, this%depth(n))
3515  qi = this%inflow(n)
3516  qr = this%rain(n) * sa
3517  qe = this%evap(n) * sa_wet
3518  qro = this%runoff(n)
3519 
3520  ! -- Water mover term; assume that it goes in at the upstream end of the reach
3521  qfrommvr = dzero
3522  if (this%imover == 1) then
3523  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3524  end if
3525 
3526  ! -- calculate downstream flow ignoring groundwater leakage
3527  qsrc = qu + qi + qr - qe + qro + qfrommvr
3528 
3529  ! -- adjust runoff or evaporation if sum of sources is negative
3530  call this%sfr_adjust_ro_ev(qsrc, qu, qi, qr, qro, qe, qfrommvr)
3531 
3532  ! -- set simulated evaporation and runoff
3533  this%simevap(n) = qe
3534  this%simrunoff(n) = qro
3535 
3536  ! -- calculate reach flow using appropriate method
3537  if (this%iboundpak(n) < 0) then
3538  call this%sfr_calc_constant(n, d1, hgwf, qgwf, qd)
3539  else
3540  if (this%gwfiss == 0 .and. this%istorage == 1) then
3541  if (this%ats_courant /= dnodata) then
3542  call this%sfr_calc_tvd(n, d1, hgwf, qu, qi, &
3543  qfrommvr, qr, qe, qro, &
3544  qgwf, qd)
3545  else
3546  call this%sfr_calc_transient(n, d1, hgwf, qu, qi, &
3547  qfrommvr, qr, qe, qro, &
3548  qgwf, qd)
3549  end if
3550  else
3551  call this%sfr_calc_steady(n, d1, hgwf, qu, qi, &
3552  qfrommvr, qr, qe, qro, &
3553  qgwf, qd)
3554  end if
3555  end if
3556 
3557  ! -- update sfr stage
3558  tp = this%strtop(n)
3559  bt = tp - this%bthick(n)
3560  hsfr = tp + d1
3561 
3562  ! -- update stored values
3563  if (lupdate) then
3564  ! -- save depth and calculate stage
3565  this%depth(n) = d1
3566  this%stage(n) = hsfr
3567  ! -- update flows
3568  call this%sfr_update_flows(n, qd, qgwf)
3569  end if
3570 
3571  ! -- calculate sumleak and sumrch
3572  sumleak = dzero
3573  sumrch = dzero
3574  if (this%gwfiss == 0) then
3575  sumleak = qgwf
3576  else
3577  sumleak = qgwf
3578  end if
3579  if (hgwf < bt) then
3580  sumrch = qgwf
3581  end if
3582 
3583  ! -- make final qgwf calculation and obtain
3584  ! gwfhcof and gwfrhs values
3585  call this%sfr_calc_qgwf(n, d1, hgwf, qgwf, gwfhcof, gwfrhs)
3586 
3587  ! -- update hcof and rhs terms
3588  if (abs(sumleak) > dzero) then
3589  ! -- stream leakage is not head dependent
3590  if (hgwf < bt) then
3591  rhs = rhs - sumrch
3592  ! -- stream leakage is head dependent
3593  else if ((sumleak - qsrc) < -dem30) then
3594  if (this%gwfiss == 0) then
3595  rhs = rhs + gwfrhs - sumrch
3596  else
3597  rhs = rhs + gwfrhs
3598  end if
3599  hcof = gwfhcof
3600  ! -- place holder for UZF
3601  else
3602  if (this%gwfiss == 0) then
3603  rhs = rhs - sumleak - sumrch
3604  else
3605  rhs = rhs - sumleak
3606  end if
3607  end if
3608 
3609  ! -- add groundwater leakage
3610  else if (hgwf < bt) then
3611  rhs = rhs - sumrch
3612  end if
3613  end if

◆ sfr_source_connectiondata()

subroutine sfrmodule::sfr_source_connectiondata ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

1276  ! -- modules
1278  use sparsemodule, only: sparsematrix
1279  ! -- dummy
1280  class(SfrType), intent(inout) :: this !< SfrType object
1281  ! -- local
1282  integer(I4B), dimension(:), pointer, contiguous :: cd_ifno => null()
1283  integer(I4B), dimension(:), pointer, contiguous :: ic_flat => null()
1284  integer(I4B), dimension(:), pointer, contiguous :: cd_ia => null()
1285  type(sparsematrix), pointer :: sparse => null()
1286  integer(I4B), dimension(:), pointer, contiguous :: rowmaxnnz => null()
1287  integer(I4B), allocatable :: nboundchk(:)
1288  integer(I4B), allocatable :: iconndata(:, :)
1289  integer(I4B), allocatable :: iup(:)
1290  integer(I4B), allocatable :: order(:)
1291  type(dag) :: sfr_dag
1292  integer(I4B) :: i, n, j, jj, jcol, jcol2, nja, nconnmax
1293  integer(I4B) :: ival, idir, nup, ipos, istat, ierr, jlocal, nread
1294  !
1295  write (this%iout, '(/1x,a)') &
1296  'PROCESSING '//trim(adjustl(this%text))//' CONNECTIONDATA'
1297  !
1298  ! -- get input context CONNECTIONDATA arrays
1299  call mem_setptr(cd_ifno, 'CONNDATA_IFNO', this%input_mempath)
1300  call mem_setptr(ic_flat, 'IC', this%input_mempath)
1301  call mem_setptr(cd_ia, 'IC_IA', this%input_mempath)
1302  !
1303  ! -- allocate and initialize check array
1304  allocate (nboundchk(this%maxbound))
1305  nboundchk = 0
1306  !
1307  ! -- build rowmaxnnz from nconnreach
1308  nja = 0
1309  nconnmax = 0
1310  allocate (rowmaxnnz(this%maxbound))
1311  do n = 1, this%maxbound
1312  ival = this%nconnreach(n)
1313  if (ival < 0) ival = 0
1314  rowmaxnnz(n) = ival + 1
1315  nja = nja + ival + 1
1316  if (ival > nconnmax) nconnmax = ival
1317  end do
1318  !
1319  ! -- reallocate connection arrays
1320  call mem_reallocate(this%ja, nja, 'JA', this%memoryPath)
1321  call mem_reallocate(this%idir, nja, 'IDIR', this%memoryPath)
1322  call mem_reallocate(this%idiv, nja, 'IDIV', this%memoryPath)
1323  call mem_reallocate(this%qconn, nja, 'QCONN', this%memoryPath)
1324  this%idir = 0
1325  this%idiv = 0
1326  this%qconn = dzero
1327  !
1328  ! -- allocate iconndata
1329  allocate (iconndata(nconnmax, this%maxbound))
1330  iconndata = 0
1331  !
1332  allocate (sparse)
1333  call sparse%init(this%maxbound, this%maxbound, rowmaxnnz)
1334  !
1335  ! -- process connection data rows
1336  do i = 1, this%maxbound
1337  n = this%validate_ifno(cd_ifno(i), this%maxbound, nboundchk, &
1338  'reach', 'CONNECTIONDATA')
1339  if (n == 0) cycle
1340  nread = cd_ia(i + 1) - cd_ia(i)
1341  if (nread /= this%nconnreach(n)) then
1342  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,a)') &
1343  'Reach', n, 'connectiondata specifies', nread, &
1344  'connections but NCON for this reach in packagedata is', &
1345  this%nconnreach(n), '.'
1346  call store_error(errmsg)
1347  cycle
1348  end if
1349  call sparse%addconnection(n, n, 1)
1350  jlocal = 0
1351  do j = cd_ia(i), cd_ia(i + 1) - 1
1352  jlocal = jlocal + 1
1353  ival = ic_flat(j)
1354  iconndata(jlocal, n) = ival
1355  if (ival < 0) then
1356  idir = -1
1357  ival = abs(ival)
1358  else if (ival == 0) then
1359  call store_error('Missing or zero connection reach in connectiondata.')
1360  cycle
1361  else
1362  idir = 1
1363  end if
1364  if (ival > this%maxbound) then
1365  call store_error('Reach number exceeds NREACHES in connectiondata.')
1366  cycle
1367  end if
1368  call sparse%addconnection(n, ival, 1)
1369  end do
1370  end do
1371  !
1372  write (this%iout, '(1x,a)') &
1373  'END OF '//trim(adjustl(this%text))//' CONNECTIONDATA'
1374  !
1375  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1376  'CONNECTIONDATA')
1377  !
1378  if (count_errors() > 0) then
1379  call store_error_filename(this%input_fname)
1380  end if
1381  !
1382  ! -- fill ia and ja from sparse
1383  call sparse%filliaja(this%ia, this%ja, ierr, sort=.true.)
1384  if (ierr /= 0) then
1385  write (errmsg, '(a,3(1x,a))') &
1386  'Could not fill', trim(this%packName), &
1387  'package IA and JA connection data.', &
1388  'Check connectivity data in connectiondata block.'
1389  call store_error(errmsg)
1390  end if
1391  !
1392  ! -- fill flat connection storage with direction
1393  do n = 1, this%maxbound
1394  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1395  jcol = this%ja(j)
1396  do jj = 1, this%nconnreach(n)
1397  jcol2 = iconndata(jj, n)
1398  if (abs(jcol2) == jcol) then
1399  idir = 1
1400  if (jcol2 < 0) idir = -1
1401  this%idir(j) = idir
1402  exit
1403  end if
1404  end do
1405  end do
1406  end do
1407  !
1408  ! -- deallocate temporaries
1409  deallocate (rowmaxnnz)
1410  deallocate (nboundchk)
1411  deallocate (iconndata)
1412  call sparse%destroy()
1413  deallocate (sparse)
1414  !
1415  ! -- compute reach order using DAG
1416  call sfr_dag%set_vertices(this%maxbound)
1417  fill_dag: do n = 1, this%maxbound
1418  nup = 0
1419  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1420  if (this%idir(j) > 0) nup = nup + 1
1421  end do
1422  if (nup == 0) cycle fill_dag
1423  allocate (iup(nup))
1424  ipos = 1
1425  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1426  if (this%idir(j) > 0) then
1427  iup(ipos) = this%ja(j)
1428  ipos = ipos + 1
1429  end if
1430  end do
1431  call sfr_dag%set_edges(n, iup)
1432  deallocate (iup)
1433  end do fill_dag
1434  call sfr_dag%toposort(order, istat)
1435  if (istat == -1) then
1436  write (warnmsg, '(a)') &
1437  trim(adjustl(this%text))//' PACKAGE ('// &
1438  trim(adjustl(this%packName))//') cannot calculate a '// &
1439  'Directed Asyclic Graph for reach connectivity because '// &
1440  'of circular dependency. Using the reach number for '// &
1441  'solution ordering.'
1442  call store_warning(warnmsg)
1443  end if
1444  do n = 1, this%maxbound
1445  if (istat == 0) then
1446  this%isfrorder(n) = order(n)
1447  else
1448  this%isfrorder(n) = n
1449  end if
1450  end do
1451  call sfr_dag%destroy()
1452  if (istat == 0) deallocate (order)
1453  !
1454  ! -- release input context connectiondata memory
1455  call memorystore_release('CONNDATA_IFNO', this%input_mempath)
1456  call memorystore_release('IC', this%input_mempath)
1457  call memorystore_release('IC_IA', this%input_mempath)
Here is the call graph for this function:

◆ sfr_source_crosssections()

subroutine sfrmodule::sfr_source_crosssections ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

1186  ! -- modules
1187  use constantsmodule, only: lenmempath
1191  ! -- dummy
1192  class(SfrType), intent(inout) :: this !< SfrType object
1193  ! -- local
1194  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
1195  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1196  tab6_filename => null()
1197  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1198  sfrtab6_mempaths => null()
1199  type(SfrCrossSection), pointer :: cross_data => null()
1200  integer(I4B) :: i, n, ncrossptstot
1201  integer(I4B), allocatable :: nboundchk(:)
1202  integer(I4B) :: isize
1203  character(len=LINELENGTH) :: tabfname
1204  character(len=LENMEMPATH) :: mempath
1205  !
1206  ! -- check if CROSSSECTIONS block was loaded (optional block)
1207  call get_isize('CROSSSECT_IFNO', this%input_mempath, isize)
1208  if (isize < 1) return
1209  !
1210  write (this%iout, '(/1x,a)') &
1211  'PROCESSING '//trim(adjustl(this%text))//' CROSSSECTIONS'
1212  !
1213  ! -- get input context arrays
1214  call mem_setptr(ifno, 'CROSSSECT_IFNO', this%input_mempath)
1215  call mem_setptr(tab6_filename, 'SFRTAB6_FILENAME', this%input_mempath)
1216  call mem_setptr(sfrtab6_mempaths, 'SFRTAB6_MEMPATH', this%input_mempath)
1217  !
1218  ! -- create cross-section object
1219  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1220  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1221  this%iacross, this%station, this%xsheight, &
1222  this%xsrough)
1223  !
1224  allocate (nboundchk(this%maxbound))
1225  nboundchk = 0
1226  !
1227  do i = 1, isize
1228  n = this%validate_ifno(ifno(i), this%maxbound, nboundchk, &
1229  'reach', 'CROSSSECTIONS')
1230  if (n == 0) cycle
1231  tabfname = tab6_filename(i)
1232  mempath = sfrtab6_mempaths(i)
1233  call cross_data%source_table(n, this%width(n), mempath, &
1234  trim(adjustl(tabfname)))
1235  end do
1236  !
1237  write (this%iout, '(1x,a)') &
1238  'END OF '//trim(adjustl(this%text))//' CROSSSECTIONS'
1239  !
1240  ! -- CROSSSECTIONS is optional; only duplicates are reported
1241  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1242  'CROSSSECTIONS', check_missing=.false.)
1243  deallocate (nboundchk)
1244  !
1245  if (count_errors() > 0) then
1246  call store_error_filename(this%input_fname)
1247  end if
1248  !
1249  ! -- reallocate cross-section arrays if needed
1250  ncrossptstot = cross_data%get_ncrossptstot()
1251  if (ncrossptstot /= this%ncrossptstot) then
1252  this%ncrossptstot = ncrossptstot
1253  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1254  this%memoryPath)
1255  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1256  this%memoryPath)
1257  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1258  this%memoryPath)
1259  end if
1260  !
1261  call cross_data%output(this%width, this%rough)
1262  call cross_data%pack(this%ncrossptstot, this%ncrosspts, this%iacross, &
1263  this%station, this%xsheight, this%xsrough)
1264  call cross_data%destroy()
1265  deallocate (cross_data)
1266  nullify (cross_data)
1267  !
1268  ! -- release input context crosssections memory
1269  call memorystore_release('CROSSSECT_IFNO', this%input_mempath)
1270  call memorystore_release('SFRTAB6_FILENAME', this%input_mempath)
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
Here is the call graph for this function:

◆ sfr_source_dimensions()

subroutine sfrmodule::sfr_source_dimensions ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

940  ! -- modules
942  ! -- dummy
943  class(SfrType), intent(inout) :: this !< SfrType object
944  ! -- local
945  logical(LGP) :: found
946  !
947  ! -- initialize dimensions to 0
948  this%maxbound = 0
949  !
950  write (this%iout, '(/1x,a)') &
951  'PROCESSING '//trim(adjustl(this%text))//' DIMENSIONS'
952  !
953  ! -- source NREACHES
954  call mem_set_value(this%maxbound, 'MAXBOUND', this%input_mempath, found, &
955  release=.false.)
956  if (found) then
957  write (this%iout, '(4x,a,i0)') 'NREACHES = ', this%maxbound
958  end if
959  !
960  write (this%iout, '(1x,a)') &
961  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
962  !
963  if (this%maxbound < 1) then
964  write (errmsg, '(a)') &
965  'NREACHES was not specified or was specified incorrectly.'
966  call store_error(errmsg)
967  call store_error_filename(this%input_fname)
968  end if
969  !
970  ! -- set npakeq (SFR adds no extra equations)
971  this%npakeq = 0
972  !
973  ! -- define the default label
974  call this%define_listlabel()
975  !
976  ! -- define default cross-section data size
977  this%ncrossptstot = this%maxbound
978  !
979  ! -- allocate arrays
980  call this%sfr_allocate_arrays()
981  !
982  ! -- source packagedata
983  call this%sfr_source_packagedata()
984  !
985  ! -- source crosssections
986  call this%sfr_source_crosssections()
987  !
988  ! -- source connectiondata
989  call this%sfr_source_connectiondata()
990  !
991  ! -- source diversions
992  call this%sfr_source_diversions()
993  !
994  ! -- alias deprecated variable names
995  call this%sfr_checkin_deprecated_names()
996  !
997  ! -- source initialstages
998  call this%sfr_source_initialstages()
999  !
1000  ! -- setup the budget object
1001  call this%sfr_setup_budobj()
1002  !
1003  ! -- setup the stage table object
1004  call this%sfr_setup_tableobj()
Here is the call graph for this function:

◆ sfr_source_diversions()

subroutine sfrmodule::sfr_source_diversions ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

1463  ! -- modules
1466  ! -- dummy
1467  class(SfrType), intent(inout) :: this !< SfrType object
1468  ! -- local
1469  integer(I4B), dimension(:), pointer, contiguous :: d_ifno => null()
1470  integer(I4B), dimension(:), pointer, contiguous :: d_idv => null()
1471  integer(I4B), dimension(:), pointer, contiguous :: d_iconr => null()
1472  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1473  d_cprior => null()
1474  integer(I4B) :: i, n, idiv, ndiversions, i0, ipos, jpos
1475  integer(I4B) :: isize
1476  integer(I4B), allocatable :: iachk(:), nboundchk(:)
1477  character(len=16) :: cval
1478  !
1479  ! -- build iadiv and count total diversions
1480  ndiversions = 0
1481  i0 = 1
1482  this%iadiv(1) = i0
1483  do n = 1, this%maxbound
1484  ndiversions = ndiversions + this%ndiv(n)
1485  i0 = i0 + this%ndiv(n)
1486  this%iadiv(n + 1) = i0
1487  end do
1488  !
1489  ! -- reallocate diversion arrays
1490  if (ndiversions > 0) then
1491  call mem_reallocate(this%divreach, ndiversions, 'DIVREACH', &
1492  this%memoryPath)
1493  allocate (this%divcprior(ndiversions))
1494  call mem_setptr(this%divflow, 'DIVFLOW', this%input_mempath)
1495  call mem_reallocate(this%divq, ndiversions, 'DIVQ', this%memoryPath)
1496  this%divq = dzero
1497  end if
1498  !
1499  ! -- check if DIVERSIONS block was loaded (optional block)
1500  call get_isize('DIVERSIONS_IFNO', this%input_mempath, isize)
1501  if (isize < 1) then
1502  if (this%idiversions /= 0) then
1503  call store_error('REQUIRED DIVERSIONS BLOCK NOT FOUND.')
1504  call store_error_filename(this%input_fname)
1505  end if
1506  return
1507  end if
1508  !
1509  if (this%idiversions == 0) then
1510  write (errmsg, '(a,1x,a)') &
1511  'A diversions block should not be', &
1512  'specified if diversions are not specified.'
1513  call store_error(errmsg)
1514  call store_error_filename(this%input_fname)
1515  return
1516  end if
1517  !
1518  write (this%iout, '(/1x,a)') &
1519  'PROCESSING '//trim(adjustl(this%text))//' DIVERSIONS'
1520  !
1521  ! -- get input context arrays
1522  call mem_setptr(d_ifno, 'DIVERSIONS_IFNO', this%input_mempath)
1523  call mem_setptr(d_idv, 'DIVERSIONS_IDV', this%input_mempath)
1524  call mem_setptr(d_iconr, 'ICONR', this%input_mempath)
1525  call mem_setptr(d_cprior, 'CPRIOR', this%input_mempath)
1526  !
1527  ! -- build check arrays
1528  allocate (iachk(this%maxbound + 1))
1529  allocate (nboundchk(ndiversions))
1530  nboundchk = 0
1531  iachk(1) = 1
1532  do n = 1, this%maxbound
1533  iachk(n + 1) = iachk(n) + this%ndiv(n)
1534  end do
1535  !
1536  do i = 1, isize
1537  n = d_ifno(i)
1538  if (n < 1 .or. n > this%maxbound) then
1539  write (errmsg, '(a,i0,a)') 'Reach number should be between 1 and ', &
1540  this%maxbound, '.'
1541  call store_error(errmsg)
1542  cycle
1543  end if
1544  if (this%ndiv(n) < 1) then
1545  write (errmsg, '(a,i0)') &
1546  'Diversions cannot be specified for reach ', n
1547  call store_error(errmsg)
1548  cycle
1549  end if
1550  idiv = d_idv(i)
1551  if (idiv < 1 .or. idiv > this%ndiv(n)) then
1552  write (errmsg, '(a,i0,a,i0,a)') &
1553  'Reach ', n, ' diversion number should be between 1 and ', &
1554  this%ndiv(n), '.'
1555  call store_error(errmsg)
1556  cycle
1557  end if
1558  ipos = iachk(n) + idiv - 1
1559  nboundchk(ipos) = nboundchk(ipos) + 1
1560  jpos = this%iadiv(n) + idiv - 1
1561  if (d_iconr(i) < 1 .or. d_iconr(i) > this%maxbound) then
1562  write (errmsg, '(a,i0,a)') &
1563  'Diversion target reach number should be between 1 and ', &
1564  this%maxbound, '.'
1565  call store_error(errmsg)
1566  cycle
1567  end if
1568  this%divreach(jpos) = d_iconr(i)
1569  cval = d_cprior(i)
1570  select case (trim(cval))
1571  case ('UPTO', 'THRESHOLD', 'FRACTION', 'EXCESS')
1572  case default
1573  errmsg = 'Invalid cprior type '//trim(cval)//'.'
1574  call store_error(errmsg)
1575  end select
1576  this%divcprior(jpos) = trim(cval)
1577  end do
1578  !
1579  write (this%iout, '(1x,a)') &
1580  'END OF '//trim(adjustl(this%text))//' DIVERSIONS'
1581  !
1582  do n = 1, this%maxbound
1583  do idiv = 1, this%ndiv(n)
1584  ipos = iachk(n) + idiv - 1
1585  if (nboundchk(ipos) == 0) then
1586  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1587  'No data specified for reach', n, 'diversion', idiv
1588  call store_error(errmsg)
1589  else if (nboundchk(ipos) > 1) then
1590  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1591  'Data for reach', n, 'diversion', idiv, &
1592  'specified', nboundchk(ipos), 'times'
1593  call store_error(errmsg)
1594  end if
1595  end do
1596  end do
1597  deallocate (iachk)
1598  deallocate (nboundchk)
1599  !
1600  if (count_errors() > 0) then
1601  call store_error_filename(this%input_fname)
1602  end if
1603  !
1604  ! -- release input context diversions memory; DIVFLOW excluded
1605  call memorystore_release('DIVERSIONS_IFNO', this%input_mempath)
1606  call memorystore_release('DIVERSIONS_IDV', this%input_mempath)
1607  call memorystore_release('ICONR', this%input_mempath)
1608  call memorystore_release('CPRIOR', this%input_mempath)
Here is the call graph for this function:

◆ sfr_source_initialstages()

subroutine sfrmodule::sfr_source_initialstages ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

1614  ! -- modules
1616  ! -- dummy
1617  class(SfrType), intent(inout) :: this !< SfrType object
1618  ! -- local
1619  integer(I4B), dimension(:), pointer, contiguous :: is_ifno => null()
1620  real(DP), dimension(:), pointer, contiguous :: is_stage => null()
1621  integer(I4B) :: i, n
1622  integer(I4B) :: isize
1623  integer(I4B), allocatable :: nboundchk(:)
1624  real(DP) :: rval
1625  !
1626  ! -- check if INITIALSTAGES block was loaded (optional block)
1627  call get_isize('INITSTAGE_IFNO', this%input_mempath, isize)
1628  if (isize < 1) then
1629  ! -- set default initial stage to reach top if STORAGE active
1630  if (this%istorage == 1) then
1631  do n = 1, this%maxbound
1632  this%stage(n) = this%strtop(n)
1633  end do
1634  end if
1635  return
1636  end if
1637  !
1638  write (this%iout, '(/1x,a)') &
1639  'PROCESSING '//trim(adjustl(this%text))//' INITIALSTAGES'
1640  !
1641  call mem_setptr(is_ifno, 'INITSTAGE_IFNO', this%input_mempath)
1642  call mem_setptr(is_stage, 'INITIALSTAGE', this%input_mempath)
1643  !
1644  allocate (nboundchk(this%maxbound))
1645  nboundchk = 0
1646  !
1647  do i = 1, isize
1648  n = this%validate_ifno(is_ifno(i), this%maxbound, nboundchk, &
1649  'reach', 'INITIALSTAGES')
1650  if (n == 0) cycle
1651  rval = is_stage(i)
1652  this%stage(n) = rval
1653  this%depth(n) = rval - this%strtop(n)
1654  if (rval < this%strtop(n)) then
1655  write (errmsg, '(a,g0,a,1x,i0,1x,a,g0,a)') &
1656  'Initial stage (', rval, ') for reach', n, &
1657  'is less than the reach top (', this%strtop(n), ').'
1658  call store_error(errmsg)
1659  end if
1660  end do
1661  !
1662  write (this%iout, '(1x,a)') &
1663  'END OF '//trim(adjustl(this%text))//' INITIALSTAGES'
1664  !
1665  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1666  'INITIALSTAGES')
1667  deallocate (nboundchk)
1668  !
1669  if (count_errors() > 0) then
1670  call store_error_filename(this%input_fname)
1671  end if
1672  !
1673  ! -- release input context initialstages memory
1674  call memorystore_release('INITSTAGE_IFNO', this%input_mempath)
1675  call memorystore_release('INITIALSTAGE', this%input_mempath)
Here is the call graph for this function:

◆ sfr_source_options()

subroutine sfrmodule::sfr_source_options ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

756  ! -- modules
757  use memorymanagermodule, only: get_isize
760  use openspecmodule, only: access, form
761  ! -- dummy
762  class(SfrType), intent(inout) :: this !< SfrType object
763  ! -- local
764  character(len=LINELENGTH) :: fname
765  logical(LGP) :: found
766  ! -- formats
767  character(len=*), parameter :: fmtpicard = &
768  &"(4x, 'MAXIMUM SFR PICARD ITERATION VALUE (',i0,') SPECIFIED.')"
769  character(len=*), parameter :: fmtiter = &
770  &"(4x, 'MAXIMUM SFR ITERATION VALUE (',i0,') SPECIFIED.')"
771  character(len=*), parameter :: fmtdmaxchg = &
772  &"(4x, 'MAXIMUM DEPTH CHANGE VALUE (',g0,') SPECIFIED.')"
773  character(len=*), parameter :: fmtlengthconv = &
774  &"(4x, 'LENGTH CONVERSION VALUE (',g0,') SPECIFIED.')"
775  character(len=*), parameter :: fmttimeconv = &
776  &"(4x, 'TIME CONVERSION VALUE (',g0,') SPECIFIED.')"
777  character(len=*), parameter :: fmtstoweight = &
778  &"(4x, 'KINEMATIC STORAGE WEIGHT (',g0,') SPECIFIED.')"
779  character(len=*), parameter :: fmtsfrbin = &
780  "(4x, 'SFR ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', a, /4x, &
781  &'OPENED ON UNIT: ', I0)"
782  integer(I4B) :: isize
783  !
784  ! -- source base BndExtType options (NAUX, BOUNDNAMES, PRINT_INPUT, etc.)
785  call this%BndExtType%source_options()
786  !
787  write (this%iout, '(/1x,a)') &
788  'PROCESSING '//trim(adjustl(this%text))//' OPTIONS'
789  !
790  ! -- STORAGE
791  call mem_set_value(this%istorage, 'STORAGE', this%input_mempath, found)
792  if (found) then
793  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
794  ' REACH STORAGE IS ACTIVE.'
795  end if
796  !
797  ! -- ATS_COURANT
798  call mem_set_value(this%ats_courant, 'ATS_COURANT', &
799  this%input_mempath, found)
800  if (found) then
801  if (this%ats_courant <= dzero) then
802  write (errmsg, '(a,g0,a)') &
803  "ATS_COURANT SPECIFIED TO BE '", this%ats_courant, &
804  "' BUT MUST BE GREATER THAN ZERO"
805  call store_error(errmsg)
806  call store_error_filename(this%input_fname)
807  else
808  write (this%iout, '(4x,a,1pg15.6)') &
809  'TARGET COURANT NUMBER FOR ADAPTIVE TIME STEPS: ', &
810  this%ats_courant
811  end if
812  end if
813  !
814  ! -- PRINT_STAGE
815  call mem_set_value(this%iprhed, 'PRINT_STAGE', this%input_mempath, found)
816  if (found) then
817  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
818  ' STAGES WILL BE PRINTED TO LISTING FILE.'
819  end if
820  !
821  ! -- STAGEFILE
822  call mem_set_value(fname, 'STAGEFILE', this%input_mempath, found)
823  if (found) then
824  this%istageout = getunit()
825  call openfile(this%istageout, this%iout, fname, 'DATA(BINARY)', &
826  form, access, 'REPLACE', mnormal)
827  write (this%iout, fmtsfrbin) 'STAGE', trim(fname), this%istageout
828  end if
829  !
830  ! -- BUDGETFILE
831  call mem_set_value(fname, 'BUDGETFILE', this%input_mempath, found)
832  if (found) then
833  call assign_iounit(this%ibudgetout, this%inunit, 'BUDGET fileout')
834  call openfile(this%ibudgetout, this%iout, fname, 'DATA(BINARY)', &
835  form, access, 'REPLACE', mnormal)
836  write (this%iout, fmtsfrbin) 'BUDGET', trim(fname), this%ibudgetout
837  end if
838  !
839  ! -- BUDGETCSVFILE
840  call mem_set_value(fname, 'BUDGETCSVFILE', this%input_mempath, found)
841  if (found) then
842  call assign_iounit(this%ibudcsv, this%inunit, 'BUDGETCSV fileout')
843  call openfile(this%ibudcsv, this%iout, fname, 'CSV', &
844  filstat_opt='REPLACE')
845  write (this%iout, fmtsfrbin) 'BUDGET CSV', trim(fname), this%ibudcsv
846  end if
847  !
848  ! -- PACKAGE_CONVERGENCE_FILENAME (mf6internal: pkgconvfname)
849  call mem_set_value(fname, 'PKGCONVFNAME', this%input_mempath, found)
850  if (found) then
851  this%ipakcsv = getunit()
852  call openfile(this%ipakcsv, this%iout, fname, 'CSV', &
853  filstat_opt='REPLACE', mode_opt=mnormal)
854  write (this%iout, fmtsfrbin) 'PACKAGE_CONVERGENCE', trim(fname), &
855  this%ipakcsv
856  end if
857  !
858  ! -- MOVER
859  call mem_set_value(this%imover, 'MOVER', this%input_mempath, found)
860  if (found) then
861  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
862  end if
863  !
864  ! -- MAXIMUM_PICARD_ITERATIONS (mf6internal: maxsfrpicard)
865  call mem_set_value(this%maxsfrpicard, 'MAXSFRPICARD', &
866  this%input_mempath, found)
867  if (found) write (this%iout, fmtpicard) this%maxsfrpicard
868  !
869  ! -- MAXIMUM_ITERATIONS (mf6internal: maxsfrit)
870  call mem_set_value(this%maxsfrit, 'MAXSFRIT', &
871  this%input_mempath, found)
872  if (found) write (this%iout, fmtiter) this%maxsfrit
873  !
874  ! -- MAXIMUM_DEPTH_CHANGE (mf6internal: dmaxchg)
875  call mem_set_value(this%dmaxchg, 'DMAXCHG', &
876  this%input_mempath, found)
877  if (found) then
878  this%deps = dp999 * this%dmaxchg
879  write (this%iout, fmtdmaxchg) this%dmaxchg
880  end if
881  !
882  ! -- LENGTH_CONVERSION (mf6internal: lengthconv)
883  call mem_set_value(this%lengthconv, 'LENGTHCONV', &
884  this%input_mempath, found)
885  if (found) write (this%iout, fmtlengthconv) this%lengthconv
886  !
887  ! -- TIME_CONVERSION
888  call mem_set_value(this%timeconv, 'TIME_CONVERSION', &
889  this%input_mempath, found)
890  if (found) write (this%iout, fmttimeconv) this%timeconv
891  !
892  ! -- UNIT_CONVERSION (deprecated)
893  call mem_set_value(this%unitconv, 'UNIT_CONVERSION', &
894  this%input_mempath, found)
895  if (found) then
896  write (warnmsg, '(a)') 'SETTING UNIT_CONVERSION DIRECTLY'
897  call deprecation_warning('OPTIONS', 'UNIT_CONVERSION', '6.4.2', &
898  warnmsg, this%inunit)
899  end if
900  !
901  ! -- DEV_STORAGE_WEIGHT (mf6internal: storage_weight)
902  call mem_set_value(this%storage_weight, 'STORAGE_WEIGHT', &
903  this%input_mempath, found)
904  if (found) then
905  if (this%storage_weight < dhalf .or. this%storage_weight > done) then
906  write (errmsg, '(a,g0,a)') &
907  "STORAGE_WEIGHT SPECIFIED TO BE '", this%storage_weight, &
908  "' BUT CANNOT BE LESS THAN 0.5 OR GREATER THAN 1.0"
909  call store_error(errmsg)
910  call store_error_filename(this%input_fname)
911  else
912  write (this%iout, fmtstoweight) this%storage_weight
913  end if
914  end if
915  !
916  ! -- DEV_NO_CHECK (mf6internal: icheck)
917  call get_isize('ICHECK', this%input_mempath, isize)
918  if (isize > 0) then
919  this%icheck = 0
920  write (this%iout, '(4x,a)') &
921  'REACH GEOMETRY AND PARAMETER CHECKS WILL NOT BE MADE'
922  end if
923  !
924  ! -- DEV_NO_FINAL_CHECK (mf6internal: iconvchk)
925  call get_isize('ICONVCHK', this%input_mempath, isize)
926  if (isize > 0) then
927  this%iconvchk = 0
928  write (this%iout, '(4x,a)') &
929  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN STREAM FLOW ROUTING '// &
930  'STAGES AND FLOWS WILL NOT BE MADE'
931  end if
932  !
933  write (this%iout, '(1x,a)') &
934  'END OF '//trim(adjustl(this%text))//' OPTIONS'
subroutine, public assign_iounit(iounit, errunit, description)
@ brief assign io unit number
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
Here is the call graph for this function:

◆ sfr_source_packagedata()

subroutine sfrmodule::sfr_source_packagedata ( class(sfrtype), intent(inout)  this)
Parameters
[in,out]thisSfrType object

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

1010  ! -- modules
1011  use memorymanagermodule, only: mem_setptr
1013  ! -- dummy
1014  class(SfrType), intent(inout) :: this !< SfrType object
1015  ! -- local
1016  integer(I4B) :: i, n, nconzero
1017  integer(I4B) :: ipos
1018  character(len=10) :: cnum
1019  character(len=LENBOUNDNAME) :: bndName
1020  character(len=LINELENGTH) :: cellid_str
1021  integer(I4B), allocatable :: nboundchk(:)
1022  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
1023  integer(I4B), dimension(:, :), pointer, contiguous :: cellid => null()
1024  real(DP), dimension(:), pointer, contiguous :: rlen => null()
1025  real(DP), dimension(:), pointer, contiguous :: rwid => null()
1026  real(DP), dimension(:), pointer, contiguous :: rgrd => null()
1027  real(DP), dimension(:), pointer, contiguous :: rtp => null()
1028  real(DP), dimension(:), pointer, contiguous :: rbth => null()
1029  integer(I4B), dimension(:), pointer, contiguous :: ncon => null()
1030  integer(I4B), dimension(:), pointer, contiguous :: ndv => null()
1031  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1032  boundname => null()
1033  integer(I4B), dimension(:, :), pointer, contiguous :: tslink => null()
1034  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1035  tslinkvars => null()
1036  !
1037  write (this%iout, '(/1x,a)') &
1038  'PROCESSING '//trim(adjustl(this%text))//' PACKAGEDATA'
1039  !
1040  ! -- get input context PACKAGEDATA column arrays
1041  call mem_setptr(ifno, 'PACKAGEDATA_IFNO', this%input_mempath)
1042  call mem_setptr(cellid, 'CELLID', this%input_mempath)
1043  call mem_setptr(rlen, 'RLEN', this%input_mempath)
1044  call mem_setptr(rwid, 'RWID', this%input_mempath)
1045  call mem_setptr(rgrd, 'RGRD', this%input_mempath)
1046  call mem_setptr(rtp, 'RTP', this%input_mempath)
1047  call mem_setptr(rbth, 'RBTH', this%input_mempath)
1048  call mem_setptr(this%input%rhk, 'RHK', this%input_mempath)
1049  call mem_setptr(this%input%man, 'MAN', this%input_mempath)
1050  call mem_setptr(ncon, 'NCON', this%input_mempath)
1051  call mem_setptr(this%input%ustrf, 'USTRF', this%input_mempath)
1052  call mem_setptr(tslink, 'TSLINK_PD', this%input_mempath)
1053  call mem_setptr(tslinkvars, 'TSLINKVARS_PD', this%input_mempath)
1054  do n = 1, size(tslinkvars)
1055  if (tslinkvars(n) == 'RHK') this%input%rhk_tslink => tslink(n, :)
1056  if (tslinkvars(n) == 'MAN') this%input%man_tslink => tslink(n, :)
1057  if (tslinkvars(n) == 'USTRF') this%input%ustrf_tslink => tslink(n, :)
1058  end do
1059  if (.not. (associated(this%input%rhk_tslink) .and. &
1060  associated(this%input%man_tslink) .and. &
1061  associated(this%input%ustrf_tslink))) then
1062  call store_error('Time series links for RHK, MAN and USTRF not found &
1063  &in input.')
1064  call store_error_filename(this%input_fname)
1065  end if
1066  call mem_setptr(ndv, 'NDV', this%input_mempath)
1067  if (this%inamedbound /= 0) then
1068  call mem_setptr(boundname, 'BOUNDNAME', this%input_mempath)
1069  end if
1070  !
1071  ! -- allocate check array
1072  allocate (nboundchk(this%maxbound))
1073  nboundchk = 0
1074  nconzero = 0
1075  !
1076  ! -- populate reach data from input context arrays
1077  do i = 1, this%maxbound
1078  n = ifno(i)
1079  !
1080  n = this%validate_ifno(n, this%maxbound, nboundchk, &
1081  'rno', 'PACKAGEDATA')
1082  if (n == 0) cycle
1083  !
1084  ! -- cellid → igwfnode: convert integer cellid array to string
1085  ! -- all-zero or negative cellid means unconnected reach (NONE keyword or 0 0 0)
1086  if (all(cellid(1:this%dis%ndim, i) <= 0)) then
1087  this%igwfnode(n) = 0
1088  else
1089  write (cellid_str, '(10(i0,1x))') cellid(1:this%dis%ndim, i)
1090  this%igwfnode(n) = this%dis%noder_from_cellid(cellid_str, &
1091  this%inunit, this%iout, &
1092  flag_string=.false., &
1093  allow_zero=.true.)
1094  end if
1095  this%igwftopnode(n) = this%igwfnode(n)
1096  if (this%igwfnode(n) < 1) this%ianynone = this%ianynone + 1
1097  !
1098  ! -- scalar reach properties
1099  this%length(n) = rlen(i)
1100  this%width(n) = rwid(i)
1101  this%slope(n) = rgrd(i)
1102  this%strtop(n) = rtp(i)
1103  this%bthick(n) = rbth(i)
1104  !
1105  ! -- ncon and nconn
1106  this%nconnreach(n) = ncon(i)
1107  this%nconn = this%nconn + ncon(i)
1108  if (ncon(i) < 0) then
1109  write (errmsg, '(a,1x,i0,1x,a,i0,a)') &
1110  'NCON for reach', n, &
1111  'must be greater than or equal to 0 (', ncon(i), ').'
1112  call store_error(errmsg)
1113  else if (ncon(i) == 0) then
1114  nconzero = nconzero + 1
1115  end if
1116  !
1117  ! -- ndv (diversions)
1118  this%ndiv(n) = ndv(i)
1119  if (ndv(i) > 0) this%idiversions = 1
1120  !
1121  ! -- bound name
1122  write (cnum, '(i10.10)') n
1123  bndname = 'Reach'//cnum
1124  if (this%inamedbound /= 0) then
1125  bndname = boundname(i)
1126  end if
1127  this%sfrname(n) = bndname
1128  !
1129  ! -- hk, roughness (Manning), upstream fraction: copied from
1130  ! input context; sfr_ad re-syncs TS-linked values each timestep
1131  this%hk(n) = this%input%rhk(i)
1132  this%rough(n) = this%input%man(i)
1133  this%ustrf(n) = this%input%ustrf(i)
1134  !
1135  ! -- initialize sstage to reach top
1136  this%sstage(n) = this%strtop(n)
1137  end do
1138  !
1139  write (this%iout, '(1x,a)') &
1140  'END OF '//trim(adjustl(this%text))//' PACKAGEDATA'
1141  !
1142  ! -- check every reach is specified exactly once
1143  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1144  'PACKAGEDATA')
1145  deallocate (nboundchk)
1146  !
1147  if (nconzero > 0) then
1148  write (warnmsg, '(a,1x,a,1x,a,1x,i0,1x,a)') &
1149  'SFR Package', trim(this%packName), &
1150  'has', nconzero, 'reach(es) with zero connections.'
1151  call store_warning(warnmsg)
1152  end if
1153  !
1154  if (count_errors() > 0) then
1155  call store_error_filename(this%input_fname)
1156  end if
1157  !
1158  ! -- initialize default cross-section data
1159  ipos = 1
1160  this%iacross(1) = ipos
1161  do i = 1, this%maxbound
1162  this%ncrosspts(i) = 1
1163  this%station(ipos) = this%width(i)
1164  this%xsheight(ipos) = dzero
1165  this%xsrough(ipos) = done
1166  ipos = ipos + 1
1167  this%iacross(i + 1) = ipos
1168  end do
1169  !
1170  ! -- release input context packagedata memory; PACKAGEDATA_IFNO excluded
1171  ! (allocate_featureauxvar); RHK/MAN/USTRF excluded
1172  call memorystore_release('CELLID', this%input_mempath)
1173  call memorystore_release('RLEN', this%input_mempath)
1174  call memorystore_release('RWID', this%input_mempath)
1175  call memorystore_release('RGRD', this%input_mempath)
1176  call memorystore_release('RTP', this%input_mempath)
1177  call memorystore_release('RBTH', this%input_mempath)
1178  call memorystore_release('NCON', this%input_mempath)
1179  call memorystore_release('NDV', this%input_mempath)
1180  call memorystore_release('BOUNDNAME', this%input_mempath)
Here is the call graph for this function:

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

3622  ! -- dummy
3623  class(SfrType), intent(inout) :: this !< SfrType object
3624  integer(I4B), intent(in) :: n !< reach number
3625  real(DP), intent(inout) :: qd !< downstream reach flow
3626  real(DP), intent(in) :: qgwf !< groundwater leakage for reach
3627  ! -- local
3628  integer(I4B) :: i
3629  integer(I4B) :: n2
3630  integer(I4B) :: idiv
3631  integer(I4B) :: jpos
3632  real(DP) :: qdiv
3633  real(DP) :: f
3634  !
3635  ! -- update reach terms
3636  !
3637  ! -- save final downstream stream flow
3638  this%dsflow(n) = qd
3639  !
3640  ! -- save groundwater leakage
3641  this%gwflow(n) = qgwf
3642  !
3643  ! -- route downstream flow
3644  if (qd > dzero) then
3645  !
3646  ! -- route water to diversions
3647  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3648  if (this%idir(i) > 0) cycle
3649  idiv = this%idiv(i)
3650  if (idiv == 0) cycle
3651  jpos = this%iadiv(n) + idiv - 1
3652  call this%sfr_calc_div(n, idiv, qd, qdiv)
3653  this%qconn(i) = qdiv
3654  this%divq(jpos) = qdiv
3655  end do
3656  !
3657  ! -- Mover terms: store outflow after diversion loss
3658  ! as qformvr and reduce outflow (qd)
3659  ! by how much was actually sent to the mover
3660  if (this%imover == 1) then
3661  call this%pakmvrobj%accumulate_qformvr(n, qd)
3662  qd = max(qd - this%pakmvrobj%get_qtomvr(n), dzero)
3663  end if
3664  !
3665  ! -- route remaining water to downstream reaches
3666  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3667  if (this%idir(i) > 0) cycle
3668  if (this%idiv(i) > 0) cycle
3669  n2 = this%ja(i)
3670  if (this%iboundpak(n2) == 0) cycle
3671  f = this%ustrf(n2) / this%ftotnd(n)
3672  this%qconn(i) = qd * f
3673  end do
3674  else
3675  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3676  if (this%idir(i) > 0) cycle
3677  this%qconn(i) = dzero
3678  idiv = this%idiv(i)
3679  if (idiv == 0) cycle
3680  jpos = this%iadiv(n) + idiv - 1
3681  this%divq(jpos) = dzero
3682  end do
3683  end if

Variable Documentation

◆ ftype

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

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

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

◆ text

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

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

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