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

Data Types

type  laktabtype
 
type  lakinputtype
 input context runtime pointers for LAK More...
 
type  laktype
 

Functions/Subroutines

subroutine, public lak_create (packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
 Create a new LAK Package and point bndobj to the new package. More...
 
subroutine lak_allocate_scalars (this)
 Allocate scalar members. More...
 
subroutine lak_allocate_arrays (this)
 Allocate scalar members. More...
 
subroutine lak_source_packagedata (this)
 Source PACKAGEDATA block from input context. More...
 
subroutine lak_source_connectiondata (this)
 Source CONNECTIONDATA block from input context. More...
 
subroutine lak_source_tables (this)
 Source TABLES block from input context. More...
 
subroutine laktables_to_vectors (this, laketables)
 Copy the laketables structure data into flattened vectors that are stored in the memory manager. More...
 
subroutine lak_source_table (this, ilak, mempath, laketable)
 Source one lake's table from its LAKTAB6 subpackage. More...
 
subroutine lak_source_outlets (this)
 Source OUTLETS block from input context. More...
 
subroutine lak_source_dimensions (this)
 Source DIMENSIONS block from input context and load static data. More...
 
subroutine lak_read_initial_attr (this)
 Read the initial parameters for this package. More...
 
subroutine lak_linear_interpolation (this, n, x, y, z, v)
 Perform linear interpolation of two vectors. More...
 
subroutine lak_calculate_sarea (this, ilak, stage, sarea)
 Calculate the surface area of a lake at a given stage. More...
 
subroutine lak_calculate_warea (this, ilak, stage, warea, hin)
 Calculate the wetted area of a lake at a given stage. More...
 
subroutine lak_calculate_conn_warea (this, ilak, iconn, stage, head, wa)
 Calculate the wetted area of a lake connection at a given stage. More...
 
subroutine lak_calculate_vol (this, ilak, stage, volume)
 Calculate the volume of a lake at a given stage. More...
 
subroutine lak_calculate_conductance (this, ilak, stage, conductance)
 Calculate the total conductance for a lake at a provided stage. More...
 
subroutine lak_calculate_cond_head (this, iconn, stage, head, vv)
 Calculate the controlling lake stage or groundwater head used to calculate the conductance for a lake connection from a provided stage and groundwater head. More...
 
subroutine lak_calculate_conn_conductance (this, ilak, iconn, stage, head, cond)
 Calculate the conductance for a lake connection at a provided stage and groundwater head. More...
 
subroutine lak_calculate_exchange (this, ilak, stage, totflow)
 Calculate the total groundwater-lake flow at a provided stage. More...
 
subroutine lak_calculate_conn_exchange (this, ilak, iconn, stage, head, flow, gwfhcof, gwfrhs)
 Calculate the groundwater-lake flow at a provided stage and groundwater head. More...
 
subroutine lak_calculate_conn_exchange_deriv (this, ilak, iconn, stage, head, flow, dqds, dqdh)
 Lakebed seepage and its derivatives for a connection (IMPLICIT) More...
 
subroutine lak_estimate_conn_exchange (this, iflag, ilak, iconn, idry, stage, head, flow, source, gwfhcof, gwfrhs)
 Calculate the groundwater-lake flow at a provided stage and groundwater head. More...
 
subroutine lak_calculate_storagechange (this, ilak, stage, stage0, delt, dvr)
 Calculate the storage change in a lake based on provided stages and a passed delt. More...
 
subroutine lak_calculate_rainfall (this, ilak, stage, ra)
 Calculate the rainfall for a lake. More...
 
subroutine lak_calculate_runoff (this, ilak, ro)
 Calculate runoff to a lake. More...
 
subroutine lak_calculate_inflow (this, ilak, qin)
 Calculate specified inflow to a lake. More...
 
subroutine lak_calculate_external (this, ilak, ex)
 Calculate the external flow terms to a lake. More...
 
subroutine lak_calculate_withdrawal (this, ilak, avail, wr)
 Calculate the withdrawal from a lake subject to an available volume. More...
 
subroutine lak_calculate_evaporation (this, ilak, stage, avail, ev)
 Calculate the evaporation from a lake at a provided stage subject to an available volume. More...
 
subroutine lak_calculate_outlet_inflow (this, ilak, outinf)
 Calculate the outlet inflow to a lake. More...
 
subroutine lak_calculate_outlet_outflow (this, ilak, stage, avail, outoutf)
 Calculate the outlet outflow from a lake. More...
 
subroutine lak_outlet_outflow_rate (this, ilak, stage, qout)
 Total uncapped outlet outflow rate from a lake at a provided stage. More...
 
subroutine lak_get_internal_inlet (this, ilak, outinf)
 Get the outlet inflow to a lake from another lake. More...
 
subroutine lak_get_internal_outlet (this, ilak, outoutf)
 Get the outlet from a lake to another lake. More...
 
subroutine lak_get_external_outlet (this, ilak, outoutf)
 Get the outlet outflow from a lake to an external boundary. More...
 
subroutine lak_get_external_mover (this, ilak, outoutf)
 Get the mover outflow from a lake to an external boundary. More...
 
subroutine lak_get_internal_mover (this, ilak, outoutf)
 Get the mover outflow from a lake to another lake. More...
 
subroutine lak_get_outlet_tomover (this, ilak, outoutf)
 Get the outlet to mover from a lake. More...
 
subroutine lak_vol2stage (this, ilak, vol, stage)
 Determine the stage from a provided volume. More...
 
integer(i4b) function lak_check_valid (this, itemno)
 Determine if a valid lake or outlet number has been specified. More...
 
subroutine lak_set_nonneg_value (this, n, itemno, setting, value_array, label)
 Apply a PERIOD lake setting and require its value be non-negative. More...
 
subroutine lak_set_attribute_error (this, ilak, keyword, msg)
 Issue a parameter error for lake ilak. More...
 
subroutine lak_source_options (this)
 Source OPTIONS block from input context. More...
 
subroutine lak_input_init (this, mempath, naux, noutlets)
 Bind LakInputType pointers. More...
 
subroutine lak_input_destroy (this)
 Nullify all LakInputType pointers. More...
 
subroutine lak_ar (this)
 Allocate and Read. More...
 
subroutine lak_rp (this)
 Read and prepare (stress period data) More...
 
subroutine lak_ad (this)
 Add package connection to matrix. More...
 
subroutine lak_cf (this)
 Formulate the HCOF and RHS terms. More...
 
subroutine lak_fc (this, rhs, ia, idxglo, matrix_sln)
 Copy rhs and hcof into solution rhs and amat. More...
 
subroutine lak_fn (this, rhs, ia, idxglo, matrix_sln)
 Fill newton terms. More...
 
subroutine lak_nur (this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
 Apply Newton under-relaxation to the lake stage. More...
 
subroutine lak_cc (this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
 Final convergence check for package. More...
 
subroutine lak_cq (this, x, flowja, iadv)
 Calculate flows. More...
 
subroutine lak_ot_package_flows (this, icbcfl, ibudfl)
 Output LAK package flow terms. More...
 
subroutine lak_ot_model_flows (this, icbcfl, ibudfl, icbcun, imap)
 Write flows to binary file and/or print flows to budget. More...
 
subroutine lak_ot_dv (this, idvsave, idvprint)
 Save LAK-calculated values to binary file. More...
 
subroutine lak_ot_bdsummary (this, kstp, kper, iout, ibudfl)
 Write LAK budget to listing file. More...
 
subroutine lak_da (this)
 Deallocate objects. More...
 
subroutine define_listlabel (this)
 Define the list heading that is written to iout when PRINT_INPUT option is used. More...
 
subroutine lak_set_pointers (this, neq, ibound, xnew, xold, flowja)
 Set pointers to model arrays and variables so that a package has access to these things. More...
 
subroutine lak_ac (this, moffset, sparse)
 Add the lake rows and columns to the sparse matrix. More...
 
subroutine lak_mc (this, moffset, matrix_sln)
 Find the matrix position of each lake row and connection. More...
 
logical function lak_obs_supported (this)
 Procedures related to observations (type-bound) More...
 
subroutine lak_df_obs (this)
 Store observation type supported by LAK package. Overrides BndTypebnd_df_obs. More...
 
subroutine lak_bd_obs (this)
 Calculate observations this time step and call ObsTypeSaveOneSimval for each LakType observation. More...
 
subroutine lak_rp_obs (this)
 Process each observation. More...
 
subroutine lak_process_obsid (obsrv, dis, inunitobs, iout)
 This procedure is pointed to by ObsDataTypeProcesssIdPtr. It processes the ID string of an observation definition for LAK package observations. More...
 
subroutine lak_accumulate_chterm (this, ilak, rrate, chratin, chratout)
 Accumulate constant head terms for budget. More...
 
subroutine lak_bound_update (this)
 Store the lake head and connection conductance in the bound array. More...
 
subroutine lak_solve (this, update, only_legacy)
 Solve for lake stage. More...
 
subroutine lak_solve_single (this, n, iter, maxiter, ncnv, lupdate)
 Advance one lake stage by a single substitution iteration. More...
 
subroutine lak_estimate_seepage_single (this, n, ncnv)
 Estimate the lakebed seepage for a single lake. More...
 
subroutine lak_bisection (this, n, ibflg, hlak, temporary_stage, dh, residual)
 @ brief Lake package bisection method More...
 
subroutine lak_calculate_available (this, n, hlak, avail, ra, ro, qinf, ex, headp)
 Calculate the available volumetric rate for a lake given a passed stage. More...
 
subroutine lak_calculate_residual (this, n, hlak, resid, headp)
 Calculate the residual for a lake given a passed stage. More...
 
subroutine lak_setup_budobj (this)
 Set up the budget object that stores all the lake flows. More...
 
subroutine lak_fill_budobj (this)
 Copy flow terms into thisbudobj. More...
 
subroutine lak_setup_tableobj (this)
 Set up the table object that is used to write the lak stage data. More...
 
subroutine lak_activate_density (this)
 Activate addition of density terms. More...
 
subroutine lak_activate_viscosity (this)
 Activate viscosity terms. More...
 
subroutine lak_calculate_density_exchange (this, iconn, stage, head, cond, botl, flow, gwfhcof, gwfrhs)
 Calculate the groundwater-lake density exchange terms. More...
 

Variables

character(len=lenftype) ftype = 'LAK'
 
character(len=lenpackagename) text = ' LAK'
 

Function/Subroutine Documentation

◆ define_listlabel()

subroutine lakmodule::define_listlabel ( class(laktype), intent(inout)  this)

Definition at line 4482 of file gwf-lak.f90.

4483  ! -- modules
4484  class(LakType), intent(inout) :: this
4485  !
4486  ! -- create the header list label
4487  this%listlabel = trim(this%filtyp)//' NO.'
4488  if (this%dis%ndim == 3) then
4489  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
4490  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
4491  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
4492  elseif (this%dis%ndim == 2) then
4493  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
4494  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
4495  else
4496  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
4497  end if
4498  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
4499  if (this%inamedbound == 1) then
4500  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
4501  end if

◆ lak_ac()

subroutine lakmodule::lak_ac ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  moffset,
type(sparsematrix), intent(inout)  sparse 
)

Implicit formulation only. Each lake adds one equation (row and column) to the groundwater flow matrix: a diagonal entry, plus a symmetric off-diagonal pair (lake-to-cell and cell-to-lake) for every lake-cell connection.

Definition at line 4549 of file gwf-lak.f90.

4550  use sparsemodule, only: sparsematrix
4551  ! -- dummy
4552  class(LakType), intent(inout) :: this
4553  integer(I4B), intent(in) :: moffset
4554  type(sparsematrix), intent(inout) :: sparse
4555  ! -- local
4556  integer(I4B) :: j, n
4557  integer(I4B) :: jj
4558  integer(I4B) :: jglo
4559  integer(I4B) :: nglo
4560  !
4561  ! -- the default formulation adds no rows to the matrix
4562  if (this%iimplicit == 0) return
4563  !
4564  ! -- add a row for each lake and its connections to the cells
4565  do n = 1, this%nlakes
4566  nglo = moffset + this%dis%nodes + this%ioffset + n
4567  call sparse%addconnection(nglo, nglo, 1)
4568  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4569  jj = this%gwfconn(j)
4570  jglo = jj + moffset
4571  call sparse%addconnection(nglo, jglo, 1)
4572  call sparse%addconnection(jglo, nglo, 1)
4573  end do
4574  end do

◆ lak_accumulate_chterm()

subroutine lakmodule::lak_accumulate_chterm ( class(laktype)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  rrate,
real(dp), intent(inout)  chratin,
real(dp), intent(inout)  chratout 
)
private

Definition at line 5124 of file gwf-lak.f90.

5125  ! -- dummy
5126  class(LakType) :: this
5127  integer(I4B), intent(in) :: ilak
5128  real(DP), intent(in) :: rrate
5129  real(DP), intent(inout) :: chratin
5130  real(DP), intent(inout) :: chratout
5131  ! -- locals
5132  real(DP) :: q
5133  !
5134  ! code
5135  if (this%iboundpak(ilak) < 0) then
5136  q = -rrate
5137  this%chterm(ilak) = this%chterm(ilak) + q
5138  !
5139  ! -- See if flow is into lake or out of lake.
5140  if (q < dzero) then
5141  !
5142  ! -- Flow is out of lake subtract rate from ratout.
5143  chratout = chratout - q
5144  else
5145  !
5146  ! -- Flow is into lake; add rate to ratin.
5147  chratin = chratin + q
5148  end if
5149  end if

◆ lak_activate_density()

subroutine lakmodule::lak_activate_density ( class(laktype), intent(inout)  this)

Definition at line 6337 of file gwf-lak.f90.

6338  ! -- dummy
6339  class(LakType), intent(inout) :: this
6340  ! -- local
6341  integer(I4B) :: i, j
6342  !
6343  ! -- the IMPLICIT formulation does not include the density terms yet
6344  if (this%iimplicit /= 0) then
6345  write (errmsg, '(a)') &
6346  'The IMPLICIT option cannot be used with the BUY package until the &
6347  &implicit formulation includes density terms. Remove the IMPLICIT &
6348  &option from LAK package '//trim(this%packName)//' to simulate &
6349  &density.'
6350  call store_error(errmsg)
6351  call store_error_filename(this%input_fname)
6352  end if
6353  !
6354  ! -- Set idense and reallocate denseterms to be of size MAXBOUND
6355  this%idense = 1
6356  call mem_reallocate(this%denseterms, 3, this%MAXBOUND, 'DENSETERMS', &
6357  this%memoryPath)
6358  do i = 1, this%maxbound
6359  do j = 1, 3
6360  this%denseterms(j, i) = dzero
6361  end do
6362  end do
6363  write (this%iout, '(/1x,a)') 'DENSITY TERMS HAVE BEEN ACTIVATED FOR LAKE &
6364  &PACKAGE: '//trim(adjustl(this%packName))
Here is the call graph for this function:

◆ lak_activate_viscosity()

subroutine lakmodule::lak_activate_viscosity ( class(laktype), intent(inout)  this)
private

Method to activate addition of viscosity terms for a LAK package reach.

Parameters
[in,out]thisLakType object

Definition at line 6371 of file gwf-lak.f90.

6372  ! -- modules
6374  ! -- dummy variables
6375  class(LakType), intent(inout) :: this !< LakType object
6376  ! -- local variables
6377  integer(I4B) :: i
6378  integer(I4B) :: j
6379  !
6380  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
6381  this%ivsc = 1
6382  call mem_reallocate(this%viscratios, 2, this%MAXBOUND, 'VISCRATIOS', &
6383  this%memoryPath)
6384  do i = 1, this%maxbound
6385  do j = 1, 2
6386  this%viscratios(j, i) = done
6387  end do
6388  end do
6389  write (this%iout, '(/1x,a)') 'VISCOSITY HAS BEEN ACTIVATED FOR LAK &
6390  &PACKAGE: '//trim(adjustl(this%packName))

◆ lak_ad()

subroutine lakmodule::lak_ad ( class(laktype)  this)

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

3402  ! -- modules
3404  ! -- dummy
3405  class(LakType) :: this
3406  ! -- local
3407  integer(I4B) :: n
3408  integer(I4B) :: j
3409  integer(I4B) :: iaux
3410  integer(I4B) :: itemno
3411  !
3412  ! -- sync PACKAGEDATA AUX TS and advance observations;
3413  ! sync_period_auxvar (inside bnd_ad) handles PERIOD AUXILIARY TS
3414  call this%BndExtType%bnd_ad()
3415  !
3416  ! -- re-sync static OUTLETS TS values (invert, width, rough, slope);
3417  ! -- skip any field a PERIOD-block setting has already overridden for
3418  ! this outlet -- that override must persist until a later PERIOD
3419  ! block changes it, not be overwritten by this baseline resync
3420  if (this%ts_active .and. this%noutlets > 0) then
3421  do n = 1, size(this%input%outletno)
3422  itemno = this%input%outletno(n)
3423  if (itemno < 1 .or. itemno > this%noutlets) cycle
3424  if (.not. this%outlet_invert_set(itemno)) &
3425  this%outinvert(itemno) = this%input%outlets_invert(n)
3426  if (.not. this%outlet_width_set(itemno)) &
3427  this%outwidth(itemno) = this%input%outlets_width(n)
3428  if (.not. this%outlet_rough_set(itemno)) &
3429  this%outrough(itemno) = this%input%outlets_rough(n)
3430  if (.not. this%outlet_slope_set(itemno)) &
3431  this%outslope(itemno) = this%input%outlets_slope(n)
3432  end do
3433  end if
3434  !
3435  ! -- update auxiliary variables
3436  if (this%naux > 0) then
3437  do n = 1, this%nlakes
3438  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3439  do iaux = 1, this%naux
3440  if (this%noupdateauxvar(iaux) /= 0) cycle
3441  this%auxvar(iaux, j) = this%featureauxvar(iaux, n)
3442  end do
3443  end do
3444  end do
3445  end if
3446  !
3447  ! -- Update or restore state
3448  if (ifailedstepretry == 0) then
3449  !
3450  ! -- copy xnew into xold and set xnewpak to stage for
3451  ! constant stage lakes
3452  do n = 1, this%nlakes
3453  this%xoldpak(n) = this%xnewpak(n)
3454  this%stageiter(n) = this%xnewpak(n)
3455  if (this%iboundpak(n) < 0) then
3456  this%xnewpak(n) = this%stage(n)
3457  end if
3458  this%seep0(n) = dzero
3459  end do
3460  else
3461  !
3462  ! -- copy xold back into xnew as this is a
3463  ! retry of this time step
3464  do n = 1, this%nlakes
3465  this%xnewpak(n) = this%xoldpak(n)
3466  this%stageiter(n) = this%xnewpak(n)
3467  if (this%iboundpak(n) < 0) then
3468  this%xnewpak(n) = this%stage(n)
3469  end if
3470  this%seep0(n) = dzero
3471  end do
3472  end if
3473  !
3474  ! -- pakmvrobj ad
3475  if (this%imover == 1) then
3476  call this%pakmvrobj%ad()
3477  end if
This module contains simulation variables.
Definition: SimVariables.f90:9
integer(i4b) ifailedstepretry
current retry for this time step

◆ lak_allocate_arrays()

subroutine lakmodule::lak_allocate_arrays ( class(laktype), intent(inout)  this)
private

Definition at line 498 of file gwf-lak.f90.

499  ! -- modules
500  ! -- dummy
501  class(LakType), intent(inout) :: this
502  ! -- local
503  integer(I4B) :: i
504  !
505  ! -- call standard BndExtType allocate arrays
506  call this%BndExtType%allocate_arrays()
507  !
508  ! -- allocate featureauxvar and set pkg_ifno/pkg_auxvar input context pointers
509  call this%BndExtType%allocate_featureauxvar()
510  !
511  ! -- allocate character array for budget text
512  allocate (this%clakbudget(this%bditems))
513  !
514  !-- fill clakbudget
515  this%clakbudget(1) = ' GWF'
516  this%clakbudget(2) = ' RAINFALL'
517  this%clakbudget(3) = ' EVAPORATION'
518  this%clakbudget(4) = ' RUNOFF'
519  this%clakbudget(5) = ' EXT-INFLOW'
520  this%clakbudget(6) = ' WITHDRAWAL'
521  this%clakbudget(7) = ' EXT-OUTFLOW'
522  this%clakbudget(8) = ' STORAGE'
523  this%clakbudget(9) = ' CONSTANT'
524  this%clakbudget(10) = ' FROM-MVR'
525  this%clakbudget(11) = ' TO-MVR'
526  !
527  ! -- allocate and initialize dbuff
528  if (this%istageout > 0) then
529  call mem_allocate(this%dbuff, this%nlakes, 'DBUFF', this%memoryPath)
530  do i = 1, this%nlakes
531  this%dbuff(i) = dzero
532  end do
533  else
534  call mem_allocate(this%dbuff, 0, 'DBUFF', this%memoryPath)
535  end if
536  !
537  ! -- allocate character array for budget text
538  allocate (this%cauxcbc(this%cbcauxitems))
539  !
540  ! -- allocate and initialize qauxcbc
541  call mem_allocate(this%qauxcbc, this%cbcauxitems, 'QAUXCBC', this%memoryPath)
542  do i = 1, this%cbcauxitems
543  this%qauxcbc(i) = dzero
544  end do
545  !
546  ! -- allocate qleak and qsto
547  call mem_allocate(this%qleak, this%maxbound, 'QLEAK', this%memoryPath)
548  do i = 1, this%maxbound
549  this%qleak(i) = dzero
550  end do
551  ! -- holdconn is only used by the implicit legacy-switch detector; allocate it at
552  ! size 0 otherwise so legacy LAK runs do not pay the maxbound memory cost
553  if (this%iimplicit /= 0) then
554  call mem_allocate(this%holdconn, this%maxbound, 'HOLDCONN', this%memoryPath)
555  do i = 1, this%maxbound
556  this%holdconn(i) = dzero
557  end do
558  else
559  call mem_allocate(this%holdconn, 0, 'HOLDCONN', this%memoryPath)
560  end if
561  call mem_allocate(this%qsto, this%nlakes, 'QSTO', this%memoryPath)
562  do i = 1, this%nlakes
563  this%qsto(i) = dzero
564  end do
565  !
566  ! -- allocate denseterms to size 0
567  call mem_allocate(this%denseterms, 3, 0, 'DENSETERMS', this%memoryPath)
568  !
569  ! -- allocate viscratios to size 0
570  call mem_allocate(this%viscratios, 2, 0, 'VISCRATIOS', this%memoryPath)

◆ lak_allocate_scalars()

subroutine lakmodule::lak_allocate_scalars ( class(laktype), intent(inout)  this)

Definition at line 436 of file gwf-lak.f90.

437  ! -- dummy
438  class(LakType), intent(inout) :: this
439  !
440  ! -- call standard BndExtType allocate scalars
441  call this%BndExtType%allocate_scalars()
442  !
443  ! -- allocate the object and assign values to object variables
444  call mem_allocate(this%iprhed, 'IPRHED', this%memoryPath)
445  call mem_allocate(this%istageout, 'ISTAGEOUT', this%memoryPath)
446  call mem_allocate(this%ibudgetout, 'IBUDGETOUT', this%memoryPath)
447  call mem_allocate(this%ibudcsv, 'IBUDCSV', this%memoryPath)
448  call mem_allocate(this%ipakcsv, 'IPAKCSV', this%memoryPath)
449  call mem_allocate(this%nlakes, 'NLAKES', this%memoryPath)
450  call mem_allocate(this%noutlets, 'NOUTLETS', this%memoryPath)
451  call mem_allocate(this%ntables, 'NTABLES', this%memoryPath)
452  call mem_allocate(this%convlength, 'CONVLENGTH', this%memoryPath)
453  call mem_allocate(this%convtime, 'CONVTIME', this%memoryPath)
454  call mem_allocate(this%outdmax, 'OUTDMAX', this%memoryPath)
455  call mem_allocate(this%igwhcopt, 'IGWHCOPT', this%memoryPath)
456  call mem_allocate(this%iconvchk, 'ICONVCHK', this%memoryPath)
457  call mem_allocate(this%maxlakit, 'MAXLAKIT', this%memoryPath)
458  call mem_allocate(this%surfdep, 'SURFDEP', this%memoryPath)
459  call mem_allocate(this%dmaxchg, 'DMAXCHG', this%memoryPath)
460  call mem_allocate(this%delh, 'DELH', this%memoryPath)
461  call mem_allocate(this%check_attr, 'CHECK_ATTR', this%memoryPath)
462  call mem_allocate(this%iimplicit, 'IIMPLICIT', this%memoryPath)
463  call mem_allocate(this%iforceleg, 'IFORCELEG', this%memoryPath)
464  call mem_allocate(this%iforceleglak, 'IFORCELEGLAK', this%memoryPath)
465  call mem_allocate(this%bditems, 'BDITEMS', this%memoryPath)
466  call mem_allocate(this%cbcauxitems, 'CBCAUXITEMS', this%memoryPath)
467  call mem_allocate(this%idense, 'IDENSE', this%memoryPath)
468  !
469  ! -- Set values
470  this%iprhed = 0
471  this%istageout = 0
472  this%ibudgetout = 0
473  this%ibudcsv = 0
474  this%ipakcsv = 0
475  this%nlakes = 0
476  this%noutlets = 0
477  this%ntables = 0
478  this%convlength = done
479  this%convtime = done
480  this%outdmax = dzero
481  this%igwhcopt = 0
482  this%iconvchk = 1
483  this%maxlakit = maxadpit
484  this%surfdep = dzero
485  this%dmaxchg = dem5
486  this%delh = dp999 * this%dmaxchg
487  this%iimplicit = 0
488  this%iforceleg = 0
489  this%iforceleglak = 0
490  this%bditems = 11
491  this%cbcauxitems = 1
492  this%idense = 0
493  this%ivsc = 0

◆ lak_ar()

subroutine lakmodule::lak_ar ( class(laktype), intent(inout)  this)
private

Create new LAK package and point bndobj to the new package

Definition at line 3128 of file gwf-lak.f90.

3129  ! -- modules
3130  use constantsmodule, only: mnormal
3131  use inputoutputmodule, only: getunit, openfile
3132  ! -- dummy
3133  class(LakType), intent(inout) :: this
3134  ! -- formats
3135  character(len=*), parameter :: fmtlakbin = &
3136  "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
3137  &a, /4x, 'OPENED ON UNIT: ', I0)"
3138  !
3139  ! -- open the deferred PACKAGE_CONVERGENCE file now that all options have
3140  ! been read. lak_cc does not write package convergence for the implicit
3141  ! formulation, because the lake stage is part of the solver (IMS)
3142  ! convergence check. With the IMPLICIT option the file is therefore left
3143  ! unopened (ipakcsv stays 0) and a warning is issued instead.
3144  if (allocated(this%pakcsvfile)) then
3145  if (this%iimplicit /= 0) then
3146  write (warnmsg, '(a)') &
3147  'PACKAGE_CONVERGENCE output file "'//trim(this%pakcsvfile)// &
3148  '" is not written when the IMPLICIT option is active; the lake '// &
3149  'stage is part of the solver (IMS) convergence check.'
3150  call store_warning(warnmsg)
3151  else
3152  this%ipakcsv = getunit()
3153  call openfile(this%ipakcsv, this%iout, this%pakcsvfile, 'CSV', &
3154  filstat_opt='REPLACE', mode_opt=mnormal)
3155  write (this%iout, fmtlakbin) 'PACKAGE_CONVERGENCE', &
3156  trim(this%pakcsvfile), this%ipakcsv
3157  end if
3158  deallocate (this%pakcsvfile)
3159  end if
3160  !
3161  call this%obs%obs_ar()
3162  !
3163  ! -- Allocate arrays in LAK and in package superclass
3164  call this%lak_allocate_arrays()
3165  !
3166  ! -- read optional initial package parameters
3167  call this%read_initial_attr()
3168  !
3169  ! -- bind input context persistent pointers
3170  call this%input%init(this%input_mempath, this%naux, this%noutlets)
3171  !
3172  ! -- setup pakmvrobj
3173  if (this%imover /= 0) then
3174  allocate (this%pakmvrobj)
3175  call this%pakmvrobj%ar(this%noutlets, this%nlakes, this%memoryPath)
3176  end if
This module contains simulation constants.
Definition: Constants.f90:9
@ mnormal
normal output mode
Definition: Constants.f90:207
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
Here is the call graph for this function:

◆ lak_bd_obs()

subroutine lakmodule::lak_bd_obs ( class(laktype)  this)
private

Definition at line 4765 of file gwf-lak.f90.

4766  ! -- dummy
4767  class(LakType) :: this
4768  ! -- local
4769  integer(I4B) :: i
4770  integer(I4B) :: igwfnode
4771  integer(I4B) :: j
4772  integer(I4B) :: jj
4773  integer(I4B) :: n
4774  real(DP) :: hgwf
4775  real(DP) :: hlak
4776  real(DP) :: v
4777  real(DP) :: v2
4778  type(ObserveType), pointer :: obsrv => null()
4779  !
4780  ! Write simulated values for all LAK observations
4781  if (this%obs%npakobs > 0) then
4782  call this%obs%obs_bd_clear()
4783  do i = 1, this%obs%npakobs
4784  obsrv => this%obs%pakobs(i)%obsrv
4785  do j = 1, obsrv%indxbnds_count
4786  v = dnodata
4787  jj = obsrv%indxbnds(j)
4788  select case (obsrv%ObsTypeId)
4789  case ('STAGE')
4790  if (this%iboundpak(jj) /= 0) then
4791  v = this%xnewpak(jj)
4792  end if
4793  case ('EXT-INFLOW')
4794  if (this%iboundpak(jj) /= 0) then
4795  call this%lak_calculate_inflow(jj, v)
4796  end if
4797  case ('OUTLET-INFLOW')
4798  if (this%iboundpak(jj) /= 0) then
4799  call this%lak_calculate_outlet_inflow(jj, v)
4800  end if
4801  case ('INFLOW')
4802  if (this%iboundpak(jj) /= 0) then
4803  call this%lak_calculate_inflow(jj, v)
4804  call this%lak_calculate_outlet_inflow(jj, v2)
4805  v = v + v2
4806  end if
4807  case ('FROM-MVR')
4808  if (this%iboundpak(jj) /= 0) then
4809  if (this%imover == 1) then
4810  v = this%pakmvrobj%get_qfrommvr(jj)
4811  end if
4812  end if
4813  case ('RAINFALL')
4814  if (this%iboundpak(jj) /= 0) then
4815  v = this%precip(jj)
4816  end if
4817  case ('RUNOFF')
4818  if (this%iboundpak(jj) /= 0) then
4819  v = this%runoff(jj)
4820  end if
4821  case ('LAK')
4822  n = this%imap(jj)
4823  if (this%iboundpak(n) /= 0) then
4824  igwfnode = this%gwfconn(jj)
4825  hgwf = this%xnew(igwfnode)
4826  if (this%hcof(jj) /= dzero) then
4827  v = -(this%hcof(jj) * (this%xnewpak(n) - hgwf))
4828  else
4829  v = -this%rhs(jj)
4830  end if
4831  end if
4832  case ('EVAPORATION')
4833  if (this%iboundpak(jj) /= 0) then
4834  v = this%evap(jj)
4835  end if
4836  case ('WITHDRAWAL')
4837  if (this%iboundpak(jj) /= 0) then
4838  v = this%withr(jj)
4839  end if
4840  case ('EXT-OUTFLOW')
4841  n = this%lakein(jj)
4842  if (this%iboundpak(n) /= 0) then
4843  if (this%lakeout(jj) == 0) then
4844  v = this%simoutrate(jj)
4845  if (v < dzero) then
4846  if (this%imover == 1) then
4847  v = v + this%pakmvrobj%get_qtomvr(jj)
4848  end if
4849  end if
4850  end if
4851  end if
4852  case ('TO-MVR')
4853  n = this%lakein(jj)
4854  if (this%iboundpak(n) /= 0) then
4855  if (this%imover == 1) then
4856  v = this%pakmvrobj%get_qtomvr(jj)
4857  if (v > dzero) then
4858  v = -v
4859  end if
4860  end if
4861  end if
4862  case ('STORAGE')
4863  if (this%iboundpak(jj) /= 0) then
4864  v = this%qsto(jj)
4865  end if
4866  case ('CONSTANT')
4867  if (this%iboundpak(jj) /= 0) then
4868  v = this%chterm(jj)
4869  end if
4870  case ('OUTLET')
4871  n = this%lakein(jj)
4872  if (this%iboundpak(n) /= 0) then
4873  v = this%simoutrate(jj)
4874  end if
4875  case ('VOLUME')
4876  if (this%iboundpak(jj) /= 0) then
4877  call this%lak_calculate_vol(jj, this%xnewpak(jj), v)
4878  end if
4879  case ('SURFACE-AREA')
4880  if (this%iboundpak(jj) /= 0) then
4881  hlak = this%xnewpak(jj)
4882  call this%lak_calculate_sarea(jj, hlak, v)
4883  end if
4884  case ('WETTED-AREA')
4885  n = this%imap(jj)
4886  if (this%iboundpak(n) /= 0) then
4887  hlak = this%xnewpak(n)
4888  igwfnode = this%gwfconn(jj)
4889  hgwf = this%xnew(igwfnode)
4890  call this%lak_calculate_conn_warea(n, jj, hlak, hgwf, v)
4891  end if
4892  case ('CONDUCTANCE')
4893  n = this%imap(jj)
4894  if (this%iboundpak(n) /= 0) then
4895  hlak = this%xnewpak(n)
4896  igwfnode = this%gwfconn(jj)
4897  hgwf = this%xnew(igwfnode)
4898  call this%lak_calculate_conn_conductance(n, jj, hlak, hgwf, v)
4899  end if
4900  case default
4901  errmsg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
4902  call store_error(errmsg)
4903  end select
4904  call this%obs%SaveOneSimval(obsrv, v)
4905  end do
4906  end do
4907  !
4908  ! -- write summary of error messages
4909  if (count_errors() > 0) then
4910  call store_error_unit(this%inunit)
4911  end if
4912  end if
Here is the call graph for this function:

◆ lak_bisection()

subroutine lakmodule::lak_bisection ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(inout)  ibflg,
real(dp), intent(in)  hlak,
real(dp), intent(inout)  temporary_stage,
real(dp), intent(inout)  dh,
real(dp), intent(inout)  residual 
)
private

