MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
gwt-lkt.f90
Go to the documentation of this file.
1 ! -- Lake Transport Module
2 ! -- todo: what to do about reactions in lake? Decay?
3 ! -- todo: save the lkt concentration into the lak aux variable?
4 ! -- todo: calculate the lak DENSE aux variable using concentration?
5 !
6 ! LAK flows (lakbudptr) index var LKT term Transport Type
7 !---------------------------------------------------------------------------------
8 
9 ! -- terms from LAK that will be handled by parent APT Package
10 ! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv
11 ! GWF (aux FLOW-AREA) idxbudgwf GWF cv2gwf
12 ! STORAGE (aux VOLUME) idxbudsto none used for cv volumes
13 ! FROM-MVR idxbudfmvr FROM-MVR q * cext = this%qfrommvr(:)
14 ! TO-MVR idxbudtmvr TO-MVR q * cfeat
15 
16 ! -- LAK terms
17 ! RAINFALL idxbudrain RAINFALL q * crain
18 ! EVAPORATION idxbudevap EVAPORATION cfeat<cevap: q*cfeat, else: q*cevap
19 ! RUNOFF idxbudroff RUNOFF q * croff
20 ! EXT-INFLOW idxbudiflw EXT-INFLOW q * ciflw
21 ! WITHDRAWAL idxbudwdrl WITHDRAWAL q * cfeat
22 ! EXT-OUTFLOW idxbudoutf EXT-OUTFLOW q * cfeat
23 
24 ! -- terms from a flow file that should be skipped
25 ! CONSTANT none none none
26 ! AUXILIARY none none none
27 
28 ! -- terms that are written to the transport budget file
29 ! none none STORAGE (aux MASS) dM/dt
30 ! none none AUXILIARY none
31 ! none none CONSTANT accumulate
32 !
33 !
35 
36  use kindmodule, only: dp, i4b
40  use bndmodule, only: bndtype, getbndfromlist
42  use tspfmimodule, only: tspfmitype
43  use lakmodule, only: laktype
44  use observemodule, only: observetype
48 
49  implicit none
50 
51  public lkt_create
52 
53  character(len=*), parameter :: ftype = 'LKT'
54  character(len=*), parameter :: flowtype = 'LAK'
55  character(len=16) :: text = ' LKT'
56 
57  type, extends(tspapttype) :: gwtlkttype
58 
59  integer(I4B), pointer :: idxbudrain => null() ! index of rainfall terms in flowbudptr
60  integer(I4B), pointer :: idxbudevap => null() ! index of evaporation terms in flowbudptr
61  integer(I4B), pointer :: idxbudroff => null() ! index of runoff terms in flowbudptr
62  integer(I4B), pointer :: idxbudiflw => null() ! index of inflow terms in flowbudptr
63  integer(I4B), pointer :: idxbudwdrl => null() ! index of withdrawal terms in flowbudptr
64  integer(I4B), pointer :: idxbudoutf => null() ! index of outflow terms in flowbudptr
65 
66  real(dp), dimension(:), pointer, contiguous :: concrain => null() ! rainfall concentration
67  real(dp), dimension(:), pointer, contiguous :: concevap => null() ! evaporation concentration
68  real(dp), dimension(:), pointer, contiguous :: concroff => null() ! runoff concentration
69  real(dp), dimension(:), pointer, contiguous :: conciflw => null() ! inflow concentration
70 
71  contains
72 
73  procedure :: bnd_da => lkt_da
74  procedure :: allocate_scalars
75  procedure :: apt_allocate_arrays => lkt_allocate_arrays
76  procedure :: find_apt_package => find_lkt_package
77  procedure :: apt_setting_value => lkt_setting_value
78  procedure :: pak_fc_expanded => lkt_fc_expanded
79  procedure :: pak_solve => lkt_solve
80  procedure :: pak_get_nbudterms => lkt_get_nbudterms
81  procedure :: pak_setup_budobj => lkt_setup_budobj
82  procedure :: pak_fill_budobj => lkt_fill_budobj
83  procedure :: lkt_rain_term
84  procedure :: lkt_evap_term
85  procedure :: lkt_roff_term
86  procedure :: lkt_iflw_term
87  procedure :: lkt_wdrl_term
88  procedure :: lkt_outf_term
89  procedure :: pak_df_obs => lkt_df_obs
90  procedure :: pak_rp_obs => lkt_rp_obs
91  procedure :: pak_bd_obs => lkt_bd_obs
92 
93  end type gwtlkttype
94 
95 contains
96 
97  !> @brief Create a new lkt package
98  !<
99  subroutine lkt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
100  mempath, fmi, eqnsclfac, dvt, dvu, dvua)
101  ! -- dummy
102  class(bndtype), pointer :: packobj
103  integer(I4B), intent(in) :: id
104  integer(I4B), intent(in) :: ibcnum
105  integer(I4B), intent(in) :: inunit
106  integer(I4B), intent(in) :: iout
107  character(len=*), intent(in) :: namemodel
108  character(len=*), intent(in) :: pakname
109  character(len=*), intent(in) :: mempath !< input memory path
110  type(tspfmitype), pointer :: fmi
111  real(dp), intent(in), pointer :: eqnsclfac !< governing equation scale factor
112  character(len=*), intent(in) :: dvt !< For GWT, set to "CONCENTRATION" in TspAptType
113  character(len=*), intent(in) :: dvu !< For GWT, set to "mass" in TspAptType
114  character(len=*), intent(in) :: dvua !< For GWT, set to "M" in TspAptType
115  ! -- local
116  type(gwtlkttype), pointer :: lktobj
117  !
118  ! -- allocate the object and assign values to object variables
119  allocate (lktobj)
120  packobj => lktobj
121  !
122  ! -- create name and memory path
123  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
124  packobj%text = text
125  !
126  ! -- allocate scalars
127  call lktobj%allocate_scalars()
128  !
129  ! -- initialize package
130  call packobj%pack_initialize()
131 
132  packobj%inunit = inunit
133  packobj%iout = iout
134  packobj%id = id
135  packobj%ibcnum = ibcnum
136  packobj%ncolbnd = 1
137  packobj%iscloc = 1
138  packobj%isadvpak = 1
139 
140  ! -- Store pointer to flow model interface. When the GwfGwt exchange is
141  ! created, it sets fmi%bndlist so that the GWT model has access to all
142  ! the flow packages
143  lktobj%fmi => fmi
144  !
145  ! -- Store pointer to governing equation scale factor
146  lktobj%eqnsclfac => eqnsclfac
147  !
148  ! -- Set labels that will be used in generalized APT class
149  lktobj%depvartype = dvt
150  lktobj%depvarunit = dvu
151  lktobj%depvarunitabbrev = dvua
152  end subroutine lkt_create
153 
154  !> @brief Find corresponding lkt package
155  !<
156  subroutine find_lkt_package(this)
157  ! -- modules
159  ! -- dummy
160  class(gwtlkttype) :: this
161  ! -- local
162  character(len=LINELENGTH) :: errmsg
163  class(bndtype), pointer :: packobj
164  integer(I4B) :: ip, icount
165  integer(I4B) :: nbudterm
166  logical :: found
167  !
168  ! -- Initialize found to false, and error later if flow package cannot
169  ! be found
170  found = .false.
171  !
172  ! -- If user is specifying flows in a binary budget file, then set up
173  ! the budget file reader, otherwise set a pointer to the flow package
174  ! budobj
175  if (this%fmi%flows_from_file) then
176  call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr)
177  if (associated(this%flowbudptr)) found = .true.
178  !
179  else
180  if (associated(this%fmi%gwfbndlist)) then
181  ! -- Look through gwfbndlist for a flow package with the same name as
182  ! this transport package name
183  do ip = 1, this%fmi%gwfbndlist%Count()
184  packobj => getbndfromlist(this%fmi%gwfbndlist, ip)
185  if (packobj%packName == this%flowpackagename) then
186  found = .true.
187  !
188  ! -- store BndType pointer to packobj, and then
189  ! use the select type to point to the budobj in flow package
190  this%flowpackagebnd => packobj
191  select type (packobj)
192  type is (laktype)
193  this%flowbudptr => packobj%budobj
194  end select
195  end if
196  if (found) exit
197  end do
198  end if
199  end if
200  !
201  ! -- error if flow package not found
202  if (.not. found) then
203  write (errmsg, '(a)') 'Could not find flow package with name '&
204  &//trim(adjustl(this%flowpackagename))//'.'
205  call store_error(errmsg)
206  call store_error_filename(this%input_fname)
207  end if
208  !
209  ! -- allocate space for idxbudssm, which indicates whether this is a
210  ! special budget term or one that is a general source and sink
211  nbudterm = this%flowbudptr%nbudterm
212  call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath)
213  !
214  ! -- Process budget terms and identify special budget terms
215  write (this%iout, '(/, a, a)') &
216  'PROCESSING '//ftype//' INFORMATION FOR ', this%packName
217  write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE'
218  write (this%iout, '(a, i0)') &
219  ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv
220  icount = 1
221  do ip = 1, this%flowbudptr%nbudterm
222  select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)))
223  case ('FLOW-JA-FACE')
224  this%idxbudfjf = ip
225  this%idxbudssm(ip) = 0
226  case ('GWF')
227  this%idxbudgwf = ip
228  this%idxbudssm(ip) = 0
229  case ('STORAGE')
230  this%idxbudsto = ip
231  this%idxbudssm(ip) = 0
232  case ('RAINFALL')
233  this%idxbudrain = ip
234  this%idxbudssm(ip) = 0
235  case ('EVAPORATION')
236  this%idxbudevap = ip
237  this%idxbudssm(ip) = 0
238  case ('RUNOFF')
239  this%idxbudroff = ip
240  this%idxbudssm(ip) = 0
241  case ('EXT-INFLOW')
242  this%idxbudiflw = ip
243  this%idxbudssm(ip) = 0
244  case ('WITHDRAWAL')
245  this%idxbudwdrl = ip
246  this%idxbudssm(ip) = 0
247  case ('EXT-OUTFLOW')
248  this%idxbudoutf = ip
249  this%idxbudssm(ip) = 0
250  case ('TO-MVR')
251  this%idxbudtmvr = ip
252  this%idxbudssm(ip) = 0
253  case ('FROM-MVR')
254  this%idxbudfmvr = ip
255  this%idxbudssm(ip) = 0
256  case ('AUXILIARY')
257  this%idxbudaux = ip
258  this%idxbudssm(ip) = 0
259  case default
260  !
261  ! -- set idxbudssm equal to a column index for where the concentrations
262  ! are stored in the concbud(nbudssm, ncv) array
263  this%idxbudssm(ip) = icount
264  icount = icount + 1
265  end select
266  write (this%iout, '(a, i0, " = ", a,/, a, i0)') &
267  ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), &
268  ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist
269  end do
270  write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION'
271  end subroutine find_lkt_package
272 
273  !> @brief Value for a package-specific PERIOD setting
274  !!
275  !! Already resolved by the input context; this only supplies it for
276  !! the shared apt_rp table echo.
277  !<
278  function lkt_setting_value(this, itemno, key) result(val)
279  ! -- dummy
280  class(gwtlkttype), intent(inout) :: this
281  integer(I4B), intent(in) :: itemno
282  character(len=*), intent(in) :: key
283  real(dp) :: val
284  !
285  val = dzero
286  select case (trim(key))
287  case ('RAINFALL')
288  val = this%concrain(itemno)
289  case ('EVAPORATION')
290  val = this%concevap(itemno)
291  case ('RUNOFF')
292  val = this%concroff(itemno)
293  case ('EXT-INFLOW')
294  val = this%conciflw(itemno)
295  end select
296  end function lkt_setting_value
297 
298  !> @brief Add matrix terms related to LKT
299  !!
300  !! This will be called from TspAptType%apt_fc_expanded()
301  !! in order to add matrix terms specifically for LKT
302  !<
303  subroutine lkt_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
304  ! -- modules
305  ! -- dummy
306  class(gwtlkttype) :: this
307  real(DP), dimension(:), intent(inout) :: rhs
308  integer(I4B), dimension(:), intent(in) :: ia
309  integer(I4B), dimension(:), intent(in) :: idxglo
310  class(matrixbasetype), pointer :: matrix_sln
311  ! -- local
312  integer(I4B) :: j, n1, n2
313  integer(I4B) :: iloc
314  integer(I4B) :: iposd
315  real(DP) :: rrate
316  real(DP) :: rhsval
317  real(DP) :: hcofval
318  !
319  ! -- add rainfall contribution
320  if (this%idxbudrain /= 0) then
321  do j = 1, this%flowbudptr%budterm(this%idxbudrain)%nlist
322  call this%lkt_rain_term(j, n1, n2, rrate, rhsval, hcofval)
323  iloc = this%idxlocnode(n1)
324  iposd = this%idxpakdiag(n1)
325  call matrix_sln%add_value_pos(iposd, hcofval)
326  rhs(iloc) = rhs(iloc) + rhsval
327  end do
328  end if
329  !
330  ! -- add evaporation contribution
331  if (this%idxbudevap /= 0) then
332  do j = 1, this%flowbudptr%budterm(this%idxbudevap)%nlist
333  call this%lkt_evap_term(j, n1, n2, rrate, rhsval, hcofval)
334  iloc = this%idxlocnode(n1)
335  iposd = this%idxpakdiag(n1)
336  call matrix_sln%add_value_pos(iposd, hcofval)
337  rhs(iloc) = rhs(iloc) + rhsval
338  end do
339  end if
340  !
341  ! -- add runoff contribution
342  if (this%idxbudroff /= 0) then
343  do j = 1, this%flowbudptr%budterm(this%idxbudroff)%nlist
344  call this%lkt_roff_term(j, n1, n2, rrate, rhsval, hcofval)
345  iloc = this%idxlocnode(n1)
346  iposd = this%idxpakdiag(n1)
347  call matrix_sln%add_value_pos(iposd, hcofval)
348  rhs(iloc) = rhs(iloc) + rhsval
349  end do
350  end if
351  !
352  ! -- add inflow contribution
353  if (this%idxbudiflw /= 0) then
354  do j = 1, this%flowbudptr%budterm(this%idxbudiflw)%nlist
355  call this%lkt_iflw_term(j, n1, n2, rrate, rhsval, hcofval)
356  iloc = this%idxlocnode(n1)
357  iposd = this%idxpakdiag(n1)
358  call matrix_sln%add_value_pos(iposd, hcofval)
359  rhs(iloc) = rhs(iloc) + rhsval
360  end do
361  end if
362  !
363  ! -- add withdrawal contribution
364  if (this%idxbudwdrl /= 0) then
365  do j = 1, this%flowbudptr%budterm(this%idxbudwdrl)%nlist
366  call this%lkt_wdrl_term(j, n1, n2, rrate, rhsval, hcofval)
367  iloc = this%idxlocnode(n1)
368  iposd = this%idxpakdiag(n1)
369  call matrix_sln%add_value_pos(iposd, hcofval)
370  rhs(iloc) = rhs(iloc) + rhsval
371  end do
372  end if
373  !
374  ! -- add outflow contribution
375  if (this%idxbudoutf /= 0) then
376  do j = 1, this%flowbudptr%budterm(this%idxbudoutf)%nlist
377  call this%lkt_outf_term(j, n1, n2, rrate, rhsval, hcofval)
378  iloc = this%idxlocnode(n1)
379  iposd = this%idxpakdiag(n1)
380  call matrix_sln%add_value_pos(iposd, hcofval)
381  rhs(iloc) = rhs(iloc) + rhsval
382  end do
383  end if
384  end subroutine lkt_fc_expanded
385 
386  !> @brief Add terms specific to lakes to the explicit lake solve
387  !<
388  subroutine lkt_solve(this)
389  ! -- dummy
390  class(gwtlkttype) :: this
391  ! -- local
392  integer(I4B) :: j
393  integer(I4B) :: n1, n2
394  real(DP) :: rrate
395  !
396  ! -- add rainfall contribution
397  if (this%idxbudrain /= 0) then
398  do j = 1, this%flowbudptr%budterm(this%idxbudrain)%nlist
399  call this%lkt_rain_term(j, n1, n2, rrate)
400  this%dbuff(n1) = this%dbuff(n1) + rrate
401  end do
402  end if
403  !
404  ! -- add evaporation contribution
405  if (this%idxbudevap /= 0) then
406  do j = 1, this%flowbudptr%budterm(this%idxbudevap)%nlist
407  call this%lkt_evap_term(j, n1, n2, rrate)
408  this%dbuff(n1) = this%dbuff(n1) + rrate
409  end do
410  end if
411  !
412  ! -- add runoff contribution
413  if (this%idxbudroff /= 0) then
414  do j = 1, this%flowbudptr%budterm(this%idxbudroff)%nlist
415  call this%lkt_roff_term(j, n1, n2, rrate)
416  this%dbuff(n1) = this%dbuff(n1) + rrate
417  end do
418  end if
419  !
420  ! -- add inflow contribution
421  if (this%idxbudiflw /= 0) then
422  do j = 1, this%flowbudptr%budterm(this%idxbudiflw)%nlist
423  call this%lkt_iflw_term(j, n1, n2, rrate)
424  this%dbuff(n1) = this%dbuff(n1) + rrate
425  end do
426  end if
427  !
428  ! -- add withdrawal contribution
429  if (this%idxbudwdrl /= 0) then
430  do j = 1, this%flowbudptr%budterm(this%idxbudwdrl)%nlist
431  call this%lkt_wdrl_term(j, n1, n2, rrate)
432  this%dbuff(n1) = this%dbuff(n1) + rrate
433  end do
434  end if
435  !
436  ! -- add outflow contribution
437  if (this%idxbudoutf /= 0) then
438  do j = 1, this%flowbudptr%budterm(this%idxbudoutf)%nlist
439  call this%lkt_outf_term(j, n1, n2, rrate)
440  this%dbuff(n1) = this%dbuff(n1) + rrate
441  end do
442  end if
443  end subroutine lkt_solve
444 
445  !> @brief Function to return the number of budget terms just for this package.
446  !!
447  !! This overrides a function in the parent class.
448  !<
449  function lkt_get_nbudterms(this) result(nbudterms)
450  ! -- modules
451  ! -- dummy
452  class(gwtlkttype) :: this
453  ! -- return
454  integer(I4B) :: nbudterms
455  ! -- local
456  !
457  ! -- Number of budget terms is 6
458  nbudterms = 6
459  end function lkt_get_nbudterms
460 
461  !> @brief Set up the budget object that stores all the lake flows
462  !<
463  subroutine lkt_setup_budobj(this, idx)
464  ! -- modules
465  use constantsmodule, only: lenbudtxt
466  ! -- dummy
467  class(gwtlkttype) :: this
468  integer(I4B), intent(inout) :: idx
469  ! -- local
470  integer(I4B) :: maxlist, naux
471  character(len=LENBUDTXT) :: text
472  !
473  ! -- Addition of mass associated with rainfall directly on lake surface
474  text = ' RAINFALL'
475  idx = idx + 1
476  maxlist = this%flowbudptr%budterm(this%idxbudrain)%maxlist
477  naux = 0
478  call this%budobj%budterm(idx)%initialize(text, &
479  this%name_model, &
480  this%packName, &
481  this%name_model, &
482  this%packName, &
483  maxlist, .false., .false., &
484  naux)
485  !
486  ! -- Loss of dissolved mass associated with evaporation when a non-zero
487  ! evaporative concentration is specified
488  text = ' EVAPORATION'
489  idx = idx + 1
490  maxlist = this%flowbudptr%budterm(this%idxbudevap)%maxlist
491  naux = 0
492  call this%budobj%budterm(idx)%initialize(text, &
493  this%name_model, &
494  this%packName, &
495  this%name_model, &
496  this%packName, &
497  maxlist, .false., .false., &
498  naux)
499  !
500  ! -- Addition of mass associated with runoff that flows to the lake
501  text = ' RUNOFF'
502  idx = idx + 1
503  maxlist = this%flowbudptr%budterm(this%idxbudroff)%maxlist
504  naux = 0
505  call this%budobj%budterm(idx)%initialize(text, &
506  this%name_model, &
507  this%packName, &
508  this%name_model, &
509  this%packName, &
510  maxlist, .false., .false., &
511  naux)
512  !
513  ! -- Addition of mass associated with user-specified inflow to the lake
514  text = ' EXT-INFLOW'
515  idx = idx + 1
516  maxlist = this%flowbudptr%budterm(this%idxbudiflw)%maxlist
517  naux = 0
518  call this%budobj%budterm(idx)%initialize(text, &
519  this%name_model, &
520  this%packName, &
521  this%name_model, &
522  this%packName, &
523  maxlist, .false., .false., &
524  naux)
525  !
526  ! -- Removal of mass associated with user-specified withdrawal from lake
527  text = ' WITHDRAWAL'
528  idx = idx + 1
529  maxlist = this%flowbudptr%budterm(this%idxbudwdrl)%maxlist
530  naux = 0
531  call this%budobj%budterm(idx)%initialize(text, &
532  this%name_model, &
533  this%packName, &
534  this%name_model, &
535  this%packName, &
536  maxlist, .false., .false., &
537  naux)
538  !
539  ! -- Removal of heat associated with outflow from lake that leaves
540  ! model domain
541  text = ' EXT-OUTFLOW'
542  idx = idx + 1
543  maxlist = this%flowbudptr%budterm(this%idxbudoutf)%maxlist
544  naux = 0
545  call this%budobj%budterm(idx)%initialize(text, &
546  this%name_model, &
547  this%packName, &
548  this%name_model, &
549  this%packName, &
550  maxlist, .false., .false., &
551  naux)
552  end subroutine lkt_setup_budobj
553 
554  !> @brief Copy flow terms into this%budobj
555  !<
556  subroutine lkt_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
557  ! -- modules
558  ! -- dummy
559  class(gwtlkttype) :: this
560  integer(I4B), intent(inout) :: idx
561  real(DP), dimension(:), intent(in) :: x
562  real(DP), dimension(:), contiguous, intent(inout) :: flowja
563  real(DP), intent(inout) :: ccratin
564  real(DP), intent(inout) :: ccratout
565  ! -- local
566  integer(I4B) :: j, n1, n2
567  integer(I4B) :: nlist
568  real(DP) :: q
569  ! -- formats
570  !
571  ! -- RAIN
572  idx = idx + 1
573  nlist = this%flowbudptr%budterm(this%idxbudrain)%nlist
574  call this%budobj%budterm(idx)%reset(nlist)
575  do j = 1, nlist
576  call this%lkt_rain_term(j, n1, n2, q)
577  call this%budobj%budterm(idx)%update_term(n1, n2, q)
578  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
579  end do
580  !
581  ! -- EVAPORATION
582  idx = idx + 1
583  nlist = this%flowbudptr%budterm(this%idxbudevap)%nlist
584  call this%budobj%budterm(idx)%reset(nlist)
585  do j = 1, nlist
586  call this%lkt_evap_term(j, n1, n2, q)
587  call this%budobj%budterm(idx)%update_term(n1, n2, q)
588  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
589  end do
590  !
591  ! -- RUNOFF
592  idx = idx + 1
593  nlist = this%flowbudptr%budterm(this%idxbudroff)%nlist
594  call this%budobj%budterm(idx)%reset(nlist)
595  do j = 1, nlist
596  call this%lkt_roff_term(j, n1, n2, q)
597  call this%budobj%budterm(idx)%update_term(n1, n2, q)
598  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
599  end do
600  !
601  ! -- EXT-INFLOW
602  idx = idx + 1
603  nlist = this%flowbudptr%budterm(this%idxbudiflw)%nlist
604  call this%budobj%budterm(idx)%reset(nlist)
605  do j = 1, nlist
606  call this%lkt_iflw_term(j, n1, n2, q)
607  call this%budobj%budterm(idx)%update_term(n1, n2, q)
608  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
609  end do
610  !
611  ! -- WITHDRAWAL
612  idx = idx + 1
613  nlist = this%flowbudptr%budterm(this%idxbudwdrl)%nlist
614  call this%budobj%budterm(idx)%reset(nlist)
615  do j = 1, nlist
616  call this%lkt_wdrl_term(j, n1, n2, q)
617  call this%budobj%budterm(idx)%update_term(n1, n2, q)
618  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
619  end do
620  !
621  ! -- EXT-OUTFLOW
622  idx = idx + 1
623  nlist = this%flowbudptr%budterm(this%idxbudoutf)%nlist
624  call this%budobj%budterm(idx)%reset(nlist)
625  do j = 1, nlist
626  call this%lkt_outf_term(j, n1, n2, q)
627  call this%budobj%budterm(idx)%update_term(n1, n2, q)
628  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
629  end do
630  end subroutine lkt_fill_budobj
631 
632  !> @brief Allocate scalars specific to the lake mass transport (LKT)
633  !! package.
634  !<
635  subroutine allocate_scalars(this)
636  ! -- modules
638  ! -- dummy
639  class(gwtlkttype) :: this
640  ! -- local
641  !
642  ! -- allocate scalars in TspAptType
643  call this%TspAptType%allocate_scalars()
644  !
645  ! -- Allocate
646  call mem_allocate(this%idxbudrain, 'IDXBUDRAIN', this%memoryPath)
647  call mem_allocate(this%idxbudevap, 'IDXBUDEVAP', this%memoryPath)
648  call mem_allocate(this%idxbudroff, 'IDXBUDROFF', this%memoryPath)
649  call mem_allocate(this%idxbudiflw, 'IDXBUDIFLW', this%memoryPath)
650  call mem_allocate(this%idxbudwdrl, 'IDXBUDWDRL', this%memoryPath)
651  call mem_allocate(this%idxbudoutf, 'IDXBUDOUTF', this%memoryPath)
652  !
653  ! -- Initialize
654  this%idxbudrain = 0
655  this%idxbudevap = 0
656  this%idxbudroff = 0
657  this%idxbudiflw = 0
658  this%idxbudwdrl = 0
659  this%idxbudoutf = 0
660  end subroutine allocate_scalars
661 
662  !> @brief Allocate arrays specific to the lake mass transport (LKT)
663  !! package.
664  !<
665  subroutine lkt_allocate_arrays(this)
666  ! -- modules
668  ! -- dummy
669  class(gwtlkttype), intent(inout) :: this
670  !
671  ! -- alias into the input context's permanent, feature-indexed arrays
672  ! (allocated and DZERO-initialized by the input context)
673  call mem_setptr(this%concrain, 'RAINFALL', this%input_mempath)
674  call mem_setptr(this%concevap, 'EVAPORATION', this%input_mempath)
675  call mem_setptr(this%concroff, 'RUNOFF', this%input_mempath)
676  call mem_setptr(this%conciflw, 'EXT_INFLOW', this%input_mempath)
677  !
678  ! -- call standard TspAptType allocate arrays
679  call this%TspAptType%apt_allocate_arrays()
680  !
681  end subroutine lkt_allocate_arrays
682 
683  !> @brief Deallocate memory
684  !<
685  subroutine lkt_da(this)
686  ! -- modules
688  ! -- dummy
689  class(gwtlkttype) :: this
690  ! -- local
691  !
692  ! -- deallocate scalars
693  call mem_deallocate(this%idxbudrain)
694  call mem_deallocate(this%idxbudevap)
695  call mem_deallocate(this%idxbudroff)
696  call mem_deallocate(this%idxbudiflw)
697  call mem_deallocate(this%idxbudwdrl)
698  call mem_deallocate(this%idxbudoutf)
699  !
700  ! -- input-context-owned aliases, not package-allocated
701  nullify (this%concrain)
702  nullify (this%concevap)
703  nullify (this%concroff)
704  nullify (this%conciflw)
705  !
706  ! -- deallocate scalars in TspAptType
707  call this%TspAptType%bnd_da()
708  end subroutine lkt_da
709 
710  !> @brief Rain term
711  !<
712  subroutine lkt_rain_term(this, ientry, n1, n2, rrate, &
713  rhsval, hcofval)
714  ! -- dummy
715  class(gwtlkttype) :: this
716  integer(I4B), intent(in) :: ientry
717  integer(I4B), intent(inout) :: n1
718  integer(I4B), intent(inout) :: n2
719  real(DP), intent(inout), optional :: rrate
720  real(DP), intent(inout), optional :: rhsval
721  real(DP), intent(inout), optional :: hcofval
722  ! -- local
723  real(DP) :: qbnd
724  real(DP) :: ctmp
725  !
726  n1 = this%flowbudptr%budterm(this%idxbudrain)%id1(ientry)
727  n2 = this%flowbudptr%budterm(this%idxbudrain)%id2(ientry)
728  qbnd = this%flowbudptr%budterm(this%idxbudrain)%flow(ientry)
729  ctmp = this%concrain(n1)
730  if (present(rrate)) rrate = ctmp * qbnd
731  if (present(rhsval)) rhsval = -rrate
732  if (present(hcofval)) hcofval = dzero
733  end subroutine lkt_rain_term
734 
735  !> @brief Evaporative term
736  !<
737  subroutine lkt_evap_term(this, ientry, n1, n2, rrate, &
738  rhsval, hcofval)
739  ! -- dummy
740  class(gwtlkttype) :: 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  real(DP) :: omega
751  !
752  n1 = this%flowbudptr%budterm(this%idxbudevap)%id1(ientry)
753  n2 = this%flowbudptr%budterm(this%idxbudevap)%id2(ientry)
754  ! -- note that qbnd is negative for evap
755  qbnd = this%flowbudptr%budterm(this%idxbudevap)%flow(ientry)
756  ctmp = this%concevap(n1)
757  if (this%xnewpak(n1) < ctmp) then
758  omega = done
759  else
760  omega = dzero
761  end if
762  if (present(rrate)) &
763  rrate = omega * qbnd * this%xnewpak(n1) + &
764  (done - omega) * qbnd * ctmp
765  if (present(rhsval)) rhsval = -(done - omega) * qbnd * ctmp
766  if (present(hcofval)) hcofval = omega * qbnd
767  end subroutine lkt_evap_term
768 
769  !> @brief Runoff term
770  !<
771  subroutine lkt_roff_term(this, ientry, n1, n2, rrate, &
772  rhsval, hcofval)
773  ! -- dummy
774  class(gwtlkttype) :: this
775  integer(I4B), intent(in) :: ientry
776  integer(I4B), intent(inout) :: n1
777  integer(I4B), intent(inout) :: n2
778  real(DP), intent(inout), optional :: rrate
779  real(DP), intent(inout), optional :: rhsval
780  real(DP), intent(inout), optional :: hcofval
781  ! -- local
782  real(DP) :: qbnd
783  real(DP) :: ctmp
784  !
785  n1 = this%flowbudptr%budterm(this%idxbudroff)%id1(ientry)
786  n2 = this%flowbudptr%budterm(this%idxbudroff)%id2(ientry)
787  qbnd = this%flowbudptr%budterm(this%idxbudroff)%flow(ientry)
788  ctmp = this%concroff(n1)
789  if (present(rrate)) rrate = ctmp * qbnd
790  if (present(rhsval)) rhsval = -rrate
791  if (present(hcofval)) hcofval = dzero
792  end subroutine lkt_roff_term
793 
794  !> @brief Inflow Term
795  !!
796  !! Accounts for mass flowing into a lake from a connected stream, for
797  !! example.
798  !<
799  subroutine lkt_iflw_term(this, ientry, n1, n2, rrate, &
800  rhsval, hcofval)
801  ! -- dummy
802  class(gwtlkttype) :: this
803  integer(I4B), intent(in) :: ientry
804  integer(I4B), intent(inout) :: n1
805  integer(I4B), intent(inout) :: n2
806  real(DP), intent(inout), optional :: rrate
807  real(DP), intent(inout), optional :: rhsval
808  real(DP), intent(inout), optional :: hcofval
809  ! -- local
810  real(DP) :: qbnd
811  real(DP) :: ctmp
812  !
813  n1 = this%flowbudptr%budterm(this%idxbudiflw)%id1(ientry)
814  n2 = this%flowbudptr%budterm(this%idxbudiflw)%id2(ientry)
815  qbnd = this%flowbudptr%budterm(this%idxbudiflw)%flow(ientry)
816  ctmp = this%conciflw(n1)
817  if (present(rrate)) rrate = ctmp * qbnd
818  if (present(rhsval)) rhsval = -rrate
819  if (present(hcofval)) hcofval = dzero
820  end subroutine lkt_iflw_term
821 
822  !> @brief Specified withdrawal term
823  !!
824  !! Accounts for mass associated with a withdrawal of water from a lake
825  !! or group of lakes.
826  !<
827  subroutine lkt_wdrl_term(this, ientry, n1, n2, rrate, &
828  rhsval, hcofval)
829  ! -- dummy
830  class(gwtlkttype) :: this
831  integer(I4B), intent(in) :: ientry
832  integer(I4B), intent(inout) :: n1
833  integer(I4B), intent(inout) :: n2
834  real(DP), intent(inout), optional :: rrate
835  real(DP), intent(inout), optional :: rhsval
836  real(DP), intent(inout), optional :: hcofval
837  ! -- local
838  real(DP) :: qbnd
839  real(DP) :: ctmp
840  !
841  n1 = this%flowbudptr%budterm(this%idxbudwdrl)%id1(ientry)
842  n2 = this%flowbudptr%budterm(this%idxbudwdrl)%id2(ientry)
843  qbnd = this%flowbudptr%budterm(this%idxbudwdrl)%flow(ientry)
844  ctmp = this%xnewpak(n1)
845  if (present(rrate)) rrate = ctmp * qbnd
846  if (present(rhsval)) rhsval = dzero
847  if (present(hcofval)) hcofval = qbnd
848  end subroutine lkt_wdrl_term
849 
850  !> @brief Outflow term
851  !!
852  !! Accounts for the mass leaving a lake, for example, mass exiting a
853  !! lake via a flow into a draining stream channel.
854  !<
855  subroutine lkt_outf_term(this, ientry, n1, n2, rrate, &
856  rhsval, hcofval)
857  ! -- dummy
858  class(gwtlkttype) :: this
859  integer(I4B), intent(in) :: ientry
860  integer(I4B), intent(inout) :: n1
861  integer(I4B), intent(inout) :: n2
862  real(DP), intent(inout), optional :: rrate
863  real(DP), intent(inout), optional :: rhsval
864  real(DP), intent(inout), optional :: hcofval
865  ! -- local
866  real(DP) :: qbnd
867  real(DP) :: ctmp
868  !
869  n1 = this%flowbudptr%budterm(this%idxbudoutf)%id1(ientry)
870  n2 = this%flowbudptr%budterm(this%idxbudoutf)%id2(ientry)
871  qbnd = this%flowbudptr%budterm(this%idxbudoutf)%flow(ientry)
872  ctmp = this%xnewpak(n1)
873  if (present(rrate)) rrate = ctmp * qbnd
874  if (present(rhsval)) rhsval = dzero
875  if (present(hcofval)) hcofval = qbnd
876  end subroutine lkt_outf_term
877 
878  !> @brief Defined observation types
879  !!
880  !! Store the observation type supported by the APT package and override
881  !! BndType%bnd_df_obs
882  !<
883  subroutine lkt_df_obs(this)
884  ! -- modules
885  ! -- dummy
886  class(gwtlkttype) :: this
887  ! -- local
888  integer(I4B) :: indx
889  !
890  ! -- Store obs type and assign procedure pointer
891  ! for concentration observation type.
892  call this%obs%StoreObsType('concentration', .false., indx)
893  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
894  !
895  ! -- Store obs type and assign procedure pointer
896  ! for flow between features, such as lake to lake.
897  call this%obs%StoreObsType('flow-ja-face', .true., indx)
898  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid12
899  !
900  ! -- Store obs type and assign procedure pointer
901  ! for from-mvr observation type.
902  call this%obs%StoreObsType('from-mvr', .true., indx)
903  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
904  !
905  ! -- Store obs type and assign procedure pointer
906  ! for to-mvr observation type.
907  call this%obs%StoreObsType('to-mvr', .true., indx)
908  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
909  !
910  ! -- Store obs type and assign procedure pointer
911  ! for storage observation type.
912  call this%obs%StoreObsType('storage', .true., indx)
913  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
914  !
915  ! -- Store obs type and assign procedure pointer
916  ! for constant observation type.
917  call this%obs%StoreObsType('constant', .true., indx)
918  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
919  !
920  ! -- Store obs type and assign procedure pointer
921  ! for observation type: lkt
922  call this%obs%StoreObsType('lkt', .true., indx)
923  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid12
924  !
925  ! -- Store obs type and assign procedure pointer
926  ! for rainfall observation type.
927  call this%obs%StoreObsType('rainfall', .true., indx)
928  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
929  !
930  ! -- Store obs type and assign procedure pointer
931  ! for evaporation observation type.
932  call this%obs%StoreObsType('evaporation', .true., indx)
933  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
934  !
935  ! -- Store obs type and assign procedure pointer
936  ! for runoff observation type.
937  call this%obs%StoreObsType('runoff', .true., indx)
938  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
939  !
940  ! -- Store obs type and assign procedure pointer
941  ! for inflow observation type.
942  call this%obs%StoreObsType('ext-inflow', .true., indx)
943  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
944  !
945  ! -- Store obs type and assign procedure pointer
946  ! for withdrawal observation type.
947  call this%obs%StoreObsType('withdrawal', .true., indx)
948  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
949  !
950  ! -- Store obs type and assign procedure pointer
951  ! for ext-outflow observation type.
952  call this%obs%StoreObsType('ext-outflow', .true., indx)
953  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
954  end subroutine lkt_df_obs
955 
956  !> @brief Process package specific obs
957  !!
958  !! Method to process specific observations for this package.
959  !<
960  subroutine lkt_rp_obs(this, obsrv, found)
961  ! -- dummy
962  class(gwtlkttype), intent(inout) :: this !< package class
963  type(observetype), intent(inout) :: obsrv !< observation object
964  logical, intent(inout) :: found !< indicate whether observation was found
965  ! -- local
966  !
967  found = .true.
968  select case (obsrv%ObsTypeId)
969  case ('RAINFALL')
970  call this%rp_obs_byfeature(obsrv)
971  case ('EVAPORATION')
972  call this%rp_obs_byfeature(obsrv)
973  case ('RUNOFF')
974  call this%rp_obs_byfeature(obsrv)
975  case ('EXT-INFLOW')
976  call this%rp_obs_byfeature(obsrv)
977  case ('WITHDRAWAL')
978  call this%rp_obs_byfeature(obsrv)
979  case ('EXT-OUTFLOW')
980  call this%rp_obs_byfeature(obsrv)
981  case ('TO-MVR')
982  call this%rp_obs_budterm(obsrv, &
983  this%flowbudptr%budterm(this%idxbudtmvr))
984  case default
985  found = .false.
986  end select
987  end subroutine lkt_rp_obs
988 
989  !> @brief Calculate observation value and pass it back to APT
990  !<
991  subroutine lkt_bd_obs(this, obstypeid, jj, v, found)
992  ! -- dummy
993  class(gwtlkttype), intent(inout) :: this
994  character(len=*), intent(in) :: obstypeid
995  real(DP), intent(inout) :: v
996  integer(I4B), intent(in) :: jj
997  logical, intent(inout) :: found
998  ! -- local
999  integer(I4B) :: n1, n2
1000  !
1001  found = .true.
1002  select case (obstypeid)
1003  case ('RAINFALL')
1004  if (this%iboundpak(jj) /= 0) then
1005  call this%lkt_rain_term(jj, n1, n2, v)
1006  end if
1007  case ('EVAPORATION')
1008  if (this%iboundpak(jj) /= 0) then
1009  call this%lkt_evap_term(jj, n1, n2, v)
1010  end if
1011  case ('RUNOFF')
1012  if (this%iboundpak(jj) /= 0) then
1013  call this%lkt_roff_term(jj, n1, n2, v)
1014  end if
1015  case ('EXT-INFLOW')
1016  if (this%iboundpak(jj) /= 0) then
1017  call this%lkt_iflw_term(jj, n1, n2, v)
1018  end if
1019  case ('WITHDRAWAL')
1020  if (this%iboundpak(jj) /= 0) then
1021  call this%lkt_wdrl_term(jj, n1, n2, v)
1022  end if
1023  case ('EXT-OUTFLOW')
1024  if (this%iboundpak(jj) /= 0) then
1025  call this%lkt_outf_term(jj, n1, n2, v)
1026  end if
1027  case default
1028  found = .false.
1029  end select
1030  end subroutine lkt_bd_obs
1031 
1032 end module gwtlktmodule
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
character(len= *), parameter flowtype
Definition: gwt-lkt.f90:54
subroutine lkt_allocate_arrays(this)
Allocate arrays specific to the lake mass transport (LKT) package.
Definition: gwt-lkt.f90:666
subroutine lkt_da(this)
Deallocate memory.
Definition: gwt-lkt.f90:686
subroutine lkt_roff_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Runoff term.
Definition: gwt-lkt.f90:773
subroutine, public lkt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath, fmi, eqnsclfac, dvt, dvu, dvua)
Create a new lkt package.
Definition: gwt-lkt.f90:101
subroutine lkt_bd_obs(this, obstypeid, jj, v, found)
Calculate observation value and pass it back to APT.
Definition: gwt-lkt.f90:992
subroutine lkt_outf_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Outflow term.
Definition: gwt-lkt.f90:857
subroutine lkt_rp_obs(this, obsrv, found)
Process package specific obs.
Definition: gwt-lkt.f90:961
subroutine find_lkt_package(this)
Find corresponding lkt package.
Definition: gwt-lkt.f90:157
character(len= *), parameter ftype
Definition: gwt-lkt.f90:53
subroutine lkt_iflw_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Inflow Term.
Definition: gwt-lkt.f90:801
subroutine lkt_solve(this)
Add terms specific to lakes to the explicit lake solve.
Definition: gwt-lkt.f90:389
subroutine lkt_evap_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Evaporative term.
Definition: gwt-lkt.f90:739
subroutine allocate_scalars(this)
Allocate scalars specific to the lake mass transport (LKT) package.
Definition: gwt-lkt.f90:636
subroutine lkt_rain_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Rain term.
Definition: gwt-lkt.f90:714
integer(i4b) function lkt_get_nbudterms(this)
Function to return the number of budget terms just for this package.
Definition: gwt-lkt.f90:450
subroutine lkt_setup_budobj(this, idx)
Set up the budget object that stores all the lake flows.
Definition: gwt-lkt.f90:464
subroutine lkt_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
Copy flow terms into thisbudobj.
Definition: gwt-lkt.f90:557
subroutine lkt_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
Add matrix terms related to LKT.
Definition: gwt-lkt.f90:304
real(dp) function lkt_setting_value(this, itemno, key)
Value for a package-specific PERIOD setting.
Definition: gwt-lkt.f90:279
character(len=16) text
Definition: gwt-lkt.f90:55
subroutine lkt_wdrl_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Specified withdrawal term.
Definition: gwt-lkt.f90:829
subroutine lkt_df_obs(this)
Defined observation types.
Definition: gwt-lkt.f90:884
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