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

5464  ! -- return variable
5465  real(DP) :: calc_area_wet !< wetted area
5466  ! -- dummy
5467  class(SfrType) :: this !< SfrType object
5468  integer(I4B), intent(in) :: n !< reach number
5469  real(DP), intent(in) :: depth !< reach depth
5470  ! -- local
5471  integer(I4B) :: npts
5472  integer(I4B) :: i0
5473  integer(I4B) :: i1
5474  !
5475  ! -- Calculate wetted area
5476  npts = this%ncrosspts(n)
5477  i0 = this%iacross(n)
5478  i1 = this%iacross(n + 1) - 1
5479  if (npts > 1) then
5480  calc_area_wet = get_cross_section_area(npts, this%station(i0:i1), &
5481  this%xsheight(i0:i1), depth)
5482  else
5483  calc_area_wet = this%station(i0) * depth
5484  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 5491 of file gwf-sfr.f90.

5492  ! -- return variable
5493  real(DP) :: calc_perimeter_wet !< wetted perimeter
5494  ! -- dummy
5495  class(SfrType) :: this !< SfrType object
5496  integer(I4B), intent(in) :: n !< reach number
5497  real(DP), intent(in) :: depth !< reach depth
5498  ! -- local
5499  integer(I4B) :: npts
5500  integer(I4B) :: i0
5501  integer(I4B) :: i1
5502  !
5503  ! -- Calculate wetted perimeter
5504  npts = this%ncrosspts(n)
5505  i0 = this%iacross(n)
5506  i1 = this%iacross(n + 1) - 1
5507  if (npts > 1) then
5508  calc_perimeter_wet = get_wetted_perimeter(npts, this%station(i0:i1), &
5509  this%xsheight(i0:i1), depth)
5510  else
5511  calc_perimeter_wet = this%station(i0) ! no depth dependence in original implementation
5512  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 5519 of file gwf-sfr.f90.

5520  ! -- return variable
5521  real(DP) :: calc_surface_area !< surface area
5522  ! -- dummy
5523  class(SfrType) :: this !< SfrType object
5524  integer(I4B), intent(in) :: n !< reach number
5525  ! -- local
5526  integer(I4B) :: npts
5527  integer(I4B) :: i0
5528  integer(I4B) :: i1
5529  real(DP) :: top_width
5530  !
5531  ! -- Calculate surface area
5532  npts = this%ncrosspts(n)
5533  i0 = this%iacross(n)
5534  i1 = this%iacross(n + 1) - 1
5535  if (npts > 1) then
5536  top_width = get_saturated_topwidth(npts, this%station(i0:i1))
5537  else
5538  top_width = this%station(i0)
5539  end if
5540  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 5547 of file gwf-sfr.f90.

5548  ! -- return variable
5549  real(DP) :: calc_surface_area_wet !< wetted surface area
5550  ! -- dummy
5551  class(SfrType) :: this !< SfrType object
5552  integer(I4B), intent(in) :: n !< reach number
5553  real(DP), intent(in) :: depth !< reach depth
5554  ! -- local
5555  real(DP) :: top_width
5556  !
5557  ! -- Calculate wetted surface area
5558  top_width = this%calc_top_width_wet(n, depth)
5559  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 5566 of file gwf-sfr.f90.

5567  ! -- return variable
5568  real(DP) :: calc_top_width_wet !< wetted top width
5569  ! -- dummy
5570  class(SfrType) :: this !< SfrType object
5571  integer(I4B), intent(in) :: n !< reach number
5572  real(DP), intent(in) :: depth !< reach depth
5573  ! -- local
5574  integer(I4B) :: npts
5575  integer(I4B) :: i0
5576  integer(I4B) :: i1
5577  real(DP) :: sat
5578  !
5579  ! -- Calculate wetted top width
5580  npts = this%ncrosspts(n)
5581  i0 = this%iacross(n)
5582  i1 = this%iacross(n + 1) - 1
5583  sat = scubicsaturation(dem5, dzero, depth, dem5)
5584  if (npts > 1) then
5585  calc_top_width_wet = sat * get_wetted_topwidth(npts, &
5586  this%station(i0:i1), &
5587  this%xsheight(i0:i1), &
5588  depth)
5589  else
5590  calc_top_width_wet = sat * this%station(i0)
5591  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 2966 of file gwf-sfr.f90.

2967  ! -- dummy
2968  class(SfrType), intent(inout) :: this !< SfrType object
2969  !
2970  ! -- create the header list label
2971  this%listlabel = trim(this%filtyp)//' NO.'
2972  if (this%dis%ndim == 3) then
2973  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
2974  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
2975  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
2976  elseif (this%dis%ndim == 2) then
2977  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
2978  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
2979  else
2980  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
2981  end if
2982  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
2983  if (this%inamedbound == 1) then
2984  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
2985  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 5598 of file gwf-sfr.f90.

5599  ! -- modules
5601  ! -- dummy
5602  class(SfrType), intent(inout) :: this !< SfrType object
5603  ! -- local
5604  integer(I4B) :: i
5605  integer(I4B) :: j
5606  !
5607  ! -- Set idense and reallocate denseterms to be of size MAXBOUND
5608  this%idense = 1
5609  call mem_reallocate(this%denseterms, 3, this%MAXBOUND, 'DENSETERMS', &
5610  this%memoryPath)
5611  do i = 1, this%maxbound
5612  do j = 1, 3
5613  this%denseterms(j, i) = dzero
5614  end do
5615  end do
5616  write (this%iout, '(/1x,a)') 'DENSITY TERMS HAVE BEEN ACTIVATED FOR SFR &
5617  &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 5625 of file gwf-sfr.f90.

5626  ! -- modules
5628  ! -- dummy
5629  class(SfrType), intent(inout) :: this !< SfrType object
5630  ! -- local
5631  integer(I4B) :: i
5632  integer(I4B) :: j
5633  !
5634  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
5635  this%ivsc = 1
5636  call mem_reallocate(this%viscratios, 2, this%MAXBOUND, 'VISCRATIOS', &
5637  this%memoryPath)
5638  do i = 1, this%maxbound
5639  do j = 1, 2
5640  this%viscratios(j, i) = done
5641  end do
5642  end do
5643  write (this%iout, '(/1x,a)') 'VISCOSITY HAS BEEN ACTIVATED FOR SFR &
5644  &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 1955 of file gwf-sfr.f90.

1956  ! -- modules
1957  use constantsmodule, only: lenvarname
1958  ! -- dummy
1959  class(SfrType) :: this !< SfrType object
1960  ! -- local
1961  integer(I4B) :: n
1962  integer(I4B) :: i
1963  integer(I4B) :: ii
1964  integer(I4B) :: idiv
1965  integer(I4B) :: iaux
1966  character(len=LENVARNAME) :: setting
1967 
1968  ! -- sync PACKAGEDATA AUX TS and advance observations;
1969  ! -- step auxvar period block overrides
1970  call this%BndExtType%bnd_ad()
1971  !
1972  ! -- update previous values
1973  if (this%istorage == 1) then
1974  do n = 1, this%maxbound
1975  this%stageold(n) = this%stage(n)
1976  this%usinflowold(n) = this%usinflow(n)
1977  this%dsflowold(n) = this%dsflow(n)
1978  end do
1979  end if
1980  !
1981  ! -- sync PACKAGEDATA and PERIOD TS fields from input context each
1982  ! timestep; skipped when no TS6 files are configured
1983  if (this%ts_active) then
1984  do i = 1, this%maxbound
1985  n = this%pkg_ifno(i)
1986  if (.not. this%bedk_set(n)) this%hk(n) = this%input%rhk(i)
1987  if (.not. this%manning_set(n)) this%rough(n) = this%input%man(i)
1988  if (.not. this%ustrf_set(n)) this%ustrf(n) = this%input%ustrf(i)
1989  end do
1990  !
1991  if (this%input%nbound > 0) then
1992  do i = 1, this%input%nbound
1993  n = this%input%ifno(i)
1994  if (n < 1 .or. n > this%maxbound) cycle
1995  ! -- BEDK, MANNING, UPSTREAM_FRAC, STAGE, INFLOW, RAINFALL, EVAPORATION, RUNOFF
1996  setting = this%input%setting(i)
1997  call this%sfr_set_period_value(i, n, setting)
1998  ! -- DIVFLOW
1999  if (trim(setting) == 'DIVERSION') then
2000  if (this%ndiv(n) >= 1) then
2001  idiv = this%input%idv(i)
2002  if (idiv >= 1 .and. idiv <= this%ndiv(n)) then
2003  ii = this%iadiv(n) + idiv - 1
2004  end if
2005  end if
2006  end if
2007  end do
2008  end if
2009  end if
2010  !
2011  ! -- check upstream fractions (only needed when USTRF may be TS-updated;
2012  ! sfr_rp already validates ustrf once per period via ichkustrm)
2013  if (this%ts_active) call this%sfr_check_ustrf()
2014  !
2015  ! -- update auxiliary variables by copying from the derived-type time
2016  ! series variable into the bndpackage auxvar variable so that this
2017  ! information is properly written to the GWF budget file
2018  if (this%naux > 0) then
2019  do n = 1, this%maxbound
2020  do iaux = 1, this%naux
2021  if (this%noupdateauxvar(iaux) /= 0) cycle
2022  this%auxvar(iaux, n) = this%featureauxvar(iaux, n)
2023  end do
2024  end do
2025  end if
2026  !
2027  ! -- reset upstream flow to zero and set specified stage
2028  do n = 1, this%maxbound
2029  this%usflow(n) = dzero
2030  if (this%iboundpak(n) < 0) then
2031  this%stage(n) = this%sstage(n)
2032  end if
2033  end do
2034  !
2035  ! -- pakmvrobj ad
2036  if (this%imover == 1) then
2037  call this%pakmvrobj%ad()
2038  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 3598 of file gwf-sfr.f90.

3599  ! -- dummy
3600  class(SfrType) :: this !< SfrType object
3601  real(DP), intent(inout) :: qc !< total reach volumetric flow
3602  real(DP), intent(in) :: qu !< upstream reach volumetric flow
3603  real(DP), intent(in) :: qi !< reach volumetric inflow
3604  real(DP), intent(in) :: qr !< reach volumetric rainfall
3605  real(DP), intent(inout) :: qro !< reach volumetric runoff
3606  real(DP), intent(inout) :: qe !< reach volumetric evaporation
3607  real(DP), intent(in) :: qfrommvr !< reach volumetric flow from mover
3608  ! -- local
3609  real(DP) :: qt
3610  !
3611  ! -- adjust runoff or evaporation if sum of sources is negative
3612  if (qc < dzero) then
3613  !
3614  ! -- calculate sources without evaporation
3615  qt = qu + qi + qr + qro + qfrommvr
3616  !
3617  ! -- runoff exceeds sources of water for reach
3618  if (qt < dzero) then
3619  if (qro < dzero) then
3620  qro = -(qu + qi + qr + qfrommvr)
3621  qe = dzero
3622  end if
3623  !
3624  ! -- evaporation exceeds sources of water for reach
3625  else
3626  if (qe > dzero) then
3627  qe = qu + qi + qr + qro + qfrommvr
3628  end if
3629  end if
3630  qc = qu + qi + qr - qe + qro + qfrommvr
3631  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 479 of file gwf-sfr.f90.

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

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

1605  ! -- modules
1606  use tdismodule, only: inats
1607  ! -- dummy
1608  class(SfrType), intent(inout) :: this !< SfrType object
1609  ! -- local
1610  integer(I4B) :: n
1611  integer(I4B) :: ierr
1612  !
1613  ! -- allocate and read observations
1614  call this%obs%obs_ar()
1615  !
1616  ! -- allocate BndType connection-level arrays (nodelist, bound, auxvar, etc.)
1617  call this%BndExtType%allocate_arrays()
1618  !
1619  ! -- allocate featureauxvar and set pkg_ifno/pkg_auxvar input context
1620  ! pointers
1621  call this%BndExtType%allocate_featureauxvar()
1622  !
1623  ! -- set persistent PERIOD pointers into input context (valid for
1624  ! simulation lifetime)
1625  call this%input%init(this%input_mempath, this%naux)
1626  !
1627  ! -- set boundname for each connection
1628  if (this%inamedbound /= 0) then
1629  do n = 1, this%maxbound
1630  this%boundname(n) = this%sfrname(n)
1631  end do
1632  end if
1633  !
1634  ! -- copy boundname into boundname_cst
1635  call this%copy_boundname()
1636  !
1637  ! -- copy igwfnode into nodelist
1638  do n = 1, this%maxbound
1639  this%nodelist(n) = this%igwfnode(n)
1640  end do
1641  !
1642  ! -- check the sfr unit conversion data
1643  call this%sfr_check_conversion()
1644  !
1645  ! -- check the storage_weight
1646  call this%sfr_check_storage_weight()
1647  !
1648  ! -- check that ATS_COURANT is only used with STORAGE
1649  if (this%ats_courant /= dnodata .and. this%istorage /= 1) then
1650  write (errmsg, '(a)') &
1651  'ATS_COURANT OPTION REQUIRES STORAGE OPTION TO BE ACTIVE'
1652  call store_error(errmsg)
1653  end if
1654  !
1655  ! -- warn when ATS_COURANT is specified but ATS is not active in TDIS
1656  if (this%ats_courant /= dnodata .and. inats == 0) then
1657  write (warnmsg, '(a)') &
1658  'ATS_COURANT IS SPECIFIED IN THE SFR OPTIONS BLOCK BUT THE '// &
1659  'ATS PACKAGE IS NOT ACTIVE IN TDIS, SO THE TIME STEP IS NOT '// &
1660  'ADAPTED TO THE COURANT NUMBER. IF THE COURANT NUMBER EXCEEDS 1 '// &
1661  'THE EXPLICIT KINEMATIC-WAVE ROUTING MAY OSCILLATE WHILE STILL '// &
1662  'CLOSING THE BUDGET. ACTIVATE THE ATS PACKAGE OR USE A SMALLER '// &
1663  'TIME STEP.'
1664  call store_warning(warnmsg)
1665  end if
1666  !
1667  ! -- pre-compute TVD upstream connectivity when ATS_COURANT is active
1668  if (this%ats_courant /= dnodata .and. this%istorage == 1) then
1669  call this%sfr_precompute_tvd()
1670  end if
1671  !
1672  ! -- check the sfr reach data
1673  call this%sfr_check_reaches()
1674 
1675  ! -- check the connection data
1676  call this%sfr_check_connections()
1677 
1678  ! -- check the diversion data
1679  if (this%idiversions /= 0) then
1680  call this%sfr_check_diversions()
1681  end if
1682 
1683  ! -- check the diversion data
1684  if (this%istorage == 1) then
1685  call this%sfr_check_initialstages()
1686  end if
1687  !
1688  ! -- terminate if errors were detected in any of the static sfr data
1689  ierr = count_errors()
1690  if (ierr > 0) then
1691  call store_error_filename(this%input_fname)
1692  end if
1693  !
1694  ! -- setup pakmvrobj
1695  if (this%imover /= 0) then
1696  allocate (this%pakmvrobj)
1697  call this%pakmvrobj%ar(this%maxbound, this%maxbound, this%memoryPath)
1698  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 3106 of file gwf-sfr.f90.

3107  ! -- dummy
3108  class(SfrType) :: this !< SfrType object
3109  ! -- local
3110  integer(I4B) :: i
3111  integer(I4B) :: j
3112  integer(I4B) :: n
3113  real(DP) :: v
3114  character(len=100) :: msg
3115  type(ObserveType), pointer :: obsrv => null()
3116  !
3117  ! Write simulated values for all sfr observations
3118  if (this%obs%npakobs > 0) then
3119  call this%obs%obs_bd_clear()
3120  do i = 1, this%obs%npakobs
3121  obsrv => this%obs%pakobs(i)%obsrv
3122  do j = 1, obsrv%indxbnds_count
3123  n = obsrv%indxbnds(j)
3124  v = dzero
3125  select case (obsrv%ObsTypeId)
3126  case ('STAGE')
3127  v = this%stage(n)
3128  case ('TO-MVR')
3129  v = dnodata
3130  if (this%imover == 1) then
3131  v = this%pakmvrobj%get_qtomvr(n)
3132  if (v > dzero) then
3133  v = -v
3134  end if
3135  end if
3136  case ('FROM-MVR')
3137  v = dnodata
3138  if (this%imover == 1) then
3139  v = this%pakmvrobj%get_qfrommvr(n)
3140  end if
3141  case ('EXT-INFLOW')
3142  v = this%inflow(n)
3143  case ('INFLOW')
3144  v = this%usflow(n)
3145  case ('OUTFLOW')
3146  v = this%qoutflow(n)
3147  case ('EXT-OUTFLOW')
3148  v = this%qextoutflow(n)
3149  case ('RAINFALL')
3150  if (this%iboundpak(n) /= 0) then
3151  v = this%rain(n)
3152  else
3153  v = dzero
3154  end if
3155  case ('RUNOFF')
3156  v = this%simrunoff(n)
3157  case ('EVAPORATION')
3158  v = this%simevap(n)
3159  case ('SFR')
3160  v = this%gwflow(n)
3161  case ('UPSTREAM-FLOW')
3162  v = this%usflow(n)
3163  if (this%imover == 1) then
3164  v = v + this%pakmvrobj%get_qfrommvr(n)
3165  end if
3166  case ('DOWNSTREAM-FLOW')
3167  v = this%dsflow(n)
3168  if (v > dzero) then
3169  v = -v
3170  end if
3171  case ('DEPTH')
3172  v = this%depth(n)
3173  case ('WET-PERIMETER')
3174  v = this%calc_perimeter_wet(n, this%depth(n))
3175  case ('WET-AREA')
3176  v = this%calc_area_wet(n, this%depth(n))
3177  case ('WET-WIDTH')
3178  v = this%calc_top_width_wet(n, this%depth(n))
3179  case default
3180  msg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
3181  call store_error(msg)
3182  end select
3183  call this%obs%SaveOneSimval(obsrv, v)
3184  end do
3185  end do
3186  !
3187  ! -- write summary of package error messages
3188  if (count_errors() > 0) then
3189  call store_error_filename(this%input_fname)
3190  end if
3191  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 2755 of file gwf-sfr.f90.

2756  ! -- dummy
2757  class(SfrType) :: this !< SfrType object
2758  integer(I4B), intent(in) :: n !< reach number
2759  real(DP), intent(in) :: q !< reach flow
2760  real(DP), intent(out) :: celerity !< kinematic-wave celerity
2761  ! -- local
2762  real(DP) :: d
2763  real(DP) :: a
2764  real(DP) :: a2
2765  !
2766  celerity = dzero
2767  call this%sfr_calc_reach_depth(n, q, d)
2768  if (d > dzero) then
2769  a = this%calc_area_wet(n, d)
2770  call this%sfr_calc_reach_depth(n, q + this%deps, d)
2771  a2 = this%calc_area_wet(n, d)
2772  if (a2 > a) then
2773  celerity = this%deps / (a2 - a)
2774  end if
2775  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 3876 of file gwf-sfr.f90.

3877  ! -- dummy
3878  class(SfrType) :: this !< SfrType object
3879  integer(I4B), intent(in) :: n !< reach number
3880  real(DP), intent(in) :: depth !< reach depth
3881  real(DP), intent(inout) :: cond !< reach-aquifer conductance
3882  real(DP), intent(in), optional :: hsfr !< stream stage
3883  real(DP), intent(in), optional :: h_temp !< head in gw cell
3884  ! -- local
3885  integer(I4B) :: node
3886  real(DP) :: wp
3887  real(DP) :: vscratio
3888  !
3889  ! -- initialize conductance
3890  cond = dzero
3891  !
3892  ! -- initial viscosity ratio to 1
3893  vscratio = done
3894  !
3895  ! -- calculate conductance if GWF cell is active
3896  ! rch-gwf flow will not occur if reach connected to an constant head cell
3897  node = this%igwfnode(n)
3898  if (node > 0) then
3899  if (this%ibound(node) > 0) then
3900  !
3901  ! -- direction of gradient across streambed determines which vsc ratio
3902  if (this%ivsc == 1) then
3903  if (hsfr > h_temp) then
3904  ! strm stg > gw head
3905  vscratio = this%viscratios(1, n)
3906  else
3907  vscratio = this%viscratios(2, n)
3908  end if
3909  end if
3910  wp = this%calc_perimeter_wet(n, depth)
3911  cond = this%hk(n) * vscratio * this%length(n) * wp / this%bthick(n)
3912  end if
3913  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 3923 of file gwf-sfr.f90.

3924  ! -- dummy
3925  class(SfrType) :: this !< SfrType object
3926  integer(I4B), intent(in) :: n !< reach number
3927  integer(I4B), intent(in) :: i !< diversion number in reach
3928  real(DP), intent(inout) :: qd !< remaining downstream flow for reach
3929  real(DP), intent(inout) :: qdiv !< diversion flow for diversion i
3930  ! -- local
3931  character(len=10) :: cp
3932  integer(I4B) :: jpos
3933  integer(I4B) :: n2
3934  real(DP) :: v
3935  !
3936  ! -- set local variables
3937  jpos = this%iadiv(n) + i - 1
3938  n2 = this%divreach(jpos)
3939  cp = this%divcprior(jpos)
3940  v = this%divflow(jpos)
3941  !
3942  ! -- calculate diversion
3943  select case (cp)
3944  ! -- flood diversion
3945  case ('EXCESS')
3946  if (qd < v) then
3947  v = dzero
3948  else
3949  v = qd - v
3950  end if
3951  ! -- diversion percentage
3952  case ('FRACTION')
3953  v = qd * v
3954  ! -- STR priority algorithm
3955  case ('THRESHOLD')
3956  if (qd < v) then
3957  v = dzero
3958  end if
3959  ! -- specified diversion
3960  case ('UPTO')
3961  if (v > qd) then
3962  v = qd
3963  end if
3964  case default
3965  v = dzero
3966  end select
3967  !
3968  ! -- update upstream from for downstream reaches
3969  qd = qd - v
3970  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 3638 of file gwf-sfr.f90.