Use bisection method to find lake stage that reduces the residual

Parameters
[in]nlake number
[in,out]ibflgbisection flag
[in]hlaklake stage
[in,out]temporary_stagetemporary lake stage
[in,out]dhlake stage change
[in,out]residuallake residual

Definition at line 5641 of file gwf-lak.f90.

5642  ! -- dummy
5643  class(LakType), intent(inout) :: this
5644  integer(I4B), intent(in) :: n !< lake number
5645  integer(I4B), intent(inout) :: ibflg !< bisection flag
5646  real(DP), intent(in) :: hlak !< lake stage
5647  real(DP), intent(inout) :: temporary_stage !< temporary lake stage
5648  real(DP), intent(inout) :: dh !< lake stage change
5649  real(DP), intent(inout) :: residual !< lake residual
5650  ! -- local
5651  integer(I4B) :: i
5652  real(DP) :: temporary_stage0
5653  real(DP) :: residuala
5654  real(DP) :: endpoint1
5655  real(DP) :: endpoint2
5656  ! -- code
5657  ibflg = 1
5658  temporary_stage0 = hlak
5659  endpoint1 = this%en1(n)
5660  endpoint2 = this%en2(n)
5661  call this%lak_calculate_residual(n, temporary_stage, residuala)
5662  if (hlak > endpoint1 .and. hlak < endpoint2) then
5663  endpoint2 = hlak
5664  end if
5665  do i = 1, this%maxlakit
5666  temporary_stage = dhalf * (endpoint1 + endpoint2)
5667  call this%lak_calculate_residual(n, temporary_stage, residual)
5668  if (abs(residual) == dzero .or. &
5669  abs(temporary_stage0 - temporary_stage) < this%dmaxchg) then
5670  exit
5671  end if
5672  call this%lak_calculate_residual(n, endpoint1, residuala)
5673  ! -- change end points
5674  ! -- root is between temporary_stage and endpoint2
5675  if (sign(done, residuala) == sign(done, residual)) then
5676  endpoint1 = temporary_stage
5677  ! -- root is between endpoint1 and temporary_stage
5678  else
5679  endpoint2 = temporary_stage
5680  end if
5681  temporary_stage0 = temporary_stage
5682  end do
5683  dh = hlak - temporary_stage

◆ lak_bound_update()

subroutine lakmodule::lak_bound_update ( class(laktype), intent(inout)  this)
private

Definition at line 5154 of file gwf-lak.f90.

5155  ! -- dummy
5156  class(LakType), intent(inout) :: this
5157  ! -- local
5158  integer(I4B) :: j, n, node
5159  real(DP) :: hlak, head, clak
5160  !
5161  ! -- Return if no lak lakes
5162  if (this%nbound == 0) return
5163  !
5164  ! -- Calculate hcof and rhs for each lak entry
5165  do n = 1, this%nlakes
5166  hlak = this%xnewpak(n)
5167  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5168  node = this%gwfconn(j)
5169  head = this%xnew(node)
5170  call this%lak_calculate_conn_conductance(n, j, hlak, head, clak)
5171  this%bound(1, j) = hlak
5172  this%bound(2, j) = clak
5173  end do
5174  end do

◆ lak_calculate_available()

subroutine lakmodule::lak_calculate_available ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  hlak,
real(dp), intent(inout)  avail,
real(dp), intent(inout)  ra,
real(dp), intent(inout)  ro,
real(dp), intent(inout)  qinf,
real(dp), intent(inout)  ex,
real(dp), intent(in), optional  headp 
)
private

Definition at line 5689 of file gwf-lak.f90.

5691  ! -- modules
5692  use tdismodule, only: delt
5693  ! -- dummy
5694  class(LakType), intent(inout) :: this
5695  integer(I4B), intent(in) :: n
5696  real(DP), intent(in) :: hlak
5697  real(DP), intent(inout) :: avail
5698  real(DP), intent(inout) :: ra
5699  real(DP), intent(inout) :: ro
5700  real(DP), intent(inout) :: qinf
5701  real(DP), intent(inout) :: ex
5702  real(DP), intent(in), optional :: headp
5703  ! -- local
5704  integer(I4B) :: j
5705  integer(I4B) :: idry
5706  integer(I4B) :: igwfnode
5707  real(DP) :: hp
5708  real(DP) :: head
5709  real(DP) :: qlakgw
5710  real(DP) :: v0
5711  !
5712  ! -- set hp
5713  if (present(headp)) then
5714  hp = headp
5715  else
5716  hp = dzero
5717  end if
5718  !
5719  ! -- initialize
5720  avail = dzero
5721  !
5722  ! -- calculate the aquifer sources to the lake
5723  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5724  igwfnode = this%gwfconn(j)
5725  if (this%ibound(igwfnode) == 0) cycle
5726  head = this%xnew(igwfnode) + hp
5727  call this%lak_estimate_conn_exchange(1, n, j, idry, hlak, head, qlakgw, &
5728  avail)
5729  end do
5730  !
5731  ! -- add rainfall
5732  call this%lak_calculate_rainfall(n, hlak, ra)
5733  avail = avail + ra
5734  !
5735  ! -- calculate runoff
5736  call this%lak_calculate_runoff(n, ro)
5737  avail = avail + ro
5738  !
5739  ! -- calculate inflow
5740  call this%lak_calculate_inflow(n, qinf)
5741  avail = avail + qinf
5742  !
5743  ! -- calculate external flow terms
5744  call this%lak_calculate_external(n, ex)
5745  avail = avail + ex
5746  !
5747  ! -- calculate volume available in storage
5748  call this%lak_calculate_vol(n, this%xoldpak(n), v0)
5749  avail = avail + v0 / delt
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:32

◆ lak_calculate_cond_head()

subroutine lakmodule::lak_calculate_cond_head ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  iconn,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(inout)  vv 
)
private

Definition at line 2093 of file gwf-lak.f90.

2094  ! -- dummy
2095  class(LakType), intent(inout) :: this
2096  integer(I4B), intent(in) :: iconn
2097  real(DP), intent(in) :: stage
2098  real(DP), intent(in) :: head
2099  real(DP), intent(inout) :: vv
2100  ! -- local
2101  real(DP) :: ss
2102  real(DP) :: hh
2103  real(DP) :: topl
2104  real(DP) :: botl
2105  !
2106  topl = this%telev(iconn)
2107  botl = this%belev(iconn)
2108  ss = min(stage, topl)
2109  hh = min(head, topl)
2110  if (this%igwhcopt > 0) then
2111  vv = hh
2112  else if (this%inewton > 0) then
2113  vv = max(ss, hh)
2114  else
2115  vv = dhalf * (ss + hh)
2116  end if

◆ lak_calculate_conductance()

subroutine lakmodule::lak_calculate_conductance ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  conductance 
)
private

Definition at line 2072 of file gwf-lak.f90.

2073  ! -- dummy
2074  class(LakType), intent(inout) :: this
2075  integer(I4B), intent(in) :: ilak
2076  real(DP), intent(in) :: stage
2077  real(DP), intent(inout) :: conductance
2078  ! -- local
2079  integer(I4B) :: i
2080  real(DP) :: c
2081  !
2082  conductance = dzero
2083  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2084  call this%lak_calculate_conn_conductance(ilak, i, stage, stage, c)
2085  conductance = conductance + c
2086  end do

◆ lak_calculate_conn_conductance()

subroutine lakmodule::lak_calculate_conn_conductance ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
integer(i4b), intent(in)  iconn,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(inout)  cond 
)
private

Definition at line 2122 of file gwf-lak.f90.

2123  ! -- dummy
2124  class(LakType), intent(inout) :: this
2125  integer(I4B), intent(in) :: ilak
2126  integer(I4B), intent(in) :: iconn
2127  real(DP), intent(in) :: stage
2128  real(DP), intent(in) :: head
2129  real(DP), intent(inout) :: cond
2130  ! -- local
2131  integer(I4B) :: node
2132  !real(DP) :: ss
2133  !real(DP) :: hh
2134  real(DP) :: vv
2135  real(DP) :: topl
2136  real(DP) :: botl
2137  real(DP) :: sat
2138  real(DP) :: wa
2139  real(DP) :: vscratio
2140  !
2141  cond = dzero
2142  vscratio = done
2143  topl = this%telev(iconn)
2144  botl = this%belev(iconn)
2145  call this%lak_calculate_cond_head(iconn, stage, head, vv)
2146  sat = squadraticsaturation(topl, botl, vv)
2147  ! vertical connection
2148  ! use full saturated conductance if top and bottom of the lake connection
2149  ! are equal
2150  if (this%ictype(iconn) == 0) then
2151  if (abs(topl - botl) < dprec) then
2152  sat = done
2153  end if
2154  ! horizontal connection
2155  ! use full saturated conductance if the connected cell is not convertible
2156  else if (this%ictype(iconn) == 1) then
2157  node = this%gwfconn(iconn)
2158  if (this%icelltype(node) == 0) then
2159  sat = done
2160  end if
2161  ! embedded connection
2162  else if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
2163  node = this%gwfconn(iconn)
2164  if (this%icelltype(node) == 0) then
2165  vv = this%telev(iconn)
2166  call this%lak_calculate_conn_warea(ilak, iconn, vv, vv, wa)
2167  else
2168  call this%lak_calculate_conn_warea(ilak, iconn, stage, head, wa)
2169  end if
2170  sat = wa
2171  end if
2172  !
2173  ! -- account for viscosity effects (if vsc active)
2174  if (this%ivsc == 1) then
2175  ! flow from lake to aquifer
2176  if (stage > head) then
2177  vscratio = this%viscratios(1, iconn)
2178  ! flow from aquifer to lake
2179  else
2180  vscratio = this%viscratios(2, iconn)
2181  end if
2182  end if
2183  cond = sat * this%satcond(iconn) * vscratio
Here is the call graph for this function:

◆ lak_calculate_conn_exchange()

subroutine lakmodule::lak_calculate_conn_exchange ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
integer(i4b), intent(in)  iconn,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(inout)  flow,
real(dp), intent(inout), optional  gwfhcof,
real(dp), intent(inout), optional  gwfrhs 
)
private

Definition at line 2212 of file gwf-lak.f90.

2214  ! -- dummy
2215  class(LakType), intent(inout) :: this
2216  integer(I4B), intent(in) :: ilak
2217  integer(I4B), intent(in) :: iconn
2218  real(DP), intent(in) :: stage
2219  real(DP), intent(in) :: head
2220  real(DP), intent(inout) :: flow
2221  real(DP), intent(inout), optional :: gwfhcof
2222  real(DP), intent(inout), optional :: gwfrhs
2223  ! -- local
2224  real(DP) :: botl
2225  real(DP) :: cond
2226  real(DP) :: ss
2227  real(DP) :: hh
2228  real(DP) :: gwfhcof0
2229  real(DP) :: gwfrhs0
2230  !
2231  flow = dzero
2232  call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2233  botl = this%belev(iconn)
2234  !
2235  ! -- Set ss to stage or botl
2236  if (stage >= botl) then
2237  ss = stage
2238  else
2239  ss = botl
2240  end if
2241  !
2242  ! -- set hh to head or botl
2243  if (head >= botl) then
2244  hh = head
2245  else
2246  hh = botl
2247  end if
2248  !
2249  ! -- calculate flow, positive into lake
2250  flow = cond * (hh - ss)
2251  !
2252  ! -- Calculate gwfhcof and gwfrhs
2253  if (head >= botl) then
2254  gwfhcof0 = -cond
2255  gwfrhs0 = -cond * ss
2256  else
2257  gwfhcof0 = dzero
2258  gwfrhs0 = flow
2259  end if
2260  !
2261  ! Add density contributions, if active
2262  if (this%idense /= 0) then
2263  call this%lak_calculate_density_exchange(iconn, stage, head, cond, botl, &
2264  flow, gwfhcof0, gwfrhs0)
2265  end if
2266  !
2267  ! -- If present update gwfhcof and gwfrhs
2268  if (present(gwfhcof)) gwfhcof = gwfhcof0
2269  if (present(gwfrhs)) gwfrhs = gwfrhs0

◆ lak_calculate_conn_exchange_deriv()

subroutine lakmodule::lak_calculate_conn_exchange_deriv ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
integer(i4b), intent(in)  iconn,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(inout)  flow,
real(dp), intent(inout), optional  dqds,
real(dp), intent(inout), optional  dqdh 
)
private

Returns the lakebed seepage for one connection, positive into the lake, and optionally its stage and head derivatives. The stage and the connected- cell head are each held at or above the lake bottom, the same wet/dry cutoff used by the default formulation, so the implicit seepage matches the default formulation exactly. lak_fc_implicit uses this to assemble the matrix and lak_cq uses it to report the budget, so the two are consistent.

Definition at line 2281 of file gwf-lak.f90.

2283  ! -- dummy
2284  class(LakType), intent(inout) :: this
2285  integer(I4B), intent(in) :: ilak
2286  integer(I4B), intent(in) :: iconn
2287  real(DP), intent(in) :: stage
2288  real(DP), intent(in) :: head
2289  real(DP), intent(inout) :: flow
2290  real(DP), intent(inout), optional :: dqds
2291  real(DP), intent(inout), optional :: dqdh
2292  ! -- local
2293  real(DP) :: cond, botl, dps, dph, ss, hh
2294  !
2295  call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2296  botl = this%belev(iconn)
2297  if (stage >= botl) then
2298  ss = stage
2299  dps = done
2300  else
2301  ss = botl
2302  dps = dzero
2303  end if
2304  if (head >= botl) then
2305  hh = head
2306  dph = done
2307  else
2308  hh = botl
2309  dph = dzero
2310  end if
2311  flow = cond * (hh - ss)
2312  if (present(dqds)) dqds = -cond * dps
2313  if (present(dqdh)) dqdh = cond * dph

◆ lak_calculate_conn_warea()

subroutine lakmodule::lak_calculate_conn_warea ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
integer(i4b), intent(in)  iconn,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(inout)  wa 
)
private

Definition at line 1968 of file gwf-lak.f90.

1969  ! -- dummy
1970  class(LakType), intent(inout) :: this
1971  integer(I4B), intent(in) :: ilak
1972  integer(I4B), intent(in) :: iconn
1973  real(DP), intent(in) :: stage
1974  real(DP), intent(in) :: head
1975  real(DP), intent(inout) :: wa
1976  ! -- local
1977  integer(I4B) :: i
1978  integer(I4B) :: ifirst
1979  integer(I4B) :: ilast
1980  integer(I4B) :: node
1981  real(DP) :: topl
1982  real(DP) :: botl
1983  real(DP) :: vv
1984  real(DP) :: sat
1985  !
1986  wa = dzero
1987  topl = this%telev(iconn)
1988  botl = this%belev(iconn)
1989  call this%lak_calculate_cond_head(iconn, stage, head, vv)
1990  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1991  if (vv > topl) vv = topl
1992  i = this%ntabrow(ilak)
1993  ifirst = this%ialaktab(ilak)
1994  ilast = this%ialaktab(ilak + 1) - 1
1995  if (vv <= this%tabstage(ifirst)) then
1996  wa = this%tabwarea(ifirst)
1997  else if (vv >= this%tabstage(ilast)) then
1998  wa = this%tabwarea(ilast)
1999  else
2000  call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2001  this%tabwarea(ifirst:ilast), &
2002  vv, wa)
2003  end if
2004  else
2005  node = this%gwfconn(iconn)
2006  ! -- confined cell
2007  if (this%icelltype(node) == 0) then
2008  sat = done
2009  ! -- convertible cell
2010  else
2011  sat = squadraticsaturation(topl, botl, vv)
2012  end if
2013  wa = sat * this%warea(iconn)
2014  end if
Here is the call graph for this function:

◆ lak_calculate_density_exchange()

subroutine lakmodule::lak_calculate_density_exchange ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  iconn,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(in)  cond,
real(dp), intent(in)  botl,
real(dp), intent(inout)  flow,
real(dp), intent(inout)  gwfhcof,
real(dp), intent(inout)  gwfrhs 
)

Arguments are as follows: iconn : lak-gwf connection number stage : lake stage head : gwf head cond : conductance botl : bottom elevation of this connection flow : calculated flow, updated here with density terms gwfhcof : gwf head coefficient, updated here with density terms gwfrhs : gwf right-hand-side value, updated here with density terms

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

Definition at line 6411 of file gwf-lak.f90.

6413  ! -- dummy
6414  class(LakType), intent(inout) :: this
6415  integer(I4B), intent(in) :: iconn
6416  real(DP), intent(in) :: stage
6417  real(DP), intent(in) :: head
6418  real(DP), intent(in) :: cond
6419  real(DP), intent(in) :: botl
6420  real(DP), intent(inout) :: flow
6421  real(DP), intent(inout) :: gwfhcof
6422  real(DP), intent(inout) :: gwfrhs
6423  ! -- local
6424  real(DP) :: ss
6425  real(DP) :: hh
6426  real(DP) :: havg
6427  real(DP) :: rdenselak
6428  real(DP) :: rdensegwf
6429  real(DP) :: rdenseavg
6430  real(DP) :: elevlak
6431  real(DP) :: elevgwf
6432  real(DP) :: elevavg
6433  real(DP) :: d1
6434  real(DP) :: d2
6435  logical(LGP) :: stage_below_bot
6436  logical(LGP) :: head_below_bot
6437  !
6438  ! -- Set lak density to lak density or gwf density
6439  if (stage >= botl) then
6440  ss = stage
6441  stage_below_bot = .false.
6442  rdenselak = this%denseterms(1, iconn) ! lak rel density
6443  else
6444  ss = botl
6445  stage_below_bot = .true.
6446  rdenselak = this%denseterms(2, iconn) ! gwf rel density
6447  end if
6448  !
6449  ! -- set hh to head or botl
6450  if (head >= botl) then
6451  hh = head
6452  head_below_bot = .false.
6453  rdensegwf = this%denseterms(2, iconn) ! gwf rel density
6454  else
6455  hh = botl
6456  head_below_bot = .true.
6457  rdensegwf = this%denseterms(1, iconn) ! lak rel density
6458  end if
6459  !
6460  ! -- todo: hack because denseterms not updated in a cf calculation
6461  if (rdensegwf == dzero) return
6462  !
6463  ! -- Update flow
6464  if (stage_below_bot .and. head_below_bot) then
6465  !
6466  ! -- flow is zero, so no terms are updated
6467  !
6468  else
6469  !
6470  ! -- calculate average relative density
6471  rdenseavg = dhalf * (rdenselak + rdensegwf)
6472  !
6473  ! -- Add contribution of first density term:
6474  ! cond * (denseavg/denseref - 1) * (hgwf - hlak)
6475  d1 = cond * (rdenseavg - done)
6476  gwfhcof = gwfhcof - d1
6477  gwfrhs = gwfrhs - d1 * ss
6478  d1 = d1 * (hh - ss)
6479  flow = flow + d1
6480  !
6481  ! -- Add second density term if stage and head not below bottom
6482  if (.not. stage_below_bot .and. .not. head_below_bot) then
6483  !
6484  ! -- Add contribution of second density term:
6485  ! cond * (havg - elevavg) * (densegwf - denselak) / denseref
6486  elevgwf = this%denseterms(3, iconn)
6487  if (this%ictype(iconn) == 0 .or. this%ictype(iconn) == 3) then
6488  ! -- vertical or embedded vertical connection
6489  elevlak = botl
6490  else
6491  ! -- horizontal or embedded horizontal connection
6492  elevlak = elevgwf
6493  end if
6494  elevavg = dhalf * (elevlak + elevgwf)
6495  havg = dhalf * (hh + ss)
6496  d2 = cond * (havg - elevavg) * (rdensegwf - rdenselak)
6497  gwfrhs = gwfrhs + d2
6498  flow = flow + d2
6499  end if
6500  end if

◆ lak_calculate_evaporation()

subroutine lakmodule::lak_calculate_evaporation ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  avail,
real(dp), intent(inout)  ev 
)
private

Definition at line 2468 of file gwf-lak.f90.

2469  ! -- dummy
2470  class(LakType), intent(inout) :: this
2471  integer(I4B), intent(in) :: ilak
2472  real(DP), intent(in) :: stage
2473  real(DP), intent(inout) :: avail
2474  real(DP), intent(inout) :: ev
2475  ! -- local
2476  real(DP) :: sa
2477  !
2478  ! -- evaporation - limit to sum of inflows and available volume
2479  call this%lak_calculate_sarea(ilak, stage, sa)
2480  ev = sa * this%evaporation(ilak)
2481  if (ev > avail) then
2482  if (is_close(avail, dprec)) then
2483  ev = dzero
2484  else
2485  ev = -avail
2486  end if
2487  else
2488  ev = -ev
2489  end if
2490  avail = avail + ev
Here is the call graph for this function:

◆ lak_calculate_exchange()

subroutine lakmodule::lak_calculate_exchange ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  totflow 
)
private

Definition at line 2188 of file gwf-lak.f90.

2189  ! -- dummy
2190  class(LakType), intent(inout) :: this
2191  integer(I4B), intent(in) :: ilak
2192  real(DP), intent(in) :: stage
2193  real(DP), intent(inout) :: totflow
2194  ! -- local
2195  integer(I4B) :: j
2196  integer(I4B) :: igwfnode
2197  real(DP) :: flow
2198  real(DP) :: hgwf
2199  !
2200  totflow = dzero
2201  do j = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2202  igwfnode = this%gwfconn(j)
2203  hgwf = this%xnew(igwfnode)
2204  call this%lak_calculate_conn_exchange(ilak, j, stage, hgwf, flow)
2205  totflow = totflow + flow
2206  end do

◆ lak_calculate_external()

subroutine lakmodule::lak_calculate_external ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  ex 
)
private

Definition at line 2430 of file gwf-lak.f90.

2431  ! -- dummy
2432  class(LakType), intent(inout) :: this
2433  integer(I4B), intent(in) :: ilak
2434  real(DP), intent(inout) :: ex
2435  !
2436  ! -- If mover is active, add receiver water to rhs and
2437  ! store available water (as positive value)
2438  ex = dzero
2439  if (this%imover == 1) then
2440  ex = this%pakmvrobj%get_qfrommvr(ilak)
2441  end if

◆ lak_calculate_inflow()

subroutine lakmodule::lak_calculate_inflow ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  qin 
)
private

Definition at line 2418 of file gwf-lak.f90.

2419  ! -- dummy
2420  class(LakType), intent(inout) :: this
2421  integer(I4B), intent(in) :: ilak
2422  real(DP), intent(inout) :: qin
2423  !
2424  ! -- inflow to lake
2425  qin = this%inflow(ilak)

◆ lak_calculate_outlet_inflow()

subroutine lakmodule::lak_calculate_outlet_inflow ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outinf 
)
private

Definition at line 2495 of file gwf-lak.f90.

2496  ! -- dummy
2497  class(LakType), intent(inout) :: this
2498  integer(I4B), intent(in) :: ilak
2499  real(DP), intent(inout) :: outinf
2500  ! -- local
2501  integer(I4B) :: n
2502  !
2503  outinf = dzero
2504  do n = 1, this%noutlets
2505  if (this%lakeout(n) == ilak) then
2506  outinf = outinf - this%simoutrate(n)
2507  if (this%imover == 1) then
2508  outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2509  end if
2510  end if
2511  end do

◆ lak_calculate_outlet_outflow()

subroutine lakmodule::lak_calculate_outlet_outflow ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  avail,
real(dp), intent(inout)  outoutf 
)
private

Definition at line 2516 of file gwf-lak.f90.

2517  ! -- dummy
2518  class(LakType), intent(inout) :: this
2519  integer(I4B), intent(in) :: ilak
2520  real(DP), intent(in) :: stage
2521  real(DP), intent(inout) :: avail
2522  real(DP), intent(inout) :: outoutf
2523  ! -- local
2524  integer(I4B) :: n
2525  real(DP) :: g
2526  real(DP) :: d
2527  real(DP) :: c
2528  real(DP) :: gsm
2529  real(DP) :: rate
2530  !
2531  outoutf = dzero
2532  do n = 1, this%noutlets
2533  if (this%lakein(n) == ilak) then
2534  rate = dzero
2535  d = stage - this%outinvert(n)
2536  if (this%outdmax > dzero) then
2537  if (d > this%outdmax) d = this%outdmax
2538  end if
2539  g = dgravity * this%convlength * this%convtime * this%convtime
2540  select case (this%iouttype(n))
2541  ! specified rate
2542  case (0)
2543  rate = this%outrate(n)
2544  if (-rate > avail) then
2545  rate = -avail
2546  end if
2547  ! manning
2548  case (1)
2549  if (d > dzero) then
2550  c = (this%convlength**donethird) * this%convtime
2551  gsm = dzero
2552  if (this%outrough(n) > dzero) then
2553  gsm = done / this%outrough(n)
2554  end if
2555  rate = -c * gsm * this%outwidth(n) * (d**dfivethirds) * &
2556  sqrt(this%outslope(n))
2557  end if
2558  ! weir
2559  case (2)
2560  if (d > dzero) then
2561  rate = -dtwothirds * dcd * this%outwidth(n) * d * &
2562  sqrt(dtwo * g * d)
2563  end if
2564  end select
2565  this%simoutrate(n) = rate
2566  avail = avail + rate
2567  outoutf = outoutf + rate
2568  end if
2569  end do

◆ lak_calculate_rainfall()

subroutine lakmodule::lak_calculate_rainfall ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  ra 
)
private

Definition at line 2384 of file gwf-lak.f90.

2385  ! -- dummy
2386  class(LakType), intent(inout) :: this
2387  integer(I4B), intent(in) :: ilak
2388  real(DP), intent(in) :: stage
2389  real(DP), intent(inout) :: ra
2390  ! -- local
2391  integer(I4B) :: iconn
2392  real(DP) :: sa
2393  !
2394  ! -- rainfall
2395  iconn = this%idxlakeconn(ilak)
2396  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
2397  sa = this%sareamax(ilak)
2398  else
2399  call this%lak_calculate_sarea(ilak, stage, sa)
2400  end if
2401  ra = this%rainfall(ilak) * sa

◆ lak_calculate_residual()

subroutine lakmodule::lak_calculate_residual ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
real(dp), intent(in)  hlak,
real(dp), intent(inout)  resid,
real(dp), intent(in), optional  headp 
)

Definition at line 5754 of file gwf-lak.f90.

5755  ! -- modules
5756  use tdismodule, only: delt
5757  ! -- dummy
5758  class(LakType), intent(inout) :: this
5759  integer(I4B), intent(in) :: n
5760  real(DP), intent(in) :: hlak
5761  real(DP), intent(inout) :: resid
5762  real(DP), intent(in), optional :: headp
5763  ! -- local
5764  integer(I4B) :: j
5765  integer(I4B) :: idry
5766  integer(I4B) :: igwfnode
5767  real(DP) :: hp
5768  real(DP) :: avail
5769  real(DP) :: head
5770  real(DP) :: ra
5771  real(DP) :: ro
5772  real(DP) :: qinf
5773  real(DP) :: ex
5774  real(DP) :: ev
5775  real(DP) :: wr
5776  real(DP) :: sout
5777  real(DP) :: sin
5778  real(DP) :: qlakgw
5779  real(DP) :: seep
5780  real(DP) :: hlak0
5781  real(DP) :: v0
5782  real(DP) :: v1
5783  !
5784  ! -- set hp
5785  if (present(headp)) then
5786  hp = headp
5787  else
5788  hp = dzero
5789  end if
5790  !
5791  ! -- initialize
5792  resid = dzero
5793  avail = dzero
5794  seep = dzero
5795  !
5796  ! -- calculate the available water
5797  call this%lak_calculate_available(n, hlak, avail, &
5798  ra, ro, qinf, ex, hp)
5799  !
5800  ! -- calculate groundwater seepage
5801  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5802  igwfnode = this%gwfconn(j)
5803  if (this%ibound(igwfnode) == 0) cycle
5804  head = this%xnew(igwfnode) + hp
5805  call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, head, qlakgw, &
5806  avail)
5807  seep = seep + qlakgw
5808  end do
5809  !
5810  ! -- limit withdrawals to lake inflows and lake storage
5811  call this%lak_calculate_withdrawal(n, avail, wr)
5812  !
5813  ! -- limit evaporation to lake inflows and lake storage
5814  call this%lak_calculate_evaporation(n, hlak, avail, ev)
5815  !
5816  ! -- no outlet flow if evaporation consumes all water
5817  call this%lak_calculate_outlet_outflow(n, hlak, avail, sout)
5818  !
5819  ! -- update the surface inflow values
5820  call this%lak_calculate_outlet_inflow(n, sin)
5821  !
5822  ! -- calculate residual
5823  resid = ra + ev + wr + ro + qinf + ex + sin + sout + seep
5824  !
5825  ! -- include storage
5826  if (this%gwfiss /= 1) then
5827  hlak0 = this%xoldpak(n)
5828  call this%lak_calculate_vol(n, hlak0, v0)
5829  call this%lak_calculate_vol(n, hlak, v1)
5830  resid = resid + (v0 - v1) / delt
5831  end if

◆ lak_calculate_runoff()

subroutine lakmodule::lak_calculate_runoff ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  ro 
)
private

Definition at line 2406 of file gwf-lak.f90.

2407  ! -- dummy
2408  class(LakType), intent(inout) :: this
2409  integer(I4B), intent(in) :: ilak
2410  real(DP), intent(inout) :: ro
2411  !
2412  ! -- runoff
2413  ro = this%runoff(ilak)

◆ lak_calculate_sarea()

subroutine lakmodule::lak_calculate_sarea ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  sarea 
)
private

Definition at line 1898 of file gwf-lak.f90.

1899  ! -- dummy
1900  class(LakType), intent(inout) :: this
1901  integer(I4B), intent(in) :: ilak
1902  real(DP), intent(in) :: stage
1903  real(DP), intent(inout) :: sarea
1904  ! -- local
1905  integer(I4B) :: i
1906  integer(I4B) :: ifirst
1907  integer(I4B) :: ilast
1908  real(DP) :: topl
1909  real(DP) :: botl
1910  real(DP) :: sat
1911  real(DP) :: sa
1912  !
1913  sarea = dzero
1914  i = this%ntabrow(ilak)
1915  if (i > 0) then
1916  ifirst = this%ialaktab(ilak)
1917  ilast = this%ialaktab(ilak + 1) - 1
1918  if (stage <= this%tabstage(ifirst)) then
1919  sarea = this%tabsarea(ifirst)
1920  else if (stage >= this%tabstage(ilast)) then
1921  sarea = this%tabsarea(ilast)
1922  else
1923  call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
1924  this%tabsarea(ifirst:ilast), &
1925  stage, sarea)
1926  end if
1927  else
1928  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
1929  topl = this%telev(i)
1930  botl = this%belev(i)
1931  sat = squadraticsaturation(topl, botl, stage)
1932  sa = sat * this%sarea(i)
1933  sarea = sarea + sa
1934  end do
1935  end if
Here is the call graph for this function:

