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

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

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

1010  ! -- dummy
1011  class(TspSsmType), intent(inout) :: this !< TspSsmType
1012  integer(I4B), intent(in) :: ip !< package number
1013  character(len=*), intent(in) :: packname !< name of corresponding flow package
1014  character(len=*), intent(in) :: spc_mempath !< input mempath for this SPC instance
1015  character(len=*), intent(in) :: input_fname !< SPC input file name (for error messages)
1016  ! -- local
1017  type(TspSpcType), pointer :: ssmiptr
1018  !
1019  ! -- initialize the TspSpcType reader for this package
1020  ssmiptr => this%ssmivec(ip)
1021  call ssmiptr%initialize(this%dis, ip, spc_mempath, this%iout, &
1022  this%name_model, trim(packname), &
1023  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 856 of file tsp-ssm.f90.

857  ! -- modules
861  ! -- dummy
862  class(TspSsmType) :: this
863  ! -- locals
864  type(CharacterStringType), dimension(:), pointer, &
865  contiguous :: pnames, ftypes, iotypes, fnames, conditions, spc6_mempaths
866  character(len=LINELENGTH) :: pname, ftype, iotype, fname, condition
867  character(len=LENMEMPATH) :: spc_mempath
868  integer(I4B) :: n, ip, isize
869  logical(LGP) :: found
870  ! -- formats
871 
872  call get_isize('PNAME', this%input_mempath, isize)
873  if (isize <= 0) then
874  write (this%iout, '(/1x,a)') &
875  'OPTIONAL SSM FILEINPUT BLOCK NOT FOUND OR EMPTY.'
876  return
877  end if
878 
879  ! set pointers to input context
880  call mem_setptr(pnames, 'PNAME', this%input_mempath)
881  call mem_setptr(ftypes, 'SPC6', this%input_mempath)
882  call mem_setptr(iotypes, 'FILEIN', this%input_mempath)
883  call mem_setptr(fnames, 'SPC6_FILENAME', this%input_mempath)
884  call mem_setptr(conditions, 'MIXED', this%input_mempath)
885  call mem_setptr(spc6_mempaths, 'SPC6_MEMPATH', this%input_mempath)
886 
887  write (this%iout, '(/1x,a)') 'PROCESSING SSM FILEINPUT'
888  do n = 1, size(pnames)
889 
890  pname = pnames(n)
891  ftype = ftypes(n)
892  iotype = iotypes(n)
893  fname = fnames(n)
894  condition = conditions(n)
895  spc_mempath = spc6_mempaths(n)
896  found = .false.
897 
898  do ip = 1, this%fmi%nflowpack
899  if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname) then
900  found = .true.
901  exit
902  end if
903  end do
904 
905  if (.not. found) then
906  write (errmsg, '(a,a)') 'Flow package cannot be found: ', &
907  trim(pname)
908  call store_error(errmsg)
909  cycle
910  end if
911 
912  ! -- Ensure package was not specified more than once in SOURCES block
913  if (this%isrctype(ip) /= 0) then
914  write (errmsg, '(a, a)') &
915  'A package cannot be specified more than once in the SSM SOURCES &
916  &block. The following package was specified more than once: ', &
917  trim(pname)
918  call store_error(errmsg)
919  cycle
920  end if
921 
922  ! verify ftype
923  if (ftype == 'SPC6') then
924  write (this%iout, '(4x,a)') 'SPC6 SOURCE DETECTED:'
925  else
926  write (errmsg, '(a,a)') &
927  'SRCTYPE must be SPC6. Found: ', trim(ftype)
928  call store_error(errmsg)
929  cycle
930  end if
931 
932  ! verify iotype
933  if (iotype /= 'FILEIN') then
934  errmsg = 'SPC6 keyword must be followed by "FILEIN" '// &
935  'then by filename and optionally by <MIXED>.'
936  call store_error(errmsg)
937  cycle
938  end if
939 
940  ! -- Use set_ssmivec to initialize the ssmi object from the
941  ! input mempath
942  call this%set_ssmivec(ip, pname, spc_mempath, trim(fname))
943 
944  if (condition == 'MIXED') then
945  this%isrctype(ip) = 4
946  write (this%iout, '(4x,a,a)') 'ASSIGNED MIXED SSM TYPE TO PACKAGE ', &
947  trim(pname)
948  else
949  this%isrctype(ip) = 3
950  end if
951  end do
952  write (this%iout, '(1x,a)') 'END PROCESSING SSM FILEINPUT'
953 
954  ! -- terminate if errors
955  if (count_errors() > 0) then
956  call store_error_filename(this%input_fname)
957  end if
958 
959  call memorystore_release('PNAME', this%input_mempath)
960  call memorystore_release('SPC6', this%input_mempath)
961  call memorystore_release('FILEIN', this%input_mempath)
962  call memorystore_release('SPC6_FILENAME', this%input_mempath)
963  call memorystore_release('MIXED', this%input_mempath)
964  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 ...
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
777  ! -- dummy
778  class(TspSsmType) :: this
779  ! -- locals
780  type(CharacterStringType), dimension(:), pointer, &
781  contiguous :: pnames, srctypes, auxnames
782  character(len=LINELENGTH) :: pname, srctype, auxname
783  integer(I4B) :: n, ip
784  logical(LGP) :: found
785  ! -- formats
786 
787  ! set pointers to input context
788  call mem_setptr(pnames, 'PNAME_SOURCES', this%input_mempath)
789  call mem_setptr(srctypes, 'SRCTYPE', this%input_mempath)
790  call mem_setptr(auxnames, 'AUXNAME', this%input_mempath)
791 
792  write (this%iout, '(/1x,a)') 'PROCESSING SSM SOURCES'
793  do n = 1, size(pnames)
794 
795  pname = pnames(n)
796  srctype = srctypes(n)
797  auxname = auxnames(n)
798  found = .false.
799 
800  do ip = 1, this%fmi%nflowpack
801  if (trim(adjustl(this%fmi%gwfpackages(ip)%name)) == pname) then
802  found = .true.
803  exit
804  end if
805  end do
806 
807  if (.not. found) then
808  write (errmsg, '(a,a)') 'Flow package cannot be found: ', &
809  trim(pname)
810  call store_error(errmsg)
811  cycle
812  end if
813 
814  ! -- Ensure package was not specified more than once in SOURCES block
815  if (this%isrctype(ip) /= 0) then
816  write (errmsg, '(a, a)') &
817  'A package cannot be specified more than once in the SSM SOURCES &
818  &block. The following package was specified more than once: ', &
819  trim(pname)
820  call store_error(errmsg)
821  cycle
822  end if
823 
824  if (srctype == 'AUX') then
825  this%isrctype(ip) = 1
826  write (this%iout, '(4x,a)') 'AUX SOURCE DETECTED.'
827  else if (srctype == 'AUXMIXED') then
828  this%isrctype(ip) = 2
829  write (this%iout, '(4x,a)') 'AUXMIXED SOURCE DETECTED.'
830  else
831  write (errmsg, '(a, a)') &
832  'SRCTYPE must be AUX or AUXMIXED. Found: ', trim(srctype)
833  call store_error(errmsg)
834  cycle
835  end if
836 
837  ! -- Find and store the auxiliary column
838  call this%set_iauxpak(ip, srctype, auxname)
839  end do
840  write (this%iout, '(1x,a)') 'END PROCESSING SSM SOURCES'
841 
842  ! -- terminate if errors
843  if (count_errors() > 0) then
844  call store_error_filename(this%input_fname)
845  end if
846 
847  call memorystore_release('PNAME_SOURCES', this%input_mempath)
848  call memorystore_release('SRCTYPE', this%input_mempath)
849  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 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:32
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: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(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'