3639  ! -- dummy
3640  class(SfrType) :: this !< SfrType object
3641  integer(I4B), intent(in) :: n !< reach number
3642  real(DP), intent(in) :: depth !< reach depth
3643  real(DP), intent(in) :: hgwf !< groundwater head in connected GWF cell
3644  real(DP), intent(inout) :: qgwf !< groundwater leakage for reach
3645  real(DP), intent(inout) :: qd !< residual
3646  ! -- local
3647  real(DP) :: qsrc
3648  !
3649  ! -- initialize residual
3650  qd = dzero
3651  !
3652  ! -- calculate total water sources excluding groundwater leakage
3653  call this%sfr_calc_qsource(n, depth, qsrc)
3654  !
3655  ! -- estimate groundwater leakage
3656  call this%sfr_calc_qgwf(n, depth, hgwf, qgwf)
3657  if (-qgwf > qsrc) qgwf = -qsrc
3658  !
3659  ! -- calculate down stream flow
3660  qd = qsrc + qgwf
3661  !
3662  ! -- limit downstream flow to a positive value
3663  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 3789 of file gwf-sfr.f90.

3790  ! -- dummy
3791  class(SfrType) :: this !< SfrType object
3792  integer(I4B), intent(in) :: n !< reach number
3793  real(DP), intent(in) :: depth !< reach depth
3794  real(DP), intent(in) :: hgwf !< head in GWF cell connected to reach
3795  real(DP), intent(inout) :: qgwf !< reach-aquifer exchange
3796  real(DP), intent(inout), optional :: gwfhcof !< diagonal coefficient term for reach
3797  real(DP), intent(inout), optional :: gwfrhs !< right-hand side term for reach
3798  ! -- local
3799  integer(I4B) :: node
3800  real(DP) :: tp
3801  real(DP) :: bt
3802  real(DP) :: hsfr
3803  real(DP) :: h_temp
3804  real(DP) :: cond
3805  real(DP) :: sat
3806  real(DP) :: derv
3807  real(DP) :: gwfhcof0
3808  real(DP) :: gwfrhs0
3809  !
3810  ! -- initialize qgwf
3811  qgwf = dzero
3812  !
3813  ! -- skip sfr-aquifer exchange in external cells
3814  node = this%igwfnode(n)
3815  if (node < 1) return
3816  !
3817  ! -- skip sfr-aquifer exchange in inactive cells
3818  if (this%ibound(node) == 0) return
3819  !
3820  ! -- calculate saturation
3821  call schsmooth(depth, sat, derv)
3822  !
3823  ! -- terms for calculating direction of gradient across streambed
3824  tp = this%strtop(n)
3825  bt = tp - this%bthick(n)
3826  hsfr = tp + depth
3827  h_temp = hgwf
3828  if (h_temp < bt) then
3829  h_temp = bt
3830  end if
3831  !
3832  ! -- calculate conductance
3833  call this%sfr_calc_cond(n, depth, cond, hsfr, h_temp)
3834  !
3835  ! -- calculate groundwater leakage
3836  qgwf = sat * cond * (h_temp - hsfr)
3837  gwfrhs0 = -sat * cond * hsfr
3838  gwfhcof0 = -sat * cond
3839  !
3840  ! Add density contributions, if active
3841  if (this%idense /= 0) then
3842  call this%sfr_calculate_density_exchange(n, hsfr, hgwf, cond, tp, &
3843  qgwf, gwfhcof0, gwfrhs0)
3844  end if
3845  !
3846  ! -- Set gwfhcof and gwfrhs if present
3847  if (present(gwfhcof)) gwfhcof = gwfhcof0
3848  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 3719 of file gwf-sfr.f90.

3720  ! -- dummy
3721  class(SfrType) :: this !< SfrType object
3722  integer(I4B), intent(in) :: n !< reach number
3723  real(DP), intent(in) :: depth !< reach depth
3724  real(DP), intent(inout) :: qman !< streamflow
3725  ! -- local
3726  integer(I4B) :: npts
3727  integer(I4B) :: i0
3728  integer(I4B) :: i1
3729  real(DP) :: sat
3730  real(DP) :: derv
3731  real(DP) :: s
3732  real(DP) :: r
3733  real(DP) :: aw
3734  real(DP) :: wp
3735  real(DP) :: rh
3736  !
3737  ! -- initialize variables
3738  qman = dzero
3739  !
3740  ! -- calculate Manning's discharge for non-zero depths
3741  if (depth > dzero) then
3742  npts = this%ncrosspts(n)
3743  !
3744  ! -- set constant terms for Manning's equation
3745  call schsmooth(depth, sat, derv)
3746  s = this%slope(n)
3747  !
3748  ! -- calculate the mannings coefficient that is a
3749  ! function of depth
3750  if (npts > 1) then
3751  !
3752  ! -- get the location of the cross-section data for the reach
3753  i0 = this%iacross(n)
3754  i1 = this%iacross(n + 1) - 1
3755  !
3756  ! -- get the Manning's sum of the Manning's discharge
3757  ! for each section
3758  qman = get_mannings_section(npts, &
3759  this%station(i0:i1), &
3760  this%xsheight(i0:i1), &
3761  this%xsrough(i0:i1), &
3762  this%rough(n), &
3763  this%unitconv, &
3764  s, &
3765  depth)
3766  else
3767  r = this%rough(n)
3768  aw = this%calc_area_wet(n, depth)
3769  wp = this%calc_perimeter_wet(n, depth)
3770  if (wp > dzero) then
3771  rh = aw / wp
3772  else
3773  rh = dzero
3774  end if
3775  qman = this%unitconv * aw * (rh**dtwothirds) * sqrt(s) / r
3776  end if
3777  !
3778  ! -- calculate stream flow
3779  qman = sat * qman
3780  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 3671 of file gwf-sfr.f90.

3672  ! -- dummy
3673  class(SfrType) :: this !< SfrType object
3674  integer(I4B), intent(in) :: n !< reach number
3675  real(DP), intent(in) :: depth !< reach depth
3676  real(DP), intent(inout) :: qsrc !< sum of sources for reach
3677  ! -- local
3678  real(DP) :: qu
3679  real(DP) :: qi
3680  real(DP) :: qr
3681  real(DP) :: qe
3682  real(DP) :: qro
3683  real(DP) :: qfrommvr
3684  real(DP) :: a
3685  real(DP) :: ae
3686  !
3687  ! -- initialize residual
3688  qsrc = dzero
3689  !
3690  ! -- calculate flow terms
3691  qu = this%usflow(n)
3692  qi = this%inflow(n)
3693  qro = this%runoff(n)
3694  !
3695  ! -- calculate rainfall and evap
3696  a = this%calc_surface_area(n)
3697  ae = this%calc_surface_area_wet(n, depth)
3698  qr = this%rain(n) * a
3699  qe = this%evap(n) * ae
3700  !
3701  ! -- calculate mover term
3702  qfrommvr = dzero
3703  if (this%imover == 1) then
3704  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
3705  end if
3706  !
3707  ! -- calculate down stream flow
3708  qsrc = qu + qi + qr - qe + qro + qfrommvr
3709  !
3710  ! -- adjust runoff or evaporation if sum of sources is negative
3711  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 3977 of file gwf-sfr.f90.

3978  ! -- dummy
3979  class(SfrType) :: this !< SfrType object
3980  integer(I4B), intent(in) :: n !< reach number
3981  real(DP), intent(in) :: q1 !< streamflow
3982  real(DP), intent(inout) :: d1 !< stream depth at midpoint of reach
3983  ! -- local
3984  real(DP) :: w
3985  real(DP) :: s
3986  real(DP) :: r
3987  real(DP) :: qconst
3988  !
3989  ! -- initialize slope and roughness
3990  s = this%slope(n)
3991  r = this%rough(n)
3992  !
3993  ! -- calculate stream depth at the midpoint
3994  if (q1 > dzero) then
3995  if (this%ncrosspts(n) > 1) then
3996  call this%sfr_calc_xs_depth(n, q1, d1)
3997  else
3998  w = this%station(this%iacross(n))
3999  qconst = this%unitconv * w * sqrt(s) / r
4000  d1 = (q1 / qconst)**dp6
4001  end if
4002  else
4003  d1 = dzero
4004  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 4012 of file gwf-sfr.f90.

4013  ! -- dummy
4014  class(SfrType) :: this !< SfrType object
4015  integer(I4B), intent(in) :: n !< reach number
4016  real(DP), intent(in) :: qrch !< streamflow
4017  real(DP), intent(inout) :: d !< stream depth at midpoint of reach
4018  ! -- local
4019  integer(I4B) :: iter
4020  real(DP) :: perturbation
4021  real(DP) :: q0
4022  real(DP) :: q1
4023  real(DP) :: dq
4024  real(DP) :: derv
4025  real(DP) :: dd
4026  real(DP) :: residual
4027  !
4028  ! -- initialize variables
4029  perturbation = this%deps * dtwo
4030  d = dzero
4031  q0 = dzero
4032  residual = q0 - qrch
4033  !
4034  ! -- Newton-Raphson iteration
4035  nriter: do iter = 1, this%maxsfrit
4036  call this%sfr_calc_qman(n, d + perturbation, q1)
4037  dq = (q1 - q0)
4038  if (dq /= dzero) then
4039  derv = perturbation / (q1 - q0)
4040  else
4041  derv = dzero
4042  end if
4043  dd = derv * residual
4044  d = d - dd
4045  call this%sfr_calc_qman(n, d, q0)
4046  residual = q0 - qrch
4047  !
4048  ! -- check for convergence
4049  if (abs(dd) < this%dmaxchg) then
4050  exit nriter
4051  end if
4052  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 5658 of file gwf-sfr.f90.

5660  ! -- dummy
5661  class(SfrType), intent(inout) :: this !< SfrType object
5662  integer(I4B), intent(in) :: n !< reach number
5663  real(DP), intent(in) :: stage !< reach stage
5664  real(DP), intent(in) :: head !< head in connected GWF cell
5665  real(DP), intent(in) :: cond !< reach conductance
5666  real(DP), intent(in) :: tops !< top elevation of streambed
5667  real(DP), intent(inout) :: flow !< calculated flow, updated here with density terms
5668  real(DP), intent(inout) :: gwfhcof !< GWF diagonal coefficient, updated here with density terms
5669  real(DP), intent(inout) :: gwfrhs !< GWF right-hand-side value, updated here with density terms
5670  ! -- local
5671  real(DP) :: ss
5672  real(DP) :: hh
5673  real(DP) :: havg
5674  real(DP) :: rdensesfr
5675  real(DP) :: rdensegwf
5676  real(DP) :: rdenseavg
5677  real(DP) :: elevsfr
5678  real(DP) :: elevgwf
5679  real(DP) :: elevavg
5680  real(DP) :: d1
5681  real(DP) :: d2
5682  logical(LGP) :: stage_below_bot
5683  logical(LGP) :: head_below_bot
5684  !
5685  ! -- Set sfr density to sfr density or gwf density
5686  if (stage >= tops) then
5687  ss = stage
5688  stage_below_bot = .false.
5689  rdensesfr = this%denseterms(1, n) ! sfr rel density
5690  else
5691  ss = tops
5692  stage_below_bot = .true.
5693  rdensesfr = this%denseterms(2, n) ! gwf rel density
5694  end if
5695  !
5696  ! -- set hh to head or tops (top elev of streambed)
5697  if (head >= tops) then
5698  hh = head
5699  head_below_bot = .false.
5700  rdensegwf = this%denseterms(2, n) ! gwf rel density
5701  else
5702  hh = tops
5703  head_below_bot = .true.
5704  rdensegwf = this%denseterms(1, n) ! sfr rel density
5705  end if
5706  !
5707  ! -- todo: hack because denseterms not updated in a cf calculation
5708  if (rdensegwf == dzero) return
5709  !
5710  ! -- Update flow
5711  if (stage_below_bot .and. head_below_bot) then
5712  !
5713  ! -- flow is zero, so no terms are updated
5714  !
5715  else
5716  !
5717  ! -- calculate average relative density
5718  rdenseavg = dhalf * (rdensesfr + rdensegwf)
5719  !
5720  ! -- Add contribution of first density term:
5721  ! cond * (denseavg/denseref - 1) * (hgwf - hsfr)
5722  d1 = cond * (rdenseavg - done)
5723  gwfhcof = gwfhcof - d1
5724  gwfrhs = gwfrhs - d1 * ss
5725  d1 = d1 * (hh - ss)
5726  flow = flow + d1
5727  !
5728  ! -- Add second density term if stage and head not below bottom
5729  if (.not. stage_below_bot .and. .not. head_below_bot) then
5730  !
5731  ! -- Add contribution of second density term:
5732  ! cond * (havg - elevavg) * (densegwf - densesfr) / denseref
5733  elevgwf = this%denseterms(3, n)
5734  elevsfr = tops
5735  elevavg = dhalf * (elevsfr + elevgwf)
5736  havg = dhalf * (hh + ss)
5737  d2 = cond * (havg - elevavg) * (rdensegwf - rdensesfr)
5738  gwfrhs = gwfrhs + d2
5739  flow = flow + d2
5740  end if
5741  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 2224 of file gwf-sfr.f90.

2225  ! -- modules
2226  use tdismodule, only: totim, kstp, kper, delt
2227  ! -- dummy
2228  class(SfrType), intent(inout) :: this !< SfrType object
2229  integer(I4B), intent(in) :: innertot !< total number of inner iterations
2230  integer(I4B), intent(in) :: kiter !< Picard iteration number
2231  integer(I4B), intent(in) :: iend !< flag indicating if this is the last Picard iteration
2232  integer(I4B), intent(in) :: icnvgmod !< flag inficating if the model has met specific convergence criteria
2233  character(len=LENPAKLOC), intent(inout) :: cpak !< string for user node
2234  integer(I4B), intent(inout) :: ipak !< location of the maximum dependent variable change
2235  real(DP), intent(inout) :: dpak !< maximum dependent variable change
2236  ! -- local
2237  character(len=LENPAKLOC) :: cloc
2238  character(len=LINELENGTH) :: tag
2239  integer(I4B) :: icheck
2240  integer(I4B) :: ipakfail
2241  integer(I4B) :: locdhmax
2242  integer(I4B) :: locrmax
2243  integer(I4B) :: locdqfrommvrmax
2244  integer(I4B) :: ntabrows
2245  integer(I4B) :: ntabcols
2246  integer(I4B) :: n
2247  real(DP) :: q
2248  real(DP) :: q0
2249  real(DP) :: qtolfact
2250  real(DP) :: dh
2251  real(DP) :: r
2252  real(DP) :: dhmax
2253  real(DP) :: rmax
2254  real(DP) :: dqfrommvr
2255  real(DP) :: dqfrommvrmax
2256  !
2257  ! -- initialize local variables
2258  icheck = this%iconvchk
2259  ipakfail = 0
2260  locdhmax = 0
2261  locrmax = 0
2262  r = dzero
2263  dhmax = dzero
2264  rmax = dzero
2265  locdqfrommvrmax = 0
2266  dqfrommvrmax = dzero
2267  !
2268  ! -- if not saving package convergence data on check convergence if
2269  ! the model is considered converged
2270  if (this%ipakcsv == 0) then
2271  if (icnvgmod == 0) then
2272  icheck = 0
2273  end if
2274  !
2275  ! -- saving package convergence data
2276  else
2277  !
2278  ! -- header for package csv
2279  if (.not. associated(this%pakcsvtab)) then
2280  !
2281  ! -- determine the number of columns and rows
2282  ntabrows = 1
2283  ntabcols = 9
2284  if (this%imover == 1) then
2285  ntabcols = ntabcols + 2
2286  end if
2287  !
2288  ! -- setup table
2289  call table_cr(this%pakcsvtab, this%packName, '')
2290  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
2291  lineseparator=.false., separator=',', &
2292  finalize=.false.)
2293  !
2294  ! -- add columns to package csv
2295  tag = 'total_inner_iterations'
2296  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2297  tag = 'totim'
2298  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2299  tag = 'kper'
2300  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2301  tag = 'kstp'
2302  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2303  tag = 'nouter'
2304  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
2305  tag = 'dvmax'
2306  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2307  tag = 'dvmax_loc'
2308  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2309  tag = 'dinflowmax'
2310  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2311  tag = 'dinflowmax_loc'
2312  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2313  if (this%imover == 1) then
2314  tag = 'dqfrommvrmax'
2315  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
2316  tag = 'dqfrommvrmax_loc'
2317  call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
2318  end if
2319  end if
2320  end if
2321  !
2322  ! -- perform package convergence check
2323  if (icheck /= 0) then
2324  final_check: do n = 1, this%maxbound
2325  if (this%iboundpak(n) == 0) cycle
2326  !
2327  ! -- set the Q to length factor
2328  qtolfact = delt / this%calc_surface_area(n)
2329  !
2330  ! -- calculate stage change
2331  dh = this%stage0(n) - this%stage(n)
2332  !
2333  ! -- evaluate flow difference if the time step is transient
2334  if (this%gwfiss == 0) then
2335  r = this%usflow0(n) - this%usflow(n)
2336  !
2337  ! -- normalize flow difference and convert to a depth
2338  r = r * qtolfact
2339  end if
2340  !
2341  ! -- q from mvr
2342  dqfrommvr = dzero
2343  if (this%imover == 1) then
2344  q = this%pakmvrobj%get_qfrommvr(n)
2345  q0 = this%pakmvrobj%get_qfrommvr0(n)
2346  dqfrommvr = qtolfact * (q0 - q)
2347  end if
2348  !
2349  ! -- evaluate magnitude of differences
2350  if (n == 1) then
2351  locdhmax = n
2352  dhmax = dh
2353  locrmax = n
2354  rmax = r
2355  dqfrommvrmax = dqfrommvr
2356  locdqfrommvrmax = n
2357  else
2358  if (abs(dh) > abs(dhmax)) then
2359  locdhmax = n
2360  dhmax = dh
2361  end if
2362  if (abs(r) > abs(rmax)) then
2363  locrmax = n
2364  rmax = r
2365  end if
2366  if (abs(dqfrommvr) > abs(dqfrommvrmax)) then
2367  dqfrommvrmax = dqfrommvr
2368  locdqfrommvrmax = n
2369  end if
2370  end if
2371  end do final_check
2372  !
2373  ! -- set dpak and cpak
2374  if (abs(dhmax) > abs(dpak)) then
2375  ipak = locdhmax
2376  dpak = dhmax
2377  write (cloc, "(a,'-',a)") trim(this%packName), 'stage'
2378  cpak = trim(cloc)
2379  end if
2380  if (abs(rmax) > abs(dpak)) then
2381  ipak = locrmax
2382  dpak = rmax
2383  write (cloc, "(a,'-',a)") trim(this%packName), 'inflow'
2384  cpak = trim(cloc)
2385  end if
2386  if (this%imover == 1) then
2387  if (abs(dqfrommvrmax) > abs(dpak)) then
2388  ipak = locdqfrommvrmax
2389  dpak = dqfrommvrmax
2390  write (cloc, "(a,'-',a)") trim(this%packName), 'qfrommvr'
2391  cpak = trim(cloc)
2392  end if
2393  end if
2394  !
2395  ! -- write convergence data to package csv
2396  if (this%ipakcsv /= 0) then
2397  !
2398  ! -- write the data
2399  call this%pakcsvtab%add_term(innertot)
2400  call this%pakcsvtab%add_term(totim)
2401  call this%pakcsvtab%add_term(kper)
2402  call this%pakcsvtab%add_term(kstp)
2403  call this%pakcsvtab%add_term(kiter)
2404  call this%pakcsvtab%add_term(dhmax)
2405  call this%pakcsvtab%add_term(locdhmax)
2406  call this%pakcsvtab%add_term(rmax)
2407  call this%pakcsvtab%add_term(locrmax)
2408  if (this%imover == 1) then
2409  call this%pakcsvtab%add_term(dqfrommvrmax)
2410  call this%pakcsvtab%add_term(locdqfrommvrmax)
2411  end if
2412  !
2413  ! -- finalize the package csv
2414  if (iend == 1) then
2415  call this%pakcsvtab%finalize_table()
2416  end if
2417  end if
2418  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 2046 of file gwf-sfr.f90.

2047  ! -- dummy
2048  class(SfrType) :: this !< SfrType object
2049  ! -- local
2050  integer(I4B) :: n
2051  integer(I4B) :: igwfnode
2052  !
2053  ! -- return if no sfr reaches
2054  if (this%nbound == 0) return
2055  !
2056  ! -- find highest active cell
2057  do n = 1, this%nbound
2058  igwfnode = this%igwftopnode(n)
2059  if (igwfnode > 0) then
2060  if (this%ibound(igwfnode) == 0) then
2061  call this%dis%highest_active(igwfnode, this%ibound)
2062  end if
2063  end if
2064  this%igwfnode(n) = igwfnode
2065  this%nodelist(n) = igwfnode
2066  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 4239 of file gwf-sfr.f90.

