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_checkin_deprecated_names (this)
 Alias deprecated LAK variable names to their current storage. 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 4587 of file gwf-lak.f90.

4588  ! -- modules
4589  class(LakType), intent(inout) :: this
4590  !
4591  ! -- create the header list label
4592  this%listlabel = trim(this%filtyp)//' NO.'
4593  if (this%dis%ndim == 3) then
4594  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
4595  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
4596  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
4597  elseif (this%dis%ndim == 2) then
4598  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
4599  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
4600  else
4601  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
4602  end if
4603  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
4604  if (this%inamedbound == 1) then
4605  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
4606  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 4654 of file gwf-lak.f90.

4655  use sparsemodule, only: sparsematrix
4656  ! -- dummy
4657  class(LakType), intent(inout) :: this
4658  integer(I4B), intent(in) :: moffset
4659  type(sparsematrix), intent(inout) :: sparse
4660  ! -- local
4661  integer(I4B) :: j, n
4662  integer(I4B) :: jj
4663  integer(I4B) :: jglo
4664  integer(I4B) :: nglo
4665  !
4666  ! -- the default formulation adds no rows to the matrix
4667  if (this%iimplicit == 0) return
4668  !
4669  ! -- add a row for each lake and its connections to the cells
4670  do n = 1, this%nlakes
4671  nglo = moffset + this%dis%nodes + this%ioffset + n
4672  call sparse%addconnection(nglo, nglo, 1)
4673  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4674  jj = this%gwfconn(j)
4675  jglo = jj + moffset
4676  call sparse%addconnection(nglo, jglo, 1)
4677  call sparse%addconnection(jglo, nglo, 1)
4678  end do
4679  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 5231 of file gwf-lak.f90.

5232  ! -- dummy
5233  class(LakType) :: this
5234  integer(I4B), intent(in) :: ilak
5235  real(DP), intent(in) :: rrate
5236  real(DP), intent(inout) :: chratin
5237  real(DP), intent(inout) :: chratout
5238  ! -- locals
5239  real(DP) :: q
5240  !
5241  ! code
5242  if (this%iboundpak(ilak) < 0) then
5243  q = -rrate
5244  this%chterm(ilak) = this%chterm(ilak) + q
5245  !
5246  ! -- See if flow is into lake or out of lake.
5247  if (q < dzero) then
5248  !
5249  ! -- Flow is out of lake subtract rate from ratout.
5250  chratout = chratout - q
5251  else
5252  !
5253  ! -- Flow is into lake; add rate to ratin.
5254  chratin = chratin + q
5255  end if
5256  end if

◆ lak_activate_density()

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

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

6445  ! -- dummy
6446  class(LakType), intent(inout) :: this
6447  ! -- local
6448  integer(I4B) :: i, j
6449  !
6450  ! -- the IMPLICIT formulation does not include the density terms yet
6451  if (this%iimplicit /= 0) then
6452  write (errmsg, '(a)') &
6453  'The IMPLICIT option cannot be used with the BUY package until the &
6454  &implicit formulation includes density terms. Remove the IMPLICIT &
6455  &option from LAK package '//trim(this%packName)//' to simulate &
6456  &density.'
6457  call store_error(errmsg)
6458  call store_error_filename(this%input_fname)
6459  end if
6460  !
6461  ! -- Set idense and reallocate denseterms to be of size MAXBOUND
6462  this%idense = 1
6463  call mem_reallocate(this%denseterms, 3, this%MAXBOUND, 'DENSETERMS', &
6464  this%memoryPath)
6465  do i = 1, this%maxbound
6466  do j = 1, 3
6467  this%denseterms(j, i) = dzero
6468  end do
6469  end do
6470  write (this%iout, '(/1x,a)') 'DENSITY TERMS HAVE BEEN ACTIVATED FOR LAKE &
6471  &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 6478 of file gwf-lak.f90.

6479  ! -- modules
6481  ! -- dummy variables
6482  class(LakType), intent(inout) :: this !< LakType object
6483  ! -- local variables
6484  integer(I4B) :: i
6485  integer(I4B) :: j
6486  !
6487  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
6488  this%ivsc = 1
6489  call mem_reallocate(this%viscratios, 2, this%MAXBOUND, 'VISCRATIOS', &
6490  this%memoryPath)
6491  do i = 1, this%maxbound
6492  do j = 1, 2
6493  this%viscratios(j, i) = done
6494  end do
6495  end do
6496  write (this%iout, '(/1x,a)') 'VISCOSITY HAS BEEN ACTIVATED FOR LAK &
6497  &PACKAGE: '//trim(adjustl(this%packName))

◆ lak_ad()

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

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

3503  ! -- modules
3505  ! -- dummy
3506  class(LakType) :: this
3507  ! -- local
3508  integer(I4B) :: n
3509  integer(I4B) :: j
3510  integer(I4B) :: iaux
3511  integer(I4B) :: itemno
3512  !
3513  ! -- sync PACKAGEDATA AUX TS and advance observations;
3514  ! sync_period_auxvar (inside bnd_ad) handles PERIOD AUXILIARY TS
3515  call this%BndExtType%bnd_ad()
3516  !
3517  ! -- re-sync static OUTLETS values (invert, width, rough, slope) linked
3518  ! to a time series, skipping any field a PERIOD-block setting has
3519  ! already overridden for this outlet -- that override must persist
3520  ! until a later PERIOD block changes it
3521  if (this%ts_active .and. this%noutlets > 0) then
3522  do n = 1, size(this%input%outletno)
3523  itemno = this%input%outletno(n)
3524  if (itemno < 1 .or. itemno > this%noutlets) cycle
3525  if (.not. this%outlet_invert_set(itemno) .and. &
3526  this%input%invert_tslink(n) /= 0) &
3527  this%outinvert(itemno) = this%input%outlets_invert(n)
3528  if (.not. this%outlet_width_set(itemno) .and. &
3529  this%input%width_tslink(n) /= 0) &
3530  this%outwidth(itemno) = this%input%outlets_width(n)
3531  if (.not. this%outlet_rough_set(itemno) .and. &
3532  this%input%rough_tslink(n) /= 0) &
3533  this%outrough(itemno) = this%input%outlets_rough(n)
3534  if (.not. this%outlet_slope_set(itemno) .and. &
3535  this%input%slope_tslink(n) /= 0) &
3536  this%outslope(itemno) = this%input%outlets_slope(n)
3537  end do
3538  end if
3539  !
3540  ! -- update auxiliary variables
3541  if (this%naux > 0) then
3542  do n = 1, this%nlakes
3543  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3544  do iaux = 1, this%naux
3545  if (this%noupdateauxvar(iaux) /= 0) cycle
3546  this%auxvar(iaux, j) = this%featureauxvar(iaux, n)
3547  end do
3548  end do
3549  end do
3550  end if
3551  !
3552  ! -- Update or restore state
3553  if (ifailedstepretry == 0) then
3554  !
3555  ! -- copy xnew into xold and set xnewpak to stage for
3556  ! constant stage lakes
3557  do n = 1, this%nlakes
3558  this%xoldpak(n) = this%xnewpak(n)
3559  this%stageiter(n) = this%xnewpak(n)
3560  if (this%iboundpak(n) < 0) then
3561  this%xnewpak(n) = this%stage(n)
3562  end if
3563  this%seep0(n) = dzero
3564  end do
3565  else
3566  !
3567  ! -- copy xold back into xnew as this is a
3568  ! retry of this time step
3569  do n = 1, this%nlakes
3570  this%xnewpak(n) = this%xoldpak(n)
3571  this%stageiter(n) = this%xnewpak(n)
3572  if (this%iboundpak(n) < 0) then
3573  this%xnewpak(n) = this%stage(n)
3574  end if
3575  this%seep0(n) = dzero
3576  end do
3577  end if
3578  !
3579  ! -- pakmvrobj ad
3580  if (this%imover == 1) then
3581  call this%pakmvrobj%ad()
3582  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 503 of file gwf-lak.f90.

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

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

3221  ! -- modules
3222  use constantsmodule, only: mnormal
3223  use inputoutputmodule, only: getunit, openfile
3224  ! -- dummy
3225  class(LakType), intent(inout) :: this
3226  ! -- formats
3227  character(len=*), parameter :: fmtlakbin = &
3228  "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
3229  &a, /4x, 'OPENED ON UNIT: ', I0)"
3230  !
3231  ! -- open the deferred PACKAGE_CONVERGENCE file now that all options have
3232  ! been read. lak_cc does not write package convergence for the implicit
3233  ! formulation, because the lake stage is part of the solver (IMS)
3234  ! convergence check. With the IMPLICIT option the file is therefore left
3235  ! unopened (ipakcsv stays 0) and a warning is issued instead.
3236  if (allocated(this%pakcsvfile)) then
3237  if (this%iimplicit /= 0) then
3238  write (warnmsg, '(a)') &
3239  'PACKAGE_CONVERGENCE output file "'//trim(this%pakcsvfile)// &
3240  '" is not written when the IMPLICIT option is active; the lake '// &
3241  'stage is part of the solver (IMS) convergence check.'
3242  call store_warning(warnmsg)
3243  else
3244  this%ipakcsv = getunit()
3245  call openfile(this%ipakcsv, this%iout, this%pakcsvfile, 'CSV', &
3246  filstat_opt='REPLACE', mode_opt=mnormal)
3247  write (this%iout, fmtlakbin) 'PACKAGE_CONVERGENCE', &
3248  trim(this%pakcsvfile), this%ipakcsv
3249  end if
3250  deallocate (this%pakcsvfile)
3251  end if
3252  !
3253  call this%obs%obs_ar()
3254  !
3255  ! -- Allocate arrays in LAK and in package superclass
3256  call this%lak_allocate_arrays()
3257  !
3258  ! -- read optional initial package parameters
3259  call this%read_initial_attr()
3260  !
3261  ! -- bind input context persistent pointers
3262  call this%input%init(this%input_mempath, this%naux, this%noutlets)
3263  if (this%noutlets > 0) then
3264  if (.not. (associated(this%input%invert_tslink) .and. &
3265  associated(this%input%width_tslink) .and. &
3266  associated(this%input%rough_tslink) .and. &
3267  associated(this%input%slope_tslink))) then
3268  call store_error('Time series links for OUTLETS not found in input.')
3269  call store_error_filename(this%input_fname)
3270  end if
3271  end if
3272  !
3273  ! -- setup pakmvrobj
3274  if (this%imover /= 0) then
3275  allocate (this%pakmvrobj)
3276  call this%pakmvrobj%ar(this%noutlets, this%nlakes, this%memoryPath)
3277  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 4870 of file gwf-lak.f90.

4871  ! -- dummy
4872  class(LakType) :: this
4873  ! -- local
4874  integer(I4B) :: i
4875  integer(I4B) :: igwfnode
4876  integer(I4B) :: j
4877  integer(I4B) :: jj
4878  integer(I4B) :: n
4879  real(DP) :: hgwf
4880  real(DP) :: hlak
4881  real(DP) :: v
4882  real(DP) :: v2
4883  type(ObserveType), pointer :: obsrv => null()
4884  !
4885  ! Write simulated values for all LAK observations
4886  if (this%obs%npakobs > 0) then
4887  call this%obs%obs_bd_clear()
4888  do i = 1, this%obs%npakobs
4889  obsrv => this%obs%pakobs(i)%obsrv
4890  do j = 1, obsrv%indxbnds_count
4891  v = dnodata
4892  jj = obsrv%indxbnds(j)
4893  select case (obsrv%ObsTypeId)
4894  case ('STAGE')
4895  if (this%iboundpak(jj) /= 0) then
4896  v = this%xnewpak(jj)
4897  end if
4898  case ('EXT-INFLOW')
4899  if (this%iboundpak(jj) /= 0) then
4900  call this%lak_calculate_inflow(jj, v)
4901  end if
4902  case ('OUTLET-INFLOW')
4903  if (this%iboundpak(jj) /= 0) then
4904  call this%lak_calculate_outlet_inflow(jj, v)
4905  end if
4906  case ('INFLOW')
4907  if (this%iboundpak(jj) /= 0) then
4908  call this%lak_calculate_inflow(jj, v)
4909  call this%lak_calculate_outlet_inflow(jj, v2)
4910  v = v + v2
4911  end if
4912  case ('FROM-MVR')
4913  if (this%iboundpak(jj) /= 0) then
4914  if (this%imover == 1) then
4915  v = this%pakmvrobj%get_qfrommvr(jj)
4916  end if
4917  end if
4918  case ('RAINFALL')
4919  if (this%iboundpak(jj) /= 0) then
4920  v = this%precip(jj)
4921  end if
4922  case ('RUNOFF')
4923  if (this%iboundpak(jj) /= 0) then
4924  v = this%runoff(jj)
4925  end if
4926  case ('LAK')
4927  n = this%imap(jj)
4928  if (this%iboundpak(n) /= 0) then
4929  igwfnode = this%gwfconn(jj)
4930  hgwf = this%xnew(igwfnode)
4931  if (this%hcof(jj) /= dzero) then
4932  v = -(this%hcof(jj) * (this%xnewpak(n) - hgwf))
4933  else
4934  v = -this%rhs(jj)
4935  end if
4936  end if
4937  case ('EVAPORATION')
4938  if (this%iboundpak(jj) /= 0) then
4939  v = this%evap(jj)
4940  end if
4941  case ('WITHDRAWAL')
4942  if (this%iboundpak(jj) /= 0) then
4943  v = this%withr(jj)
4944  end if
4945  case ('EXT-OUTFLOW')
4946  n = this%lakein(jj)
4947  if (this%iboundpak(n) /= 0) then
4948  if (this%lakeout(jj) == 0) then
4949  v = this%simoutrate(jj)
4950  if (v < dzero) then
4951  if (this%imover == 1) then
4952  v = v + this%pakmvrobj%get_qtomvr(jj)
4953  end if
4954  end if
4955  end if
4956  end if
4957  case ('TO-MVR')
4958  n = this%lakein(jj)
4959  if (this%iboundpak(n) /= 0) then
4960  if (this%imover == 1) then
4961  v = this%pakmvrobj%get_qtomvr(jj)
4962  if (v > dzero) then
4963  v = -v
4964  end if
4965  end if
4966  end if
4967  case ('STORAGE')
4968  if (this%iboundpak(jj) /= 0) then
4969  v = this%qsto(jj)
4970  end if
4971  case ('CONSTANT')
4972  if (this%iboundpak(jj) /= 0) then
4973  v = this%chterm(jj)
4974  end if
4975  case ('OUTLET')
4976  n = this%lakein(jj)
4977  if (this%iboundpak(n) /= 0) then
4978  v = this%simoutrate(jj)
4979  end if
4980  case ('VOLUME')
4981  if (this%iboundpak(jj) /= 0) then
4982  call this%lak_calculate_vol(jj, this%xnewpak(jj), v)
4983  end if
4984  case ('SURFACE-AREA')
4985  if (this%iboundpak(jj) /= 0) then
4986  hlak = this%xnewpak(jj)
4987  call this%lak_calculate_sarea(jj, hlak, v)
4988  end if
4989  case ('WETTED-AREA')
4990  n = this%imap(jj)
4991  if (this%iboundpak(n) /= 0) then
4992  hlak = this%xnewpak(n)
4993  igwfnode = this%gwfconn(jj)
4994  hgwf = this%xnew(igwfnode)
4995  call this%lak_calculate_conn_warea(n, jj, hlak, hgwf, v)
4996  end if
4997  case ('CONDUCTANCE')
4998  n = this%imap(jj)
4999  if (this%iboundpak(n) /= 0) then
5000  hlak = this%xnewpak(n)
5001  igwfnode = this%gwfconn(jj)
5002  hgwf = this%xnew(igwfnode)
5003  call this%lak_calculate_conn_conductance(n, jj, hlak, hgwf, v)
5004  end if
5005  case default
5006  errmsg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
5007  call store_error(errmsg)
5008  end select
5009  call this%obs%SaveOneSimval(obsrv, v)
5010  end do
5011  end do
5012  !
5013  ! -- write summary of error messages
5014  if (count_errors() > 0) then
5015  call store_error_filename(this%input_fname)
5016  end if
5017  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 5748 of file gwf-lak.f90.

5749  ! -- dummy
5750  class(LakType), intent(inout) :: this
5751  integer(I4B), intent(in) :: n !< lake number
5752  integer(I4B), intent(inout) :: ibflg !< bisection flag
5753  real(DP), intent(in) :: hlak !< lake stage
5754  real(DP), intent(inout) :: temporary_stage !< temporary lake stage
5755  real(DP), intent(inout) :: dh !< lake stage change
5756  real(DP), intent(inout) :: residual !< lake residual
5757  ! -- local
5758  integer(I4B) :: i
5759  real(DP) :: temporary_stage0
5760  real(DP) :: residuala
5761  real(DP) :: endpoint1
5762  real(DP) :: endpoint2
5763  ! -- code
5764  ibflg = 1
5765  temporary_stage0 = hlak
5766  endpoint1 = this%en1(n)
5767  endpoint2 = this%en2(n)
5768  call this%lak_calculate_residual(n, temporary_stage, residuala)
5769  if (hlak > endpoint1 .and. hlak < endpoint2) then
5770  endpoint2 = hlak
5771  end if
5772  do i = 1, this%maxlakit
5773  temporary_stage = dhalf * (endpoint1 + endpoint2)
5774  call this%lak_calculate_residual(n, temporary_stage, residual)
5775  if (abs(residual) == dzero .or. &
5776  abs(temporary_stage0 - temporary_stage) < this%dmaxchg) then
5777  exit
5778  end if
5779  call this%lak_calculate_residual(n, endpoint1, residuala)
5780  ! -- change end points
5781  ! -- root is between temporary_stage and endpoint2
5782  if (sign(done, residuala) == sign(done, residual)) then
5783  endpoint1 = temporary_stage
5784  ! -- root is between endpoint1 and temporary_stage
5785  else
5786  endpoint2 = temporary_stage
5787  end if
5788  temporary_stage0 = temporary_stage
5789  end do
5790  dh = hlak - temporary_stage

◆ lak_bound_update()

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

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

5262  ! -- dummy
5263  class(LakType), intent(inout) :: this
5264  ! -- local
5265  integer(I4B) :: j, n, node
5266  real(DP) :: hlak, head, clak
5267  !
5268  ! -- Return if no lak lakes
5269  if (this%nbound == 0) return
5270  !
5271  ! -- Calculate hcof and rhs for each lak entry
5272  do n = 1, this%nlakes
5273  hlak = this%xnewpak(n)
5274  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5275  node = this%gwfconn(j)
5276  head = this%xnew(node)
5277  call this%lak_calculate_conn_conductance(n, j, hlak, head, clak)
5278  this%bound(1, j) = hlak
5279  this%bound(2, j) = clak
5280  end do
5281  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 5796 of file gwf-lak.f90.

5798  ! -- modules
5799  use tdismodule, only: delt
5800  ! -- dummy
5801  class(LakType), intent(inout) :: this
5802  integer(I4B), intent(in) :: n
5803  real(DP), intent(in) :: hlak
5804  real(DP), intent(inout) :: avail
5805  real(DP), intent(inout) :: ra
5806  real(DP), intent(inout) :: ro
5807  real(DP), intent(inout) :: qinf
5808  real(DP), intent(inout) :: ex
5809  real(DP), intent(in), optional :: headp
5810  ! -- local
5811  integer(I4B) :: j
5812  integer(I4B) :: idry
5813  integer(I4B) :: igwfnode
5814  real(DP) :: hp
5815  real(DP) :: head
5816  real(DP) :: qlakgw
5817  real(DP) :: v0
5818  !
5819  ! -- set hp
5820  if (present(headp)) then
5821  hp = headp
5822  else
5823  hp = dzero
5824  end if
5825  !
5826  ! -- initialize
5827  avail = dzero
5828  !
5829  ! -- calculate the aquifer sources to the lake
5830  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5831  igwfnode = this%gwfconn(j)
5832  if (this%ibound(igwfnode) == 0) cycle
5833  head = this%xnew(igwfnode) + hp
5834  call this%lak_estimate_conn_exchange(1, n, j, idry, hlak, head, qlakgw, &
5835  avail)
5836  end do
5837  !
5838  ! -- add rainfall
5839  call this%lak_calculate_rainfall(n, hlak, ra)
5840  avail = avail + ra
5841  !
5842  ! -- calculate runoff
5843  call this%lak_calculate_runoff(n, ro)
5844  avail = avail + ro
5845  !
5846  ! -- calculate inflow
5847  call this%lak_calculate_inflow(n, qinf)
5848  avail = avail + qinf
5849  !
5850  ! -- calculate external flow terms
5851  call this%lak_calculate_external(n, ex)
5852  avail = avail + ex
5853  !
5854  ! -- calculate volume available in storage
5855  call this%lak_calculate_vol(n, this%xoldpak(n), v0)
5856  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 2167 of file gwf-lak.f90.

2168  ! -- dummy
2169  class(LakType), intent(inout) :: this
2170  integer(I4B), intent(in) :: iconn
2171  real(DP), intent(in) :: stage
2172  real(DP), intent(in) :: head
2173  real(DP), intent(inout) :: vv
2174  ! -- local
2175  real(DP) :: ss
2176  real(DP) :: hh
2177  real(DP) :: topl
2178  real(DP) :: botl
2179  !
2180  topl = this%telev(iconn)
2181  botl = this%belev(iconn)
2182  ss = min(stage, topl)
2183  hh = min(head, topl)
2184  if (this%igwhcopt > 0) then
2185  vv = hh
2186  else if (this%inewton > 0) then
2187  vv = max(ss, hh)
2188  else
2189  vv = dhalf * (ss + hh)
2190  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 2146 of file gwf-lak.f90.

2147  ! -- dummy
2148  class(LakType), intent(inout) :: this
2149  integer(I4B), intent(in) :: ilak
2150  real(DP), intent(in) :: stage
2151  real(DP), intent(inout) :: conductance
2152  ! -- local
2153  integer(I4B) :: i
2154  real(DP) :: c
2155  !
2156  conductance = dzero
2157  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2158  call this%lak_calculate_conn_conductance(ilak, i, stage, stage, c)
2159  conductance = conductance + c
2160  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 2196 of file gwf-lak.f90.

2197  ! -- dummy
2198  class(LakType), intent(inout) :: this
2199  integer(I4B), intent(in) :: ilak
2200  integer(I4B), intent(in) :: iconn
2201  real(DP), intent(in) :: stage
2202  real(DP), intent(in) :: head
2203  real(DP), intent(inout) :: cond
2204  ! -- local
2205  integer(I4B) :: node
2206  !real(DP) :: ss
2207  !real(DP) :: hh
2208  real(DP) :: vv
2209  real(DP) :: topl
2210  real(DP) :: botl
2211  real(DP) :: sat
2212  real(DP) :: wa
2213  real(DP) :: vscratio
2214  !
2215  cond = dzero
2216  vscratio = done
2217  topl = this%telev(iconn)
2218  botl = this%belev(iconn)
2219  call this%lak_calculate_cond_head(iconn, stage, head, vv)
2220  sat = squadraticsaturation(topl, botl, vv)
2221  ! vertical connection
2222  ! use full saturated conductance if top and bottom of the lake connection
2223  ! are equal
2224  if (this%ictype(iconn) == 0) then
2225  if (abs(topl - botl) < dprec) then
2226  sat = done
2227  end if
2228  ! horizontal connection
2229  ! use full saturated conductance if the connected cell is not convertible
2230  else if (this%ictype(iconn) == 1) then
2231  node = this%gwfconn(iconn)
2232  if (this%icelltype(node) == 0) then
2233  sat = done
2234  end if
2235  ! embedded connection
2236  else if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
2237  node = this%gwfconn(iconn)
2238  if (this%icelltype(node) == 0) then
2239  vv = this%telev(iconn)
2240  call this%lak_calculate_conn_warea(ilak, iconn, vv, vv, wa)
2241  else
2242  call this%lak_calculate_conn_warea(ilak, iconn, stage, head, wa)
2243  end if
2244  sat = wa
2245  end if
2246  !
2247  ! -- account for viscosity effects (if vsc active)
2248  if (this%ivsc == 1) then
2249  ! flow from lake to aquifer
2250  if (stage > head) then
2251  vscratio = this%viscratios(1, iconn)
2252  ! flow from aquifer to lake
2253  else
2254  vscratio = this%viscratios(2, iconn)
2255  end if
2256  end if
2257  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 2286 of file gwf-lak.f90.

2288  ! -- dummy
2289  class(LakType), intent(inout) :: this
2290  integer(I4B), intent(in) :: ilak
2291  integer(I4B), intent(in) :: iconn
2292  real(DP), intent(in) :: stage
2293  real(DP), intent(in) :: head
2294  real(DP), intent(inout) :: flow
2295  real(DP), intent(inout), optional :: gwfhcof
2296  real(DP), intent(inout), optional :: gwfrhs
2297  ! -- local
2298  real(DP) :: botl
2299  real(DP) :: cond
2300  real(DP) :: ss
2301  real(DP) :: hh
2302  real(DP) :: gwfhcof0
2303  real(DP) :: gwfrhs0
2304  !
2305  flow = dzero
2306  call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2307  botl = this%belev(iconn)
2308  !
2309  ! -- Set ss to stage or botl
2310  if (stage >= botl) then
2311  ss = stage
2312  else
2313  ss = botl
2314  end if
2315  !
2316  ! -- set hh to head or botl
2317  if (head >= botl) then
2318  hh = head
2319  else
2320  hh = botl
2321  end if
2322  !
2323  ! -- calculate flow, positive into lake
2324  flow = cond * (hh - ss)
2325  !
2326  ! -- Calculate gwfhcof and gwfrhs
2327  if (head >= botl) then
2328  gwfhcof0 = -cond
2329  gwfrhs0 = -cond * ss
2330  else
2331  gwfhcof0 = dzero
2332  gwfrhs0 = flow
2333  end if
2334  !
2335  ! Add density contributions, if active
2336  if (this%idense /= 0) then
2337  call this%lak_calculate_density_exchange(iconn, stage, head, cond, botl, &
2338  flow, gwfhcof0, gwfrhs0)
2339  end if
2340  !
2341  ! -- If present update gwfhcof and gwfrhs
2342  if (present(gwfhcof)) gwfhcof = gwfhcof0
2343  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 2355 of file gwf-lak.f90.

2357  ! -- dummy
2358  class(LakType), intent(inout) :: this
2359  integer(I4B), intent(in) :: ilak
2360  integer(I4B), intent(in) :: iconn
2361  real(DP), intent(in) :: stage
2362  real(DP), intent(in) :: head
2363  real(DP), intent(inout) :: flow
2364  real(DP), intent(inout), optional :: dqds
2365  real(DP), intent(inout), optional :: dqdh
2366  ! -- local
2367  real(DP) :: cond, botl, dps, dph, ss, hh
2368  !
2369  call this%lak_calculate_conn_conductance(ilak, iconn, stage, head, cond)
2370  botl = this%belev(iconn)
2371  if (stage >= botl) then
2372  ss = stage
2373  dps = done
2374  else
2375  ss = botl
2376  dps = dzero
2377  end if
2378  if (head >= botl) then
2379  hh = head
2380  dph = done
2381  else
2382  hh = botl
2383  dph = dzero
2384  end if
2385  flow = cond * (hh - ss)
2386  if (present(dqds)) dqds = -cond * dps
2387  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 2042 of file gwf-lak.f90.

2043  ! -- dummy
2044  class(LakType), intent(inout) :: this
2045  integer(I4B), intent(in) :: ilak
2046  integer(I4B), intent(in) :: iconn
2047  real(DP), intent(in) :: stage
2048  real(DP), intent(in) :: head
2049  real(DP), intent(inout) :: wa
2050  ! -- local
2051  integer(I4B) :: i
2052  integer(I4B) :: ifirst
2053  integer(I4B) :: ilast
2054  integer(I4B) :: node
2055  real(DP) :: topl
2056  real(DP) :: botl
2057  real(DP) :: vv
2058  real(DP) :: sat
2059  !
2060  wa = dzero
2061  topl = this%telev(iconn)
2062  botl = this%belev(iconn)
2063  call this%lak_calculate_cond_head(iconn, stage, head, vv)
2064  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
2065  if (vv > topl) vv = topl
2066  i = this%ntabrow(ilak)
2067  ifirst = this%ialaktab(ilak)
2068  ilast = this%ialaktab(ilak + 1) - 1
2069  if (vv <= this%tabstage(ifirst)) then
2070  wa = this%tabwarea(ifirst)
2071  else if (vv >= this%tabstage(ilast)) then
2072  wa = this%tabwarea(ilast)
2073  else
2074  call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2075  this%tabwarea(ifirst:ilast), &
2076  vv, wa)
2077  end if
2078  else
2079  node = this%gwfconn(iconn)
2080  ! -- confined cell
2081  if (this%icelltype(node) == 0) then
2082  sat = done
2083  ! -- convertible cell
2084  else
2085  sat = squadraticsaturation(topl, botl, vv)
2086  end if
2087  wa = sat * this%warea(iconn)
2088  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 6518 of file gwf-lak.f90.

