MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
gwf-riv.f90
Go to the documentation of this file.
1 module rivmodule
2  use kindmodule, only: dp, i4b
4  use simvariablesmodule, only: errmsg
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 
28  procedure :: allocate_arrays => riv_allocate_arrays
29  procedure :: source_options => riv_options
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
37  procedure :: bound_value => riv_bound_value
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 
45 contains
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%ictMemPath = create_mem_path(namemodel, 'NPF')
82  !
83  ! -- Return
84  return
85  end subroutine riv_create
86 
87  !> @brief Deallocate memory
88  !<
89  subroutine riv_da(this)
90  ! -- modules
92  ! -- dummy
93  class(rivtype) :: this
94  !
95  ! -- Deallocate parent package
96  call this%BndExtType%bnd_da()
97  !
98  ! -- arrays
99  call mem_deallocate(this%stage, 'STAGE', this%memoryPath)
100  call mem_deallocate(this%cond, 'COND', this%memoryPath)
101  call mem_deallocate(this%rbot, 'RBOT', this%memoryPath)
102  !
103  ! -- Return
104  return
105  end subroutine riv_da
106 
107  !> @brief Set options specific to RivType
108  !<
109  subroutine riv_options(this)
110  ! -- modules
114  ! -- dummy
115  class(rivtype), intent(inout) :: this
116  ! -- local
117  type(gwfrivparamfoundtype) :: found
118  !
119  ! -- source base class options
120  call this%BndExtType%source_options()
121  !
122  ! -- source options from input context
123  call mem_set_value(this%imover, 'MOVER', this%input_mempath, found%mover)
124  !
125  ! -- log riv specific options
126  call this%log_riv_options(found)
127  !
128  ! -- Return
129  return
130  end subroutine riv_options
131 
132  !> @brief Log options specific to RivType
133  !<
134  subroutine log_riv_options(this, found)
135  ! -- modules
137  ! -- dummy variables
138  class(rivtype), intent(inout) :: this !< BndExtType object
139  type(gwfrivparamfoundtype), intent(in) :: found
140  !
141  ! -- log found options
142  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
143  //' OPTIONS'
144  !
145  if (found%mover) then
146  write (this%iout, '(4x,A)') 'MOVER OPTION ENABLED'
147  end if
148  !
149  ! -- close logging block
150  write (this%iout, '(1x,a)') &
151  'END OF '//trim(adjustl(this%text))//' OPTIONS'
152  !
153  ! -- Return
154  return
155  end subroutine log_riv_options
156 
157  !> @brief Allocate package arrays
158  !<
159  subroutine riv_allocate_arrays(this, nodelist, auxvar)
160  ! -- modules
162  ! -- dummy
163  class(rivtype) :: this
164  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
165  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
166  !
167  ! -- call base type allocate arrays
168  call this%BndExtType%allocate_arrays(nodelist, auxvar)
169  !
170  ! -- set riv input context pointers
171  call mem_setptr(this%stage, 'STAGE', this%input_mempath)
172  call mem_setptr(this%cond, 'COND', this%input_mempath)
173  call mem_setptr(this%rbot, 'RBOT', this%input_mempath)
174  !
175  ! --checkin riv input context pointers
176  call mem_checkin(this%stage, 'STAGE', this%memoryPath, &
177  'STAGE', this%input_mempath)
178  call mem_checkin(this%cond, 'COND', this%memoryPath, &
179  'COND', this%input_mempath)
180  call mem_checkin(this%rbot, 'RBOT', this%memoryPath, &
181  'RBOT', this%input_mempath)
182  !
183  ! -- Return
184  return
185  end subroutine riv_allocate_arrays
186 
187  !> @brief Read and prepare
188  !<
189  subroutine riv_rp(this)
190  ! -- modules
191  use tdismodule, only: kper
192  ! -- dummy
193  class(rivtype), intent(inout) :: this
194  !
195  if (this%iper /= kper) return
196  !
197  ! -- Call the parent class read and prepare
198  call this%BndExtType%bnd_rp()
199  !
200  ! -- store user cond
201  if (this%ivsc == 1) then
202  call this%riv_store_user_cond()
203  end if
204  !
205  ! -- Write the list to iout if requested
206  if (this%iprpak /= 0) then
207  call this%write_list()
208  end if
209  !
210  ! -- Return
211  return
212  end subroutine riv_rp
213 
214  !> @brief Check river boundary condition data
215  !<
216  subroutine riv_ck(this)
217  ! -- modules
218  use constantsmodule, only: linelength
220  ! -- dummy
221  class(rivtype), intent(inout) :: this
222  ! -- local
223  character(len=LINELENGTH) :: errmsg
224  integer(I4B) :: i
225  integer(I4B) :: node
226  real(DP) :: bt
227  real(DP) :: stage
228  real(DP) :: rbot
229  ! -- formats
230  character(len=*), parameter :: fmtriverr = &
231  "('RIV BOUNDARY (',i0,') RIVER BOTTOM (',f10.4,') IS LESS &
232  &THAN CELL BOTTOM (',f10.4,')')"
233  character(len=*), parameter :: fmtriverr2 = &
234  "('RIV BOUNDARY (',i0,') RIVER STAGE (',f10.4,') IS LESS &
235  &THAN RIVER BOTTOM (',f10.4,')')"
236  character(len=*), parameter :: fmtriverr3 = &
237  "('RIV BOUNDARY (',i0,') RIVER STAGE (',f10.4,') IS LESS &
238  &THAN CELL BOTTOM (',f10.4,')')"
239  character(len=*), parameter :: fmtcondmulterr = &
240  "('RIV BOUNDARY (',i0,') CONDUCTANCE MULTIPLIER (',g10.3,') IS &
241  &LESS THAN ZERO')"
242  character(len=*), parameter :: fmtconderr = &
243  "('RIV BOUNDARY (',i0,') CONDUCTANCE (',g10.3,') IS LESS THAN &
244  &ZERO')"
245  !
246  ! -- check stress period data
247  do i = 1, this%nbound
248  node = this%nodelist(i)
249  bt = this%dis%bot(node)
250  stage = this%stage(i)
251  rbot = this%rbot(i)
252  ! -- accumulate errors
253  if (rbot < bt .and. this%icelltype(node) /= 0) then
254  write (errmsg, fmt=fmtriverr) i, rbot, bt
255  call store_error(errmsg)
256  end if
257  if (stage < rbot) then
258  write (errmsg, fmt=fmtriverr2) i, stage, rbot
259  call store_error(errmsg)
260  end if
261  if (stage < bt .and. this%icelltype(node) /= 0) then
262  write (errmsg, fmt=fmtriverr3) i, stage, bt
263  call store_error(errmsg)
264  end if
265  if (this%iauxmultcol > 0) then
266  if (this%auxvar(this%iauxmultcol, i) < dzero) then
267  write (errmsg, fmt=fmtcondmulterr) &
268  i, this%auxvar(this%iauxmultcol, i)
269  call store_error(errmsg)
270  end if
271  end if
272  if (this%cond(i) < dzero) then
273  write (errmsg, fmt=fmtconderr) i, this%cond(i)
274  call store_error(errmsg)
275  end if
276  end do
277  !
278  ! -- write summary of river package error messages
279  if (count_errors() > 0) then
280  call store_error_unit(this%inunit)
281  end if
282  !
283  ! -- Return
284  return
285  end subroutine riv_ck
286 
287  !> @brief Formulate the HCOF and RHS terms
288  !!
289  !! Skip in no rivs, otherwise calculate hcof and rhs
290  !<
291  subroutine riv_cf(this)
292  ! -- dummy
293  class(rivtype) :: this
294  ! -- local
295  integer(I4B) :: i, node
296  real(DP) :: hriv, criv, rbot
297  !
298  ! -- Return if no rivs
299  if (this%nbound .eq. 0) return
300  !
301  ! -- Calculate hcof and rhs for each riv entry
302  do i = 1, this%nbound
303  node = this%nodelist(i)
304  if (this%ibound(node) <= 0) then
305  this%hcof(i) = dzero
306  this%rhs(i) = dzero
307  cycle
308  end if
309  hriv = this%stage(i)
310  criv = this%cond_mult(i)
311  rbot = this%rbot(i)
312  if (this%xnew(node) <= rbot) then
313  this%rhs(i) = -criv * (hriv - rbot)
314  this%hcof(i) = dzero
315  else
316  this%rhs(i) = -criv * hriv
317  this%hcof(i) = -criv
318  end if
319  end do
320  !
321  ! -- Return
322  return
323  end subroutine riv_cf
324 
325  !> @brief Copy rhs and hcof into solution rhs and amat
326  !<
327  subroutine riv_fc(this, rhs, ia, idxglo, matrix_sln)
328  ! -- dummy
329  class(rivtype) :: this
330  real(DP), dimension(:), intent(inout) :: rhs
331  integer(I4B), dimension(:), intent(in) :: ia
332  integer(I4B), dimension(:), intent(in) :: idxglo
333  class(matrixbasetype), pointer :: matrix_sln
334  ! -- local
335  integer(I4B) :: i, n, ipos
336  real(DP) :: cond, stage, qriv !, rbot
337  !
338  ! -- pakmvrobj fc
339  if (this%imover == 1) then
340  call this%pakmvrobj%fc()
341  end if
342  !
343  ! -- Copy package rhs and hcof into solution rhs and amat
344  do i = 1, this%nbound
345  n = this%nodelist(i)
346  rhs(n) = rhs(n) + this%rhs(i)
347  ipos = ia(n)
348  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
349  !
350  ! -- If mover is active and this river cell is discharging,
351  ! store available water (as positive value).
352  stage = this%stage(i)
353  if (this%imover == 1 .and. this%xnew(n) > stage) then
354  cond = this%cond_mult(i)
355  qriv = cond * (this%xnew(n) - stage)
356  call this%pakmvrobj%accumulate_qformvr(i, qriv)
357  end if
358  end do
359  !
360  ! -- Return
361  return
362  end subroutine riv_fc
363 
364  !> @brief Define the list heading that is written to iout when PRINT_INPUT
365  !! option is used.
366  !<
367  subroutine define_listlabel(this)
368  ! -- modules
369  class(rivtype), intent(inout) :: this
370  !
371  ! -- create the header list label
372  this%listlabel = trim(this%filtyp)//' NO.'
373  if (this%dis%ndim == 3) then
374  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
375  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
376  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
377  elseif (this%dis%ndim == 2) then
378  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
379  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
380  else
381  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
382  end if
383  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STAGE'
384  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'CONDUCTANCE'
385  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOTTOM EL.'
386  if (this%inamedbound == 1) then
387  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
388  end if
389  !
390  ! -- Return
391  return
392  end subroutine define_listlabel
393 
394  ! -- Procedures related to observations
395 
396  !> @brief Return true because RIV package supports observations
397  !!
398  !! Return true because RIV package supports observations.
399  !>
400  logical function riv_obs_supported(this)
401  implicit none
402  ! -- dummy
403  class(rivtype) :: this
404  !
405  riv_obs_supported = .true.
406  !
407  ! -- Return
408  return
409  end function riv_obs_supported
410 
411  !> @brief Store observation type supported by RIV package
412  !!
413  !! Overrides BndType%bnd_df_obs
414  !<
415  subroutine riv_df_obs(this)
416  implicit none
417  ! -- dummy
418  class(rivtype) :: this
419  ! -- local
420  integer(I4B) :: indx
421  !
422  call this%obs%StoreObsType('riv', .true., indx)
423  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
424  !
425  ! -- Store obs type and assign procedure pointer
426  ! for to-mvr observation type.
427  call this%obs%StoreObsType('to-mvr', .true., indx)
428  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
429  !
430  ! -- Return
431  return
432  end subroutine riv_df_obs
433 
434  !> @brief Store user-specified conductance value
435  !<
436  subroutine riv_store_user_cond(this)
437  ! -- dummy
438  class(rivtype), intent(inout) :: this !< BndExtType object
439  ! -- local
440  integer(I4B) :: n
441  !
442  ! -- store backup copy of conductance values
443  do n = 1, this%nbound
444  this%condinput(n) = this%cond_mult(n)
445  end do
446  !
447  ! -- Return
448  return
449  end subroutine riv_store_user_cond
450 
451  !> @brief Apply multiplier to conductance if auxmultcol option is in use
452  !<
453  function cond_mult(this, row) result(cond)
454  ! -- modules
455  use constantsmodule, only: dzero
456  ! -- dummy
457  class(rivtype), intent(inout) :: this !< BndExtType object
458  integer(I4B), intent(in) :: row
459  ! -- result
460  real(dp) :: cond
461  !
462  if (this%iauxmultcol > 0) then
463  cond = this%cond(row) * this%auxvar(this%iauxmultcol, row)
464  else
465  cond = this%cond(row)
466  end if
467  !
468  ! -- Return
469  return
470  end function cond_mult
471 
472  !> @brief Return requested boundary value
473  !<
474  function riv_bound_value(this, col, row) result(bndval)
475  ! -- modules
476  use constantsmodule, only: dzero
477  ! -- dummy
478  class(rivtype), intent(inout) :: this !< BndExtType object
479  integer(I4B), intent(in) :: col
480  integer(I4B), intent(in) :: row
481  ! -- result
482  real(dp) :: bndval
483  !
484  select case (col)
485  case (1)
486  bndval = this%stage(row)
487  case (2)
488  bndval = this%cond_mult(row)
489  case (3)
490  bndval = this%rbot(row)
491  case default
492  errmsg = 'Programming error. RIV bound value requested column '&
493  &'outside range of ncolbnd (3).'
494  call store_error(errmsg)
495  call store_error_filename(this%input_fname)
496  end select
497  !
498  ! -- Return
499  return
500  end function riv_bound_value
501 
502 end module rivmodule
This module contains the extended boundary package.
This module contains the base boundary package.
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:44
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:22
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:38
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
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:249
subroutine riv_store_user_cond(this)
Store user-specified conductance value.
Definition: gwf-riv.f90:437
logical function riv_obs_supported(this)
Return true because RIV package supports observations.
Definition: gwf-riv.f90:401
real(dp) function cond_mult(this, row)
Apply multiplier to conductance if auxmultcol option is in use.
Definition: gwf-riv.f90:454
subroutine riv_allocate_arrays(this, nodelist, auxvar)
Allocate package arrays.
Definition: gwf-riv.f90:160
subroutine log_riv_options(this, found)
Log options specific to RivType.
Definition: gwf-riv.f90:135
subroutine riv_df_obs(this)
Store observation type supported by RIV package.
Definition: gwf-riv.f90:416
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:368
subroutine riv_options(this)
Set options specific to RivType.
Definition: gwf-riv.f90:110
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:292
real(dp) function riv_bound_value(this, col, row)
Return requested boundary value.
Definition: gwf-riv.f90:475
subroutine riv_ck(this)
Check river boundary condition data.
Definition: gwf-riv.f90:217
subroutine riv_da(this)
Deallocate memory.
Definition: gwf-riv.f90:90
subroutine riv_fc(this, rhs, ia, idxglo, matrix_sln)
Copy rhs and hcof into solution rhs and amat.
Definition: gwf-riv.f90:328
subroutine riv_rp(this)
Read and prepare.
Definition: gwf-riv.f90:190
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:203
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
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:23
@ brief BndType
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23