4240  ! -- dummy
4241  class(SfrType) :: this !< SfrType object
4242  ! -- local
4243  logical(LGP) :: lreorder
4244  character(len=5) :: crch
4245  character(len=5) :: crch2
4246  character(len=LINELENGTH) :: text
4247  character(len=LINELENGTH) :: title
4248  integer(I4B) :: n
4249  integer(I4B) :: nn
4250  integer(I4B) :: nc
4251  integer(I4B) :: i
4252  integer(I4B) :: ii
4253  integer(I4B) :: j
4254  integer(I4B) :: ifound
4255  integer(I4B) :: ierr
4256  integer(I4B) :: maxconn
4257  integer(I4B) :: ntabcol
4258  !
4259  ! -- determine if the reaches have been reordered
4260  lreorder = .false.
4261  do j = 1, this%MAXBOUND
4262  n = this%isfrorder(j)
4263  if (n /= j) then
4264  lreorder = .true.
4265  exit
4266  end if
4267  end do
4268  !
4269  ! -- write message that the solution order h
4270  if (lreorder) then
4271  write (this%iout, '(/,1x,a)') &
4272  trim(adjustl(this%text))//' PACKAGE ('// &
4273  trim(adjustl(this%packName))//') REACH SOLUTION HAS BEEN '// &
4274  'REORDERED USING A DAG'
4275  !
4276  ! -- print table
4277  if (this%iprpak /= 0) then
4278  !
4279  ! -- reset the input table object
4280  ntabcol = 2
4281  title = trim(adjustl(this%text))//' PACKAGE ('// &
4282  trim(adjustl(this%packName))//') REACH SOLUTION ORDER'
4283  call table_cr(this%inputtab, this%packName, title)
4284  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4285  text = 'ORDER'
4286  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4287  text = 'REACH'
4288  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4289  !
4290  ! -- upstream connection data
4291  do j = 1, this%maxbound
4292  n = this%isfrorder(j)
4293  call this%inputtab%add_term(j)
4294  call this%inputtab%add_term(n)
4295  end do
4296  end if
4297  end if
4298  !
4299  ! -- create input table for reach connections data
4300  if (this%iprpak /= 0) then
4301  !
4302  ! -- calculate the maximum number of connections
4303  maxconn = 0
4304  do n = 1, this%maxbound
4305  maxconn = max(maxconn, this%nconnreach(n))
4306  end do
4307  ntabcol = 1 + maxconn
4308  !
4309  ! -- reset the input table object
4310  title = trim(adjustl(this%text))//' PACKAGE ('// &
4311  trim(adjustl(this%packName))//') STATIC REACH CONNECTION DATA'
4312  call table_cr(this%inputtab, this%packName, title)
4313  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4314  text = 'REACH'
4315  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4316  do n = 1, maxconn
4317  write (text, '(a,1x,i6)') 'CONN', n
4318  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4319  end do
4320  end if
4321  !
4322  ! -- verify every listed connection is reciprocated: if reach n lists
4323  ! -- reach nn, reach nn must list reach n back
4324  do n = 1, this%MAXBOUND
4325  write (crch, '(i5)') n
4326  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4327  nn = this%ja(i)
4328  write (crch2, '(i5)') nn
4329  ifound = 0
4330  connreach: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4331  nc = this%ja(ii)
4332  if (nc == n) then
4333  ifound = 1
4334  exit connreach
4335  end if
4336  end do connreach
4337  if (ifound /= 1) then
4338  errmsg = 'Reach '//crch//' is connected to '// &
4339  'reach '//crch2//' but reach '//crch2// &
4340  ' is not connected to reach '//crch//'.'
4341  call store_error(errmsg)
4342  end if
4343  end do eachconn
4344  !
4345  ! -- write connection data to the table
4346  if (this%iprpak /= 0) then
4347  call this%inputtab%add_term(n)
4348  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4349  call this%inputtab%add_term(this%ja(i))
4350  end do
4351  nn = maxconn - this%nconnreach(n)
4352  do i = 1, nn
4353  call this%inputtab%add_term(' ')
4354  end do
4355  end if
4356  end do
4357  !
4358  ! -- verify upstream connections don't form a mutual pair: two reaches
4359  ! -- cannot each list the other as upstream
4360  ierr = 0
4361  do n = 1, this%maxbound
4362  write (crch, '(i5)') n
4363  eachconnv: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4364  !
4365  ! -- skip downstream connections
4366  if (this%idir(i) < 0) cycle eachconnv
4367  nn = this%ja(i)
4368  write (crch2, '(i5)') nn
4369  connreachv: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4370  ! -- skip downstream connections
4371  if (this%idir(ii) < 0) cycle connreachv
4372  nc = this%ja(ii)
4373  !
4374  ! -- if nc == n then that means reach n is an upstream connection for
4375  ! reach nn and reach nn is an upstream connection for reach n
4376  if (nc == n) then
4377  ierr = ierr + 1
4378  errmsg = 'Reach '//crch//' is connected to '// &
4379  'reach '//crch2//' but streamflow from reach '// &
4380  crch//' to reach '//crch2//' is not permitted.'
4381  call store_error(errmsg)
4382  exit connreachv
4383  end if
4384  end do connreachv
4385  end do eachconnv
4386  end do
4387  !
4388  ! -- terminate if connectivity errors
4389  if (count_errors() > 0) then
4390  call store_error_filename(this%input_fname)
4391  end if
4392  !
4393  ! -- check that downstream reaches for a reach are
4394  ! the upstream reaches for the reach
4395  do n = 1, this%maxbound
4396  write (crch, '(i5)') n
4397  eachconnds: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4398  nn = this%ja(i)
4399  if (this%idir(i) > 0) cycle eachconnds
4400  write (crch2, '(i5)') nn
4401  ifound = 0
4402  connreachds: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4403  nc = this%ja(ii)
4404  if (nc == n) then
4405  if (this%idir(i) /= this%idir(ii)) then
4406  ifound = 1
4407  end if
4408  exit connreachds
4409  end if
4410  end do connreachds
4411  if (ifound /= 1) then
4412  errmsg = 'Reach '//crch//' downstream connected reach '// &
4413  'is reach '//crch2//' but reach '//crch//' is not'// &
4414  ' the upstream connected reach for reach '//crch2//'.'
4415  call store_error(errmsg)
4416  end if
4417  end do eachconnds
4418  end do
4419  !
4420  ! -- create input table for upstream and downstream connections
4421  if (this%iprpak /= 0) then
4422  !
4423  ! -- calculate the maximum number of upstream connections
4424  maxconn = 0
4425  do n = 1, this%maxbound
4426  ii = 0
4427  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4428  if (this%idir(i) > 0) then
4429  ii = ii + 1
4430  end if
4431  end do
4432  maxconn = max(maxconn, ii)
4433  end do
4434  ntabcol = 1 + maxconn
4435  !
4436  ! -- reset the input table object
4437  title = trim(adjustl(this%text))//' PACKAGE ('// &
4438  trim(adjustl(this%packName))//') STATIC UPSTREAM REACH '// &
4439  'CONNECTION DATA'
4440  call table_cr(this%inputtab, this%packName, title)
4441  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4442  text = 'REACH'
4443  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4444  do n = 1, maxconn
4445  write (text, '(a,1x,i6)') 'UPSTREAM CONN', n
4446  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4447  end do
4448  !
4449  ! -- upstream connection data
4450  do n = 1, this%maxbound
4451  call this%inputtab%add_term(n)
4452  ii = 0
4453  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4454  if (this%idir(i) > 0) then
4455  call this%inputtab%add_term(this%ja(i))
4456  ii = ii + 1
4457  end if
4458  end do
4459  nn = maxconn - ii
4460  do i = 1, nn
4461  call this%inputtab%add_term(' ')
4462  end do
4463  end do
4464  !
4465  ! -- calculate the maximum number of downstream connections
4466  maxconn = 0
4467  do n = 1, this%maxbound
4468  ii = 0
4469  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4470  if (this%idir(i) < 0) then
4471  ii = ii + 1
4472  end if
4473  end do
4474  maxconn = max(maxconn, ii)
4475  end do
4476  ntabcol = 1 + maxconn
4477  !
4478  ! -- reset the input table object
4479  title = trim(adjustl(this%text))//' PACKAGE ('// &
4480  trim(adjustl(this%packName))//') STATIC DOWNSTREAM '// &
4481  'REACH CONNECTION DATA'
4482  call table_cr(this%inputtab, this%packName, title)
4483  call this%inputtab%table_df(this%maxbound, ntabcol, this%iout)
4484  text = 'REACH'
4485  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4486  do n = 1, maxconn
4487  write (text, '(a,1x,i6)') 'DOWNSTREAM CONN', n
4488  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4489  end do
4490  !
4491  ! -- downstream connection data
4492  do n = 1, this%maxbound
4493  call this%inputtab%add_term(n)
4494  ii = 0
4495  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4496  if (this%idir(i) < 0) then
4497  call this%inputtab%add_term(this%ja(i))
4498  ii = ii + 1
4499  end if
4500  end do
4501  nn = maxconn - ii
4502  do i = 1, nn
4503  call this%inputtab%add_term(' ')
4504  end do
4505  end do
4506  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 4060 of file gwf-sfr.f90.

4061  ! -- dummy
4062  class(SfrType) :: this !< SfrType object
4063  ! -- local
4064  ! -- formats
4065  character(len=*), parameter :: fmtunitconv_error = &
4066  &"('SFR (',a,') UNIT_CONVERSION SPECIFIED VALUE (',g0,') AND', &
4067  &1x,'LENGTH_CONVERSION OR TIME_CONVERSION SPECIFIED.')"
4068  character(len=*), parameter :: fmtunitconv = &
4069  &"(1x,'SFR PACKAGE (',a,') CONVERSION DATA',&
4070  &/4x,'UNIT CONVERSION VALUE (',g0,').',/)"
4071  !
4072  ! -- check the reach data for simple errors
4073  if (this%lengthconv /= dnodata .or. this%timeconv /= dnodata) then
4074  if (this%unitconv /= done) then
4075  write (errmsg, fmtunitconv_error) &
4076  trim(adjustl(this%packName)), this%unitconv
4077  call store_error(errmsg)
4078  else
4079  if (this%lengthconv /= dnodata) then
4080  this%unitconv = this%unitconv * this%lengthconv**donethird
4081  end if
4082  if (this%timeconv /= dnodata) then
4083  this%unitconv = this%unitconv * this%timeconv
4084  end if
4085  write (this%iout, fmtunitconv) &
4086  trim(adjustl(this%packName)), this%unitconv
4087  end if
4088  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 4515 of file gwf-sfr.f90.

4516  ! -- dummy
4517  class(SfrType) :: this !< SfrType object
4518  ! -- local
4519  character(len=LINELENGTH) :: title
4520  character(len=LINELENGTH) :: text
4521  character(len=5) :: crch
4522  character(len=5) :: cdiv
4523  character(len=5) :: crch2
4524  character(len=10) :: cprior
4525  integer(I4B) :: maxdiv
4526  integer(I4B) :: n
4527  integer(I4B) :: nn
4528  integer(I4B) :: nc
4529  integer(I4B) :: ii
4530  integer(I4B) :: idiv
4531  integer(I4B) :: ifound
4532  integer(I4B) :: jpos
4533  ! -- format
4534 10 format('Diversion ', i0, ' of reach ', i0, &
4535  ' is invalid or has not been defined.')
4536  !
4537  ! -- write header
4538  if (this%iprpak /= 0) then
4539  !
4540  ! -- determine the maximum number of diversions
4541  maxdiv = 0
4542  do n = 1, this%maxbound
4543  maxdiv = maxdiv + this%ndiv(n)
4544  end do
4545  !
4546  ! -- reset the input table object
4547  title = trim(adjustl(this%text))//' PACKAGE ('// &
4548  trim(adjustl(this%packName))//') REACH DIVERSION DATA'
4549  call table_cr(this%inputtab, this%packName, title)
4550  call this%inputtab%table_df(maxdiv, 4, this%iout)
4551  text = 'REACH'
4552  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4553  text = 'DIVERSION'
4554  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4555  text = 'REACH 2'
4556  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4557  text = 'CPRIOR'
4558  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4559  end if
4560  !
4561  ! -- check that diversion data are correct
4562  do n = 1, this%maxbound
4563  if (this%ndiv(n) < 1) cycle
4564  write (crch, '(i5)') n
4565 
4566  do idiv = 1, this%ndiv(n)
4567  !
4568  ! -- determine diversion index
4569  jpos = this%iadiv(n) + idiv - 1
4570  !
4571  ! -- write idiv to cdiv
4572  write (cdiv, '(i5)') idiv
4573  !
4574  !
4575  nn = this%divreach(jpos)
4576  write (crch2, '(i5)') nn
4577  !
4578  ! -- make sure diversion reach is connected to current reach
4579  ifound = 0
4580  if (nn < 1 .or. nn > this%maxbound) then
4581  write (errmsg, 10) idiv, n
4582  call store_error(errmsg)
4583  cycle
4584  end if
4585  connreach: do ii = this%ia(nn) + 1, this%ia(nn + 1) - 1
4586  nc = this%ja(ii)
4587  if (nc == n) then
4588  if (this%idir(ii) > 0) then
4589  ifound = 1
4590  end if
4591  exit connreach
4592  end if
4593  end do connreach
4594  if (ifound /= 1) then
4595  errmsg = 'Reach '//crch//' is not a upstream reach for '// &
4596  'reach '//crch2//' as a result diversion '//cdiv// &
4597  ' from reach '//crch//' to reach '//crch2// &
4598  ' is not possible. Check reach connectivity.'
4599  call store_error(errmsg)
4600  end if
4601  ! -- iprior
4602  cprior = this%divcprior(jpos)
4603  !
4604  ! -- add terms to the table
4605  if (this%iprpak /= 0) then
4606  call this%inputtab%add_term(n)
4607  call this%inputtab%add_term(idiv)
4608  call this%inputtab%add_term(nn)
4609  call this%inputtab%add_term(cprior)
4610  end if
4611  end do
4612  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 4622 of file gwf-sfr.f90.

4623  class(SfrType) :: this !< SfrType object
4624 
4625  character(len=LINELENGTH) :: title
4626  character(len=LINELENGTH) :: text
4627  character(len=5) :: crch
4628  integer(I4B) :: n
4629  real(DP) :: qman
4630 
4631  ! skip check if storage is not activated
4632  if (this%istorage == 0) return
4633 
4634  ! write header
4635  if (this%iprpak /= 0) then
4636  !
4637  ! -- reset the input table object
4638  title = trim(adjustl(this%text))//' PACKAGE ('// &
4639  trim(adjustl(this%packName))//') REACH INITIAL STAGE DATA'
4640  call table_cr(this%inputtab, this%packName, title)
4641  call this%inputtab%table_df(this%maxbound, 4, this%iout)
4642  text = 'REACH'
4643  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4644  text = 'INITIAL STAGE'
4645  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4646  text = 'INITIAL DEPTH'
4647  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4648  text = 'INITIAL FLOW'
4649  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4650  end if
4651  !
4652  ! -- check that data are correct
4653  do n = 1, this%maxbound
4654  write (crch, '(i5)') n
4655 
4656  ! calculate the initial flows
4657  call this%sfr_calc_qman(n, this%depth(n), qman)
4658  this%usinflow(n) = qman
4659  this%dsflow(n) = qman
4660 
4661  ! add terms to the table
4662  if (this%iprpak /= 0) then
4663  call this%inputtab%add_term(n)
4664  call this%inputtab%add_term(this%stage(n))
4665  call this%inputtab%add_term(this%depth(n))
4666  call this%inputtab%add_term(qman)
4667  end if
4668  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 4121 of file gwf-sfr.f90.

4122  ! -- dummy
4123  class(SfrType) :: this !< SfrType object
4124  ! -- local
4125  character(len=5) :: crch
4126  character(len=10) :: cval
4127  character(len=30) :: nodestr
4128  character(len=LINELENGTH) :: title
4129  character(len=LINELENGTH) :: text
4130  integer(I4B) :: n
4131  integer(I4B) :: nn
4132  real(DP) :: btgwf
4133  real(DP) :: bt
4134  !
4135  ! -- setup inputtab tableobj
4136  if (this%iprpak /= 0) then
4137  title = trim(adjustl(this%text))//' PACKAGE ('// &
4138  trim(adjustl(this%packName))//') STATIC REACH DATA'
4139  call table_cr(this%inputtab, this%packName, title)
4140  call this%inputtab%table_df(this%maxbound, 10, this%iout)
4141  text = 'NUMBER'
4142  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4143  text = 'CELLID'
4144  call this%inputtab%initialize_column(text, 20, alignment=tableft)
4145  text = 'LENGTH'
4146  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4147  text = 'WIDTH'
4148  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4149  text = 'SLOPE'
4150  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4151  text = 'TOP'
4152  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4153  text = 'THICKNESS'
4154  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4155  text = 'HK'
4156  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4157  text = 'ROUGHNESS'
4158  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4159  text = 'UPSTREAM FRACTION'
4160  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4161  end if
4162  !
4163  ! -- check the reach data for simple errors
4164  do n = 1, this%maxbound
4165  write (crch, '(i5)') n
4166  nn = this%igwfnode(n)
4167  if (nn > 0) then
4168  btgwf = this%dis%bot(nn)
4169  call this%dis%noder_to_string(nn, nodestr)
4170  else
4171  nodestr = 'none'
4172  end if
4173  ! -- check reach length
4174  if (this%length(n) <= dzero) then
4175  errmsg = 'Reach '//crch//' length must be greater than 0.0.'
4176  call store_error(errmsg)
4177  end if
4178  ! -- check reach width
4179  if (this%width(n) <= dzero) then
4180  errmsg = 'Reach '//crch//' width must be greater than 0.0.'
4181  call store_error(errmsg)
4182  end if
4183  ! -- check reach slope
4184  if (this%slope(n) <= dzero) then
4185  errmsg = 'Reach '//crch//' slope must be greater than 0.0.'
4186  call store_error(errmsg)
4187  end if
4188  ! -- check bed thickness and bed hk for reaches connected to GWF
4189  if (nn > 0) then
4190  bt = this%strtop(n) - this%bthick(n)
4191  if (bt <= btgwf .and. this%icheck /= 0) then
4192  write (cval, '(f10.4)') bt
4193  errmsg = 'Reach '//crch//' bed bottom (rtp-rbth ='// &
4194  cval//') must be greater than the bottom of cell ('// &
4195  nodestr
4196  write (cval, '(f10.4)') btgwf
4197  errmsg = trim(adjustl(errmsg))//'='//cval//').'
4198  call store_error(errmsg)
4199  end if
4200  if (this%hk(n) < dzero) then
4201  errmsg = 'Reach '//crch//' hk must be greater than or equal to 0.0.'
4202  call store_error(errmsg)
4203  end if
4204  end if
4205  ! -- check reach roughness
4206  if (this%rough(n) <= dzero) then
4207  errmsg = 'Reach '//crch//" Manning's roughness "// &
4208  'coefficient must be greater than 0.0.'
4209  call store_error(errmsg)
4210  end if
4211  ! -- check reach upstream fraction
4212  if (this%ustrf(n) < dzero) then
4213  errmsg = 'Reach '//crch//' upstream fraction must be greater '// &
4214  'than or equal to 0.0.'
4215  call store_error(errmsg)
4216  end if
4217  ! -- write summary of reach information
4218  if (this%iprpak /= 0) then
4219  call this%inputtab%add_term(n)
4220  call this%inputtab%add_term(nodestr)
4221  call this%inputtab%add_term(this%length(n))
4222  call this%inputtab%add_term(this%width(n))
4223  call this%inputtab%add_term(this%slope(n))
4224  call this%inputtab%add_term(this%strtop(n))
4225  call this%inputtab%add_term(this%bthick(n))
4226  call this%inputtab%add_term(this%hk(n))
4227  call this%inputtab%add_term(this%rough(n))
4228  call this%inputtab%add_term(this%ustrf(n))
4229  end if
4230  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 4097 of file gwf-sfr.f90.

4098  ! -- dummy
4099  class(SfrType) :: this !< SfrType object
4100  ! -- formats
4101  character(len=*), parameter :: fmtweight = &
4102  &"(1x,'SFR PACKAGE (',a,') SETTING DEFAULT',&
4103  &/4x,'STORAGE_WEIGHT VALUE (',g0,').',/)"
4104  !
4105  ! -- set storage weight if it has not been defined yet
4106  if (this%istorage == 1) then
4107  if (this%storage_weight == dnodata) then
4108  this%storage_weight = done
4109  write (this%iout, fmtweight) &
4110  trim(adjustl(this%packName)), this%storage_weight
4111  end if
4112  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 4677 of file gwf-sfr.f90.

