MODFLOW 6  version 6.7.0.dev2
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, filename)
 @ brief 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 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 1023 of file tsp-ssm.f90.

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

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

This routine initializes the SPC input file.

Parameters
[in,out]thisTspSsmType
[in]ippackage number
[in]packnamename of package
[in]filenamepackage input file

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

994  ! -- module
996  ! -- dummy
997  class(TspSsmType), intent(inout) :: this !< TspSsmType
998  integer(I4B), intent(in) :: ip !< package number
999  character(len=*), intent(in) :: packname !< name of package
1000  character(len=*), intent(in) :: filename !< package input file
1001  ! -- local
1002  type(TspSpcType), pointer :: ssmiptr
1003  integer(I4B) :: inunit
1004  !
1005  ! -- open file
1006  inunit = getunit()
1007  call openfile(inunit, this%iout, filename, 'SPC', filstat_opt='OLD')
1008  !
1009  ! -- Create the SPC file object
1010  ssmiptr => this%ssmivec(ip)
1011  call ssmiptr%initialize(this%dis, ip, inunit, this%iout, this%name_model, &
1012  trim(packname), this%depvartype)
1013  !
1014  write (this%iout, '(4x, a, a, a, a, a)') 'USING SPC INPUT FILE ', &
1015  trim(filename), ' TO SET ', trim(this%depvartype), &
1016  'S FOR PACKAGE ', trim(packname)
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
Here is the call graph for this function:

◆ source_fileinput()

subroutine tspssmmodule::source_fileinput ( class(tspssmtype this)

Initialize an SPC input file reader for each input entry.

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

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

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'