MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
gwf-tvs.f90
Go to the documentation of this file.
1 !> @brief This module contains the time-varying storage package methods
2 !!
3 !! This module contains the methods used to allow storage parameters in the
4 !! STO package (specific storage and specific yield) to be varied throughout
5 !! a simulation.
6 !!
7 !<
8 module tvsmodule
9  use basedismodule, only: disbasetype
11  use kindmodule, only: i4b, dp
14  use simmodule, only: store_error
15  use simvariablesmodule, only: errmsg
16  use tdismodule, only: kper
18 
19  implicit none
20 
21  private
22 
23  public :: tvstype
24  public :: tvs_cr
25 
26  type, extends(tvbasetype) :: tvstype
27  integer(I4B), pointer :: integratechanges => null() !< STO flag indicating if mid-simulation ss and sy changes should be integrated via an additional matrix formulation term
28  integer(I4B), pointer :: iusesy => null() !< STO flag set if any cell is convertible (0, 1)
29  real(dp), dimension(:), pointer, contiguous :: ss => null() !< STO specific storage or storage coefficient
30  real(dp), dimension(:), pointer, contiguous :: sy => null() !< STO specific yield
31  real(dp), dimension(:), pointer, contiguous :: ss_src => null() !< input SS values
32  real(dp), dimension(:), pointer, contiguous :: sy_src => null() !< input SY values
33 
34  contains
35 
36  procedure :: da => tvs_da
38  procedure :: source_package_options => tvs_source_package_options
43  end type tvstype
44 
45 contains
46 
47  !> @brief Create a new TvsType object
48  !!
49  !! Create a new time-varying storage (TVS) object.
50  !<
51  subroutine tvs_cr(tvs, name_model, mempath, inunit, iout)
52  ! -- dummy
53  type(tvstype), pointer, intent(out) :: tvs
54  character(len=*), intent(in) :: name_model
55  character(len=*), intent(in) :: mempath
56  integer(I4B), intent(in) :: inunit
57  integer(I4B), intent(in) :: iout
58  !
59  allocate (tvs)
60  call tvs%init(name_model, 'TVS', 'TVS', mempath, inunit, iout)
61  end subroutine tvs_cr
62 
63  !> @brief Announce package and set pointers to variables
64  !!
65  !! Announce package version, set array and variable pointers from the STO
66  !! package for access by TVS, and enable storage change integration.
67  !<
68  subroutine tvs_ar_set_pointers(this)
69  ! -- dummy
70  class(tvstype) :: this
71  ! -- local
72  character(len=LENMEMPATH) :: stoMemoryPath
73  ! -- formats
74  character(len=*), parameter :: fmttvs = &
75  "(1x,/1x,'TVS -- TIME-VARYING S PACKAGE, VERSION 1, 08/18/2021', &
76  &' INPUT READ FROM MEMPATH ', A, //)"
77  !
78  write (this%iout, fmttvs) this%input_mempath
79  !
80  stomemorypath = create_mem_path(this%name_model, 'STO')
81  call mem_setptr(this%integratechanges, 'INTEGRATECHANGES', stomemorypath)
82  call mem_setptr(this%iusesy, 'IUSESY', stomemorypath)
83  call mem_setptr(this%ss, 'SS', stomemorypath)
84  call mem_setptr(this%sy, 'SY', stomemorypath)
85  !
86  ! -- Instruct STO to integrate storage changes, since TVS is active
87  this%integratechanges = 1
88  !
89  ! -- set input mempath pointers
90  call mem_setptr(this%ss_src, 'SS', this%input_mempath)
91  call mem_setptr(this%sy_src, 'SY', this%input_mempath)
92  end subroutine tvs_ar_set_pointers
93 
94  !> @brief Source TVS-specific options from the input memory path.
95  !<
96  subroutine tvs_source_package_options(this)
97  ! -- dummy
98  class(tvstype) :: this
99  ! -- locals
100  integer(I4B) :: isize
101  ! -- formats
102  character(len=*), parameter :: fmtdsci = &
103  "(4X, 'DISABLE_STORAGE_CHANGE_INTEGRATION OPTION:', /, 6X, &
104  &'Storage derivative terms will not be added to STO matrix formulation')"
105  !
106  ! -- DISABLE_STORAGE_CHANGE_INTEGRATION is a keyword; check via get_isize
107  call get_isize('DISABLE_SC_INT', this%input_mempath, isize)
108  if (isize > 0) then
109  this%integratechanges = 0
110  write (this%iout, fmtdsci)
111  end if
112  end subroutine tvs_source_package_options
113 
114  !> @brief Apply this node's SS/SY input values to node.
115  !!
116  !! Called for every tracked node; the DNODATA check on each field
117  !! makes this a no-op except where a value is set. node may be invalid
118  !! even when a field has a value at nodeu, so each field validates
119  !! node itself before using it.
120  !<
121  subroutine tvs_apply_row_changes(this, nodeu, node)
122  ! -- dummy
123  class(tvstype) :: this
124  integer(I4B), intent(in) :: nodeu
125  integer(I4B), intent(in) :: node
126  ! -- local
127  character(len=LINELENGTH) :: cellstr
128  ! -- formats
129  character(len=*), parameter :: fmtvalchg = &
130  "(a, ' package: Setting ', a, ' value for cell ', a, ' at start of &
131  &stress period ', i0, ' = ', g12.5)"
132  !
133  if (this%ss_src(nodeu) /= dnodata) then
134  if (node < 1 .or. node > this%dis%nodes) then
135  call this%dis%noder_to_string(node, cellstr)
136  write (errmsg, '(a,2(1x,a))') &
137  'CELLID', trim(cellstr), 'is not in the active model domain.'
138  call store_error(errmsg)
139  else
140  this%ss(node) = this%ss_src(nodeu)
141  call this%validate_change(node, 'SS')
142  if (this%iprpak /= 0) then
143  call this%dis%noder_to_string(node, cellstr)
144  write (this%iout, fmtvalchg) &
145  trim(adjustl(this%packName)), 'SS', trim(cellstr), kper, &
146  this%ss(node)
147  end if
148  end if
149  end if
150  !
151  if (this%sy_src(nodeu) /= dnodata) then
152  if (node < 1 .or. node > this%dis%nodes) then
153  call this%dis%noder_to_string(node, cellstr)
154  write (errmsg, '(a,2(1x,a))') &
155  'CELLID', trim(cellstr), 'is not in the active model domain.'
156  call store_error(errmsg)
157  else
158  this%sy(node) = this%sy_src(nodeu)
159  call this%validate_change(node, 'SY')
160  if (this%iprpak /= 0) then
161  call this%dis%noder_to_string(node, cellstr)
162  write (this%iout, fmtvalchg) &
163  trim(adjustl(this%packName)), 'SY', trim(cellstr), kper, &
164  this%sy(node)
165  end if
166  end if
167  end if
168  end subroutine tvs_apply_row_changes
169 
170  !> @brief Mark property changes as having occurred at (kper, kstp)
171  !!
172  !! Deferred procedure implementation called by the TvBaseType code when a
173  !! property value change occurs at (kper, kstp).
174  !<
175  subroutine tvs_set_changed_at(this, kper, kstp)
176  ! -- dummy
177  class(tvstype) :: this
178  integer(I4B), intent(in) :: kper
179  integer(I4B), intent(in) :: kstp
180  !
181  ! -- No need to record TVS/STO changes, as no other packages cache
182  ! -- Ss or Sy values
183  end subroutine tvs_set_changed_at
184 
185  !> @brief Clear all per-node change flags
186  !!
187  !! Deferred procedure implementation called by the TvBaseType code when a
188  !! new time step commences, indicating that any previously set per-node
189  !! property value change flags should be reset.
190  !<
191  subroutine tvs_reset_change_flags(this)
192  ! -- dummy
193  class(tvstype) :: this
194  !
195  ! -- No need to record TVS/STO changes, as no other packages cache
196  ! -- Ss or Sy values
197  end subroutine tvs_reset_change_flags
198 
199  !> @brief Check that a given property value is valid
200  !!
201  !! Deferred procedure implementation called by the TvBaseType code after a
202  !! property value change occurs. Check if the property value of the given
203  !! variable at the given node is invalid, and log an error if so.
204  !<
205  subroutine tvs_validate_change(this, n, varName)
206  ! -- dummy
207  class(tvstype) :: this
208  integer(I4B), intent(in) :: n
209  character(len=*), intent(in) :: varName
210  ! -- local
211  character(len=LINELENGTH) :: cellstr
212  ! -- formats
213  character(len=*), parameter :: fmtserr = &
214  "(1x, a, ' changed storage property ', a, ' is < 0 for cell ', a,' ', &
215  &1pg15.6)"
216  character(len=*), parameter :: fmtsyerr = &
217  "(1x, a, ' cannot change ', a ,' for cell ', a, ' because SY is unused &
218  &in this model (all ICONVERT flags are 0).')"
219  !
220  if (varname == 'SS') then
221  if (this%ss(n) < dzero) then
222  call this%dis%noder_to_string(n, cellstr)
223  write (errmsg, fmtserr) trim(adjustl(this%packName)), 'SS', &
224  trim(cellstr), this%ss(n)
225  call store_error(errmsg)
226  end if
227  elseif (varname == 'SY') then
228  if (this%iusesy /= 1) then
229  call this%dis%noder_to_string(n, cellstr)
230  write (errmsg, fmtsyerr) trim(adjustl(this%packName)), 'SY', &
231  trim(cellstr)
232  call store_error(errmsg)
233  elseif (this%sy(n) < dzero) then
234  call this%dis%noder_to_string(n, cellstr)
235  write (errmsg, fmtserr) trim(adjustl(this%packName)), 'SY', &
236  trim(cellstr), this%sy(n)
237  call store_error(errmsg)
238  end if
239  end if
240  end subroutine tvs_validate_change
241 
242  !> @brief Deallocate package memory
243  !!
244  !! Deallocate TVS package scalars and arrays.
245  !<
246  subroutine tvs_da(this)
247  ! -- dummy
248  class(tvstype) :: this
249  !
250  nullify (this%integratechanges)
251  nullify (this%iusesy)
252  nullify (this%ss)
253  nullify (this%sy)
254  nullify (this%ss_src)
255  nullify (this%sy_src)
256  call tvbase_da(this)
257  end subroutine tvs_da
258 
259 end module tvsmodule
Apply this node's current input value(s) to the model property array(s).
Definition: TvBase.f90:72
Announce package and set pointers to variables.
Definition: TvBase.f90:57
Clear all per-node change flags.
Definition: TvBase.f90:103
Mark property changes as having occurred at (kper, kstp)
Definition: TvBase.f90:87
Check that a given property value is valid.
Definition: TvBase.f90:118
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
This module defines variable data types.
Definition: kind.f90:8
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:26
This module contains common time-varying property functionality.
Definition: TvBase.f90:8
subroutine, public tvbase_da(this)
Deallocate package memory.
Definition: TvBase.f90:336
This module contains the time-varying storage package methods.
Definition: gwf-tvs.f90:8
subroutine tvs_ar_set_pointers(this)
Announce package and set pointers to variables.
Definition: gwf-tvs.f90:69
subroutine tvs_validate_change(this, n, varName)
Check that a given property value is valid.
Definition: gwf-tvs.f90:206
subroutine tvs_set_changed_at(this, kper, kstp)
Mark property changes as having occurred at (kper, kstp)
Definition: gwf-tvs.f90:176
subroutine tvs_apply_row_changes(this, nodeu, node)
Apply this node's SS/SY input values to node.
Definition: gwf-tvs.f90:122
subroutine tvs_source_package_options(this)
Source TVS-specific options from the input memory path.
Definition: gwf-tvs.f90:97
subroutine tvs_reset_change_flags(this)
Clear all per-node change flags.
Definition: gwf-tvs.f90:192
subroutine tvs_da(this)
Deallocate package memory.
Definition: gwf-tvs.f90:247
subroutine, public tvs_cr(tvs, name_model, mempath, inunit, iout)
Create a new TvsType object.
Definition: gwf-tvs.f90:52