4678  ! -- dummy
4679  class(SfrType) :: this !< SfrType object
4680  ! -- local
4681  character(len=LINELENGTH) :: title
4682  character(len=LINELENGTH) :: text
4683  logical(LGP) :: lcycle
4684  logical(LGP) :: ladd
4685  character(len=5) :: crch
4686  character(len=5) :: crch2
4687  character(len=10) :: cval
4688  integer(I4B) :: maxcols
4689  integer(I4B) :: npairs
4690  integer(I4B) :: ipair
4691  integer(I4B) :: i
4692  integer(I4B) :: n
4693  integer(I4B) :: n2
4694  integer(I4B) :: idiv
4695  integer(I4B) :: i0
4696  integer(I4B) :: i1
4697  integer(I4B) :: jpos
4698  integer(I4B) :: ids
4699  real(DP) :: f
4700  real(DP) :: rval
4701  !
4702  ! -- write table header
4703  if (this%iprpak /= 0) then
4704  !
4705  ! -- determine the maximum number of columns
4706  npairs = 0
4707  do n = 1, this%maxbound
4708  ipair = 0
4709  ec: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4710  !
4711  ! -- skip upstream connections
4712  if (this%idir(i) > 0) cycle ec
4713  n2 = this%ja(i)
4714  !
4715  ! -- skip inactive downstream reaches
4716  if (this%iboundpak(n2) == 0) cycle ec
4717  !
4718  ! -- increment ipair and see if it exceeds npairs
4719  ipair = ipair + 1
4720  npairs = max(npairs, ipair)
4721  end do ec
4722  end do
4723  maxcols = 1 + npairs * 2
4724  !
4725  ! -- reset the input table object
4726  title = trim(adjustl(this%text))//' PACKAGE ('// &
4727  trim(adjustl(this%packName))//') CONNECTED REACH UPSTREAM '// &
4728  'FRACTION DATA'
4729  call table_cr(this%inputtab, this%packName, title)
4730  call this%inputtab%table_df(this%maxbound, maxcols, this%iout)
4731  text = 'REACH'
4732  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4733  do i = 1, npairs
4734  write (cval, '(i10)') i
4735  text = 'DOWNSTREAM REACH '//trim(adjustl(cval))
4736  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
4737  text = 'FRACTION '//trim(adjustl(cval))
4738  call this%inputtab%initialize_column(text, 12, alignment=tabcenter)
4739  end do
4740  end if
4741  !
4742  ! -- fill diversion number for each connection
4743  do n = 1, this%maxbound
4744  do idiv = 1, this%ndiv(n)
4745  i0 = this%iadiv(n)
4746  i1 = this%iadiv(n + 1) - 1
4747  do jpos = i0, i1
4748  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4749  n2 = this%ja(i)
4750  if (this%divreach(jpos) == n2) then
4751  this%idiv(i) = jpos - i0 + 1
4752  exit
4753  end if
4754  end do
4755  end do
4756  end do
4757  end do
4758  !
4759  ! -- check that the upstream fraction for reach connected by
4760  ! a diversion is zero
4761  do n = 1, this%maxbound
4762  !
4763  ! -- determine the number of downstream reaches
4764  ids = 0
4765  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4766  if (this%idir(i) < 0) then
4767  ids = ids + 1
4768  end if
4769  end do
4770  !
4771  ! -- evaluate the diversions
4772  do idiv = 1, this%ndiv(n)
4773  jpos = this%iadiv(n) + idiv - 1
4774  n2 = this%divreach(jpos)
4775  f = this%ustrf(n2)
4776  if (f /= dzero) then
4777  write (errmsg, '(a,2(1x,i0,1x,a),1x,a,g0,a,2(1x,a))') &
4778  'Reach', n, 'is connected to reach', n2, 'by a diversion', &
4779  'but the upstream fraction is not equal to zero (', f, '). Check', &
4780  trim(this%packName), 'package diversion and package data.'
4781  if (ids > 1) then
4782  call store_error(errmsg)
4783  else
4784  write (warnmsg, '(a,3(1x,a))') &
4785  trim(warnmsg), &
4786  'A warning instead of an error is issued because', &
4787  'the reach is only connected to the diversion reach in the ', &
4788  'downstream direction.'
4789  call store_warning(warnmsg)
4790  end if
4791  end if
4792  end do
4793  end do
4794  !
4795  ! -- calculate the total fraction of connected reaches that are
4796  ! not diversions and check that the sum of upstream fractions
4797  ! is equal to 1 for each reach
4798  do n = 1, this%maxbound
4799  ids = 0
4800  rval = dzero
4801  f = dzero
4802  write (crch, '(i5)') n
4803  if (this%iprpak /= 0) then
4804  call this%inputtab%add_term(n)
4805  end if
4806  ipair = 0
4807  eachconn: do i = this%ia(n) + 1, this%ia(n + 1) - 1
4808  lcycle = .false.
4809  !
4810  ! -- initialize downstream connection q
4811  this%qconn(i) = dzero
4812  !
4813  ! -- skip upstream connections
4814  if (this%idir(i) > 0) then
4815  lcycle = .true.
4816  end if
4817  n2 = this%ja(i)
4818  !
4819  ! -- skip inactive downstream reaches
4820  if (this%iboundpak(n2) == 0) then
4821  lcycle = .true.
4822  end if
4823  if (lcycle) then
4824  cycle eachconn
4825  end if
4826  ipair = ipair + 1
4827  write (crch2, '(i5)') n2
4828  ids = ids + 1
4829  ladd = .true.
4830  f = f + this%ustrf(n2)
4831  write (cval, '(f10.4)') this%ustrf(n2)
4832  !
4833  ! -- write upstream fractions
4834  if (this%iprpak /= 0) then
4835  call this%inputtab%add_term(n2)
4836  call this%inputtab%add_term(this%ustrf(n2))
4837  end if
4838  eachdiv: do idiv = 1, this%ndiv(n)
4839  jpos = this%iadiv(n) + idiv - 1
4840  if (this%divreach(jpos) == n2) then
4841  ladd = .false.
4842  exit eachdiv
4843  end if
4844  end do eachdiv
4845  if (ladd) then
4846  rval = rval + this%ustrf(n2)
4847  end if
4848  end do eachconn
4849  this%ftotnd(n) = rval
4850  !
4851  ! -- write remaining table columns
4852  if (this%iprpak /= 0) then
4853  ipair = ipair + 1
4854  do i = ipair, npairs
4855  call this%inputtab%add_term(' ')
4856  call this%inputtab%add_term(' ')
4857  end do
4858  end if
4859  !
4860  ! -- evaluate if an error condition has occurred
4861  ! the sum of fractions is not equal to 1
4862  if (ids /= 0) then
4863  if (abs(f - done) > dem6) then
4864  write (errmsg, '(a,1x,i0,1x,a,g0,a,3(1x,a))') &
4865  'Upstream fractions for reach ', n, 'is not equal to one (', f, &
4866  '). Check', trim(this%packName), 'package reach connectivity and', &
4867  'package data.'
4868  call store_error(errmsg)
4869  end if
4870  end if
4871  end do
Here is the call graph for this function:

◆ sfr_cq()

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

Calculate the flow between connected SFR package control volumes.

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

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

2426  ! -- modules
2427  use budgetmodule, only: budgettype
2428  ! -- dummy
2429  class(SfrType), intent(inout) :: this !< SfrType object
2430  real(DP), dimension(:), intent(in) :: x !< current dependent-variable value
2431  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
2432  integer(I4B), optional, intent(in) :: iadv !< flag that indicates if this is an advance package
2433  ! -- local
2434  integer(I4B) :: i
2435  real(DP) :: qext
2436  ! -- for budget
2437  integer(I4B) :: n
2438  integer(I4B) :: n2
2439  real(DP) :: qoutflow
2440  real(DP) :: qfrommvr
2441  real(DP) :: qtomvr
2442  !
2443  ! -- call base functionality in bnd_cq. This will calculate sfr-gwf flows
2444  ! and put them into this%simvals
2445  call this%BndType%bnd_cq(x, flowja, iadv=1)
2446  !
2447  ! -- Calculate qextoutflow and qoutflow for subsequent budgets
2448  do n = 1, this%maxbound
2449  !
2450  ! -- mover
2451  qfrommvr = dzero
2452  qtomvr = dzero
2453  if (this%imover == 1) then
2454  qfrommvr = this%pakmvrobj%get_qfrommvr(n)
2455  qtomvr = this%pakmvrobj%get_qtomvr(n)
2456  if (qtomvr > dzero) then
2457  qtomvr = -qtomvr
2458  end if
2459  end if
2460  !
2461  ! -- external downstream stream flow
2462  qext = this%dsflow(n)
2463  qoutflow = dzero
2464  if (qext > dzero) then
2465  qext = -qext
2466  end if
2467  do i = this%ia(n) + 1, this%ia(n + 1) - 1
2468  if (this%idir(i) > 0) cycle
2469  n2 = this%ja(i)
2470  if (this%iboundpak(n2) == 0) cycle
2471  qext = dzero
2472  exit
2473  end do
2474  !
2475  ! -- adjust external downstream stream flow using qtomvr
2476  if (qext < dzero) then
2477  if (qtomvr < dzero) then
2478  qext = qext - qtomvr
2479  end if
2480  else
2481  qoutflow = this%dsflow(n)
2482  if (qoutflow > dzero) then
2483  qoutflow = -qoutflow
2484  end if
2485  end if
2486  !
2487  ! -- set qextoutflow and qoutflow for cell by cell budget
2488  ! output and observations
2489  this%qextoutflow(n) = qext
2490  this%qoutflow(n) = qoutflow
2491  !
2492  end do
2493  !
2494  ! -- fill the budget object
2495  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 363 of file gwf-sfr.f90.

365  ! -- modules
367  ! -- dummy
368  class(BndType), pointer :: packobj !< pointer to default package type
369  integer(I4B), intent(in) :: id !< package id
370  integer(I4B), intent(in) :: ibcnum !< boundary condition number
371  integer(I4B), intent(in) :: inunit !< unit number of SFR package input file
372  integer(I4B), intent(in) :: iout !< unit number of model listing file
373  character(len=*), intent(in) :: namemodel !< model name
374  character(len=*), intent(in) :: pakname !< package name
375  character(len=*), intent(in) :: mempath !< input mempath
376  ! -- local
377  type(SfrType), pointer :: sfrobj
378  !
379  ! -- allocate the object and assign values to object variables
380  allocate (sfrobj)
381  packobj => sfrobj
382  !
383  ! -- create name and memory path
384  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
385  packobj%text = text
386  !
387  ! -- allocate scalars
388  call sfrobj%sfr_allocate_scalars()
389  !
390  ! -- initialize package
391  call packobj%pack_initialize()
392 
393  packobj%inunit = inunit
394  packobj%iout = iout
395  packobj%id = id
396  packobj%ibcnum = ibcnum
397  packobj%ncolbnd = 4
398  packobj%iscloc = 0 ! not supported
399  packobj%isadvpak = 1
400  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 2782 of file gwf-sfr.f90.

2783  ! -- modules
2785  ! -- dummy
2786  class(SfrType) :: this !< SfrType object
2787  !
2788  ! -- deallocate arrays
2789  call mem_deallocate(this%qoutflow)
2790  call mem_deallocate(this%qextoutflow)
2791  deallocate (this%csfrbudget)
2792  call mem_deallocate(this%sfrname, 'SFRNAME', this%memoryPath)
2793  call mem_deallocate(this%dbuff)
2794  deallocate (this%cauxcbc)
2795  call mem_deallocate(this%qauxcbc)
2796  call mem_deallocate(this%iboundpak)
2797  call mem_deallocate(this%igwfnode)
2798  call mem_deallocate(this%igwftopnode)
2799  call mem_deallocate(this%length)
2800  call mem_deallocate(this%width)
2801  call mem_deallocate(this%strtop)
2802  call mem_deallocate(this%bthick)
2803  call mem_deallocate(this%slope)
2804  call mem_deallocate(this%nconnreach)
2805  call mem_deallocate(this%bedk_set)
2806  call mem_deallocate(this%manning_set)
2807  call mem_deallocate(this%ustrf_set)
2808  call mem_deallocate(this%ftotnd)
2809  call mem_deallocate(this%usflow)
2810  call mem_deallocate(this%dsflow)
2811  call mem_deallocate(this%depth)
2812  call mem_deallocate(this%stage)
2813  call mem_deallocate(this%gwflow)
2814  call mem_deallocate(this%simevap)
2815  call mem_deallocate(this%simrunoff)
2816  call mem_deallocate(this%stage0)
2817  call mem_deallocate(this%usflow0)
2818  call mem_deallocate(this%denseterms)
2819  call mem_deallocate(this%viscratios)
2820  !
2821  ! -- stage, usflow, and dsflow for previous timestep
2822  if (this%istorage == 1) then
2823  call mem_deallocate(this%stageold)
2824  call mem_deallocate(this%dsflowold)
2825  call mem_deallocate(this%storage)
2826  call mem_deallocate(this%usinflow)
2827  call mem_deallocate(this%usinflowold)
2828  call mem_deallocate(this%crmin)
2829  call mem_deallocate(this%crmax)
2830  call mem_deallocate(this%crsum)
2831  call mem_deallocate(this%crcnt)
2832  call mem_deallocate(this%itvd_upstream)
2833  end if
2834  !
2835  ! -- deallocate reach order and connection data
2836  call mem_deallocate(this%isfrorder)
2837  call mem_deallocate(this%ia)
2838  call mem_deallocate(this%ja)
2839  call mem_deallocate(this%idir)
2840  call mem_deallocate(this%idiv)
2841  call mem_deallocate(this%qconn)
2842  !
2843  nullify (this%rain)
2844  nullify (this%evap)
2845  nullify (this%inflow)
2846  nullify (this%runoff)
2847  nullify (this%sstage)
2848  nullify (this%hk)
2849  nullify (this%rough)
2850  nullify (this%ustrf)
2851  !
2852  ! -- deallocate diversion variables
2853  call mem_deallocate(this%iadiv)
2854  call mem_deallocate(this%divreach)
2855  if (associated(this%divcprior)) then
2856  deallocate (this%divcprior)
2857  end if
2858  nullify (this%divflow)
2859  call mem_deallocate(this%divq)
2860  call mem_deallocate(this%ndiv)
2861  !
2862  ! -- deallocate cross-section data
2863  call mem_deallocate(this%ncrosspts)
2864  call mem_deallocate(this%iacross)
2865  call mem_deallocate(this%station)
2866  call mem_deallocate(this%xsheight)
2867  call mem_deallocate(this%xsrough)
2868  !
2869  ! -- deallocate budobj
2870  call this%budobj%budgetobject_da()
2871  deallocate (this%budobj)
2872  nullify (this%budobj)
2873  !
2874  ! -- deallocate stage table
2875  if (this%iprhed > 0) then
2876  call this%stagetab%table_da()
2877  deallocate (this%stagetab)
2878  nullify (this%stagetab)
2879  end if
2880  !
2881  ! -- deallocate Courant number table
2882  if (associated(this%couranttab)) then
2883  call this%couranttab%table_da()
2884  deallocate (this%couranttab)
2885  nullify (this%couranttab)
2886  end if
2887  !
2888  ! -- deallocate package csv table
2889  if (this%ipakcsv > 0) then
2890  if (associated(this%pakcsvtab)) then
2891  call this%pakcsvtab%table_da()
2892  deallocate (this%pakcsvtab)
2893  nullify (this%pakcsvtab)
2894  end if
2895  end if
2896  !
2897  ! -- deallocate scalars
2898  call mem_deallocate(this%ats_courant)
2899  call mem_deallocate(this%istorage)
2900  call mem_deallocate(this%storage_weight)
2901  call mem_deallocate(this%iprhed)
2902  call mem_deallocate(this%istageout)
2903  call mem_deallocate(this%ibudgetout)
2904  call mem_deallocate(this%ibudcsv)
2905  call mem_deallocate(this%ipakcsv)
2906  call mem_deallocate(this%idiversions)
2907  call mem_deallocate(this%maxsfrpicard)
2908  call mem_deallocate(this%maxsfrit)
2909  call mem_deallocate(this%bditems)
2910  call mem_deallocate(this%cbcauxitems)
2911  call mem_deallocate(this%unitconv)
2912  call mem_deallocate(this%lengthconv)
2913  call mem_deallocate(this%timeconv)
2914  call mem_deallocate(this%dmaxchg)
2915  call mem_deallocate(this%deps)
2916  call mem_deallocate(this%nconn)
2917  call mem_deallocate(this%icheck)
2918  call mem_deallocate(this%iconvchk)
2919  call mem_deallocate(this%idense)
2920  call mem_deallocate(this%ianynone)
2921  call mem_deallocate(this%ncrossptstot)
2922  nullify (this%gwfiss)
2923  !
2924  ! -- nullify SFR input context pointers (input context owns the memory)
2925  call this%input%destroy()
2926  !
2927  ! -- call base BndExtType deallocate
2928  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 3010 of file gwf-sfr.f90.

3011  ! -- dummy
3012  class(SfrType) :: this !< SfrType object
3013  ! -- local
3014  integer(I4B) :: indx
3015  !
3016  ! -- Store obs type and assign procedure pointer
3017  ! for stage observation type.
3018  call this%obs%StoreObsType('stage', .false., indx)
3019  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3020  !
3021  ! -- Store obs type and assign procedure pointer
3022  ! for inflow observation type.
3023  call this%obs%StoreObsType('inflow', .true., indx)
3024  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3025  !
3026  ! -- Store obs type and assign procedure pointer
3027  ! for inflow observation type.
3028  call this%obs%StoreObsType('ext-inflow', .true., indx)
3029  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3030  !
3031  ! -- Store obs type and assign procedure pointer
3032  ! for rainfall observation type.
3033  call this%obs%StoreObsType('rainfall', .true., indx)
3034  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3035  !
3036  ! -- Store obs type and assign procedure pointer
3037  ! for runoff observation type.
3038  call this%obs%StoreObsType('runoff', .true., indx)
3039  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3040  !
3041  ! -- Store obs type and assign procedure pointer
3042  ! for evaporation observation type.
3043  call this%obs%StoreObsType('evaporation', .true., indx)
3044  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3045  !
3046  ! -- Store obs type and assign procedure pointer
3047  ! for outflow observation type.
3048  call this%obs%StoreObsType('outflow', .true., indx)
3049  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3050  !
3051  ! -- Store obs type and assign procedure pointer
3052  ! for ext-outflow observation type.
3053  call this%obs%StoreObsType('ext-outflow', .true., indx)
3054  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3055  !
3056  ! -- Store obs type and assign procedure pointer
3057  ! for to-mvr observation type.
3058  call this%obs%StoreObsType('to-mvr', .true., indx)
3059  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3060  !
3061  ! -- Store obs type and assign procedure pointer
3062  ! for sfr-frommvr observation type.
3063  call this%obs%StoreObsType('from-mvr', .true., indx)
3064  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3065  !
3066  ! -- Store obs type and assign procedure pointer
3067  ! for sfr observation type.
3068  call this%obs%StoreObsType('sfr', .true., indx)
3069  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3070  !
3071  ! -- Store obs type and assign procedure pointer
3072  ! for upstream flow observation type.
3073  call this%obs%StoreObsType('upstream-flow', .true., indx)
3074  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3075  !
3076  ! -- Store obs type and assign procedure pointer
3077  ! for downstream flow observation type.
3078  call this%obs%StoreObsType('downstream-flow', .true., indx)
3079  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3080  !
3081  ! -- Store obs type and assign procedure pointer
3082  ! for depth observation type.
3083  call this%obs%StoreObsType('depth', .false., indx)
3084  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3085  !
3086  ! -- Store obs type and assign procedure pointer
3087  ! for wetted-perimeter observation type.
3088  call this%obs%StoreObsType('wet-perimeter', .false., indx)
3089  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3090  !
3091  ! -- Store obs type and assign procedure pointer
3092  ! for wetted-area observation type.
3093  call this%obs%StoreObsType('wet-area', .false., indx)
3094  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid
3095  !
3096  ! -- Store obs type and assign procedure pointer
3097  ! for wetted-width observation type.
3098  call this%obs%StoreObsType('wet-width', .false., indx)
3099  this%obs%obsData(indx)%ProcessIdPtr => sfr_process_obsid

◆ sfr_dt()

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

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

2718  ! -- modules
2719  use tdismodule, only: kstp, kper, ats
2720  ! -- dummy
2721  class(SfrType) :: this !< SfrType object
2722  ! -- local
2723  integer(I4B) :: n
2724  integer(I4B) :: nrmin
2725  real(DP) :: celerity
2726  real(DP) :: dt_n
2727  real(DP) :: dtmin
2728  character(len=LINELENGTH) :: msg
2729  !
2730  if (this%ats_courant == dnodata) return
2731  if (this%istorage /= 1) return
2732  !
2733  dtmin = dnodata
2734  nrmin = 0
2735  !
2736  do n = 1, this%maxbound
2737  call this%sfr_calc_celerity(n, this%dsflow(n), celerity)
2738  if (celerity > dzero) then
2739  dt_n = this%ats_courant * this%length(n) / celerity
2740  if (dt_n < dtmin) then
2741  dtmin = dt_n
2742  nrmin = n
2743  end if
2744  end if
2745  end do
2746  !
2747  if (nrmin > 0) then
2748  write (msg, '(a,i0)') trim(this%packName)//'-REACH-', nrmin
2749  call ats%ats_submit_delt(kstp, kper, dtmin, trim(msg))
2750  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 2074 of file gwf-sfr.f90.

2075  ! -- dummy
2076  class(SfrType) :: this !< SfrType object
2077  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2078  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2079  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2080  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2081  ! -- local
2082  integer(I4B) :: i
2083  integer(I4B) :: j
2084  integer(I4B) :: n
2085  integer(I4B) :: ipos
2086  integer(I4B) :: node
2087  real(DP) :: s0
2088  real(DP) :: ds
2089  real(DP) :: dsmax
2090  real(DP) :: hgwf
2091  real(DP) :: v
2092  real(DP) :: hhcof
2093  real(DP) :: rrhs
2094  !
2095  ! -- picard iterations for sfr to achieve good solution regardless
2096  ! of reach order
2097  sfrpicard: do i = 1, this%maxsfrpicard
2098  !
2099  ! -- initialize maximum stage change for iteration to zero
2100  dsmax = dzero
2101  !
2102  ! -- pakmvrobj fc - reset qformvr to zero
2103  if (this%imover == 1) then
2104  call this%pakmvrobj%fc()
2105  end if
2106  !
2107  ! -- solve for each sfr reach
2108  reachsolve: do j = 1, this%nbound
2109  n = this%isfrorder(j)
2110  node = this%igwfnode(n)
2111  if (node > 0) then
2112  hgwf = this%xnew(node)
2113  else
2114  hgwf = dep20
2115  end if
2116  !
2117  ! -- save previous stage and upstream flow
2118  if (i == 1) then
2119  this%stage0(n) = this%stage(n)
2120  this%usflow0(n) = this%usflow(n)
2121  end if
2122  !
2123  ! -- set initial stage to calculate stage change
2124  s0 = this%stage(n)
2125  !
2126  ! -- solve for flow in swr
2127  if (this%iboundpak(n) /= 0) then
2128  call this%sfr_solve(n, hgwf, hhcof, rrhs)
2129  else
2130  this%depth(n) = dzero
2131  this%stage(n) = this%strtop(n)
2132  v = dzero
2133  call this%sfr_update_flows(n, v, v)
2134  hhcof = dzero
2135  rrhs = dzero
2136  end if
2137  !
2138  ! -- set package hcof and rhs
2139  this%hcof(n) = hhcof
2140  this%rhs(n) = rrhs
2141  !
2142  ! -- calculate stage change
2143  ds = s0 - this%stage(n)
2144  !
2145  ! -- evaluate if stage change exceeds dsmax
2146  if (abs(ds) > abs(dsmax)) then
2147  dsmax = ds
2148  end if
2149 
2150  end do reachsolve
2151  !
2152  ! -- evaluate if the sfr picard iterations should be terminated
2153  if (abs(dsmax) <= this%dmaxchg) then
2154  exit sfrpicard
2155  end if
2156 
2157  end do sfrpicard
2158  !
2159  ! -- Copy package rhs and hcof into solution rhs and amat
2160  do n = 1, this%nbound
2161  node = this%nodelist(n)
2162  if (node < 1) cycle
2163  rhs(node) = rhs(node) + this%rhs(n)
2164  ipos = ia(node)
2165  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(n))
2166  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 5117 of file gwf-sfr.f90.