◆ lak_calculate_storagechange()

subroutine lakmodule::lak_calculate_storagechange ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(in)  stage0,
real(dp), intent(in)  delt,
real(dp), intent(inout)  dvr 
)
private

Definition at line 2362 of file gwf-lak.f90.

2363  ! -- dummy
2364  class(LakType), intent(inout) :: this
2365  integer(I4B), intent(in) :: ilak
2366  real(DP), intent(in) :: stage
2367  real(DP), intent(in) :: stage0
2368  real(DP), intent(in) :: delt
2369  real(DP), intent(inout) :: dvr
2370  ! -- local
2371  real(DP) :: v
2372  real(DP) :: v0
2373  !
2374  dvr = dzero
2375  if (this%gwfiss /= 1) then
2376  call this%lak_calculate_vol(ilak, stage, v)
2377  call this%lak_calculate_vol(ilak, stage0, v0)
2378  dvr = (v0 - v) / delt
2379  end if

◆ lak_calculate_vol()

subroutine lakmodule::lak_calculate_vol ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  volume 
)
private

Definition at line 2019 of file gwf-lak.f90.

2020  ! -- dummy
2021  class(LakType), intent(inout) :: this
2022  integer(I4B), intent(in) :: ilak
2023  real(DP), intent(in) :: stage
2024  real(DP), intent(inout) :: volume
2025  ! -- local
2026  integer(I4B) :: i
2027  integer(I4B) :: ifirst
2028  integer(I4B) :: ilast
2029  real(DP) :: topl
2030  real(DP) :: botl
2031  real(DP) :: ds
2032  real(DP) :: sa
2033  real(DP) :: v
2034  real(DP) :: sat
2035  !
2036  volume = dzero
2037  i = this%ntabrow(ilak)
2038  if (i > 0) then
2039  ifirst = this%ialaktab(ilak)
2040  ilast = this%ialaktab(ilak + 1) - 1
2041  if (stage <= this%tabstage(ifirst)) then
2042  volume = this%tabvolume(ifirst)
2043  else if (stage >= this%tabstage(ilast)) then
2044  ds = stage - this%tabstage(ilast)
2045  sa = this%tabsarea(ilast)
2046  volume = this%tabvolume(ilast) + ds * sa
2047  else
2048  call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2049  this%tabvolume(ifirst:ilast), &
2050  stage, volume)
2051  end if
2052  else
2053  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2054  topl = this%telev(i)
2055  botl = this%belev(i)
2056  sat = squadraticsaturation(topl, botl, stage)
2057  sa = sat * this%sarea(i)
2058  if (stage < botl) then
2059  v = dzero
2060  else if (stage > botl .and. stage < topl) then
2061  v = sa * (stage - botl)
2062  else
2063  v = sa * (topl - botl) + sa * (stage - topl)
2064  end if
2065  volume = volume + v
2066  end do
2067  end if
Here is the call graph for this function:

◆ lak_calculate_warea()

subroutine lakmodule::lak_calculate_warea ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  warea,
real(dp), intent(inout), optional  hin 
)
private

Definition at line 1940 of file gwf-lak.f90.

1941  ! -- dummy
1942  class(LakType), intent(inout) :: this
1943  integer(I4B), intent(in) :: ilak
1944  real(DP), intent(in) :: stage
1945  real(DP), intent(inout) :: warea
1946  real(DP), optional, intent(inout) :: hin
1947  ! -- local
1948  integer(I4B) :: i
1949  integer(I4B) :: igwfnode
1950  real(DP) :: head
1951  real(DP) :: wa
1952  !
1953  warea = dzero
1954  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
1955  if (present(hin)) then
1956  head = hin
1957  else
1958  igwfnode = this%gwfconn(i)
1959  head = this%xnew(igwfnode)
1960  end if
1961  call this%lak_calculate_conn_warea(ilak, i, stage, head, wa)
1962  warea = warea + wa
1963  end do

◆ lak_calculate_withdrawal()

subroutine lakmodule::lak_calculate_withdrawal ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  avail,
real(dp), intent(inout)  wr 
)
private

Definition at line 2446 of file gwf-lak.f90.

2447  ! -- dummy
2448  class(LakType), intent(inout) :: this
2449  integer(I4B), intent(in) :: ilak
2450  real(DP), intent(inout) :: avail
2451  real(DP), intent(inout) :: wr
2452  !
2453  ! -- withdrawals - limit to sum of inflows and available volume
2454  wr = this%withdrawal(ilak)
2455  if (wr > avail) then
2456  wr = -avail
2457  else
2458  if (wr > dzero) then
2459  wr = -wr
2460  end if
2461  end if
2462  avail = avail + wr

◆ lak_cc()

subroutine lakmodule::lak_cc ( class(laktype), 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

Definition at line 3721 of file gwf-lak.f90.

3722  ! -- modules
3723  use tdismodule, only: totim, kstp, kper, delt
3724  ! -- dummy
3725  class(LakType), intent(inout) :: this
3726  integer(I4B), intent(in) :: innertot
3727  integer(I4B), intent(in) :: kiter
3728  integer(I4B), intent(in) :: iend
3729  integer(I4B), intent(in) :: icnvgmod
3730  character(len=LENPAKLOC), intent(inout) :: cpak
3731  integer(I4B), intent(inout) :: ipak
3732  real(DP), intent(inout) :: dpak
3733  ! -- local
3734  character(len=LENPAKLOC) :: cloc
3735  character(len=LINELENGTH) :: tag
3736  integer(I4B) :: icheck
3737  integer(I4B) :: ipakfail
3738  integer(I4B) :: locdhmax
3739  integer(I4B) :: locresidmax
3740  integer(I4B) :: locdgwfmax
3741  integer(I4B) :: locdqoutmax
3742  integer(I4B) :: locdqfrommvrmax
3743  integer(I4B) :: ntabrows
3744  integer(I4B) :: ntabcols
3745  integer(I4B) :: n
3746  real(DP) :: q
3747  real(DP) :: q0
3748  real(DP) :: qtolfact
3749  real(DP) :: area
3750  real(DP) :: gwf0
3751  real(DP) :: gwf
3752  real(DP) :: dh
3753  real(DP) :: resid
3754  real(DP) :: dgwf
3755  real(DP) :: hlak0
3756  real(DP) :: hlak
3757  real(DP) :: qout0
3758  real(DP) :: qout
3759  real(DP) :: dqout
3760  real(DP) :: inf
3761  real(DP) :: ra
3762  real(DP) :: ro
3763  real(DP) :: qinf
3764  real(DP) :: ex
3765  real(DP) :: dhmax
3766  real(DP) :: residmax
3767  real(DP) :: dgwfmax
3768  real(DP) :: dqoutmax
3769  real(DP) :: dqfrommvr
3770  real(DP) :: dqfrommvrmax
3771  ! -- switch any stalled IMPLICIT lake back to the legacy solver
3772  call this%lak_set_legacy(kiter, icnvgmod)
3773  !
3774  ! -- on the last outer iteration of a solution that has not converged, warn
3775  ! about a perched (disconnected) lake that has no practical steady state.
3776  ! Done for both formulations (the implicit path returns just below).
3777  if (iend /= 0 .and. icnvgmod == 0) then
3778  call this%lak_check_disconnected()
3779  end if
3780  !
3781  ! -- implicit formulation: lake stage is solved in the global matrix,
3782  ! so its convergence is governed by the solution's dvclose check on the
3783  ! stage unknown; no separate package convergence check is performed here.
3784  if (this%iimplicit /= 0) then
3785  return
3786  end if
3787  !
3788  ! -- initialize local variables
3789  icheck = this%iconvchk
3790  ipakfail = 0
3791  locdhmax = 0
3792  locresidmax = 0
3793  locdgwfmax = 0
3794  locdqoutmax = 0
3795  locdqfrommvrmax = 0
3796  dhmax = dzero
3797  residmax = dzero
3798  dgwfmax = dzero
3799  dqoutmax = dzero
3800  dqfrommvrmax = dzero
3801  !
3802  ! -- if not saving package convergence data on check convergence if
3803  ! the model is considered converged
3804  if (this%ipakcsv == 0) then
3805  if (icnvgmod == 0) then
3806  icheck = 0
3807  end if
3808  !
3809  ! -- saving package convergence data
3810  else
3811  !
3812  ! -- header for package csv
3813  if (.not. associated(this%pakcsvtab)) then
3814  !
3815  ! -- determine the number of columns and rows
3816  ntabrows = 1
3817  ntabcols = 11
3818  if (this%noutlets > 0) then
3819  ntabcols = ntabcols + 2
3820  end if
3821  if (this%imover == 1) then
3822  ntabcols = ntabcols + 2
3823  end if
3824  !
3825  ! -- setup table
3826  call table_cr(this%pakcsvtab, this%packName, '')
3827  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
3828  lineseparator=.false., separator=',', &
3829  finalize=.false.)
3830  !
3831  ! -- add columns to package csv
3832  tag = 'total_inner_iterations'
3833  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3834  tag = 'totim'
3835  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3836  tag = 'kper'
3837  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3838  tag = 'kstp'
3839  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3840  tag = 'nouter'
3841  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3842  tag = 'dvmax'
3843  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3844  tag = 'dvmax_loc'
3845  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3846  tag = 'residmax'
3847  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3848  tag = 'residmax_loc'
3849  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3850  tag = 'dgwfmax'
3851  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3852  tag = 'dgwfmax_loc'
3853  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3854  if (this%noutlets > 0) then
3855  tag = 'dqoutmax'
3856  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3857  tag = 'dqoutmax_loc'
3858  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3859  end if
3860  if (this%imover == 1) then
3861  tag = 'dqfrommvrmax'
3862  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3863  tag = 'dqfrommvrmax_loc'
3864  call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
3865  end if
3866  end if
3867  end if
3868  !
3869  ! -- perform package convergence check
3870  if (icheck /= 0) then
3871  final_check: do n = 1, this%nlakes
3872  if (this%iboundpak(n) < 1) cycle
3873  !
3874  ! -- set previous and current lake stage
3875  hlak0 = this%s0(n)
3876  hlak = this%xnewpak(n)
3877  !
3878  ! -- stage difference
3879  dh = hlak0 - hlak
3880  !
3881  ! -- calculate surface area
3882  call this%lak_calculate_sarea(n, hlak, area)
3883  !
3884  ! -- set the Q to length factor
3885  if (area > dzero) then
3886  qtolfact = delt / area
3887  else
3888  qtolfact = dzero
3889  end if
3890  !
3891  ! -- difference in the residual
3892  call this%lak_calculate_residual(n, hlak, resid)
3893  resid = resid * qtolfact
3894  !
3895  ! -- change in gwf exchange
3896  dgwf = dzero
3897  if (area > dzero) then
3898  gwf0 = this%qgwf0(n)
3899  call this%lak_calculate_exchange(n, hlak, gwf)
3900  dgwf = (gwf0 - gwf) * qtolfact
3901  end if
3902  !
3903  ! -- change in outflows
3904  dqout = dzero
3905  if (this%noutlets > 0) then
3906  if (area > dzero) then
3907  call this%lak_calculate_available(n, hlak0, inf, ra, ro, qinf, ex)
3908  call this%lak_calculate_outlet_outflow(n, hlak0, inf, qout0)
3909  call this%lak_calculate_available(n, hlak, inf, ra, ro, qinf, ex)
3910  call this%lak_calculate_outlet_outflow(n, hlak, inf, qout)
3911  dqout = (qout0 - qout) * qtolfact
3912  end if
3913  end if
3914  !
3915  ! -- q from mvr
3916  dqfrommvr = dzero
3917  if (this%imover == 1) then
3918  q = this%pakmvrobj%get_qfrommvr(n)
3919  q0 = this%pakmvrobj%get_qfrommvr0(n)
3920  dqfrommvr = qtolfact * (q0 - q)
3921  end if
3922  !
3923  ! -- evaluate magnitude of differences
3924  if (n == 1) then
3925  locdhmax = n
3926  dhmax = dh
3927  locdgwfmax = n
3928  residmax = resid
3929  locresidmax = n
3930  dgwfmax = dgwf
3931  locdqoutmax = n
3932  dqoutmax = dqout
3933  dqfrommvrmax = dqfrommvr
3934  locdqfrommvrmax = n
3935  else
3936  if (abs(dh) > abs(dhmax)) then
3937  locdhmax = n
3938  dhmax = dh
3939  end if
3940  if (abs(resid) > abs(residmax)) then
3941  locresidmax = n
3942  residmax = resid
3943  end if
3944  if (abs(dgwf) > abs(dgwfmax)) then
3945  locdgwfmax = n
3946  dgwfmax = dgwf
3947  end if
3948  if (abs(dqout) > abs(dqoutmax)) then
3949  locdqoutmax = n
3950  dqoutmax = dqout
3951  end if
3952  if (abs(dqfrommvr) > abs(dqfrommvrmax)) then
3953  dqfrommvrmax = dqfrommvr
3954  locdqfrommvrmax = n
3955  end if
3956  end if
3957  end do final_check
3958  !
3959  ! -- set dpak and cpak
3960  if (abs(dhmax) > abs(dpak)) then
3961  ipak = locdhmax
3962  dpak = dhmax
3963  write (cloc, "(a,'-',a)") &
3964  trim(this%packName), 'stage'
3965  cpak = trim(cloc)
3966  end if
3967  if (abs(residmax) > abs(dpak)) then
3968  ipak = locresidmax
3969  dpak = residmax
3970  write (cloc, "(a,'-',a)") &
3971  trim(this%packName), 'residual'
3972  cpak = trim(cloc)
3973  end if
3974  if (abs(dgwfmax) > abs(dpak)) then
3975  ipak = locdgwfmax
3976  dpak = dgwfmax
3977  write (cloc, "(a,'-',a)") &
3978  trim(this%packName), 'gwf'
3979  cpak = trim(cloc)
3980  end if
3981  if (this%noutlets > 0) then
3982  if (abs(dqoutmax) > abs(dpak)) then
3983  ipak = locdqoutmax
3984  dpak = dqoutmax
3985  write (cloc, "(a,'-',a)") &
3986  trim(this%packName), 'outlet'
3987  cpak = trim(cloc)
3988  end if
3989  end if
3990  if (this%imover == 1) then
3991  if (abs(dqfrommvrmax) > abs(dpak)) then
3992  ipak = locdqfrommvrmax
3993  dpak = dqfrommvrmax
3994  write (cloc, "(a,'-',a)") trim(this%packName), 'qfrommvr'
3995  cpak = trim(cloc)
3996  end if
3997  end if
3998  !
3999  ! -- write convergence data to package csv
4000  if (this%ipakcsv /= 0) then
4001  !
4002  ! -- write the data
4003  call this%pakcsvtab%add_term(innertot)
4004  call this%pakcsvtab%add_term(totim)
4005  call this%pakcsvtab%add_term(kper)
4006  call this%pakcsvtab%add_term(kstp)
4007  call this%pakcsvtab%add_term(kiter)
4008  call this%pakcsvtab%add_term(dhmax)
4009  call this%pakcsvtab%add_term(locdhmax)
4010  call this%pakcsvtab%add_term(residmax)
4011  call this%pakcsvtab%add_term(locresidmax)
4012  call this%pakcsvtab%add_term(dgwfmax)
4013  call this%pakcsvtab%add_term(locdgwfmax)
4014  if (this%noutlets > 0) then
4015  call this%pakcsvtab%add_term(dqoutmax)
4016  call this%pakcsvtab%add_term(locdqoutmax)
4017  end if
4018  if (this%imover == 1) then
4019  call this%pakcsvtab%add_term(dqfrommvrmax)
4020  call this%pakcsvtab%add_term(locdqfrommvrmax)
4021  end if
4022  !
4023  ! -- finalize the package csv
4024  if (iend == 1) then
4025  call this%pakcsvtab%finalize_table()
4026  end if
4027  end if
4028  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
Here is the call graph for this function:

◆ lak_cf()

subroutine lakmodule::lak_cf ( class(laktype)  this)

Skip if no lakes, otherwise calculate hcof and rhs

Definition at line 3484 of file gwf-lak.f90.

3485  ! -- dummy
3486  class(LakType) :: this
3487  ! -- local
3488  integer(I4B) :: j, n
3489  integer(I4B) :: igwfnode
3490  real(DP) :: hlak, bottom_lake
3491  !
3492  ! -- save groundwater seepage for lake solution
3493  do n = 1, this%nlakes
3494  this%seep0(n) = this%seep(n)
3495  end do
3496  !
3497  ! -- save variables for convergence check
3498  do n = 1, this%nlakes
3499  this%s0(n) = this%xnewpak(n)
3500  call this%lak_calculate_exchange(n, this%s0(n), this%qgwf0(n))
3501  end do
3502  !
3503  ! -- find highest active cell
3504  do n = 1, this%nlakes
3505  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3506  ! -- skip horizontal connections
3507  if (this%ictype(j) /= 0) then
3508  cycle
3509  end if
3510  igwfnode = this%nodesontop(j)
3511  if (this%ibound(igwfnode) == 0) then
3512  call this%dis%highest_active(igwfnode, this%ibound)
3513  end if
3514  this%nodelist(j) = igwfnode
3515  this%gwfconn(j) = igwfnode
3516  end do
3517  end do
3518  !
3519  ! -- reset ibound for cells where lake stage is above the bottom
3520  ! of the lake in the cell or the lake is inactive - only applied to
3521  ! vertical connections
3522  do n = 1, this%nlakes
3523  !
3524  hlak = this%xnewpak(n)
3525  !
3526  ! -- Go through lake connections
3527  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3528  !
3529  ! -- assign gwf node number
3530  igwfnode = this%gwfconn(j)
3531  !
3532  ! -- skip inactive or constant head GWF cells
3533  if (this%ibound(igwfnode) < 1) then
3534  cycle
3535  end if
3536  !
3537  ! -- skip horizontal connections
3538  if (this%ictype(j) /= 0) then
3539  cycle
3540  end if
3541  !
3542  ! -- skip embedded lakes
3543  if (this%ictype(j) == 2 .or. this%ictype(j) == 3) then
3544  cycle
3545  end if
3546  !
3547  ! -- Mark ibound for wet lakes or inactive lakes; reset to 1 otherwise
3548  bottom_lake = this%belev(j)
3549  if (hlak > bottom_lake .or. this%iboundpak(n) == 0) then
3550  this%ibound(igwfnode) = iwetlake
3551  else
3552  this%ibound(igwfnode) = 1
3553  end if
3554  end do
3555  !
3556  end do
3557  !
3558  ! -- Store the lake stage and cond in bound array for other
3559  ! packages, such as the BUY package
3560  call this%lak_bound_update()

◆ lak_check_valid()

integer(i4b) function lakmodule::lak_check_valid ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  itemno 
)
private

Definition at line 2821 of file gwf-lak.f90.

2822  ! -- modules
2823  use simmodule, only: store_error
2824  ! -- return
2825  integer(I4B) :: ierr
2826  ! -- dummy
2827  class(LakType), intent(inout) :: this
2828  integer(I4B), intent(in) :: itemno
2829  ! -- local
2830  integer(I4B) :: ival
2831  !
2832  ierr = 0
2833  ival = abs(itemno)
2834  if (itemno > 0) then
2835  if (ival < 1 .or. ival > this%nlakes) then
2836  write (errmsg, '(a,1x,i0,1x,a,1x,i0,a)') &
2837  'LAKENO', itemno, 'must be greater than 0 and less than or equal to', &
2838  this%nlakes, '.'
2839  call store_error(errmsg)
2840  ierr = 1
2841  end if
2842  else
2843  if (ival < 1 .or. ival > this%noutlets) then
2844  write (errmsg, '(a,1x,i0,1x,a,1x,i0,a)') &
2845  'IOUTLET', itemno, 'must be greater than 0 and less than or equal to', &
2846  this%noutlets, '.'
2847  call store_error(errmsg)
2848  ierr = 1
2849  end if
2850  end if
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
Here is the call graph for this function:

◆ lak_cq()

subroutine lakmodule::lak_cq ( class(laktype), intent(inout)  this,
real(dp), dimension(:), intent(in)  x,
real(dp), dimension(:), intent(inout), contiguous  flowja,
integer(i4b), intent(in), optional  iadv 
)

Definition at line 4033 of file gwf-lak.f90.

4034  ! -- modules
4035  use tdismodule, only: delt
4036  ! -- dummy
4037  class(LakType), intent(inout) :: this
4038  real(DP), dimension(:), intent(in) :: x
4039  real(DP), dimension(:), contiguous, intent(inout) :: flowja
4040  integer(I4B), optional, intent(in) :: iadv
4041  ! -- local
4042  real(DP) :: rrate
4043  real(DP) :: chratin, chratout
4044  ! -- for budget
4045  integer(I4B) :: j, n, igwfnode
4046  real(DP) :: hlak, head, flow, dqdh
4047  real(DP) :: v0, v1, sa, sf
4048  !
4049  call this%lak_solve(update=.false.)
4050  !
4051  ! -- for the IMPLICIT formulation, report the lake terms with the same
4052  ! treatment that lak_fc_implicit assembled into the matrix, so the lake
4053  ! and gwf-cell budgets match the solved flows. lak_solve above set these
4054  ! from the substitution path (hard-cutoff seepage; availability-limited
4055  ! losses), which is correct for a lake on the legacy solver but
4056  ! not for an implicit lake, so overwrite them for the implicit
4057  ! (non-legacy) lakes only.
4058  if (this%iimplicit /= 0) then
4059  do n = 1, this%nlakes
4060  if (this%iboundpak(n) < 1 .or. this%ilegacy(n) /= 0) cycle
4061  hlak = this%xnewpak(n)
4062  !
4063  ! -- lakebed seepage: use the same exchange the matrix assembled
4064  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4065  igwfnode = this%gwfconn(j)
4066  if (this%ibound(igwfnode) < 1) cycle
4067  head = this%xnew(igwfnode)
4068  call this%lak_calculate_conn_exchange_deriv(n, j, hlak, head, &
4069  flow, dqdh=dqdh)
4070  this%hcof(j) = -dqdh
4071  this%rhs(j) = -dqdh * head + flow
4072  end do
4073  !
4074  ! -- stage-driven losses: the matrix (lak_budget_nogwf) ramps
4075  ! evaporation and withdrawal toward zero as the lake approaches its
4076  ! bottom with the surfdep factor (sf) rather than the substitution
4077  ! solver's availability limiting, so report them the same way. This
4078  ! keeps the lake budget closed for a drying lake. (The outlet
4079  ! outflow is already near zero at the bottom, as its invert is above
4080  ! the lake bottom, and the storage term reflects the solved stage.)
4081  call this%lak_calculate_sarea(n, hlak, sa)
4082  sf = done
4083  if (this%surfdep > dzero) then
4084  sf = squadraticsaturation(this%lakebot(n) + this%surfdep, &
4085  this%lakebot(n), hlak)
4086  end if
4087  this%evap(n) = -this%evaporation(n) * sa * sf
4088  this%withr(n) = -this%withdrawal(n) * sf
4089  end do
4090  end if
4091  !
4092  ! -- call base functionality in bnd_cq. This will calculate lake-gwf flows
4093  ! and put them into this%simvals
4094  call this%BndType%bnd_cq(x, flowja, iadv=1)
4095  !
4096  ! -- calculate several budget terms
4097  chratin = dzero
4098  chratout = dzero
4099  do n = 1, this%nlakes
4100  this%chterm(n) = dzero
4101  if (this%iboundpak(n) == 0) cycle
4102  hlak = this%xnewpak(n)
4103  call this%lak_calculate_vol(n, hlak, v1)
4104  !
4105  ! -- add budget terms for active lakes
4106  if (this%iboundpak(n) /= 0) then
4107  !
4108  ! -- rainfall
4109  rrate = this%precip(n)
4110  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4111  !
4112  ! -- evaporation
4113  rrate = this%evap(n)
4114  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4115  !
4116  ! -- runoff
4117  rrate = this%runoff(n)
4118  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4119  !
4120  ! -- inflow
4121  rrate = this%inflow(n)
4122  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4123  !
4124  ! -- withdrawals
4125  rrate = this%withr(n)
4126  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4127  !
4128  ! -- add lake storage changes
4129  rrate = dzero
4130  if (this%iboundpak(n) > 0) then
4131  if (this%gwfiss /= 1) then
4132  call this%lak_calculate_vol(n, this%xoldpak(n), v0)
4133  rrate = -(v1 - v0) / delt
4134  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4135  end if
4136  end if
4137  this%qsto(n) = rrate
4138  !
4139  ! -- add external outlets
4140  call this%lak_get_external_outlet(n, rrate)
4141  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4142  !
4143  ! -- add mover terms
4144  if (this%imover == 1) then
4145  if (this%iboundpak(n) /= 0) then
4146  rrate = this%pakmvrobj%get_qfrommvr(n)
4147  else
4148  rrate = dzero
4149  end if
4150  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4151  end if
4152  end if
4153  end do
4154  !
4155  ! -- gwf flow and constant flow to lake
4156  do n = 1, this%nlakes
4157  rrate = dzero
4158  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4159  ! simvals is from aquifer perspective, and so it is positive
4160  ! for flow into the aquifer. Need to switch sign for lake
4161  ! perspective.
4162  rrate = -this%simvals(j)
4163  this%qleak(j) = rrate
4164  if (this%iboundpak(n) /= 0) then
4165  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4166  end if
4167  end do
4168  end do
4169  !
4170  ! -- fill the budget object
4171  call this%lak_fill_budobj()
Here is the call graph for this function:

◆ lak_create()

subroutine, public lakmodule::lak_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 
)

Definition at line 394 of file gwf-lak.f90.

396  ! -- modules
398  ! -- dummy
399  class(BndType), pointer :: packobj
400  integer(I4B), intent(in) :: id
401  integer(I4B), intent(in) :: ibcnum
402  integer(I4B), intent(in) :: inunit
403  integer(I4B), intent(in) :: iout
404  character(len=*), intent(in) :: namemodel
405  character(len=*), intent(in) :: pakname
406  character(len=*), intent(in) :: mempath
407  ! -- local
408  type(LakType), pointer :: lakobj
409  !
410  ! -- allocate the object and assign values to object variables
411  allocate (lakobj)
412  packobj => lakobj
413  !
414  ! -- create name and memory path
415  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
416  packobj%text = text
417  !
418  ! -- allocate scalars
419  call lakobj%lak_allocate_scalars()
420  !
421  ! -- initialize package
422  call packobj%pack_initialize()
423  !
424  packobj%inunit = inunit
425  packobj%iout = iout
426  packobj%id = id
427  packobj%ibcnum = ibcnum
428  packobj%ncolbnd = 3
429  packobj%iscloc = 0 ! not supported
430  packobj%isadvpak = 1
431  packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
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:
Here is the caller graph for this function:

◆ lak_da()

subroutine lakmodule::lak_da ( class(laktype)  this)

Definition at line 4301 of file gwf-lak.f90.

4302  ! -- modules
4304  ! -- dummy
4305  class(LakType) :: this
4306  !
4307  ! -- nullify input context runtime pointers
4308  call this%input%destroy()
4309  !
4310  ! -- arrays
4311  deallocate (this%lakename)
4312  deallocate (this%status)
4313  deallocate (this%clakbudget)
4314  call mem_deallocate(this%dbuff)
4315  deallocate (this%cauxcbc)
4316  call mem_deallocate(this%qauxcbc)
4317  call mem_deallocate(this%qleak)
4318  call mem_deallocate(this%holdconn)
4319  call mem_deallocate(this%qsto)
4320  call mem_deallocate(this%denseterms)
4321  call mem_deallocate(this%viscratios)
4322  !
4323  ! -- tables
4324  if (this%ntables > 0) then
4325  call mem_deallocate(this%ialaktab)
4326  call mem_deallocate(this%tabstage)
4327  call mem_deallocate(this%tabvolume)
4328  call mem_deallocate(this%tabsarea)
4329  call mem_deallocate(this%tabwarea)
4330  end if
4331  !
4332  ! -- budobj
4333  call this%budobj%budgetobject_da()
4334  deallocate (this%budobj)
4335  nullify (this%budobj)
4336  !
4337  ! -- outlets
4338  if (this%noutlets > 0) then
4339  call mem_deallocate(this%lakein)
4340  call mem_deallocate(this%lakeout)
4341  call mem_deallocate(this%iouttype)
4342  ! -- outrate/outinvert/outwidth/outrough/outslope are live aliases
4343  ! into the input context's permanent arrays, not owned here
4344  call mem_deallocate(this%simoutrate)
4345  call mem_deallocate(this%outlet_invert_set)
4346  call mem_deallocate(this%outlet_width_set)
4347  call mem_deallocate(this%outlet_rough_set)
4348  call mem_deallocate(this%outlet_slope_set)
4349  end if
4350  !
4351  ! -- stage table
4352  if (this%iprhed > 0) then
4353  call this%stagetab%table_da()
4354  deallocate (this%stagetab)
4355  nullify (this%stagetab)
4356  end if
4357  !
4358  ! -- package csv table
4359  if (this%ipakcsv > 0) then
4360  if (associated(this%pakcsvtab)) then
4361  call this%pakcsvtab%table_da()
4362  deallocate (this%pakcsvtab)
4363  nullify (this%pakcsvtab)
4364  end if
4365  end if
4366  !
4367  ! -- scalars
4368  call mem_deallocate(this%iprhed)
4369  call mem_deallocate(this%istageout)
4370  call mem_deallocate(this%ibudgetout)
4371  call mem_deallocate(this%ibudcsv)
4372  call mem_deallocate(this%ipakcsv)
4373  if (allocated(this%pakcsvfile)) deallocate (this%pakcsvfile)
4374  call mem_deallocate(this%nlakes)
4375  call mem_deallocate(this%noutlets)
4376  call mem_deallocate(this%ntables)
4377  call mem_deallocate(this%convlength)
4378  call mem_deallocate(this%convtime)
4379  call mem_deallocate(this%outdmax)
4380  call mem_deallocate(this%igwhcopt)
4381  call mem_deallocate(this%iconvchk)
4382  call mem_deallocate(this%maxlakit)
4383  call mem_deallocate(this%surfdep)
4384  call mem_deallocate(this%dmaxchg)
4385  call mem_deallocate(this%delh)
4386  call mem_deallocate(this%check_attr)
4387  call mem_deallocate(this%iimplicit)
4388  call mem_deallocate(this%iforceleg)
4389  call mem_deallocate(this%iforceleglak)
4390  call mem_deallocate(this%bditems)
4391  call mem_deallocate(this%cbcauxitems)
4392  call mem_deallocate(this%idense)
4393  !
4394  call mem_deallocate(this%nlakeconn)
4395  call mem_deallocate(this%idxlakeconn)
4396  call mem_deallocate(this%ntabrow)
4397  call mem_deallocate(this%strt)
4398  call mem_deallocate(this%laketop)
4399  call mem_deallocate(this%lakebot)
4400  call mem_deallocate(this%sareamax)
4401  ! -- stage/rainfall/evaporation/runoff/inflow/withdrawal are live aliases
4402  ! into the input context's permanent arrays, not owned here
4403  call mem_deallocate(this%avail)
4404  call mem_deallocate(this%lkgwsink)
4405  call mem_deallocate(this%ncncvr)
4406  call mem_deallocate(this%ilegacy)
4407  call mem_deallocate(this%nstuck)
4408  call mem_deallocate(this%surfin)
4409  call mem_deallocate(this%surfout)
4410  call mem_deallocate(this%surfout1)
4411  call mem_deallocate(this%precip)
4412  call mem_deallocate(this%precip1)
4413  call mem_deallocate(this%evap)
4414  call mem_deallocate(this%evap1)
4415  call mem_deallocate(this%evapo)
4416  call mem_deallocate(this%withr)
4417  call mem_deallocate(this%withr1)
4418  call mem_deallocate(this%flwin)
4419  call mem_deallocate(this%flwiter)
4420  call mem_deallocate(this%flwiter1)
4421  call mem_deallocate(this%seep)
4422  call mem_deallocate(this%seep1)
4423  call mem_deallocate(this%seep0)
4424  call mem_deallocate(this%stageiter)
4425  call mem_deallocate(this%chterm)
4426  !
4427  ! -- lake boundary and stages
4428  if (this%iimplicit == 0) then
4429  call mem_deallocate(this%iboundpak)
4430  call mem_deallocate(this%xnewpak)
4431  else
4432  ! -- iboundpak aliases the global ibound (not deallocated here); xnewpak
4433  ! was checked in to the global x vector
4434  call mem_deallocate(this%xnewpak, 'XNEWPAK', this%memoryPath)
4435  end if
4436  call mem_deallocate(this%xoldpak)
4437  !
4438  ! -- implicit-formulation matrix-mapping arrays
4439  call mem_deallocate(this%idxlocnode)
4440  call mem_deallocate(this%idxdiag)
4441  call mem_deallocate(this%idxoffdglo)
4442  call mem_deallocate(this%idxsymdglo)
4443  call mem_deallocate(this%idxsymoffdglo)
4444  !
4445  ! -- lake iteration variables
4446  call mem_deallocate(this%iseepc)
4447  call mem_deallocate(this%idhc)
4448  call mem_deallocate(this%en1)
4449  call mem_deallocate(this%en2)
4450  call mem_deallocate(this%r1)
4451  call mem_deallocate(this%r2)
4452  call mem_deallocate(this%dh0)
4453  call mem_deallocate(this%s0)
4454  call mem_deallocate(this%qgwf0)
4455  !
4456  ! -- lake connection variables
4457  call mem_deallocate(this%imap)
4458  call mem_deallocate(this%gwfconn)
4459  call mem_deallocate(this%nodesontop)
4460  call mem_deallocate(this%ictype)
4461  call mem_deallocate(this%bedleak)
4462  call mem_deallocate(this%belev)
4463  call mem_deallocate(this%telev)
4464  call mem_deallocate(this%connlength)
4465  call mem_deallocate(this%connwidth)
4466  call mem_deallocate(this%sarea)
4467  call mem_deallocate(this%warea)
4468  call mem_deallocate(this%satcond)
4469  call mem_deallocate(this%simcond)
4470  call mem_deallocate(this%simlakgw)
4471  !
4472  ! -- pointers to gwf variables
4473  nullify (this%gwfiss)
4474  !
4475  ! -- Parent object
4476  call this%BndExtType%bnd_da()