6520  ! -- dummy
6521  class(LakType), intent(inout) :: this
6522  integer(I4B), intent(in) :: iconn
6523  real(DP), intent(in) :: stage
6524  real(DP), intent(in) :: head
6525  real(DP), intent(in) :: cond
6526  real(DP), intent(in) :: botl
6527  real(DP), intent(inout) :: flow
6528  real(DP), intent(inout) :: gwfhcof
6529  real(DP), intent(inout) :: gwfrhs
6530  ! -- local
6531  real(DP) :: ss
6532  real(DP) :: hh
6533  real(DP) :: havg
6534  real(DP) :: rdenselak
6535  real(DP) :: rdensegwf
6536  real(DP) :: rdenseavg
6537  real(DP) :: elevlak
6538  real(DP) :: elevgwf
6539  real(DP) :: elevavg
6540  real(DP) :: d1
6541  real(DP) :: d2
6542  logical(LGP) :: stage_below_bot
6543  logical(LGP) :: head_below_bot
6544  !
6545  ! -- Set lak density to lak density or gwf density
6546  if (stage >= botl) then
6547  ss = stage
6548  stage_below_bot = .false.
6549  rdenselak = this%denseterms(1, iconn) ! lak rel density
6550  else
6551  ss = botl
6552  stage_below_bot = .true.
6553  rdenselak = this%denseterms(2, iconn) ! gwf rel density
6554  end if
6555  !
6556  ! -- set hh to head or botl
6557  if (head >= botl) then
6558  hh = head
6559  head_below_bot = .false.
6560  rdensegwf = this%denseterms(2, iconn) ! gwf rel density
6561  else
6562  hh = botl
6563  head_below_bot = .true.
6564  rdensegwf = this%denseterms(1, iconn) ! lak rel density
6565  end if
6566  !
6567  ! -- todo: hack because denseterms not updated in a cf calculation
6568  if (rdensegwf == dzero) return
6569  !
6570  ! -- Update flow
6571  if (stage_below_bot .and. head_below_bot) then
6572  !
6573  ! -- flow is zero, so no terms are updated
6574  !
6575  else
6576  !
6577  ! -- calculate average relative density
6578  rdenseavg = dhalf * (rdenselak + rdensegwf)
6579  !
6580  ! -- Add contribution of first density term:
6581  ! cond * (denseavg/denseref - 1) * (hgwf - hlak)
6582  d1 = cond * (rdenseavg - done)
6583  gwfhcof = gwfhcof - d1
6584  gwfrhs = gwfrhs - d1 * ss
6585  d1 = d1 * (hh - ss)
6586  flow = flow + d1
6587  !
6588  ! -- Add second density term if stage and head not below bottom
6589  if (.not. stage_below_bot .and. .not. head_below_bot) then
6590  !
6591  ! -- Add contribution of second density term:
6592  ! cond * (havg - elevavg) * (densegwf - denselak) / denseref
6593  elevgwf = this%denseterms(3, iconn)
6594  if (this%ictype(iconn) == 0 .or. this%ictype(iconn) == 3) then
6595  ! -- vertical or embedded vertical connection
6596  elevlak = botl
6597  else
6598  ! -- horizontal or embedded horizontal connection
6599  elevlak = elevgwf
6600  end if
6601  elevavg = dhalf * (elevlak + elevgwf)
6602  havg = dhalf * (hh + ss)
6603  d2 = cond * (havg - elevavg) * (rdensegwf - rdenselak)
6604  gwfrhs = gwfrhs + d2
6605  flow = flow + d2
6606  end if
6607  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 2542 of file gwf-lak.f90.

2543  ! -- dummy
2544  class(LakType), intent(inout) :: this
2545  integer(I4B), intent(in) :: ilak
2546  real(DP), intent(in) :: stage
2547  real(DP), intent(inout) :: avail
2548  real(DP), intent(inout) :: ev
2549  ! -- local
2550  real(DP) :: sa
2551  !
2552  ! -- evaporation - limit to sum of inflows and available volume
2553  call this%lak_calculate_sarea(ilak, stage, sa)
2554  ev = sa * this%evaporation(ilak)
2555  if (ev > avail) then
2556  if (is_close(avail, dprec)) then
2557  ev = dzero
2558  else
2559  ev = -avail
2560  end if
2561  else
2562  ev = -ev
2563  end if
2564  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 2262 of file gwf-lak.f90.

2263  ! -- dummy
2264  class(LakType), intent(inout) :: this
2265  integer(I4B), intent(in) :: ilak
2266  real(DP), intent(in) :: stage
2267  real(DP), intent(inout) :: totflow
2268  ! -- local
2269  integer(I4B) :: j
2270  integer(I4B) :: igwfnode
2271  real(DP) :: flow
2272  real(DP) :: hgwf
2273  !
2274  totflow = dzero
2275  do j = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2276  igwfnode = this%gwfconn(j)
2277  hgwf = this%xnew(igwfnode)
2278  call this%lak_calculate_conn_exchange(ilak, j, stage, hgwf, flow)
2279  totflow = totflow + flow
2280  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 2504 of file gwf-lak.f90.

2505  ! -- dummy
2506  class(LakType), intent(inout) :: this
2507  integer(I4B), intent(in) :: ilak
2508  real(DP), intent(inout) :: ex
2509  !
2510  ! -- If mover is active, add receiver water to rhs and
2511  ! store available water (as positive value)
2512  ex = dzero
2513  if (this%imover == 1) then
2514  ex = this%pakmvrobj%get_qfrommvr(ilak)
2515  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 2492 of file gwf-lak.f90.

2493  ! -- dummy
2494  class(LakType), intent(inout) :: this
2495  integer(I4B), intent(in) :: ilak
2496  real(DP), intent(inout) :: qin
2497  !
2498  ! -- inflow to lake
2499  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 2569 of file gwf-lak.f90.

2570  ! -- dummy
2571  class(LakType), intent(inout) :: this
2572  integer(I4B), intent(in) :: ilak
2573  real(DP), intent(inout) :: outinf
2574  ! -- local
2575  integer(I4B) :: n
2576  !
2577  outinf = dzero
2578  do n = 1, this%noutlets
2579  if (this%lakeout(n) == ilak) then
2580  outinf = outinf - this%simoutrate(n)
2581  if (this%imover == 1) then
2582  outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2583  end if
2584  end if
2585  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 2590 of file gwf-lak.f90.

2591  ! -- dummy
2592  class(LakType), intent(inout) :: this
2593  integer(I4B), intent(in) :: ilak
2594  real(DP), intent(in) :: stage
2595  real(DP), intent(inout) :: avail
2596  real(DP), intent(inout) :: outoutf
2597  ! -- local
2598  integer(I4B) :: n
2599  real(DP) :: g
2600  real(DP) :: d
2601  real(DP) :: c
2602  real(DP) :: gsm
2603  real(DP) :: rate
2604  !
2605  outoutf = dzero
2606  do n = 1, this%noutlets
2607  if (this%lakein(n) == ilak) then
2608  rate = dzero
2609  d = stage - this%outinvert(n)
2610  if (this%outdmax > dzero) then
2611  if (d > this%outdmax) d = this%outdmax
2612  end if
2613  g = dgravity * this%convlength * this%convtime * this%convtime
2614  select case (this%iouttype(n))
2615  ! specified rate
2616  case (0)
2617  rate = this%outrate(n)
2618  if (-rate > avail) then
2619  rate = -avail
2620  end if
2621  ! manning
2622  case (1)
2623  if (d > dzero) then
2624  c = (this%convlength**donethird) * this%convtime
2625  gsm = dzero
2626  if (this%outrough(n) > dzero) then
2627  gsm = done / this%outrough(n)
2628  end if
2629  rate = -c * gsm * this%outwidth(n) * (d**dfivethirds) * &
2630  sqrt(this%outslope(n))
2631  end if
2632  ! weir
2633  case (2)
2634  if (d > dzero) then
2635  rate = -dtwothirds * dcd * this%outwidth(n) * d * &
2636  sqrt(dtwo * g * d)
2637  end if
2638  end select
2639  this%simoutrate(n) = rate
2640  avail = avail + rate
2641  outoutf = outoutf + rate
2642  end if
2643  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 2458 of file gwf-lak.f90.

2459  ! -- dummy
2460  class(LakType), intent(inout) :: this
2461  integer(I4B), intent(in) :: ilak
2462  real(DP), intent(in) :: stage
2463  real(DP), intent(inout) :: ra
2464  ! -- local
2465  integer(I4B) :: iconn
2466  real(DP) :: sa
2467  !
2468  ! -- rainfall
2469  iconn = this%idxlakeconn(ilak)
2470  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
2471  sa = this%sareamax(ilak)
2472  else
2473  call this%lak_calculate_sarea(ilak, stage, sa)
2474  end if
2475  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 5861 of file gwf-lak.f90.

5862  ! -- modules
5863  use tdismodule, only: delt
5864  ! -- dummy
5865  class(LakType), intent(inout) :: this
5866  integer(I4B), intent(in) :: n
5867  real(DP), intent(in) :: hlak
5868  real(DP), intent(inout) :: resid
5869  real(DP), intent(in), optional :: headp
5870  ! -- local
5871  integer(I4B) :: j
5872  integer(I4B) :: idry
5873  integer(I4B) :: igwfnode
5874  real(DP) :: hp
5875  real(DP) :: avail
5876  real(DP) :: head
5877  real(DP) :: ra
5878  real(DP) :: ro
5879  real(DP) :: qinf
5880  real(DP) :: ex
5881  real(DP) :: ev
5882  real(DP) :: wr
5883  real(DP) :: sout
5884  real(DP) :: sin
5885  real(DP) :: qlakgw
5886  real(DP) :: seep
5887  real(DP) :: hlak0
5888  real(DP) :: v0
5889  real(DP) :: v1
5890  !
5891  ! -- set hp
5892  if (present(headp)) then
5893  hp = headp
5894  else
5895  hp = dzero
5896  end if
5897  !
5898  ! -- initialize
5899  resid = dzero
5900  avail = dzero
5901  seep = dzero
5902  !
5903  ! -- calculate the available water
5904  call this%lak_calculate_available(n, hlak, avail, &
5905  ra, ro, qinf, ex, hp)
5906  !
5907  ! -- calculate groundwater seepage
5908  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5909  igwfnode = this%gwfconn(j)
5910  if (this%ibound(igwfnode) == 0) cycle
5911  head = this%xnew(igwfnode) + hp
5912  call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, head, qlakgw, &
5913  avail)
5914  seep = seep + qlakgw
5915  end do
5916  !
5917  ! -- limit withdrawals to lake inflows and lake storage
5918  call this%lak_calculate_withdrawal(n, avail, wr)
5919  !
5920  ! -- limit evaporation to lake inflows and lake storage
5921  call this%lak_calculate_evaporation(n, hlak, avail, ev)
5922  !
5923  ! -- no outlet flow if evaporation consumes all water
5924  call this%lak_calculate_outlet_outflow(n, hlak, avail, sout)
5925  !
5926  ! -- update the surface inflow values
5927  call this%lak_calculate_outlet_inflow(n, sin)
5928  !
5929  ! -- calculate residual
5930  resid = ra + ev + wr + ro + qinf + ex + sin + sout + seep
5931  !
5932  ! -- include storage
5933  if (this%gwfiss /= 1) then
5934  hlak0 = this%xoldpak(n)
5935  call this%lak_calculate_vol(n, hlak0, v0)
5936  call this%lak_calculate_vol(n, hlak, v1)
5937  resid = resid + (v0 - v1) / delt
5938  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 2480 of file gwf-lak.f90.

2481  ! -- dummy
2482  class(LakType), intent(inout) :: this
2483  integer(I4B), intent(in) :: ilak
2484  real(DP), intent(inout) :: ro
2485  !
2486  ! -- runoff
2487  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 1972 of file gwf-lak.f90.

1973  ! -- dummy
1974  class(LakType), intent(inout) :: this
1975  integer(I4B), intent(in) :: ilak
1976  real(DP), intent(in) :: stage
1977  real(DP), intent(inout) :: sarea
1978  ! -- local
1979  integer(I4B) :: i
1980  integer(I4B) :: ifirst
1981  integer(I4B) :: ilast
1982  real(DP) :: topl
1983  real(DP) :: botl
1984  real(DP) :: sat
1985  real(DP) :: sa
1986  !
1987  sarea = dzero
1988  i = this%ntabrow(ilak)
1989  if (i > 0) then
1990  ifirst = this%ialaktab(ilak)
1991  ilast = this%ialaktab(ilak + 1) - 1
1992  if (stage <= this%tabstage(ifirst)) then
1993  sarea = this%tabsarea(ifirst)
1994  else if (stage >= this%tabstage(ilast)) then
1995  sarea = this%tabsarea(ilast)
1996  else
1997  call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
1998  this%tabsarea(ifirst:ilast), &
1999  stage, sarea)
2000  end if
2001  else
2002  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2003  topl = this%telev(i)
2004  botl = this%belev(i)
2005  sat = squadraticsaturation(topl, botl, stage)
2006  sa = sat * this%sarea(i)
2007  sarea = sarea + sa
2008  end do
2009  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 2436 of file gwf-lak.f90.

2437  ! -- dummy
2438  class(LakType), intent(inout) :: this
2439  integer(I4B), intent(in) :: ilak
2440  real(DP), intent(in) :: stage
2441  real(DP), intent(in) :: stage0
2442  real(DP), intent(in) :: delt
2443  real(DP), intent(inout) :: dvr
2444  ! -- local
2445  real(DP) :: v
2446  real(DP) :: v0
2447  !
2448  dvr = dzero
2449  if (this%gwfiss /= 1) then
2450  call this%lak_calculate_vol(ilak, stage, v)
2451  call this%lak_calculate_vol(ilak, stage0, v0)
2452  dvr = (v0 - v) / delt
2453  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 2093 of file gwf-lak.f90.

2094  ! -- dummy
2095  class(LakType), intent(inout) :: this
2096  integer(I4B), intent(in) :: ilak
2097  real(DP), intent(in) :: stage
2098  real(DP), intent(inout) :: volume
2099  ! -- local
2100  integer(I4B) :: i
2101  integer(I4B) :: ifirst
2102  integer(I4B) :: ilast
2103  real(DP) :: topl
2104  real(DP) :: botl
2105  real(DP) :: ds
2106  real(DP) :: sa
2107  real(DP) :: v
2108  real(DP) :: sat
2109  !
2110  volume = dzero
2111  i = this%ntabrow(ilak)
2112  if (i > 0) then
2113  ifirst = this%ialaktab(ilak)
2114  ilast = this%ialaktab(ilak + 1) - 1
2115  if (stage <= this%tabstage(ifirst)) then
2116  volume = this%tabvolume(ifirst)
2117  else if (stage >= this%tabstage(ilast)) then
2118  ds = stage - this%tabstage(ilast)
2119  sa = this%tabsarea(ilast)
2120  volume = this%tabvolume(ilast) + ds * sa
2121  else
2122  call this%lak_linear_interpolation(i, this%tabstage(ifirst:ilast), &
2123  this%tabvolume(ifirst:ilast), &
2124  stage, volume)
2125  end if
2126  else
2127  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2128  topl = this%telev(i)
2129  botl = this%belev(i)
2130  sat = squadraticsaturation(topl, botl, stage)
2131  sa = sat * this%sarea(i)
2132  if (stage < botl) then
2133  v = dzero
2134  else if (stage > botl .and. stage < topl) then
2135  v = sa * (stage - botl)
2136  else
2137  v = sa * (topl - botl) + sa * (stage - topl)
2138  end if
2139  volume = volume + v
2140  end do
2141  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 2014 of file gwf-lak.f90.

2015  ! -- dummy
2016  class(LakType), intent(inout) :: this
2017  integer(I4B), intent(in) :: ilak
2018  real(DP), intent(in) :: stage
2019  real(DP), intent(inout) :: warea
2020  real(DP), optional, intent(inout) :: hin
2021  ! -- local
2022  integer(I4B) :: i
2023  integer(I4B) :: igwfnode
2024  real(DP) :: head
2025  real(DP) :: wa
2026  !
2027  warea = dzero
2028  do i = this%idxlakeconn(ilak), this%idxlakeconn(ilak + 1) - 1
2029  if (present(hin)) then
2030  head = hin
2031  else
2032  igwfnode = this%gwfconn(i)
2033  head = this%xnew(igwfnode)
2034  end if
2035  call this%lak_calculate_conn_warea(ilak, i, stage, head, wa)
2036  warea = warea + wa
2037  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 2520 of file gwf-lak.f90.

2521  ! -- dummy
2522  class(LakType), intent(inout) :: this
2523  integer(I4B), intent(in) :: ilak
2524  real(DP), intent(inout) :: avail
2525  real(DP), intent(inout) :: wr
2526  !
2527  ! -- withdrawals - limit to sum of inflows and available volume
2528  wr = this%withdrawal(ilak)
2529  if (wr > avail) then
2530  wr = -avail
2531  else
2532  if (wr > dzero) then
2533  wr = -wr
2534  end if
2535  end if
2536  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 3826 of file gwf-lak.f90.

3827  ! -- modules
3828  use tdismodule, only: totim, kstp, kper, delt
3829  ! -- dummy
3830  class(LakType), intent(inout) :: this
3831  integer(I4B), intent(in) :: innertot
3832  integer(I4B), intent(in) :: kiter
3833  integer(I4B), intent(in) :: iend
3834  integer(I4B), intent(in) :: icnvgmod
3835  character(len=LENPAKLOC), intent(inout) :: cpak
3836  integer(I4B), intent(inout) :: ipak
3837  real(DP), intent(inout) :: dpak
3838  ! -- local
3839  character(len=LENPAKLOC) :: cloc
3840  character(len=LINELENGTH) :: tag
3841  integer(I4B) :: icheck
3842  integer(I4B) :: ipakfail
3843  integer(I4B) :: locdhmax
3844  integer(I4B) :: locresidmax
3845  integer(I4B) :: locdgwfmax
3846  integer(I4B) :: locdqoutmax
3847  integer(I4B) :: locdqfrommvrmax
3848  integer(I4B) :: ntabrows
3849  integer(I4B) :: ntabcols
3850  integer(I4B) :: n
3851  real(DP) :: q
3852  real(DP) :: q0
3853  real(DP) :: qtolfact
3854  real(DP) :: area
3855  real(DP) :: gwf0
3856  real(DP) :: gwf
3857  real(DP) :: dh
3858  real(DP) :: resid
3859  real(DP) :: dgwf
3860  real(DP) :: hlak0
3861  real(DP) :: hlak
3862  real(DP) :: qout0
3863  real(DP) :: qout
3864  real(DP) :: dqout
3865  real(DP) :: inf
3866  real(DP) :: ra
3867  real(DP) :: ro
3868  real(DP) :: qinf
3869  real(DP) :: ex
3870  real(DP) :: dhmax
3871  real(DP) :: residmax
3872  real(DP) :: dgwfmax
3873  real(DP) :: dqoutmax
3874  real(DP) :: dqfrommvr
3875  real(DP) :: dqfrommvrmax
3876  ! -- switch any stalled IMPLICIT lake back to the legacy solver
3877  call this%lak_set_legacy(kiter, icnvgmod)
3878  !
3879  ! -- on the last outer iteration of a solution that has not converged, warn
3880  ! about a perched (disconnected) lake that has no practical steady state.
3881  ! Done for both formulations (the implicit path returns just below).
3882  if (iend /= 0 .and. icnvgmod == 0) then
3883  call this%lak_check_disconnected()
3884  end if
3885  !
3886  ! -- implicit formulation: lake stage is solved in the global matrix,
3887  ! so its convergence is governed by the solution's dvclose check on the
3888  ! stage unknown; no separate package convergence check is performed here.
3889  if (this%iimplicit /= 0) then
3890  return
3891  end if
3892  !
3893  ! -- initialize local variables
3894  icheck = this%iconvchk
3895  ipakfail = 0
3896  locdhmax = 0
3897  locresidmax = 0
3898  locdgwfmax = 0
3899  locdqoutmax = 0
3900  locdqfrommvrmax = 0
3901  dhmax = dzero
3902  residmax = dzero
3903  dgwfmax = dzero
3904  dqoutmax = dzero
3905  dqfrommvrmax = dzero
3906  !
3907  ! -- if not saving package convergence data on check convergence if
3908  ! the model is considered converged
3909  if (this%ipakcsv == 0) then
3910  if (icnvgmod == 0) then
3911  icheck = 0
3912  end if
3913  !
3914  ! -- saving package convergence data
3915  else
3916  !
3917  ! -- header for package csv
3918  if (.not. associated(this%pakcsvtab)) then
3919  !
3920  ! -- determine the number of columns and rows
3921  ntabrows = 1
3922  ntabcols = 11
3923  if (this%noutlets > 0) then
3924  ntabcols = ntabcols + 2
3925  end if
3926  if (this%imover == 1) then
3927  ntabcols = ntabcols + 2
3928  end if
3929  !
3930  ! -- setup table
3931  call table_cr(this%pakcsvtab, this%packName, '')
3932  call this%pakcsvtab%table_df(ntabrows, ntabcols, this%ipakcsv, &
3933  lineseparator=.false., separator=',', &
3934  finalize=.false.)
3935  !
3936  ! -- add columns to package csv
3937  tag = 'total_inner_iterations'
3938  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3939  tag = 'totim'
3940  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3941  tag = 'kper'
3942  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3943  tag = 'kstp'
3944  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3945  tag = 'nouter'
3946  call this%pakcsvtab%initialize_column(tag, 10, alignment=tableft)
3947  tag = 'dvmax'
3948  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3949  tag = 'dvmax_loc'
3950  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3951  tag = 'residmax'
3952  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3953  tag = 'residmax_loc'
3954  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3955  tag = 'dgwfmax'
3956  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3957  tag = 'dgwfmax_loc'
3958  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3959  if (this%noutlets > 0) then
3960  tag = 'dqoutmax'
3961  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3962  tag = 'dqoutmax_loc'
3963  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3964  end if
3965  if (this%imover == 1) then
3966  tag = 'dqfrommvrmax'
3967  call this%pakcsvtab%initialize_column(tag, 15, alignment=tableft)
3968  tag = 'dqfrommvrmax_loc'
3969  call this%pakcsvtab%initialize_column(tag, 16, alignment=tableft)
3970  end if
3971  end if
3972  end if
3973  !
3974  ! -- perform package convergence check
3975  if (icheck /= 0) then
3976  final_check: do n = 1, this%nlakes
3977  if (this%iboundpak(n) < 1) cycle
3978  !
3979  ! -- set previous and current lake stage
3980  hlak0 = this%s0(n)
3981  hlak = this%xnewpak(n)
3982  !
3983  ! -- stage difference
3984  dh = hlak0 - hlak
3985  !
3986  ! -- calculate surface area
3987  call this%lak_calculate_sarea(n, hlak, area)
3988  !
3989  ! -- set the Q to length factor
3990  if (area > dzero) then
3991  qtolfact = delt / area
3992  else
3993  qtolfact = dzero
3994  end if
3995  !
3996  ! -- difference in the residual
3997  call this%lak_calculate_residual(n, hlak, resid)
3998  resid = resid * qtolfact
3999  !
4000  ! -- change in gwf exchange
4001  dgwf = dzero
4002  if (area > dzero) then
4003  gwf0 = this%qgwf0(n)
4004  call this%lak_calculate_exchange(n, hlak, gwf)
4005  dgwf = (gwf0 - gwf) * qtolfact
4006  end if
4007  !
4008  ! -- change in outflows
4009  dqout = dzero
4010  if (this%noutlets > 0) then
4011  if (area > dzero) then
4012  call this%lak_calculate_available(n, hlak0, inf, ra, ro, qinf, ex)
4013  call this%lak_calculate_outlet_outflow(n, hlak0, inf, qout0)
4014  call this%lak_calculate_available(n, hlak, inf, ra, ro, qinf, ex)
4015  call this%lak_calculate_outlet_outflow(n, hlak, inf, qout)
4016  dqout = (qout0 - qout) * qtolfact
4017  end if
4018  end if
4019  !
4020  ! -- q from mvr
4021  dqfrommvr = dzero
4022  if (this%imover == 1) then
4023  q = this%pakmvrobj%get_qfrommvr(n)
4024  q0 = this%pakmvrobj%get_qfrommvr0(n)
4025  dqfrommvr = qtolfact * (q0 - q)
4026  end if
4027  !
4028  ! -- evaluate magnitude of differences
4029  if (n == 1) then
4030  locdhmax = n
4031  dhmax = dh
4032  locdgwfmax = n
4033  residmax = resid
4034  locresidmax = n
4035  dgwfmax = dgwf
4036  locdqoutmax = n
4037  dqoutmax = dqout
4038  dqfrommvrmax = dqfrommvr
4039  locdqfrommvrmax = n
4040  else
4041  if (abs(dh) > abs(dhmax)) then
4042  locdhmax = n
4043  dhmax = dh
4044  end if
4045  if (abs(resid) > abs(residmax)) then
4046  locresidmax = n
4047  residmax = resid
4048  end if
4049  if (abs(dgwf) > abs(dgwfmax)) then
4050  locdgwfmax = n
4051  dgwfmax = dgwf
4052  end if
4053  if (abs(dqout) > abs(dqoutmax)) then
4054  locdqoutmax = n
4055  dqoutmax = dqout
4056  end if
4057  if (abs(dqfrommvr) > abs(dqfrommvrmax)) then
4058  dqfrommvrmax = dqfrommvr
4059  locdqfrommvrmax = n
4060  end if
4061  end if
4062  end do final_check
4063  !
4064  ! -- set dpak and cpak
4065  if (abs(dhmax) > abs(dpak)) then
4066  ipak = locdhmax
4067  dpak = dhmax
4068  write (cloc, "(a,'-',a)") &
4069  trim(this%packName), 'stage'
4070  cpak = trim(cloc)
4071  end if
4072  if (abs(residmax) > abs(dpak)) then
4073  ipak = locresidmax
4074  dpak = residmax
4075  write (cloc, "(a,'-',a)") &
4076  trim(this%packName), 'residual'
4077  cpak = trim(cloc)
4078  end if
4079  if (abs(dgwfmax) > abs(dpak)) then
4080  ipak = locdgwfmax
4081  dpak = dgwfmax
4082  write (cloc, "(a,'-',a)") &
4083  trim(this%packName), 'gwf'
4084  cpak = trim(cloc)
4085  end if
4086  if (this%noutlets > 0) then
4087  if (abs(dqoutmax) > abs(dpak)) then
4088  ipak = locdqoutmax
4089  dpak = dqoutmax
4090  write (cloc, "(a,'-',a)") &
4091  trim(this%packName), 'outlet'
4092  cpak = trim(cloc)
4093  end if
4094  end if
4095  if (this%imover == 1) then
4096  if (abs(dqfrommvrmax) > abs(dpak)) then
4097  ipak = locdqfrommvrmax
4098  dpak = dqfrommvrmax
4099  write (cloc, "(a,'-',a)") trim(this%packName), 'qfrommvr'
4100  cpak = trim(cloc)
4101  end if
4102  end if
4103  !
4104  ! -- write convergence data to package csv
4105  if (this%ipakcsv /= 0) then
4106  !
4107  ! -- write the data
4108  call this%pakcsvtab%add_term(innertot)
4109  call this%pakcsvtab%add_term(totim)
4110  call this%pakcsvtab%add_term(kper)
4111  call this%pakcsvtab%add_term(kstp)
4112  call this%pakcsvtab%add_term(kiter)
4113  call this%pakcsvtab%add_term(dhmax)
4114  call this%pakcsvtab%add_term(locdhmax)
4115  call this%pakcsvtab%add_term(residmax)
4116  call this%pakcsvtab%add_term(locresidmax)
4117  call this%pakcsvtab%add_term(dgwfmax)
4118  call this%pakcsvtab%add_term(locdgwfmax)
4119  if (this%noutlets > 0) then
4120  call this%pakcsvtab%add_term(dqoutmax)
4121  call this%pakcsvtab%add_term(locdqoutmax)
4122  end if
4123  if (this%imover == 1) then
4124  call this%pakcsvtab%add_term(dqfrommvrmax)
4125  call this%pakcsvtab%add_term(locdqfrommvrmax)
4126  end if
4127  !
4128  ! -- finalize the package csv
4129  if (iend == 1) then
4130  call this%pakcsvtab%finalize_table()
4131  end if
4132  end if
4133  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 3589 of file gwf-lak.f90.

