MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
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 More...
 
subroutine ssm_df (this)
 @ brief Define SSM Package More...
 
subroutine ssm_ar (this, dis, ibound, cnew)
 @ brief Allocate and read SSM Package More...
 
subroutine ssm_rp (this)
 @ brief Read and prepare this SSM Package More...
 
subroutine ssm_ad (this)
 @ brief Advance the SSM Package More...
 
subroutine ssm_term (this, ipackage, ientry, rrate, rhsval, hcofval, cssm, qssm)
 @ brief Calculate the SSM mass flow rate and hcof and rhs values More...
 
subroutine get_ssm_conc (this, ipackage, ientry, nbound_flow, conc, lauxmixed)
 @ brief Provide bound concentration (or temperature) and mixed flag More...
 
subroutine ssm_fc (this, matrix_sln, idxglo, rhs)
 @ brief Fill coefficients More...
 
subroutine ssm_cq (this, flowja)
 @ brief Calculate flow More...
 
subroutine ssm_bd (this, isuppress_output, model_budget)
 @ brief Calculate the global SSM budget terms More...
 
subroutine ssm_ot_flow (this, icbcfl, ibudfl, icbcun)
 @ brief Output flows More...
 
subroutine ssm_da (this)
 @ brief Deallocate More...
 
subroutine allocate_scalars (this)
 @ brief Allocate scalars More...
 
subroutine allocate_arrays (this)
 @ brief Allocate arrays More...
 
subroutine source_options (this)
 Source input options. More...
 
subroutine source_sources (this)
 Source sources input block. More...
 
subroutine source_fileinput (this)
 Source fileinput input block. More...
 
subroutine set_iauxpak (this, ip, packname, auxname)
 @ brief Set iauxpak array value for package ip More...
 
subroutine set_ssmivec (this, ip, packname, spc_mempath, input_fname)
 Set ssmivec array value for package ip. More...
 
subroutine pak_setup_outputtab (this)
 @ brief Setup the output table More...
 

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 711 of file tsp-ssm.f90.

712  ! -- modules
714  ! -- dummy
715  class(TspSsmType) :: this !< TspSsmType object
716  ! -- local
717  integer(I4B) :: nflowpack
718  integer(I4B) :: i
719  !
720  ! -- Allocate
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)
724  !
725  ! -- Initialize
726  do i = 1, nflowpack
727  this%iauxpak(i) = 0
728  this%isrctype(i) = 0
729  end do
730  !
731  ! -- Allocate the ssmivec array
732  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 691 of file tsp-ssm.f90.

692  ! -- modules
694  ! -- dummy
695  class(TspSsmType) :: this !< TspSsmType object
696  !
697  ! -- allocate scalars in NumericalPackageType
698  call this%NumericalPackageType%allocate_scalars()
699  !
700  ! -- Allocate
701  call mem_allocate(this%nbound, 'NBOUND', this%memoryPath)
702  !
703  ! -- Initialize
704  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 355 of file tsp-ssm.f90.

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

1018  ! -- dummy
1019  class(TspSsmType), intent(inout) :: this
1020  ! -- local
1021  character(len=LINELENGTH) :: title
1022  character(len=LINELENGTH) :: text
1023  integer(I4B) :: ntabcol
1024  !
1025  ! -- allocate and initialize the output table
1026  if (this%iprflow /= 0) then
1027  !
1028  ! -- dimension table
1029  ntabcol = 6
1030  !if (this%inamedbound > 0) then
1031  ! ntabcol = ntabcol + 1
1032  !end if
1033  !
1034  ! -- initialize the output table object
1035  title = 'SSM PACKAGE ('//trim(this%packName)// &
1036  ') FLOW RATES'
1037  call table_cr(this%outputtab, this%packName, title)
1038  call this%outputtab%table_df(1, ntabcol, this%iout, transient=.true.)
1039  text = 'NUMBER'
1040  call this%outputtab%initialize_column(text, 10, alignment=tabcenter)
1041  text = 'CELLID'
1042  call this%outputtab%initialize_column(text, 20, alignment=tableft)
1043  text = 'BOUND Q'
1044  call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1045  text = 'SSM CONC'
1046  call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1047  text = 'RATE'
1048  call this%outputtab%initialize_column(text, 15, alignment=tabcenter)
1049  text = 'PACKAGE NAME'
1050  call this%outputtab%initialize_column(text, 16, alignment=tabcenter)
1051  !if (this%inamedbound > 0) then
1052  ! text = 'NAME'
1053  ! call this%outputtab%initialize_column(text, 20, alignment=TABLEFT)
1054  !end if
1055  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 960 of file tsp-ssm.f90.