◆ lak_df_obs()

subroutine lakmodule::lak_df_obs ( class(laktype)  this)
private

Definition at line 4660 of file gwf-lak.f90.

4661  ! -- dummy
4662  class(LakType) :: this
4663  ! -- local
4664  integer(I4B) :: indx
4665  !
4666  ! -- Store obs type and assign procedure pointer
4667  ! for stage observation type.
4668  call this%obs%StoreObsType('stage', .false., indx)
4669  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4670  !
4671  ! -- Store obs type and assign procedure pointer
4672  ! for ext-inflow observation type.
4673  call this%obs%StoreObsType('ext-inflow', .true., indx)
4674  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4675  !
4676  ! -- Store obs type and assign procedure pointer
4677  ! for outlet-inflow observation type.
4678  call this%obs%StoreObsType('outlet-inflow', .true., indx)
4679  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4680  !
4681  ! -- Store obs type and assign procedure pointer
4682  ! for inflow observation type.
4683  call this%obs%StoreObsType('inflow', .true., indx)
4684  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4685  !
4686  ! -- Store obs type and assign procedure pointer
4687  ! for from-mvr observation type.
4688  call this%obs%StoreObsType('from-mvr', .true., indx)
4689  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4690  !
4691  ! -- Store obs type and assign procedure pointer
4692  ! for rainfall observation type.
4693  call this%obs%StoreObsType('rainfall', .true., indx)
4694  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4695  !
4696  ! -- Store obs type and assign procedure pointer
4697  ! for runoff observation type.
4698  call this%obs%StoreObsType('runoff', .true., indx)
4699  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4700  !
4701  ! -- Store obs type and assign procedure pointer
4702  ! for lak observation type.
4703  call this%obs%StoreObsType('lak', .true., indx)
4704  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4705  !
4706  ! -- Store obs type and assign procedure pointer
4707  ! for evaporation observation type.
4708  call this%obs%StoreObsType('evaporation', .true., indx)
4709  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4710  !
4711  ! -- Store obs type and assign procedure pointer
4712  ! for withdrawal observation type.
4713  call this%obs%StoreObsType('withdrawal', .true., indx)
4714  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4715  !
4716  ! -- Store obs type and assign procedure pointer
4717  ! for ext-outflow observation type.
4718  call this%obs%StoreObsType('ext-outflow', .true., indx)
4719  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4720  !
4721  ! -- Store obs type and assign procedure pointer
4722  ! for to-mvr observation type.
4723  call this%obs%StoreObsType('to-mvr', .true., indx)
4724  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4725  !
4726  ! -- Store obs type and assign procedure pointer
4727  ! for storage observation type.
4728  call this%obs%StoreObsType('storage', .true., indx)
4729  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4730  !
4731  ! -- Store obs type and assign procedure pointer
4732  ! for constant observation type.
4733  call this%obs%StoreObsType('constant', .true., indx)
4734  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4735  !
4736  ! -- Store obs type and assign procedure pointer
4737  ! for outlet observation type.
4738  call this%obs%StoreObsType('outlet', .true., indx)
4739  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4740  !
4741  ! -- Store obs type and assign procedure pointer
4742  ! for volume observation type.
4743  call this%obs%StoreObsType('volume', .true., indx)
4744  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4745  !
4746  ! -- Store obs type and assign procedure pointer
4747  ! for surface-area observation type.
4748  call this%obs%StoreObsType('surface-area', .true., indx)
4749  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4750  !
4751  ! -- Store obs type and assign procedure pointer
4752  ! for wetted-area observation type.
4753  call this%obs%StoreObsType('wetted-area', .true., indx)
4754  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4755  !
4756  ! -- Store obs type and assign procedure pointer
4757  ! for conductance observation type.
4758  call this%obs%StoreObsType('conductance', .true., indx)
4759  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid

◆ lak_estimate_conn_exchange()

subroutine lakmodule::lak_estimate_conn_exchange ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  iflag,
integer(i4b), intent(in)  ilak,
integer(i4b), intent(in)  iconn,
integer(i4b), intent(inout)  idry,
real(dp), intent(in)  stage,
real(dp), intent(in)  head,
real(dp), intent(inout)  flow,
real(dp), intent(inout)  source,
real(dp), intent(inout), optional  gwfhcof,
real(dp), intent(inout), optional  gwfrhs 
)
private

Definition at line 2319 of file gwf-lak.f90.

2321  ! -- dummy
2322  class(LakType), intent(inout) :: this
2323  integer(I4B), intent(in) :: iflag
2324  integer(I4B), intent(in) :: ilak
2325  integer(I4B), intent(in) :: iconn
2326  integer(I4B), intent(inout) :: idry
2327  real(DP), intent(in) :: stage
2328  real(DP), intent(in) :: head
2329  real(DP), intent(inout) :: flow
2330  real(DP), intent(inout) :: source
2331  real(DP), intent(inout), optional :: gwfhcof
2332  real(DP), intent(inout), optional :: gwfrhs
2333  ! -- local
2334  real(DP) :: gwfhcof0, gwfrhs0
2335  !
2336  flow = dzero
2337  idry = 0
2338  call this%lak_calculate_conn_exchange(ilak, iconn, stage, head, flow, &
2339  gwfhcof0, gwfrhs0)
2340  if (iflag == 1) then
2341  if (flow > dzero) then
2342  source = source + flow
2343  end if
2344  else if (iflag == 2) then
2345  if (-flow > source) then
2346  flow = -source
2347  source = dzero
2348  idry = 1
2349  else if (flow < dzero) then
2350  source = source + flow
2351  end if
2352  end if
2353  !
2354  ! -- Set gwfhcof and gwfrhs if present
2355  if (present(gwfhcof)) gwfhcof = gwfhcof0
2356  if (present(gwfrhs)) gwfrhs = gwfrhs0

◆ lak_estimate_seepage_single()

subroutine lakmodule::lak_estimate_seepage_single ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  ncnv 
)

Runs the two-pass connection-seepage estimate for lake n at its current stage and the perturbed stage, accumulating thisseep(n)/thisseep1(n) and, on the final pass when ncnv == 0, the gwf-cell hcof/rhs contributions. Lakes do not couple within this estimate (each connection touches only its own lake's flwiter), so evaluating both passes per lake is equivalent to the all-lakes-per-pass ordering in lak_solve. Extracted from lak_solve so the same estimate can drive the single-lake legacy solve for the IMPLICIT formulation.

Definition at line 5571 of file gwf-lak.f90.

5572  ! -- dummy
5573  class(LakType), intent(inout) :: this
5574  integer(I4B), intent(in) :: n
5575  integer(I4B), intent(in) :: ncnv
5576  ! -- local
5577  integer(I4B) :: i
5578  integer(I4B) :: j
5579  integer(I4B) :: igwfnode
5580  integer(I4B) :: idry
5581  integer(I4B) :: idry1
5582  real(DP) :: hlak
5583  real(DP) :: head
5584  real(DP) :: qlakgw
5585  real(DP) :: qlakgw1
5586  real(DP) :: gwfhcof
5587  real(DP) :: gwfrhs
5588  real(DP) :: delh
5589  !
5590  delh = this%delh
5591  !
5592  ! -- skip inactive lakes
5593  if (this%iboundpak(n) == 0) return
5594  !
5595  estseep: do i = 1, 2
5596  ! - set xoldpak to xnewpak if steady-state
5597  if (this%gwfiss /= 0) then
5598  this%xoldpak(n) = this%xnewpak(n)
5599  end if
5600  hlak = this%xnewpak(n)
5601  calcconnseep: do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5602  igwfnode = this%gwfconn(j)
5603  head = this%xnew(igwfnode)
5604  if (this%ncncvr(n) /= 2) then
5605  if (this%ibound(igwfnode) > 0) then
5606  call this%lak_estimate_conn_exchange(i, n, j, idry, hlak, &
5607  head, qlakgw, &
5608  this%flwiter(n), &
5609  gwfhcof, gwfrhs)
5610  call this%lak_estimate_conn_exchange(i, n, j, idry1, &
5611  hlak + delh, head, qlakgw1, &
5612  this%flwiter1(n))
5613  !
5614  ! -- add to gwf matrix
5615  if (ncnv == 0 .and. i == 2) then
5616  if (j == this%maxbound) then
5617  this%ncncvr(n) = 2
5618  end if
5619  if (idry /= 1) then
5620  this%hcof(j) = gwfhcof
5621  this%rhs(j) = gwfrhs
5622  else
5623  this%hcof(j) = dzero
5624  this%rhs(j) = qlakgw
5625  end if
5626  end if
5627  if (i == 2) then
5628  this%seep(n) = this%seep(n) + qlakgw
5629  this%seep1(n) = this%seep1(n) + qlakgw1
5630  end if
5631  end if
5632  end if
5633  end do calcconnseep
5634  end do estseep

◆ lak_fc()

subroutine lakmodule::lak_fc ( class(laktype)  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

Definition at line 3565 of file gwf-lak.f90.

3566  ! -- dummy
3567  class(LakType) :: this
3568  real(DP), dimension(:), intent(inout) :: rhs
3569  integer(I4B), dimension(:), intent(in) :: ia
3570  integer(I4B), dimension(:), intent(in) :: idxglo
3571  class(MatrixBaseType), pointer :: matrix_sln
3572  ! -- local
3573  integer(I4B) :: j, n
3574  integer(I4B) :: igwfnode
3575  integer(I4B) :: ipossymd
3576  !
3577  ! -- pakmvrobj fc
3578  if (this%imover == 1) then
3579  call this%pakmvrobj%fc()
3580  end if
3581  !
3582  ! -- implicit formulation: assemble the lake equations directly into the
3583  ! groundwater flow matrix instead of solving the stage by substitution
3584  if (this%iimplicit /= 0) then
3585  call this%lak_fc_implicit(rhs, matrix_sln)
3586  return
3587  end if
3588  !
3589  ! -- legacy formulation: solve the lake stage by substitution, then add the
3590  ! resulting lake-aquifer exchange terms to the groundwater flow matrix
3591  call this%lak_solve()
3592  do n = 1, this%nlakes
3593  if (this%iboundpak(n) == 0) cycle
3594  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3595  igwfnode = this%gwfconn(j)
3596  if (this%ibound(igwfnode) < 1) cycle
3597  ipossymd = idxglo(ia(igwfnode))
3598  call matrix_sln%add_value_pos(ipossymd, this%hcof(j))
3599  rhs(igwfnode) = rhs(igwfnode) + this%rhs(j)
3600  end do
3601  end do

◆ lak_fill_budobj()

subroutine lakmodule::lak_fill_budobj ( class(laktype)  this)

Definition at line 6088 of file gwf-lak.f90.

6089  ! -- dummy
6090  class(LakType) :: this
6091  ! -- local
6092  integer(I4B) :: naux
6093  real(DP), dimension(:), allocatable :: auxvartmp
6094  !integer(I4B) :: i
6095  integer(I4B) :: j
6096  integer(I4B) :: n
6097  integer(I4B) :: n1
6098  integer(I4B) :: n2
6099  integer(I4B) :: ii
6100  integer(I4B) :: jj
6101  integer(I4B) :: idx
6102  integer(I4B) :: nlen
6103  real(DP) :: v, v1
6104  real(DP) :: q
6105  real(DP) :: lkstg, gwhead, wa
6106  !
6107  ! -- initialize counter
6108  idx = 0
6109 
6110  ! -- FLOW JA FACE
6111  nlen = 0
6112  do n = 1, this%noutlets
6113  if (this%lakein(n) > 0 .and. this%lakeout(n) > 0) then
6114  nlen = nlen + 1
6115  end if
6116  end do
6117  if (nlen > 0) then
6118  idx = idx + 1
6119  call this%budobj%budterm(idx)%reset(2 * nlen)
6120  do n = 1, this%noutlets
6121  n1 = this%lakein(n)
6122  n2 = this%lakeout(n)
6123  if (n1 > 0 .and. n2 > 0) then
6124  q = this%simoutrate(n)
6125  if (this%imover == 1) then
6126  q = q + this%pakmvrobj%get_qtomvr(n)
6127  end if
6128  call this%budobj%budterm(idx)%update_term(n1, n2, q)
6129  call this%budobj%budterm(idx)%update_term(n2, n1, -q)
6130  end if
6131  end do
6132  end if
6133  !
6134  ! -- GWF (LEAKAGE)
6135  idx = idx + 1
6136  call this%budobj%budterm(idx)%reset(this%maxbound)
6137  do n = 1, this%nlakes
6138  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
6139  n2 = this%gwfconn(j)
6140  q = this%qleak(j)
6141  lkstg = this%xnewpak(n)
6142  ! -- For the case when the lak stage is exactly equal
6143  ! to the lake bottom, the wetted area is not returned
6144  ! equal to 0.0
6145  gwhead = this%xnew(n2)
6146  call this%lak_calculate_conn_warea(n, j, lkstg, gwhead, wa)
6147  ! -- For thermal conduction between a lake and a gw cell,
6148  ! the shared wetted area should be reset to zero when the lake
6149  ! stage is below the cell bottom
6150  if (this%belev(j) > lkstg) wa = dzero
6151  this%qauxcbc(1) = wa
6152  call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
6153  end do
6154  end do
6155  !
6156  ! -- RAIN
6157  idx = idx + 1
6158  call this%budobj%budterm(idx)%reset(this%nlakes)
6159  do n = 1, this%nlakes
6160  q = this%precip(n)
6161  call this%budobj%budterm(idx)%update_term(n, n, q)
6162  end do
6163  !
6164  ! -- EVAPORATION
6165  idx = idx + 1
6166  call this%budobj%budterm(idx)%reset(this%nlakes)
6167  do n = 1, this%nlakes
6168  q = this%evap(n)
6169  call this%budobj%budterm(idx)%update_term(n, n, q)
6170  end do
6171  !
6172  ! -- RUNOFF
6173  idx = idx + 1
6174  call this%budobj%budterm(idx)%reset(this%nlakes)
6175  do n = 1, this%nlakes
6176  q = this%runoff(n)
6177  call this%budobj%budterm(idx)%update_term(n, n, q)
6178  end do
6179  !
6180  ! -- INFLOW
6181  idx = idx + 1
6182  call this%budobj%budterm(idx)%reset(this%nlakes)
6183  do n = 1, this%nlakes
6184  q = this%inflow(n)
6185  call this%budobj%budterm(idx)%update_term(n, n, q)
6186  end do
6187  !
6188  ! -- WITHDRAWAL
6189  idx = idx + 1
6190  call this%budobj%budterm(idx)%reset(this%nlakes)
6191  do n = 1, this%nlakes
6192  q = this%withr(n)
6193  call this%budobj%budterm(idx)%update_term(n, n, q)
6194  end do
6195  !
6196  ! -- EXTERNAL OUTFLOW
6197  idx = idx + 1
6198  call this%budobj%budterm(idx)%reset(this%nlakes)
6199  do n = 1, this%nlakes
6200  call this%lak_get_external_outlet(n, q)
6201  ! subtract tomover from external outflow
6202  call this%lak_get_external_mover(n, v)
6203  q = q + v
6204  call this%budobj%budterm(idx)%update_term(n, n, q)
6205  end do
6206  !
6207  ! -- STORAGE
6208  idx = idx + 1
6209  call this%budobj%budterm(idx)%reset(this%nlakes)
6210  do n = 1, this%nlakes
6211  call this%lak_calculate_vol(n, this%xnewpak(n), v1)
6212  q = this%qsto(n)
6213  this%qauxcbc(1) = v1
6214  call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
6215  end do
6216  !
6217  ! -- CONSTANT FLOW
6218  idx = idx + 1
6219  call this%budobj%budterm(idx)%reset(this%nlakes)
6220  do n = 1, this%nlakes
6221  q = this%chterm(n)
6222  call this%budobj%budterm(idx)%update_term(n, n, q)
6223  end do
6224  !
6225  ! -- MOVER
6226  if (this%imover == 1) then
6227  !
6228  ! -- FROM MOVER
6229  idx = idx + 1
6230  call this%budobj%budterm(idx)%reset(this%nlakes)
6231  do n = 1, this%nlakes
6232  q = this%pakmvrobj%get_qfrommvr(n)
6233  call this%budobj%budterm(idx)%update_term(n, n, q)
6234  end do
6235  !
6236  ! -- TO MOVER
6237  idx = idx + 1
6238  call this%budobj%budterm(idx)%reset(this%noutlets)
6239  do n = 1, this%noutlets
6240  n1 = this%lakein(n)
6241  q = this%pakmvrobj%get_qtomvr(n)
6242  if (q > dzero) then
6243  q = -q
6244  end if
6245  call this%budobj%budterm(idx)%update_term(n1, n1, q)
6246  end do
6247  !
6248  end if
6249  !
6250  ! -- AUXILIARY VARIABLES
6251  naux = this%naux
6252  if (naux > 0) then
6253  idx = idx + 1
6254  allocate (auxvartmp(naux))
6255  call this%budobj%budterm(idx)%reset(this%nlakes)
6256  do n = 1, this%nlakes
6257  q = dzero
6258  do jj = 1, naux
6259  ii = n
6260  auxvartmp(jj) = this%featureauxvar(jj, ii)
6261  end do
6262  call this%budobj%budterm(idx)%update_term(n, n, q, auxvartmp)
6263  end do
6264  deallocate (auxvartmp)
6265  end if
6266  !
6267  ! --Terms are filled, now accumulate them for this time step
6268  call this%budobj%accumulate_terms()

◆ lak_fn()

subroutine lakmodule::lak_fn ( class(laktype)  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

Definition at line 3606 of file gwf-lak.f90.

3607  ! -- dummy
3608  class(LakType) :: this
3609  real(DP), dimension(:), intent(inout) :: rhs
3610  integer(I4B), dimension(:), intent(in) :: ia
3611  integer(I4B), dimension(:), intent(in) :: idxglo
3612  class(MatrixBaseType), pointer :: matrix_sln
3613  ! -- local
3614  integer(I4B) :: j, n
3615  integer(I4B) :: ipos
3616  integer(I4B) :: igwfnode
3617  integer(I4B) :: idry
3618  real(DP) :: hlak
3619  real(DP) :: avail
3620  real(DP) :: ra
3621  real(DP) :: ro
3622  real(DP) :: qinf
3623  real(DP) :: ex
3624  real(DP) :: head
3625  real(DP) :: q
3626  real(DP) :: q1
3627  real(DP) :: rterm
3628  real(DP) :: drterm
3629  !
3630  ! -- implicit formulation: the lakebed seepage Jacobian is already
3631  ! assembled exactly in lak_fc_implicit for constant-conductance
3632  ! (confined / saturated) connections. Nonlinear conductance Newton terms
3633  ! are Phase 2.
3634  if (this%iimplicit /= 0) then
3635  return
3636  end if
3637  !
3638  do n = 1, this%nlakes
3639  if (this%iboundpak(n) == 0) cycle
3640  hlak = this%xnewpak(n)
3641  call this%lak_calculate_available(n, hlak, avail, &
3642  ra, ro, qinf, ex, this%delh)
3643  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3644  igwfnode = this%gwfconn(j)
3645  ipos = ia(igwfnode)
3646  head = this%xnew(igwfnode)
3647  if (-this%hcof(j) > dzero) then
3648  if (this%ibound(igwfnode) > 0) then
3649  ! -- estimate lake-aquifer exchange with perturbed groundwater head
3650  ! exchange is relative to the lake
3651  !avail = DEP20
3652  call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, &
3653  head + this%delh, q1, avail)
3654  q1 = -q1
3655  ! -- calculate unperturbed lake-aquifer exchange
3656  q = this%hcof(j) * head - this%rhs(j)
3657  ! -- calculate rterm
3658  rterm = this%hcof(j) * head
3659  ! -- calculate derivative
3660  drterm = (q1 - q) / this%delh
3661  ! -- add terms to convert conductance formulation into
3662  ! newton-raphson formulation
3663  call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(j))
3664  rhs(igwfnode) = rhs(igwfnode) - rterm + drterm * head
3665  end if
3666  end if
3667  end do
3668  end do

◆ lak_get_external_mover()

subroutine lakmodule::lak_get_external_mover ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outoutf 
)
private

Definition at line 2678 of file gwf-lak.f90.

2679  ! -- dummy
2680  class(LakType), intent(inout) :: this
2681  integer(I4B), intent(in) :: ilak
2682  real(DP), intent(inout) :: outoutf
2683  ! -- local
2684  integer(I4B) :: n
2685  !
2686  outoutf = dzero
2687  if (this%imover == 1) then
2688  do n = 1, this%noutlets
2689  if (this%lakein(n) == ilak) then
2690  if (this%lakeout(n) > 0) cycle
2691  outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2692  end if
2693  end do
2694  end if

◆ lak_get_external_outlet()

subroutine lakmodule::lak_get_external_outlet ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outoutf 
)
private

Definition at line 2659 of file gwf-lak.f90.

2660  ! -- dummy
2661  class(LakType), intent(inout) :: this
2662  integer(I4B), intent(in) :: ilak
2663  real(DP), intent(inout) :: outoutf
2664  ! -- local
2665  integer(I4B) :: n
2666  !
2667  outoutf = dzero
2668  do n = 1, this%noutlets
2669  if (this%lakein(n) == ilak) then
2670  if (this%lakeout(n) > 0) cycle
2671  outoutf = outoutf + this%simoutrate(n)
2672  end if
2673  end do

◆ lak_get_internal_inlet()

subroutine lakmodule::lak_get_internal_inlet ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outinf 
)
private

Definition at line 2619 of file gwf-lak.f90.

2620  ! -- dummy
2621  class(LakType), intent(inout) :: this
2622  integer(I4B), intent(in) :: ilak
2623  real(DP), intent(inout) :: outinf
2624  ! -- local
2625  integer(I4B) :: n
2626  !
2627  outinf = dzero
2628  do n = 1, this%noutlets
2629  if (this%lakeout(n) == ilak) then
2630  outinf = outinf - this%simoutrate(n)
2631  if (this%imover == 1) then
2632  outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2633  end if
2634  end if
2635  end do

◆ lak_get_internal_mover()

subroutine lakmodule::lak_get_internal_mover ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outoutf 
)
private

Definition at line 2699 of file gwf-lak.f90.

2700  ! -- dummy
2701  class(LakType), intent(inout) :: this
2702  integer(I4B), intent(in) :: ilak
2703  real(DP), intent(inout) :: outoutf
2704  ! -- local
2705  integer(I4B) :: n
2706  !
2707  outoutf = dzero
2708  if (this%imover == 1) then
2709  do n = 1, this%noutlets
2710  if (this%lakein(n) == ilak) then
2711  if (this%lakeout(n) < 1) cycle
2712  outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2713  end if
2714  end do
2715  end if

◆ lak_get_internal_outlet()

subroutine lakmodule::lak_get_internal_outlet ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outoutf 
)
private

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

2641  ! -- dummy
2642  class(LakType), intent(inout) :: this
2643  integer(I4B), intent(in) :: ilak
2644  real(DP), intent(inout) :: outoutf
2645  ! -- local
2646  integer(I4B) :: n
2647  !
2648  outoutf = dzero
2649  do n = 1, this%noutlets
2650  if (this%lakein(n) == ilak) then
2651  if (this%lakeout(n) < 1) cycle
2652  outoutf = outoutf + this%simoutrate(n)
2653  end if
2654  end do

◆ lak_get_outlet_tomover()

subroutine lakmodule::lak_get_outlet_tomover ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(inout)  outoutf 
)
private

Definition at line 2720 of file gwf-lak.f90.

2721  ! -- dummy
2722  class(LakType), intent(inout) :: this
2723  integer(I4B), intent(in) :: ilak
2724  real(DP), intent(inout) :: outoutf
2725  ! -- local
2726  integer(I4B) :: n
2727  !
2728  outoutf = dzero
2729  if (this%imover == 1) then
2730  do n = 1, this%noutlets
2731  if (this%lakein(n) == ilak) then
2732  outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2733  end if
2734  end do
2735  end if

◆ lak_input_destroy()

subroutine lakmodule::lak_input_destroy ( class(lakinputtype), intent(inout)  this)

Definition at line 3107 of file gwf-lak.f90.

3108  ! -- dummy
3109  class(LakInputType), intent(inout) :: this
3110  !
3111  nullify (this%nbound)
3112  nullify (this%ifno)
3113  nullify (this%setting)
3114  nullify (this%status)
3115  nullify (this%auxname)
3116  nullify (this%auxval)
3117  nullify (this%outletno)
3118  nullify (this%outlets_invert)
3119  nullify (this%outlets_width)
3120  nullify (this%outlets_rough)
3121  nullify (this%outlets_slope)

◆ lak_input_init()

subroutine lakmodule::lak_input_init ( class(lakinputtype), intent(inout)  this,
character(len=*), intent(in)  mempath,
integer(i4b), intent(in)  naux,
integer(i4b), intent(in)  noutlets 
)
private

Called once from lak_ar; pointers remain valid for the simulation lifetime. Input tsmanager advances TS-linked values transparently each timestep.

Definition at line 3078 of file gwf-lak.f90.

3079  use memorymanagermodule, only: mem_setptr
3080  ! -- dummy
3081  class(LakInputType), intent(inout) :: this
3082  character(len=*), intent(in) :: mempath
3083  integer(I4B), intent(in) :: naux
3084  integer(I4B), intent(in) :: noutlets
3085  !
3086  ! -- period
3087  call mem_setptr(this%nbound, 'NBOUND', mempath)
3088  call mem_setptr(this%ifno, 'IFNO', mempath)
3089  call mem_setptr(this%setting, 'SETTING', mempath)
3090  call mem_setptr(this%status, 'STATUS', mempath)
3091  if (naux > 0) then
3092  call mem_setptr(this%auxname, 'AUXNAME', mempath)
3093  call mem_setptr(this%auxval, 'AUXVAL', mempath)
3094  end if
3095  ! -- outlets
3096  if (noutlets > 0) then
3097  call mem_setptr(this%outletno, 'OUTLETS_OUTLETNO', mempath)
3098  call mem_setptr(this%outlets_invert, 'OUTLETS_INVERT', mempath)
3099  call mem_setptr(this%outlets_width, 'OUTLETS_WIDTH', mempath)
3100  call mem_setptr(this%outlets_rough, 'OUTLETS_ROUGH', mempath)
3101  call mem_setptr(this%outlets_slope, 'OUTLETS_SLOPE', mempath)
3102  end if

◆ lak_linear_interpolation()

subroutine lakmodule::lak_linear_interpolation ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
real(dp), dimension(n), intent(in)  x,
real(dp), dimension(n), intent(in)  y,
real(dp), intent(in)  z,
real(dp), intent(inout)  v 
)

Function assumes x data is sorted in ascending order

Definition at line 1853 of file gwf-lak.f90.

1854  ! -- dummy
1855  class(LakType), intent(inout) :: this
1856  integer(I4B), intent(in) :: n
1857  real(DP), dimension(n), intent(in) :: x
1858  real(DP), dimension(n), intent(in) :: y
1859  real(DP), intent(in) :: z
1860  real(DP), intent(inout) :: v
1861  ! -- local
1862  integer(I4B) :: i
1863  real(DP) :: dx, dydx
1864  ! code
1865  v = dzero
1866  ! below bottom of range - set to lowest value
1867  if (z <= x(1)) then
1868  v = y(1)
1869  ! above highest value
1870  ! slope calculated from interval between n and n-1
1871  else if (z > x(n)) then
1872  dx = x(n) - x(n - 1)
1873  dydx = dzero
1874  if (abs(dx) > dzero) then
1875  dydx = (y(n) - y(n - 1)) / dx
1876  end if
1877  dx = (z - x(n))
1878  v = y(n) + dydx * dx
1879  ! between lowest and highest value in current interval
1880  else
1881  do i = 2, n
1882  dx = x(i) - x(i - 1)
1883  dydx = dzero
1884  if (z >= x(i - 1) .and. z <= x(i)) then
1885  if (abs(dx) > dzero) then
1886  dydx = (y(i) - y(i - 1)) / dx
1887  end if
1888  dx = (z - x(i - 1))
1889  v = y(i - 1) + dydx * dx
1890  exit
1891  end if
1892  end do
1893  end if

◆ lak_mc()

subroutine lakmodule::lak_mc ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  moffset,
class(matrixbasetype), pointer  matrix_sln 
)

Implicit formulation only. Finds the position in the assembled matrix of each lake-row diagonal, lake-to-cell, cell diagonal, and cell-to-lake entry and stores them in the idx* arrays so they can be filled during assembly.

Definition at line 4583 of file gwf-lak.f90.

