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
671 character(len=*),
intent(in) :: name
677 do i = 1,
size(this%aptbudobj)
678 if (this%aptbudobj(i)%ptr%name == name)
then
679 budobjptr => this%aptbudobj(i)%ptr
697 integer(I4B) :: nflowpack
698 integer(I4B) :: i, ip
700 logical :: found_flowja
701 logical :: found_dataspdis
702 logical :: found_datasat
703 logical :: found_stoss
704 logical :: found_stosy
705 integer(I4B),
dimension(:),
allocatable :: imap
708 allocate (imap(this%bfr%nbudterms))
711 found_flowja = .false.
712 found_dataspdis = .false.
713 found_datasat = .false.
714 found_stoss = .false.
715 found_stosy = .false.
716 do i = 1, this%bfr%nbudterms
717 select case (trim(adjustl(this%bfr%budtxtarray(i))))
718 case (
'FLOW-JA-FACE')
719 found_flowja = .true.
721 found_dataspdis = .true.
723 found_datasat = .true.
731 nflowpack = nflowpack + 1
737 call this%allocate_gwfpackages(nflowpack)
742 do i = 1, this%bfr%nbudterms
743 if (imap(i) == 0) cycle
744 call this%gwfpackages(ip)%set_name(this%bfr%dstpackagenamearray(i), &
745 this%bfr%budtxtarray(i))
746 naux = this%bfr%nauxarray(i)
747 call this%gwfpackages(ip)%set_auxname(naux, &
748 this%bfr%auxtxtarray(1:naux, i))
756 if (imap(i) == 1)
then
757 this%flowpacknamearray(ip) = this%bfr%dstpackagenamearray(i)
763 if (.not. found_dataspdis)
then
764 write (
errmsg,
'(a)')
'Specific discharge not found in &
765 &budget file. SAVE_SPECIFIC_DISCHARGE and &
766 &SAVE_FLOWS must be activated in the NPF package.'
769 if (.not. found_datasat)
then
770 write (
errmsg,
'(a)')
'Saturation not found in &
771 &budget file. SAVE_SATURATION and &
772 &SAVE_FLOWS must be activated in the NPF package.'
775 if (.not. found_flowja)
then
776 write (
errmsg,
'(a)')
'FLOWJA not found in &
777 &budget file. SAVE_FLOWS must &
778 &be activated in the NPF package.'
796 integer(I4B) :: ngwfpack
797 integer(I4B) :: ngwfterms
799 integer(I4B) :: imover
800 integer(I4B) :: ntomvr
801 integer(I4B) :: iterm
802 character(len=LENPACKAGENAME) :: budtxt
803 class(
bndtype),
pointer :: packobj => null()
806 ngwfpack = this%gwfbndlist%Count()
814 imover = packobj%imover
815 if (packobj%isadvpak /= 0) imover = 0
816 if (imover /= 0)
then
823 ngwfterms = ngwfpack + ntomvr
824 call this%allocate_gwfpackages(ngwfterms)
832 budtxt = adjustl(packobj%text)
833 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
834 this%flowpacknamearray(iterm) = packobj%packName
835 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
841 imover = packobj%imover
842 if (packobj%isadvpak /= 0) imover = 0
843 if (imover /= 0)
then
844 budtxt = trim(adjustl(packobj%text))//
'-TO-MVR'
845 call this%gwfpackages(iterm)%set_name(packobj%packName, budtxt)
846 this%flowpacknamearray(iterm) = packobj%packName
847 call this%gwfpackages(iterm)%set_auxname(packobj%naux, &
849 this%igwfmvrterm(iterm) = 1
866 integer(I4B),
intent(in) :: ngwfterms
869 character(len=LENMEMPATH) :: memPath
872 allocate (this%gwfpackages(ngwfterms))
873 allocate (this%flowpacknamearray(ngwfterms))
874 allocate (this%datp(ngwfterms))
877 call mem_allocate(this%iatp, ngwfterms,
'IATP', this%memoryPath)
878 call mem_allocate(this%igwfmvrterm, ngwfterms,
'IGWFMVRTERM', this%memoryPath)
881 this%nflowpack = ngwfterms
882 do n = 1, this%nflowpack
884 this%igwfmvrterm(n) = 0
885 this%flowpacknamearray(n) =
''
889 write (mempath,
'(a, i0)') trim(this%memoryPath)//
'-FT', n
890 call this%gwfpackages(n)%initialize(mempath)
906 do n = 1, this%nflowpack
907 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.
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
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.