MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
tspssmmodule Module Reference

This module contains the TspSsm Module. More...

Data Types

type  tspssmtype
 Derived type for the SSM Package. More...

Functions/Subroutines

subroutine, public ssm_cr (ssmobj, name_model, input_mempath, inunit, iout, fmi, eqnsclfac, depvartype)
 @ brief Create a new SSM package
subroutine ssm_df (this)
 @ brief Define SSM Package
subroutine ssm_ar (this, dis, ibound, cnew)
 @ brief Allocate and read SSM Package
subroutine ssm_rp (this)
 @ brief Read and prepare this SSM Package
subroutine ssm_ad (this)
 @ brief Advance the SSM Package
subroutine ssm_term (this, ipackage, ientry, rrate, rhsval, hcofval, cssm, qssm)
 @ brief Calculate the SSM mass flow rate and hcof and rhs values
subroutine get_ssm_conc (this, ipackage, ientry, nbound_flow, conc, lauxmixed)
 @ brief Provide bound concentration (or temperature) and mixed flag
subroutine ssm_fc (this, matrix_sln, idxglo, rhs)
 @ brief Fill coefficients
subroutine ssm_cq (this, flowja)
 @ brief Calculate flow
subroutine ssm_bd (this, isuppress_output, model_budget)
 @ brief Calculate the global SSM budget terms
subroutine ssm_ot_flow (this, icbcfl, ibudfl, icbcun)
 @ brief Output flows
subroutine ssm_da (this)
 @ brief Deallocate
subroutine allocate_scalars (this)
 @ brief Allocate scalars
subroutine allocate_arrays (this)
 @ brief Allocate arrays
subroutine source_options (this)
 Source input options.
subroutine source_sources (this)
 Source sources input block.
subroutine source_fileinput (this)
 Source fileinput input block.
subroutine set_iauxpak (this, ip, packname, auxname)
 @ brief Set iauxpak array value for package ip
subroutine set_ssmivec (this, ip, packname, spc_mempath, input_fname)
 Set ssmivec array value for package ip.
subroutine pak_setup_outputtab (this)
 @ brief Setup the output table

Variables

character(len=lenftype) ftype = 'SSM'
character(len=lenpackagename) text = ' SOURCE-SINK MIX'

Detailed Description

This module contains the code for handling sources and sinks associated with groundwater flow model stress packages.

todo: need observations for SSM terms

Function/Subroutine Documentation

◆ allocate_arrays()

subroutine tspssmmodule::allocate_arrays ( class(tspssmtype) this)

Allocate array variables for this derived type

Parameters
thisTspSsmType object

Definition at line 710 of file tsp-ssm.f90.

711 ! -- modules
713 ! -- dummy
714 class(TspSsmType) :: this !< TspSsmType object
715 ! -- local
716 integer(I4B) :: nflowpack
717 integer(I4B) :: i
718 !
719 ! -- Allocate
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)
723 !
724 ! -- Initialize
725 do i = 1, nflowpack
726 this%iauxpak(i) = 0
727 this%isrctype(i) = 0
728 end do
729 !
730 ! -- Allocate the ssmivec array
731 allocate (this%ssmivec(nflowpack))

◆ allocate_scalars()

subroutine tspssmmodule::allocate_scalars ( class(tspssmtype) this)

Allocate scalar variables for this derived type

Parameters
thisTspSsmType object

Definition at line 690 of file tsp-ssm.f90.

691 ! -- modules
693 ! -- dummy
694 class(TspSsmType) :: this !< TspSsmType object
695 !
696 ! -- allocate scalars in NumericalPackageType
697 call this%NumericalPackageType%allocate_scalars()
698 !
699 ! -- Allocate
700 call mem_allocate(this%nbound, 'NBOUND', this%memoryPath)
701 !
702 ! -- Initialize
703 this%nbound = 0

◆ get_ssm_conc()

subroutine tspssmmodule::get_ssm_conc ( class(tspssmtype) this,
integer(i4b), intent(in) ipackage,
integer(i4b), intent(in) ientry,
integer(i4b), intent(in) nbound_flow,
real(dp), intent(out) conc,
logical(lgp), intent(out) lauxmixed )

SSM concentrations and temperatures can be provided in auxiliary variables or through separate SPC files. If not provided, the default concentration (or temperature) is zero. This single routine provides the SSM bound concentration (or temperature) based on these different approaches. The mixed flag indicates whether or not the boundary as a mixed type.

Parameters
thisTspSsmType
[in]ipackagepackage number
[in]ientrybound number
[in]nbound_flowsize of flow package bound list
[out]concuser-specified concentration/temperature for this bound
[out]lauxmixeduser-specified flag for marking this as a mixed boundary

Definition at line 354 of file tsp-ssm.f90.

