MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
gwfstomodule Module Reference

This module contains the storage package methods. More...

Data Types

type  gwfstotype
 

Functions/Subroutines

subroutine, public sto_cr (stoobj, name_model, inunit, iout)
 @ brief Create a new package object More...
 
subroutine sto_ar (this, dis, ibound)
 @ brief Allocate and read method for package More...
 
subroutine sto_rp (this)
 @ brief Read and prepare method for package More...
 
subroutine sto_ad (this)
 @ brief Advance the package More...
 
subroutine sto_fc (this, kiter, hold, hnew, matrix_sln, idxglo, rhs)
 @ brief Fill A and right-hand side for the package More...
 
subroutine sto_fn (this, kiter, hold, hnew, matrix_sln, idxglo, rhs)
 @ brief Fill Newton-Raphson terms in A and right-hand side for the package More...
 
subroutine sto_cq (this, flowja, hnew, hold)
 @ brief Calculate flows for package More...
 
subroutine sto_bd (this, isuppress_output, model_budget)
 @ brief Model budget calculation for package More...
 
subroutine sto_save_model_flows (this, icbcfl, icbcun)
 @ brief Save model flows for package More...
 
subroutine sto_da (this)
 @ brief Deallocate package memory More...
 
subroutine allocate_scalars (this)
 @ brief Allocate scalars More...
 
subroutine allocate_arrays (this, nodes)
 @ brief Allocate package arrays More...
 
subroutine read_options (this)
 @ brief Read options for package More...
 
subroutine read_data (this)
 @ brief Read data for package More...
 
subroutine save_old_ss_sy (this)
 @ brief Save old storage property values More...
 

Variables

character(len=lenbudtxt), dimension(2) budtxt = [' STO-SS', ' STO-SY']
 

Detailed Description

This module contains the methods used to add the effects of storage on the groundwater flow equation. The contribution of specific storage and specific yield can be represented.

Function/Subroutine Documentation

◆ allocate_arrays()

subroutine gwfstomodule::allocate_arrays ( class(gwfstotype), target  this,
integer(i4b), intent(in)  nodes 
)

Allocate and initialize STO package arrays.

Parameters
thisGwfStoType object
[in]nodesactive model nodes

Definition at line 805 of file gwf-sto.f90.

806  ! -- modules
808  ! -- dummy variables
809  class(GwfStoType), target :: this !< GwfStoType object
810  integer(I4B), intent(in) :: nodes !< active model nodes
811  ! -- local variables
812  integer(I4B) :: n
813  !
814  ! -- Allocate arrays
815  call mem_allocate(this%iconvert, nodes, 'ICONVERT', this%memoryPath)
816  call mem_allocate(this%ss, nodes, 'SS', this%memoryPath)
817  call mem_allocate(this%sy, nodes, 'SY', this%memoryPath)
818  call mem_allocate(this%strgss, nodes, 'STRGSS', this%memoryPath)
819  call mem_allocate(this%strgsy, nodes, 'STRGSY', this%memoryPath)
820  !
821  ! -- Initialize arrays
822  this%iss = 0
823  do n = 1, nodes
824  this%iconvert(n) = 1
825  this%ss(n) = dzero
826  this%sy(n) = dzero
827  this%strgss(n) = dzero
828  this%strgsy(n) = dzero
829  if (this%integratechanges /= 0) then
830  this%oldss(n) = dzero
831  if (this%iusesy /= 0) then
832  this%oldsy(n) = dzero
833  end if
834  end if
835  end do
836  !
837  ! -- return
838  return

◆ allocate_scalars()

