MODFLOW 6  version 6.7.0.dev3
USGS Modular Hydrologic Model
gwtmstmodule Module Reference

– @ brief Mobile Storage and Transfer (MST) Module More...

Data Types

type  gwtmsttype
 @ brief Mobile storage and transfer More...
 

Enumerations

enum  { decay_off = 0 , decay_first_order = 1 , decay_zero_order = 2 }
 Enumerator that defines the decay options. More...
 

Functions/Subroutines

subroutine, public mst_cr (mstobj, name_model, input_mempath, inunit, iout, fmi)
 @ brief Create a new package object More...
 
subroutine mst_ar (this, dis, ibound)
 @ brief Allocate and read method for package More...
 
subroutine mst_fc (this, nodes, cold, nja, matrix_sln, idxglo, cnew, rhs, kiter)
 @ brief Fill coefficient method for package More...
 
subroutine mst_fc_sto (this, nodes, cold, nja, matrix_sln, idxglo, rhs)
 @ brief Fill storage coefficient method for package More...
 
subroutine mst_fc_dcy (this, nodes, cold, cnew, nja, matrix_sln, idxglo, rhs, kiter)
 @ brief Fill decay coefficient method for package More...
 
subroutine mst_fc_srb (this, nodes, cold, nja, matrix_sln, idxglo, rhs, cnew)
 @ brief Fill sorption coefficient method for package More...
 
subroutine mst_fc_dcy_srb (this, nodes, cold, nja, matrix_sln, idxglo, rhs, cnew, kiter)
 @ brief Fill sorption-decay coefficient method for package More...
 
subroutine mst_cq (this, nodes, cnew, cold, flowja)
 @ brief Calculate flows for package More...
 
subroutine mst_cq_sto (this, nodes, cnew, cold, flowja)
 @ brief Calculate storage terms for package More...
 
subroutine mst_cq_dcy (this, nodes, cnew, cold, flowja)
 @ brief Calculate decay terms for package More...
 
subroutine mst_cq_srb (this, nodes, cnew, cold, flowja)
 @ brief Calculate sorption terms for package More...
 
subroutine mst_cq_dcy_srb (this, nodes, cnew, cold, flowja)
 @ brief Calculate decay-sorption terms for package More...
 
subroutine mst_calc_csrb (this, cnew)
 @ brief Calculate sorbed concentration More...
 
subroutine mst_bd (this, isuppress_output, model_budget)
 @ brief Calculate budget terms for package More...
 
subroutine mst_ot_flow (this, icbcfl, icbcun)
 @ brief Output flow terms for package More...
 
subroutine mst_ot_dv (this, idvsave)
 Save sorbate concentration array to binary file. More...
 
subroutine mst_da (this)
 @ brief Deallocate More...
 
subroutine allocate_scalars (this)
 @ brief Allocate scalar variables for package More...
 
subroutine allocate_arrays (this, nodes)
 @ brief Allocate arrays for package More...
 
subroutine source_options (this)
 @ brief Source options for package More...
 
subroutine log_options (this, found, sorbate_fname)
 Log user options to list file. More...
 
subroutine source_data (this)
 @ brief Source data for package More...
 
subroutine log_data (this, found)
 Log user data to list file. More...
 
subroutine addto_volfracim (this, volfracim)
 @ brief Add volfrac values to volfracim More...
 
real(dp) function get_volfracm (this, node)
 @ brief Return mobile domain volume fraction More...
 
real(dp) function get_zero_order_decay (decay_rate_usr, decay_rate_last, kiter, cold, cnew, delt)
 @ brief Calculate zero-order decay rate and constrain if necessary More...
 

Variables

integer(i4b), parameter nbditems = 4
 
