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(this%fmi%gwfpackages(ip)%nbound, &
199 this%fmi%gwfpackages(ip)%budtxt)
226 do ip = 1, this%fmi%nflowpack
227 if (this%fmi%iatp(ip) /= 0) cycle
228 do i = 1, this%fmi%gwfpackages(ip)%nbound
229 node = this%fmi%gwfpackages(ip)%nodelist(i)
231 this%nbound = this%nbound + 1
238 do ip = 1, this%fmi%nflowpack
239 if (this%fmi%iatp(ip) /= 0) cycle
240 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
241 ssmiptr => this%ssmivec(ip)
242 call ssmiptr%spc_ad(this%fmi%gwfpackages(ip)%nbound, &
243 this%fmi%gwfpackages(ip)%budtxt)
255 subroutine ssm_term(this, ipackage, ientry, rrate, rhsval, hcofval, &
259 integer(I4B),
intent(in) :: ipackage
260 integer(I4B),
intent(in) :: ientry
261 real(DP),
intent(out),
optional :: rrate
262 real(DP),
intent(out),
optional :: rhsval
263 real(DP),
intent(out),
optional :: hcofval
264 real(DP),
intent(out),
optional :: cssm
265 real(DP),
intent(out),
optional :: qssm
267 logical(LGP) :: lauxmixed
269 integer(I4B) :: nbound_flow
281 nbound_flow = this%fmi%gwfpackages(ipackage)%nbound
282 n = this%fmi%gwfpackages(ipackage)%nodelist(ientry)
285 if (this%ibound(n) > 0)
then
288 qbnd = this%fmi%gwfpackages(ipackage)%get_flow(ientry)
289 call this%get_ssm_conc(ipackage, ientry, nbound_flow, ctmp, lauxmixed)
293 if (.not. lauxmixed)
then
299 if (qbnd >=
dzero)
then
304 if (ctmp <
dzero)
then
316 if (qbnd >=
dzero)
then
319 if (ctmp < this%cnew(n))
then
329 if (qbnd <=
dzero)
then
330 hcoftmp = qbnd * omega * this%eqnsclfac
332 rhstmp = -qbnd * ctmp * (
done - omega) * this%eqnsclfac
339 if (
present(hcofval)) hcofval = hcoftmp
340 if (
present(rhsval)) rhsval = rhstmp
341 if (
present(rrate)) rrate = hcoftmp * ctmp - rhstmp
342 if (
present(cssm)) cssm = ctmp
343 if (
present(qssm)) qssm = qbnd
359 integer(I4B),
intent(in) :: ipackage
360 integer(I4B),
intent(in) :: ientry
361 integer(I4B),
intent(in) :: nbound_flow
362 real(DP),
intent(out) :: conc
363 logical(LGP),
intent(out) :: lauxmixed
365 integer(I4B) :: isrctype
366 integer(I4B) :: iauxpos
370 isrctype = this%isrctype(ipackage)
372 select case (isrctype)
374 iauxpos = this%iauxpak(ipackage)
375 conc = this%fmi%gwfpackages(ipackage)%auxvar(iauxpos, ientry)
376 if (isrctype == 2) lauxmixed = .true.
378 conc = this%ssmivec(ipackage)%get_value(ientry, nbound_flow)
379 if (isrctype == 4) lauxmixed = .true.
388 subroutine ssm_fc(this, matrix_sln, idxglo, rhs)
392 integer(I4B),
intent(in),
dimension(:) :: idxglo
393 real(DP),
intent(inout),
dimension(:) :: rhs
398 integer(I4B) :: idiag
399 integer(I4B) :: nflowpack
400 integer(I4B) :: nbound
405 nflowpack = this%fmi%nflowpack
407 if (this%fmi%iatp(ip) /= 0) cycle
410 nbound = this%fmi%gwfpackages(ip)%nbound
412 n = this%fmi%gwfpackages(ip)%nodelist(i)
414 call this%ssm_term(ip, i, rhsval=rhsval, hcofval=hcofval)
415 idiag = idxglo(this%dis%con%ia(n))
416 call matrix_sln%add_value_pos(idiag, hcofval)
417 rhs(n) = rhs(n) + rhsval
433 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
438 integer(I4B) :: idiag
442 do ip = 1, this%fmi%nflowpack
445 if (this%fmi%iatp(ip) /= 0) cycle
448 do i = 1, this%fmi%gwfpackages(ip)%nbound
449 n = this%fmi%gwfpackages(ip)%nodelist(i)
451 call this%ssm_term(ip, i, rrate=rate)
452 idiag = this%dis%con%ia(n)
453 flowja(idiag) = flowja(idiag) + rate
465 subroutine ssm_bd(this, isuppress_output, model_budget)
471 integer(I4B),
intent(in) :: isuppress_output
472 type(
budgettype),
intent(inout) :: model_budget
474 character(len=LENBUDROWLABEL) :: rowlabel
484 do ip = 1, this%fmi%nflowpack
487 if (this%fmi%iatp(ip) /= 0) cycle
494 do i = 1, this%fmi%gwfpackages(ip)%nbound
495 n = this%fmi%gwfpackages(ip)%nodelist(i)
497 call this%ssm_term(ip, i, rrate=rate)
498 if (rate <
dzero)
then
506 rowlabel =
'SSM_'//adjustl(trim(this%fmi%flowpacknamearray(ip)))
507 call model_budget%addentry(rin, rout,
delt, &
508 this%fmi%gwfpackages(ip)%budtxt, &
509 isuppress_output, rowlabel=rowlabel)
525 integer(I4B),
intent(in) :: icbcfl
526 integer(I4B),
intent(in) :: ibudfl
527 integer(I4B),
intent(in) :: icbcun
529 character(len=LINELENGTH) :: title
530 integer(I4B) :: node, nodeu
531 character(len=20) :: nodestr
532 integer(I4B) :: maxrows
534 integer(I4B) :: i, n2, ibinun
539 real(DP),
dimension(0) :: auxrow
540 character(len=LENAUXNAME),
dimension(0) :: auxname
542 character(len=LENBOUNDNAME) :: bname
544 character(len=*),
parameter :: fmttkk = &
545 &
"(1X,/1X,A,' PERIOD ',I0,' STEP ',I0)"
550 if (ibudfl /= 0 .and. this%iprflow /= 0)
then
551 call this%outputtab%set_kstpkper(
kstp,
kper)
552 do ip = 1, this%fmi%nflowpack
553 if (this%fmi%iatp(ip) /= 0) cycle
556 do i = 1, this%fmi%gwfpackages(ip)%nbound
557 node = this%fmi%gwfpackages(ip)%nodelist(i)
559 maxrows = maxrows + 1
563 if (maxrows > 0)
then
564 call this%outputtab%set_maxbound(maxrows)
566 title =
'SSM PACKAGE ('//trim(this%packName)// &
568 call this%outputtab%set_title(title)
572 if (this%ipakcb < 0)
then
574 else if (this%ipakcb == 0)
then
579 if (icbcfl == 0) ibinun = 0
582 if (ibinun /= 0)
then
583 call this%dis%record_srcdst_list_header(
text, this%name_model, &
584 this%name_model, this%name_model, &
585 this%packName, naux, auxname, &
586 ibinun, this%nbound, this%iout)
590 if (this%nbound > 0)
then
593 do ip = 1, this%fmi%nflowpack
594 if (this%fmi%iatp(ip) /= 0) cycle
597 do i = 1, this%fmi%gwfpackages(ip)%nbound
600 node = this%fmi%gwfpackages(ip)%nodelist(i)
602 call this%ssm_term(ip, i, rrate=rrate, qssm=qssm, cssm=cssm)
606 if (ibudfl /= 0)
then
607 if (this%iprflow /= 0)
then
610 nodeu = this%dis%get_nodeuser(node)
611 call this%dis%nodeu_to_string(nodeu, nodestr)
612 bname = this%fmi%gwfpackages(ip)%name
613 call this%outputtab%add_term(i)
614 call this%outputtab%add_term(trim(adjustl(nodestr)))
615 call this%outputtab%add_term(qssm)
616 call this%outputtab%add_term(cssm)
617 call this%outputtab%add_term(rrate)
618 call this%outputtab%add_term(bname)
623 if (ibinun /= 0)
then
625 call this%dis%record_mf6_list_entry(ibinun, node, n2, rrate, &
634 if (ibudfl /= 0)
then
635 if (this%iprflow /= 0)
then
636 write (this%iout,
'(1x)')
655 if (this%inunit > 0)
then
656 do ip = 1,
size(this%ssmivec)
657 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
658 ssmiptr => this%ssmivec(ip)
659 call ssmiptr%spc_da()
662 deallocate (this%ssmivec)
666 if (this%inunit > 0)
then
669 this%ibound => null()
674 if (
associated(this%outputtab))
then
675 call this%outputtab%table_da()
676 deallocate (this%outputtab)
677 nullify (this%outputtab)
684 call this%NumericalPackageType%da()
698 call this%NumericalPackageType%allocate_scalars()
701 call mem_allocate(this%nbound,
'NBOUND', this%memoryPath)
717 integer(I4B) :: nflowpack
721 nflowpack = this%fmi%nflowpack
722 call mem_allocate(this%iauxpak, nflowpack,
'IAUXPAK', this%memoryPath)
723 call mem_allocate(this%isrctype, nflowpack,
'ISRCTYPE', this%memoryPath)
732 allocate (this%ssmivec(nflowpack))
747 character(len=*),
parameter :: fmtiprflow = &
748 "(4x,'SSM FLOW INFORMATION WILL BE PRINTED TO LISTING FILE &
749 &WHENEVER ICBCFL IS NOT ZERO.')"
750 character(len=*),
parameter :: fmtisvflow = &
751 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
752 &WHENEVER ICBCFL IS NOT ZERO.')"
755 call mem_set_value(this%iprflow,
'PRINT_FLOWS', this%input_mempath, &
757 call mem_set_value(this%ipakcb,
'SAVE_FLOWS', this%input_mempath, &
760 if (found%save_flows) this%ipakcb = -1
763 write (this%iout,
'(1x,a)')
'PROCESSING SSM OPTIONS'
764 if (found%print_flows)
write (this%iout, fmtiprflow)
765 if (found%save_flows)
write (this%iout, fmtisvflow)
766 write (this%iout,
'(1x,a)')
'END OF SSM OPTIONS'
780 contiguous :: pnames, srctypes, auxnames
781 character(len=LINELENGTH) :: pname, srctype, auxname
782 integer(I4B) :: n, ip
783 logical(LGP) :: found
787 call mem_setptr(pnames,
'PNAME_SOURCES', this%input_mempath)
788 call mem_setptr(srctypes,
'SRCTYPE', this%input_mempath)
789 call mem_setptr(auxnames,
'AUXNAME', this%input_mempath)
791 write (this%iout,
'(/1x,a)')
'PROCESSING SSM SOURCES'
792 do n = 1,
size(pnames)
795 srctype = srctypes(n)
796 auxname = auxnames(n)
799 do ip = 1, this%fmi%nflowpack
800 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname)
then
806 if (.not. found)
then
807 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
814 if (this%isrctype(ip) /= 0)
then
815 write (
errmsg,
'(a, a)') &
816 'A package cannot be specified more than once in the SSM SOURCES &
817 &block. The following package was specified more than once: ', &
823 if (srctype ==
'AUX')
then
824 this%isrctype(ip) = 1
825 write (this%iout,
'(4x,a)')
'AUX SOURCE DETECTED.'
826 else if (srctype ==
'AUXMIXED')
then
827 this%isrctype(ip) = 2
828 write (this%iout,
'(4x,a)')
'AUXMIXED SOURCE DETECTED.'
830 write (
errmsg,
'(a, a)') &
831 'SRCTYPE must be AUX or AUXMIXED. Found: ', trim(srctype)
837 call this%set_iauxpak(ip, srctype, auxname)
839 write (this%iout,
'(1x,a)')
'END PROCESSING SSM SOURCES'
859 contiguous :: pnames, ftypes, iotypes, fnames, conditions, spc6_mempaths
860 character(len=LINELENGTH) :: pname, ftype, iotype, fname, condition
861 character(len=LENMEMPATH) :: spc_mempath
862 integer(I4B) :: n, ip, isize
863 logical(LGP) :: found
866 call get_isize(
'PNAME', this%input_mempath, isize)
868 write (this%iout,
'(/1x,a)') &
869 'OPTIONAL SSM FILEINPUT BLOCK NOT FOUND OR EMPTY.'
874 call mem_setptr(pnames,
'PNAME', this%input_mempath)
875 call mem_setptr(ftypes,
'SPC6', this%input_mempath)
876 call mem_setptr(iotypes,
'FILEIN', this%input_mempath)
877 call mem_setptr(fnames,
'SPC6_FILENAME', this%input_mempath)
878 call mem_setptr(conditions,
'MIXED', this%input_mempath)
879 call mem_setptr(spc6_mempaths,
'SPC6_MEMPATH', this%input_mempath)
881 write (this%iout,
'(/1x,a)')
'PROCESSING SSM FILEINPUT'
882 do n = 1,
size(pnames)
888 condition = conditions(n)
889 spc_mempath = spc6_mempaths(n)
892 do ip = 1, this%fmi%nflowpack
893 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname)
then
899 if (.not. found)
then
900 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
907 if (this%isrctype(ip) /= 0)
then
908 write (
errmsg,
'(a, a)') &
909 'A package cannot be specified more than once in the SSM SOURCES &
910 &block. The following package was specified more than once: ', &
917 if (ftype ==
'SPC6')
then
918 write (this%iout,
'(4x,a)')
'SPC6 SOURCE DETECTED:'
921 'SRCTYPE must be SPC6. Found: ', trim(ftype)
927 if (iotype /=
'FILEIN')
then
928 errmsg =
'SPC6 keyword must be followed by "FILEIN" '// &
929 'then by filename and optionally by <MIXED>.'
936 call this%set_ssmivec(ip, pname, spc_mempath, trim(fname))
938 if (condition ==
'MIXED')
then
939 this%isrctype(ip) = 4
940 write (this%iout,
'(4x,a,a)')
'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
943 this%isrctype(ip) = 3
946 write (this%iout,
'(1x,a)')
'END PROCESSING SSM FILEINPUT'
963 integer(I4B),
intent(in) :: ip
964 character(len=*),
intent(in) :: packname
965 character(len=*),
intent(in) :: auxname
972 do iaux = 1, this%fmi%gwfpackages(ip)%naux
973 if (trim(this%fmi%gwfpackages(ip)%auxname(iaux)) == &
979 if (.not. auxfound)
then
980 write (
errmsg,
'(a, a)') &
981 'Auxiliary name cannot be found: ', trim(auxname)
987 this%iauxpak(ip) = iaux
988 write (this%iout,
'(4x, a, i0, a, a)')
'USING AUX COLUMN ', &
989 iaux,
' IN PACKAGE ', trim(packname)
996 subroutine set_ssmivec(this, ip, packname, spc_mempath, input_fname)
999 integer(I4B),
intent(in) :: ip
1000 character(len=*),
intent(in) :: packname
1001 character(len=*),
intent(in) :: spc_mempath
1002 character(len=*),
intent(in) :: input_fname
1007 ssmiptr => this%ssmivec(ip)
1008 call ssmiptr%initialize(this%dis, ip, spc_mempath, this%iout, &
1009 this%name_model, trim(packname), &
1010 this%depvartype, input_fname)
1021 character(len=LINELENGTH) :: title
1022 character(len=LINELENGTH) :: text
1023 integer(I4B) :: ntabcol
1026 if (this%iprflow /= 0)
then
1035 title =
'SSM PACKAGE ('//trim(this%packName)// &
1037 call table_cr(this%outputtab, this%packName, title)
1038 call this%outputtab%table_df(1, ntabcol, this%iout, transient=.true.)
1040 call this%outputtab%initialize_column(text, 10, alignment=
tabcenter)
1042 call this%outputtab%initialize_column(text, 20, alignment=
tableft)
1044 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1046 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1048 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1049 text =
'PACKAGE NAME'
1050 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
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 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
subroutine set_ssmivec(this, ip, packname, spc_mempath, input_fname)
Set ssmivec array value for package ip.
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 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.