28 character(len=LENFTYPE) ::
ftype =
'SSM'
29 character(len=LENPACKAGENAME) ::
text =
' SOURCE-SINK MIX'
39 integer(I4B),
pointer :: nbound
40 integer(I4B),
dimension(:),
pointer,
contiguous :: isrctype => null()
41 integer(I4B),
dimension(:),
pointer,
contiguous :: iauxpak => null()
42 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound => null()
43 real(dp),
dimension(:),
pointer,
contiguous :: cnew => null()
46 type(
tspspctype),
dimension(:),
pointer :: ssmivec => null()
47 real(dp),
pointer :: eqnsclfac => null()
48 character(len=LENVARNAME) :: depvartype =
''
80 subroutine ssm_cr(ssmobj, name_model, input_mempath, inunit, iout, fmi, &
81 eqnsclfac, depvartype)
84 character(len=*),
intent(in) :: name_model
85 character(len=*),
intent(in) :: input_mempath
86 integer(I4B),
intent(in) :: inunit
87 integer(I4B),
intent(in) :: iout
89 real(dp),
intent(in),
pointer :: eqnsclfac
90 character(len=LENVARNAME),
intent(in) :: depvartype
96 call ssmobj%set_names(1, name_model,
'SSM',
'SSM', input_mempath)
99 call ssmobj%allocate_scalars()
102 ssmobj%inunit = inunit
105 ssmobj%eqnsclfac => eqnsclfac
109 ssmobj%depvartype = depvartype
130 subroutine ssm_ar(this, dis, ibound, cnew)
136 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
137 real(DP),
dimension(:),
pointer,
contiguous :: cnew
139 character(len=*),
parameter :: fmtssm = &
140 "(1x,/1x,'SSM -- SOURCE-SINK MIXING PACKAGE, VERSION 1, 8/25/2017', &
141 &' INPUT READ FROM MEMPATH: ', A, //)"
144 write (this%iout, fmtssm) this%input_mempath
148 this%ibound => ibound
152 if (this%fmi%nflowpack == 0)
then
153 write (
errmsg,
'(a)')
'SSM package does not detect any boundary flows &
154 &that require SSM terms. Activate GWF-GWT (or &
155 &GWF-GWE, as appropriate) exchange or activate &
156 &FMI package and provide a budget file that &
157 &contains boundary flows. If no boundary flows &
158 &are present in corresponding GWF model then this &
159 &SSM package should be removed.'
165 call this%allocate_arrays()
168 call this%source_options()
171 call this%source_sources()
172 call this%source_fileinput()
175 call this%pak_setup_outputtab()
194 do ip = 1, this%fmi%nflowpack
195 if (this%fmi%iatp(ip) /= 0) cycle
196 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
197 ssmiptr => this%ssmivec(ip)
198 call ssmiptr%spc_rp()
225 do ip = 1, this%fmi%nflowpack
226 if (this%fmi%iatp(ip) /= 0) cycle
227 do i = 1, this%fmi%gwfpackages(ip)%nbound
228 node = this%fmi%gwfpackages(ip)%nodelist(i)
230 this%nbound = this%nbound + 1
237 do ip = 1, this%fmi%nflowpack
238 if (this%fmi%iatp(ip) /= 0) cycle
239 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
240 ssmiptr => this%ssmivec(ip)
241 call ssmiptr%spc_ad(this%fmi%gwfpackages(ip)%nbound, &
242 this%fmi%gwfpackages(ip)%budtxt)
254 subroutine ssm_term(this, ipackage, ientry, rrate, rhsval, hcofval, &
258 integer(I4B),
intent(in) :: ipackage
259 integer(I4B),
intent(in) :: ientry
260 real(DP),
intent(out),
optional :: rrate
261 real(DP),
intent(out),
optional :: rhsval
262 real(DP),
intent(out),
optional :: hcofval
263 real(DP),
intent(out),
optional :: cssm
264 real(DP),
intent(out),
optional :: qssm
266 logical(LGP) :: lauxmixed
268 integer(I4B) :: nbound_flow
280 nbound_flow = this%fmi%gwfpackages(ipackage)%nbound
281 n = this%fmi%gwfpackages(ipackage)%nodelist(ientry)
284 if (this%ibound(n) > 0)
then
287 qbnd = this%fmi%gwfpackages(ipackage)%get_flow(ientry)
288 call this%get_ssm_conc(ipackage, ientry, nbound_flow, ctmp, lauxmixed)
292 if (.not. lauxmixed)
then
298 if (qbnd >=
dzero)
then
303 if (ctmp <
dzero)
then
315 if (qbnd >=
dzero)
then
318 if (ctmp < this%cnew(n))
then
328 if (qbnd <=
dzero)
then
329 hcoftmp = qbnd * omega * this%eqnsclfac
331 rhstmp = -qbnd * ctmp * (
done - omega) * this%eqnsclfac
338 if (
present(hcofval)) hcofval = hcoftmp
339 if (
present(rhsval)) rhsval = rhstmp
340 if (
present(rrate)) rrate = hcoftmp * ctmp - rhstmp
341 if (
present(cssm)) cssm = ctmp
342 if (
present(qssm)) qssm = qbnd
358 integer(I4B),
intent(in) :: ipackage
359 integer(I4B),
intent(in) :: ientry
360 integer(I4B),
intent(in) :: nbound_flow
361 real(DP),
intent(out) :: conc
362 logical(LGP),
intent(out) :: lauxmixed
364 integer(I4B) :: isrctype
365 integer(I4B) :: iauxpos
369 isrctype = this%isrctype(ipackage)
371 select case (isrctype)
373 iauxpos = this%iauxpak(ipackage)
374 conc = this%fmi%gwfpackages(ipackage)%auxvar(iauxpos, ientry)
375 if (isrctype == 2) lauxmixed = .true.
377 conc = this%ssmivec(ipackage)%get_value(ientry, nbound_flow)
378 if (isrctype == 4) lauxmixed = .true.
387 subroutine ssm_fc(this, matrix_sln, idxglo, rhs)
391 integer(I4B),
intent(in),
dimension(:) :: idxglo
392 real(DP),
intent(inout),
dimension(:) :: rhs
397 integer(I4B) :: idiag
398 integer(I4B) :: nflowpack
399 integer(I4B) :: nbound
404 nflowpack = this%fmi%nflowpack
406 if (this%fmi%iatp(ip) /= 0) cycle
409 nbound = this%fmi%gwfpackages(ip)%nbound
411 n = this%fmi%gwfpackages(ip)%nodelist(i)
413 call this%ssm_term(ip, i, rhsval=rhsval, hcofval=hcofval)
414 idiag = idxglo(this%dis%con%ia(n))
415 call matrix_sln%add_value_pos(idiag, hcofval)
416 rhs(n) = rhs(n) + rhsval
432 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
437 integer(I4B) :: idiag
441 do ip = 1, this%fmi%nflowpack
444 if (this%fmi%iatp(ip) /= 0) cycle
447 do i = 1, this%fmi%gwfpackages(ip)%nbound
448 n = this%fmi%gwfpackages(ip)%nodelist(i)
450 call this%ssm_term(ip, i, rrate=rate)
451 idiag = this%dis%con%ia(n)
452 flowja(idiag) = flowja(idiag) + rate
464 subroutine ssm_bd(this, isuppress_output, model_budget)
470 integer(I4B),
intent(in) :: isuppress_output
471 type(
budgettype),
intent(inout) :: model_budget
473 character(len=LENBUDROWLABEL) :: rowlabel
483 do ip = 1, this%fmi%nflowpack
486 if (this%fmi%iatp(ip) /= 0) cycle
493 do i = 1, this%fmi%gwfpackages(ip)%nbound
494 n = this%fmi%gwfpackages(ip)%nodelist(i)
496 call this%ssm_term(ip, i, rrate=rate)
497 if (rate <
dzero)
then
505 rowlabel =
'SSM_'//adjustl(trim(this%fmi%flowpacknamearray(ip)))
506 call model_budget%addentry(rin, rout,
delt, &
507 this%fmi%gwfpackages(ip)%budtxt, &
508 isuppress_output, rowlabel=rowlabel)
524 integer(I4B),
intent(in) :: icbcfl
525 integer(I4B),
intent(in) :: ibudfl
526 integer(I4B),
intent(in) :: icbcun
528 character(len=LINELENGTH) :: title
529 integer(I4B) :: node, nodeu
530 character(len=20) :: nodestr
531 integer(I4B) :: maxrows
533 integer(I4B) :: i, n2, ibinun
538 real(DP),
dimension(0) :: auxrow
539 character(len=LENAUXNAME),
dimension(0) :: auxname
541 character(len=LENBOUNDNAME) :: bname
543 character(len=*),
parameter :: fmttkk = &
544 &
"(1X,/1X,A,' PERIOD ',I0,' STEP ',I0)"
549 if (ibudfl /= 0 .and. this%iprflow /= 0)
then
550 call this%outputtab%set_kstpkper(
kstp,
kper)
551 do ip = 1, this%fmi%nflowpack
552 if (this%fmi%iatp(ip) /= 0) cycle
555 do i = 1, this%fmi%gwfpackages(ip)%nbound
556 node = this%fmi%gwfpackages(ip)%nodelist(i)
558 maxrows = maxrows + 1
562 if (maxrows > 0)
then
563 call this%outputtab%set_maxbound(maxrows)
565 title =
'SSM PACKAGE ('//trim(this%packName)// &
567 call this%outputtab%set_title(title)
571 if (this%ipakcb < 0)
then
573 else if (this%ipakcb == 0)
then
578 if (icbcfl == 0) ibinun = 0
581 if (ibinun /= 0)
then
582 call this%dis%record_srcdst_list_header(
text, this%name_model, &
583 this%name_model, this%name_model, &
584 this%packName, naux, auxname, &
585 ibinun, this%nbound, this%iout)
589 if (this%nbound > 0)
then
592 do ip = 1, this%fmi%nflowpack
593 if (this%fmi%iatp(ip) /= 0) cycle
596 do i = 1, this%fmi%gwfpackages(ip)%nbound
599 node = this%fmi%gwfpackages(ip)%nodelist(i)
601 call this%ssm_term(ip, i, rrate=rrate, qssm=qssm, cssm=cssm)
605 if (ibudfl /= 0)
then
606 if (this%iprflow /= 0)
then
609 nodeu = this%dis%get_nodeuser(node)
610 call this%dis%nodeu_to_string(nodeu, nodestr)
611 bname = this%fmi%gwfpackages(ip)%name
612 call this%outputtab%add_term(i)
613 call this%outputtab%add_term(trim(adjustl(nodestr)))
614 call this%outputtab%add_term(qssm)
615 call this%outputtab%add_term(cssm)
616 call this%outputtab%add_term(rrate)
617 call this%outputtab%add_term(bname)
622 if (ibinun /= 0)
then
624 call this%dis%record_mf6_list_entry(ibinun, node, n2, rrate, &
633 if (ibudfl /= 0)
then
634 if (this%iprflow /= 0)
then
635 write (this%iout,
'(1x)')
654 if (this%inunit > 0)
then
655 do ip = 1,
size(this%ssmivec)
656 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
657 ssmiptr => this%ssmivec(ip)
658 call ssmiptr%spc_da()
661 deallocate (this%ssmivec)
665 if (this%inunit > 0)
then
668 this%ibound => null()
673 if (
associated(this%outputtab))
then
674 call this%outputtab%table_da()
675 deallocate (this%outputtab)
676 nullify (this%outputtab)
683 call this%NumericalPackageType%da()
697 call this%NumericalPackageType%allocate_scalars()
700 call mem_allocate(this%nbound,
'NBOUND', this%memoryPath)
716 integer(I4B) :: nflowpack
720 nflowpack = this%fmi%nflowpack
721 call mem_allocate(this%iauxpak, nflowpack,
'IAUXPAK', this%memoryPath)
722 call mem_allocate(this%isrctype, nflowpack,
'ISRCTYPE', this%memoryPath)
731 allocate (this%ssmivec(nflowpack))
746 character(len=*),
parameter :: fmtiprflow = &
747 "(4x,'SSM FLOW INFORMATION WILL BE PRINTED TO LISTING FILE &
748 &WHENEVER ICBCFL IS NOT ZERO.')"
749 character(len=*),
parameter :: fmtisvflow = &
750 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
751 &WHENEVER ICBCFL IS NOT ZERO.')"
754 call mem_set_value(this%iprflow,
'PRINT_FLOWS', this%input_mempath, &
756 call mem_set_value(this%ipakcb,
'SAVE_FLOWS', this%input_mempath, &
759 if (found%save_flows) this%ipakcb = -1
762 write (this%iout,
'(1x,a)')
'PROCESSING SSM OPTIONS'
763 if (found%print_flows)
write (this%iout, fmtiprflow)
764 if (found%save_flows)
write (this%iout, fmtisvflow)
765 write (this%iout,
'(1x,a)')
'END OF SSM OPTIONS'
779 contiguous :: pnames, srctypes, auxnames
780 character(len=LINELENGTH) :: pname, srctype, auxname
781 integer(I4B) :: n, ip
782 logical(LGP) :: found
786 call mem_setptr(pnames,
'PNAME_SOURCES', this%input_mempath)
787 call mem_setptr(srctypes,
'SRCTYPE', this%input_mempath)
788 call mem_setptr(auxnames,
'AUXNAME', this%input_mempath)
790 write (this%iout,
'(/1x,a)')
'PROCESSING SSM SOURCES'
791 do n = 1,
size(pnames)
794 srctype = srctypes(n)
795 auxname = auxnames(n)
798 do ip = 1, this%fmi%nflowpack
799 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname)
then
805 if (.not. found)
then
806 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
813 if (this%isrctype(ip) /= 0)
then
814 write (
errmsg,
'(a, a)') &
815 'A package cannot be specified more than once in the SSM SOURCES &
816 &block. The following package was specified more than once: ', &
822 if (srctype ==
'AUX')
then
823 this%isrctype(ip) = 1
824 write (this%iout,
'(4x,a)')
'AUX SOURCE DETECTED.'
825 else if (srctype ==
'AUXMIXED')
then
826 this%isrctype(ip) = 2
827 write (this%iout,
'(4x,a)')
'AUXMIXED SOURCE DETECTED.'
829 write (
errmsg,
'(a, a)') &
830 'SRCTYPE must be AUX or AUXMIXED. Found: ', trim(srctype)
836 call this%set_iauxpak(ip, srctype, auxname)
838 write (this%iout,
'(1x,a)')
'END PROCESSING SSM SOURCES'
859 contiguous :: pnames, ftypes, iotypes, fnames, conditions
860 character(len=LINELENGTH) :: pname, ftype, iotype, fname, condition
861 integer(I4B) :: n, ip, isize
862 logical(LGP) :: found
865 call get_isize(
'PNAME', this%input_mempath, isize)
866 if (isize == -1)
then
867 write (this%iout,
'(/1x,a)') &
868 'OPTIONAL SSM FILEINPUT BLOCK INPUT NOT FOUND.'
873 call mem_setptr(pnames,
'PNAME', this%input_mempath)
874 call mem_setptr(ftypes,
'SPC6', this%input_mempath)
875 call mem_setptr(iotypes,
'FILEIN', this%input_mempath)
876 call mem_setptr(fnames,
'SPC6_FILENAME', this%input_mempath)
877 call mem_setptr(conditions,
'MIXED', this%input_mempath)
879 write (this%iout,
'(/1x,a)')
'PROCESSING SSM FILEINPUT'
880 do n = 1,
size(pnames)
886 condition = conditions(n)
889 do ip = 1, this%fmi%nflowpack
890 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname)
then
896 if (.not. found)
then
897 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
904 if (this%isrctype(ip) /= 0)
then
905 write (
errmsg,
'(a, a)') &
906 'A package cannot be specified more than once in the SSM SOURCES &
907 &block. The following package was specified more than once: ', &
914 if (ftype ==
'SPC6')
then
915 write (this%iout,
'(4x,a)')
'SPC6 SOURCE DETECTED:'
918 'SRCTYPE must be SPC6. Found: ', trim(ftype)
924 if (iotype /=
'FILEIN')
then
925 errmsg =
'SPC6 keyword must be followed by "FILEIN" '// &
926 'then by filename and optionally by <MIXED>.'
933 call this%set_ssmivec(ip, pname, fname)
935 if (condition ==
'MIXED')
then
936 this%isrctype(ip) = 4
937 write (this%iout,
'(4x,a,a)')
'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
940 this%isrctype(ip) = 3
943 write (this%iout,
'(1x,a)')
'END PROCESSING SSM FILEINPUT'
960 integer(I4B),
intent(in) :: ip
961 character(len=*),
intent(in) :: packname
962 character(len=*),
intent(in) :: auxname
969 do iaux = 1, this%fmi%gwfpackages(ip)%naux
970 if (trim(this%fmi%gwfpackages(ip)%auxname(iaux)) == &
976 if (.not. auxfound)
then
977 write (
errmsg,
'(a, a)') &
978 'Auxiliary name cannot be found: ', trim(auxname)
984 this%iauxpak(ip) = iaux
985 write (this%iout,
'(4x, a, i0, a, a)')
'USING AUX COLUMN ', &
986 iaux,
' IN PACKAGE ', trim(packname)
998 integer(I4B),
intent(in) :: ip
999 character(len=*),
intent(in) :: packname
1000 character(len=*),
intent(in) :: filename
1003 integer(I4B) :: inunit
1007 call openfile(inunit, this%iout, filename,
'SPC', filstat_opt=
'OLD')
1010 ssmiptr => this%ssmivec(ip)
1011 call ssmiptr%initialize(this%dis, ip, inunit, this%iout, this%name_model, &
1012 trim(packname), this%depvartype)
1014 write (this%iout,
'(4x, a, a, a, a, a)')
'USING SPC INPUT FILE ', &
1015 trim(filename),
' TO SET ', trim(this%depvartype), &
1016 'S FOR PACKAGE ', trim(packname)
1027 character(len=LINELENGTH) :: title
1028 character(len=LINELENGTH) :: text
1029 integer(I4B) :: ntabcol
1032 if (this%iprflow /= 0)
then
1041 title =
'SSM PACKAGE ('//trim(this%packName)// &
1043 call table_cr(this%outputtab, this%packName, title)
1044 call this%outputtab%table_df(1, ntabcol, this%iout, transient=.true.)
1046 call this%outputtab%initialize_column(text, 10, alignment=
tabcenter)
1048 call this%outputtab%initialize_column(text, 20, alignment=
tableft)
1050 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1052 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1054 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1055 text =
'PACKAGE NAME'
1056 call this%outputtab%initialize_column(text, 16, alignment=
tabcenter)
This module contains the BudgetModule.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
@ tabcenter
centered table column
@ tableft
left justified table column
integer(i4b), parameter lenpackagename
maximum length of the package name
integer(i4b), parameter lenbudrowlabel
maximum length of the rowlabel string used in the budget table
integer(i4b), parameter lenvarname
maximum length of a variable name
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
integer(i4b), parameter lenauxname
maximum length of a aux variable
integer(i4b), parameter lenboundname
maximum length of a bound name
real(dp), parameter dzero
real constant zero
real(dp), parameter done
real constant 1
This module defines variable data types.
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains the base numerical package type.
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
subroutine, public table_cr(this, name, title)
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
This module contains the TspSpc Module.
This module contains the TspSsm Module.
subroutine ssm_fc(this, matrix_sln, idxglo, rhs)
@ brief Fill coefficients
subroutine ssm_ot_flow(this, icbcfl, ibudfl, icbcun)
@ brief Output flows
subroutine source_sources(this)
Source sources input block.
subroutine ssm_term(this, ipackage, ientry, rrate, rhsval, hcofval, cssm, qssm)
@ brief Calculate the SSM mass flow rate and hcof and rhs values
subroutine allocate_scalars(this)
@ brief Allocate scalars
subroutine ssm_cq(this, flowja)
@ brief Calculate flow
subroutine source_fileinput(this)
Source fileinput input block.
subroutine ssm_bd(this, isuppress_output, model_budget)
@ brief Calculate the global SSM budget terms
subroutine source_options(this)
Source input options.
subroutine pak_setup_outputtab(this)
@ brief Setup the output table
subroutine ssm_df(this)
@ brief Define SSM Package
subroutine get_ssm_conc(this, ipackage, ientry, nbound_flow, conc, lauxmixed)
@ brief Provide bound concentration (or temperature) and mixed flag
subroutine ssm_rp(this)
@ brief Read and prepare this SSM Package
character(len=lenpackagename) text
subroutine ssm_ar(this, dis, ibound, cnew)
@ brief Allocate and read SSM Package
subroutine allocate_arrays(this)
@ brief Allocate arrays
character(len=lenftype) ftype
subroutine set_ssmivec(this, ip, packname, filename)
@ brief Set ssmivec array value for package ip
subroutine ssm_ad(this)
@ brief Advance the SSM Package
subroutine ssm_da(this)
@ brief Deallocate
subroutine, public ssm_cr(ssmobj, name_model, input_mempath, inunit, iout, fmi, eqnsclfac, depvartype)
@ brief Create a new SSM package
subroutine set_iauxpak(this, ip, packname, auxname)
@ brief Set iauxpak array value for package ip
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 ...
Derived type for managing SPC input.
Derived type for the SSM Package.