356 ! -- dummy
357 class(TspSsmType) :: this !< TspSsmType
358 integer(I4B), intent(in) :: ipackage !< package number
359 integer(I4B), intent(in) :: ientry !< bound number
360 integer(I4B), intent(in) :: nbound_flow !< size of flow package bound list
361 real(DP), intent(out) :: conc !< user-specified concentration/temperature for this bound
362 logical(LGP), intent(out) :: lauxmixed !< user-specified flag for marking this as a mixed boundary
363 ! -- local
364 integer(I4B) :: isrctype
365 integer(I4B) :: iauxpos
366 !
367 conc = dzero
368 lauxmixed = .false.
369 isrctype = this%isrctype(ipackage)
370 !
371 select case (isrctype)
372 case (1, 2)
373 iauxpos = this%iauxpak(ipackage)
374 conc = this%fmi%gwfpackages(ipackage)%auxvar(iauxpos, ientry)
375 if (isrctype == 2) lauxmixed = .true.
376 case (3, 4)
377 conc = this%ssmivec(ipackage)%get_value(ientry, nbound_flow)
378 if (isrctype == 4) lauxmixed = .true.
379 end select

◆ pak_setup_outputtab()

subroutine tspssmmodule::pak_setup_outputtab ( class(tspssmtype), intent(inout) this)

Setup the output table by creating the column headers.

Definition at line 1029 of file tsp-ssm.f90.

1030 ! -- dummy
1031 class(TspSsmType), intent(inout) :: this
1032 ! -- local
1033 character(len=LINELENGTH) :: title
1034 character(len=LINELENGTH) :: text
1035 integer(I4B) :: ntabcol
1036 !
1037 ! -- allocate and initialize the output table
1038 if (this%iprflow /= 0) then
1039 !
1040 ! -- dimension table
1041 ntabcol = 6
1042 !if (this%inamedbound > 0) then
1043 ! ntabcol = ntabcol + 1
1044 !end if
1045 !
1046 ! -- initialize the output table object
1047 title = 'SSM PACKAGE ('//trim(this%packName)// &
1048 ') FLOW RATES'
1049 call table_cr(this%outputtab, this%packName, title)
1050 call this%outputtab%table_df(1, ntabcol, this%iout, transient=.true.)
1051 text = 'NUMBER'
1052 call this%outputtab%initialize_column(text, 10, alignment=tabcenter)
1053 text = 'CELLID'
1054 call this%outputtab%initialize_column(text, 20, alignment=tableft)
1055 text = 'BOUND Q'
1056 call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1057 text = 'SSM CONC'
1058 call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1059 text = 'RATE'
1060 call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1061 text = 'PACKAGE NAME'
1062 call this%outputtab%initialize_column(text, 16, alignment=tabcenter)
1063 !if (this%inamedbound > 0) then
1064 ! text = 'NAME'
1065 ! call this%outputtab%initialize_column(text, 20, alignment=TABLEFT)
1066 !end if
1067 end if
Here is the call graph for this function:

◆ set_iauxpak()

subroutine tspssmmodule::set_iauxpak ( class(tspssmtype), intent(inout) this,
integer(i4b), intent(in) ip,
character(len=*), intent(in) packname,
character(len=*), intent(in) auxname )

The routine searches through the auxiliary names in package ip and sets iauxpak to the column number corresponding to the correct auxiliary column.

Parameters
[in,out]thisTspSsmType
[in]ippackage number
[in]packnamename of package
[in]auxnamename of aux

Definition at line 972 of file tsp-ssm.f90.

973 ! -- dummy
974 class(TspSsmType), intent(inout) :: this !< TspSsmType
975 integer(I4B), intent(in) :: ip !< package number
976 character(len=*), intent(in) :: packname !< name of package
977 character(len=*), intent(in) :: auxname !< name of aux
978 ! -- local
979 logical :: auxfound
980 integer(I4B) :: iaux
981 !
982 ! -- match package auxiliary
983 auxfound = .false.
984 do iaux = 1, this%fmi%gwfpackages(ip)%naux
985 if (trim(this%fmi%gwfpackages(ip)%auxname(iaux)) == &
986 trim(auxname)) then
987 auxfound = .true.
988 exit
989 end if
990 end do
991 if (.not. auxfound) then
992 write (errmsg, '(a, a)') &
993 'Auxiliary name cannot be found: ', trim(auxname)
994 call store_error(errmsg)
995 call store_error_filename(this%input_fname)
996 end if
997 !
998 ! -- set iauxpak and write message
999 this%iauxpak(ip) = iaux
1000 write (this%iout, '(4x, a, i0, a, a)') 'USING AUX COLUMN ', &
1001 iaux, ' IN PACKAGE ', trim(packname)
Here is the call graph for this function:

◆ set_ssmivec()

subroutine tspssmmodule::set_ssmivec ( class(tspssmtype), intent(inout) this,
integer(i4b), intent(in) ip,
character(len=*), intent(in) packname,
character(len=*), intent(in) spc_mempath,
character(len=*), intent(in) input_fname )

Initialize TspSpcType from the input mempath.