subroutine gwfstomodule::allocate_scalars ( class(gwfstotype this)

Allocate and initialize scalars for the STO package. The base numerical package allocate scalars method is also called.

Parameters
thisGwfStoType object

Definition at line 768 of file gwf-sto.f90.

769  ! -- modules
771  ! -- dummy variables
772  class(GwfStoType) :: this !< GwfStoType object
773  !
774  ! -- allocate scalars in NumericalPackageType
775  call this%NumericalPackageType%allocate_scalars()
776  !
777  ! -- allocate scalars
778  call mem_allocate(this%istor_coef, 'ISTOR_COEF', this%memoryPath)
779  call mem_allocate(this%iconf_ss, 'ICONF_SS', this%memoryPath)
780  call mem_allocate(this%iorig_ss, 'IORIG_SS', this%memoryPath)
781  call mem_allocate(this%iusesy, 'IUSESY', this%memoryPath)
782  call mem_allocate(this%satomega, 'SATOMEGA', this%memoryPath)
783  call mem_allocate(this%integratechanges, 'INTEGRATECHANGES', &
784  this%memoryPath)
785  call mem_allocate(this%intvs, 'INTVS', this%memoryPath)
786  !
787  ! -- initialize scalars
788  this%istor_coef = 0
789  this%iconf_ss = 0
790  this%iorig_ss = 0
791  this%iusesy = 0
792  this%satomega = dzero
793  this%integratechanges = 0
794  this%intvs = 0
795  !
796  ! -- return
797  return

◆ read_data()

subroutine gwfstomodule::read_data ( class(gwfstotype this)

Read griddata block for STO package.

Parameters
thisGwfStoType object

Definition at line 944 of file gwf-sto.f90.

945  ! -- modules
946  ! -- dummy variables
947  class(GwfStotype) :: this !< GwfStoType object
948  ! -- local variables
949  character(len=LINELENGTH) :: keyword
950  character(len=:), allocatable :: line
951  character(len=LINELENGTH) :: cellstr
952  integer(I4B) :: istart, istop, lloc, ierr
953  logical :: isfound, endOfBlock
954  logical :: readiconv
955  logical :: readss
956  logical :: readsy
957  logical :: isconv
958  character(len=24), dimension(4) :: aname
959  integer(I4B) :: n
960  ! -- formats
961  !data
962  data aname(1)/' ICONVERT'/
963  data aname(2)/' SPECIFIC STORAGE'/
964  data aname(3)/' SPECIFIC YIELD'/
965  data aname(4)/' STORAGE COEFFICIENT'/
966  !
967  ! -- initialize
968  isfound = .false.
969  readiconv = .false.
970  readss = .false.
971  readsy = .false.
972  isconv = .false.
973  !
974  ! -- get stodata block
975  call this%parser%GetBlock('GRIDDATA', isfound, ierr)
976  if (isfound) then
977  write (this%iout, '(1x,a)') 'PROCESSING GRIDDATA'
978  do
979  call this%parser%GetNextLine(endofblock)
980  if (endofblock) exit
981  call this%parser%GetStringCaps(keyword)
982  call this%parser%GetRemainingLine(line)
983  lloc = 1
984  select case (keyword)
985  case ('ICONVERT')
986  call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
987  this%parser%iuactive, this%iconvert, &
988  aname(1))
989  readiconv = .true.
990  case ('SS')
991  call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
992  this%parser%iuactive, this%ss, &
993  aname(2))
994  readss = .true.
995  case ('SY')
996  call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
997  this%parser%iuactive, this%sy, &
998  aname(3))
999  readsy = .true.
1000  case default
1001  write (errmsg, '(a,a)') 'Unknown GRIDDATA tag: ', &
1002  trim(keyword)
1003  call store_error(errmsg)
1004  call this%parser%StoreErrorUnit()
1005  end select
1006  end do
1007  write (this%iout, '(1x,a)') 'END PROCESSING GRIDDATA'
1008  else
1009  write (errmsg, '(a)') 'Required GRIDDATA block not found.'
1010  call store_error(errmsg)
1011  call this%parser%StoreErrorUnit()
1012  end if
1013  !
1014  ! -- Check for ICONVERT
1015  if (.not. readiconv) then
1016  write (errmsg, '(a, a, a)') 'Error in GRIDDATA block: ', &
1017  trim(adjustl(aname(1))), ' not found.'
1018  call store_error(errmsg)
1019  else
1020  isconv = .false.
1021  do n = 1, this%dis%nodes
1022  if (this%iconvert(n) /= 0) then
1023  isconv = .true.
1024  this%iusesy = 1
1025  exit
1026  end if
1027  end do
1028  end if
1029  !
1030  ! -- Check for SS
1031  if (.not. readss) then
1032  write (errmsg, '(a, a, a)') 'Error in GRIDDATA block: ', &
1033  trim(adjustl(aname(2))), ' not found.'
1034  call store_error(errmsg)
1035  end if
1036  !
1037  ! -- Check for SY
1038  if (.not. readsy .and. isconv) then
1039  write (errmsg, '(a, a, a)') 'Error in GRIDDATA block: ', &
1040  trim(adjustl(aname(3))), ' not found.'
1041  call store_error(errmsg)
1042  end if
1043  !
1044  if (count_errors() > 0) then
1045  call this%parser%StoreErrorUnit()
1046  end if
1047  !
1048  ! -- Check SS and SY for negative values
1049  do n = 1, this%dis%nodes
1050  if (this%ss(n) < dzero) then
1051  call this%dis%noder_to_string(n, cellstr)
1052  write (errmsg, '(a,2(1x,a),1x,g0,1x,a)') &
1053  'Error in SS DATA: SS value in cell', trim(adjustl(cellstr)), &
1054  'is less than zero (', this%ss(n), ').'
1055  call store_error(errmsg)
1056  end if
1057  if (readsy) then
1058  if (this%sy(n) < dzero) then
1059  call this%dis%noder_to_string(n, cellstr)
1060  write (errmsg, '(a,2(1x,a),1x,g0,1x,a)') &
1061  'Error in SY DATA: SY value in cell', trim(adjustl(cellstr)), &
1062  'is less than zero (', this%sy(n), ').'
1063  call store_error(errmsg)
1064  end if
1065  end if
1066  end do
1067  !
1068  ! -- return
1069  return
Here is the call graph for this function:

◆ read_options()