3590  ! -- dummy
3591  class(LakType) :: this
3592  ! -- local
3593  integer(I4B) :: j, n
3594  integer(I4B) :: igwfnode
3595  real(DP) :: hlak, bottom_lake
3596  !
3597  ! -- save groundwater seepage for lake solution
3598  do n = 1, this%nlakes
3599  this%seep0(n) = this%seep(n)
3600  end do
3601  !
3602  ! -- save variables for convergence check
3603  do n = 1, this%nlakes
3604  this%s0(n) = this%xnewpak(n)
3605  call this%lak_calculate_exchange(n, this%s0(n), this%qgwf0(n))
3606  end do
3607  !
3608  ! -- find highest active cell
3609  do n = 1, this%nlakes
3610  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3611  ! -- skip horizontal connections
3612  if (this%ictype(j) /= 0) then
3613  cycle
3614  end if
3615  igwfnode = this%nodesontop(j)
3616  if (this%ibound(igwfnode) == 0) then
3617  call this%dis%highest_active(igwfnode, this%ibound)
3618  end if
3619  this%nodelist(j) = igwfnode
3620  this%gwfconn(j) = igwfnode
3621  end do
3622  end do
3623  !
3624  ! -- reset ibound for cells where lake stage is above the bottom
3625  ! of the lake in the cell or the lake is inactive - only applied to
3626  ! vertical connections
3627  do n = 1, this%nlakes
3628  !
3629  hlak = this%xnewpak(n)
3630  !
3631  ! -- Go through lake connections
3632  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3633  !
3634  ! -- assign gwf node number
3635  igwfnode = this%gwfconn(j)
3636  !
3637  ! -- skip inactive or constant head GWF cells
3638  if (this%ibound(igwfnode) < 1) then
3639  cycle
3640  end if
3641  !
3642  ! -- skip horizontal connections
3643  if (this%ictype(j) /= 0) then
3644  cycle
3645  end if
3646  !
3647  ! -- skip embedded lakes
3648  if (this%ictype(j) == 2 .or. this%ictype(j) == 3) then
3649  cycle
3650  end if
3651  !
3652  ! -- Mark ibound for wet lakes or inactive lakes; reset to 1 otherwise
3653  bottom_lake = this%belev(j)
3654  if (hlak > bottom_lake .or. this%iboundpak(n) == 0) then
3655  this%ibound(igwfnode) = iwetlake
3656  else
3657  this%ibound(igwfnode) = 1
3658  end if
3659  end do
3660  !
3661  end do
3662  !
3663  ! -- Store the lake stage and cond in bound array for other
3664  ! packages, such as the BUY package
3665  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 2895 of file gwf-lak.f90.

2896  ! -- modules
2897  use simmodule, only: store_error
2898  ! -- return
2899  integer(I4B) :: ierr
2900  ! -- dummy
2901  class(LakType), intent(inout) :: this
2902  integer(I4B), intent(in) :: itemno
2903  ! -- local
2904  integer(I4B) :: ival
2905  !
2906  ierr = 0
2907  ival = abs(itemno)
2908  if (itemno > 0) then
2909  if (ival < 1 .or. ival > this%nlakes) then
2910  write (errmsg, '(a,1x,i0,1x,a,1x,i0,a)') &
2911  'LAKENO', itemno, 'must be greater than 0 and less than or equal to', &
2912  this%nlakes, '.'
2913  call store_error(errmsg)
2914  ierr = 1
2915  end if
2916  else
2917  if (ival < 1 .or. ival > this%noutlets) then
2918  write (errmsg, '(a,1x,i0,1x,a,1x,i0,a)') &
2919  'IOUTLET', itemno, 'must be greater than 0 and less than or equal to', &
2920  this%noutlets, '.'
2921  call store_error(errmsg)
2922  ierr = 1
2923  end if
2924  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_checkin_deprecated_names()

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