4585  ! -- dummy
4586  class(LakType), intent(inout) :: this
4587  integer(I4B), intent(in) :: moffset
4588  class(MatrixBaseType), pointer :: matrix_sln
4589  ! -- local
4590  integer(I4B) :: n
4591  integer(I4B) :: j
4592  integer(I4B) :: iglo
4593  integer(I4B) :: jglo
4594  integer(I4B) :: ipos
4595  !
4596  ! -- the connection-mapping vectors are only used by the implicit
4597  ! formulation; allocate them at size 0 otherwise so legacy LAK runs do not
4598  ! pay the maxbound memory cost (lak_da stays symmetric either way)
4599  if (this%iimplicit == 0) then
4600  call mem_allocate(this%idxlocnode, 0, 'IDXLOCNODE', this%memoryPath)
4601  call mem_allocate(this%idxdiag, 0, 'IDXDIAG', this%memoryPath)
4602  call mem_allocate(this%idxoffdglo, 0, 'IDXOFFDGLO', this%memoryPath)
4603  call mem_allocate(this%idxsymdglo, 0, 'IDXSYMDGLO', this%memoryPath)
4604  call mem_allocate(this%idxsymoffdglo, 0, 'IDXSYMOFFDGLO', this%memoryPath)
4605  return
4606  end if
4607  call mem_allocate(this%idxlocnode, this%nlakes, 'IDXLOCNODE', &
4608  this%memoryPath)
4609  call mem_allocate(this%idxdiag, this%nlakes, 'IDXDIAG', this%memoryPath)
4610  call mem_allocate(this%idxoffdglo, this%maxbound, 'IDXOFFDGLO', &
4611  this%memoryPath)
4612  call mem_allocate(this%idxsymdglo, this%maxbound, 'IDXSYMDGLO', &
4613  this%memoryPath)
4614  call mem_allocate(this%idxsymoffdglo, this%maxbound, 'IDXSYMOFFDGLO', &
4615  this%memoryPath)
4616  !
4617  ! -- lake rows: a per-lake diagonal position and the per-connection
4618  ! lake->cell off-diagonals. The diagonal is stored per lake (idxdiag) so a
4619  ! lake with no connections still has a valid diagonal position.
4620  ipos = 1
4621  do n = 1, this%nlakes
4622  iglo = moffset + this%dis%nodes + this%ioffset + n
4623  this%idxlocnode(n) = this%dis%nodes + this%ioffset + n
4624  this%idxdiag(n) = matrix_sln%get_position_diag(iglo)
4625  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4626  jglo = this%gwfconn(j) + moffset
4627  this%idxoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4628  ipos = ipos + 1
4629  end do
4630  end do
4631  !
4632  ! -- lake contributions to the gwf portion of the global matrix
4633  ipos = 1
4634  do n = 1, this%nlakes
4635  jglo = moffset + this%dis%nodes + this%ioffset + n
4636  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4637  iglo = this%gwfconn(j) + moffset
4638  this%idxsymdglo(ipos) = matrix_sln%get_position_diag(iglo)
4639  this%idxsymoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4640  ipos = ipos + 1
4641  end do
4642  end do

◆ lak_nur()

subroutine lakmodule::lak_nur ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  neqpak,
real(dp), dimension(neqpak), intent(inout)  x,
real(dp), dimension(neqpak), intent(in)  xtemp,
real(dp), dimension(neqpak), intent(inout)  dx,
integer(i4b), intent(inout)  inewtonur,
real(dp), intent(inout)  dxmax,
integer(i4b), intent(inout)  locmax 
)
private

Implicit formulation only. The model Newton under-relaxation step (gwf_nur) calls this routine with the lake-stage part of the solution. If an updated stage falls below the lake bottom, it is relaxed back toward the bottom (90 percent of the way) and its change is zeroed. Active only when the model uses NEWTON UNDER_RELAXATION.

Definition at line 3679 of file gwf-lak.f90.

3680  ! -- dummy
3681  class(LakType), intent(inout) :: this
3682  integer(I4B), intent(in) :: neqpak
3683  real(DP), dimension(neqpak), intent(inout) :: x
3684  real(DP), dimension(neqpak), intent(in) :: xtemp
3685  real(DP), dimension(neqpak), intent(inout) :: dx
3686  integer(I4B), intent(inout) :: inewtonur
3687  real(DP), intent(inout) :: dxmax
3688  integer(I4B), intent(inout) :: locmax
3689  ! -- local
3690  integer(I4B) :: n
3691  real(DP) :: botl
3692  real(DP) :: xx
3693  real(DP) :: dxx
3694  !
3695  ! -- only the implicit formulation has the lake stage in the global solution
3696  if (this%iimplicit == 0) return
3697  !
3698  ! -- Newton-Raphson under-relaxation: hold the stage at the lake bottom
3699  do n = 1, this%nlakes
3700  if (this%iboundpak(n) < 1) cycle
3701  botl = this%lakebot(n)
3702  !
3703  ! -- only apply under-relaxation if the updated stage is below the bottom
3704  ! of the lake
3705  if (x(n) < botl) then
3706  inewtonur = 1
3707  xx = xtemp(n) * (done - dp9) + botl * dp9
3708  dxx = x(n) - xx
3709  if (abs(dxx) > abs(dxmax)) then
3710  locmax = n
3711  dxmax = dxx
3712  end if
3713  x(n) = xx
3714  dx(n) = dzero
3715  end if
3716  end do

◆ lak_obs_supported()

logical function lakmodule::lak_obs_supported ( class(laktype)  this)

Return true because LAK package supports observations. Overrides BndTypebnd_obs_supported()

Definition at line 4650 of file gwf-lak.f90.

4651  ! -- dummy
4652  class(LakType) :: this
4653  !
4654  lak_obs_supported = .true.

◆ lak_ot_bdsummary()

subroutine lakmodule::lak_ot_bdsummary ( class(laktype)  this,
integer(i4b), intent(in)  kstp,
integer(i4b), intent(in)  kper,
integer(i4b), intent(in)  iout,
integer(i4b), intent(in)  ibudfl 
)
Parameters
thisLakType 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 4286 of file gwf-lak.f90.

4287  ! -- module
4288  use tdismodule, only: totim, delt
4289  ! -- dummy
4290  class(LakType) :: this !< LakType object
4291  integer(I4B), intent(in) :: kstp !< time step number
4292  integer(I4B), intent(in) :: kper !< period number
4293  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
4294  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
4295  !
4296  call this%budobj%write_budtable(kstp, kper, iout, ibudfl, totim, delt)

◆ lak_ot_dv()

subroutine lakmodule::lak_ot_dv ( class(laktype)  this,
integer(i4b), intent(in)  idvsave,
integer(i4b), intent(in)  idvprint 
)
private

Definition at line 4215 of file gwf-lak.f90.

4216  use tdismodule, only: kstp, kper, pertim, totim
4217  use constantsmodule, only: dhnoflo, dhdry
4218  use inputoutputmodule, only: ulasav
4219  class(LakType) :: this
4220  integer(I4B), intent(in) :: idvsave
4221  integer(I4B), intent(in) :: idvprint
4222  integer(I4B) :: ibinun
4223  integer(I4B) :: n
4224  real(DP) :: v
4225  real(DP) :: d
4226  real(DP) :: stage
4227  real(DP) :: sa
4228  real(DP) :: wa
4229  !
4230  ! -- set unit number for binary dependent variable output
4231  ibinun = 0
4232  if (this%istageout /= 0) then
4233  ibinun = this%istageout
4234  end if
4235  if (idvsave == 0) ibinun = 0
4236  !
4237  ! -- write lake binary output
4238  if (ibinun > 0) then
4239  do n = 1, this%nlakes
4240  v = this%xnewpak(n)
4241  d = v - this%lakebot(n)
4242  if (this%iboundpak(n) == 0) then
4243  v = dhnoflo
4244  else if (d <= dzero) then
4245  v = dhdry
4246  end if
4247  this%dbuff(n) = v
4248  end do
4249  call ulasav(this%dbuff, ' STAGE', kstp, kper, pertim, totim, &
4250  this%nlakes, 1, 1, ibinun)
4251  end if
4252  !
4253  ! -- Print lake stage table
4254  if (idvprint /= 0 .and. this%iprhed /= 0) then
4255  !
4256  ! -- set table kstp and kper
4257  call this%stagetab%set_kstpkper(kstp, kper)
4258  !
4259  ! -- write data
4260  do n = 1, this%nlakes
4261  if (this%iboundpak(n) == 0) then
4262  stage = dhnoflo
4263  sa = dhnoflo
4264  wa = dhnoflo
4265  v = dhnoflo
4266  else
4267  stage = this%xnewpak(n)
4268  call this%lak_calculate_sarea(n, stage, sa)
4269  call this%lak_calculate_warea(n, stage, wa)
4270  call this%lak_calculate_vol(n, stage, v)
4271  end if
4272  if (this%inamedbound == 1) then
4273  call this%stagetab%add_term(this%lakename(n))
4274  end if
4275  call this%stagetab%add_term(n)
4276  call this%stagetab%add_term(stage)
4277  call this%stagetab%add_term(sa)
4278  call this%stagetab%add_term(wa)
4279  call this%stagetab%add_term(v)
4280  end do
4281  end if
real(dp), parameter dhdry
real dry cell constant
Definition: Constants.f90:94
real(dp), parameter dhnoflo
real no flow constant
Definition: Constants.f90:93
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:

◆ lak_ot_model_flows()

subroutine lakmodule::lak_ot_model_flows ( class(laktype)  this,
integer(i4b), intent(in)  icbcfl,
integer(i4b), intent(in)  ibudfl,
integer(i4b), intent(in)  icbcun,
integer(i4b), dimension(:), intent(in), optional  imap 
)

Definition at line 4202 of file gwf-lak.f90.

4203  class(LakType) :: this
4204  integer(I4B), intent(in) :: icbcfl
4205  integer(I4B), intent(in) :: ibudfl
4206  integer(I4B), intent(in) :: icbcun
4207  integer(I4B), dimension(:), optional, intent(in) :: imap
4208  !
4209  ! -- write the flows from the budobj
4210  call this%BndType%bnd_ot_model_flows(icbcfl, ibudfl, icbcun, this%imap)

◆ lak_ot_package_flows()

subroutine lakmodule::lak_ot_package_flows ( class(laktype)  this,
integer(i4b), intent(in)  icbcfl,
integer(i4b), intent(in)  ibudfl 
)

Definition at line 4176 of file gwf-lak.f90.

4177  use tdismodule, only: kstp, kper, delt, pertim, totim
4178  class(LakType) :: this
4179  integer(I4B), intent(in) :: icbcfl
4180  integer(I4B), intent(in) :: ibudfl
4181  integer(I4B) :: ibinun
4182  !
4183  ! -- write the flows from the budobj
4184  ibinun = 0
4185  if (this%ibudgetout /= 0) then
4186  ibinun = this%ibudgetout
4187  end if
4188  if (icbcfl == 0) ibinun = 0
4189  if (ibinun > 0) then
4190  call this%budobj%save_flows(this%dis, ibinun, kstp, kper, delt, &
4191  pertim, totim, this%iout)
4192  end if
4193  !
4194  ! -- Print lake flows table
4195  if (ibudfl /= 0 .and. this%iprflow /= 0) then
4196  call this%budobj%write_flowtable(this%dis, kstp, kper)
4197  end if

◆ lak_outlet_outflow_rate()

subroutine lakmodule::lak_outlet_outflow_rate ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  stage,
real(dp), intent(inout)  qout 
)
private

Side-effect-free companion to lak_calculate_outlet_outflow used by the implicit formulation: returns the summed (negative) rating-curve outflow for all outlets whose source is ilak, without applying the available-water cap or updating simoutrate. Used to linearize the outlet-outflow sink on the lake row in stage.

Definition at line 2580 of file gwf-lak.f90.

2581  ! -- dummy
2582  class(LakType), intent(inout) :: this
2583  integer(I4B), intent(in) :: ilak
2584  real(DP), intent(in) :: stage
2585  real(DP), intent(inout) :: qout
2586  ! -- local
2587  integer(I4B) :: n
2588  real(DP) :: g, d, c, gsm, rate
2589  !
2590  qout = dzero
2591  do n = 1, this%noutlets
2592  if (this%lakein(n) /= ilak) cycle
2593  rate = dzero
2594  d = stage - this%outinvert(n)
2595  if (this%outdmax > dzero .and. d > this%outdmax) d = this%outdmax
2596  g = dgravity * this%convlength * this%convtime * this%convtime
2597  select case (this%iouttype(n))
2598  case (0) ! specified rate
2599  rate = this%outrate(n)
2600  case (1) ! manning
2601  if (d > dzero) then
2602  c = (this%convlength**donethird) * this%convtime
2603  gsm = dzero
2604  if (this%outrough(n) > dzero) gsm = done / this%outrough(n)
2605  rate = -c * gsm * this%outwidth(n) * (d**dfivethirds) * &
2606  sqrt(this%outslope(n))
2607  end if
2608  case (2) ! weir
2609  if (d > dzero) then
2610  rate = -dtwothirds * dcd * this%outwidth(n) * d * sqrt(dtwo * g * d)
2611  end if
2612  end select
2613  qout = qout + rate
2614  end do

◆ lak_process_obsid()

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

Definition at line 5072 of file gwf-lak.f90.

5073  ! -- dummy
5074  type(ObserveType), intent(inout) :: obsrv
5075  class(DisBaseType), intent(in) :: dis
5076  integer(I4B), intent(in) :: inunitobs
5077  integer(I4B), intent(in) :: iout
5078  ! -- local
5079  integer(I4B) :: nn1, nn2
5080  integer(I4B) :: icol, istart, istop
5081  character(len=LINELENGTH) :: string
5082  character(len=LENBOUNDNAME) :: bndname
5083  !
5084  string = obsrv%IDstring
5085  ! -- Extract lake number from string and store it.
5086  ! If 1st item is not an integer(I4B), it should be a
5087  ! lake name--deal with it.
5088  icol = 1
5089  ! -- get lake number or boundary name
5090  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
5091  if (nn1 == namedboundflag) then
5092  obsrv%FeatureName = bndname
5093  else
5094  if (obsrv%ObsTypeId == 'LAK' .or. obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
5095  obsrv%ObsTypeId == 'WETTED-AREA') then
5096  call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname)
5097  if (len_trim(bndname) < 1 .and. nn2 < 0) then
5098  write (errmsg, '(a,1x,a,a,1x,a,1x,a)') &
5099  'For observation type', trim(adjustl(obsrv%ObsTypeId)), &
5100  ', ID given as an integer and not as boundname,', &
5101  'but ID2 (iconn) is missing. Either change ID to valid', &
5102  'boundname or supply valid entry for ID2.'
5103  call store_error(errmsg)
5104  end if
5105  if (nn2 == namedboundflag) then
5106  obsrv%FeatureName = bndname
5107  ! -- reset nn1
5108  nn1 = nn2
5109  else
5110  obsrv%NodeNumber2 = nn2
5111  end if
5112  end if
5113  end if
5114  ! -- store lake number (NodeNumber)
5115  obsrv%NodeNumber = nn1
Here is the call graph for this function:

◆ lak_read_initial_attr()

subroutine lakmodule::lak_read_initial_attr ( class(laktype), intent(inout)  this)
private

Definition at line 1591 of file gwf-lak.f90.

1592  use constantsmodule, only: linelength
1594  use simmodule, only: store_error, count_errors
1595  ! -- dummy
1596  class(LakType), intent(inout) :: this
1597  ! -- local
1598  integer(I4B) :: j, n
1599  integer(I4B) :: nn
1600  integer(I4B) :: idx
1601  real(DP) :: top
1602  real(DP) :: bot
1603  real(DP) :: k
1604  real(DP) :: area
1605  real(DP) :: length
1606  real(DP) :: s
1607  real(DP) :: dx
1608  real(DP) :: c
1609  real(DP) :: sa
1610  real(DP) :: wa
1611  real(DP) :: v
1612  real(DP) :: fact
1613  real(DP) :: c1
1614  real(DP) :: c2
1615  real(DP), allocatable, dimension(:) :: clb, caq
1616  character(len=14) :: cbedleak
1617  character(len=14) :: cbedcond
1618  character(len=10), dimension(0:3) :: ctype
1619  character(len=15) :: nodestr
1620  ! -- data
1621  data ctype(0)/'VERTICAL '/
1622  data ctype(1)/'HORIZONTAL'/
1623  data ctype(2)/'EMBEDDEDH '/
1624  data ctype(3)/'EMBEDDEDV '/
1625  !
1626  ! -- initialize xnewpak and set stage
1627  do n = 1, this%nlakes
1628  this%xnewpak(n) = this%strt(n)
1629  this%stage(n) = this%strt(n)
1630  end do
1631  !
1632  ! -- initialize status (iboundpak) of lakes to active
1633  do n = 1, this%nlakes
1634  if (this%status(n) == 'CONSTANT') then
1635  this%iboundpak(n) = -1
1636  else if (this%status(n) == 'INACTIVE') then
1637  this%iboundpak(n) = 0
1638  else if (this%status(n) == 'ACTIVE ') then
1639  this%iboundpak(n) = 1
1640  end if
1641  end do
1642  !
1643  ! -- set boundname for each connection
1644  if (this%inamedbound /= 0) then
1645  do n = 1, this%nlakes
1646  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1647  this%boundname(j) = this%lakename(n)
1648  end do
1649  end do
1650  end if
1651  !
1652  ! -- copy boundname into boundname_cst
1653  call this%copy_boundname()
1654  !
1655  ! -- set pointer to gwf iss and gwf hk
1656  call mem_setptr(this%gwfiss, 'ISS', create_mem_path(this%name_model))
1657  call mem_setptr(this%gwfk11, 'K11', create_mem_path(this%name_model, 'NPF'))
1658  call mem_setptr(this%gwfk33, 'K33', create_mem_path(this%name_model, 'NPF'))
1659  call mem_setptr(this%gwfik33, 'IK33', create_mem_path(this%name_model, 'NPF'))
1660  call mem_setptr(this%gwfsat, 'SAT', create_mem_path(this%name_model, 'NPF'))
1661  !
1662  ! -- allocate temporary storage
1663  allocate (clb(this%MAXBOUND))
1664  allocate (caq(this%MAXBOUND))
1665  !
1666  ! -- calculate saturated conductance for each connection
1667  do n = 1, this%nlakes
1668  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1669  nn = this%gwfconn(j)
1670  top = this%dis%top(nn)
1671  bot = this%dis%bot(nn)
1672  ! vertical connection
1673  if (this%ictype(j) == 0) then
1674  area = this%dis%area(nn)
1675  this%sarea(j) = area
1676  this%warea(j) = area
1677  this%sareamax(n) = this%sareamax(n) + area
1678  if (this%gwfik33 == 0) then
1679  k = this%gwfk11(nn)
1680  else
1681  k = this%gwfk33(nn)
1682  end if
1683  length = dhalf * (top - bot)
1684  ! horizontal connection
1685  else if (this%ictype(j) == 1) then
1686  area = (this%telev(j) - this%belev(j)) * this%connwidth(j)
1687  ! -- recalculate area if connected cell is confined and lake
1688  ! connection top and bot are equal to the cell top and bot
1689  if (top == this%telev(j) .and. bot == this%belev(j)) then
1690  if (this%icelltype(nn) == 0) then
1691  area = this%gwfsat(nn) * (top - bot) * this%connwidth(j)
1692  end if
1693  end if
1694  this%sarea(j) = dzero
1695  this%warea(j) = area
1696  this%sareamax(n) = this%sareamax(n) + dzero
1697  k = this%gwfk11(nn)
1698  length = this%connlength(j)
1699  ! embedded horizontal connection
1700  else if (this%ictype(j) == 2) then
1701  area = done
1702  this%sarea(j) = dzero
1703  this%warea(j) = area
1704  this%sareamax(n) = this%sareamax(n) + dzero
1705  k = this%gwfk11(nn)
1706  length = this%connlength(j)
1707  ! embedded vertical connection
1708  else if (this%ictype(j) == 3) then
1709  area = done
1710  this%sarea(j) = dzero
1711  this%warea(j) = area
1712  this%sareamax(n) = this%sareamax(n) + dzero
1713  if (this%gwfik33 == 0) then
1714  k = this%gwfk11(nn)
1715  else
1716  k = this%gwfk33(nn)
1717  end if
1718  length = this%connlength(j)
1719  end if
1720  if (is_close(this%bedleak(j), dnodata)) then
1721  clb(j) = dnodata
1722  else if (this%bedleak(j) > dzero) then
1723  clb(j) = done / this%bedleak(j)
1724  else
1725  clb(j) = dzero
1726  end if
1727  if (k > dzero) then
1728  caq(j) = length / k
1729  else
1730  caq(j) = dzero
1731  end if
1732  if (is_close(this%bedleak(j), dnodata)) then
1733  this%satcond(j) = area / caq(j)
1734  else if (clb(j) * caq(j) > dzero) then
1735  this%satcond(j) = area / (clb(j) + caq(j))
1736  else
1737  this%satcond(j) = dzero
1738  end if
1739  end do
1740  end do
1741  !
1742  ! -- write a summary of the conductance
1743  if (this%iprpak > 0) then
1744  write (this%iout, '(//,29x,a,/)') &
1745  'INTERFACE CONDUCTANCE BETWEEN LAKE AND AQUIFER CELLS'
1746  write (this%iout, '(1x,a)') &
1747  & ' LAKE CONNECTION CONNECTION LAKEBED'// &
1748  & ' C O N D U C T A N C E S '
1749  write (this%iout, '(1x,a)') &
1750  & ' NUMBER NUMBER CELLID DIRECTION LEAKANCE'// &
1751  & ' LAKEBED AQUIFER COMBINED'
1752  write (this%iout, "(1x,108('-'))")
1753  do n = 1, this%nlakes
1754  idx = 0
1755  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1756  idx = idx + 1
1757  fact = done
1758  if (this%ictype(j) == 1) then
1759  fact = this%telev(j) - this%belev(j)
1760  if (abs(fact) > dzero) then
1761  fact = done / fact
1762  end if
1763  end if
1764  nn = this%gwfconn(j)
1765  area = this%warea(j)
1766  c1 = dzero
1767  if (is_close(clb(j), dnodata)) then
1768  cbedleak = ' NONE '
1769  cbedcond = ' NONE '
1770  else if (clb(j) > dzero) then
1771  c1 = area * fact / clb(j)
1772  write (cbedleak, '(g14.5)') this%bedleak(j)
1773  write (cbedcond, '(g14.5)') c1
1774  else
1775  write (cbedleak, '(g14.5)') c1
1776  write (cbedcond, '(g14.5)') c1
1777  end if
1778  c2 = dzero
1779  if (caq(j) > dzero) then
1780  c2 = area * fact / caq(j)
1781  end if
1782  call this%dis%noder_to_string(nn, nodestr)
1783  write (this%iout, &
1784  '(1x,i10,1x,i10,1x,a15,1x,a10,2(1x,a14),2(1x,g14.5))') &
1785  n, idx, nodestr, ctype(this%ictype(j)), cbedleak, &
1786  cbedcond, c2, this%satcond(j) * fact
1787  end do
1788  end do
1789  write (this%iout, "(1x,108('-'))")
1790  write (this%iout, '(1x,a)') &
1791  'IF VERTICAL CONNECTION, CONDUCTANCE (L^2/T) IS &
1792  &BETWEEN AQUIFER CELL AND OVERLYING LAKE CELL.'
1793  write (this%iout, '(1x,a)') &
1794  'IF HORIZONTAL CONNECTION, CONDUCTANCES ARE PER &
1795  &UNIT SATURATED THICKNESS (L/T).'
1796  write (this%iout, '(1x,a)') &
1797  'IF EMBEDDED CONNECTION, CONDUCTANCES ARE PER &
1798  &UNIT EXCHANGE AREA (1/T).'
1799  !
1800  ! write(this%iout,*) n, idx, nodestr, this%sarea(j), this%warea(j)
1801  !
1802  ! -- calculate stage, surface area, wetted area, volume relation
1803  do n = 1, this%nlakes
1804  write (this%iout, '(//1x,a,1x,i10)') 'STAGE/VOLUME RELATION FOR LAKE ', n
1805  write (this%iout, '(/1x,5(a14))') ' STAGE', ' SURFACE AREA', &
1806  & ' WETTED AREA', ' CONDUCTANCE', &
1807  & ' VOLUME'
1808  write (this%iout, "(1x,70('-'))")
1809  dx = (this%laketop(n) - this%lakebot(n)) / 150.
1810  s = this%lakebot(n)
1811  do j = 1, 151
1812  call this%lak_calculate_conductance(n, s, c)
1813  call this%lak_calculate_sarea(n, s, sa)
1814  call this%lak_calculate_warea(n, s, wa, s)
1815  call this%lak_calculate_vol(n, s, v)
1816  write (this%iout, '(1x,5(E14.5))') s, sa, wa, c, v
1817  s = s + dx
1818  end do
1819  write (this%iout, "(1x,70('-'))")
1820  !
1821  write (this%iout, '(//1x,a,1x,i10)') 'STAGE/VOLUME RELATION FOR LAKE ', n
1822  write (this%iout, '(/1x,4(a14))') ' ', ' ', &
1823  & ' CALCULATED', ' STAGE'
1824  write (this%iout, '(1x,4(a14))') ' STAGE', ' VOLUME', &
1825  & ' STAGE', ' DIFFERENCE'
1826  write (this%iout, "(1x,56('-'))")
1827  s = this%lakebot(n) - dx
1828  do j = 1, 156
1829  call this%lak_calculate_vol(n, s, v)
1830  call this%lak_vol2stage(n, v, c)
1831  write (this%iout, '(1x,4(E14.5))') s, v, c, s - c
1832  s = s + dx
1833  end do
1834  write (this%iout, "(1x,56('-'))")
1835  end do
1836  end if
1837  !
1838  ! -- finished with pointer to gwf hydraulic conductivity
1839  this%gwfk11 => null()
1840  this%gwfk33 => null()
1841  this%gwfsat => null()
1842  this%gwfik33 => null()
1843  !
1844  ! -- deallocate temporary storage
1845  deallocate (clb)
1846  deallocate (caq)
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
Here is the call graph for this function:

◆ lak_rp()

subroutine lakmodule::lak_rp ( class(laktype), intent(inout)  this)

Definition at line 3181 of file gwf-lak.f90.

3182  ! -- modules
3183  use constantsmodule, only: lenvarname
3184  use tdismodule, only: kper
3185  ! -- dummy
3186  class(LakType), intent(inout) :: this
3187  ! -- local
3188  character(len=LINELENGTH) :: str = ' '
3189  real(DP) :: auxvaldbl = dzero
3190  character(len=LINELENGTH) :: title
3191  character(len=LINELENGTH) :: text
3192  character(len=LENVARNAME) :: setting
3193  integer(I4B) :: node, n, j, itemno
3194  integer(I4B) :: istat
3195  ! -- formats
3196  character(len=*), parameter :: fmtlsp = &
3197  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
3198  !
3199  ! -- set nbound to maxbound
3200  this%nbound = this%maxbound
3201  !
3202  ! -- check if data has been loaded for this stress period
3203  if (this%iper == kper) then
3204  !
3205  this%check_attr = 1
3206  !
3207  ! -- setup table to echo period data
3208  if (this%iprpak /= 0) then
3209  title = trim(adjustl(this%text))//' PACKAGE ('// &
3210  trim(adjustl(this%packName))//') DATA FOR PERIOD'
3211  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
3212  call table_cr(this%inputtab, this%packName, title)
3213  call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
3214  text = 'NUMBER'
3215  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
3216  text = 'KEYWORD'
3217  call this%inputtab%initialize_column(text, 20, alignment=tableft)
3218  do n = 1, 2
3219  write (text, '(a,1x,i6)') 'VALUE', n
3220  call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
3221  end do
3222  end if
3223  !
3224  ! -- process each period data entry
3225  do n = 1, this%input%nbound
3226  itemno = this%input%ifno(n)
3227  !
3228  ! -- dispatch key for this row
3229  setting = this%input%setting(n)
3230  str = ' '
3231  !
3232  ! -- STATUS (lake only; not TS-enabled)
3233  if (trim(setting) == 'STATUS') then
3234  str = this%input%status(n)
3235  istat = this%lak_check_valid(itemno)
3236  if (istat == 0 .and. itemno >= 1 .and. itemno <= this%nlakes) then
3237  if (trim(str) == 'CONSTANT') then
3238  this%iboundpak(itemno) = -1
3239  else if (trim(str) == 'INACTIVE') then
3240  this%iboundpak(itemno) = 0
3241  else if (trim(str) == 'ACTIVE') then
3242  this%iboundpak(itemno) = 1
3243  else
3244  write (errmsg, '(a,a)') &
3245  'Unknown '//trim(this%text)//' STATUS keyword: ', &
3246  trim(str)//'.'
3247  call store_error(errmsg)
3248  end if
3249  this%status(itemno) = trim(str)
3250  end if
3251  end if
3252  !
3253  ! -- STAGE (validate itemno; assignment via helper)
3254  if (trim(setting) == 'STAGE') then
3255  istat = this%lak_check_valid(itemno)
3256  end if
3257  !
3258  ! -- RAINFALL, EVAPORATION, RUNOFF, INFLOW, WITHDRAWAL (require
3259  ! non-negative)
3260  if (trim(setting) == 'RAINFALL') &
3261  call this%lak_set_nonneg_value(n, itemno, setting, this%rainfall, &
3262  'rainfall')
3263  if (trim(setting) == 'EVAPORATION') &
3264  call this%lak_set_nonneg_value(n, itemno, setting, &
3265  this%evaporation, 'evaporation')
3266  if (trim(setting) == 'RUNOFF') &
3267  call this%lak_set_nonneg_value(n, itemno, setting, this%runoff, &
3268  'runoff')
3269  if (trim(setting) == 'INFLOW') &
3270  call this%lak_set_nonneg_value(n, itemno, setting, this%inflow, &
3271  'inflow')
3272  if (trim(setting) == 'WITHDRAWAL') &
3273  call this%lak_set_nonneg_value(n, itemno, setting, &
3274  this%withdrawal, 'withdrawal')
3275  !
3276  ! -- RATE, INVERT, WIDTH, ROUGH, SLOPE (outlet; validate with
3277  ! negative sign convention)
3278  if (trim(setting) == 'RATE' .or. trim(setting) == 'INVERT' .or. &
3279  trim(setting) == 'WIDTH' .or. trim(setting) == 'ROUGH' .or. &
3280  trim(setting) == 'SLOPE') then
3281  istat = this%lak_check_valid(-itemno)
3282  end if
3283  !
3284  ! -- INVERT, WIDTH, ROUGH, SLOPE latch here so the OUTLETS block's
3285  ! own (separately time-series-linked) baseline resync in lak_ad
3286  ! stops overwriting this outlet's PERIOD-block override
3287  if (istat == 0 .and. itemno >= 1 .and. itemno <= this%noutlets) then
3288  if (trim(setting) == 'INVERT') this%outlet_invert_set(itemno) = .true.
3289  if (trim(setting) == 'WIDTH') this%outlet_width_set(itemno) = .true.
3290  if (trim(setting) == 'ROUGH') this%outlet_rough_set(itemno) = .true.
3291  if (trim(setting) == 'SLOPE') this%outlet_slope_set(itemno) = .true.
3292  end if
3293  !
3294  ! -- AUXILIARY; featureauxvar set via sync_auxvar()
3295  if (this%naux > 0) then
3296  if (trim(setting) == 'PERIOD_AUXILIARY') then
3297  if (itemno >= 1 .and. itemno <= this%nlakes) then
3298  str = this%input%auxname(n)
3299  auxvaldbl = this%input%auxval(n)
3300  end if
3301  end if
3302  end if
3303  !
3304  ! -- echo row to period data table
3305  if (this%iprpak /= 0) then
3306  call this%inputtab%add_term(itemno)
3307  if (trim(setting) == 'PERIOD_AUXILIARY') then
3308  call this%inputtab%add_term('AUXILIARY')
3309  else
3310  call this%inputtab%add_term(trim(setting))
3311  end if
3312  select case (trim(setting))
3313  case ('STATUS')
3314  call this%inputtab%add_term(trim(str))
3315  call this%inputtab%add_term(' ')
3316  case ('STAGE')
3317  call this%inputtab%add_term(this%stage(itemno))
3318  call this%inputtab%add_term(' ')
3319  case ('RAINFALL')
3320  call this%inputtab%add_term(this%rainfall(itemno))
3321  call this%inputtab%add_term(' ')
3322  case ('EVAPORATION')
3323  call this%inputtab%add_term(this%evaporation(itemno))
3324  call this%inputtab%add_term(' ')
3325  case ('RUNOFF')
3326  call this%inputtab%add_term(this%runoff(itemno))
3327  call this%inputtab%add_term(' ')
3328  case ('INFLOW')
3329  call this%inputtab%add_term(this%inflow(itemno))
3330  call this%inputtab%add_term(' ')
3331  case ('WITHDRAWAL')
3332  call this%inputtab%add_term(this%withdrawal(itemno))
3333  call this%inputtab%add_term(' ')
3334  case ('RATE')
3335  call this%inputtab%add_term(this%outrate(itemno))
3336  call this%inputtab%add_term(' ')
3337  case ('INVERT')
3338  call this%inputtab%add_term(this%outinvert(itemno))
3339  call this%inputtab%add_term(' ')
3340  case ('WIDTH')
3341  call this%inputtab%add_term(this%outwidth(itemno))
3342  call this%inputtab%add_term(' ')
3343  case ('ROUGH')
3344  call this%inputtab%add_term(this%outrough(itemno))
3345  call this%inputtab%add_term(' ')
3346  case ('SLOPE')
3347  call this%inputtab%add_term(this%outslope(itemno))
3348  call this%inputtab%add_term(' ')
3349  case ('PERIOD_AUXILIARY')
3350  call this%inputtab%add_term(trim(str))
3351  call this%inputtab%add_term(auxvaldbl)
3352  case default
3353  call this%inputtab%add_term(' ')
3354  call this%inputtab%add_term(' ')
3355  end select
3356  end if
3357  end do
3358  if (this%iprpak /= 0) then
3359  call this%inputtab%finalize_table()
3360  end if
3361  !
3362  ! -- write summary of lake stress period error messages
3363  if (count_errors() > 0) then
3364  call store_error_filename(this%input_fname)
3365  end if
3366  !
3367  ! -- fill bound array with lake stage, conductance, and bottom elevation
3368  do n = 1, this%nlakes
3369  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3370  node = this%gwfconn(j)
3371  this%nodelist(j) = node
3372  this%bound(1, j) = this%xnewpak(n)
3373  this%bound(2, j) = this%satcond(j)
3374  this%bound(3, j) = this%belev(j)
3375  end do
3376  end do
3377  !
3378  ! -- copy lakein into iprmap so mvr budget contains lake instead of outlet
3379  if (this%imover == 1) then
3380  do n = 1, this%noutlets
3381  this%pakmvrobj%iprmap(n) = this%lakein(n)
3382  end do
3383  end if
3384  else
3385  write (this%iout, fmtlsp) trim(this%filtyp)
3386  end if
3387  !
3388  ! -- fill nodelist and bound(3) every period; nodelist for non-vertical
3389  ! connections is not updated by lak_cf so must be set here.
3390  ! bound(3) (bed elevation) is static and only needs to be set once.
3391  do n = 1, this%nlakes
3392  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3393  this%nodelist(j) = this%gwfconn(j)
3394  this%bound(3, j) = this%belev(j)
3395  end do
3396  end do
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
Here is the call graph for this function:

◆ lak_rp_obs()

subroutine lakmodule::lak_rp_obs ( class(laktype), intent(inout)  this)
private

Only done the first stress period since boundaries are fixed for the simulation

Definition at line 4920 of file gwf-lak.f90.

4921  use tdismodule, only: kper
4922  ! -- dummy
4923  class(LakType), intent(inout) :: this
4924  ! -- local
4925  integer(I4B) :: i
4926  integer(I4B) :: j
4927  integer(I4B) :: nn1
4928  integer(I4B) :: nn2
4929  integer(I4B) :: jj
4930  character(len=LENBOUNDNAME) :: bname
4931  logical(LGP) :: jfound
4932  class(ObserveType), pointer :: obsrv => null()
4933  ! -- formats
4934 10 format('Boundary "', a, '" for observation "', a, &
4935  '" is invalid in package "', a, '"')
4936  !
4937  ! -- process each package observation
4938  ! only done the first stress period since boundaries are fixed
4939  ! for the simulation
4940  if (kper == 1) then
4941  do i = 1, this%obs%npakobs
4942  obsrv => this%obs%pakobs(i)%obsrv
4943  !
4944  ! -- get node number 1
4945  nn1 = obsrv%NodeNumber
4946  if (nn1 == namedboundflag) then
4947  bname = obsrv%FeatureName
4948  if (bname /= '') then
4949  ! -- Observation lake is based on a boundary name.
4950  ! Iterate through all lakes to identify and store
4951  ! corresponding index in bound array.
4952  jfound = .false.
4953  if (obsrv%ObsTypeId == 'LAK' .or. &
4954  obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
4955  obsrv%ObsTypeId == 'WETTED-AREA') then
4956  do j = 1, this%nlakes
4957  do jj = this%idxlakeconn(j), this%idxlakeconn(j + 1) - 1
4958  if (this%boundname(jj) == bname) then
4959  jfound = .true.
4960  call obsrv%AddObsIndex(jj)
4961  end if
4962  end do
4963  end do
4964  else if (obsrv%ObsTypeId == 'EXT-OUTFLOW' .or. &
4965  obsrv%ObsTypeId == 'TO-MVR' .or. &
4966  obsrv%ObsTypeId == 'OUTLET') then
4967  do j = 1, this%noutlets
4968  jj = this%lakein(j)
4969  if (this%lakename(jj) == bname) then
4970  jfound = .true.
4971  call obsrv%AddObsIndex(j)
4972  end if
4973  end do
4974  else
4975  do j = 1, this%nlakes
4976  if (this%lakename(j) == bname) then
4977  jfound = .true.
4978  call obsrv%AddObsIndex(j)
4979  end if
4980  end do
4981  end if
4982  if (.not. jfound) then
4983  write (errmsg, 10) &
4984  trim(bname), trim(obsrv%Name), trim(this%packName)
4985  call store_error(errmsg)
4986  end if
4987  end if
4988  else
4989  if (obsrv%indxbnds_count == 0) then
4990  if (obsrv%ObsTypeId == 'LAK' .or. &
4991  obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
4992  obsrv%ObsTypeId == 'WETTED-AREA') then
4993  nn2 = obsrv%NodeNumber2
4994  j = this%idxlakeconn(nn1) + nn2 - 1
4995  call obsrv%AddObsIndex(j)
4996  else
4997  call obsrv%AddObsIndex(nn1)
4998  end if
4999  else
5000  errmsg = 'Programming error in lak_rp_obs'
5001  call store_error(errmsg)
5002  end if
5003  end if
5004  !
5005  ! -- catch non-cumulative observation assigned to observation defined
5006  ! by a boundname that is assigned to more than one element
5007  if (obsrv%ObsTypeId == 'STAGE') then
5008  if (obsrv%indxbnds_count > 1) then
5009  write (errmsg, '(a,3(1x,a))') &
5010  trim(adjustl(obsrv%ObsTypeId)), &
5011  'for observation', trim(adjustl(obsrv%Name)), &
5012  ' must be assigned to a lake with a unique boundname.'
5013  call store_error(errmsg)
5014  end if
5015  end if
5016  !
5017  ! -- check that index values are valid
5018  if (obsrv%ObsTypeId == 'TO-MVR' .or. &
5019  obsrv%ObsTypeId == 'EXT-OUTFLOW' .or. &
5020  obsrv%ObsTypeId == 'OUTLET') then
5021  do j = 1, obsrv%indxbnds_count
5022  nn1 = obsrv%indxbnds(j)
5023  if (nn1 < 1 .or. nn1 > this%noutlets) then
5024  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5025  trim(adjustl(obsrv%ObsTypeId)), &
5026  ' outlet must be > 0 and <=', this%noutlets, &
5027  '(specified value is ', nn1, ')'
5028  call store_error(errmsg)
5029  end if
5030  end do
5031  else if (obsrv%ObsTypeId == 'LAK' .or. &
5032  obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
5033  obsrv%ObsTypeId == 'WETTED-AREA') then
5034  do j = 1, obsrv%indxbnds_count
5035  nn1 = obsrv%indxbnds(j)
5036  if (nn1 < 1 .or. nn1 > this%maxbound) then
5037  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5038  trim(adjustl(obsrv%ObsTypeId)), &
5039  'lake connection number must be > 0 and <=', this%maxbound, &
5040  '(specified value is ', nn1, ')'
5041  call store_error(errmsg)
5042  end if
5043  end do
5044  else
5045  do j = 1, obsrv%indxbnds_count
5046  nn1 = obsrv%indxbnds(j)
5047  if (nn1 < 1 .or. nn1 > this%nlakes) then
5048  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5049  trim(adjustl(obsrv%ObsTypeId)), &
5050  ' lake must be > 0 and <=', this%nlakes, &
5051  '(specified value is ', nn1, ')'
5052  call store_error(errmsg)
5053  end if
5054  end do
5055  end if
5056  end do
5057  !
5058  ! -- evaluate if there are any observation errors
5059  if (count_errors() > 0) then
5060  call store_error_unit(this%inunit)
5061  end if
5062  end if
Here is the call graph for this function:

◆ lak_set_attribute_error()

subroutine lakmodule::lak_set_attribute_error ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
character(len=*), intent(in)  keyword,
character(len=*), intent(in)  msg 
)
private

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

2879  ! -- modules
2880  use simmodule, only: store_error
2881  ! -- dummy
2882  class(LakType), intent(inout) :: this
2883  integer(I4B), intent(in) :: ilak
2884  character(len=*), intent(in) :: keyword
2885  character(len=*), intent(in) :: msg
2886  !
2887  if (len(msg) == 0) then
2888  write (errmsg, '(a,1x,a,1x,i0,1x,a)') &
2889  keyword, ' for LAKE', ilak, 'has already been set.'
2890  else
2891  write (errmsg, '(a,1x,a,1x,i0,1x,a)') keyword, ' for LAKE', ilak, msg
2892  end if
2893  call store_error(errmsg)
Here is the call graph for this function:

◆ lak_set_nonneg_value()

subroutine lakmodule::lak_set_nonneg_value ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  itemno,
character(len=*), intent(in)  setting,
real(dp), dimension(:), intent(inout)  value_array,
character(len=*), intent(in)  label 
)

Definition at line 2854 of file gwf-lak.f90.

2855  ! -- dummy
2856  class(LakType), intent(inout) :: this
2857  integer(I4B), intent(in) :: n
2858  integer(I4B), intent(in) :: itemno
2859  character(len=*), intent(in) :: setting
2860  real(DP), dimension(:), intent(inout) :: value_array
2861  character(len=*), intent(in) :: label
2862  ! -- local
2863  integer(I4B) :: istat
2864  !
2865  istat = this%lak_check_valid(itemno)
2866  if (istat /= 0) return
2867  if (itemno < 1 .or. itemno > this%nlakes) return
2868  if (value_array(itemno) < dzero) then
2869  write (errmsg, '(a,i0,a,g0,a)') &
2870  'Lake ', itemno, ' was assigned a '//trim(label)//' value of ', &
2871  value_array(itemno), '. Value must be positive.'
2872  call store_error(errmsg)
2873  end if
Here is the call graph for this function:

◆ lak_set_pointers()

subroutine lakmodule::lak_set_pointers ( class(laktype)  this,
integer(i4b), pointer  neq,
integer(i4b), dimension(:), pointer, contiguous  ibound,
real(dp), dimension(:), pointer, contiguous  xnew,
real(dp), dimension(:), pointer, contiguous  xold,
real(dp), dimension(:), pointer, contiguous  flowja 
)
private

Definition at line 4507 of file gwf-lak.f90.

4508  ! -- modules
4510  ! -- dummy
4511  class(LakType) :: this
4512  integer(I4B), pointer :: neq
4513  integer(I4B), dimension(:), pointer, contiguous :: ibound
4514  real(DP), dimension(:), pointer, contiguous :: xnew
4515  real(DP), dimension(:), pointer, contiguous :: xold
4516  real(DP), dimension(:), pointer, contiguous :: flowja
4517  ! -- local
4518  integer(I4B) :: n
4519  integer(I4B) :: istart, iend
4520  !
4521  ! -- call base BndType set_pointers
4522  call this%BndType%set_pointers(neq, ibound, xnew, xold, flowja)
4523  !
4524  ! -- for the implicit formulation, point the lake stage and ibound at the
4525  ! matching slice of the model solution (xnew) and ibound vectors so the
4526  ! stage is solved directly in the matrix. (The default formulation keeps
4527  ! these as its own arrays, allocated in lak_allocate_arrays.)
4528  if (this%iimplicit /= 0) then
4529  istart = this%dis%nodes + this%ioffset + 1
4530  iend = istart + this%nlakes - 1
4531  this%iboundpak => this%ibound(istart:iend)
4532  this%xnewpak => this%xnew(istart:iend)
4533  call mem_checkin(this%xnewpak, 'XNEWPAK', this%memoryPath, 'X', &
4534  this%memoryPathModel)
4535  !
4536  ! -- initialize xnewpak
4537  do n = 1, this%nlakes
4538  this%xnewpak(n) = dep20
4539  end do
4540  end if

◆ lak_setup_budobj()

subroutine lakmodule::lak_setup_budobj ( class(laktype)  this)

Definition at line 5836 of file gwf-lak.f90.

5837  ! -- modules
5838  use constantsmodule, only: lenbudtxt
5839  ! -- dummy
5840  class(LakType) :: this
5841  ! -- local
5842  integer(I4B) :: nbudterm
5843  integer(I4B) :: nlen
5844  integer(I4B) :: j, n, n1, n2
5845  integer(I4B) :: maxlist, naux
5846  integer(I4B) :: idx
5847  real(DP) :: q
5848  character(len=LENBUDTXT) :: text
5849  character(len=LENBUDTXT), dimension(1) :: auxtxt
5850  !
5851  ! -- Determine the number of lake budget terms. These are fixed for
5852  ! the simulation and cannot change
5853  nbudterm = 9
5854  nlen = 0
5855  do n = 1, this%noutlets
5856  if (this%lakein(n) > 0 .and. this%lakeout(n) > 0) then
5857  nlen = nlen + 1
5858  end if
5859  end do
5860  if (nlen > 0) nbudterm = nbudterm + 1
5861  if (this%imover == 1) nbudterm = nbudterm + 2
5862  if (this%naux > 0) nbudterm = nbudterm + 1
5863  !
5864  ! -- set up budobj
5865  call budgetobject_cr(this%budobj, this%packName)
5866  call this%budobj%budgetobject_df(this%nlakes, nbudterm, 0, 0, &
5867  ibudcsv=this%ibudcsv)
5868  idx = 0
5869  !
5870  ! -- Go through and set up each budget term. nlen is the number
5871  ! of outlets that discharge into another lake
5872  if (nlen > 0) then
5873  text = ' FLOW-JA-FACE'
5874  idx = idx + 1
5875  maxlist = 2 * nlen
5876  naux = 0
5877  call this%budobj%budterm(idx)%initialize(text, &
5878  this%name_model, &
5879  this%packName, &
5880  this%name_model, &
5881  this%packName, &
5882  maxlist, .false., .false., &
5883  naux, ordered_id1=.false.)
5884  !
5885  ! -- store connectivity
5886  call this%budobj%budterm(idx)%reset(2 * nlen)
5887  q = dzero
5888  do n = 1, this%noutlets
5889  n1 = this%lakein(n)
5890  n2 = this%lakeout(n)
5891  if (n1 > 0 .and. n2 > 0) then
5892  call this%budobj%budterm(idx)%update_term(n1, n2, q)
5893  call this%budobj%budterm(idx)%update_term(n2, n1, -q)
5894  end if
5895  end do
5896  end if
5897  !
5898  ! --
5899  text = ' GWF'
5900  idx = idx + 1
5901  maxlist = this%maxbound
5902  naux = 1
5903  auxtxt(1) = ' FLOW-AREA'
5904  call this%budobj%budterm(idx)%initialize(text, &
5905  this%name_model, &
5906  this%packName, &
5907  this%name_model, &
5908  this%name_model, &
5909  maxlist, .false., .true., &
5910  naux, auxtxt)
5911  call this%budobj%budterm(idx)%reset(this%maxbound)
5912  q = dzero
5913  do n = 1, this%nlakes
5914  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5915  n2 = this%gwfconn(j)
5916  call this%budobj%budterm(idx)%update_term(n, n2, q)
5917  end do
5918  end do
5919  !
5920  ! --
5921  text = ' RAINFALL'
5922  idx = idx + 1
5923  maxlist = this%nlakes
5924  naux = 0
5925  call this%budobj%budterm(idx)%initialize(text, &
5926  this%name_model, &
5927  this%packName, &
5928  this%name_model, &
5929  this%packName, &
5930  maxlist, .false., .false., &
5931  naux)
5932  !
5933  ! --
5934  text = ' EVAPORATION'
5935  idx = idx + 1
5936  maxlist = this%nlakes
5937  naux = 0
5938  call this%budobj%budterm(idx)%initialize(text, &
5939  this%name_model, &
5940  this%packName, &
5941  this%name_model, &
5942  this%packName, &
5943  maxlist, .false., .false., &
5944  naux)
5945  !
5946  ! --
5947  text = ' RUNOFF'
5948  idx = idx + 1
5949  maxlist = this%nlakes
5950  naux = 0
5951  call this%budobj%budterm(idx)%initialize(text, &
5952  this%name_model, &
5953  this%packName, &
5954  this%name_model, &
5955  this%packName, &
5956  maxlist, .false., .false., &
5957  naux)
5958  !
5959  ! --
5960  text = ' EXT-INFLOW'
5961  idx = idx + 1
5962  maxlist = this%nlakes
5963  naux = 0
5964  call this%budobj%budterm(idx)%initialize(text, &
5965  this%name_model, &
5966  this%packName, &
5967  this%name_model, &
5968  this%packName, &
5969  maxlist, .false., .false., &
5970  naux)
5971  !
5972  ! --
5973  text = ' WITHDRAWAL'
5974  idx = idx + 1
5975  maxlist = this%nlakes
5976  naux = 0
5977  call this%budobj%budterm(idx)%initialize(text, &
5978  this%name_model, &
5979  this%packName, &
5980  this%name_model, &
5981  this%packName, &
5982  maxlist, .false., .false., &
5983  naux)
5984  !
5985  ! --
5986  text = ' EXT-OUTFLOW'
5987  idx = idx + 1
5988  maxlist = this%nlakes
5989  naux = 0
5990  call this%budobj%budterm(idx)%initialize(text, &
5991  this%name_model, &
5992  this%packName, &
5993  this%name_model, &
5994  this%packName, &
5995  maxlist, .false., .false., &
5996  naux)
5997  !
5998  ! --
5999  text = ' STORAGE'
6000  idx = idx + 1
6001  maxlist = this%nlakes
6002  naux = 1
6003  auxtxt(1) = ' VOLUME'
6004  call this%budobj%budterm(idx)%initialize(text, &
6005  this%name_model, &
6006  this%packName, &
6007  this%name_model, &
6008  this%packName, &
6009  maxlist, .false., .false., &
6010  naux, auxtxt)
6011  !
6012  ! --
6013  text = ' CONSTANT'
6014  idx = idx + 1
6015  maxlist = this%nlakes
6016  naux = 0
6017  call this%budobj%budterm(idx)%initialize(text, &
6018  this%name_model, &
6019  this%packName, &
6020  this%name_model, &
6021  this%packName, &
6022  maxlist, .false., .false., &
6023  naux)
6024  !
6025  ! --
6026  if (this%imover == 1) then
6027  !
6028  ! --
6029  text = ' FROM-MVR'
6030  idx = idx + 1
6031  maxlist = this%nlakes
6032  naux = 0
6033  call this%budobj%budterm(idx)%initialize(text, &
6034  this%name_model, &
6035  this%packName, &
6036  this%name_model, &
6037  this%packName, &
6038  maxlist, .false., .false., &
6039  naux)
6040  !
6041  ! --
6042  text = ' TO-MVR'
6043  idx = idx + 1
6044  maxlist = this%noutlets
6045  naux = 0
6046  call this%budobj%budterm(idx)%initialize(text, &
6047  this%name_model, &
6048  this%packName, &
6049  this%name_model, &
6050  this%packName, &
6051  maxlist, .false., .false., &
6052  naux, ordered_id1=.false.)
6053  !
6054  ! -- store to-mvr connection information
6055  call this%budobj%budterm(idx)%reset(this%noutlets)
6056  q = dzero
6057  do n = 1, this%noutlets
6058  n1 = this%lakein(n)
6059  call this%budobj%budterm(idx)%update_term(n1, n1, q)
6060  end do
6061  end if
6062  !
6063  ! --
6064  naux = this%naux
6065  if (naux > 0) then
6066  !
6067  ! --
6068  text = ' AUXILIARY'
6069  idx = idx + 1
6070  maxlist = this%nlakes
6071  call this%budobj%budterm(idx)%initialize(text, &
6072  this%name_model, &
6073  this%packName, &
6074  this%name_model, &
6075  this%packName, &
6076  maxlist, .false., .false., &
6077  naux, this%auxname)
6078  end if
6079  !
6080  ! -- if lake flow for each reach are written to the listing file
6081  if (this%iprflow /= 0) then
6082  call this%budobj%flowtable_df(this%iout)
6083  end if
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:37
Here is the call graph for this function:

◆ lak_setup_tableobj()

subroutine lakmodule::lak_setup_tableobj ( class(laktype)  this)
private

The terms listed here must correspond in number and order to the ones written to the stage table in the lak_ot method

Definition at line 6276 of file gwf-lak.f90.

6277  ! -- modules
6279  ! -- dummy
6280  class(LakType) :: this
6281  ! -- local
6282  integer(I4B) :: nterms
6283  character(len=LINELENGTH) :: title
6284  character(len=LINELENGTH) :: text
6285  !
6286  ! -- setup stage table
6287  if (this%iprhed > 0) then
6288  !
6289  ! -- Determine the number of lake stage terms. These are fixed for
6290  ! the simulation and cannot change. This includes FLOW-JA-FACE
6291  ! so they can be written to the binary budget files, but these internal
6292  ! flows are not included as part of the budget table.
6293  nterms = 5
6294  if (this%inamedbound == 1) then
6295  nterms = nterms + 1
6296  end if
6297  !
6298  ! -- set up table title
6299  title = trim(adjustl(this%text))//' PACKAGE ('// &
6300  trim(adjustl(this%packName))//') STAGES FOR EACH CONTROL VOLUME'
6301  !
6302  ! -- set up stage tableobj
6303  call table_cr(this%stagetab, this%packName, title)
6304  call this%stagetab%table_df(this%nlakes, nterms, this%iout, &
6305  transient=.true.)
6306  !
6307  ! -- Go through and set up table budget term
6308  if (this%inamedbound == 1) then
6309  text = 'NAME'
6310  call this%stagetab%initialize_column(text, 20, alignment=tableft)
6311  end if
6312  !
6313  ! -- lake number
6314  text = 'NUMBER'
6315  call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
6316  !
6317  ! -- lake stage
6318  text = 'STAGE'
6319  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6320  !
6321  ! -- lake surface area
6322  text = 'SURFACE AREA'
6323  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6324  !
6325  ! -- lake wetted area
6326  text = 'WETTED AREA'
6327  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6328  !
6329  ! -- lake volume
6330  text = 'VOLUME'
6331  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6332  end if
Here is the call graph for this function:

◆ lak_solve()

subroutine lakmodule::lak_solve ( class(laktype), intent(inout)  this,
logical(lgp), intent(in), optional  update,
logical(lgp), intent(in), optional  only_legacy 
)
private

Solve the lake stage by substitution. With only_legacy set, solve only the lakes flagged for the legacy solver (thisilegacy /= 0) and leave the remaining lakes – whose stage is solved in the global matrix by the IMPLICIT formulation – untouched. Without it (the default), every active lake is solved.

Definition at line 5185 of file gwf-lak.f90.

5186  ! -- modules
5187  use tdismodule, only: delt
5188  ! -- dummy
5189  class(LakType), intent(inout) :: this
5190  logical(LGP), intent(in), optional :: update
5191  logical(LGP), intent(in), optional :: only_legacy
5192  ! -- local
5193  logical(LGP) :: lupdate
5194  logical(LGP) :: legonly
5195  integer(I4B) :: j
5196  integer(I4B) :: n
5197  integer(I4B) :: iicnvg
5198  integer(I4B) :: iter
5199  integer(I4B) :: maxiter
5200  integer(I4B) :: ncnv
5201  real(DP) :: hlak
5202  real(DP) :: hlak0
5203  real(DP) :: v0
5204  real(DP) :: v1
5205  real(DP) :: ro
5206  real(DP) :: qinf
5207  real(DP) :: ex
5208  real(DP) :: outinf
5209  real(DP) :: avail
5210  !
5211  ! -- set lupdate
5212  if (present(update)) then
5213  lupdate = update
5214  else
5215  lupdate = .true.
5216  end if
5217  !
5218  ! -- set legonly (solve only the lakes flagged for the legacy solver)
5219  if (present(only_legacy)) then
5220  legonly = only_legacy
5221  else
5222  legonly = .false.
5223  end if
5224  !
5225  ! -- initialize
5226  avail = dzero
5227  !
5228  ! -- initialize
5229  do n = 1, this%nlakes
5230  ! -- a lake not being solved on this call (an IMPLICIT lake when only the
5231  ! flagged lakes are solved) is treated as already converged and left
5232  ! untouched
5233  if (legonly .and. this%ilegacy(n) == 0) then
5234  this%ncncvr(n) = 1
5235  cycle
5236  end if
5237  this%ncncvr(n) = 0
5238  this%surfin(n) = dzero
5239  this%surfout(n) = dzero
5240  this%surfout1(n) = dzero
5241  if (this%xnewpak(n) < this%lakebot(n)) then
5242  this%xnewpak(n) = this%lakebot(n)
5243  end if
5244  if (this%gwfiss /= 0) then
5245  this%xoldpak(n) = this%xnewpak(n)
5246  end if
5247  ! -- lake iteration items
5248  this%iseepc(n) = 0
5249  this%idhc(n) = 0
5250  this%en1(n) = this%lakebot(n)
5251  call this%lak_calculate_residual(n, this%en1(n), this%r1(n))
5252  this%en2(n) = this%laketop(n)
5253  call this%lak_calculate_residual(n, this%en2(n), this%r2(n))
5254  end do
5255  ! -- a legacy-only solve keeps the outlet rates of the implicit lakes,
5256  ! which are final and still needed for the mover and downstream lakes
5257  do n = 1, this%noutlets
5258  if (legonly .and. this%ilegacy(this%lakein(n)) == 0) cycle
5259  this%simoutrate(n) = dzero
5260  end do
5261  !
5262  ! -- sum up inflows from mover inflows
5263  do n = 1, this%nlakes
5264  call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5265  end do
5266  !
5267  ! -- sum up overland runoff, inflows, and external flows into lake
5268  ! (includes maximum lake volume)
5269  do n = 1, this%nlakes
5270  hlak0 = this%xoldpak(n)
5271  hlak = this%xnewpak(n)
5272  call this%lak_calculate_runoff(n, ro)
5273  call this%lak_calculate_inflow(n, qinf)
5274  call this%lak_calculate_external(n, ex)
5275  call this%lak_calculate_vol(n, hlak0, v0)
5276  call this%lak_calculate_vol(n, hlak, v1)
5277  this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5278  max(v0, v1) / delt
5279  end do
5280  !
5281  ! -- sum up inflows from upstream outlets
5282  do n = 1, this%nlakes
5283  call this%lak_calculate_outlet_inflow(n, outinf)
5284  this%flwin(n) = this%flwin(n) + outinf
5285  end do
5286  !
5287  iicnvg = 0
5288  maxiter = this%maxlakit
5289  !
5290  ! -- outer loop
5291  converge: do iter = 1, maxiter
5292  ncnv = 0
5293  do n = 1, this%nlakes
5294  if (this%ncncvr(n) == 0) ncnv = 1
5295  end do
5296  if (iter == maxiter) ncnv = 0
5297  if (ncnv == 0) iicnvg = 1
5298  !
5299  ! -- initialize variables
5300  do n = 1, this%nlakes
5301  this%evap(n) = dzero
5302  this%precip(n) = dzero
5303  this%precip1(n) = dzero
5304  this%seep(n) = dzero
5305  this%seep1(n) = dzero
5306  this%evap(n) = dzero
5307  this%evap1(n) = dzero
5308  this%evapo(n) = dzero
5309  this%withr(n) = dzero
5310  this%withr1(n) = dzero
5311  this%flwiter(n) = this%flwin(n)
5312  this%flwiter1(n) = this%flwin(n)
5313  if (this%gwfiss /= 0) then
5314  this%flwiter(n) = dep20
5315  this%flwiter1(n) = dep20
5316  end if
5317  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5318  this%hcof(j) = dzero
5319  this%rhs(j) = dzero
5320  end do
5321  end do
5322  !
5323  do n = 1, this%nlakes
5324  if (legonly .and. this%ilegacy(n) == 0) cycle
5325  call this%lak_estimate_seepage_single(n, ncnv)
5326  end do
5327  !
5328  laklevel: do n = 1, this%nlakes
5329  if (legonly .and. this%ilegacy(n) == 0) cycle laklevel
5330  call this%lak_solve_single(n, iter, maxiter, ncnv, lupdate)
5331  end do laklevel
5332  !
5333  if (iicnvg == 1) exit converge
5334  !
5335  end do converge
5336  !
5337  ! -- Mover terms: store outflow after diversion loss
5338  ! as qformvr and reduce outflow (qd)
5339  ! by how much was actually sent to the mover. A legacy-only solve
5340  ! skips this because the implicit formulation accumulates the mover
5341  ! terms for every outlet once the legacy-solved stages are known.
5342  if (this%imover == 1 .and. .not. legonly) then
5343  do n = 1, this%noutlets
5344  call this%pakmvrobj%accumulate_qformvr(n, -this%simoutrate(n))
5345  end do
5346  end if

◆ lak_solve_single()

subroutine lakmodule::lak_solve_single ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  n,
integer(i4b), intent(in)  iter,
integer(i4b), intent(in)  maxiter,
integer(i4b), intent(in)  ncnv,
logical(lgp), intent(in)  lupdate 
)

Performs one Newton update (with a bisection backup) of lake n's stage in the default substitution solver, using the per-iteration seepage estimate (thisseep / thisseep1) already computed for the lake. Extracted from lak_solve so the same per-lake update can be reused to solve a single lake stage on its own – the per-lake legacy solve for the IMPLICIT formulation.

Definition at line 5357 of file gwf-lak.f90.

