MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
gwf-riv.f90
Go to the documentation of this file.
2 use kindmodule, only: dp, i4b
7 use bndmodule, only: bndtype
8 use bndextmodule, only: bndexttype
11 !
12 implicit none
13 !
14 private
15 public :: riv_create
16 public :: rivtype
17 !
18 character(len=LENFTYPE) :: ftype = 'RIV'
19 character(len=LENPACKAGENAME) :: text = ' RIV'
20 !
21 type, extends(bndexttype) :: rivtype
22 real(dp), dimension(:), pointer, contiguous :: stage => null() !< RIV head
23 real(dp), dimension(:), pointer, contiguous :: cond => null() !< RIV bed hydraulic conductance
24 real(dp), dimension(:), pointer, contiguous :: rbot => null() !< RIV bed bottom elevation
25
26 contains
27
30 procedure :: log_riv_options
31 procedure :: bnd_rp => riv_rp
32 procedure :: bnd_ck => riv_ck
33 procedure :: bnd_cf => riv_cf
34 procedure :: bnd_fc => riv_fc
35 procedure :: bnd_da => riv_da
36 procedure :: define_listlabel
38 procedure :: cond_mult
39 ! -- methods for observations
40 procedure, public :: bnd_obs_supported => riv_obs_supported
41 procedure, public :: bnd_df_obs => riv_df_obs
42 procedure, public :: riv_store_user_cond
43 end type rivtype
44
45contains
46
47 !> @brief Create a New Riv Package and point packobj to the new package
48 !<
49 subroutine riv_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
50 mempath)
51 ! -- dummy
52 class(bndtype), pointer :: packobj
53 integer(I4B), intent(in) :: id
54 integer(I4B), intent(in) :: ibcnum
55 integer(I4B), intent(in) :: inunit
56 integer(I4B), intent(in) :: iout
57 character(len=*), intent(in) :: namemodel
58 character(len=*), intent(in) :: pakname
59 character(len=*), intent(in) :: mempath
60 ! -- local
61 type(rivtype), pointer :: rivobj
62 !
63 ! -- allocate the object and assign values to object variables
64 allocate (rivobj)
65 packobj => rivobj
66 !
67 ! -- create name and memory path
68 call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
69 packobj%text = text
70 !
71 ! -- allocate scalars
72 call rivobj%allocate_scalars()
73 !
74 ! -- initialize package
75 call packobj%pack_initialize()
76 !
77 packobj%inunit = inunit
78 packobj%iout = iout
79 packobj%id = id
80 packobj%ibcnum = ibcnum
81 packobj%ncolbnd = 3
82 packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
83 end subroutine riv_create
84
85 !> @brief Deallocate memory
86 !<
87 subroutine riv_da(this)
88 ! -- modules
90 ! -- dummy
91 class(rivtype) :: this
92 !
93 ! -- Deallocate parent package
94 call this%BndExtType%bnd_da()
95 !
96 ! -- arrays
97 call mem_deallocate(this%stage, 'STAGE', this%memoryPath)
98 call mem_deallocate(this%cond, 'COND', this%memoryPath)
99 call mem_deallocate(this%rbot, 'RBOT', this%memoryPath)
100 end subroutine riv_da
101
102 !> @brief Set options specific to RivType
103 !<
104 subroutine riv_options(this)
105 ! -- modules
109 ! -- dummy
110 class(rivtype), intent(inout) :: this
111 ! -- local
112 type(gwfrivparamfoundtype) :: found
113 !
114 ! -- source base class options
115 call this%BndExtType%source_options()
116 !
117 ! -- source options from input context
118 call mem_set_value(this%imover, 'MOVER', this%input_mempath, found%mover)
119 !
120 ! -- log riv specific options
121 call this%log_riv_options(found)
122 end subroutine riv_options
123
124 !> @brief Log options specific to RivType
125 !<
126 subroutine log_riv_options(this, found)
127 ! -- modules
129 ! -- dummy variables
130 class(rivtype), intent(inout) :: this
131 type(gwfrivparamfoundtype), intent(in) :: found
132 !
133 ! -- log found options
134 write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
135 //' OPTIONS'
136 !
137 if (found%mover) then
138 write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
139 end if
140 !
141 ! -- close logging block
142 write (this%iout, '(1x,a)') &
143 'END OF '//trim(adjustl(this%text))//' OPTIONS'
144 end subroutine log_riv_options
145
146 !> @brief Allocate package arrays
147 !<
148 subroutine riv_allocate_arrays(this, nodelist, auxvar)
149 ! -- modules
151 ! -- dummy
152 class(rivtype) :: this
153 integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
154 real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
155 !
156 ! -- call base type allocate arrays
157 call this%BndExtType%allocate_arrays(nodelist, auxvar)
158 !
159 ! -- set riv input context pointers
160 call mem_setptr(this%stage, 'STAGE', this%input_mempath)
161 call mem_setptr(this%cond, 'COND', this%input_mempath)
162 call mem_setptr(this%rbot, 'RBOT', this%input_mempath)
163 !
164 ! --checkin riv input context pointers
165 call mem_checkin(this%stage, 'STAGE', this%memoryPath, &
166 'STAGE', this%input_mempath)
167 call mem_checkin(this%cond, 'COND', this%memoryPath, &
168 'COND', this%input_mempath)
169 call mem_checkin(this%rbot, 'RBOT', this%memoryPath, &
170 'RBOT', this%input_mempath)
171 end subroutine riv_allocate_arrays
172
173 !> @brief Read and prepare
174 !<
175 subroutine riv_rp(this)
176 ! -- modules
177 use tdismodule, only: kper
178 ! -- dummy
179 class(rivtype), intent(inout) :: this
180 !
181 if (this%iper /= kper) return
182 !
183 ! -- Call the parent class read and prepare
184 call this%BndExtType%bnd_rp()
185 !
186 ! -- store user cond
187 if (this%ivsc == 1) then
188 call this%riv_store_user_cond()
189 end if
190 end subroutine riv_rp
191
192 !> @brief Check river boundary condition data
193 !<
194 subroutine riv_ck(this)
195 ! -- modules
196 use constantsmodule, only: linelength
198 ! -- dummy
199 class(rivtype), intent(inout) :: this
200 ! -- local
201 character(len=LINELENGTH) :: errmsg
202 integer(I4B) :: i
203 integer(I4B) :: node
204 real(DP) :: bt
205 real(DP) :: stage
206 real(DP) :: rbot
207 ! -- formats
208 character(len=*), parameter :: fmtriverr = &
209 "('RIV BOUNDARY (',i0,') RIVER BOTTOM (',f10.4,') IS LESS &
210 &THAN CELL BOTTOM (',f10.4,')')"
211 character(len=*), parameter :: fmtriverr2 = &
212 "('RIV BOUNDARY (',i0,') RIVER STAGE (',f10.4,') IS LESS &
213 &THAN RIVER BOTTOM (',f10.4,')')"
214 character(len=*), parameter :: fmtriverr3 = &
215 "('RIV BOUNDARY (',i0,') RIVER STAGE (',f10.4,') IS LESS &
216 &THAN CELL BOTTOM (',f10.4,')')"
217 character(len=*), parameter :: fmtcondmulterr = &
218 "('RIV BOUNDARY (',i0,') CONDUCTANCE MULTIPLIER (',g10.3,') IS &
219 &LESS THAN ZERO')"
220 character(len=*), parameter :: fmtconderr = &
221 "('RIV BOUNDARY (',i0,') CONDUCTANCE (',g10.3,') IS LESS THAN &
222 &ZERO')"
223 !
224 ! -- check stress period data
225 do i = 1, this%nbound
226 node = this%nodelist(i)
227 bt = this%dis%bot(node)
228 stage = this%stage(i)
229 rbot = this%rbot(i)
230 ! -- accumulate errors
231 if (rbot < bt .and. this%icelltype(node) /= 0) then
232 write (errmsg, fmt=fmtriverr) i, rbot, bt
233 call store_error(errmsg)
234 end if
235 if (stage < rbot) then
236 write (errmsg, fmt=fmtriverr2) i, stage, rbot
237 call store_error(errmsg)
238 end if
239 if (stage < bt .and. this%icelltype(node) /= 0) then
240 write (errmsg, fmt=fmtriverr3) i, stage, bt
241 call store_error(errmsg)
242 end if
243 if (this%iauxmultcol > 0) then
244 if (this%auxvar(this%iauxmultcol, i) < dzero) then
245 write (errmsg, fmt=fmtcondmulterr) &
246 i, this%auxvar(this%iauxmultcol, i)
247 call store_error(errmsg)
248 end if
249 end if
250 if (this%cond(i) < dzero) then
251 write (errmsg, fmt=fmtconderr) i, this%cond(i)
252 call store_error(errmsg)
253 end if
254 end do
255 !
256 ! -- write summary of river package error messages
257 if (count_errors() > 0) then
258 call store_error_unit(this%inunit)
259 end if
260 end subroutine riv_ck
261
262 !> @brief Formulate the HCOF and RHS terms
263 !!
264 !! Skip in no rivs, otherwise calculate hcof and rhs
265 !<
266 subroutine riv_cf(this)
267 ! -- dummy
268 class(rivtype) :: this
269 ! -- local
270 integer(I4B) :: i, node
271 real(DP) :: hriv, criv, rbot
272 !
273 ! -- Return if no rivs
274 if (this%nbound .eq. 0) return
275 !
276 ! -- Calculate hcof and rhs for each riv entry
277 do i = 1, this%nbound
278 node = this%nodelist(i)
279 if (this%ibound(node) <= 0) then
280 this%hcof(i) = dzero
281 this%rhs(i) = dzero
282 cycle
283 end if
284 hriv = this%stage(i)
285 criv = this%cond_mult(i)
286 rbot = this%rbot(i)
287 if (this%xnew(node) <= rbot) then
288 this%rhs(i) = -criv * (hriv - rbot)
289 this%hcof(i) = dzero
290 else
291 this%rhs(i) = -criv * hriv
292 this%hcof(i) = -criv
293 end if
294 end do
295 end subroutine riv_cf
296
297 !> @brief Copy rhs and hcof into solution rhs and amat
298 !<
299 subroutine riv_fc(this, rhs, ia, idxglo, matrix_sln)
300 ! -- dummy
301 class(rivtype) :: this
302 real(DP), dimension(:), intent(inout) :: rhs
303 integer(I4B), dimension(:), intent(in) :: ia
304 integer(I4B), dimension(:), intent(in) :: idxglo
305 class(matrixbasetype), pointer :: matrix_sln
306 ! -- local
307 integer(I4B) :: i, n, ipos
308 real(DP) :: qriv
309 !
310 ! -- pakmvrobj fc
311 if (this%imover == 1) then
312 call this%pakmvrobj%fc()
313 end if
314 !
315 ! -- Copy package rhs and hcof into solution rhs and amat
316 do i = 1, this%nbound
317 n = this%nodelist(i)
318 rhs(n) = rhs(n) + this%rhs(i)
319 ipos = ia(n)
320 call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
321 !
322 ! -- If mover is active and this river cell is discharging,
323 ! store available water (as positive value). Use the assembled
324 ! coefficients so terms added to hcof and rhs after riv_cf, such
325 ! as the BUY density terms, are included.
326 if (this%imover == 1) then
327 qriv = this%rhs(i) - this%hcof(i) * this%xnew(n)
328 if (qriv > dzero) then
329 call this%pakmvrobj%accumulate_qformvr(i, qriv)
330 end if
331 end if
332 end do
333 end subroutine riv_fc
334
335 !> @brief Define the list heading that is written to iout when PRINT_INPUT
336 !! option is used.
337 !<
338 subroutine define_listlabel(this)
339 ! -- modules
340 class(rivtype), intent(inout) :: this
341 !
342 ! -- create the header list label
343 this%listlabel = trim(this%filtyp)//' NO.'
344 if (this%dis%ndim == 3) then
345 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
346 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
347 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
348 elseif (this%dis%ndim == 2) then
349 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
350 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
351 else
352 write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
353 end if
354 write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STAGE'
355 write (this%listlabel, '(a, a16)') trim(this%listlabel), 'CONDUCTANCE'
356 write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOTTOM EL.'
357 if (this%inamedbound == 1) then
358 write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
359 end if
360 end subroutine define_listlabel
361
362 ! -- Procedures related to observations
363
364 !> @brief Return true because RIV package supports observations
365 !!
366 !! Return true because RIV package supports observations.
367 !>
368 logical function riv_obs_supported(this)
369 implicit none
370 ! -- dummy
371 class(rivtype) :: this
372 !
373 riv_obs_supported = .true.
374 end function riv_obs_supported
375
376 !> @brief Store observation type supported by RIV package
377 !!
378 !! Overrides BndType%bnd_df_obs
379 !<
380 subroutine riv_df_obs(this)
381 implicit none
382 ! -- dummy
383 class(rivtype) :: this
384 ! -- local
385 integer(I4B) :: indx
386 !
387 call this%obs%StoreObsType('riv', .true., indx)
388 this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
389 !
390 ! -- Store obs type and assign procedure pointer
391 ! for to-mvr observation type.
392 call this%obs%StoreObsType('to-mvr', .true., indx)
393 this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
394 end subroutine riv_df_obs
395
396 !> @brief Store user-specified conductance value
397 !<
398 subroutine riv_store_user_cond(this)
399 ! -- dummy
400 class(rivtype), intent(inout) :: this
401 ! -- local
402 integer(I4B) :: n
403 !
404 ! -- store backup copy of conductance values
405 do n = 1, this%nbound
406 this%condinput(n) = this%cond_mult(n)
407 end do
408 end subroutine riv_store_user_cond
409
410 !> @brief Apply multiplier to conductance if auxmultcol option is in use
411 !<
412 function cond_mult(this, row) result(cond)
413 ! -- modules
414 use constantsmodule, only: dzero
415 ! -- dummy
416 class(rivtype), intent(inout) :: this
417 integer(I4B), intent(in) :: row
418 ! -- result
419 real(dp) :: cond
420 !
421 if (this%iauxmultcol > 0) then
422 cond = this%cond(row) * this%auxvar(this%iauxmultcol, row)
423 else
424 cond = this%cond(row)
425 end if
426 end function cond_mult
427
428 !> @brief Return requested boundary value
429 !<
430 function riv_bound_value(this, col, row) result(bndval)
431 ! -- modules
432 use constantsmodule, only: dzero
433 ! -- dummy
434 class(rivtype), intent(inout) :: this
435 integer(I4B), intent(in) :: col
436 integer(I4B), intent(in) :: row
437 ! -- result
438 real(dp) :: bndval
439 !
440 select case (col)
441 case (1)
442 bndval = this%stage(row)
443 case (2)
444 bndval = this%cond_mult(row)
445 case (3)
446 bndval = this%rbot(row)
447 case default
448 errmsg = 'Programming error. RIV bound value requested column '&
449 &'outside range of ncolbnd (3).'
450 call store_error(errmsg)
451 call store_error_filename(this%input_fname)
452 end select
453 end function riv_bound_value
454
455end module rivmodule
This module contains the extended boundary package.
real(dp) function bound_value(this, col, row)
@ brief Return a bound value
subroutine source_options(this)
@ brief Source package options from input context
This module contains the base boundary package.
logical(lgp) function bnd_obs_supported(this)
Determine if observations are supported.
subroutine bnd_rp(this)
@ brief Allocate and read method for package
subroutine bnd_da(this)
@ brief Deallocate package memory
subroutine bnd_fc(this, rhs, ia, idxglo, matrix_sln)
@ brief Copy hcof and rhs terms into solution.
subroutine allocate_arrays(this, nodelist, auxvar)
@ brief Allocate package arrays
subroutine bnd_ck(this)
@ brief Check boundary package period data
subroutine bnd_df_obs(this)
Define the observation types available in the package.
subroutine bnd_cf(this)
@ brief Formulate the package hcof and rhs terms.
This module contains simulation constants.
Definition Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition Constants.f90:45
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition Constants.f90:23
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition Constants.f90:39
real(dp), parameter dzero
real constant zero
Definition Constants.f90:65
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 the derived type ObsType.
Definition Obs.f90:127
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
Definition Obs.f90:246
subroutine riv_store_user_cond(this)
Store user-specified conductance value.
Definition gwf-riv.f90:399
logical function riv_obs_supported(this)
Return true because RIV package supports observations.
Definition gwf-riv.f90:369
real(dp) function cond_mult(this, row)
Apply multiplier to conductance if auxmultcol option is in use.
Definition gwf-riv.f90:413
subroutine riv_allocate_arrays(this, nodelist, auxvar)
Allocate package arrays.
Definition gwf-riv.f90:149
subroutine log_riv_options(this, found)
Log options specific to RivType.
Definition gwf-riv.f90:127
subroutine riv_df_obs(this)
Store observation type supported by RIV package.
Definition gwf-riv.f90:381
character(len=lenftype) ftype
Definition gwf-riv.f90:18
subroutine define_listlabel(this)
Define the list heading that is written to iout when PRINT_INPUT option is used.
Definition gwf-riv.f90:339
subroutine riv_options(this)
Set options specific to RivType.
Definition gwf-riv.f90:105
character(len=lenpackagename) text
Definition gwf-riv.f90:19
subroutine, public riv_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
Create a New Riv Package and point packobj to the new package.
Definition gwf-riv.f90:51
subroutine riv_cf(this)
Formulate the HCOF and RHS terms.
Definition gwf-riv.f90:267
real(dp) function riv_bound_value(this, col, row)
Return requested boundary value.
Definition gwf-riv.f90:431
subroutine riv_ck(this)
Check river boundary condition data.
Definition gwf-riv.f90:195
subroutine riv_da(this)
Deallocate memory.
Definition gwf-riv.f90:88
subroutine riv_fc(this, rhs, ia, idxglo, matrix_sln)
Copy rhs and hcof into solution rhs and amat.
Definition gwf-riv.f90:300
subroutine riv_rp(this)
Read and prepare.
Definition gwf-riv.f90:176
This module contains simulation methods.
Definition Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition Sim.f90:92
integer(i4b) function, public count_errors()
Return number of errors.
Definition Sim.f90:59
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition Sim.f90:204
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition Sim.f90:169
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
integer(i4b) iout
file unit number for simulation output
integer(i4b), pointer, public kper
current stress period number
Definition tdis.f90:26
This class is used to store a single deferred-length character string. It was designed to work in an ...