IDM integration (#3021) moved several lake and outlet variables into the input context, renaming some, and renamed the lake connection cell array. The legacy solver refactor (#2976) renamed the fallback variables. These aliases share memory with the current variables so that programs addressing them through the API by their old package-path names continue to resolve; each use is reported as deprecated. Outlet names are only aliased when outlets are present.

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

589  ! -- modules
592  ! -- dummy
593  class(LakType), intent(inout) :: this
594  ! -- local
595  real(DP), dimension(:, :), pointer, contiguous :: aux => null()
596  integer(I4B) :: isize
597  ! -- code
598  !
599  ! -- lake period data
600  call mem_alias_deprecated(this%stage, 'STAGE', this%memoryPath, &
601  'STAGE', this%input_mempath, '6.8.2')
602  call mem_alias_deprecated(this%rainfall, 'RAINFALL', this%memoryPath, &
603  'RAINFALL', this%input_mempath, '6.8.2')
604  call mem_alias_deprecated(this%evaporation, 'EVAPORATION', &
605  this%memoryPath, 'EVAPORATION', &
606  this%input_mempath, '6.8.2')
607  call mem_alias_deprecated(this%runoff, 'RUNOFF', this%memoryPath, &
608  'RUNOFF', this%input_mempath, '6.8.2')
609  call mem_alias_deprecated(this%inflow, 'INFLOW', this%memoryPath, &
610  'INFLOW', this%input_mempath, '6.8.2')
611  call mem_alias_deprecated(this%withdrawal, 'WITHDRAWAL', this%memoryPath, &
612  'WITHDRAWAL', this%input_mempath, '6.8.2')
613  !
614  ! -- outlet period data
615  call mem_alias_deprecated(this%outrate, 'OUTRATE', this%memoryPath, &
616  'RATE', this%input_mempath, '6.8.2')
617  call mem_alias_deprecated(this%outinvert, 'OUTINVERT', this%memoryPath, &
618  'INVERT', this%input_mempath, '6.8.2')
619  call mem_alias_deprecated(this%outwidth, 'OUTWIDTH', this%memoryPath, &
620  'WIDTH', this%input_mempath, '6.8.2')
621  call mem_alias_deprecated(this%outslope, 'OUTSLOPE', this%memoryPath, &
622  'SLOPE', this%input_mempath, '6.8.2')
623  call mem_alias_deprecated(this%outrough, 'OUTROUGH', this%memoryPath, &
624  'ROUGH', this%input_mempath, '6.8.2')
625  !
626  ! -- lake auxiliary values, present (possibly empty) in the input context
627  call get_isize('AUX', this%input_mempath, isize)
628  if (isize >= 0) then
629  call mem_setptr(aux, 'AUX', this%input_mempath)
630  call mem_alias_deprecated(aux, 'LAUXVAR', this%memoryPath, &
631  'AUX', this%input_mempath, '6.8.2')
632  end if
633  !
634  ! -- renamed at the package path: CELLID by IDM integration (#3021),
635  ! IFALLBACK and IFORCEFB by the legacy solver refactor (#2976)
636  call mem_alias_deprecated(this%gwfconn, 'CELLID', this%memoryPath, &
637  'GWFCONN', this%memoryPath, '6.8.2')
638  call mem_alias_deprecated(this%ilegacy, 'IFALLBACK', this%memoryPath, &
639  'ILEGACY', this%memoryPath, '6.8.2')
640  call mem_alias_deprecated(this%iforceleg, 'IFORCEFB', this%memoryPath, &
641  'IFORCELEG', this%memoryPath, '6.8.2')
Previous variable names checked in as deprecated aliases.
Definition: MemoryAlias.f90:7
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
Here is the call graph for this function:

◆ 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 4138 of file gwf-lak.f90.

4139  ! -- modules
4140  use tdismodule, only: delt
4141  ! -- dummy
4142  class(LakType), intent(inout) :: this
4143  real(DP), dimension(:), intent(in) :: x
4144  real(DP), dimension(:), contiguous, intent(inout) :: flowja
4145  integer(I4B), optional, intent(in) :: iadv
4146  ! -- local
4147  real(DP) :: rrate
4148  real(DP) :: chratin, chratout
4149  ! -- for budget
4150  integer(I4B) :: j, n, igwfnode
4151  real(DP) :: hlak, head, flow, dqdh
4152  real(DP) :: v0, v1, sa, sf
4153  !
4154  call this%lak_solve(update=.false.)
4155  !
4156  ! -- for the IMPLICIT formulation, report the lake terms with the same
4157  ! treatment that lak_fc_implicit assembled into the matrix, so the lake
4158  ! and gwf-cell budgets match the solved flows. lak_solve above set these
4159  ! from the substitution path (hard-cutoff seepage; availability-limited
4160  ! losses), which is correct for a lake on the legacy solver but
4161  ! not for an implicit lake, so overwrite them for the implicit
4162  ! (non-legacy) lakes only.
4163  if (this%iimplicit /= 0) then
4164  do n = 1, this%nlakes
4165  if (this%iboundpak(n) < 1 .or. this%ilegacy(n) /= 0) cycle
4166  hlak = this%xnewpak(n)
4167  !
4168  ! -- lakebed seepage: use the same exchange the matrix assembled
4169  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4170  igwfnode = this%gwfconn(j)
4171  if (this%ibound(igwfnode) < 1) cycle
4172  head = this%xnew(igwfnode)
4173  call this%lak_calculate_conn_exchange_deriv(n, j, hlak, head, &
4174  flow, dqdh=dqdh)
4175  this%hcof(j) = -dqdh
4176  this%rhs(j) = -dqdh * head + flow
4177  end do
4178  !
4179  ! -- stage-driven losses: the matrix (lak_budget_nogwf) ramps
4180  ! evaporation and withdrawal toward zero as the lake approaches its
4181  ! bottom with the surfdep factor (sf) rather than the substitution
4182  ! solver's availability limiting, so report them the same way. This
4183  ! keeps the lake budget closed for a drying lake. (The outlet
4184  ! outflow is already near zero at the bottom, as its invert is above
4185  ! the lake bottom, and the storage term reflects the solved stage.)
4186  call this%lak_calculate_sarea(n, hlak, sa)
4187  sf = done
4188  if (this%surfdep > dzero) then
4189  sf = squadraticsaturation(this%lakebot(n) + this%surfdep, &
4190  this%lakebot(n), hlak)
4191  end if
4192  this%evap(n) = -this%evaporation(n) * sa * sf
4193  this%withr(n) = -this%withdrawal(n) * sf
4194  end do
4195  end if
4196  !
4197  ! -- call base functionality in bnd_cq. This will calculate lake-gwf flows
4198  ! and put them into this%simvals
4199  call this%BndType%bnd_cq(x, flowja, iadv=1)
4200  !
4201  ! -- calculate several budget terms
4202  chratin = dzero
4203  chratout = dzero
4204  do n = 1, this%nlakes
4205  this%chterm(n) = dzero
4206  if (this%iboundpak(n) == 0) cycle
4207  hlak = this%xnewpak(n)
4208  call this%lak_calculate_vol(n, hlak, v1)
4209  !
4210  ! -- add budget terms for active lakes
4211  if (this%iboundpak(n) /= 0) then
4212  !
4213  ! -- rainfall
4214  rrate = this%precip(n)
4215  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4216  !
4217  ! -- evaporation
4218  rrate = this%evap(n)
4219  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4220  !
4221  ! -- runoff
4222  rrate = this%runoff(n)
4223  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4224  !
4225  ! -- inflow
4226  rrate = this%inflow(n)
4227  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4228  !
4229  ! -- withdrawals
4230  rrate = this%withr(n)
4231  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4232  !
4233  ! -- add lake storage changes
4234  rrate = dzero
4235  if (this%iboundpak(n) > 0) then
4236  if (this%gwfiss /= 1) then
4237  call this%lak_calculate_vol(n, this%xoldpak(n), v0)
4238  rrate = -(v1 - v0) / delt
4239  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4240  end if
4241  end if
4242  this%qsto(n) = rrate
4243  !
4244  ! -- add external outlets
4245  call this%lak_get_external_outlet(n, rrate)
4246  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4247  !
4248  ! -- add mover terms
4249  if (this%imover == 1) then
4250  if (this%iboundpak(n) /= 0) then
4251  rrate = this%pakmvrobj%get_qfrommvr(n)
4252  else
4253  rrate = dzero
4254  end if
4255  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4256  end if
4257  end if
4258  end do
4259  !
4260  ! -- gwf flow and constant flow to lake
4261  do n = 1, this%nlakes
4262  rrate = dzero
4263  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4264  ! simvals is from aquifer perspective, and so it is positive
4265  ! for flow into the aquifer. Need to switch sign for lake
4266  ! perspective.
4267  rrate = -this%simvals(j)
4268  this%qleak(j) = rrate
4269  if (this%iboundpak(n) /= 0) then
4270  call this%lak_accumulate_chterm(n, rrate, chratin, chratout)
4271  end if
4272  end do
4273  end do
4274  !
4275  ! -- fill the budget object
4276  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 399 of file gwf-lak.f90.

401  ! -- modules
403  ! -- dummy
404  class(BndType), pointer :: packobj
405  integer(I4B), intent(in) :: id
406  integer(I4B), intent(in) :: ibcnum
407  integer(I4B), intent(in) :: inunit
408  integer(I4B), intent(in) :: iout
409  character(len=*), intent(in) :: namemodel
410  character(len=*), intent(in) :: pakname
411  character(len=*), intent(in) :: mempath
412  ! -- local
413  type(LakType), pointer :: lakobj
414  !
415  ! -- allocate the object and assign values to object variables
416  allocate (lakobj)
417  packobj => lakobj
418  !
419  ! -- create name and memory path
420  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
421  packobj%text = text
422  !
423  ! -- allocate scalars
424  call lakobj%lak_allocate_scalars()
425  !
426  ! -- initialize package
427  call packobj%pack_initialize()
428  !
429  packobj%inunit = inunit
430  packobj%iout = iout
431  packobj%id = id
432  packobj%ibcnum = ibcnum
433  packobj%ncolbnd = 3
434  packobj%iscloc = 0 ! not supported
435  packobj%isadvpak = 1
436  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 4406 of file gwf-lak.f90.

4407  ! -- modules
4409  ! -- dummy
4410  class(LakType) :: this
4411  !
4412  ! -- nullify input context runtime pointers
4413  call this%input%destroy()
4414  !
4415  ! -- arrays
4416  deallocate (this%lakename)
4417  deallocate (this%status)
4418  deallocate (this%clakbudget)
4419  call mem_deallocate(this%dbuff)
4420  deallocate (this%cauxcbc)
4421  call mem_deallocate(this%qauxcbc)
4422  call mem_deallocate(this%qleak)
4423  call mem_deallocate(this%holdconn)
4424  call mem_deallocate(this%qsto)
4425  call mem_deallocate(this%denseterms)
4426  call mem_deallocate(this%viscratios)
4427  !
4428  ! -- tables
4429  if (this%ntables > 0) then
4430  call mem_deallocate(this%ialaktab)
4431  call mem_deallocate(this%tabstage)
4432  call mem_deallocate(this%tabvolume)
4433  call mem_deallocate(this%tabsarea)
4434  call mem_deallocate(this%tabwarea)
4435  end if
4436  !
4437  ! -- budobj
4438  call this%budobj%budgetobject_da()
4439  deallocate (this%budobj)
4440  nullify (this%budobj)
4441  !
4442  ! -- outlets
4443  if (this%noutlets > 0) then
4444  call mem_deallocate(this%lakein)
4445  call mem_deallocate(this%lakeout)
4446  call mem_deallocate(this%iouttype)
4447  ! -- outrate/outinvert/outwidth/outrough/outslope are live aliases
4448  ! into the input context's permanent arrays, not owned here
4449  call mem_deallocate(this%simoutrate)
4450  call mem_deallocate(this%outlet_invert_set)
4451  call mem_deallocate(this%outlet_width_set)
4452  call mem_deallocate(this%outlet_rough_set)
4453  call mem_deallocate(this%outlet_slope_set)
4454  end if
4455  !
4456  ! -- stage table
4457  if (this%iprhed > 0) then
4458  call this%stagetab%table_da()
4459  deallocate (this%stagetab)
4460  nullify (this%stagetab)
4461  end if
4462  !
4463  ! -- package csv table
4464  if (this%ipakcsv > 0) then
4465  if (associated(this%pakcsvtab)) then
4466  call this%pakcsvtab%table_da()
4467  deallocate (this%pakcsvtab)
4468  nullify (this%pakcsvtab)
4469  end if
4470  end if
4471  !
4472  ! -- scalars
4473  call mem_deallocate(this%iprhed)
4474  call mem_deallocate(this%istageout)
4475  call mem_deallocate(this%ibudgetout)
4476  call mem_deallocate(this%ibudcsv)
4477  call mem_deallocate(this%ipakcsv)
4478  if (allocated(this%pakcsvfile)) deallocate (this%pakcsvfile)
4479  call mem_deallocate(this%nlakes)
4480  call mem_deallocate(this%noutlets)
4481  call mem_deallocate(this%ntables)
4482  call mem_deallocate(this%convlength)
4483  call mem_deallocate(this%convtime)
4484  call mem_deallocate(this%outdmax)
4485  call mem_deallocate(this%igwhcopt)
4486  call mem_deallocate(this%iconvchk)
4487  call mem_deallocate(this%maxlakit)
4488  call mem_deallocate(this%surfdep)
4489  call mem_deallocate(this%dmaxchg)
4490  call mem_deallocate(this%delh)
4491  call mem_deallocate(this%check_attr)
4492  call mem_deallocate(this%iimplicit)
4493  call mem_deallocate(this%iforceleg)
4494  call mem_deallocate(this%iforceleglak)
4495  call mem_deallocate(this%bditems)
4496  call mem_deallocate(this%cbcauxitems)
4497  call mem_deallocate(this%idense)
4498  !
4499  call mem_deallocate(this%nlakeconn)
4500  call mem_deallocate(this%idxlakeconn)
4501  call mem_deallocate(this%ntabrow)
4502  call mem_deallocate(this%strt)
4503  call mem_deallocate(this%laketop)
4504  call mem_deallocate(this%lakebot)
4505  call mem_deallocate(this%sareamax)
4506  ! -- stage/rainfall/evaporation/runoff/inflow/withdrawal are live aliases
4507  ! into the input context's permanent arrays, not owned here
4508  call mem_deallocate(this%avail)
4509  call mem_deallocate(this%lkgwsink)
4510  call mem_deallocate(this%ncncvr)
4511  call mem_deallocate(this%ilegacy)
4512  call mem_deallocate(this%nstuck)
4513  call mem_deallocate(this%surfin)
4514  call mem_deallocate(this%surfout)
4515  call mem_deallocate(this%surfout1)
4516  call mem_deallocate(this%precip)
4517  call mem_deallocate(this%precip1)
4518  call mem_deallocate(this%evap)
4519  call mem_deallocate(this%evap1)
4520  call mem_deallocate(this%evapo)
4521  call mem_deallocate(this%withr)
4522  call mem_deallocate(this%withr1)
4523  call mem_deallocate(this%flwin)
4524  call mem_deallocate(this%flwiter)
4525  call mem_deallocate(this%flwiter1)
4526  call mem_deallocate(this%seep)
4527  call mem_deallocate(this%seep1)
4528  call mem_deallocate(this%seep0)
4529  call mem_deallocate(this%stageiter)
4530  call mem_deallocate(this%chterm)
4531  !
4532  ! -- lake boundary and stages
4533  if (this%iimplicit == 0) then
4534  call mem_deallocate(this%iboundpak)
4535  call mem_deallocate(this%xnewpak)
4536  else
4537  ! -- iboundpak aliases the global ibound (not deallocated here); xnewpak
4538  ! was checked in to the global x vector
4539  call mem_deallocate(this%xnewpak, 'XNEWPAK', this%memoryPath)
4540  end if
4541  call mem_deallocate(this%xoldpak)
4542  !
4543  ! -- implicit-formulation matrix-mapping arrays
4544  call mem_deallocate(this%idxlocnode)
4545  call mem_deallocate(this%idxdiag)
4546  call mem_deallocate(this%idxoffdglo)
4547  call mem_deallocate(this%idxsymdglo)
4548  call mem_deallocate(this%idxsymoffdglo)
4549  !
4550  ! -- lake iteration variables
4551  call mem_deallocate(this%iseepc)
4552  call mem_deallocate(this%idhc)
4553  call mem_deallocate(this%en1)
4554  call mem_deallocate(this%en2)
4555  call mem_deallocate(this%r1)
4556  call mem_deallocate(this%r2)
4557  call mem_deallocate(this%dh0)
4558  call mem_deallocate(this%s0)
4559  call mem_deallocate(this%qgwf0)
4560  !
4561  ! -- lake connection variables
4562  call mem_deallocate(this%imap)
4563  call mem_deallocate(this%gwfconn)
4564  call mem_deallocate(this%nodesontop)
4565  call mem_deallocate(this%ictype)
4566  call mem_deallocate(this%bedleak)
4567  call mem_deallocate(this%belev)
4568  call mem_deallocate(this%telev)
4569  call mem_deallocate(this%connlength)
4570  call mem_deallocate(this%connwidth)
4571  call mem_deallocate(this%sarea)
4572  call mem_deallocate(this%warea)
4573  call mem_deallocate(this%satcond)
4574  call mem_deallocate(this%simcond)
4575  call mem_deallocate(this%simlakgw)
4576  !
4577  ! -- pointers to gwf variables
4578  nullify (this%gwfiss)
4579  !
4580  ! -- Parent object
4581  call this%BndExtType%bnd_da()

◆ lak_df_obs()

subroutine lakmodule::lak_df_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) :: indx
4770  !
4771  ! -- Store obs type and assign procedure pointer
4772  ! for stage observation type.
4773  call this%obs%StoreObsType('stage', .false., indx)
4774  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4775  !
4776  ! -- Store obs type and assign procedure pointer
4777  ! for ext-inflow observation type.
4778  call this%obs%StoreObsType('ext-inflow', .true., indx)
4779  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4780  !
4781  ! -- Store obs type and assign procedure pointer
4782  ! for outlet-inflow observation type.
4783  call this%obs%StoreObsType('outlet-inflow', .true., indx)
4784  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4785  !
4786  ! -- Store obs type and assign procedure pointer
4787  ! for inflow observation type.
4788  call this%obs%StoreObsType('inflow', .true., indx)
4789  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4790  !
4791  ! -- Store obs type and assign procedure pointer
4792  ! for from-mvr observation type.
4793  call this%obs%StoreObsType('from-mvr', .true., indx)
4794  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4795  !
4796  ! -- Store obs type and assign procedure pointer
4797  ! for rainfall observation type.
4798  call this%obs%StoreObsType('rainfall', .true., indx)
4799  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4800  !
4801  ! -- Store obs type and assign procedure pointer
4802  ! for runoff observation type.
4803  call this%obs%StoreObsType('runoff', .true., indx)
4804  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4805  !
4806  ! -- Store obs type and assign procedure pointer
4807  ! for lak observation type.
4808  call this%obs%StoreObsType('lak', .true., indx)
4809  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4810  !
4811  ! -- Store obs type and assign procedure pointer
4812  ! for evaporation observation type.
4813  call this%obs%StoreObsType('evaporation', .true., indx)
4814  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4815  !
4816  ! -- Store obs type and assign procedure pointer
4817  ! for withdrawal observation type.
4818  call this%obs%StoreObsType('withdrawal', .true., indx)
4819  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4820  !
4821  ! -- Store obs type and assign procedure pointer
4822  ! for ext-outflow observation type.
4823  call this%obs%StoreObsType('ext-outflow', .true., indx)
4824  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4825  !
4826  ! -- Store obs type and assign procedure pointer
4827  ! for to-mvr observation type.
4828  call this%obs%StoreObsType('to-mvr', .true., indx)
4829  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4830  !
4831  ! -- Store obs type and assign procedure pointer
4832  ! for storage observation type.
4833  call this%obs%StoreObsType('storage', .true., indx)
4834  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4835  !
4836  ! -- Store obs type and assign procedure pointer
4837  ! for constant observation type.
4838  call this%obs%StoreObsType('constant', .true., indx)
4839  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4840  !
4841  ! -- Store obs type and assign procedure pointer
4842  ! for outlet observation type.
4843  call this%obs%StoreObsType('outlet', .true., indx)
4844  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4845  !
4846  ! -- Store obs type and assign procedure pointer
4847  ! for volume observation type.
4848  call this%obs%StoreObsType('volume', .true., indx)
4849  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4850  !
4851  ! -- Store obs type and assign procedure pointer
4852  ! for surface-area observation type.
4853  call this%obs%StoreObsType('surface-area', .true., indx)
4854  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4855  !
4856  ! -- Store obs type and assign procedure pointer
4857  ! for wetted-area observation type.
4858  call this%obs%StoreObsType('wetted-area', .true., indx)
4859  this%obs%obsData(indx)%ProcessIdPtr => lak_process_obsid
4860  !
4861  ! -- Store obs type and assign procedure pointer
4862  ! for conductance observation type.
4863  call this%obs%StoreObsType('conductance', .true., indx)
4864  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 2393 of file gwf-lak.f90.

2395  ! -- dummy
2396  class(LakType), intent(inout) :: this
2397  integer(I4B), intent(in) :: iflag
2398  integer(I4B), intent(in) :: ilak
2399  integer(I4B), intent(in) :: iconn
2400  integer(I4B), intent(inout) :: idry
2401  real(DP), intent(in) :: stage
2402  real(DP), intent(in) :: head
2403  real(DP), intent(inout) :: flow
2404  real(DP), intent(inout) :: source
2405  real(DP), intent(inout), optional :: gwfhcof
2406  real(DP), intent(inout), optional :: gwfrhs
2407  ! -- local
2408  real(DP) :: gwfhcof0, gwfrhs0
2409  !
2410  flow = dzero
2411  idry = 0
2412  call this%lak_calculate_conn_exchange(ilak, iconn, stage, head, flow, &
2413  gwfhcof0, gwfrhs0)
2414  if (iflag == 1) then
2415  if (flow > dzero) then
2416  source = source + flow
2417  end if
2418  else if (iflag == 2) then
2419  if (-flow > source) then
2420  flow = -source
2421  source = dzero
2422  idry = 1
2423  else if (flow < dzero) then
2424  source = source + flow
2425  end if
2426  end if
2427  !
2428  ! -- Set gwfhcof and gwfrhs if present
2429  if (present(gwfhcof)) gwfhcof = gwfhcof0
2430  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 5678 of file gwf-lak.f90.

5679  ! -- dummy
5680  class(LakType), intent(inout) :: this
5681  integer(I4B), intent(in) :: n
5682  integer(I4B), intent(in) :: ncnv
5683  ! -- local
5684  integer(I4B) :: i
5685  integer(I4B) :: j
5686  integer(I4B) :: igwfnode
5687  integer(I4B) :: idry
5688  integer(I4B) :: idry1
5689  real(DP) :: hlak
5690  real(DP) :: head
5691  real(DP) :: qlakgw
5692  real(DP) :: qlakgw1
5693  real(DP) :: gwfhcof
5694  real(DP) :: gwfrhs
5695  real(DP) :: delh
5696  !
5697  delh = this%delh
5698  !
5699  ! -- skip inactive lakes
5700  if (this%iboundpak(n) == 0) return
5701  !
5702  estseep: do i = 1, 2
5703  ! - set xoldpak to xnewpak if steady-state
5704  if (this%gwfiss /= 0) then
5705  this%xoldpak(n) = this%xnewpak(n)
5706  end if
5707  hlak = this%xnewpak(n)
5708  calcconnseep: do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5709  igwfnode = this%gwfconn(j)
5710  head = this%xnew(igwfnode)
5711  if (this%ncncvr(n) /= 2) then
5712  if (this%ibound(igwfnode) > 0) then
5713  call this%lak_estimate_conn_exchange(i, n, j, idry, hlak, &
5714  head, qlakgw, &
5715  this%flwiter(n), &
5716  gwfhcof, gwfrhs)
5717  call this%lak_estimate_conn_exchange(i, n, j, idry1, &
5718  hlak + delh, head, qlakgw1, &
5719  this%flwiter1(n))
5720  !
5721  ! -- add to gwf matrix
5722  if (ncnv == 0 .and. i == 2) then
5723  if (j == this%maxbound) then
5724  this%ncncvr(n) = 2
5725  end if
5726  if (idry /= 1) then
5727  this%hcof(j) = gwfhcof
5728  this%rhs(j) = gwfrhs
5729  else
5730  this%hcof(j) = dzero
5731  this%rhs(j) = qlakgw
5732  end if
5733  end if
5734  if (i == 2) then
5735  this%seep(n) = this%seep(n) + qlakgw
5736  this%seep1(n) = this%seep1(n) + qlakgw1
5737  end if
5738  end if
5739  end if
5740  end do calcconnseep
5741  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 3670 of file gwf-lak.f90.

3671  ! -- dummy
3672  class(LakType) :: this
3673  real(DP), dimension(:), intent(inout) :: rhs
3674  integer(I4B), dimension(:), intent(in) :: ia
3675  integer(I4B), dimension(:), intent(in) :: idxglo
3676  class(MatrixBaseType), pointer :: matrix_sln
3677  ! -- local
3678  integer(I4B) :: j, n
3679  integer(I4B) :: igwfnode
3680  integer(I4B) :: ipossymd
3681  !
3682  ! -- pakmvrobj fc
3683  if (this%imover == 1) then
3684  call this%pakmvrobj%fc()
3685  end if
3686  !
3687  ! -- implicit formulation: assemble the lake equations directly into the
3688  ! groundwater flow matrix instead of solving the stage by substitution
3689  if (this%iimplicit /= 0) then
3690  call this%lak_fc_implicit(rhs, matrix_sln)
3691  return
3692  end if
3693  !
3694  ! -- legacy formulation: solve the lake stage by substitution, then add the
3695  ! resulting lake-aquifer exchange terms to the groundwater flow matrix
3696  call this%lak_solve()
3697  do n = 1, this%nlakes
3698  if (this%iboundpak(n) == 0) cycle
3699  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3700  igwfnode = this%gwfconn(j)
3701  if (this%ibound(igwfnode) < 1) cycle
3702  ipossymd = idxglo(ia(igwfnode))
3703  call matrix_sln%add_value_pos(ipossymd, this%hcof(j))
3704  rhs(igwfnode) = rhs(igwfnode) + this%rhs(j)
3705  end do
3706  end do

◆ lak_fill_budobj()

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

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

6196  ! -- dummy
6197  class(LakType) :: this
6198  ! -- local
6199  integer(I4B) :: naux
6200  real(DP), dimension(:), allocatable :: auxvartmp
6201  !integer(I4B) :: i
6202  integer(I4B) :: j
6203  integer(I4B) :: n
6204  integer(I4B) :: n1
6205  integer(I4B) :: n2
6206  integer(I4B) :: ii
6207  integer(I4B) :: jj
6208  integer(I4B) :: idx
6209  integer(I4B) :: nlen
6210  real(DP) :: v, v1
6211  real(DP) :: q
6212  real(DP) :: lkstg, gwhead, wa
6213  !
6214  ! -- initialize counter
6215  idx = 0
6216 
6217  ! -- FLOW JA FACE
6218  nlen = 0
6219  do n = 1, this%noutlets
6220  if (this%lakein(n) > 0 .and. this%lakeout(n) > 0) then
6221  nlen = nlen + 1
6222  end if
6223  end do
6224  if (nlen > 0) then
6225  idx = idx + 1
6226  call this%budobj%budterm(idx)%reset(2 * nlen)
6227  do n = 1, this%noutlets
6228  n1 = this%lakein(n)
6229  n2 = this%lakeout(n)
6230  if (n1 > 0 .and. n2 > 0) then
6231  q = this%simoutrate(n)
6232  if (this%imover == 1) then
6233  q = q + this%pakmvrobj%get_qtomvr(n)
6234  end if
6235  call this%budobj%budterm(idx)%update_term(n1, n2, q)
6236  call this%budobj%budterm(idx)%update_term(n2, n1, -q)
6237  end if
6238  end do
6239  end if
6240  !
6241  ! -- GWF (LEAKAGE)
6242  idx = idx + 1
6243  call this%budobj%budterm(idx)%reset(this%maxbound)
6244  do n = 1, this%nlakes
6245  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
6246  n2 = this%gwfconn(j)
6247  q = this%qleak(j)
6248  lkstg = this%xnewpak(n)
6249  ! -- For the case when the lak stage is exactly equal
6250  ! to the lake bottom, the wetted area is not returned
6251  ! equal to 0.0
6252  gwhead = this%xnew(n2)
6253  call this%lak_calculate_conn_warea(n, j, lkstg, gwhead, wa)
6254  ! -- For thermal conduction between a lake and a gw cell,
6255  ! the shared wetted area should be reset to zero when the lake
6256  ! stage is below the cell bottom
6257  if (this%belev(j) > lkstg) wa = dzero
6258  this%qauxcbc(1) = wa
6259  call this%budobj%budterm(idx)%update_term(n, n2, q, this%qauxcbc)
6260  end do
6261  end do
6262  !
6263  ! -- RAIN
6264  idx = idx + 1
6265  call this%budobj%budterm(idx)%reset(this%nlakes)
6266  do n = 1, this%nlakes
6267  q = this%precip(n)
6268  call this%budobj%budterm(idx)%update_term(n, n, q)
6269  end do
6270  !
6271  ! -- EVAPORATION
6272  idx = idx + 1
6273  call this%budobj%budterm(idx)%reset(this%nlakes)
6274  do n = 1, this%nlakes
6275  q = this%evap(n)
6276  call this%budobj%budterm(idx)%update_term(n, n, q)
6277  end do
6278  !
6279  ! -- RUNOFF
6280  idx = idx + 1
6281  call this%budobj%budterm(idx)%reset(this%nlakes)
6282  do n = 1, this%nlakes
6283  q = this%runoff(n)
6284  call this%budobj%budterm(idx)%update_term(n, n, q)
6285  end do
6286  !
6287  ! -- INFLOW
6288  idx = idx + 1
6289  call this%budobj%budterm(idx)%reset(this%nlakes)
6290  do n = 1, this%nlakes
6291  q = this%inflow(n)
6292  call this%budobj%budterm(idx)%update_term(n, n, q)
6293  end do
6294  !
6295  ! -- WITHDRAWAL
6296  idx = idx + 1
6297  call this%budobj%budterm(idx)%reset(this%nlakes)
6298  do n = 1, this%nlakes
6299  q = this%withr(n)
6300  call this%budobj%budterm(idx)%update_term(n, n, q)
6301  end do
6302  !
6303  ! -- EXTERNAL OUTFLOW
6304  idx = idx + 1
6305  call this%budobj%budterm(idx)%reset(this%nlakes)
6306  do n = 1, this%nlakes
6307  call this%lak_get_external_outlet(n, q)
6308  ! subtract tomover from external outflow
6309  call this%lak_get_external_mover(n, v)
6310  q = q + v
6311  call this%budobj%budterm(idx)%update_term(n, n, q)
6312  end do
6313  !
6314  ! -- STORAGE
6315  idx = idx + 1
6316  call this%budobj%budterm(idx)%reset(this%nlakes)
6317  do n = 1, this%nlakes
6318  call this%lak_calculate_vol(n, this%xnewpak(n), v1)
6319  q = this%qsto(n)
6320  this%qauxcbc(1) = v1
6321  call this%budobj%budterm(idx)%update_term(n, n, q, this%qauxcbc)
6322  end do
6323  !
6324  ! -- CONSTANT FLOW
6325  idx = idx + 1
6326  call this%budobj%budterm(idx)%reset(this%nlakes)
6327  do n = 1, this%nlakes
6328  q = this%chterm(n)
6329  call this%budobj%budterm(idx)%update_term(n, n, q)
6330  end do
6331  !
6332  ! -- MOVER
6333  if (this%imover == 1) then
6334  !
6335  ! -- FROM MOVER
6336  idx = idx + 1
6337  call this%budobj%budterm(idx)%reset(this%nlakes)
6338  do n = 1, this%nlakes
6339  q = this%pakmvrobj%get_qfrommvr(n)
6340  call this%budobj%budterm(idx)%update_term(n, n, q)
6341  end do
6342  !
6343  ! -- TO MOVER
6344  idx = idx + 1
6345  call this%budobj%budterm(idx)%reset(this%noutlets)
6346  do n = 1, this%noutlets
6347  n1 = this%lakein(n)
6348  q = this%pakmvrobj%get_qtomvr(n)
6349  if (q > dzero) then
6350  q = -q
6351  end if
6352  call this%budobj%budterm(idx)%update_term(n1, n1, q)
6353  end do
6354  !
6355  end if
6356  !
6357  ! -- AUXILIARY VARIABLES
6358  naux = this%naux
6359  if (naux > 0) then
6360  idx = idx + 1
6361  allocate (auxvartmp(naux))
6362  call this%budobj%budterm(idx)%reset(this%nlakes)
6363  do n = 1, this%nlakes
6364  q = dzero
6365  do jj = 1, naux
6366  ii = n
6367  auxvartmp(jj) = this%featureauxvar(jj, ii)
6368  end do
6369  call this%budobj%budterm(idx)%update_term(n, n, q, auxvartmp)
6370  end do
6371  deallocate (auxvartmp)
6372  end if
6373  !
6374  ! --Terms are filled, now accumulate them for this time step
6375  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 3711 of file gwf-lak.f90.

3712  ! -- dummy
3713  class(LakType) :: this
3714  real(DP), dimension(:), intent(inout) :: rhs
3715  integer(I4B), dimension(:), intent(in) :: ia
3716  integer(I4B), dimension(:), intent(in) :: idxglo
3717  class(MatrixBaseType), pointer :: matrix_sln
3718  ! -- local
3719  integer(I4B) :: j, n
3720  integer(I4B) :: ipos
3721  integer(I4B) :: igwfnode
3722  integer(I4B) :: idry
3723  real(DP) :: hlak
3724  real(DP) :: avail
3725  real(DP) :: ra
3726  real(DP) :: ro
3727  real(DP) :: qinf
3728  real(DP) :: ex
3729  real(DP) :: head
3730  real(DP) :: q
3731  real(DP) :: q1
3732  real(DP) :: rterm
3733  real(DP) :: drterm
3734  !
3735  ! -- implicit formulation: the lakebed seepage Jacobian is already
3736  ! assembled exactly in lak_fc_implicit for constant-conductance
3737  ! (confined / saturated) connections. Nonlinear conductance Newton terms
3738  ! are Phase 2.
3739  if (this%iimplicit /= 0) then
3740  return
3741  end if
3742  !
3743  do n = 1, this%nlakes
3744  if (this%iboundpak(n) == 0) cycle
3745  hlak = this%xnewpak(n)
3746  call this%lak_calculate_available(n, hlak, avail, &
3747  ra, ro, qinf, ex, this%delh)
3748  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3749  igwfnode = this%gwfconn(j)
3750  ipos = ia(igwfnode)
3751  head = this%xnew(igwfnode)
3752  if (-this%hcof(j) > dzero) then
3753  if (this%ibound(igwfnode) > 0) then
3754  ! -- estimate lake-aquifer exchange with perturbed groundwater head
3755  ! exchange is relative to the lake
3756  !avail = DEP20
3757  call this%lak_estimate_conn_exchange(2, n, j, idry, hlak, &
3758  head + this%delh, q1, avail)
3759  q1 = -q1
3760  ! -- calculate unperturbed lake-aquifer exchange
3761  q = this%hcof(j) * head - this%rhs(j)
3762  ! -- calculate rterm
3763  rterm = this%hcof(j) * head
3764  ! -- calculate derivative
3765  drterm = (q1 - q) / this%delh
3766  ! -- add terms to convert conductance formulation into
3767  ! newton-raphson formulation
3768  call matrix_sln%add_value_pos(idxglo(ipos), drterm - this%hcof(j))
3769  rhs(igwfnode) = rhs(igwfnode) - rterm + drterm * head
3770  end if
3771  end if
3772  end do
3773  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 2752 of file gwf-lak.f90.

2753  ! -- dummy
2754  class(LakType), intent(inout) :: this
2755  integer(I4B), intent(in) :: ilak
2756  real(DP), intent(inout) :: outoutf
2757  ! -- local
2758  integer(I4B) :: n
2759  !
2760  outoutf = dzero
2761  if (this%imover == 1) then
2762  do n = 1, this%noutlets
2763  if (this%lakein(n) == ilak) then
2764  if (this%lakeout(n) > 0) cycle
2765  outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2766  end if
2767  end do
2768  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 2733 of file gwf-lak.f90.

2734  ! -- dummy
2735  class(LakType), intent(inout) :: this
2736  integer(I4B), intent(in) :: ilak
2737  real(DP), intent(inout) :: outoutf
2738  ! -- local
2739  integer(I4B) :: n
2740  !
2741  outoutf = dzero
2742  do n = 1, this%noutlets
2743  if (this%lakein(n) == ilak) then
2744  if (this%lakeout(n) > 0) cycle
2745  outoutf = outoutf + this%simoutrate(n)
2746  end if
2747  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 2693 of file gwf-lak.f90.

2694  ! -- dummy
2695  class(LakType), intent(inout) :: this
2696  integer(I4B), intent(in) :: ilak
2697  real(DP), intent(inout) :: outinf
2698  ! -- local
2699  integer(I4B) :: n
2700  !
2701  outinf = dzero
2702  do n = 1, this%noutlets
2703  if (this%lakeout(n) == ilak) then
2704  outinf = outinf - this%simoutrate(n)
2705  if (this%imover == 1) then
2706  outinf = outinf - this%pakmvrobj%get_qtomvr(n)
2707  end if
2708  end if
2709  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 2773 of file gwf-lak.f90.

2774  ! -- dummy
2775  class(LakType), intent(inout) :: this
2776  integer(I4B), intent(in) :: ilak
2777  real(DP), intent(inout) :: outoutf
2778  ! -- local
2779  integer(I4B) :: n
2780  !
2781  outoutf = dzero
2782  if (this%imover == 1) then
2783  do n = 1, this%noutlets
2784  if (this%lakein(n) == ilak) then
2785  if (this%lakeout(n) < 1) cycle
2786  outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2787  end if
2788  end do
2789  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 2714 of file gwf-lak.f90.

2715  ! -- dummy
2716  class(LakType), intent(inout) :: this
2717  integer(I4B), intent(in) :: ilak
2718  real(DP), intent(inout) :: outoutf
2719  ! -- local
2720  integer(I4B) :: n
2721  !
2722  outoutf = dzero
2723  do n = 1, this%noutlets
2724  if (this%lakein(n) == ilak) then
2725  if (this%lakeout(n) < 1) cycle
2726  outoutf = outoutf + this%simoutrate(n)
2727  end if
2728  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 2794 of file gwf-lak.f90.

2795  ! -- dummy
2796  class(LakType), intent(inout) :: this
2797  integer(I4B), intent(in) :: ilak
2798  real(DP), intent(inout) :: outoutf
2799  ! -- local
2800  integer(I4B) :: n
2801  !
2802  outoutf = dzero
2803  if (this%imover == 1) then
2804  do n = 1, this%noutlets
2805  if (this%lakein(n) == ilak) then
2806  outoutf = outoutf + this%pakmvrobj%get_qtomvr(n)
2807  end if
2808  end do
2809  end if

◆ lak_input_destroy()

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

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

3196  ! -- dummy
3197  class(LakInputType), intent(inout) :: this
3198  !
3199  nullify (this%nbound)
3200  nullify (this%ifno)
3201  nullify (this%setting)
3202  nullify (this%status)
3203  nullify (this%auxname)
3204  nullify (this%auxval)
3205  nullify (this%outletno)
3206  nullify (this%outlets_invert)
3207  nullify (this%outlets_width)
3208  nullify (this%outlets_rough)
3209  nullify (this%outlets_slope)
3210  nullify (this%invert_tslink)
3211  nullify (this%width_tslink)
3212  nullify (this%rough_tslink)
3213  nullify (this%slope_tslink)

◆ 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 3152 of file gwf-lak.f90.

3153  use memorymanagermodule, only: mem_setptr
3154  ! -- dummy
3155  class(LakInputType), intent(inout) :: this
3156  character(len=*), intent(in) :: mempath
3157  integer(I4B), intent(in) :: naux
3158  integer(I4B), intent(in) :: noutlets
3159  ! -- local
3160  integer(I4B), dimension(:, :), pointer, contiguous :: tslink => null()
3161  type(CharacterStringType), dimension(:), pointer, contiguous :: &
3162  tslinkvars => null()
3163  integer(I4B) :: n
3164  !
3165  ! -- period
3166  call mem_setptr(this%nbound, 'NBOUND', mempath)
3167  call mem_setptr(this%ifno, 'IFNO', mempath)
3168  call mem_setptr(this%setting, 'SETTING', mempath)
3169  call mem_setptr(this%status, 'STATUS', mempath)
3170  if (naux > 0) then
3171  call mem_setptr(this%auxname, 'AUXNAME', mempath)
3172  call mem_setptr(this%auxval, 'AUXVAL', mempath)
3173  end if
3174  ! -- outlets
3175  if (noutlets > 0) then
3176  call mem_setptr(this%outletno, 'OUTLETS_OUTLETNO', mempath)
3177  call mem_setptr(this%outlets_invert, 'OUTLETS_INVERT', mempath)
3178  call mem_setptr(this%outlets_width, 'OUTLETS_WIDTH', mempath)
3179  call mem_setptr(this%outlets_rough, 'OUTLETS_ROUGH', mempath)
3180  call mem_setptr(this%outlets_slope, 'OUTLETS_SLOPE', mempath)
3181  call mem_setptr(tslink, 'TSLINK_OL', mempath)
3182  call mem_setptr(tslinkvars, 'TSLINKVARS_OL', mempath)
3183  do n = 1, size(tslinkvars)
3184  if (tslinkvars(n) == 'OUTLETS_INVERT') &
3185  this%invert_tslink => tslink(n, :)
3186  if (tslinkvars(n) == 'OUTLETS_WIDTH') this%width_tslink => tslink(n, :)
3187  if (tslinkvars(n) == 'OUTLETS_ROUGH') this%rough_tslink => tslink(n, :)
3188  if (tslinkvars(n) == 'OUTLETS_SLOPE') this%slope_tslink => tslink(n, :)
3189  end do
3190  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 1927 of file gwf-lak.f90.

1928  ! -- dummy
1929  class(LakType), intent(inout) :: this
1930  integer(I4B), intent(in) :: n
1931  real(DP), dimension(n), intent(in) :: x
1932  real(DP), dimension(n), intent(in) :: y
1933  real(DP), intent(in) :: z
1934  real(DP), intent(inout) :: v
1935  ! -- local
1936  integer(I4B) :: i
1937  real(DP) :: dx, dydx
1938  ! code
1939  v = dzero
1940  ! below bottom of range - set to lowest value
1941  if (z <= x(1)) then
1942  v = y(1)
1943  ! above highest value
1944  ! slope calculated from interval between n and n-1
1945  else if (z > x(n)) then
1946  dx = x(n) - x(n - 1)
1947  dydx = dzero
1948  if (abs(dx) > dzero) then
1949  dydx = (y(n) - y(n - 1)) / dx
1950  end if
1951  dx = (z - x(n))
1952  v = y(n) + dydx * dx
1953  ! between lowest and highest value in current interval
1954  else
1955  do i = 2, n
1956  dx = x(i) - x(i - 1)
1957  dydx = dzero
1958  if (z >= x(i - 1) .and. z <= x(i)) then
1959  if (abs(dx) > dzero) then
1960  dydx = (y(i) - y(i - 1)) / dx
1961  end if
1962  dx = (z - x(i - 1))
1963  v = y(i - 1) + dydx * dx
1964  exit
1965  end if
1966  end do
1967  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 4688 of file gwf-lak.f90.

4690  ! -- dummy
4691  class(LakType), intent(inout) :: this
4692  integer(I4B), intent(in) :: moffset
4693  class(MatrixBaseType), pointer :: matrix_sln
4694  ! -- local
4695  integer(I4B) :: n
4696  integer(I4B) :: j
4697  integer(I4B) :: iglo
4698  integer(I4B) :: jglo
4699  integer(I4B) :: ipos
4700  !
4701  ! -- the connection-mapping vectors are only used by the implicit
4702  ! formulation; allocate them at size 0 otherwise so legacy LAK runs do not
4703  ! pay the maxbound memory cost (lak_da stays symmetric either way)
4704  if (this%iimplicit == 0) then
4705  call mem_allocate(this%idxlocnode, 0, 'IDXLOCNODE', this%memoryPath)
4706  call mem_allocate(this%idxdiag, 0, 'IDXDIAG', this%memoryPath)
4707  call mem_allocate(this%idxoffdglo, 0, 'IDXOFFDGLO', this%memoryPath)
4708  call mem_allocate(this%idxsymdglo, 0, 'IDXSYMDGLO', this%memoryPath)
4709  call mem_allocate(this%idxsymoffdglo, 0, 'IDXSYMOFFDGLO', this%memoryPath)
4710  return
4711  end if
4712  call mem_allocate(this%idxlocnode, this%nlakes, 'IDXLOCNODE', &
4713  this%memoryPath)
4714  call mem_allocate(this%idxdiag, this%nlakes, 'IDXDIAG', this%memoryPath)
4715  call mem_allocate(this%idxoffdglo, this%maxbound, 'IDXOFFDGLO', &
4716  this%memoryPath)
4717  call mem_allocate(this%idxsymdglo, this%maxbound, 'IDXSYMDGLO', &
4718  this%memoryPath)
4719  call mem_allocate(this%idxsymoffdglo, this%maxbound, 'IDXSYMOFFDGLO', &
4720  this%memoryPath)
4721  !
4722  ! -- lake rows: a per-lake diagonal position and the per-connection
4723  ! lake->cell off-diagonals. The diagonal is stored per lake (idxdiag) so a
4724  ! lake with no connections still has a valid diagonal position.
4725  ipos = 1
4726  do n = 1, this%nlakes
4727  iglo = moffset + this%dis%nodes + this%ioffset + n
4728  this%idxlocnode(n) = this%dis%nodes + this%ioffset + n
4729  this%idxdiag(n) = matrix_sln%get_position_diag(iglo)
4730  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4731  jglo = this%gwfconn(j) + moffset
4732  this%idxoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4733  ipos = ipos + 1
4734  end do
4735  end do
4736  !
4737  ! -- lake contributions to the gwf portion of the global matrix
4738  ipos = 1
4739  do n = 1, this%nlakes
4740  jglo = moffset + this%dis%nodes + this%ioffset + n
4741  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
4742  iglo = this%gwfconn(j) + moffset
4743  this%idxsymdglo(ipos) = matrix_sln%get_position_diag(iglo)
4744  this%idxsymoffdglo(ipos) = matrix_sln%get_position(iglo, jglo)
4745  ipos = ipos + 1
4746  end do
4747  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 3784 of file gwf-lak.f90.

3785  ! -- dummy
3786  class(LakType), intent(inout) :: this
3787  integer(I4B), intent(in) :: neqpak
3788  real(DP), dimension(neqpak), intent(inout) :: x
3789  real(DP), dimension(neqpak), intent(in) :: xtemp
3790  real(DP), dimension(neqpak), intent(inout) :: dx
3791  integer(I4B), intent(inout) :: inewtonur
3792  real(DP), intent(inout) :: dxmax
3793  integer(I4B), intent(inout) :: locmax
3794  ! -- local
3795  integer(I4B) :: n
3796  real(DP) :: botl
3797  real(DP) :: xx
3798  real(DP) :: dxx
3799  !
3800  ! -- only the implicit formulation has the lake stage in the global solution
3801  if (this%iimplicit == 0) return
3802  !
3803  ! -- Newton-Raphson under-relaxation: hold the stage at the lake bottom
3804  do n = 1, this%nlakes
3805  if (this%iboundpak(n) < 1) cycle
3806  botl = this%lakebot(n)
3807  !
3808  ! -- only apply under-relaxation if the updated stage is below the bottom
3809  ! of the lake
3810  if (x(n) < botl) then
3811  inewtonur = 1
3812  xx = xtemp(n) * (done - dp9) + botl * dp9
3813  dxx = x(n) - xx
3814  if (abs(dxx) > abs(dxmax)) then
3815  locmax = n
3816  dxmax = dxx
3817  end if
3818  x(n) = xx
3819  dx(n) = dzero
3820  end if
3821  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 4755 of file gwf-lak.f90.

4756  ! -- dummy
4757  class(LakType) :: this
4758  !
4759  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 4391 of file gwf-lak.f90.

4392  ! -- module
4393  use tdismodule, only: totim, delt
4394  ! -- dummy
4395  class(LakType) :: this !< LakType object
4396  integer(I4B), intent(in) :: kstp !< time step number
4397  integer(I4B), intent(in) :: kper !< period number
4398  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
4399  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
4400  !
4401  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 4320 of file gwf-lak.f90.

4321  use tdismodule, only: kstp, kper, pertim, totim
4322  use constantsmodule, only: dhnoflo, dhdry
4323  use inputoutputmodule, only: ulasav
4324  class(LakType) :: this
4325  integer(I4B), intent(in) :: idvsave
4326  integer(I4B), intent(in) :: idvprint
4327  integer(I4B) :: ibinun
4328  integer(I4B) :: n
4329  real(DP) :: v
4330  real(DP) :: d
4331  real(DP) :: stage
4332  real(DP) :: sa
4333  real(DP) :: wa
4334  !
4335  ! -- set unit number for binary dependent variable output
4336  ibinun = 0
4337  if (this%istageout /= 0) then
4338  ibinun = this%istageout
4339  end if
4340  if (idvsave == 0) ibinun = 0
4341  !
4342  ! -- write lake binary output
4343  if (ibinun > 0) then
4344  do n = 1, this%nlakes
4345  v = this%xnewpak(n)
4346  d = v - this%lakebot(n)
4347  if (this%iboundpak(n) == 0) then
4348  v = dhnoflo
4349  else if (d <= dzero) then
4350  v = dhdry
4351  end if
4352  this%dbuff(n) = v
4353  end do
4354  call ulasav(this%dbuff, ' STAGE', kstp, kper, pertim, totim, &
4355  this%nlakes, 1, 1, ibinun)
4356  end if
4357  !
4358  ! -- Print lake stage table
4359  if (idvprint /= 0 .and. this%iprhed /= 0) then
4360  !
4361  ! -- set table kstp and kper
4362  call this%stagetab%set_kstpkper(kstp, kper)
4363  !
4364  ! -- write data
4365  do n = 1, this%nlakes
4366  if (this%iboundpak(n) == 0) then
4367  stage = dhnoflo
4368  sa = dhnoflo
4369  wa = dhnoflo
4370  v = dhnoflo
4371  else
4372  stage = this%xnewpak(n)
4373  call this%lak_calculate_sarea(n, stage, sa)
4374  call this%lak_calculate_warea(n, stage, wa)
4375  call this%lak_calculate_vol(n, stage, v)
4376  end if
4377  if (this%inamedbound == 1) then
4378  call this%stagetab%add_term(this%lakename(n))
4379  end if
4380  call this%stagetab%add_term(n)
4381  call this%stagetab%add_term(stage)
4382  call this%stagetab%add_term(sa)
4383  call this%stagetab%add_term(wa)
4384  call this%stagetab%add_term(v)
4385  end do
4386  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 4307 of file gwf-lak.f90.

4308  class(LakType) :: this
4309  integer(I4B), intent(in) :: icbcfl
4310  integer(I4B), intent(in) :: ibudfl
4311  integer(I4B), intent(in) :: icbcun
4312  integer(I4B), dimension(:), optional, intent(in) :: imap
4313  !
4314  ! -- write the flows from the budobj
4315  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 4281 of file gwf-lak.f90.

4282  use tdismodule, only: kstp, kper, delt, pertim, totim
4283  class(LakType) :: this
4284  integer(I4B), intent(in) :: icbcfl
4285  integer(I4B), intent(in) :: ibudfl
4286  integer(I4B) :: ibinun
4287  !
4288  ! -- write the flows from the budobj
4289  ibinun = 0
4290  if (this%ibudgetout /= 0) then
4291  ibinun = this%ibudgetout
4292  end if
4293  if (icbcfl == 0) ibinun = 0
4294  if (ibinun > 0) then
4295  call this%budobj%save_flows(this%dis, ibinun, kstp, kper, delt, &
4296  pertim, totim, this%iout)
4297  end if
4298  !
4299  ! -- Print lake flows table
4300  if (ibudfl /= 0 .and. this%iprflow /= 0) then
4301  call this%budobj%write_flowtable(this%dis, kstp, kper)
4302  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 2654 of file gwf-lak.f90.

2655  ! -- dummy
2656  class(LakType), intent(inout) :: this
2657  integer(I4B), intent(in) :: ilak
2658  real(DP), intent(in) :: stage
2659  real(DP), intent(inout) :: qout
2660  ! -- local
2661  integer(I4B) :: n
2662  real(DP) :: g, d, c, gsm, rate
2663  !
2664  qout = dzero
2665  do n = 1, this%noutlets
2666  if (this%lakein(n) /= ilak) cycle
2667  rate = dzero
2668  d = stage - this%outinvert(n)
2669  if (this%outdmax > dzero .and. d > this%outdmax) d = this%outdmax
2670  g = dgravity * this%convlength * this%convtime * this%convtime
2671  select case (this%iouttype(n))
2672  case (0) ! specified rate
2673  rate = this%outrate(n)
2674  case (1) ! manning
2675  if (d > dzero) then
2676  c = (this%convlength**donethird) * this%convtime
2677  gsm = dzero
2678  if (this%outrough(n) > dzero) gsm = done / this%outrough(n)
2679  rate = -c * gsm * this%outwidth(n) * (d**dfivethirds) * &
2680  sqrt(this%outslope(n))
2681  end if
2682  case (2) ! weir
2683  if (d > dzero) then
2684  rate = -dtwothirds * dcd * this%outwidth(n) * d * sqrt(dtwo * g * d)
2685  end if
2686  end select
2687  qout = qout + rate
2688  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 5179 of file gwf-lak.f90.

5180  ! -- dummy
5181  type(ObserveType), intent(inout) :: obsrv
5182  class(DisBaseType), intent(in) :: dis
5183  integer(I4B), intent(in) :: inunitobs
5184  integer(I4B), intent(in) :: iout
5185  ! -- local
5186  integer(I4B) :: nn1, nn2
5187  integer(I4B) :: icol, istart, istop
5188  character(len=LINELENGTH) :: string
5189  character(len=LENBOUNDNAME) :: bndname
5190  !
5191  string = obsrv%IDstring
5192  ! -- Extract lake number from string and store it.
5193  ! If 1st item is not an integer(I4B), it should be a
5194  ! lake name--deal with it.
5195  icol = 1
5196  ! -- get lake number or boundary name
5197  call extract_idnum_or_bndname(string, icol, istart, istop, nn1, bndname)
5198  if (nn1 == namedboundflag) then
5199  obsrv%FeatureName = bndname
5200  else
5201  if (obsrv%ObsTypeId == 'LAK' .or. obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
5202  obsrv%ObsTypeId == 'WETTED-AREA') then
5203  call extract_idnum_or_bndname(string, icol, istart, istop, nn2, bndname)
5204  if (len_trim(bndname) < 1 .and. nn2 < 0) then
5205  write (errmsg, '(a,1x,a,a,1x,a,1x,a)') &
5206  'For observation type', trim(adjustl(obsrv%ObsTypeId)), &
5207  ', ID given as an integer and not as boundname,', &
5208  'but ID2 (iconn) is missing. Either change ID to valid', &
5209  'boundname or supply valid entry for ID2.'
5210  call store_error(errmsg)
5211  end if
5212  if (nn2 == namedboundflag) then
5213  obsrv%FeatureName = bndname
5214  ! -- reset nn1
5215  nn1 = nn2
5216  else
5217  obsrv%NodeNumber2 = nn2
5218  end if
5219  end if
5220  end if
5221  ! -- store lake number (NodeNumber)
5222  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 1665 of file gwf-lak.f90.

1666  use constantsmodule, only: linelength
1668  use simmodule, only: store_error, count_errors
1669  ! -- dummy
1670  class(LakType), intent(inout) :: this
1671  ! -- local
1672  integer(I4B) :: j, n
1673  integer(I4B) :: nn
1674  integer(I4B) :: idx
1675  real(DP) :: top
1676  real(DP) :: bot
1677  real(DP) :: k
1678  real(DP) :: area
1679  real(DP) :: length
1680  real(DP) :: s
1681  real(DP) :: dx
1682  real(DP) :: c
1683  real(DP) :: sa
1684  real(DP) :: wa
1685  real(DP) :: v
1686  real(DP) :: fact
1687  real(DP) :: c1
1688  real(DP) :: c2
1689  real(DP), allocatable, dimension(:) :: clb, caq
1690  character(len=14) :: cbedleak
1691  character(len=14) :: cbedcond
1692  character(len=10), dimension(0:3) :: ctype
1693  character(len=15) :: nodestr
1694  ! -- data
1695  data ctype(0)/'VERTICAL '/
1696  data ctype(1)/'HORIZONTAL'/
1697  data ctype(2)/'EMBEDDEDH '/
1698  data ctype(3)/'EMBEDDEDV '/
1699  !
1700  ! -- initialize xnewpak and set stage
1701  do n = 1, this%nlakes
1702  this%xnewpak(n) = this%strt(n)
1703  this%stage(n) = this%strt(n)
1704  end do
1705  !
1706  ! -- initialize status (iboundpak) of lakes to active
1707  do n = 1, this%nlakes
1708  if (this%status(n) == 'CONSTANT') then
1709  this%iboundpak(n) = -1
1710  else if (this%status(n) == 'INACTIVE') then
1711  this%iboundpak(n) = 0
1712  else if (this%status(n) == 'ACTIVE ') then
1713  this%iboundpak(n) = 1
1714  end if
1715  end do
1716  !
1717  ! -- set boundname for each connection
1718  if (this%inamedbound /= 0) then
1719  do n = 1, this%nlakes
1720  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1721  this%boundname(j) = this%lakename(n)
1722  end do
1723  end do
1724  end if
1725  !
1726  ! -- copy boundname into boundname_cst
1727  call this%copy_boundname()
1728  !
1729  ! -- set pointer to gwf iss and gwf hk
1730  call mem_setptr(this%gwfiss, 'ISS', create_mem_path(this%name_model))
1731  call mem_setptr(this%gwfk11, 'K11', create_mem_path(this%name_model, 'NPF'))
1732  call mem_setptr(this%gwfk33, 'K33', create_mem_path(this%name_model, 'NPF'))
1733  call mem_setptr(this%gwfik33, 'IK33', create_mem_path(this%name_model, 'NPF'))
1734  call mem_setptr(this%gwfsat, 'SAT', create_mem_path(this%name_model, 'NPF'))
1735  !
1736  ! -- allocate temporary storage
1737  allocate (clb(this%MAXBOUND))
1738  allocate (caq(this%MAXBOUND))
1739  !
1740  ! -- calculate saturated conductance for each connection
1741  do n = 1, this%nlakes
1742  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1743  nn = this%gwfconn(j)
1744  top = this%dis%top(nn)
1745  bot = this%dis%bot(nn)
1746  ! vertical connection
1747  if (this%ictype(j) == 0) then
1748  area = this%dis%area(nn)
1749  this%sarea(j) = area
1750  this%warea(j) = area
1751  this%sareamax(n) = this%sareamax(n) + area
1752  if (this%gwfik33 == 0) then
1753  k = this%gwfk11(nn)
1754  else
1755  k = this%gwfk33(nn)
1756  end if
1757  length = dhalf * (top - bot)
1758  ! horizontal connection
1759  else if (this%ictype(j) == 1) then
1760  area = (this%telev(j) - this%belev(j)) * this%connwidth(j)
1761  ! -- recalculate area if connected cell is confined and lake
1762  ! connection top and bot are equal to the cell top and bot
1763  if (top == this%telev(j) .and. bot == this%belev(j)) then
1764  if (this%icelltype(nn) == 0) then
1765  area = this%gwfsat(nn) * (top - bot) * this%connwidth(j)
1766  end if
1767  end if
1768  this%sarea(j) = dzero
1769  this%warea(j) = area
1770  this%sareamax(n) = this%sareamax(n) + dzero
1771  k = this%gwfk11(nn)
1772  length = this%connlength(j)
1773  ! embedded horizontal connection
1774  else if (this%ictype(j) == 2) then
1775  area = done
1776  this%sarea(j) = dzero
1777  this%warea(j) = area
1778  this%sareamax(n) = this%sareamax(n) + dzero
1779  k = this%gwfk11(nn)
1780  length = this%connlength(j)
1781  ! embedded vertical connection
1782  else if (this%ictype(j) == 3) then
1783  area = done
1784  this%sarea(j) = dzero
1785  this%warea(j) = area
1786  this%sareamax(n) = this%sareamax(n) + dzero
1787  if (this%gwfik33 == 0) then
1788  k = this%gwfk11(nn)
1789  else
1790  k = this%gwfk33(nn)
1791  end if
1792  length = this%connlength(j)
1793  end if
1794  if (is_close(this%bedleak(j), dnodata)) then
1795  clb(j) = dnodata
1796  else if (this%bedleak(j) > dzero) then
1797  clb(j) = done / this%bedleak(j)
1798  else
1799  clb(j) = dzero
1800  end if
1801  if (k > dzero) then
1802  caq(j) = length / k
1803  else
1804  caq(j) = dzero
1805  end if
1806  if (is_close(this%bedleak(j), dnodata)) then
1807  this%satcond(j) = area / caq(j)
1808  else if (clb(j) * caq(j) > dzero) then
1809  this%satcond(j) = area / (clb(j) + caq(j))
1810  else
1811  this%satcond(j) = dzero
1812  end if
1813  end do
1814  end do
1815  !
1816  ! -- write a summary of the conductance
1817  if (this%iprpak > 0) then
1818  write (this%iout, '(//,29x,a,/)') &
1819  'INTERFACE CONDUCTANCE BETWEEN LAKE AND AQUIFER CELLS'
1820  write (this%iout, '(1x,a)') &
1821  & ' LAKE CONNECTION CONNECTION LAKEBED'// &
1822  & ' C O N D U C T A N C E S '
1823  write (this%iout, '(1x,a)') &
1824  & ' NUMBER NUMBER CELLID DIRECTION LEAKANCE'// &
1825  & ' LAKEBED AQUIFER COMBINED'
1826  write (this%iout, "(1x,108('-'))")
1827  do n = 1, this%nlakes
1828  idx = 0
1829  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1830  idx = idx + 1
1831  fact = done
1832  if (this%ictype(j) == 1) then
1833  fact = this%telev(j) - this%belev(j)
1834  if (abs(fact) > dzero) then
1835  fact = done / fact
1836  end if
1837  end if
1838  nn = this%gwfconn(j)
1839  area = this%warea(j)
1840  c1 = dzero
1841  if (is_close(clb(j), dnodata)) then
1842  cbedleak = ' NONE '
1843  cbedcond = ' NONE '
1844  else if (clb(j) > dzero) then
1845  c1 = area * fact / clb(j)
1846  write (cbedleak, '(g14.5)') this%bedleak(j)
1847  write (cbedcond, '(g14.5)') c1
1848  else
1849  write (cbedleak, '(g14.5)') c1
1850  write (cbedcond, '(g14.5)') c1
1851  end if
1852  c2 = dzero
1853  if (caq(j) > dzero) then
1854  c2 = area * fact / caq(j)
1855  end if
1856  call this%dis%noder_to_string(nn, nodestr)
1857  write (this%iout, &
1858  '(1x,i10,1x,i10,1x,a15,1x,a10,2(1x,a14),2(1x,g14.5))') &
1859  n, idx, nodestr, ctype(this%ictype(j)), cbedleak, &
1860  cbedcond, c2, this%satcond(j) * fact
1861  end do
1862  end do
1863  write (this%iout, "(1x,108('-'))")
1864  write (this%iout, '(1x,a)') &
1865  'IF VERTICAL CONNECTION, CONDUCTANCE (L^2/T) IS &
1866  &BETWEEN AQUIFER CELL AND OVERLYING LAKE CELL.'
1867  write (this%iout, '(1x,a)') &
1868  'IF HORIZONTAL CONNECTION, CONDUCTANCES ARE PER &
1869  &UNIT SATURATED THICKNESS (L/T).'
1870  write (this%iout, '(1x,a)') &
1871  'IF EMBEDDED CONNECTION, CONDUCTANCES ARE PER &
1872  &UNIT EXCHANGE AREA (1/T).'
1873  !
1874  ! write(this%iout,*) n, idx, nodestr, this%sarea(j), this%warea(j)
1875  !
1876  ! -- calculate stage, surface area, wetted area, volume relation
1877  do n = 1, this%nlakes
1878  write (this%iout, '(//1x,a,1x,i10)') 'STAGE/VOLUME RELATION FOR LAKE ', n
1879  write (this%iout, '(/1x,5(a14))') ' STAGE', ' SURFACE AREA', &
1880  & ' WETTED AREA', ' CONDUCTANCE', &
1881  & ' VOLUME'
1882  write (this%iout, "(1x,70('-'))")
1883  dx = (this%laketop(n) - this%lakebot(n)) / 150.
1884  s = this%lakebot(n)
1885  do j = 1, 151
1886  call this%lak_calculate_conductance(n, s, c)
1887  call this%lak_calculate_sarea(n, s, sa)
1888  call this%lak_calculate_warea(n, s, wa, s)
1889  call this%lak_calculate_vol(n, s, v)
1890  write (this%iout, '(1x,5(E14.5))') s, sa, wa, c, v
1891  s = s + dx
1892  end do
1893  write (this%iout, "(1x,70('-'))")
1894  !
1895  write (this%iout, '(//1x,a,1x,i10)') 'STAGE/VOLUME RELATION FOR LAKE ', n
1896  write (this%iout, '(/1x,4(a14))') ' ', ' ', &
1897  & ' CALCULATED', ' STAGE'
1898  write (this%iout, '(1x,4(a14))') ' STAGE', ' VOLUME', &
1899  & ' STAGE', ' DIFFERENCE'
1900  write (this%iout, "(1x,56('-'))")
1901  s = this%lakebot(n) - dx
1902  do j = 1, 156
1903  call this%lak_calculate_vol(n, s, v)
1904  call this%lak_vol2stage(n, v, c)
1905  write (this%iout, '(1x,4(E14.5))') s, v, c, s - c
1906  s = s + dx
1907  end do
1908  write (this%iout, "(1x,56('-'))")
1909  end do
1910  end if
1911  !
1912  ! -- finished with pointer to gwf hydraulic conductivity
1913  this%gwfk11 => null()
1914  this%gwfk33 => null()
1915  this%gwfsat => null()
1916  this%gwfik33 => null()
1917  !
1918  ! -- deallocate temporary storage
1919  deallocate (clb)
1920  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 3282 of file gwf-lak.f90.

3283  ! -- modules
3284  use constantsmodule, only: lenvarname
3285  use tdismodule, only: kper
3286  ! -- dummy
3287  class(LakType), intent(inout) :: this
3288  ! -- local
3289  character(len=LINELENGTH) :: str = ' '
3290  real(DP) :: auxvaldbl = dzero
3291  character(len=LINELENGTH) :: title
3292  character(len=LINELENGTH) :: text
3293  character(len=LENVARNAME) :: setting
3294  integer(I4B) :: node, n, j, itemno
3295  integer(I4B) :: istat
3296  ! -- formats
3297  character(len=*), parameter :: fmtlsp = &
3298  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
3299  !
3300  ! -- set nbound to maxbound
3301  this%nbound = this%maxbound
3302  !
3303  ! -- check if data has been loaded for this stress period
3304  if (this%iper == kper) then
3305  !
3306  this%check_attr = 1
3307  !
3308  ! -- setup table to echo period data
3309  if (this%iprpak /= 0) then
3310  title = trim(adjustl(this%text))//' PACKAGE ('// &
3311  trim(adjustl(this%packName))//') DATA FOR PERIOD'
3312  write (title, '(a,1x,i6)') trim(adjustl(title)), kper
3313  call table_cr(this%inputtab, this%packName, title)
3314  call this%inputtab%table_df(1, 4, this%iout, finalize=.false.)
3315  text = 'NUMBER'
3316  call this%inputtab%initialize_column(text, 10, alignment=tabcenter)
3317  text = 'KEYWORD'
3318  call this%inputtab%initialize_column(text, 20, alignment=tableft)
3319  do n = 1, 2
3320  write (text, '(a,1x,i6)') 'VALUE', n
3321  call this%inputtab%initialize_column(text, 15, alignment=tabcenter)
3322  end do
3323  end if
3324  !
3325  ! -- process each period data entry
3326  do n = 1, this%input%nbound
3327  itemno = this%input%ifno(n)
3328  !
3329  ! -- dispatch key for this row
3330  setting = this%input%setting(n)
3331  str = ' '
3332  !
3333  ! -- STATUS (lake only; not TS-enabled)
3334  if (trim(setting) == 'STATUS') then
3335  str = this%input%status(n)
3336  istat = this%lak_check_valid(itemno)
3337  if (istat == 0 .and. itemno >= 1 .and. itemno <= this%nlakes) then
3338  if (trim(str) == 'CONSTANT') then
3339  this%iboundpak(itemno) = -1
3340  else if (trim(str) == 'INACTIVE') then
3341  this%iboundpak(itemno) = 0
3342  else if (trim(str) == 'ACTIVE') then
3343  this%iboundpak(itemno) = 1
3344  else
3345  write (errmsg, '(a,a)') &
3346  'Unknown '//trim(this%text)//' STATUS keyword: ', &
3347  trim(str)//'.'
3348  call store_error(errmsg)
3349  end if
3350  this%status(itemno) = trim(str)
3351  end if
3352  end if
3353  !
3354  ! -- STAGE (validate itemno; assignment via helper)
3355  if (trim(setting) == 'STAGE') then
3356  istat = this%lak_check_valid(itemno)
3357  end if
3358  !
3359  ! -- RAINFALL, EVAPORATION, RUNOFF, INFLOW, WITHDRAWAL (require
3360  ! non-negative)
3361  if (trim(setting) == 'RAINFALL') &
3362  call this%lak_set_nonneg_value(n, itemno, setting, this%rainfall, &
3363  'rainfall')
3364  if (trim(setting) == 'EVAPORATION') &
3365  call this%lak_set_nonneg_value(n, itemno, setting, &
3366  this%evaporation, 'evaporation')
3367  if (trim(setting) == 'RUNOFF') &
3368  call this%lak_set_nonneg_value(n, itemno, setting, this%runoff, &
3369  'runoff')
3370  if (trim(setting) == 'INFLOW') &
3371  call this%lak_set_nonneg_value(n, itemno, setting, this%inflow, &
3372  'inflow')
3373  if (trim(setting) == 'WITHDRAWAL') &
3374  call this%lak_set_nonneg_value(n, itemno, setting, &
3375  this%withdrawal, 'withdrawal')
3376  !
3377  ! -- RATE, INVERT, WIDTH, ROUGH, SLOPE (outlet; validate with
3378  ! negative sign convention)
3379  if (trim(setting) == 'RATE' .or. trim(setting) == 'INVERT' .or. &
3380  trim(setting) == 'WIDTH' .or. trim(setting) == 'ROUGH' .or. &
3381  trim(setting) == 'SLOPE') then
3382  istat = this%lak_check_valid(-itemno)
3383  end if
3384  !
3385  ! -- INVERT, WIDTH, ROUGH, SLOPE latch here so the OUTLETS block's
3386  ! own (separately time-series-linked) baseline resync in lak_ad
3387  ! stops overwriting this outlet's PERIOD-block override
3388  if (istat == 0 .and. itemno >= 1 .and. itemno <= this%noutlets) then
3389  if (trim(setting) == 'INVERT') this%outlet_invert_set(itemno) = .true.
3390  if (trim(setting) == 'WIDTH') this%outlet_width_set(itemno) = .true.
3391  if (trim(setting) == 'ROUGH') this%outlet_rough_set(itemno) = .true.
3392  if (trim(setting) == 'SLOPE') this%outlet_slope_set(itemno) = .true.
3393  end if
3394  !
3395  ! -- AUXILIARY; featureauxvar set via sync_auxvar()
3396  if (this%naux > 0) then
3397  if (trim(setting) == 'PERIOD_AUXILIARY') then
3398  if (itemno >= 1 .and. itemno <= this%nlakes) then
3399  str = this%input%auxname(n)
3400  auxvaldbl = this%input%auxval(n)
3401  end if
3402  end if
3403  end if
3404  !
3405  ! -- echo row to period data table
3406  if (this%iprpak /= 0) then
3407  call this%inputtab%add_term(itemno)
3408  if (trim(setting) == 'PERIOD_AUXILIARY') then
3409  call this%inputtab%add_term('AUXILIARY')
3410  else
3411  call this%inputtab%add_term(trim(setting))
3412  end if
3413  select case (trim(setting))
3414  case ('STATUS')
3415  call this%inputtab%add_term(trim(str))
3416  call this%inputtab%add_term(' ')
3417  case ('STAGE')
3418  call this%inputtab%add_term(this%stage(itemno))
3419  call this%inputtab%add_term(' ')
3420  case ('RAINFALL')
3421  call this%inputtab%add_term(this%rainfall(itemno))
3422  call this%inputtab%add_term(' ')
3423  case ('EVAPORATION')
3424  call this%inputtab%add_term(this%evaporation(itemno))
3425  call this%inputtab%add_term(' ')
3426  case ('RUNOFF')
3427  call this%inputtab%add_term(this%runoff(itemno))
3428  call this%inputtab%add_term(' ')
3429  case ('INFLOW')
3430  call this%inputtab%add_term(this%inflow(itemno))
3431  call this%inputtab%add_term(' ')
3432  case ('WITHDRAWAL')
3433  call this%inputtab%add_term(this%withdrawal(itemno))
3434  call this%inputtab%add_term(' ')
3435  case ('RATE')
3436  call this%inputtab%add_term(this%outrate(itemno))
3437  call this%inputtab%add_term(' ')
3438  case ('INVERT')
3439  call this%inputtab%add_term(this%outinvert(itemno))
3440  call this%inputtab%add_term(' ')
3441  case ('WIDTH')
3442  call this%inputtab%add_term(this%outwidth(itemno))
3443  call this%inputtab%add_term(' ')
3444  case ('ROUGH')
3445  call this%inputtab%add_term(this%outrough(itemno))
3446  call this%inputtab%add_term(' ')
3447  case ('SLOPE')
3448  call this%inputtab%add_term(this%outslope(itemno))
3449  call this%inputtab%add_term(' ')
3450  case ('PERIOD_AUXILIARY')
3451  call this%inputtab%add_term(trim(str))
3452  call this%inputtab%add_term(auxvaldbl)
3453  case default
3454  call this%inputtab%add_term(' ')
3455  call this%inputtab%add_term(' ')
3456  end select
3457  end if
3458  end do
3459  if (this%iprpak /= 0) then
3460  call this%inputtab%finalize_table()
3461  end if
3462  !
3463  ! -- write summary of lake stress period error messages
3464  if (count_errors() > 0) then
3465  call store_error_filename(this%input_fname)
3466  end if
3467  !
3468  ! -- fill bound array with lake stage, conductance, and bottom elevation
3469  do n = 1, this%nlakes
3470  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3471  node = this%gwfconn(j)
3472  this%nodelist(j) = node
3473  this%bound(1, j) = this%xnewpak(n)
3474  this%bound(2, j) = this%satcond(j)
3475  this%bound(3, j) = this%belev(j)
3476  end do
3477  end do
3478  !
3479  ! -- copy lakein into iprmap so mvr budget contains lake instead of outlet
3480  if (this%imover == 1) then
3481  do n = 1, this%noutlets
3482  this%pakmvrobj%iprmap(n) = this%lakein(n)
3483  end do
3484  end if
3485  else
3486  write (this%iout, fmtlsp) trim(this%filtyp)
3487  end if
3488  !
3489  ! -- fill nodelist and bound(3) every period; nodelist for non-vertical
3490  ! connections is not updated by lak_cf so must be set here.
3491  ! bound(3) (bed elevation) is static and only needs to be set once.
3492  do n = 1, this%nlakes
3493  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
3494  this%nodelist(j) = this%gwfconn(j)
3495  this%bound(3, j) = this%belev(j)
3496  end do
3497  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 5025 of file gwf-lak.f90.

5026  use tdismodule, only: kper
5027  ! -- dummy
5028  class(LakType), intent(inout) :: this
5029  ! -- local
5030  integer(I4B) :: i
5031  integer(I4B) :: j
5032  integer(I4B) :: nn1
5033  integer(I4B) :: nn2
5034  integer(I4B) :: jj
5035  character(len=LENBOUNDNAME) :: bname
5036  logical(LGP) :: jfound
5037  class(ObserveType), pointer :: obsrv => null()
5038  ! -- formats
5039 10 format('Boundary "', a, '" for observation "', a, &
5040  '" is invalid in package "', a, '"')
5041  !
5042  ! -- process each package observation
5043  ! only done the first stress period since boundaries are fixed
5044  ! for the simulation
5045  if (kper == 1) then
5046  do i = 1, this%obs%npakobs
5047  obsrv => this%obs%pakobs(i)%obsrv
5048  !
5049  ! -- get node number 1
5050  nn1 = obsrv%NodeNumber
5051  if (nn1 == namedboundflag) then
5052  bname = obsrv%FeatureName
5053  if (bname /= '') then
5054  ! -- Observation lake is based on a boundary name.
5055  ! Iterate through all lakes to identify and store
5056  ! corresponding index in bound array.
5057  jfound = .false.
5058  if (obsrv%ObsTypeId == 'LAK' .or. &
5059  obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
5060  obsrv%ObsTypeId == 'WETTED-AREA') then
5061  if (this%inamedbound /= 0) then
5062  do j = 1, this%nlakes
5063  do jj = this%idxlakeconn(j), this%idxlakeconn(j + 1) - 1
5064  if (this%boundname(jj) == bname) then
5065  jfound = .true.
5066  call obsrv%AddObsIndex(jj)
5067  end if
5068  end do
5069  end do
5070  end if
5071  else if (obsrv%ObsTypeId == 'EXT-OUTFLOW' .or. &
5072  obsrv%ObsTypeId == 'TO-MVR' .or. &
5073  obsrv%ObsTypeId == 'OUTLET') then
5074  do j = 1, this%noutlets
5075  jj = this%lakein(j)
5076  if (this%lakename(jj) == bname) then
5077  jfound = .true.
5078  call obsrv%AddObsIndex(j)
5079  end if
5080  end do
5081  else
5082  do j = 1, this%nlakes
5083  if (this%lakename(j) == bname) then
5084  jfound = .true.
5085  call obsrv%AddObsIndex(j)
5086  end if
5087  end do
5088  end if
5089  if (.not. jfound) then
5090  write (errmsg, 10) &
5091  trim(bname), trim(obsrv%Name), trim(this%packName)
5092  call store_error(errmsg)
5093  end if
5094  end if
5095  else
5096  if (obsrv%indxbnds_count == 0) then
5097  if (obsrv%ObsTypeId == 'LAK' .or. &
5098  obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
5099  obsrv%ObsTypeId == 'WETTED-AREA') then
5100  nn2 = obsrv%NodeNumber2
5101  j = this%idxlakeconn(nn1) + nn2 - 1
5102  call obsrv%AddObsIndex(j)
5103  else
5104  call obsrv%AddObsIndex(nn1)
5105  end if
5106  else
5107  errmsg = 'Programming error in lak_rp_obs'
5108  call store_error(errmsg)
5109  end if
5110  end if
5111  !
5112  ! -- catch non-cumulative observation assigned to observation defined
5113  ! by a boundname that is assigned to more than one element
5114  if (obsrv%ObsTypeId == 'STAGE') then
5115  if (obsrv%indxbnds_count > 1) then
5116  write (errmsg, '(a,3(1x,a))') &
5117  trim(adjustl(obsrv%ObsTypeId)), &
5118  'for observation', trim(adjustl(obsrv%Name)), &
5119  ' must be assigned to a lake with a unique boundname.'
5120  call store_error(errmsg)
5121  end if
5122  end if
5123  !
5124  ! -- check that index values are valid
5125  if (obsrv%ObsTypeId == 'TO-MVR' .or. &
5126  obsrv%ObsTypeId == 'EXT-OUTFLOW' .or. &
5127  obsrv%ObsTypeId == 'OUTLET') then
5128  do j = 1, obsrv%indxbnds_count
5129  nn1 = obsrv%indxbnds(j)
5130  if (nn1 < 1 .or. nn1 > this%noutlets) then
5131  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5132  trim(adjustl(obsrv%ObsTypeId)), &
5133  ' outlet must be > 0 and <=', this%noutlets, &
5134  '(specified value is ', nn1, ')'
5135  call store_error(errmsg)
5136  end if
5137  end do
5138  else if (obsrv%ObsTypeId == 'LAK' .or. &
5139  obsrv%ObsTypeId == 'CONDUCTANCE' .or. &
5140  obsrv%ObsTypeId == 'WETTED-AREA') then
5141  do j = 1, obsrv%indxbnds_count
5142  nn1 = obsrv%indxbnds(j)
5143  if (nn1 < 1 .or. nn1 > this%maxbound) then
5144  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5145  trim(adjustl(obsrv%ObsTypeId)), &
5146  'lake connection number must be > 0 and <=', this%maxbound, &
5147  '(specified value is ', nn1, ')'
5148  call store_error(errmsg)
5149  end if
5150  end do
5151  else
5152  do j = 1, obsrv%indxbnds_count
5153  nn1 = obsrv%indxbnds(j)
5154  if (nn1 < 1 .or. nn1 > this%nlakes) then
5155  write (errmsg, '(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
5156  trim(adjustl(obsrv%ObsTypeId)), &
5157  ' lake must be > 0 and <=', this%nlakes, &
5158  '(specified value is ', nn1, ')'
5159  call store_error(errmsg)
5160  end if
5161  end do
5162  end if
5163  end do
5164  !
5165  ! -- evaluate if there are any observation errors
5166  if (count_errors() > 0) then
5167  call store_error_filename(this%input_fname)
5168  end if
5169  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 2952 of file gwf-lak.f90.

2953  ! -- modules
2954  use simmodule, only: store_error
2955  ! -- dummy
2956  class(LakType), intent(inout) :: this
2957  integer(I4B), intent(in) :: ilak
2958  character(len=*), intent(in) :: keyword
2959  character(len=*), intent(in) :: msg
2960  !
2961  if (len(msg) == 0) then
2962  write (errmsg, '(a,1x,a,1x,i0,1x,a)') &
2963  keyword, ' for LAKE', ilak, 'has already been set.'
2964  else
2965  write (errmsg, '(a,1x,a,1x,i0,1x,a)') keyword, ' for LAKE', ilak, msg
2966  end if
2967  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 2928 of file gwf-lak.f90.

2929  ! -- dummy
2930  class(LakType), intent(inout) :: this
2931  integer(I4B), intent(in) :: n
2932  integer(I4B), intent(in) :: itemno
2933  character(len=*), intent(in) :: setting
2934  real(DP), dimension(:), intent(inout) :: value_array
2935  character(len=*), intent(in) :: label
2936  ! -- local
2937  integer(I4B) :: istat
2938  !
2939  istat = this%lak_check_valid(itemno)
2940  if (istat /= 0) return
2941  if (itemno < 1 .or. itemno > this%nlakes) return
2942  if (value_array(itemno) < dzero) then
2943  write (errmsg, '(a,i0,a,g0,a)') &
2944  'Lake ', itemno, ' was assigned a '//trim(label)//' value of ', &
2945  value_array(itemno), '. Value must be positive.'
2946  call store_error(errmsg)
2947  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 4612 of file gwf-lak.f90.

4613  ! -- modules
4615  ! -- dummy
4616  class(LakType) :: this
4617  integer(I4B), pointer :: neq
4618  integer(I4B), dimension(:), pointer, contiguous :: ibound
4619  real(DP), dimension(:), pointer, contiguous :: xnew
4620  real(DP), dimension(:), pointer, contiguous :: xold
4621  real(DP), dimension(:), pointer, contiguous :: flowja
4622  ! -- local
4623  integer(I4B) :: n
4624  integer(I4B) :: istart, iend
4625  !
4626  ! -- call base BndType set_pointers
4627  call this%BndType%set_pointers(neq, ibound, xnew, xold, flowja)
4628  !
4629  ! -- for the implicit formulation, point the lake stage and ibound at the
4630  ! matching slice of the model solution (xnew) and ibound vectors so the
4631  ! stage is solved directly in the matrix. (The default formulation keeps
4632  ! these as its own arrays, allocated in lak_allocate_arrays.)
4633  if (this%iimplicit /= 0) then
4634  istart = this%dis%nodes + this%ioffset + 1
4635  iend = istart + this%nlakes - 1
4636  this%iboundpak => this%ibound(istart:iend)
4637  this%xnewpak => this%xnew(istart:iend)
4638  call mem_checkin(this%xnewpak, 'XNEWPAK', this%memoryPath, 'X', &
4639  this%memoryPathModel)
4640  !
4641  ! -- initialize xnewpak
4642  do n = 1, this%nlakes
4643  this%xnewpak(n) = dep20
4644  end do
4645  end if

◆ lak_setup_budobj()

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

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

5944  ! -- modules
5945  use constantsmodule, only: lenbudtxt
5946  ! -- dummy
5947  class(LakType) :: this
5948  ! -- local
5949  integer(I4B) :: nbudterm
5950  integer(I4B) :: nlen
5951  integer(I4B) :: j, n, n1, n2
5952  integer(I4B) :: maxlist, naux
5953  integer(I4B) :: idx
5954  real(DP) :: q
5955  character(len=LENBUDTXT) :: text
5956  character(len=LENBUDTXT), dimension(1) :: auxtxt
5957  !
5958  ! -- Determine the number of lake budget terms. These are fixed for
5959  ! the simulation and cannot change
5960  nbudterm = 9
5961  nlen = 0
5962  do n = 1, this%noutlets
5963  if (this%lakein(n) > 0 .and. this%lakeout(n) > 0) then
5964  nlen = nlen + 1
5965  end if
5966  end do
5967  if (nlen > 0) nbudterm = nbudterm + 1
5968  if (this%imover == 1) nbudterm = nbudterm + 2
5969  if (this%naux > 0) nbudterm = nbudterm + 1
5970  !
5971  ! -- set up budobj
5972  call budgetobject_cr(this%budobj, this%packName)
5973  call this%budobj%budgetobject_df(this%nlakes, nbudterm, 0, 0, &
5974  ibudcsv=this%ibudcsv)
5975  idx = 0
5976  !
5977  ! -- Go through and set up each budget term. nlen is the number
5978  ! of outlets that discharge into another lake
5979  if (nlen > 0) then
5980  text = ' FLOW-JA-FACE'
5981  idx = idx + 1
5982  maxlist = 2 * nlen
5983  naux = 0
5984  call this%budobj%budterm(idx)%initialize(text, &
5985  this%name_model, &
5986  this%packName, &
5987  this%name_model, &
5988  this%packName, &
5989  maxlist, .false., .false., &
5990  naux, ordered_id1=.false.)
5991  !
5992  ! -- store connectivity
5993  call this%budobj%budterm(idx)%reset(2 * nlen)
5994  q = dzero
5995  do n = 1, this%noutlets
5996  n1 = this%lakein(n)
5997  n2 = this%lakeout(n)
5998  if (n1 > 0 .and. n2 > 0) then
5999  call this%budobj%budterm(idx)%update_term(n1, n2, q)
6000  call this%budobj%budterm(idx)%update_term(n2, n1, -q)
6001  end if
6002  end do
6003  end if
6004  !
6005  ! --
6006  text = ' GWF'
6007  idx = idx + 1
6008  maxlist = this%maxbound
6009  naux = 1
6010  auxtxt(1) = ' FLOW-AREA'
6011  call this%budobj%budterm(idx)%initialize(text, &
6012  this%name_model, &
6013  this%packName, &
6014  this%name_model, &
6015  this%name_model, &
6016  maxlist, .false., .true., &
6017  naux, auxtxt)
6018  call this%budobj%budterm(idx)%reset(this%maxbound)
6019  q = dzero
6020  do n = 1, this%nlakes
6021  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
6022  n2 = this%gwfconn(j)
6023  call this%budobj%budterm(idx)%update_term(n, n2, q)
6024  end do
6025  end do
6026  !
6027  ! --
6028  text = ' RAINFALL'
6029  idx = idx + 1
6030  maxlist = this%nlakes
6031  naux = 0
6032  call this%budobj%budterm(idx)%initialize(text, &
6033  this%name_model, &
6034  this%packName, &
6035  this%name_model, &
6036  this%packName, &
6037  maxlist, .false., .false., &
6038  naux)
6039  !
6040  ! --
6041  text = ' EVAPORATION'
6042  idx = idx + 1
6043  maxlist = this%nlakes
6044  naux = 0
6045  call this%budobj%budterm(idx)%initialize(text, &
6046  this%name_model, &
6047  this%packName, &
6048  this%name_model, &
6049  this%packName, &
6050  maxlist, .false., .false., &
6051  naux)
6052  !
6053  ! --
6054  text = ' RUNOFF'
6055  idx = idx + 1
6056  maxlist = this%nlakes
6057  naux = 0
6058  call this%budobj%budterm(idx)%initialize(text, &
6059  this%name_model, &
6060  this%packName, &
6061  this%name_model, &
6062  this%packName, &
6063  maxlist, .false., .false., &
6064  naux)
6065  !
6066  ! --
6067  text = ' EXT-INFLOW'
6068  idx = idx + 1
6069  maxlist = this%nlakes
6070  naux = 0
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)
6078  !
6079  ! --
6080  text = ' WITHDRAWAL'
6081  idx = idx + 1
6082  maxlist = this%nlakes
6083  naux = 0
6084  call this%budobj%budterm(idx)%initialize(text, &
6085  this%name_model, &
6086  this%packName, &
6087  this%name_model, &
6088  this%packName, &
6089  maxlist, .false., .false., &
6090  naux)
6091  !
6092  ! --
6093  text = ' EXT-OUTFLOW'
6094  idx = idx + 1
6095  maxlist = this%nlakes
6096  naux = 0
6097  call this%budobj%budterm(idx)%initialize(text, &
6098  this%name_model, &
6099  this%packName, &
6100  this%name_model, &
6101  this%packName, &
6102  maxlist, .false., .false., &
6103  naux)
6104  !
6105  ! --
6106  text = ' STORAGE'
6107  idx = idx + 1
6108  maxlist = this%nlakes
6109  naux = 1
6110  auxtxt(1) = ' VOLUME'
6111  call this%budobj%budterm(idx)%initialize(text, &
6112  this%name_model, &
6113  this%packName, &
6114  this%name_model, &
6115  this%packName, &
6116  maxlist, .false., .false., &
6117  naux, auxtxt)
6118  !
6119  ! --
6120  text = ' CONSTANT'
6121  idx = idx + 1
6122  maxlist = this%nlakes
6123  naux = 0
6124  call this%budobj%budterm(idx)%initialize(text, &
6125  this%name_model, &
6126  this%packName, &
6127  this%name_model, &
6128  this%packName, &
6129  maxlist, .false., .false., &
6130  naux)
6131  !
6132  ! --
6133  if (this%imover == 1) then
6134  !
6135  ! --
6136  text = ' FROM-MVR'
6137  idx = idx + 1
6138  maxlist = this%nlakes
6139  naux = 0
6140  call this%budobj%budterm(idx)%initialize(text, &
6141  this%name_model, &
6142  this%packName, &
6143  this%name_model, &
6144  this%packName, &
6145  maxlist, .false., .false., &
6146  naux)
6147  !
6148  ! --
6149  text = ' TO-MVR'
6150  idx = idx + 1
6151  maxlist = this%noutlets
6152  naux = 0
6153  call this%budobj%budterm(idx)%initialize(text, &
6154  this%name_model, &
6155  this%packName, &
6156  this%name_model, &
6157  this%packName, &
6158  maxlist, .false., .false., &
6159  naux, ordered_id1=.false.)
6160  !
6161  ! -- store to-mvr connection information
6162  call this%budobj%budterm(idx)%reset(this%noutlets)
6163  q = dzero
6164  do n = 1, this%noutlets
6165  n1 = this%lakein(n)
6166  call this%budobj%budterm(idx)%update_term(n1, n1, q)
6167  end do
6168  end if
6169  !
6170  ! --
6171  naux = this%naux
6172  if (naux > 0) then
6173  !
6174  ! --
6175  text = ' AUXILIARY'
6176  idx = idx + 1
6177  maxlist = this%nlakes
6178  call this%budobj%budterm(idx)%initialize(text, &
6179  this%name_model, &
6180  this%packName, &
6181  this%name_model, &
6182  this%packName, &
6183  maxlist, .false., .false., &
6184  naux, this%auxname)
6185  end if
6186  !
6187  ! -- if lake flow for each reach are written to the listing file
6188  if (this%iprflow /= 0) then
6189  call this%budobj%flowtable_df(this%iout)
6190  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 6383 of file gwf-lak.f90.

6384  ! -- modules
6386  ! -- dummy
6387  class(LakType) :: this
6388  ! -- local
6389  integer(I4B) :: nterms
6390  character(len=LINELENGTH) :: title
6391  character(len=LINELENGTH) :: text
6392  !
6393  ! -- setup stage table
6394  if (this%iprhed > 0) then
6395  !
6396  ! -- Determine the number of lake stage terms. These are fixed for
6397  ! the simulation and cannot change. This includes FLOW-JA-FACE
6398  ! so they can be written to the binary budget files, but these internal
6399  ! flows are not included as part of the budget table.
6400  nterms = 5
6401  if (this%inamedbound == 1) then
6402  nterms = nterms + 1
6403  end if
6404  !
6405  ! -- set up table title
6406  title = trim(adjustl(this%text))//' PACKAGE ('// &
6407  trim(adjustl(this%packName))//') STAGES FOR EACH CONTROL VOLUME'
6408  !
6409  ! -- set up stage tableobj
6410  call table_cr(this%stagetab, this%packName, title)
6411  call this%stagetab%table_df(this%nlakes, nterms, this%iout, &
6412  transient=.true.)
6413  !
6414  ! -- Go through and set up table budget term
6415  if (this%inamedbound == 1) then
6416  text = 'NAME'
6417  call this%stagetab%initialize_column(text, 20, alignment=tableft)
6418  end if
6419  !
6420  ! -- lake number
6421  text = 'NUMBER'
6422  call this%stagetab%initialize_column(text, 10, alignment=tabcenter)
6423  !
6424  ! -- lake stage
6425  text = 'STAGE'
6426  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6427  !
6428  ! -- lake surface area
6429  text = 'SURFACE AREA'
6430  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6431  !
6432  ! -- lake wetted area
6433  text = 'WETTED AREA'
6434  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6435  !
6436  ! -- lake volume
6437  text = 'VOLUME'
6438  call this%stagetab%initialize_column(text, 12, alignment=tabcenter)
6439  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 5292 of file gwf-lak.f90.

5293  ! -- modules
5294  use tdismodule, only: delt
5295  ! -- dummy
5296  class(LakType), intent(inout) :: this
5297  logical(LGP), intent(in), optional :: update
5298  logical(LGP), intent(in), optional :: only_legacy
5299  ! -- local
5300  logical(LGP) :: lupdate
5301  logical(LGP) :: legonly
5302  integer(I4B) :: j
5303  integer(I4B) :: n
5304  integer(I4B) :: iicnvg
5305  integer(I4B) :: iter
5306  integer(I4B) :: maxiter
5307  integer(I4B) :: ncnv
5308  real(DP) :: hlak
5309  real(DP) :: hlak0
5310  real(DP) :: v0
5311  real(DP) :: v1
5312  real(DP) :: ro
5313  real(DP) :: qinf
5314  real(DP) :: ex
5315  real(DP) :: outinf
5316  real(DP) :: avail
5317  !
5318  ! -- set lupdate
5319  if (present(update)) then
5320  lupdate = update
5321  else
5322  lupdate = .true.
5323  end if
5324  !
5325  ! -- set legonly (solve only the lakes flagged for the legacy solver)
5326  if (present(only_legacy)) then
5327  legonly = only_legacy
5328  else
5329  legonly = .false.
5330  end if
5331  !
5332  ! -- initialize
5333  avail = dzero
5334  !
5335  ! -- initialize
5336  do n = 1, this%nlakes
5337  ! -- a lake not being solved on this call (an IMPLICIT lake when only the
5338  ! flagged lakes are solved) is treated as already converged and left
5339  ! untouched
5340  if (legonly .and. this%ilegacy(n) == 0) then
5341  this%ncncvr(n) = 1
5342  cycle
5343  end if
5344  this%ncncvr(n) = 0
5345  this%surfin(n) = dzero
5346  this%surfout(n) = dzero
5347  this%surfout1(n) = dzero
5348  if (this%xnewpak(n) < this%lakebot(n)) then
5349  this%xnewpak(n) = this%lakebot(n)
5350  end if
5351  if (this%gwfiss /= 0) then
5352  this%xoldpak(n) = this%xnewpak(n)
5353  end if
5354  ! -- lake iteration items
5355  this%iseepc(n) = 0
5356  this%idhc(n) = 0
5357  this%en1(n) = this%lakebot(n)
5358  call this%lak_calculate_residual(n, this%en1(n), this%r1(n))
5359  this%en2(n) = this%laketop(n)
5360  call this%lak_calculate_residual(n, this%en2(n), this%r2(n))
5361  end do
5362  ! -- a legacy-only solve keeps the outlet rates of the implicit lakes,
5363  ! which are final and still needed for the mover and downstream lakes
5364  do n = 1, this%noutlets
5365  if (legonly .and. this%ilegacy(this%lakein(n)) == 0) cycle
5366  this%simoutrate(n) = dzero
5367  end do
5368  !
5369  ! -- sum up inflows from mover inflows
5370  do n = 1, this%nlakes
5371  call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5372  end do
5373  !
5374  ! -- sum up overland runoff, inflows, and external flows into lake
5375  ! (includes maximum lake volume)
5376  do n = 1, this%nlakes
5377  hlak0 = this%xoldpak(n)
5378  hlak = this%xnewpak(n)
5379  call this%lak_calculate_runoff(n, ro)
5380  call this%lak_calculate_inflow(n, qinf)
5381  call this%lak_calculate_external(n, ex)
5382  call this%lak_calculate_vol(n, hlak0, v0)
5383  call this%lak_calculate_vol(n, hlak, v1)
5384  this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5385  max(v0, v1) / delt
5386  end do
5387  !
5388  ! -- sum up inflows from upstream outlets
5389  do n = 1, this%nlakes
5390  call this%lak_calculate_outlet_inflow(n, outinf)
5391  this%flwin(n) = this%flwin(n) + outinf
5392  end do
5393  !
5394  iicnvg = 0
5395  maxiter = this%maxlakit
5396  !
5397  ! -- outer loop
5398  converge: do iter = 1, maxiter
5399  ncnv = 0
5400  do n = 1, this%nlakes
5401  if (this%ncncvr(n) == 0) ncnv = 1
5402  end do
5403  if (iter == maxiter) ncnv = 0
5404  if (ncnv == 0) iicnvg = 1
5405  !
5406  ! -- initialize variables
5407  do n = 1, this%nlakes
5408  this%evap(n) = dzero
5409  this%precip(n) = dzero
5410  this%precip1(n) = dzero
5411  this%seep(n) = dzero
5412  this%seep1(n) = dzero
5413  this%evap(n) = dzero
5414  this%evap1(n) = dzero
5415  this%evapo(n) = dzero
5416  this%withr(n) = dzero
5417  this%withr1(n) = dzero
5418  this%flwiter(n) = this%flwin(n)
5419  this%flwiter1(n) = this%flwin(n)
5420  if (this%gwfiss /= 0) then
5421  this%flwiter(n) = dep20
5422  this%flwiter1(n) = dep20
5423  end if
5424  do j = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
5425  this%hcof(j) = dzero
5426  this%rhs(j) = dzero
5427  end do
5428  end do
5429  !
5430  do n = 1, this%nlakes
5431  if (legonly .and. this%ilegacy(n) == 0) cycle
5432  call this%lak_estimate_seepage_single(n, ncnv)
5433  end do
5434  !
5435  laklevel: do n = 1, this%nlakes
5436  if (legonly .and. this%ilegacy(n) == 0) cycle laklevel
5437  call this%lak_solve_single(n, iter, maxiter, ncnv, lupdate)
5438  end do laklevel
5439  !
5440  if (iicnvg == 1) exit converge
5441  !
5442  end do converge
5443  !
5444  ! -- Mover terms: store outflow after diversion loss
5445  ! as qformvr and reduce outflow (qd)
5446  ! by how much was actually sent to the mover. A legacy-only solve
5447  ! skips this because the implicit formulation accumulates the mover
5448  ! terms for every outlet once the legacy-solved stages are known.
5449  if (this%imover == 1 .and. .not. legonly) then
5450  do n = 1, this%noutlets
5451  call this%pakmvrobj%accumulate_qformvr(n, -this%simoutrate(n))
5452  end do
5453  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 5464 of file gwf-lak.f90.

5465  ! -- modules
5466  use tdismodule, only: delt
5467  ! -- dummy
5468  class(LakType), intent(inout) :: this
5469  integer(I4B), intent(in) :: n
5470  integer(I4B), intent(in) :: iter
5471  integer(I4B), intent(in) :: maxiter
5472  integer(I4B), intent(in) :: ncnv
5473  logical(LGP), intent(in) :: lupdate
5474  ! -- local
5475  integer(I4B) :: ibflg
5476  integer(I4B) :: idhp
5477  real(DP) :: hlak
5478  real(DP) :: hlak0
5479  real(DP) :: ra
5480  real(DP) :: ro
5481  real(DP) :: qinf
5482  real(DP) :: ex
5483  real(DP) :: ev
5484  real(DP) :: wr
5485  real(DP) :: resid
5486  real(DP) :: resid1
5487  real(DP) :: residb
5488  real(DP) :: derv
5489  real(DP) :: dh
5490  real(DP) :: ts
5491  real(DP) :: adh
5492  real(DP) :: adh0
5493  real(DP) :: v0
5494  real(DP) :: v1
5495  real(DP) :: area
5496  real(DP) :: qtolfact
5497  real(DP) :: delh
5498  !
5499  delh = this%delh
5500  !
5501  ! -- skip inactive lakes
5502  if (this%iboundpak(n) == 0) then
5503  this%ncncvr(n) = 1
5504  return
5505  end if
5506  ibflg = 0
5507  hlak = this%xnewpak(n)
5508  if (iter < maxiter) then
5509  this%stageiter(n) = this%xnewpak(n)
5510  end if
5511  call this%lak_calculate_rainfall(n, hlak, ra)
5512  this%precip(n) = ra
5513  this%flwiter(n) = this%flwiter(n) + ra
5514  call this%lak_calculate_rainfall(n, hlak + delh, ra)
5515  this%precip1(n) = ra
5516  this%flwiter1(n) = this%flwiter1(n) + ra
5517  !
5518  ! -- limit withdrawals to lake inflows and lake storage
5519  call this%lak_calculate_withdrawal(n, this%flwiter(n), wr)
5520  this%withr(n) = wr
5521  call this%lak_calculate_withdrawal(n, this%flwiter1(n), wr)
5522  this%withr1(n) = wr
5523  !
5524  ! -- limit evaporation to lake inflows and lake storage
5525  call this%lak_calculate_evaporation(n, hlak, this%flwiter(n), ev)
5526  this%evap(n) = ev
5527  call this%lak_calculate_evaporation(n, hlak + delh, this%flwiter1(n), ev)
5528  this%evap1(n) = ev
5529  !
5530  ! -- no outlet flow if evaporation consumes all water
5531  call this%lak_calculate_outlet_outflow(n, hlak + delh, &
5532  this%flwiter1(n), &
5533  this%surfout1(n))
5534  call this%lak_calculate_outlet_outflow(n, hlak, this%flwiter(n), &
5535  this%surfout(n))
5536  !
5537  ! -- update the surface inflow values
5538  call this%lak_calculate_outlet_inflow(n, this%surfin(n))
5539  !
5540  !
5541  if (ncnv == 1) then
5542  if (this%iboundpak(n) > 0 .and. lupdate .eqv. .true.) then
5543  !
5544  ! -- recalculate flwin
5545  hlak0 = this%xoldpak(n)
5546  hlak = this%xnewpak(n)
5547  call this%lak_calculate_vol(n, hlak0, v0)
5548  call this%lak_calculate_vol(n, hlak, v1)
5549  call this%lak_calculate_runoff(n, ro)
5550  call this%lak_calculate_inflow(n, qinf)
5551  call this%lak_calculate_external(n, ex)
5552  this%flwin(n) = this%surfin(n) + ro + qinf + ex + &
5553  max(v0, v1) / delt
5554  !
5555  ! -- compute new lake stage using Newton's method
5556  resid = this%precip(n) + this%evap(n) + this%withr(n) + ro + &
5557  qinf + ex + this%surfin(n) + &
5558  this%surfout(n) + this%seep(n)
5559  resid1 = this%precip1(n) + this%evap1(n) + this%withr1(n) + ro + &
5560  qinf + ex + this%surfin(n) + &
5561  this%surfout1(n) + this%seep1(n)
5562  !
5563  ! -- add storage changes for transient stress periods
5564  hlak = this%xnewpak(n)
5565  if (this%gwfiss /= 1) then
5566  call this%lak_calculate_vol(n, hlak, v1)
5567  resid = resid + (v0 - v1) / delt
5568  call this%lak_calculate_vol(n, hlak + delh, v1)
5569  resid1 = resid1 + (v0 - v1) / delt
5570  end if
5571  !
5572  ! -- determine the derivative and the stage change
5573  if (abs(resid1 - resid) > dzero) then
5574  derv = (resid1 - resid) / delh
5575  dh = dzero
5576  if (abs(derv) > dprec) then
5577  dh = resid / derv
5578  end if
5579  else
5580  if (resid < dzero) then
5581  resid = dzero
5582  end if
5583  call this%lak_vol2stage(n, resid, dh)
5584  dh = hlak - dh
5585  this%ncncvr(n) = 1
5586  end if
5587  !
5588  ! -- determine if the updated stage is outside the endpoints
5589  ts = hlak - dh
5590  if (iter == 1) this%dh0(n) = dh
5591  adh = abs(dh)
5592  adh0 = abs(this%dh0(n))
5593  if ((ts >= this%en2(n)) .or. (ts < this%en1(n))) then
5594  ! -- use bisection if dh is increasing or updated stage is below the
5595  ! bottom of the lake
5596  if ((adh > adh0) .or. (ts - this%lakebot(n)) < dprec) then
5597  residb = resid
5598  call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5599  end if
5600  end if
5601  !
5602  ! -- set seep0 on the first lake iteration
5603  if (iter == 1) then
5604  this%seep0(n) = this%seep(n)
5605  end if
5606  !
5607  ! -- check for slow convergence
5608  if (this%seep(n) * this%seep0(n) < dprec) then
5609  this%iseepc(n) = this%iseepc(n) + 1
5610  else
5611  this%iseepc(n) = 0
5612  end if
5613  ! -- determine of convergence is slow and oscillating
5614  idhp = 0
5615  if (dh * this%dh0(n) < dprec) idhp = 1
5616  ! -- determine if stage change is increasing
5617  adh = abs(dh)
5618  if (adh > adh0) idhp = 1
5619  ! -- increment idhc convergence flag
5620  if (idhp == 1) then
5621  this%idhc(n) = this%idhc(n) + 1
5622  end if
5623  !
5624  ! -- switch to bisection when the Newton-Raphson method oscillates
5625  ! or when convergence is slow
5626  if (ibflg == 1) then
5627  if (this%iseepc(n) > 7 .or. this%idhc(n) > 12) then
5628  call this%lak_bisection(n, ibflg, hlak, ts, dh, residb)
5629  end if
5630  end if
5631  else
5632  dh = dzero
5633  end if
5634  !
5635  ! -- update lake stage
5636  hlak = hlak - dh
5637  if (hlak < this%lakebot(n)) then
5638  hlak = this%lakebot(n)
5639  end if
5640  !
5641  ! -- calculate surface area
5642  call this%lak_calculate_sarea(n, hlak, area)
5643  !
5644  ! -- set the Q to length factor
5645  if (area > dzero) then
5646  qtolfact = delt / area
5647  else
5648  qtolfact = dzero
5649  end if
5650  !
5651  ! -- recalculate the residual
5652  call this%lak_calculate_residual(n, hlak, resid)
5653  !
5654  ! -- evaluate convergence
5655  !if (ABS(dh) < delh) then
5656  if (abs(dh) < delh .and. abs(resid) * qtolfact < this%dmaxchg) then
5657  this%ncncvr(n) = 1
5658  end if
5659  this%xnewpak(n) = hlak
5660  !
5661  ! -- save iterates for lake
5662  this%seep0(n) = this%seep(n)
5663  this%dh0(n) = dh
5664  end if

◆ lak_source_connectiondata()

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

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

848  ! -- dummy
849  class(LakType), intent(inout) :: this
850  ! -- local
851  integer(I4B) :: n, j, ipos, nn
852  integer(I4B) :: ilak, iconn
853  integer(I4B) :: ipos0, icellid0, icellid, nn2
854  logical(LGP) :: is_lake_bed
855  character(len=LINELENGTH) :: cellid_str
856  character(len=LINELENGTH) :: ctypenm
857  character(len=LINELENGTH) :: cbleak
858  real(DP) :: top, bot, rval
859  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
860  integer(I4B), dimension(:), pointer, contiguous :: iconns => null()
861  integer(I4B), dimension(:, :), pointer, contiguous :: cellid => null()
862  type(CharacterStringType), dimension(:), pointer, contiguous :: &
863  claktype => null()
864  type(CharacterStringType), dimension(:), pointer, contiguous :: &
865  bedleak => null()
866  real(DP), dimension(:), pointer, contiguous :: belev => null()
867  real(DP), dimension(:), pointer, contiguous :: telev => null()
868  real(DP), dimension(:), pointer, contiguous :: connlen => null()
869  real(DP), dimension(:), pointer, contiguous :: connwidth => null()
870  integer(I4B), allocatable :: nboundchk(:)
871  !
872  ! -- allocate connection data arrays
873  call mem_allocate(this%imap, this%MAXBOUND, 'IMAP', this%memoryPath)
874  call mem_allocate(this%gwfconn, this%MAXBOUND, 'GWFCONN', this%memoryPath)
875  call mem_allocate(this%nodesontop, this%MAXBOUND, 'NODESONTOP', &
876  this%memoryPath)
877  call mem_allocate(this%ictype, this%MAXBOUND, 'ICTYPE', this%memoryPath)
878  call mem_allocate(this%bedleak, this%MAXBOUND, 'BEDLEAK', this%memoryPath)
879  call mem_allocate(this%belev, this%MAXBOUND, 'BELEV', this%memoryPath)
880  call mem_allocate(this%telev, this%MAXBOUND, 'TELEV', this%memoryPath)
881  call mem_allocate(this%connlength, this%MAXBOUND, 'CONNLENGTH', &
882  this%memoryPath)
883  call mem_allocate(this%connwidth, this%MAXBOUND, 'CONNWIDTH', &
884  this%memoryPath)
885  call mem_allocate(this%sarea, this%MAXBOUND, 'SAREA', this%memoryPath)
886  call mem_allocate(this%warea, this%MAXBOUND, 'WAREA', this%memoryPath)
887  call mem_allocate(this%satcond, this%MAXBOUND, 'SATCOND', this%memoryPath)
888  call mem_allocate(this%simcond, this%MAXBOUND, 'SIMCOND', this%memoryPath)
889  call mem_allocate(this%simlakgw, this%MAXBOUND, 'SIMLAKGW', this%memoryPath)
890  !
891  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
892  ' CONNECTIONDATA'
893  !
894  ! -- get input context CONNECTIONDATA column arrays
895  call mem_setptr(ifno, 'CONNDATA_IFNO', this%input_mempath)
896  call mem_setptr(iconns, 'ICONN', this%input_mempath)
897  call mem_setptr(cellid, 'CELLID', this%input_mempath)
898  call mem_setptr(claktype, 'CLAKTYPE', this%input_mempath)
899  call mem_setptr(bedleak, 'BEDLEAK', this%input_mempath)
900  call mem_setptr(belev, 'BELEV', this%input_mempath)
901  call mem_setptr(telev, 'TELEV', this%input_mempath)
902  call mem_setptr(connlen, 'CONNLEN', this%input_mempath)
903  call mem_setptr(connwidth, 'CONNWIDTH', this%input_mempath)
904  !
905  ! -- allocate check array
906  allocate (nboundchk(this%MAXBOUND))
907  nboundchk = 0
908  !
909  do n = 1, this%MAXBOUND
910  !
911  ilak = ifno(n)
912  iconn = iconns(n)
913  !
914  if (ilak < 1 .or. ilak > this%nlakes) then
915  write (errmsg, '(a,1x,i0)') 'lakeno MUST BE > 0 and <= ', this%nlakes
916  call store_error(errmsg)
917  cycle
918  end if
919  if (iconn < 1 .or. iconn > this%nlakeconn(ilak)) then
920  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
921  'iconn FOR LAKE ', ilak, 'MUST BE > 0 and <= ', this%nlakeconn(ilak)
922  call store_error(errmsg)
923  cycle
924  end if
925  !
926  ipos = this%idxlakeconn(ilak) + iconn - 1
927  this%imap(ipos) = ilak
928  nboundchk(ipos) = nboundchk(ipos) + 1
929  !
930  ! -- convert cellid integer array to string and resolve to a node number.
931  write (cellid_str, '(10(i0,1x))') cellid(1:this%dis%ndim, n)
932  nn = this%dis%noder_from_cellid(cellid_str, this%inunit, this%iout)
933  if (nn < 1) then
934  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
935  'INVALID cellid FOR LAKE ', ilak, 'connection', iconn
936  call store_error(errmsg)
937  end if
938  this%gwfconn(ipos) = nn
939  this%nodesontop(ipos) = nn
940  !
941  ! -- connection type
942  ctypenm = claktype(n)
943  select case (trim(ctypenm))
944  case ('VERTICAL')
945  this%ictype(ipos) = 0
946  case ('HORIZONTAL')
947  this%ictype(ipos) = 1
948  case ('EMBEDDEDH')
949  this%ictype(ipos) = 2
950  case ('EMBEDDEDV')
951  this%ictype(ipos) = 3
952  case default
953  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,a,a)') &
954  'UNKNOWN ctype FOR LAKE ', ilak, 'connection', iconn, &
955  '(', trim(ctypenm), ')'
956  call store_error(errmsg)
957  end select
958  !
959  ! -- bed leakance
960  cbleak = bedleak(n)
961  select case (trim(cbleak))
962  case ('NONE')
963  is_lake_bed = .false.
964  rval = dnodata
965  write (warnmsg, '(2(a,1x,i0,1x),a,1pe8.1,a)') &
966  'BEDLEAK for connection', iconn, 'in lake', ilak, &
967  'is specified to be NONE. Lake connections where the lake-GWF '// &
968  'connection conductance is solely a function of aquifer '// &
969  'properties in the connected GWF cell should be specified '// &
970  'with a DNODATA (', dnodata, ') value.'
971  call deprecation_warning('CONNECTIONDATA', 'bedleak=NONE', '6.4.3', &
972  warnmsg, this%inunit)
973  case default
974  read (cbleak, *) rval
975  if (is_close(rval, dnodata)) then
976  is_lake_bed = .false.
977  else
978  is_lake_bed = .true.
979  end if
980  end select
981  this%bedleak(ipos) = rval
982  if (is_lake_bed .and. this%bedleak(ipos) < dzero) then
983  write (errmsg, '(a,1x,i0,1x,a)') 'bedleak FOR LAKE ', ilak, &
984  'MUST BE >= 0'
985  call store_error(errmsg)
986  end if
987  !
988  ! -- belev
989  this%belev(ipos) = belev(n)
990  !
991  ! -- telev
992  this%telev(ipos) = telev(n)
993  !
994  ! -- connection length
995  rval = connlen(n)
996  if (rval <= dzero) then
997  if (this%ictype(ipos) == 1 .or. this%ictype(ipos) == 2 .or. &
998  this%ictype(ipos) == 3) then
999  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,a,1x,a)') &
1000  'connection length (connlen) FOR LAKE ', ilak, &
1001  ', CONNECTION NO.', iconn, ', MUST BE > 0 FOR SPECIFIED ', &
1002  'connection type (ctype)', trim(ctypenm)
1003  call store_error(errmsg)
1004  else
1005  rval = dzero
1006  end if
1007  end if
1008  this%connlength(ipos) = rval
1009  !
1010  ! -- connection width
1011  rval = connwidth(n)
1012  if (rval < dzero) then
1013  if (this%ictype(ipos) == 1) then
1014  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1015  'cell width (connwidth) FOR LAKE ', ilak, &
1016  ' HORIZONTAL CONNECTION ', iconn, 'MUST BE >= 0'
1017  call store_error(errmsg)
1018  else
1019  rval = dzero
1020  end if
1021  end if
1022  this%connwidth(ipos) = rval
1023  end do
1024  !
1025  write (this%iout, '(1x,a)') &
1026  'END OF '//trim(adjustl(this%text))//' CONNECTIONDATA'
1027  !
1028  ! -- terminate if any errors were detected
1029  if (count_errors() > 0) then
1030  call store_error_filename(this%input_fname)
1031  end if
1032  !
1033  ! -- check that embedded lakes have only one connection
1034  do n = 1, this%nlakes
1035  j = 0
1036  do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1037  if (this%ictype(ipos) /= 2 .and. this%ictype(ipos) /= 3) cycle
1038  j = j + 1
1039  if (j > 1) then
1040  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1041  'nlakeconn FOR LAKE', n, 'EMBEDDED CONNECTION', j, ' EXCEEDS 1.'
1042  call store_error(errmsg)
1043  end if
1044  end do
1045  end do
1046  ! -- check that an embedded lake is not in the same cell as a lake
1047  ! with a vertical connection
1048  do n = 1, this%nlakes
1049  ipos0 = this%idxlakeconn(n)
1050  icellid0 = this%gwfconn(ipos0)
1051  if (this%ictype(ipos0) /= 2 .and. this%ictype(ipos0) /= 3) cycle
1052  do nn2 = 1, this%nlakes
1053  if (nn2 == n) cycle
1054  j = 0
1055  do ipos = this%idxlakeconn(nn2), this%idxlakeconn(nn2 + 1) - 1
1056  j = j + 1
1057  icellid = this%gwfconn(ipos)
1058  if (icellid == icellid0) then
1059  if (this%ictype(ipos) == 0) then
1060  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1061  'EMBEDDED LAKE', n, &
1062  'CANNOT COINCIDE WITH VERTICAL CONNECTION', j, &
1063  'IN LAKE', nn2, '.'
1064  call store_error(errmsg)
1065  end if
1066  end if
1067  end do
1068  end do
1069  end do
1070  !
1071  ! -- process the data (post-processing: telev/belev/laketop/lakebot)
1072  do n = 1, this%nlakes
1073  j = 0
1074  do ipos = this%idxlakeconn(n), this%idxlakeconn(n + 1) - 1
1075  j = j + 1
1076  nn = this%gwfconn(ipos)
1077  top = this%dis%top(nn)
1078  bot = this%dis%bot(nn)
1079  if (this%ictype(ipos) == 0) then
1080  this%telev(ipos) = top + this%surfdep
1081  this%belev(ipos) = top
1082  this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1083  else if (this%ictype(ipos) == 1) then
1084  if (this%belev(ipos) == this%telev(ipos)) then
1085  this%telev(ipos) = top
1086  this%belev(ipos) = bot
1087  else
1088  if (this%belev(ipos) >= this%telev(ipos)) then
1089  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
1090  'telev FOR LAKE ', n, ' HORIZONTAL CONNECTION ', j, &
1091  'MUST BE >= belev'
1092  call store_error(errmsg)
1093  else if (this%belev(ipos) < bot) then
1094  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1095  'belev FOR LAKE ', n, ' HORIZONTAL CONNECTION ', j, &
1096  'MUST BE >= cell bottom (', bot, ')'
1097  call store_error(errmsg)
1098  else if (this%telev(ipos) > top) then
1099  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.7,1x,a)') &
1100  'telev FOR LAKE ', n, ' HORIZONTAL CONNECTION ', j, &
1101  'MUST BE <= cell top (', top, ')'
1102  call store_error(errmsg)
1103  end if
1104  end if
1105  this%laketop(n) = max(this%telev(ipos), this%laketop(n))
1106  this%lakebot(n) = min(this%belev(ipos), this%lakebot(n))
1107  else if (this%ictype(ipos) == 2 .or. this%ictype(ipos) == 3) then
1108  this%telev(ipos) = top
1109  this%belev(ipos) = bot
1110  this%lakebot(n) = bot
1111  end if
1112  !
1113  ! -- check for missing or duplicate connections
1114  if (nboundchk(ipos) == 0) then
1115  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1116  'NO DATA SPECIFIED FOR LAKE', n, 'CONNECTION', j
1117  call store_error(errmsg)
1118  else if (nboundchk(ipos) > 1) then
1119  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a,1x,i0,1x,a)') &
1120  'DATA FOR LAKE', n, 'CONNECTION', j, &
1121  'SPECIFIED', nboundchk(ipos), 'TIMES'
1122  call store_error(errmsg)
1123  end if
1124  end do
1125  if (this%laketop(n) == -dep20) then
1126  this%laketop(n) = this%lakebot(n) + 100.
1127  end if
1128  end do
1129  !
1130  deallocate (nboundchk)
1131  !
1132  if (count_errors() > 0) then
1133  call store_error_filename(this%input_fname)
1134  end if
1135  !
1136  ! -- release input context connectiondata memory
1137  call memorystore_release('CONNDATA_IFNO', this%input_mempath)
1138  call memorystore_release('ICONN', this%input_mempath)
1139  call memorystore_release('CELLID', this%input_mempath)
1140  call memorystore_release('CLAKTYPE', this%input_mempath)
1141  call memorystore_release('BEDLEAK', this%input_mempath)
1142  call memorystore_release('BELEV', this%input_mempath)
1143  call memorystore_release('TELEV', this%input_mempath)
1144  call memorystore_release('CONNLEN', this%input_mempath)
1145  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 1575 of file gwf-lak.f90.

