MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
gwt-uzt.f90
Go to the documentation of this file.
1 ! -- Unsaturated Zone Flow Transport Module
2 ! -- todo: what to do about reactions in uzf? Decay?
3 ! -- todo: save the uzt concentration into the uzt aux variable?
4 ! -- todo: calculate the uzf DENSE aux variable using concentration?
5 ! -- todo: GWD and GWD-TO-MVR do not seem to be included; prob in UZF?
6 !
7 ! UZF flows (flowbudptr) index var UZT term Transport Type
8 !---------------------------------------------------------------------------------
9 
10 ! -- terms from UZF that will be handled by parent APT Package
11 ! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv
12 ! GWF (aux FLOW-AREA) idxbudgwf GWF uzf2gwf
13 ! STORAGE (aux VOLUME) idxbudsto none used for water volumes
14 ! FROM-MVR idxbudfmvr FROM-MVR q * cext = this%qfrommvr(:)
15 ! AUXILIARY none none none
16 ! none none STORAGE (aux MASS)
17 ! none none AUXILIARY none
18 
19 ! -- terms from UZF that need to be handled here
20 ! INFILTRATION idxbudinfl INFILTRATION q < 0: q * cwell, else q * cuser
21 ! REJ-INF idxbudrinf REJ-INF q * cuzt
22 ! UZET idxbuduzet UZET q * cet
23 ! REJ-INF-TO-MVR idxbudritm REJ-INF-TO-MVR q * cinfil?
24 
25 ! -- terms from UZF that should be skipped
26 
28 
29  use kindmodule, only: dp, i4b
34  use bndmodule, only: bndtype, getbndfromlist
35  use tspfmimodule, only: tspfmitype
36  use uzfmodule, only: uzftype
37  use observemodule, only: observetype
41  implicit none
42 
43  public uzt_create
44 
45  character(len=*), parameter :: ftype = 'UZT'
46  character(len=*), parameter :: flowtype = 'UZF'
47  character(len=16) :: text = ' UZT'
48 
49  type, extends(tspapttype) :: gwtuzttype
50 
51  integer(I4B), pointer :: idxbudinfl => null() ! index of uzf infiltration terms in flowbudptr
52  integer(I4B), pointer :: idxbudrinf => null() ! index of rejected infiltration terms in flowbudptr
53  integer(I4B), pointer :: idxbuduzet => null() ! index of unsat et terms in flowbudptr
54  integer(I4B), pointer :: idxbudritm => null() ! index of rej infil to mover rate to mover terms in flowbudptr
55  real(dp), dimension(:), pointer, contiguous :: concinfl => null() ! infiltration concentration
56  real(dp), dimension(:), pointer, contiguous :: concuzet => null() ! unsat et concentration
57 
58  contains
59 
60  procedure :: bnd_da => uzt_da
61  procedure :: allocate_scalars
62  procedure :: apt_allocate_arrays => uzt_allocate_arrays
63  procedure :: find_apt_package => find_uzt_package
64  procedure :: apt_setting_value => uzt_setting_value
65  procedure :: pak_fc_expanded => uzt_fc_expanded
66  procedure :: pak_solve => uzt_solve
67  procedure :: pak_get_nbudterms => uzt_get_nbudterms
68  procedure :: pak_setup_budobj => uzt_setup_budobj
69  procedure :: pak_fill_budobj => uzt_fill_budobj
70  procedure :: uzt_infl_term
71  procedure :: uzt_rinf_term
72  procedure :: uzt_uzet_term
73  procedure :: uzt_ritm_term
74  procedure :: pak_df_obs => uzt_df_obs
75  procedure :: pak_rp_obs => uzt_rp_obs
76  procedure :: pak_bd_obs => uzt_bd_obs
77  procedure :: get_mvr_depvar
78 
79  end type gwtuzttype
80 
81 contains
82 
83  !> @brief Create a new UZT package
84  !<
85  subroutine uzt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
86  mempath, fmi, eqnsclfac, dvt, dvu, dvua)
87  ! -- dummy
88  class(bndtype), pointer :: packobj
89  integer(I4B), intent(in) :: id
90  integer(I4B), intent(in) :: ibcnum
91  integer(I4B), intent(in) :: inunit
92  integer(I4B), intent(in) :: iout
93  character(len=*), intent(in) :: namemodel
94  character(len=*), intent(in) :: pakname
95  character(len=*), intent(in) :: mempath !< input memory path
96  type(tspfmitype), pointer :: fmi
97  real(dp), intent(in), pointer :: eqnsclfac !< governing equation scale factor
98  character(len=*), intent(in) :: dvt !< For GWT, set to "CONCENTRATION" in TspAptType
99  character(len=*), intent(in) :: dvu !< For GWT, set to "mass" in TspAptType
100  character(len=*), intent(in) :: dvua !< For GWT, set to "M" in TspAptType
101  ! -- local
102  type(gwtuzttype), pointer :: uztobj
103  !
104  ! -- allocate the object and assign values to object variables
105  allocate (uztobj)
106  packobj => uztobj
107  !
108  ! -- create name and memory path
109  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
110  packobj%text = text
111  !
112  ! -- allocate scalars
113  call uztobj%allocate_scalars()
114  !
115  ! -- initialize package
116  call packobj%pack_initialize()
117  !
118  packobj%inunit = inunit
119  packobj%iout = iout
120  packobj%id = id
121  packobj%ibcnum = ibcnum
122  packobj%ncolbnd = 1
123  packobj%iscloc = 1
124  packobj%isadvpak = 1
125  !
126  ! -- Store pointer to flow model interface. When the GwfGwt exchange is
127  ! created, it sets fmi%bndlist so that the GWT model has access to all
128  ! the flow packages
129  uztobj%fmi => fmi
130  !
131  ! -- Store pointer to governing equation scale factor
132  uztobj%eqnsclfac => eqnsclfac
133  !
134  ! -- Set labels that will be used in generalized APT class
135  uztobj%depvartype = dvt
136  uztobj%depvarunit = dvu
137  uztobj%depvarunitabbrev = dvua
138  end subroutine uzt_create
139 
140  !> @brief Find corresponding uzt package
141  !<
142  subroutine find_uzt_package(this)
143  ! -- modules
145  ! -- dummy
146  class(gwtuzttype) :: this
147  ! -- local
148  character(len=LINELENGTH) :: errmsg
149  class(bndtype), pointer :: packobj
150  integer(I4B) :: ip, icount
151  integer(I4B) :: nbudterm
152  logical :: found
153  !
154  ! -- Initialize found to false, and error later if flow package cannot
155  ! be found
156  found = .false.
157  !
158  ! -- If user is specifying flows in a binary budget file, then set up
159  ! the budget file reader, otherwise set a pointer to the flow package
160  ! budobj
161  if (this%fmi%flows_from_file) then
162  call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr)
163  if (associated(this%flowbudptr)) found = .true.
164  !
165  else
166  if (associated(this%fmi%gwfbndlist)) then
167  ! -- Look through gwfbndlist for a flow package with the same name as
168  ! this transport package name
169  do ip = 1, this%fmi%gwfbndlist%Count()
170  packobj => getbndfromlist(this%fmi%gwfbndlist, ip)
171  if (packobj%packName == this%flowpackagename) then
172  found = .true.
173  !
174  ! -- store BndType pointer to packobj, and then
175  ! use the select type to point to the budobj in flow package
176  this%flowpackagebnd => packobj
177  select type (packobj)
178  type is (uzftype)
179  this%flowbudptr => packobj%budobj
180  end select
181  end if
182  if (found) exit
183  end do
184  end if
185  end if
186  !
187  ! -- error if flow package not found
188  if (.not. found) then
189  write (errmsg, '(a)') 'Could not find flow package with name '&
190  &//trim(adjustl(this%flowpackagename))//'.'
191  call store_error(errmsg)
192  call store_error_filename(this%input_fname)
193  end if
194  !
195  ! -- allocate space for idxbudssm, which indicates whether this is a
196  ! special budget term or one that is a general source and sink
197  nbudterm = this%flowbudptr%nbudterm
198  call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath)
199  !
200  ! -- Process budget terms and identify special budget terms
201  write (this%iout, '(/, a, a)') &
202  'PROCESSING '//ftype//' INFORMATION FOR ', this%packName
203  write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE'
204  write (this%iout, '(a, i0)') &
205  ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv
206  icount = 1
207  do ip = 1, this%flowbudptr%nbudterm
208  select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)))
209  case ('FLOW-JA-FACE')
210  this%idxbudfjf = ip
211  this%idxbudssm(ip) = 0
212  case ('GWF')
213  this%idxbudgwf = ip
214  this%idxbudssm(ip) = 0
215  case ('STORAGE')
216  this%idxbudsto = ip
217  this%idxbudssm(ip) = 0
218  case ('INFILTRATION')
219  this%idxbudinfl = ip
220  this%idxbudssm(ip) = 0
221  case ('REJ-INF')
222  this%idxbudrinf = ip
223  this%idxbudssm(ip) = 0
224  case ('UZET')
225  this%idxbuduzet = ip
226  this%idxbudssm(ip) = 0
227  case ('REJ-INF-TO-MVR')
228  this%idxbudritm = ip
229  this%idxbudssm(ip) = 0
230  case ('TO-MVR')
231  this%idxbudtmvr = ip
232  this%idxbudssm(ip) = 0
233  case ('FROM-MVR')
234  this%idxbudfmvr = ip
235  this%idxbudssm(ip) = 0
236  case ('AUXILIARY')
237  this%idxbudaux = ip
238  this%idxbudssm(ip) = 0
239  case default
240  !
241  ! -- set idxbudssm equal to a column index for where the concentrations
242  ! are stored in the concbud(nbudssm, ncv) array
243  this%idxbudssm(ip) = icount
244  icount = icount + 1
245  end select
246  write (this%iout, '(a, i0, " = ", a,/, a, i0)') &
247  ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), &
248  ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist
249  end do
250  write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION'
251  end subroutine find_uzt_package
252 
253  !> @brief Value for a package-specific PERIOD setting
254  !!
255  !! Already resolved by the input context; this only supplies it for
256  !! the shared apt_rp table echo.
257  !<
258  function uzt_setting_value(this, itemno, key) result(val)
259  ! -- dummy
260  class(gwtuzttype), intent(inout) :: this
261  integer(I4B), intent(in) :: itemno
262  character(len=*), intent(in) :: key
263  real(dp) :: val
264  !
265  val = dzero
266  select case (trim(key))
267  case ('INFILTRATION')
268  val = this%concinfl(itemno)
269  case ('UZET')
270  val = this%concuzet(itemno)
271  end select
272  end function uzt_setting_value
273 
274  !> @brief Add matrix terms related to UZT
275  !!
276  !! This will be called from TspAptType%apt_fc_expanded()
277  !! in order to add matrix terms specifically for this package
278  !<
279  subroutine uzt_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
280  ! -- modules
281  ! -- dummy
282  class(gwtuzttype) :: this
283  real(DP), dimension(:), intent(inout) :: rhs
284  integer(I4B), dimension(:), intent(in) :: ia
285  integer(I4B), dimension(:), intent(in) :: idxglo
286  class(matrixbasetype), pointer :: matrix_sln
287  ! -- local
288  integer(I4B) :: j, n1, n2
289  integer(I4B) :: iloc
290  integer(I4B) :: iposd
291  real(DP) :: rrate
292  real(DP) :: rhsval
293  real(DP) :: hcofval
294  !
295  ! -- add infiltration contribution
296  if (this%idxbudinfl /= 0) then
297  do j = 1, this%flowbudptr%budterm(this%idxbudinfl)%nlist
298  call this%uzt_infl_term(j, n1, n2, rrate, rhsval, hcofval)
299  iloc = this%idxlocnode(n1)
300  iposd = this%idxpakdiag(n1)
301  call matrix_sln%add_value_pos(iposd, hcofval)
302  rhs(iloc) = rhs(iloc) + rhsval
303  end do
304  end if
305  !
306  ! -- add rejected infiltration contribution
307  if (this%idxbudrinf /= 0) then
308  do j = 1, this%flowbudptr%budterm(this%idxbudrinf)%nlist
309  call this%uzt_rinf_term(j, n1, n2, rrate, rhsval, hcofval)
310  iloc = this%idxlocnode(n1)
311  iposd = this%idxpakdiag(n1)
312  call matrix_sln%add_value_pos(iposd, hcofval)
313  rhs(iloc) = rhs(iloc) + rhsval
314  end do
315  end if
316  !
317  ! -- add unsaturated et contribution
318  if (this%idxbuduzet /= 0) then
319  do j = 1, this%flowbudptr%budterm(this%idxbuduzet)%nlist
320  call this%uzt_uzet_term(j, n1, n2, rrate, rhsval, hcofval)
321  iloc = this%idxlocnode(n1)
322  iposd = this%idxpakdiag(n1)
323  call matrix_sln%add_value_pos(iposd, hcofval)
324  rhs(iloc) = rhs(iloc) + rhsval
325  end do
326  end if
327  !
328  ! -- add rejected infiltration to mover contribution
329  if (this%idxbudritm /= 0) then
330  do j = 1, this%flowbudptr%budterm(this%idxbudritm)%nlist
331  call this%uzt_ritm_term(j, n1, n2, rrate, rhsval, hcofval)
332  iloc = this%idxlocnode(n1)
333  iposd = this%idxpakdiag(n1)
334  call matrix_sln%add_value_pos(iposd, hcofval)
335  rhs(iloc) = rhs(iloc) + rhsval
336  end do
337  end if
338  end subroutine uzt_fc_expanded
339 
340  !> @brief Explicit solve
341  !!
342  !! Add terms specific to the unsaturated zone to the explicit unsaturated-
343  !! zone solve
344  subroutine uzt_solve(this)
345  ! -- dummy
346  class(gwtuzttype) :: this
347  ! -- local
348  integer(I4B) :: j
349  integer(I4B) :: n1, n2
350  real(DP) :: rrate
351  !
352  ! -- add infiltration contribution
353  if (this%idxbudinfl /= 0) then
354  do j = 1, this%flowbudptr%budterm(this%idxbudinfl)%nlist
355  call this%uzt_infl_term(j, n1, n2, rrate)
356  this%dbuff(n1) = this%dbuff(n1) + rrate
357  end do
358  end if
359  !
360  ! -- add rejected infiltration contribution
361  if (this%idxbudrinf /= 0) then
362  do j = 1, this%flowbudptr%budterm(this%idxbudrinf)%nlist
363  call this%uzt_rinf_term(j, n1, n2, rrate)
364  this%dbuff(n1) = this%dbuff(n1) + rrate
365  end do
366  end if
367  !
368  ! -- add unsaturated et contribution
369  if (this%idxbuduzet /= 0) then
370  do j = 1, this%flowbudptr%budterm(this%idxbuduzet)%nlist
371  call this%uzt_uzet_term(j, n1, n2, rrate)
372  this%dbuff(n1) = this%dbuff(n1) + rrate
373  end do
374  end if
375  !
376  ! -- add rejected infiltration to mover contribution
377  if (this%idxbudritm /= 0) then
378  do j = 1, this%flowbudptr%budterm(this%idxbudritm)%nlist
379  call this%uzt_ritm_term(j, n1, n2, rrate)
380  this%dbuff(n1) = this%dbuff(n1) + rrate
381  end do
382  end if
383  end subroutine uzt_solve
384 
385  !> @brief Function that returns the number of budget terms for this package
386  !!
387  !! This overrides function in parent.
388  !<
389  function uzt_get_nbudterms(this) result(nbudterms)
390  ! -- modules
391  ! -- dummy
392  class(gwtuzttype) :: this
393  ! -- return
394  integer(I4B) :: nbudterms
395  ! -- local
396  !
397  ! -- Number of budget terms is 4
398  nbudterms = 0
399  if (this%idxbudinfl /= 0) nbudterms = nbudterms + 1
400  if (this%idxbudrinf /= 0) nbudterms = nbudterms + 1
401  if (this%idxbuduzet /= 0) nbudterms = nbudterms + 1
402  if (this%idxbudritm /= 0) nbudterms = nbudterms + 1
403  end function uzt_get_nbudterms
404 
405  !> @brief Override similarly named function in APT
406  !!
407  !! Set the concentration to be used by MVT as the user-specified
408  !! concentration applied to the infiltration
409  !<
410  function get_mvr_depvar(this)
411  ! -- dummy
412  class(gwtuzttype) :: this
413  ! -- return
414  real(dp), dimension(:), contiguous, pointer :: get_mvr_depvar
415  !
416  get_mvr_depvar => this%concinfl
417  end function get_mvr_depvar
418 
419  !> @brief Set up the budget object that stores all the unsaturated-zone flows
420  !<
421  subroutine uzt_setup_budobj(this, idx)
422  ! -- modules
423  use constantsmodule, only: lenbudtxt
424  ! -- dummy
425  class(gwtuzttype) :: this
426  integer(I4B), intent(inout) :: idx
427  ! -- local
428  integer(I4B) :: maxlist, naux
429  character(len=LENBUDTXT) :: text
430  !
431  ! -- Infiltration flux
432  text = ' INFILTRATION'
433  idx = idx + 1
434  maxlist = this%flowbudptr%budterm(this%idxbudinfl)%maxlist
435  naux = 0
436  call this%budobj%budterm(idx)%initialize(text, &
437  this%name_model, &
438  this%packName, &
439  this%name_model, &
440  this%packName, &
441  maxlist, .false., .false., &
442  naux)
443  !
444  ! -- Rejected infiltration flux (and subsequently removed from the model)
445  if (this%idxbudrinf /= 0) then
446  text = ' REJ-INF'
447  idx = idx + 1
448  maxlist = this%flowbudptr%budterm(this%idxbudrinf)%maxlist
449  naux = 0
450  call this%budobj%budterm(idx)%initialize(text, &
451  this%name_model, &
452  this%packName, &
453  this%name_model, &
454  this%packName, &
455  maxlist, .false., .false., &
456  naux)
457  end if
458  !
459  ! -- Evapotranspiration flux originating from the unsaturated zone
460  if (this%idxbuduzet /= 0) then
461  text = ' UZET'
462  idx = idx + 1
463  maxlist = this%flowbudptr%budterm(this%idxbuduzet)%maxlist
464  naux = 0
465  call this%budobj%budterm(idx)%initialize(text, &
466  this%name_model, &
467  this%packName, &
468  this%name_model, &
469  this%packName, &
470  maxlist, .false., .false., &
471  naux)
472  end if
473  !
474  ! -- Rejected infiltration flux that is transferred to the MVR/MVT packages
475  if (this%idxbudritm /= 0) then
476  text = ' INF-REJ-TO-MVR'
477  idx = idx + 1
478  maxlist = this%flowbudptr%budterm(this%idxbudritm)%maxlist
479  naux = 0
480  call this%budobj%budterm(idx)%initialize(text, &
481  this%name_model, &
482  this%packName, &
483  this%name_model, &
484  this%packName, &
485  maxlist, .false., .false., &
486  naux)
487  end if
488  end subroutine uzt_setup_budobj
489 
490  !> @brief Copy flow terms into this%budobj
491  subroutine uzt_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
492  ! -- modules
493  ! -- dummy
494  class(gwtuzttype) :: this
495  integer(I4B), intent(inout) :: idx
496  real(DP), dimension(:), intent(in) :: x
497  real(DP), dimension(:), contiguous, intent(inout) :: flowja
498  real(DP), intent(inout) :: ccratin
499  real(DP), intent(inout) :: ccratout
500  ! -- local
501  integer(I4B) :: j, n1, n2
502  integer(I4B) :: nlist
503  real(DP) :: q
504  ! -- formats
505  !
506  ! -- INFILTRATION
507  idx = idx + 1
508  nlist = this%flowbudptr%budterm(this%idxbudinfl)%nlist
509  call this%budobj%budterm(idx)%reset(nlist)
510  do j = 1, nlist
511  call this%uzt_infl_term(j, n1, n2, q)
512  call this%budobj%budterm(idx)%update_term(n1, n2, q)
513  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
514  end do
515  !
516  ! -- REJ-INF
517  if (this%idxbudrinf /= 0) then
518  idx = idx + 1
519  nlist = this%flowbudptr%budterm(this%idxbudrinf)%nlist
520  call this%budobj%budterm(idx)%reset(nlist)
521  do j = 1, nlist
522  call this%uzt_rinf_term(j, n1, n2, q)
523  call this%budobj%budterm(idx)%update_term(n1, n2, q)
524  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
525  end do
526  end if
527  !
528  ! -- UZET
529  if (this%idxbuduzet /= 0) then
530  idx = idx + 1
531  nlist = this%flowbudptr%budterm(this%idxbuduzet)%nlist
532  call this%budobj%budterm(idx)%reset(nlist)
533  do j = 1, nlist
534  call this%uzt_uzet_term(j, n1, n2, q)
535  call this%budobj%budterm(idx)%update_term(n1, n2, q)
536  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
537  end do
538  end if
539  !
540  ! -- REJ-INF-TO-MVR
541  if (this%idxbudritm /= 0) then
542  idx = idx + 1
543  nlist = this%flowbudptr%budterm(this%idxbudritm)%nlist
544  call this%budobj%budterm(idx)%reset(nlist)
545  do j = 1, nlist
546  call this%uzt_ritm_term(j, n1, n2, q)
547  call this%budobj%budterm(idx)%update_term(n1, n2, q)
548  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
549  end do
550  end if
551  end subroutine uzt_fill_budobj
552 
553  !> @brief Allocate scalar variables for package
554  !!
555  !! Method to allocate scalar variables for the package.
556  !<
557  subroutine allocate_scalars(this)
558  ! -- modules
560  ! -- dummy
561  class(gwtuzttype) :: this
562  ! -- local
563  !
564  ! -- allocate scalars in TspAptType
565  call this%TspAptType%allocate_scalars()
566  !
567  ! -- Allocate
568  call mem_allocate(this%idxbudinfl, 'IDXBUDINFL', this%memoryPath)
569  call mem_allocate(this%idxbudrinf, 'IDXBUDRINF', this%memoryPath)
570  call mem_allocate(this%idxbuduzet, 'IDXBUDUZET', this%memoryPath)
571  call mem_allocate(this%idxbudritm, 'IDXBUDRITM', this%memoryPath)
572  !
573  ! -- Initialize
574  this%idxbudinfl = 0
575  this%idxbudrinf = 0
576  this%idxbuduzet = 0
577  this%idxbudritm = 0
578  end subroutine allocate_scalars
579 
580  !> @brief Allocate arrays for package
581  !!
582  !! Method to allocate arrays for the package.
583  !<
584  subroutine uzt_allocate_arrays(this)
585  ! -- modules
587  ! -- dummy
588  class(gwtuzttype), intent(inout) :: this
589  !
590  ! -- alias into the input context's permanent, feature-indexed arrays
591  ! (allocated and DZERO-initialized by the input context)
592  call mem_setptr(this%concinfl, 'INFILTRATION', this%input_mempath)
593  call mem_setptr(this%concuzet, 'UZET', this%input_mempath)
594  !
595  ! -- call standard TspAptType allocate arrays
596  call this%TspAptType%apt_allocate_arrays()
597  !
598  end subroutine uzt_allocate_arrays
599 
600  !> @brief Deallocate memory
601  !!
602  !! Method to deallocate memory for the package.
603  !<
604  subroutine uzt_da(this)
605  ! -- modules
607  ! -- dummy
608  class(gwtuzttype) :: this
609  ! -- local
610  !
611  ! -- deallocate scalars
612  call mem_deallocate(this%idxbudinfl)
613  call mem_deallocate(this%idxbudrinf)
614  call mem_deallocate(this%idxbuduzet)
615  call mem_deallocate(this%idxbudritm)
616  !
617  ! -- input-context-owned aliases, not package-allocated
618  nullify (this%concinfl)
619  nullify (this%concuzet)
620  !
621  ! -- deallocate scalars in TspAptType
622  call this%TspAptType%bnd_da()
623  end subroutine uzt_da
624 
625  !> @brief Infiltration term
626  !!
627  !! Accounts for mass added to the subsurface via infiltration. For example,
628  !! mass entering the model domain via rainfall or irrigation.
629  !<
630  subroutine uzt_infl_term(this, ientry, n1, n2, rrate, &
631  rhsval, hcofval)
632  ! -- dummy
633  class(gwtuzttype) :: this
634  integer(I4B), intent(in) :: ientry
635  integer(I4B), intent(inout) :: n1
636  integer(I4B), intent(inout) :: n2
637  real(DP), intent(inout), optional :: rrate
638  real(DP), intent(inout), optional :: rhsval
639  real(DP), intent(inout), optional :: hcofval
640  ! -- local
641  real(DP) :: qbnd
642  real(DP) :: ctmp
643  real(DP) :: h, r
644  !
645  n1 = this%flowbudptr%budterm(this%idxbudinfl)%id1(ientry)
646  n2 = this%flowbudptr%budterm(this%idxbudinfl)%id2(ientry)
647  ! -- note that qbnd is negative for negative infiltration
648  qbnd = this%flowbudptr%budterm(this%idxbudinfl)%flow(ientry)
649  if (qbnd < dzero) then
650  ctmp = this%xnewpak(n1)
651  h = qbnd
652  r = dzero
653  else
654  ctmp = this%concinfl(n1)
655  h = dzero
656  r = -qbnd * ctmp
657  end if
658  if (present(rrate)) rrate = qbnd * ctmp
659  if (present(rhsval)) rhsval = r
660  if (present(hcofval)) hcofval = h
661  end subroutine uzt_infl_term
662 
663  !> @brief Rejected infiltration term
664  !!
665  !! Accounts for mass that is added to the model from specifying an
666  !! infiltration rate and concentration, but is subsequently removed from
667  !! the model as that portion of the infiltration that is rejected (and
668  !! NOT transferred to another advanced package via the MVR/MVT packages).
669  !<
670  subroutine uzt_rinf_term(this, ientry, n1, n2, rrate, &
671  rhsval, hcofval)
672  ! -- dummy
673  class(gwtuzttype) :: this
674  integer(I4B), intent(in) :: ientry
675  integer(I4B), intent(inout) :: n1
676  integer(I4B), intent(inout) :: n2
677  real(DP), intent(inout), optional :: rrate
678  real(DP), intent(inout), optional :: rhsval
679  real(DP), intent(inout), optional :: hcofval
680  ! -- local
681  real(DP) :: qbnd
682  real(DP) :: ctmp
683  !
684  n1 = this%flowbudptr%budterm(this%idxbudrinf)%id1(ientry)
685  n2 = this%flowbudptr%budterm(this%idxbudrinf)%id2(ientry)
686  qbnd = this%flowbudptr%budterm(this%idxbudrinf)%flow(ientry)
687  ctmp = this%concinfl(n1)
688  if (present(rrate)) rrate = ctmp * qbnd
689  if (present(rhsval)) rhsval = dzero
690  if (present(hcofval)) hcofval = qbnd
691  end subroutine uzt_rinf_term
692 
693  !> @brief Evapotranspiration from the unsaturated-zone term
694  !!
695  !! Accounts for mass removed as a result of evapotranspiration from the
696  !! unsaturated zone.
697  !<
698  subroutine uzt_uzet_term(this, ientry, n1, n2, rrate, &
699  rhsval, hcofval)
700  ! -- dummy
701  class(gwtuzttype) :: this
702  integer(I4B), intent(in) :: ientry
703  integer(I4B), intent(inout) :: n1
704  integer(I4B), intent(inout) :: n2
705  real(DP), intent(inout), optional :: rrate
706  real(DP), intent(inout), optional :: rhsval
707  real(DP), intent(inout), optional :: hcofval
708  ! -- local
709  real(DP) :: qbnd
710  real(DP) :: ctmp
711  real(DP) :: omega
712  !
713  n1 = this%flowbudptr%budterm(this%idxbuduzet)%id1(ientry)
714  n2 = this%flowbudptr%budterm(this%idxbuduzet)%id2(ientry)
715  ! -- note that qbnd is negative for uzet
716  qbnd = this%flowbudptr%budterm(this%idxbuduzet)%flow(ientry)
717  ctmp = this%concuzet(n1)
718  if (this%xnewpak(n1) < ctmp) then
719  omega = done
720  else
721  omega = dzero
722  end if
723  if (present(rrate)) &
724  rrate = omega * qbnd * this%xnewpak(n1) + &
725  (done - omega) * qbnd * ctmp
726  if (present(rhsval)) rhsval = -(done - omega) * qbnd * ctmp
727  if (present(hcofval)) hcofval = omega * qbnd
728  end subroutine uzt_uzet_term
729 
730  !> @brief Rejected infiltration to MVR/MVT term
731  !!
732  !! Accounts for energy that is added to the model from specifying an
733  !! infiltration rate and temperature, but does not infiltrate into the
734  !! subsurface. This subroutine is called when the rejected infiltration
735  !! is transferred to another advanced package via the MVR/MVT packages.
736  !<
737  subroutine uzt_ritm_term(this, ientry, n1, n2, rrate, &
738  rhsval, hcofval)
739  ! -- dummy
740  class(gwtuzttype) :: this
741  integer(I4B), intent(in) :: ientry
742  integer(I4B), intent(inout) :: n1
743  integer(I4B), intent(inout) :: n2
744  real(DP), intent(inout), optional :: rrate
745  real(DP), intent(inout), optional :: rhsval
746  real(DP), intent(inout), optional :: hcofval
747  ! -- local
748  real(DP) :: qbnd
749  real(DP) :: ctmp
750  !
751  n1 = this%flowbudptr%budterm(this%idxbudritm)%id1(ientry)
752  n2 = this%flowbudptr%budterm(this%idxbudritm)%id2(ientry)
753  qbnd = this%flowbudptr%budterm(this%idxbudritm)%flow(ientry)
754  ctmp = this%concinfl(n1)
755  if (present(rrate)) rrate = ctmp * qbnd
756  if (present(rhsval)) rhsval = dzero
757  if (present(hcofval)) hcofval = qbnd
758  end subroutine uzt_ritm_term
759 
760  !> @brief Define UZT Observation
761  !!
762  !! This subroutine:
763  !! - Stores observation types supported by the parent APT package.
764  !! - Overrides BndType%bnd_df_obs
765  !<
766  subroutine uzt_df_obs(this)
767  ! -- modules
768  ! -- dummy
769  class(gwtuzttype) :: this
770  ! -- local
771  integer(I4B) :: indx
772  !
773  ! -- Store obs type and assign procedure pointer
774  ! for concentration observation type.
775  call this%obs%StoreObsType('concentration', .false., indx)
776  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
777  !
778  ! -- Store obs type and assign procedure pointer
779  ! for flow between uzt cells.
780  call this%obs%StoreObsType('flow-ja-face', .true., indx)
781  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid12
782  !
783  ! -- Store obs type and assign procedure pointer
784  ! for from-mvr observation type.
785  call this%obs%StoreObsType('from-mvr', .true., indx)
786  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
787  !
788  ! -- to-mvr not supported for uzt
789  !call this%obs%StoreObsType('to-mvr', .true., indx)
790  !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID
791  !
792  ! -- Store obs type and assign procedure pointer
793  ! for storage observation type.
794  call this%obs%StoreObsType('storage', .true., indx)
795  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
796  !
797  ! -- Store obs type and assign procedure pointer
798  ! for constant observation type.
799  call this%obs%StoreObsType('constant', .true., indx)
800  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
801  !
802  ! -- Store obs type and assign procedure pointer
803  ! for observation type: uzt
804  call this%obs%StoreObsType('uzt', .true., indx)
805  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
806  !
807  ! -- Store obs type and assign procedure pointer
808  ! for observation type.
809  call this%obs%StoreObsType('infiltration', .true., indx)
810  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
811  !
812  ! -- Store obs type and assign procedure pointer
813  ! for observation type.
814  call this%obs%StoreObsType('rej-inf', .true., indx)
815  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
816  !
817  ! -- Store obs type and assign procedure pointer
818  ! for observation type.
819  call this%obs%StoreObsType('uzet', .true., indx)
820  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
821  !
822  ! -- Store obs type and assign procedure pointer
823  ! for observation type.
824  call this%obs%StoreObsType('rej-inf-to-mvr', .true., indx)
825  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
826  end subroutine uzt_df_obs
827 
828  !> @brief Process package specific obs
829  !!
830  !! Method to process specific observations for this package.
831  !<
832  subroutine uzt_rp_obs(this, obsrv, found)
833  ! -- dummy
834  class(gwtuzttype), intent(inout) :: this !< package class
835  type(observetype), intent(inout) :: obsrv !< observation object
836  logical, intent(inout) :: found !< indicate whether observation was found
837  ! -- local
838  !
839  found = .true.
840  select case (obsrv%ObsTypeId)
841  case ('INFILTRATION')
842  call this%rp_obs_byfeature(obsrv)
843  case ('REJ-INF')
844  call this%rp_obs_byfeature(obsrv)
845  case ('UZET')
846  call this%rp_obs_byfeature(obsrv)
847  case ('REJ-INF-TO-MVR')
848  call this%rp_obs_byfeature(obsrv)
849  case default
850  found = .false.
851  end select
852  end subroutine uzt_rp_obs
853 
854  !> @brief Calculate observation value and pass it back to APT
855  !<
856  subroutine uzt_bd_obs(this, obstypeid, jj, v, found)
857  ! -- dummy
858  class(gwtuzttype), intent(inout) :: this
859  character(len=*), intent(in) :: obstypeid
860  real(DP), intent(inout) :: v
861  integer(I4B), intent(in) :: jj
862  logical, intent(inout) :: found
863  ! -- local
864  integer(I4B) :: n1, n2
865  !
866  found = .true.
867  select case (obstypeid)
868  case ('INFILTRATION')
869  if (this%iboundpak(jj) /= 0 .and. this%idxbudinfl > 0) then
870  call this%uzt_infl_term(jj, n1, n2, v)
871  end if
872  case ('REJ-INF')
873  if (this%iboundpak(jj) /= 0 .and. this%idxbudrinf > 0) then
874  call this%uzt_rinf_term(jj, n1, n2, v)
875  end if
876  case ('UZET')
877  if (this%iboundpak(jj) /= 0 .and. this%idxbuduzet > 0) then
878  call this%uzt_uzet_term(jj, n1, n2, v)
879  end if
880  case ('REJ-INF-TO-MVR')
881  if (this%iboundpak(jj) /= 0 .and. this%idxbudritm > 0) then
882  call this%uzt_ritm_term(jj, n1, n2, v)
883  end if
884  case default
885  found = .false.
886  end select
887  end subroutine uzt_bd_obs
888 
889 end module gwtuztmodule
This module contains the base boundary package.
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
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
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:37
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine uzt_ritm_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Rejected infiltration to MVR/MVT term.
Definition: gwt-uzt.f90:739
subroutine uzt_rp_obs(this, obsrv, found)
Process package specific obs.
Definition: gwt-uzt.f90:833
subroutine uzt_solve(this)
Explicit solve.
Definition: gwt-uzt.f90:345
integer(i4b) function uzt_get_nbudterms(this)
Function that returns the number of budget terms for this package.
Definition: gwt-uzt.f90:390
subroutine uzt_df_obs(this)
Define UZT Observation.
Definition: gwt-uzt.f90:767
subroutine uzt_da(this)
Deallocate memory.
Definition: gwt-uzt.f90:605
character(len= *), parameter flowtype
Definition: gwt-uzt.f90:46
real(dp) function, dimension(:), pointer, contiguous get_mvr_depvar(this)
Override similarly named function in APT.
Definition: gwt-uzt.f90:411
subroutine allocate_scalars(this)
Allocate scalar variables for package.
Definition: gwt-uzt.f90:558
subroutine uzt_allocate_arrays(this)
Allocate arrays for package.
Definition: gwt-uzt.f90:585
subroutine uzt_setup_budobj(this, idx)
Set up the budget object that stores all the unsaturated-zone flows.
Definition: gwt-uzt.f90:422
character(len=16) text
Definition: gwt-uzt.f90:47
subroutine uzt_infl_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Infiltration term.
Definition: gwt-uzt.f90:632
subroutine uzt_rinf_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Rejected infiltration term.
Definition: gwt-uzt.f90:672
subroutine uzt_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
Add matrix terms related to UZT.
Definition: gwt-uzt.f90:280
subroutine uzt_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
Copy flow terms into thisbudobj.
Definition: gwt-uzt.f90:492
real(dp) function uzt_setting_value(this, itemno, key)
Value for a package-specific PERIOD setting.
Definition: gwt-uzt.f90:259
subroutine uzt_bd_obs(this, obstypeid, jj, v, found)
Calculate observation value and pass it back to APT.
Definition: gwt-uzt.f90:857
character(len= *), parameter ftype
Definition: gwt-uzt.f90:45
subroutine uzt_uzet_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Evapotranspiration from the unsaturated-zone term.
Definition: gwt-uzt.f90:700
subroutine, public uzt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath, fmi, eqnsclfac, dvt, dvu, dvua)
Create a new UZT package.
Definition: gwt-uzt.f90:87
subroutine find_uzt_package(this)
Find corresponding uzt package.
Definition: gwt-uzt.f90:143
This module defines variable data types.
Definition: kind.f90:8
This module contains the derived types ObserveType and ObsDataType.
Definition: Observe.f90:15
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:204
subroutine, public apt_process_obsid(obsrv, dis, inunitobs, iout)
Process observation IDs for an advanced package.
Definition: tsp-apt.f90:2690
subroutine, public apt_process_obsid12(obsrv, dis, inunitobs, iout)
Process observation IDs for a package.
Definition: tsp-apt.f90:2733
@ 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