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'
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'
864 contiguous :: pnames, ftypes, iotypes, fnames, conditions, spc6_mempaths
865 character(len=LINELENGTH) :: pname, ftype, iotype, fname, condition
866 character(len=LENMEMPATH) :: spc_mempath
867 integer(I4B) :: n, ip, isize
868 logical(LGP) :: found
871 call get_isize(
'PNAME', this%input_mempath, isize)
873 write (this%iout,
'(/1x,a)') &
874 'OPTIONAL SSM FILEINPUT BLOCK NOT FOUND OR EMPTY.'
879 call mem_setptr(pnames,
'PNAME', this%input_mempath)
880 call mem_setptr(ftypes,
'SPC6', this%input_mempath)
881 call mem_setptr(iotypes,
'FILEIN', this%input_mempath)
882 call mem_setptr(fnames,
'SPC6_FILENAME', this%input_mempath)
883 call mem_setptr(conditions,
'MIXED', this%input_mempath)
884 call mem_setptr(spc6_mempaths,
'SPC6_MEMPATH', this%input_mempath)
886 write (this%iout,
'(/1x,a)')
'PROCESSING SSM FILEINPUT'
887 do n = 1,
size(pnames)
893 condition = conditions(n)
894 spc_mempath = spc6_mempaths(n)
897 do ip = 1, this%fmi%nflowpack
898 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname)
then
904 if (.not. found)
then
905 write (
errmsg,
'(a,a)')
'Flow package cannot be found: ', &
912 if (this%isrctype(ip) /= 0)
then
913 write (
errmsg,
'(a, a)') &
914 'A package cannot be specified more than once in the SSM SOURCES &
915 &block. The following package was specified more than once: ', &
922 if (ftype ==
'SPC6')
then
923 write (this%iout,
'(4x,a)')
'SPC6 SOURCE DETECTED:'
926 'SRCTYPE must be SPC6. Found: ', trim(ftype)
932 if (iotype /=
'FILEIN')
then
933 errmsg =
'SPC6 keyword must be followed by "FILEIN" '// &
934 'then by filename and optionally by <MIXED>.'
941 call this%set_ssmivec(ip, pname, spc_mempath, trim(fname))
943 if (condition ==
'MIXED')
then
944 this%isrctype(ip) = 4
945 write (this%iout,
'(4x,a,a)')
'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
948 this%isrctype(ip) = 3
951 write (this%iout,
'(1x,a)')
'END PROCESSING SSM FILEINPUT'
975 integer(I4B),
intent(in) :: ip
976 character(len=*),
intent(in) :: packname
977 character(len=*),
intent(in) :: auxname
984 do iaux = 1, this%fmi%gwfpackages(ip)%naux
985 if (trim(this%fmi%gwfpackages(ip)%auxname(iaux)) == &
991 if (.not. auxfound)
then
992 write (
errmsg,
'(a, a)') &
993 'Auxiliary name cannot be found: ', trim(auxname)
999 this%iauxpak(ip) = iaux
1000 write (this%iout,
'(4x, a, i0, a, a)')
'USING AUX COLUMN ', &
1001 iaux,
' IN PACKAGE ', trim(packname)
1011 integer(I4B),
intent(in) :: ip
1012 character(len=*),
intent(in) :: packname
1013 character(len=*),
intent(in) :: spc_mempath
1014 character(len=*),
intent(in) :: input_fname
1019 ssmiptr => this%ssmivec(ip)
1020 call ssmiptr%initialize(this%dis, ip, spc_mempath, this%iout, &
1021 this%name_model, trim(packname), &
1022 this%depvartype, input_fname)
1033 character(len=LINELENGTH) :: title
1034 character(len=LINELENGTH) :: text
1035 integer(I4B) :: ntabcol
1038 if (this%iprflow /= 0)
then
1047 title =
'SSM PACKAGE ('//trim(this%packName)// &
1049 call table_cr(this%outputtab, this%packName, title)
1050 call this%outputtab%table_df(1, ntabcol, this%iout, transient=.true.)
1052 call this%outputtab%initialize_column(text, 10, alignment=tabcenter)
1054 call this%outputtab%initialize_column(text, 20, alignment=tableft)
1056 call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1058 call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1060 call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1061 text =
'PACKAGE NAME'
1062 call this%outputtab%initialize_column(text, 16, alignment=tabcenter)
subroutine allocate_scalars(this, name_model, input_mempath)
Allocate and initialize scalar variables.
subroutine allocate_arrays(this)
Allocate and initialize arrays.
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 memorystore_release(varname, memory_path)
Release a single variable from the memory store.
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
integer(i4b) iout
file unit number for simulation output
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
character(len=lenpackagename) text
This module contains the TspSpc Module.
character(len=lenftype) ftype
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 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.
subroutine ssm_ar(this, dis, ibound, cnew)
@ brief Allocate and read SSM Package
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.