5358  ! -- modules
5359  use tdismodule, only: delt
5360  ! -- dummy
5361  class(LakType), intent(inout) :: this
5362  integer(I4B), intent(in) :: n
5363  integer(I4B), intent(in) :: iter
5364  integer(I4B), intent(in) :: maxiter
5365  integer(I4B), intent(in) :: ncnv
5366  logical(LGP), intent(in) :: lupdate
5367  ! -- local
5368  integer(I4B) :: ibflg
5369  integer(I4B) :: idhp
5370  real(DP) :: hlak
5371  real(DP) :: hlak0
5372  real(DP) :: ra
5373  real(DP) :: ro
5374  real(DP) :: qinf
5375  real(DP) :: ex
5376  real(DP) :: ev
5377  real(DP) :: wr
5378  real(DP) :: resid
5379  real(DP) :: resid1
5380  real(DP) :: residb
5381  real(DP) :: derv
5382  real(DP) :: dh
5383  real(DP) :: ts
5384  real(DP) :: adh
5385  real(DP) :: adh0
5386  real(DP) :: v0
5387  real(DP) :: v1
5388  real(DP) :: area
5389  real(DP) :: qtolfact
5390  real(DP) :: delh
5391  !
5392  delh = this%delh
5393  !
5394  ! -- skip inactive lakes
5395  if (this%iboundpak(n) == 0) then
5396  this%ncncvr(n) = 1
5397  return
5398  end if
5399  ibflg = 0
5400  hlak = this%xnewpak(n)
5401  if (iter < maxiter) then
5402  this%stageiter(n) = this%xnewpak(n)
5403  end if
5404  call this%lak_calculate_rainfall(n, hlak, ra)
5405  this%precip(n) = ra
5406  this%flwiter(n) = this%flwiter(n) + ra
5407  call this%lak_calculate_rainfall(n, hlak + delh, ra)
5408  this%precip1(n) = ra
5409  this%flwiter1(n) = this%flwiter1(n) + ra
5410  !
5411  ! -- limit withdrawals to lake inflows and lake storage
5412  call this%lak_calculate_withdrawal(n, this%flwiter(n), wr)
5413  this%withr(n) = wr
5414  call this%lak_calculate_withdrawal(n, this%flwiter1(n), wr)
5415  this%withr1(n) = wr
5416  !
5417  ! -- limit evaporation to lake inflows and lake storage
5418  call this%lak_calculate_evaporation(n, hlak, this%flwiter(n), ev)
5419  this%evap(n) = ev
5420  call this%lak_calculate_evaporation(n, hlak + delh, this%flwiter1(n), ev)
5421  this%evap1(n) = ev
5422  !
5423  ! -- no outlet flow if evaporation consumes all water
5424  call this%lak_calculate_outlet_outflow(n, hlak + delh, &
5425  this%flwiter1(n), &
5426  this%surfout1(n))
5427  call this%lak_calculate_outlet_outflow(n, hlak, this%flwiter(n), &
5428  this%surfout(n))
5429  !
5430  ! -- update the surface inflow values
5431  call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5432  !
5433  !
5434  if (ncnv == 1) then
5435  if (this%iboundpak(n) > 0 .and. lupdate .eqv. .true.) then
5436  !
5437  ! -- recalculate flwin
5438  hlak0 = this%xoldpak(n)
5439  hlak = this%xnewpak(n)
5440  call this%lak_calculate_vol(n, hlak0, v0)
5441  call this%lak_calculate_vol(n, hlak, v1)
5442  call this%lak_calculate_runoff(n, ro)
5443  call this%lak_calculate_inflow(n, qinf)
5444  call this%lak_calculate_external(n, ex)
5445  this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5446  max(v0, v1) / delt
5447  !
5448  ! -- compute new lake stage using Newton's method
5449  resid = this%precip(n) + this%evap(n) + this%withr(n) + ro + &
5450  qinf + ex + this%surfin(n) + &
5451  this%surfout(n) + this%seep(n)
5452  resid1 = this%precip1(n) + this%evap1(n) + this%withr1(n) + ro + &
5453  qinf + ex + this%surfin(n) + &
5454  this%surfout1(n) + this%seep1(n)
5455  !
5456  ! -- add storage changes for transient stress periods
5457  hlak = this%xnewpak(n)
5458  if (this%gwfiss /= 1) then
5459  call this%lak_calculate_vol(n, hlak, v1)
5460  resid = resid + (v0 - v1) / delt
5461  call this%lak_calculate_vol(n, hlak + delh, v1)
5462  resid1 = resid1 + (v0 - v1) / delt
5463  end if
5464  !
5465  ! -- determine the derivative and the stage change
5466  if (abs(resid1 - resid) > dzero) then
5467  derv = (resid1 - resid) / delh
5468  dh = dzero
5469  if (abs(derv) > dprec) then
5470  dh = resid / derv
5471  end if
5472  else
5473  if (resid < dzero) then
5474  resid = dzero
5475  end if
5476  call this%lak_vol2stage(n, resid, dh)
5477  dh = hlak - dh
5478  this%ncncvr(n) = 1
5479  end if
5480  !
5481  ! -- determine if the updated stage is outside the endpoints
5482  ts = hlak - dh
5483  if (iter == 1) this%dh0(n) = dh
5484  adh = abs(dh)
5485  adh0 = abs(this%dh0(n))
5486  if ((ts >= this%en2(n)) .or. (ts < this%en1(n))) then
5487  ! -- use bisection if dh is increasing or updated stage is below the
5488  ! bottom of the lake
5489  if ((adh > adh0) .or. (ts - this%lakebot(n)) < dprec) then
5490  residb = resid
5491  call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5492  end if
5493  end if
5494  !
5495  ! -- set seep0 on the first lake iteration
5496  if (iter == 1) then
5497  this%seep0(n) = this%seep(n)
5498  end if
5499  !
5500  ! -- check for slow convergence
5501  if (this%seep(n) * this%seep0(n) < dprec) then
5502  this%iseepc(n) = this%iseepc(n) + 1
5503  else
5504  this%iseepc(n) = 0
5505  end if
5506  ! -- determine of convergence is slow and oscillating
5507  idhp = 0
5508  if (dh * this%dh0(n) < dprec) idhp = 1
5509  ! -- determine if stage change is increasing
5510  adh = abs(dh)
5511  if (adh > adh0) idhp = 1
5512  ! -- increment idhc convergence flag
5513  if (idhp == 1) then
5514  this%idhc(n) = this%idhc(n) + 1
5515  end if
5516  !
5517  ! -- switch to bisection when the Newton-Raphson method oscillates
5518  ! or when convergence is slow
5519  if (ibflg == 1) then
5520  if (this%iseepc(n) > 7 .or. this%idhc(n) > 12) then
5521  call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5522  end if
5523  end if
5524  else
5525  dh = dzero
5526  end if
5527  !
5528  ! -- update lake stage
5529  hlak = hlak - dh
5530  if (hlak < this%lakebot(n)) then
5531  hlak = this%lakebot(n)
5532  end if
5533  !
5534  ! -- calculate surface area
5535  call this%lak_calculate_sarea(n, hlak, area)
5536  !
5537  ! -- set the Q to length factor
5538  if (area > dzero) then
5539  qtolfact = delt / area
5540  else
5541  qtolfact = dzero
5542  end if
5543  !
5544  ! -- recalculate the residual
5545  call this%lak_calculate_residual(n, hlak, resid)
5546  !
5547  ! -- evaluate convergence
5548  !if (ABS(dh) < delh) then
5549  if (abs(dh) < delh .and. abs(resid) * qtolfact < this%dmaxchg) then
5550  this%ncncvr(n) = 1
5551  end if
5552  this%xnewpak(n) = hlak
5553  !
5554  ! -- save iterates for lake
5555  this%seep0(n) = this%seep(n)
5556  this%dh0(n) = dh
5557  end if

◆ lak_source_connectiondata()

subroutine lakmodule::lak_source_connectiondata ( class(laktype), intent(inout)  this)
private

Definition at line 776 of file gwf-lak.f90.

777  ! -- dummy
778  class(LakType), intent(inout) :: this
779  ! -- local
780  integer(I4B) :: n, j, ipos, nn
781  integer(I4B) :: ilak, iconn
782  integer(I4B) :: ipos0, icellid0, icellid, nn2
783  logical(LGP) :: is_lake_bed
784  character(len=LINELENGTH) :: cellid_str
785  character(len=LINELENGTH) :: ctypenm
786  character(len=LINELENGTH) :: cbleak
787  real(DP) :: top, bot, rval
788  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
789  integer(I4B), dimension(:), pointer, contiguous :: iconns => null()
790  integer(I4B), dimension(:, :), pointer, contiguous :: cellid => null()
791  type(CharacterStringType), dimension(:), pointer, contiguous :: &
792  claktype => null()
793  type(CharacterStringType), dimension(:), pointer, contiguous :: &
794  bedleak => null()
795  real(DP), dimension(:), pointer, contiguous :: belev => null()
796  real(DP), dimension(:), pointer, contiguous :: telev => null()
797  real(DP), dimension(:), pointer, contiguous :: connlen => null()
798  real(DP), dimension(:), pointer, contiguous :: connwidth => null()
799  integer(I4B), allocatable :: nboundchk(:)
800  !
801  ! -- allocate connection data arrays
802  call mem_allocate(this%imap, this%MAXBOUND, 'IMAP', this%memoryPath)
803  call mem_allocate(this%gwfconn, this%MAXBOUND, 'GWFCONN', this%memoryPath)
804  call mem_allocate(this%nodesontop, this%MAXBOUND, 'NODESONTOP', &
805  this%memoryPath)
806  call mem_allocate(this%ictype, this%MAXBOUND, 'ICTYPE', this%memoryPath)
807  call mem_allocate(this%bedleak, this%MAXBOUND, 'BEDLEAK', this%memoryPath)
808  call mem_allocate(this%belev, this%MAXBOUND, 'BELEV', this%memoryPath)
809  call mem_allocate(this%telev, this%MAXBOUND, 'TELEV', this%memoryPath)
810  call mem_allocate(this%connlength, this%MAXBOUND, 'CONNLENGTH', &
811  this%memoryPath)
812  call mem_allocate(this%connwidth, this%MAXBOUND, 'CONNWIDTH', &
813  this%memoryPath)
814  call mem_allocate(this%sarea, this%MAXBOUND, 'SAREA', this%memoryPath)
815  call mem_allocate(this%warea, this%MAXBOUND, 'WAREA', this%memoryPath)
816  call mem_allocate(this%satcond, this%MAXBOUND, 'SATCOND', this%memoryPath)
817  call mem_allocate(this%simcond, this%MAXBOUND, 'SIMCOND', this%memoryPath)
818  call mem_allocate(this%simlakgw, this%MAXBOUND, 'SIMLAKGW', this%memoryPath)
819  !
820  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
821  ' CONNECTIONDATA'
822  !
823  ! -- get input context CONNECTIONDATA column arrays
824  call mem_setptr(ifno, 'CONNDATA_IFNO', this%input_mempath)
825  call mem_setptr(iconns, 'ICONN', this%input_mempath)
826  call mem_setptr(cellid, 'CELLID', this%input_mempath)
827  call mem_setptr(claktype, 'CLAKTYPE', this%input_mempath)
828  call mem_setptr(bedleak, 'BEDLEAK', this%input_mempath)
829  call mem_setptr(belev, 'BELEV', this%input_mempath)
830  call mem_setptr(telev, 'TELEV', this%input_mempath)
831  call mem_setptr(connlen, 'CONNLEN', this%input_mempath)
832  call mem_setptr(connwidth, 'CONNWIDTH', this%input_mempath)
833  !
834  ! -- allocate check array
835  allocate (nboundchk(this%MAXBOUND))
836  nboundchk = 0
837  !
838  do n = 1, this%MAXBOUND
839  !
840  ilak = ifno(n)
841  iconn = iconns(n)
842  !
843  if (ilak < 1 .or. ilak > this%nlakes) then
844  write (errmsg, '(a,1x,i0)') 'lakeno MUST BE > 0 and <= ', this%nlakes
845  call store_error(errmsg)
846  cycle
847  end if
848  if (iconn < 1 .or. iconn > this%nlakeconn(ilak)) then
849  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
850  'iconn FOR LAKE ', ilak, 'MUST BE > 0 and <= ', this%nlakeconn(ilak)
851  call store_error(errmsg)
852  cycle
853  end if
854  !
855  ipos = this%idxlakeconn(ilak) + iconn - 1
856  this%imap(ipos) = ilak
857  nboundchk(ipos) = nboundchk(ipos) + 1
858  !
859  ! -- convert cellid integer array to string and resolve to a node number.
860  write (cellid_str, '(10(i0,1x))') cellid(1:this%dis%ndim, n)
861  nn = this%dis%noder_from_cellid(cellid_str, this%inunit, this%iout)
862  if (nn < 1) then
863  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
864  'INVALID cellid FOR LAKE ', ilak, 'connection', iconn
865  call store_error(errmsg)
866  end if
867  this%gwfconn(ipos) = nn
868  this%nodesontop(ipos) = nn
869  !
870  ! -- connection type
871  ctypenm = claktype(n)
872  select case (trim(ctypenm))
873  case ('VERTICAL')
874  this%ictype(ipos) = 0
875  case ('HORIZONTAL')
876  this%ictype(ipos) = 1
877  case ('EMBEDDEDH')
878  this%ictype(ipos) = 2
879  case ('EMBEDDEDV')
880  this%ictype(ipos) = 3
881  case default
882  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,a,a)') &
883  'UNKNOWN ctype FOR LAKE ', ilak, 'connection', iconn, &
884  '(', trim(ctypenm), ')'
885  call store_error(errmsg)
886  end select
887  !
888  ! -- bed leakance
889  cbleak = bedleak(n)
890  select case (trim(cbleak))
891  case ('NONE')
892  is_lake_bed = .false.
893  rval = dnodata
894  write (warnmsg, '(2(a,1x,i0,1x),a,1pe8.1,a)') &
895  'BEDLEAK for connection', iconn, 'in lake', ilak, &
896  'is specified to be NONE. Lake connections where the lake-GWF '// &
897  'connection conductance is solely a function of aquifer '// &
898  'properties in the connected GWF cell should be specified '// &
899  'with a DNODATA (', dnodata, ') value.'
900  call deprecation_warning('CONNECTIONDATA', 'bedleak=NONE', '6.4.3', &
901  warnmsg, this%inunit)
902  case default
903  read (cbleak, *) rval
904  if (is_close(rval, dnodata)) then
905  is_lake_bed = .false.
906  else
907  is_lake_bed = .true.
908  end if
909  end select
910  this%bedleak(ipos) = rval
911  if (is_lake_bed .and. this%bedleak(ipos) < dzero) then
912  write (errmsg, '(a,1x,i0,1x,a)') 'bedleak FOR LAKE ', ilak, &
913  'MUST BE >= 0'
914  call store_error(errmsg)
915  end if
916  !
917  ! -- belev
918  this%belev(ipos) = belev(n)
919  !
920  ! -- telev
921  this%telev(ipos) = telev(n)
922  !
923  ! -- connection length
924  rval = connlen(n)
925  if (rval <= dzero) then
926  if (this%ictype(ipos) == 1 .or. this%ictype(ipos) == 2 .or. &
927  this%ictype(ipos) == 3) then
928  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,a,1x,a)') &
929  'connection length (connlen) FOR LAKE ', ilak, &
930  ', CONNECTION NO.', iconn, ', MUST BE > 0 FOR SPECIFIED ', &
931  'connection type (ctype)', trim(ctypenm)
932  call store_error(errmsg)
933  else
934  rval = dzero
935  end if
936  end if
937  this%connlength(ipos) = rval
938  !
939  ! -- connection width
940  rval = connwidth(n)
941  if (rval < dzero) then
942  if (this%ictype(ipos) == 1) then
943  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
944  'cell width (connwidth) FOR LAKE ', ilak, &
945  ' HORIZONTAL CONNECTION ', iconn, 'MUST BE >= 0'
946  call store_error(errmsg)
947  else
948  rval = dzero
949  end if
950  end if
951  this%connwidth(ipos) = rval
952  end do
953  !
954  write (this%iout, '(1x,a)') &
955  'END OF '//trim(adjustl(this%text))//' CONNECTIONDATA'
956  !
957  ! -- terminate if any errors were detected
958  if (count_errors() > 0) then
959  call store_error_filename(this%input_fname)
960  end if
961  !
962  ! -- check that embedded lakes have only one connection
963  do n = 1, this%nlakes
964  j = 0
965  do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
966  if (this%ictype(ipos) /= 2 .and. this%ictype(ipos) /= 3) cycle
967  j = j + 1
968  if (j > 1) then
969  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
970  'nlakeconn FOR LAKE', n, 'EMBEDDED CONNECTION', j, ' EXCEEDS 1.'
971  call store_error(errmsg)
972  end if
973  end do
974  end do
975  ! -- check that an embedded lake is not in the same cell as a lake
976  ! with a vertical connection
977  do n = 1, this%nlakes
978  ipos0 = this%idxlakeconn(n)
979  icellid0 = this%gwfconn(ipos0)
980  if (this%ictype(ipos0) /= 2 .and. this%ictype(ipos0) /= 3) cycle
981  do nn2 = 1, this%nlakes
982  if (nn2 == n) cycle
983  j = 0
984  do ipos = this%idxlakeconn(nn2), this%idxlakeconn(nn2 + 1) - 1
985  j = j + 1
986  icellid = this%gwfconn(ipos)
987  if (icellid == icellid0) then
988  if (this%ictype(ipos) == 0) then
989  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
990  'EMBEDDED LAKE', n, &
991  'CANNOT COINCIDE WITH VERTICAL CONNECTION', j, &
992  'IN LAKE', nn2, '.'
993  call store_error(errmsg)
994  end if
995  end if
996  end do
997  end do
998  end do
999  !
1000  ! -- process the data (post-processing: telev/belev/laketop/lakebot)
1001  do n = 1, this%nlakes
1002  j = 0
1003  do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1004  j = j + 1
1005  nn = this%gwfconn(ipos)
1006  top = this%dis%top(nn)
1007  bot = this%dis%bot(nn)
1008  if (this%ictype(ipos) == 0) then
1009  this%telev(ipos) = top + this%surfdep
1010  this%belev(ipos) = top
1011  this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1012  else if (this%ictype(ipos) == 1) then
1013  if (this%belev(ipos) == this%telev(ipos)) then
1014  this%telev(ipos) = top
1015  this%belev(ipos) = bot
1016  else
1017  if (this%belev(ipos) >= this%telev(ipos)) then
1018  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1019  'telev FOR LAKE ', n, ' HORIZONTAL CONNECTION ', j, &
1020  'MUST BE >= belev'
1021  call store_error(errmsg)
1022  else if (this%belev(ipos) < bot) then
1023  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1024  'belev FOR LAKE ', n, ' HORIZONTAL CONNECTION ', j, &
1025  'MUST BE >= cell bottom (', bot, ')'
1026  call store_error(errmsg)
1027  else if (this%telev(ipos) > top) then
1028  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1029  'telev FOR LAKE ', n, ' HORIZONTAL CONNECTION ', j, &
1030  'MUST BE <= cell top (', top, ')'
1031  call store_error(errmsg)
1032  end if
1033  end if
1034  this%laketop(n) = max(this%telev(ipos), this%laketop(n))
1035  this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1036  else if (this%ictype(ipos) == 2 .or. this%ictype(ipos) == 3) then
1037  this%telev(ipos) = top
1038  this%belev(ipos) = bot
1039  this%lakebot(n) = bot
1040  end if
1041  !
1042  ! -- check for missing or duplicate connections
1043  if (nboundchk(ipos) == 0) then
1044  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1045  'NO DATA SPECIFIED FOR LAKE', n, 'CONNECTION', j
1046  call store_error(errmsg)
1047  else if (nboundchk(ipos) > 1) then
1048  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1049  'DATA FOR LAKE', n, 'CONNECTION', j, &
1050  'SPECIFIED', nboundchk(ipos), 'TIMES'
1051  call store_error(errmsg)
1052  end if
1053  end do
1054  if (this%laketop(n) == -dep20) then
1055  this%laketop(n) = this%lakebot(n) + 100.
1056  end if
1057  end do
1058  !
1059  deallocate (nboundchk)
1060  !
1061  if (count_errors() > 0) then
1062  call store_error_filename(this%input_fname)
1063  end if
1064  !
1065  ! -- release input context connectiondata memory
1066  call memorystore_release('CONNDATA_IFNO', this%input_mempath)
1067  call memorystore_release('ICONN', this%input_mempath)
1068  call memorystore_release('CELLID', this%input_mempath)
1069  call memorystore_release('CLAKTYPE', this%input_mempath)
1070  call memorystore_release('BEDLEAK', this%input_mempath)
1071  call memorystore_release('BELEV', this%input_mempath)
1072  call memorystore_release('TELEV', this%input_mempath)
1073  call memorystore_release('CONNLEN', this%input_mempath)
1074  call memorystore_release('CONNWIDTH', this%input_mempath)
Here is the call graph for this function:

◆ lak_source_dimensions()

subroutine lakmodule::lak_source_dimensions ( class(laktype), intent(inout)  this)
private

Definition at line 1504 of file gwf-lak.f90.

1505  ! -- dummy
1506  class(LakType), intent(inout) :: this
1507  ! -- local
1508  type(GwfLakParamFoundType) :: found
1509  !
1510  ! -- initialize dimensions to -1
1511  this%nlakes = -1
1512  this%maxbound = -1
1513  !
1514  write (this%iout, '(/1x,a)') &
1515  'PROCESSING '//trim(adjustl(this%text))//' DIMENSIONS'
1516  !
1517  ! -- NLAKES (mf6internal: nlakes); kept in the input context (not
1518  ! released) since PERIOD settings resolve it by name via SHAPE
1519  call mem_set_value(this%nlakes, 'NLAKES', this%input_mempath, &
1520  found%nlakes, release=.false.)
1521  if (found%nlakes) write (this%iout, '(4x,a,i7)') 'NLAKES = ', this%nlakes
1522  !
1523  ! -- NOUTLETS (mf6internal: noutlets); kept in the input context (not
1524  ! released) since PERIOD settings resolve it by name via SHAPE
1525  call mem_set_value(this%noutlets, 'NOUTLETS', this%input_mempath, &
1526  found%noutlets, release=.false.)
1527  if (found%noutlets) write (this%iout, '(4x,a,i7)') &
1528  'NOUTLETS = ', this%noutlets
1529  !
1530  ! -- NTABLES (mf6internal: ntables)
1531  call mem_set_value(this%ntables, 'NTABLES', this%input_mempath, found%ntables)
1532  if (found%ntables) write (this%iout, '(4x,a,i7)') 'NTABLES = ', this%ntables
1533  !
1534  write (this%iout, '(1x,a)') &
1535  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
1536  !
1537  if (this%nlakes < 0) then
1538  write (errmsg, '(a)') &
1539  'NLAKES WAS NOT SPECIFIED OR WAS SPECIFIED INCORRECTLY.'
1540  call store_error(errmsg)
1541  call store_error_filename(this%input_fname)
1542  return
1543  end if
1544  !
1545  if (this%iforceleglak /= 0) then
1546  if (this%iforceleglak < 1 .or. this%iforceleglak > this%nlakes) then
1547  write (errmsg, '(a,i0,a,i0,a)') &
1548  'DEV_FORCE_LEGACY_LAKE (', this%iforceleglak, &
1549  ') MUST BE BETWEEN 1 AND NLAKES (', this%nlakes, ').'
1550  call store_error(errmsg)
1551  call store_error_filename(this%input_fname)
1552  return
1553  end if
1554  end if
1555  !
1556  ! -- read PACKAGEDATA
1557  call this%lak_source_packagedata()
1558  !
1559  ! -- for the implicit formulation each lake adds one equation (one row and
1560  ! column) to the groundwater flow matrix
1561  if (this%iimplicit /= 0) then
1562  this%npakeq = this%nlakes
1563  ! -- the implicit lake-aquifer coupling is asymmetric for perched
1564  ! connections, so flag the coefficient matrix as asymmetric (which
1565  ! requires the BICGSTAB linear acceleration). Only raise the flag; never
1566  ! clear an asymmetry already indicated elsewhere.
1567  this%iasym = 1
1568  end if
1569  !
1570  ! -- read CONNECTIONDATA
1571  call this%lak_source_connectiondata()
1572  !
1573  ! -- read TABLES
1574  call this%lak_source_tables()
1575  !
1576  ! -- read OUTLETS
1577  call this%lak_source_outlets()
1578  !
1579  ! -- Call define_listlabel
1580  call this%define_listlabel()
1581  !
1582  ! -- setup the budget object
1583  call this%lak_setup_budobj()
1584  !
1585  ! -- setup the stage table object
1586  call this%lak_setup_tableobj()
Here is the call graph for this function:

◆ lak_source_options()

subroutine lakmodule::lak_source_options ( class(laktype), intent(inout)  this)

Definition at line 2898 of file gwf-lak.f90.

2899  ! -- dummy
2900  class(LakType), intent(inout) :: this
2901  ! -- local
2902  type(GwfLakParamFoundType) :: found
2903  integer(I4B) :: isize
2904  character(len=LINELENGTH) :: fname
2905  ! -- formats
2906  character(len=*), parameter :: fmtlengthconv = &
2907  &"(4x, 'LENGTH CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2908  character(len=*), parameter :: fmttimeconv = &
2909  &"(4x, 'TIME CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2910  character(len=*), parameter :: fmtlakeopt = &
2911  &"(4x, 'LAKE ', a, ' VALUE (',g15.7,') SPECIFIED.')"
2912  character(len=*), parameter :: fmtoutdmax = &
2913  &"(4x, 'MAXIMUM OUTLET WATER DEPTH (',g15.7,') SPECIFIED.')"
2914  character(len=*), parameter :: fmtlakbin = &
2915  "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
2916  &a, /4x, 'OPENED ON UNIT: ', I0)"
2917  character(len=*), parameter :: fmtiter = &
2918  &"(4x, 'MAXIMUM LAK ITERATION VALUE (',i0,') SPECIFIED.')"
2919  character(len=*), parameter :: fmtdmaxchg = &
2920  &"(4x, 'MAXIMUM STAGE CHANGE VALUE (',g0,') SPECIFIED.')"
2921  !
2922  ! -- call base class to handle AUXILIARY/NAUX, BOUNDNAMES, PRINT_INPUT,
2923  ! PRINT_FLOWS, SAVE_FLOWS, OBS6_FILENAME
2924  call this%BndExtType%source_options()
2925  !
2926  write (this%iout, '(1x,a)') &
2927  'PROCESSING '//trim(adjustl(this%text))//' OPTIONS'
2928  !
2929  ! -- PRINT_STAGE
2930  call mem_set_value(this%iprhed, 'PRINT_STAGE', this%input_mempath, &
2931  found%print_stage)
2932  if (found%print_stage) then
2933  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
2934  ' STAGES WILL BE PRINTED TO LISTING FILE.'
2935  end if
2936  !
2937  ! -- STAGE FILEOUT
2938  call mem_set_value(fname, 'STAGEFILE', this%input_mempath, found%stagefile)
2939  if (found%stagefile) then
2940  this%istageout = getunit()
2941  call openfile(this%istageout, this%iout, fname, 'DATA(BINARY)', &
2942  form, access, 'REPLACE', mode_opt=mnormal)
2943  write (this%iout, fmtlakbin) 'STAGE', trim(adjustl(fname)), this%istageout
2944  end if
2945  !
2946  ! -- BUDGET FILEOUT
2947  call mem_set_value(fname, 'BUDGETFILE', this%input_mempath, found%budgetfile)
2948  if (found%budgetfile) then
2949  call assign_iounit(this%ibudgetout, this%inunit, 'BUDGET fileout')
2950  call openfile(this%ibudgetout, this%iout, fname, 'DATA(BINARY)', &
2951  form, access, 'REPLACE', mode_opt=mnormal)
2952  write (this%iout, fmtlakbin) 'BUDGET', trim(adjustl(fname)), this%ibudgetout
2953  end if
2954  !
2955  ! -- BUDGETCSV FILEOUT
2956  call mem_set_value(fname, 'BUDGETCSVFILE', this%input_mempath, &
2957  found%budgetcsvfile)
2958  if (found%budgetcsvfile) then
2959  call assign_iounit(this%ibudcsv, this%inunit, 'BUDGETCSV fileout')
2960  call openfile(this%ibudcsv, this%iout, fname, 'CSV', filstat_opt='REPLACE')
2961  write (this%iout, fmtlakbin) 'BUDGET CSV', trim(adjustl(fname)), &
2962  this%ibudcsv
2963  end if
2964  !
2965  ! -- PACKAGE_CONVERGENCE FILEOUT (mf6internal: pkgconvfname)
2966  ! -- defer opening until lak_ar, where the IMPLICIT option is known. The
2967  ! file is not opened for the implicit formulation (lak_cc does not
2968  ! write package convergence in that case).
2969  call mem_set_value(fname, 'PKGCONVFNAME', this%input_mempath, &
2970  found%pkgconvfname)
2971  if (found%pkgconvfname) then
2972  this%pakcsvfile = trim(adjustl(fname))
2973  end if
2974  !
2975  ! -- MOVER
2976  call mem_set_value(this%imover, 'MOVER', this%input_mempath, found%mover)
2977  if (found%mover) then
2978  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
2979  end if
2980  !
2981  ! -- LENGTH_CONVERSION (mf6internal: convlength)
2982  call mem_set_value(this%convlength, 'CONVLENGTH', this%input_mempath, &
2983  found%convlength)
2984  if (found%convlength) write (this%iout, fmtlengthconv) this%convlength
2985  !
2986  ! -- TIME_CONVERSION (mf6internal: convtime)
2987  call mem_set_value(this%convtime, 'CONVTIME', this%input_mempath, &
2988  found%convtime)
2989  if (found%convtime) write (this%iout, fmttimeconv) this%convtime
2990  !
2991  ! -- SURFDEP (mf6internal: surfdep)
2992  call mem_set_value(this%surfdep, 'SURFDEP', this%input_mempath, found%surfdep)
2993  if (found%surfdep) then
2994  if (this%surfdep < dzero) this%surfdep = dzero
2995  write (this%iout, fmtlakeopt) 'SURFDEP', this%surfdep
2996  end if
2997  !
2998  ! -- MAXIMUM_ITERATIONS (mf6internal: maxlakit)
2999  call mem_set_value(this%maxlakit, 'MAXLAKIT', this%input_mempath, &
3000  found%maxlakit)
3001  if (found%maxlakit) write (this%iout, fmtiter) this%maxlakit
3002  !
3003  ! -- MAXIMUM_STAGE_CHANGE (mf6internal: dmaxchg)
3004  call mem_set_value(this%dmaxchg, 'DMAXCHG', this%input_mempath, found%dmaxchg)
3005  if (found%dmaxchg) then
3006  this%delh = dp999 * this%dmaxchg
3007  write (this%iout, fmtdmaxchg) this%dmaxchg
3008  end if
3009  !
3010  ! -- DEV_GROUNDWATER_HEAD_CONDUCTANCE (mf6internal: igwhcopt)
3011  call mem_set_value(this%igwhcopt, 'IGWHCOPT', this%input_mempath, &
3012  found%igwhcopt)
3013  if (found%igwhcopt) then
3014  write (this%iout, '(4x,a)') &
3015  'CONDUCTANCE FOR HORIZONTAL CONNECTIONS WILL BE CALCULATED &
3016  &USING THE GROUNDWATER HEAD'
3017  end if
3018  !
3019  ! -- IMPLICIT (mf6internal: iimplicit)
3020  call mem_set_value(this%iimplicit, 'IIMPLICIT', this%input_mempath, &
3021  found%iimplicit)
3022  if (found%iimplicit) then
3023  write (this%iout, '(4x,a)') &
3024  'LAKE STAGE WILL BE SOLVED AS AN UNKNOWN IN THE GROUNDWATER FLOW '// &
3025  'MATRIX (IMPLICIT FORMULATION)'
3026  end if
3027  !
3028  ! -- DEV_FORCE_LEGACY (mf6internal: iforceleg)
3029  call mem_set_value(this%iforceleg, 'IFORCELEG', this%input_mempath, &
3030  found%iforceleg)
3031  !
3032  ! -- DEV_FORCE_LEGACY_LAKE (mf6internal: iforceleglak); loaded before
3033  ! either block below so both mutual-exclusion checks see a final value
3034  call mem_set_value(this%iforceleglak, 'IFORCELEGLAK', this%input_mempath, &
3035  found%iforceleglak)
3036  !
3037  if (found%iforceleg) then
3038  write (this%iout, '(4x,a)') &
3039  'EVERY ACTIVE LAKE WILL BE SOLVED WITH THE LEGACY SUBSTITUTION '// &
3040  'SOLVER UNDER THE IMPLICIT FORMULATION'
3041  if (this%iforceleglak /= 0) then
3042  call store_error('DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3043  'cannot both be specified.')
3044  end if
3045  end if
3046  !
3047  if (found%iforceleglak) then
3048  write (this%iout, '(4x,a,i0,a)') 'LAKE ', this%iforceleglak, &
3049  ' WILL BE SOLVED WITH THE LEGACY SUBSTITUTION SOLVER UNDER THE '// &
3050  'IMPLICIT FORMULATION'
3051  if (this%iforceleg /= 0) then
3052  call store_error('DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3053  'cannot both be specified.')
3054  end if
3055  end if
3056  !
3057  ! -- DEV_NO_FINAL_CHECK (mf6internal: iconvchk)
3058  call get_isize('ICONVCHK', this%input_mempath, isize)
3059  if (isize > 0) then
3060  this%iconvchk = 0
3061  write (this%iout, '(4x,a)') &
3062  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN LAKE STAGES &
3063  &WILL NOT BE MADE'
3064  end if
3065  !
3066  ! -- DEV_MAXIMUM_OUTLET_DEPTH (mf6internal: outdmax)
3067  call mem_set_value(this%outdmax, 'OUTDMAX', this%input_mempath, found%outdmax)
3068  if (found%outdmax) write (this%iout, fmtoutdmax) this%outdmax
3069  !
3070  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))//' OPTIONS'
Here is the call graph for this function:

◆ lak_source_outlets()

subroutine lakmodule::lak_source_outlets ( class(laktype), intent(inout)  this)
private

Definition at line 1370 of file gwf-lak.f90.