1576  ! -- dummy
1577  class(LakType), intent(inout) :: this
1578  ! -- local
1579  type(GwfLakParamFoundType) :: found
1580  !
1581  ! -- initialize dimensions to -1
1582  this%nlakes = -1
1583  this%maxbound = -1
1584  !
1585  write (this%iout, '(/1x,a)') &
1586  'PROCESSING '//trim(adjustl(this%text))//' DIMENSIONS'
1587  !
1588  ! -- NLAKES (mf6internal: nlakes); kept in the input context (not
1589  ! released) since PERIOD settings resolve it by name via SHAPE
1590  call mem_set_value(this%nlakes, 'NLAKES', this%input_mempath, &
1591  found%nlakes, release=.false.)
1592  if (found%nlakes) write (this%iout, '(4x,a,i7)') 'NLAKES = ', this%nlakes
1593  !
1594  ! -- NOUTLETS (mf6internal: noutlets); kept in the input context (not
1595  ! released) since PERIOD settings resolve it by name via SHAPE
1596  call mem_set_value(this%noutlets, 'NOUTLETS', this%input_mempath, &
1597  found%noutlets, release=.false.)
1598  if (found%noutlets) write (this%iout, '(4x,a,i7)') &
1599  'NOUTLETS = ', this%noutlets
1600  !
1601  ! -- NTABLES (mf6internal: ntables)
1602  call mem_set_value(this%ntables, 'NTABLES', this%input_mempath, found%ntables)
1603  if (found%ntables) write (this%iout, '(4x,a,i7)') 'NTABLES = ', this%ntables
1604  !
1605  write (this%iout, '(1x,a)') &
1606  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
1607  !
1608  if (this%nlakes < 0) then
1609  write (errmsg, '(a)') &
1610  'NLAKES WAS NOT SPECIFIED OR WAS SPECIFIED INCORRECTLY.'
1611  call store_error(errmsg)
1612  call store_error_filename(this%input_fname)
1613  return
1614  end if
1615  !
1616  if (this%iforceleglak /= 0) then
1617  if (this%iforceleglak < 1 .or. this%iforceleglak > this%nlakes) then
1618  write (errmsg, '(a,i0,a,i0,a)') &
1619  'DEV_FORCE_LEGACY_LAKE (', this%iforceleglak, &
1620  ') MUST BE BETWEEN 1 AND NLAKES (', this%nlakes, ').'
1621  call store_error(errmsg)
1622  call store_error_filename(this%input_fname)
1623  return
1624  end if
1625  end if
1626  !
1627  ! -- read PACKAGEDATA
1628  call this%lak_source_packagedata()
1629  !
1630  ! -- for the implicit formulation each lake adds one equation (one row and
1631  ! column) to the groundwater flow matrix
1632  if (this%iimplicit /= 0) then
1633  this%npakeq = this%nlakes
1634  ! -- the implicit lake-aquifer coupling is asymmetric for perched
1635  ! connections, so flag the coefficient matrix as asymmetric (which
1636  ! requires the BICGSTAB linear acceleration). Only raise the flag; never
1637  ! clear an asymmetry already indicated elsewhere.
1638  this%iasym = 1
1639  end if
1640  !
1641  ! -- read CONNECTIONDATA
1642  call this%lak_source_connectiondata()
1643  !
1644  ! -- read TABLES
1645  call this%lak_source_tables()
1646  !
1647  ! -- read OUTLETS
1648  call this%lak_source_outlets()
1649  !
1650  ! -- alias deprecated variable names
1651  call this%lak_checkin_deprecated_names()
1652  !
1653  ! -- Call define_listlabel
1654  call this%define_listlabel()
1655  !
1656  ! -- setup the budget object
1657  call this%lak_setup_budobj()
1658  !
1659  ! -- setup the stage table object
1660  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 2972 of file gwf-lak.f90.

