MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
gwf-rch.f90
Go to the documentation of this file.
1 module rchmodule
2  !
3  use kindmodule, only: dp, i4b, lgp
7  use bndmodule, only: bndtype
8  use bndextmodule, only: bndexttype
10  use simvariablesmodule, only: errmsg
13  !
14  implicit none
15  !
16  private
17  public :: rch_create
18  !
19  character(len=LENFTYPE) :: ftype = 'RCH'
20  character(len=LENPACKAGENAME) :: text = ' RCH'
21  character(len=LENPACKAGENAME) :: texta = ' RCHA'
22  !
23  type, extends(bndexttype) :: rchtype
24  real(dp), dimension(:), pointer, contiguous :: recharge => null() !< boundary recharge array
25  integer(I4B), dimension(:), pointer, contiguous :: nodesontop => null() ! User provided cell numbers; nodelist is cells where recharge is applied)
26  logical, pointer, private :: fixed_cell
27 
28  contains
29 
30  procedure :: rch_allocate_scalars
31  procedure :: allocate_arrays => rch_allocate_arrays
32  procedure :: source_options => rch_source_options
33  procedure :: log_rch_options
34  procedure :: read_initial_attr => rch_read_initial_attr
35  procedure :: bnd_rp => rch_rp
36  procedure :: bnd_cf => rch_cf
37  procedure :: bnd_fc => rch_fc
38  procedure :: bnd_da => rch_da
39  procedure :: set_nodesontop
40  procedure :: define_listlabel => rch_define_listlabel
41  procedure :: bound_value => rch_bound_value
42  ! -- for observations
43  procedure, public :: bnd_obs_supported => rch_obs_supported
44  procedure, public :: bnd_df_obs => rch_df_obs
45 
46  end type rchtype
47 
48 contains
49 
50  !> @brief Create a New Recharge Package
51  !!
52  !! Create new RCH package and point packobj to the new package
53  !<
54  subroutine rch_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
55  mempath)
56  ! -- dummy
57  class(bndtype), pointer :: packobj
58  integer(I4B), intent(in) :: id
59  integer(I4B), intent(in) :: ibcnum
60  integer(I4B), intent(in) :: inunit
61  integer(I4B), intent(in) :: iout
62  character(len=*), intent(in) :: namemodel
63  character(len=*), intent(in) :: pakname
64  character(len=*), intent(in) :: mempath
65  ! -- local
66  type(rchtype), pointer :: rchobj
67  !
68  ! -- allocate recharge object and scalar variables
69  allocate (rchobj)
70  packobj => rchobj
71  !
72  ! -- create name and memory path
73  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
74  packobj%text = text
75  !
76  ! -- allocate scalars
77  call rchobj%rch_allocate_scalars()
78  !
79  ! -- initialize package
80  call packobj%pack_initialize()
81  !
82  packobj%inunit = inunit
83  packobj%iout = iout
84  packobj%id = id
85  packobj%ibcnum = ibcnum
86  packobj%ncolbnd = 1
87  packobj%ictMemPath = create_mem_path(namemodel, 'NPF')
88  end subroutine rch_create
89 
90  !> @brief Allocate scalar members
91  !<
92  subroutine rch_allocate_scalars(this)
93  ! -- dummy
94  class(rchtype), intent(inout) :: this
95  !
96  ! -- allocate base scalars
97  call this%BndExtType%allocate_scalars()
98  !
99  ! -- allocate internal members
100  allocate (this%fixed_cell)
101  !
102  ! -- Set values
103  this%fixed_cell = .false.
104  end subroutine rch_allocate_scalars
105 
106  !> @brief Allocate package arrays
107  !<
108  subroutine rch_allocate_arrays(this, nodelist, auxvar)
109  ! -- modules
111  ! -- dummy
112  class(rchtype) :: this
113  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
114  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
115  !
116  ! -- allocate base arrays
117  call this%BndExtType%allocate_arrays(nodelist, auxvar)
118  !
119  ! -- set recharge input context pointer
120  call mem_setptr(this%recharge, 'RECHARGE', this%input_mempath)
121  !
122  ! -- checkin recharge input context pointer
123  call mem_checkin(this%recharge, 'RECHARGE', this%memoryPath, &
124  'RECHARGE', this%input_mempath)
125  end subroutine rch_allocate_arrays
126 
127  !> @brief Source options specific to RchType
128  !<
129  subroutine rch_source_options(this)
130  ! -- modules
132  implicit none
133  ! -- dummy
134  class(rchtype), intent(inout) :: this
135  ! -- local
136  logical(LGP) :: found_fixed_cell = .false.
137  !
138  ! -- source common bound options
139  call this%BndExtType%source_options()
140  !
141  ! -- update defaults with idm sourced values
142  call mem_set_value(this%fixed_cell, 'FIXED_CELL', this%input_mempath, &
143  found_fixed_cell)
144  !
145  if (this%readasarrays) then
146  this%text = texta
147  end if
148  !
149  ! -- log rch params
150  call this%log_rch_options(found_fixed_cell)
151  end subroutine rch_source_options
152 
153  !> @brief Log options specific to RchType
154  !<
155  subroutine log_rch_options(this, found_fixed_cell)
156  implicit none
157  ! -- dummy
158  class(rchtype), intent(inout) :: this
159  logical(LGP), intent(in) :: found_fixed_cell
160  ! -- formats
161  character(len=*), parameter :: fmtfixedcell = &
162  &"(4x, 'RECHARGE WILL BE APPLIED TO SPECIFIED CELL.')"
163  !
164  ! -- log found options
165  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%text)) &
166  //' OPTIONS'
167  !
168  if (found_fixed_cell) then
169  write (this%iout, fmtfixedcell)
170  end if
171  !
172  ! -- close logging block
173  write (this%iout, '(1x,a)') &
174  'END OF '//trim(adjustl(this%text))//' OPTIONS'
175  end subroutine log_rch_options
176 
177  !> @brief Part of allocate and read
178  !<
179  subroutine rch_read_initial_attr(this)
180  ! -- dummy
181  class(rchtype), intent(inout) :: this
182  !
183  if (this%readasarrays) then
184  call this%default_nodelist()
185  end if
186  !
187  ! -- if fixed_cell option not set, then need to store nodelist
188  ! in the nodesontop array
189  if (.not. this%fixed_cell) call this%set_nodesontop()
190  end subroutine rch_read_initial_attr
191 
192  !> @brief Read and Prepare
193  !!
194  !! Read itmp and read new boundaries if itmp > 0
195  !<
196  subroutine rch_rp(this)
197  ! -- modules
198  use tdismodule, only: kper
199  implicit none
200  ! -- dummy
201  class(rchtype), intent(inout) :: this
202  !
203  if (this%iper /= kper) return
204  !
205  call this%BndExtType%bnd_rp()
206  !
207  ! -- copy nodelist to nodesontop if not fixed cell
208  if (.not. this%fixed_cell) call this%set_nodesontop()
209  !
210  end subroutine rch_rp
211 
212  !> @brief Store nodelist in nodesontop
213  !<
214  subroutine set_nodesontop(this)
215  implicit none
216  ! -- dummy
217  class(rchtype), intent(inout) :: this
218  ! -- local
219  integer(I4B) :: n
220  !
221  ! -- allocate if necessary
222  if (.not. associated(this%nodesontop)) then
223  allocate (this%nodesontop(this%maxbound))
224  end if
225  !
226  ! -- copy nodelist into nodesontop
227  do n = 1, this%nbound
228  this%nodesontop(n) = this%nodelist(n)
229  end do
230  end subroutine set_nodesontop
231 
232  !> @brief Formulate the HCOF and RHS terms
233  !!
234  !! Skip if no recharge. Otherwise, calculate hcof and rhs
235  !<
236  subroutine rch_cf(this)
237  ! -- dummy
238  class(rchtype) :: this
239  ! -- local
240  integer(I4B) :: i, node
241  !
242  ! -- Return if no recharge
243  if (this%nbound == 0) return
244  !
245  ! -- Calculate hcof and rhs for each recharge entry
246  do i = 1, this%nbound
247  !
248  ! -- Find the node number
249  if (this%fixed_cell) then
250  node = this%nodelist(i)
251  else
252  node = this%nodesontop(i)
253  end if
254  !
255  ! -- cycle if nonexistent bound
256  if (node <= 0) then
257  this%hcof(i) = dzero
258  this%rhs(i) = dzero
259  cycle
260  end if
261  !
262  ! -- reset nodelist to highest active
263  if (.not. this%fixed_cell) then
264  if (this%ibound(node) == 0) &
265  call this%dis%highest_active(node, this%ibound)
266  this%nodelist(i) = node
267  end if
268  !
269  ! -- Set rhs and hcof
270  this%hcof(i) = dzero
271  if (this%iauxmultcol > 0) then
272  this%rhs(i) = -this%recharge(i) * this%dis%get_area(node) * &
273  this%auxvar(this%iauxmultcol, i)
274  else
275  this%rhs(i) = -this%recharge(i) * this%dis%get_area(node)
276  end if
277  if (this%ibound(node) <= 0) then
278  this%rhs(i) = dzero
279  cycle
280  end if
281  if (this%ibound(node) == iwetlake) then
282  this%rhs(i) = dzero
283  cycle
284  end if
285  end do
286  end subroutine rch_cf
287 
288  !> @brief Copy rhs and hcof into solution rhs and amat
289  !<
290  subroutine rch_fc(this, rhs, ia, idxglo, matrix_sln)
291  ! -- dummy
292  class(rchtype) :: this
293  real(DP), dimension(:), intent(inout) :: rhs
294  integer(I4B), dimension(:), intent(in) :: ia
295  integer(I4B), dimension(:), intent(in) :: idxglo
296  class(matrixbasetype), pointer :: matrix_sln
297  ! -- local
298  integer(I4B) :: i, n, ipos
299  !
300  ! -- Copy package rhs and hcof into solution rhs and amat
301  do i = 1, this%nbound
302  n = this%nodelist(i)
303  if (n <= 0) cycle
304  ! -- reset hcof and rhs for excluded cells
305  if (this%ibound(n) == iwetlake) then
306  this%hcof(i) = dzero
307  this%rhs(i) = dzero
308  cycle
309  end if
310  rhs(n) = rhs(n) + this%rhs(i)
311  ipos = ia(n)
312  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
313  end do
314  end subroutine rch_fc
315 
316  !> @brief Deallocate memory
317  !<
318  subroutine rch_da(this)
319  ! -- modules
321  ! -- dummy
322  class(rchtype) :: this
323  !
324  ! -- Deallocate parent package
325  call this%BndExtType%bnd_da()
326  !
327  ! -- scalars
328  deallocate (this%fixed_cell)
329  !
330  ! -- arrays
331  if (associated(this%nodesontop)) deallocate (this%nodesontop)
332  call mem_deallocate(this%recharge, 'RECHARGE', this%memoryPath)
333  end subroutine rch_da
334 
335  !> @brief Define the list heading that is written to iout when PRINT_INPUT
336  !! option is used.
337  !<
338  subroutine rch_define_listlabel(this)
339  ! -- dummy
340  class(rchtype), 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), 'RECHARGE'
355 ! if(this%multindex > 0) &
356 ! write(this%listlabel, '(a, a16)') trim(this%listlabel), 'MULTIPLIER'
357  if (this%inamedbound == 1) then
358  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
359  end if
360  end subroutine rch_define_listlabel
361 
362  ! -- Procedures related to observations
363 
364  !> @brief
365  !!
366  !! Overrides BndType%bnd_obs_supported()
367  !<
368  logical function rch_obs_supported(this)
369  implicit none
370  ! -- dummy
371  class(rchtype) :: this
372  !
373  rch_obs_supported = .true.
374  end function rch_obs_supported
375 
376  !> @brief Implements bnd_df_obs
377  !!
378  !! Store observation type supported by RCH package. Overrides
379  !! BndType%bnd_df_obs
380  !<
381  subroutine rch_df_obs(this)
382  implicit none
383  ! -- dummy
384  class(rchtype) :: this
385  ! -- local
386  integer(I4B) :: indx
387  !
388  call this%obs%StoreObsType('rch', .true., indx)
389  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
390  end subroutine rch_df_obs
391 
392  !> @brief Return requested boundary value
393  !<
394  function rch_bound_value(this, col, row) result(bndval)
395  ! -- modules
396  use constantsmodule, only: dzero
397  ! -- dummy
398  class(rchtype), intent(inout) :: this
399  integer(I4B), intent(in) :: col
400  integer(I4B), intent(in) :: row
401  ! -- result
402  real(dp) :: bndval
403  !
404  select case (col)
405  case (1)
406  if (this%iauxmultcol > 0) then
407  bndval = this%recharge(row) * this%auxvar(this%iauxmultcol, row)
408  else
409  bndval = this%recharge(row)
410  end if
411  case default
412  errmsg = 'Programming error. RCH bound value requested column '&
413  &'outside range of ncolbnd (1).'
414  call store_error(errmsg)
415  call store_error_filename(this%input_fname)
416  end select
417  end function rch_bound_value
418 
419 end module rchmodule
420 
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:45
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
integer(i4b), parameter iwetlake
integer constant for a dry lake
Definition: Constants.f90:52
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
integer(i4b), parameter maxcharlen
maximum length of char string
Definition: Constants.f90:47
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 rch_allocate_arrays(this, nodelist, auxvar)
Allocate package arrays.
Definition: gwf-rch.f90:109
logical function rch_obs_supported(this)
Overrides BndTypebnd_obs_supported()
Definition: gwf-rch.f90:369
subroutine rch_df_obs(this)
Implements bnd_df_obs.
Definition: gwf-rch.f90:382
subroutine, public rch_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
Create a New Recharge Package.
Definition: gwf-rch.f90:56
subroutine rch_fc(this, rhs, ia, idxglo, matrix_sln)
Copy rhs and hcof into solution rhs and amat.
Definition: gwf-rch.f90:291
real(dp) function rch_bound_value(this, col, row)
Return requested boundary value.
Definition: gwf-rch.f90:395
subroutine rch_allocate_scalars(this)
Allocate scalar members.
Definition: gwf-rch.f90:93
character(len=lenpackagename) texta
Definition: gwf-rch.f90:21
subroutine rch_read_initial_attr(this)
Part of allocate and read.
Definition: gwf-rch.f90:180
subroutine rch_rp(this)
Read and Prepare.
Definition: gwf-rch.f90:197
subroutine rch_define_listlabel(this)
Define the list heading that is written to iout when PRINT_INPUT option is used.
Definition: gwf-rch.f90:339
subroutine rch_cf(this)
Formulate the HCOF and RHS terms.
Definition: gwf-rch.f90:237
subroutine rch_source_options(this)
Source options specific to RchType.
Definition: gwf-rch.f90:130
subroutine rch_da(this)
Deallocate memory.
Definition: gwf-rch.f90:319
character(len=lenpackagename) text
Definition: gwf-rch.f90:20
subroutine log_rch_options(this, found_fixed_cell)
Log options specific to RchType.
Definition: gwf-rch.f90:156
subroutine set_nodesontop(this)
Store nodelist in nodesontop.
Definition: gwf-rch.f90:215
character(len=lenftype) ftype
Definition: gwf-rch.f90:19
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
Definition: Sim.f90:203
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