MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
gwt.f90
Go to the documentation of this file.
1 ! Groundwater Transport (GWT) Model
2 ! The following are additional features/checks to add
3 ! * Add check that discretization is the same between both models
4 ! * Consider implementation of steady-state transport (affects MST, IST)
5 ! * Check and handle pore space discrepancy between flow and transport (porosity vs specific yield)
6 ! * UZT may not have the required porosity term
7 
8 module gwtmodule
9 
10  use kindmodule, only: dp, i4b
14 
17  use gwtdspmodule, only: gwtdsptype
18  use gwtmstmodule, only: gwtmsttype
19  use budgetmodule, only: budgettype
22 
23  implicit none
24 
25  private
26  public :: gwt_cr
27  public :: gwtmodeltype
28  public :: castasgwtmodel
29  public :: gwt_nbasepkg, gwt_nmultipkg
30  public :: gwt_basepkg, gwt_multipkg
31  character(len=LENVARNAME), parameter :: dvt = 'CONCENTRATION ' !< dependent variable type, varies based on model type
32  character(len=LENVARNAME), parameter :: dvu = 'MASS ' !< dependent variable unit of measure, either "mass" or "energy"
33  character(len=LENVARNAME), parameter :: dvua = 'M ' !< abbreviation of the dependent variable unit of measure, either "M" or "E"
34 
35  type, extends(transportmodeltype) :: gwtmodeltype
36 
37  type(gwtmsttype), pointer :: mst => null() ! mass storage and transfer package
38  type(gwtdsptype), pointer :: dsp => null() ! dispersion package
39  integer(I4B), pointer :: inmst => null() ! unit number MST
40  integer(I4B), pointer :: indsp => null() ! DSP enabled flag
41 
42  contains
43 
44  procedure :: model_df => gwt_df
45  procedure :: model_ac => gwt_ac
46  procedure :: model_mc => gwt_mc
47  procedure :: model_ar => gwt_ar
48  procedure :: model_rp => gwt_rp
49  procedure :: model_ad => gwt_ad
50  procedure :: model_cf => gwt_cf
51  procedure :: model_fc => gwt_fc
52  procedure :: model_cc => gwt_cc
53  procedure :: model_cq => gwt_cq
54  procedure :: model_bd => gwt_bd
55  procedure :: model_ot => gwt_ot
56  procedure :: model_da => gwt_da
57  procedure :: model_bdentry => gwt_bdentry
58  procedure :: allocate_scalars
59  procedure :: get_iasym => gwt_get_iasym
60  procedure :: create_packages => create_gwt_packages
61  procedure, private :: create_bndpkgs
62  procedure, private :: package_create
63 
64  end type gwtmodeltype
65 
66  !> @brief GWT base package array descriptors
67  !!
68  !! GWT6 model base package types. Only listed packages are candidates
69  !! for input and these will be loaded in the order specified.
70  !<
71  integer(I4B), parameter :: gwt_nbasepkg = 50
72  character(len=LENPACKAGETYPE), dimension(GWT_NBASEPKG) :: gwt_basepkg
73  data gwt_basepkg/'DIS6 ', 'DISV6', 'DISU6', ' ', ' ', & ! 5
74  &'IC6 ', 'FMI6 ', 'MST6 ', 'ADV6 ', ' ', & ! 10
75  &'DSP6 ', 'SSM6 ', 'MVT6 ', 'OC6 ', ' ', & ! 15
76  &'OBS6 ', ' ', ' ', ' ', ' ', & ! 20
77  &30*' '/ ! 50
78 
79  !> @brief GWT multi package array descriptors
80  !!
81  !! GWT6 model multi-instance package types. Only listed packages are
82  !! candidates for input and these will be loaded in the order specified.
83  !<
84  integer(I4B), parameter :: gwt_nmultipkg = 50
85  character(len=LENPACKAGETYPE), dimension(GWT_NMULTIPKG) :: gwt_multipkg
86  data gwt_multipkg/'CNC6 ', 'SRC6 ', 'LKT6 ', 'IST6 ', ' ', & ! 5
87  &'SFT6 ', 'MWT6 ', 'UZT6 ', 'API6 ', ' ', & ! 10
88  &40*' '/ ! 50
89 
90  ! -- size of supported model package arrays
91  integer(I4B), parameter :: niunit_gwt = gwt_nbasepkg + gwt_nmultipkg
92 
93 contains
94 
95  !> @brief Create a new groundwater transport model object
96  !<
97  subroutine gwt_cr(filename, id, modelname)
98  ! -- modules
99  use listsmodule, only: basemodellist
105  use budgetmodule, only: budget_cr
106  ! -- dummy
107  character(len=*), intent(in) :: filename !< input file
108  integer(I4B), intent(in) :: id !< consecutive model number listed in mfsim.nam
109  character(len=*), intent(in) :: modelname !< name of the model
110  ! -- local
111  integer(I4B) :: indis
112  type(gwtmodeltype), pointer :: this
113  class(basemodeltype), pointer :: model
114  !
115  ! -- Allocate a new GWT Model (this)
116  allocate (this)
117  !
118  ! -- Set memory path before allocation in memory manager can be done
119  this%memoryPath = create_mem_path(modelname)
120  !
121  ! -- Allocate scalars and add model to basemodellist
122  call this%allocate_scalars(modelname)
123  !
124  ! -- set labels for transport model - needed by create_packages() below
125  call this%set_tsp_labels(this%macronym, dvt, dvu, dvua)
126  !
127  model => this
128  call addbasemodeltolist(basemodellist, model)
129  !
130  ! -- Call parent class routine
131  call this%tsp_cr(filename, id, modelname, 'GWT', indis)
132  !
133  ! -- create model packages
134  call this%create_packages(indis)
135  !
136  ! -- Return
137  return
138  end subroutine gwt_cr
139 
140  !> @brief Define packages of the GWT model
141  !!
142  !! This subroutine defines a gwt model type. Steps include:
143  !! (1) call df routines for each package
144  !! (2) set variables and pointers
145  !<
146  subroutine gwt_df(this)
147  ! -- modules
148  use simmodule, only: store_error
149  ! -- dummy
150  class(gwtmodeltype) :: this
151  ! -- local
152  integer(I4B) :: ip
153  class(bndtype), pointer :: packobj
154  !
155  ! -- Define packages and utility objects
156  call this%dis%dis_df()
157  call this%fmi%fmi_df(this%dis, 1)
158  if (this%inmvt > 0) call this%mvt%mvt_df(this%dis)
159  if (this%inadv > 0) call this%adv%adv_df()
160  if (this%indsp > 0) call this%dsp%dsp_df(this%dis)
161  if (this%inssm > 0) call this%ssm%ssm_df()
162  call this%oc%oc_df()
163  call this%budget%budget_df(niunit_gwt, this%depvarunit, &
164  this%depvarunitabbrev)
165  !
166  ! -- Check for SSM package
167  if (this%inssm == 0) then
168  if (this%fmi%nflowpack > 0) then
169  call store_error('Flow model has boundary packages, but there &
170  &is no SSM package. The SSM package must be activated.', &
171  terminate=.true.)
172  end if
173  end if
174  !
175  ! -- Assign or point model members to dis members
176  this%neq = this%dis%nodes
177  this%nja = this%dis%nja
178  this%ia => this%dis%con%ia
179  this%ja => this%dis%con%ja
180  !
181  ! -- Allocate model arrays, now that neq and nja are assigned
182  call this%allocate_arrays()
183  !
184  ! -- Define packages and assign iout for time series managers
185  do ip = 1, this%bndlist%Count()
186  packobj => getbndfromlist(this%bndlist, ip)
187  call packobj%bnd_df(this%neq, this%dis)
188  packobj%TsManager%iout = this%iout
189  packobj%TasManager%iout = this%iout
190  end do
191  !
192  ! -- Store information needed for observations
193  call this%obs%obs_df(this%iout, this%name, 'GWT', this%dis)
194  !
195  ! -- Return
196  return
197  end subroutine gwt_df
198 
199  !> @brief Add the internal connections of this model to the sparse matrix
200  !<
201  subroutine gwt_ac(this, sparse)
202  ! -- modules
203  use sparsemodule, only: sparsematrix
204  ! -- dummy
205  class(gwtmodeltype) :: this
206  type(sparsematrix), intent(inout) :: sparse
207  ! -- local
208  class(bndtype), pointer :: packobj
209  integer(I4B) :: ip
210  !
211  ! -- Add the internal connections of this model to sparse
212  call this%dis%dis_ac(this%moffset, sparse)
213  if (this%indsp > 0) &
214  call this%dsp%dsp_ac(this%moffset, sparse)
215  !
216  ! -- Add any package connections
217  do ip = 1, this%bndlist%Count()
218  packobj => getbndfromlist(this%bndlist, ip)
219  call packobj%bnd_ac(this%moffset, sparse)
220  end do
221  !
222  ! -- Return
223  return
224  end subroutine gwt_ac
225 
226  !> @brief Map the positions of the GWT model connections in the numerical
227  !! solution coefficient matrix.
228  !<
229  subroutine gwt_mc(this, matrix_sln)
230  ! -- dummy
231  class(gwtmodeltype) :: this
232  class(matrixbasetype), pointer :: matrix_sln !< global system matrix
233  ! -- local
234  class(bndtype), pointer :: packobj
235  integer(I4B) :: ip
236  !
237  ! -- Find the position of each connection in the global ia, ja structure
238  ! and store them in idxglo.
239  call this%dis%dis_mc(this%moffset, this%idxglo, matrix_sln)
240  !
241  if (this%indsp > 0) call this%dsp%dsp_mc(this%moffset, matrix_sln)
242  !
243  ! -- Map any package connections
244  do ip = 1, this%bndlist%Count()
245  packobj => getbndfromlist(this%bndlist, ip)
246  call packobj%bnd_mc(this%moffset, matrix_sln)
247  end do
248  !
249  ! -- Return
250  return
251  end subroutine gwt_mc
252 
253  !> @brief GWT Model Allocate and Read
254  !!
255  !! This subroutine:
256  !! - allocates and reads packages that are part of this model,
257  !! - allocates memory for arrays used by this model object
258  !<
259  subroutine gwt_ar(this)
260  ! -- modules
261  use constantsmodule, only: dhnoflo
262  ! -- dummy
263  class(gwtmodeltype) :: this
264  ! -- locals
265  integer(I4B) :: ip
266  class(bndtype), pointer :: packobj
267  !
268  ! -- Allocate and read modules attached to model
269  call this%fmi%fmi_ar(this%ibound)
270  if (this%inmvt > 0) call this%mvt%mvt_ar()
271  if (this%inic > 0) call this%ic%ic_ar(this%x)
272  if (this%inmst > 0) call this%mst%mst_ar(this%dis, this%ibound)
273  if (this%inadv > 0) call this%adv%adv_ar(this%dis, this%ibound)
274  if (this%indsp > 0) call this%dsp%dsp_ar(this%ibound, this%mst%thetam)
275  if (this%inssm > 0) call this%ssm%ssm_ar(this%dis, this%ibound, this%x)
276  if (this%inobs > 0) call this%obs%tsp_obs_ar(this%ic, this%x, this%flowja)
277  !
278  ! -- Set governing equation scale factor. Note that this scale factor
279  ! -- cannot be set arbitrarily. For solute transport, it must be set
280  ! -- to 1. Setting it to a different value will NOT automatically
281  ! -- scale all the terms of the governing equation correctly by that
282  ! -- value. This is because much of the coding in the associated
283  ! -- packages implicitly assumes the governing equation for solute
284  ! -- transport is scaled by 1. (effectively unscaled).
285  this%eqnsclfac = done
286  !
287  ! -- Call dis_ar to write binary grid file
288  !call this%dis%dis_ar(this%npf%icelltype)
289  !
290  ! -- set up output control
291  call this%oc%oc_ar(this%x, this%dis, dhnoflo, this%depvartype)
292  call this%budget%set_ibudcsv(this%oc%ibudcsv)
293  !
294  ! -- Package input files now open, so allocate and read
295  do ip = 1, this%bndlist%Count()
296  packobj => getbndfromlist(this%bndlist, ip)
297  call packobj%set_pointers(this%dis%nodes, this%ibound, this%x, &
298  this%xold, this%flowja)
299  ! -- Read and allocate package
300  call packobj%bnd_ar()
301  end do
302  !
303  ! -- Return
304  return
305  end subroutine gwt_ar
306 
307  !> @brief GWT Model Read and Prepare
308  !!
309  !! Call the read and prepare routines of the attached packages
310  !<
311  subroutine gwt_rp(this)
312  ! -- modules
313  use tdismodule, only: readnewdata
314  ! -- dummy
315  class(gwtmodeltype) :: this
316  ! -- local
317  class(bndtype), pointer :: packobj
318  integer(I4B) :: ip
319  !
320  ! -- In fmi, check for mvt and mvrbudobj consistency
321  call this%fmi%fmi_rp(this%inmvt)
322  if (this%inmvt > 0) call this%mvt%mvt_rp()
323  !
324  ! -- Check with TDIS on whether or not it is time to RP
325  if (.not. readnewdata) return
326  !
327  ! -- Read and prepare
328  if (this%inoc > 0) call this%oc%oc_rp()
329  if (this%inssm > 0) call this%ssm%ssm_rp()
330  do ip = 1, this%bndlist%Count()
331  packobj => getbndfromlist(this%bndlist, ip)
332  call packobj%bnd_rp()
333  call packobj%bnd_rp_obs()
334  end do
335  !
336  ! -- Return
337  return
338  end subroutine gwt_rp
339 
340  !> @brief GWT Model Time Step Advance
341  !!
342  !! Call the advance subroutines of the attached packages
343  !<
344  subroutine gwt_ad(this)
345  ! -- modules
347  ! -- dummy
348  class(gwtmodeltype) :: this
349  class(bndtype), pointer :: packobj
350  ! -- local
351  integer(I4B) :: irestore
352  integer(I4B) :: ip, n
353  !
354  ! -- Reset state variable
355  irestore = 0
356  if (ifailedstepretry > 0) irestore = 1
357  if (irestore == 0) then
358  !
359  ! -- copy x into xold
360  do n = 1, this%dis%nodes
361  if (this%ibound(n) == 0) then
362  this%xold(n) = dzero
363  else
364  this%xold(n) = this%x(n)
365  end if
366  end do
367  else
368  !
369  ! -- copy xold into x if this time step is a redo
370  do n = 1, this%dis%nodes
371  this%x(n) = this%xold(n)
372  end do
373  end if
374  !
375  ! -- Advance fmi
376  call this%fmi%fmi_ad(this%x)
377  !
378  ! -- Advance
379  if (this%indsp > 0) call this%dsp%dsp_ad()
380  if (this%inssm > 0) call this%ssm%ssm_ad()
381  do ip = 1, this%bndlist%Count()
382  packobj => getbndfromlist(this%bndlist, ip)
383  call packobj%bnd_ad()
384  if (isimcheck > 0) then
385  call packobj%bnd_ck()
386  end if
387  end do
388  !
389  ! -- Push simulated values to preceding time/subtime step
390  call this%obs%obs_ad()
391  !
392  ! -- Return
393  return
394  end subroutine gwt_ad
395 
396  !> @brief GWT Model calculate coefficients
397  !!
398  !! Call the calculate coefficients subroutines of the attached packages
399  !<
400  subroutine gwt_cf(this, kiter)
401  ! -- modules
402  ! -- dummy
403  class(gwtmodeltype) :: this
404  integer(I4B), intent(in) :: kiter
405  ! -- local
406  class(bndtype), pointer :: packobj
407  integer(I4B) :: ip
408  !
409  ! -- Call package cf routines
410  do ip = 1, this%bndlist%Count()
411  packobj => getbndfromlist(this%bndlist, ip)
412  call packobj%bnd_cf()
413  end do
414  !
415  ! -- Return
416  return
417  end subroutine gwt_cf
418 
419  !> @brief GWT Model fill coefficients
420  !!
421  !! Call the fill coefficients subroutines attached packages
422  !<
423  subroutine gwt_fc(this, kiter, matrix_sln, inwtflag)
424  ! -- modules
425  ! -- dummy
426  class(gwtmodeltype) :: this
427  integer(I4B), intent(in) :: kiter
428  class(matrixbasetype), pointer :: matrix_sln
429  integer(I4B), intent(in) :: inwtflag
430  ! -- local
431  class(bndtype), pointer :: packobj
432  integer(I4B) :: ip
433  !
434  ! -- call fc routines
435  call this%fmi%fmi_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, &
436  this%idxglo, this%rhs)
437  if (this%inmvt > 0) then
438  call this%mvt%mvt_fc(this%x, this%x)
439  end if
440  if (this%inmst > 0) then
441  call this%mst%mst_fc(this%dis%nodes, this%xold, this%nja, matrix_sln, &
442  this%idxglo, this%x, this%rhs, kiter)
443  end if
444  if (this%inadv > 0) then
445  call this%adv%adv_fc(this%dis%nodes, matrix_sln, this%idxglo, this%x, &
446  this%rhs)
447  end if
448  if (this%indsp > 0) then
449  call this%dsp%dsp_fc(kiter, this%dis%nodes, this%nja, matrix_sln, &
450  this%idxglo, this%rhs, this%x)
451  end if
452  if (this%inssm > 0) then
453  call this%ssm%ssm_fc(matrix_sln, this%idxglo, this%rhs)
454  end if
455  !
456  ! -- packages
457  do ip = 1, this%bndlist%Count()
458  packobj => getbndfromlist(this%bndlist, ip)
459  call packobj%bnd_fc(this%rhs, this%ia, this%idxglo, matrix_sln)
460  end do
461  !
462  ! -- Return
463  return
464  end subroutine gwt_fc
465 
466  !> @brief GWT Model Final Convergence Check
467  !!
468  !! If MVR/MVT is active, call the MVR convergence check subroutines to force
469  !! at least 2 outer iterations. The other advanced transport packages are
470  !! solved in the matrix equations directly which means the solver is
471  !! completing the necessary checks thereby eliminating need to call package
472  !! cc routines. That is, no need to loop over active packages and run:
473  !! call packobj%bnd_cc(iend, icnvg, hclose, rclose)
474  !<
475  subroutine gwt_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
476  ! -- dummy
477  class(gwtmodeltype) :: this
478  integer(I4B), intent(in) :: innertot
479  integer(I4B), intent(in) :: kiter
480  integer(I4B), intent(in) :: iend
481  integer(I4B), intent(in) :: icnvgmod
482  character(len=LENPAKLOC), intent(inout) :: cpak
483  integer(I4B), intent(inout) :: ipak
484  real(DP), intent(inout) :: dpak
485  ! -- local
486  ! -- formats
487  !
488  ! -- If mover is on, then at least 2 outers required
489  if (this%inmvt > 0) call this%mvt%mvt_cc(kiter, iend, icnvgmod, cpak, dpak)
490  !
491  ! -- Return
492  return
493  end subroutine gwt_cc
494 
495  !> @brief GWT Model calculate flow
496  !!
497  !! Call the intercell flows (flow ja) subroutine
498  !<
499  subroutine gwt_cq(this, icnvg, isuppress_output)
500  ! -- modules
501  use sparsemodule, only: csr_diagsum
502  ! -- dummy
503  class(gwtmodeltype) :: this
504  integer(I4B), intent(in) :: icnvg
505  integer(I4B), intent(in) :: isuppress_output
506  ! -- local
507  integer(I4B) :: i
508  integer(I4B) :: ip
509  class(bndtype), pointer :: packobj
510  !
511  ! -- Construct the flowja array. Flowja is calculated each time, even if
512  ! output is suppressed. (flowja is positive into a cell.) The diagonal
513  ! position of the flowja array will contain the flow residual after
514  ! these routines are called, so each package is responsible for adding
515  ! its flow to this diagonal position.
516  do i = 1, this%nja
517  this%flowja(i) = dzero
518  end do
519  if (this%inadv > 0) call this%adv%adv_cq(this%x, this%flowja)
520  if (this%indsp > 0) call this%dsp%dsp_cq(this%x, this%flowja)
521  if (this%inmst > 0) call this%mst%mst_cq(this%dis%nodes, this%x, this%xold, &
522  this%flowja)
523  if (this%inssm > 0) call this%ssm%ssm_cq(this%flowja)
524  if (this%infmi > 0) call this%fmi%fmi_cq(this%x, this%flowja)
525  !
526  ! -- Go through packages and call cq routines. cf() routines are called
527  ! first to regenerate non-linear terms to be consistent with the final
528  ! conc solution.
529  do ip = 1, this%bndlist%Count()
530  packobj => getbndfromlist(this%bndlist, ip)
531  call packobj%bnd_cf()
532  call packobj%bnd_cq(this%x, this%flowja)
533  end do
534  !
535  ! -- Finalize calculation of flowja by adding face flows to the diagonal.
536  ! This results in the flow residual being stored in the diagonal
537  ! position for each cell.
538  call csr_diagsum(this%dis%con%ia, this%flowja)
539  !
540  ! -- Return
541  return
542  end subroutine gwt_cq
543 
544  !> @brief GWT Model Budget
545  !!
546  !! This subroutine:
547  !! (1) calculates intercell flows (flowja)
548  !! (2) calculates package contributions to the model budget
549  !<
550  subroutine gwt_bd(this, icnvg, isuppress_output)
551  use constantsmodule, only: dzero
552  ! -- dummy
553  class(gwtmodeltype) :: this
554  integer(I4B), intent(in) :: icnvg
555  integer(I4B), intent(in) :: isuppress_output
556  ! -- local
557  integer(I4B) :: ip
558  class(bndtype), pointer :: packobj
559  !
560  ! -- Save the solution convergence flag
561  this%icnvg = icnvg
562  !
563  ! -- Budget routines (start by resetting). Sole purpose of this section
564  ! is to add in and outs to model budget. All ins and out for a model
565  ! should be added here to this%budget. In a subsequent exchange call,
566  ! exchange flows might also be added.
567  call this%budget%reset()
568  if (this%inmst > 0) call this%mst%mst_bd(isuppress_output, this%budget)
569  if (this%inssm > 0) call this%ssm%ssm_bd(isuppress_output, this%budget)
570  if (this%infmi > 0) call this%fmi%fmi_bd(isuppress_output, this%budget)
571  if (this%inmvt > 0) call this%mvt%mvt_bd(this%x, this%x)
572  do ip = 1, this%bndlist%Count()
573  packobj => getbndfromlist(this%bndlist, ip)
574  call packobj%bnd_bd(this%budget)
575  end do
576  !
577  ! -- Return
578  return
579  end subroutine gwt_bd
580 
581  !> @brief Print and/or save model output
582  !!
583  !! Call the parent class output routine
584  !<
585  subroutine gwt_ot(this)
586  ! -- dummy
587  class(gwtmodeltype) :: this
588  ! -- local
589  integer(I4B) :: icbcfl
590  integer(I4B) :: icbcun
591  !
592  !
593  ! -- Initialize
594  icbcfl = 0
595  !
596  ! -- Because mst belongs to gwt, call mst_ot_flow directly (and not from parent)
597  if (this%oc%oc_save('BUDGET')) icbcfl = 1
598  icbcun = this%oc%oc_save_unit('BUDGET')
599  if (this%inmst > 0) call this%mst%mst_ot_flow(icbcfl, icbcun)
600  !
601  ! -- Call parent class _ot routines.
602  call this%tsp_ot(this%inmst)
603  !
604  ! -- Return
605  return
606  end subroutine gwt_ot
607 
608  !> @brief Deallocate
609  !!
610  !! Deallocate memory at conclusion of model run
611  !<
612  subroutine gwt_da(this)
613  ! -- modules
617  ! -- dummy
618  class(gwtmodeltype) :: this
619  ! -- local
620  integer(I4B) :: ip
621  class(bndtype), pointer :: packobj
622  !
623  ! -- Deallocate idm memory
624  call memorylist_remove(this%name, 'NAM', idm_context)
625  call memorylist_remove(component=this%name, context=idm_context)
626  !
627  ! -- Internal flow packages deallocate
628  call this%dis%dis_da()
629  call this%ic%ic_da()
630  call this%fmi%fmi_da()
631  call this%adv%adv_da()
632  call this%dsp%dsp_da()
633  call this%ssm%ssm_da()
634  call this%mst%mst_da()
635  call this%mvt%mvt_da()
636  call this%budget%budget_da()
637  call this%oc%oc_da()
638  call this%obs%obs_da()
639  !
640  ! -- Internal package objects
641  deallocate (this%dis)
642  deallocate (this%ic)
643  deallocate (this%dsp)
644  deallocate (this%ssm)
645  deallocate (this%mst)
646  deallocate (this%adv)
647  deallocate (this%mvt)
648  deallocate (this%budget)
649  deallocate (this%oc)
650  deallocate (this%obs)
651  !
652  ! -- Boundary packages
653  do ip = 1, this%bndlist%Count()
654  packobj => getbndfromlist(this%bndlist, ip)
655  call packobj%bnd_da()
656  deallocate (packobj)
657  end do
658  !
659  ! -- Scalars
660  call mem_deallocate(this%indsp)
661  call mem_deallocate(this%inmst)
662  !
663  ! -- Parent class members
664  call this%TransportModelType%tsp_da()
665  !
666  ! -- NumericalModelType
667  call this%NumericalModelType%model_da()
668  !
669  ! -- Return
670  return
671  end subroutine gwt_da
672 
673  !> @brief GroundWater Transport Model Budget Entry
674  !!
675  !! This subroutine adds a budget entry to the flow budget. It was added as
676  !! a method for the gwt model object so that the exchange object could add its
677  !! contributions.
678  !<
679  subroutine gwt_bdentry(this, budterm, budtxt, rowlabel)
680  ! -- modules
681  use constantsmodule, only: lenbudtxt
682  use tdismodule, only: delt
683  ! -- dummy
684  class(gwtmodeltype) :: this
685  real(DP), dimension(:, :), intent(in) :: budterm
686  character(len=LENBUDTXT), dimension(:), intent(in) :: budtxt
687  character(len=*), intent(in) :: rowlabel
688  !
689  call this%budget%addentry(budterm, delt, budtxt, rowlabel=rowlabel)
690  !
691  ! -- Return
692  return
693  end subroutine gwt_bdentry
694 
695  !> @brief return 1 if any package causes the matrix to be asymmetric.
696  !! Otherwise return 0.
697  !<
698  function gwt_get_iasym(this) result(iasym)
699  class(gwtmodeltype) :: this
700  ! -- local
701  integer(I4B) :: iasym
702  integer(I4B) :: ip
703  class(bndtype), pointer :: packobj
704  !
705  ! -- Start by setting iasym to zero
706  iasym = 0
707  !
708  ! -- ADV
709  if (this%inadv > 0) then
710  if (this%adv%iasym /= 0) iasym = 1
711  end if
712  !
713  ! -- DSP
714  if (this%indsp > 0) then
715  if (this%dsp%ixt3d /= 0) iasym = 1
716  end if
717  !
718  ! -- Check for any packages that introduce matrix asymmetry
719  do ip = 1, this%bndlist%Count()
720  packobj => getbndfromlist(this%bndlist, ip)
721  if (packobj%iasym /= 0) iasym = 1
722  end do
723  !
724  ! -- Return
725  return
726  end function gwt_get_iasym
727 
728  !> Allocate memory for non-allocatable members
729  !!
730  !! A subroutine for allocating the scalars specific to the GWT model type.
731  !! Additional scalars used by the parent class are allocated by the parent
732  !! class.
733  !<
734  subroutine allocate_scalars(this, modelname)
735  ! -- modules
737  ! -- dummy
738  class(gwtmodeltype) :: this
739  character(len=*), intent(in) :: modelname
740  !
741  ! -- allocate parent class scalars
742  call this%allocate_tsp_scalars(modelname)
743  !
744  ! -- allocate additional members specific to GWT model type
745  call mem_allocate(this%inmst, 'INMST', this%memoryPath)
746  call mem_allocate(this%indsp, 'INDSP', this%memoryPath)
747  !
748  this%inmst = 0
749  this%indsp = 0
750  !
751  ! -- Return
752  return
753  end subroutine allocate_scalars
754 
755  !> @brief Create boundary condition packages for this model
756  !!
757  !! Call the package create routines for packages activated by the user.
758  !<
759  subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, &
760  inunit, iout)
761  ! -- modules
762  use constantsmodule, only: linelength
763  use simmodule, only: store_error
764  use gwtcncmodule, only: cnc_create
765  use gwtsrcmodule, only: src_create
766  use gwtistmodule, only: ist_create
767  use gwtlktmodule, only: lkt_create
768  use gwtsftmodule, only: sft_create
769  use gwtmwtmodule, only: mwt_create
770  use gwtuztmodule, only: uzt_create
771  use apimodule, only: api_create
772  ! -- dummy
773  class(gwtmodeltype) :: this
774  character(len=*), intent(in) :: filtyp
775  character(len=LINELENGTH) :: errmsg
776  integer(I4B), intent(in) :: ipakid
777  integer(I4B), intent(in) :: ipaknum
778  character(len=*), intent(in) :: pakname
779  character(len=*), intent(in) :: mempath
780  integer(I4B), intent(in) :: inunit
781  integer(I4B), intent(in) :: iout
782  ! -- local
783  class(bndtype), pointer :: packobj
784  class(bndtype), pointer :: packobj2
785  integer(I4B) :: ip
786  !
787  ! -- This part creates the package object
788  select case (filtyp)
789  case ('CNC6')
790  call cnc_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
791  pakname, dvt, mempath)
792  case ('SRC6')
793  call src_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
794  this%depvartype, pakname)
795  case ('LKT6')
796  call lkt_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
797  pakname, this%fmi, this%eqnsclfac, this%depvartype, &
798  this%depvarunit, this%depvarunitabbrev)
799  case ('SFT6')
800  call sft_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
801  pakname, this%fmi, this%eqnsclfac, this%depvartype, &
802  this%depvarunit, this%depvarunitabbrev)
803  case ('MWT6')
804  call mwt_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
805  pakname, this%fmi, this%eqnsclfac, this%depvartype, &
806  this%depvarunit, this%depvarunitabbrev)
807  case ('UZT6')
808  call uzt_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
809  pakname, this%fmi, this%eqnsclfac, this%depvartype, &
810  this%depvarunit, this%depvarunitabbrev)
811  case ('IST6')
812  call ist_create(packobj, ipakid, ipaknum, inunit, iout, this%name, &
813  pakname, this%fmi, this%mst)
814  case ('API6')
815  call api_create(packobj, ipakid, ipaknum, inunit, iout, this%name, pakname)
816  case default
817  write (errmsg, *) 'Invalid package type: ', filtyp
818  call store_error(errmsg, terminate=.true.)
819  end select
820  !
821  ! -- Packages is the bndlist that is associated with the parent model
822  ! -- The following statement puts a pointer to this package in the ipakid
823  ! -- position of packages.
824  do ip = 1, this%bndlist%Count()
825  packobj2 => getbndfromlist(this%bndlist, ip)
826  if (packobj2%packName == pakname) then
827  write (errmsg, '(a,a)') 'Cannot create package. Package name '// &
828  'already exists: ', trim(pakname)
829  call store_error(errmsg, terminate=.true.)
830  end if
831  end do
832  call addbndtolist(this%bndlist, packobj)
833  !
834  ! -- Return
835  return
836  end subroutine package_create
837 
838  !> @brief Cast to GwtModelType
839  !<
840  function castasgwtmodel(model) result(gwtmodel)
841  class(*), pointer :: model !< The object to be cast
842  class(gwtmodeltype), pointer :: gwtmodel !< The GWT model
843  !
844  gwtmodel => null()
845  if (.not. associated(model)) return
846  select type (model)
847  type is (gwtmodeltype)
848  gwtmodel => model
849  end select
850  !
851  ! -- Return
852  return
853  end function castasgwtmodel
854 
855  !> @brief Source package info and begin to process
856  !<
857  subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, &
858  mempaths, inunits)
859  ! -- modules
862  ! -- dummy
863  class(gwtmodeltype) :: this
864  integer(I4B), dimension(:), allocatable, intent(inout) :: bndpkgs
865  type(characterstringtype), dimension(:), contiguous, &
866  pointer, intent(inout) :: pkgtypes
867  type(characterstringtype), dimension(:), contiguous, &
868  pointer, intent(inout) :: pkgnames
869  type(characterstringtype), dimension(:), contiguous, &
870  pointer, intent(inout) :: mempaths
871  integer(I4B), dimension(:), contiguous, &
872  pointer, intent(inout) :: inunits
873  ! -- local
874  integer(I4B) :: ipakid, ipaknum
875  character(len=LENFTYPE) :: pkgtype, bndptype
876  character(len=LENPACKAGENAME) :: pkgname
877  character(len=LENMEMPATH) :: mempath
878  integer(I4B), pointer :: inunit
879  integer(I4B) :: n
880  !
881  if (allocated(bndpkgs)) then
882  !
883  ! -- create stress packages
884  ipakid = 1
885  bndptype = ''
886  do n = 1, size(bndpkgs)
887  !
888  pkgtype = pkgtypes(bndpkgs(n))
889  pkgname = pkgnames(bndpkgs(n))
890  mempath = mempaths(bndpkgs(n))
891  inunit => inunits(bndpkgs(n))
892  !
893  if (bndptype /= pkgtype) then
894  ipaknum = 1
895  bndptype = pkgtype
896  end if
897  !
898  call this%package_create(pkgtype, ipakid, ipaknum, pkgname, mempath, &
899  inunit, this%iout)
900  ipakid = ipakid + 1
901  ipaknum = ipaknum + 1
902  end do
903  !
904  ! -- cleanup
905  deallocate (bndpkgs)
906  end if
907  !
908  ! -- Return
909  return
910  end subroutine create_bndpkgs
911 
912  !> @brief Source package info and begin to process
913  !<
914  subroutine create_gwt_packages(this, indis)
915  ! -- modules
922  use gwtmstmodule, only: mst_cr
923  use gwtdspmodule, only: dsp_cr
924  ! -- dummy
925  class(gwtmodeltype) :: this
926  integer(I4B), intent(in) :: indis
927  ! -- local
928  type(characterstringtype), dimension(:), contiguous, &
929  pointer :: pkgtypes => null()
930  type(characterstringtype), dimension(:), contiguous, &
931  pointer :: pkgnames => null()
932  type(characterstringtype), dimension(:), contiguous, &
933  pointer :: mempaths => null()
934  integer(I4B), dimension(:), contiguous, &
935  pointer :: inunits => null()
936  character(len=LENMEMPATH) :: model_mempath
937  character(len=LENFTYPE) :: pkgtype
938  character(len=LENPACKAGENAME) :: pkgname
939  character(len=LENMEMPATH) :: mempath
940  integer(I4B), pointer :: inunit
941  integer(I4B), dimension(:), allocatable :: bndpkgs
942  integer(I4B) :: n
943  character(len=LENMEMPATH) :: mempathdsp = ''
944  !
945  ! -- set input memory paths, input/model and input/model/namfile
946  model_mempath = create_mem_path(component=this%name, context=idm_context)
947  !
948  ! -- set pointers to model path package info
949  call mem_setptr(pkgtypes, 'PKGTYPES', model_mempath)
950  call mem_setptr(pkgnames, 'PKGNAMES', model_mempath)
951  call mem_setptr(mempaths, 'MEMPATHS', model_mempath)
952  call mem_setptr(inunits, 'INUNITS', model_mempath)
953  !
954  do n = 1, size(pkgtypes)
955  !
956  ! attributes for this input package
957  pkgtype = pkgtypes(n)
958  pkgname = pkgnames(n)
959  mempath = mempaths(n)
960  inunit => inunits(n)
961  !
962  ! -- create dis package as it is a prerequisite for other packages
963  select case (pkgtype)
964  case ('MST6')
965  this%inmst = inunit
966  case ('DSP6')
967  this%indsp = 1
968  mempathdsp = mempath
969  case ('CNC6', 'SRC6', 'LKT6', 'SFT6', &
970  'MWT6', 'UZT6', 'IST6', 'API6')
971  call expandarray(bndpkgs)
972  bndpkgs(size(bndpkgs)) = n
973  case default
974  ! TODO
975  end select
976  end do
977  !
978  ! -- Create packages that are tied directly to model
979  call mst_cr(this%mst, this%name, this%inmst, this%iout, this%fmi)
980  call dsp_cr(this%dsp, this%name, mempathdsp, this%indsp, this%iout, &
981  this%fmi)
982  !
983  ! -- Check to make sure that required ftype's have been specified
984  call this%ftype_check(indis, this%inmst)
985  !
986  call this%create_bndpkgs(bndpkgs, pkgtypes, pkgnames, mempaths, inunits)
987  !
988  ! -- Return
989  return
990  end subroutine create_gwt_packages
991 
992 end module gwtmodule
This module contains the API package methods.
Definition: gwf-api.f90:12
subroutine, public api_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname)
@ brief Create a new package object
Definition: gwf-api.f90:49
subroutine, public addbasemodeltolist(list, model)
Definition: BaseModel.f90:161
This module contains the base boundary package.
subroutine, public addbndtolist(list, bnd)
Add boundary to package list.
class(bndtype) function, pointer, public getbndfromlist(list, idx)
Get boundary from package list.
This module contains the BudgetModule.
Definition: Budget.f90:20
subroutine, public budget_cr(this, name_model)
@ brief Create a new budget object
Definition: Budget.f90:84
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:44
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:22
integer(i4b), parameter lenpackagetype
maximum length of a package type (DIS6, SFR6, CSUB6, etc.)
Definition: Constants.f90:37
real(dp), parameter dhnoflo
real no flow constant
Definition: Constants.f90:92
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:49
integer(i4b), parameter lenvarname
maximum length of a variable name
Definition: Constants.f90:17
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:38
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
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:26
real(dp), parameter done
real constant 1
Definition: Constants.f90:75
subroutine, public cnc_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, depvartype, mempath)
Create a new constant concentration or temperature package.
Definition: gwt-cnc.f90:58
subroutine, public dsp_cr(dspobj, name_model, input_mempath, inunit, iout, fmi)
Create a DSP object.
Definition: gwt-dsp.f90:78
– @ brief Immobile Storage and Transfer (IST) Module
Definition: gwt-ist.f90:14
subroutine, public ist_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi, mst)
@ brief Create a new package object
Definition: gwt-ist.f90:109
subroutine, public lkt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi, eqnsclfac, dvt, dvu, dvua)
Create a new lkt package.
Definition: gwt-lkt.f90:99
Definition: gwt.f90:8
subroutine gwt_ar(this)
GWT Model Allocate and Read.
Definition: gwt.f90:260
subroutine gwt_fc(this, kiter, matrix_sln, inwtflag)
GWT Model fill coefficients.
Definition: gwt.f90:424
subroutine gwt_cc(this, innertot, kiter, iend, icnvgmod, cpak, ipak, dpak)
GWT Model Final Convergence Check.
Definition: gwt.f90:476
character(len=lenvarname), parameter dvu
dependent variable unit of measure, either "mass" or "energy"
Definition: gwt.f90:32
integer(i4b), parameter niunit_gwt
Definition: gwt.f90:91
subroutine create_gwt_packages(this, indis)
Source package info and begin to process.
Definition: gwt.f90:915
subroutine gwt_mc(this, matrix_sln)
Map the positions of the GWT model connections in the numerical solution coefficient matrix.
Definition: gwt.f90:230
character(len=lenvarname), parameter dvua
abbreviation of the dependent variable unit of measure, either "M" or "E"
Definition: gwt.f90:33
subroutine gwt_cq(this, icnvg, isuppress_output)
GWT Model calculate flow.
Definition: gwt.f90:500
subroutine gwt_bd(this, icnvg, isuppress_output)
GWT Model Budget.
Definition: gwt.f90:551
subroutine allocate_scalars(this, modelname)
Allocate memory for non-allocatable members.
Definition: gwt.f90:735
subroutine gwt_ot(this)
Print and/or save model output.
Definition: gwt.f90:586
subroutine gwt_da(this)
Deallocate.
Definition: gwt.f90:613
class(gwtmodeltype) function, pointer, public castasgwtmodel(model)
Cast to GwtModelType.
Definition: gwt.f90:841
integer(i4b), parameter, public gwt_nbasepkg
GWT base package array descriptors.
Definition: gwt.f90:71
subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, mempaths, inunits)
Source package info and begin to process.
Definition: gwt.f90:859
character(len=lenpackagetype), dimension(gwt_nmultipkg), public gwt_multipkg
Definition: gwt.f90:85
subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, inunit, iout)
Create boundary condition packages for this model.
Definition: gwt.f90:761
subroutine gwt_ac(this, sparse)
Add the internal connections of this model to the sparse matrix.
Definition: gwt.f90:202
integer(i4b) function gwt_get_iasym(this)
return 1 if any package causes the matrix to be asymmetric. Otherwise return 0.
Definition: gwt.f90:699
subroutine gwt_df(this)
Define packages of the GWT model.
Definition: gwt.f90:147
subroutine gwt_ad(this)
GWT Model Time Step Advance.
Definition: gwt.f90:345
subroutine gwt_cf(this, kiter)
GWT Model calculate coefficients.
Definition: gwt.f90:401
subroutine gwt_rp(this)
GWT Model Read and Prepare.
Definition: gwt.f90:312
subroutine, public gwt_cr(filename, id, modelname)
Create a new groundwater transport model object.
Definition: gwt.f90:98
character(len=lenpackagetype), dimension(gwt_nbasepkg), public gwt_basepkg
Definition: gwt.f90:72
character(len=lenvarname), parameter dvt
dependent variable type, varies based on model type
Definition: gwt.f90:31
subroutine gwt_bdentry(this, budterm, budtxt, rowlabel)
GroundWater Transport Model Budget Entry.
Definition: gwt.f90:680
integer(i4b), parameter, public gwt_nmultipkg
GWT multi package array descriptors.
Definition: gwt.f90:84
– @ brief Mobile Storage and Transfer (MST) Module
Definition: gwt-mst.f90:10
subroutine, public mst_cr(mstobj, name_model, inunit, iout, fmi)
@ brief Create a new package object
Definition: gwt-mst.f90:98
subroutine, public mwt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi, eqnsclfac, dvt, dvu, dvua)
Create new MWT package.
Definition: gwt-mwt.f90:92
subroutine, public sft_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi, eqnsclfac, dvt, dvu, dvua)
Create a new sft package.
Definition: gwt-sft.f90:96
subroutine, public src_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, depvartype)
Create a source loading package.
Definition: gwt-src.f90:47
subroutine, public uzt_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi, eqnsclfac, dvt, dvu, dvua)
Create a new UZT package.
Definition: gwt-uzt.f90:85
This module defines variable data types.
Definition: kind.f90:8
type(listtype), public basemodellist
Definition: mf6lists.f90:16
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public memorylist_remove(component, subcomponent, context)
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_error(msg, terminate)
Store an error message.
Definition: Sim.f90:92
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=linelength) idm_context
integer(i4b) isimcheck
simulation input check flag (1) to check input, (0) to ignore checks
integer(i4b) ifailedstepretry
current retry for this time step
subroutine csr_diagsum(ia, flowja)
Definition: Sparse.f90:281
logical(lgp), pointer, public readnewdata
flag indicating time to read new data
Definition: tdis.f90:26
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
This module contains the base transport model type.
Definition: tsp.f90:7
Highest level model type. All models extend this parent type.
Definition: BaseModel.f90:13
@ brief BndType
Derived type for the Budget object.
Definition: Budget.f90:39
This class is used to store a single deferred-length character string. It was designed to work in an ...
Definition: CharString.f90:23
@ brief Mobile storage and transfer
Definition: gwt-mst.f90:37