2973  ! -- dummy
2974  class(LakType), intent(inout) :: this
2975  ! -- local
2976  type(GwfLakParamFoundType) :: found
2977  integer(I4B) :: isize
2978  character(len=LINELENGTH) :: fname
2979  ! -- formats
2980  character(len=*), parameter :: fmtlengthconv = &
2981  &"(4x, 'LENGTH CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2982  character(len=*), parameter :: fmttimeconv = &
2983  &"(4x, 'TIME CONVERSION VALUE (',g15.7,') SPECIFIED.')"
2984  character(len=*), parameter :: fmtlakeopt = &
2985  &"(4x, 'LAKE ', a, ' VALUE (',g15.7,') SPECIFIED.')"
2986  character(len=*), parameter :: fmtoutdmax = &
2987  &"(4x, 'MAXIMUM OUTLET WATER DEPTH (',g15.7,') SPECIFIED.')"
2988  character(len=*), parameter :: fmtlakbin = &
2989  "(4x, 'LAK ', 1x, a, 1x, ' WILL BE SAVED TO FILE: ', &
2990  &a, /4x, 'OPENED ON UNIT: ', I0)"
2991  character(len=*), parameter :: fmtiter = &
2992  &"(4x, 'MAXIMUM LAK ITERATION VALUE (',i0,') SPECIFIED.')"
2993  character(len=*), parameter :: fmtdmaxchg = &
2994  &"(4x, 'MAXIMUM STAGE CHANGE VALUE (',g0,') SPECIFIED.')"
2995  !
2996  ! -- call base class to handle AUXILIARY/NAUX, BOUNDNAMES, PRINT_INPUT,
2997  ! PRINT_FLOWS, SAVE_FLOWS, OBS6_FILENAME
2998  call this%BndExtType%source_options()
2999  !
3000  write (this%iout, '(1x,a)') &
3001  'PROCESSING '//trim(adjustl(this%text))//' OPTIONS'
3002  !
3003  ! -- PRINT_STAGE
3004  call mem_set_value(this%iprhed, 'PRINT_STAGE', this%input_mempath, &
3005  found%print_stage)
3006  if (found%print_stage) then
3007  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
3008  ' STAGES WILL BE PRINTED TO LISTING FILE.'
3009  end if
3010  !
3011  ! -- STAGE FILEOUT
3012  call mem_set_value(fname, 'STAGEFILE', this%input_mempath, found%stagefile)
3013  if (found%stagefile) then
3014  this%istageout = getunit()
3015  call openfile(this%istageout, this%iout, fname, 'DATA(BINARY)', &
3016  form, access, 'REPLACE', mode_opt=mnormal)
3017  write (this%iout, fmtlakbin) 'STAGE', trim(adjustl(fname)), this%istageout
3018  end if
3019  !
3020  ! -- BUDGET FILEOUT
3021  call mem_set_value(fname, 'BUDGETFILE', this%input_mempath, found%budgetfile)
3022  if (found%budgetfile) then
3023  call assign_iounit(this%ibudgetout, this%inunit, 'BUDGET fileout')
3024  call openfile(this%ibudgetout, this%iout, fname, 'DATA(BINARY)', &
3025  form, access, 'REPLACE', mode_opt=mnormal)
3026  write (this%iout, fmtlakbin) 'BUDGET', trim(adjustl(fname)), this%ibudgetout
3027  end if
3028  !
3029  ! -- BUDGETCSV FILEOUT
3030  call mem_set_value(fname, 'BUDGETCSVFILE', this%input_mempath, &
3031  found%budgetcsvfile)
3032  if (found%budgetcsvfile) then
3033  call assign_iounit(this%ibudcsv, this%inunit, 'BUDGETCSV fileout')
3034  call openfile(this%ibudcsv, this%iout, fname, 'CSV', filstat_opt='REPLACE')
3035  write (this%iout, fmtlakbin) 'BUDGET CSV', trim(adjustl(fname)), &
3036  this%ibudcsv
3037  end if
3038  !
3039  ! -- PACKAGE_CONVERGENCE FILEOUT (mf6internal: pkgconvfname)
3040  ! -- defer opening until lak_ar, where the IMPLICIT option is known. The
3041  ! file is not opened for the implicit formulation (lak_cc does not
3042  ! write package convergence in that case).
3043  call mem_set_value(fname, 'PKGCONVFNAME', this%input_mempath, &
3044  found%pkgconvfname)
3045  if (found%pkgconvfname) then
3046  this%pakcsvfile = trim(adjustl(fname))
3047  end if
3048  !
3049  ! -- MOVER
3050  call mem_set_value(this%imover, 'MOVER', this%input_mempath, found%mover)
3051  if (found%mover) then
3052  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
3053  end if
3054  !
3055  ! -- LENGTH_CONVERSION (mf6internal: convlength)
3056  call mem_set_value(this%convlength, 'CONVLENGTH', this%input_mempath, &
3057  found%convlength)
3058  if (found%convlength) write (this%iout, fmtlengthconv) this%convlength
3059  !
3060  ! -- TIME_CONVERSION (mf6internal: convtime)
3061  call mem_set_value(this%convtime, 'CONVTIME', this%input_mempath, &
3062  found%convtime)
3063  if (found%convtime) write (this%iout, fmttimeconv) this%convtime
3064  !
3065  ! -- SURFDEP (mf6internal: surfdep)
3066  call mem_set_value(this%surfdep, 'SURFDEP', this%input_mempath, found%surfdep)
3067  if (found%surfdep) then
3068  if (this%surfdep < dzero) this%surfdep = dzero
3069  write (this%iout, fmtlakeopt) 'SURFDEP', this%surfdep
3070  end if
3071  !
3072  ! -- MAXIMUM_ITERATIONS (mf6internal: maxlakit)
3073  call mem_set_value(this%maxlakit, 'MAXLAKIT', this%input_mempath, &
3074  found%maxlakit)
3075  if (found%maxlakit) write (this%iout, fmtiter) this%maxlakit
3076  !
3077  ! -- MAXIMUM_STAGE_CHANGE (mf6internal: dmaxchg)
3078  call mem_set_value(this%dmaxchg, 'DMAXCHG', this%input_mempath, found%dmaxchg)
3079  if (found%dmaxchg) then
3080  this%delh = dp999 * this%dmaxchg
3081  write (this%iout, fmtdmaxchg) this%dmaxchg
3082  end if
3083  !
3084  ! -- DEV_GROUNDWATER_HEAD_CONDUCTANCE (mf6internal: igwhcopt)
3085  call mem_set_value(this%igwhcopt, 'IGWHCOPT', this%input_mempath, &
3086  found%igwhcopt)
3087  if (found%igwhcopt) then
3088  write (this%iout, '(4x,a)') &
3089  'CONDUCTANCE FOR HORIZONTAL CONNECTIONS WILL BE CALCULATED &
3090  &USING THE GROUNDWATER HEAD'
3091  end if
3092  !
3093  ! -- IMPLICIT (mf6internal: iimplicit)
3094  call mem_set_value(this%iimplicit, 'IIMPLICIT', this%input_mempath, &
3095  found%iimplicit)
3096  if (found%iimplicit) then
3097  write (this%iout, '(4x,a)') &
3098  'LAKE STAGE WILL BE SOLVED AS AN UNKNOWN IN THE GROUNDWATER FLOW '// &
3099  'MATRIX (IMPLICIT FORMULATION)'
3100  end if
3101  !
3102  ! -- DEV_FORCE_LEGACY (mf6internal: iforceleg)
3103  call mem_set_value(this%iforceleg, 'IFORCELEG', this%input_mempath, &
3104  found%iforceleg)
3105  !
3106  ! -- DEV_FORCE_LEGACY_LAKE (mf6internal: iforceleglak); loaded before
3107  ! either block below so both mutual-exclusion checks see a final value
3108  call mem_set_value(this%iforceleglak, 'IFORCELEGLAK', this%input_mempath, &
3109  found%iforceleglak)
3110  !
3111  if (found%iforceleg) then
3112  write (this%iout, '(4x,a)') &
3113  'EVERY ACTIVE LAKE WILL BE SOLVED WITH THE LEGACY SUBSTITUTION '// &
3114  'SOLVER UNDER THE IMPLICIT FORMULATION'
3115  if (this%iforceleglak /= 0) then
3116  call store_error('DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3117  'cannot both be specified.')
3118  end if
3119  end if
3120  !
3121  if (found%iforceleglak) then
3122  write (this%iout, '(4x,a,i0,a)') 'LAKE ', this%iforceleglak, &
3123  ' WILL BE SOLVED WITH THE LEGACY SUBSTITUTION SOLVER UNDER THE '// &
3124  'IMPLICIT FORMULATION'
3125  if (this%iforceleg /= 0) then
3126  call store_error('DEV_FORCE_LEGACY and DEV_FORCE_LEGACY_LAKE '// &
3127  'cannot both be specified.')
3128  end if
3129  end if
3130  !
3131  ! -- DEV_NO_FINAL_CHECK (mf6internal: iconvchk)
3132  call get_isize('ICONVCHK', this%input_mempath, isize)
3133  if (isize > 0) then
3134  this%iconvchk = 0
3135  write (this%iout, '(4x,a)') &
3136  'A FINAL CONVERGENCE CHECK OF THE CHANGE IN LAKE STAGES &
3137  &WILL NOT BE MADE'
3138  end if
3139  !
3140  ! -- DEV_MAXIMUM_OUTLET_DEPTH (mf6internal: outdmax)
3141  call mem_set_value(this%outdmax, 'OUTDMAX', this%input_mempath, found%outdmax)
3142  if (found%outdmax) write (this%iout, fmtoutdmax) this%outdmax
3143  !
3144  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 1441 of file gwf-lak.f90.

1442  ! -- dummy
1443  class(LakType), intent(inout) :: this
1444  ! -- local
1445  integer(I4B) :: n, isize, ioutlet
1446  character(len=LINELENGTH) :: keyword
1447  integer(I4B), dimension(:), pointer, contiguous :: outletno => null()
1448  integer(I4B), dimension(:), pointer, contiguous :: lakein => null()
1449  integer(I4B), dimension(:), pointer, contiguous :: lakeout => null()
1450  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1451  couttype => null()
1452  real(DP), dimension(:), pointer, contiguous :: outlets_invert => null()
1453  real(DP), dimension(:), pointer, contiguous :: outlets_width => null()
1454  real(DP), dimension(:), pointer, contiguous :: outlets_rough => null()
1455  real(DP), dimension(:), pointer, contiguous :: outlets_slope => null()
1456  integer(I4B), allocatable :: nboundchk(:)
1457  !
1458  ! -- skip if no outlets
1459  if (this%noutlets < 1) return
1460  !
1461  ! -- guard: OUTLETS block required when noutlets > 0
1462  call get_isize('OUTLETS_OUTLETNO', this%input_mempath, isize)
1463  if (isize < 1) then
1464  write (errmsg, '(a)') &
1465  'NOUTLETS > 0 BUT AN OUTLETS BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1466  call store_error(errmsg, .true.)
1467  end if
1468  !
1469  ! -- allocate outlet arrays
1470  call mem_allocate(this%lakein, this%noutlets, 'LAKEIN', this%memoryPath)
1471  call mem_allocate(this%lakeout, this%noutlets, 'LAKEOUT', this%memoryPath)
1472  call mem_allocate(this%iouttype, this%noutlets, 'IOUTTYPE', this%memoryPath)
1473  ! -- alias into the input context's permanent, feature-indexed arrays
1474  ! (allocated and DZERO-initialized by the loader)
1475  call mem_setptr(this%outrate, 'RATE', this%input_mempath)
1476  call mem_setptr(this%outinvert, 'INVERT', this%input_mempath)
1477  call mem_setptr(this%outwidth, 'WIDTH', this%input_mempath)
1478  call mem_setptr(this%outrough, 'ROUGH', this%input_mempath)
1479  call mem_setptr(this%outslope, 'SLOPE', this%input_mempath)
1480  call mem_allocate(this%simoutrate, this%noutlets, 'SIMOUTRATE', &
1481  this%memoryPath)
1482  call mem_allocate(this%outlet_invert_set, this%noutlets, &
1483  'INVERT_SET', this%memoryPath)
1484  call mem_allocate(this%outlet_width_set, this%noutlets, &
1485  'WIDTH_SET', this%memoryPath)
1486  call mem_allocate(this%outlet_rough_set, this%noutlets, &
1487  'ROUGH_SET', this%memoryPath)
1488  call mem_allocate(this%outlet_slope_set, this%noutlets, &
1489  'SLOPE_SET', this%memoryPath)
1490  this%outlet_invert_set = .false.
1491  this%outlet_width_set = .false.
1492  this%outlet_rough_set = .false.
1493  this%outlet_slope_set = .false.
1494  !
1495  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1496  ' OUTLETS'
1497  !
1498  ! -- set input context pointers
1499  call mem_setptr(outletno, 'OUTLETS_OUTLETNO', this%input_mempath)
1500  call mem_setptr(lakein, 'LAKEIN', this%input_mempath)
1501  call mem_setptr(lakeout, 'LAKEOUT', this%input_mempath)
1502  call mem_setptr(couttype, 'COUTTYPE', this%input_mempath)
1503  call mem_setptr(outlets_invert, 'OUTLETS_INVERT', this%input_mempath)
1504  call mem_setptr(outlets_width, 'OUTLETS_WIDTH', this%input_mempath)
1505  call mem_setptr(outlets_rough, 'OUTLETS_ROUGH', this%input_mempath)
1506  call mem_setptr(outlets_slope, 'OUTLETS_SLOPE', this%input_mempath)
1507  !
1508  allocate (nboundchk(this%noutlets))
1509  nboundchk = 0
1510  !
1511  do n = 1, size(outletno)
1512  ioutlet = this%validate_ifno(outletno(n), this%noutlets, &
1513  nboundchk, 'outletno', 'OUTLETS')
1514  if (ioutlet == 0) cycle
1515  !
1516  ! -- lakein
1517  if (lakein(n) < 1 .or. lakein(n) > this%nlakes) then
1518  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1519  'lakein FOR OUTLET ', ioutlet, 'MUST BE > 0 and <= ', this%nlakes
1520  call store_error(errmsg)
1521  end if
1522  this%lakein(ioutlet) = lakein(n)
1523  !
1524  ! -- lakeout
1525  if (lakeout(n) < 0 .or. lakeout(n) > this%nlakes) then
1526  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1527  'lakeout FOR OUTLET ', ioutlet, 'MUST BE >= 0 and <= ', this%nlakes
1528  call store_error(errmsg)
1529  end if
1530  this%lakeout(ioutlet) = lakeout(n)
1531  !
1532  ! -- outlet type
1533  keyword = couttype(n)
1534  select case (trim(keyword))
1535  case ('SPECIFIED')
1536  this%iouttype(ioutlet) = 0
1537  case ('MANNING')
1538  this%iouttype(ioutlet) = 1
1539  case ('WEIR')
1540  this%iouttype(ioutlet) = 2
1541  case default
1542  write (errmsg, '(a,1x,i0,1x,a,a,a)') &
1543  'UNKNOWN couttype FOR OUTLET ', ioutlet, '(', trim(keyword), ')'
1544  call store_error(errmsg)
1545  end select
1546  !
1547  ! -- outlet invert, width, roughness, slope
1548  this%outinvert(ioutlet) = outlets_invert(n)
1549  this%outwidth(ioutlet) = outlets_width(n)
1550  this%outrough(ioutlet) = outlets_rough(n)
1551  this%outslope(ioutlet) = outlets_slope(n)
1552  end do
1553  !
1554  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))//' OUTLETS'
1555  !
1556  ! -- check for duplicate or missing outlets
1557  call this%report_ifno_coverage(nboundchk, this%noutlets, 'outlet', &
1558  'OUTLETS')
1559  !
1560  deallocate (nboundchk)
1561  !
1562  if (count_errors() > 0) then
1563  call store_error_filename(this%input_fname)
1564  end if
1565  !
1566  ! -- release input context outlets memory; OUTLETS_OUTLETNO/INVERT/
1567  ! WIDTH/ROUGH/SLOPE excluded (bound by lak_input_init for PERIOD use)
1568  call memorystore_release('LAKEIN', this%input_mempath)
1569  call memorystore_release('LAKEOUT', this%input_mempath)
1570  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)

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

