MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
gwf-tvk.f90
Go to the documentation of this file.
1 !> @brief This module contains time-varying conductivity package methods
2 !!
3 !! This module contains the methods used to allow hydraulic conductivity
4 !! parameters in the NPF package (K11, K22, K33) to be varied throughout
5 !! a simulation.
6 !!
7 !<
8 module tvkmodule
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 :: tvktype
24  public :: tvk_cr
25 
26  type, extends(tvbasetype) :: tvktype
27  integer(I4B), pointer :: ik22overk => null() !< NPF flag that k22 is specified as anisotropy ratio
28  integer(I4B), pointer :: ik33overk => null() !< NPF flag that k33 is specified as anisotropy ratio
29  real(dp), dimension(:), pointer, contiguous :: k11 => null() !< NPF hydraulic conductivity; if anisotropic, then this is Kx prior to rotation
30  real(dp), dimension(:), pointer, contiguous :: k22 => null() !< NPF hydraulic conductivity; if specified then this is Ky prior to rotation
31  real(dp), dimension(:), pointer, contiguous :: k33 => null() !< NPF hydraulic conductivity; if specified then this is Kz prior to rotation
32  integer(I4B), pointer :: kchangeper => null() !< NPF last stress period in which any node K (or K22, or K33) values were changed (0 if unchanged from start of simulation)
33  integer(I4B), pointer :: kchangestp => null() !< NPF last time step in which any node K (or K22, or K33) values were changed (0 if unchanged from start of simulation)
34  integer(I4B), dimension(:), pointer, contiguous :: nodekchange => null() !< NPF grid array of flags indicating for each node whether its K (or K22, or K33) value changed (1) at (kchangeper, kchangestp) or not (0)
35  real(dp), dimension(:), pointer, contiguous :: k11_src => null() !< input K values
36  real(dp), dimension(:), pointer, contiguous :: k22_src => null() !< input K22 values
37  real(dp), dimension(:), pointer, contiguous :: k33_src => null() !< input K33 values
38 
39  contains
40 
41  procedure :: da => tvk_da
47  end type tvktype
48 
49 contains
50 
51  !> @brief Create a new TvkType object
52  !!
53  !! Create a new time-varying conductivity (TvkType) object.
54  !<
55  subroutine tvk_cr(tvk, name_model, mempath, inunit, iout)
56  ! -- dummy
57  type(tvktype), pointer, intent(out) :: tvk
58  character(len=*), intent(in) :: name_model
59  character(len=*), intent(in) :: mempath
60  integer(I4B), intent(in) :: inunit
61  integer(I4B), intent(in) :: iout
62  !
63  allocate (tvk)
64  call tvk%init(name_model, 'TVK', 'TVK', mempath, inunit, iout)
65  end subroutine tvk_cr
66 
67  !> @brief Announce package and set pointers to variables
68  !!
69  !! Announce package version and set array and variable pointers from the NPF
70  !! package for access by TVK.
71  !<
72  subroutine tvk_ar_set_pointers(this)
73  ! -- dummy
74  class(tvktype) :: this
75  ! -- local
76  character(len=LENMEMPATH) :: npfMemoryPath
77  ! -- formats
78  character(len=*), parameter :: fmttvk = &
79  "(1x,/1x,'TVK -- TIME-VARYING K PACKAGE, VERSION 1, 08/18/2021', &
80  &' INPUT READ FROM MEMPATH ', A, //)"
81  !
82  write (this%iout, fmttvk) this%input_mempath
83  !
84  npfmemorypath = create_mem_path(this%name_model, 'NPF')
85  call mem_setptr(this%ik22overk, 'IK22OVERK', npfmemorypath)
86  call mem_setptr(this%ik33overk, 'IK33OVERK', npfmemorypath)
87  call mem_setptr(this%k11, 'K11', npfmemorypath)
88  call mem_setptr(this%k22, 'K22', npfmemorypath)
89  call mem_setptr(this%k33, 'K33', npfmemorypath)
90  call mem_setptr(this%kchangeper, 'KCHANGEPER', npfmemorypath)
91  call mem_setptr(this%kchangestp, 'KCHANGESTP', npfmemorypath)
92  call mem_setptr(this%nodekchange, 'NODEKCHANGE', npfmemorypath)
93  !
94  ! -- set input mempath pointers
95  call mem_setptr(this%k11_src, 'K', this%input_mempath)
96  call mem_setptr(this%k22_src, 'K22', this%input_mempath)
97  call mem_setptr(this%k33_src, 'K33', this%input_mempath)
98  end subroutine tvk_ar_set_pointers
99 
100  !> @brief Apply this node's K/K22/K33 input values to node.
101  !!
102  !! Called for every tracked node; the DNODATA check on each field
103  !! makes this a no-op except where a value is set. node may be invalid
104  !! even when a field has a value at nodeu, so each field validates
105  !! node itself before using it.
106  !<
107  subroutine tvk_apply_row_changes(this, nodeu, node)
108  ! -- dummy
109  class(tvktype) :: this
110  integer(I4B), intent(in) :: nodeu
111  integer(I4B), intent(in) :: node
112  ! -- local
113  character(len=LINELENGTH) :: cellstr
114  ! -- formats
115  character(len=*), parameter :: fmtvalchg = &
116  "(a, ' package: Setting ', a, ' value for cell ', a, ' at start of &
117  &stress period ', i0, ' = ', g12.5)"
118  !
119  ! -- K is processed before K22/K33 so that validate_change can use
120  ! -- the already-updated k11 value when ik22overk/ik33overk are set.
121  if (this%k11_src(nodeu) /= dnodata) then
122  if (node < 1 .or. node > this%dis%nodes) then
123  call this%dis%noder_to_string(node, cellstr)
124  write (errmsg, '(a,2(1x,a))') &
125  'CELLID', trim(cellstr), 'is not in the active model domain.'
126  call store_error(errmsg)
127  else
128  this%k11(node) = this%k11_src(nodeu)
129  call this%validate_change(node, 'K')
130  if (this%iprpak /= 0) then
131  call this%dis%noder_to_string(node, cellstr)
132  write (this%iout, fmtvalchg) &
133  trim(adjustl(this%packName)), 'K', trim(cellstr), kper, &
134  this%k11(node)
135  end if
136  end if
137  end if
138  !
139  if (this%k22_src(nodeu) /= dnodata) then
140  if (node < 1 .or. node > this%dis%nodes) then
141  call this%dis%noder_to_string(node, cellstr)
142  write (errmsg, '(a,2(1x,a))') &
143  'CELLID', trim(cellstr), 'is not in the active model domain.'
144  call store_error(errmsg)
145  else
146  this%k22(node) = this%k22_src(nodeu)
147  call this%validate_change(node, 'K22')
148  if (this%iprpak /= 0) then
149  call this%dis%noder_to_string(node, cellstr)
150  write (this%iout, fmtvalchg) &
151  trim(adjustl(this%packName)), 'K22', trim(cellstr), kper, &
152  this%k22(node)
153  end if
154  end if
155  end if
156  !
157  if (this%k33_src(nodeu) /= dnodata) then
158  if (node < 1 .or. node > this%dis%nodes) then
159  call this%dis%noder_to_string(node, cellstr)
160  write (errmsg, '(a,2(1x,a))') &
161  'CELLID', trim(cellstr), 'is not in the active model domain.'
162  call store_error(errmsg)
163  else
164  this%k33(node) = this%k33_src(nodeu)
165  call this%validate_change(node, 'K33')
166  if (this%iprpak /= 0) then
167  call this%dis%noder_to_string(node, cellstr)
168  write (this%iout, fmtvalchg) &
169  trim(adjustl(this%packName)), 'K33', trim(cellstr), kper, &
170  this%k33(node)
171  end if
172  end if
173  end if
174  end subroutine tvk_apply_row_changes
175 
176  !> @brief Mark property changes as having occurred at (kper, kstp)
177  !!
178  !! Deferred procedure implementation called by the TvBaseType code when a
179  !! property value change occurs at (kper, kstp).
180  !<
181  subroutine tvk_set_changed_at(this, kper, kstp)
182  ! -- dummy
183  class(tvktype) :: this
184  integer(I4B), intent(in) :: kper
185  integer(I4B), intent(in) :: kstp
186  !
187  this%kchangeper = kper
188  this%kchangestp = kstp
189  end subroutine tvk_set_changed_at
190 
191  !> @brief Clear all per-node change flags
192  !!
193  !! Deferred procedure implementation called by the TvBaseType code when a
194  !! new time step commences, indicating that any previously set per-node
195  !! property value change flags should be reset.
196  !<
197  subroutine tvk_reset_change_flags(this)
198  ! -- dummy variables
199  class(tvktype) :: this
200  ! -- local variables
201  integer(I4B) :: i
202  !
203  do i = 1, this%dis%nodes
204  this%nodekchange(i) = 0
205  end do
206  end subroutine tvk_reset_change_flags
207 
208  !> @brief Check that a given property value is valid
209  !!
210  !! Deferred procedure implementation called by the TvBaseType code after a
211  !! property value change occurs. Check if the property value of the given
212  !! variable at the given node is invalid, and log an error if so. Update
213  !! K22 and K33 values appropriately when specified as anisotropy.
214  !<
215  subroutine tvk_validate_change(this, n, varName)
216  ! -- dummy
217  class(tvktype) :: this
218  integer(I4B), intent(in) :: n
219  character(len=*), intent(in) :: varName
220  ! -- local
221  character(len=LINELENGTH) :: cellstr
222  ! -- formats
223  character(len=*), parameter :: fmtkerr = &
224  "(1x, a, ' changed hydraulic property ', a, ' is <= 0 for cell ', a, &
225  &' ', 1pg15.6)"
226  !
227  ! -- Mark the node as being changed this time step
228  this%nodekchange(n) = 1
229  !
230  ! -- Check the changed value is ok
231  if (varname == 'K') then
232  if (this%k11(n) <= dzero) then
233  call this%dis%noder_to_string(n, cellstr)
234  write (errmsg, fmtkerr) &
235  trim(adjustl(this%packName)), 'K', trim(cellstr), this%k11(n)
236  call store_error(errmsg)
237  end if
238  elseif (varname == 'K22') then
239  if (this%ik22overk == 1) then
240  this%k22(n) = this%k22(n) * this%k11(n)
241  end if
242  if (this%k22(n) <= dzero) then
243  call this%dis%noder_to_string(n, cellstr)
244  write (errmsg, fmtkerr) &
245  trim(adjustl(this%packName)), 'K22', trim(cellstr), this%k22(n)
246  call store_error(errmsg)
247  end if
248  elseif (varname == 'K33') then
249  if (this%ik33overk == 1) then
250  this%k33(n) = this%k33(n) * this%k11(n)
251  end if
252  if (this%k33(n) <= dzero) then
253  call this%dis%noder_to_string(n, cellstr)
254  write (errmsg, fmtkerr) &
255  trim(adjustl(this%packName)), 'K33', trim(cellstr), this%k33(n)
256  call store_error(errmsg)
257  end if
258  end if
259  end subroutine tvk_validate_change
260 
261  !> @brief Deallocate package memory
262  !!
263  !! Deallocate TVK package scalars and arrays.
264  !<
265  subroutine tvk_da(this)
266  ! -- dummy
267  class(tvktype) :: this
268  !
269  nullify (this%ik22overk)
270  nullify (this%ik33overk)
271  nullify (this%k11)
272  nullify (this%k22)
273  nullify (this%k33)
274  nullify (this%kchangeper)
275  nullify (this%kchangestp)
276  nullify (this%nodekchange)
277  nullify (this%k11_src)
278  nullify (this%k22_src)
279  nullify (this%k33_src)
280  call tvbase_da(this)
281  end subroutine tvk_da
282 
283 end module tvkmodule
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
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 time-varying conductivity package methods.
Definition: gwf-tvk.f90:8
subroutine tvk_set_changed_at(this, kper, kstp)
Mark property changes as having occurred at (kper, kstp)
Definition: gwf-tvk.f90:182
subroutine tvk_da(this)
Deallocate package memory.
Definition: gwf-tvk.f90:266
subroutine tvk_ar_set_pointers(this)
Announce package and set pointers to variables.
Definition: gwf-tvk.f90:73
subroutine tvk_validate_change(this, n, varName)
Check that a given property value is valid.
Definition: gwf-tvk.f90:216
subroutine tvk_apply_row_changes(this, nodeu, node)
Apply this node's K/K22/K33 input values to node.
Definition: gwf-tvk.f90:108
subroutine tvk_reset_change_flags(this)
Clear all per-node change flags.
Definition: gwf-tvk.f90:198
subroutine, public tvk_cr(tvk, name_model, mempath, inunit, iout)
Create a new TvkType object.
Definition: gwf-tvk.f90:56