character(len=lenbudtxt), dimension(nbditemsbudtxt
 

Detailed Description

The GwtMstModule contains the GwtMstType, which is the derived type responsible for adding the effects of

  1. Changes in dissolved solute mass
  2. Decay of dissolved solute mass
  3. Sorption
  4. Decay of sorbed solute mass

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
decay_off 

Decay (or production) of mass inactive (default)

decay_first_order 

First-order decay.

decay_zero_order 

Zeroth-order decay.

Definition at line 37 of file gwt-mst.f90.

Function/Subroutine Documentation

◆ addto_volfracim()

subroutine gwtmstmodule::addto_volfracim ( class(gwtmsttype this,
real(dp), dimension(:), intent(in)  volfracim 
)

Method to add immobile domain volume fracions, which are stored as a cumulative value in volfracim.

Parameters
thisGwtMstType object
[in]volfracimimmobile domain volume fraction that contributes to total immobile volume fraction

Definition at line 1408 of file gwt-mst.f90.

1409  ! -- dummy
1410  class(GwtMstType) :: this !< GwtMstType object
1411  real(DP), dimension(:), intent(in) :: volfracim !< immobile domain volume fraction that contributes to total immobile volume fraction
1412  ! -- local
1413  integer(I4B) :: n
1414  !
1415  ! -- Add to volfracim
1416  do n = 1, this%dis%nodes
1417  this%volfracim(n) = this%volfracim(n) + volfracim(n)
1418  end do
1419  !
1420  ! -- An immobile domain is adding a volume fraction, so update thetam
1421  ! accordingly.
1422  do n = 1, this%dis%nodes
1423  this%thetam(n) = this%get_volfracm(n) * this%porosity(n)
1424  end do

◆ allocate_arrays()

subroutine gwtmstmodule::allocate_arrays ( class(gwtmsttype this,
integer(i4b), intent(in)  nodes 
)

Method to allocate arrays for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes

Definition at line 1015 of file gwt-mst.f90.

1016  ! -- modules
1018  use constantsmodule, only: dzero
1019  ! -- dummy
1020  class(GwtMstType) :: this !< GwtMstType object
1021  integer(I4B), intent(in) :: nodes !< number of nodes
1022  ! -- local
1023  integer(I4B) :: n
1024  !
1025  ! -- Allocate
1026  ! -- sto
1027  call mem_allocate(this%porosity, nodes, 'POROSITY', this%memoryPath)
1028  call mem_allocate(this%thetam, nodes, 'THETAM', this%memoryPath)
1029  call mem_allocate(this%volfracim, nodes, 'VOLFRACIM', this%memoryPath)
1030  call mem_allocate(this%ratesto, nodes, 'RATESTO', this%memoryPath)
1031  !
1032  ! -- dcy
1033  if (this%idcy == decay_off) then
1034  call mem_allocate(this%ratedcy, 1, 'RATEDCY', this%memoryPath)
1035  call mem_allocate(this%decay, 1, 'DECAY', this%memoryPath)
1036  call mem_allocate(this%decaylast, 1, 'DECAYLAST', this%memoryPath)
1037  else
1038  call mem_allocate(this%ratedcy, this%dis%nodes, 'RATEDCY', this%memoryPath)
1039  call mem_allocate(this%decay, nodes, 'DECAY', this%memoryPath)
1040  call mem_allocate(this%decaylast, nodes, 'DECAYLAST', this%memoryPath)
1041  end if
1042  if (this%idcy /= decay_off .and. this%isrb /= sorption_off) then
1043  call mem_allocate(this%ratedcys, this%dis%nodes, 'RATEDCYS', &
1044  this%memoryPath)
1045  call mem_allocate(this%decayslast, this%dis%nodes, 'DECAYSLAST', &
1046  this%memoryPath)
1047  else
1048  call mem_allocate(this%ratedcys, 1, 'RATEDCYS', this%memoryPath)
1049  call mem_allocate(this%decayslast, 1, 'DECAYSLAST', this%memoryPath)
1050  end if
1051  call mem_allocate(this%decay_sorbed, 1, 'DECAY_SORBED', &
1052  this%memoryPath)
1053  !
1054  ! -- srb
1055  if (this%isrb == sorption_off) then
1056  call mem_allocate(this%bulk_density, 1, 'BULK_DENSITY', this%memoryPath)
1057  call mem_allocate(this%sp2, 1, 'SP2', this%memoryPath)
1058  call mem_allocate(this%distcoef, 1, 'DISTCOEF', this%memoryPath)
1059  call mem_allocate(this%ratesrb, 1, 'RATESRB', this%memoryPath)
1060  call mem_allocate(this%csrb, 1, 'CSRB', this%memoryPath)
1061  else
1062  call mem_allocate(this%bulk_density, nodes, 'BULK_DENSITY', this%memoryPath)
1063  call mem_allocate(this%distcoef, nodes, 'DISTCOEF', this%memoryPath)
1064  call mem_allocate(this%ratesrb, nodes, 'RATESRB', this%memoryPath)
1065  call mem_allocate(this%csrb, nodes, 'CSRB', this%memoryPath)
1066  if (this%isrb == sorption_linear) then
1067  call mem_allocate(this%sp2, 1, 'SP2', this%memoryPath)
1068  else
1069  call mem_allocate(this%sp2, nodes, 'SP2', this%memoryPath)
1070  end if
1071  end if
1072  !
1073  ! -- Initialize
1074  do n = 1, nodes
1075  this%porosity(n) = dzero
1076  this%thetam(n) = dzero
1077  this%volfracim(n) = dzero
1078  this%ratesto(n) = dzero
1079  end do
1080  do n = 1, size(this%decay)
1081  this%decay(n) = dzero
1082  this%ratedcy(n) = dzero
1083  this%decaylast(n) = dzero
1084  end do
1085  do n = 1, size(this%bulk_density)
1086  this%bulk_density(n) = dzero
1087  this%distcoef(n) = dzero
1088  this%ratesrb(n) = dzero
1089  this%csrb(n) = dzero
1090  end do
1091  do n = 1, size(this%sp2)
1092  this%sp2(n) = dzero
1093  end do
1094  do n = 1, size(this%ratedcys)
1095  this%ratedcys(n) = dzero
1096  this%decayslast(n) = dzero
1097  end do
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65

◆ allocate_scalars()

subroutine gwtmstmodule::allocate_scalars ( class(gwtmsttype this)

Method to allocate scalar variables for the package.

Parameters
thisGwtMstType object

Definition at line 991 of file gwt-mst.f90.

992  ! -- modules
994  ! -- dummy
995  class(GwtMstType) :: this !< GwtMstType object
996  !
997  ! -- Allocate scalars in NumericalPackageType
998  call this%NumericalPackageType%allocate_scalars()
999  !
1000  ! -- Allocate
1001  call mem_allocate(this%isrb, 'ISRB', this%memoryPath)
1002  call mem_allocate(this%ioutsorbate, 'IOUTSORBATE', this%memoryPath)
1003  call mem_allocate(this%idcy, 'IDCY', this%memoryPath)
1004  !
1005  ! -- Initialize
1006  this%isrb = izero
1007  this%ioutsorbate = 0
1008  this%idcy = izero

◆ get_volfracm()

real(dp) function gwtmstmodule::get_volfracm ( class(gwtmsttype this,
integer(i4b), intent(in)  node 
)

Calculate and return the volume fraction of the aquifer that is mobile

Parameters
thisGwtMstType object
[in]nodenode number

Definition at line 1431 of file gwt-mst.f90.

1432  ! -- dummy
1433  class(GwtMstType) :: this !< GwtMstType object
1434  integer(I4B), intent(in) :: node !< node number
1435  ! -- return
1436  real(DP) :: volfracm
1437  !
1438  volfracm = done - this%volfracim(node)

◆ get_zero_order_decay()

real(dp) function gwtmstmodule::get_zero_order_decay ( real(dp), intent(in)  decay_rate_usr,
real(dp), intent(in)  decay_rate_last,
integer(i4b), intent(in)  kiter,
real(dp), intent(in)  cold,
real(dp), intent(in)  cnew,
real(dp), intent(in)  delt 
)

Function to calculate the zero-order decay rate from the user specified decay rate. If the decay rate is positive, then the decay rate must be constrained so that more mass is not removed than is available. Without this constraint, negative concentrations could result from zero-order decay.

Parameters
[in]decay_rate_usruser-entered decay rate
[in]decay_rate_lastdecay rate used for last iteration
[in]kiterPicard iteration counter
[in]coldconcentration at end of last time step
[in]cnewconcentration at end of this time step
[in]deltlength of time step
Returns
returned value for decay rate

Definition at line 1449 of file gwt-mst.f90.

1451  ! -- dummy
1452  real(DP), intent(in) :: decay_rate_usr !< user-entered decay rate
1453  real(DP), intent(in) :: decay_rate_last !< decay rate used for last iteration
1454  integer(I4B), intent(in) :: kiter !< Picard iteration counter
1455  real(DP), intent(in) :: cold !< concentration at end of last time step
1456  real(DP), intent(in) :: cnew !< concentration at end of this time step
1457  real(DP), intent(in) :: delt !< length of time step
1458  ! -- return
1459  real(DP) :: decay_rate !< returned value for decay rate
1460  !
1461  ! -- Return user rate if production, otherwise constrain, if necessary
1462  if (decay_rate_usr < dzero) then
1463  !
1464  ! -- Production, no need to limit rate
1465  decay_rate = decay_rate_usr
1466  else
1467  !
1468  ! -- Need to ensure decay does not result in negative
1469  ! concentration, so reduce the rate if it would result in
1470  ! removing more mass than is in the cell.
1471  if (kiter == 1) then
1472  decay_rate = min(decay_rate_usr, cold / delt)
1473  else
1474  decay_rate = decay_rate_last
1475  if (cnew < dzero) then
1476  decay_rate = decay_rate_last + cnew / delt
1477  else if (cnew > cold) then
1478  decay_rate = decay_rate_last + cnew / delt
1479  end if
1480  decay_rate = min(decay_rate_usr, decay_rate)
1481  end if
1482  decay_rate = max(decay_rate, dzero)
1483  end if
Here is the caller graph for this function:

◆ log_data()

subroutine gwtmstmodule::log_data ( class(gwtmsttype this,
type(gwtmstparamfoundtype), intent(in)  found 
)

Definition at line 1376 of file gwt-mst.f90.

1378  class(GwTMstType) :: this
1379  type(GwtMstParamFoundType), intent(in) :: found
1380 
1381  write (this%iout, '(1x,a)') 'PROCESSING GRIDDATA'
1382  if (found%porosity) then
1383  write (this%iout, '(4x,a)') 'MOBILE DOMAIN POROSITY set from input file'
1384  end if
1385  if (found%decay) then
1386  write (this%iout, '(4x,a)') 'DECAY RATE set from input file'
1387  end if
1388  if (found%decay_sorbed) then
1389  write (this%iout, '(4x,a)') 'DECAY SORBED RATE set from input file'
1390  end if
1391  if (found%bulk_density) then
1392  write (this%iout, '(4x,a)') 'BULK DENSITY set from input file'
1393  end if
1394  if (found%distcoef) then
1395  write (this%iout, '(4x,a)') 'DISTRIBUTION COEFFICIENT set from input file'
1396  end if
1397  if (found%sp2) then
1398  write (this%iout, '(4x,a)') 'SECOND SORPTION PARAM set from input file'
1399  end if
1400  write (this%iout, '(1x,a)') 'END PROCESSING GRIDDATA'

◆ log_options()

subroutine gwtmstmodule::log_options ( class(gwtmsttype this,
type(gwtmstparamfoundtype), intent(in)  found,
character(len=*), intent(in)  sorbate_fname 
)

Definition at line 1157 of file gwt-mst.f90.

1159  class(GwTMstType) :: this
1160  type(GwtMstParamFoundType), intent(in) :: found
1161  character(len=*), intent(in) :: sorbate_fname
1162  ! -- formats
1163  character(len=*), parameter :: fmtisvflow = &
1164  "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
1165  &WHENEVER ICBCFL IS NOT ZERO.')"
1166  character(len=*), parameter :: fmtlinear = &
1167  &"(4x,'LINEAR SORPTION IS ACTIVE. ')"
1168  character(len=*), parameter :: fmtfreundlich = &
1169  &"(4x,'FREUNDLICH SORPTION IS ACTIVE. ')"
1170  character(len=*), parameter :: fmtlangmuir = &
1171  &"(4x,'LANGMUIR SORPTION IS ACTIVE. ')"
1172  character(len=*), parameter :: fmtidcy1 = &
1173  &"(4x,'FIRST-ORDER DECAY IS ACTIVE. ')"
1174  character(len=*), parameter :: fmtidcy2 = &
1175  &"(4x,'ZERO-ORDER DECAY IS ACTIVE. ')"
1176  character(len=*), parameter :: fmtfileout = &
1177  "(4x,'MST ',1x,a,1x,' WILL BE SAVED TO FILE: ',a,/4x,&
1178  &'OPENED ON UNIT: ',I7)"
1179 
1180  write (this%iout, '(1x,a)') 'PROCESSING MOBILE STORAGE AND TRANSFER OPTIONS'
1181  if (found%save_flows) then
1182  write (this%iout, fmtisvflow)
1183  end if
1184  if (found%order1_decay) then
1185  write (this%iout, fmtidcy1)
1186  end if
1187  if (found%order0_decay) then
1188  write (this%iout, fmtidcy2)
1189  end if
1190  if (found%sorption) then
1191  select case (this%isrb)
1192  case (sorption_linear)
1193  write (this%iout, fmtlinear)
1194  case (sorption_freund)
1195  write (this%iout, fmtfreundlich)
1196  case (sorption_lang)
1197  write (this%iout, fmtlangmuir)
1198  end select
1199  end if
1200  if (found%sorbatefile) then
1201  write (this%iout, fmtfileout) &
1202  'SORBATE', sorbate_fname, this%ioutsorbate
1203  end if
1204  write (this%iout, '(1x,a)') 'END OF MOBILE STORAGE AND TRANSFER OPTIONS'

◆ mst_ar()

subroutine gwtmstmodule::mst_ar ( class(gwtmsttype), intent(inout)  this,
class(disbasetype), intent(in), pointer  dis,
integer(i4b), dimension(:), pointer, contiguous  ibound 
)

Method to allocate and read static data for the package.

Parameters
[in,out]thisGwtMstType object
[in]dispointer to dis package
iboundpointer to GWT ibound array

Definition at line 142 of file gwt-mst.f90.

143  ! -- modules
144  ! -- dummy
145  class(GwtMstType), intent(inout) :: this !< GwtMstType object
146  class(DisBaseType), pointer, intent(in) :: dis !< pointer to dis package
147  integer(I4B), dimension(:), pointer, contiguous :: ibound !< pointer to GWT ibound array
148  ! -- local
149  ! -- formats
150  character(len=*), parameter :: fmtmst = &
151  "(1x,/1x,'MST -- MOBILE STORAGE AND TRANSFER PACKAGE, VERSION 1, &
152  &7/29/2020 INPUT READ FROM MEMPATH: ', A, //)"
153  !
154  ! --print a message identifying the mobile storage and transfer package.
155  write (this%iout, fmtmst) this%input_mempath
156  !
157  ! -- Source options
158  call this%source_options()
159  !
160  ! -- store pointers to arguments that were passed in
161  this%dis => dis
162  this%ibound => ibound
163  !
164  ! -- Allocate arrays
165  call this%allocate_arrays(dis%nodes)
166  !
167  ! -- source the data block
168  call this%source_data()
169  !
170  ! -- Create isotherm object if sorption is active
171  this%isotherm => create_isotherm(this%isrb, this%distcoef, this%sp2)
Here is the call graph for this function:

◆ mst_bd()

subroutine gwtmstmodule::mst_bd ( class(gwtmsttype this,
integer(i4b), intent(in)  isuppress_output,
type(budgettype), intent(inout)  model_budget 
)
Parameters
thisGwtMstType object
[in]isuppress_outputflag to suppress output
[in,out]model_budgetmodel budget object

Definition at line 811 of file gwt-mst.f90.

812  ! -- modules
813  use tdismodule, only: delt
815  ! -- dummy
816  class(GwtMstType) :: this !< GwtMstType object
817  integer(I4B), intent(in) :: isuppress_output !< flag to suppress output
818  type(BudgetType), intent(inout) :: model_budget !< model budget object
819  ! -- local
820  real(DP) :: rin
821  real(DP) :: rout
822  !
823  ! -- sto
824  call rate_accumulator(this%ratesto, rin, rout)
825  call model_budget%addentry(rin, rout, delt, budtxt(1), &
826  isuppress_output, rowlabel=this%packName)
827  !
828  ! -- dcy
829  if (this%idcy /= decay_off) then
830  call rate_accumulator(this%ratedcy, rin, rout)
831  call model_budget%addentry(rin, rout, delt, budtxt(2), &
832  isuppress_output, rowlabel=this%packName)
833  end if
834  !
835  ! -- srb
836  if (this%isrb /= sorption_off) then
837  call rate_accumulator(this%ratesrb, rin, rout)
838  call model_budget%addentry(rin, rout, delt, budtxt(3), &
839  isuppress_output, rowlabel=this%packName)
840  end if
841  !
842  ! -- srb dcy
843  if (this%isrb /= sorption_off .and. this%idcy /= decay_off) then
844  call rate_accumulator(this%ratedcys, rin, rout)
845  call model_budget%addentry(rin, rout, delt, budtxt(4), &
846  isuppress_output, rowlabel=this%packName)
847  end if
This module contains the BudgetModule.
Definition: Budget.f90:20
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
Definition: Budget.f90:632
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
Here is the call graph for this function:

◆ mst_calc_csrb()

subroutine gwtmstmodule::mst_calc_csrb ( class(gwtmsttype this,
real(dp), dimension(:), intent(in)  cnew 
)
Parameters
thisGwtMstType object
[in]cnewconcentration at end of this time step

Definition at line 790 of file gwt-mst.f90.

791  ! -- dummy
792  class(GwtMstType) :: this !< GwtMstType object
793  real(DP), intent(in), dimension(:) :: cnew !< concentration at end of this time step
794  ! -- local
795  integer(I4B) :: n
796  real(DP) :: csrb
797 
798  ! Calculate sorbed concentration
799  do n = 1, size(cnew)
800  csrb = dzero
801  if (this%ibound(n) > 0 .and. this%isrb /= sorption_off) then
802  csrb = this%isotherm%value(cnew, n)
803  end if
804  this%csrb(n) = csrb
805  end do
806 

◆ mst_cq()

subroutine gwtmstmodule::mst_cq ( class(gwtmsttype this,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cnew,
real(dp), dimension(nodes), intent(in)  cold,
real(dp), dimension(:), intent(inout), contiguous  flowja 
)

Method to calculate flows for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]cnewconcentration at end of this time step
[in]coldconcentration at end of last time step
[in,out]flowjaflow between two connected control volumes

Definition at line 485 of file gwt-mst.f90.

486  ! -- dummy
487  class(GwtMstType) :: this !< GwtMstType object
488  integer(I4B), intent(in) :: nodes !< number of nodes
489  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
490  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
491  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
492  !
493  ! - storage
494  call this%mst_cq_sto(nodes, cnew, cold, flowja)
495  !
496  ! -- decay
497  if (this%idcy /= decay_off) then
498  call this%mst_cq_dcy(nodes, cnew, cold, flowja)
499  end if
500  !
501  ! -- sorption
502  if (this%isrb /= sorption_off) then
503  call this%mst_cq_srb(nodes, cnew, cold, flowja)
504  end if
505  !
506  ! -- decay sorbed
507  if (this%isrb /= sorption_off .and. this%idcy /= decay_off) then
508  call this%mst_cq_dcy_srb(nodes, cnew, cold, flowja)
509  end if
510  !
511  ! -- calculate csrb
512  if (this%isrb /= sorption_off) then
513  call this%mst_calc_csrb(cnew)
514  end if

◆ mst_cq_dcy()

subroutine gwtmstmodule::mst_cq_dcy ( class(gwtmsttype this,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cnew,
real(dp), dimension(nodes), intent(in)  cold,
real(dp), dimension(:), intent(inout), contiguous  flowja 
)

Method to calculate decay terms for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]cnewconcentration at end of this time step
[in]coldconcentration at end of last time step
[in,out]flowjaflow between two connected control volumes

Definition at line 569 of file gwt-mst.f90.

570  ! -- modules
571  use tdismodule, only: delt
572  ! -- dummy
573  class(GwtMstType) :: this !< GwtMstType object
574  integer(I4B), intent(in) :: nodes !< number of nodes
575  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
576  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
577  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
578  ! -- local
579  integer(I4B) :: n
580  integer(I4B) :: idiag
581  real(DP) :: rate
582  real(DP) :: swtpdt
583  real(DP) :: hhcof, rrhs
584  real(DP) :: vcell
585  real(DP) :: decay_rate
586  !
587  ! -- initialize
588  !
589  ! -- Calculate decay change
590  do n = 1, nodes
591  !
592  ! -- skip if transport inactive
593  this%ratedcy(n) = dzero
594  if (this%ibound(n) <= 0) cycle
595  !
596  ! -- calculate new and old water volumes
597  vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
598  swtpdt = this%fmi%gwfsat(n)
599  !
600  ! -- calculate decay gains and losses
601  rate = dzero
602  hhcof = dzero
603  rrhs = dzero
604  if (this%idcy == decay_first_order) then
605  if (cnew(n) > dzero) then
606  hhcof = -this%decay(n) * vcell * swtpdt * this%thetam(n)
607  end if
608  elseif (this%idcy == decay_zero_order) then
609  decay_rate = get_zero_order_decay(this%decay(n), this%decaylast(n), &
610  0, cold(n), cnew(n), delt)
611  rrhs = decay_rate * vcell * swtpdt * this%thetam(n)
612  end if
613  rate = hhcof * cnew(n) - rrhs
614  this%ratedcy(n) = rate
615  idiag = this%dis%con%ia(n)
616  flowja(idiag) = flowja(idiag) + rate
617  !
618  end do
Here is the call graph for this function:

◆ mst_cq_dcy_srb()

subroutine gwtmstmodule::mst_cq_dcy_srb ( class(gwtmsttype this,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cnew,
real(dp), dimension(nodes), intent(in)  cold,
real(dp), dimension(:), intent(inout), contiguous  flowja 
)

Method to calculate decay-sorption terms for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]cnewconcentration at end of this time step
[in]coldconcentration at end of last time step
[in,out]flowjaflow between two connected control volumes

Definition at line 695 of file gwt-mst.f90.

696  ! -- modules
697  use tdismodule, only: delt
698  ! -- dummy
699  class(GwtMstType) :: this !< GwtMstType object
700  integer(I4B), intent(in) :: nodes !< number of nodes
701  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
702  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
703  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
704  ! -- local
705  integer(I4B) :: n
706  integer(I4B) :: idiag
707  real(DP) :: rate
708  real(DP) :: hhcof, rrhs
709  real(DP) :: vcell
710  real(DP) :: swnew
711  real(DP) :: distcoef
712  real(DP) :: volfracm
713  real(DP) :: rhobm
714  real(DP) :: term
715  real(DP) :: csrb
716  real(DP) :: csrbnew
717  real(DP) :: csrbold
718  real(DP) :: decay_rate
719  !
720  ! -- Calculate sorbed decay change
721  ! This routine will only be called if sorption and decay are active
722  do n = 1, nodes
723  !
724  ! -- initialize rates
725  this%ratedcys(n) = dzero
726  !
727  ! -- skip if transport inactive
728  if (this%ibound(n) <= 0) cycle
729  !
730  ! -- set variables
731  hhcof = dzero
732  rrhs = dzero
733  vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
734  swnew = this%fmi%gwfsat(n)
735  distcoef = this%distcoef(n)
736  volfracm = this%get_volfracm(n)
737  rhobm = this%bulk_density(n)
738  term = this%decay_sorbed(n) * volfracm * rhobm * swnew * vcell
739  !
740  ! -- add sorbed mass decay rate terms to accumulators
741  select case (this%idcy)
742  case (decay_first_order)
743 
744  !
745  select case (this%isrb)
746  case (sorption_linear)
747  !
748  ! -- first order decay rate is a function of concentration, so add
749  ! to left hand side
750  if (cnew(n) > dzero) then
751  hhcof = -term * distcoef
752  end if
753  case (sorption_freund)
754  !
755  ! -- nonlinear Freundlich sorption, so add to RHS
756  csrb = this%isotherm%value(cnew, n)
757  rrhs = term * csrb
758  case (sorption_lang)
759  !
760  ! -- nonlinear Lanmuir sorption, so add to RHS
761  csrb = this%isotherm%value(cnew, n)
762  rrhs = term * csrb
763  end select
764  case (decay_zero_order)
765  !
766  ! -- Call function to get zero-order decay rate, which may be changed
767  ! from the user-specified rate to prevent negative concentrations
768  if (distcoef > dzero) then
769  csrbold = this%isotherm%value(cold, n)
770  csrbnew = this%isotherm%value(cnew, n)
771 
772  decay_rate = get_zero_order_decay(this%decay_sorbed(n), &
773  this%decayslast(n), &
774  0, csrbold, csrbnew, delt)
775  rrhs = decay_rate * volfracm * rhobm * swnew * vcell
776  end if
777  end select
778  !
779  ! -- calculate rate
780  rate = hhcof * cnew(n) - rrhs
781  this%ratedcys(n) = rate
782  idiag = this%dis%con%ia(n)
783  flowja(idiag) = flowja(idiag) + rate
784  !
785  end do
Here is the call graph for this function:

◆ mst_cq_srb()

subroutine gwtmstmodule::mst_cq_srb ( class(gwtmsttype this,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cnew,
real(dp), dimension(nodes), intent(in)  cold,
real(dp), dimension(:), intent(inout), contiguous  flowja 
)

Method to calculate sorption terms for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]cnewconcentration at end of this time step
[in]coldconcentration at end of last time step
[in,out]flowjaflow between two connected control volumes

Definition at line 625 of file gwt-mst.f90.

626  ! -- modules
627  use tdismodule, only: delt
628  ! -- dummy
629  class(GwtMstType) :: this !< GwtMstType object
630  integer(I4B), intent(in) :: nodes !< number of nodes
631  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
632  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
633  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
634  ! -- local
635  integer(I4B) :: n
636  integer(I4B) :: idiag
637  real(DP) :: rate
638  real(DP) :: tled
639  real(DP) :: vcell
640  real(DP) :: volfracm
641  real(DP) :: rhobm
642  real(DP), dimension(nodes) :: c_half
643  real(DP) :: cbar_derv_half
644  real(DP) :: cbar_new, cbar_half, cbar_old
645  real(DP) :: sat_new, sat_half, sat_old
646  !
647  ! -- initialize
648  tled = done / delt
649  c_half = 0.5_dp * (cold + cnew)
650  !
651  ! -- Calculate sorption change
652  do n = 1, nodes
653  !
654  ! -- initialize rates
655  this%ratesrb(n) = dzero
656  rate = 0.0_dp
657  !
658  ! -- skip if transport inactive
659  if (this%ibound(n) <= 0) cycle
660  !
661  ! -- assign variables
662  vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
663 
664  rhobm = this%bulk_density(n)
665  volfracm = this%get_volfracm(n)
666  sat_new = this%fmi%gwfsat(n)
667  sat_old = this%fmi%gwfsatold(n, delt)
668 
669  ! -- Midpoint formulation using average values
670  cbar_new = this%isotherm%value(cnew, n)
671  cbar_old = this%isotherm%value(cold, n)
672  cbar_half = 0.5 * (cbar_new + cbar_old)
673 
674  sat_half = 0.5 * (sat_new + sat_old)
675  cbar_derv_half = this%isotherm%derivative(c_half, n)
676 
677  rate = -volfracm * rhobm * cbar_derv_half * sat_half * cnew(n) &
678  * vcell * tled
679  rate = rate + volfracm * rhobm * cbar_derv_half * sat_half * cold(n) &
680  * vcell * tled
681  rate = rate - volfracm * rhobm * cbar_half * (sat_new - sat_old) &
682  * vcell * tled
683 
684  this%ratesrb(n) = rate
685  idiag = this%dis%con%ia(n)
686  flowja(idiag) = flowja(idiag) + rate
687  !
688  end do

◆ mst_cq_sto()

subroutine gwtmstmodule::mst_cq_sto ( class(gwtmsttype this,
integer(i4b), intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cnew,
real(dp), dimension(nodes), intent(in)  cold,
real(dp), dimension(:), intent(inout), contiguous  flowja 
)

Method to calculate storage terms for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]cnewconcentration at end of this time step
[in]coldconcentration at end of last time step
[in,out]flowjaflow between two connected control volumes

Definition at line 521 of file gwt-mst.f90.

522  ! -- modules
523  use tdismodule, only: delt
524  ! -- dummy
525  class(GwtMstType) :: this !< GwtMstType object
526  integer(I4B), intent(in) :: nodes !< number of nodes
527  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
528  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
529  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< flow between two connected control volumes
530  ! -- local
531  integer(I4B) :: n
532  integer(I4B) :: idiag
533  real(DP) :: rate
534  real(DP) :: tled
535  real(DP) :: vnew, vold
536  real(DP) :: hhcof, rrhs
537  !
538  ! -- initialize
539  tled = done / delt
540  !
541  ! -- Calculate storage change
542  do n = 1, nodes
543  this%ratesto(n) = dzero
544  !
545  ! -- skip if transport inactive
546  if (this%ibound(n) <= 0) cycle
547  !
548  ! -- calculate new and old water volumes
549  vnew = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) * &
550  this%fmi%gwfsat(n) * this%thetam(n)
551  vold = vnew
552  if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) * delt
553  if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) * delt
554  !
555  ! -- calculate rate
556  hhcof = -vnew * tled
557  rrhs = -vold * tled * cold(n)
558  rate = hhcof * cnew(n) - rrhs
559  this%ratesto(n) = rate
560  idiag = this%dis%con%ia(n)
561  flowja(idiag) = flowja(idiag) + rate
562  end do

◆ mst_cr()

subroutine, public gwtmstmodule::mst_cr ( type(gwtmsttype), pointer  mstobj,
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 
)

Create a new MST object

Parameters
mstobjunallocated new mst object to create
[in]name_modelname of the model
[in]input_mempathmemory path of input
[in]inunitunit number of WEL package input file
[in]ioutunit number of model listing file
[in]fmifmi package for this GWT model

Definition at line 114 of file gwt-mst.f90.

115  ! -- dummy
116  type(GwtMstType), pointer :: mstobj !< unallocated new mst object to create
117  character(len=*), intent(in) :: name_model !< name of the model
118  character(len=*), intent(in) :: input_mempath !< memory path of input
119  integer(I4B), intent(in) :: inunit !< unit number of WEL package input file
120  integer(I4B), intent(in) :: iout !< unit number of model listing file
121  type(TspFmiType), intent(in), target :: fmi !< fmi package for this GWT model
122  !
123  ! -- Create the object
124  allocate (mstobj)
125  !
126  ! -- create name and memory path
127  call mstobj%set_names(1, name_model, 'MST', 'MST', input_mempath)
128  !
129  ! -- Allocate scalars
130  call mstobj%allocate_scalars()
131  !
132  ! -- Set variables
133  mstobj%inunit = inunit
134  mstobj%iout = iout
135  mstobj%fmi => fmi
Here is the caller graph for this function:

◆ mst_da()

subroutine gwtmstmodule::mst_da ( class(gwtmsttype this)

Method to deallocate memory for the package.

Parameters
thisGwtMstType object

Definition at line 945 of file gwt-mst.f90.

946  ! -- modules
948  ! -- dummy
949  class(GwtMstType) :: this !< GwtMstType object
950  !
951  ! -- Deallocate arrays if package was active
952  if (this%inunit > 0) then
953  call mem_deallocate(this%porosity)
954  call mem_deallocate(this%thetam)
955  call mem_deallocate(this%volfracim)
956  call mem_deallocate(this%ratesto)
957  call mem_deallocate(this%idcy)
958  call mem_deallocate(this%decay)
959  call mem_deallocate(this%decay_sorbed)
960  call mem_deallocate(this%ratedcy)
961  call mem_deallocate(this%decaylast)
962  call mem_deallocate(this%decayslast)
963  call mem_deallocate(this%isrb)
964  call mem_deallocate(this%ioutsorbate)
965  call mem_deallocate(this%bulk_density)
966  call mem_deallocate(this%distcoef)
967  call mem_deallocate(this%sp2)
968  call mem_deallocate(this%ratesrb)
969  call mem_deallocate(this%csrb)
970  call mem_deallocate(this%ratedcys)
971  this%ibound => null()
972  this%fmi => null()
973  end if
974  !
975  ! -- Scalars
976  !
977  ! -- Objects
978  if (associated(this%isotherm)) then
979  deallocate (this%isotherm)
980  nullify (this%isotherm)
981  end if
982  !
983  ! -- deallocate parent
984  call this%NumericalPackageType%da()

◆ mst_fc()

subroutine gwtmstmodule::mst_fc ( class(gwtmsttype this,
integer, intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cold,
integer(i4b), intent(in)  nja,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(nja), intent(in)  idxglo,
real(dp), dimension(nodes), intent(in)  cnew,
real(dp), dimension(nodes), intent(inout)  rhs,
integer(i4b), intent(in)  kiter 
)

Method to calculate and fill coefficients for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]coldconcentration at end of last time step
[in]njanumber of GWT connections
matrix_slnsolution matrix
[in]idxglomapping vector for model (local) to solution (global)
[in,out]rhsright-hand side vector for model
[in]cnewconcentration at end of this time step
[in]kitersolution outer iteration number

Definition at line 178 of file gwt-mst.f90.

180  ! -- modules
181  ! -- dummy
182  class(GwtMstType) :: this !< GwtMstType object
183  integer, intent(in) :: nodes !< number of nodes
184  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
185  integer(I4B), intent(in) :: nja !< number of GWT connections
186  class(MatrixBaseType), pointer :: matrix_sln !< solution matrix
187  integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global)
188  real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model
189  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
190  integer(I4B), intent(in) :: kiter !< solution outer iteration number
191  !
192  ! -- storage contribution
193  call this%mst_fc_sto(nodes, cold, nja, matrix_sln, idxglo, rhs)
194  !
195  ! -- decay contribution
196  if (this%idcy /= decay_off) then
197  call this%mst_fc_dcy(nodes, cold, cnew, nja, matrix_sln, idxglo, &
198  rhs, kiter)
199  end if
200  !
201  ! -- sorption contribution
202  if (this%isrb /= sorption_off) then
203  call this%mst_fc_srb(nodes, cold, nja, matrix_sln, idxglo, rhs, cnew)
204  end if
205  !
206  ! -- decay sorbed contribution
207  if (this%isrb /= sorption_off .and. this%idcy /= decay_off) then
208  call this%mst_fc_dcy_srb(nodes, cold, nja, matrix_sln, idxglo, rhs, &
209  cnew, kiter)
210  end if

◆ mst_fc_dcy()

subroutine gwtmstmodule::mst_fc_dcy ( class(gwtmsttype this,
integer, intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cold,
real(dp), dimension(nodes), intent(in)  cnew,
integer(i4b), intent(in)  nja,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(nja), intent(in)  idxglo,
real(dp), dimension(nodes), intent(inout)  rhs,
integer(i4b), intent(in)  kiter 
)

Method to calculate and fill decay coefficients for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]coldconcentration at end of last time step
[in]cnewconcentration at end of this time step
[in]njanumber of GWT connections
matrix_slnsolution coefficient matrix
[in]idxglomapping vector for model (local) to solution (global)
[in,out]rhsright-hand side vector for model
[in]kitersolution outer iteration number

Definition at line 263 of file gwt-mst.f90.

265  ! -- modules
266  use tdismodule, only: delt
267  ! -- dummy
268  class(GwtMstType) :: this !< GwtMstType object
269  integer, intent(in) :: nodes !< number of nodes
270  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
271  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
272  integer(I4B), intent(in) :: nja !< number of GWT connections
273  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
274  integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global)
275  real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model
276  integer(I4B), intent(in) :: kiter !< solution outer iteration number
277  ! -- local
278  integer(I4B) :: n, idiag
279  real(DP) :: hhcof, rrhs
280  real(DP) :: swtpdt
281  real(DP) :: vcell
282  real(DP) :: decay_rate
283  !
284  ! -- loop through and calculate decay contribution to hcof and rhs
285  do n = 1, this%dis%nodes
286  !
287  ! -- skip if transport inactive
288  if (this%ibound(n) <= 0) cycle
289  !
290  ! -- calculate new and old water volumes
291  vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
292  swtpdt = this%fmi%gwfsat(n)
293  !
294  ! -- add decay rate terms to accumulators
295  idiag = this%dis%con%ia(n)
296  select case (this%idcy)
297  case (decay_first_order)
298  !
299  ! -- first order decay rate is a function of concentration, so add
300  ! to left hand side
301  if (cnew(n) > dzero) then
302  hhcof = -this%decay(n) * vcell * swtpdt * this%thetam(n)
303  call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
304  end if
305  case (decay_zero_order)
306  !
307  ! -- Call function to get zero-order decay rate, which may be changed
308  ! from the user-specified rate to prevent negative concentrations
309  decay_rate = get_zero_order_decay(this%decay(n), this%decaylast(n), &
310  kiter, cold(n), cnew(n), delt)
311  this%decaylast(n) = decay_rate
312  rrhs = decay_rate * vcell * swtpdt * this%thetam(n)
313  rhs(n) = rhs(n) + rrhs
314  end select
315  !
316  end do
Here is the call graph for this function:

◆ mst_fc_dcy_srb()

subroutine gwtmstmodule::mst_fc_dcy_srb ( class(gwtmsttype this,
integer, intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cold,
integer(i4b), intent(in)  nja,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(nja), intent(in)  idxglo,
real(dp), dimension(nodes), intent(inout)  rhs,
real(dp), dimension(nodes), intent(in)  cnew,
integer(i4b), intent(in)  kiter 
)

Method to calculate and fill sorption-decay coefficients for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]coldconcentration at end of last time step
[in]njanumber of GWT connections
matrix_slnsolution coefficient matrix
[in]idxglomapping vector for model (local) to solution (global)
[in,out]rhsright-hand side vector for model
[in]cnewconcentration at end of this time step
[in]kitersolution outer iteration number

Definition at line 391 of file gwt-mst.f90.

393  ! -- modules
394  use tdismodule, only: delt
395  ! -- dummy
396  class(GwtMstType) :: this !< GwtMstType object
397  integer, intent(in) :: nodes !< number of nodes
398  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
399  integer(I4B), intent(in) :: nja !< number of GWT connections
400  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
401  integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global)
402  real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model
403  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
404  integer(I4B), intent(in) :: kiter !< solution outer iteration number
405  ! -- local
406  integer(I4B) :: n, idiag
407  real(DP) :: hhcof, rrhs
408  real(DP) :: vcell
409  real(DP) :: swnew
410  real(DP) :: distcoef
411  real(DP) :: volfracm
412  real(DP) :: rhobm
413  real(DP) :: term
414  real(DP) :: csrb
415  real(DP) :: decay_rate
416  real(DP) :: csrbold
417  real(DP) :: csrbnew
418  !
419  ! -- loop through and calculate sorption contribution to hcof and rhs
420  do n = 1, this%dis%nodes
421  !
422  ! -- skip if transport inactive
423  if (this%ibound(n) <= 0) cycle
424  !
425  ! -- set variables
426  hhcof = dzero
427  rrhs = dzero
428  vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
429  swnew = this%fmi%gwfsat(n)
430  distcoef = this%distcoef(n)
431  idiag = this%dis%con%ia(n)
432  volfracm = this%get_volfracm(n)
433  rhobm = this%bulk_density(n)
434  term = this%decay_sorbed(n) * volfracm * rhobm * swnew * vcell
435  !
436  ! -- add sorbed mass decay rate terms to accumulators
437  select case (this%idcy)
438  case (decay_first_order)
439  select case (this%isrb)
440  case (sorption_linear)
441  !
442  ! -- first order decay rate is a function of concentration, so add
443  ! to left hand side
444  if (cnew(n) > dzero) then
445  hhcof = -term * distcoef
446  end if
447  case (sorption_freund)
448  !
449  ! -- nonlinear Freundlich sorption, so add to RHS
450  csrb = this%isotherm%value(cnew, n)
451  rrhs = term * csrb
452  case (sorption_lang)
453  !
454  ! -- nonlinear Lanmuir sorption, so add to RHS
455  csrb = this%isotherm%value(cnew, n)
456  rrhs = term * csrb
457  end select
458  case (decay_zero_order)
459  !
460  ! -- call function to get zero-order decay rate, which may be changed
461  ! from the user-specified rate to prevent negative concentrations
462  if (distcoef > dzero) then
463  csrbold = this%isotherm%value(cold, n)
464  csrbnew = this%isotherm%value(cnew, n)
465  !
466  decay_rate = get_zero_order_decay(this%decay_sorbed(n), &
467  this%decayslast(n), &
468  kiter, csrbold, csrbnew, delt)
469  this%decayslast(n) = decay_rate
470  rrhs = decay_rate * volfracm * rhobm * swnew * vcell
471  end if
472  end select
473  !
474  ! -- Add hhcof to diagonal and rrhs to right-hand side
475  call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
476  rhs(n) = rhs(n) + rrhs
477  !
478  end do
Here is the call graph for this function:

◆ mst_fc_srb()

subroutine gwtmstmodule::mst_fc_srb ( class(gwtmsttype this,
integer, intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cold,
integer(i4b), intent(in)  nja,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(nja), intent(in)  idxglo,
real(dp), dimension(nodes), intent(inout)  rhs,
real(dp), dimension(nodes), intent(in)  cnew 
)

Method to calculate and fill sorption coefficients for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]coldconcentration at end of last time step
[in]njanumber of GWT connections
matrix_slnsolution coefficient matrix
[in]idxglomapping vector for model (local) to solution (global)
[in,out]rhsright-hand side vector for model
[in]cnewconcentration at end of this time step

Definition at line 323 of file gwt-mst.f90.

325  ! -- modules
326  use tdismodule, only: delt
327  ! -- dummy
328  class(GwtMstType) :: this !< GwtMstType object
329  integer, intent(in) :: nodes !< number of nodes
330  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
331  integer(I4B), intent(in) :: nja !< number of GWT connections
332  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
333  integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global)
334  real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model
335  real(DP), intent(in), dimension(nodes) :: cnew !< concentration at end of this time step
336  ! -- local
337  integer(I4B) :: n, idiag
338  real(DP) :: tled
339  real(DP) :: hhcof, rrhs
340  real(DP) :: vcell
341  real(DP) :: volfracm
342  real(DP) :: rhobm
343  real(DP), dimension(nodes) :: c_half
344  real(DP) :: cbar_derv_half
345  real(DP) :: cbar_new, cbar_half, cbar_old
346  real(DP) :: sat_new, sat_half, sat_old
347  !
348  ! -- set variables
349  tled = done / delt
350  c_half = 0.5_dp * (cold + cnew)
351  !
352  ! -- loop through and calculate sorption contribution to hcof and rhs
353  do n = 1, this%dis%nodes
354  !
355  ! -- skip if transport inactive
356  if (this%ibound(n) <= 0) cycle
357  !
358  ! -- assign variables
359  vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
360  volfracm = this%get_volfracm(n)
361  rhobm = this%bulk_density(n)
362  sat_new = this%fmi%gwfsat(n)
363  sat_old = this%fmi%gwfsatold(n, delt)
364 
365  ! -- Midpoint formulation using average values
366  cbar_new = this%isotherm%value(cnew, n)
367  cbar_old = this%isotherm%value(cold, n)
368  cbar_half = 0.5 * (cbar_new + cbar_old)
369 
370  sat_half = 0.5 * (sat_new + sat_old)
371  cbar_derv_half = this%isotherm%derivative(c_half, n)
372 
373  hhcof = -volfracm * rhobm * cbar_derv_half * sat_half * vcell * tled
374  idiag = this%dis%con%ia(n)
375  call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
376 
377  rrhs = -volfracm * rhobm * cbar_derv_half * sat_half * cold(n) &
378  * vcell * tled
379  rhs(n) = rhs(n) + rrhs
380 
381  rrhs = volfracm * rhobm * cbar_half * (sat_new - sat_old) * vcell * tled
382  rhs(n) = rhs(n) + rrhs
383 
384  end do

◆ mst_fc_sto()

subroutine gwtmstmodule::mst_fc_sto ( class(gwtmsttype this,
integer, intent(in)  nodes,
real(dp), dimension(nodes), intent(in)  cold,
integer(i4b), intent(in)  nja,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(nja), intent(in)  idxglo,
real(dp), dimension(nodes), intent(inout)  rhs 
)

Method to calculate and fill storage coefficients for the package.

Parameters
thisGwtMstType object
[in]nodesnumber of nodes
[in]coldconcentration at end of last time step
[in]njanumber of GWT connections
matrix_slnsolution coefficient matrix
[in]idxglomapping vector for model (local) to solution (global)
[in,out]rhsright-hand side vector for model

Definition at line 217 of file gwt-mst.f90.

218  ! -- modules
219  use tdismodule, only: delt
220  ! -- dummy
221  class(GwtMstType) :: this !< GwtMstType object
222  integer, intent(in) :: nodes !< number of nodes
223  real(DP), intent(in), dimension(nodes) :: cold !< concentration at end of last time step
224  integer(I4B), intent(in) :: nja !< number of GWT connections
225  class(MatrixBaseType), pointer :: matrix_sln !< solution coefficient matrix
226  integer(I4B), intent(in), dimension(nja) :: idxglo !< mapping vector for model (local) to solution (global)
227  real(DP), intent(inout), dimension(nodes) :: rhs !< right-hand side vector for model
228  ! -- local
229  integer(I4B) :: n, idiag
230  real(DP) :: tled
231  real(DP) :: hhcof, rrhs
232  real(DP) :: vnew, vold
233  !
234  ! -- set variables
235  tled = done / delt
236  !
237  ! -- loop through and calculate storage contribution to hcof and rhs
238  do n = 1, this%dis%nodes
239  !
240  ! -- skip if transport inactive
241  if (this%ibound(n) <= 0) cycle
242  !
243  ! -- calculate new and old water volumes
244  vnew = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) * &
245  this%fmi%gwfsat(n) * this%thetam(n)
246  vold = vnew
247  if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) * delt
248  if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) * delt
249  !
250  ! -- add terms to diagonal and rhs accumulators
251  hhcof = -vnew * tled
252  rrhs = -vold * tled * cold(n)
253  idiag = this%dis%con%ia(n)
254  call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
255  rhs(n) = rhs(n) + rrhs
256  end do