Parameters
[in,out]thisTspSsmType
[in]ippackage number
[in]packnamename of corresponding flow package
[in]spc_mempathinput mempath for this SPC instance
[in]input_fnameSPC input file name (for error messages)

Definition at line 1008 of file tsp-ssm.f90.

1009 ! -- dummy
1010 class(TspSsmType), intent(inout) :: this !< TspSsmType
1011 integer(I4B), intent(in) :: ip !< package number
1012 character(len=*), intent(in) :: packname !< name of corresponding flow package
1013 character(len=*), intent(in) :: spc_mempath !< input mempath for this SPC instance
1014 character(len=*), intent(in) :: input_fname !< SPC input file name (for error messages)
1015 ! -- local
1016 type(TspSpcType), pointer :: ssmiptr
1017 !
1018 ! -- initialize the TspSpcType reader for this package
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)

◆ source_fileinput()

subroutine tspssmmodule::source_fileinput ( class(tspssmtype) this)

Initialize an SPC input file reader for each input entry.

Definition at line 855 of file tsp-ssm.f90.

856 ! -- modules
860 ! -- dummy
861 class(TspSsmType) :: this
862 ! -- locals
863 type(CharacterStringType), dimension(:), pointer, &
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
869 ! -- formats
870
871 call get_isize('PNAME', this%input_mempath, isize)
872 if (isize <= 0) then
873 write (this%iout, '(/1x,a)') &
874 'OPTIONAL SSM FILEINPUT BLOCK NOT FOUND OR EMPTY.'
875 return
876 end if
877
878 ! set pointers to input context
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)
885
886 write (this%iout, '(/1x,a)') 'PROCESSING SSM FILEINPUT'
887 do n = 1, size(pnames)
888
889 pname = pnames(n)
890 ftype = ftypes(n)
891 iotype = iotypes(n)
892 fname = fnames(n)
893 condition = conditions(n)
894 spc_mempath = spc6_mempaths(n)
895 found = .false.
896
897 do ip = 1, this%fmi%nflowpack
898 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname) then
899 found = .true.
900 exit
901 end if
902 end do
903
904 if (.not. found) then
905 write (errmsg, '(a,a)') 'Flow package cannot be found: ', &
906 trim(pname)
907 call store_error(errmsg)
908 cycle
909 end if
910
911 ! -- Ensure package was not specified more than once in SOURCES block
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: ', &
916 trim(pname)
917 call store_error(errmsg)
918 cycle
919 end if
920
921 ! verify ftype
922 if (ftype == 'SPC6') then
923 write (this%iout, '(4x,a)') 'SPC6 SOURCE DETECTED:'
924 else
925 write (errmsg, '(a,a)') &
926 'SRCTYPE must be SPC6. Found: ', trim(ftype)
927 call store_error(errmsg)
928 cycle
929 end if
930
931 ! verify iotype
932 if (iotype /= 'FILEIN') then
933 errmsg = 'SPC6 keyword must be followed by "FILEIN" '// &
934 'then by filename and optionally by <MIXED>.'
935 call store_error(errmsg)
936 cycle
937 end if
938
939 ! -- Use set_ssmivec to initialize the ssmi object from the
940 ! input mempath
941 call this%set_ssmivec(ip, pname, spc_mempath, trim(fname))
942
943 if (condition == 'MIXED') then
944 this%isrctype(ip) = 4
945 write (this%iout, '(4x,a,a)') 'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
946 trim(pname)
947 else
948 this%isrctype(ip) = 3
949 end if
950 end do
951 write (this%iout, '(1x,a)') 'END PROCESSING SSM FILEINPUT'
952
953 ! -- terminate if errors
954 if (count_errors() > 0) then
955 call store_error_filename(this%input_fname)
956 end if
957
958 call memorystore_release('PNAME', this%input_mempath)
959 call memorystore_release('SPC6', this%input_mempath)
960 call memorystore_release('FILEIN', this%input_mempath)
961 call memorystore_release('SPC6_FILENAME', this%input_mempath)
962 call memorystore_release('MIXED', this%input_mempath)
963 call memorystore_release('SPC6_MEMPATH', this%input_mempath)
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 class is used to store a single deferred-length character string. It was designed to work in an ...
Here is the call graph for this function:

◆ source_options()

subroutine tspssmmodule::source_options ( class(tspssmtype) this)

Definition at line 736 of file tsp-ssm.f90.

737 ! -- modules
738 !use KindModule, only: LGP
741 ! -- dummy
742 class(TspSsmType) :: this
743 ! -- locals
744 type(GwtSsmParamFoundType) :: found
745 ! -- formats
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.')"
752 !
753 ! -- update defaults with idm sourced values
754 call mem_set_value(this%iprflow, 'PRINT_FLOWS', this%input_mempath, &
755 found%print_flows)
756 call mem_set_value(this%ipakcb, 'SAVE_FLOWS', this%input_mempath, &
757 found%save_flows)
758
759 if (found%save_flows) this%ipakcb = -1
760
761 ! log options
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'

