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