5118  ! -- dummy
5119  class(SfrType) :: this !< SfrType object
5120  ! -- local
5121  integer(I4B) :: naux
5122  integer(I4B) :: i
5123  integer(I4B) :: n
5124  integer(I4B) :: n1
5125  integer(I4B) :: n2
5126  integer(I4B) :: ii
5127  integer(I4B) :: idx
5128  integer(I4B) :: idiv
5129  integer(I4B) :: jpos
5130  real(DP) :: q
5131  real(DP) :: qt
5132  real(DP) :: d
5133  real(DP) :: ca
5134  real(DP) :: a
5135  real(DP) :: wp
5136  real(DP) :: l
5137  !
5138  ! -- initialize counter
5139  idx = 0
5140  !
5141  ! -- FLOW JA FACE
5142  idx = idx + 1
5143  call this%budobj%budterm(idx)%reset(this%nconn)
5144  do n = 1, this%maxbound
5145  n1 = n
5146  q = dzero
5147  ca = dzero
5148  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5149  n2 = this%ja(i)
5150  if (this%iboundpak(n) /= 0) then
5151  ! flow to downstream reaches
5152  if (this%idir(i) < 0) then
5153  qt = this%dsflow(n)
5154  q = -this%qconn(i)
5155  ! flow from upstream reaches
5156  else
5157  qt = this%usflow(n)
5158  do ii = this%ia(n2) + 1, this%ia(n2 + 1) - 1
5159  if (this%idir(ii) > 0) cycle
5160  if (this%ja(ii) /= n) cycle
5161  q = this%qconn(ii)
5162  exit
5163  end do
5164  end if
5165  ! calculate flow area
5166  call this%sfr_calc_reach_depth(n, qt, d)
5167  ca = this%calc_area_wet(n, d)
5168  else
5169  q = dzero
5170  ca = dzero
5171  end if
5172  this%qauxcbc(1) = ca
5173  call this%budobj%budterm(idx)%update_term(n1, n2, q, this%qauxcbc)
5174  end do
5175  end do
5176  !
5177  ! -- GWF (LEAKAGE)
5178  idx = idx + 1
5179  call this%budobj%budterm(idx)%reset(this%maxbound - this%ianynone)
5180  do n = 1, this%maxbound
5181  n2 = this%igwfnode(n)
5182  if (n2 > 0) then
5183  if (this%iboundpak(n) /= 0) then
5184  ! -- calc_perimeter_wet() does not enforce depth dependence
5185  if (this%depth(n) > dzero) then
5186  wp = this%calc_perimeter_wet(n, this%depth(n))
5187  else
5188  wp = dzero
5189  end if
5190  l = this%length(n)
5191  a = wp * l
5192  this%qauxcbc(1) = a
5193  q = -this%gwflow(n)
5194  else
5195  this%qauxcbc(1) = dzero
5196  q = dzero
5197  end if
5198  call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
5199  end if
5200  end do
5201  !
5202  ! -- RAIN
5203  idx = idx + 1
5204  call this%budobj%budterm(idx)%reset(this%maxbound)
5205  do n = 1, this%maxbound
5206  if (this%iboundpak(n) /= 0) then
5207  a = this%calc_surface_area(n)
5208  q = this%rain(n) * a
5209  else
5210  q = dzero
5211  end if
5212  call this%budobj%budterm(idx)%update_term(n, n, q)
5213  end do
5214  !
5215  ! -- EVAPORATION
5216  idx = idx + 1
5217  call this%budobj%budterm(idx)%reset(this%maxbound)
5218  do n = 1, this%maxbound
5219  if (this%iboundpak(n) /= 0) then
5220  q = -this%simevap(n)
5221  else
5222  q = dzero
5223  end if
5224  call this%budobj%budterm(idx)%update_term(n, n, q)
5225  end do
5226  !
5227  ! -- RUNOFF
5228  idx = idx + 1
5229  call this%budobj%budterm(idx)%reset(this%maxbound)
5230  do n = 1, this%maxbound
5231  if (this%iboundpak(n) /= 0) then
5232  q = this%simrunoff(n)
5233  else
5234  q = dzero
5235  end if
5236  call this%budobj%budterm(idx)%update_term(n, n, q)
5237  end do
5238  !
5239  ! -- INFLOW
5240  idx = idx + 1
5241  call this%budobj%budterm(idx)%reset(this%maxbound)
5242  do n = 1, this%maxbound
5243  if (this%iboundpak(n) /= 0) then
5244  q = this%inflow(n)
5245  else
5246  q = dzero
5247  end if
5248  call this%budobj%budterm(idx)%update_term(n, n, q)
5249  end do
5250  !
5251  ! -- EXTERNAL OUTFLOW
5252  idx = idx + 1
5253  call this%budobj%budterm(idx)%reset(this%maxbound)
5254  do n = 1, this%maxbound
5255  q = dzero
5256  if (this%iboundpak(n) /= 0) then
5257  do i = this%ia(n) + 1, this%ia(n + 1) - 1
5258  if (this%idir(i) > 0) cycle
5259  idiv = this%idiv(i)
5260  if (idiv > 0) then
5261  jpos = this%iadiv(n) + idiv - 1
5262  q = q + this%divq(jpos)
5263  else
5264  q = q + this%qconn(i)
5265  end if
5266  end do
5267  q = q - this%dsflow(n)
5268  if (this%imover == 1) then
5269  q = q + this%pakmvrobj%get_qtomvr(n)
5270  end if
5271  else
5272  if (this%imover == 1) then
5273  q = this%pakmvrobj%get_qfrommvr(n)
5274  end if
5275  end if
5276  call this%budobj%budterm(idx)%update_term(n, n, q)
5277  end do
5278  !
5279  ! -- STORAGE
5280  idx = idx + 1
5281  call this%budobj%budterm(idx)%reset(this%maxbound)
5282  do n = 1, this%maxbound
5283  q = dzero
5284  if (this%iboundpak(n) /= 0) then
5285  d = this%depth(n)
5286  a = this%calc_surface_area_wet(n, d)
5287  this%qauxcbc(1) = a * d
5288  if (this%gwfiss == 0 .and. this%istorage == 1) then
5289  q = this%storage(n)
5290  end if
5291  else
5292  q = dzero
5293  this%qauxcbc(1) = dzero
5294  end if
5295  call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
5296  end do
5297  !
5298  ! -- MOVER
5299  if (this%imover == 1) then
5300  !
5301  ! -- FROM MOVER
5302  idx = idx + 1
5303  call this%budobj%budterm(idx)%reset(this%maxbound)
5304  do n = 1, this%maxbound
5305  q = dzero
5306  if (this%iboundpak(n) /= 0) then
5307  q = this%pakmvrobj%get_qfrommvr(n)
5308  end if
5309  call this%budobj%budterm(idx)%update_term(n, n, q)
5310  end do
5311  !
5312  ! -- TO MOVER
5313  idx = idx + 1
5314  call this%budobj%budterm(idx)%reset(this%maxbound)
5315  do n = 1, this%maxbound
5316  if (this%iboundpak(n) /= 0) then
5317  q = this%pakmvrobj%get_qtomvr(n)
5318  if (q > dzero) then
5319  q = -q
5320  end if
5321  else
5322  q = dzero
5323  end if
5324  call this%budobj%budterm(idx)%update_term(n, n, q)
5325  end do
5326  end if
5327  !
5328  ! -- AUXILIARY VARIABLES
5329  naux = this%naux
5330  if (naux > 0) then
5331  idx = idx + 1
5332  call this%budobj%budterm(idx)%reset(this%maxbound)
5333  do n = 1, this%maxbound
5334  q = dzero
5335  call this%budobj%budterm(idx)%update_term(n, n, q, this%auxvar(:, n))
5336  end do
5337  end if
5338  !
5339  ! --Terms are filled, now accumulate them for this time step
5340  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 2174 of file gwf-sfr.f90.

2175  ! -- dummy
2176  class(SfrType) :: this !< SfrType object
2177  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
2178  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
2179  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
2180  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
2181  ! -- local
2182  integer(I4B) :: i
2183  integer(I4B) :: j
2184  integer(I4B) :: n
2185  integer(I4B) :: ipos
2186  real(DP) :: rterm
2187  real(DP) :: drterm
2188  real(DP) :: rhs1
2189  real(DP) :: hcof1
2190  real(DP) :: q1
2191  real(DP) :: q2
2192  real(DP) :: hgwf
2193  !
2194  ! -- Copy package rhs and hcof into solution rhs and amat
2195  do j = 1, this%nbound
2196  i = this%isfrorder(j)
2197  ! -- skip inactive reaches
2198  if (this%iboundpak(i) < 1) cycle
2199  ! -- skip if reach is not connected to gwf
2200  n = this%nodelist(i)
2201  if (n < 1) cycle
2202  ipos = ia(n)
2203  rterm = this%hcof(i) * this%xnew(n)
2204  ! -- calculate perturbed head
2205  hgwf = this%xnew(n) + dem4
2206  call this%sfr_solve(i, hgwf, hcof1, rhs1, update=.false.)
2207  q1 = rhs1 - hcof1 * hgwf
2208  ! -- calculate unperturbed head
2209  q2 = this%rhs(i) - this%hcof(i) * this%xnew(n)
2210  ! -- calculate derivative
2211  drterm = (q2 - q1) / dem4
2212  ! -- add terms to convert conductance formulation into
2213  ! newton-raphson formulation
2214  call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(i))
2215  rhs(n) = rhs(n) - rterm + drterm * this%xnew(n)
2216  end do

◆ sfr_fp()

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

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

2683  ! -- dummy
2684  class(SfrType) :: this !< SfrType object
2685  ! -- local
2686  integer(I4B) :: n
2687  real(DP) :: crmean
2688  !
2689  if (this%istorage == 1) then
2690  do n = 1, this%maxbound
2691  if (this%inamedbound == 1) then
2692  call this%couranttab%add_term(this%boundname(n))
2693  end if
2694  call this%couranttab%add_term(n)
2695  if (this%crmin(n) == dep20) then
2696  call this%couranttab%add_term('--')
2697  else
2698  call this%couranttab%add_term(this%crmin(n))
2699  end if
2700  if (this%crmax(n) < dzero) then
2701  call this%couranttab%add_term('--')
2702  else
2703  call this%couranttab%add_term(this%crmax(n))
2704  end if
2705  if (this%crcnt(n) > 0) then
2706  crmean = this%crsum(n) / real(this%crcnt(n), dp)
2707  call this%couranttab%add_term(crmean)
2708  else
2709  call this%couranttab%add_term('--')
2710  end if
2711  end do
2712  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 3856 of file gwf-sfr.f90.

3857  ! -- return variable
3858  integer(I4B) :: sfr_gwf_conn !< flag indicating if reach is connected to a gwf cell
3859  ! -- dummy
3860  class(SfrType) :: this !< SfrType object
3861  integer(I4B), intent(in) :: n !< reach number
3862  ! -- local
3863  integer(I4B) :: node
3864 
3865  sfr_gwf_conn = 0
3866  node = this%igwfnode(n)
3867  if (node > 0 .and. this%hk(n) > dzero) then
3868  sfr_gwf_conn = 1
3869  end if

◆ sfr_input_destroy()

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

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

5769  class(SfrInputType), intent(inout) :: this
5770  nullify (this%rhk)
5771  nullify (this%man)
5772  nullify (this%ustrf)
5773  nullify (this%nbound)
5774  nullify (this%ifno)
5775  nullify (this%status)
5776  nullify (this%setting)
5777  nullify (this%idv)
5778  nullify (this%tab6_filename)
5779  nullify (this%auxname)
5780  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 5749 of file gwf-sfr.f90.

5750  use memorymanagermodule, only: mem_setptr
5751  class(SfrInputType), intent(inout) :: this
5752  character(len=*), intent(in) :: mempath
5753  integer(I4B), intent(in) :: naux
5754  call mem_setptr(this%nbound, 'NBOUND', mempath)
5755  call mem_setptr(this%ifno, 'IFNO', mempath)
5756  call mem_setptr(this%setting, 'SETTING', mempath)
5757  call mem_setptr(this%status, 'STATUS', mempath)
5758  call mem_setptr(this%idv, 'IDV', mempath)
5759  call mem_setptr(this%tab6_filename, 'TAB6_FILENAME', mempath)
5760  if (naux > 0) then
5761  call mem_setptr(this%auxname, 'AUXNAME', mempath)
5762  call mem_setptr(this%auxval, 'AUXVAL', mempath)
5763  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 2998 of file gwf-sfr.f90.

2999  ! -- dummy
3000  class(SfrType) :: this !< SfrType object
3001  !
3002  ! -- set boolean
3003  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 2667 of file gwf-sfr.f90.

2668  ! -- module
2669  use tdismodule, only: totim, delt
2670  ! -- dummy
2671  class(SfrType) :: this !< SfrType object
2672  integer(I4B), intent(in) :: kstp !< time step number
2673  integer(I4B), intent(in) :: kper !< period number
2674  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
2675  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
2676  !
2677  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 2555 of file gwf-sfr.f90.

2556  ! -- modules
2557  use tdismodule, only: kstp, kper, pertim, totim
2558  use inputoutputmodule, only: ulasav
2559  ! -- dummy
2560  class(SfrType) :: this !< SfrType object
2561  integer(I4B), intent(in) :: idvsave !< flag and unit number for dependent-variable output
2562  integer(I4B), intent(in) :: idvprint !< flag indicating if dependent-variable should be written to the model listing file
2563  ! -- local
2564  character(len=20) :: cellid
2565  integer(I4B) :: ibinun
2566  integer(I4B) :: n
2567  integer(I4B) :: node
2568  real(DP) :: d
2569  real(DP) :: v
2570  real(DP) :: hgwf
2571  real(DP) :: sbot
2572  real(DP) :: depth
2573  real(DP) :: stage
2574  real(DP) :: w
2575  real(DP) :: cond
2576  real(DP) :: grad
2577  !
2578  ! -- set unit number for binary dependent variable output
2579  ibinun = 0
2580  if (this%istageout /= 0) then
2581  ibinun = this%istageout
2582  end if
2583  if (idvsave == 0) ibinun = 0
2584  !
2585  ! -- write sfr binary output
2586  if (ibinun > 0) then
2587  do n = 1, this%maxbound
2588  d = this%depth(n)
2589  v = this%stage(n)
2590  if (this%iboundpak(n) == 0) then
2591  v = dhnoflo
2592  else if (d == dzero) then
2593  v = dhdry
2594  end if
2595  this%dbuff(n) = v
2596  end do
2597  call ulasav(this%dbuff, ' STAGE', kstp, kper, pertim, totim, &
2598  this%maxbound, 1, 1, ibinun)
2599  end if
2600  !
2601  ! -- print sfr stage and depth table
2602  if (idvprint /= 0 .and. this%iprhed /= 0) then
2603  !
2604  ! -- set table kstp and kper
2605  call this%stagetab%set_kstpkper(kstp, kper)
2606  !
2607  ! -- fill stage data
2608  do n = 1, this%maxbound
2609  node = this%igwfnode(n)
2610  if (node > 0) then
2611  call this%dis%noder_to_string(node, cellid)
2612  hgwf = this%xnew(node)
2613  else
2614  cellid = 'NONE'
2615  end if
2616  if (this%inamedbound == 1) then
2617  call this%stagetab%add_term(this%boundname(n))
2618  end if
2619  call this%stagetab%add_term(n)
2620  call this%stagetab%add_term(cellid)
2621  if (this%iboundpak(n) /= 0) then
2622  depth = this%depth(n)
2623  stage = this%stage(n)
2624  w = this%calc_top_width_wet(n, depth)
2625  call this%sfr_calc_cond(n, depth, cond, stage, hgwf)
2626  else
2627  depth = dhnoflo
2628  stage = dhnoflo
2629  w = dhnoflo
2630  cond = dhnoflo
2631  end if
2632  if (depth == dzero) then
2633  call this%stagetab%add_term(dhdry)
2634  else
2635  call this%stagetab%add_term(stage)
2636  end if
2637  call this%stagetab%add_term(depth)
2638  call this%stagetab%add_term(w)
2639  if (node > 0) then
2640  if (this%iboundpak(n) /= 0) then
2641  sbot = this%strtop(n) - this%bthick(n)
2642  if (hgwf < sbot) then
2643  grad = stage - sbot
2644  else
2645  grad = stage - hgwf
2646  end if
2647  grad = grad / this%bthick(n)
2648  else
2649  grad = dhnoflo
2650  end if
2651  call this%stagetab%add_term(hgwf)
2652  call this%stagetab%add_term(cond)
2653  call this%stagetab%add_term(grad)
2654  else
2655  call this%stagetab%add_term('--')
2656  call this%stagetab%add_term('--')
2657  call this%stagetab%add_term('--')
2658  end if
2659  end do
2660  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 2502 of file gwf-sfr.f90.

2503  ! -- modules
2504  use tdismodule, only: kstp, kper, delt, pertim, totim
2505  ! -- dummy
2506  class(SfrType) :: this !< SfrType object
2507  integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output
2508  integer(I4B), intent(in) :: ibudfl !< flag indication if cell-by-cell data should be saved
2509  ! -- local
2510  integer(I4B) :: ibinun
2511  character(len=20), dimension(:), allocatable :: cellidstr
2512  integer(I4B) :: n
2513  integer(I4B) :: node
2514  !
2515  ! -- write the flows from the budobj
2516  ibinun = 0
2517  if (this%ibudgetout /= 0) then
2518  ibinun = this%ibudgetout
2519  end if
2520  if (icbcfl == 0) ibinun = 0
2521  if (ibinun > 0) then
2522  call this%budobj%save_flows(this%dis, ibinun, kstp, kper, delt, &
2523  pertim, totim, this%iout)
2524  end if
2525  !
2526  ! -- Print sfr flows table
2527  if (ibudfl /= 0 .and. this%iprflow /= 0) then
2528  !
2529  ! -- If there are any 'none' gwf connections then need to calculate
2530  ! a vector of cellids and pass that in to the budget flow table because
2531  ! the table assumes that there are maxbound gwf entries, which is not
2532  ! the case if any 'none's are specified.
2533  if (this%ianynone > 0) then
2534  allocate (cellidstr(this%maxbound))
2535  do n = 1, this%maxbound
2536  node = this%igwfnode(n)
2537  if (node > 0) then
2538  call this%dis%noder_to_string(node, cellidstr(n))
2539  else
2540  cellidstr(n) = 'NONE'
2541  end if
2542  end do
2543  call this%budobj%write_flowtable(this%dis, kstp, kper, cellidstr)
2544  deallocate (cellidstr)
2545  else
2546  call this%budobj%write_flowtable(this%dis, kstp, kper)
2547  end if
2548  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 2935 of file gwf-sfr.f90.

2936  ! -- dummy
2937  class(SfrType), intent(inout) :: this !< SfrType object
2938  ! -- local
2939  integer(I4B) :: n
2940  integer(I4B) :: j
2941  integer(I4B) :: iup_count
2942  integer(I4B) :: m
2943  !
2944  do n = 1, this%maxbound
2945  iup_count = 0
2946  m = 0
2947  do j = this%ia(n) + 1, this%ia(n + 1) - 1
2948  if (this%idir(j) > 0) then
2949  iup_count = iup_count + 1
2950  m = this%ja(j)
2951  end if
2952  end do
2953  if (iup_count == 1) then
2954  this%itvd_upstream(n) = m
2955  else
2956  this%itvd_upstream(n) = 0
2957  end if
2958  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 3308 of file gwf-sfr.f90.

3309  ! -- dummy
3310  type(ObserveType), intent(inout) :: obsrv !< Observation object
3311  class(DisBaseType), intent(in) :: dis !< Discretization object
3312  integer(I4B), intent(in) :: inunitobs !< file unit number for the package observation file
3313  integer(I4B), intent(in) :: iout !< model listing file unit number
3314  ! -- local
3315  integer(I4B) :: nn1
3316  integer(I4B) :: icol
3317  integer(I4B) :: istart
3318  integer(I4B) :: istop
3319  character(len=LINELENGTH) :: string
3320  character(len=LENBOUNDNAME) :: bndname
3321  !
3322  ! -- initialize local variables
3323  string = obsrv%IDstring
3324  !
3325  ! -- Extract reach number from string and store it.
3326  ! If 1st item is not an integer(I4B), it should be a
3327  ! boundary name--deal with it.
3328  icol = 1
3329  !
3330  ! -- get reach number or boundary name
3331  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
3332  if (nn1 == namedboundflag) then
3333  obsrv%FeatureName = bndname
3334  end if
3335  !
3336  ! -- store reach number (NodeNumber)
3337  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 1705 of file gwf-sfr.f90.

