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, inunit, iout, eqnsclfac, depvartype)
77 character(len=*),
intent(in) :: name_model
78 integer(I4B),
intent(in) :: inunit
79 integer(I4B),
intent(in) :: iout
80 real(dp),
intent(in),
pointer :: eqnsclfac
81 character(len=LENVARNAME),
intent(in) :: depvartype
87 call fmiobj%set_names(1, name_model,
'FMI',
'FMI')
91 call fmiobj%allocate_scalars()
94 fmiobj%inunit = inunit
98 call fmiobj%parser%Initialize(fmiobj%inunit, fmiobj%iout)
101 fmiobj%depvartype = depvartype
104 fmiobj%eqnsclfac => eqnsclfac
114 integer(I4B),
intent(in) :: inmvr
122 if (
associated(this%mvrbudobj) .and. inmvr == 0)
then
123 write (
errmsg,
'(a)')
'GWF water mover is active but the GWT MVT &
124 &package has not been specified. activate GWT MVT package.'
127 if (.not.
associated(this%mvrbudobj) .and. inmvr > 0)
then
128 write (
errmsg,
'(a)')
'GWF water mover terms are not available &
129 &but the GWT MVT package has been activated. Activate GWF-GWT &
130 &exchange or specify GWFMOVER in FMI PACKAGEDATA.'
143 real(DP),
intent(inout),
dimension(:) :: cnew
146 character(len=*),
parameter :: fmtdry = &
147 &
"(/1X,'WARNING: DRY CELL ENCOUNTERED AT ',a,'; RESET AS INACTIVE &
148 &WITH DRY CONCENTRATION = ', G13.5)"
149 character(len=*),
parameter :: fmtrewet = &
150 &
"(/1X,'DRY CELL REACTIVATED AT ', a,&
151 &' WITH STARTING CONCENTRATION =',G13.5)"
156 this%iflowsupdated = 1
159 if (this%iubud /= 0)
then
160 call this%advance_bfr()
164 if (this%iuhds /= 0)
then
165 call this%advance_hfr()
169 if (this%iumvr /= 0)
then
170 call this%mvrbudobj%bfr_advance(this%dis, this%iout)
174 if (this%flows_from_file .and. this%inunit /= 0)
then
175 do n = 1,
size(this%aptbudobj)
176 call this%aptbudobj(n)%ptr%bfr_advance(this%dis, this%iout)
181 if (this%idryinactive /= 0)
then
182 call this%set_active_status(cnew)
189 subroutine fmi_fc(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
192 integer,
intent(in) :: nodes
193 real(DP),
intent(in),
dimension(nodes) :: cold
194 integer(I4B),
intent(in) :: nja
196 integer(I4B),
intent(in),
dimension(nja) :: idxglo
197 real(DP),
intent(inout),
dimension(nodes) :: rhs
199 integer(I4B) :: n, idiag, idiag_sln
203 if (this%iflowerr /= 0)
then
208 idiag = this%dis%con%ia(n)
209 idiag_sln = idxglo(idiag)
211 qcorr = -this%gwfflowja(idiag) * this%eqnsclfac
212 call matrix_sln%add_value_pos(idiag_sln, qcorr)
226 real(DP),
intent(in),
dimension(:) :: cnew
227 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
230 integer(I4B) :: idiag
234 if (this%iflowerr /= 0)
then
237 do n = 1, this%dis%nodes
239 idiag = this%dis%con%ia(n)
240 if (this%ibound(n) > 0)
then
241 rate = -this%gwfflowja(idiag) * cnew(n) * this%eqnsclfac
243 this%flowcorrect(n) = rate
244 flowja(idiag) = flowja(idiag) + rate
251 subroutine fmi_bd(this, isuppress_output, model_budget)
257 integer(I4B),
intent(in) :: isuppress_output
258 type(
budgettype),
intent(inout) :: model_budget
264 if (this%iflowerr /= 0)
then
266 call model_budget%addentry(rin, rout,
delt,
budtxt(2), isuppress_output)
275 integer(I4B),
intent(in) :: icbcfl
276 integer(I4B),
intent(in) :: icbcun
278 integer(I4B) :: ibinun
279 integer(I4B) :: iprint, nvaluesp, nwidthp
280 character(len=1) :: cdatafmp =
' ', editdesc =
' '
284 if (this%ipakcb < 0)
then
286 elseif (this%ipakcb == 0)
then
291 if (icbcfl == 0) ibinun = 0
294 if (this%iflowerr == 0) ibinun = 0
297 if (ibinun /= 0)
then
302 call this%dis%record_array(this%flowcorrect, this%iout, iprint, -ibinun, &
303 budtxt(2), cdatafmp, nvaluesp, &
304 nwidthp, editdesc, dinact)
320 call this%deallocate_gwfpackages()
323 if (
associated(this%datp))
then
324 deallocate (this%datp)
325 deallocate (this%gwfpackages)
326 deallocate (this%flowpacknamearray)
331 deallocate (this%aptbudobj)
334 if (this%flows_from_file)
then
359 call this%NumericalPackageType%da()
374 call this%FlowModelInterfaceType%allocate_scalars()
377 call mem_allocate(this%iflowerr,
'IFLOWERR', this%memoryPath)
381 allocate (this%aptbudobj(0))
397 integer(I4B),
intent(in) :: nodes
402 call this%FlowModelInterfaceType%allocate_arrays(nodes)
405 if (this%iflowerr == 0)
then
406 call mem_allocate(this%flowcorrect, 1,
'FLOWCORRECT', this%memoryPath)
408 call mem_allocate(this%flowcorrect, nodes,
'FLOWCORRECT', this%memoryPath)
410 do n = 1,
size(this%flowcorrect)
411 this%flowcorrect(n) =
dzero
426 real(DP),
intent(inout),
dimension(:) :: cnew
431 real(DP) :: crewet, tflow, flownm
432 character(len=15) :: nodestr
434 character(len=*),
parameter :: fmtoutmsg1 = &
435 "(1x,'WARNING: DRY CELL ENCOUNTERED AT ', a,'; RESET AS INACTIVE WITH &
436 &DRY ', a, '=', G13.5)"
437 character(len=*),
parameter :: fmtoutmsg2 = &
438 &
"(1x,'DRY CELL REACTIVATED AT', a, 'WITH STARTING', a, '=', G13.5)"
440 do n = 1, this%dis%nodes
443 if (this%gwfsat(n) > dzero)
then
444 this%ibdgwfsat0(n) = 1
446 this%ibdgwfsat0(n) = 0
450 if (this%ibound(n) > 0)
then
451 if (this%gwfhead(n) ==
dhdry)
then
455 call this%dis%noder_to_string(n, nodestr)
456 write (this%iout, fmtoutmsg1) &
457 trim(nodestr), trim(adjustl(this%depvartype)),
dhdry
463 do n = 1, this%dis%nodes
466 if (cnew(n) ==
dhdry)
then
467 if (this%gwfhead(n) /=
dhdry)
then
472 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
473 m = this%dis%con%ja(ipos)
474 flownm = this%gwfflowja(ipos)
476 if (this%ibound(m) /= 0)
then
477 crewet = crewet + cnew(m) * flownm
478 tflow = tflow + this%gwfflowja(ipos)
482 if (tflow > dzero)
then
483 crewet = crewet / tflow
491 call this%dis%noder_to_string(n, nodestr)
492 write (this%iout, fmtoutmsg2) &
493 trim(nodestr), trim(adjustl(this%depvartype)), crewet
508 integer(I4B),
intent(in) :: n
509 real(dp),
intent(in) :: delt
518 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
519 vnew = vcell * this%gwfsat(n)
521 if (this%igwfstrgss /= 0) vold = vold + this%gwfstrgss(n) * delt
522 if (this%igwfstrgsy /= 0) vold = vold + this%gwfstrgsy(n) * delt
523 satold = vold / vcell
536 character(len=LINELENGTH) :: keyword
538 logical :: isfound, endOfBlock
539 character(len=*),
parameter :: fmtisvflow = &
540 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
541 &WHENEVER ICBCFL IS NOT ZERO AND FLOW IMBALANCE CORRECTION ACTIVE.')"
542 character(len=*),
parameter :: fmtifc = &
543 &
"(4x,'MASS WILL BE ADDED OR REMOVED TO COMPENSATE FOR FLOW IMBALANCE.')"
546 call this%parser%GetBlock(
'OPTIONS', isfound, ierr, blockrequired=.false., &
547 supportopenclose=.true.)
551 write (this%iout,
'(1x,a)')
'PROCESSING FMI OPTIONS'
553 call this%parser%GetNextLine(endofblock)
555 call this%parser%GetStringCaps(keyword)
556 select case (keyword)
559 write (this%iout, fmtisvflow)
560 case (
'FLOW_IMBALANCE_CORRECTION')
561 write (this%iout, fmtifc)
564 write (
errmsg,
'(a,a)')
'Unknown FMI option: ', &
567 call this%parser%StoreErrorUnit()
570 write (this%iout,
'(1x,a)')
'END OF FMI OPTIONS'
588 character(len=LINELENGTH) :: keyword, fname
589 character(len=LENPACKAGENAME) :: pname
592 integer(I4B) :: inunit
594 logical :: isfound, endOfBlock
595 logical :: blockrequired
601 blockrequired = .true.
604 call this%parser%GetBlock(
'PACKAGEDATA', isfound, ierr, &
605 blockrequired=blockrequired, &
606 supportopenclose=.true.)
610 write (this%iout,
'(1x,a)')
'PROCESSING FMI PACKAGEDATA'
612 call this%parser%GetNextLine(endofblock)
614 call this%parser%GetStringCaps(keyword)
615 select case (keyword)
617 call this%parser%GetStringCaps(keyword)
618 if (keyword /=
'FILEIN')
then
619 call store_error(
'GWFBUDGET keyword must be followed by '// &
620 '"FILEIN" then by filename.')
621 call this%parser%StoreErrorUnit()
623 call this%parser%GetString(fname)
625 inquire (file=trim(fname), exist=exist)
626 if (.not. exist)
then
627 call store_error(
'Could not find file '//trim(fname))
628 call this%parser%StoreErrorUnit()
630 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
633 call this%initialize_bfr()
635 call this%parser%GetStringCaps(keyword)
636 if (keyword /=
'FILEIN')
then
637 call store_error(
'GWFHEAD keyword must be followed by '// &
638 '"FILEIN" then by filename.')
639 call this%parser%StoreErrorUnit()
641 call this%parser%GetString(fname)
642 inquire (file=trim(fname), exist=exist)
643 if (.not. exist)
then
644 call store_error(
'Could not find file '//trim(fname))
645 call this%parser%StoreErrorUnit()
648 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
651 call this%initialize_hfr()
653 call this%parser%GetStringCaps(keyword)
654 if (keyword /=
'FILEIN')
then
655 call store_error(
'GWFMOVER keyword must be followed by '// &
656 '"FILEIN" then by filename.')
657 call this%parser%StoreErrorUnit()
659 call this%parser%GetString(fname)
661 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
666 call this%mvrbudobj%fill_from_bfr(this%dis, this%iout)
670 allocate (tmpbudobj(iapt))
671 do i = 1,
size(this%aptbudobj)
672 tmpbudobj(i)%ptr => this%aptbudobj(i)%ptr
674 deallocate (this%aptbudobj)
675 allocate (this%aptbudobj(iapt + 1))
676 do i = 1,
size(tmpbudobj)
677 this%aptbudobj(i)%ptr => tmpbudobj(i)%ptr
679 deallocate (tmpbudobj)
684 call this%parser%GetStringCaps(keyword)
685 if (keyword /=
'FILEIN')
then
686 call store_error(
'Package name must be followed by '// &
687 '"FILEIN" then by filename.')
688 call this%parser%StoreErrorUnit()
690 call this%parser%GetString(fname)
692 call openfile(inunit, this%iout, fname,
'DATA(BINARY)',
form, &
695 this%iout, colconv2=[
'GWF '])
696 call budobjptr%fill_from_bfr(this%dis, this%iout)
697 this%aptbudobj(iapt)%ptr => budobjptr
700 write (this%iout,
'(1x,a)')
'END OF FMI PACKAGEDATA'
715 character(len=*),
intent(in) :: name
721 do i = 1,
size(this%aptbudobj)
722 if (this%aptbudobj(i)%ptr%name == name)
then
723 budobjptr => this%aptbudobj(i)%ptr
742 integer(I4B) :: nflowpack
743 integer(I4B) :: i, ip
745 logical :: found_flowja
746 logical :: found_dataspdis
747 logical :: found_datasat
748 logical :: found_stoss
749 logical :: found_stosy
750 integer(I4B),
dimension(:),
allocatable :: imap
753 allocate (imap(this%bfr%nbudterms))
756 found_flowja = .false.
757 found_dataspdis = .false.
758 found_datasat = .false.
759 found_stoss = .false.
760 found_stosy = .false.
761 do i = 1, this%bfr%nbudterms
762 select case (trim(adjustl(this%bfr%budtxtarray(i))))
763 case (
'FLOW-JA-FACE')
764 found_flowja = .true.
766 found_dataspdis = .true.
768 found_datasat = .true.
776 nflowpack = nflowpack + 1
782 call this%allocate_gwfpackages(nflowpack)
787 do i = 1, this%bfr%nbudterms
788 if (imap(i) == 0) cycle
789 call this%gwfpackages(ip)%set_name(this%bfr%dstpackagenamearray(i), &
790 this%bfr%budtxtarray(i))
791 naux = this%bfr%nauxarray(i)
792 call this%gwfpackages(ip)%set_auxname(naux, &
793 this%bfr%auxtxtarray(1:naux, i))
801 if (imap(i) == 1)
then
802 this%flowpacknamearray(ip) = this%bfr%dstpackagenamearray(i)
808 if (.not. found_dataspdis)
then
809 write (
errmsg,
'(a)')
'Specific discharge not found in &
810 &budget file. SAVE_SPECIFIC_DISCHARGE and &
811 &SAVE_FLOWS must be activated in the NPF package.'
814 if (.not. found_datasat)
then
815 write (
errmsg,
'(a)')
'Saturation not found in &
816 &budget file. SAVE_SATURATION and &
817 &SAVE_FLOWS must be activated in the NPF package.'
820 if (.not. found_flowja)
then
821 write (
errmsg,
'(a)')
'FLOWJA not found in &
822 &budget file. SAVE_FLOWS must &
823 &be activated in the NPF package.'
827 call this%parser%StoreErrorUnit()
841 integer(I4B) :: ngwfpack
842 integer(I4B) :: ngwfterms
844 integer(I4B) :: imover
845 integer(I4B) :: ntomvr
846 integer(I4B) :: iterm
847 character(len=LENPACKAGENAME) :: budtxt
848 class(
bndtype),
pointer :: packobj => null()
851 ngwfpack = this%gwfbndlist%Count()
859 imover = packobj%imover
860 if (packobj%isadvpak /= 0) imover = 0
861 if (imover /= 0)
then
868 ngwfterms = ngwfpack + ntomvr
869 call this%allocate_gwfpackages(ngwfterms)
877 budtxt = adjustl(packobj%text)
878 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
879 this%flowpacknamearray(iterm) = packobj%packName
880 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
886 imover = packobj%imover
887 if (packobj%isadvpak /= 0) imover = 0
888 if (imover /= 0)
then
889 budtxt = trim(adjustl(packobj%text))//
'-TO-MVR'
890 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
891 this%flowpacknamearray(iterm) = packobj%packName
892 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
894 this%igwfmvrterm(iterm) = 1
911 integer(I4B),
intent(in) :: ngwfterms
914 character(len=LENMEMPATH) :: memPath
917 allocate (this%gwfpackages(ngwfterms))
918 allocate (this%flowpacknamearray(ngwfterms))
919 allocate (this%datp(ngwfterms))
922 call mem_allocate(this%iatp, ngwfterms,
'IATP', this%memoryPath)
923 call mem_allocate(this%igwfmvrterm, ngwfterms,
'IGWFMVRTERM', this%memoryPath)
926 this%nflowpack = ngwfterms
927 do n = 1, this%nflowpack
929 this%igwfmvrterm(n) = 0
930 this%flowpacknamearray(n) =
''
934 write (mempath,
'(a, i0)') trim(this%memoryPath)//
'-FT', n
935 call this%gwfpackages(n)%initialize(mempath)
951 do n = 1, this%nflowpack
952 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_unit(iunit, terminate)
Store the file unit number.
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 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 gwtfmi_read_options(this)
Read options from input file.
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_read_packagedata(this)
Read PACKAGEDATA block.
subroutine, public fmi_cr(fmiobj, name_model, inunit, iout, eqnsclfac, depvartype)
Create a new FMI object.
Derived type for the Budget object.
A generic heterogeneous doubly-linked list.
Derived type for storing flows.