961  ! -- dummy
962  class(TspSsmType), intent(inout) :: this !< TspSsmType
963  integer(I4B), intent(in) :: ip !< package number
964  character(len=*), intent(in) :: packname !< name of package
965  character(len=*), intent(in) :: auxname !< name of aux
966  ! -- local
967  logical :: auxfound
968  integer(I4B) :: iaux
969  !
970  ! -- match package auxiliary
971  auxfound = .false.
972  do iaux = 1, this%fmi%gwfpackages(ip)%naux
973  if (trim(this%fmi%gwfpackages(ip)%auxname(iaux)) == &
974  trim(auxname)) then
975  auxfound = .true.
976  exit
977  end if
978  end do
979  if (.not. auxfound) then
980  write (errmsg, '(a, a)') &
981  'Auxiliary name cannot be found: ', trim(auxname)
982  call store_error(errmsg)
983  call store_error_filename(this%input_fname)
984  end if
985  !
986  ! -- set iauxpak and write message
987  this%iauxpak(ip) = iaux
988  write (this%iout, '(4x, a, i0, a, a)') 'USING AUX COLUMN ', &
989  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 996 of file tsp-ssm.f90.

997  ! -- dummy
998  class(TspSsmType), intent(inout) :: this !< TspSsmType
999  integer(I4B), intent(in) :: ip !< package number
1000  character(len=*), intent(in) :: packname !< name of corresponding flow package
1001  character(len=*), intent(in) :: spc_mempath !< input mempath for this SPC instance
1002  character(len=*), intent(in) :: input_fname !< SPC input file name (for error messages)
1003  ! -- local
1004  type(TspSpcType), pointer :: ssmiptr
1005  !
1006  ! -- initialize the TspSpcType reader for this package
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)

◆ source_fileinput()

subroutine tspssmmodule::source_fileinput ( class(tspssmtype this)

Initialize an SPC input file reader for each input entry.

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

852  ! -- modules
855  ! -- dummy
856  class(TspSsmType) :: this
857  ! -- locals
858  type(CharacterStringType), dimension(:), pointer, &
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
864  ! -- formats
865 
866  call get_isize('PNAME', this%input_mempath, isize)
867  if (isize <= 0) then
868  write (this%iout, '(/1x,a)') &
869  'OPTIONAL SSM FILEINPUT BLOCK NOT FOUND OR EMPTY.'
870  return
871  end if
872 
873  ! set pointers to input context
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)
880 
881  write (this%iout, '(/1x,a)') 'PROCESSING SSM FILEINPUT'
882  do n = 1, size(pnames)
883 
884  pname = pnames(n)
885  ftype = ftypes(n)
886  iotype = iotypes(n)
887  fname = fnames(n)
888  condition = conditions(n)
889  spc_mempath = spc6_mempaths(n)
890  found = .false.
891 
892  do ip = 1, this%fmi%nflowpack
893  if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname) then
894  found = .true.
895  exit
896  end if
897  end do
898 
899  if (.not. found) then
900  write (errmsg, '(a,a)') 'Flow package cannot be found: ', &
901  trim(pname)
902  call store_error(errmsg)
903  cycle
904  end if
905 
906  ! -- Ensure package was not specified more than once in SOURCES block
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: ', &
911  trim(pname)
912  call store_error(errmsg)
913  cycle
914  end if
915 
916  ! verify ftype
917  if (ftype == 'SPC6') then
918  write (this%iout, '(4x,a)') 'SPC6 SOURCE DETECTED:'
919  else
920  write (errmsg, '(a,a)') &
921  'SRCTYPE must be SPC6. Found: ', trim(ftype)
922  call store_error(errmsg)
923  cycle
924  end if
925 
926  ! verify iotype
927  if (iotype /= 'FILEIN') then
928  errmsg = 'SPC6 keyword must be followed by "FILEIN" '// &
929  'then by filename and optionally by <MIXED>.'
930  call store_error(errmsg)
931  cycle
932  end if
933 
934  ! -- Use set_ssmivec to initialize the ssmi object from the
935  ! input mempath
936  call this%set_ssmivec(ip, pname, spc_mempath, trim(fname))
937 
938  if (condition == 'MIXED') then
939  this%isrctype(ip) = 4
940  write (this%iout, '(4x,a,a)') 'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
941  trim(pname)
942  else
943  this%isrctype(ip) = 3
944  end if
945  end do
946  write (this%iout, '(1x,a)') 'END PROCESSING SSM FILEINPUT'
947 
948  ! -- terminate if errors
949  if (count_errors() > 0) then
950  call store_error_filename(this%input_fname)
951  end if
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 ...
Definition: CharString.f90:23
Here is the call graph for this function:

◆ source_options()

subroutine tspssmmodule::source_options ( class(tspssmtype this)

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

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

◆ source_sources()

subroutine tspssmmodule::source_sources ( class(tspssmtype this)

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

772  ! -- modules
773  !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
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 213 of file tsp-ssm.f90.

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

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

◆ 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 430 of file tsp-ssm.f90.

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

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

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

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

◆ 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(this%fmi%gwfpackages(ip)%nbound, &
199  this%fmi%gwfpackages(ip)%budtxt)
200  end if
201  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 255 of file tsp-ssm.f90.

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

Variable Documentation

◆ ftype

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

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

28  character(len=LENFTYPE) :: ftype = 'SSM'

◆ text

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

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

29  character(len=LENPACKAGENAME) :: text = ' SOURCE-SINK MIX'