38 character(len=LENFTYPE) ::
ftype =
'WEL'
39 character(len=16) ::
text =
' WEL'
42 real(dp),
dimension(:),
pointer,
contiguous :: q => null()
43 integer(I4B),
pointer :: iflowred => null()
44 real(dp),
pointer :: flowred => null()
45 integer(I4B),
pointer :: ioutafrcsv => null()
46 integer(I4B),
pointer :: iflowredlen => null()
47 integer(I4B),
pointer :: iafrauxcol => null()
77 subroutine wel_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
80 class(
bndtype),
pointer :: packobj
81 integer(I4B),
intent(in) :: id
82 integer(I4B),
intent(in) :: ibcnum
83 integer(I4B),
intent(in) :: inunit
84 integer(I4B),
intent(in) :: iout
85 character(len=*),
intent(in) :: namemodel
86 character(len=*),
intent(in) :: pakname
87 character(len=*),
intent(in) :: mempath
89 type(
weltype),
pointer :: welobj
96 call packobj%set_names(ibcnum, namemodel, pakname,
ftype, mempath)
100 call welobj%allocate_scalars()
103 call packobj%pack_initialize()
105 packobj%inunit = inunit
108 packobj%ibcnum = ibcnum
125 call this%BndExtType%bnd_da()
149 call this%BndExtType%allocate_scalars()
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)
176 integer(I4B),
dimension(:),
pointer,
contiguous,
optional :: nodelist
177 real(DP),
dimension(:, :),
pointer,
contiguous,
optional :: auxvar
181 call this%BndExtType%allocate_arrays(nodelist, auxvar)
184 call mem_setptr(this%q,
'Q', this%input_mempath)
188 'Q', this%input_mempath)
202 class(
weltype),
intent(inout) :: this
204 character(len=LINELENGTH) :: fname
205 character(len=LENAUXNAME) :: afrauxname
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,').')"
215 call this%BndExtType%source_options()
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, &
223 call mem_set_value(afrauxname,
'AFRAUXNAME', this%input_mempath, &
226 if (found%iflowredlen)
then
227 if (found%flowred .eqv. .false.)
then
229 'FLOW_REDUCTION_LENGTH option specified but a AUTO_FLOW_REDUCTION value &
230 &is not specified. The FLOW_REDUCTION_LENGTH option will be ignored.'
237 if (found%flowred)
then
239 if (this%flowred <=
dzero)
then
240 if (found%iflowredlen)
then
242 'An AUTO_FLOW_REDUCTION value less than or equal to zero cannot be &
243 &specified if the FLOW_REDUCTION_LENGTH option is specified.'
248 else if (this%flowred >
done .and. this%iflowredlen == 0)
then
253 if (found%afrcsvfile)
then
254 call this%wel_afr_csv_init(fname)
257 if (found%mover)
then
261 if (found%afrauxname)
then
262 if (.not. found%flowred)
then
264 'AUTO_FLOW_REDUCE_AUXNAME is specified but AUTO_FLOW_REDUCE is not &
265 &specified. The AUTO_FLOW_REDUCE_AUXNAME option will be ignored.'
268 if (.not. found%iflowredlen)
then
270 'AUTO_FLOW_REDUCE_AUXNAME is specified but FLOW_REDUCTION_LENGTH is &
271 ¬ specified. The AUTO_FLOW_REDUCE_AUXNAME value will be &
272 &interpreted as a fraction of the cell thickness.'
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.'
284 if (afrauxname == this%auxname(n))
then
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.'
300 call this%log_wel_options(found)
314 class(
weltype),
intent(inout) :: this
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,').')"
326 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text)) &
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'
335 if (found%flowred)
then
336 if (this%iflowredlen == 0)
then
337 write (this%iout, fmtflowredv) this%flowred
339 write (this%iout, fmtflowredl) this%flowred
343 if (found%afrcsvfile)
then
347 if (found%mover)
then
348 write (this%iout,
'(4x,A)')
'MOVER OPTION ENABLED'
351 if (found%afrauxname)
then
352 write (this%iout,
'(4x,A)') &
353 'AUTO_FLOW_REDUCE_AUXNAME OPTION ENABLED FOR PER-WELL FLOW REDUCTION'
357 write (this%iout,
'(1x,a)') &
358 'END OF '//trim(adjustl(this%text))//
' OPTIONS'
376 class(
weltype),
intent(inout) :: this
378 character(len=LINELENGTH) :: errmsg
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.')"
394 if (this%iflowred == 0 .or. this%iafrauxcol == 0)
return
401 do i = 1, this%nbound
402 node = this%nodelist(i)
405 if (this%icelltype(node) == 0) cycle
406 afraux = this%auxvar(this%iafrauxcol, i)
407 if (this%iflowredlen == 0)
then
409 if (afraux <=
dzero .or. afraux >
done)
then
410 write (errmsg, fmt=fmtfracerr) i, afraux
411 call store_error(errmsg)
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)
439 integer(I4B) :: i, node, ict
447 if (this%nbound == 0)
return
450 do i = 1, this%nbound
451 node = this%nodelist(i)
453 if (this%ibound(node) <= 0)
then
458 if (this%iflowred /= 0 .and. q <
dzero)
then
459 ict = this%icelltype(node)
461 bt = this%dis%bot(node)
462 if (this%iflowredlen == 0)
then
463 thick = this%dis%top(node) - bt
467 if (this%iafrauxcol > 0)
then
468 tp = bt + this%auxvar(this%iafrauxcol, i) * thick
470 tp = bt + this%flowred * thick
486 subroutine wel_fc(this, rhs, ia, idxglo, matrix_sln)
489 real(DP),
dimension(:),
intent(inout) :: rhs
490 integer(I4B),
dimension(:),
intent(in) :: ia
491 integer(I4B),
dimension(:),
intent(in) :: idxglo
499 if (this%imover == 1)
then
500 call this%pakmvrobj%fc()
504 do i = 1, this%nbound
506 rhs(n) = rhs(n) + this%rhs(i)
508 call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
512 if (this%imover == 1 .and. this%rhs(i) >
dzero)
then
513 call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i))
524 subroutine wel_fn(this, rhs, ia, idxglo, matrix_sln)
527 real(DP),
dimension(:),
intent(inout) :: rhs
528 integer(I4B),
dimension(:),
intent(in) :: ia
529 integer(I4B),
dimension(:),
intent(in) :: idxglo
543 do i = 1, this%nbound
544 node = this%nodelist(i)
547 if (this%ibound(node) <= 0)
then
552 ict = this%icelltype(node)
553 if (this%iflowred /= 0 .and. ict /= 0)
then
558 tp = this%dis%top(node)
559 bt = this%dis%bot(node)
560 if (this%iflowredlen == 0)
then
565 if (this%iafrauxcol > 0)
then
566 tp = bt + this%auxvar(this%iafrauxcol, i) * thick
568 tp = bt + this%flowred * thick
571 drterm = drterm * this%q_mult(i)
573 call matrix_sln%add_value_pos(idxglo(ipos), drterm)
574 rhs(node) = rhs(node) + drterm * this%xnew(node)
583 class(
weltype),
intent(inout) :: this
584 character(len=*),
intent(in) :: fname
586 character(len=*),
parameter :: fmtafrcsv = &
587 "(4x, 'AUTO FLOW REDUCE INFORMATION WILL BE SAVED TO FILE: ', a, /4x, &
588 &'OPENED ON UNIT: ', I0)"
591 call openfile(this%ioutafrcsv, this%iout, fname,
'CSV', &
592 filstat_opt=
'REPLACE')
593 write (this%iout, fmtafrcsv) trim(adjustl(fname)), &
595 write (this%ioutafrcsv,
'(a)') &
596 'time,period,step,boundnumber,cellnumber,rate-requested,&
597 &rate-actual,wel-reduction'
605 class(
weltype),
intent(inout) :: this
608 integer(I4B) :: nodereduced
609 integer(I4B) :: nodeuser
612 do i = 1, this%nbound
613 nodereduced = this%nodelist(i)
616 if (this%ibound(nodereduced) <= 0)
then
619 v = this%q_mult(i) + this%rhs(i)
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
636 class(
weltype),
intent(inout) :: this
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'
648 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'NODE'
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'
686 call this%obs%StoreObsType(
'wel', .true., indx)
691 call this%obs%StoreObsType(
'to-mvr', .true., indx)
696 call this%obs%StoreObsType(
'wel-reduction', .true., indx)
716 call this%obs%obs_bd_clear()
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
724 jj = obsrv%indxbnds(n)
725 select case (obsrv%ObsTypeId)
727 if (this%imover == 1)
then
728 v = this%pakmvrobj%get_qtomvr(jj)
735 case (
'WEL-REDUCTION')
736 if (this%iflowred > 0)
then
737 v = this%q_mult(jj) + this%rhs(jj)
740 errmsg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
743 call this%obs%SaveOneSimval(obsrv, v)
746 call this%obs%SaveOneSimval(obsrv,
dnodata)
751 if (this%ioutafrcsv > 0)
then
752 call this%wel_afr_csv_write()
760 class(
weltype),
intent(inout) :: this
761 integer(I4B),
intent(in) :: row
765 if (this%iauxmultcol > 0)
then
766 q = this%q(row) * this%auxvar(this%iauxmultcol, row)
782 class(
weltype),
intent(inout) :: this
783 integer(I4B),
intent(in) :: col
784 integer(I4B),
intent(in) :: row
790 bndval = this%q_mult(row)
792 errmsg =
'Programming error. WEL bound value requested column '&
793 &
'outside range of ncolbnd (1).'
This module contains block parser methods.
This module contains the extended boundary package.
This module contains the base boundary package.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
real(dp), parameter dnodata
real no data constant
real(dp), parameter dem1
real constant 1e-1
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
integer(i4b), parameter lenauxname
maximum length of a aux variable
real(dp), parameter dzero
real constant zero
real(dp), parameter done
real constant 1
This module defines variable data types.
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.
This module contains the derived type ObsType.
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
This module contains simulation methods.
subroutine, public store_warning(msg, substring)
Store warning message.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
This module contains simulation variables.
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
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public kper
current stress period number
This module contains the WEL package methods.
subroutine, public wel_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
@ brief Create a new package object
subroutine wel_allocate_scalars(this)
@ brief Allocate scalars
subroutine wel_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
subroutine define_listlabel(this)
@ brief Define the list label for the package
subroutine wel_allocate_arrays(this, nodelist, auxvar)
@ brief Allocate arrays
subroutine wel_ck(this)
@ brief Check WEL period data.
subroutine wel_options(this)
@ brief Source additional options for package
subroutine wel_afr_csv_write(this)
Write out auto flow reductions only when & where they occur.
real(dp) function q_mult(this, row)
real(dp) function wel_bound_value(this, col, row)
@ brief Return a bound value
subroutine wel_da(this)
@ brief Deallocate package memory
subroutine wel_fn(this, rhs, ia, idxglo, matrix_sln)
@ brief Add Newton-Raphson terms for package into solution.
subroutine wel_afr_csv_init(this, fname)
Initialize the auto flow reduce csv output file.
character(len=lenftype) ftype
package ftype
subroutine wel_cf(this)
@ brief Formulate the package hcof and rhs terms.
subroutine wel_bd_obs(this)
Save observations for the package.
logical function wel_obs_supported(this)
Determine if observations are supported.
subroutine log_wel_options(this, found)
@ brief Log WEL specific package options
character(len=16) text
package flow text string
subroutine wel_df_obs(this)
Define the observation types available in the package.