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