1706  ! -- modules
1707  use constantsmodule, only: lenvarname
1708  use tdismodule, only: kper
1711  ! -- dummy
1712  class(SfrType), intent(inout) :: this !< SfrType object
1713  ! -- local
1714  character(len=LINELENGTH) :: crossfile
1715  character(len=LINELENGTH) :: str
1716  real(DP) :: auxvaldbl
1717  character(len=LINELENGTH) :: title
1718  character(len=LINELENGTH) :: text
1719  character(len=LENVARNAME) :: setting
1720  character(len=10) :: cnum
1721  character(len=10) :: cp
1722  integer(I4B) :: n
1723  integer(I4B) :: i
1724  integer(I4B) :: ii
1725  integer(I4B) :: jj
1726  integer(I4B) :: idiv
1727  integer(I4B) :: ichkustrm
1728  integer(I4B) :: ncrossptstot
1729  type(SfrCrossSection), pointer :: cross_data => null()
1730  ! -- formats
1731  character(len=*), parameter :: fmtlsp = &
1732  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
1733  !
1734  ! -- initialize flags
1735  ichkustrm = 0
1736  if (kper == 1) then
1737  ichkustrm = 1
1738  end if
1739  !
1740  ! -- set nbound to maxbound
1741  this%nbound = this%maxbound
1742  !
1743  ! -- check if input context has been updated for this stress period
1744  if (this%iper == kper) then
1745  !
1746  ! -- create and initialize cross-section data
1747  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1748  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1749  this%iacross, &
1750  this%station, this%xsheight, &
1751  this%xsrough)
1752  !
1753  ! -- setup table to echo period data
1754  if (this%iprpak /= 0) then
1755  title = trim(adjustl(this%text))//' PACKAGE ('// &
1756  trim(adjustl(this%packName))//') DATA FOR PERIOD'
1757  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
1758  call table_cr(this%inputtab, this%packName, title)
1759  call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
1760  text = 'NUMBER'
1761  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
1762  text = 'KEYWORD'
1763  call this%inputtab%initialize_column(text, 20, alignment=tableft)
1764  do jj = 1, 2
1765  write (text, '(a,1x,i6)') 'VALUE', jj
1766  call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
1767  end do
1768  end if
1769  !
1770  ! -- process each period data entry
1771  do i = 1, this%input%nbound
1772  n = this%input%ifno(i)
1773  if (n < 1 .or. n > this%maxbound) then
1774  write (errmsg, '(a,1x,a,1x,i0,a)') &
1775  'Reach number (RNO) must be greater than 0 and', &
1776  'less than or equal to', this%maxbound, '.'
1777  call store_error(errmsg)
1778  cycle
1779  end if
1780  !
1781  ! -- dispatch key for this row
1782  setting = this%input%setting(i)
1783  !
1784  ! -- STATUS
1785  if (trim(setting) == 'STATUS') then
1786  str = this%input%status(i)
1787  ichkustrm = 1
1788  if (str == 'INACTIVE') then
1789  this%iboundpak(n) = 0
1790  else if (str == 'ACTIVE') then
1791  this%iboundpak(n) = 1
1792  else if (str == 'SIMPLE') then
1793  this%iboundpak(n) = -1
1794  else
1795  write (errmsg, '(2a)') &
1796  'Unknown '//trim(this%text)//' sfr status keyword: ', trim(str)
1797  call store_error(errmsg)
1798  end if
1799  end if
1800  !
1801  ! -- BEDK, MANNING, STAGE, INFLOW, RAINFALL, EVAPORATION, RUNOFF,
1802  ! UPSTREAM_FRAC; sfr_ad re-syncs these each timestep if TS-linked
1803  call this%sfr_set_period_value(i, n, setting)
1804  if (trim(setting) == 'UPSTREAM_FRAC') ichkustrm = 1
1805  !
1806  ! -- DIVERSION (compound group)
1807  if (trim(setting) == 'DIVERSION') then
1808  if (this%ndiv(n) < 1) then
1809  write (cnum, '(i0)') n
1810  errmsg = 'diversions cannot be specified for reach '//trim(cnum)
1811  call store_error(errmsg)
1812  else
1813  idiv = this%input%idv(i)
1814  if (idiv < 1 .or. idiv > this%ndiv(n)) then
1815  write (cnum, '(i0)') n
1816  errmsg = 'Reach '//trim(cnum)
1817  write (cnum, '(i0)') this%ndiv(n)
1818  errmsg = trim(errmsg)//' diversion number should be between 1 '// &
1819  'and '//trim(cnum)//'.'
1820  call store_error(errmsg)
1821  else
1822  ii = this%iadiv(n) + idiv - 1
1823  ! -- if cprior is 'FRACTION', check 0.0 <= divflow <= 1.0
1824  cp = this%divcprior(ii)
1825  if (cp == 'FRACTION' .and. &
1826  (this%divflow(ii) < dzero .or. this%divflow(ii) > done)) then
1827  write (errmsg, '(a,1x,i0,a)') &
1828  'cprior is type FRACTION for diversion no.', ii, &
1829  ', but divflow not within the range 0.0 to 1.0'
1830  call store_error(errmsg)
1831  end if
1832  end if
1833  end if
1834  end if
1835  !
1836  ! -- CROSS_SECTION (compound group)
1837  if (trim(setting) == 'CROSS_SECTION') then
1838  crossfile = this%input%tab6_filename(i)
1839  call cross_data%read_table(n, this%width(n), trim(adjustl(crossfile)))
1840  end if
1841  !
1842  ! -- AUXILIARY (compound group): featureauxvar already holds the
1843  ! -- current value; only extract auxname for echoing this row
1844  if (this%naux > 0) then
1845  if (trim(setting) == 'PERIOD_AUXILIARY') then
1846  str = this%input%auxname(i)
1847  auxvaldbl = this%input%auxval(i)
1848  end if
1849  end if
1850  !
1851  ! -- echo row to period data table
1852  if (this%iprpak /= 0) then
1853  call this%inputtab%add_term(n)
1854  if (trim(setting) == 'PERIOD_AUXILIARY') then
1855  call this%inputtab%add_term('AUXILIARY')
1856  else
1857  call this%inputtab%add_term(trim(setting))
1858  end if
1859  select case (trim(setting))
1860  case ('STATUS')
1861  call this%inputtab%add_term(trim(str))
1862  call this%inputtab%add_term(' ')
1863  case ('BEDK')
1864  call this%inputtab%add_term(this%hk(n))
1865  call this%inputtab%add_term(' ')
1866  case ('MANNING')
1867  call this%inputtab%add_term(this%rough(n))
1868  call this%inputtab%add_term(' ')
1869  case ('STAGE')
1870  call this%inputtab%add_term(this%sstage(n))
1871  call this%inputtab%add_term(' ')
1872  case ('INFLOW')
1873  call this%inputtab%add_term(this%inflow(n))
1874  call this%inputtab%add_term(' ')
1875  case ('RAINFALL')
1876  call this%inputtab%add_term(this%rain(n))
1877  call this%inputtab%add_term(' ')
1878  case ('EVAPORATION')
1879  call this%inputtab%add_term(this%evap(n))
1880  call this%inputtab%add_term(' ')
1881  case ('RUNOFF')
1882  call this%inputtab%add_term(this%runoff(n))
1883  call this%inputtab%add_term(' ')
1884  case ('UPSTREAM_FRAC')
1885  call this%inputtab%add_term(this%ustrf(n))
1886  call this%inputtab%add_term(' ')
1887  case ('DIVERSION')
1888  call this%inputtab%add_term(idiv)
1889  call this%inputtab%add_term(this%divflow(ii))
1890  case ('CROSS_SECTION')
1891  call this%inputtab%add_term(trim(crossfile))
1892  call this%inputtab%add_term(' ')
1893  case ('PERIOD_AUXILIARY')
1894  call this%inputtab%add_term(trim(str))
1895  call this%inputtab%add_term(auxvaldbl)
1896  case default
1897  call this%inputtab%add_term(' ')
1898  call this%inputtab%add_term(' ')
1899  end select
1900  end if
1901  end do
1902  if (this%iprpak /= 0) then
1903  call this%inputtab%finalize_table()
1904  end if
1905  !
1906  ! -- determine the current size of cross-section data
1907  ncrossptstot = cross_data%get_ncrossptstot()
1908  !
1909  ! -- reallocate sfr package cross-section data if size changed
1910  if (ncrossptstot /= this%ncrossptstot) then
1911  this%ncrossptstot = ncrossptstot
1912  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1913  this%memoryPath)
1914  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1915  this%memoryPath)
1916  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1917  this%memoryPath)
1918  end if
1919  !
1920  ! -- write cross-section data to the model listing file
1921  call cross_data%output(this%width, this%rough, kstp=1, kper=kper)
1922  !
1923  ! -- pack cross-section data
1924  call cross_data%pack(this%ncrossptstot, this%ncrosspts, &
1925  this%iacross, &
1926  this%station, &
1927  this%xsheight, &
1928  this%xsrough)
1929  !
1930  ! -- deallocate temporary local storage for reach cross-sections
1931  call cross_data%destroy()
1932  deallocate (cross_data)
1933  nullify (cross_data)
1934  else
1935  write (this%iout, fmtlsp) trim(this%filtyp)
1936  end if
1937  !
1938  ! -- check upstream fraction values every period; ftotnd must be
1939  ! initialized for sfr_update_flows even when there is no period data
1940  if (ichkustrm /= 0) then
1941  call this%sfr_check_ustrf()
1942  end if
1943  !
1944  ! -- write summary of package block error messages
1945  if (count_errors() > 0) then
1946  call store_error_filename(this%input_fname)
1947  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 3198 of file gwf-sfr.f90.

3199  ! -- modules
3200  use tdismodule, only: kper
3201  ! -- dummy
3202  class(SfrType), intent(inout) :: this !< SfrType object
3203  ! -- local
3204  integer(I4B) :: i
3205  integer(I4B) :: j
3206  integer(I4B) :: nn1
3207  character(len=LENBOUNDNAME) :: bname
3208  logical(LGP) :: jfound
3209  class(ObserveType), pointer :: obsrv => null()
3210  ! -- formats
3211 10 format('Boundary "', a, '" for observation "', a, &
3212  '" is invalid in package "', a, '"')
3213 30 format('Boundary name not provided for observation "', a, &
3214  '" in package "', a, '"')
3215  !
3216  ! -- process each package observation
3217  ! only done the first stress period since boundaries are fixed
3218  ! for the simulation
3219  if (kper == 1) then
3220  do i = 1, this%obs%npakobs
3221  obsrv => this%obs%pakobs(i)%obsrv
3222  !
3223  ! -- get node number 1
3224  nn1 = obsrv%NodeNumber
3225  if (nn1 == namedboundflag) then
3226  bname = obsrv%FeatureName
3227  if (bname /= '') then
3228  ! -- Observation location(s) is(are) based on a boundary name.
3229  ! Iterate through all boundaries to identify and store
3230  ! corresponding index(indices) in bound array.
3231  jfound = .false.
3232  do j = 1, this%maxbound
3233  if (this%boundname(j) == bname) then
3234  jfound = .true.
3235  call obsrv%AddObsIndex(j)
3236  end if
3237  end do
3238  if (.not. jfound) then
3239  write (errmsg, 10) &
3240  trim(bname), trim(obsrv%name), trim(this%packName)
3241  call store_error(errmsg)
3242  end if
3243  else
3244  write (errmsg, 30) trim(obsrv%name), trim(this%packName)
3245  call store_error(errmsg)
3246  end if
3247  else if (nn1 < 1 .or. nn1 > this%maxbound) then
3248  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3249  trim(adjustl(obsrv%ObsTypeId)), &
3250  'reach must be greater than 0 and less than or equal to', &
3251  this%maxbound, '(specified value is ', nn1, ')'
3252  call store_error(errmsg)
3253  else
3254  if (obsrv%indxbnds_count == 0) then
3255  call obsrv%AddObsIndex(nn1)
3256  else
3257  errmsg = 'Programming error in sfr_rp_obs'
3258  call store_error(errmsg)
3259  end if
3260  end if
3261  !
3262  ! -- catch non-cumulative observation assigned to observation defined
3263  ! by a boundname that is assigned to more than one element
3264  if (obsrv%ObsTypeId == 'STAGE' .or. &
3265  obsrv%ObsTypeId == 'DEPTH' .or. &
3266  obsrv%ObsTypeId == 'WET-PERIMETER' .or. &
3267  obsrv%ObsTypeId == 'WET-AREA' .or. &
3268  obsrv%ObsTypeId == 'WET-WIDTH') then
3269  nn1 = obsrv%NodeNumber
3270  if (nn1 == namedboundflag) then
3271  if (obsrv%indxbnds_count > 1) then
3272  write (errmsg, '(a,3(1x,a))') &
3273  trim(adjustl(obsrv%ObsTypeId)), &
3274  'for observation', trim(adjustl(obsrv%Name)), &
3275  ' must be assigned to a reach with a unique boundname.'
3276  call store_error(errmsg)
3277  end if
3278  end if
3279  end if
3280  !
3281  ! -- check that node number 1 is valid; call store_error if not
3282  do j = 1, obsrv%indxbnds_count
3283  nn1 = obsrv%indxbnds(j)
3284  if (nn1 < 1 .or. nn1 > this%maxbound) then
3285  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
3286  trim(adjustl(obsrv%ObsTypeId)), &
3287  'reach must be greater than 0 and less than or equal to', &
3288  this%maxbound, '(specified value is ', nn1, ')'
3289  call store_error(errmsg)
3290  end if
3291  end do
3292  end do
3293  !
3294  ! -- evaluate if there are any observation errors
3295  if (count_errors() > 0) then
3296  call store_error_filename(this%input_fname)
3297  end if
3298  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 4879 of file gwf-sfr.f90.

4880  ! -- dummy
4881  class(SfrType), intent(inout) :: this
4882  integer(I4B), intent(in) :: i !< row index into input context arrays
4883  integer(I4B), intent(in) :: n !< reach number
4884  character(len=*), intent(in) :: setting !< uppercase mf6varname dispatch key
4885  !
4886  select case (trim(setting))
4887  case ('BEDK')
4888  this%bedk_set(n) = .true.
4889  case ('MANNING')
4890  this%manning_set(n) = .true.
4891  case ('UPSTREAM_FRAC')
4892  this%ustrf_set(n) = .true.
4893  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 4902 of file gwf-sfr.f90.

4903  ! -- dummy
4904  class(SfrType) :: this !< SfrType object
4905  ! -- local
4906  integer(I4B) :: nbudterm
4907  integer(I4B) :: i
4908  integer(I4B) :: n
4909  integer(I4B) :: n1
4910  integer(I4B) :: n2
4911  integer(I4B) :: maxlist
4912  integer(I4B) :: naux
4913  integer(I4B) :: idx
4914  real(DP) :: q
4915  character(len=LENBUDTXT) :: text
4916  character(len=LENBUDTXT), dimension(1) :: auxtxt
4917  !
4918  ! -- Determine the number of sfr budget terms. These are fixed for
4919  ! the simulation and cannot change. This includes FLOW-JA-FACE
4920  ! so they can be written to the binary budget files, but these internal
4921  ! flows are not included as part of the budget table.
4922  nbudterm = 8
4923  if (this%imover == 1) nbudterm = nbudterm + 2
4924  if (this%naux > 0) nbudterm = nbudterm + 1
4925  !
4926  ! -- set up budobj
4927  call budgetobject_cr(this%budobj, this%packName)
4928  call this%budobj%budgetobject_df(this%maxbound, nbudterm, 0, 0, &
4929  ibudcsv=this%ibudcsv)
4930  idx = 0
4931  !
4932  ! -- Go through and set up each budget term
4933  text = ' FLOW-JA-FACE'
4934  idx = idx + 1
4935  maxlist = this%nconn
4936  naux = 1
4937  auxtxt(1) = ' FLOW-AREA'
4938  call this%budobj%budterm(idx)%initialize(text, &
4939  this%name_model, &
4940  this%packName, &
4941  this%name_model, &
4942  this%packName, &
4943  maxlist, .false., .false., &
4944  naux, auxtxt)
4945  !
4946  ! -- store connectivity
4947  call this%budobj%budterm(idx)%reset(this%nconn)
4948  q = dzero
4949  do n = 1, this%maxbound
4950  n1 = n
4951  do i = this%ia(n) + 1, this%ia(n + 1) - 1
4952  n2 = this%ja(i)
4953  call this%budobj%budterm(idx)%update_term(n1, n2, q)
4954  end do
4955  end do
4956  !
4957  ! --
4958  text = ' GWF'
4959  idx = idx + 1
4960  maxlist = this%maxbound - this%ianynone
4961  naux = 1
4962  auxtxt(1) = ' FLOW-AREA'
4963  call this%budobj%budterm(idx)%initialize(text, &
4964  this%name_model, &
4965  this%packName, &
4966  this%name_model, &
4967  this%name_model, &
4968  maxlist, .false., .true., &
4969  naux, auxtxt)
4970  call this%budobj%budterm(idx)%reset(maxlist)
4971  q = dzero
4972  do n = 1, this%maxbound
4973  n2 = this%igwfnode(n)
4974  if (n2 > 0) then
4975  call this%budobj%budterm(idx)%update_term(n, n2, q)
4976  end if
4977  end do
4978  !
4979  ! --
4980  text = ' RAINFALL'
4981  idx = idx + 1
4982  maxlist = this%maxbound
4983  naux = 0
4984  call this%budobj%budterm(idx)%initialize(text, &
4985  this%name_model, &
4986  this%packName, &
4987  this%name_model, &
4988  this%packName, &
4989  maxlist, .false., .false., &
4990  naux)
4991  !
4992  ! --
4993  text = ' EVAPORATION'
4994  idx = idx + 1
4995  maxlist = this%maxbound
4996  naux = 0
4997  call this%budobj%budterm(idx)%initialize(text, &
4998  this%name_model, &
4999  this%packName, &
5000  this%name_model, &
5001  this%packName, &
5002  maxlist, .false., .false., &
5003  naux)
5004  !
5005  ! --
5006  text = ' RUNOFF'
5007  idx = idx + 1
5008  maxlist = this%maxbound
5009  naux = 0
5010  call this%budobj%budterm(idx)%initialize(text, &
5011  this%name_model, &
5012  this%packName, &
5013  this%name_model, &
5014  this%packName, &
5015  maxlist, .false., .false., &
5016  naux)
5017  !
5018  ! --
5019  text = ' EXT-INFLOW'
5020  idx = idx + 1
5021  maxlist = this%maxbound
5022  naux = 0
5023  call this%budobj%budterm(idx)%initialize(text, &
5024  this%name_model, &
5025  this%packName, &
5026  this%name_model, &
5027  this%packName, &
5028  maxlist, .false., .false., &
5029  naux)
5030  !
5031  ! --
5032  text = ' EXT-OUTFLOW'
5033  idx = idx + 1
5034  maxlist = this%maxbound
5035  naux = 0
5036  call this%budobj%budterm(idx)%initialize(text, &
5037  this%name_model, &
5038  this%packName, &
5039  this%name_model, &
5040  this%packName, &
5041  maxlist, .false., .false., &
5042  naux)
5043  !
5044  ! --
5045  text = ' STORAGE'
5046  idx = idx + 1
5047  maxlist = this%maxbound
5048  naux = 1
5049  auxtxt(1) = ' VOLUME'
5050  call this%budobj%budterm(idx)%initialize(text, &
5051  this%name_model, &
5052  this%packName, &
5053  this%name_model, &
5054  this%packName, &
5055  maxlist, .false., .false., &
5056  naux, auxtxt)
5057  !
5058  ! --
5059  if (this%imover == 1) then
5060  !
5061  ! --
5062  text = ' FROM-MVR'
5063  idx = idx + 1
5064  maxlist = this%maxbound
5065  naux = 0
5066  call this%budobj%budterm(idx)%initialize(text, &
5067  this%name_model, &
5068  this%packName, &
5069  this%name_model, &
5070  this%packName, &
5071  maxlist, .false., .false., &
5072  naux)
5073  !
5074  ! --
5075  text = ' TO-MVR'
5076  idx = idx + 1
5077  maxlist = this%maxbound
5078  naux = 0
5079  call this%budobj%budterm(idx)%initialize(text, &
5080  this%name_model, &
5081  this%packName, &
5082  this%name_model, &
5083  this%packName, &
5084  maxlist, .false., .false., &
5085  naux)
5086  end if
5087  !
5088  ! --
5089  naux = this%naux
5090  if (naux > 0) then
5091  !
5092  ! --
5093  text = ' AUXILIARY'
5094  idx = idx + 1
5095  maxlist = this%maxbound
5096  call this%budobj%budterm(idx)%initialize(text, &
5097  this%name_model, &
5098  this%packName, &
5099  this%name_model, &
5100  this%packName, &
5101  maxlist, .false., .false., &
5102  naux, this%auxname)
5103  end if
5104  !
5105  ! -- if sfr flow for each reach are written to the listing file
5106  if (this%iprflow /= 0) then
5107  call this%budobj%flowtable_df(this%iout, cellids='GWF')
5108  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 5349 of file gwf-sfr.f90.