1371  ! -- dummy
1372  class(LakType), intent(inout) :: this
1373  ! -- local
1374  integer(I4B) :: n, isize, ioutlet
1375  character(len=LINELENGTH) :: keyword
1376  integer(I4B), dimension(:), pointer, contiguous :: outletno => null()
1377  integer(I4B), dimension(:), pointer, contiguous :: lakein => null()
1378  integer(I4B), dimension(:), pointer, contiguous :: lakeout => null()
1379  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1380  couttype => null()
1381  real(DP), dimension(:), pointer, contiguous :: outlets_invert => null()
1382  real(DP), dimension(:), pointer, contiguous :: outlets_width => null()
1383  real(DP), dimension(:), pointer, contiguous :: outlets_rough => null()
1384  real(DP), dimension(:), pointer, contiguous :: outlets_slope => null()
1385  integer(I4B), allocatable :: nboundchk(:)
1386  !
1387  ! -- skip if no outlets
1388  if (this%noutlets < 1) return
1389  !
1390  ! -- guard: OUTLETS block required when noutlets > 0
1391  call get_isize('OUTLETS_OUTLETNO', this%input_mempath, isize)
1392  if (isize < 1) then
1393  write (errmsg, '(a)') &
1394  'NOUTLETS > 0 BUT AN OUTLETS BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1395  call store_error(errmsg, .true.)
1396  end if
1397  !
1398  ! -- allocate outlet arrays
1399  call mem_allocate(this%lakein, this%noutlets, 'LAKEIN', this%memoryPath)
1400  call mem_allocate(this%lakeout, this%noutlets, 'LAKEOUT', this%memoryPath)
1401  call mem_allocate(this%iouttype, this%noutlets, 'IOUTTYPE', this%memoryPath)
1402  ! -- alias into the input context's permanent, feature-indexed arrays
1403  ! (allocated and DZERO-initialized by the loader)
1404  call mem_setptr(this%outrate, 'RATE', this%input_mempath)
1405  call mem_setptr(this%outinvert, 'INVERT', this%input_mempath)
1406  call mem_setptr(this%outwidth, 'WIDTH', this%input_mempath)
1407  call mem_setptr(this%outrough, 'ROUGH', this%input_mempath)
1408  call mem_setptr(this%outslope, 'SLOPE', this%input_mempath)
1409  call mem_allocate(this%simoutrate, this%noutlets, 'SIMOUTRATE', &
1410  this%memoryPath)
1411  call mem_allocate(this%outlet_invert_set, this%noutlets, &
1412  'INVERT_SET', this%memoryPath)
1413  call mem_allocate(this%outlet_width_set, this%noutlets, &
1414  'WIDTH_SET', this%memoryPath)
1415  call mem_allocate(this%outlet_rough_set, this%noutlets, &
1416  'ROUGH_SET', this%memoryPath)
1417  call mem_allocate(this%outlet_slope_set, this%noutlets, &
1418  'SLOPE_SET', this%memoryPath)
1419  this%outlet_invert_set = .false.
1420  this%outlet_width_set = .false.
1421  this%outlet_rough_set = .false.
1422  this%outlet_slope_set = .false.
1423  !
1424  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1425  ' OUTLETS'
1426  !
1427  ! -- set input context pointers
1428  call mem_setptr(outletno, 'OUTLETS_OUTLETNO', this%input_mempath)
1429  call mem_setptr(lakein, 'LAKEIN', this%input_mempath)
1430  call mem_setptr(lakeout, 'LAKEOUT', this%input_mempath)
1431  call mem_setptr(couttype, 'COUTTYPE', this%input_mempath)
1432  call mem_setptr(outlets_invert, 'OUTLETS_INVERT', this%input_mempath)
1433  call mem_setptr(outlets_width, 'OUTLETS_WIDTH', this%input_mempath)
1434  call mem_setptr(outlets_rough, 'OUTLETS_ROUGH', this%input_mempath)
1435  call mem_setptr(outlets_slope, 'OUTLETS_SLOPE', this%input_mempath)
1436  !
1437  allocate (nboundchk(this%noutlets))
1438  nboundchk = 0
1439  !
1440  do n = 1, size(outletno)
1441  ioutlet = this%validate_ifno(outletno(n), this%noutlets, &
1442  nboundchk, 'outletno', 'OUTLETS')
1443  if (ioutlet == 0) cycle
1444  !
1445  ! -- lakein
1446  if (lakein(n) < 1 .or. lakein(n) > this%nlakes) then
1447  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1448  'lakein FOR OUTLET ', ioutlet, 'MUST BE > 0 and <= ', this%nlakes
1449  call store_error(errmsg)
1450  end if
1451  this%lakein(ioutlet) = lakein(n)
1452  !
1453  ! -- lakeout
1454  if (lakeout(n) < 0 .or. lakeout(n) > this%nlakes) then
1455  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1456  'lakeout FOR OUTLET ', ioutlet, 'MUST BE >= 0 and <= ', this%nlakes
1457  call store_error(errmsg)
1458  end if
1459  this%lakeout(ioutlet) = lakeout(n)
1460  !
1461  ! -- outlet type
1462  keyword = couttype(n)
1463  select case (trim(keyword))
1464  case ('SPECIFIED')
1465  this%iouttype(ioutlet) = 0
1466  case ('MANNING')
1467  this%iouttype(ioutlet) = 1
1468  case ('WEIR')
1469  this%iouttype(ioutlet) = 2
1470  case default
1471  write (errmsg, '(a,1x,i0,1x,a,a,a)') &
1472  'UNKNOWN couttype FOR OUTLET ', ioutlet, '(', trim(keyword), ')'
1473  call store_error(errmsg)
1474  end select
1475  !
1476  ! -- outlet invert, width, roughness, slope
1477  this%outinvert(ioutlet) = outlets_invert(n)
1478  this%outwidth(ioutlet) = outlets_width(n)
1479  this%outrough(ioutlet) = outlets_rough(n)
1480  this%outslope(ioutlet) = outlets_slope(n)
1481  end do
1482  !
1483  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))//' OUTLETS'
1484  !
1485  ! -- check for duplicate or missing outlets
1486  call this%report_ifno_coverage(nboundchk, this%noutlets, 'outlet', &
1487  'OUTLETS')
1488  !
1489  deallocate (nboundchk)
1490  !
1491  if (count_errors() > 0) then
1492  call store_error_filename(this%input_fname)
1493  end if
1494  !
1495  ! -- release input context outlets memory; OUTLETS_OUTLETNO/INVERT/
1496  ! WIDTH/ROUGH/SLOPE excluded (bound by lak_input_init for PERIOD use)
1497  call memorystore_release('LAKEIN', this%input_mempath)
1498  call memorystore_release('LAKEOUT', this%input_mempath)
1499  call memorystore_release('COUTTYPE', this%input_mempath)
Here is the call graph for this function:

◆ lak_source_packagedata()

subroutine lakmodule::lak_source_packagedata ( class(laktype), intent(inout)  this)
private

Definition at line 575 of file gwf-lak.f90.

576  ! -- dummy
577  class(LakType), intent(inout) :: this
578  ! -- local
579  integer(I4B) :: n
580  integer(I4B) :: ilak, nconn
581  character(len=9) :: cno
582  character(len=LENBOUNDNAME) :: bndName
583  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
584  real(DP), dimension(:), pointer, contiguous :: strt => null()
585  integer(I4B), dimension(:), pointer, contiguous :: nlakeconn => null()
586  type(CharacterStringType), dimension(:), pointer, contiguous :: &
587  boundname_cst => null()
588  integer(I4B), allocatable :: nboundchk(:)
589  !
590  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
591  ' PACKAGEDATA'
592  !
593  ! -- allocate lake arrays
594  call mem_allocate(this%nlakeconn, this%nlakes, 'NLAKECONN', this%memoryPath)
595  call mem_allocate(this%idxlakeconn, this%nlakes + 1, 'IDXLAKECONN', &
596  this%memoryPath)
597  call mem_allocate(this%ntabrow, this%nlakes, 'NTABROW', this%memoryPath)
598  call mem_allocate(this%strt, this%nlakes, 'STRT', this%memoryPath)
599  call mem_allocate(this%laketop, this%nlakes, 'LAKETOP', this%memoryPath)
600  call mem_allocate(this%lakebot, this%nlakes, 'LAKEBOT', this%memoryPath)
601  call mem_allocate(this%sareamax, this%nlakes, 'SAREAMAX', this%memoryPath)
602  ! -- alias into the input context's permanent, feature-indexed arrays
603  ! (allocated and DZERO-initialized by the loader)
604  call mem_setptr(this%stage, 'STAGE', this%input_mempath)
605  call mem_setptr(this%rainfall, 'RAINFALL', this%input_mempath)
606  call mem_setptr(this%evaporation, 'EVAPORATION', this%input_mempath)
607  call mem_setptr(this%runoff, 'RUNOFF', this%input_mempath)
608  call mem_setptr(this%inflow, 'INFLOW', this%input_mempath)
609  call mem_setptr(this%withdrawal, 'WITHDRAWAL', this%input_mempath)
610  call mem_allocate(this%avail, this%nlakes, 'AVAIL', this%memoryPath)
611  call mem_allocate(this%lkgwsink, this%nlakes, 'LKGWSINK', this%memoryPath)
612  call mem_allocate(this%ncncvr, this%nlakes, 'NCNCVR', this%memoryPath)
613  call mem_allocate(this%ilegacy, this%nlakes, 'ILEGACY', this%memoryPath)
614  call mem_allocate(this%nstuck, this%nlakes, 'NSTUCK', this%memoryPath)
615  call mem_allocate(this%surfin, this%nlakes, 'SURFIN', this%memoryPath)
616  call mem_allocate(this%surfout, this%nlakes, 'SURFOUT', this%memoryPath)
617  call mem_allocate(this%surfout1, this%nlakes, 'SURFOUT1', this%memoryPath)
618  call mem_allocate(this%precip, this%nlakes, 'PRECIP', this%memoryPath)
619  call mem_allocate(this%precip1, this%nlakes, 'PRECIP1', this%memoryPath)
620  call mem_allocate(this%evap, this%nlakes, 'EVAP', this%memoryPath)
621  call mem_allocate(this%evap1, this%nlakes, 'EVAP1', this%memoryPath)
622  call mem_allocate(this%evapo, this%nlakes, 'EVAPO', this%memoryPath)
623  call mem_allocate(this%withr, this%nlakes, 'WITHR', this%memoryPath)
624  call mem_allocate(this%withr1, this%nlakes, 'WITHR1', this%memoryPath)
625  call mem_allocate(this%flwin, this%nlakes, 'FLWIN', this%memoryPath)
626  call mem_allocate(this%flwiter, this%nlakes, 'FLWITER', this%memoryPath)
627  call mem_allocate(this%flwiter1, this%nlakes, 'FLWITER1', this%memoryPath)
628  call mem_allocate(this%seep, this%nlakes, 'SEEP', this%memoryPath)
629  call mem_allocate(this%seep1, this%nlakes, 'SEEP1', this%memoryPath)
630  call mem_allocate(this%seep0, this%nlakes, 'SEEP0', this%memoryPath)
631  call mem_allocate(this%stageiter, this%nlakes, 'STAGEITER', this%memoryPath)
632  call mem_allocate(this%chterm, this%nlakes, 'CHTERM', this%memoryPath)
633  !
634  ! -- lake boundary and stages. In the implicit formulation iboundpak
635  ! and xnewpak are aliased to slices of the global ibound/x vectors in
636  ! lak_set_pointers (called before this routine), so they are not
637  ! allocated here.
638  if (this%iimplicit == 0) then
639  call mem_allocate(this%iboundpak, this%nlakes, 'IBOUND', this%memoryPath)
640  call mem_allocate(this%xnewpak, this%nlakes, 'XNEWPAK', this%memoryPath)
641  end if
642  call mem_allocate(this%xoldpak, this%nlakes, 'XOLDPAK', this%memoryPath)
643  !
644  ! -- lake iteration variables
645  call mem_allocate(this%iseepc, this%nlakes, 'ISEEPC', this%memoryPath)
646  call mem_allocate(this%idhc, this%nlakes, 'IDHC', this%memoryPath)
647  call mem_allocate(this%en1, this%nlakes, 'EN1', this%memoryPath)
648  call mem_allocate(this%en2, this%nlakes, 'EN2', this%memoryPath)
649  call mem_allocate(this%r1, this%nlakes, 'R1', this%memoryPath)
650  call mem_allocate(this%r2, this%nlakes, 'R2', this%memoryPath)
651  call mem_allocate(this%dh0, this%nlakes, 'DH0', this%memoryPath)
652  call mem_allocate(this%s0, this%nlakes, 'S0', this%memoryPath)
653  call mem_allocate(this%qgwf0, this%nlakes, 'QGWF0', this%memoryPath)
654  !
655  ! -- allocate character storage
656  allocate (this%lakename(this%nlakes))
657  allocate (this%status(this%nlakes))
658  !
659  ! -- initialize arrays
660  do n = 1, this%nlakes
661  this%ntabrow(n) = 0
662  this%status(n) = 'ACTIVE'
663  this%laketop(n) = -dep20
664  this%lakebot(n) = dep20
665  this%sareamax(n) = dzero
666  ! -- in the implicit formulation iboundpak/xnewpak are not yet associated
667  ! (they are aliased to the global arrays later in lak_set_pointers and
668  ! initialized in lak_read_initial_attr); only touch them here for the
669  ! legacy formulation
670  if (this%iimplicit == 0) then
671  this%iboundpak(n) = 1
672  this%xnewpak(n) = dep20
673  end if
674  this%xoldpak(n) = dep20
675  this%rainfall(n) = dzero
676  this%evaporation(n) = dzero
677  this%runoff(n) = dzero
678  this%inflow(n) = dzero
679  this%withdrawal(n) = dzero
680  this%ilegacy(n) = 0
681  this%nstuck(n) = 0
682  end do
683  !
684  ! -- get input context PACKAGEDATA column arrays
685  call mem_setptr(ifno, 'PACKAGEDATA_IFNO', this%input_mempath)
686  call mem_setptr(strt, 'STRT', this%input_mempath)
687  call mem_setptr(nlakeconn, 'NLAKECONN', this%input_mempath)
688  if (this%inamedbound /= 0) then
689  call mem_setptr(boundname_cst, 'BOUNDNAME', this%input_mempath)
690  end if
691  !
692  ! -- allocate check array
693  allocate (nboundchk(this%nlakes))
694  nboundchk = 0
695  ilak = 0
696  nconn = 0
697  !
698  do n = 1, this%nlakes
699  !
700  ! -- lake number from input
701  ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
702  'lakeno', 'PACKAGEDATA')
703  if (ilak == 0) cycle
704  !
705  ! -- strt
706  this%strt(ilak) = strt(n)
707  !
708  ! -- nlakeconn
709  if (nlakeconn(n) < 0) then
710  write (errmsg, '(a,1x,i0)') 'nlakeconn MUST BE >= 0 for lake ', ilak
711  call store_error(errmsg)
712  end if
713  !
714  ! -- the IMPLICIT formulation solves the lake stage as a matrix unknown,
715  ! which requires at least one groundwater connection to give the lake
716  ! row a non-zero diagonal; a lake with no connections is not supported
717  if (this%iimplicit /= 0 .and. nlakeconn(n) == 0) then
718  write (errmsg, '(a,1x,i0,1x,a)') &
719  'lake', ilak, 'has no connections; the IMPLICIT option requires &
720  &each lake to have at least one GWF connection.'
721  call store_error(errmsg)
722  end if
723  !
724  nconn = nconn + nlakeconn(n)
725  this%nlakeconn(ilak) = nlakeconn(n)
726  !
727  ! -- set default bndName
728  write (cno, '(i9.9)') ilak
729  bndname = 'Lake'//cno
730  !
731  ! -- lakename from boundname if provided
732  if (this%inamedbound /= 0) then
733  bndname = boundname_cst(n)
734  if (trim(bndname) == '') then
735  write (cno, '(i9.9)') ilak
736  bndname = 'Lake'//cno
737  end if
738  end if
739  this%lakename(ilak) = bndname
740  end do
741  !
742  ! -- check for duplicate or missing lakes
743  call this%report_ifno_coverage(nboundchk, this%nlakes, 'lake', &
744  'PACKAGEDATA')
745  !
746  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))// &
747  ' PACKAGEDATA'
748  !
749  ! -- terminate if any errors were detected
750  if (count_errors() > 0) then
751  call store_error_filename(this%input_fname)
752  end if
753  !
754  ! -- set MAXBOUND
755  this%MAXBOUND = nconn
756  write (this%iout, '(//4x,a,i7)') 'MAXBOUND = ', this%maxbound
757  !
758  ! -- set idxlakeconn
759  this%idxlakeconn(1) = 1
760  do n = 1, this%nlakes
761  this%idxlakeconn(n + 1) = this%idxlakeconn(n) + this%nlakeconn(n)
762  end do
763  !
764  ! -- deallocate check array
765  deallocate (nboundchk)
766  !
767  ! -- release input context packagedata memory; PACKAGEDATA_IFNO excluded
768  ! because allocate_featureauxvar retains a pointer to it
769  call memorystore_release('STRT', this%input_mempath)
770  call memorystore_release('NLAKECONN', this%input_mempath)
771  call memorystore_release('BOUNDNAME', this%input_mempath)
Here is the call graph for this function:

◆ lak_source_table()

subroutine lakmodule::lak_source_table ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
character(len=*), intent(in)  mempath,
type(laktabtype), intent(inout)  laketable 
)
private

Definition at line 1219 of file gwf-lak.f90.

1220  ! -- dummy
1221  class(LakType), intent(inout) :: this
1222  integer(I4B), intent(in) :: ilak
1223  character(len=*), intent(in) :: mempath
1224  type(LakTabType), intent(inout) :: laketable
1225  ! -- local
1226  integer(I4B), pointer :: nrow => null()
1227  integer(I4B), pointer :: ncol => null()
1228  real(DP), dimension(:), pointer, contiguous :: stage => null()
1229  real(DP), dimension(:), pointer, contiguous :: volume => null()
1230  real(DP), dimension(:), pointer, contiguous :: sarea => null()
1231  real(DP), dimension(:), pointer, contiguous :: barea => null()
1232  character(len=:), pointer :: tabfname => null()
1233  integer(I4B) :: jmin, iconn, n, nerr0
1234  real(DP) :: vol, sa, wa, v, v0
1235  ! -- formats
1236  character(len=*), parameter :: fmttaberr = &
1237  &'(a,1x,i0,1x,a,1x,g15.6,1x,a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.6,1x,a)'
1238  !
1239  ! -- this table's own input file, for error attribution below
1240  call mem_setptr(tabfname, 'INPUT_FNAME', mempath)
1241  call mem_setptr(nrow, 'NROW', mempath)
1242  call mem_setptr(ncol, 'NCOL', mempath)
1243  !
1244  ! -- errors added below this point belong to this lake's own table
1245  nerr0 = count_errors()
1246  !
1247  if (nrow < 1) then
1248  write (errmsg, '(a,1x,i0)') &
1249  'LAKE TABLE NROW MUST BE > 0 FOR LAKE', ilak
1250  call store_error(errmsg)
1251  end if
1252  !
1253  iconn = this%idxlakeconn(ilak)
1254  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1255  jmin = 4
1256  else
1257  jmin = 3
1258  end if
1259  if (ncol < jmin) then
1260  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1261  'LAKE TABLE NCOL MUST BE >=', jmin, 'FOR LAKE', ilak
1262  call store_error(errmsg)
1263  end if
1264  !
1265  if (count_errors() > nerr0) then
1266  call store_error_filename(tabfname, terminate=.false.)
1267  call memorystore_release('NROW', mempath)
1268  call memorystore_release('NCOL', mempath)
1269  call memorystore_release('INPUT_FNAME', mempath)
1270  return
1271  end if
1272  !
1273  this%ntabrow(ilak) = nrow
1274  allocate (laketable%tabstage(nrow))
1275  allocate (laketable%tabvolume(nrow))
1276  allocate (laketable%tabsarea(nrow))
1277  call mem_setptr(stage, 'STAGE', mempath)
1278  call mem_setptr(volume, 'VOLUME', mempath)
1279  call mem_setptr(sarea, 'SAREA', mempath)
1280  laketable%tabstage = stage
1281  laketable%tabvolume = volume
1282  laketable%tabsarea = sarea
1283  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1284  allocate (laketable%tabwarea(nrow))
1285  call mem_setptr(barea, 'BAREA', mempath)
1286  laketable%tabwarea = barea
1287  end if
1288  !
1289  ! -- set lake bottom based on table if it is an embedded lake
1290  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1291  do n = 1, this%ntabrow(ilak)
1292  vol = laketable%tabvolume(n)
1293  sa = laketable%tabsarea(n)
1294  wa = laketable%tabwarea(n)
1295  vol = vol * sa * wa
1296  ! -- check if all entries are zero
1297  if (vol > dzero) exit
1298  ! -- set lake bottom
1299  this%lakebot(ilak) = laketable%tabstage(n)
1300  this%belev(ilak) = laketable%tabstage(n)
1301  end do
1302  ! -- set maximum surface area for rainfall
1303  n = this%ntabrow(ilak)
1304  this%sareamax(ilak) = laketable%tabsarea(n)
1305  end if
1306  !
1307  ! -- verify the table data
1308  do n = 2, this%ntabrow(ilak)
1309  v = laketable%tabstage(n)
1310  v0 = laketable%tabstage(n - 1)
1311  if (v <= v0) then
1312  write (errmsg, fmttaberr) &
1313  'TABLE STAGE ENTRY', n, '(', laketable%tabstage(n), ') FOR LAKE ', &
1314  ilak, 'MUST BE GREATER THAN THE PREVIOUS STAGE ENTRY', &
1315  n - 1, '(', laketable%tabstage(n - 1), ')'
1316  call store_error(errmsg)
1317  end if
1318  v = laketable%tabvolume(n)
1319  v0 = laketable%tabvolume(n - 1)
1320  if (v <= v0) then
1321  write (errmsg, fmttaberr) &
1322  'TABLE VOLUME ENTRY', n, '(', laketable%tabvolume(n), &
1323  ') FOR LAKE ', &
1324  ilak, 'MUST BE GREATER THAN THE PREVIOUS VOLUME ENTRY', &
1325  n - 1, '(', laketable%tabvolume(n - 1), ')'
1326  call store_error(errmsg)
1327  end if
1328  v = laketable%tabsarea(n)
1329  v0 = laketable%tabsarea(n - 1)
1330  if (v < v0) then
1331  write (errmsg, fmttaberr) &
1332  'TABLE SURFACE AREA ENTRY', n, '(', &
1333  laketable%tabsarea(n), ') FOR LAKE ', ilak, &
1334  'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS SURFACE AREA ENTRY', &
1335  n - 1, '(', laketable%tabsarea(n - 1), ')'
1336  call store_error(errmsg)
1337  end if
1338  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1339  v = laketable%tabwarea(n)
1340  v0 = laketable%tabwarea(n - 1)
1341  if (v < v0) then
1342  write (errmsg, fmttaberr) &
1343  'TABLE EXCHANGE AREA ENTRY', n, '(', &
1344  laketable%tabwarea(n), ') FOR LAKE ', ilak, &
1345  'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS EXCHANGE AREA '// &
1346  'ENTRY', n - 1, '(', laketable%tabwarea(n - 1), ')'
1347  call store_error(errmsg)
1348  end if
1349  end if
1350  end do
1351  !
1352  if (count_errors() > nerr0) then
1353  call store_error_filename(tabfname, terminate=.false.)
1354  end if
1355  !
1356  ! -- release this table's own input context memory
1357  call memorystore_release('NROW', mempath)
1358  call memorystore_release('NCOL', mempath)
1359  call memorystore_release('STAGE', mempath)
1360  call memorystore_release('VOLUME', mempath)
1361  call memorystore_release('SAREA', mempath)
1362  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1363  call memorystore_release('BAREA', mempath)
1364  end if
1365  call memorystore_release('INPUT_FNAME', mempath)
Here is the call graph for this function:

◆ lak_source_tables()

subroutine lakmodule::lak_source_tables ( class(laktype), intent(inout)  this)
private

Definition at line 1079 of file gwf-lak.f90.

1080  ! -- dummy
1081  class(LakType), intent(inout) :: this
1082  ! -- local
1083  integer(I4B) :: n, ntabs
1084  integer(I4B) :: ilak, iconn
1085  character(len=LENMEMPATH) :: mempath
1086  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
1087  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1088  laktab6_mempaths => null()
1089  type(LakTabType), dimension(:), allocatable :: laketables
1090  integer(I4B), allocatable :: nboundchk(:)
1091  !
1092  ! -- skip if no tables
1093  if (this%ntables < 1) return
1094  !
1095  ! -- guard: TABLES block required when ntables > 0
1096  call get_isize('TABLES_IFNO', this%input_mempath, ntabs)
1097  if (ntabs < 1) then
1098  write (errmsg, '(a)') &
1099  'NTABLES > 0 BUT A TABLES BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1100  call store_error(errmsg, .true.)
1101  end if
1102  !
1103  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1104  ' TABLES'
1105  !
1106  ! -- set input context pointers
1107  call mem_setptr(ifno, 'TABLES_IFNO', this%input_mempath)
1108  call mem_setptr(laktab6_mempaths, 'LAKTAB6_MEMPATH', this%input_mempath)
1109  !
1110  ntabs = size(ifno)
1111  !
1112  ! -- allocate
1113  allocate (laketables(this%nlakes))
1114  allocate (nboundchk(this%nlakes))
1115  nboundchk = 0
1116  !
1117  do n = 1, ntabs
1118  ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
1119  'lakeno', 'TABLES')
1120  if (ilak == 0) cycle
1121  mempath = laktab6_mempaths(n)
1122  call this%lak_source_table(ilak, mempath, laketables(ilak))
1123  end do
1124  !
1125  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))//' TABLES'
1126  !
1127  ! -- check for missing or duplicate table data
1128  if (ntabs < this%ntables) then
1129  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1130  'TABLE DATA ARE SPECIFIED', ntabs, &
1131  'TIMES BUT NTABLES IS SET TO', this%ntables
1132  call store_error(errmsg)
1133  end if
1134  ! -- a table that never loaded any rows is not reported as a duplicate
1135  do n = 1, this%nlakes
1136  if (this%ntabrow(n) == 0) nboundchk(n) = 0
1137  end do
1138  call this%report_ifno_coverage(nboundchk, this%nlakes, 'lakeno', &
1139  'TABLES', check_missing=.false.)
1140  !
1141  deallocate (nboundchk)
1142  !
1143  if (count_errors() > 0) then
1144  call store_error_filename(this%input_fname)
1145  end if
1146  !
1147  ! -- release input context tables memory
1148  call memorystore_release('TABLES_IFNO', this%input_mempath)
1149  !
1150  ! -- convert laketables to vectors
1151  call this%laktables_to_vectors(laketables)
1152  !
1153  ! -- destroy laketables
1154  do n = 1, this%nlakes
1155  if (this%ntabrow(n) > 0) then
1156  deallocate (laketables(n)%tabstage)
1157  deallocate (laketables(n)%tabvolume)
1158  deallocate (laketables(n)%tabsarea)
1159  iconn = this%idxlakeconn(n)
1160  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1161  deallocate (laketables(n)%tabwarea)
1162  end if
1163  end if
1164  end do
1165  deallocate (laketables)
Here is the call graph for this function:

◆ lak_vol2stage()

subroutine lakmodule::lak_vol2stage ( class(laktype), intent(inout)  this,
integer(i4b), intent(in)  ilak,
real(dp), intent(in)  vol,
real(dp), intent(inout)  stage 
)
private

Definition at line 2740 of file gwf-lak.f90.

2741  ! -- dummy
2742  class(LakType), intent(inout) :: this
2743  integer(I4B), intent(in) :: ilak
2744  real(DP), intent(in) :: vol
2745  real(DP), intent(inout) :: stage
2746  ! -- local
2747  integer(I4B) :: i
2748  integer(I4B) :: ibs
2749  real(DP) :: s0, s1, sm
2750  real(DP) :: v0, v1, vm
2751  real(DP) :: f0, f1, fm
2752  real(DP) :: sa
2753  real(DP) :: en0, en1
2754  real(DP) :: ds, ds0
2755  real(DP) :: denom
2756  !
2757  s0 = this%lakebot(ilak)
2758  call this%lak_calculate_vol(ilak, s0, v0)
2759  s1 = this%laketop(ilak)
2760  call this%lak_calculate_vol(ilak, s1, v1)
2761  ! -- zero volume
2762  if (vol <= v0) then
2763  stage = s0
2764  ! -- linear relation between stage and volume above top of lake
2765  else if (vol >= v1) then
2766  call this%lak_calculate_sarea(ilak, s1, sa)
2767  stage = s1 + (vol - v1) / sa
2768  ! -- use combination of secant and bisection
2769  else
2770  en0 = s0
2771  en1 = s1
2772  ! sm = s1 ! causes divide by zero in 1st line in secantbisection loop
2773  ! sm = s0 ! causes divide by zero in 1st line in secantbisection loop
2774  sm = dzero
2775  f0 = vol - v0
2776  f1 = vol - v1
2777  ibs = 0
2778  secantbisection: do i = 1, 150
2779  denom = f1 - f0
2780  if (denom /= dzero) then
2781  ds = f1 * (s1 - s0) / denom
2782  else
2783  ibs = 13
2784  end if
2785  if (i == 1) then
2786  ds0 = ds
2787  end if
2788  ! -- use bisection if end points are exceeded
2789  if (sm < en0 .or. sm > en1) ibs = 13
2790  ! -- use bisection if secant method stagnates or if
2791  ! ds exceeds previous ds - bisection would occur
2792  ! after conditions exceeded in 13 iterations
2793  if (ds * ds0 < dprec .or. abs(ds) > abs(ds0)) ibs = ibs + 1
2794  if (ibs > 12) then
2795  ds = dhalf * (s1 - s0)
2796  ibs = 0
2797  end if
2798  sm = s1 - ds
2799  if (abs(ds) < dem6) then
2800  exit secantbisection
2801  end if
2802  call this%lak_calculate_vol(ilak, sm, vm)
2803  fm = vol - vm
2804  s0 = s1
2805  f0 = f1
2806  s1 = sm
2807  f1 = fm
2808  ds0 = ds
2809  end do secantbisection
2810  stage = sm
2811  if (abs(ds) >= dem6) then
2812  write (this%iout, '(1x,a,1x,i0,4(1x,a,1x,g15.6))') &
2813  & 'LAK_VOL2STAGE failed for lake', ilak, 'volume error =', fm, &
2814  & 'finding stage (', stage, ') for volume =', vol, &
2815  & 'final change in stage =', ds
2816  end if
2817  end if

◆ laktables_to_vectors()

subroutine lakmodule::laktables_to_vectors ( class(laktype), intent(inout)  this,
type(laktabtype), dimension(:), intent(in), contiguous  laketables 
)
private

Definition at line 1171 of file gwf-lak.f90.

1172  class(LakType), intent(inout) :: this
1173  type(LakTabType), intent(in), dimension(:), contiguous :: laketables
1174  integer(I4B) :: n
1175  integer(I4B) :: ntabrows
1176  integer(I4B) :: j
1177  integer(I4B) :: ipos
1178  integer(I4B) :: iconn
1179  !
1180  ! -- allocate index array for lak tables
1181  call mem_allocate(this%ialaktab, this%nlakes + 1, 'IALAKTAB', this%memoryPath)
1182  !
1183  ! -- Move the laktables structure information into flattened arrays
1184  this%ialaktab(1) = 1
1185  do n = 1, this%nlakes
1186  ! -- ialaktab contains a pointer into the flattened lak table data
1187  this%ialaktab(n + 1) = this%ialaktab(n) + this%ntabrow(n)
1188  end do
1189  !
1190  ! -- Allocate vectors for storing all lake table data
1191  ntabrows = this%ialaktab(this%nlakes + 1) - 1
1192  call mem_allocate(this%tabstage, ntabrows, 'TABSTAGE', this%memoryPath)
1193  call mem_allocate(this%tabvolume, ntabrows, 'TABVOLUME', this%memoryPath)
1194  call mem_allocate(this%tabsarea, ntabrows, 'TABSAREA', this%memoryPath)
1195  call mem_allocate(this%tabwarea, ntabrows, 'TABWAREA', this%memoryPath)
1196  !
1197  ! -- Copy data from laketables into vectors
1198  do n = 1, this%nlakes
1199  j = 1
1200  do ipos = this%ialaktab(n), this%ialaktab(n + 1) - 1
1201  this%tabstage(ipos) = laketables(n)%tabstage(j)
1202  this%tabvolume(ipos) = laketables(n)%tabvolume(j)
1203  this%tabsarea(ipos) = laketables(n)%tabsarea(j)
1204  iconn = this%idxlakeconn(n)
1205  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1206  !
1207  ! -- tabwarea only filled for ictype 2 and 3
1208  this%tabwarea(ipos) = laketables(n)%tabwarea(j)
1209  else
1210  this%tabwarea(ipos) = dzero
1211  end if
1212  j = j + 1
1213  end do
1214  end do

Variable Documentation

◆ ftype

character(len=lenftype) lakmodule::ftype = 'LAK'
private

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

46  character(len=LENFTYPE) :: ftype = 'LAK'

◆ text

character(len=lenpackagename) lakmodule::text = ' LAK'
private

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

47  character(len=LENPACKAGENAME) :: text = ' LAK'