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 =
''
82 subroutine ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, &
86 character(len=*),
intent(in) :: name_model
87 integer(I4B),
intent(in) :: inunit
88 integer(I4B),
intent(in) :: iout
90 real(dp),
intent(in),
pointer :: eqnsclfac
91 character(len=LENVARNAME),
intent(in) :: depvartype
97 call ssmobj%set_names(1, name_model,
'SSM',
'SSM')
100 call ssmobj%allocate_scalars()
103 ssmobj%inunit = inunit
106 ssmobj%eqnsclfac => eqnsclfac
109 call ssmobj%parser%Initialize(ssmobj%inunit, ssmobj%iout)
113 ssmobj%depvartype = depvartype
134 subroutine ssm_ar(this, dis, ibound, cnew)
140 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
141 real(DP),
dimension(:),
pointer,
contiguous :: cnew
143 character(len=*),
parameter :: fmtssm = &
144 "(1x,/1x,'SSM -- SOURCE-SINK MIXING PACKAGE, VERSION 1, 8/25/2017', &
145 &' INPUT READ FROM UNIT ', i0, //)"
148 write (this%iout, fmtssm) this%inunit
152 this%ibound => ibound
156 if (this%fmi%nflowpack == 0)
then
157 write (
errmsg,
'(a)')
'SSM package does not detect any boundary flows &
158 &that require SSM terms. Activate GWF-GWT &
159 &exchange or activate FMI package and provide a &
160 &budget file that contains boundary flows. If no &
161 &boundary flows are present in corresponding GWF &
162 &model then this SSM package should be removed.'
164 call this%parser%StoreErrorUnit()
168 call this%allocate_arrays()
171 call this%read_options()
174 call this%read_data()
177 call this%pak_setup_outputtab()
196 do ip = 1, this%fmi%nflowpack
197 if (this%fmi%iatp(ip) /= 0) cycle
198 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
199 ssmiptr => this%ssmivec(ip)
200 call ssmiptr%spc_rp()
227 do ip = 1, this%fmi%nflowpack
228 if (this%fmi%iatp(ip) /= 0) cycle
229 do i = 1, this%fmi%gwfpackages(ip)%nbound
230 node = this%fmi%gwfpackages(ip)%nodelist(i)
232 this%nbound = this%nbound + 1
239 do ip = 1, this%fmi%nflowpack
240 if (this%fmi%iatp(ip) /= 0) cycle
241 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
242 ssmiptr => this%ssmivec(ip)
243 call ssmiptr%spc_ad(this%fmi%gwfpackages(ip)%nbound, &
244 this%fmi%gwfpackages(ip)%budtxt)
256 subroutine ssm_term(this, ipackage, ientry, rrate, rhsval, hcofval, &
260 integer(I4B),
intent(in) :: ipackage
261 integer(I4B),
intent(in) :: ientry
262 real(DP),
intent(out),
optional :: rrate
263 real(DP),
intent(out),
optional :: rhsval
264 real(DP),
intent(out),
optional :: hcofval
265 real(DP),
intent(out),
optional :: cssm
266 real(DP),
intent(out),
optional :: qssm
268 logical(LGP) :: lauxmixed
270 integer(I4B) :: nbound_flow
282 nbound_flow = this%fmi%gwfpackages(ipackage)%nbound
283 n = this%fmi%gwfpackages(ipackage)%nodelist(ientry)
286 if (this%ibound(n) > 0)
then
289 qbnd = this%fmi%gwfpackages(ipackage)%get_flow(ientry)
290 call this%get_ssm_conc(ipackage, ientry, nbound_flow, ctmp, lauxmixed)
294 if (.not. lauxmixed)
then
300 if (qbnd >=
dzero)
then
305 if (ctmp <
dzero)
then
317 if (qbnd >=
dzero)
then
320 if (ctmp < this%cnew(n))
then
330 if (qbnd <=
dzero)
then
331 hcoftmp = qbnd * omega * this%eqnsclfac
333 rhstmp = -qbnd * ctmp * (
done - omega) * this%eqnsclfac
340 if (
present(hcofval)) hcofval = hcoftmp
341 if (
present(rhsval)) rhsval = rhstmp
342 if (
present(rrate)) rrate = hcoftmp * ctmp - rhstmp
343 if (
present(cssm)) cssm = ctmp
344 if (
present(qssm)) qssm = qbnd
360 integer(I4B),
intent(in) :: ipackage
361 integer(I4B),
intent(in) :: ientry
362 integer(I4B),
intent(in) :: nbound_flow
363 real(DP),
intent(out) :: conc
364 logical(LGP),
intent(out) :: lauxmixed
366 integer(I4B) :: isrctype
367 integer(I4B) :: iauxpos
371 isrctype = this%isrctype(ipackage)
373 select case (isrctype)
375 iauxpos = this%iauxpak(ipackage)
376 conc = this%fmi%gwfpackages(ipackage)%auxvar(iauxpos, ientry)
377 if (isrctype == 2) lauxmixed = .true.
379 conc = this%ssmivec(ipackage)%get_value(ientry, nbound_flow)
380 if (isrctype == 4) lauxmixed = .true.
389 subroutine ssm_fc(this, matrix_sln, idxglo, rhs)
393 integer(I4B),
intent(in),
dimension(:) :: idxglo
394 real(DP),
intent(inout),
dimension(:) :: rhs
399 integer(I4B) :: idiag
400 integer(I4B) :: nflowpack
401 integer(I4B) :: nbound
406 nflowpack = this%fmi%nflowpack
408 if (this%fmi%iatp(ip) /= 0) cycle
411 nbound = this%fmi%gwfpackages(ip)%nbound
413 n = this%fmi%gwfpackages(ip)%nodelist(i)
415 call this%ssm_term(ip, i, rhsval=rhsval, hcofval=hcofval)
416 idiag = idxglo(this%dis%con%ia(n))
417 call matrix_sln%add_value_pos(idiag, hcofval)
418 rhs(n) = rhs(n) + rhsval
434 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
439 integer(I4B) :: idiag
443 do ip = 1, this%fmi%nflowpack
446 if (this%fmi%iatp(ip) /= 0) cycle
449 do i = 1, this%fmi%gwfpackages(ip)%nbound
450 n = this%fmi%gwfpackages(ip)%nodelist(i)
452 call this%ssm_term(ip, i, rrate=rate)
453 idiag = this%dis%con%ia(n)
454 flowja(idiag) = flowja(idiag) + rate
466 subroutine ssm_bd(this, isuppress_output, model_budget)
472 integer(I4B),
intent(in) :: isuppress_output
473 type(
budgettype),
intent(inout) :: model_budget
475 character(len=LENBUDROWLABEL) :: rowlabel
485 do ip = 1, this%fmi%nflowpack
488 if (this%fmi%iatp(ip) /= 0) cycle
495 do i = 1, this%fmi%gwfpackages(ip)%nbound
496 n = this%fmi%gwfpackages(ip)%nodelist(i)
498 call this%ssm_term(ip, i, rrate=rate)
499 if (rate <
dzero)
then
507 rowlabel =
'SSM_'//adjustl(trim(this%fmi%flowpacknamearray(ip)))
508 call model_budget%addentry(rin, rout,
delt, &
509 this%fmi%gwfpackages(ip)%budtxt, &
510 isuppress_output, rowlabel=rowlabel)
526 integer(I4B),
intent(in) :: icbcfl
527 integer(I4B),
intent(in) :: ibudfl
528 integer(I4B),
intent(in) :: icbcun
530 character(len=LINELENGTH) :: title
531 integer(I4B) :: node, nodeu
532 character(len=20) :: nodestr
533 integer(I4B) :: maxrows
535 integer(I4B) :: i, n2, ibinun
540 real(DP),
dimension(0) :: auxrow
541 character(len=LENAUXNAME),
dimension(0) :: auxname
543 character(len=LENBOUNDNAME) :: bname
545 character(len=*),
parameter :: fmttkk = &
546 &
"(1X,/1X,A,' PERIOD ',I0,' STEP ',I0)"
551 if (ibudfl /= 0 .and. this%iprflow /= 0)
then
552 call this%outputtab%set_kstpkper(
kstp,
kper)
553 do ip = 1, this%fmi%nflowpack
554 if (this%fmi%iatp(ip) /= 0) cycle
557 do i = 1, this%fmi%gwfpackages(ip)%nbound
558 node = this%fmi%gwfpackages(ip)%nodelist(i)
560 maxrows = maxrows + 1
564 if (maxrows > 0)
then
565 call this%outputtab%set_maxbound(maxrows)
567 title =
'SSM PACKAGE ('//trim(this%packName)// &
569 call this%outputtab%set_title(title)
573 if (this%ipakcb < 0)
then
575 else if (this%ipakcb == 0)
then
580 if (icbcfl == 0) ibinun = 0
583 if (ibinun /= 0)
then
584 call this%dis%record_srcdst_list_header(
text, this%name_model, &
585 this%name_model, this%name_model, &
586 this%packName, naux, auxname, &
587 ibinun, this%nbound, this%iout)
591 if (this%nbound > 0)
then
594 do ip = 1, this%fmi%nflowpack
595 if (this%fmi%iatp(ip) /= 0) cycle
598 do i = 1, this%fmi%gwfpackages(ip)%nbound
601 node = this%fmi%gwfpackages(ip)%nodelist(i)
603 call this%ssm_term(ip, i, rrate=rrate, qssm=qssm, cssm=cssm)
607 if (ibudfl /= 0)
then
608 if (this%iprflow /= 0)
then
611 nodeu = this%dis%get_nodeuser(node)
612 call this%dis%nodeu_to_string(nodeu, nodestr)
613 bname = this%fmi%gwfpackages(ip)%name
614 call this%outputtab%add_term(i)
615 call this%outputtab%add_term(trim(adjustl(nodestr)))
616 call this%outputtab%add_term(qssm)
617 call this%outputtab%add_term(cssm)
618 call this%outputtab%add_term(rrate)
619 call this%outputtab%add_term(bname)
624 if (ibinun /= 0)
then
626 call this%dis%record_mf6_list_entry(ibinun, node, n2, rrate, &
635 if (ibudfl /= 0)
then
636 if (this%iprflow /= 0)
then
637 write (this%iout,
'(1x)')
656 if (this%inunit > 0)
then
657 do ip = 1,
size(this%ssmivec)
658 if (this%isrctype(ip) == 3 .or. this%isrctype(ip) == 4)
then
659 ssmiptr => this%ssmivec(ip)
660 call ssmiptr%spc_da()
663 deallocate (this%ssmivec)
667 if (this%inunit > 0)
then
670 this%ibound => null()
675 if (
associated(this%outputtab))
then
676 call this%outputtab%table_da()
677 deallocate (this%outputtab)
678 nullify (this%outputtab)
685 call this%NumericalPackageType%da()
699 call this%NumericalPackageType%allocate_scalars()
702 call mem_allocate(this%nbound,
'NBOUND', this%memoryPath)
718 integer(I4B) :: nflowpack
722 nflowpack = this%fmi%nflowpack
723 call mem_allocate(this%iauxpak, nflowpack,
'IAUXPAK', this%memoryPath)
724 call mem_allocate(this%isrctype, nflowpack,
'ISRCTYPE', this%memoryPath)
733 allocate (this%ssmivec(nflowpack))
744 character(len=LINELENGTH) :: keyword
746 logical :: isfound, endOfBlock
748 character(len=*),
parameter :: fmtiprflow = &
749 "(4x,'SSM FLOW INFORMATION WILL BE PRINTED TO LISTING FILE &
750 &WHENEVER ICBCFL IS NOT ZERO.')"
751 character(len=*),
parameter :: fmtisvflow = &
752 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
753 &WHENEVER ICBCFL IS NOT ZERO.')"
756 call this%parser%GetBlock(
'OPTIONS', isfound, ierr, blockrequired=.false., &
757 supportopenclose=.true.)
761 write (this%iout,
'(1x,a)')
'PROCESSING SSM OPTIONS'
763 call this%parser%GetNextLine(endofblock)
765 call this%parser%GetStringCaps(keyword)
766 select case (keyword)
769 write (this%iout, fmtiprflow)
772 write (this%iout, fmtisvflow)
774 write (
errmsg,
'(a,a)')
'Unknown SSM option: ', trim(keyword)
776 call this%parser%StoreErrorUnit()
779 write (this%iout,
'(1x,a)')
'END OF SSM OPTIONS'
792 call this%read_sources_aux()
795 call this%read_sources_fileinput()
807 character(len=LINELENGTH) :: keyword
808 character(len=20) :: srctype
811 integer(I4B) :: nflowpack
812 integer(I4B) :: isrctype
813 logical :: isfound, endOfBlock
820 nflowpack = this%fmi%nflowpack
823 call this%parser%GetBlock(
'SOURCES', isfound, ierr, &
824 supportopenclose=.true., &
825 blockrequired=.true.)
827 write (this%iout,
'(1x,a)')
'PROCESSING SOURCES'
829 call this%parser%GetNextLine(endofblock)
833 call this%parser%GetStringCaps(keyword)
836 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == keyword)
then
841 if (.not. pakfound)
then
842 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
845 call this%parser%StoreErrorUnit()
849 if (this%isrctype(ip) /= 0)
then
850 write (
errmsg,
'(a, a)') &
851 'A package cannot be specified more than once in the SSM SOURCES &
852 &block. The following package was specified more than once: ', &
855 call this%parser%StoreErrorUnit()
859 call this%parser%GetStringCaps(srctype)
860 select case (srctype)
862 write (this%iout,
'(1x,a)')
'AUX SOURCE DETECTED.'
865 write (this%iout,
'(1x,a)')
'AUXMIXED SOURCE DETECTED.'
869 write (
errmsg,
'(a, a)') &
870 'SRCTYPE must be AUX or AUXMIXED. Found: ', trim(srctype)
872 call this%parser%StoreErrorUnit()
876 this%isrctype(ip) = isrctype
879 call this%set_iauxpak(ip, trim(keyword))
882 write (this%iout,
'(1x,a)')
'END PROCESSING SOURCES'
884 write (
errmsg,
'(a)')
'Required SOURCES block not found.'
886 call this%parser%StoreErrorUnit()
891 call this%parser%StoreErrorUnit()
904 character(len=LINELENGTH) :: keyword
905 character(len=LINELENGTH) :: keyword2
906 character(len=20) :: srctype
909 integer(I4B) :: nflowpack
910 integer(I4B) :: isrctype
911 logical :: isfound, endOfBlock
918 nflowpack = this%fmi%nflowpack
921 call this%parser%GetBlock(
'FILEINPUT', isfound, ierr, &
922 supportopenclose=.true., &
923 blockrequired=.false.)
925 write (this%iout,
'(1x,a)')
'PROCESSING FILEINPUT'
927 call this%parser%GetNextLine(endofblock)
931 call this%parser%GetStringCaps(keyword)
934 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == keyword)
then
939 if (.not. pakfound)
then
940 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
943 call this%parser%StoreErrorUnit()
947 if (this%isrctype(ip) /= 0)
then
948 write (
errmsg,
'(a, a)') &
949 'A package cannot be specified more than once in the SSM SOURCES &
950 &and SOURCES_FILES blocks. The following package was specified &
951 &more than once: ', &
954 call this%parser%StoreErrorUnit()
958 call this%parser%GetStringCaps(srctype)
959 select case (srctype)
961 write (this%iout,
'(1x,a)')
'SPC6 SOURCE DETECTED.'
965 call this%parser%GetStringCaps(keyword2)
966 if (trim(adjustl(keyword2)) /=
'FILEIN')
then
967 errmsg =
'SPC6 keyword must be followed by "FILEIN" '// &
968 'then by filename and optionally by <MIXED>.'
970 call this%parser%StoreErrorUnit()
975 call this%set_ssmivec(ip, trim(keyword))
978 call this%parser%GetStringCaps(keyword2)
979 if (trim(keyword2) ==
'MIXED')
then
981 write (this%iout,
'(1x,a,a)')
'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
986 'SRCTYPE must be SPC6. Found: ', trim(srctype)
988 call this%parser%StoreErrorUnit()
992 this%isrctype(ip) = isrctype
995 write (this%iout,
'(1x,a)')
'END PROCESSING FILEINPUT'
997 write (this%iout,
'(1x,a)') &
998 'OPTIONAL FILEINPUT BLOCK NOT FOUND. CONTINUING.'
1003 call this%parser%StoreErrorUnit()
1018 integer(I4B),
intent(in) :: ip
1019 character(len=*),
intent(in) :: packname
1021 character(len=LENAUXNAME) :: auxname
1023 integer(I4B) :: iaux
1026 call this%parser%GetStringCaps(auxname)
1028 do iaux = 1, this%fmi%gwfpackages(ip)%naux
1029 if (trim(this%fmi%gwfpackages(ip)%auxname(iaux)) == &
1035 if (.not. auxfound)
then
1036 write (
errmsg,
'(a, a)') &
1037 'Auxiliary name cannot be found: ', trim(auxname)
1039 call this%parser%StoreErrorUnit()
1043 this%iauxpak(ip) = iaux
1044 write (this%iout,
'(4x, a, i0, a, a)')
'USING AUX COLUMN ', &
1045 iaux,
' IN PACKAGE ', trim(packname)
1059 integer(I4B),
intent(in) :: ip
1060 character(len=*),
intent(in) :: packname
1062 character(len=LINELENGTH) :: filename
1064 integer(I4B) :: inunit
1067 call this%parser%GetString(filename)
1069 call openfile(inunit, this%iout, filename,
'SPC', filstat_opt=
'OLD')
1072 ssmiptr => this%ssmivec(ip)
1073 call ssmiptr%initialize(this%dis, ip, inunit, this%iout, this%name_model, &
1074 trim(packname), this%depvartype)
1076 write (this%iout,
'(4x, a, a, a, a, a)')
'USING SPC INPUT FILE ', &
1077 trim(filename),
' TO SET ', trim(this%depvartype), &
1078 'S FOR PACKAGE ', trim(packname)
1089 character(len=LINELENGTH) :: title
1090 character(len=LINELENGTH) :: text
1091 integer(I4B) :: ntabcol
1094 if (this%iprflow /= 0)
then
1103 title =
'SSM PACKAGE ('//trim(this%packName)// &
1105 call table_cr(this%outputtab, this%packName, title)
1106 call this%outputtab%table_df(1, ntabcol, this%iout, transient=.true.)
1108 call this%outputtab%initialize_column(text, 10, alignment=
tabcenter)
1110 call this%outputtab%initialize_column(text, 20, alignment=
tableft)
1112 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1114 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1116 call this%outputtab%initialize_column(text, 15, alignment=
tabcenter)
1117 text =
'PACKAGE NAME'
1118 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.
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_unit(iunit, terminate)
Store the file unit number.
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 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 ssm_bd(this, isuppress_output, model_budget)
@ brief Calculate the global SSM budget terms
subroutine pak_setup_outputtab(this)
@ brief Setup the output table
subroutine ssm_df(this)
@ brief Define SSM Package
subroutine set_ssmivec(this, ip, packname)
@ brief Set ssmivec array value for package ip
subroutine set_iauxpak(this, ip, packname)
@ brief Set iauxpak array value for package ip
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 read_sources_fileinput(this)
@ brief Read FILEINPUT block
character(len=lenpackagename) text
subroutine ssm_ar(this, dis, ibound, cnew)
@ brief Allocate and read SSM Package
subroutine read_sources_aux(this)
@ brief Read SOURCES block
subroutine, public ssm_cr(ssmobj, name_model, inunit, iout, fmi, eqnsclfac, depvartype)
@ brief Create a new SSM package
subroutine allocate_arrays(this)
@ brief Allocate arrays
character(len=lenftype) ftype
subroutine ssm_ad(this)
@ brief Advance the SSM Package
subroutine read_options(this)
@ brief Read package options
subroutine ssm_da(this)
@ brief Deallocate
subroutine read_data(this)
@ brief Read package data
Derived type for the Budget object.
Derived type for managing SPC input.
Derived type for the SSM Package.