MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
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
43  use simvariablesmodule, only: errmsg
45  use bndmodule, only: bndtype, getbndfromlist
46  use tspfmimodule, only: tspfmitype
47  use mawmodule, only: mawtype
48  use observemodule, only: observetype
53 
54  implicit none
55 
56  public mwe_create
57 
58  character(len=*), parameter :: ftype = 'MWE'
59  character(len=*), parameter :: flowtype = 'MAW'
60  character(len=16) :: text = ' MWE'
61 
62  type, extends(tspapttype) :: gwemwetype
63 
64  type(gweinputdatatype), pointer :: gwecommon => null() !< pointer to shared gwe data used by multiple packages but set in mst
65 
66  integer(I4B), pointer :: idxbudrate => null() ! index of well rate terms in flowbudptr
67  integer(I4B), pointer :: idxbudfwrt => null() ! index of flowing well rate terms in flowbudptr
68  integer(I4B), pointer :: idxbudrtmv => null() ! index of rate to mover terms in flowbudptr
69  integer(I4B), pointer :: idxbudfrtm => null() ! index of flowing well rate to mover terms in flowbudptr
70  integer(I4B), pointer :: idxbudmwcd => null() ! index of well bore conduction terms in flowbudptr
71  real(dp), dimension(:), pointer, contiguous :: ktf => null() !< thermal conductivity between the sfe and groundwater cell
72  real(dp), dimension(:), pointer, contiguous :: rfeatthk => null() !< thickness of streambed material through which thermal conduction occurs
73  real(dp), dimension(:), pointer, contiguous :: temprate => null() ! well rate temperature
74 
75  contains
76 
77  procedure :: bnd_da => mwe_da
78  procedure :: allocate_scalars
79  procedure :: apt_allocate_arrays => mwe_allocate_arrays
80  procedure :: apt_source_cvs => mwe_read_cvs
81  procedure :: find_apt_package => find_mwe_package
82  procedure :: apt_setting_value => mwe_setting_value
83  procedure :: pak_fc_expanded => mwe_fc_expanded
84  procedure :: pak_solve => mwe_solve
85  procedure :: pak_get_nbudterms => mwe_get_nbudterms
86  procedure :: pak_setup_budobj => mwe_setup_budobj
87  procedure :: pak_fill_budobj => mwe_fill_budobj
88  procedure :: mwe_rate_term
89  procedure :: mwe_fwrt_term
90  procedure :: mwe_rtmv_term
91  procedure :: mwe_frtm_term
92  procedure :: pak_df_obs => mwe_df_obs
93  procedure :: pak_rp_obs => mwe_rp_obs
94  procedure :: pak_bd_obs => mwe_bd_obs
95 
96  end type gwemwetype
97 
98 contains
99 
100  !> Create new MWE package
101  !<
102  subroutine mwe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, &
103  mempath, fmi, eqnsclfac, gwecommon, dvt, dvu, dvua)
104  ! -- dummy
105  class(bndtype), pointer :: packobj
106  integer(I4B), intent(in) :: id
107  integer(I4B), intent(in) :: ibcnum
108  integer(I4B), intent(in) :: inunit
109  integer(I4B), intent(in) :: iout
110  character(len=*), intent(in) :: namemodel
111  character(len=*), intent(in) :: pakname
112  character(len=*), intent(in) :: mempath !< input memory path
113  type(tspfmitype), pointer :: fmi
114  real(dp), intent(in), pointer :: eqnsclfac !< governing equation scale factor
115  type(gweinputdatatype), intent(in), target :: gwecommon !< shared data container for use by multiple GWE packages
116  character(len=*), intent(in) :: dvt !< For GWE, set to "TEMPERATURE" in TspAptType
117  character(len=*), intent(in) :: dvu !< For GWE, set to "energy" in TspAptType
118  character(len=*), intent(in) :: dvua !< For GWE, set to "E" in TspAptType
119  ! -- local
120  type(gwemwetype), pointer :: mweobj
121  !
122  ! -- Allocate the object and assign values to object variables
123  allocate (mweobj)
124  packobj => mweobj
125  !
126  ! -- Create name and memory path
127  call packobj%set_names(ibcnum, namemodel, pakname, ftype, mempath)
128  packobj%text = text
129  !
130  ! -- Allocate scalars
131  call mweobj%allocate_scalars()
132  !
133  ! -- Initialize package
134  call packobj%pack_initialize()
135  !
136  packobj%inunit = inunit
137  packobj%iout = iout
138  packobj%id = id
139  packobj%ibcnum = ibcnum
140  packobj%ncolbnd = 1
141  packobj%iscloc = 1
142  packobj%isadvpak = 1
143  !
144  ! -- Store pointer to flow model interface. When the GwfGwe exchange is
145  ! created, it sets fmi%bndlist so that the GWE model has access to all
146  ! the flow packages
147  mweobj%fmi => fmi
148  !
149  ! -- Store pointer to governing equation scale factor
150  mweobj%eqnsclfac => eqnsclfac
151  !
152  ! -- Store pointer to shared data module for accessing cpw, rhow
153  ! for the budget calculations, and for accessing the latent heat of
154  ! vaporization for evaporative cooling.
155  mweobj%gwecommon => gwecommon
156  !
157  ! -- Set labels that will be used in generalized APT class
158  mweobj%depvartype = dvt
159  mweobj%depvarunit = dvu
160  mweobj%depvarunitabbrev = dvua
161  end subroutine mwe_create
162 
163  !> @brief Find corresponding mwe package
164  !<
165  subroutine find_mwe_package(this)
166  ! -- modules
168  ! -- dummy
169  class(gwemwetype) :: this
170  ! -- local
171  character(len=LINELENGTH) :: errmsg
172  class(bndtype), pointer :: packobj
173  integer(I4B) :: ip, icount
174  integer(I4B) :: nbudterm
175  logical :: found
176  !
177  ! -- Initialize found to false, and error later if flow package cannot
178  ! be found
179  found = .false.
180  !
181  ! -- If user is specifying flows in a binary budget file, then set up
182  ! the budget file reader, otherwise set a pointer to the flow package
183  ! budobj
184  if (this%fmi%flows_from_file) then
185  call this%fmi%set_aptbudobj_pointer(this%flowpackagename, this%flowbudptr)
186  if (associated(this%flowbudptr)) found = .true.
187  !
188  else
189  if (associated(this%fmi%gwfbndlist)) then
190  ! -- Look through gwfbndlist for a flow package with the same name as
191  ! this transport package name
192  do ip = 1, this%fmi%gwfbndlist%Count()
193  packobj => getbndfromlist(this%fmi%gwfbndlist, ip)
194  if (packobj%packName == this%flowpackagename) then
195  found = .true.
196  !
197  ! -- Store BndType pointer to packobj, and then
198  ! use the select type to point to the budobj in flow package
199  this%flowpackagebnd => packobj
200  select type (packobj)
201  type is (mawtype)
202  this%flowbudptr => packobj%budobj
203  end select
204  end if
205  if (found) exit
206  end do
207  end if
208  end if
209  !
210  ! -- Error if flow package not found
211  if (.not. found) then
212  write (errmsg, '(a)') 'Could not find flow package with name '&
213  &//trim(adjustl(this%flowpackagename))//'.'
214  call store_error(errmsg)
215  call store_error_filename(this%input_fname)
216  end if
217  !
218  ! -- Allocate space for idxbudssm, which indicates whether this is a
219  ! special budget term or one that is a general source and sink
220  nbudterm = this%flowbudptr%nbudterm
221  call mem_allocate(this%idxbudssm, nbudterm, 'IDXBUDSSM', this%memoryPath)
222  !
223  ! -- Process budget terms and identify special budget terms
224  write (this%iout, '(/, a, a)') &
225  'PROCESSING '//ftype//' INFORMATION FOR ', this%packName
226  write (this%iout, '(a)') ' IDENTIFYING FLOW TERMS IN '//flowtype//' PACKAGE'
227  write (this%iout, '(a, i0)') &
228  ' NUMBER OF '//flowtype//' = ', this%flowbudptr%ncv
229  icount = 1
230  do ip = 1, this%flowbudptr%nbudterm
231  select case (trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)))
232  case ('FLOW-JA-FACE')
233  this%idxbudfjf = ip
234  this%idxbudssm(ip) = 0
235  case ('GWF')
236  this%idxbudgwf = ip
237  this%idxbudssm(ip) = 0
238  case ('STORAGE')
239  this%idxbudsto = ip
240  this%idxbudssm(ip) = 0
241  case ('RATE')
242  this%idxbudrate = ip
243  this%idxbudssm(ip) = 0
244  case ('FW-RATE')
245  this%idxbudfwrt = ip
246  this%idxbudssm(ip) = 0
247  case ('RATE-TO-MVR')
248  this%idxbudrtmv = ip
249  this%idxbudssm(ip) = 0
250  case ('FW-RATE-TO-MVR')
251  this%idxbudfrtm = ip
252  this%idxbudssm(ip) = 0
253  case ('TO-MVR')
254  this%idxbudtmvr = ip
255  this%idxbudssm(ip) = 0
256  case ('FROM-MVR')
257  this%idxbudfmvr = ip
258  this%idxbudssm(ip) = 0
259  case ('AUXILIARY')
260  this%idxbudaux = ip
261  this%idxbudssm(ip) = 0
262  case default
263  !
264  ! -- Set idxbudssm equal to a column index for where the temperatures
265  ! are stored in the tempbud(nbudssm, ncv) array
266  this%idxbudssm(ip) = icount
267  icount = icount + 1
268  end select
269  write (this%iout, '(a, i0, " = ", a,/, a, i0)') &
270  ' TERM ', ip, trim(adjustl(this%flowbudptr%budterm(ip)%flowtype)), &
271  ' MAX NO. OF ENTRIES = ', this%flowbudptr%budterm(ip)%maxlist
272  end do
273  write (this%iout, '(a, //)') 'DONE PROCESSING '//ftype//' INFORMATION'
274  !
275  ! -- Streambed conduction term
276  this%idxbudmwcd = this%idxbudgwf
277  end subroutine find_mwe_package
278 
279  !> @brief Value for a package-specific PERIOD setting
280  !!
281  !! Already resolved by the input context; this only supplies it for
282  !! the shared apt_rp table echo.
283  !<
284  function mwe_setting_value(this, itemno, key) result(val)
285  ! -- dummy
286  class(gwemwetype), intent(inout) :: this
287  integer(I4B), intent(in) :: itemno
288  character(len=*), intent(in) :: key
289  real(dp) :: val
290  !
291  val = dzero
292  select case (trim(key))
293  case ('RATE')
294  val = this%temprate(itemno)
295  end select
296  end function mwe_setting_value
297 
298  !> @brief Add matrix terms related to MWE
299  !!
300  !! This routine is called from TspAptType%apt_fc_expanded() in
301  !! order to add matrix terms specifically for MWE
302  !<
303  subroutine mwe_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
304  ! -- dummy
305  class(gwemwetype) :: 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, n, n1, n2
312  integer(I4B) :: iloc
313  integer(I4B) :: iposd, iposoffd
314  integer(I4B) :: ipossymd, ipossymoffd
315  integer(I4B) :: auxpos
316  real(DP) :: rrate
317  real(DP) :: rhsval
318  real(DP) :: hcofval
319  real(DP) :: ctherm ! kluge?
320  real(DP) :: wa !< wetted area
321  real(DP) :: ktf !< thermal conductivity of streambed material
322  real(DP) :: s !< thickness of conductive wellbore material
323  !
324  ! -- Add puping rate contribution
325  if (this%idxbudrate /= 0) then
326  do j = 1, this%flowbudptr%budterm(this%idxbudrate)%nlist
327  call this%mwe_rate_term(j, n1, n2, rrate, rhsval, hcofval)
328  iloc = this%idxlocnode(n1)
329  iposd = this%idxpakdiag(n1)
330  call matrix_sln%add_value_pos(iposd, hcofval)
331  rhs(iloc) = rhs(iloc) + rhsval
332  end do
333  end if
334  !
335  ! -- Add flowing well rate contribution
336  if (this%idxbudfwrt /= 0) then
337  do j = 1, this%flowbudptr%budterm(this%idxbudfwrt)%nlist
338  call this%mwe_fwrt_term(j, n1, n2, rrate, rhsval, hcofval)
339  iloc = this%idxlocnode(n1)
340  iposd = this%idxpakdiag(n1)
341  call matrix_sln%add_value_pos(iposd, hcofval)
342  rhs(iloc) = rhs(iloc) + rhsval
343  end do
344  end if
345  !
346  ! -- Add rate to mover contribution
347  if (this%idxbudrtmv /= 0) then
348  do j = 1, this%flowbudptr%budterm(this%idxbudrtmv)%nlist
349  call this%mwe_rtmv_term(j, n1, n2, rrate, rhsval, hcofval)
350  iloc = this%idxlocnode(n1)
351  iposd = this%idxpakdiag(n1)
352  call matrix_sln%add_value_pos(iposd, hcofval)
353  rhs(iloc) = rhs(iloc) + rhsval
354  end do
355  end if
356  !
357  ! -- Add puping rate contribution
358  if (this%idxbudfrtm /= 0) then
359  do j = 1, this%flowbudptr%budterm(this%idxbudfrtm)%nlist
360  call this%mwe_frtm_term(j, n1, n2, rrate, rhsval, hcofval)
361  iloc = this%idxlocnode(n1)
362  iposd = this%idxpakdiag(n1)
363  call matrix_sln%add_value_pos(iposd, hcofval)
364  rhs(iloc) = rhs(iloc) + rhsval
365  end do
366  end if
367  !
368  ! -- Add wellbore conduction contribution
369  do j = 1, this%flowbudptr%budterm(this%idxbudgwf)%nlist
370  !
371  ! -- Set n to feature number and process if active features
372  n = this%flowbudptr%budterm(this%idxbudgwf)%id1(j)
373  if (this%iboundpak(n) /= 0) then
374  !
375  ! -- Set acoef and rhs to negative so they are relative to mwe and not gwe
376  auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux
377  wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j)
378  ktf = this%ktf(n)
379  s = this%rfeatthk(n)
380  ctherm = ktf * wa / s
381  !
382  ! -- Add to mwe row
383  iposd = this%idxdglo(j)
384  iposoffd = this%idxoffdglo(j)
385  call matrix_sln%add_value_pos(iposd, -ctherm) ! kluge note: make sure the signs on ctherm are correct here and below
386  call matrix_sln%add_value_pos(iposoffd, ctherm)
387  !
388  ! -- Add to gwe row for mwe connection
389  ipossymd = this%idxsymdglo(j)
390  ipossymoffd = this%idxsymoffdglo(j)
391  call matrix_sln%add_value_pos(ipossymd, -ctherm)
392  call matrix_sln%add_value_pos(ipossymoffd, ctherm)
393  end if
394  end do
395  end subroutine mwe_fc_expanded
396 
397  !> @brief Add terms specific to multi-aquifer wells to the explicit multi-
398  !! aquifer well energy transport solve
399  !<
400  subroutine mwe_solve(this)
401  ! -- dummy
402  class(gwemwetype) :: this
403  ! -- local
404  integer(I4B) :: j
405  integer(I4B) :: n1, n2
406  real(DP) :: rrate
407  !
408  ! -- Add well pumping contribution
409  if (this%idxbudrate /= 0) then
410  do j = 1, this%flowbudptr%budterm(this%idxbudrate)%nlist
411  call this%mwe_rate_term(j, n1, n2, rrate)
412  this%dbuff(n1) = this%dbuff(n1) + rrate
413  end do
414  end if
415  !
416  ! -- Add flowing well rate contribution
417  if (this%idxbudfwrt /= 0) then
418  do j = 1, this%flowbudptr%budterm(this%idxbudfwrt)%nlist
419  call this%mwe_fwrt_term(j, n1, n2, rrate)
420  this%dbuff(n1) = this%dbuff(n1) + rrate
421  end do
422  end if
423  !
424  ! -- Add well pumping rate to mover contribution
425  if (this%idxbudrtmv /= 0) then
426  do j = 1, this%flowbudptr%budterm(this%idxbudrtmv)%nlist
427  call this%mwe_rtmv_term(j, n1, n2, rrate)
428  this%dbuff(n1) = this%dbuff(n1) + rrate
429  end do
430  end if
431  !
432  ! -- Add flowing well rate to mover contribution
433  if (this%idxbudfrtm /= 0) then
434  do j = 1, this%flowbudptr%budterm(this%idxbudfrtm)%nlist
435  call this%mwe_frtm_term(j, n1, n2, rrate)
436  this%dbuff(n1) = this%dbuff(n1) + rrate
437  end do
438  end if
439  end subroutine mwe_solve
440 
441  !> @brief Function to return the number of budget terms just for this package
442  !!
443  !! This overrides a function in the parent class.
444  !<
445  function mwe_get_nbudterms(this) result(nbudterms)
446  ! -- dummy
447  class(gwemwetype) :: this
448  ! -- return
449  integer(I4B) :: nbudterms
450  !
451  ! -- Number of potential budget terms is 5
452  nbudterms = 1 ! RATE
453  if (this%idxbudfwrt /= 0) nbudterms = nbudterms + 1
454  if (this%idxbudrtmv /= 0) nbudterms = nbudterms + 1
455  if (this%idxbudfrtm /= 0) nbudterms = nbudterms + 1
456  if (this%idxbudmwcd /= 0) nbudterms = nbudterms + 1
457  end function mwe_get_nbudterms
458 
459  !> @brief Set up the budget object that stores all the mwe flows
460  !<
461  subroutine mwe_setup_budobj(this, idx)
462  ! -- modules
463  use constantsmodule, only: lenbudtxt
464  ! -- dummy
465  class(gwemwetype) :: this
466  integer(I4B), intent(inout) :: idx
467  ! -- local
468  integer(I4B) :: n, n1, n2
469  integer(I4B) :: maxlist, naux
470  real(DP) :: q
471  character(len=LENBUDTXT) :: text
472  !
473  ! -- User-specified rate
474  text = ' RATE'
475  idx = idx + 1
476  maxlist = this%flowbudptr%budterm(this%idxbudrate)%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  ! -- Flowing well rate
487  if (this%idxbudfwrt /= 0) then
488  text = ' FW-RATE'
489  idx = idx + 1
490  maxlist = this%flowbudptr%budterm(this%idxbudfwrt)%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  end if
500  !
501  ! -- User-specified flow rate to mover
502  if (this%idxbudrtmv /= 0) then
503  text = ' RATE-TO-MVR'
504  idx = idx + 1
505  maxlist = this%flowbudptr%budterm(this%idxbudrtmv)%maxlist
506  naux = 0
507  call this%budobj%budterm(idx)%initialize(text, &
508  this%name_model, &
509  this%packName, &
510  this%name_model, &
511  this%packName, &
512  maxlist, .false., .false., &
513  naux)
514  end if
515  !
516  ! -- Fflowing well rate to mover
517  if (this%idxbudfrtm /= 0) then
518  text = ' FW-RATE-TO-MVR'
519  idx = idx + 1
520  maxlist = this%flowbudptr%budterm(this%idxbudfrtm)%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  end if
530  !
531  ! -- Conduction through wellbore (and/or filter pack)
532  text = ' WELLBORE-COND'
533  idx = idx + 1
534  maxlist = this%flowbudptr%budterm(this%idxbudmwcd)%maxlist
535  naux = 0
536  call this%budobj%budterm(idx)%initialize(text, &
537  this%name_model, &
538  this%packName, &
539  this%name_model, &
540  this%packName, &
541  maxlist, .false., .false., &
542  naux)
543  call this%budobj%budterm(idx)%reset(maxlist)
544  q = dzero
545  do n = 1, maxlist
546  n1 = this%flowbudptr%budterm(this%idxbudgwf)%id1(n)
547  n2 = this%flowbudptr%budterm(this%idxbudgwf)%id2(n)
548  call this%budobj%budterm(idx)%update_term(n1, n2, q)
549  end do
550  end subroutine mwe_setup_budobj
551 
552  !> @brief Copy flow terms into this%budobj
553  !<
554  subroutine mwe_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
555  ! -- dummy
556  class(gwemwetype) :: this
557  integer(I4B), intent(inout) :: idx
558  real(DP), dimension(:), intent(in) :: x
559  real(DP), dimension(:), contiguous, intent(inout) :: flowja
560  real(DP), intent(inout) :: ccratin
561  real(DP), intent(inout) :: ccratout
562  ! -- local
563  integer(I4B) :: j, n1, n2
564  integer(I4B) :: nlist
565  integer(I4B) :: igwfnode
566  integer(I4B) :: idiag
567  integer(I4B) :: auxpos
568  real(DP) :: q
569  real(DP) :: ctherm
570  real(DP) :: wa !< wetted area
571  real(DP) :: ktf !< thermal conductivity of streambed material
572  real(DP) :: s !< thickness of conductive streambed materia
573  !
574  ! -- Rate
575  idx = idx + 1
576  nlist = this%flowbudptr%budterm(this%idxbudrate)%nlist
577  call this%budobj%budterm(idx)%reset(nlist)
578  do j = 1, nlist
579  call this%mwe_rate_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  !
584  ! -- FW-Rate
585  if (this%idxbudfwrt /= 0) then
586  idx = idx + 1
587  nlist = this%flowbudptr%budterm(this%idxbudfwrt)%nlist
588  call this%budobj%budterm(idx)%reset(nlist)
589  do j = 1, nlist
590  call this%mwe_fwrt_term(j, n1, n2, q)
591  call this%budobj%budterm(idx)%update_term(n1, n2, q)
592  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
593  end do
594  end if
595  !
596  ! -- Rate-To-MVR
597  if (this%idxbudrtmv /= 0) then
598  idx = idx + 1
599  nlist = this%flowbudptr%budterm(this%idxbudrtmv)%nlist
600  call this%budobj%budterm(idx)%reset(nlist)
601  do j = 1, nlist
602  call this%mwe_rtmv_term(j, n1, n2, q)
603  call this%budobj%budterm(idx)%update_term(n1, n2, q)
604  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
605  end do
606  end if
607  !
608  ! -- FW-Rate-To-MVR
609  if (this%idxbudfrtm /= 0) then
610  idx = idx + 1
611  nlist = this%flowbudptr%budterm(this%idxbudfrtm)%nlist
612  call this%budobj%budterm(idx)%reset(nlist)
613  do j = 1, nlist
614  call this%mwe_frtm_term(j, n1, n2, q)
615  call this%budobj%budterm(idx)%update_term(n1, n2, q)
616  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
617  end do
618  end if
619  !
620  ! -- Wellbore-Cond
621  idx = idx + 1
622  call this%budobj%budterm(idx)%reset(this%maxbound)
623  do j = 1, this%flowbudptr%budterm(this%idxbudmwcd)%nlist
624  q = dzero
625  n1 = this%flowbudptr%budterm(this%idxbudmwcd)%id1(j)
626  igwfnode = this%flowbudptr%budterm(this%idxbudmwcd)%id2(j)
627  if (this%iboundpak(n1) /= 0) then
628  auxpos = this%flowbudptr%budterm(this%idxbudgwf)%naux
629  wa = this%flowbudptr%budterm(this%idxbudgwf)%auxvar(auxpos, j)
630  ktf = this%ktf(n1)
631  s = this%rfeatthk(n1)
632  ctherm = ktf * wa / s
633  q = ctherm * (x(igwfnode) - this%xnewpak(n1))
634  end if
635  call this%budobj%budterm(idx)%update_term(n1, igwfnode, q)
636  call this%apt_accumulate_ccterm(n1, q, ccratin, ccratout)
637  if (this%iboundpak(n1) /= 0) then
638  ! -- Contribution to gwe cell budget
639  this%simvals(j) = this%simvals(j) - q
640  idiag = this%dis%con%ia(igwfnode)
641  flowja(idiag) = flowja(idiag) - q
642  end if
643  end do
644  end subroutine mwe_fill_budobj
645 
646  !> @brief Allocate scalars specific to the multi-aquifer well energy
647  !! transport (MWE) package.
648  !<
649  subroutine allocate_scalars(this)
650  ! -- modules
652  ! -- dummy
653  class(gwemwetype) :: this
654  !
655  ! -- Allocate scalars in TspAptType
656  call this%TspAptType%allocate_scalars()
657  !
658  ! -- Allocate
659  call mem_allocate(this%idxbudrate, 'IDXBUDRATE', this%memoryPath)
660  call mem_allocate(this%idxbudfwrt, 'IDXBUDFWRT', this%memoryPath)
661  call mem_allocate(this%idxbudrtmv, 'IDXBUDRTMV', this%memoryPath)
662  call mem_allocate(this%idxbudfrtm, 'IDXBUDFRTM', this%memoryPath)
663  call mem_allocate(this%idxbudmwcd, 'IDXBUDMWCD', this%memoryPath)
664  !
665  ! -- Initialize
666  this%idxbudrate = 0
667  this%idxbudfwrt = 0
668  this%idxbudrtmv = 0
669  this%idxbudfrtm = 0
670  this%idxbudmwcd = 0
671  end subroutine allocate_scalars
672 
673  !> @brief Allocate arrays specific to the streamflow mass transport (SFT)
674  !! package
675  !<
676  subroutine mwe_allocate_arrays(this)
677  ! -- modules
679  ! -- dummy
680  class(gwemwetype), intent(inout) :: this
681  !
682  ! -- alias into the input context's permanent, feature-indexed RATE
683  ! array (allocated and DZERO-initialized by the input context)
684  call mem_setptr(this%temprate, 'RATE', this%input_mempath)
685  !
686  ! -- Call standard TspAptType allocate arrays
687  call this%TspAptType%apt_allocate_arrays()
688  !
689  end subroutine mwe_allocate_arrays
690 
691  !> @brief Deallocate memory associated with MWE package
692  !<
693  subroutine mwe_da(this)
694  ! -- modules
696  ! -- dummy
697  class(gwemwetype) :: this
698  !
699  ! -- Deallocate scalars
700  call mem_deallocate(this%idxbudrate)
701  call mem_deallocate(this%idxbudfwrt)
702  call mem_deallocate(this%idxbudrtmv)
703  call mem_deallocate(this%idxbudfrtm)
704  call mem_deallocate(this%idxbudmwcd)
705  !
706  ! -- input-context-owned alias, not package-allocated
707  nullify (this%temprate)
708  !
709  ! -- Deallocate arrays
710  call mem_deallocate(this%ktf)
711  call mem_deallocate(this%rfeatthk)
712  !
713  ! -- Deallocate scalars in TspAptType
714  call this%TspAptType%bnd_da()
715  end subroutine mwe_da
716 
717  !> @brief Thermal transport matrix term(s) associated with a user-specified
718  !! flow rate (mwe_rate_term)
719  !<
720  subroutine mwe_rate_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
721  ! -- dummy
722  class(gwemwetype) :: this
723  integer(I4B), intent(in) :: ientry
724  integer(I4B), intent(inout) :: n1
725  integer(I4B), intent(inout) :: n2
726  real(DP), intent(inout), optional :: rrate
727  real(DP), intent(inout), optional :: rhsval
728  real(DP), intent(inout), optional :: hcofval
729  ! -- local
730  real(DP) :: qbnd
731  real(DP) :: ctmp
732  real(DP) :: h, r
733  !
734  n1 = this%flowbudptr%budterm(this%idxbudrate)%id1(ientry)
735  n2 = this%flowbudptr%budterm(this%idxbudrate)%id2(ientry)
736  ! -- Note that qbnd is negative for an extracting well
737  qbnd = this%flowbudptr%budterm(this%idxbudrate)%flow(ientry)
738  if (qbnd < dzero) then
739  ctmp = this%xnewpak(n1)
740  h = qbnd
741  r = dzero
742  else
743  ctmp = this%temprate(n1)
744  h = dzero
745  r = -qbnd * ctmp
746  end if
747  if (present(rrate)) rrate = qbnd * ctmp * this%eqnsclfac
748  if (present(rhsval)) rhsval = r * this%eqnsclfac
749  if (present(hcofval)) hcofval = h * this%eqnsclfac
750  end subroutine mwe_rate_term
751 
752  !> @brief Thermal transport matrix term(s) associated with a flowing-
753  !! well rate term associated with pumping (or injection)
754  !<
755  subroutine mwe_fwrt_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
756  ! -- dummy
757  class(gwemwetype) :: this
758  integer(I4B), intent(in) :: ientry
759  integer(I4B), intent(inout) :: n1
760  integer(I4B), intent(inout) :: n2
761  real(DP), intent(inout), optional :: rrate
762  real(DP), intent(inout), optional :: rhsval
763  real(DP), intent(inout), optional :: hcofval
764  ! -- local
765  real(DP) :: qbnd
766  real(DP) :: ctmp
767  !
768  n1 = this%flowbudptr%budterm(this%idxbudfwrt)%id1(ientry)
769  n2 = this%flowbudptr%budterm(this%idxbudfwrt)%id2(ientry)
770  qbnd = this%flowbudptr%budterm(this%idxbudfwrt)%flow(ientry)
771  ctmp = this%xnewpak(n1)
772  if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac
773  if (present(rhsval)) rhsval = dzero
774  if (present(hcofval)) hcofval = qbnd * this%eqnsclfac
775  end subroutine mwe_fwrt_term
776 
777  !> @brief Thermal transport matrix term(s) associated with pumped-water-
778  !! to-mover term (mwe_rtmv_term)
779  !<
780  subroutine mwe_rtmv_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
781  ! -- dummy
782  class(gwemwetype) :: this
783  integer(I4B), intent(in) :: ientry
784  integer(I4B), intent(inout) :: n1
785  integer(I4B), intent(inout) :: n2
786  real(DP), intent(inout), optional :: rrate
787  real(DP), intent(inout), optional :: rhsval
788  real(DP), intent(inout), optional :: hcofval
789  ! -- local
790  real(DP) :: qbnd
791  real(DP) :: ctmp
792  !
793  n1 = this%flowbudptr%budterm(this%idxbudrtmv)%id1(ientry)
794  n2 = this%flowbudptr%budterm(this%idxbudrtmv)%id2(ientry)
795  qbnd = this%flowbudptr%budterm(this%idxbudrtmv)%flow(ientry)
796  ctmp = this%xnewpak(n1)
797  if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac
798  if (present(rhsval)) rhsval = dzero
799  if (present(hcofval)) hcofval = qbnd * this%eqnsclfac
800  end subroutine mwe_rtmv_term
801 
802  !> @brief Thermal transport matrix term(s) associated with the flowing-
803  !! well-rate-to-mover term (mwe_frtm_term)
804  !<
805  subroutine mwe_frtm_term(this, ientry, n1, n2, rrate, rhsval, hcofval)
806  ! -- dummy
807  class(gwemwetype) :: this
808  integer(I4B), intent(in) :: ientry
809  integer(I4B), intent(inout) :: n1
810  integer(I4B), intent(inout) :: n2
811  real(DP), intent(inout), optional :: rrate
812  real(DP), intent(inout), optional :: rhsval
813  real(DP), intent(inout), optional :: hcofval
814  ! -- local
815  real(DP) :: qbnd
816  real(DP) :: ctmp
817  !
818  n1 = this%flowbudptr%budterm(this%idxbudfrtm)%id1(ientry)
819  n2 = this%flowbudptr%budterm(this%idxbudfrtm)%id2(ientry)
820  qbnd = this%flowbudptr%budterm(this%idxbudfrtm)%flow(ientry)
821  ctmp = this%xnewpak(n1)
822  if (present(rrate)) rrate = ctmp * qbnd * this%eqnsclfac
823  if (present(rhsval)) rhsval = dzero
824  if (present(hcofval)) hcofval = qbnd * this%eqnsclfac
825  end subroutine mwe_frtm_term
826 
827  !> @brief Observations
828  !!
829  !! Store the observation type supported by the APT package and override
830  !! BndType%bnd_df_obs
831  !<
832  subroutine mwe_df_obs(this)
833  ! -- dummy
834  class(gwemwetype) :: this
835  ! -- local
836  integer(I4B) :: indx
837  !
838  ! -- Store obs type and assign procedure pointer
839  ! for temperature observation type.
840  call this%obs%StoreObsType('temperature', .false., indx)
841  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
842  !
843  ! -- Flow-ja-face not supported for MWE
844  !call this%obs%StoreObsType('flow-ja-face', .true., indx)
845  !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID
846  !
847  ! -- Store obs type and assign procedure pointer
848  ! for from-mvr observation type.
849  call this%obs%StoreObsType('from-mvr', .true., indx)
850  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
851  !
852  ! -- To-mvr not supported for mwe
853  !call this%obs%StoreObsType('to-mvr', .true., indx)
854  !this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsID
855  !
856  ! -- Store obs type and assign procedure pointer
857  ! for storage observation type.
858  call this%obs%StoreObsType('storage', .true., indx)
859  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
860  !
861  ! -- Store obs type and assign procedure pointer
862  ! for constant observation type.
863  call this%obs%StoreObsType('constant', .true., indx)
864  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
865  !
866  ! -- Store obs type and assign procedure pointer
867  ! for observation type: mwe
868  call this%obs%StoreObsType('mwe', .true., indx)
869  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid12
870  !
871  ! -- Store obs type and assign procedure pointer
872  ! for rate observation type.
873  call this%obs%StoreObsType('rate', .true., indx)
874  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
875  !
876  ! -- Store obs type and assign procedure pointer
877  ! for observation type.
878  call this%obs%StoreObsType('fw-rate', .true., indx)
879  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
880  !
881  ! -- Store obs type and assign procedure pointer
882  ! for observation type.
883  call this%obs%StoreObsType('rate-to-mvr', .true., indx)
884  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
885  !
886  ! -- Store obs type and assign procedure pointer
887  ! for observation type.
888  call this%obs%StoreObsType('fw-rate-to-mvr', .true., indx)
889  this%obs%obsData(indx)%ProcessIdPtr => apt_process_obsid
890  end subroutine mwe_df_obs
891 
892  !> @brief Process package specific obs
893  !!
894  !! Method to process specific observations for this package.
895  !<
896  subroutine mwe_rp_obs(this, obsrv, found)
897  ! -- dummy
898  class(gwemwetype), intent(inout) :: this !< package class
899  type(observetype), intent(inout) :: obsrv !< observation object
900  logical, intent(inout) :: found !< indicate whether observation was found
901  !
902  found = .true.
903  select case (obsrv%ObsTypeId)
904  case ('RATE')
905  call this%rp_obs_byfeature(obsrv)
906  case ('FW-RATE')
907  call this%rp_obs_byfeature(obsrv)
908  case ('RATE-TO-MVR')
909  call this%rp_obs_byfeature(obsrv)
910  case ('FW-RATE-TO-MVR')
911  call this%rp_obs_byfeature(obsrv)
912  case default
913  found = .false.
914  end select
915  end subroutine mwe_rp_obs
916 
917  !> @brief Calculate observation value and pass it back to APT
918  !<
919  subroutine mwe_bd_obs(this, obstypeid, jj, v, found)
920  ! -- dummy
921  class(gwemwetype), intent(inout) :: this
922  character(len=*), intent(in) :: obstypeid
923  real(DP), intent(inout) :: v
924  integer(I4B), intent(in) :: jj
925  logical, intent(inout) :: found
926  ! -- local
927  integer(I4B) :: n1, n2
928  !
929  found = .true.
930  select case (obstypeid)
931  case ('RATE')
932  if (this%iboundpak(jj) /= 0) then
933  call this%mwe_rate_term(jj, n1, n2, v)
934  end if
935  case ('FW-RATE')
936  if (this%iboundpak(jj) /= 0 .and. this%idxbudfwrt > 0) then
937  call this%mwe_fwrt_term(jj, n1, n2, v)
938  end if
939  case ('RATE-TO-MVR')
940  if (this%iboundpak(jj) /= 0 .and. this%idxbudrtmv > 0) then
941  call this%mwe_rtmv_term(jj, n1, n2, v)
942  end if
943  case ('FW-RATE-TO-MVR')
944  if (this%iboundpak(jj) /= 0 .and. this%idxbudfrtm > 0) then
945  call this%mwe_frtm_term(jj, n1, n2, v)
946  end if
947  case default
948  found = .false.
949  end select
950  end subroutine mwe_bd_obs
951 
952  !> @brief Read feature information for this advanced package
953  !<
954  subroutine mwe_read_cvs(this)
957  class(gwemwetype), intent(inout) :: this
958  integer(I4B) :: n, ifeat
959  real(DP), dimension(:), pointer, contiguous :: ktf_ptr => null()
960  real(DP), dimension(:), pointer, contiguous :: fthk_ptr => null()
961  call this%TspAptType%apt_source_cvs()
962  call mem_allocate(this%ktf, this%ncv, 'KTF', this%memoryPath)
963  call mem_allocate(this%rfeatthk, this%ncv, 'RFEATTHK', this%memoryPath)
964  call mem_setptr(ktf_ptr, 'KTF', this%input_mempath)
965  call mem_setptr(fthk_ptr, 'FTHK', this%input_mempath)
966  do n = 1, size(this%pkg_ifno)
967  ifeat = this%pkg_ifno(n)
968  if (ifeat < 1 .or. ifeat > this%ncv) cycle
969  this%ktf(ifeat) = ktf_ptr(n)
970  this%rfeatthk(ifeat) = fthk_ptr(n)
971  if (this%rfeatthk(ifeat) <= dzero) then
972  write (errmsg, '(4x,a)') &
973  '****ERROR. Specified thickness used for thermal '// &
974  'conduction MUST BE > 0 else divide by zero error occurs'
975  call store_error(errmsg)
976  end if
977  end do
978  if (count_errors() > 0) then
979  call store_error_filename(this%input_fname)
980  end if
981  call memorystore_release('KTF', this%input_mempath)
982  call memorystore_release('FTHK', this%input_mempath)
983  end subroutine mwe_read_cvs
984 
985 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:45
real(dp), parameter dnodata
real no data constant
Definition: Constants.f90:95
real(dp), parameter dep20
real constant 1e20
Definition: Constants.f90:91
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:36
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
subroutine, public mwe_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath, fmi, eqnsclfac, gwecommon, dvt, dvu, dvua)
Create new MWE package.
Definition: gwe-mwe.f90:104
subroutine allocate_scalars(this)
Allocate scalars specific to the multi-aquifer well energy transport (MWE) package.
Definition: gwe-mwe.f90:650
character(len= *), parameter flowtype
Definition: gwe-mwe.f90:59
subroutine mwe_rp_obs(this, obsrv, found)
Process package specific obs.
Definition: gwe-mwe.f90:897
real(dp) function mwe_setting_value(this, itemno, key)
Value for a package-specific PERIOD setting.
Definition: gwe-mwe.f90:285
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:781
subroutine mwe_allocate_arrays(this)
Allocate arrays specific to the streamflow mass transport (SFT) package.
Definition: gwe-mwe.f90:677
subroutine mwe_bd_obs(this, obstypeid, jj, v, found)
Calculate observation value and pass it back to APT.
Definition: gwe-mwe.f90:920
subroutine find_mwe_package(this)
Find corresponding mwe package.
Definition: gwe-mwe.f90:166
subroutine mwe_fill_budobj(this, idx, x, flowja, ccratin, ccratout)
Copy flow terms into thisbudobj.
Definition: gwe-mwe.f90:555
character(len= *), parameter ftype
Definition: gwe-mwe.f90:58
character(len=16) text
Definition: gwe-mwe.f90:60
subroutine mwe_da(this)
Deallocate memory associated with MWE package.
Definition: gwe-mwe.f90:694
subroutine mwe_setup_budobj(this, idx)
Set up the budget object that stores all the mwe flows.
Definition: gwe-mwe.f90:462
integer(i4b) function mwe_get_nbudterms(this)
Function to return the number of budget terms just for this package.
Definition: gwe-mwe.f90:446
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:806
subroutine mwe_solve(this)
Add terms specific to multi-aquifer wells to the explicit multi- aquifer well energy transport solve.
Definition: gwe-mwe.f90:401
subroutine mwe_fc_expanded(this, rhs, ia, idxglo, matrix_sln)
Add matrix terms related to MWE.
Definition: gwe-mwe.f90:304
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:756
subroutine mwe_read_cvs(this)
Read feature information for this advanced package.
Definition: gwe-mwe.f90:955
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:721
subroutine mwe_df_obs(this)
Observations.
Definition: gwe-mwe.f90:833
This module defines variable data types.
Definition: kind.f90:8
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
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
integer(i4b) function, public count_errors()
Return number of errors.
Definition: Sim.f90:59
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
character(len=maxcharlen) errmsg
error message string
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
Data for sharing among multiple packages. Originally read in from.