◆ source_sources()

subroutine tspssmmodule::source_sources ( class(tspssmtype) this)

Definition at line 770 of file tsp-ssm.f90.

771 ! -- modules
772 !use KindModule, only: LGP
776 ! -- dummy
777 class(TspSsmType) :: this
778 ! -- locals
779 type(CharacterStringType), dimension(:), pointer, &
780 contiguous :: pnames, srctypes, auxnames
781 character(len=LINELENGTH) :: pname, srctype, auxname
782 integer(I4B) :: n, ip
783 logical(LGP) :: found
784 ! -- formats
785
786 ! set pointers to input context
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)
790
791 write (this%iout, '(/1x,a)') 'PROCESSING SSM SOURCES'
792 do n = 1, size(pnames)
793
794 pname = pnames(n)
795 srctype = srctypes(n)
796 auxname = auxnames(n)
797 found = .false.
798
799 do ip = 1, this%fmi%nflowpack
800 if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname) then
801 found = .true.
802 exit
803 end if
804 end do
805
806 if (.not. found) then
807 write (errmsg, '(a,a)') 'Flow package cannot be found: ', &
808 trim(pname)
809 call store_error(errmsg)
810 cycle
811 end if
812
813 ! -- Ensure package was not specified more than once in SOURCES block
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: ', &
818 trim(pname)
819 call store_error(errmsg)
820 cycle
821 end if
822
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.'
829 else
830 write (errmsg, '(a, a)') &
831 'SRCTYPE must be AUX or AUXMIXED. Found: ', trim(srctype)
832 call store_error(errmsg)
833 cycle
834 end if
835
836 ! -- Find and store the auxiliary column
837 call this%set_iauxpak(ip, srctype, auxname)
838 end do
839 write (this%iout, '(1x,a)') 'END PROCESSING SSM SOURCES'
840
841 ! -- terminate if errors
842 if (count_errors() > 0) then
843 call store_error_filename(this%input_fname)
844 end if
845
846 call memorystore_release('PNAME_SOURCES', this%input_mempath)
847 call memorystore_release('SRCTYPE', this%input_mempath)
848 call memorystore_release('AUXNAME', this%input_mempath)
Here is the call graph for this function:

◆ ssm_ad()

subroutine tspssmmodule::ssm_ad ( class(tspssmtype) this)

This routine is called from gwt_ad(). It is called at the beginning of each time step. The total number of flow boundaries is counted and stored in thisnbound. Also, if any SPC input files are used to provide source and sink concentrations (or temperatures) and time series are referenced in those files, then ssm concenrations must be interpolated for the time step.

Parameters
thisTspSsmType object

Definition at line 212 of file tsp-ssm.f90.

213 ! -- dummy
214 class(TspSsmType) :: this !< TspSsmType object
215 ! -- local
216 integer(I4B) :: ip
217 type(TspSpcType), pointer :: ssmiptr
218 integer(I4B) :: i
219 integer(I4B) :: node
220 !
221 ! -- Calculate total number of existing flow boundaries. It is possible
222 ! that a node may equal zero. In this case, the bound should be
223 ! skipped and not written to ssm output.
224 this%nbound = 0
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)
229 if (node > 0) then
230 this%nbound = this%nbound + 1
231 end if
232 end do
233 end do
234 !
235 ! -- Call the ad method on any ssm input files so that values for
236 ! time-series are interpolated
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)
243 end if
244 end do

◆ ssm_ar()

subroutine tspssmmodule::ssm_ar ( class(tspssmtype) this,
class(disbasetype), intent(in), pointer dis,
integer(i4b), dimension(:), pointer, contiguous ibound,
real(dp), dimension(:), pointer, contiguous cnew )

This routine is called from gwt_ar(). It allocates arrays, reads options and data, and sets up the output table.

Parameters
thisTspSsmType object
[in]disdiscretization package
iboundGWT model ibound
cnewGWT model dependent variable

Definition at line 130 of file tsp-ssm.f90.

131 ! -- modules
133 ! -- dummy
134 class(TspSsmType) :: this !< TspSsmType object
135 class(DisBaseType), pointer, intent(in) :: dis !< discretization package
136 integer(I4B), dimension(:), pointer, contiguous :: ibound !< GWT model ibound
137 real(DP), dimension(:), pointer, contiguous :: cnew !< GWT model dependent variable
138 ! -- formats
139 character(len=*), parameter :: fmtssm = &
140 "(1x,/1x,'SSM -- SOURCE-SINK MIXING PACKAGE, VERSION 1, 8/25/2017', &
141 &' INPUT READ FROM MEMPATH: ', A, //)"
142 !
143 ! -- print a message identifying the storage package.
144 write (this%iout, fmtssm) this%input_mempath
145 !
146 ! -- store pointers to arguments that were passed in
147 this%dis => dis
148 this%ibound => ibound
149 this%cnew => cnew
150 !
151 ! -- Check to make sure that there are flow packages
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.'
160 call store_error(errmsg)
161 call store_error_filename(this%input_fname)
162 end if
163 !
164 ! -- Allocate arrays
165 call this%allocate_arrays()
166 !
167 ! -- read ssm options
168 call this%source_options()
169 !
170 ! -- read data blocks
171 call this%source_sources()
172 call this%source_fileinput()
173 !
174 ! -- setup the output table
175 call this%pak_setup_outputtab()
Here is the call graph for this function:

◆ ssm_bd()

subroutine tspssmmodule::ssm_bd ( class(tspssmtype) this,
integer(i4b), intent(in) isuppress_output,
type(budgettype), intent(inout) model_budget )

Calculate the global SSM budget terms using separate in and out entries for each flow package.

Parameters
thisTspSsmType object
[in]isuppress_outputflag to suppress output
[in,out]model_budgetbudget object for the GWT model

Definition at line 464 of file tsp-ssm.f90.

465 ! -- modules
466 use tdismodule, only: delt
467 use budgetmodule, only: budgettype
468 ! -- dummy
469 class(TspSsmType) :: this !< TspSsmType object
470 integer(I4B), intent(in) :: isuppress_output !< flag to suppress output
471 type(BudgetType), intent(inout) :: model_budget !< budget object for the GWT model
472 ! -- local
473 character(len=LENBUDROWLABEL) :: rowlabel
474 integer(I4B) :: ip
475 integer(I4B) :: i
476 integer(I4B) :: n
477 real(DP) :: rate
478 real(DP) :: rin
479 real(DP) :: rout
480 !
481 ! -- do for each flow package, unless it is being handled by an advanced
482 ! transport package
483 do ip = 1, this%fmi%nflowpack
484 !
485 ! -- cycle if package is being managed as an advanced package
486 if (this%fmi%iatp(ip) /= 0) cycle
487 !
488 ! -- Initialize the rate accumulators
489 rin = dzero
490 rout = dzero
491 !
492 ! -- do for each boundary
493 do i = 1, this%fmi%gwfpackages(ip)%nbound
494 n = this%fmi%gwfpackages(ip)%nodelist(i)
495 if (n <= 0) cycle
496 call this%ssm_term(ip, i, rrate=rate)
497 if (rate < dzero) then
498 rout = rout - rate
499 else
500 rin = rin + rate
501 end if
502 !
503 end do
504 !
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)
509 end do
This module contains the BudgetModule.
Definition Budget.f90:20
real(dp), pointer, public delt
length of the current time step
Definition tdis.f90:32
Derived type for the Budget object.
Definition Budget.f90:40

◆ ssm_cq()

subroutine tspssmmodule::ssm_cq ( class(tspssmtype) this,
real(dp), dimension(:), intent(inout), contiguous flowja )

Calculate the resulting mass flow between the boundary and the connected GWT/GWE model cell. Update the diagonal position of the flowja array so that it ultimately contains the solute balance residual.

Parameters
thisTspSsmType object
[in,out]flowjaflow across each face in the model grid

Definition at line 429 of file tsp-ssm.f90.

430 ! -- dummy
431 class(TspSsmType) :: this !< TspSsmType object
432 real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow across each face in the model grid
433 ! -- local
434 integer(I4B) :: ip
435 integer(I4B) :: i
436 integer(I4B) :: n
437 integer(I4B) :: idiag
438 real(DP) :: rate
439 !
440 ! -- do for each flow package
441 do ip = 1, this%fmi%nflowpack
442 !
443 ! -- cycle if package is being managed as an advanced package
444 if (this%fmi%iatp(ip) /= 0) cycle
445 !
446 ! -- do for each boundary
447 do i = 1, this%fmi%gwfpackages(ip)%nbound
448 n = this%fmi%gwfpackages(ip)%nodelist(i)
449 if (n <= 0) cycle
450 call this%ssm_term(ip, i, rrate=rate)
451 idiag = this%dis%con%ia(n)
452 flowja(idiag) = flowja(idiag) + rate
453 !
454 end do
455 !
456 end do

◆ ssm_cr()

subroutine, public tspssmmodule::ssm_cr ( type(tspssmtype), pointer ssmobj,
character(len=*), intent(in) name_model,
character(len=*), intent(in) input_mempath,
integer(i4b), intent(in) inunit,
integer(i4b), intent(in) iout,
type(tspfmitype), intent(in), target fmi,
real(dp), intent(in), pointer eqnsclfac,
character(len=lenvarname), intent(in) depvartype )

Create a new SSM package by defining names, allocating scalars

Parameters
ssmobjTspSsmType object
[in]name_modelname of the model
[in]input_mempathinput mempath
[in]inunitfortran unit for input
[in]ioutfortran unit for output
[in]fmiTransport FMI package
[in]eqnsclfacgoverning equation scale factor
[in]depvartypedependent variable type ('concentration' or 'temperature')

Definition at line 80 of file tsp-ssm.f90.

