22 character(len=LENPACKAGENAME) ::
text =
' GWTFMI'
25 character(len=LENBUDTXT),
dimension(NBDITEMS) ::
budtxt
26 data budtxt/
' FLOW-ERROR',
' FLOW-CORRECTION'/
29 real(dp),
dimension(:),
contiguous,
pointer :: concpack => null()
30 real(dp),
dimension(:),
contiguous,
pointer :: qmfrommvr => null()
39 integer(I4B),
dimension(:),
pointer,
contiguous :: iatp => null()
40 integer(I4B),
pointer :: iflowerr => null()
41 real(dp),
dimension(:),
pointer,
contiguous :: flowcorrect => null()
42 real(dp),
pointer :: eqnsclfac => null()
44 dimension(:),
pointer,
contiguous :: datp => null()
73 subroutine fmi_cr(fmiobj, name_model, input_mempath, inunit, iout, eqnsclfac, &
77 character(len=*),
intent(in) :: name_model
78 character(len=*),
intent(in) :: input_mempath
79 integer(I4B),
intent(in) :: inunit
80 integer(I4B),
intent(in) :: iout
81 real(dp),
intent(in),
pointer :: eqnsclfac
82 character(len=LENVARNAME),
intent(in) :: depvartype
88 call fmiobj%set_names(1, name_model,
'FMI',
'FMI', input_mempath)
92 call fmiobj%allocate_scalars()
95 fmiobj%inunit = inunit
99 fmiobj%depvartype = depvartype
102 fmiobj%eqnsclfac => eqnsclfac
112 integer(I4B),
intent(in) :: inmvr
120 if (
associated(this%mvrbudobj) .and. inmvr == 0)
then
121 write (
errmsg,
'(a)')
'GWF water mover is active but the GWT MVT &
122 &package has not been specified. activate GWT MVT package.'
125 if (.not.
associated(this%mvrbudobj) .and. inmvr > 0)
then
126 write (
errmsg,
'(a)')
'GWF water mover terms are not available &
127 &but the GWT MVT package has been activated. Activate GWF-GWT &
128 &exchange or specify GWFMOVER in FMI PACKAGEDATA.'
141 real(DP),
intent(inout),
dimension(:) :: cnew
144 character(len=*),
parameter :: fmtdry = &
145 &
"(/1X,'WARNING: DRY CELL ENCOUNTERED AT ',a,'; RESET AS INACTIVE &
146 &WITH DRY CONCENTRATION = ', G13.5)"
147 character(len=*),
parameter :: fmtrewet = &
148 &
"(/1X,'DRY CELL REACTIVATED AT ', a,&
149 &' WITH STARTING CONCENTRATION =',G13.5)"
154 this%iflowsupdated = 1
157 if (this%iubud /= 0)
then
158 call this%advance_bfr()
162 if (this%iuhds /= 0)
then
163 call this%advance_hfr()
167 if (this%iumvr /= 0)
then
168 call this%mvrbudobj%bfr_advance(this%dis, this%iout)
172 if (this%flows_from_file .and. this%inunit /= 0)
then
173 do n = 1,
size(this%aptbudobj)
174 call this%aptbudobj(n)%ptr%bfr_advance(this%dis, this%iout)
179 if (this%idryinactive /= 0)
then
180 call this%set_active_status(cnew)
187 subroutine fmi_fc(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
190 integer,
intent(in) :: nodes
191 real(DP),
intent(in),
dimension(nodes) :: cold
192 integer(I4B),
intent(in) :: nja
194 integer(I4B),
intent(in),
dimension(nja) :: idxglo
195 real(DP),
intent(inout),
dimension(nodes) :: rhs
197 integer(I4B) :: n, idiag, idiag_sln
201 if (this%iflowerr /= 0)
then
206 idiag = this%dis%con%ia(n)
207 idiag_sln = idxglo(idiag)
209 qcorr = -this%gwfflowja(idiag) * this%eqnsclfac
210 call matrix_sln%add_value_pos(idiag_sln, qcorr)
224 real(DP),
intent(in),
dimension(:) :: cnew
225 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
228 integer(I4B) :: idiag
232 if (this%iflowerr /= 0)
then
235 do n = 1, this%dis%nodes
237 idiag = this%dis%con%ia(n)
238 if (this%ibound(n) > 0)
then
239 rate = -this%gwfflowja(idiag) * cnew(n) * this%eqnsclfac
241 this%flowcorrect(n) = rate
242 flowja(idiag) = flowja(idiag) + rate
249 subroutine fmi_bd(this, isuppress_output, model_budget)
255 integer(I4B),
intent(in) :: isuppress_output
256 type(
budgettype),
intent(inout) :: model_budget
262 if (this%iflowerr /= 0)
then
264 call model_budget%addentry(rin, rout,
delt,
budtxt(2), isuppress_output)
273 integer(I4B),
intent(in) :: icbcfl
274 integer(I4B),
intent(in) :: icbcun
276 integer(I4B) :: ibinun
277 integer(I4B) :: iprint, nvaluesp, nwidthp
278 character(len=1) :: cdatafmp =
' ', editdesc =
' '
282 if (this%ipakcb < 0)
then
284 elseif (this%ipakcb == 0)
then
289 if (icbcfl == 0) ibinun = 0
292 if (this%iflowerr == 0) ibinun = 0
295 if (ibinun /= 0)
then
300 call this%dis%record_array(this%flowcorrect, this%iout, iprint, -ibinun, &
301 budtxt(2), cdatafmp, nvaluesp, &
302 nwidthp, editdesc, dinact)
317 if (
associated(this%datp))
then
318 deallocate (this%datp)
321 deallocate (this%aptbudobj)
328 call this%FlowModelInterfaceType%fmi_da()
343 call this%FlowModelInterfaceType%allocate_scalars()
346 call mem_allocate(this%iflowerr,
'IFLOWERR', this%memoryPath)
350 allocate (this%aptbudobj(0))
366 integer(I4B),
intent(in) :: nodes
371 call this%FlowModelInterfaceType%allocate_arrays(nodes)
374 if (this%iflowerr == 0)
then
375 call mem_allocate(this%flowcorrect, 1,
'FLOWCORRECT', this%memoryPath)
377 call mem_allocate(this%flowcorrect, nodes,
'FLOWCORRECT', this%memoryPath)
379 do n = 1,
size(this%flowcorrect)
380 this%flowcorrect(n) =
dzero
395 real(DP),
intent(inout),
dimension(:) :: cnew
400 real(DP) :: crewet, tflow, flownm
401 character(len=15) :: nodestr
403 character(len=*),
parameter :: fmtoutmsg1 = &
404 "(1x,'WARNING: DRY CELL ENCOUNTERED AT ', a,'; RESET AS INACTIVE WITH &
405 &DRY ', a, '=', G13.5)"
406 character(len=*),
parameter :: fmtoutmsg2 = &
407 &
"(1x,'DRY CELL REACTIVATED AT', a, 'WITH STARTING', a, '=', G13.5)"
409 do n = 1, this%dis%nodes
412 if (this%gwfsat(n) > dzero)
then
413 this%ibdgwfsat0(n) = 1
415 this%ibdgwfsat0(n) = 0
419 if (this%ibound(n) > 0)
then
420 if (this%gwfhead(n) ==
dhdry)
then
424 call this%dis%noder_to_string(n, nodestr)
425 write (this%iout, fmtoutmsg1) &
426 trim(nodestr), trim(adjustl(this%depvartype)),
dhdry
432 do n = 1, this%dis%nodes
435 if (cnew(n) ==
dhdry)
then
436 if (this%gwfhead(n) /=
dhdry)
then
441 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
442 m = this%dis%con%ja(ipos)
443 flownm = this%gwfflowja(ipos)
445 if (this%ibound(m) /= 0)
then
446 crewet = crewet + cnew(m) * flownm
447 tflow = tflow + this%gwfflowja(ipos)
451 if (tflow > dzero)
then
452 crewet = crewet / tflow
460 call this%dis%noder_to_string(n, nodestr)
461 write (this%iout, fmtoutmsg2) &
462 trim(nodestr), trim(adjustl(this%depvartype)), crewet
477 integer(I4B),
intent(in) :: n
478 real(dp),
intent(in) :: delt
487 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
488 vnew = vcell * this%gwfsat(n)
490 if (this%igwfstrgss /= 0) vold = vold + this%gwfstrgss(n) * delt
491 if (this%igwfstrgsy /= 0) vold = vold + this%gwfstrgsy(n) * delt
492 satold = vold / vcell
503 logical(LGP) :: found_ipakcb, found_flowerr
504 character(len=*),
parameter :: fmtisvflow = &
505 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
506 &WHENEVER ICBCFL IS NOT ZERO AND FLOW IMBALANCE CORRECTION ACTIVE.')"
507 character(len=*),
parameter :: fmtifc = &
508 &
"(4x,'MASS WILL BE ADDED OR REMOVED TO COMPENSATE FOR FLOW IMBALANCE.')"
510 write (this%iout,
'(1x,a)')
'PROCESSING FMI OPTIONS'
512 call mem_set_value(this%ipakcb,
'SAVE_FLOWS', this%input_mempath, &
514 call mem_set_value(this%iflowerr,
'IMBALANCECORRECT', this%input_mempath, &
517 if (found_ipakcb)
then
519 write (this%iout, fmtisvflow)
521 if (found_flowerr)
write (this%iout, fmtifc)
523 write (this%iout,
'(1x,a)')
'END OF FMI OPTIONS'
538 character(len=*),
intent(in) :: flowtype
539 character(len=*),
intent(in) :: fname
543 integer(I4B) :: iapt, inunit, i
546 iapt =
size(this%aptbudobj)
547 allocate (tmpbudobj(iapt))
549 tmpbudobj(i)%ptr => this%aptbudobj(i)%ptr
551 deallocate (this%aptbudobj)
552 allocate (this%aptbudobj(iapt + 1))
554 this%aptbudobj(i)%ptr => tmpbudobj(i)%ptr
556 deallocate (tmpbudobj)
561 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
564 this%iout, colconv2=[
'GWF '])
565 call budobjptr%fill_from_bfr(this%dis, this%iout)
566 this%aptbudobj(iapt)%ptr => budobjptr
580 character(len=*),
intent(in) :: name
586 do i = 1,
size(this%aptbudobj)
587 if (this%aptbudobj(i)%ptr%name == name)
then
588 budobjptr => this%aptbudobj(i)%ptr
606 integer(I4B) :: nflowpack
607 integer(I4B) :: i, ip
609 logical :: found_flowja
610 logical :: found_dataspdis
611 logical :: found_datasat
612 logical :: found_stoss
613 logical :: found_stosy
614 integer(I4B),
dimension(:),
allocatable :: imap
617 allocate (imap(this%bfr%nbudterms))
620 found_flowja = .false.
621 found_dataspdis = .false.
622 found_datasat = .false.
623 found_stoss = .false.
624 found_stosy = .false.
625 do i = 1, this%bfr%nbudterms
626 select case (trim(adjustl(this%bfr%budtxtarray(i))))
627 case (
'FLOW-JA-FACE')
628 found_flowja = .true.
630 found_dataspdis = .true.
632 found_datasat = .true.
640 nflowpack = nflowpack + 1
646 call this%allocate_gwfpackages(nflowpack)
651 do i = 1, this%bfr%nbudterms
652 if (imap(i) == 0) cycle
653 call this%gwfpackages(ip)%set_name(this%bfr%dstpackagenamearray(i), &
654 this%bfr%budtxtarray(i))
655 naux = this%bfr%nauxarray(i)
656 call this%gwfpackages(ip)%set_auxname(naux, &
657 this%bfr%auxtxtarray(1:naux, i))
665 if (imap(i) == 1)
then
666 this%flowpacknamearray(ip) = this%bfr%dstpackagenamearray(i)
672 if (.not. found_dataspdis)
then
673 write (
errmsg,
'(a)')
'Specific discharge not found in &
674 &budget file. SAVE_SPECIFIC_DISCHARGE and &
675 &SAVE_FLOWS must be activated in the NPF package.'
678 if (.not. found_datasat)
then
679 write (
errmsg,
'(a)')
'Saturation not found in &
680 &budget file. SAVE_SATURATION and &
681 &SAVE_FLOWS must be activated in the NPF package.'
684 if (.not. found_flowja)
then
685 write (
errmsg,
'(a)')
'FLOWJA not found in &
686 &budget file. SAVE_FLOWS must &
687 &be activated in the NPF package.'
705 integer(I4B) :: ngwfpack
706 integer(I4B) :: ngwfterms
708 integer(I4B) :: imover
709 integer(I4B) :: ntomvr
710 integer(I4B) :: iterm
711 character(len=LENPACKAGENAME) :: budtxt
712 class(
bndtype),
pointer :: packobj => null()
715 ngwfpack = this%gwfbndlist%Count()
723 imover = packobj%imover
724 if (packobj%isadvpak /= 0) imover = 0
725 if (imover /= 0)
then
732 ngwfterms = ngwfpack + ntomvr
733 call this%allocate_gwfpackages(ngwfterms)
741 budtxt = adjustl(packobj%text)
742 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
743 this%flowpacknamearray(iterm) = packobj%packName
744 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
750 imover = packobj%imover
751 if (packobj%isadvpak /= 0) imover = 0
752 if (imover /= 0)
then
753 budtxt = trim(adjustl(packobj%text))//
'-TO-MVR'
754 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
755 this%flowpacknamearray(iterm) = packobj%packName
756 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
758 this%igwfmvrterm(iterm) = 1
775 integer(I4B),
intent(in) :: ngwfterms
778 character(len=LENMEMPATH) :: memPath
781 allocate (this%gwfpackages(ngwfterms))
782 allocate (this%flowpacknamearray(ngwfterms))
783 allocate (this%datp(ngwfterms))
786 call mem_allocate(this%iatp, ngwfterms,
'IATP', this%memoryPath)
787 call mem_allocate(this%igwfmvrterm, ngwfterms,
'IGWFMVRTERM', this%memoryPath)
790 this%nflowpack = ngwfterms
791 do n = 1, this%nflowpack
793 this%igwfmvrterm(n) = 0
794 this%flowpacknamearray(n) =
''
798 write (mempath,
'(a, i0)') trim(this%memoryPath)//
'-FT', n
799 call this%gwfpackages(n)%initialize(mempath)
This module contains the base boundary package.
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
This module contains the BudgetModule.
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
subroutine, public budgetobject_cr_bfr(this, name, ibinun, iout, colconv1, colconv2)
Create a new budget object from a binary flow file.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
real(dp), parameter dhdry
real dry cell constant
integer(i4b), parameter lenpackagename
maximum length of the package name
integer(i4b), parameter lenvarname
maximum length of a variable name
real(dp), parameter dhalf
real constant 1/2
real(dp), parameter dzero
real constant zero
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
integer(i4b), parameter lenmempath
maximum length of the memory path
real(dp), parameter done
real constant 1
This module defines variable data types.
This module contains the PackageBudgetModule Module.
This module contains simulation methods.
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.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public kper
current stress period number
real(dp), pointer, public delt
length of the current time step
real(dp) function gwfsatold(this, n, delt)
Calculate the previous saturation level.
integer(i4b), parameter nbditems
subroutine fmi_bd(this, isuppress_output, model_budget)
Calculate budget terms associated with FMI object.
character(len=lenbudtxt), dimension(nbditems) budtxt
subroutine gwtfmi_allocate_scalars(this)
@ brief Allocate scalars
subroutine gwtfmi_allocate_arrays(this, nodes)
@ brief Allocate arrays for FMI object
subroutine, public fmi_cr(fmiobj, name_model, input_mempath, inunit, iout, eqnsclfac, depvartype)
Create a new FMI object.
subroutine gwtfmi_source_options(this)
@ brief Source input options for package
subroutine initialize_gwfterms_from_gwfbndlist(this)
Initialize groundwater flow terms from the groundwater budget.
subroutine gwtfmi_allocate_gwfpackages(this, ngwfterms)
Initialize an array for storing PackageBudget objects.
subroutine fmi_fc(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
Calculate coefficients and fill matrix and rhs terms associated with FMI object.
subroutine initialize_gwfterms_from_bfr(this)
Initialize the groundwater flow terms based on the budget file reader.
subroutine fmi_rp(this, inmvr)
Read and prepare.
subroutine set_aptbudobj_pointer(this, name, budobjptr)
Set the pointer to a budget object.
subroutine set_active_status(this, cnew)
Set gwt transport cell status.
subroutine fmi_ot_flow(this, icbcfl, icbcun)
Save budget terms associated with FMI object.
character(len=lenpackagename) text
subroutine fmi_ad(this, cnew)
Advance routine for FMI object.
subroutine fmi_cq(this, cnew, flowja)
Calculate flow correction.
subroutine gwtfmi_da(this)
Deallocate variables.
subroutine gwtfmi_source_packagedata_other(this, flowtype, fname)
Source a packagedata entry with a model-specific flow type.
Derived type for the Budget object.
A generic heterogeneous doubly-linked list.
Derived type for storing flows.