◆ mst_ot_dv()

subroutine gwtmstmodule::mst_ot_dv ( class(gwtmsttype this,
integer(i4b), intent(in)  idvsave 
)

Definition at line 907 of file gwt-mst.f90.

908  ! -- dummy
909  class(GwtMstType) :: this
910  integer(I4B), intent(in) :: idvsave
911  ! -- local
912  character(len=1) :: cdatafmp = ' ', editdesc = ' '
913  integer(I4B) :: ibinun
914  integer(I4B) :: iprint
915  integer(I4B) :: nvaluesp
916  integer(I4B) :: nwidthp
917  real(DP) :: dinact
918 
919  ! Set unit number for sorbate output
920  if (this%ioutsorbate /= 0) then
921  ibinun = 1
922  else
923  ibinun = 0
924  end if
925  if (idvsave == 0) ibinun = 0
926 
927  ! save sorbate concentration array
928  if (ibinun /= 0) then
929  iprint = 0
930  dinact = dhnoflo
931  if (this%ioutsorbate /= 0) then
932  ibinun = this%ioutsorbate
933  call this%dis%record_array(this%csrb, this%iout, iprint, ibinun, &
934  ' SORBATE', cdatafmp, nvaluesp, &
935  nwidthp, editdesc, dinact)
936  end if
937  end if
938 

◆ mst_ot_flow()

subroutine gwtmstmodule::mst_ot_flow ( class(gwtmsttype this,
integer(i4b), intent(in)  icbcfl,
integer(i4b), intent(in)  icbcun 
)

Method to output terms for the package.

Parameters
thisGwtMstType object
[in]icbcflflag and unit number for cell-by-cell output
[in]icbcunflag indication if cell-by-cell data should be saved

Definition at line 854 of file gwt-mst.f90.

855  ! -- dummy
856  class(GwtMstType) :: this !< GwtMstType object
857  integer(I4B), intent(in) :: icbcfl !< flag and unit number for cell-by-cell output
858  integer(I4B), intent(in) :: icbcun !< flag indication if cell-by-cell data should be saved
859  ! -- local
860  integer(I4B) :: ibinun
861  integer(I4B) :: iprint, nvaluesp, nwidthp
862  character(len=1) :: cdatafmp = ' ', editdesc = ' '
863  real(DP) :: dinact
864  !
865  ! -- Set unit number for binary output
866  if (this%ipakcb < 0) then
867  ibinun = icbcun
868  elseif (this%ipakcb == 0) then
869  ibinun = 0
870  else
871  ibinun = this%ipakcb
872  end if
873  if (icbcfl == 0) ibinun = 0
874  !
875  ! -- Record the storage rate if requested
876  if (ibinun /= 0) then
877  iprint = 0
878  dinact = dzero
879  !
880  ! -- sto
881  call this%dis%record_array(this%ratesto, this%iout, iprint, -ibinun, &
882  budtxt(1), cdatafmp, nvaluesp, &
883  nwidthp, editdesc, dinact)
884  !
885  ! -- dcy
886  if (this%idcy /= decay_off) &
887  call this%dis%record_array(this%ratedcy, this%iout, iprint, -ibinun, &
888  budtxt(2), cdatafmp, nvaluesp, &
889  nwidthp, editdesc, dinact)
890  !
891  ! -- srb
892  if (this%isrb /= sorption_off) &
893  call this%dis%record_array(this%ratesrb, this%iout, iprint, -ibinun, &
894  budtxt(3), cdatafmp, nvaluesp, &
895  nwidthp, editdesc, dinact)
896  !
897  ! -- dcy srb
898  if (this%isrb /= sorption_off .and. this%idcy /= decay_off) &
899  call this%dis%record_array(this%ratedcys, this%iout, iprint, -ibinun, &
900  budtxt(4), cdatafmp, nvaluesp, &
901  nwidthp, editdesc, dinact)
902  end if

◆ source_data()

subroutine gwtmstmodule::source_data ( class(gwtmsttype this)

Method to source data for the package.

Definition at line 1211 of file gwt-mst.f90.

1212  ! -- modules
1216  ! -- dummy
1217  class(GwtMsttype) :: this
1218  ! -- locals
1219  character(len=LINELENGTH) :: errmsg
1220  type(GwtMstParamFoundType) :: found
1221  integer(I4B) :: n, asize
1222  integer(I4B), dimension(:), pointer, contiguous :: map
1223  !
1224  ! -- set map to convert user input data into reduced data
1225  map => null()
1226  if (this%dis%nodes < this%dis%nodesuser) map => this%dis%nodeuser
1227  !
1228  ! -- reallocate
1229  if (this%isrb == sorption_off) then
1230  call get_isize('BULK_DENSITY', this%input_mempath, asize)
1231  if (asize > 0) &
1232  call mem_reallocate(this%bulk_density, this%dis%nodes, &
1233  'BULK_DENSITY', this%memoryPath)
1234  call get_isize('DISTCOEF', this%input_mempath, asize)
1235  if (asize > 0) &
1236  call mem_reallocate(this%distcoef, this%dis%nodes, 'DISTCOEF', &
1237  this%memoryPath)
1238  end if
1239  if (this%idcy == decay_off) then
1240  call get_isize('DECAY', this%input_mempath, asize)
1241  if (asize > 0) &
1242  call mem_reallocate(this%decay, this%dis%nodes, 'DECAY', this%memoryPath)
1243  end if
1244  call get_isize('DECAY_SORBED', this%input_mempath, asize)
1245  if (asize > 0) then
1246  call mem_reallocate(this%decay_sorbed, this%dis%nodes, &
1247  'DECAY_SORBED', this%memoryPath)
1248  end if
1249  if (this%isrb == sorption_off .or. this%isrb == sorption_linear) then
1250  call get_isize('SP2', this%input_mempath, asize)
1251  if (asize > 0) &
1252  call mem_reallocate(this%sp2, this%dis%nodes, 'SP2', this%memoryPath)
1253  end if
1254  !
1255  ! -- update defaults with memory sourced values
1256  call mem_set_value(this%porosity, 'POROSITY', this%input_mempath, map, &
1257  found%porosity)
1258  call mem_set_value(this%decay, 'DECAY', this%input_mempath, map, &
1259  found%decay)
1260  call mem_set_value(this%decay_sorbed, 'DECAY_SORBED', this%input_mempath, &
1261  map, found%decay_sorbed)
1262  call mem_set_value(this%bulk_density, 'BULK_DENSITY', this%input_mempath, &
1263  map, found%bulk_density)
1264  call mem_set_value(this%distcoef, 'DISTCOEF', this%input_mempath, map, &
1265  found%distcoef)
1266  call mem_set_value(this%sp2, 'SP2', this%input_mempath, map, &
1267  found%sp2)
1268 
1269  ! -- log options
1270  if (this%iout > 0) then
1271  call this%log_data(found)
1272  end if
1273 
1274  ! -- Check for required porosity
1275  if (.not. found%porosity) then
1276  write (errmsg, '(a)') 'POROSITY not specified in GRIDDATA block.'
1277  call store_error(errmsg)
1278  end if
1279 
1280  ! -- Check for required sorption variables
1281  if (this%isrb == sorption_linear .or. this%isrb == sorption_freund .or. &
1282  this%isrb == sorption_lang) then
1283  if (.not. found%bulk_density) then
1284  write (errmsg, '(a)') 'Sorption is active but BULK_DENSITY &
1285  &not specified. BULK_DENSITY must be specified in GRIDDATA block.'
1286  call store_error(errmsg)
1287  end if
1288  if (.not. found%distcoef) then
1289  write (errmsg, '(a)') 'Sorption is active but distribution &
1290  &coefficient not specified. DISTCOEF must be specified in &
1291  &GRIDDATA block.'
1292  call store_error(errmsg)
1293  end if
1294  if (this%isrb == sorption_freund .or. this%isrb == sorption_lang) then
1295  if (.not. found%sp2) then
1296  write (errmsg, '(a)') 'Freundlich or langmuir sorption is active &
1297  &but SP2 not specified. SP2 must be specified in &
1298  &GRIDDATA block.'
1299  call store_error(errmsg)
1300  end if
1301  end if
1302  else
1303  if (found%bulk_density) then
1304  write (warnmsg, '(a)') 'Sorption is not active but &
1305  &BULK_DENSITY was specified. BULK_DENSITY will have no affect on &
1306  &simulation results.'
1307  call store_warning(warnmsg)
1308  write (this%iout, '(1x,a)') 'WARNING. '//warnmsg
1309  end if
1310  if (found%distcoef) then
1311  write (warnmsg, '(a)') 'Sorption is not active but &
1312  &distribution coefficient was specified. DISTCOEF will have &
1313  &no affect on simulation results.'
1314  call store_warning(warnmsg)
1315  write (this%iout, '(1x,a)') 'WARNING. '//warnmsg
1316  end if
1317  if (found%sp2) then
1318  write (warnmsg, '(a)') 'Sorption is not active but &
1319  &SP2 was specified. SP2 will have &
1320  &no affect on simulation results.'
1321  call store_warning(warnmsg)
1322  write (this%iout, '(1x,a)') 'WARNING. '//warnmsg
1323  end if
1324  end if
1325 
1326  ! -- Check for required decay/production rate coefficients
1327  if (this%idcy /= decay_off) then
1328  if (.not. found%decay) then
1329  write (errmsg, '(a)') 'First or zero order decay is &
1330  &active but the first rate coefficient is not specified. DECAY &
1331  &must be specified in GRIDDATA block.'
1332  call store_error(errmsg)
1333  end if
1334  if (.not. found%decay_sorbed) then
1335  !
1336  ! -- If DECAY_SORBED not specified and sorption is active, then
1337  ! terminate with an error
1338  if (this%isrb == sorption_linear .or. this%isrb == sorption_freund .or. &
1339  this%isrb == sorption_lang) then
1340  write (errmsg, '(a)') 'DECAY_SORBED not provided in GRIDDATA &
1341  &block but decay and sorption are active. Specify DECAY_SORBED &
1342  &in GRIDDATA block.'
1343  call store_error(errmsg)
1344  end if
1345  end if
1346  else
1347  if (found%decay) then
1348  write (warnmsg, '(a)') 'First- or zero-order decay &
1349  &is not active but decay was specified. DECAY will &
1350  &have no affect on simulation results.'
1351  call store_warning(warnmsg)
1352  write (this%iout, '(1x,a)') 'WARNING. '//warnmsg
1353  end if
1354  if (found%decay_sorbed) then
1355  write (warnmsg, '(a)') 'First- or zero-order decay &
1356  &is not active but DECAY_SORBED was specified. &
1357  &DECAY_SORBED will have no affect on simulation results.'
1358  call store_warning(warnmsg)
1359  write (this%iout, '(1x,a)') 'WARNING. '//warnmsg
1360  end if
1361  end if
1362 
1363  ! -- terminate if errors
1364  if (count_errors() > 0) then
1365  call store_error_filename(this%input_fname)
1366  end if
1367 
1368  ! -- initialize thetam from porosity
1369  do n = 1, size(this%porosity)
1370  this%thetam(n) = this%porosity(n)
1371  end do
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
Here is the call graph for this function:

◆ source_options()

subroutine gwtmstmodule::source_options ( class(gwtmsttype this)

Method to source options for the package.

Definition at line 1104 of file gwt-mst.f90.

1105  ! -- modules
1106  use constantsmodule, only: lenvarname
1107  use openspecmodule, only: access, form
1108  use inputoutputmodule, only: getunit, openfile
1111  ! -- dummy
1112  class(GwtMstType) :: this
1113  ! -- locals
1114  type(GwtMstParamFoundType) :: found
1115  character(len=LENVARNAME), dimension(3) :: sorption_method = &
1116  &[character(len=LENVARNAME) :: 'LINEAR', 'FREUNDLICH', 'LANGMUIR']
1117  character(len=linelength) :: fname
1118  !
1119  ! -- update defaults with memory sourced values
1120  call mem_set_value(this%ipakcb, 'SAVE_FLOWS', this%input_mempath, &
1121  found%save_flows)
1122  call mem_set_value(this%idcy, 'ORDER1_DECAY', this%input_mempath, &
1123  found%order1_decay)
1124  call mem_set_value(this%idcy, 'ORDER0_DECAY', this%input_mempath, &
1125  found%order0_decay)
1126  call mem_set_value(this%isrb, 'SORPTION', this%input_mempath, &
1127  sorption_method, found%sorption)
1128  call mem_set_value(fname, 'SORBATEFILE', this%input_mempath, &
1129  found%sorbatefile)
1130 
1131  ! -- found side effects
1132  if (found%save_flows) this%ipakcb = -1
1133  if (found%order1_decay) this%idcy = decay_first_order
1134  if (found%order0_decay) this%idcy = decay_zero_order
1135  if (found%sorption) then
1136  if (this%isrb == izero) then
1137  call store_error('Unknown sorption type was specified. &
1138  &Sorption must be specified as LINEAR, &
1139  &FREUNDLICH, or LANGMUIR.')
1140  call store_error_filename(this%input_fname)
1141  end if
1142  end if
1143  if (found%sorbatefile) then
1144  this%ioutsorbate = getunit()
1145  call openfile(this%ioutsorbate, this%iout, fname, 'DATA(BINARY)', &
1146  form, access, 'REPLACE', mode_opt=mnormal)
1147  end if
1148  !
1149  ! -- log options
1150  if (this%iout > 0) then
1151  call this%log_options(found, fname)
1152  end if
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
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
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
Here is the call graph for this function:

Variable Documentation

◆ budtxt

character(len=lenbudtxt), dimension(nbditems) gwtmstmodule::budtxt

Definition at line 31 of file gwt-mst.f90.

31  character(len=LENBUDTXT), dimension(NBDITEMS) :: budtxt

◆ nbditems

integer(i4b), parameter gwtmstmodule::nbditems = 4

Definition at line 30 of file gwt-mst.f90.

30  integer(I4B), parameter :: NBDITEMS = 4