82 ! -- dummy
83 type(TspSsmType), pointer :: ssmobj !< TspSsmType object
84 character(len=*), intent(in) :: name_model !< name of the model
85 character(len=*), intent(in) :: input_mempath !< input mempath
86 integer(I4B), intent(in) :: inunit !< fortran unit for input
87 integer(I4B), intent(in) :: iout !< fortran unit for output
88 type(TspFmiType), intent(in), target :: fmi !< Transport FMI package
89 real(DP), intent(in), pointer :: eqnsclfac !< governing equation scale factor
90 character(len=LENVARNAME), intent(in) :: depvartype !< dependent variable type ('concentration' or 'temperature')
91 !
92 ! -- Create the object
93 allocate (ssmobj)
94 !
95 ! -- create name and memory path
96 call ssmobj%set_names(1, name_model, 'SSM', 'SSM', input_mempath)
97 !
98 ! -- Allocate scalars
99 call ssmobj%allocate_scalars()
100 !
101 ! -- Set variables
102 ssmobj%inunit = inunit
103 ssmobj%iout = iout
104 ssmobj%fmi => fmi
105 ssmobj%eqnsclfac => eqnsclfac
106 !
107 ! -- Store pointer to labels associated with the current model so that the
108 ! package has access to the corresponding dependent variable type
109 ssmobj%depvartype = depvartype
Here is the caller graph for this function:

◆ ssm_da()

subroutine tspssmmodule::ssm_da ( class(tspssmtype) this)

Deallocate the memory associated with this derived type

Parameters
thisTspSsmType object

Definition at line 644 of file tsp-ssm.f90.

645 ! -- modules
647 ! -- dummy
648 class(TspSsmType) :: this !< TspSsmType object
649 ! -- local
650 integer(I4B) :: ip
651 type(TspSpcType), pointer :: ssmiptr
652 !
653 ! -- Deallocate the ssmi objects if package was active
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()
659 end if
660 end do
661 deallocate (this%ssmivec)
662 end if
663 !
664 ! -- Deallocate arrays if package was active
665 if (this%inunit > 0) then
666 call mem_deallocate(this%iauxpak)
667 call mem_deallocate(this%isrctype)
668 this%ibound => null()
669 this%fmi => null()
670 end if
671 !
672 ! -- output table object
673 if (associated(this%outputtab)) then
674 call this%outputtab%table_da()
675 deallocate (this%outputtab)
676 nullify (this%outputtab)
677 end if
678 !
679 ! -- Scalars
680 call mem_deallocate(this%nbound)
681 !
682 ! -- deallocate parent
683 call this%NumericalPackageType%da()

◆ ssm_df()

subroutine tspssmmodule::ssm_df ( class(tspssmtype) this)

This routine is called from gwt_df(), but does not do anything because df is typically used to set up dimensions. For the ssm package, the total number of ssm entries is defined by the flow model.

Parameters
thisTspSsmType object

Definition at line 118 of file tsp-ssm.f90.

119 ! -- modules
121 ! -- dummy
122 class(TspSsmType) :: this !< TspSsmType object

◆ ssm_fc()

subroutine tspssmmodule::ssm_fc ( class(tspssmtype) this,
class(matrixbasetype), pointer matrix_sln,
integer(i4b), dimension(:), intent(in) idxglo,
real(dp), dimension(:), intent(inout) rhs )

This routine adds the effects of the SSM to the matrix equations by updating the a matrix and right-hand side vector.

Definition at line 387 of file tsp-ssm.f90.

388 ! -- dummy
389 class(TspSsmType) :: this
390 class(MatrixBaseType), pointer :: matrix_sln
391 integer(I4B), intent(in), dimension(:) :: idxglo
392 real(DP), intent(inout), dimension(:) :: rhs
393 ! -- local
394 integer(I4B) :: ip
395 integer(I4B) :: i
396 integer(I4B) :: n
397 integer(I4B) :: idiag
398 integer(I4B) :: nflowpack
399 integer(I4B) :: nbound
400 real(DP) :: hcofval
401 real(DP) :: rhsval
402 !
403 ! -- do for each flow package
404 nflowpack = this%fmi%nflowpack
405 do ip = 1, nflowpack
406 if (this%fmi%iatp(ip) /= 0) cycle
407 !
408 ! -- do for each entry in package (ip)
409 nbound = this%fmi%gwfpackages(ip)%nbound
410 do i = 1, nbound
411 n = this%fmi%gwfpackages(ip)%nodelist(i)
412 if (n <= 0) cycle
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
417 !
418 end do
419 !
420 end do

◆ ssm_ot_flow()

subroutine tspssmmodule::ssm_ot_flow ( class(tspssmtype) this,
integer(i4b), intent(in) icbcfl,
integer(i4b), intent(in) ibudfl,
integer(i4b), intent(in) icbcun )

Based on user-specified controls, print SSM mass flow rates to the GWT listing file and/or write the SSM mass flow rates to the GWT binary budget file.