647  ! -- dummy
648  class(LakType), intent(inout) :: this
649  ! -- local
650  integer(I4B) :: n
651  integer(I4B) :: ilak, nconn
652  character(len=9) :: cno
653  character(len=LENBOUNDNAME) :: bndName
654  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
655  real(DP), dimension(:), pointer, contiguous :: strt => null()
656  integer(I4B), dimension(:), pointer, contiguous :: nlakeconn => null()
657  type(CharacterStringType), dimension(:), pointer, contiguous :: &
658  boundname_cst => null()
659  integer(I4B), allocatable :: nboundchk(:)
660  !
661  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
662  ' PACKAGEDATA'
663  !
664  ! -- allocate lake arrays
665  call mem_allocate(this%nlakeconn, this%nlakes, 'NLAKECONN', this%memoryPath)
666  call mem_allocate(this%idxlakeconn, this%nlakes + 1, 'IDXLAKECONN', &
667  this%memoryPath)
668  call mem_allocate(this%ntabrow, this%nlakes, 'NTABROW', this%memoryPath)
669  call mem_allocate(this%strt, this%nlakes, 'STRT', this%memoryPath)
670  call mem_allocate(this%laketop, this%nlakes, 'LAKETOP', this%memoryPath)
671  call mem_allocate(this%lakebot, this%nlakes, 'LAKEBOT', this%memoryPath)
672  call mem_allocate(this%sareamax, this%nlakes, 'SAREAMAX', this%memoryPath)
673  ! -- alias into the input context's permanent, feature-indexed arrays
674  ! (allocated and DZERO-initialized by the loader)
675  call mem_setptr(this%stage, 'STAGE', this%input_mempath)
676  call mem_setptr(this%rainfall, 'RAINFALL', this%input_mempath)
677  call mem_setptr(this%evaporation, 'EVAPORATION', this%input_mempath)
678  call mem_setptr(this%runoff, 'RUNOFF', this%input_mempath)
679  call mem_setptr(this%inflow, 'INFLOW', this%input_mempath)
680  call mem_setptr(this%withdrawal, 'WITHDRAWAL', this%input_mempath)
681  call mem_allocate(this%avail, this%nlakes, 'AVAIL', this%memoryPath)
682  call mem_allocate(this%lkgwsink, this%nlakes, 'LKGWSINK', this%memoryPath)
683  call mem_allocate(this%ncncvr, this%nlakes, 'NCNCVR', this%memoryPath)
684  call mem_allocate(this%ilegacy, this%nlakes, 'ILEGACY', this%memoryPath)
685  call mem_allocate(this%nstuck, this%nlakes, 'NSTUCK', this%memoryPath)
686  call mem_allocate(this%surfin, this%nlakes, 'SURFIN', this%memoryPath)
687  call mem_allocate(this%surfout, this%nlakes, 'SURFOUT', this%memoryPath)
688  call mem_allocate(this%surfout1, this%nlakes, 'SURFOUT1', this%memoryPath)
689  call mem_allocate(this%precip, this%nlakes, 'PRECIP', this%memoryPath)
690  call mem_allocate(this%precip1, this%nlakes, 'PRECIP1', this%memoryPath)
691  call mem_allocate(this%evap, this%nlakes, 'EVAP', this%memoryPath)
692  call mem_allocate(this%evap1, this%nlakes, 'EVAP1', this%memoryPath)
693  call mem_allocate(this%evapo, this%nlakes, 'EVAPO', this%memoryPath)
694  call mem_allocate(this%withr, this%nlakes, 'WITHR', this%memoryPath)
695  call mem_allocate(this%withr1, this%nlakes, 'WITHR1', this%memoryPath)
696  call mem_allocate(this%flwin, this%nlakes, 'FLWIN', this%memoryPath)
697  call mem_allocate(this%flwiter, this%nlakes, 'FLWITER', this%memoryPath)
698  call mem_allocate(this%flwiter1, this%nlakes, 'FLWITER1', this%memoryPath)
699  call mem_allocate(this%seep, this%nlakes, 'SEEP', this%memoryPath)
700  call mem_allocate(this%seep1, this%nlakes, 'SEEP1', this%memoryPath)
701  call mem_allocate(this%seep0, this%nlakes, 'SEEP0', this%memoryPath)
702  call mem_allocate(this%stageiter, this%nlakes, 'STAGEITER', this%memoryPath)
703  call mem_allocate(this%chterm, this%nlakes, 'CHTERM', this%memoryPath)
704  !
705  ! -- lake boundary and stages. In the implicit formulation iboundpak
706  ! and xnewpak are aliased to slices of the global ibound/x vectors in
707  ! lak_set_pointers (called before this routine), so they are not
708  ! allocated here.
709  if (this%iimplicit == 0) then
710  call mem_allocate(this%iboundpak, this%nlakes, 'IBOUND', this%memoryPath)
711  call mem_allocate(this%xnewpak, this%nlakes, 'XNEWPAK', this%memoryPath)
712  end if
713  call mem_allocate(this%xoldpak, this%nlakes, 'XOLDPAK', this%memoryPath)
714  !
715  ! -- lake iteration variables
716  call mem_allocate(this%iseepc, this%nlakes, 'ISEEPC', this%memoryPath)
717  call mem_allocate(this%idhc, this%nlakes, 'IDHC', this%memoryPath)
718  call mem_allocate(this%en1, this%nlakes, 'EN1', this%memoryPath)
719  call mem_allocate(this%en2, this%nlakes, 'EN2', this%memoryPath)
720  call mem_allocate(this%r1, this%nlakes, 'R1', this%memoryPath)
721  call mem_allocate(this%r2, this%nlakes, 'R2', this%memoryPath)
722  call mem_allocate(this%dh0, this%nlakes, 'DH0', this%memoryPath)
723  call mem_allocate(this%s0, this%nlakes, 'S0', this%memoryPath)
724  call mem_allocate(this%qgwf0, this%nlakes, 'QGWF0', this%memoryPath)
725  !
726  ! -- allocate character storage
727  allocate (this%lakename(this%nlakes))
728  allocate (this%status(this%nlakes))
729  !
730  ! -- initialize arrays
731  do n = 1, this%nlakes
732  this%ntabrow(n) = 0
733  this%status(n) = 'ACTIVE'
734  this%laketop(n) = -dep20
735  this%lakebot(n) = dep20
736  this%sareamax(n) = dzero
737  ! -- in the implicit formulation iboundpak/xnewpak are not yet associated
738  ! (they are aliased to the global arrays later in lak_set_pointers and
739  ! initialized in lak_read_initial_attr); only touch them here for the
740  ! legacy formulation
741  if (this%iimplicit == 0) then
742  this%iboundpak(n) = 1
743  this%xnewpak(n) = dep20
744  end if
745  this%xoldpak(n) = dep20
746  this%rainfall(n) = dzero
747  this%evaporation(n) = dzero
748  this%runoff(n) = dzero
749  this%inflow(n) = dzero
750  this%withdrawal(n) = dzero
751  this%ilegacy(n) = 0
752  this%nstuck(n) = 0
753  end do
754  !
755  ! -- get input context PACKAGEDATA column arrays
756  call mem_setptr(ifno, 'PACKAGEDATA_IFNO', this%input_mempath)
757  call mem_setptr(strt, 'STRT', this%input_mempath)
758  call mem_setptr(nlakeconn, 'NLAKECONN', this%input_mempath)
759  if (this%inamedbound /= 0) then
760  call mem_setptr(boundname_cst, 'BOUNDNAME', this%input_mempath)
761  end if
762  !
763  ! -- allocate check array
764  allocate (nboundchk(this%nlakes))
765  nboundchk = 0
766  ilak = 0
767  nconn = 0
768  !
769  do n = 1, this%nlakes
770  !
771  ! -- lake number from input
772  ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
773  'lakeno', 'PACKAGEDATA')
774  if (ilak == 0) cycle
775  !
776  ! -- strt
777  this%strt(ilak) = strt(n)
778  !
779  ! -- nlakeconn
780  if (nlakeconn(n) < 0) then
781  write (errmsg, '(a,1x,i0)') 'nlakeconn MUST BE >= 0 for lake ', ilak
782  call store_error(errmsg)
783  end if
784  !
785  ! -- the IMPLICIT formulation solves the lake stage as a matrix unknown,
786  ! which requires at least one groundwater connection to give the lake
787  ! row a non-zero diagonal; a lake with no connections is not supported
788  if (this%iimplicit /= 0 .and. nlakeconn(n) == 0) then
789  write (errmsg, '(a,1x,i0,1x,a)') &
790  'lake', ilak, 'has no connections; the IMPLICIT option requires &
791  &each lake to have at least one GWF connection.'
792  call store_error(errmsg)
793  end if
794  !
795  nconn = nconn + nlakeconn(n)
796  this%nlakeconn(ilak) = nlakeconn(n)
797  !
798  ! -- set default bndName
799  write (cno, '(i9.9)') ilak
800  bndname = 'Lake'//cno
801  !
802  ! -- lakename from boundname if provided
803  if (this%inamedbound /= 0) then
804  bndname = boundname_cst(n)
805  if (trim(bndname) == '') then
806  write (cno, '(i9.9)') ilak
807  bndname = 'Lake'//cno
808  end if
809  end if
810  this%lakename(ilak) = bndname
811  end do
812  !
813  ! -- check for duplicate or missing lakes
814  call this%report_ifno_coverage(nboundchk, this%nlakes, 'lake', &
815  'PACKAGEDATA')
816  !
817  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))// &
818  ' PACKAGEDATA'
819  !
820  ! -- terminate if any errors were detected
821  if (count_errors() > 0) then
822  call store_error_filename(this%input_fname)
823  end if
824  !
825  ! -- set MAXBOUND
826  this%MAXBOUND = nconn
827  write (this%iout, '(//4x,a,i7)') 'MAXBOUND = ', this%maxbound
828  !
829  ! -- set idxlakeconn
830  this%idxlakeconn(1) = 1
831  do n = 1, this%nlakes
832  this%idxlakeconn(n + 1) = this%idxlakeconn(n) + this%nlakeconn(n)
833  end do
834  !
835  ! -- deallocate check array
836  deallocate (nboundchk)
837  !
838  ! -- release input context packagedata memory; PACKAGEDATA_IFNO excluded
839  ! because allocate_featureauxvar retains a pointer to it
840  call memorystore_release('STRT', this%input_mempath)
841  call memorystore_release('NLAKECONN', this%input_mempath)
842  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 1290 of file gwf-lak.f90.

