40 character(len=LENFTYPE) ::
ftype =
'WEL'
41 character(len=16) ::
text =
' WEL'
44 real(dp),
dimension(:),
pointer,
contiguous :: q => null()
45 integer(I4B),
pointer :: iflowred => null()
46 real(dp),
pointer :: flowred => null()
47 integer(I4B),
pointer :: ioutafrcsv => null()
48 integer(I4B),
pointer :: iflowredlen => null()
49 integer(I4B),
pointer :: iafrauxcol => null()
81 subroutine wel_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
84 class(
bndtype),
pointer :: packobj
85 integer(I4B),
intent(in) :: id
86 integer(I4B),
intent(in) :: ibcnum
87 integer(I4B),
intent(in) :: inunit
88 integer(I4B),
intent(in) ::
iout
89 character(len=*),
intent(in) :: namemodel
90 character(len=*),
intent(in) :: pakname
91 character(len=*),
intent(in) :: mempath
93 type(
weltype),
pointer :: welobj
100 call packobj%set_names(ibcnum, namemodel, pakname,
ftype, mempath)
104 call welobj%allocate_scalars()
107 call packobj%pack_initialize()
109 packobj%inunit = inunit
112 packobj%ibcnum = ibcnum
129 call this%BndExtType%bnd_da()
138 nullify (this%flowred_provider)
154 call this%BndExtType%allocate_scalars()
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)
181 integer(I4B),
dimension(:),
pointer,
contiguous,
optional :: nodelist
182 real(DP),
dimension(:, :),
pointer,
contiguous,
optional :: auxvar
186 call this%BndExtType%allocate_arrays(nodelist, auxvar)
189 call mem_setptr(this%q,
'Q', this%input_mempath)
193 'Q', this%input_mempath)
207 class(
weltype),
intent(inout) :: this
209 character(len=LINELENGTH) :: fname
210 character(len=LENAUXNAME) :: afrauxname
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,').')"
220 call this%BndExtType%source_options()
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, &
228 call mem_set_value(afrauxname,
'AFRAUXNAME', this%input_mempath, &
231 if (found%iflowredlen)
then
232 if (found%flowred .eqv. .false.)
then
234 'FLOW_REDUCTION_LENGTH option specified but a AUTO_FLOW_REDUCTION value &
235 &is not specified. The FLOW_REDUCTION_LENGTH option will be ignored.'
242 if (found%flowred)
then
244 if (this%flowred <=
dzero)
then
245 if (found%iflowredlen)
then
247 'An AUTO_FLOW_REDUCTION value less than or equal to zero cannot be &
248 &specified if the FLOW_REDUCTION_LENGTH option is specified.'
253 else if (this%flowred >
done .and. this%iflowredlen == 0)
then
258 if (found%afrcsvfile)
then
259 call this%wel_afr_csv_init(fname)
262 if (found%mover)
then
266 if (found%afrauxname)
then
267 if (.not. found%flowred)
then
269 'AUTO_FLOW_REDUCE_AUXNAME is specified but AUTO_FLOW_REDUCE is not &
270 &specified. The AUTO_FLOW_REDUCE_AUXNAME option will be ignored.'
273 if (.not. found%iflowredlen)
then
275 'AUTO_FLOW_REDUCE_AUXNAME is specified but FLOW_REDUCTION_LENGTH is &
276 ¬ specified. The AUTO_FLOW_REDUCE_AUXNAME value will be &
277 &interpreted as a fraction of the cell thickness.'
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.'
289 if (afrauxname == this%auxname(n))
then
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.'
305 call this%log_wel_options(found)
319 class(
weltype),
intent(inout) :: this
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,').')"
331 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text)) &
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'
340 if (found%flowred)
then
341 if (this%iflowredlen == 0)
then
342 write (this%iout, fmtflowredv) this%flowred
344 write (this%iout, fmtflowredl) this%flowred
348 if (found%afrcsvfile)
then
352 if (found%mover)
then
353 write (this%iout,
'(4x,A)')
'MOVER OPTION ENABLED'
356 if (found%afrauxname)
then
357 write (this%iout,
'(4x,A)') &
358 'AUTO_FLOW_REDUCE_AUXNAME OPTION ENABLED FOR PER-WELL FLOW REDUCTION'
362 write (this%iout,
'(1x,a)') &
363 'END OF '//trim(adjustl(this%text))//
' OPTIONS'
381 class(
weltype),
intent(inout) :: this
383 character(len=LINELENGTH) :: errmsg
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.')"
399 if (this%iflowred == 0 .or. this%iafrauxcol == 0)
return
406 do i = 1, this%nbound
407 node = this%nodelist(i)
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
417 if (afraux <=
dzero .or. afraux >
done)
then
418 write (errmsg, fmt=fmtfracerr) i, afraux
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
447 integer(I4B) :: i, node
453 if (this%nbound == 0)
return
456 do i = 1, this%nbound
457 node = this%nodelist(i)
459 if (this%ibound(node) <= 0)
then
464 if (this%iflowred /= 0 .and. q <
dzero)
then
465 call this%reduction_factor(i, node, f, dfdh)
483 class(
weltype),
intent(inout) :: this
484 integer(I4B),
intent(in) :: i
485 integer(I4B),
intent(in) :: node
486 real(DP),
intent(out) :: f
487 real(DP),
intent(out) :: dfdh
489 real(DP) :: taper, bt, tp
495 if (this%iafrauxcol > 0)
then
496 taper = this%auxvar(this%iafrauxcol, i)
500 if (this%iflowredlen == 0)
then
501 taper = taper * (this%dis%top(node) - this%dis%bot(node))
505 if (
associated(this%flowred_provider))
then
506 call this%flowred_provider%reduce(node, this%xnew(node), taper, f, dfdh)
511 if (this%icelltype(node) == 0)
return
512 bt = this%dis%bot(node)
526 subroutine wel_fc(this, rhs, ia, idxglo, matrix_sln)
529 real(DP),
dimension(:),
intent(inout) :: rhs
530 integer(I4B),
dimension(:),
intent(in) :: ia
531 integer(I4B),
dimension(:),
intent(in) :: idxglo
539 if (this%imover == 1)
then
540 call this%pakmvrobj%fc()
544 do i = 1, this%nbound
546 rhs(n) = rhs(n) + this%rhs(i)
548 call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
552 if (this%imover == 1 .and. this%rhs(i) >
dzero)
then
553 call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i))
564 subroutine wel_fn(this, rhs, ia, idxglo, matrix_sln)
567 real(DP),
dimension(:),
intent(inout) :: rhs
568 integer(I4B),
dimension(:),
intent(in) :: ia
569 integer(I4B),
dimension(:),
intent(in) :: idxglo
581 do i = 1, this%nbound
582 node = this%nodelist(i)
585 if (this%ibound(node) <= 0)
then
590 if (this%iflowred /= 0)
then
594 call this%reduction_factor(i, node, f, dfdh)
595 drterm = dfdh * this%q_mult(i)
596 if (drterm ==
dzero) cycle
599 call matrix_sln%add_value_pos(idxglo(ipos), drterm)
600 rhs(node) = rhs(node) + drterm * this%xnew(node)
609 class(
weltype),
intent(inout) :: this
610 character(len=*),
intent(in) :: fname
612 character(len=*),
parameter :: fmtafrcsv = &
613 "(4x, 'AUTO FLOW REDUCE INFORMATION WILL BE SAVED TO FILE: ', a, /4x, &
614 &'OPENED ON UNIT: ', I0)"
617 call openfile(this%ioutafrcsv, this%iout, fname,
'CSV', &
618 filstat_opt=
'REPLACE')
619 write (this%iout, fmtafrcsv) trim(adjustl(fname)), &
621 write (this%ioutafrcsv,
'(a)') &
622 'time,period,step,boundnumber,cellnumber,rate-requested,&
623 &rate-actual,wel-reduction'
631 class(
weltype),
intent(inout) :: this
634 integer(I4B) :: nodereduced
635 integer(I4B) :: nodeuser
638 do i = 1, this%nbound
639 nodereduced = this%nodelist(i)
642 if (this%ibound(nodereduced) <= 0)
then
645 v = this%q_mult(i) + this%rhs(i)
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
662 class(
weltype),
intent(inout) :: this
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'
674 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'NODE'
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'
712 call this%obs%StoreObsType(
'wel', .true., indx)
717 call this%obs%StoreObsType(
'to-mvr', .true., indx)
722 call this%obs%StoreObsType(
'wel-reduction', .true., indx)
742 call this%obs%obs_bd_clear()
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
750 jj = obsrv%indxbnds(n)
751 select case (obsrv%ObsTypeId)
753 if (this%imover == 1)
then
754 v = this%pakmvrobj%get_qtomvr(jj)
761 case (
'WEL-REDUCTION')
762 if (this%iflowred > 0)
then
763 v = this%q_mult(jj) + this%rhs(jj)
766 errmsg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
769 call this%obs%SaveOneSimval(obsrv, v)
772 call this%obs%SaveOneSimval(obsrv,
dnodata)
777 if (this%ioutafrcsv > 0)
then
778 call this%wel_afr_csv_write()
786 class(
weltype),
intent(inout) :: this
787 integer(I4B),
intent(in) :: row
791 if (this%iauxmultcol > 0)
then
792 q = this%q(row) * this%auxvar(this%iauxmultcol, row)
808 class(
weltype),
intent(inout) :: this
809 integer(I4B),
intent(in) :: col
810 integer(I4B),
intent(in) :: row
816 bndval = this%q_mult(row)
818 errmsg =
'Programming error. WEL bound value requested column '&
819 &
'outside range of ncolbnd (1).'
821 call store_error_filename(this%input_fname)
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.
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
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
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 reduction_factor(this, i, node, f, dfdh)
Factor by which a withdrawal is reduced, and its derivative.
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.
Interface for supplying a flow-reduction factor.