MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
gwt-src.f90
Go to the documentation of this file.
2  !
3  use kindmodule, only: dp, i4b, lgp
5  use tspfmimodule, only: tspfmitype
6  use bndmodule, only: bndtype
12  !
13  implicit none
14  !
15  private
16  public :: src_create
17  !
18  character(len=LENFTYPE) :: ftype = 'SRC'
19  character(len=16) :: text = ' SRC'
20  !
21  type, extends(bndtype) :: gwtsrctype
22 
23  character(len=LENVARNAME) :: depvartype = '' !< stores string of dependent variable type, depending on model type
24  type(tspfmitype), pointer :: fmi => null() ! pointer to GWE fmi object
25  logical(LGP), pointer :: highest_sat => null()
26  integer(I4B), dimension(:), pointer, contiguous :: nodesontop => null() ! User provided cell numbers; nodelist is cells where recharge is applied)
27 
28  contains
29 
30  procedure :: allocate_scalars => src_allocate_scalars
31  procedure :: allocate_arrays => src_allocate_arrays
32  procedure :: bnd_options => src_options
33  procedure :: bnd_rp => src_rp
34  procedure :: bnd_cf => src_cf
35  procedure :: bnd_fc => src_fc
36  procedure :: bnd_da => src_da
37  procedure :: define_listlabel
38  procedure :: set_nodesontop
39  ! -- methods for observations
40  procedure, public :: bnd_obs_supported => src_obs_supported
41  procedure, public :: bnd_df_obs => src_df_obs
42  ! -- methods for time series
43  procedure, public :: bnd_rp_ts => src_rp_ts
44 
45  end type gwtsrctype
46 
47 contains
48 
49  !> @brief Create a source loading package
50  !!
51  !! This subroutine points bndobj to the newly created package
52  !<
53  subroutine src_create(packobj, id, ibcnum, inunit, iout, namemodel, &
54  depvartype, pakname, fmi)
55  ! -- dummy
56  class(bndtype), pointer :: packobj
57  integer(I4B), intent(in) :: id
58  integer(I4B), intent(in) :: ibcnum
59  integer(I4B), intent(in) :: inunit
60  integer(I4B), intent(in) :: iout
61  character(len=*), intent(in) :: namemodel
62  character(len=*), intent(in) :: pakname
63  character(len=LENVARNAME), intent(in) :: depvartype
64  type(tspfmitype), intent(in), target :: fmi
65  ! -- local
66  type(gwtsrctype), pointer :: srcobj
67  !
68  ! -- allocate the object and assign values to object variables
69  allocate (srcobj)
70  packobj => srcobj
71  !
72  ! -- create name and memory path
73  call packobj%set_names(ibcnum, namemodel, pakname, ftype)
74  packobj%text = text
75  !
76  ! -- allocate scalars
77  call srcobj%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%iscloc = 1
88  !
89  ! -- Store the appropriate label based on the dependent variable
90  srcobj%depvartype = depvartype
91 
92  srcobj%fmi => fmi
93 
94  end subroutine src_create
95 
96  !> @brief Set additional options specific to the GwtSrcType
97  !!
98  !! This routine overrides BndType%bnd_options
99  !<
100  subroutine src_options(this, option, found)
101  ! -- dummy
102  class(gwtsrctype), intent(inout) :: this
103  character(len=*), intent(inout) :: option
104  logical, intent(inout) :: found
105  ! -- local
106  ! -- formats
107 
108  found = .true.
109  select case (option)
110  case ('HIGHEST_SATURATED')
111  this%highest_sat = .true.
112  write (this%iout, '(4x,a)') &
113  'Mass source loading rate will be applied to the highest cell at or below &
114  &the specified cellid with a non-zero saturation.'
115  case default
116  !
117  ! -- No options found
118  found = .false.
119  end select
120  end subroutine src_options
121 
122  !> @brief Deallocate memory
123  !<
124  subroutine src_da(this)
125  ! -- modules
127  ! -- dummy
128  class(gwtsrctype) :: this
129  !
130  ! -- Deallocate parent package
131  call this%BndType%bnd_da()
132  !
133  ! -- arrays
134  if (this%highest_sat) then
135  call mem_deallocate(this%nodesontop, "NODESONTOP", this%memoryPath)
136  end if
137  !
138  ! -- scalars
139  call mem_deallocate(this%highest_sat)
140  end subroutine src_da
141 
142  !> @brief Allocate scalars
143  !!
144  !! Allocate scalars specific to this source loading package
145  !<
146  subroutine src_allocate_scalars(this)
148  ! -- dummy
149  class(gwtsrctype) :: this
150  !
151  ! -- call standard BndType allocate scalars
152  call this%BndType%allocate_scalars()
153  !
154  ! -- allocate the object and assign values to object variables
155  call mem_allocate(this%highest_sat, 'HIGHEST_SAT', this%memoryPath)
156  !
157  ! -- Set values
158  this%highest_sat = .false.
159 
160  end subroutine src_allocate_scalars
161 
162  !> @brief Allocate arrays
163  !!
164  !! Allocate scalars specific to this source loading package
165  !<
166  subroutine src_allocate_arrays(this, nodelist, auxvar)
168  ! -- dummy
169  class(gwtsrctype) :: this
170  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist !< package nodelist
171  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar !< package aux variable array
172  ! local
173  integer(I4B) :: n
174  !
175  ! -- call standard BndType allocate scalars
176  call this%BndType%allocate_arrays(nodelist, auxvar)
177  !
178  ! -- allocate the object and assign values to object variables
179  if (this%highest_sat) then
180  call mem_allocate(this%nodesontop, this%maxbound, 'NODESONTOP', &
181  this%memoryPath)
182  end if
183  !
184  ! -- Set values
185  if (this%highest_sat) then
186  do n = 1, this%maxbound
187  this%nodesontop(n) = 0
188  end do
189  end if
190 
191  end subroutine src_allocate_arrays
192 
193  subroutine src_rp(this)
194  ! -- modules
195  ! -- dummy
196  class(gwtsrctype), intent(inout) :: this !< BndType object
197 
198  ! call standard BndType rp
199  call this%BndType%bnd_rp()
200 
201  if (this%highest_sat) call this%set_nodesontop()
202 
203  return
204 
205  end subroutine src_rp
206 
207  !> @brief Store nodelist in nodesontop
208  !<
209  subroutine set_nodesontop(this)
210  implicit none
211  ! -- dummy
212  class(gwtsrctype), intent(inout) :: this
213  ! -- local
214  integer(I4B) :: n
215  ! !
216  ! ! -- allocate if necessary
217  ! if (.not. associated(this%nodesontop)) then
218  ! allocate (this%nodesontop(this%maxbound))
219  ! end if
220  !
221  ! -- copy nodelist into nodesontop
222  do n = 1, this%nbound
223  this%nodesontop(n) = this%nodelist(n)
224  end do
225  end subroutine set_nodesontop
226 
227  !> @brief Formulate the HCOF and RHS terms
228  !!
229  !! This subroutine:
230  !! - calculates hcof and rhs terms
231  !! - skip if no sources
232  !<
233  subroutine src_cf(this)
234  ! -- dummy
235  class(gwtsrctype) :: this
236  ! -- local
237  integer(I4B) :: i, node
238  real(DP) :: q
239  !
240  ! -- Return if no sources
241  if (this%nbound == 0) return
242  !
243  ! -- Calculate hcof and rhs for each source entry
244  do i = 1, this%nbound
245  !
246  ! -- Find the node number
247  if (this%highest_sat) then
248  node = this%nodesontop(i)
249  else
250  node = this%nodelist(i)
251  end if
252  !
253  ! -- reset nodelist to highest active
254  if (this%highest_sat) then
255  if (this%fmi%gwfsat(node) == 0) &
256  call this%dis%highest_saturated(node, this%fmi%gwfsat)
257  this%nodelist(i) = node
258  end if
259 
260  this%hcof(i) = dzero
261  if (this%ibound(node) <= 0) then
262  this%rhs(i) = dzero
263  cycle
264  end if
265  q = this%bound(1, i)
266  this%rhs(i) = -q
267  end do
268  end subroutine src_cf
269 
270  !> @brief Add matrix terms related to specified mass source loading
271  !!
272  !! Copy rhs and hcof into solution rhs and amat
273  !<
274  subroutine src_fc(this, rhs, ia, idxglo, matrix_sln)
275  ! -- dummy
276  class(gwtsrctype) :: this
277  real(DP), dimension(:), intent(inout) :: rhs
278  integer(I4B), dimension(:), intent(in) :: ia
279  integer(I4B), dimension(:), intent(in) :: idxglo
280  class(matrixbasetype), pointer :: matrix_sln
281  ! -- local
282  integer(I4B) :: i, n, ipos
283  !
284  ! -- pakmvrobj fc
285  if (this%imover == 1) then
286  call this%pakmvrobj%fc()
287  end if
288  !
289  ! -- Copy package rhs and hcof into solution rhs and amat
290  do i = 1, this%nbound
291  n = this%nodelist(i)
292  rhs(n) = rhs(n) + this%rhs(i)
293  ipos = ia(n)
294  call matrix_sln%add_value_pos(idxglo(ipos), this%hcof(i))
295  !
296  ! -- If mover is active and mass is being withdrawn,
297  ! store available mass (as positive value).
298  if (this%imover == 1 .and. this%rhs(i) > dzero) then
299  call this%pakmvrobj%accumulate_qformvr(i, this%rhs(i))
300  end if
301  end do
302  end subroutine src_fc
303 
304  !> @brief Define list labels
305  !!
306  !! Define the list heading that is written to iout when PRINT_INPUT
307  !! option is used.
308  !<
309  subroutine define_listlabel(this)
310  ! -- dummy
311  class(gwtsrctype), intent(inout) :: this
312  ! -- local
313  !
314  ! -- create the header list label
315  this%listlabel = trim(this%filtyp)//' NO.'
316  if (this%dis%ndim == 3) then
317  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
318  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'ROW'
319  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'COL'
320  elseif (this%dis%ndim == 2) then
321  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'LAYER'
322  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'CELL2D'
323  else
324  write (this%listlabel, '(a, a7)') trim(this%listlabel), 'NODE'
325  end if
326  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'STRESS RATE'
327  if (this%inamedbound == 1) then
328  write (this%listlabel, '(a, a16)') trim(this%listlabel), 'BOUNDARY NAME'
329  end if
330  end subroutine define_listlabel
331 
332  ! -- Procedures related to observations
333  !> @brief Support function for specified mass source loading observations
334  !!
335  !! This function:
336  !! - returns true because SRC package supports observations.
337  !! - overrides BndType%bnd_obs_supported()
338  !<
339  logical function src_obs_supported(this)
340  implicit none
341  ! -- dummy
342  class(gwtsrctype) :: this
343  !
344  src_obs_supported = .true.
345  end function src_obs_supported
346 
347  !> @brief Define observations
348  !!
349  !! This subroutine:
350  !! - stores observation types supported by SRC package.
351  !! - overrides BndType%bnd_df_obs
352  !<
353  subroutine src_df_obs(this)
354  implicit none
355  ! -- dummy
356  class(gwtsrctype) :: this
357  ! -- local
358  integer(I4B) :: indx
359  !
360  call this%obs%StoreObsType('src', .true., indx)
361  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
362  !
363  ! -- Store obs type and assign procedure pointer
364  ! for to-mvr observation type.
365  call this%obs%StoreObsType('to-mvr', .true., indx)
366  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
367  end subroutine src_df_obs
368 
369  !> @brief Procedure related to time series
370  !!
371  !! Assign tsLink%Text appropriately for all time series in use by package.
372  !! In the SRC package only the SMASSRATE variable can be controlled by time
373  !! series.
374  !<
375  subroutine src_rp_ts(this)
376  ! -- dummy
377  class(gwtsrctype), intent(inout) :: this
378  ! -- local
379  integer(I4B) :: i, nlinks
380  type(timeserieslinktype), pointer :: tslink => null()
381  !
382  nlinks = this%TsManager%boundtslinks%Count()
383  do i = 1, nlinks
384  tslink => gettimeserieslinkfromlist(this%TsManager%boundtslinks, i)
385  if (associated(tslink)) then
386  if (tslink%JCol == 1) then
387  tslink%Text = 'SMASSRATE'
388  end if
389  end if
390  end do
391  end subroutine src_rp_ts
392 
393 end module gwtsrcmodule
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains the base boundary package.
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dem1
real constant 1e-1
Definition: Constants.f90:103
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
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
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
character(len=lenftype) ftype
Definition: gwt-src.f90:18
subroutine src_fc(this, rhs, ia, idxglo, matrix_sln)
Add matrix terms related to specified mass source loading.
Definition: gwt-src.f90:275
subroutine src_cf(this)
Formulate the HCOF and RHS terms.
Definition: gwt-src.f90:234
character(len=16) text
Definition: gwt-src.f90:19
subroutine src_allocate_arrays(this, nodelist, auxvar)
Allocate arrays.
Definition: gwt-src.f90:167
subroutine, public src_create(packobj, id, ibcnum, inunit, iout, namemodel, depvartype, pakname, fmi)
Create a source loading package.
Definition: gwt-src.f90:55
subroutine set_nodesontop(this)
Store nodelist in nodesontop.
Definition: gwt-src.f90:210
subroutine src_allocate_scalars(this)
Allocate scalars.
Definition: gwt-src.f90:147
subroutine src_options(this, option, found)
Set additional options specific to the GwtSrcType.
Definition: gwt-src.f90:101
subroutine src_da(this)
Deallocate memory.
Definition: gwt-src.f90:125
subroutine define_listlabel(this)
Define list labels.
Definition: gwt-src.f90:310
subroutine src_rp(this)
Definition: gwt-src.f90:194
subroutine src_rp_ts(this)
Procedure related to time series.
Definition: gwt-src.f90:376
subroutine src_df_obs(this)
Define observations.
Definition: gwt-src.f90:354
logical function src_obs_supported(this)
Support function for specified mass source loading observations.
Definition: gwt-src.f90:340
This module defines variable data types.
Definition: kind.f90:8
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
type(timeserieslinktype) function, pointer, public gettimeserieslinkfromlist(list, indx)
Get time series link from a list.
@ brief BndType