MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
gwe-mwe.f90
Go to the documentation of this file.
1 ! -- Multi-Aquifer Well Energy Transport Module
2 ! -- todo: save the mwe temperature into the mwe aux variable?
3 ! -- todo: calculate the maw DENSE aux variable using temperature?
4 !
5 ! MAW flows (flowbudptr) index var MWE term Transport Type
6 !---------------------------------------------------------------------------------
7 
8 ! -- terms from MAW that will be handled by parent APT Package
9 ! FLOW-JA-FACE idxbudfjf FLOW-JA-FACE cv2cv (note that this doesn't exist for MAW)
10 ! GWF (aux FLOW-AREA) idxbudgwf GWF cv2gwf
11 ! STORAGE (aux VOLUME) idxbudsto none used for cv volumes
12 ! FROM-MVR idxbudfmvr FROM-MVR q * text = this%qfrommvr(:)
13 ! TO-MVR idxbudtmvr TO-MVR q * tfeat
14 
15 ! -- MAW terms
16 ! RATE idxbudrate RATE q < 0: q * twell, else q * tuser
17 ! FW-RATE idxbudfwrt FW-RATE q * twell
18 ! RATE-TO-MVR idxbudrtmv RATE-TO-MVR q * twell
19 ! FW-RATE-TO-MVR idxbudfrtm FW-RATE-TO-MVR q * twell
20 ! WELL-AQUIFER CONDUCTION idxbudmwcd MW-CONDUCTION K_t_f * WetArea / thickness
21 
22 ! -- terms from MAW that should be skipped
23 ! CONSTANT-TO-MVR ? CONSTANT-TO-MVR q * twell
24 
25 ! -- terms from a flow file that should be skipped
26 ! CONSTANT none none none
27 ! AUXILIARY none none none
28 
29 ! -- terms that are written to the energy transport budget file
30 ! none none STORAGE (aux ENER) dE/dt
31 ! none none AUXILIARY none
32 ! none none CONSTANT accumulate
33 !
34 !
36 
37  use kindmodule, only: dp, i4b
38  use constantsmodule, only: dzero, linelength
39  use simmodule, only: store_error
40  use bndmodule, only: bndtype, getbndfromlist
41  use tspfmimodule, only: tspfmitype
42  use mawmodule, only: mawtype
43  use observemodule, only: observetype
48 
49  implicit none
50 
51  public mwe_create
52 
53  character(len=*), parameter :: ftype = 'MWE'
54  character(len=*), parameter :: flowtype = 'MAW'
55  character(len=16) :: text = ' MWE'
56 
57  type, extends(tspapttype) :: gwemwetype
58 
59  type(gweinputdatatype), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst
60 
61  integer(I4B), pointer :: idxbudrate => null() ! index of well rate terms in flowbudptr
62  integer(I4B), pointer :: idxbudfwrt => null() ! index of flowing well rate terms in flowbudptr
63  integer(I4B), pointer :: idxbudrtmv => null() ! index of rate to mover terms in flowbudptr
64  integer(I4B), pointer :: idxbudfrtm => null() ! index of flowing well rate to mover terms in flowbudptr
65  integer(I4B), pointer :: idxbudmwcd => null() ! index of well bore conduction terms in flowbudptr
66  real(dp), dimension(:), pointer, contiguous :: temprate => null() ! well rate temperature
67 
68  contains
69 
70  procedure :: bnd_da => mwe_da
71  procedure :: allocate_scalars
72  procedure :: apt_allocate_arrays => mwe_allocate_arrays
73  procedure :: find_apt_package => find_mwe_package
74  procedure :: pak_fc_expanded => mwe_fc_expanded
75  procedure :: pak_solve => mwe_solve
76  procedure :: pak_get_nbudterms => mwe_get_nbudterms
77  procedure :: pak_setup_budobj => mwe_setup_budobj
78  procedure :: pak_fill_budobj => mwe_fill_budobj
79  procedure :: mwe_rate_term
80  procedure :: mwe_fwrt_term
81  procedure :: mwe_rtmv_term
82  procedure :: mwe_frtm_term
83  procedure :: pak_df_obs => mwe_df_obs
84  procedure :: pak_rp_obs => mwe_rp_obs
85  procedure :: pak_bd_obs => mwe_bd_obs
86  procedure :: pak_set_stressperiod => mwe_set_stressperiod
87 
88  end type gwemwetype
89 
90 contains
91 
92  !> Create new MWE package
93  !<
94  subroutine mwe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
95  fmi, eqnsclfac, gwecommon, dvt, dvu, dvua)
96  ! -- dummy
97  class(bndtype), pointer :: packobj
98  integer(I4B), intent(in) :: id
99  integer(I4B), intent(in) :: ibcnum
100  integer(I4B), intent(in) :: inunit
101  integer(I4B), intent(in) :: iout
102  character(len=*), intent(in) :: namemodel
103  character(len=*), intent(in) :: pakname
104  type(tspfmitype), pointer :: fmi
105  real(dp), intent(in), pointer :: eqnsclfac !< governing equation scale factor
106  type(gweinputdatatype), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages
107  character(len=*), intent(in) :: dvt !< For GWE, set to "TEMPERATURE" in TspAptType
108  character(len=*), intent(in) :: dvu !< For GWE, set to "energy" in TspAptType
109  character(len=*), intent(in) :: dvua !< For GWE, set to "E" in TspAptType
110  ! -- local
111  type(gwemwetype), pointer :: mweobj
112  !
113  ! -- Allocate the object and assign values to object variables
114  allocate (mweobj)
115  packobj => mweobj
116  !
117  ! -- Create name and memory path
118  call packobj%set_names(ibcnum, namemodel, pakname, ftype)
119  packobj%text = text
120  !
121  ! -- Allocate scalars
122  call mweobj%allocate_scalars()
123  !
124  ! -- Initialize package
125  call packobj%pack_initialize()
126  !
127  packobj%inunit = inunit
128  packobj%iout = iout
129  packobj%id = id
130  packobj%ibcnum = ibcnum
131  packobj%ncolbnd = 1
132  packobj%iscloc = 1
133  !
134  ! -- Store pointer to flow model interface. When the GwfGwe exchange is
135  ! created, it sets fmi%bndlist so that the GWE model has access to all
136  ! the flow packages
137  mweobj%fmi => fmi
138  !
139  ! -- Store pointer to governing equation scale factor
140  mweobj%eqnsclfac => eqnsclfac
141  !
142  ! -- Store pointer to shared data module for accessing cpw, rhow
143  ! for the budget calculations, and for accessing the latent heat of
144  ! vaporization for evaporative cooling.
145  mweobj%gwecommon => gwecommon
146  !
147  ! -- Set labels that will be used in generalized APT class
148  mweobj%depvartype = dvt
149  mweobj%depvarunit = dvu
150  mweobj%depvarunitabbrev = dvua
151  !
152  ! -- Return
153  return
154  end subroutine mwe_create
155 
156  !> @brief Find corresponding mwe package
157  !<
158  subroutine find_mwe_package(this)
159  ! -- modules
161  ! -- dummy
162  class(gwemwetype) :: 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 (mawtype)
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 this%parser%StoreErrorUnit()
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 ('RATE')
235  this%idxbudrate = ip
236  this%idxbudssm(ip) = 0
237  case ('FW-RATE')
238  this%idxbudfwrt = ip
239  this%idxbudssm(ip) = 0
240  case ('RATE-TO-MVR')
241  this%idxbudrtmv = ip
242  this%idxbudssm(ip) = 0
243  case ('FW-RATE-TO-MVR')
244  this%idxbudfrtm = ip
245  this%idxbudssm(ip) = 0
246  case ('TO-MVR')
247  this%idxbudtmvr = ip
248  this%idxbudssm(ip) = 0
249  case ('FROM-MVR')
250  this%idxbudfmvr = ip
251  this%idxbudssm(ip) = 0
252  case ('AUXILIARY')
253  this%idxbudaux = ip
254  this%idxbudssm(ip) = 0
255  case default
256  !
257  ! -- Set idxbudssm equal to a column index for where the temperatures
258  ! are stored in the tempbud(nbudssm, ncv) array
259  this%idxbudssm(ip) = icount
260  icount = icount + 1
261  end select
262  write (this%iout, '(a, i0, " = ", a,/, a, i0)') &
263  ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), &
264  ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist
265  end do
266  write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION'
267  !
268  ! -- Streambed conduction term
269  this%idxbudmwcd = this%idxbudgwf
270  !
271  ! -- Return
272  return
273  end subroutine find_mwe_package
274 
275  !> @brief Add matrix terms related to MWE
276  !!
277  !! This routine is called from TspAptType%apt_fc_expanded() in
278  !! order to add matrix terms specifically for MWE
279  !<
280  subroutine mwe_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
281  ! -- dummy
282  class(gwemwetype) :: 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, n, n1, n2
289  integer(I4B) :: iloc
290  integer(I4B) :: iposd, iposoffd
291  integer(I4B) :: ipossymd, ipossymoffd
292  integer(I4B) :: auxpos
293  real(DP) :: rrate
294  real(DP) :: rhsval
295  real(DP) :: hcofval
296  real(DP) :: ctherm ! kluge?
297  real(DP) :: wa !< wetted area
298  real(DP) :: ktf !< thermal conductivity of streambed material
299  real(DP) :: s !< thickness of conductive wellbore material
300  !
301  ! -- Add puping rate contribution
302  if (this%idxbudrate /= 0) then
303  do j = 1, this%flowbudptr%budterm(this%idxbudrate)%nlist
304  call this%mwe_rate_term(j, n1, n2, rrate, rhsval, hcofval)
305  iloc = this%idxlocnode(n1)
306  iposd = this%idxpakdiag(n1)
307  call matrix_sln%add_value_pos(iposd, hcofval)
308  rhs(iloc) = rhs(iloc) + rhsval
309  end do
310  end if
311  !
312  ! -- Add flowing well rate contribution
313  if (this%idxbudfwrt /= 0) then
314  do j = 1, this%flowbudptr%budterm(this%idxbudfwrt)%nlist
315  call this%mwe_fwrt_term(j, n1, n2, rrate, rhsval, hcofval)
316  iloc = this%idxlocnode(n1)
317  iposd = this%idxpakdiag(n1)
318  call matrix_sln%add_value_pos(iposd, hcofval)
319  rhs(iloc) = rhs(iloc) + rhsval
320  end do
321  end if
322  !
323  ! -- Add rate to mover contribution
324  if (this%idxbudrtmv /= 0) then
325  do j = 1, this%flowbudptr%budterm(this%idxbudrtmv)%nlist
326  call this%mwe_rtmv_term(j, n1, n2, rrate, rhsval, hcofval)
327  iloc = this%idxlocnode(n1)
328  iposd = this%idxpakdiag(n1)
329  call matrix_sln%add_value_pos(iposd, hcofval)
330  rhs(iloc) = rhs(iloc) + rhsval
331  end do
332  end if
333  !
334  ! -- Add puping rate contribution
335  if (this%idxbudfrtm /= 0) then
336  do j = 1, this%flowbudptr%budterm(this%idxbudfrtm)%nlist
337  call this%mwe_frtm_term(j, n1, n2, rrate, rhsval, hcofval)
338  iloc = this%idxlocnode(n1)
339  iposd = this%idxpakdiag(n1)
340  call matrix_sln%add_value_pos(iposd, hcofval)
341  rhs(iloc) = rhs(iloc) + rhsval
342  end do
343  end if
344  !
345  ! -- Add wellbore conduction contribution
346  do j = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist
347  !
348  ! -- Set n to feature number and process if active features
349  n = this%flowbudptr%budterm(this%idxbudgwf)%id1(j)
350  if (this%iboundpak(n) /= 0) then
351  !
352  ! -- Set acoef and rhs to negative so they are relative to mwe and not gwe
353  auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux
354  wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j)
355  ktf = this%ktf(n)
356  s = this%rfeatthk(n)
357  ctherm = ktf * wa / s
358  !
359  ! -- Add to mwe row
360  iposd = this%idxdglo(j)
361  iposoffd = this%idxoffdglo(j)
362  call matrix_sln%add_value_pos(iposd, -ctherm) ! kluge note: make sure the signs on ctherm are correct here and below
363  call matrix_sln%add_value_pos(iposoffd, ctherm)
364  !
365  ! -- Add to gwe row for mwe connection
366  ipossymd = this%idxsymdglo(j)
367  ipossymoffd = this%idxsymoffdglo(j)
368  call matrix_sln%add_value_pos(ipossymd, -ctherm)
369  call matrix_sln%add_value_pos(ipossymoffd, ctherm)
370  end if
371  end do
372  !
373  ! -- Return
374  return
375  end subroutine mwe_fc_expanded
376 
377  !> @brief Add terms specific to multi-aquifer wells to the explicit multi-
378  !! aquifer well energy transport solve
379  !<
380  subroutine mwe_solve(this)
381  ! -- dummy
382  class(gwemwetype) :: this
383  ! -- local
384  integer(I4B) :: j
385  integer(I4B) :: n1, n2
386  real(DP) :: rrate
387  !
388  ! -- Add well pumping contribution
389  if (this%idxbudrate /= 0) then
390  do j = 1, this%flowbudptr%budterm(this%idxbudrate)%nlist
391  call this%mwe_rate_term(j, n1, n2, rrate)
392  this%dbuff(n1) = this%dbuff(n1) + rrate
393  end do
394  end if
395  !
396  ! -- Add flowing well rate contribution
397  if (this%idxbudfwrt /= 0) then
398  do j = 1, this%flowbudptr%budterm(this%idxbudfwrt)%nlist
399  call this%mwe_fwrt_term(j, n1, n2, rrate)
400  this%dbuff(n1) = this%dbuff(n1) + rrate
401  end do
402  end if
403  !
404  ! -- Add well pumping rate to mover contribution
405  if (this%idxbudrtmv /= 0) then
406  do j = 1, this%flowbudptr%budterm(this%idxbudrtmv)%nlist
407  call this%mwe_rtmv_term(j, n1, n2, rrate)
408  this%dbuff(n1) = this%dbuff(n1) + rrate
409  end do
410  end if
411  !
412  ! -- Add flowing well rate to mover contribution
413  if (this%idxbudfrtm /= 0) then
414  do j = 1, this%flowbudptr%budterm(this%idxbudfrtm)%nlist
415  call this%mwe_frtm_term(j, n1, n2, rrate)
416  this%dbuff(n1) = this%dbuff(n1) + rrate
417  end do
418  end if
419  !
420  ! -- Return
421  return
422  end subroutine mwe_solve
423 
424  !> @brief Function to return the number of budget terms just for this package
425  !!
426  !! This overrides a function in the parent class.
427  !<
428  function mwe_get_nbudterms(this) result(nbudterms)
429  ! -- dummy
430  class(gwemwetype) :: this
431  ! -- return
432  integer(I4B) :: nbudterms
433  !
434  ! -- Number of potential budget terms is 5
435  nbudterms = 1 ! RATE
436  if (this%idxbudfwrt /= 0) nbudterms = nbudterms + 1
437  if (this%idxbudrtmv /= 0) nbudterms = nbudterms + 1
438  if (this%idxbudfrtm /= 0) nbudterms = nbudterms + 1
439  if (this%idxbudmwcd /= 0) nbudterms = nbudterms + 1
440  !
441  ! -- Return
442  return
443  end function mwe_get_nbudterms
444 
445  !> @brief Set up the budget object that stores all the mwe flows
446  !<
447  subroutine mwe_setup_budobj(this, idx)
448  ! -- modules
449  use constantsmodule, only: lenbudtxt
450  ! -- dummy
451  class(gwemwetype) :: this
452  integer(I4B), intent(inout) :: idx
453  ! -- local
454  integer(I4B) :: n, n1, n2
455  integer(I4B) :: maxlist, naux
456  real(DP) :: q
457  character(len=LENBUDTXT) :: text
458  !
459  ! -- User-specified rate
460  text = ' RATE'
461  idx = idx + 1
462  maxlist = this%flowbudptr%budterm(this%idxbudrate)%maxlist
463  naux = 0
464  call this%budobj%budterm(idx)%initialize(text, &
465  this%name_model, &
466  this%packName, &
467  this%name_model, &
468  this%packName, &
469  maxlist, .false., .false., &
470  naux)
471  !
472  ! -- Flowing well rate
473  if (this%idxbudfwrt /= 0) then
474  text = ' FW-RATE'
475  idx = idx + 1
476  maxlist = this%flowbudptr%budterm(this%idxbudfwrt)%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  end if
486  !
487  ! -- User-specified flow rate to mover
488  if (this%idxbudrtmv /= 0) then
489  text = ' RATE-TO-MVR'
490  idx = idx + 1
491  maxlist = this%flowbudptr%budterm(this%idxbudrtmv)%maxlist
492  naux = 0
493  call this%budobj%budterm(idx)%initialize(text, &
494  this%name_model, &
495  this%packName, &
496  this%name_model, &
497  this%packName, &
498  maxlist, .false., .false., &
499  naux)
500  end if
501  !
502  ! -- Fflowing well rate to mover
503  if (this%idxbudfrtm /= 0) then
504  text = ' FW-RATE-TO-MVR'
505  idx = idx + 1
506  maxlist = this%flowbudptr%budterm(this%idxbudfrtm)%maxlist
507  naux = 0
508  call this%budobj%budterm(idx)%initialize(text, &
509  this%name_model, &
510  this%packName, &
511  this%name_model, &
512  this%packName, &
513  maxlist, .false., .false., &
514  naux)
515  end if
516  !
517  ! -- Conduction through wellbore (and/or filter pack)
518  text = ' WELLBORE-COND'
519  idx = idx + 1
520  maxlist = this%flowbudptr%budterm(this%idxbudmwcd)%maxlist
521  naux = 0
522  call this%budobj%budterm(idx)%initialize(text, &
523  this%name_model, &
524  this%packName, &
525  this%name_model, &
526  this%packName, &
527  maxlist, .false., .false., &
528  naux)
529  call this%budobj%budterm(idx)%reset(maxlist)
530  q = dzero
531  do n = 1, maxlist
532  n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(n)
533  n2 = this%flowbudptr%budterm(this%idxbudgwf)%id2(n)
534  call this%budobj%budterm(idx)%update_term(n1, n2, q)
535  end do
536  !
537  ! -- Return
538  return
539  end subroutine mwe_setup_budobj
540 
541  !> @brief Copy flow terms into this%budobj
542  !<
543  subroutine mwe_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
544  ! -- dummy
545  class(gwemwetype) :: this
546  integer(I4B), intent(inout) :: idx
547  real(DP), dimension(:), intent(in) :: x
548  real(DP), dimension(:), contiguous, intent(inout) :: flowja
549  real(DP), intent(inout) :: ccratin
550  real(DP), intent(inout) :: ccratout
551  ! -- local
552  integer(I4B) :: j, n1, n2
553  integer(I4B) :: nlist
554  integer(I4B) :: igwfnode
555  integer(I4B) :: idiag
556  integer(I4B) :: auxpos
557  real(DP) :: q
558  real(DP) :: ctherm
559  real(DP) :: wa !< wetted area
560  real(DP) :: ktf !< thermal conductivity of streambed material
561  real(DP) :: s !< thickness of conductive streambed materia
562  !
563  ! -- Rate
564  idx = idx + 1
565  nlist = this%flowbudptr%budterm(this%idxbudrate)%nlist
566  call this%budobj%budterm(idx)%reset(nlist)
567  do j = 1, nlist
568  call this%mwe_rate_term(j, n1, n2, q)
569  call this%budobj%budterm(idx)%update_term(n1, n2, q)
570  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
571  end do
572  !
573  ! -- FW-Rate
574  if (this%idxbudfwrt /= 0) then
575  idx = idx + 1
576  nlist = this%flowbudptr%budterm(this%idxbudfwrt)%nlist
577  call this%budobj%budterm(idx)%reset(nlist)
578  do j = 1, nlist
579  call this%mwe_fwrt_term(j, n1, n2, q)
580  call this%budobj%budterm(idx)%update_term(n1, n2, q)
581  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
582  end do
583  end if
584  !
585  ! -- Rate-To-MVR
586  if (this%idxbudrtmv /= 0) then
587  idx = idx + 1
588  nlist = this%flowbudptr%budterm(this%idxbudrtmv)%nlist
589  call this%budobj%budterm(idx)%reset(nlist)
590  do j = 1, nlist
591  call this%mwe_rtmv_term(j, n1, n2, q)
592  call this%budobj%budterm(idx)%update_term(n1, n2, q)
593  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
594  end do
595  end if
596  !
597  ! -- FW-Rate-To-MVR
598  if (this%idxbudfrtm /= 0) then
599  idx = idx + 1
600  nlist = this%flowbudptr%budterm(this%idxbudfrtm)%nlist
601  call this%budobj%budterm(idx)%reset(nlist)
602  do j = 1, nlist
603  call this%mwe_frtm_term(j, n1, n2, q)
604  call this%budobj%budterm(idx)%update_term(n1, n2, q)
605  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
606  end do
607  end if
608  !
609  ! -- Wellbore-Cond
610  idx = idx + 1
611  call this%budobj%budterm(idx)%reset(this%maxbound)
612  do j = 1, this%flowbudptr%budterm(this%idxbudmwcd)%nlist
613  q = dzero
614  n1 = this%flowbudptr%budterm(this%idxbudmwcd)%id1(j)
615  if (this%iboundpak(n1) /= 0) then
616  igwfnode = this%flowbudptr%budterm(this%idxbudmwcd)%id2(j)
617  auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux
618  wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j)
619  ktf = this%ktf(n1)
620  s = this%rfeatthk(n1)
621  ctherm = ktf * wa / s
622  q = ctherm * (x(igwfnode) - this%xnewpak(n1))
623  end if
624  call this%budobj%budterm(idx)%update_term(n1, igwfnode, q)
625  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
626  if (this%iboundpak(n1) /= 0) then
627  ! -- Contribution to gwe cell budget
628  this%simvals(j) = this%simvals(j) - q
629  idiag = this%dis%con%ia(igwfnode)
630  flowja(idiag) = flowja(idiag) - q
631  end if
632  end do
633  !
634  ! -- Return
635  return
636  end subroutine mwe_fill_budobj
637 
638  !> @brief Allocate scalars specific to the multi-aquifer well energy
639  !! transport (MWE) package.
640  !<
641  subroutine allocate_scalars(this)
642  ! -- modules
644  ! -- dummy
645  class(gwemwetype) :: this
646  !
647  ! -- Allocate scalars in TspAptType
648  call this%TspAptType%allocate_scalars()
649  !
650  ! -- Allocate
651  call mem_allocate(this%idxbudrate, 'IDXBUDRATE', this%memoryPath)
652  call mem_allocate(this%idxbudfwrt, 'IDXBUDFWRT', this%memoryPath)
653  call mem_allocate(this%idxbudrtmv, 'IDXBUDRTMV', this%memoryPath)
654  call mem_allocate(this%idxbudfrtm, 'IDXBUDFRTM', this%memoryPath)
655  call mem_allocate(this%idxbudmwcd, 'IDXBUDMWCD', this%memoryPath)
656  !
657  ! -- Initialize
658  this%idxbudrate = 0
659  this%idxbudfwrt = 0
660  this%idxbudrtmv = 0
661  this%idxbudfrtm = 0
662  this%idxbudmwcd = 0
663  !
664  ! -- Return
665  return
666  end subroutine allocate_scalars
667 
668  !> @brief Allocate arrays specific to the streamflow mass transport (SFT)
669  !! package
670  !<
671  subroutine mwe_allocate_arrays(this)
672  ! -- modules
674  ! -- dummy
675  class(gwemwetype), intent(inout) :: this
676  ! -- local
677  integer(I4B) :: n
678  !
679  ! -- Time series
680  call mem_allocate(this%temprate, this%ncv, 'TEMPRATE', this%memoryPath)
681  !
682  ! -- Call standard TspAptType allocate arrays
683  call this%TspAptType%apt_allocate_arrays()
684  !
685  ! -- Initialize
686  do n = 1, this%ncv
687  this%temprate(n) = dzero
688  end do
689  !
690  ! -- Return
691  return
692  end subroutine mwe_allocate_arrays
693 
694  !> @brief Deallocate memory associated with MWE package
695  !<
696  subroutine mwe_da(this)
697  ! -- modules
699  ! -- dummy
700  class(gwemwetype) :: this
701  !
702  ! -- Deallocate scalars
703  call mem_deallocate(this%idxbudrate)
704  call mem_deallocate(this%idxbudfwrt)
705  call mem_deallocate(this%idxbudrtmv)
706  call mem_deallocate(this%idxbudfrtm)
707  call mem_deallocate(this%idxbudmwcd)
708  !
709  ! -- Deallocate time series
710  call mem_deallocate(this%temprate)
711  !
712  ! -- Deallocate scalars in TspAptType
713  call this%TspAptType%bnd_da()
714  !
715  ! -- Return
716  return
717  end subroutine mwe_da
718 
719  !> @brief Thermal transport matrix term(s) associated with a user-specified
720  !! flow rate (mwe_rate_term)
721  !<
722  subroutine mwe_rate_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
723  ! -- dummy
724  class(gwemwetype) :: this
725  integer(I4B), intent(in) :: ientry
726  integer(I4B), intent(inout) :: n1
727  integer(I4B), intent(inout) :: n2
728  real(DP), intent(inout), optional :: rrate
729  real(DP), intent(inout), optional :: rhsval
730  real(DP), intent(inout), optional :: hcofval
731  ! -- local
732  real(DP) :: qbnd
733  real(DP) :: ctmp
734  real(DP) :: h, r
735  !
736  n1 = this%flowbudptr%budterm(this%idxbudrate)%id1(ientry)
737  n2 = this%flowbudptr%budterm(this%idxbudrate)%id2(ientry)
738  ! -- Note that qbnd is negative for an extracting well
739  qbnd = this%flowbudptr%budterm(this%idxbudrate)%flow(ientry)
740  if (qbnd < dzero) then
741  ctmp = this%xnewpak(n1)
742  h = qbnd
743  r = dzero
744  else
745  ctmp = this%temprate(n1)
746  h = dzero
747  r = -qbnd * ctmp
748  end if
749  if (present(rrate)) rrate = qbnd * ctmp * this%eqnsclfac
750  if (present(rhsval)) rhsval = r * this%eqnsclfac
751  if (present(hcofval)) hcofval = h * this%eqnsclfac
752  !
753  ! -- Return
754  return
755  end subroutine mwe_rate_term
756 
757  !> @brief Thermal transport matrix term(s) associated with a flowing-
758  !! well rate term associated with pumping (or injection)
759  !<
760  subroutine mwe_fwrt_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
761  ! -- dummy
762  class(gwemwetype) :: this
763  integer(I4B), intent(in) :: ientry
764  integer(I4B), intent(inout) :: n1
765  integer(I4B), intent(inout) :: n2
766  real(DP), intent(inout), optional :: rrate
767  real(DP), intent(inout), optional :: rhsval
768  real(DP), intent(inout), optional :: hcofval
769  ! -- local
770  real(DP) :: qbnd
771  real(DP) :: ctmp
772  !
773  n1 = this%flowbudptr%budterm(this%idxbudfwrt)%id1(ientry)
774  n2 = this%flowbudptr%budterm(this%idxbudfwrt)%id2(ientry)
775  qbnd = this%flowbudptr%budterm(this%idxbudfwrt)%flow(ientry)
776  ctmp = this%xnewpak(n1)
777  if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac
778  if (present(rhsval)) rhsval = dzero
779  if (present(hcofval)) hcofval = qbnd * this%eqnsclfac
780  !
781  ! -- Return
782  return
783  end subroutine mwe_fwrt_term
784 
785  !> @brief Thermal transport matrix term(s) associated with pumped-water-
786  !! to-mover term (mwe_rtmv_term)
787  !<
788  subroutine mwe_rtmv_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
789  ! -- dummy
790  class(gwemwetype) :: this
791  integer(I4B), intent(in) :: ientry
792  integer(I4B), intent(inout) :: n1
793  integer(I4B), intent(inout) :: n2
794  real(DP), intent(inout), optional :: rrate
795  real(DP), intent(inout), optional :: rhsval
796  real(DP), intent(inout), optional :: hcofval
797  ! -- local
798  real(DP) :: qbnd
799  real(DP) :: ctmp
800  !
801  n1 = this%flowbudptr%budterm(this%idxbudrtmv)%id1(ientry)
802  n2 = this%flowbudptr%budterm(this%idxbudrtmv)%id2(ientry)
803  qbnd = this%flowbudptr%budterm(this%idxbudrtmv)%flow(ientry)
804  ctmp = this%xnewpak(n1)
805  if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac
806  if (present(rhsval)) rhsval = dzero
807  if (present(hcofval)) hcofval = qbnd * this%eqnsclfac
808  !
809  ! -- Return
810  return
811  end subroutine mwe_rtmv_term
812 
813  !> @brief Thermal transport matrix term(s) associated with the flowing-
814  !! well-rate-to-mover term (mwe_frtm_term)
815  !<
816  subroutine mwe_frtm_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
817  ! -- dummy
818  class(gwemwetype) :: this
819  integer(I4B), intent(in) :: ientry
820  integer(I4B), intent(inout) :: n1
821  integer(I4B), intent(inout) :: n2
822  real(DP), intent(inout), optional :: rrate
823  real(DP), intent(inout), optional :: rhsval
824  real(DP), intent(inout), optional :: hcofval
825  ! -- local
826  real(DP) :: qbnd
827  real(DP) :: ctmp
828  !
829  n1 = this%flowbudptr%budterm(this%idxbudfrtm)%id1(ientry)
830  n2 = this%flowbudptr%budterm(this%idxbudfrtm)%id2(ientry)
831  qbnd = this%flowbudptr%budterm(this%idxbudfrtm)%flow(ientry)
832  ctmp = this%xnewpak(n1)
833  if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac
834  if (present(rhsval)) rhsval = dzero
835  if (present(hcofval)) hcofval = qbnd * this%eqnsclfac
836  !
837  ! -- Return
838  return
839  end subroutine mwe_frtm_term
840 
841  !> @brief Observations
842  !!
843  !! Store the observation type supported by the APT package and override
844  !! BndType%bnd_df_obs
845  !<
846  subroutine mwe_df_obs(this)
847  ! -- dummy
848  class(gwemwetype) :: this
849  ! -- local
850  integer(I4B) :: indx
851  !
852  ! -- Store obs type and assign procedure pointer
853  ! for temperature observation type.
854  call this%obs%StoreObsType('temperature', .false., indx)
855  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
856  !
857  ! -- Flow-ja-face not supported for MWE
858  !call this%obs%StoreObsType('flow-ja-face', .true., indx)
859  !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID
860  !
861  ! -- Store obs type and assign procedure pointer
862  ! for from-mvr observation type.
863  call this%obs%StoreObsType('from-mvr', .true., indx)
864  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
865  !
866  ! -- To-mvr not supported for mwe
867  !call this%obs%StoreObsType('to-mvr', .true., indx)
868  !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID
869  !
870  ! -- Store obs type and assign procedure pointer
871  ! for storage observation type.
872  call this%obs%StoreObsType('storage', .true., indx)
873  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
874  !
875  ! -- Store obs type and assign procedure pointer
876  ! for constant observation type.
877  call this%obs%StoreObsType('constant', .true., indx)
878  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
879  !
880  ! -- Store obs type and assign procedure pointer
881  ! for observation type: mwe
882  call this%obs%StoreObsType('mwe', .true., indx)
883  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid12
884  !
885  ! -- Store obs type and assign procedure pointer
886  ! for rate observation type.
887  call this%obs%StoreObsType('rate', .true., indx)
888  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
889  !
890  ! -- Store obs type and assign procedure pointer
891  ! for observation type.
892  call this%obs%StoreObsType('fw-rate', .true., indx)
893  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
894  !
895  ! -- Store obs type and assign procedure pointer
896  ! for observation type.
897  call this%obs%StoreObsType('rate-to-mvr', .true., indx)
898  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
899  !
900  ! -- Store obs type and assign procedure pointer
901  ! for observation type.
902  call this%obs%StoreObsType('fw-rate-to-mvr', .true., indx)
903  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
904  !
905  ! -- Return
906  return
907  end subroutine mwe_df_obs
908 
909  !> @brief Process package specific obs
910  !!
911  !! Method to process specific observations for this package.
912  !<
913  subroutine mwe_rp_obs(this, obsrv, found)
914  ! -- dummy
915  class(gwemwetype), intent(inout) :: this !< package class
916  type(observetype), intent(inout) :: obsrv !< observation object
917  logical, intent(inout) :: found !< indicate whether observation was found
918  !
919  found = .true.
920  select case (obsrv%ObsTypeId)
921  case ('RATE')
922  call this%rp_obs_byfeature(obsrv)
923  case ('FW-RATE')
924  call this%rp_obs_byfeature(obsrv)
925  case ('RATE-TO-MVR')
926  call this%rp_obs_byfeature(obsrv)
927  case ('FW-RATE-TO-MVR')
928  call this%rp_obs_byfeature(obsrv)
929  case default
930  found = .false.
931  end select
932  !
933  ! -- Return
934  return
935  end subroutine mwe_rp_obs
936 
937  !> @brief Calculate observation value and pass it back to APT
938  !<
939  subroutine mwe_bd_obs(this, obstypeid, jj, v, found)
940  ! -- dummy
941  class(gwemwetype), intent(inout) :: this
942  character(len=*), intent(in) :: obstypeid
943  real(DP), intent(inout) :: v
944  integer(I4B), intent(in) :: jj
945  logical, intent(inout) :: found
946  ! -- local
947  integer(I4B) :: n1, n2
948  !
949  found = .true.
950  select case (obstypeid)
951  case ('RATE')
952  if (this%iboundpak(jj) /= 0) then
953  call this%mwe_rate_term(jj, n1, n2, v)
954  end if
955  case ('FW-RATE')
956  if (this%iboundpak(jj) /= 0 .and. this%idxbudfwrt > 0) then
957  call this%mwe_fwrt_term(jj, n1, n2, v)
958  end if
959  case ('RATE-TO-MVR')
960  if (this%iboundpak(jj) /= 0 .and. this%idxbudrtmv > 0) then
961  call this%mwe_rtmv_term(jj, n1, n2, v)
962  end if
963  case ('FW-RATE-TO-MVR')
964  if (this%iboundpak(jj) /= 0 .and. this%idxbudfrtm > 0) then
965  call this%mwe_frtm_term(jj, n1, n2, v)
966  end if
967  case default
968  found = .false.
969  end select
970  !
971  ! -- Return
972  return
973  end subroutine mwe_bd_obs
974 
975  !> @brief Sets the stress period attributes for keyword use.
976  !<
977  subroutine mwe_set_stressperiod(this, itemno, keyword, found)
978  ! -- modules
980  ! -- dummy
981  class(gwemwetype), intent(inout) :: this
982  integer(I4B), intent(in) :: itemno
983  character(len=*), intent(in) :: keyword
984  logical, intent(inout) :: found
985  ! -- local
986  character(len=LINELENGTH) :: text
987  integer(I4B) :: ierr
988  integer(I4B) :: jj
989  real(DP), pointer :: bndElem => null()
990  !
991  ! RATE <rate>
992  !
993  found = .true.
994  select case (keyword)
995  case ('RATE')
996  ierr = this%apt_check_valid(itemno)
997  if (ierr /= 0) then
998  goto 999
999  end if
1000  call this%parser%GetString(text)
1001  jj = 1
1002  bndelem => this%temprate(itemno)
1003  call read_value_or_time_series_adv(text, itemno, jj, bndelem, &
1004  this%packName, 'BND', this%tsManager, &
1005  this%iprpak, 'RATE')
1006  case default
1007  !
1008  ! -- Keyword not recognized so return to caller with found = .false.
1009  found = .false.
1010  end select
1011  !
1012 999 continue
1013  !
1014  ! -- Return
1015  return
1016  end subroutine mwe_set_stressperiod
1017 
1018 end module gwemwemodule
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:44
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:64
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
Definition: Constants.f90:36
subroutine allocate_scalars(this)
Allocate scalars specific to the multi-aquifer well energy transport (MWE) package.
Definition: gwe-mwe.f90:642
character(len= *), parameter flowtype
Definition: gwe-mwe.f90:54
subroutine mwe_rp_obs(this, obsrv, found)
Process package specific obs.
Definition: gwe-mwe.f90:914
subroutine mwe_rtmv_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Thermal transport matrix term(s) associated with pumped-water- to-mover term (mwe_rtmv_term)
Definition: gwe-mwe.f90:789
subroutine mwe_allocate_arrays(this)
Allocate arrays specific to the streamflow mass transport (SFT) package.
Definition: gwe-mwe.f90:672
subroutine, public mwe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi, eqnsclfac, gwecommon, dvt, dvu, dvua)
Create new MWE package.
Definition: gwe-mwe.f90:96
subroutine mwe_bd_obs(this, obstypeid, jj, v, found)
Calculate observation value and pass it back to APT.
Definition: gwe-mwe.f90:940
subroutine find_mwe_package(this)
Find corresponding mwe package.
Definition: gwe-mwe.f90:159
subroutine mwe_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
Copy flow terms into thisbudobj.
Definition: gwe-mwe.f90:544
character(len= *), parameter ftype
Definition: gwe-mwe.f90:53
character(len=16) text
Definition: gwe-mwe.f90:55
subroutine mwe_da(this)
Deallocate memory associated with MWE package.
Definition: gwe-mwe.f90:697
subroutine mwe_setup_budobj(this, idx)
Set up the budget object that stores all the mwe flows.
Definition: gwe-mwe.f90:448
integer(i4b) function mwe_get_nbudterms(this)
Function to return the number of budget terms just for this package.
Definition: gwe-mwe.f90:429
subroutine mwe_frtm_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Thermal transport matrix term(s) associated with the flowing- well-rate-to-mover term (mwe_frtm_term)
Definition: gwe-mwe.f90:817
subroutine mwe_solve(this)
Add terms specific to multi-aquifer wells to the explicit multi- aquifer well energy transport solve.
Definition: gwe-mwe.f90:381
subroutine mwe_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
Add matrix terms related to MWE.
Definition: gwe-mwe.f90:281
subroutine mwe_set_stressperiod(this, itemno, keyword, found)
Sets the stress period attributes for keyword use.
Definition: gwe-mwe.f90:978
subroutine mwe_fwrt_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Thermal transport matrix term(s) associated with a flowing- well rate term associated with pumping (o...
Definition: gwe-mwe.f90:761
subroutine mwe_rate_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
Thermal transport matrix term(s) associated with a user-specified flow rate (mwe_rate_term)
Definition: gwe-mwe.f90:723
subroutine mwe_df_obs(this)
Observations.
Definition: gwe-mwe.f90:847
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 read_value_or_time_series_adv(textInput, ii, jj, bndElem, pkgName, auxOrBnd, tsManager, iprpak, varName)
Call this subroutine from advanced packages to define timeseries link for a variable (varName).
subroutine, public apt_process_obsid(obsrv, dis, inunitobs, iout)
Process observation IDs for an advanced package.
Definition: tsp-apt.f90:2998
subroutine, public apt_process_obsid12(obsrv, dis, inunitobs, iout)
Process observation IDs for a package.
Definition: tsp-apt.f90:3044
@ brief BndType
Data for sharing among multiple packages. Originally read in from.