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()
74 subroutine fmi_cr(fmiobj, name_model, input_mempath, inunit, iout, eqnsclfac, &
78 character(len=*),
intent(in) :: name_model
79 character(len=*),
intent(in) :: input_mempath
80 integer(I4B),
intent(in) :: inunit
81 integer(I4B),
intent(in) :: iout
82 real(dp),
intent(in),
pointer :: eqnsclfac
83 character(len=LENVARNAME),
intent(in) :: depvartype
89 call fmiobj%set_names(1, name_model,
'FMI',
'FMI', input_mempath)
93 call fmiobj%allocate_scalars()
96 fmiobj%inunit = inunit
100 fmiobj%depvartype = depvartype
103 fmiobj%eqnsclfac => eqnsclfac
113 integer(I4B),
intent(in) :: inmvr
121 if (
associated(this%mvrbudobj) .and. inmvr == 0)
then
122 write (
errmsg,
'(a)')
'GWF water mover is active but the GWT MVT &
123 &package has not been specified. activate GWT MVT package.'
126 if (.not.
associated(this%mvrbudobj) .and. inmvr > 0)
then
127 write (
errmsg,
'(a)')
'GWF water mover terms are not available &
128 &but the GWT MVT package has been activated. Activate GWF-GWT &
129 &exchange or specify GWFMOVER in FMI PACKAGEDATA.'
142 real(DP),
intent(inout),
dimension(:) :: cnew
145 character(len=*),
parameter :: fmtdry = &
146 &
"(/1X,'WARNING: DRY CELL ENCOUNTERED AT ',a,'; RESET AS INACTIVE &
147 &WITH DRY CONCENTRATION = ', G13.5)"
148 character(len=*),
parameter :: fmtrewet = &
149 &
"(/1X,'DRY CELL REACTIVATED AT ', a,&
150 &' WITH STARTING CONCENTRATION =',G13.5)"
155 this%iflowsupdated = 1
158 if (this%iubud /= 0)
then
159 call this%advance_bfr()
163 if (this%iuhds /= 0)
then
164 call this%advance_hfr()
168 if (this%iumvr /= 0)
then
169 call this%mvrbudobj%bfr_advance(this%dis, this%iout)
173 if (this%flows_from_file .and. this%inunit /= 0)
then
174 do n = 1,
size(this%aptbudobj)
175 call this%aptbudobj(n)%ptr%bfr_advance(this%dis, this%iout)
180 if (this%idryinactive /= 0)
then
181 call this%set_active_status(cnew)
188 subroutine fmi_fc(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
191 integer,
intent(in) :: nodes
192 real(DP),
intent(in),
dimension(nodes) :: cold
193 integer(I4B),
intent(in) :: nja
195 integer(I4B),
intent(in),
dimension(nja) :: idxglo
196 real(DP),
intent(inout),
dimension(nodes) :: rhs
198 integer(I4B) :: n, idiag, idiag_sln
202 if (this%iflowerr /= 0)
then
207 idiag = this%dis%con%ia(n)
208 idiag_sln = idxglo(idiag)
210 qcorr = -this%gwfflowja(idiag) * this%eqnsclfac
211 call matrix_sln%add_value_pos(idiag_sln, qcorr)
225 real(DP),
intent(in),
dimension(:) :: cnew
226 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
229 integer(I4B) :: idiag
233 if (this%iflowerr /= 0)
then
236 do n = 1, this%dis%nodes
238 idiag = this%dis%con%ia(n)
239 if (this%ibound(n) > 0)
then
240 rate = -this%gwfflowja(idiag) * cnew(n) * this%eqnsclfac
242 this%flowcorrect(n) = rate
243 flowja(idiag) = flowja(idiag) + rate
250 subroutine fmi_bd(this, isuppress_output, model_budget)
256 integer(I4B),
intent(in) :: isuppress_output
257 type(
budgettype),
intent(inout) :: model_budget
263 if (this%iflowerr /= 0)
then
265 call model_budget%addentry(rin, rout,
delt,
budtxt(2), isuppress_output)
274 integer(I4B),
intent(in) :: icbcfl
275 integer(I4B),
intent(in) :: icbcun
277 integer(I4B) :: ibinun
278 integer(I4B) :: iprint, nvaluesp, nwidthp
279 character(len=1) :: cdatafmp =
' ', editdesc =
' '
283 if (this%ipakcb < 0)
then
285 elseif (this%ipakcb == 0)
then
290 if (icbcfl == 0) ibinun = 0
293 if (this%iflowerr == 0) ibinun = 0
296 if (ibinun /= 0)
then
301 call this%dis%record_array(this%flowcorrect, this%iout, iprint, -ibinun, &
302 budtxt(2), cdatafmp, nvaluesp, &
303 nwidthp, editdesc, dinact)
319 call this%deallocate_gwfpackages()
322 if (
associated(this%datp))
then
323 deallocate (this%datp)
324 deallocate (this%gwfpackages)
325 deallocate (this%flowpacknamearray)
330 deallocate (this%aptbudobj)
333 if (this%flows_from_file)
then
358 call this%NumericalPackageType%da()
373 call this%FlowModelInterfaceType%allocate_scalars()
376 call mem_allocate(this%iflowerr,
'IFLOWERR', this%memoryPath)
380 allocate (this%aptbudobj(0))
396 integer(I4B),
intent(in) :: nodes
401 call this%FlowModelInterfaceType%allocate_arrays(nodes)
404 if (this%iflowerr == 0)
then
405 call mem_allocate(this%flowcorrect, 1,
'FLOWCORRECT', this%memoryPath)
407 call mem_allocate(this%flowcorrect, nodes,
'FLOWCORRECT', this%memoryPath)
409 do n = 1,
size(this%flowcorrect)
410 this%flowcorrect(n) =
dzero
425 real(DP),
intent(inout),
dimension(:) :: cnew
430 real(DP) :: crewet, tflow, flownm
431 character(len=15) :: nodestr
433 character(len=*),
parameter :: fmtoutmsg1 = &
434 "(1x,'WARNING: DRY CELL ENCOUNTERED AT ', a,'; RESET AS INACTIVE WITH &
435 &DRY ', a, '=', G13.5)"
436 character(len=*),
parameter :: fmtoutmsg2 = &
437 &
"(1x,'DRY CELL REACTIVATED AT', a, 'WITH STARTING', a, '=', G13.5)"
439 do n = 1, this%dis%nodes
442 if (this%gwfsat(n) > dzero)
then
443 this%ibdgwfsat0(n) = 1
445 this%ibdgwfsat0(n) = 0
449 if (this%ibound(n) > 0)
then
450 if (this%gwfhead(n) ==
dhdry)
then
454 call this%dis%noder_to_string(n, nodestr)
455 write (this%iout, fmtoutmsg1) &
456 trim(nodestr), trim(adjustl(this%depvartype)),
dhdry
462 do n = 1, this%dis%nodes
465 if (cnew(n) ==
dhdry)
then
466 if (this%gwfhead(n) /=
dhdry)
then
471 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
472 m = this%dis%con%ja(ipos)
473 flownm = this%gwfflowja(ipos)
475 if (this%ibound(m) /= 0)
then
476 crewet = crewet + cnew(m) * flownm
477 tflow = tflow + this%gwfflowja(ipos)
481 if (tflow > dzero)
then
482 crewet = crewet / tflow
490 call this%dis%noder_to_string(n, nodestr)
491 write (this%iout, fmtoutmsg2) &
492 trim(nodestr), trim(adjustl(this%depvartype)), crewet
507 integer(I4B),
intent(in) :: n
508 real(dp),
intent(in) :: delt
517 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
518 vnew = vcell * this%gwfsat(n)
520 if (this%igwfstrgss /= 0) vold = vold + this%gwfstrgss(n) * delt
521 if (this%igwfstrgsy /= 0) vold = vold + this%gwfstrgsy(n) * delt
522 satold = vold / vcell
533 logical(LGP) :: found_ipakcb, found_flowerr
534 character(len=*),
parameter :: fmtisvflow = &
535 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
536 &WHENEVER ICBCFL IS NOT ZERO AND FLOW IMBALANCE CORRECTION ACTIVE.')"
537 character(len=*),
parameter :: fmtifc = &
538 &
"(4x,'MASS WILL BE ADDED OR REMOVED TO COMPENSATE FOR FLOW IMBALANCE.')"
540 write (this%iout,
'(1x,a)')
'PROCESSING FMI OPTIONS'
542 call mem_set_value(this%ipakcb,
'SAVE_FLOWS', this%input_mempath, &
544 call mem_set_value(this%iflowerr,
'IMBALANCECORRECT', this%input_mempath, &
547 if (found_ipakcb)
then
549 write (this%iout, fmtisvflow)
551 if (found_flowerr)
write (this%iout, fmtifc)
553 write (this%iout,
'(1x,a)')
'END OF FMI OPTIONS'
577 character(len=LINELENGTH) :: flowtype, fileop, fname
578 integer(I4B) :: iapt, inunit, n, i
579 logical(LGP) :: exist
583 call mem_setptr(flowtypes,
'FLOWTYPE', this%input_mempath)
584 call mem_setptr(fileops,
'FILEIN', this%input_mempath)
585 call mem_setptr(fnames,
'FNAME', this%input_mempath)
587 do n = 1,
size(flowtypes)
588 flowtype = flowtypes(n)
592 inquire (file=trim(fname), exist=exist)
593 if (.not. exist)
then
594 call store_error(
'Could not find file '//trim(fname))
598 if (fileop /=
'FILEIN')
then
599 call store_error(
'Unexpected packagedata input keyword read: "' &
600 //trim(fileop)//
'".')
604 select case (flowtype)
607 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
610 call this%initialize_bfr()
613 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
616 call this%initialize_hfr()
619 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
624 call this%mvrbudobj%fill_from_bfr(this%dis, this%iout)
628 allocate (tmpbudobj(iapt))
629 do i = 1,
size(this%aptbudobj)
630 tmpbudobj(i)%ptr => this%aptbudobj(i)%ptr
632 deallocate (this%aptbudobj)
633 allocate (this%aptbudobj(iapt + 1))
634 do i = 1,
size(tmpbudobj)
635 this%aptbudobj(i)%ptr => tmpbudobj(i)%ptr
637 deallocate (tmpbudobj)
642 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
645 this%iout, colconv2=[
'GWF '])
646 call budobjptr%fill_from_bfr(this%dis, this%iout)
647 this%aptbudobj(iapt)%ptr => budobjptr
667 character(len=*),
intent(in) :: name
673 do i = 1,
size(this%aptbudobj)
674 if (this%aptbudobj(i)%ptr%name == name)
then
675 budobjptr => this%aptbudobj(i)%ptr
693 integer(I4B) :: nflowpack
694 integer(I4B) :: i, ip
696 logical :: found_flowja
697 logical :: found_dataspdis
698 logical :: found_datasat
699 logical :: found_stoss
700 logical :: found_stosy
701 integer(I4B),
dimension(:),
allocatable :: imap
704 allocate (imap(this%bfr%nbudterms))
707 found_flowja = .false.
708 found_dataspdis = .false.
709 found_datasat = .false.
710 found_stoss = .false.
711 found_stosy = .false.
712 do i = 1, this%bfr%nbudterms
713 select case (trim(adjustl(this%bfr%budtxtarray(i))))
714 case (
'FLOW-JA-FACE')
715 found_flowja = .true.
717 found_dataspdis = .true.
719 found_datasat = .true.
727 nflowpack = nflowpack + 1
733 call this%allocate_gwfpackages(nflowpack)
738 do i = 1, this%bfr%nbudterms
739 if (imap(i) == 0) cycle
740 call this%gwfpackages(ip)%set_name(this%bfr%dstpackagenamearray(i), &
741 this%bfr%budtxtarray(i))
742 naux = this%bfr%nauxarray(i)
743 call this%gwfpackages(ip)%set_auxname(naux, &
744 this%bfr%auxtxtarray(1:naux, i))
752 if (imap(i) == 1)
then
753 this%flowpacknamearray(ip) = this%bfr%dstpackagenamearray(i)
759 if (.not. found_dataspdis)
then
760 write (
errmsg,
'(a)')
'Specific discharge not found in &
761 &budget file. SAVE_SPECIFIC_DISCHARGE and &
762 &SAVE_FLOWS must be activated in the NPF package.'
765 if (.not. found_datasat)
then
766 write (
errmsg,
'(a)')
'Saturation not found in &
767 &budget file. SAVE_SATURATION and &
768 &SAVE_FLOWS must be activated in the NPF package.'
771 if (.not. found_flowja)
then
772 write (
errmsg,
'(a)')
'FLOWJA not found in &
773 &budget file. SAVE_FLOWS must &
774 &be activated in the NPF package.'
792 integer(I4B) :: ngwfpack
793 integer(I4B) :: ngwfterms
795 integer(I4B) :: imover
796 integer(I4B) :: ntomvr
797 integer(I4B) :: iterm
798 character(len=LENPACKAGENAME) :: budtxt
799 class(
bndtype),
pointer :: packobj => null()
802 ngwfpack = this%gwfbndlist%Count()
810 imover = packobj%imover
811 if (packobj%isadvpak /= 0) imover = 0
812 if (imover /= 0)
then
819 ngwfterms = ngwfpack + ntomvr
820 call this%allocate_gwfpackages(ngwfterms)
828 budtxt = adjustl(packobj%text)
829 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
830 this%flowpacknamearray(iterm) = packobj%packName
831 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
837 imover = packobj%imover
838 if (packobj%isadvpak /= 0) imover = 0
839 if (imover /= 0)
then
840 budtxt = trim(adjustl(packobj%text))//
'-TO-MVR'
841 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
842 this%flowpacknamearray(iterm) = packobj%packName
843 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
845 this%igwfmvrterm(iterm) = 1
862 integer(I4B),
intent(in) :: ngwfterms
865 character(len=LENMEMPATH) :: memPath
868 allocate (this%gwfpackages(ngwfterms))
869 allocate (this%flowpacknamearray(ngwfterms))
870 allocate (this%datp(ngwfterms))
873 call mem_allocate(this%iatp, ngwfterms,
'IATP', this%memoryPath)
874 call mem_allocate(this%igwfmvrterm, ngwfterms,
'IGWFMVRTERM', this%memoryPath)
877 this%nflowpack = ngwfterms
878 do n = 1, this%nflowpack
880 this%igwfmvrterm(n) = 0
881 this%flowpacknamearray(n) =
''
885 write (mempath,
'(a, i0)') trim(this%memoryPath)//
'-FT', n
886 call this%gwfpackages(n)%initialize(mempath)
902 do n = 1, this%nflowpack
903 call this%gwfpackages(n)%da()
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 dem6
real constant 1e-6
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.
subroutine gwtfmi_deallocate_gwfpackages(this)
Deallocate memory.
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 gwtfmi_source_packagedata(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.
Derived type for the Budget object.
This class is used to store a single deferred-length character string. It was designed to work in an ...
A generic heterogeneous doubly-linked list.
Derived type for storing flows.