1291  ! -- dummy
1292  class(LakType), intent(inout) :: this
1293  integer(I4B), intent(in) :: ilak
1294  character(len=*), intent(in) :: mempath
1295  type(LakTabType), intent(inout) :: laketable
1296  ! -- local
1297  integer(I4B), pointer :: nrow => null()
1298  integer(I4B), pointer :: ncol => null()
1299  real(DP), dimension(:), pointer, contiguous :: stage => null()
1300  real(DP), dimension(:), pointer, contiguous :: volume => null()
1301  real(DP), dimension(:), pointer, contiguous :: sarea => null()
1302  real(DP), dimension(:), pointer, contiguous :: barea => null()
1303  character(len=:), pointer :: tabfname => null()
1304  integer(I4B) :: jmin, iconn, n, nerr0
1305  real(DP) :: vol, sa, wa, v, v0
1306  ! -- formats
1307  character(len=*), parameter :: fmttaberr = &
1308  &'(a,1x,i0,1x,a,1x,g15.6,1x,a,1x,i0,1x,a,1x,i0,1x,a,1x,g15.6,1x,a)'
1309  !
1310  ! -- this table's own input file, for error attribution below
1311  call mem_setptr(tabfname, 'INPUT_FNAME', mempath)
1312  call mem_setptr(nrow, 'NROW', mempath)
1313  call mem_setptr(ncol, 'NCOL', mempath)
1314  !
1315  ! -- errors added below this point belong to this lake's own table
1316  nerr0 = count_errors()
1317  !
1318  if (nrow < 1) then
1319  write (errmsg, '(a,1x,i0)') &
1320  'LAKE TABLE NROW MUST BE > 0 FOR LAKE', ilak
1321  call store_error(errmsg)
1322  end if
1323  !
1324  iconn = this%idxlakeconn(ilak)
1325  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1326  jmin = 4
1327  else
1328  jmin = 3
1329  end if
1330  if (ncol < jmin) then
1331  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1332  'LAKE TABLE NCOL MUST BE >=', jmin, 'FOR LAKE', ilak
1333  call store_error(errmsg)
1334  end if
1335  !
1336  if (count_errors() > nerr0) then
1337  call store_error_filename(tabfname, terminate=.false.)
1338  call memorystore_release('NROW', mempath)
1339  call memorystore_release('NCOL', mempath)
1340  call memorystore_release('INPUT_FNAME', mempath)
1341  return
1342  end if
1343  !
1344  this%ntabrow(ilak) = nrow
1345  allocate (laketable%tabstage(nrow))
1346  allocate (laketable%tabvolume(nrow))
1347  allocate (laketable%tabsarea(nrow))
1348  call mem_setptr(stage, 'STAGE', mempath)
1349  call mem_setptr(volume, 'VOLUME', mempath)
1350  call mem_setptr(sarea, 'SAREA', mempath)
1351  laketable%tabstage = stage
1352  laketable%tabvolume = volume
1353  laketable%tabsarea = sarea
1354  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1355  allocate (laketable%tabwarea(nrow))
1356  call mem_setptr(barea, 'BAREA', mempath)
1357  laketable%tabwarea = barea
1358  end if
1359  !
1360  ! -- set lake bottom based on table if it is an embedded lake
1361  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1362  do n = 1, this%ntabrow(ilak)
1363  vol = laketable%tabvolume(n)
1364  sa = laketable%tabsarea(n)
1365  wa = laketable%tabwarea(n)
1366  vol = vol * sa * wa
1367  ! -- check if all entries are zero
1368  if (vol > dzero) exit
1369  ! -- set lake bottom
1370  this%lakebot(ilak) = laketable%tabstage(n)
1371  this%belev(ilak) = laketable%tabstage(n)
1372  end do
1373  ! -- set maximum surface area for rainfall
1374  n = this%ntabrow(ilak)
1375  this%sareamax(ilak) = laketable%tabsarea(n)
1376  end if
1377  !
1378  ! -- verify the table data
1379  do n = 2, this%ntabrow(ilak)
1380  v = laketable%tabstage(n)
1381  v0 = laketable%tabstage(n - 1)
1382  if (v <= v0) then
1383  write (errmsg, fmttaberr) &
1384  'TABLE STAGE ENTRY', n, '(', laketable%tabstage(n), ') FOR LAKE ', &
1385  ilak, 'MUST BE GREATER THAN THE PREVIOUS STAGE ENTRY', &
1386  n - 1, '(', laketable%tabstage(n - 1), ')'
1387  call store_error(errmsg)
1388  end if
1389  v = laketable%tabvolume(n)
1390  v0 = laketable%tabvolume(n - 1)
1391  if (v <= v0) then
1392  write (errmsg, fmttaberr) &
1393  'TABLE VOLUME ENTRY', n, '(', laketable%tabvolume(n), &
1394  ') FOR LAKE ', &
1395  ilak, 'MUST BE GREATER THAN THE PREVIOUS VOLUME ENTRY', &
1396  n - 1, '(', laketable%tabvolume(n - 1), ')'
1397  call store_error(errmsg)
1398  end if
1399  v = laketable%tabsarea(n)
1400  v0 = laketable%tabsarea(n - 1)
1401  if (v < v0) then
1402  write (errmsg, fmttaberr) &
1403  'TABLE SURFACE AREA ENTRY', n, '(', &
1404  laketable%tabsarea(n), ') FOR LAKE ', ilak, &
1405  'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS SURFACE AREA ENTRY', &
1406  n - 1, '(', laketable%tabsarea(n - 1), ')'
1407  call store_error(errmsg)
1408  end if
1409  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1410  v = laketable%tabwarea(n)
1411  v0 = laketable%tabwarea(n - 1)
1412  if (v < v0) then
1413  write (errmsg, fmttaberr) &
1414  'TABLE EXCHANGE AREA ENTRY', n, '(', &
1415  laketable%tabwarea(n), ') FOR LAKE ', ilak, &
1416  'MUST BE GREATER THAN OR EQUAL TO THE PREVIOUS EXCHANGE AREA '// &
1417  'ENTRY', n - 1, '(', laketable%tabwarea(n - 1), ')'
1418  call store_error(errmsg)
1419  end if
1420  end if
1421  end do
1422  !
1423  if (count_errors() > nerr0) then
1424  call store_error_filename(tabfname, terminate=.false.)
1425  end if
1426  !
1427  ! -- release this table's own input context memory
1428  call memorystore_release('NROW', mempath)
1429  call memorystore_release('NCOL', mempath)
1430  call memorystore_release('STAGE', mempath)
1431  call memorystore_release('VOLUME', mempath)
1432  call memorystore_release('SAREA', mempath)
1433  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1434  call memorystore_release('BAREA', mempath)
1435  end if
1436  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 1150 of file gwf-lak.f90.

1151  ! -- dummy
1152  class(LakType), intent(inout) :: this
1153  ! -- local
1154  integer(I4B) :: n, ntabs
1155  integer(I4B) :: ilak, iconn
1156  character(len=LENMEMPATH) :: mempath
1157  integer(I4B), dimension(:), pointer, contiguous :: ifno => null()
1158  type(CharacterStringType), dimension(:), pointer, contiguous :: &
1159  laktab6_mempaths => null()
1160  type(LakTabType), dimension(:), allocatable :: laketables
1161  integer(I4B), allocatable :: nboundchk(:)
1162  !
1163  ! -- skip if no tables
1164  if (this%ntables < 1) return
1165  !
1166  ! -- guard: TABLES block required when ntables > 0
1167  call get_isize('TABLES_IFNO', this%input_mempath, ntabs)
1168  if (ntabs < 1) then
1169  write (errmsg, '(a)') &
1170  'NTABLES > 0 BUT A TABLES BLOCK WAS NOT FOUND IN THE LAK INPUT.'
1171  call store_error(errmsg, .true.)
1172  end if
1173  !
1174  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1175  ' TABLES'
1176  !
1177  ! -- set input context pointers
1178  call mem_setptr(ifno, 'TABLES_IFNO', this%input_mempath)
1179  call mem_setptr(laktab6_mempaths, 'LAKTAB6_MEMPATH', this%input_mempath)
1180  !
1181  ntabs = size(ifno)
1182  !
1183  ! -- allocate
1184  allocate (laketables(this%nlakes))
1185  allocate (nboundchk(this%nlakes))
1186  nboundchk = 0
1187  !
1188  do n = 1, ntabs
1189  ilak = this%validate_ifno(ifno(n), this%nlakes, nboundchk, &
1190  'lakeno', 'TABLES')
1191  if (ilak == 0) cycle
1192  mempath = laktab6_mempaths(n)
1193  call this%lak_source_table(ilak, mempath, laketables(ilak))
1194  end do
1195  !
1196  write (this%iout, '(1x,a)') 'END OF '//trim(adjustl(this%text))//' TABLES'
1197  !
1198  ! -- check for missing or duplicate table data
1199  if (ntabs < this%ntables) then
1200  write (errmsg, '(a,1x,i0,1x,a,1x,i0)') &
1201  'TABLE DATA ARE SPECIFIED', ntabs, &
1202  'TIMES BUT NTABLES IS SET TO', this%ntables
1203  call store_error(errmsg)
1204  end if
1205  ! -- a table that never loaded any rows is not reported as a duplicate
1206  do n = 1, this%nlakes
1207  if (this%ntabrow(n) == 0) nboundchk(n) = 0
1208  end do
1209  call this%report_ifno_coverage(nboundchk, this%nlakes, 'lakeno', &
1210  'TABLES', check_missing=.false.)
1211  !
1212  deallocate (nboundchk)
1213  !
1214  if (count_errors() > 0) then
1215  call store_error_filename(this%input_fname)
1216  end if
1217  !
1218  ! -- release input context tables memory
1219  call memorystore_release('TABLES_IFNO', this%input_mempath)
1220  !
1221  ! -- convert laketables to vectors
1222  call this%laktables_to_vectors(laketables)
1223  !
1224  ! -- destroy laketables
1225  do n = 1, this%nlakes
1226  if (this%ntabrow(n) > 0) then
1227  deallocate (laketables(n)%tabstage)
1228  deallocate (laketables(n)%tabvolume)
1229  deallocate (laketables(n)%tabsarea)
1230  iconn = this%idxlakeconn(n)
1231  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1232  deallocate (laketables(n)%tabwarea)
1233  end if
1234  end if
1235  end do
1236  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 2814 of file gwf-lak.f90.

2815  ! -- dummy
2816  class(LakType), intent(inout) :: this
2817  integer(I4B), intent(in) :: ilak
2818  real(DP), intent(in) :: vol
2819  real(DP), intent(inout) :: stage
2820  ! -- local
2821  integer(I4B) :: i
2822  integer(I4B) :: ibs
2823  real(DP) :: s0, s1, sm
2824  real(DP) :: v0, v1, vm
2825  real(DP) :: f0, f1, fm
2826  real(DP) :: sa
2827  real(DP) :: en0, en1
2828  real(DP) :: ds, ds0
2829  real(DP) :: denom
2830  !
2831  s0 = this%lakebot(ilak)
2832  call this%lak_calculate_vol(ilak, s0, v0)
2833  s1 = this%laketop(ilak)
2834  call this%lak_calculate_vol(ilak, s1, v1)
2835  ! -- zero volume
2836  if (vol <= v0) then
2837  stage = s0
2838  ! -- linear relation between stage and volume above top of lake
2839  else if (vol >= v1) then
2840  call this%lak_calculate_sarea(ilak, s1, sa)
2841  stage = s1 + (vol - v1) / sa
2842  ! -- use combination of secant and bisection
2843  else
2844  en0 = s0
2845  en1 = s1
2846  ! sm = s1 ! causes divide by zero in 1st line in secantbisection loop
2847  ! sm = s0 ! causes divide by zero in 1st line in secantbisection loop
2848  sm = dzero
2849  f0 = vol - v0
2850  f1 = vol - v1
2851  ibs = 0
2852  secantbisection: do i = 1, 150
2853  denom = f1 - f0
2854  if (denom /= dzero) then
2855  ds = f1 * (s1 - s0) / denom
2856  else
2857  ibs = 13
2858  end if
2859  if (i == 1) then
2860  ds0 = ds
2861  end if
2862  ! -- use bisection if end points are exceeded
2863  if (sm < en0 .or. sm > en1) ibs = 13
2864  ! -- use bisection if secant method stagnates or if
2865  ! ds exceeds previous ds - bisection would occur
2866  ! after conditions exceeded in 13 iterations
2867  if (ds * ds0 < dprec .or. abs(ds) > abs(ds0)) ibs = ibs + 1
2868  if (ibs > 12) then
2869  ds = dhalf * (s1 - s0)
2870  ibs = 0
2871  end if
2872  sm = s1 - ds
2873  if (abs(ds) < dem6) then
2874  exit secantbisection
2875  end if
2876  call this%lak_calculate_vol(ilak, sm, vm)
2877  fm = vol - vm
2878  s0 = s1
2879  f0 = f1
2880  s1 = sm
2881  f1 = fm
2882  ds0 = ds
2883  end do secantbisection
2884  stage = sm
2885  if (abs(ds) >= dem6) then
2886  write (this%iout, '(1x,a,1x,i0,4(1x,a,1x,g15.6))') &
2887  & 'LAK_VOL2STAGE failed for lake', ilak, 'volume error =', fm, &
2888  & 'finding stage (', stage, ') for volume =', vol, &
2889  & 'final change in stage =', ds
2890  end if
2891  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 1242 of file gwf-lak.f90.

1243  class(LakType), intent(inout) :: this
1244  type(LakTabType), intent(in), dimension(:), contiguous :: laketables
1245  integer(I4B) :: n
1246  integer(I4B) :: ntabrows
1247  integer(I4B) :: j
1248  integer(I4B) :: ipos
1249  integer(I4B) :: iconn
1250  !
1251  ! -- allocate index array for lak tables
1252  call mem_allocate(this%ialaktab, this%nlakes + 1, 'IALAKTAB', this%memoryPath)
1253  !
1254  ! -- Move the laktables structure information into flattened arrays
1255  this%ialaktab(1) = 1
1256  do n = 1, this%nlakes
1257  ! -- ialaktab contains a pointer into the flattened lak table data
1258  this%ialaktab(n + 1) = this%ialaktab(n) + this%ntabrow(n)
1259  end do
1260  !
1261  ! -- Allocate vectors for storing all lake table data
1262  ntabrows = this%ialaktab(this%nlakes + 1) - 1
1263  call mem_allocate(this%tabstage, ntabrows, 'TABSTAGE', this%memoryPath)
1264  call mem_allocate(this%tabvolume, ntabrows, 'TABVOLUME', this%memoryPath)
1265  call mem_allocate(this%tabsarea, ntabrows, 'TABSAREA', this%memoryPath)
1266  call mem_allocate(this%tabwarea, ntabrows, 'TABWAREA', this%memoryPath)
1267  !
1268  ! -- Copy data from laketables into vectors
1269  do n = 1, this%nlakes
1270  j = 1
1271  do ipos = this%ialaktab(n), this%ialaktab(n + 1) - 1
1272  this%tabstage(ipos) = laketables(n)%tabstage(j)
1273  this%tabvolume(ipos) = laketables(n)%tabvolume(j)
1274  this%tabsarea(ipos) = laketables(n)%tabsarea(j)
1275  iconn = this%idxlakeconn(n)
1276  if (this%ictype(iconn) == 2 .or. this%ictype(iconn) == 3) then
1277  !
1278  ! -- tabwarea only filled for ictype 2 and 3
1279  this%tabwarea(ipos) = laketables(n)%tabwarea(j)
1280  else
1281  this%tabwarea(ipos) = dzero
1282  end if
1283  j = j + 1
1284  end do
1285  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'