5350  ! -- dummy
5351  class(SfrType) :: this !< SfrType object
5352  ! -- local
5353  integer(I4B) :: nterms
5354  character(len=LINELENGTH) :: title
5355  character(len=LINELENGTH) :: text
5356  !
5357  ! -- setup stage table
5358  if (this%iprhed > 0) then
5359  !
5360  ! -- Determine the number of sfr budget terms. These are fixed for
5361  ! the simulation and cannot change. This includes FLOW-JA-FACE
5362  ! so they can be written to the binary budget files, but these internal
5363  ! flows are not included as part of the budget table.
5364  nterms = 8
5365  if (this%inamedbound == 1) then
5366  nterms = nterms + 1
5367  end if
5368  !
5369  ! -- set up table title
5370  title = trim(adjustl(this%text))//' PACKAGE ('// &
5371  trim(adjustl(this%packName))//') STAGES FOR EACH CONTROL VOLUME'
5372  !
5373  ! -- set up stage tableobj
5374  call table_cr(this%stagetab, this%packName, title)
5375  call this%stagetab%table_df(this%maxbound, nterms, this%iout, &
5376  transient=.true.)
5377  !
5378  ! -- Go through and set up table budget term
5379  if (this%inamedbound == 1) then
5380  text = 'NAME'
5381  call this%stagetab%initialize_column(text, lenboundname, &
5382  alignment=tableft)
5383  end if
5384  !
5385  ! -- reach number
5386  text = 'NUMBER'
5387  call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
5388  !
5389  ! -- cellids
5390  text = 'CELLID'
5391  call this%stagetab%initialize_column(text, 20, alignment=tableft)
5392  !
5393  ! -- reach stage
5394  text = 'STAGE'
5395  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5396  !
5397  ! -- reach depth
5398  text = 'DEPTH'
5399  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5400  !
5401  ! -- reach width
5402  text = 'WIDTH'
5403  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5404  !
5405  ! -- gwf head
5406  text = 'GWF HEAD'
5407  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5408  !
5409  ! -- streambed conductance
5410  text = 'STREAMBED CONDUCTANCE'
5411  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5412  !
5413  ! -- streambed gradient
5414  text = 'STREAMBED GRADIENT'
5415  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
5416  end if
5417  !
5418  ! -- setup Courant number table
5419  if (this%istorage == 1) then
5420  nterms = 4
5421  if (this%inamedbound == 1) then
5422  nterms = nterms + 1
5423  end if
5424  !
5425  ! -- set up table title
5426  title = trim(adjustl(this%text))//' PACKAGE ('// &
5427  trim(adjustl(this%packName))//') COURANT NUMBER FOR EACH REACH'
5428  !
5429  ! -- set up Courant tableobj
5430  call table_cr(this%couranttab, this%packName, title)
5431  call this%couranttab%table_df(this%maxbound, nterms, this%iout)
5432  !
5433  if (this%inamedbound == 1) then
5434  text = 'NAME'
5435  call this%couranttab%initialize_column(text, lenboundname, &
5436  alignment=tableft)
5437  end if
5438  !
5439  ! -- reach number
5440  text = 'NUMBER'
5441  call this%couranttab%initialize_column(text, 10, alignment=tabcenter)
5442  !
5443  ! -- minimum Courant number
5444  text = 'MINIMUM'
5445  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5446  !
5447  ! -- maximum Courant number
5448  text = 'MAXIMUM'
5449  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5450  !
5451  ! -- mean Courant number
5452  text = 'MEAN'
5453  call this%couranttab%initialize_column(text, 16, alignment=tabcenter)
5454  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 3344 of file gwf-sfr.f90.

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

◆ sfr_source_connectiondata()

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

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

1198  ! -- modules
1200  use sparsemodule, only: sparsematrix
1201  ! -- dummy
1202  class(SfrType), intent(inout) :: this !< SfrType object
1203  ! -- local
1204  integer(I4B), dimension(:), pointer, contiguous :: cd_ifno => null()
1205  integer(I4B), dimension(:), pointer, contiguous :: ic_flat => null()
1206  integer(I4B), dimension(:), pointer, contiguous :: cd_ia => null()
1207  type(sparsematrix), pointer :: sparse => null()
1208  integer(I4B), dimension(:), pointer, contiguous :: rowmaxnnz => null()
1209  integer(I4B), allocatable :: nboundchk(:)
1210  integer(I4B), allocatable :: iconndata(:, :)
1211  integer(I4B), allocatable :: iup(:)
1212  integer(I4B), allocatable :: order(:)
1213  type(dag) :: sfr_dag
1214  integer(I4B) :: i, n, j, jj, jcol, jcol2, nja, nconnmax
1215  integer(I4B) :: ival, idir, nup, ipos, istat, ierr, jlocal, nread
1216  !
1217  write (this%iout, '(/1x,a)') &
1218  'PROCESSING '//trim(adjustl(this%text))//' CONNECTIONDATA'
1219  !
1220  ! -- get input context CONNECTIONDATA arrays
1221  call mem_setptr(cd_ifno, 'CONNDATA_IFNO', this%input_mempath)
1222  call mem_setptr(ic_flat, 'IC', this%input_mempath)
1223  call mem_setptr(cd_ia, 'IC_IA', this%input_mempath)
1224  !
1225  ! -- allocate and initialize check array
1226  allocate (nboundchk(this%maxbound))
1227  nboundchk = 0
1228  !
1229  ! -- build rowmaxnnz from nconnreach
1230  nja = 0
1231  nconnmax = 0
1232  allocate (rowmaxnnz(this%maxbound))
1233  do n = 1, this%maxbound
1234  ival = this%nconnreach(n)
1235  if (ival < 0) ival = 0
1236  rowmaxnnz(n) = ival + 1
1237  nja = nja + ival + 1
1238  if (ival > nconnmax) nconnmax = ival
1239  end do
1240  !
1241  ! -- reallocate connection arrays
1242  call mem_reallocate(this%ja, nja, 'JA', this%memoryPath)
1243  call mem_reallocate(this%idir, nja, 'IDIR', this%memoryPath)
1244  call mem_reallocate(this%idiv, nja, 'IDIV', this%memoryPath)
1245  call mem_reallocate(this%qconn, nja, 'QCONN', this%memoryPath)
1246  this%idir = 0
1247  this%idiv = 0
1248  this%qconn = dzero
1249  !
1250  ! -- allocate iconndata
1251  allocate (iconndata(nconnmax, this%maxbound))
1252  iconndata = 0
1253  !
1254  allocate (sparse)
1255  call sparse%init(this%maxbound, this%maxbound, rowmaxnnz)
1256  !
1257  ! -- process connection data rows
1258  do i = 1, this%maxbound
1259  n = this%validate_ifno(cd_ifno(i), this%maxbound, nboundchk, &
1260  'reach', 'CONNECTIONDATA')
1261  if (n == 0) cycle
1262  nread = cd_ia(i + 1) - cd_ia(i)
1263  if (nread /= this%nconnreach(n)) then
1264  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,a)') &
1265  'Reach', n, 'connectiondata specifies', nread, &
1266  'connections but NCON for this reach in packagedata is', &
1267  this%nconnreach(n), '.'
1268  call store_error(errmsg)
1269  cycle
1270  end if
1271  call sparse%addconnection(n, n, 1)
1272  jlocal = 0
1273  do j = cd_ia(i), cd_ia(i + 1) - 1
1274  jlocal = jlocal + 1
1275  ival = ic_flat(j)
1276  iconndata(jlocal, n) = ival
1277  if (ival < 0) then
1278  idir = -1
1279  ival = abs(ival)
1280  else if (ival == 0) then
1281  call store_error('Missing or zero connection reach in connectiondata.')
1282  cycle
1283  else
1284  idir = 1
1285  end if
1286  if (ival > this%maxbound) then
1287  call store_error('Reach number exceeds NREACHES in connectiondata.')
1288  cycle
1289  end if
1290  call sparse%addconnection(n, ival, 1)
1291  end do
1292  end do
1293  !
1294  write (this%iout, '(1x,a)') &
1295  'END OF '//trim(adjustl(this%text))//' CONNECTIONDATA'
1296  !
1297  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1298  'CONNECTIONDATA')
1299  !
1300  if (count_errors() > 0) then
1301  call store_error_filename(this%input_fname)
1302  end if
1303  !
1304  ! -- fill ia and ja from sparse
1305  call sparse%filliaja(this%ia, this%ja, ierr, sort=.true.)
1306  if (ierr /= 0) then
1307  write (errmsg, '(a,3(1x,a))') &
1308  'Could not fill', trim(this%packName), &
1309  'package IA and JA connection data.', &
1310  'Check connectivity data in connectiondata block.'
1311  call store_error(errmsg)
1312  end if
1313  !
1314  ! -- fill flat connection storage with direction
1315  do n = 1, this%maxbound
1316  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1317  jcol = this%ja(j)
1318  do jj = 1, this%nconnreach(n)
1319  jcol2 = iconndata(jj, n)
1320  if (abs(jcol2) == jcol) then
1321  idir = 1
1322  if (jcol2 < 0) idir = -1
1323  this%idir(j) = idir
1324  exit
1325  end if
1326  end do
1327  end do
1328  end do
1329  !
1330  ! -- deallocate temporaries
1331  deallocate (rowmaxnnz)
1332  deallocate (nboundchk)
1333  deallocate (iconndata)
1334  call sparse%destroy()
1335  deallocate (sparse)
1336  !
1337  ! -- compute reach order using DAG
1338  call sfr_dag%set_vertices(this%maxbound)
1339  fill_dag: do n = 1, this%maxbound
1340  nup = 0
1341  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1342  if (this%idir(j) > 0) nup = nup + 1
1343  end do
1344  if (nup == 0) cycle fill_dag
1345  allocate (iup(nup))
1346  ipos = 1
1347  do j = this%ia(n) + 1, this%ia(n + 1) - 1
1348  if (this%idir(j) > 0) then
1349  iup(ipos) = this%ja(j)
1350  ipos = ipos + 1
1351  end if
1352  end do
1353  call sfr_dag%set_edges(n, iup)
1354  deallocate (iup)
1355  end do fill_dag
1356  call sfr_dag%toposort(order, istat)
1357  if (istat == -1) then
1358  write (warnmsg, '(a)') &
1359  trim(adjustl(this%text))//' PACKAGE ('// &
1360  trim(adjustl(this%packName))//') cannot calculate a '// &
1361  'Directed Asyclic Graph for reach connectivity because '// &
1362  'of circular dependency. Using the reach number for '// &
1363  'solution ordering.'
1364  call store_warning(warnmsg)
1365  end if
1366  do n = 1, this%maxbound
1367  if (istat == 0) then
1368  this%isfrorder(n) = order(n)
1369  else
1370  this%isfrorder(n) = n
1371  end if
1372  end do
1373  call sfr_dag%destroy()
1374  if (istat == 0) deallocate (order)
1375  !
1376  ! -- release input context connectiondata memory
1377  call memorystore_release('CONNDATA_IFNO', this%input_mempath)
1378  call memorystore_release('IC', this%input_mempath)
1379  call memorystore_release('IC_IA', this%input_mempath)
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_source_crosssections()

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

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

1108  ! -- modules
1109  use constantsmodule, only: lenmempath
1113  ! -- dummy
1114  class(SfrType), intent(inout) :: this !< SfrType object
1115  ! -- local
1116  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
1117  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1118  tab6_filename => null()
1119  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1120  sfrtab6_mempaths => null()
1121  type(SfrCrossSection), pointer :: cross_data => null()
1122  integer(I4B) :: i, n, ncrossptstot
1123  integer(I4B), allocatable :: nboundchk(:)
1124  integer(I4B) :: isize
1125  character(len=LINELENGTH) :: tabfname
1126  character(len=LENMEMPATH) :: mempath
1127  !
1128  ! -- check if CROSSSECTIONS block was loaded (optional block)
1129  call get_isize('CROSSSECT_IFNO', this%input_mempath, isize)
1130  if (isize < 1) return
1131  !
1132  write (this%iout, '(/1x,a)') &
1133  'PROCESSING '//trim(adjustl(this%text))//' CROSSSECTIONS'
1134  !
1135  ! -- get input context arrays
1136  call mem_setptr(ifno, 'CROSSSECT_IFNO', this%input_mempath)
1137  call mem_setptr(tab6_filename, 'SFRTAB6_FILENAME', this%input_mempath)
1138  call mem_setptr(sfrtab6_mempaths, 'SFRTAB6_MEMPATH', this%input_mempath)
1139  !
1140  ! -- create cross-section object
1141  call cross_section_cr(cross_data, this%iout, this%iprpak, this%maxbound)
1142  call cross_data%initialize(this%ncrossptstot, this%ncrosspts, &
1143  this%iacross, this%station, this%xsheight, &
1144  this%xsrough)
1145  !
1146  allocate (nboundchk(this%maxbound))
1147  nboundchk = 0
1148  !
1149  do i = 1, isize
1150  n = this%validate_ifno(ifno(i), this%maxbound, nboundchk, &
1151  'reach', 'CROSSSECTIONS')
1152  if (n == 0) cycle
1153  tabfname = tab6_filename(i)
1154  mempath = sfrtab6_mempaths(i)
1155  call cross_data%source_table(n, this%width(n), mempath, &
1156  trim(adjustl(tabfname)))
1157  end do
1158  !
1159  write (this%iout, '(1x,a)') &
1160  'END OF '//trim(adjustl(this%text))//' CROSSSECTIONS'
1161  !
1162  ! -- CROSSSECTIONS is optional; only duplicates are reported
1163  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1164  'CROSSSECTIONS', check_missing=.false.)
1165  deallocate (nboundchk)
1166  !
1167  if (count_errors() > 0) then
1168  call store_error_filename(this%input_fname)
1169  end if
1170  !
1171  ! -- reallocate cross-section arrays if needed
1172  ncrossptstot = cross_data%get_ncrossptstot()
1173  if (ncrossptstot /= this%ncrossptstot) then
1174  this%ncrossptstot = ncrossptstot
1175  call mem_reallocate(this%station, this%ncrossptstot, 'STATION', &
1176  this%memoryPath)
1177  call mem_reallocate(this%xsheight, this%ncrossptstot, 'XSHEIGHT', &
1178  this%memoryPath)
1179  call mem_reallocate(this%xsrough, this%ncrossptstot, 'XSROUGH', &
1180  this%memoryPath)
1181  end if
1182  !
1183  call cross_data%output(this%width, this%rough)
1184  call cross_data%pack(this%ncrossptstot, this%ncrosspts, this%iacross, &
1185  this%station, this%xsheight, this%xsrough)
1186  call cross_data%destroy()
1187  deallocate (cross_data)
1188  nullify (cross_data)
1189  !
1190  ! -- release input context crosssections memory
1191  call memorystore_release('CROSSSECT_IFNO', this%input_mempath)
1192  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 881 of file gwf-sfr.f90.

882  ! -- modules
884  ! -- dummy
885  class(SfrType), intent(inout) :: this !< SfrType object
886  ! -- local
887  logical(LGP) :: found
888  !
889  ! -- initialize dimensions to 0
890  this%maxbound = 0
891  !
892  write (this%iout, '(/1x,a)') &
893  'PROCESSING '//trim(adjustl(this%text))//' DIMENSIONS'
894  !
895  ! -- source NREACHES
896  call mem_set_value(this%maxbound, 'MAXBOUND', this%input_mempath, found, &
897  release=.false.)
898  if (found) then
899  write (this%iout, '(4x,a,i0)') 'NREACHES = ', this%maxbound
900  end if
901  !
902  write (this%iout, '(1x,a)') &
903  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
904  !
905  if (this%maxbound < 1) then
906  write (errmsg, '(a)') &
907  'NREACHES was not specified or was specified incorrectly.'
908  call store_error(errmsg)
909  call store_error_filename(this%input_fname)
910  end if
911  !
912  ! -- set npakeq (SFR adds no extra equations)
913  this%npakeq = 0
914  !
915  ! -- define the default label
916  call this%define_listlabel()
917  !
918  ! -- define default cross-section data size
919  this%ncrossptstot = this%maxbound
920  !
921  ! -- allocate arrays
922  call this%sfr_allocate_arrays()
923  !
924  ! -- source packagedata
925  call this%sfr_source_packagedata()
926  !
927  ! -- source crosssections
928  call this%sfr_source_crosssections()
929  !
930  ! -- source connectiondata
931  call this%sfr_source_connectiondata()
932  !
933  ! -- source diversions
934  call this%sfr_source_diversions()
935  !
936  ! -- source initialstages
937  call this%sfr_source_initialstages()
938  !
939  ! -- setup the budget object
940  call this%sfr_setup_budobj()
941  !
942  ! -- setup the stage table object
943  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 1384 of file gwf-sfr.f90.

1385  ! -- modules
1388  ! -- dummy
1389  class(SfrType), intent(inout) :: this !< SfrType object
1390  ! -- local
1391  integer(I4B), dimension(:), pointer, contiguous :: d_ifno => null()
1392  integer(I4B), dimension(:), pointer, contiguous :: d_idv => null()
1393  integer(I4B), dimension(:), pointer, contiguous :: d_iconr => null()
1394  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1395  d_cprior => null()
1396  integer(I4B) :: i, n, idiv, ndiversions, i0, ipos, jpos
1397  integer(I4B) :: isize
1398  integer(I4B), allocatable :: iachk(:), nboundchk(:)
1399  character(len=16) :: cval
1400  !
1401  ! -- build iadiv and count total diversions
1402  ndiversions = 0
1403  i0 = 1
1404  this%iadiv(1) = i0
1405  do n = 1, this%maxbound
1406  ndiversions = ndiversions + this%ndiv(n)
1407  i0 = i0 + this%ndiv(n)
1408  this%iadiv(n + 1) = i0
1409  end do
1410  !
1411  ! -- reallocate diversion arrays
1412  if (ndiversions > 0) then
1413  call mem_reallocate(this%divreach, ndiversions, 'DIVREACH', &
1414  this%memoryPath)
1415  allocate (this%divcprior(ndiversions))
1416  call mem_setptr(this%divflow, 'DIVFLOW', this%input_mempath)
1417  call mem_reallocate(this%divq, ndiversions, 'DIVQ', this%memoryPath)
1418  this%divq = dzero
1419  end if
1420  !
1421  ! -- check if DIVERSIONS block was loaded (optional block)
1422  call get_isize('DIVERSIONS_IFNO', this%input_mempath, isize)
1423  if (isize < 1) then
1424  if (this%idiversions /= 0) then
1425  call store_error('REQUIRED DIVERSIONS BLOCK NOT FOUND.')
1426  call store_error_filename(this%input_fname)
1427  end if
1428  return
1429  end if
1430  !
1431  if (this%idiversions == 0) then
1432  write (errmsg, '(a,1x,a)') &
1433  'A diversions block should not be', &
1434  'specified if diversions are not specified.'
1435  call store_error(errmsg)
1436  call store_error_filename(this%input_fname)
1437  return
1438  end if
1439  !
1440  write (this%iout, '(/1x,a)') &
1441  'PROCESSING '//trim(adjustl(this%text))//' DIVERSIONS'
1442  !
1443  ! -- get input context arrays
1444  call mem_setptr(d_ifno, 'DIVERSIONS_IFNO', this%input_mempath)
1445  call mem_setptr(d_idv, 'DIVERSIONS_IDV', this%input_mempath)
1446  call mem_setptr(d_iconr, 'ICONR', this%input_mempath)
1447  call mem_setptr(d_cprior, 'CPRIOR', this%input_mempath)
1448  !
1449  ! -- build check arrays
1450  allocate (iachk(this%maxbound + 1))
1451  allocate (nboundchk(ndiversions))
1452  nboundchk = 0
1453  iachk(1) = 1
1454  do n = 1, this%maxbound
1455  iachk(n + 1) = iachk(n) + this%ndiv(n)
1456  end do
1457  !
1458  do i = 1, isize
1459  n = d_ifno(i)
1460  if (n < 1 .or. n > this%maxbound) then
1461  write (errmsg, '(a,i0,a)') 'Reach number should be between 1 and ', &
1462  this%maxbound, '.'
1463  call store_error(errmsg)
1464  cycle
1465  end if
1466  if (this%ndiv(n) < 1) then
1467  write (errmsg, '(a,i0)') &
1468  'Diversions cannot be specified for reach ', n
1469  call store_error(errmsg)
1470  cycle
1471  end if
1472  idiv = d_idv(i)
1473  if (idiv < 1 .or. idiv > this%ndiv(n)) then
1474  write (errmsg, '(a,i0,a,i0,a)') &
1475  'Reach ', n, ' diversion number should be between 1 and ', &
1476  this%ndiv(n), '.'
1477  call store_error(errmsg)
1478  cycle
1479  end if
1480  ipos = iachk(n) + idiv - 1
1481  nboundchk(ipos) = nboundchk(ipos) + 1
1482  jpos = this%iadiv(n) + idiv - 1
1483  if (d_iconr(i) < 1 .or. d_iconr(i) > this%maxbound) then
1484  write (errmsg, '(a,i0,a)') &
1485  'Diversion target reach number should be between 1 and ', &
1486  this%maxbound, '.'
1487  call store_error(errmsg)
1488  cycle
1489  end if
1490  this%divreach(jpos) = d_iconr(i)
1491  cval = d_cprior(i)
1492  select case (trim(cval))
1493  case ('UPTO', 'THRESHOLD', 'FRACTION', 'EXCESS')
1494  case default
1495  errmsg = 'Invalid cprior type '//trim(cval)//'.'
1496  call store_error(errmsg)
1497  end select
1498  this%divcprior(jpos) = trim(cval)
1499  end do
1500  !
1501  write (this%iout, '(1x,a)') &
1502  'END OF '//trim(adjustl(this%text))//' DIVERSIONS'
1503  !
1504  do n = 1, this%maxbound
1505  do idiv = 1, this%ndiv(n)
1506  ipos = iachk(n) + idiv - 1
1507  if (nboundchk(ipos) == 0) then
1508  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1509  'No data specified for reach', n, 'diversion', idiv
1510  call store_error(errmsg)
1511  else if (nboundchk(ipos) > 1) then
1512  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1513  'Data for reach', n, 'diversion', idiv, &
1514  'specified', nboundchk(ipos), 'times'
1515  call store_error(errmsg)
1516  end if
1517  end do
1518  end do
1519  deallocate (iachk)
1520  deallocate (nboundchk)
1521  !
1522  if (count_errors() > 0) then
1523  call store_error_filename(this%input_fname)
1524  end if
1525  !
1526  ! -- release input context diversions memory; DIVFLOW excluded
1527  call memorystore_release('DIVERSIONS_IFNO', this%input_mempath)
1528  call memorystore_release('DIVERSIONS_IDV', this%input_mempath)
1529  call memorystore_release('ICONR', this%input_mempath)
1530  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 1535 of file gwf-sfr.f90.

