MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
gwf-wel.f90
Go to the documentation of this file.
1 !> @brief This module contains the WEL package methods
2 !!
3 !! This module contains the overridden methods for the standard WEL package.
4 !! Several methods need to be overridden because of the AUTO_FLOW_REDUCE
5 !! option. Overridden methods include:
6 !! - bnd_cf (AUTO_FLOW_REDUCE)
7 !! - bnd_fc (AUTO_FLOW_REDUCE)
8 !! - bnd_fn (AUTO_FLOW_REDUCE Newton-Raphson terms)
9 !! - bnd_ot_package_flows (write AUTO_FLOW_REDUCE terms to csv file)
10 !! - bnd_da (deallocate AUTO_FLOW_REDUCE variables)
11 !! - bnd_bd_obs (wel-reduction observation added)
12 !!
13 !<
14 
15 module welmodule
16  ! -- modules used by WelModule methods
17  use kindmodule, only: dp, i4b
23  use bndmodule, only: bndtype
24  use bndextmodule, only: bndexttype
27  use observemodule, only: observetype
31  !
32  implicit none
33  !
34  private
35  public :: wel_create
36  !
37  character(len=LENFTYPE) :: ftype = 'WEL' !< package ftype
38  character(len=16) :: text = ' WEL' !< package flow text string
39  !
40  type, extends(bndexttype) :: weltype
41  real(dp), dimension(:), pointer, contiguous :: q => null() !< volumetric well rate
42  integer(I4B), pointer :: iflowred => null() !< flag indicating if the AUTO_FLOW_REDUCE option is active
43  real(dp), pointer :: flowred => null() !< AUTO_FLOW_REDUCE variable
44  integer(I4B), pointer :: ioutafrcsv => null() !< unit number for CSV output file containing wells with reduced puping rates
45  integer(I4B), pointer :: iflowredlen => null() !< flag indicating flowred variable is a length value
46  integer(I4B), pointer :: iafrauxcol => null() !< column index in auxvar for AUTO_FLOW_REDUCE_AUXNAME (0 if not active)
47  contains
48  procedure :: allocate_scalars => wel_allocate_scalars
49  procedure :: allocate_arrays => wel_allocate_arrays
50  procedure :: source_options => wel_options
51  procedure :: log_wel_options
52  procedure :: bnd_ck => wel_ck
53  procedure :: bnd_cf => wel_cf
54  procedure :: bnd_fc => wel_fc
55  procedure :: bnd_fn => wel_fn
56  procedure :: bnd_da => wel_da
57  procedure :: define_listlabel
58  procedure :: bound_value => wel_bound_value
59  procedure :: q_mult
60  ! -- methods for observations
61  procedure, public :: bnd_obs_supported => wel_obs_supported
62  procedure, public :: bnd_df_obs => wel_df_obs
63  procedure, public :: bnd_bd_obs => wel_bd_obs
64  ! -- afr
65  procedure, private :: wel_afr_csv_init
66  procedure, private :: wel_afr_csv_write
67  end type weltype
68 
69 contains
70 
71  !> @ brief Create a new package object
72  !!
73  !! Create a new WEL Package object
74  !!
75  !<
76  subroutine wel_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
77  mempath)
78  ! -- dummy variables
79  class(bndtype), pointer :: packobj !< pointer to default package type
80  integer(I4B), intent(in) :: id !< package id
81  integer(I4B), intent(in) :: ibcnum !< boundary condition number
82  integer(I4B), intent(in) :: inunit !< unit number of WEL package input file
83  integer(I4B), intent(in) :: iout !< unit number of model listing file
84  character(len=*), intent(in) :: namemodel !< model name
85  character(len=*), intent(in) :: pakname !< package name
86  character(len=*), intent(in) :: mempath !< input mempath
87  ! -- local variables
88  type(weltype), pointer :: welobj
89  !
90  ! -- allocate the object and assign values to object variables
91  allocate (welobj)
92  packobj => welobj
93  !
94  ! -- create name and memory path
95  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
96  packobj%text = text
97  !
98  ! -- allocate scalars
99  call welobj%allocate_scalars()
100  !
101  ! -- initialize package
102  call packobj%pack_initialize()
103 
104  packobj%inunit = inunit
105  packobj%iout = iout
106  packobj%id = id
107  packobj%ibcnum = ibcnum
108  packobj%ncolbnd = 1
109  packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
110  end subroutine wel_create
111 
112  !> @ brief Deallocate package memory
113  !!
114  !! Deallocate WEL package scalars and arrays.
115  !!
116  !<
117  subroutine wel_da(this)
118  ! -- modules
120  ! -- dummy variables
121  class(weltype) :: this !< WelType object
122  !
123  ! -- Deallocate parent package
124  call this%BndExtType%bnd_da()
125  !
126  ! -- scalars
127  call mem_deallocate(this%iflowred)
128  call mem_deallocate(this%flowred)
129  call mem_deallocate(this%ioutafrcsv)
130  call mem_deallocate(this%iflowredlen)
131  call mem_deallocate(this%iafrauxcol)
132  call mem_deallocate(this%q, 'Q', this%memoryPath)
133  end subroutine wel_da
134 
135  !> @ brief Allocate scalars
136  !!
137  !! Allocate and initialize scalars for the WEL package. The base model
138  !! allocate scalars method is also called.
139  !!
140  !<
141  subroutine wel_allocate_scalars(this)
142  ! -- modules
144  ! -- dummy variables
145  class(weltype) :: this !< WelType object
146  !
147  ! -- call base type allocate scalars
148  call this%BndExtType%allocate_scalars()
149  !
150  ! -- allocate the object and assign values to object variables
151  call mem_allocate(this%iflowred, 'IFLOWRED', this%memoryPath)
152  call mem_allocate(this%flowred, 'FLOWRED', this%memoryPath)
153  call mem_allocate(this%ioutafrcsv, 'IOUTAFRCSV', this%memoryPath)
154  call mem_allocate(this%iflowredlen, 'IFLOWREDLEN', this%memoryPath)
155  call mem_allocate(this%iafrauxcol, 'IAFRAUXCOL', this%memoryPath)
156  !
157  ! -- Set values
158  this%iflowred = 0
159  this%ioutafrcsv = 0
160  this%flowred = dzero
161  this%iflowredlen = 0
162  this%iafrauxcol = 0
163  end subroutine wel_allocate_scalars
164 
165  !> @ brief Allocate arrays
166  !!
167  !! Allocate and initialize arrays for the WEL package
168  !!
169  !<
170  subroutine wel_allocate_arrays(this, nodelist, auxvar)
171  ! -- modules
173  ! -- dummy
174  class(weltype) :: this
175  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
176  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
177  ! -- local
178  !
179  ! -- call BndExtType allocate scalars
180  call this%BndExtType%allocate_arrays(nodelist, auxvar)
181  !
182  ! -- set constant head array input context pointer
183  call mem_setptr(this%q, 'Q', this%input_mempath)
184  !
185  ! -- checkin constant head array input context pointer
186  call mem_checkin(this%q, 'Q', this%memoryPath, &
187  'Q', this%input_mempath)
188  end subroutine wel_allocate_arrays
189 
190  !> @ brief Source additional options for package
191  !!
192  !! Source additional options for WEL package.
193  !!
194  !<
195  subroutine wel_options(this)
196  ! -- modules
197  use inputoutputmodule, only: urword
200  ! -- dummy variables
201  class(weltype), intent(inout) :: this !< WelType object
202  ! -- local variables
203  character(len=LINELENGTH) :: fname
204  character(len=LENAUXNAME) :: afrauxname
205  type(gwfwelparamfoundtype) :: found
206  integer(I4B) :: n
207  ! -- formats
208  character(len=*), parameter :: fmtflowred = &
209  &"(4x, 'AUTOMATIC FLOW REDUCTION OF WELLS IMPLEMENTED.')"
210  character(len=*), parameter :: fmtflowredv = &
211  &"(4x, 'AUTOMATIC FLOW REDUCTION FRACTION (',g15.7,').')"
212  !
213  ! -- source base BndExtType options
214  call this%BndExtType%source_options()
215  !
216  ! -- source well options from input context
217  call mem_set_value(this%flowred, 'FLOWRED', this%input_mempath, found%flowred)
218  call mem_set_value(fname, 'AFRCSVFILE', this%input_mempath, found%afrcsvfile)
219  call mem_set_value(this%imover, 'MOVER', this%input_mempath, found%mover)
220  call mem_set_value(this%iflowredlen, 'IFLOWREDLEN', this%input_mempath, &
221  found%iflowredlen)
222  call mem_set_value(afrauxname, 'AFRAUXNAME', this%input_mempath, &
223  found%afrauxname)
224 
225  if (found%iflowredlen) then
226  if (found%flowred .eqv. .false.) then
227  write (warnmsg, '(a)') &
228  'FLOW_REDUCTION_LENGTH option specified but a AUTO_FLOW_REDUCTION value &
229  &is not specified. The FLOW_REDUCTION_LENGTH option will be ignored.'
230  call store_warning(warnmsg)
231  else
232  this%iflowredlen = 1
233  end if
234  end if
235 
236  if (found%flowred) then
237  this%iflowred = 1
238  if (this%flowred <= dzero) then
239  if (found%iflowredlen) then
240  write (errmsg, '(a)') &
241  'An AUTO_FLOW_REDUCTION value less than or equal to zero cannot be &
242  &specified if the FLOW_REDUCTION_LENGTH option is specified.'
243  call store_error(errmsg)
244  else
245  this%flowred = dem1
246  end if
247  else if (this%flowred > done .and. this%iflowredlen == 0) then
248  this%flowred = done
249  end if
250  end if
251 
252  if (found%afrcsvfile) then
253  call this%wel_afr_csv_init(fname)
254  end if
255 
256  if (found%mover) then
257  this%imover = 1
258  end if
259 
260  if (found%afrauxname) then
261  if (.not. found%flowred) then
262  write (warnmsg, '(a)') &
263  'AUTO_FLOW_REDUCE_AUXNAME is specified but AUTO_FLOW_REDUCE is not &
264  &specified. The AUTO_FLOW_REDUCE_AUXNAME option will be ignored.'
265  call store_warning(warnmsg)
266  end if
267  if (.not. found%iflowredlen) then
268  write (warnmsg, '(a)') &
269  'AUTO_FLOW_REDUCE_AUXNAME is specified but FLOW_REDUCTION_LENGTH is &
270  &not specified. The AUTO_FLOW_REDUCE_AUXNAME value will be &
271  &interpreted as a fraction of the cell thickness.'
272  call store_warning(warnmsg)
273  end if
274  if (found%flowred) then
275  if (this%naux == 0) then
276  write (errmsg, '(a,2(1x,a))') &
277  'AUTO_FLOW_REDUCE_AUXNAME was specified as', &
278  trim(adjustl(afrauxname)), 'but no AUX variables specified.'
279  call store_error(errmsg)
280  end if
281  this%iafrauxcol = 0
282  do n = 1, this%naux
283  if (afrauxname == this%auxname(n)) then
284  this%iafrauxcol = n
285  exit
286  end if
287  end do
288  if (this%iafrauxcol == 0) then
289  write (errmsg, '(a,2(1x,a))') &
290  'AUTO_FLOW_REDUCE_AUXNAME was specified as', &
291  trim(adjustl(afrauxname)), &
292  'but no AUX variable found with this name.'
293  call store_error(errmsg)
294  end if
295  end if
296  end if
297 
298  ! -- log WEL specific options
299  call this%log_wel_options(found)
300  end subroutine wel_options
301 
302  !> @ brief Log WEL specific package options
303  !<
304  subroutine log_wel_options(this, found)
305  ! -- modules
307  ! -- dummy variables
308  class(weltype), intent(inout) :: this
309  type(gwfwelparamfoundtype), intent(in) :: found
310  ! -- local variables
311  ! -- format
312  character(len=*), parameter :: fmtflowred = &
313  &"(4x, 'AUTOMATIC FLOW REDUCTION OF WELLS IMPLEMENTED.')"
314  character(len=*), parameter :: fmtflowredv = &
315  &"(4x, 'AUTOMATIC FLOW REDUCTION FRACTION (',g15.7,').')"
316  character(len=*), parameter :: fmtflowredl = &
317  &"(4x, 'AUTOMATIC FLOW REDUCTION LENGTH (',g15.7,').')"
318  !
319  ! -- log found options
320  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
321  //' OPTIONS'
322 
323  if (found%iflowredlen) then
324  write (this%iout, fmtflowred)
325  write (this%iout, '(4x,A)') &
326  'AUTOMATIC FLOW REDUCTION FRACTION INTERPRETED AS A LENGTH'
327  end if
328 
329  if (found%flowred) then
330  if (this%iflowredlen == 0) then
331  write (this%iout, fmtflowredv) this%flowred
332  else
333  write (this%iout, fmtflowredl) this%flowred
334  end if
335  end if
336  !
337  if (found%afrcsvfile) then
338  ! -- currently no-op
339  end if
340 
341  if (found%mover) then
342  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
343  end if
344 
345  if (found%afrauxname) then
346  write (this%iout, '(4x,A)') &
347  'AUTO_FLOW_REDUCE_AUXNAME OPTION ENABLED FOR PER-WELL FLOW REDUCTION'
348  end if
349  !
350  ! -- close logging block
351  write (this%iout, '(1x,a)') &
352  'END OF '//trim(adjustl(this%text))//' OPTIONS'
353  end subroutine log_wel_options
354 
355  !> @ brief Check WEL period data.
356  !!
357  !! Verify that the per-well AUTO_FLOW_REDUCE_AUXNAME auxiliary values are
358  !! within valid bounds. When FLOW_REDUCTION_LENGTH is not specified the
359  !! value is interpreted as a fraction of the cell thickness and must be
360  !! between 0 and 1. When FLOW_REDUCTION_LENGTH is specified the value is
361  !! interpreted as a length above the cell bottom and must be between 0 and
362  !! the cell thickness. The check runs each stress period because the
363  !! auxiliary values may change between periods.
364  !!
365  !<
366  subroutine wel_ck(this)
367  ! -- modules
369  ! -- dummy variables
370  class(weltype), intent(inout) :: this !< WelType object
371  ! -- local variables
372  character(len=LINELENGTH) :: errmsg
373  integer(I4B) :: i
374  integer(I4B) :: node
375  real(DP) :: afraux
376  real(DP) :: thick
377  ! -- formats
378  character(len=*), parameter :: fmtfracerr = &
379  "('WELL (',i0,') AUTO_FLOW_REDUCE_AUXNAME value (',g0,') must be greater &
380  &than 0 and less than or equal to 1 when FLOW_REDUCTION_LENGTH is not &
381  &specified (it is interpreted as a fraction of the cell thickness).')"
382  character(len=*), parameter :: fmtlenerr = &
383  "('WELL (',i0,') AUTO_FLOW_REDUCE_AUXNAME value (',g0,') must be greater &
384  &than 0 and less than or equal to the cell thickness (',g0,') when &
385  &FLOW_REDUCTION_LENGTH is specified.')"
386  !
387  ! -- nothing to check unless AUTO_FLOW_REDUCE_AUXNAME is active
388  if (this%iflowred == 0 .or. this%iafrauxcol == 0) return
389  !
390  ! -- check the per-well auxiliary flow reduction values. The value must be
391  ! strictly greater than zero: a value of zero places the turnoff
392  ! threshold at the cell bottom, giving a zero-width smoothing interval
393  ! (a divide-by-zero in sQSaturation), consistent with the global
394  ! AUTO_FLOW_REDUCE length-mode check.
395  do i = 1, this%nbound
396  node = this%nodelist(i)
397  if (node == 0) cycle
398  ! -- the reduction is only applied to convertible cells
399  if (this%icelltype(node) == 0) cycle
400  afraux = this%auxvar(this%iafrauxcol, i)
401  if (this%iflowredlen == 0) then
402  ! -- value is a fraction of the cell thickness: valid range (0, 1]
403  if (afraux <= dzero .or. afraux > done) then
404  write (errmsg, fmt=fmtfracerr) i, afraux
405  call store_error(errmsg)
406  end if
407  else
408  ! -- value is a length above the cell bottom: valid range (0, thick]
409  thick = this%dis%top(node) - this%dis%bot(node)
410  if (afraux <= dzero .or. afraux > thick) then
411  write (errmsg, fmt=fmtlenerr) i, afraux, thick
412  call store_error(errmsg)
413  end if
414  end if
415  end do
416  !
417  ! -- terminate if any errors were detected
418  if (count_errors() > 0) then
419  call store_error_unit(this%inunit)
420  end if
421  end subroutine wel_ck
422 
423  !> @ brief Formulate the package hcof and rhs terms.
424  !!
425  !! Formulate the hcof and rhs terms for the WEL package that will be
426  !! added to the coefficient matrix and right-hand side vector.
427  !!
428  !<
429  subroutine wel_cf(this)
430  ! -- dummy variables
431  class(weltype) :: this !< WelType object
432  ! -- local variables
433  integer(I4B) :: i, node, ict
434  real(DP) :: qmult
435  real(DP) :: q
436  real(DP) :: tp
437  real(DP) :: bt
438  real(DP) :: thick
439  !
440  ! -- Return if no wells
441  if (this%nbound == 0) return
442  !
443  ! -- Calculate hcof and rhs for each well entry
444  do i = 1, this%nbound
445  node = this%nodelist(i)
446  this%hcof(i) = dzero
447  if (this%ibound(node) <= 0) then
448  this%rhs(i) = dzero
449  cycle
450  end if
451  q = this%q_mult(i)
452  if (this%iflowred /= 0 .and. q < dzero) then
453  ict = this%icelltype(node)
454  if (ict /= 0) then
455  bt = this%dis%bot(node)
456  if (this%iflowredlen == 0) then
457  thick = this%dis%top(node) - bt
458  else
459  thick = done
460  end if
461  if (this%iafrauxcol > 0) then
462  tp = bt + this%auxvar(this%iafrauxcol, i) * thick
463  else
464  tp = bt + this%flowred * thick
465  end if
466  qmult = sqsaturation(tp, bt, this%xnew(node))
467  q = q * qmult
468  end if
469  end if
470  this%rhs(i) = -q
471  end do
472  end subroutine wel_cf
473 
474  !> @ brief Copy hcof and rhs terms into solution.
475  !!
476  !! Add the hcof and rhs terms for the WEL package to the
477  !! coefficient matrix and right-hand side vector.
478  !!
479  !<
480  subroutine wel_fc(this, rhs, ia, idxglo, matrix_sln)
481  ! -- dummy variables
482  class(weltype) :: this !< WelType object
483  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
484  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
485  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
486  class(matrixbasetype), pointer :: matrix_sln !< solution coefficient matrix
487  ! -- local variables
488  integer(I4B) :: i
489  integer(I4B) :: n
490  integer(I4B) :: ipos
491  !
492  ! -- pakmvrobj fc
493  if (this%imover == 1) then
494  call this%pakmvrobj%fc()
495  end if
496  !
497  ! -- Copy package rhs and hcof into solution rhs and amat
498  do i = 1, this%nbound
499  n = this%nodelist(i)
500  rhs(n) = rhs(n) + this%rhs(i)
501  ipos = ia(n)
502  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
503  !
504  ! -- If mover is active and this well is discharging,
505  ! store available water (as positive value).
506  if (this%imover == 1 .and. this%rhs(i) > dzero) then
507  call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i))
508  end if
509  end do
510  end subroutine wel_fc
511 
512  !> @ brief Add Newton-Raphson terms for package into solution.
513  !!
514  !! Calculate and add the Newton-Raphson terms for the WEL package to the
515  !! coefficient matrix and right-hand side vector.
516  !!
517  !<
518  subroutine wel_fn(this, rhs, ia, idxglo, matrix_sln)
519  ! -- dummy variables
520  class(weltype) :: this !< WelType object
521  real(DP), dimension(:), intent(inout) :: rhs !< right-hand side vector for model
522  integer(I4B), dimension(:), intent(in) :: ia !< solution CRS row pointers
523  integer(I4B), dimension(:), intent(in) :: idxglo !< mapping vector for model (local) to solution (global)
524  class(matrixbasetype), pointer :: matrix_sln !< solution coefficient matrix
525  ! -- local variables
526  integer(I4B) :: i
527  integer(I4B) :: node
528  integer(I4B) :: ipos
529  integer(I4B) :: ict
530  real(DP) :: drterm
531  real(DP) :: q
532  real(DP) :: tp
533  real(DP) :: bt
534  real(DP) :: thick
535  !
536  ! -- Copy package rhs and hcof into solution rhs and amat
537  do i = 1, this%nbound
538  node = this%nodelist(i)
539  !
540  ! -- test if node is constant or inactive
541  if (this%ibound(node) <= 0) then
542  cycle
543  end if
544  !
545  ! -- well rate is possibly head dependent
546  ict = this%icelltype(node)
547  if (this%iflowred /= 0 .and. ict /= 0) then
548  ipos = ia(node)
549  q = -this%rhs(i)
550  if (q < dzero) then
551  ! -- calculate derivative for well
552  tp = this%dis%top(node)
553  bt = this%dis%bot(node)
554  if (this%iflowredlen == 0) then
555  thick = tp - bt
556  else
557  thick = done
558  end if
559  if (this%iafrauxcol > 0) then
560  tp = bt + this%auxvar(this%iafrauxcol, i) * thick
561  else
562  tp = bt + this%flowred * thick
563  end if
564  drterm = sqsaturationderivative(tp, bt, this%xnew(node))
565  drterm = drterm * this%q_mult(i)
566  !--fill amat and rhs with newton-raphson terms
567  call matrix_sln%add_value_pos(idxglo(ipos), drterm)
568  rhs(node) = rhs(node) + drterm * this%xnew(node)
569  end if
570  end if
571  end do
572  end subroutine wel_fn
573 
574  !> @brief Initialize the auto flow reduce csv output file
575  subroutine wel_afr_csv_init(this, fname)
576  ! -- dummy variables
577  class(weltype), intent(inout) :: this !< WelType object
578  character(len=*), intent(in) :: fname
579  ! -- format
580  character(len=*), parameter :: fmtafrcsv = &
581  "(4x, 'AUTO FLOW REDUCE INFORMATION WILL BE SAVED TO FILE: ', a, /4x, &
582  &'OPENED ON UNIT: ', I0)"
583 
584  this%ioutafrcsv = getunit()
585  call openfile(this%ioutafrcsv, this%iout, fname, 'CSV', &
586  filstat_opt='REPLACE')
587  write (this%iout, fmtafrcsv) trim(adjustl(fname)), &
588  this%ioutafrcsv
589  write (this%ioutafrcsv, '(a)') &
590  'time,period,step,boundnumber,cellnumber,rate-requested,&
591  &rate-actual,wel-reduction'
592  end subroutine wel_afr_csv_init
593 
594  !> @brief Write out auto flow reductions only when & where they occur
595  subroutine wel_afr_csv_write(this)
596  ! -- modules
597  use tdismodule, only: totim, kstp, kper
598  ! -- dummy variables
599  class(weltype), intent(inout) :: this !< WelType object
600  ! -- local
601  integer(I4B) :: i
602  integer(I4B) :: nodereduced
603  integer(I4B) :: nodeuser
604  real(DP) :: v
605  ! -- format
606  do i = 1, this%nbound
607  nodereduced = this%nodelist(i)
608  !
609  ! -- test if node is constant or inactive
610  if (this%ibound(nodereduced) <= 0) then
611  cycle
612  end if
613  v = this%q_mult(i) + this%rhs(i)
614  if (v < dzero) then
615  nodeuser = this%dis%get_nodeuser(nodereduced)
616  write (this%ioutafrcsv, '(*(G0,:,","))') &
617  totim, kper, kstp, i, nodeuser, this%q_mult(i), this%simvals(i), v
618  end if
619  end do
620  end subroutine wel_afr_csv_write
621 
622  !> @ brief Define the list label for the package
623  !!
624  !! Method defined the list label for the WEL package. The list label is
625  !! the heading that is written to iout when PRINT_INPUT option is used.
626  !!
627  !<
628  subroutine define_listlabel(this)
629  ! -- dummy variables
630  class(weltype), intent(inout) :: this !< WelType object
631  !
632  ! -- create the header list label
633  this%listlabel = trim(this%filtyp)//' NO.'
634  if (this%dis%ndim == 3) then
635  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
636  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
637  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
638  elseif (this%dis%ndim == 2) then
639  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
640  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
641  else
642  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
643  end if
644  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
645  if (this%inamedbound == 1) then
646  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
647  end if
648  end subroutine define_listlabel
649 
650  ! -- Procedures related to observations
651 
652  !> @brief Determine if observations are supported.
653  !!
654  !! Function to determine if observations are supported by the WEL package.
655  !! Observations are supported by the WEL package.
656  !!
657  !! @return wel_obs_supported boolean indicating if observations are supported
658  !!
659  !<
660  logical function wel_obs_supported(this)
661  ! -- dummy variables
662  class(weltype) :: this !< WelType object
663  !
664  ! -- set boolean
665  wel_obs_supported = .true.
666  end function wel_obs_supported
667 
668  !> @brief Define the observation types available in the package
669  !!
670  !! Method to define the observation types available in the WEL package.
671  !!
672  !<
673  subroutine wel_df_obs(this)
674  ! -- dummy variables
675  class(weltype) :: this !< WelType object
676  ! -- local variables
677  integer(I4B) :: indx
678  !
679  ! -- initialize observations
680  call this%obs%StoreObsType('wel', .true., indx)
681  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
682  !
683  ! -- Store obs type and assign procedure pointer
684  ! for to-mvr observation type.
685  call this%obs%StoreObsType('to-mvr', .true., indx)
686  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
687  !
688  ! -- Store obs type and assign procedure pointer
689  ! for wel-reduction observation type.
690  call this%obs%StoreObsType('wel-reduction', .true., indx)
691  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
692  end subroutine wel_df_obs
693 
694  !> @brief Save observations for the package
695  !!
696  !! Method to save simulated values for the WEL package.
697  !!
698  !<
699  subroutine wel_bd_obs(this)
700  ! -- dummy variables
701  class(weltype) :: this !< WelType object
702  ! -- local variables
703  integer(I4B) :: i
704  integer(I4B) :: n
705  integer(I4B) :: jj
706  real(DP) :: v
707  type(observetype), pointer :: obsrv => null()
708  !
709  ! -- clear the observations
710  call this%obs%obs_bd_clear()
711  !
712  ! -- Save simulated values for all of package's observations.
713  do i = 1, this%obs%npakobs
714  obsrv => this%obs%pakobs(i)%obsrv
715  if (obsrv%BndFound) then
716  do n = 1, obsrv%indxbnds_count
717  v = dnodata
718  jj = obsrv%indxbnds(n)
719  select case (obsrv%ObsTypeId)
720  case ('TO-MVR')
721  if (this%imover == 1) then
722  v = this%pakmvrobj%get_qtomvr(jj)
723  if (v > dzero) then
724  v = -v
725  end if
726  end if
727  case ('WEL')
728  v = this%simvals(jj)
729  case ('WEL-REDUCTION')
730  if (this%iflowred > 0) then
731  v = this%q_mult(jj) + this%rhs(jj)
732  end if
733  case default
734  errmsg = 'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
735  call store_error(errmsg)
736  end select
737  call this%obs%SaveOneSimval(obsrv, v)
738  end do
739  else
740  call this%obs%SaveOneSimval(obsrv, dnodata)
741  end if
742  end do
743  !
744  ! -- Write the auto flow reduce csv file entries for this step
745  if (this%ioutafrcsv > 0) then
746  call this%wel_afr_csv_write()
747  end if
748  end subroutine wel_bd_obs
749 
750  function q_mult(this, row) result(q)
751  ! -- modules
752  use constantsmodule, only: dzero
753  ! -- dummy variables
754  class(weltype), intent(inout) :: this
755  integer(I4B), intent(in) :: row
756  ! -- result
757  real(dp) :: q
758  !
759  if (this%iauxmultcol > 0) then
760  q = this%q(row) * this%auxvar(this%iauxmultcol, row)
761  else
762  q = this%q(row)
763  end if
764  end function q_mult
765 
766  !> @ brief Return a bound value
767  !!
768  !! Return a bound value associated with an ncolbnd index
769  !! and row.
770  !!
771  !<
772  function wel_bound_value(this, col, row) result(bndval)
773  ! -- modules
774  use constantsmodule, only: dzero
775  ! -- dummy variables
776  class(weltype), intent(inout) :: this
777  integer(I4B), intent(in) :: col
778  integer(I4B), intent(in) :: row
779  ! -- result
780  real(dp) :: bndval
781  !
782  select case (col)
783  case (1)
784  bndval = this%q_mult(row)
785  case default
786  errmsg = 'Programming error. WEL bound value requested column '&
787  &'outside range of ncolbnd (1).'
788  call store_error(errmsg)
789  call store_error_filename(this%input_fname)
790  end select
791  end function wel_bound_value
792 
793 end module welmodule
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains the extended boundary package.
This module contains the base boundary package.
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dem1
real constant 1e-1
Definition: Constants.f90:103
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
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
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
subroutine, public urword(line, icol, istart, istop, ncode, n, r, iout, in)
Extract a word from a string.
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 derived types ObserveType and ObsDataType.
Definition: Observe.f90:15
This module contains the derived type ObsType.
Definition: Obs.f90:127
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
Definition: Obs.f90:246
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
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_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
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
character(len=maxcharlen) warnmsg
warning message string
real(dp) function sqsaturationderivative(top, bot, x, c1, c2)
@ brief sQSaturationDerivative
real(dp) function sqsaturation(top, bot, x, c1, c2)
@ brief sQSaturation
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
This module contains the WEL package methods.
Definition: gwf-wel.f90:15
subroutine, public wel_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
@ brief Create a new package object
Definition: gwf-wel.f90:78
subroutine wel_allocate_scalars(this)
@ brief Allocate scalars
Definition: gwf-wel.f90:142
subroutine wel_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
Definition: gwf-wel.f90:481
subroutine define_listlabel(this)
@ brief Define the list label for the package
Definition: gwf-wel.f90:629
subroutine wel_allocate_arrays(this, nodelist, auxvar)
@ brief Allocate arrays
Definition: gwf-wel.f90:171
subroutine wel_ck(this)
@ brief Check WEL period data.
Definition: gwf-wel.f90:367
subroutine wel_options(this)
@ brief Source additional options for package
Definition: gwf-wel.f90:196
subroutine wel_afr_csv_write(this)
Write out auto flow reductions only when & where they occur.
Definition: gwf-wel.f90:596
real(dp) function q_mult(this, row)
Definition: gwf-wel.f90:751
real(dp) function wel_bound_value(this, col, row)
@ brief Return a bound value
Definition: gwf-wel.f90:773
subroutine wel_da(this)
@ brief Deallocate package memory
Definition: gwf-wel.f90:118
subroutine wel_fn(this, rhs, ia, idxglo, matrix_sln)
@ brief Add Newton-Raphson terms for package into solution.
Definition: gwf-wel.f90:519
subroutine wel_afr_csv_init(this, fname)
Initialize the auto flow reduce csv output file.
Definition: gwf-wel.f90:576
character(len=lenftype) ftype
package ftype
Definition: gwf-wel.f90:37
subroutine wel_cf(this)
@ brief Formulate the package hcof and rhs terms.
Definition: gwf-wel.f90:430
subroutine wel_bd_obs(this)
Save observations for the package.
Definition: gwf-wel.f90:700
logical function wel_obs_supported(this)
Determine if observations are supported.
Definition: gwf-wel.f90:661
subroutine log_wel_options(this, found)
@ brief Log WEL specific package options
Definition: gwf-wel.f90:305
character(len=16) text
package flow text string
Definition: gwf-wel.f90:38
subroutine wel_df_obs(this)
Define the observation types available in the package.
Definition: gwf-wel.f90:674
@ brief BndType