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