Parameters
thisTspSsmType object
[in]icbcflflag for writing binary budget terms
[in]ibudflflag for printing budget terms to list file
[in]icbcunfortran unit number for binary budget file

Definition at line 518 of file tsp-ssm.f90.

519 ! -- modules
520 use tdismodule, only: kstp, kper
522 ! -- dummy
523 class(TspSsmType) :: this !< TspSsmType object
524 integer(I4B), intent(in) :: icbcfl !< flag for writing binary budget terms
525 integer(I4B), intent(in) :: ibudfl !< flag for printing budget terms to list file
526 integer(I4B), intent(in) :: icbcun !< fortran unit number for binary budget file
527 ! -- local
528 character(len=LINELENGTH) :: title
529 integer(I4B) :: node, nodeu
530 character(len=20) :: nodestr
531 integer(I4B) :: maxrows
532 integer(I4B) :: ip
533 integer(I4B) :: i, n2, ibinun
534 real(DP) :: rrate
535 real(DP) :: qssm
536 real(DP) :: cssm
537 integer(I4B) :: naux
538 real(DP), dimension(0) :: auxrow
539 character(len=LENAUXNAME), dimension(0) :: auxname
540 ! -- for observations
541 character(len=LENBOUNDNAME) :: bname
542 ! -- formats
543 character(len=*), parameter :: fmttkk = &
544 &"(1X,/1X,A,' PERIOD ',I0,' STEP ',I0)"
545 !
546 ! -- initialize
547 naux = 0
548 maxrows = 0
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
553 !
554 ! -- do for each boundary
555 do i = 1, this%fmi%gwfpackages(ip)%nbound
556 node = this%fmi%gwfpackages(ip)%nodelist(i)
557 if (node > 0) then
558 maxrows = maxrows + 1
559 end if
560 end do
561 end do
562 if (maxrows > 0) then
563 call this%outputtab%set_maxbound(maxrows)
564 end if
565 title = 'SSM PACKAGE ('//trim(this%packName)// &
566 ') FLOW RATES'
567 call this%outputtab%set_title(title)
568 end if
569 !
570 ! -- Set unit number for binary output
571 if (this%ipakcb < 0) then
572 ibinun = icbcun
573 else if (this%ipakcb == 0) then
574 ibinun = 0
575 else
576 ibinun = this%ipakcb
577 end if
578 if (icbcfl == 0) ibinun = 0
579 !
580 ! -- If cell-by-cell flows will be saved as a list, write header.
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)
586 end if
587 !
588 ! -- If no boundaries, skip flow calculations.
589 if (this%nbound > 0) then
590 !
591 ! -- Loop through each boundary calculating flow.
592 do ip = 1, this%fmi%nflowpack
593 if (this%fmi%iatp(ip) /= 0) cycle
594 !
595 ! -- do for each boundary
596 do i = 1, this%fmi%gwfpackages(ip)%nbound
597 !
598 ! -- Calculate rate for this entry
599 node = this%fmi%gwfpackages(ip)%nodelist(i)
600 if (node <= 0) cycle
601 call this%ssm_term(ip, i, rrate=rrate, qssm=qssm, cssm=cssm)
602 !
603 ! -- Print the individual rates if the budget is being printed
604 ! and PRINT_FLOWS was specified (this%iprflow<0)
605 if (ibudfl /= 0) then
606 if (this%iprflow /= 0) then
607 !
608 ! -- set nodestr and write outputtab table
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)
618 end if
619 end if
620 !
621 ! -- If saving cell-by-cell flows in list, write flow
622 if (ibinun /= 0) then
623 n2 = i
624 call this%dis%record_mf6_list_entry(ibinun, node, n2, rrate, &
625 naux, auxrow, &
626 olconv2=.false.)
627 end if
628 !
629 end do
630 !
631 end do
632 end if
633 if (ibudfl /= 0) then
634 if (this%iprflow /= 0) then
635 write (this%iout, '(1x)')
636 end if
637 end if
This module contains simulation constants.
Definition Constants.f90:9
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition Constants.f90:23
integer(i4b), parameter lenauxname
maximum length of a aux variable
Definition Constants.f90:35
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition Constants.f90:36
real(dp), parameter dzero
real constant zero
Definition Constants.f90:65
integer(i4b), pointer, public kstp
current time step number
Definition tdis.f90:27
integer(i4b), pointer, public kper
current stress period number
Definition tdis.f90:26

◆ ssm_rp()

subroutine tspssmmodule::ssm_rp ( class(tspssmtype) this)

This routine is called from gwt_rp(). It is called at the beginning of each stress period. If any SPC input files are used to provide source and sink concentrations (or temperatures), then period blocks for the current stress period are read.

Parameters
thisTspSsmType object

Definition at line 185 of file tsp-ssm.f90.

186 ! -- dummy
187 class(TspSsmType) :: this !< TspSsmType object
188 ! -- local
189 integer(I4B) :: ip
190 type(TspSpcType), pointer :: ssmiptr
191 ! -- formats
192 !
193 ! -- Call the rp method on any ssm input files
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()
199 end if
200 end do