subroutine gwfstomodule::read_options ( class(gwfstotype this)

Read options block for STO package.

Parameters
thisGwfStoType object

Definition at line 846 of file gwf-sto.f90.

847  ! -- modules
848  ! -- dummy variables
849  class(GwfStoType) :: this !< GwfStoType object
850  ! -- local variables
851  character(len=LINELENGTH) :: keyword, fname
852  integer(I4B) :: ierr
853  logical :: isfound, endOfBlock
854  ! -- formats
855  character(len=*), parameter :: fmtisvflow = &
856  "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
857  &WHENEVER ICBCFL IS NOT ZERO.')"
858  character(len=*), parameter :: fmtflow = &
859  &"(4x, 'FLOWS WILL BE SAVED TO FILE: ', a, /4x, 'OPENED ON UNIT: ', I7)"
860  character(len=*), parameter :: fmtorigss = &
861  "(4X,'ORIGINAL_SPECIFIC_STORAGE OPTION:',/, &
862  &1X,'The original specific storage formulation will be used')"
863  character(len=*), parameter :: fmtstoc = &
864  "(4X,'STORAGECOEFFICIENT OPTION:',/, &
865  &1X,'Read storage coefficient rather than specific storage')"
866  character(len=*), parameter :: fmtconfss = &
867  "(4X,'SS_CONFINED_ONLY OPTION:',/, &
868  &1X,'Specific storage changes only occur under confined conditions')"
869  !
870  ! -- get options block
871  call this%parser%GetBlock('OPTIONS', isfound, ierr, &
872  supportopenclose=.true., blockrequired=.false.)
873  !
874  ! -- parse options block if detected
875  if (isfound) then
876  write (this%iout, '(1x,a)') 'PROCESSING STORAGE OPTIONS'
877  do
878  call this%parser%GetNextLine(endofblock)
879  if (endofblock) exit
880  call this%parser%GetStringCaps(keyword)
881  select case (keyword)
882  case ('SAVE_FLOWS')
883  this%ipakcb = -1
884  write (this%iout, fmtisvflow)
885  case ('STORAGECOEFFICIENT')
886  this%istor_coef = 1
887  write (this%iout, fmtstoc)
888  case ('SS_CONFINED_ONLY')
889  this%iconf_ss = 1
890  this%iorig_ss = 0
891  write (this%iout, fmtconfss)
892  case ('TVS6')
893  if (this%intvs /= 0) then
894  errmsg = 'Multiple TVS6 keywords detected in OPTIONS block.'// &
895  ' Only one TVS6 entry allowed.'
896  call store_error(errmsg, terminate=.true.)
897  end if
898  call this%parser%GetStringCaps(keyword)
899  if (trim(adjustl(keyword)) /= 'FILEIN') then
900  errmsg = 'TVS6 keyword must be followed by "FILEIN" '// &
901  'then by filename.'
902  call store_error(errmsg, terminate=.true.)
903  end if
904  call this%parser%GetString(fname)
905  this%intvs = getunit()
906  call openfile(this%intvs, this%iout, fname, 'TVS')
907  call tvs_cr(this%tvs, this%name_model, this%intvs, this%iout)
908  !
909  ! -- right now these are options that are only available in the
910  ! development version and are not included in the documentation.
911  ! These options are only available when IDEVELOPMODE in
912  ! constants module is set to 1
913  case ('DEV_ORIGINAL_SPECIFIC_STORAGE')
914  this%iorig_ss = 1
915  write (this%iout, fmtorigss)
916  case ('DEV_OLDSTORAGEFORMULATION')
917  call this%parser%DevOpt()
918  this%iconf_ss = 1
919  this%iorig_ss = 0
920  write (this%iout, fmtconfss)
921  case default
922  write (errmsg, '(a,a)') 'Unknown STO option: ', &
923  trim(keyword)
924  call store_error(errmsg, terminate=.true.)
925  end select
926  end do
927  write (this%iout, '(1x,a)') 'END OF STORAGE OPTIONS'
928  end if
929  !
930  ! -- set omega value used for saturation calculations
931  if (this%inewton > 0) then
932  this%satomega = dem6
933  end if
934  !
935  ! -- return
936  return
Here is the call graph for this function:

◆ save_old_ss_sy()

