MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
BoundaryPackage.f90
Go to the documentation of this file.
1 !> @brief This module contains the base boundary package
2 !!
3 !! This module contains the base model boundary package class that is
4 !! extended by all model boundary packages. The base model boundary
5 !! package extends the NumericalPackageType.
6 !<
7 module bndmodule
8 
9  use kindmodule, only: dp, lgp, i4b
11  dzero, done, &
16  use simvariablesmodule, only: errmsg
17  use simmodule, only: count_errors, store_error, &
20  use obsmodule, only: obstype, obs_cr
21  use tdismodule, only: delt, totimc
22  use observemodule, only: observetype
27  use listmodule, only: listtype
29  use basedismodule, only: disbasetype
31  use tablemodule, only: tabletype, table_cr
34 
35  implicit none
36 
37  private
39  public :: save_print_model_flows
40  private :: castasbndclass
41 
42  !> @ brief BndType
43  !!
44  !! Generic boundary package type. This derived type can be overridden to
45  !! become concrete boundary package types.
46  !<
47  type, extends(numericalpackagetype) :: bndtype
48  ! -- characters
49  character(len=LENLISTLABEL), pointer :: listlabel => null() !< title of table written for RP
50  character(len=LENPACKAGENAME) :: text = '' !< text string for package flow term
51  character(len=LENAUXNAME), dimension(:), pointer, &
52  contiguous :: auxname => null() !< vector of auxname
53  type(characterstringtype), dimension(:), pointer, &
54  contiguous :: auxname_cst => null() !< copy of vector auxname that can be stored in memory manager
55  character(len=LENBOUNDNAME), dimension(:), pointer, &
56  contiguous :: boundname => null() !< vector of boundnames
57  type(characterstringtype), dimension(:), pointer, &
58  contiguous :: boundname_cst => null() !< copy of vector boundname that can be stored in memory manager
59  !
60  ! -- scalars
61  integer(I4B), pointer :: isadvpak => null() !< flag indicating package is advanced (1) or not (0)
62  integer(I4B), pointer :: ibcnum => null() !< consecutive package number for this boundary condition
63  integer(I4B), pointer :: maxbound => null() !< max number of boundaries
64  integer(I4B), pointer :: nbound => null() !< number of boundaries for current stress period
65  integer(I4B), pointer :: ncolbnd => null() !< number of columns of the bound array
66  integer(I4B), pointer :: iscloc => null() !< bound column to scale with SFAC
67  integer(I4B), pointer :: naux => null() !< number of auxiliary variables
68  integer(I4B), pointer :: inamedbound => null() !< flag to read boundnames
69  integer(I4B), pointer :: iauxmultcol => null() !< column to use as multiplier for column iscloc
70  integer(I4B), pointer :: npakeq => null() !< number of equations in this package (normally 0 unless package adds rows to matrix)
71  integer(I4B), pointer :: ioffset => null() !< offset of this package in the model
72  ! -- arrays
73  integer(I4B), dimension(:), pointer, contiguous :: nodelist => null() !< vector of reduced node numbers
74  integer(I4B), dimension(:), pointer, contiguous :: noupdateauxvar => null() !< override auxvars from being updated
75  real(dp), dimension(:, :), pointer, contiguous :: bound => null() !< array of package specific boundary numbers
76  real(dp), dimension(:), pointer, contiguous :: hcof => null() !< diagonal contribution
77  real(dp), dimension(:), pointer, contiguous :: rhs => null() !< right-hand side contribution
78  real(dp), dimension(:, :), pointer, contiguous :: auxvar => null() !< auxiliary variable array
79  real(dp), dimension(:), pointer, contiguous :: simvals => null() !< simulated values
80  real(dp), dimension(:), pointer, contiguous :: simtomvr => null() !< simulated to mover values
81  !
82  ! -- water mover flag and object
83  integer(I4B), pointer :: imover => null() !< flag indicating if the mover is active in the package
84  type(packagemovertype), pointer :: pakmvrobj => null() !< mover object for package
85  !
86  ! -- viscosity flag and safe-copy of conductance array
87  integer(I4B), pointer :: ivsc => null() !< flag indicating if viscosity is active in the model
88  real(dp), dimension(:), pointer, contiguous :: condinput => null() !< stores user-specified conductance values
89  !
90  ! -- timeseries
91  type(timeseriesmanagertype), pointer :: tsmanager => null() !< time series manager
92  type(timearrayseriesmanagertype), pointer :: tasmanager => null() !< time array series manager
93  integer(I4B) :: indxconvertflux = 0 !< indxconvertflux is column of bound to multiply by area to convert flux to rate
94  logical(LGP) :: allowtimearrayseries = .false.
95  !
96  ! -- pointers for observations
97  integer(I4B), pointer :: inobspkg => null() !< unit number for obs package
98  type(obstype), pointer :: obs => null() !< observation package
99  !
100  ! -- pointers to model/solution variables
101  integer(I4B), pointer :: neq !< number of equations for model
102  integer(I4B), dimension(:), pointer, contiguous :: ibound => null() !< model ibound array
103  real(dp), dimension(:), pointer, contiguous :: xnew => null() !< model dependent variable (head) for this time step
104  real(dp), dimension(:), pointer, contiguous :: xold => null() !< model dependent variable for last time step
105  real(dp), dimension(:), pointer, contiguous :: flowja => null() !< model intercell flows
106  integer(I4B), dimension(:), pointer, contiguous :: icelltype => null() !< pointer to icelltype array in NPF
107  character(len=LENMEMPATH) :: ictmempath = '' !< memory path to the icelltype data (for GWF this is in NPF)
108  !
109  ! -- table objects
110  type(tabletype), pointer :: inputtab => null() !< input table object
111  type(tabletype), pointer :: outputtab => null() !< output table object for package flows writtent to the model listing file
112  type(tabletype), pointer :: errortab => null() !< package error table
113 
114  contains
115  procedure, public :: bnd_df
116  procedure :: bnd_ac
117  procedure :: bnd_mc
118  procedure :: bnd_ar
119  procedure :: bnd_rp
120  procedure :: bnd_ad
121  procedure :: bnd_ck
122  procedure :: bnd_reset
123  procedure :: bnd_cf
124  procedure :: bnd_fc
125  procedure :: bnd_fn
126  procedure :: bnd_nur
127  procedure :: bnd_cc
128  procedure :: bnd_cq
129  procedure :: bnd_bd
130  procedure :: bnd_ot_model_flows
131  procedure :: bnd_ot_package_flows
132  procedure :: bnd_ot_dv
133  procedure :: bnd_ot_bdsummary
134  procedure :: bnd_da
135 
136  procedure :: allocate_scalars
137  procedure :: allocate_arrays
138  procedure :: pack_initialize
139  procedure :: read_options => bnd_read_options
140  procedure :: read_dimensions => bnd_read_dimensions
141  procedure :: read_initial_attr => bnd_read_initial_attr
142  procedure :: bnd_options
143  procedure :: bnd_cq_simrate
144  procedure :: bnd_cq_simtomvr
145  procedure :: set_pointers
146  procedure :: define_listlabel
147  procedure :: copy_boundname
148  procedure, private :: pak_setup_outputtab
149  !
150  ! -- procedures to support observations
151  procedure, public :: bnd_obs_supported
152  procedure, public :: bnd_df_obs
153  procedure, public :: bnd_bd_obs
154  procedure, public :: bnd_ot_obs
155  procedure, public :: bnd_rp_obs
156  procedure, public :: bnd_rp_log
157  !
158  ! -- procedure to support time series
159  procedure, public :: bnd_rp_ts
160  !
161  ! -- procedure to inform package that viscosity active
162  procedure, public :: bnd_activate_viscosity
163  !
164  ! -- procedure to backup user-specified conductance
165  procedure, private :: bnd_store_user_cond
166  !
167  end type bndtype
168 
169 contains
170 
171  !> @ brief Define boundary package options and dimensions
172  !!
173  !! Define base boundary package options and dimensions for
174  !! a model boundary package.
175  !<
176  subroutine bnd_df(this, neq, dis)
177  ! -- modules
180  ! -- dummy
181  class(bndtype), intent(inout) :: this !< BndType object
182  integer(I4B), intent(inout) :: neq !< number of equations
183  class(disbasetype), pointer :: dis !< discretization object
184  !
185  ! -- set pointer to dis object for the model
186  this%dis => dis
187  !
188  ! -- Create time series managers
189  call tsmanager_cr(this%TsManager, this%iout)
190  call tasmanager_cr(this%TasManager, dis, this%name_model, this%iout)
191  !
192  ! -- create obs package
193  call obs_cr(this%obs, this%inobspkg)
194  !
195  ! -- Write information to model list file
196  write (this%iout, 1) this%filtyp, trim(adjustl(this%text)), this%inunit
197 1 format(1x, /1x, a, ' -- ', a, ' PACKAGE, VERSION 8, 2/22/2014', &
198  ' INPUT READ FROM UNIT ', i0)
199  !
200  ! -- Initialize block parser
201  call this%parser%Initialize(this%inunit, this%iout)
202  !
203  ! -- set and read options
204  call this%read_options()
205  !
206  ! -- Now that time series will have been read, need to call the df
207  ! routine to define the manager
208  call this%tsmanager%tsmanager_df()
209  call this%tasmanager%tasmanager_df()
210  !
211  ! -- read the package dimensions block
212  call this%read_dimensions()
213  !
214  ! -- update package moffset for packages that add rows
215  if (this%npakeq > 0) then
216  this%ioffset = neq - this%dis%nodes
217  end if
218  !
219  ! -- update neq
220  neq = neq + this%npakeq
221  !
222  ! -- Store information needed for observations
223  if (this%bnd_obs_supported()) then
224  call this%obs%obs_df(this%iout, this%packName, this%filtyp, this%dis)
225  call this%bnd_df_obs()
226  end if
227  end subroutine bnd_df
228 
229  !> @ brief Add boundary package connection to matrix
230  !!
231  !! Add boundary package connection to the matrix for packages that add
232  !! connections to the coefficient matrix. An example would be the GWF model
233  !! MAW package. Base implementation that must be extended.
234  !<
235  subroutine bnd_ac(this, moffset, sparse)
236  ! -- modules
237  use sparsemodule, only: sparsematrix
238  use simmodule, only: store_error
239  ! -- dummy
240  class(bndtype), intent(inout) :: this !< BndType object
241  integer(I4B), intent(in) :: moffset !< solution matrix model offset
242  type(sparsematrix), intent(inout) :: sparse !< sparse object
243  end subroutine bnd_ac
244 
245  !> @ brief Map boundary package connection to matrix
246  !!
247  !! Map boundary package connection to the matrix for packages that add
248  !! connections to the coefficient matrix. An example would be the GWF model
249  !! MAW package. Base implementation that must be extended.
250  !<
251  subroutine bnd_mc(this, moffset, matrix_sln)
252  ! -- dummy
253  class(bndtype), intent(inout) :: this !< BndType object
254  integer(I4B), intent(in) :: moffset !< solution matrix model offset
255  class(matrixbasetype), pointer :: matrix_sln !< global system matrix
256  end subroutine bnd_mc
257 
258  !> @ brief Allocate and read method for boundary package
259  !!
260  !! Generic method to allocate and read static data for model boundary
261  !! packages. A boundary package only needs to override this method if
262  !! input data varies from the standard boundary package.
263  !<
264  subroutine bnd_ar(this)
265  ! -- modules
267  ! -- dummy
268  class(bndtype), intent(inout) :: this !< BndType object
269  !
270  ! -- allocate and read observations
271  call this%obs%obs_ar()
272  !
273  ! -- Allocate arrays in package superclass
274  call this%allocate_arrays()
275  !
276  ! -- read optional initial package parameters
277  call this%read_initial_attr()
278  !
279  ! -- setup pakmvrobj for standard stress packages
280  if (this%imover == 1) then
281  allocate (this%pakmvrobj)
282  call this%pakmvrobj%ar(this%maxbound, 0, this%memoryPath)
283  end if
284  end subroutine bnd_ar
285 
286  !> @ brief Allocate and read method for package
287  !!
288  !! Generic method to read and prepare period data for model boundary
289  !! packages. A boundary package only needs to override this method if
290  !! period data varies from the standard boundary package.
291  !<
292  subroutine bnd_rp(this)
293  ! -- modules
294  use tdismodule, only: kper, nper
295  ! -- dummy
296  class(bndtype), intent(inout) :: this !< BndType object
297  ! -- local
298  integer(I4B) :: ierr
299  integer(I4B) :: nlist
300  logical(LGP) :: isfound
301  character(len=LINELENGTH) :: line
302  ! -- formats
303  character(len=*), parameter :: fmtblkerr = &
304  &"('Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
305  character(len=*), parameter :: fmtlsp = &
306  &"(1X,/1X,'REUSING ',A,'S FROM LAST STRESS PERIOD')"
307  character(len=*), parameter :: fmtnbd = &
308  "(1X,/1X,'THE NUMBER OF ACTIVE ',A,'S (',I6, &
309  &') IS GREATER THAN MAXIMUM(',I6,')')"
310  !
311  ! -- Set ionper to the stress period number for which a new block of data
312  ! will be read.
313  if (this%inunit == 0) return
314  !
315  ! -- get stress period data
316  if (this%ionper < kper) then
317  !
318  ! -- get period block
319  call this%parser%GetBlock('PERIOD', isfound, ierr, &
320  supportopenclose=.true., &
321  blockrequired=.false.)
322  if (isfound) then
323  !
324  ! -- read ionper and check for increasing period numbers
325  call this%read_check_ionper()
326  else
327  !
328  ! -- PERIOD block not found
329  if (ierr < 0) then
330  ! -- End of file found; data applies for remainder of simulation.
331  this%ionper = nper + 1
332  else
333  ! -- Found invalid block
334  call this%parser%GetCurrentLine(line)
335  write (errmsg, fmtblkerr) adjustl(trim(line))
336  call store_error(errmsg)
337  call this%parser%StoreErrorUnit()
338  end if
339  end if
340  end if
341  !
342  ! -- read data if ionper == kper
343  if (this%ionper == kper) then
344  nlist = -1
345  ! -- Remove all time-series and time-array-series links associated with
346  ! this package.
347  call this%TsManager%Reset(this%packName)
348  call this%TasManager%Reset(this%packName)
349  !
350  ! -- Read data as a list
351  call this%dis%read_list(this%parser%line_reader, &
352  this%parser%iuactive, this%iout, &
353  this%iprpak, nlist, this%inamedbound, &
354  this%iauxmultcol, this%nodelist, &
355  this%bound, this%auxvar, this%auxname, &
356  this%boundname, this%listlabel, &
357  this%packName, this%tsManager, this%iscloc)
358  this%nbound = nlist
359  !
360  ! -- save user-specified conductance if vsc package is active
361  if (this%ivsc == 1) then
362  call this%bnd_store_user_cond(nlist, this%bound, this%condinput)
363  end if
364  !
365  ! Define the tsLink%Text value(s) appropriately.
366  ! E.g. for WEL package, entry 1, assign tsLink%Text = 'Q'
367  ! For RIV package, entry 1 text = 'STAGE', entry 2 text = 'COND',
368  ! entry 3 text = 'RBOT'; etc.
369  call this%bnd_rp_ts()
370  !
371  ! -- Terminate the block
372  call this%parser%terminateblock()
373  !
374  ! -- Copy boundname into boundname_cst
375  call this%copy_boundname()
376  !
377  else
378  write (this%iout, fmtlsp) trim(this%filtyp)
379  end if
380  end subroutine bnd_rp
381 
382  !> @ brief Advance the boundary package
383  !!
384  !! Advance data in the boundary package. The method sets advances
385  !! time series, time array series, and observation data. A boundary
386  !! package only needs to override this method if additional data
387  !! needs to be advanced.
388  !<
389  subroutine bnd_ad(this)
390  ! -- dummy
391  class(bndtype) :: this !< BndType object
392  ! -- local
393  real(DP) :: begintime, endtime
394  !
395  ! -- Initialize time variables
396  begintime = totimc
397  endtime = begintime + delt
398  !
399  ! -- Advance the time series managers
400  call this%TsManager%ad()
401  call this%TasManager%ad()
402  !
403  ! -- For each observation, push simulated value and corresponding
404  ! simulation time from "current" to "preceding" and reset
405  ! "current" value.
406  call this%obs%obs_ad()
407  end subroutine bnd_ad
408 
409  !> @ brief Check boundary package period data
410  !!
411  !! Check the boundary package period data. Base implementation that
412  !! must be extended by each model boundary package.
413  !<
414  subroutine bnd_ck(this)
415  ! -- dummy
416  class(bndtype), intent(inout) :: this !< BndType object
417  !
418  ! -- check stress period data
419  ! -- each package must override generic functionality
420  end subroutine bnd_ck
421 
422  !> @ brief Reset bnd package before formulating
423  !<
424  subroutine bnd_reset(this)
425  class(bndtype) :: this !< BndType object
426 
427  if (this%imover == 1) then
428  call this%pakmvrobj%reset()
429  end if
430 
431  end subroutine bnd_reset
432 
433  !> @ brief Formulate the package hcof and rhs terms.
434  !!
435  !! Formulate the hcof and rhs terms for the package that will be
436  !! added to the coefficient matrix and right-hand side vector.
437  !! Base implementation that must be extended by each model
438  !! boundary package.
439  !<
440  subroutine bnd_cf(this)
441  ! -- modules
442  class(bndtype) :: this !< BndType object
443  !
444  ! -- bnd has no cf routine
445  end subroutine bnd_cf
446 
447  !> @ brief Copy hcof and rhs terms into solution.
448  !!
449  !! Add the hcof and rhs terms for the boundary package to the
450  !! coefficient matrix and right-hand side vector. A boundary
451  !! package only needs to override this method if it is different for
452  !! a specific boundary package.
453  !<
454  subroutine bnd_fc(this, rhs, ia, idxglo, matrix_sln)
455  ! -- dummy
456  class(bndtype) :: this !< BndType object
457  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
458  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
459  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
460  class(matrixbasetype), pointer :: matrix_sln !< solution coefficient matrix
461  ! -- local
462  integer(I4B) :: i
463  integer(I4B) :: n
464  integer(I4B) :: ipos
465  !
466  ! -- Copy package rhs and hcof into solution rhs and amat
467  do i = 1, this%nbound
468  n = this%nodelist(i)
469  rhs(n) = rhs(n) + this%rhs(i)
470  ipos = ia(n)
471  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
472  end do
473  end subroutine bnd_fc
474 
475  !> @ brief Add Newton-Raphson terms for package into solution.
476  !!
477  !! Calculate and add the Newton-Raphson terms for the boundary package
478  !! to the coefficient matrix and right-hand side vector. A boundary
479  !! package only needs to override this method if a specific boundary
480  !! package needs to add Newton-Raphson terms.
481  !<
482  subroutine bnd_fn(this, rhs, ia, idxglo, matrix_sln)
483  ! -- dummy
484  class(bndtype) :: this !< BndType object
485  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
486  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
487  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
488  class(matrixbasetype), pointer :: matrix_sln !< solution coefficient matrix
489  !
490  ! -- No addition terms for Newton-Raphson with constant conductance
491  ! boundary conditions
492  end subroutine bnd_fn
493 
494  !> @ brief Apply Newton-Raphson under-relaxation for package.
495  !!
496  !! Apply Newton-Raphson under-relaxation for a boundary package. A boundary
497  !! package only needs to override this method if a specific boundary
498  !! package needs to apply Newton-Raphson under-relaxation. An example is
499  !! the MAW package which adds rows to the system of equations and may need
500  !! to have the dependent-variable constrained by the bottom of the model.
501  !<
502  subroutine bnd_nur(this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
503  ! -- dummy
504  class(bndtype), intent(inout) :: this !< BndType object
505  integer(I4B), intent(in) :: neqpak !< number of equations in the package
506  real(DP), dimension(neqpak), intent(inout) :: x !< dependent variable
507  real(DP), dimension(neqpak), intent(in) :: xtemp !< previous dependent variable
508  real(DP), dimension(neqpak), intent(inout) :: dx !< change in dependent variable
509  integer(I4B), intent(inout) :: inewtonur !< flag indicating if newton-raphson under-relaxation should be applied
510  real(DP), intent(inout) :: dxmax !< maximum change in the dependent variable
511  integer(I4B), intent(inout) :: locmax !< location of the maximum change in the dependent variable
512  ! -- local
513  !
514  ! -- Newton-Raphson under-relaxation
515  end subroutine bnd_nur
516 
517  !> @ brief Convergence check for package.
518  !!
519  !! Perform additional convergence checks on the flow between the package
520  !! and the model it is attached to. This additional convergence check is
521  !! applied to packages that solve their own continuity equation as
522  !! part of the formulate step at the beginning of a Picard iteration.
523  !! A boundary package only needs to override this method if a specific boundary
524  !! package solves its own continuity equation. Example packages that implement
525  !! this additional convergence check is the CSUB, SFR, LAK, and UZF packages.
526  !<
527  subroutine bnd_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
528  ! -- dummy
529  class(bndtype), intent(inout) :: this !< BndType object
530  integer(I4B), intent(in) :: innertot !< total number of inner iterations
531  integer(I4B), intent(in) :: kiter !< Picard iteration number
532  integer(I4B), intent(in) :: iend !< flag indicating if this is the last Picard iteration
533  integer(I4B), intent(in) :: icnvgmod !< flag inficating if the model has met specific convergence criteria
534  character(len=LENPAKLOC), intent(inout) :: cpak !< string for user node
535  integer(I4B), intent(inout) :: ipak !< location of the maximum dependent variable change
536  real(DP), intent(inout) :: dpak !< maximum dependent variable change
537  !
538  ! -- No addition convergence check for boundary conditions
539  end subroutine bnd_cc
540 
541  !> @ brief Calculate advanced package flows.
542  !!
543  !! Calculate the flow between connected advanced package control volumes.
544  !! Only advanced boundary packages need to override this method.
545  !<
546  subroutine bnd_cq(this, x, flowja, iadv)
547  ! -- dummy
548  class(bndtype), intent(inout) :: this !< BndType object
549  real(DP), dimension(:), intent(in) :: x !< current dependent-variable value
550  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
551  integer(I4B), optional, intent(in) :: iadv !< flag that indicates if this is an advance package
552  ! -- local
553  integer(I4B) :: imover
554  !
555  ! -- check for iadv optional variable to indicate this is an advanced
556  ! package and that mover calculations should not be done here
557  if (present(iadv)) then
558  if (iadv == 1) then
559  imover = 0
560  else
561  imover = 1
562  end if
563  else
564  imover = this%imover
565  end if
566  !
567  ! -- Calculate package flows. In the first call, simval is calculated
568  ! from hcof, rhs, and head. The second call may reduce the value in
569  ! simval by what is sent to the mover. The mover rate is stored in
570  ! simtomvr. imover is set to zero here for advanced packages, which
571  ! handle and store mover quantities separately.
572  call this%bnd_cq_simrate(x, flowja, imover)
573  if (imover == 1) then
574  call this%bnd_cq_simtomvr(flowja)
575  end if
576  end subroutine bnd_cq
577 
578  !> @ brief Calculate simrate.
579  !!
580  !! Calculate the flow between package and the model (for example, GHB and
581  !! groundwater cell) and store in the simvals variable. This method only
582  !! needs to be overridden if a different calculation needs to be made.
583  !<
584  subroutine bnd_cq_simrate(this, hnew, flowja, imover)
585  ! -- dummy
586  class(bndtype) :: this !< BndType object
587  real(DP), dimension(:), intent(in) :: hnew !< current dependent-variable value
588  real(DP), dimension(:), intent(inout) :: flowja !< flow between package and model
589  integer(I4B), intent(in) :: imover !< flag indicating if the mover package is active
590  ! -- local
591  integer(I4B) :: i
592  integer(I4B) :: node
593  integer(I4B) :: idiag
594  real(DP) :: rrate
595  !
596  ! -- If no boundaries, skip flow calculations.
597  if (this%nbound > 0) then
598  !
599  ! -- Loop through each boundary calculating flow.
600  do i = 1, this%nbound
601  node = this%nodelist(i)
602  !
603  ! -- If cell is no-flow or constant-head, then ignore it.
604  rrate = dzero
605  if (node > 0) then
606  idiag = this%dis%con%ia(node)
607  if (this%ibound(node) > 0) then
608  !
609  ! -- Calculate the flow rate into the cell.
610  rrate = this%hcof(i) * hnew(node) - this%rhs(i)
611  end if
612  flowja(idiag) = flowja(idiag) + rrate
613  end if
614  !
615  ! -- Save simulated value to simvals array.
616  this%simvals(i) = rrate
617  !
618  end do
619  end if
620  end subroutine bnd_cq_simrate
621 
622  !> @ brief Calculate flow to the mover.
623  !!
624  !! Calculate the flow between package and the model that is sent to the
625  !! mover package and store in the simtomvr variable. This method only
626  !! needs to be overridden if a different calculation needs to be made.
627  !<
628  subroutine bnd_cq_simtomvr(this, flowja)
629  ! -- dummy
630  class(bndtype) :: this !< BndType object
631  real(DP), dimension(:), intent(inout) :: flowja !< flow between package and model
632  ! -- local
633  integer(I4B) :: i
634  integer(I4B) :: node
635  real(DP) :: q
636  real(DP) :: fact
637  real(DP) :: rrate
638  !
639  ! -- If no boundaries, skip flow calculations.
640  if (this%nbound > 0) then
641  !
642  ! -- Loop through each boundary calculating flow.
643  do i = 1, this%nbound
644  node = this%nodelist(i)
645  !
646  ! -- If cell is no-flow or constant-head, then ignore it.
647  rrate = dzero
648  if (node > 0) then
649  if (this%ibound(node) > 0) then
650  !
651  ! -- Calculate the flow rate into the cell.
652  q = this%simvals(i)
653 
654  if (q < dzero) then
655  rrate = this%pakmvrobj%get_qtomvr(i)
656  !
657  ! -- Evaluate if qtomvr exceeds the calculated rrate.
658  ! When fact is greater than 1, qtomvr is numerically
659  ! larger than rrate (which should never happen) and
660  ! represents a water budget error. When this happens,
661  ! rrate is set to 0. so that the water budget error is
662  ! correctly accounted for in the listing water budget.
663  fact = -rrate / q
664  if (fact > done) then
665  ! -- all flow goes to mover
666  q = dzero
667  else
668  ! -- magnitude of rrate (which is negative) is reduced by
669  ! qtomvr (which is positive)
670  q = q + rrate
671  end if
672  this%simvals(i) = q
673 
674  if (rrate > dzero) then
675  rrate = -rrate
676  end if
677  end if
678  end if
679  end if
680  !
681  ! -- Save simulated value to simtomvr array.
682  this%simtomvr(i) = rrate
683  !
684  end do
685  end if
686  end subroutine bnd_cq_simtomvr
687 
688  !> @ brief Add package flows to model budget.
689  !!
690  !! Add the flow between package and the model (ratin and ratout) to the
691  !! model budget. This method only needs to be overridden if a different
692  !! calculation needs to be made.
693  !<
694  subroutine bnd_bd(this, model_budget)
695  ! -- modules
696  use tdismodule, only: delt
698  ! -- dummy
699  class(bndtype) :: this !< BndType object
700  type(budgettype), intent(inout) :: model_budget !< model budget object
701  ! -- local
702  character(len=LENPACKAGENAME) :: text
703  real(DP) :: ratin
704  real(DP) :: ratout
705  integer(I4B) :: isuppress_output
706  !
707  ! -- initialize local variables
708  isuppress_output = 0
709  !
710  ! -- call accumulator and add to the model budget
711  call rate_accumulator(this%simvals(1:this%nbound), ratin, ratout)
712  call model_budget%addentry(ratin, ratout, delt, this%text, &
713  isuppress_output, this%packName)
714  if (this%imover == 1 .and. this%isadvpak == 0) then
715  text = trim(adjustl(this%text))//'-TO-MVR'
716  text = adjustr(text)
717  call rate_accumulator(this%simtomvr(1:this%nbound), ratin, ratout)
718  call model_budget%addentry(ratin, ratout, delt, text, &
719  isuppress_output, this%packName)
720  end if
721  end subroutine bnd_bd
722 
723  !> @ brief Output advanced package flow terms.
724  !!
725  !! Output advanced boundary package flow terms. This method only needs to
726  !! be overridden for advanced packages that save flow terms than contribute
727  !! to the continuity equation for each control volume.
728  !<
729  subroutine bnd_ot_package_flows(this, icbcfl, ibudfl)
730  ! -- dummy
731  class(bndtype) :: this !< BndType object
732  integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output
733  integer(I4B), intent(in) :: ibudfl !< flag indication if cell-by-cell data should be saved
734  !
735  ! -- override for advanced packages
736  end subroutine bnd_ot_package_flows
737 
738  !> @ brief Output advanced package dependent-variable terms.
739  !!
740  !! Output advanced boundary package dependent-variable terms. This method only needs
741  !! to be overridden for advanced packages that save dependent variable terms
742  !! for each control volume.
743  !<
744  subroutine bnd_ot_dv(this, idvsave, idvprint)
745  ! -- dummy
746  class(bndtype) :: this !< BndType object
747  integer(I4B), intent(in) :: idvsave !< flag and unit number for dependent-variable output
748  integer(I4B), intent(in) :: idvprint !< flag indicating if dependent-variable should be written to the model listing file
749  !
750  ! -- override for advanced packages
751  end subroutine bnd_ot_dv
752 
753  !> @ brief Output advanced package budget summary.
754  !!
755  !! Output advanced boundary package budget summary. This method only needs
756  !! to be overridden for advanced packages that save budget summaries
757  !! to the model listing file.
758  !<
759  subroutine bnd_ot_bdsummary(this, kstp, kper, iout, ibudfl)
760  ! -- dummy
761  class(bndtype) :: this !< BndType object
762  integer(I4B), intent(in) :: kstp !< time step number
763  integer(I4B), intent(in) :: kper !< period number
764  integer(I4B), intent(in) :: iout !< flag and unit number for the model listing file
765  integer(I4B), intent(in) :: ibudfl !< flag indicating budget should be written
766  !
767  ! -- override for advanced packages
768  end subroutine bnd_ot_bdsummary
769 
770  !> @ brief Output package flow terms.
771  !!
772  !! Output flow terms between the boundary package and model to a binary file and/or
773  !! print flows to the model listing file. This method should not need to
774  !! be overridden.
775  !<
776  subroutine bnd_ot_model_flows(this, icbcfl, ibudfl, icbcun, imap)
777  ! -- dummy
778  class(bndtype) :: this !< BndType object
779  integer(I4B), intent(in) :: icbcfl !< flag for cell-by-cell output
780  integer(I4B), intent(in) :: ibudfl !< flag indication if cell-by-cell data should be saved
781  integer(I4B), intent(in) :: icbcun !< unit number for cell-by-cell output
782  integer(I4B), dimension(:), optional, intent(in) :: imap !< mapping vector that converts the 1 to nbound values to lake number, maw number, etc.
783  ! -- local
784  character(len=LINELENGTH) :: title
785  character(len=LENPACKAGENAME) :: text
786  integer(I4B) :: imover
787  !
788  ! -- Call generic subroutine to save and print simvals and simtomvr
789  title = trim(adjustl(this%text))//' PACKAGE ('//trim(this%packName)// &
790  ') FLOW RATES'
791  if (present(imap)) then
792  call save_print_model_flows(icbcfl, ibudfl, icbcun, this%iprflow, &
793  this%outputtab, this%nbound, this%nodelist, &
794  this%simvals, this%ibound, title, this%text, &
795  this%ipakcb, this%dis, this%naux, &
796  this%name_model, this%name_model, &
797  this%name_model, this%packName, &
798  this%auxname, this%auxvar, this%iout, &
799  this%inamedbound, this%boundname, imap)
800  else
801  call save_print_model_flows(icbcfl, ibudfl, icbcun, this%iprflow, &
802  this%outputtab, this%nbound, this%nodelist, &
803  this%simvals, this%ibound, title, this%text, &
804  this%ipakcb, this%dis, this%naux, &
805  this%name_model, this%name_model, &
806  this%name_model, this%packName, &
807  this%auxname, this%auxvar, this%iout, &
808  this%inamedbound, this%boundname)
809  end if
810  !
811  ! -- Set mover flag, and shut off if this is an advanced package. Advanced
812  ! packages must handle mover flows differently by including them in
813  ! their balance equations. These simtomvr flows are the general
814  ! flow to mover terms calculated by bnd_cq_simtomvr()
815  imover = this%imover
816  if (this%isadvpak /= 0) imover = 0
817  if (imover == 1) then
818  text = trim(adjustl(this%text))//'-TO-MVR'
819  text = adjustr(text)
820  title = trim(adjustl(this%text))//' PACKAGE ('// &
821  trim(this%packName)//') FLOW RATES TO-MVR'
822  call save_print_model_flows(icbcfl, ibudfl, icbcun, this%iprflow, &
823  this%outputtab, this%nbound, this%nodelist, &
824  this%simtomvr, this%ibound, title, text, &
825  this%ipakcb, this%dis, this%naux, &
826  this%name_model, this%name_model, &
827  this%name_model, this%packName, &
828  this%auxname, this%auxvar, this%iout, &
829  this%inamedbound, this%boundname)
830  end if
831  end subroutine bnd_ot_model_flows
832 
833  !> @ brief Deallocate package memory
834  !!
835  !! Deallocate base boundary package scalars and arrays. This method
836  !! only needs to be overridden if additional variables are defined
837  !! for a specific package.
838  !<
839  subroutine bnd_da(this)
840  ! -- modules
842  ! -- dummy
843  class(bndtype) :: this !< BndType object
844  !
845  ! -- deallocate arrays
846  call mem_deallocate(this%nodelist, 'NODELIST', this%memoryPath)
847  call mem_deallocate(this%noupdateauxvar, 'NOUPDATEAUXVAR', this%memoryPath)
848  call mem_deallocate(this%bound, 'BOUND', this%memoryPath)
849  call mem_deallocate(this%condinput, 'CONDINPUT', this%memoryPath)
850  call mem_deallocate(this%hcof, 'HCOF', this%memoryPath)
851  call mem_deallocate(this%rhs, 'RHS', this%memoryPath)
852  call mem_deallocate(this%simvals, 'SIMVALS', this%memoryPath)
853  call mem_deallocate(this%simtomvr, 'SIMTOMVR', this%memoryPath)
854  call mem_deallocate(this%auxvar, 'AUXVAR', this%memoryPath)
855  call mem_deallocate(this%boundname, 'BOUNDNAME', this%memoryPath)
856  call mem_deallocate(this%boundname_cst, 'BOUNDNAME_CST', this%memoryPath)
857  call mem_deallocate(this%auxname, 'AUXNAME', this%memoryPath)
858  call mem_deallocate(this%auxname_cst, 'AUXNAME_CST', this%memoryPath)
859  nullify (this%icelltype)
860  !
861  ! -- pakmvrobj
862  if (this%imover /= 0) then
863  call this%pakmvrobj%da()
864  deallocate (this%pakmvrobj)
865  nullify (this%pakmvrobj)
866  end if
867  !
868  ! -- input table object
869  if (associated(this%inputtab)) then
870  call this%inputtab%table_da()
871  deallocate (this%inputtab)
872  nullify (this%inputtab)
873  end if
874  !
875  ! -- output table object
876  if (associated(this%outputtab)) then
877  call this%outputtab%table_da()
878  deallocate (this%outputtab)
879  nullify (this%outputtab)
880  end if
881  !
882  ! -- error table object
883  if (associated(this%errortab)) then
884  call this%errortab%table_da()
885  deallocate (this%errortab)
886  nullify (this%errortab)
887  end if
888  !
889  ! -- deallocate character variables
890  call mem_deallocate(this%listlabel, 'LISTLABEL', this%memoryPath)
891  !
892  ! -- Deallocate scalars
893  call mem_deallocate(this%isadvpak)
894  call mem_deallocate(this%ibcnum)
895  call mem_deallocate(this%maxbound)
896  call mem_deallocate(this%nbound)
897  call mem_deallocate(this%ncolbnd)
898  call mem_deallocate(this%iscloc)
899  call mem_deallocate(this%naux)
900  call mem_deallocate(this%inamedbound)
901  call mem_deallocate(this%iauxmultcol)
902  call mem_deallocate(this%inobspkg)
903  call mem_deallocate(this%imover)
904  call mem_deallocate(this%npakeq)
905  call mem_deallocate(this%ioffset)
906  call mem_deallocate(this%ivsc)
907  !
908  ! -- deallocate methods on objects
909  call this%obs%obs_da()
910  call this%TsManager%da()
911  call this%TasManager%da()
912  !
913  ! -- deallocate objects
914  deallocate (this%obs)
915  deallocate (this%TsManager)
916  deallocate (this%TasManager)
917  nullify (this%TsManager)
918  nullify (this%TasManager)
919  !
920  ! -- Deallocate parent object
921  call this%NumericalPackageType%da()
922  end subroutine bnd_da
923 
924  !> @ brief Allocate package scalars
925  !!
926  !! Allocate and initialize base boundary package scalars. This method
927  !! only needs to be overridden if additional scalars are defined
928  !! for a specific package.
929  !<
930  subroutine allocate_scalars(this)
931  ! -- modules
934  ! -- dummy
935  class(bndtype) :: this !< BndType object
936  ! -- local
937  integer(I4B), pointer :: imodelnewton => null()
938  !
939  ! -- allocate scalars in NumericalPackageType
940  call this%NumericalPackageType%allocate_scalars()
941  !
942  ! -- allocate character variables
943  call mem_allocate(this%listlabel, lenlistlabel, 'LISTLABEL', &
944  this%memoryPath)
945  !
946  ! -- allocate integer variables
947  call mem_allocate(this%isadvpak, 'ISADVPAK', this%memoryPath)
948  call mem_allocate(this%ibcnum, 'IBCNUM', this%memoryPath)
949  call mem_allocate(this%maxbound, 'MAXBOUND', this%memoryPath)
950  call mem_allocate(this%nbound, 'NBOUND', this%memoryPath)
951  call mem_allocate(this%ncolbnd, 'NCOLBND', this%memoryPath)
952  call mem_allocate(this%iscloc, 'ISCLOC', this%memoryPath)
953  call mem_allocate(this%naux, 'NAUX', this%memoryPath)
954  call mem_allocate(this%inamedbound, 'INAMEDBOUND', this%memoryPath)
955  call mem_allocate(this%iauxmultcol, 'IAUXMULTCOL', this%memoryPath)
956  call mem_allocate(this%inobspkg, 'INOBSPKG', this%memoryPath)
957  !
958  ! -- allocate the object and assign values to object variables
959  call mem_allocate(this%imover, 'IMOVER', this%memoryPath)
960  !
961  ! -- allocate flag for determining if vsc active
962  call mem_allocate(this%ivsc, 'IVSC', this%memoryPath)
963  !
964  ! -- allocate scalars for packages that add rows to the matrix (e.g. MAW)
965  call mem_allocate(this%npakeq, 'NPAKEQ', this%memoryPath)
966  call mem_allocate(this%ioffset, 'IOFFSET', this%memoryPath)
967  !
968  ! -- allocate TS objects
969  allocate (this%TsManager)
970  allocate (this%TasManager)
971  !
972  ! -- allocate text strings
973  call mem_allocate(this%auxname, lenauxname, 0, 'AUXNAME', this%memoryPath)
974  call mem_allocate(this%auxname_cst, lenauxname, 0, 'AUXNAME_CST', &
975  this%memoryPath)
976  !
977  ! -- Initialize variables
978  this%isadvpak = 0
979  this%ibcnum = 0
980  this%maxbound = 0
981  this%nbound = 0
982  this%ncolbnd = 0
983  this%iscloc = 0
984  this%naux = 0
985  this%inamedbound = 0
986  this%iauxmultcol = 0
987  this%inobspkg = 0
988  this%imover = 0
989  this%npakeq = 0
990  this%ioffset = 0
991  this%ivsc = 0
992  !
993  ! -- Set pointer to model inewton variable
994  call mem_setptr(imodelnewton, 'INEWTON', create_mem_path(this%name_model))
995  this%inewton = imodelnewton
996  imodelnewton => null()
997  end subroutine allocate_scalars
998 
999  !> @ brief Allocate package arrays
1000  !!
1001  !! Allocate and initialize base boundary package arrays. This method
1002  !! only needs to be overridden if additional arrays are defined
1003  !! for a specific package.
1004  !<
1005  subroutine allocate_arrays(this, nodelist, auxvar)
1006  ! -- modules
1008  ! -- dummy
1009  class(bndtype) :: this !< BndType object
1010  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist !< package nodelist
1011  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar !< package aux variable array
1012  ! -- local
1013  integer(I4B) :: i
1014  integer(I4B) :: j
1015  !
1016  ! -- Point nodelist if it is passed in, otherwise allocate
1017  if (present(nodelist)) then
1018  this%nodelist => nodelist
1019  else
1020  call mem_allocate(this%nodelist, this%maxbound, 'NODELIST', &
1021  this%memoryPath)
1022  do j = 1, this%maxbound
1023  this%nodelist(j) = 0
1024  end do
1025  end if
1026  !
1027  ! -- noupdateauxvar (allows an external caller to stop auxvars from being
1028  ! recalculated
1029  call mem_allocate(this%noupdateauxvar, this%naux, 'NOUPDATEAUXVAR', &
1030  this%memoryPath)
1031  this%noupdateauxvar(:) = 0
1032  !
1033  ! -- Allocate the bound array
1034  call mem_allocate(this%bound, this%ncolbnd, this%maxbound, 'BOUND', &
1035  this%memoryPath)
1036  !
1037  !-- Allocate array for storing user-specified conductances
1038  ! Will be reallocated to size maxbound if vsc active
1039  call mem_allocate(this%condinput, 0, 'CONDINPUT', this%memoryPath)
1040  !
1041  ! -- Allocate hcof and rhs
1042  call mem_allocate(this%hcof, this%maxbound, 'HCOF', this%memoryPath)
1043  call mem_allocate(this%rhs, this%maxbound, 'RHS', this%memoryPath)
1044  !
1045  ! -- Allocate the simvals array
1046  call mem_allocate(this%simvals, this%maxbound, 'SIMVALS', this%memoryPath)
1047  if (this%imover == 1) then
1048  call mem_allocate(this%simtomvr, this%maxbound, 'SIMTOMVR', &
1049  this%memoryPath)
1050  do i = 1, this%maxbound
1051  this%simtomvr(i) = dzero
1052  end do
1053  else
1054  call mem_allocate(this%simtomvr, 0, 'SIMTOMVR', this%memoryPath)
1055  end if
1056  !
1057  ! -- Point or allocate auxvar
1058  if (present(auxvar)) then
1059  this%auxvar => auxvar
1060  else
1061  call mem_allocate(this%auxvar, this%naux, this%maxbound, 'AUXVAR', &
1062  this%memoryPath)
1063  do i = 1, this%maxbound
1064  do j = 1, this%naux
1065  this%auxvar(j, i) = dzero
1066  end do
1067  end do
1068  end if
1069  !
1070  ! -- Allocate boundname
1071  if (this%inamedbound /= 0) then
1072  call mem_allocate(this%boundname, lenboundname, this%maxbound, &
1073  'BOUNDNAME', this%memoryPath)
1074  call mem_allocate(this%boundname_cst, lenboundname, this%maxbound, &
1075  'BOUNDNAME_CST', this%memoryPath)
1076  else
1077  call mem_allocate(this%boundname, lenboundname, 0, &
1078  'BOUNDNAME', this%memoryPath)
1079  call mem_allocate(this%boundname_cst, lenboundname, 0, &
1080  'BOUNDNAME_CST', this%memoryPath)
1081  end if
1082  !
1083  ! -- Set pointer to ICELLTYPE. For GWF boundary packages,
1084  ! this%ictMemPath will be 'NPF'. If boundary packages do not set
1085  ! this%ictMemPath, then icelltype will remain as null()
1086  if (this%ictMemPath /= '') then
1087  call mem_setptr(this%icelltype, 'ICELLTYPE', this%ictMemPath)
1088  end if
1089  !
1090  ! -- Initialize values
1091  do j = 1, this%maxbound
1092  do i = 1, this%ncolbnd
1093  this%bound(i, j) = dzero
1094  end do
1095  end do
1096  do i = 1, this%maxbound
1097  this%hcof(i) = dzero
1098  this%rhs(i) = dzero
1099  end do
1100  !
1101  ! -- setup the output table
1102  call this%pak_setup_outputtab()
1103  end subroutine allocate_arrays
1104 
1105  !> @ brief Allocate and initialize select package members
1106  !!
1107  !! Allocate and initialize select base boundary package members.
1108  !! This method needs to be overridden by a package if it is
1109  !! needed for a specific package.
1110  !<
1111  subroutine pack_initialize(this)
1112  ! -- dummy
1113  class(bndtype) :: this !< BndType object
1114  end subroutine pack_initialize
1115 
1116  !> @ brief Set pointers to model variables
1117  !!
1118  !! Set pointers to model variables so that a package has access to these
1119  !! variables. This base method should not need to be overridden.
1120  !<
1121  subroutine set_pointers(this, neq, ibound, xnew, xold, flowja)
1122  ! -- dummy
1123  class(bndtype) :: this !< BndType object
1124  integer(I4B), pointer :: neq !< number of equations in the model
1125  integer(I4B), dimension(:), pointer, contiguous :: ibound !< model idomain
1126  real(DP), dimension(:), pointer, contiguous :: xnew !< current dependent variable
1127  real(DP), dimension(:), pointer, contiguous :: xold !< previous dependent variable
1128  real(DP), dimension(:), pointer, contiguous :: flowja !< connection flow terms
1129  !
1130  ! -- Set the pointers
1131  this%neq => neq
1132  this%ibound => ibound
1133  this%xnew => xnew
1134  this%xold => xold
1135  this%flowja => flowja
1136  end subroutine set_pointers
1137 
1138  !> @ brief Read additional options for package
1139  !!
1140  !! Read base options for boundary packages.
1141  !<
1142  subroutine bnd_read_options(this)
1143  ! -- modules
1144  use inputoutputmodule, only: urdaux
1146  ! -- dummy
1147  class(bndtype), intent(inout) :: this !< BndType object
1148  ! -- local
1149  character(len=:), allocatable :: line
1150  character(len=LINELENGTH) :: fname
1151  character(len=LINELENGTH) :: keyword
1152  character(len=LENAUXNAME) :: sfacauxname
1153  character(len=LENAUXNAME), dimension(:), allocatable :: caux
1154  integer(I4B) :: lloc
1155  integer(I4B) :: istart
1156  integer(I4B) :: istop
1157  integer(I4B) :: n
1158  integer(I4B) :: ierr
1159  integer(I4B) :: inobs
1160  logical(LGP) :: isfound
1161  logical(LGP) :: endOfBlock
1162  logical(LGP) :: foundchildclassoption
1163  ! -- format
1164  character(len=*), parameter :: fmtflow = &
1165  &"(4x, 'FLOWS WILL BE SAVED TO FILE: ', a, /4x, 'OPENED ON UNIT: ', I7)"
1166  character(len=*), parameter :: fmtflow2 = &
1167  &"(4x, 'FLOWS WILL BE SAVED TO BUDGET FILE SPECIFIED IN OUTPUT CONTROL')"
1168  character(len=*), parameter :: fmttas = &
1169  &"(4x, 'TIME-ARRAY SERIES DATA WILL BE READ FROM FILE: ', a)"
1170  character(len=*), parameter :: fmtts = &
1171  &"(4x, 'TIME-SERIES DATA WILL BE READ FROM FILE: ', a)"
1172  character(len=*), parameter :: fmtnme = &
1173  &"(a, i0, a)"
1174  !
1175  ! -- set default options
1176  !
1177  ! -- get options block
1178  call this%parser%GetBlock('OPTIONS', isfound, ierr, &
1179  supportopenclose=.true., blockrequired=.false.)
1180  !
1181  ! -- parse options block if detected
1182  if (isfound) then
1183  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
1184  //' OPTIONS'
1185  do
1186  call this%parser%GetNextLine(endofblock)
1187  if (endofblock) then
1188  exit
1189  end if
1190  call this%parser%GetStringCaps(keyword)
1191  select case (keyword)
1192  case ('AUX', 'AUXILIARY')
1193  call this%parser%GetRemainingLine(line)
1194  lloc = 1
1195  call urdaux(this%naux, this%parser%iuactive, this%iout, lloc, &
1196  istart, istop, caux, line, this%text)
1197  call mem_reallocate(this%auxname, lenauxname, this%naux, &
1198  'AUXNAME', this%memoryPath)
1199  call mem_reallocate(this%auxname_cst, lenauxname, this%naux, &
1200  'AUXNAME_CST', this%memoryPath)
1201  do n = 1, this%naux
1202  this%auxname(n) = caux(n)
1203  this%auxname_cst(n) = caux(n)
1204  end do
1205  deallocate (caux)
1206  case ('SAVE_FLOWS')
1207  this%ipakcb = -1
1208  write (this%iout, fmtflow2)
1209  case ('PRINT_INPUT')
1210  this%iprpak = 1
1211  write (this%iout, '(4x,a)') &
1212  'LISTS OF '//trim(adjustl(this%text))//' CELLS WILL BE PRINTED.'
1213  case ('PRINT_FLOWS')
1214  this%iprflow = 1
1215  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
1216  ' FLOWS WILL BE PRINTED TO LISTING FILE.'
1217  case ('BOUNDNAMES')
1218  this%inamedbound = 1
1219  write (this%iout, '(4x,a)') trim(adjustl(this%text))// &
1220  ' BOUNDARIES HAVE NAMES IN LAST COLUMN.'
1221  case ('TS6')
1222  call this%parser%GetStringCaps(keyword)
1223  if (trim(adjustl(keyword)) /= 'FILEIN') then
1224  errmsg = 'TS6 keyword must be followed by "FILEIN" '// &
1225  'then by filename.'
1226  call store_error(errmsg)
1227  end if
1228  call this%parser%GetString(fname)
1229  write (this%iout, fmtts) trim(fname)
1230  call this%TsManager%add_tsfile(fname, this%inunit)
1231  case ('TAS6')
1232  if (this%AllowTimeArraySeries) then
1233  if (.not. this%dis%supports_layers()) then
1234  errmsg = 'TAS6 FILE cannot be used '// &
1235  'with selected discretization type.'
1236  call store_error(errmsg)
1237  end if
1238  else
1239  errmsg = 'The '//trim(this%filtyp)// &
1240  ' package does not support TIMEARRAYSERIESFILE'
1241  call store_error(errmsg)
1242  call this%parser%StoreErrorUnit()
1243  end if
1244  call this%parser%GetStringCaps(keyword)
1245  if (trim(adjustl(keyword)) /= 'FILEIN') then
1246  errmsg = 'TAS6 keyword must be followed by "FILEIN" '// &
1247  'then by filename.'
1248  call store_error(errmsg)
1249  call this%parser%StoreErrorUnit()
1250  end if
1251  call this%parser%GetString(fname)
1252  write (this%iout, fmttas) trim(fname)
1253  call this%TasManager%add_tasfile(fname)
1254  case ('AUXMULTNAME')
1255  call this%parser%GetStringCaps(sfacauxname)
1256  this%iauxmultcol = -1
1257  write (this%iout, '(4x,a,a)') &
1258  'AUXILIARY MULTIPLIER NAME: ', sfacauxname
1259  case ('OBS6')
1260  call this%parser%GetStringCaps(keyword)
1261  if (trim(adjustl(keyword)) /= 'FILEIN') then
1262  errmsg = 'OBS6 keyword must be followed by "FILEIN" '// &
1263  'then by filename.'
1264  call store_error(errmsg)
1265  call this%parser%StoreErrorUnit()
1266  end if
1267  if (this%obs%active) then
1268  errmsg = 'Multiple OBS6 keywords detected in OPTIONS block. '// &
1269  'Only one OBS6 entry allowed for a package.'
1270  call store_error(errmsg)
1271  end if
1272  this%obs%active = .true.
1273  call this%parser%GetString(this%obs%inputFilename)
1274  inobs = getunit()
1275  call openfile(inobs, this%iout, this%obs%inputFilename, 'OBS')
1276  this%obs%inUnitObs = inobs
1277  !
1278  ! -- right now these are options that are only available in the
1279  ! development version and are not included in the documentation.
1280  ! These options are only available when IDEVELOPMODE in
1281  ! constants module is set to 1
1282  case ('DEV_NO_NEWTON')
1283  call this%parser%DevOpt()
1284  this%inewton = 0
1285  write (this%iout, '(4x,a)') &
1286  'NEWTON-RAPHSON method disabled for unconfined cells'
1287  case default
1288  !
1289  ! -- Check for child class options
1290  call this%bnd_options(keyword, foundchildclassoption)
1291  !
1292  ! -- No child class options found, so print error message
1293  if (.not. foundchildclassoption) then
1294  write (errmsg, '(a,3(1x,a))') &
1295  'UNKNOWN', trim(adjustl(this%text)), 'OPTION:', trim(keyword)
1296  call store_error(errmsg)
1297  end if
1298  end select
1299  end do
1300  write (this%iout, '(1x,a)') &
1301  'END OF '//trim(adjustl(this%text))//' OPTIONS'
1302  else
1303  write (this%iout, '(1x,a)') 'NO '//trim(adjustl(this%text))// &
1304  ' OPTION BLOCK DETECTED.'
1305  end if
1306  !
1307  ! -- AUXMULTNAME was specified, so find column of auxvar that will be multiplier
1308  if (this%iauxmultcol < 0) then
1309  !
1310  ! -- Error if no aux variable specified
1311  if (this%naux == 0) then
1312  write (errmsg, '(a,2(1x,a))') &
1313  'AUXMULTNAME was specified as', trim(adjustl(sfacauxname)), &
1314  'but no AUX variables specified.'
1315  call store_error(errmsg)
1316  end if
1317  !
1318  ! -- Assign mult column
1319  this%iauxmultcol = 0
1320  do n = 1, this%naux
1321  if (sfacauxname == this%auxname(n)) then
1322  this%iauxmultcol = n
1323  exit
1324  end if
1325  end do
1326  !
1327  ! -- Error if aux variable cannot be found
1328  if (this%iauxmultcol == 0) then
1329  write (errmsg, '(a,2(1x,a))') &
1330  'AUXMULTNAME was specified as', trim(adjustl(sfacauxname)), &
1331  'but no AUX variable found with this name.'
1332  call store_error(errmsg)
1333  end if
1334  end if
1335  !
1336  ! -- terminate if errors were detected
1337  if (count_errors() > 0) then
1338  call this%parser%StoreErrorUnit()
1339  end if
1340  end subroutine bnd_read_options
1341 
1342  !> @ brief Read dimensions for package
1343  !!
1344  !! Read base dimensions for boundary packages. This method should not
1345  !! need to be overridden unless more than MAXBOUND is specified in the
1346  !! DIMENSIONS block.
1347  !<
1348  subroutine bnd_read_dimensions(this)
1349  ! -- dummy
1350  class(bndtype), intent(inout) :: this !< BndType object
1351  ! -- local
1352  character(len=LINELENGTH) :: keyword
1353  logical(LGP) :: isfound
1354  logical(LGP) :: endOfBlock
1355  integer(I4B) :: ierr
1356  !
1357  ! -- get dimensions block
1358  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
1359  supportopenclose=.true.)
1360  !
1361  ! -- parse dimensions block if detected
1362  if (isfound) then
1363  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text))// &
1364  ' DIMENSIONS'
1365  do
1366  call this%parser%GetNextLine(endofblock)
1367  if (endofblock) exit
1368  call this%parser%GetStringCaps(keyword)
1369  select case (keyword)
1370  case ('MAXBOUND')
1371  this%maxbound = this%parser%GetInteger()
1372  write (this%iout, '(4x,a,i7)') 'MAXBOUND = ', this%maxbound
1373  case default
1374  write (errmsg, '(a,3(1x,a))') &
1375  'Unknown', trim(this%text), 'dimension:', trim(keyword)
1376  call store_error(errmsg)
1377  end select
1378  end do
1379  !
1380  write (this%iout, '(1x,a)') &
1381  'END OF '//trim(adjustl(this%text))//' DIMENSIONS'
1382  else
1383  call store_error('Required DIMENSIONS block not found.')
1384  call this%parser%StoreErrorUnit()
1385  end if
1386  !
1387  ! -- verify dimensions were set
1388  if (this%maxbound <= 0) then
1389  write (errmsg, '(a)') 'MAXBOUND must be an integer greater than zero.'
1390  call store_error(errmsg)
1391  end if
1392  !
1393  ! -- terminate if there are errors
1394  if (count_errors() > 0) then
1395  call this%parser%StoreErrorUnit()
1396  end if
1397  !
1398  ! -- Call define_listlabel to construct the list label that is written
1399  ! when PRINT_INPUT option is used.
1400  call this%define_listlabel()
1401  end subroutine bnd_read_dimensions
1402 
1403  !> @ brief Store user-specified conductances when vsc is active
1404  !!
1405  !! VSC will update boundary package conductance values. Because
1406  !! viscosity can change every stress period, but user-specified
1407  !! conductances may not, the base user-input should be stored in
1408  !! backup array so that viscosity-updated conductances may be
1409  !! recalculated every stress period/time step
1410  !<
1411  subroutine bnd_store_user_cond(this, nlist, rlist, condinput)
1412  ! -- modules
1413  use simmodule, only: store_error
1414  ! -- dummy
1415  class(bndtype), intent(inout) :: this !< BndType object
1416  integer(I4B), intent(in) :: nlist
1417  real(DP), dimension(:, :), pointer, contiguous, intent(in) :: rlist
1418  real(DP), dimension(:), pointer, contiguous, intent(inout) :: condinput
1419  ! -- local
1420  integer(I4B) :: l
1421  !
1422  ! -- store backup copy of conductance values
1423  do l = 1, nlist
1424  condinput(l) = rlist(2, l)
1425  end do
1426  end subroutine bnd_store_user_cond
1427 
1428  !> @ brief Read initial parameters for package
1429  !!
1430  !! Read initial parameters for a boundary package. This method is not
1431  !! needed for most boundary packages. The SFR package is an example of a
1432  !! package that has overridden this method.
1433  !<
1434  subroutine bnd_read_initial_attr(this)
1435  ! -- dummy
1436  class(bndtype), intent(inout) :: this !< BndType object
1437  end subroutine bnd_read_initial_attr
1438 
1439  !> @ brief Read additional options for package
1440  !!
1441  !! Read additional options for a boundary package. This method should
1442  !! be overridden options in addition to the base options are implemented
1443  !! in a boundary package.
1444  !<
1445  subroutine bnd_options(this, option, found)
1446  ! -- dummy
1447  class(bndtype), intent(inout) :: this !< BndType object
1448  character(len=*), intent(inout) :: option !< option keyword string
1449  logical(LGP), intent(inout) :: found !< boolean indicating if the option was found
1450  !
1451  ! Return with found = .false.
1452  found = .false.
1453  end subroutine bnd_options
1454 
1455  !> @ brief Copy boundnames into boundnames_cst
1456  !!
1457  !! boundnames_cst is an array of type(CharacterStringType),
1458  !! which can be stored in the MemoryManager.
1459  !<
1460  subroutine copy_boundname(this)
1461  ! -- dummy
1462  class(bndtype), intent(inout) :: this !< BndType object
1463  ! -- local
1464  integer(I4B) :: i
1465  !
1466  ! copy from boundname to boundname_cst, which can be
1467  ! stored in the memory manager
1468  if (this%inamedbound /= 0) then
1469  do i = 1, size(this%boundname)
1470  this%boundname_cst(i) = this%boundname(i)
1471  end do
1472  end if
1473  end subroutine copy_boundname
1474 
1475  !> @ brief Setup output table for package
1476  !!
1477  !! Setup output table for a boundary package that is used to output
1478  !! package to model flow terms to the model listing file.
1479  !<
1480  subroutine pak_setup_outputtab(this)
1481  ! -- dummy
1482  class(bndtype), intent(inout) :: this !< BndType object
1483  ! -- local
1484  character(len=LINELENGTH) :: title
1485  character(len=LINELENGTH) :: text
1486  integer(I4B) :: ntabcol
1487  !
1488  ! -- allocate and initialize the output table
1489  if (this%iprflow /= 0) then
1490  !
1491  ! -- dimension table
1492  ntabcol = 3
1493  if (this%inamedbound > 0) then
1494  ntabcol = ntabcol + 1
1495  end if
1496  !
1497  ! -- initialize the output table object
1498  title = trim(adjustl(this%text))//' PACKAGE ('//trim(this%packName)// &
1499  ') FLOW RATES'
1500  call table_cr(this%outputtab, this%packName, title)
1501  call this%outputtab%table_df(this%maxbound, ntabcol, this%iout, &
1502  transient=.true.)
1503  text = 'NUMBER'
1504  call this%outputtab%initialize_column(text, 10, alignment=tabcenter)
1505  text = 'CELLID'
1506  call this%outputtab%initialize_column(text, 20, alignment=tableft)
1507  text = 'RATE'
1508  call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1509  if (this%inamedbound > 0) then
1510  text = 'NAME'
1511  call this%outputtab%initialize_column(text, lenboundname, &
1512  alignment=tableft)
1513  end if
1514  end if
1515  end subroutine pak_setup_outputtab
1516 
1517  !> @ brief Define the list label for the package
1518  !!
1519  !! Method defined the list label for the boundary package. This method
1520  !! needs to be overridden by each boundary package.
1521  !<
1522  subroutine define_listlabel(this)
1523  ! -- dummy
1524  class(bndtype), intent(inout) :: this !< BndType object
1525  end subroutine define_listlabel
1526 
1527  ! -- Procedures related to observations
1528 
1529  !> @brief Determine if observations are supported.
1530  !!
1531  !! Function to determine if observations are supported by the boundary package.
1532  !! By default, observations are not supported. This method should be overridden
1533  !! if observations are supported in a boundary package.
1534  !!
1535  !! @return supported boolean indicating if observations are supported
1536  !<
1537  function bnd_obs_supported(this) result(supported)
1538  ! -- return variable
1539  logical(LGP) :: supported !< boolean indicating if observations are supported
1540  ! -- dummy
1541  class(bndtype) :: this !< BndType object
1542  !
1543  ! -- initialize return variables
1544  supported = .false.
1545  end function bnd_obs_supported
1546 
1547  !> @brief Define the observation types available in the package
1548  !!
1549  !! Method to define the observation types available in a boundary
1550  !! package. This method should be overridden if observations are
1551  !! supported in a boundary package.
1552  !<
1553  subroutine bnd_df_obs(this)
1554  !
1555  ! -- dummy
1556  class(bndtype) :: this !< BndType object
1557  !
1558  ! -- do nothing here. Override as needed.
1559  end subroutine bnd_df_obs
1560 
1561  !> @brief Read and prepare observations for a package
1562  !!
1563  !! Method to read and prepare observations for a boundary package
1564  !! This method should not need to be overridden for most boundary
1565  !! packages.
1566  !<
1567  subroutine bnd_rp_obs(this)
1568  ! -- dummy
1569  class(bndtype), intent(inout) :: this !< BndType object
1570  ! -- local
1571  integer(I4B) :: i
1572  integer(I4B) :: j
1573  class(observetype), pointer :: obsrv => null()
1574  character(len=LENBOUNDNAME) :: bname
1575  logical(LGP) :: jfound
1576  !
1577  if (.not. this%bnd_obs_supported()) return
1578  !
1579  do i = 1, this%obs%npakobs
1580  obsrv => this%obs%pakobs(i)%obsrv
1581  !
1582  ! -- indxbnds needs to be reset each stress period because
1583  ! list of boundaries can change each stress period.
1584  call obsrv%ResetObsIndex()
1585  obsrv%BndFound = .false.
1586  !
1587  bname = obsrv%FeatureName
1588  if (bname /= '') then
1589  !
1590  ! -- Observation location(s) is(are) based on a boundary name.
1591  ! Iterate through all boundaries to identify and store
1592  ! corresponding index(indices) in bound array.
1593  jfound = .false.
1594  do j = 1, this%nbound
1595  if (this%boundname(j) == bname) then
1596  jfound = .true.
1597  obsrv%BndFound = .true.
1598  obsrv%CurrentTimeStepEndValue = dzero
1599  call obsrv%AddObsIndex(j)
1600  end if
1601  end do
1602  else
1603  !
1604  ! -- Observation location is a single node number
1605  jfound = .false.
1606  jloop: do j = 1, this%nbound
1607  if (this%nodelist(j) == obsrv%NodeNumber) then
1608  jfound = .true.
1609  obsrv%BndFound = .true.
1610  obsrv%CurrentTimeStepEndValue = dzero
1611  call obsrv%AddObsIndex(j)
1612  end if
1613  end do jloop
1614  end if
1615  end do
1616  !
1617  if (count_errors() > 0) then
1618  call store_error_unit(this%inunit)
1619  end if
1620  end subroutine bnd_rp_obs
1621 
1622  !> @brief Save observations for the package
1623  !!
1624  !! Method to save simulated values for the boundary package.
1625  !! This method will need to be overridden for boundary packages
1626  !! with more observations than the calculate flow term (simvals)
1627  !! and to-mover.
1628  !<
1629  subroutine bnd_bd_obs(this)
1630  ! -- dummy
1631  class(bndtype) :: this !< BndType object
1632  ! -- local
1633  integer(I4B) :: i
1634  integer(I4B) :: n
1635  real(DP) :: v
1636  type(observetype), pointer :: obsrv => null()
1637  !
1638  ! -- clear the observations
1639  call this%obs%obs_bd_clear()
1640  !
1641  ! -- Save simulated values for all of package's observations.
1642  do i = 1, this%obs%npakobs
1643  obsrv => this%obs%pakobs(i)%obsrv
1644  if (obsrv%BndFound) then
1645  do n = 1, obsrv%indxbnds_count
1646  if (obsrv%ObsTypeId == 'TO-MVR') then
1647  if (this%imover == 1) then
1648  v = this%pakmvrobj%get_qtomvr(obsrv%indxbnds(n))
1649  if (v > dzero) then
1650  v = -v
1651  end if
1652  else
1653  v = dnodata
1654  end if
1655  else
1656  v = this%simvals(obsrv%indxbnds(n))
1657  end if
1658  call this%obs%SaveOneSimval(obsrv, v)
1659  end do
1660  else
1661  call this%obs%SaveOneSimval(obsrv, dnodata)
1662  end if
1663  end do
1664  end subroutine bnd_bd_obs
1665 
1666  !> @brief Output observations for the package
1667  !!
1668  !! Method to output simulated values for the boundary package.
1669  !! This method should not need to be overridden.
1670  !<
1671  subroutine bnd_ot_obs(this)
1672  ! -- dummy
1673  class(bndtype) :: this !< BndType object
1674  !
1675  ! -- call the observation output method
1676  call this%obs%obs_ot()
1677  end subroutine bnd_ot_obs
1678 
1679  ! -- Procedures related to time series
1680 
1681  !> @brief Assign time series links for the package
1682  !!
1683  !! Assign the time series links for the boundary package. This
1684  !! method will need to be overridden for boundary packages that
1685  !! support time series.
1686  !<
1687  subroutine bnd_rp_ts(this)
1688  ! -- dummy
1689  class(bndtype), intent(inout) :: this
1690  end subroutine bnd_rp_ts
1691 
1692  !> @brief Log period input for a boundary package
1693  !!
1694  !! Write stress period input to the listing file if requested. This
1695  !! default implementation is a no-op; BndExtType overrides it.
1696  !<
1697  subroutine bnd_rp_log(this)
1698  ! -- dummy
1699  class(bndtype), intent(inout) :: this
1700  end subroutine bnd_rp_log
1701 
1702  ! -- Procedures related to casting
1703 
1704  !> @brief Cast as a boundary type
1705  !!
1706  !! Subroutine to cast an object as a boundary package type.
1707  !<
1708  function castasbndclass(obj) result(res)
1709  class(*), pointer, intent(inout) :: obj !< input object
1710  class(bndtype), pointer :: res !< output class of type BndType
1711  !
1712  ! -- initialize res
1713  res => null()
1714  !
1715  ! -- make sure obj is associated
1716  if (.not. associated(obj)) return
1717  !
1718  ! -- point res to obj
1719  select type (obj)
1720  class is (bndtype)
1721  res => obj
1722  end select
1723  end function castasbndclass
1724 
1725  !> @brief Add boundary to package list
1726  !!
1727  !! Subroutine to add a boundary package to a package list.
1728  !<
1729  subroutine addbndtolist(list, bnd)
1730  ! -- dummy
1731  type(listtype), intent(inout) :: list !< package list
1732  class(bndtype), pointer, intent(inout) :: bnd !< boundary package
1733  ! -- local
1734  class(*), pointer :: obj
1735  !
1736  obj => bnd
1737  call list%Add(obj)
1738  end subroutine addbndtolist
1739 
1740  !> @brief Get boundary from package list
1741  !!
1742  !! Function to get a boundary package from a package list.
1743  !!
1744  !! @return res boundary package object
1745  !<
1746  function getbndfromlist(list, idx) result(res)
1747  ! -- dummy
1748  type(listtype), intent(inout) :: list !< package list
1749  integer(I4B), intent(in) :: idx !< package number
1750  class(bndtype), pointer :: res !< boundary package idx
1751  ! -- local
1752  class(*), pointer :: obj
1753  !
1754  ! -- get the package from the list
1755  obj => list%GetItem(idx)
1756  res => castasbndclass(obj)
1757  end function getbndfromlist
1758 
1759  !> @brief Save and/or print flows for a package
1760  !!
1761  !! Subroutine to save and/or print package flows to a model to a
1762  !! binary cell-by-cell flow file and the model listing file.
1763  !<
1764  subroutine save_print_model_flows(icbcfl, ibudfl, icbcun, iprflow, &
1765  outputtab, nbound, nodelist, flow, ibound, &
1766  title, text, ipakcb, dis, naux, textmodel, &
1767  textpackage, dstmodel, dstpackage, &
1768  auxname, auxvar, iout, inamedbound, &
1769  boundname, imap)
1770  ! -- modules
1771  use tdismodule, only: kstp, kper
1772  ! -- dummy
1773  integer(I4B), intent(in) :: icbcfl !< flag indicating if the flow should be saved to the binary cell-by-cell flow file
1774  integer(I4B), intent(in) :: ibudfl !< flag indicating if the flow should be saved or printed
1775  integer(I4B), intent(in) :: icbcun !< file unit number for the binary cell-by-cell file
1776  integer(I4B), intent(in) :: iprflow !< print flows to list file
1777  type(tabletype), pointer, intent(inout) :: outputtab !< output table object
1778  integer(I4B), intent(in) :: nbound !< number of boundaries this stress period
1779  integer(I4B), dimension(:), contiguous, intent(in) :: nodelist !< boundary node list
1780  real(dp), dimension(:), contiguous, intent(in) :: flow !< boundary flow terms
1781  integer(I4B), dimension(:), contiguous, intent(in) :: ibound !< ibound array for the model
1782  character(len=*), intent(in) :: title !< title for the output table
1783  character(len=*), intent(in) :: text !< flow term description
1784  integer(I4B), intent(in) :: ipakcb !< flag indicating if flows will be saved
1785  class(disbasetype), intent(in) :: dis !< model discretization object
1786  integer(I4B), intent(in) :: naux !< number of aux variables
1787  character(len=*), intent(in) :: textmodel !< model name
1788  character(len=*), intent(in) :: textpackage !< package name
1789  character(len=*), intent(in) :: dstmodel !< mover destination model
1790  character(len=*), intent(in) :: dstpackage !< mover destination package
1791  character(len=*), dimension(:), intent(in) :: auxname !< aux variable name
1792  real(dp), dimension(:, :), intent(in) :: auxvar !< aux variable
1793  integer(I4B), intent(in) :: iout !< model listing file unit
1794  integer(I4B), intent(in) :: inamedbound !< flag indicating if boundnames are defined for the boundary entries
1795  character(len=LENBOUNDNAME), dimension(:), contiguous :: boundname !< bound names
1796  integer(I4B), dimension(:), optional, intent(in) :: imap !< mapping array
1797  ! -- local
1798  character(len=20) :: nodestr
1799  integer(I4B) :: nodeu
1800  integer(I4B) :: maxrows
1801  integer(I4B) :: i
1802  integer(I4B) :: node
1803  integer(I4B) :: n2
1804  integer(I4B) :: ibinun
1805  integer(I4B) :: nboundcount
1806  real(dp) :: rrate
1807  real(dp), dimension(naux) :: auxrow
1808  ! -- for observations
1809  character(len=LENBOUNDNAME) :: bname
1810  !
1811  ! -- set table kstp and kper
1812  if (iprflow /= 0) then
1813  call outputtab%set_kstpkper(kstp, kper)
1814  end if
1815  !
1816  ! -- set maxrows
1817  maxrows = 0
1818  if (ibudfl /= 0 .and. iprflow /= 0) then
1819  do i = 1, nbound
1820  node = nodelist(i)
1821  if (node > 0) then
1822  maxrows = maxrows + 1
1823  end if
1824  end do
1825  if (maxrows > 0) then
1826  call outputtab%set_maxbound(maxrows)
1827  end if
1828  call outputtab%set_title(title)
1829  end if
1830  !
1831  ! -- Set unit number for binary output
1832  if (ipakcb < 0) then
1833  ibinun = icbcun
1834  else if (ipakcb == 0) then
1835  ibinun = 0
1836  else
1837  ibinun = ipakcb
1838  end if
1839  if (icbcfl == 0) then
1840  ibinun = 0
1841  end if
1842  !
1843  ! -- If cell-by-cell flows will be saved as a list, write header.
1844  if (ibinun /= 0) then
1845  !
1846  ! -- Count nbound as the number of entries with node > 0
1847  ! SFR, for example, can have a 'none' connection, which
1848  ! means it should be excluded from budget file
1849  nboundcount = 0
1850  do i = 1, nbound
1851  node = nodelist(i)
1852  if (node > 0) nboundcount = nboundcount + 1
1853  end do
1854  call dis%record_srcdst_list_header(text, textmodel, textpackage, &
1855  dstmodel, dstpackage, naux, &
1856  auxname, ibinun, nboundcount, iout)
1857  end if
1858  !
1859  ! -- If no boundaries, skip flow calculations.
1860  if (nbound > 0) then
1861  !
1862  ! -- Loop through each boundary calculating flow.
1863  do i = 1, nbound
1864  node = nodelist(i)
1865  ! -- assign boundary name
1866  if (inamedbound > 0) then
1867  bname = boundname(i)
1868  else
1869  bname = ''
1870  end if
1871  !
1872  ! -- If cell is no-flow or constant-head, then ignore it.
1873  rrate = dzero
1874  if (node > 0) then
1875  !
1876  ! -- Use simval, which was calculated in cq()
1877  rrate = flow(i)
1878  !
1879  ! -- Print the individual rates if the budget is being printed
1880  ! and PRINT_FLOWS was specified (iprflow < 0). Rates are
1881  ! printed even if ibound < 1.
1882  if (ibudfl /= 0) then
1883  if (iprflow /= 0) then
1884  !
1885  ! -- set nodestr and write outputtab table
1886  nodeu = dis%get_nodeuser(node)
1887  call dis%nodeu_to_string(nodeu, nodestr)
1888  call outputtab%print_list_entry(i, trim(adjustl(nodestr)), &
1889  rrate, bname)
1890  end if
1891  end if
1892  !
1893  ! -- If saving cell-by-cell flows in list, write flow
1894  if (ibinun /= 0) then
1895  n2 = i
1896  if (present(imap)) n2 = imap(i)
1897  if (naux > 0) then
1898  auxrow(:) = auxvar(:, i)
1899  end if
1900  call dis%record_mf6_list_entry(ibinun, node, n2, rrate, naux, &
1901  auxrow, olconv2=.false.)
1902  end if
1903  end if
1904  !
1905  end do
1906  if (ibudfl /= 0) then
1907  if (iprflow /= 0) then
1908  write (iout, '(1x)')
1909  end if
1910  end if
1911 
1912  end if
1913  end subroutine save_print_model_flows
1914 
1915  !> @brief Activate viscosity terms
1916  !!
1917  !! Method to activate addition of viscosity terms when package type
1918  !! is DRN, GHB, or RIV (method not needed by other packages at this point)
1919  !<
1920  subroutine bnd_activate_viscosity(this)
1921  ! -- modules
1923  ! -- dummy
1924  class(bndtype), intent(inout) :: this !< BndType object
1925  ! -- local
1926  integer(I4B) :: i
1927  !
1928  ! -- Set ivsc and reallocate viscratios to be of size MAXBOUND
1929  this%ivsc = 1
1930  !
1931  ! -- Allocate array for storing user-specified conductances
1932  ! modified by updated viscosity values
1933  call mem_reallocate(this%condinput, this%maxbound, 'CONDINPUT', &
1934  this%memoryPath)
1935  do i = 1, this%maxbound
1936  this%condinput(i) = dzero
1937  end do
1938  !
1939  ! -- Notify user via listing file viscosity accounted for by standard
1940  ! boundary package.
1941  write (this%iout, '(/1x,a,a)') 'VISCOSITY ACTIVE IN ', &
1942  trim(this%filtyp)//' PACKAGE CALCULATIONS: '//trim(adjustl(this%packName))
1943  end subroutine bnd_activate_viscosity
1944 
1945 end module bndmodule
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains the base boundary package.
subroutine bnd_read_dimensions(this)
@ brief Read dimensions for package
logical(lgp) function bnd_obs_supported(this)
Determine if observations are supported.
subroutine bnd_ar(this)
@ brief Allocate and read method for boundary package
subroutine bnd_rp(this)
@ brief Allocate and read method for package
subroutine allocate_scalars(this)
@ brief Allocate package scalars
subroutine bnd_ot_dv(this, idvsave, idvprint)
@ brief Output advanced package dependent-variable terms.
subroutine bnd_store_user_cond(this, nlist, rlist, condinput)
@ brief Store user-specified conductances when vsc is active
subroutine bnd_ot_obs(this)
Output observations for the package.
subroutine bnd_nur(this, neqpak, x, xtemp, dx, inewtonur, dxmax, locmax)
@ brief Apply Newton-Raphson under-relaxation for package.
subroutine bnd_ot_package_flows(this, icbcfl, ibudfl)
@ brief Output advanced package flow terms.
subroutine bnd_read_options(this)
@ brief Read additional options for package
subroutine bnd_ot_model_flows(this, icbcfl, ibudfl, icbcun, imap)
@ brief Output package flow terms.
subroutine bnd_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
@ brief Convergence check for package.
subroutine bnd_rp_ts(this)
Assign time series links for the package.
subroutine bnd_bd_obs(this)
Save observations for the package.
subroutine bnd_options(this, option, found)
@ brief Read additional options for package
subroutine bnd_da(this)
@ brief Deallocate package memory
subroutine bnd_bd(this, model_budget)
@ brief Add package flows to model budget.
subroutine, public addbndtolist(list, bnd)
Add boundary to package list.
subroutine bnd_cq_simrate(this, hnew, flowja, imover)
@ brief Calculate simrate.
subroutine bnd_mc(this, moffset, matrix_sln)
@ brief Map boundary package connection to matrix
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
subroutine bnd_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
subroutine allocate_arrays(this, nodelist, auxvar)
@ brief Allocate package arrays
subroutine bnd_ck(this)
@ brief Check boundary package period data
subroutine pak_setup_outputtab(this)
@ brief Setup output table for package
subroutine bnd_ac(this, moffset, sparse)
@ brief Add boundary package connection to matrix
subroutine bnd_ot_bdsummary(this, kstp, kper, iout, ibudfl)
@ brief Output advanced package budget summary.
subroutine copy_boundname(this)
@ brief Copy boundnames into boundnames_cst
subroutine bnd_df_obs(this)
Define the observation types available in the package.
subroutine bnd_reset(this)
@ brief Reset bnd package before formulating
subroutine bnd_activate_viscosity(this)
Activate viscosity terms.
subroutine bnd_cq_simtomvr(this, flowja)
@ brief Calculate flow to the mover.
subroutine bnd_read_initial_attr(this)
@ brief Read initial parameters for package
subroutine, public save_print_model_flows(icbcfl, ibudfl, icbcun, iprflow, outputtab, nbound, nodelist, flow, ibound, title, text, ipakcb, dis, naux, textmodel, textpackage, dstmodel, dstpackage, auxname, auxvar, iout, inamedbound, boundname, imap)
Save and/or print flows for a package.
subroutine set_pointers(this, neq, ibound, xnew, xold, flowja)
@ brief Set pointers to model variables
subroutine bnd_rp_log(this)
Log period input for a boundary package.
subroutine bnd_rp_obs(this)
Read and prepare observations for a package.
subroutine bnd_cf(this)
@ brief Formulate the package hcof and rhs terms.
subroutine bnd_fn(this, rhs, ia, idxglo, matrix_sln)
@ brief Add Newton-Raphson terms for package into solution.
subroutine bnd_ad(this)
@ brief Advance the boundary package
class(bndtype) function, pointer, private castasbndclass(obj)
Cast as a boundary type.
subroutine bnd_cq(this, x, flowja, iadv)
@ brief Calculate advanced package flows.
subroutine define_listlabel(this)
@ brief Define the list label for the package
subroutine pack_initialize(this)
@ brief Allocate and initialize select package members
subroutine bnd_df(this, neq, dis)
@ brief Define boundary package options and dimensions
This module contains the BudgetModule.
Definition: Budget.f90:20
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
Definition: Budget.f90:632
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
@ tabcenter
centered table column
Definition: Constants.f90:172
@ tableft
left justified table column
Definition: Constants.f90:171
integer(i4b), parameter lenmodelname
maximum length of the model name
Definition: Constants.f90:22
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
integer(i4b), parameter lenlistlabel
maximum length of a llist label
Definition: Constants.f90:46
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:50
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:39
integer(i4b), parameter lenauxname
maximum length of a aux variable
Definition: Constants.f90:35
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:36
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter maxcharlen
maximum length of char string
Definition: Constants.f90:47
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine, public urdaux(naux, inunit, iout, lloc, istart, istop, auxname, line, text)
Read auxiliary variables from an input line.
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
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
This module contains the base numerical package type.
This module contains the derived types ObserveType and ObsDataType.
Definition: Observe.f90:15
This module contains the derived type ObsType.
Definition: Obs.f90:127
subroutine, public obs_cr(obs, inobs)
@ brief Create a new ObsType object
Definition: Obs.f90:225
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
subroutine, public table_cr(this, name, title)
Definition: Table.f90:87
real(dp), pointer, public totimc
simulation time at start of time step
Definition: tdis.f90:33
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21
subroutine, public tasmanager_cr(this, dis, modelname, iout)
Create the time-array series manager.
subroutine, public tsmanager_cr(this, iout, removeTsLinksOnCompletion, extendTsToEndOfSimulation)
Create the tsmanager.
@ brief BndType
Derived type for the Budget object.
Definition: Budget.f90:39
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
A generic heterogeneous doubly-linked list.
Definition: List.f90:14