1536  ! -- modules
1538  ! -- dummy
1539  class(SfrType), intent(inout) :: this !< SfrType object
1540  ! -- local
1541  integer(I4B), dimension(:), pointer, contiguous :: is_ifno => null()
1542  real(DP), dimension(:), pointer, contiguous :: is_stage => null()
1543  integer(I4B) :: i, n
1544  integer(I4B) :: isize
1545  integer(I4B), allocatable :: nboundchk(:)
1546  real(DP) :: rval
1547  !
1548  ! -- check if INITIALSTAGES block was loaded (optional block)
1549  call get_isize('INITSTAGE_IFNO', this%input_mempath, isize)
1550  if (isize < 1) then
1551  ! -- set default initial stage to reach top if STORAGE active
1552  if (this%istorage == 1) then
1553  do n = 1, this%maxbound
1554  this%stage(n) = this%strtop(n)
1555  end do
1556  end if
1557  return
1558  end if
1559  !
1560  write (this%iout, '(/1x,a)') &
1561  'PROCESSING '//trim(adjustl(this%text))//' INITIALSTAGES'
1562  !
1563  call mem_setptr(is_ifno, 'INITSTAGE_IFNO', this%input_mempath)
1564  call mem_setptr(is_stage, 'INITIALSTAGE', this%input_mempath)
1565  !
1566  allocate (nboundchk(this%maxbound))
1567  nboundchk = 0
1568  !
1569  do i = 1, isize
1570  n = this%validate_ifno(is_ifno(i), this%maxbound, nboundchk, &
1571  'reach', 'INITIALSTAGES')
1572  if (n == 0) cycle
1573  rval = is_stage(i)
1574  this%stage(n) = rval
1575  this%depth(n) = rval - this%strtop(n)
1576  if (rval < this%strtop(n)) then
1577  write (errmsg, '(a,g0,a,1x,i0,1x,a,g0,a)') &
1578  'Initial stage (', rval, ') for reach', n, &
1579  'is less than the reach top (', this%strtop(n), ').'
1580  call store_error(errmsg)
1581  end if
1582  end do
1583  !
1584  write (this%iout, '(1x,a)') &
1585  'END OF '//trim(adjustl(this%text))//' INITIALSTAGES'
1586  !
1587  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1588  'INITIALSTAGES')
1589  deallocate (nboundchk)
1590  !
1591  if (count_errors() > 0) then
1592  call store_error_filename(this%input_fname)
1593  end if
1594  !
1595  ! -- release input context initialstages memory
1596  call memorystore_release('INITSTAGE_IFNO', this%input_mempath)
1597  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 697 of file gwf-sfr.f90.

698  ! -- modules
699  use memorymanagermodule, only: get_isize
702  use openspecmodule, only: access, form
703  ! -- dummy
704  class(SfrType), intent(inout) :: this !< SfrType object
705  ! -- local
706  character(len=LINELENGTH) :: fname
707  logical(LGP) :: found
708  ! -- formats
709  character(len=*), parameter :: fmtpicard = &
710  &"(4x, 'MAXIMUM SFR PICARD ITERATION VALUE (',i0,') SPECIFIED.')"
711  character(len=*), parameter :: fmtiter = &
712  &"(4x, 'MAXIMUM SFR ITERATION VALUE (',i0,') SPECIFIED.')"
713  character(len=*), parameter :: fmtdmaxchg = &
714  &"(4x, 'MAXIMUM DEPTH CHANGE VALUE (',g0,') SPECIFIED.')"
715  character(len=*), parameter :: fmtlengthconv = &
716  &"(4x, 'LENGTH CONVERSION VALUE (',g0,') SPECIFIED.')"
717  character(len=*), parameter :: fmttimeconv = &
718  &"(4x, 'TIME CONVERSION VALUE (',g0,') SPECIFIED.')"
719  character(len=*), parameter :: fmtstoweight = &
720  &"(4x, 'KINEMATIC STORAGE WEIGHT (',g0,') SPECIFIED.')"
721  character(len=*), parameter :: fmtsfrbin = &
722  "(4x, 'SFR ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', a, /4x, &
723  &'OPENED ON UNIT: ', I0)"
724  integer(I4B) :: isize
725  !
726  ! -- source base BndExtType options (NAUX, BOUNDNAMES, PRINT_INPUT, etc.)
727  call this%BndExtType%source_options()
728  !
729  write (this%iout, '(/1x,a)') &
730  'PROCESSING '//trim(adjustl(this%text))//' OPTIONS'
731  !
732  ! -- STORAGE
733  call mem_set_value(this%istorage, 'STORAGE', this%input_mempath, found)
734  if (found) then
735  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
736  ' REACH STORAGE IS ACTIVE.'
737  end if
738  !
739  ! -- ATS_COURANT
740  call mem_set_value(this%ats_courant, 'ATS_COURANT', &
741  this%input_mempath, found)
742  if (found) then
743  if (this%ats_courant <= dzero) then
744  write (errmsg, '(a,g0,a)') &
745  "ATS_COURANT SPECIFIED TO BE '", this%ats_courant, &
746  "' BUT MUST BE GREATER THAN ZERO"
747  call store_error(errmsg)
748  call store_error_filename(this%input_fname)
749  else
750  write (this%iout, '(4x,a,1pg15.6)') &
751  'TARGET COURANT NUMBER FOR ADAPTIVE TIME STEPS: ', &
752  this%ats_courant
753  end if
754  end if
755  !
756  ! -- PRINT_STAGE
757  call mem_set_value(this%iprhed, 'PRINT_STAGE', this%input_mempath, found)
758  if (found) then
759  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
760  ' STAGES WILL BE PRINTED TO LISTING FILE.'
761  end if
762  !
763  ! -- STAGEFILE
764  call mem_set_value(fname, 'STAGEFILE', this%input_mempath, found)
765  if (found) then
766  this%istageout = getunit()
767  call openfile(this%istageout, this%iout, fname, 'DATA(BINARY)', &
768  form, access, 'REPLACE', mnormal)
769  write (this%iout, fmtsfrbin) 'STAGE', trim(fname), this%istageout
770  end if
771  !
772  ! -- BUDGETFILE
773  call mem_set_value(fname, 'BUDGETFILE', this%input_mempath, found)
774  if (found) then
775  call assign_iounit(this%ibudgetout, this%inunit, 'BUDGET fileout')
776  call openfile(this%ibudgetout, this%iout, fname, 'DATA(BINARY)', &
777  form, access, 'REPLACE', mnormal)
778  write (this%iout, fmtsfrbin) 'BUDGET', trim(fname), this%ibudgetout
779  end if
780  !
781  ! -- BUDGETCSVFILE
782  call mem_set_value(fname, 'BUDGETCSVFILE', this%input_mempath, found)
783  if (found) then
784  call assign_iounit(this%ibudcsv, this%inunit, 'BUDGETCSV fileout')
785  call openfile(this%ibudcsv, this%iout, fname, 'CSV', &
786  filstat_opt='REPLACE')
787  write (this%iout, fmtsfrbin) 'BUDGET CSV', trim(fname), this%ibudcsv
788  end if
789  !
790  ! -- PACKAGE_CONVERGENCE_FILENAME (mf6internal: pkgconvfname)
791  call mem_set_value(fname, 'PKGCONVFNAME', this%input_mempath, found)
792  if (found) then
793  this%ipakcsv = getunit()
794  call openfile(this%ipakcsv, this%iout, fname, 'CSV', &
795  filstat_opt='REPLACE', mode_opt=mnormal)
796  write (this%iout, fmtsfrbin) 'PACKAGE_CONVERGENCE', trim(fname), &
797  this%ipakcsv
798  end if
799  !
800  ! -- MOVER
801  call mem_set_value(this%imover, 'MOVER', this%input_mempath, found)
802  if (found) then
803  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
804  end if
805  !
806  ! -- MAXIMUM_PICARD_ITERATIONS (mf6internal: maxsfrpicard)
807  call mem_set_value(this%maxsfrpicard, 'MAXSFRPICARD', &
808  this%input_mempath, found)
809  if (found) write (this%iout, fmtpicard) this%maxsfrpicard
810  !
811  ! -- MAXIMUM_ITERATIONS (mf6internal: maxsfrit)
812  call mem_set_value(this%maxsfrit, 'MAXSFRIT', &
813  this%input_mempath, found)
814  if (found) write (this%iout, fmtiter) this%maxsfrit
815  !
816  ! -- MAXIMUM_DEPTH_CHANGE (mf6internal: dmaxchg)
817  call mem_set_value(this%dmaxchg, 'DMAXCHG', &
818  this%input_mempath, found)
819  if (found) then
820  this%deps = dp999 * this%dmaxchg
821  write (this%iout, fmtdmaxchg) this%dmaxchg
822  end if
823  !
824  ! -- LENGTH_CONVERSION (mf6internal: lengthconv)
825  call mem_set_value(this%lengthconv, 'LENGTHCONV', &
826  this%input_mempath, found)
827  if (found) write (this%iout, fmtlengthconv) this%lengthconv
828  !
829  ! -- TIME_CONVERSION
830  call mem_set_value(this%timeconv, 'TIME_CONVERSION', &
831  this%input_mempath, found)
832  if (found) write (this%iout, fmttimeconv) this%timeconv
833  !
834  ! -- UNIT_CONVERSION (deprecated)
835  call mem_set_value(this%unitconv, 'UNIT_CONVERSION', &
836  this%input_mempath, found)
837  if (found) then
838  write (warnmsg, '(a)') 'SETTING UNIT_CONVERSION DIRECTLY'
839  call deprecation_warning('OPTIONS', 'UNIT_CONVERSION', '6.4.2', &
840  warnmsg, this%inunit)
841  end if
842  !
843  ! -- DEV_STORAGE_WEIGHT (mf6internal: storage_weight)
844  call mem_set_value(this%storage_weight, 'STORAGE_WEIGHT', &
845  this%input_mempath, found)
846  if (found) then
847  if (this%storage_weight < dhalf .or. this%storage_weight > done) then
848  write (errmsg, '(a,g0,a)') &
849  "STORAGE_WEIGHT SPECIFIED TO BE '", this%storage_weight, &
850  "' BUT CANNOT BE LESS THAN 0.5 OR GREATER THAN 1.0"
851  call store_error(errmsg)
852  call store_error_filename(this%input_fname)
853  else
854  write (this%iout, fmtstoweight) this%storage_weight
855  end if
856  end if
857  !
858  ! -- DEV_NO_CHECK (mf6internal: icheck)
859  call get_isize('ICHECK', this%input_mempath, isize)
860  if (isize > 0) then
861  this%icheck = 0
862  write (this%iout, '(4x,a)') &
863  'REACH GEOMETRY AND PARAMETER CHECKS WILL NOT BE MADE'
864  end if
865  !
866  ! -- DEV_NO_FINAL_CHECK (mf6internal: iconvchk)
867  call get_isize('ICONVCHK', this%input_mempath, isize)
868  if (isize > 0) then
869  this%iconvchk = 0
870  write (this%iout, '(4x,a)') &
871  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN STREAM FLOW ROUTING '// &
872  'STAGES AND FLOWS WILL NOT BE MADE'
873  end if
874  !
875  write (this%iout, '(1x,a)') &
876  '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 948 of file gwf-sfr.f90.

949  ! -- modules
952  ! -- dummy
953  class(SfrType), intent(inout) :: this !< SfrType object
954  ! -- local
955  integer(I4B) :: i, n, nconzero
956  integer(I4B) :: ipos
957  character(len=10) :: cnum
958  character(len=LENBOUNDNAME) :: bndName
959  character(len=LINELENGTH) :: cellid_str
960  integer(I4B), allocatable :: nboundchk(:)
961  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
962  integer(I4B), dimension(:, :), pointer, contiguous :: cellid => null()
963  real(DP), dimension(:), pointer, contiguous :: rlen => null()
964  real(DP), dimension(:), pointer, contiguous :: rwid => null()
965  real(DP), dimension(:), pointer, contiguous :: rgrd => null()
966  real(DP), dimension(:), pointer, contiguous :: rtp => null()
967  real(DP), dimension(:), pointer, contiguous :: rbth => null()
968  integer(I4B), dimension(:), pointer, contiguous :: ncon => null()
969  integer(I4B), dimension(:), pointer, contiguous :: ndv => null()
970  type(CharacterStringType), dimension(:), pointer, contiguous :: &
971  boundname => null()
972  !
973  write (this%iout, '(/1x,a)') &
974  'PROCESSING '//trim(adjustl(this%text))//' PACKAGEDATA'
975  !
976  ! -- get input context PACKAGEDATA column arrays
977  call mem_setptr(ifno, 'PACKAGEDATA_IFNO', this%input_mempath)
978  call mem_setptr(cellid, 'CELLID', this%input_mempath)
979  call mem_setptr(rlen, 'RLEN', this%input_mempath)
980  call mem_setptr(rwid, 'RWID', this%input_mempath)
981  call mem_setptr(rgrd, 'RGRD', this%input_mempath)
982  call mem_setptr(rtp, 'RTP', this%input_mempath)
983  call mem_setptr(rbth, 'RBTH', this%input_mempath)
984  call mem_setptr(this%input%rhk, 'RHK', this%input_mempath)
985  call mem_setptr(this%input%man, 'MAN', this%input_mempath)
986  call mem_setptr(ncon, 'NCON', this%input_mempath)
987  call mem_setptr(this%input%ustrf, 'USTRF', this%input_mempath)
988  call mem_setptr(ndv, 'NDV', this%input_mempath)
989  if (this%inamedbound /= 0) then
990  call mem_setptr(boundname, 'BOUNDNAME', this%input_mempath)
991  end if
992  !
993  ! -- allocate check array
994  allocate (nboundchk(this%maxbound))
995  nboundchk = 0
996  nconzero = 0
997  !
998  ! -- populate reach data from input context arrays
999  do i = 1, this%maxbound
1000  n = ifno(i)
1001  !
1002  n = this%validate_ifno(n, this%maxbound, nboundchk, &
1003  'rno', 'PACKAGEDATA')
1004  if (n == 0) cycle
1005  !
1006  ! -- cellid → igwfnode: convert integer cellid array to string
1007  ! -- all-zero or negative cellid means unconnected reach (NONE keyword or 0 0 0)
1008  if (all(cellid(1:this%dis%ndim, i) <= 0)) then
1009  this%igwfnode(n) = 0
1010  else
1011  write (cellid_str, '(10(i0,1x))') cellid(1:this%dis%ndim, i)
1012  this%igwfnode(n) = this%dis%noder_from_cellid(cellid_str, &
1013  this%inunit, this%iout, &
1014  flag_string=.false., &
1015  allow_zero=.true.)
1016  end if
1017  this%igwftopnode(n) = this%igwfnode(n)
1018  if (this%igwfnode(n) < 1) this%ianynone = this%ianynone + 1
1019  !
1020  ! -- scalar reach properties
1021  this%length(n) = rlen(i)
1022  this%width(n) = rwid(i)
1023  this%slope(n) = rgrd(i)
1024  this%strtop(n) = rtp(i)
1025  this%bthick(n) = rbth(i)
1026  !
1027  ! -- ncon and nconn
1028  this%nconnreach(n) = ncon(i)
1029  this%nconn = this%nconn + ncon(i)
1030  if (ncon(i) < 0) then
1031  write (errmsg, '(a,1x,i0,1x,a,i0,a)') &
1032  'NCON for reach', n, &
1033  'must be greater than or equal to 0 (', ncon(i), ').'
1034  call store_error(errmsg)
1035  else if (ncon(i) == 0) then
1036  nconzero = nconzero + 1
1037  end if
1038  !
1039  ! -- ndv (diversions)
1040  this%ndiv(n) = ndv(i)
1041  if (ndv(i) > 0) this%idiversions = 1
1042  !
1043  ! -- bound name
1044  write (cnum, '(i10.10)') n
1045  bndname = 'Reach'//cnum
1046  if (this%inamedbound /= 0) then
1047  bndname = boundname(i)
1048  end if
1049  this%sfrname(n) = bndname
1050  !
1051  ! -- hk, roughness (Manning), upstream fraction: copied from
1052  ! input context; sfr_ad re-syncs TS-linked values each timestep
1053  this%hk(n) = this%input%rhk(i)
1054  this%rough(n) = this%input%man(i)
1055  this%ustrf(n) = this%input%ustrf(i)
1056  !
1057  ! -- initialize sstage to reach top
1058  this%sstage(n) = this%strtop(n)
1059  end do
1060  !
1061  write (this%iout, '(1x,a)') &
1062  'END OF '//trim(adjustl(this%text))//' PACKAGEDATA'
1063  !
1064  ! -- check every reach is specified exactly once
1065  call this%report_ifno_coverage(nboundchk, this%maxbound, 'reach', &
1066  'PACKAGEDATA')
1067  deallocate (nboundchk)
1068  !
1069  if (nconzero > 0) then
1070  write (warnmsg, '(a,1x,a,1x,a,1x,i0,1x,a)') &
1071  'SFR Package', trim(this%packName), &
1072  'has', nconzero, 'reach(es) with zero connections.'
1073  call store_warning(warnmsg)
1074  end if
1075  !
1076  if (count_errors() > 0) then
1077  call store_error_filename(this%input_fname)
1078  end if
1079  !
1080  ! -- initialize default cross-section data
1081  ipos = 1
1082  this%iacross(1) = ipos
1083  do i = 1, this%maxbound
1084  this%ncrosspts(i) = 1
1085  this%station(ipos) = this%width(i)
1086  this%xsheight(ipos) = dzero
1087  this%xsrough(ipos) = done
1088  ipos = ipos + 1
1089  this%iacross(i + 1) = ipos
1090  end do
1091  !
1092  ! -- release input context packagedata memory; PACKAGEDATA_IFNO excluded
1093  ! (allocate_featureauxvar); RHK/MAN/USTRF excluded
1094  call memorystore_release('CELLID', this%input_mempath)
1095  call memorystore_release('RLEN', this%input_mempath)
1096  call memorystore_release('RWID', this%input_mempath)
1097  call memorystore_release('RGRD', this%input_mempath)
1098  call memorystore_release('RTP', this%input_mempath)
1099  call memorystore_release('RBTH', this%input_mempath)
1100  call memorystore_release('NCON', this%input_mempath)
1101  call memorystore_release('NDV', this%input_mempath)
1102  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 3528 of file gwf-sfr.f90.

3529  ! -- dummy
3530  class(SfrType), intent(inout) :: this !< SfrType object
3531  integer(I4B), intent(in) :: n !< reach number
3532  real(DP), intent(inout) :: qd !< downstream reach flow
3533  real(DP), intent(in) :: qgwf !< groundwater leakage for reach
3534  ! -- local
3535  integer(I4B) :: i
3536  integer(I4B) :: n2
3537  integer(I4B) :: idiv
3538  integer(I4B) :: jpos
3539  real(DP) :: qdiv
3540  real(DP) :: f
3541  !
3542  ! -- update reach terms
3543  !
3544  ! -- save final downstream stream flow
3545  this%dsflow(n) = qd
3546  !
3547  ! -- save groundwater leakage
3548  this%gwflow(n) = qgwf
3549  !
3550  ! -- route downstream flow
3551  if (qd > dzero) then
3552  !
3553  ! -- route water to diversions
3554  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3555  if (this%idir(i) > 0) cycle
3556  idiv = this%idiv(i)
3557  if (idiv == 0) cycle
3558  jpos = this%iadiv(n) + idiv - 1
3559  call this%sfr_calc_div(n, idiv, qd, qdiv)
3560  this%qconn(i) = qdiv
3561  this%divq(jpos) = qdiv
3562  end do
3563  !
3564  ! -- Mover terms: store outflow after diversion loss
3565  ! as qformvr and reduce outflow (qd)
3566  ! by how much was actually sent to the mover
3567  if (this%imover == 1) then
3568  call this%pakmvrobj%accumulate_qformvr(n, qd)
3569  qd = max(qd - this%pakmvrobj%get_qtomvr(n), dzero)
3570  end if
3571  !
3572  ! -- route remaining water to downstream reaches
3573  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3574  if (this%idir(i) > 0) cycle
3575  if (this%idiv(i) > 0) cycle
3576  n2 = this%ja(i)
3577  if (this%iboundpak(n2) == 0) cycle
3578  f = this%ustrf(n2) / this%ftotnd(n)
3579  this%qconn(i) = qd * f
3580  end do
3581  else
3582  do i = this%ia(n) + 1, this%ia(n + 1) - 1
3583  if (this%idir(i) > 0) cycle
3584  this%qconn(i) = dzero
3585  idiv = this%idiv(i)
3586  if (idiv == 0) cycle
3587  jpos = this%iadiv(n) + idiv - 1
3588  this%divq(jpos) = dzero
3589  end do
3590  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