◆ ssm_term()

subroutine tspssmmodule::ssm_term ( class(tspssmtype) this,
integer(i4b), intent(in) ipackage,
integer(i4b), intent(in) ientry,
real(dp), intent(out), optional rrate,
real(dp), intent(out), optional rhsval,
real(dp), intent(out), optional hcofval,
real(dp), intent(out), optional cssm,
real(dp), intent(out), optional qssm )

This is the primary SSM routine that calculates the matrix coefficient and right-hand-side value for any package and package entry. It returns several different optional variables that are used throughout this package to update matrix terms, budget calculations, and output tables.

Parameters
thisTspSsmType
[in]ipackagepackage number
[in]ientrybound number
[out]rratecalculated mass flow rate
[out]rhsvalcalculated rhs value
[out]hcofvalcalculated hcof value
[out]cssmcalculated source concentration/temperature depending on flow direction
[out]qssmwater flow rate into model cell from boundary package

Definition at line 254 of file tsp-ssm.f90.

256 ! -- dummy
257 class(TspSsmType) :: this !< TspSsmType
258 integer(I4B), intent(in) :: ipackage !< package number
259 integer(I4B), intent(in) :: ientry !< bound number
260 real(DP), intent(out), optional :: rrate !< calculated mass flow rate
261 real(DP), intent(out), optional :: rhsval !< calculated rhs value
262 real(DP), intent(out), optional :: hcofval !< calculated hcof value
263 real(DP), intent(out), optional :: cssm !< calculated source concentration/temperature depending on flow direction
264 real(DP), intent(out), optional :: qssm !< water flow rate into model cell from boundary package
265 ! -- local
266 logical(LGP) :: lauxmixed
267 integer(I4B) :: n
268 integer(I4B) :: nbound_flow
269 real(DP) :: qbnd
270 real(DP) :: ctmp
271 real(DP) :: omega
272 real(DP) :: hcoftmp
273 real(DP) :: rhstmp
274 !
275 ! -- retrieve node number, qbnd and iauxpos
276 hcoftmp = dzero
277 rhstmp = dzero
278 ctmp = dzero
279 qbnd = dzero
280 nbound_flow = this%fmi%gwfpackages(ipackage)%nbound
281 n = this%fmi%gwfpackages(ipackage)%nodelist(ientry)
282 !
283 ! -- If cell is active (ibound > 0) then calculate values
284 if (this%ibound(n) > 0) then
285 !
286 ! -- retrieve qbnd and iauxpos
287 qbnd = this%fmi%gwfpackages(ipackage)%get_flow(ientry)
288 call this%get_ssm_conc(ipackage, ientry, nbound_flow, ctmp, lauxmixed)
289 !
290 ! -- assign values for hcoftmp, rhstmp, and ctmp for subsequent assignment
291 ! of hcof, rhs, and rate
292 if (.not. lauxmixed) then
293 !
294 ! -- If qbnd is positive, then concentration (or temperature) represents
295 ! the inflow concentration (or temperature). If qbnd is negative,
296 ! then the outflow concentration (or temperature) is set equal to the
297 ! simulated cell's concentration (or temperature).
298 if (qbnd >= dzero) then
299 omega = dzero ! rhs
300 else
301 ctmp = this%cnew(n)
302 omega = done ! lhs
303 if (ctmp < dzero) then
304 omega = dzero ! concentration/temperature is negative, so set mass flux to zero
305 end if
306 end if
307 else
308 !
309 ! -- lauxmixed value indicates that this is a mixed sink type where
310 ! the concentration (or temperature) value represents the injected
311 ! concentration (or temperature) if qbnd is positive. If qbnd is
312 ! negative, then the withdrawn water is equal to the minimum of the
313 ! aux concentration (or temperature) and the cell concentration
314 ! (or temperature).
315 if (qbnd >= dzero) then
316 omega = dzero ! rhs (ctmp is aux value)
317 else
318 if (ctmp < this%cnew(n)) then
319 omega = dzero ! rhs (ctmp is aux value)
320 else
321 omega = done ! lhs (ctmp is cell concentration)
322 ctmp = this%cnew(n)
323 end if
324 end if
325 end if
326 !
327 ! -- Add terms based on qbnd sign
328 if (qbnd <= dzero) then
329 hcoftmp = qbnd * omega * this%eqnsclfac
330 else
331 rhstmp = -qbnd * ctmp * (done - omega) * this%eqnsclfac
332 end if
333 !
334 ! -- end of active ibound
335 end if
336 !
337 ! -- set requested values
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

Variable Documentation

◆ ftype

character(len=lenftype) tspssmmodule::ftype = 'SSM'

Definition at line 28 of file tsp-ssm.f90.

◆ text

character(len=lenpackagename) tspssmmodule::text = ' SOURCE-SINK MIX'

Definition at line 29 of file tsp-ssm.f90.