37 character(len=LENFTYPE) ::
ftype =
'WEL'
38 character(len=16) ::
text =
' WEL'
41 real(dp),
dimension(:),
pointer,
contiguous :: q => null()
42 integer(I4B),
pointer :: iflowred => null()
43 real(dp),
pointer :: flowred => null()
44 integer(I4B),
pointer :: ioutafrcsv => null()
45 integer(I4B),
pointer :: iflowredlen => null()
46 integer(I4B),
pointer :: iafrauxcol => null()
76 subroutine wel_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
79 class(
bndtype),
pointer :: packobj
80 integer(I4B),
intent(in) :: id
81 integer(I4B),
intent(in) :: ibcnum
82 integer(I4B),
intent(in) :: inunit
83 integer(I4B),
intent(in) :: iout
84 character(len=*),
intent(in) :: namemodel
85 character(len=*),
intent(in) :: pakname
86 character(len=*),
intent(in) :: mempath
88 type(
weltype),
pointer :: welobj
95 call packobj%set_names(ibcnum, namemodel, pakname,
ftype, mempath)
99 call welobj%allocate_scalars()
102 call packobj%pack_initialize()
104 packobj%inunit = inunit
107 packobj%ibcnum = ibcnum
124 call this%BndExtType%bnd_da()
148 call this%BndExtType%allocate_scalars()
151 call mem_allocate(this%iflowred,
'IFLOWRED', this%memoryPath)
152 call mem_allocate(this%flowred,
'FLOWRED', this%memoryPath)
153 call mem_allocate(this%ioutafrcsv,
'IOUTAFRCSV', this%memoryPath)
154 call mem_allocate(this%iflowredlen,
'IFLOWREDLEN', this%memoryPath)
155 call mem_allocate(this%iafrauxcol,
'IAFRAUXCOL', this%memoryPath)
175 integer(I4B),
dimension(:),
pointer,
contiguous,
optional :: nodelist
176 real(DP),
dimension(:, :),
pointer,
contiguous,
optional :: auxvar
180 call this%BndExtType%allocate_arrays(nodelist, auxvar)
183 call mem_setptr(this%q,
'Q', this%input_mempath)
187 'Q', this%input_mempath)
201 class(
weltype),
intent(inout) :: this
203 character(len=LINELENGTH) :: fname
204 character(len=LENAUXNAME) :: afrauxname
208 character(len=*),
parameter :: fmtflowred = &
209 &
"(4x, 'AUTOMATIC FLOW REDUCTION OF WELLS IMPLEMENTED.')"
210 character(len=*),
parameter :: fmtflowredv = &
211 &
"(4x, 'AUTOMATIC FLOW REDUCTION FRACTION (',g15.7,').')"
214 call this%BndExtType%source_options()
217 call mem_set_value(this%flowred,
'FLOWRED', this%input_mempath, found%flowred)
218 call mem_set_value(fname,
'AFRCSVFILE', this%input_mempath, found%afrcsvfile)
219 call mem_set_value(this%imover,
'MOVER', this%input_mempath, found%mover)
220 call mem_set_value(this%iflowredlen,
'IFLOWREDLEN', this%input_mempath, &
222 call mem_set_value(afrauxname,
'AFRAUXNAME', this%input_mempath, &
225 if (found%iflowredlen)
then
226 if (found%flowred .eqv. .false.)
then
228 'FLOW_REDUCTION_LENGTH option specified but a AUTO_FLOW_REDUCTION value &
229 &is not specified. The FLOW_REDUCTION_LENGTH option will be ignored.'
236 if (found%flowred)
then
238 if (this%flowred <=
dzero)
then
239 if (found%iflowredlen)
then
241 'An AUTO_FLOW_REDUCTION value less than or equal to zero cannot be &
242 &specified if the FLOW_REDUCTION_LENGTH option is specified.'
247 else if (this%flowred >
done .and. this%iflowredlen == 0)
then
252 if (found%afrcsvfile)
then
253 call this%wel_afr_csv_init(fname)
256 if (found%mover)
then
260 if (found%afrauxname)
then
261 if (.not. found%flowred)
then
263 'AUTO_FLOW_REDUCE_AUXNAME is specified but AUTO_FLOW_REDUCE is not &
264 &specified. The AUTO_FLOW_REDUCE_AUXNAME option will be ignored.'
267 if (.not. found%iflowredlen)
then
269 'AUTO_FLOW_REDUCE_AUXNAME is specified but FLOW_REDUCTION_LENGTH is &
270 ¬ specified. The AUTO_FLOW_REDUCE_AUXNAME value will be &
271 &interpreted as a fraction of the cell thickness.'
274 if (found%flowred)
then
275 if (this%naux == 0)
then
276 write (
errmsg,
'(a,2(1x,a))') &
277 'AUTO_FLOW_REDUCE_AUXNAME was specified as', &
278 trim(adjustl(afrauxname)),
'but no AUX variables specified.'
283 if (afrauxname == this%auxname(n))
then
288 if (this%iafrauxcol == 0)
then
289 write (
errmsg,
'(a,2(1x,a))') &
290 'AUTO_FLOW_REDUCE_AUXNAME was specified as', &
291 trim(adjustl(afrauxname)), &
292 'but no AUX variable found with this name.'
299 call this%log_wel_options(found)
308 class(
weltype),
intent(inout) :: this
312 character(len=*),
parameter :: fmtflowred = &
313 &
"(4x, 'AUTOMATIC FLOW REDUCTION OF WELLS IMPLEMENTED.')"
314 character(len=*),
parameter :: fmtflowredv = &
315 &
"(4x, 'AUTOMATIC FLOW REDUCTION FRACTION (',g15.7,').')"
316 character(len=*),
parameter :: fmtflowredl = &
317 &
"(4x, 'AUTOMATIC FLOW REDUCTION LENGTH (',g15.7,').')"
320 write (this%iout,
'(/1x,a)')
'PROCESSING '//trim(adjustl(this%text)) &
323 if (found%iflowredlen)
then
324 write (this%iout, fmtflowred)
325 write (this%iout,
'(4x,A)') &
326 'AUTOMATIC FLOW REDUCTION FRACTION INTERPRETED AS A LENGTH'
329 if (found%flowred)
then
330 if (this%iflowredlen == 0)
then
331 write (this%iout, fmtflowredv) this%flowred
333 write (this%iout, fmtflowredl) this%flowred
337 if (found%afrcsvfile)
then
341 if (found%mover)
then
342 write (this%iout,
'(4x,A)')
'MOVER OPTION ENABLED'
345 if (found%afrauxname)
then
346 write (this%iout,
'(4x,A)') &
347 'AUTO_FLOW_REDUCE_AUXNAME OPTION ENABLED FOR PER-WELL FLOW REDUCTION'
351 write (this%iout,
'(1x,a)') &
352 'END OF '//trim(adjustl(this%text))//
' OPTIONS'
370 class(
weltype),
intent(inout) :: this
372 character(len=LINELENGTH) :: errmsg
378 character(len=*),
parameter :: fmtfracerr = &
379 "('WELL (',i0,') AUTO_FLOW_REDUCE_AUXNAME value (',g0,') must be greater &
380 &than 0 and less than or equal to 1 when FLOW_REDUCTION_LENGTH is not &
381 &specified (it is interpreted as a fraction of the cell thickness).')"
382 character(len=*),
parameter :: fmtlenerr = &
383 "('WELL (',i0,') AUTO_FLOW_REDUCE_AUXNAME value (',g0,') must be greater &
384 &than 0 and less than or equal to the cell thickness (',g0,') when &
385 &FLOW_REDUCTION_LENGTH is specified.')"
388 if (this%iflowred == 0 .or. this%iafrauxcol == 0)
return
395 do i = 1, this%nbound
396 node = this%nodelist(i)
399 if (this%icelltype(node) == 0) cycle
400 afraux = this%auxvar(this%iafrauxcol, i)
401 if (this%iflowredlen == 0)
then
403 if (afraux <=
dzero .or. afraux >
done)
then
404 write (errmsg, fmt=fmtfracerr) i, afraux
405 call store_error(errmsg)
409 thick = this%dis%top(node) - this%dis%bot(node)
410 if (afraux <=
dzero .or. afraux > thick)
then
411 write (errmsg, fmt=fmtlenerr) i, afraux, thick
412 call store_error(errmsg)
433 integer(I4B) :: i, node, ict
441 if (this%nbound == 0)
return
444 do i = 1, this%nbound
445 node = this%nodelist(i)
447 if (this%ibound(node) <= 0)
then
452 if (this%iflowred /= 0 .and. q <
dzero)
then
453 ict = this%icelltype(node)
455 bt = this%dis%bot(node)
456 if (this%iflowredlen == 0)
then
457 thick = this%dis%top(node) - bt
461 if (this%iafrauxcol > 0)
then
462 tp = bt + this%auxvar(this%iafrauxcol, i) * thick
464 tp = bt + this%flowred * thick
480 subroutine wel_fc(this, rhs, ia, idxglo, matrix_sln)
483 real(DP),
dimension(:),
intent(inout) :: rhs
484 integer(I4B),
dimension(:),
intent(in) :: ia
485 integer(I4B),
dimension(:),
intent(in) :: idxglo
493 if (this%imover == 1)
then
494 call this%pakmvrobj%fc()
498 do i = 1, this%nbound
500 rhs(n) = rhs(n) + this%rhs(i)
502 call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
506 if (this%imover == 1 .and. this%rhs(i) >
dzero)
then
507 call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i))
518 subroutine wel_fn(this, rhs, ia, idxglo, matrix_sln)
521 real(DP),
dimension(:),
intent(inout) :: rhs
522 integer(I4B),
dimension(:),
intent(in) :: ia
523 integer(I4B),
dimension(:),
intent(in) :: idxglo
537 do i = 1, this%nbound
538 node = this%nodelist(i)
541 if (this%ibound(node) <= 0)
then
546 ict = this%icelltype(node)
547 if (this%iflowred /= 0 .and. ict /= 0)
then
552 tp = this%dis%top(node)
553 bt = this%dis%bot(node)
554 if (this%iflowredlen == 0)
then
559 if (this%iafrauxcol > 0)
then
560 tp = bt + this%auxvar(this%iafrauxcol, i) * thick
562 tp = bt + this%flowred * thick
565 drterm = drterm * this%q_mult(i)
567 call matrix_sln%add_value_pos(idxglo(ipos), drterm)
568 rhs(node) = rhs(node) + drterm * this%xnew(node)
577 class(
weltype),
intent(inout) :: this
578 character(len=*),
intent(in) :: fname
580 character(len=*),
parameter :: fmtafrcsv = &
581 "(4x, 'AUTO FLOW REDUCE INFORMATION WILL BE SAVED TO FILE: ', a, /4x, &
582 &'OPENED ON UNIT: ', I0)"
585 call openfile(this%ioutafrcsv, this%iout, fname,
'CSV', &
586 filstat_opt=
'REPLACE')
587 write (this%iout, fmtafrcsv) trim(adjustl(fname)), &
589 write (this%ioutafrcsv,
'(a)') &
590 'time,period,step,boundnumber,cellnumber,rate-requested,&
591 &rate-actual,wel-reduction'
599 class(
weltype),
intent(inout) :: this
602 integer(I4B) :: nodereduced
603 integer(I4B) :: nodeuser
606 do i = 1, this%nbound
607 nodereduced = this%nodelist(i)
610 if (this%ibound(nodereduced) <= 0)
then
613 v = this%q_mult(i) + this%rhs(i)
615 nodeuser = this%dis%get_nodeuser(nodereduced)
616 write (this%ioutafrcsv,
'(*(G0,:,","))') &
617 totim,
kper,
kstp, i, nodeuser, this%q_mult(i), this%simvals(i), v
630 class(
weltype),
intent(inout) :: this
633 this%listlabel = trim(this%filtyp)//
' NO.'
634 if (this%dis%ndim == 3)
then
635 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
636 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'ROW'
637 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'COL'
638 elseif (this%dis%ndim == 2)
then
639 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'LAYER'
640 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'CELL2D'
642 write (this%listlabel,
'(a, a7)') trim(this%listlabel),
'NODE'
644 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'STRESS RATE'
645 if (this%inamedbound == 1)
then
646 write (this%listlabel,
'(a, a16)') trim(this%listlabel),
'BOUNDARY NAME'
680 call this%obs%StoreObsType(
'wel', .true., indx)
685 call this%obs%StoreObsType(
'to-mvr', .true., indx)
690 call this%obs%StoreObsType(
'wel-reduction', .true., indx)
710 call this%obs%obs_bd_clear()
713 do i = 1, this%obs%npakobs
714 obsrv => this%obs%pakobs(i)%obsrv
715 if (obsrv%BndFound)
then
716 do n = 1, obsrv%indxbnds_count
718 jj = obsrv%indxbnds(n)
719 select case (obsrv%ObsTypeId)
721 if (this%imover == 1)
then
722 v = this%pakmvrobj%get_qtomvr(jj)
729 case (
'WEL-REDUCTION')
730 if (this%iflowred > 0)
then
731 v = this%q_mult(jj) + this%rhs(jj)
734 errmsg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
737 call this%obs%SaveOneSimval(obsrv, v)
740 call this%obs%SaveOneSimval(obsrv,
dnodata)
745 if (this%ioutafrcsv > 0)
then
746 call this%wel_afr_csv_write()
754 class(
weltype),
intent(inout) :: this
755 integer(I4B),
intent(in) :: row
759 if (this%iauxmultcol > 0)
then
760 q = this%q(row) * this%auxvar(this%iauxmultcol, row)
776 class(
weltype),
intent(inout) :: this
777 integer(I4B),
intent(in) :: col
778 integer(I4B),
intent(in) :: row
784 bndval = this%q_mult(row)
786 errmsg =
'Programming error. WEL bound value requested column '&
787 &
'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.