subroutine gwfstomodule::save_old_ss_sy ( class(gwfstotype this)

Save ss and sy values from the previous time step for use with storage integration when integratechanges is non-zero.

Parameters
thisGwfStoType object

Definition at line 1078 of file gwf-sto.f90.

1079  ! -- modules
1081  ! -- dummy variables
1082  class(GwfStoType) :: this !< GwfStoType object
1083  ! -- local variables
1084  integer(I4B) :: n
1085  !
1086  ! -- Allocate TVS arrays if needed
1087  if (.not. associated(this%oldss)) then
1088  call mem_allocate(this%oldss, this%dis%nodes, 'OLDSS', this%memoryPath)
1089  end if
1090  if (this%iusesy == 1 .and. .not. associated(this%oldsy)) then
1091  call mem_allocate(this%oldsy, this%dis%nodes, 'OLDSY', this%memoryPath)
1092  end if
1093  !
1094  ! -- Save current specific storage
1095  do n = 1, this%dis%nodes
1096  this%oldss(n) = this%ss(n)
1097  end do
1098  !
1099  ! -- Save current specific yield, if used
1100  if (this%iusesy == 1) then
1101  do n = 1, this%dis%nodes
1102  this%oldsy(n) = this%sy(n)
1103  end do
1104  end if
1105  !
1106  ! -- Return
1107  return

◆ sto_ad()

subroutine gwfstomodule::sto_ad ( class(gwfstotype this)

Advance data in the STO package.

Parameters
thisGwfStoType object

Definition at line 256 of file gwf-sto.f90.

257  ! -- modules
258  use tdismodule, only: kstp
259  ! -- dummy variables
260  class(GwfStoType) :: this !< GwfStoType object
261  !
262  ! -- Store ss and sy values from end of last time step if needed
263  if (this%integratechanges /= 0 .and. kstp > 1) then
264  call this%save_old_ss_sy()
265  end if
266  !
267  ! -- TVS
268  if (this%intvs /= 0) then
269  call this%tvs%ad()
270  end if
271  !
272  ! -- return
273  return
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24

◆ sto_ar()

subroutine gwfstomodule::sto_ar ( class(gwfstotype this,
class(disbasetype), intent(in), pointer  dis,
integer(i4b), dimension(:), pointer, contiguous  ibound 
)

Method to allocate and read static data for the STO package.

Parameters
thisGwfStoType object
[in]dismodel discretization object
iboundmodel ibound array

Definition at line 107 of file gwf-sto.f90.

108  ! -- modules
111  ! -- dummy variables
112  class(GwfStoType) :: this !< GwfStoType object
113  class(DisBaseType), pointer, intent(in) :: dis !< model discretization object
114  integer(I4B), dimension(:), pointer, contiguous :: ibound !< model ibound array
115  ! -- local variables
116  ! -- formats
117  character(len=*), parameter :: fmtsto = &
118  "(1x,/1x,'STO -- STORAGE PACKAGE, VERSION 1, 5/19/2014', &
119  &' INPUT READ FROM UNIT ', i0, //)"
120  !
121  ! --print a message identifying the storage package.
122  write (this%iout, fmtsto) this%inunit
123  !
124  ! -- store pointers to arguments that were passed in
125  this%dis => dis
126  this%ibound => ibound
127  !
128  ! -- set pointer to gwf iss
129  call mem_setptr(this%iss, 'ISS', create_mem_path(this%name_model))
130  !
131  ! -- Allocate arrays
132  call this%allocate_arrays(dis%nodes)
133  !!
134  !! -- Register side effect handlers
135  !call this%register_handlers()
136  !
137  ! -- Read storage options
138  call this%read_options()
139  !
140  ! -- read the data block
141  call this%read_data()
142  !
143  ! -- TVS
144  if (this%intvs /= 0) then
145  call this%tvs%ar(this%dis)
146  end if
147  !
148  ! -- return
149  return
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
Here is the call graph for this function:

◆ sto_bd()

subroutine gwfstomodule::sto_bd ( class(gwfstotype this,
integer(i4b), intent(in)  isuppress_output,
type(budgettype), intent(inout)  model_budget 
)

Budget calculation for the STO package components. Components include specific storage and specific yield storage.

Parameters
thisGwfStoType object
[in]isuppress_outputflag to suppress model output
[in,out]model_budgetmodel budget object

Definition at line 636 of file gwf-sto.f90.

637  ! -- modules
638  use tdismodule, only: delt
640  ! -- dummy variables
641  class(GwfStoType) :: this !< GwfStoType object
642  integer(I4B), intent(in) :: isuppress_output !< flag to suppress model output
643  type(BudgetType), intent(inout) :: model_budget !< model budget object
644  ! -- local variables
645  real(DP) :: rin
646  real(DP) :: rout
647  !
648  ! -- Add confined storage rates to model budget
649  call rate_accumulator(this%strgss, rin, rout)
650  call model_budget%addentry(rin, rout, delt, budtxt(1), &
651  isuppress_output, ' STORAGE')
652  !
653  ! -- Add unconfined storage rates to model budget
654  if (this%iusesy == 1) then
655  call rate_accumulator(this%strgsy, rin, rout)
656  call model_budget%addentry(rin, rout, delt, budtxt(2), &
657  isuppress_output, ' STORAGE')
658  end if
659  !
660  ! -- return
661  return
This module contains the BudgetModule.
Definition: Budget.f90:20
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
Definition: Budget.f90:664
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:

◆ sto_cq()

subroutine gwfstomodule::sto_cq ( class(gwfstotype this,
real(dp), dimension(:), intent(inout), contiguous  flowja,
real(dp), dimension(:), intent(in), contiguous  hnew,
real(dp), dimension(:), intent(in), contiguous  hold 
)

Flow calculation for the STO package components. Components include specific storage and specific yield storage.

Parameters
thisGwfStoType object
[in,out]flowjaconnection flows
[in]hnewcurrent head
[in]holdprevious head

Definition at line 508 of file gwf-sto.f90.

509  ! -- modules
510  use tdismodule, only: delt
511  ! -- dummy variables
512  class(GwfStoType) :: this !< GwfStoType object
513  real(DP), dimension(:), contiguous, intent(inout) :: flowja !< connection flows
514  real(DP), dimension(:), contiguous, intent(in) :: hnew !< current head
515  real(DP), dimension(:), contiguous, intent(in) :: hold !< previous head
516  ! -- local variables
517  integer(I4B) :: n
518  integer(I4B) :: idiag
519  real(DP) :: rate
520  real(DP) :: tled
521  real(DP) :: sc1
522  real(DP) :: sc2
523  real(DP) :: rho1
524  real(DP) :: rho2
525  real(DP) :: sc1old
526  real(DP) :: sc2old
527  real(DP) :: rho1old
528  real(DP) :: rho2old
529  real(DP) :: tp
530  real(DP) :: bt
531  real(DP) :: snold
532  real(DP) :: snnew
533  real(DP) :: aterm
534  real(DP) :: rhsterm
535  !
536  ! -- initialize strg arrays
537  do n = 1, this%dis%nodes
538  this%strgss(n) = dzero
539  this%strgsy(n) = dzero
540  end do
541  !
542  ! -- Set strt to zero or calculate terms if not steady-state stress period
543  if (this%iss == 0) then
544  !
545  ! -- set variables
546  tled = done / delt
547  !
548  ! -- Calculate storage change
549  do n = 1, this%dis%nodes
550  if (this%ibound(n) <= 0) cycle
551  ! -- aquifer elevations and thickness
552  tp = this%dis%top(n)
553  bt = this%dis%bot(n)
554  !
555  ! -- aquifer saturation
556  if (this%iconvert(n) == 0) then
557  snold = done
558  snnew = done
559  else
560  snold = squadraticsaturation(tp, bt, hold(n), this%satomega)
561  snnew = squadraticsaturation(tp, bt, hnew(n), this%satomega)
562  end if
563  !
564  ! -- primary storage coefficient
565  sc1 = sscapacity(this%istor_coef, tp, bt, this%dis%area(n), this%ss(n))
566  rho1 = sc1 * tled
567  !
568  if (this%integratechanges /= 0) then
569  ! -- Integration of storage changes (e.g. when using TVS):
570  ! separate the old (start of time step) and new (end of time step)
571  ! primary storage capacities
572  sc1old = sscapacity(this%istor_coef, tp, bt, this%dis%area(n), &
573  this%oldss(n))
574  rho1old = sc1old * tled
575  else
576  ! -- No integration of storage changes: old and new values are
577  ! identical => normal MF6 storage formulation
578  rho1old = rho1
579  end if
580  !
581  ! -- calculate specific storage terms and rate
582  call ssterms(this%iconvert(n), this%iorig_ss, this%iconf_ss, tp, bt, &
583  rho1, rho1old, snnew, snold, hnew(n), hold(n), &
584  aterm, rhsterm, rate)
585  !
586  ! -- save rate
587  this%strgss(n) = rate
588  !
589  ! -- add storage term to flowja
590  idiag = this%dis%con%ia(n)
591  flowja(idiag) = flowja(idiag) + rate
592  !
593  ! -- specific yield
594  rate = dzero
595  if (this%iconvert(n) /= 0) then
596  !
597  ! -- secondary storage coefficient
598  sc2 = sycapacity(this%dis%area(n), this%sy(n))
599  rho2 = sc2 * tled
600  !
601  if (this%integratechanges /= 0) then
602  ! -- Integration of storage changes (e.g. when using TVS):
603  ! separate the old (start of time step) and new (end of time
604  ! step) secondary storage capacities
605  sc2old = sycapacity(this%dis%area(n), this%oldsy(n))
606  rho2old = sc2old * tled
607  else
608  ! -- No integration of storage changes: old and new values are
609  ! identical => normal MF6 storage formulation
610  rho2old = rho2
611  end if
612  !
613  ! -- calculate specific yield storage terms and rate
614  call syterms(tp, bt, rho2, rho2old, snnew, snold, &
615  aterm, rhsterm, rate)
616 
617  end if
618  this%strgsy(n) = rate
619  !
620  ! -- add storage term to flowja
621  idiag = this%dis%con%ia(n)
622  flowja(idiag) = flowja(idiag) + rate
623  end do
624  end if
625  !
626  ! -- return
627  return
Here is the call graph for this function:

◆ sto_cr()

subroutine, public gwfstomodule::sto_cr ( type(gwfstotype), pointer  stoobj,
character(len=*), intent(in)  name_model,
integer(i4b), intent(in)  inunit,
integer(i4b), intent(in)  iout 
)

Create a new storage (STO) object

Parameters
stoobjGwfStoType object
[in]name_modelname of model
[in]inunitpackage input file unit
[in]ioutmodel listing file unit

Definition at line 75 of file gwf-sto.f90.

76  ! -- dummy variables
77  type(GwfStoType), pointer :: stoobj !< GwfStoType object
78  character(len=*), intent(in) :: name_model !< name of model
79  integer(I4B), intent(in) :: inunit !< package input file unit
80  integer(I4B), intent(in) :: iout !< model listing file unit
81  !
82  ! -- Create the object
83  allocate (stoobj)
84  !
85  ! -- create name and memory path
86  call stoobj%set_names(1, name_model, 'STO', 'STO')
87  !
88  ! -- Allocate scalars
89  call stoobj%allocate_scalars()
90  !
91  ! -- Set variables
92  stoobj%inunit = inunit
93  stoobj%iout = iout
94  !
95  ! -- Initialize block parser
96  call stoobj%parser%Initialize(stoobj%inunit, stoobj%iout)
97  !
98  ! -- return
99  return
Here is the caller graph for this function:

◆ sto_da()

subroutine gwfstomodule::sto_da ( class(gwfstotype this)

Deallocate STO package scalars and arrays.

Parameters
thisGwfStoType object

Definition at line 717 of file gwf-sto.f90.

718  ! -- modules
720  ! -- dummy variables
721  class(GwfStoType) :: this !< GwfStoType object
722  !
723  ! -- TVS
724  if (this%intvs /= 0) then
725  call this%tvs%da()
726  deallocate (this%tvs)
727  end if
728  !
729  ! -- Deallocate arrays if package is active
730  if (this%inunit > 0) then
731  call mem_deallocate(this%iconvert)
732  call mem_deallocate(this%ss)
733  call mem_deallocate(this%sy)
734  call mem_deallocate(this%strgss)
735  call mem_deallocate(this%strgsy)
736  !
737  ! -- deallocate TVS arrays
738  if (associated(this%oldss)) then
739  call mem_deallocate(this%oldss)
740  end if
741  if (associated(this%oldsy)) then
742  call mem_deallocate(this%oldsy)
743  end if
744  end if
745  !
746  ! -- Deallocate scalars
747  call mem_deallocate(this%istor_coef)
748  call mem_deallocate(this%iconf_ss)
749  call mem_deallocate(this%iorig_ss)
750  call mem_deallocate(this%iusesy)
751  call mem_deallocate(this%satomega)
752  call mem_deallocate(this%integratechanges)
753  call mem_deallocate(this%intvs)
754  !
755  ! -- deallocate parent
756  call this%NumericalPackageType%da()
757  !
758  ! -- return
759  return

◆ sto_fc()

subroutine gwfstomodule::sto_fc ( class(gwfstotype this,
integer(i4b), intent(in)  kiter,
real(dp), dimension(:), intent(in)  hold,
real(dp), dimension(:), intent(in)  hnew,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  rhs 
)

Fill the coefficient matrix and right-hand side with the STO package terms.

Parameters
thisGwfStoType object
[in]kiterouter iteration number
[in]holdprevious heads
[in]hnewcurrent heads
matrix_slnA matrix
[in]idxgloglobal index model to solution
[in,out]rhsright-hand side

Definition at line 281 of file gwf-sto.f90.

282  ! -- modules
283  use tdismodule, only: delt
284  ! -- dummy variables
285  class(GwfStoType) :: this !< GwfStoType object
286  integer(I4B), intent(in) :: kiter !< outer iteration number
287  real(DP), intent(in), dimension(:) :: hold !< previous heads
288  real(DP), intent(in), dimension(:) :: hnew !< current heads
289  class(MatrixBaseType), pointer :: matrix_sln !< A matrix
290  integer(I4B), intent(in), dimension(:) :: idxglo !< global index model to solution
291  real(DP), intent(inout), dimension(:) :: rhs !< right-hand side
292  ! -- local variables
293  integer(I4B) :: n
294  integer(I4B) :: idiag
295  real(DP) :: tled
296  real(DP) :: sc1
297  real(DP) :: sc2
298  real(DP) :: rho1
299  real(DP) :: rho2
300  real(DP) :: sc1old
301  real(DP) :: sc2old
302  real(DP) :: rho1old
303  real(DP) :: rho2old
304  real(DP) :: tp
305  real(DP) :: bt
306  real(DP) :: snold
307  real(DP) :: snnew
308  real(DP) :: aterm
309  real(DP) :: rhsterm
310  ! -- formats
311  character(len=*), parameter :: fmtsperror = &
312  &"('DETECTED TIME STEP LENGTH OF ZERO. GWF STORAGE PACKAGE CANNOT BE ', &
313  &'USED UNLESS DELT IS NON-ZERO.')"
314  !
315  ! -- test if steady-state stress period
316  if (this%iss /= 0) return
317  !
318  ! -- Ensure time step length is not zero
319  if (delt == dzero) then
320  write (errmsg, fmtsperror)
321  call store_error(errmsg, terminate=.true.)
322  end if
323  !
324  ! -- set variables
325  tled = done / delt
326  !
327  ! -- loop through and calculate storage contribution to hcof and rhs
328  do n = 1, this%dis%nodes
329  idiag = this%dis%con%ia(n)
330  if (this%ibound(n) < 1) cycle
331  !
332  ! -- aquifer elevations and thickness
333  tp = this%dis%top(n)
334  bt = this%dis%bot(n)
335  !
336  ! -- aquifer saturation
337  if (this%iconvert(n) == 0) then
338  snold = done
339  snnew = done
340  else
341  snold = squadraticsaturation(tp, bt, hold(n), this%satomega)
342  snnew = squadraticsaturation(tp, bt, hnew(n), this%satomega)
343  end if
344  !
345  ! -- storage coefficients
346  sc1 = sscapacity(this%istor_coef, tp, bt, this%dis%area(n), this%ss(n))
347  rho1 = sc1 * tled
348  !
349  if (this%integratechanges /= 0) then
350  ! -- Integration of storage changes (e.g. when using TVS):
351  ! separate the old (start of time step) and new (end of time step)
352  ! primary storage capacities
353  sc1old = sscapacity(this%istor_coef, tp, bt, this%dis%area(n), &
354  this%oldss(n))
355  rho1old = sc1old * tled
356  else
357  ! -- No integration of storage changes: old and new values are
358  ! identical => normal MF6 storage formulation
359  rho1old = rho1
360  end if
361  !
362  ! -- calculate specific storage terms
363  call ssterms(this%iconvert(n), this%iorig_ss, this%iconf_ss, tp, bt, &
364  rho1, rho1old, snnew, snold, hnew(n), hold(n), &
365  aterm, rhsterm)
366  !
367  ! -- add specific storage terms to amat and rhs
368  call matrix_sln%add_value_pos(idxglo(idiag), aterm)
369  rhs(n) = rhs(n) + rhsterm
370  !
371  ! -- specific yield
372  if (this%iconvert(n) /= 0) then
373  rhsterm = dzero
374  !
375  ! -- secondary storage coefficient
376  sc2 = sycapacity(this%dis%area(n), this%sy(n))
377  rho2 = sc2 * tled
378  !
379  if (this%integratechanges /= 0) then
380  ! -- Integration of storage changes (e.g. when using TVS):
381  ! separate the old (start of time step) and new (end of time step)
382  ! secondary storage capacities
383  sc2old = sycapacity(this%dis%area(n), this%oldsy(n))
384  rho2old = sc2old * tled
385  else
386  ! -- No integration of storage changes: old and new values are
387  ! identical => normal MF6 storage formulation
388  rho2old = rho2
389  end if
390  !
391  ! -- calculate specific storage terms
392  call syterms(tp, bt, rho2, rho2old, snnew, snold, &
393  aterm, rhsterm)
394 !
395  ! -- add specific yield terms to amat and rhs
396  call matrix_sln%add_value_pos(idxglo(idiag), aterm)
397  rhs(n) = rhs(n) + rhsterm
398  end if
399  end do
400  !
401  ! -- return
402  return
Here is the call graph for this function:

◆ sto_fn()

subroutine gwfstomodule::sto_fn ( class(gwfstotype this,
integer(i4b), intent(in)  kiter,
real(dp), dimension(:), intent(in)  hold,
real(dp), dimension(:), intent(in)  hnew,
class(matrixbasetype), pointer  matrix_sln,
integer(i4b), dimension(:), intent(in)  idxglo,
real(dp), dimension(:), intent(inout)  rhs 
)

Fill the coefficient matrix and right-hand side with STO package with Newton-Raphson terms.

Parameters
thisGwfStoType object
[in]kiterouter iteration number
[in]holdprevious heads
[in]hnewcurrent heads
matrix_slnA matrix
[in]idxgloglobal index model to solution
[in,out]rhsright-hand side

Definition at line 411 of file gwf-sto.f90.

412  ! -- modules
413  use tdismodule, only: delt
414  ! -- dummy variables
415  class(GwfStoType) :: this !< GwfStoType object
416  integer(I4B), intent(in) :: kiter !< outer iteration number
417  real(DP), intent(in), dimension(:) :: hold !< previous heads
418  real(DP), intent(in), dimension(:) :: hnew !< current heads
419  class(MatrixBaseType), pointer :: matrix_sln !< A matrix
420  integer(I4B), intent(in), dimension(:) :: idxglo !< global index model to solution
421  real(DP), intent(inout), dimension(:) :: rhs !< right-hand side
422  ! -- local variables
423  integer(I4B) :: n
424  integer(I4B) :: idiag
425  real(DP) :: tled
426  real(DP) :: sc1
427  real(DP) :: sc2
428  real(DP) :: rho1
429  real(DP) :: rho2
430  real(DP) :: tp
431  real(DP) :: bt
432  real(DP) :: tthk
433  real(DP) :: h
434  real(DP) :: snnew
435  real(DP) :: derv
436  real(DP) :: rterm
437  real(DP) :: drterm
438  !
439  ! -- test if steady-state stress period
440  if (this%iss /= 0) return
441  !
442  ! -- set variables
443  tled = done / delt
444  !
445  ! -- loop through and calculate storage contribution to hcof and rhs
446  do n = 1, this%dis%nodes
447  idiag = this%dis%con%ia(n)
448  if (this%ibound(n) <= 0) cycle
449  !
450  ! -- aquifer elevations and thickness
451  tp = this%dis%top(n)
452  bt = this%dis%bot(n)
453  tthk = tp - bt
454  h = hnew(n)
455  !
456  ! -- aquifer saturation
457  snnew = squadraticsaturation(tp, bt, h)
458  !
459  ! -- storage coefficients
460  sc1 = sscapacity(this%istor_coef, tp, bt, this%dis%area(n), this%ss(n))
461  sc2 = sycapacity(this%dis%area(n), this%sy(n))
462  rho1 = sc1 * tled
463  rho2 = sc2 * tled
464  !
465  ! -- calculate newton terms for specific storage
466  ! and specific yield
467  if (this%iconvert(n) /= 0) then
468  !
469  ! -- calculate saturation derivative
470  derv = squadraticsaturationderivative(tp, bt, h)
471  !
472  ! -- newton terms for specific storage
473  if (this%iconf_ss == 0) then
474  if (this%iorig_ss == 0) then
475  drterm = -rho1 * derv * (h - bt) + rho1 * tthk * snnew * derv
476  else
477  drterm = -(rho1 * derv * h)
478  end if
479  call matrix_sln%add_value_pos(idxglo(idiag), drterm)
480  rhs(n) = rhs(n) + drterm * h
481  end if
482  !
483  ! -- newton terms for specific yield
484  ! only calculated if the current saturation
485  ! is less than one
486  if (snnew < done) then
487  ! -- calculate newton terms for specific yield
488  if (snnew > dzero) then
489  rterm = -rho2 * tthk * snnew
490  drterm = -rho2 * tthk * derv
491  call matrix_sln%add_value_pos(idxglo(idiag), drterm + rho2)
492  rhs(n) = rhs(n) - rterm + drterm * h + rho2 * bt
493  end if
494  end if
495  end if
496  end do
497  !
498  ! -- return
499  return
Here is the call graph for this function:

◆ sto_rp()

subroutine gwfstomodule::sto_rp ( class(gwfstotype this)

Method to read and prepare stress period data for the STO package.

Parameters
thisGwfStoType object

Definition at line 157 of file gwf-sto.f90.

158  ! -- modules
159  use tdismodule, only: kper, nper
160  implicit none
161  ! -- dummy variables
162  class(GwfStoType) :: this !< GwfStoType object
163  ! -- local variables
164  integer(I4B) :: ierr
165  logical :: isfound, readss, readsy, endOfBlock
166  character(len=16) :: css(0:1)
167  character(len=LINELENGTH) :: line, keyword
168  ! -- formats
169  character(len=*), parameter :: fmtlsp = &
170  &"(1X,/1X,'REUSING ',A,' FROM LAST STRESS PERIOD')"
171  character(len=*), parameter :: fmtblkerr = &
172  &"('Error. Looking for BEGIN PERIOD iper. Found ', a, ' instead.')"
173  ! -- data
174  data css(0)/' TRANSIENT'/
175  data css(1)/' STEADY-STATE'/
176 ! ------------------------------------------------------------------------------
177  !
178  ! -- Store ss and sy values from end of last stress period if needed
179  if (this%integratechanges /= 0) then
180  call this%save_old_ss_sy()
181  end if
182  !
183  ! -- get stress period data
184  if (this%ionper < kper) then
185  !
186  ! -- get period block
187  call this%parser%GetBlock('PERIOD', isfound, ierr, &
188  supportopenclose=.true., &
189  blockrequired=.false.)
190  if (isfound) then
191  !
192  ! -- read ionper and check for increasing period numbers
193  call this%read_check_ionper()
194  else
195  !
196  ! -- PERIOD block not found
197  if (ierr < 0) then
198  ! -- End of file found; data applies for remainder of simulation.
199  this%ionper = nper + 1
200  else
201  ! -- Found invalid block
202  call this%parser%GetCurrentLine(line)
203  write (errmsg, fmtblkerr) adjustl(trim(line))
204  call store_error(errmsg)
205  call this%parser%StoreErrorUnit()
206  end if
207  end if
208  end if
209  !
210  ! -- read data if ionper == kper
211  ! are these here to anticipate reading ss,sy per stress period?
212  readss = .false.
213  readsy = .false.
214 
215  !stotxt = aname(2)
216  if (this%ionper == kper) then
217  write (this%iout, '(//,1x,a)') 'PROCESSING STORAGE PERIOD DATA'
218  do
219  call this%parser%GetNextLine(endofblock)
220  if (endofblock) exit
221  call this%parser%GetStringCaps(keyword)
222  select case (keyword)
223  case ('STEADY-STATE')
224  this%iss = 1
225  case ('TRANSIENT')
226  this%iss = 0
227  case default
228  write (errmsg, '(a,a)') 'Unknown STORAGE data tag: ', &
229  trim(keyword)
230  call store_error(errmsg)
231  call this%parser%StoreErrorUnit()
232  end select
233  end do
234  write (this%iout, '(1x,a)') 'END PROCESSING STORAGE PERIOD DATA'
235  !else
236  ! write(this%iout,fmtlsp) 'STORAGE VALUES'
237  end if
238 
239  write (this%iout, '(//1X,A,I0,A,A,/)') &
240  'STRESS PERIOD ', kper, ' IS ', trim(adjustl(css(this%iss)))
241  !
242  ! -- TVS
243  if (this%intvs /= 0) then
244  call this%tvs%rp()
245  end if
246  !
247  ! -- return
248  return
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21
Here is the call graph for this function:

◆ sto_save_model_flows()

subroutine gwfstomodule::sto_save_model_flows ( class(gwfstotype this,
integer(i4b), intent(in)  icbcfl,
integer(i4b), intent(in)  icbcun 
)

Save cell-by-cell budget terms for the STO package.

Parameters
thisGwfStoType object
[in]icbcflflag to output budget data
[in]icbcuncell-by-cell file unit number

Definition at line 669 of file gwf-sto.f90.

670  ! -- dummy variables
671  class(GwfStoType) :: this !< GwfStoType object
672  integer(I4B), intent(in) :: icbcfl !< flag to output budget data
673  integer(I4B), intent(in) :: icbcun !< cell-by-cell file unit number
674  ! -- local variables
675  integer(I4B) :: ibinun
676  integer(I4B) :: iprint, nvaluesp, nwidthp
677  character(len=1) :: cdatafmp = ' ', editdesc = ' '
678  real(DP) :: dinact
679  !
680  ! -- Set unit number for binary output
681  if (this%ipakcb < 0) then
682  ibinun = icbcun
683  elseif (this%ipakcb == 0) then
684  ibinun = 0
685  else
686  ibinun = this%ipakcb
687  end if
688  if (icbcfl == 0) ibinun = 0
689  !
690  ! -- Record the storage rates if requested
691  if (ibinun /= 0) then
692  iprint = 0
693  dinact = dzero
694  !
695  ! -- storage(ss)
696  call this%dis%record_array(this%strgss, this%iout, iprint, -ibinun, &
697  budtxt(1), cdatafmp, nvaluesp, &
698  nwidthp, editdesc, dinact)
699  !
700  ! -- storage(sy)
701  if (this%iusesy == 1) then
702  call this%dis%record_array(this%strgsy, this%iout, iprint, -ibinun, &
703  budtxt(2), cdatafmp, nvaluesp, &
704  nwidthp, editdesc, dinact)
705  end if
706  end if
707  !
708  ! -- return
709  return

Variable Documentation

◆ budtxt

character(len=lenbudtxt), dimension(2) gwfstomodule::budtxt = [' STO-SS', ' STO-SY']

Definition at line 29 of file gwf-sto.f90.

29  character(len=LENBUDTXT), dimension(2) :: budtxt = & !< text labels for budget terms
30  &[' STO-SS', ' STO-SY']