MODFLOW 6  version 6.7.0.dev3
USGS Modular Hydrologic Model
prt.f90
Go to the documentation of this file.
1 module prtmodule
2  use kindmodule, only: dp, i4b, lgp
3  use errorutilmodule, only: pstop
12  use dismodule, only: distype, dis_cr
13  use disvmodule, only: disvtype, disv_cr
14  use disumodule, only: disutype, disu_cr
15  use prtprpmodule, only: prtprptype
16  use prtfmimodule, only: prtfmitype
17  use prtmipmodule, only: prtmiptype
18  use prtocmodule, only: prtoctype
19  use budgetmodule, only: budgettype
20  use listmodule, only: listtype
31 
32  implicit none
33 
34  private
35  public :: prt_cr
36  public :: prtmodeltype
37  public :: prt_nbasepkg, prt_nmultipkg
38  public :: prt_basepkg, prt_multipkg
39 
40  integer(I4B), parameter :: nbditems = 2
41  character(len=LENBUDTXT), dimension(NBDITEMS) :: budtxt
42  data budtxt/' STORAGE', ' TERMINATION'/
43 
44  !> @brief Particle tracking (PRT) model
45  type, extends(numericalmodeltype) :: prtmodeltype
46  type(prtfmitype), pointer :: fmi => null() ! flow model interface
47  type(prtmiptype), pointer :: mip => null() ! model input package
48  type(prtoctype), pointer :: oc => null() ! output control package
49  type(budgettype), pointer :: budget => null() ! budget object
50  class(methodtype), pointer :: method => null() ! tracking method
51  type(particleeventdispatchertype), pointer :: events => null() ! event dispatcher
52  class(particletrackstype), pointer :: tracks ! track output manager
53  integer(I4B), pointer :: infmi => null() ! unit number FMI
54  integer(I4B), pointer :: inmip => null() ! unit number MIP
55  integer(I4B), pointer :: inmvt => null() ! unit number MVT
56  integer(I4B), pointer :: inmst => null() ! unit number MST
57  integer(I4B), pointer :: inadv => null() ! unit number ADV
58  integer(I4B), pointer :: indsp => null() ! unit number DSP
59  integer(I4B), pointer :: inssm => null() ! unit number SSM
60  integer(I4B), pointer :: inoc => null() ! unit number OC
61  integer(I4B), pointer :: nprp => null() ! number of PRP packages in the model
62  real(dp), dimension(:), pointer, contiguous :: masssto => null() !< particle mass storage in cells, new value
63  real(dp), dimension(:), pointer, contiguous :: massstoold => null() !< particle mass storage in cells, old value
64  real(dp), dimension(:), pointer, contiguous :: ratesto => null() !< particle mass storage rate in cells
65  real(dp), dimension(:), pointer, contiguous :: masstrm => null() !< particle mass terminating in cells, new value
66  real(dp), dimension(:), pointer, contiguous :: ratetrm => null() !< particle mass termination rate in cells
67  type(hashtabletype), pointer :: trm_ids => null() !< terminated particle ids
68  contains
69  ! Override BaseModelType procs
70  procedure :: model_df => prt_df
71  procedure :: model_ar => prt_ar
72  procedure :: model_rp => prt_rp
73  procedure :: model_ad => prt_ad
74  procedure :: model_cq => prt_cq
75  procedure :: model_bd => prt_bd
76  procedure :: model_ot => prt_ot
77  procedure :: model_da => prt_da
78  procedure :: model_solve => prt_solve
79 
80  ! Private utilities
81  procedure :: allocate_scalars
82  procedure :: allocate_arrays
83  procedure, private :: package_create
84  procedure, private :: ftype_check
85  procedure, private :: prt_ot_flow
86  procedure, private :: prt_ot_saveflow
87  procedure, private :: prt_ot_printflow
88  procedure, private :: prt_ot_dv
89  procedure, private :: prt_ot_bdsummary
90  procedure, private :: prt_cq_budterms
91  procedure, private :: create_packages
92  procedure, private :: create_bndpkgs
93  procedure, private :: log_namfile_options
94 
95  end type prtmodeltype
96 
97  !> @brief PRT base package array descriptors
98  !!
99  !! PRT6 model base package types. Only listed packages are candidates
100  !! for input and these will be loaded in the order specified.
101  !<
102  integer(I4B), parameter :: prt_nbasepkg = 50
103  character(len=LENPACKAGETYPE), dimension(PRT_NBASEPKG) :: prt_basepkg
104  data prt_basepkg/'DIS6 ', 'DISV6', 'DISU6', 'IC6 ', 'MST6 ', & ! 5
105  &'ADV6 ', 'DSP6 ', 'SSM6 ', 'MIP6 ', 'CNC6 ', & ! 10
106  &'OC6 ', ' ', 'FMI6 ', ' ', 'IST6 ', & ! 15
107  &'LKT6 ', 'SFT6 ', 'MWT6 ', 'UZT6 ', 'MVT6 ', & ! 20
108  &'API6 ', ' ', ' ', ' ', ' ', & ! 25
109  25*' '/ ! 50
110 
111  !> @brief PRT multi package array descriptors
112  !!
113  !! PRT6 model multi-instance package types. Only listed packages are
114  !! candidates for input and these will be loaded in the order specified.
115  !<
116  integer(I4B), parameter :: prt_nmultipkg = 50
117  character(len=LENPACKAGETYPE), dimension(PRT_NMULTIPKG) :: prt_multipkg
118  data prt_multipkg/'PRP6 ', ' ', ' ', ' ', ' ', & ! 5
119  &45*' '/ ! 50
120 
121  ! size of supported model package arrays
122  integer(I4B), parameter :: niunit_prt = prt_nbasepkg + prt_nmultipkg
123 
124 contains
125 
126  !> @brief Create a new particle tracking model object
127  subroutine prt_cr(filename, id, modelname)
128  ! modules
129  use listsmodule, only: basemodellist
132  use compilerversion
137  ! dummy
138  character(len=*), intent(in) :: filename
139  integer(I4B), intent(in) :: id
140  character(len=*), intent(in) :: modelname
141  ! local
142  type(prtmodeltype), pointer :: this
143  class(basemodeltype), pointer :: model
144  character(len=LENMEMPATH) :: input_mempath
145  character(len=LINELENGTH) :: lst_fname
146  type(prtnamparamfoundtype) :: found
147 
148  ! Allocate a new PRT Model (this)
149  allocate (this)
150 
151  ! Set this before any allocs in the memory manager can be done
152  this%memoryPath = create_mem_path(modelname)
153 
154  ! Allocate event system and track output manager
155  allocate (this%events)
156  allocate (this%tracks)
157 
158  ! Allocate scalars and add model to basemodellist
159  call this%allocate_scalars(modelname)
160  model => this
161  call addbasemodeltolist(basemodellist, model)
162 
163  ! Assign variables
164  this%filename = filename
165  this%name = modelname
166  this%macronym = 'PRT'
167  this%id = id
168 
169  ! Set input model namfile memory path
170  input_mempath = create_mem_path(modelname, 'NAM', idm_context)
171 
172  ! Copy options from input context
173  call mem_set_value(this%iprpak, 'PRINT_INPUT', input_mempath, &
174  found%print_input)
175  call mem_set_value(this%iprflow, 'PRINT_FLOWS', input_mempath, &
176  found%print_flows)
177  call mem_set_value(this%ipakcb, 'SAVE_FLOWS', input_mempath, &
178  found%save_flows)
179 
180  ! Create the list file
181  call this%create_lstfile(lst_fname, filename, found%list, &
182  'PARTICLE TRACKING MODEL (PRT)')
183 
184  ! Activate save_flows if found
185  if (found%save_flows) then
186  this%ipakcb = -1
187  end if
188 
189  ! Create model packages
190  call this%create_packages()
191 
192  ! Create hash table for terminated particle ids
193  call hash_table_cr(this%trm_ids)
194 
195  ! Log options
196  if (this%iout > 0) then
197  call this%log_namfile_options(found)
198  end if
199 
200  end subroutine prt_cr
201 
202  !> @brief Define packages
203  !!
204  !! (1) call df routines for each package
205  !! (2) set variables and pointers
206  !<
207  subroutine prt_df(this)
208  ! modules
209  use prtprpmodule, only: prtprptype
210  ! dummy
211  class(prtmodeltype) :: this
212  ! local
213  integer(I4B) :: ip
214  class(bndtype), pointer :: packobj
215 
216  ! Define packages and utility objects
217  call this%dis%dis_df()
218  call this%fmi%fmi_df(this%dis, 1)
219  call this%oc%oc_df()
220  call this%budget%budget_df(niunit_prt, 'MASS', 'M')
221 
222  ! Define packages and assign iout for time series managers
223  do ip = 1, this%bndlist%Count()
224  packobj => getbndfromlist(this%bndlist, ip)
225  call packobj%bnd_df(this%dis%nodes, this%dis)
226  packobj%TsManager%iout = this%iout
227  packobj%TasManager%iout = this%iout
228  end do
229 
230  ! Allocate model arrays
231  call this%allocate_arrays()
232 
233  end subroutine prt_df
234 
235  !> @brief Allocate and read
236  !!
237  !! (1) allocates and reads packages part of this model,
238  !! (2) allocates memory for arrays part of this model object
239  !<
240  subroutine prt_ar(this)
241  ! modules
242  use constantsmodule, only: dhnoflo
243  use prtprpmodule, only: prtprptype
244  use prtmipmodule, only: prtmiptype
246  ! dummy
247  class(prtmodeltype) :: this
248  ! locals
249  integer(I4B) :: ip, nprp
250  class(bndtype), pointer :: packobj
251 
252  ! Set up basic packages
253  call this%fmi%fmi_ar(this%ibound)
254  if (this%inmip > 0) call this%mip%mip_ar()
255 
256  ! Set up output control and budget
257  call this%oc%oc_ar(this%dis, dhnoflo)
258  call this%budget%set_ibudcsv(this%oc%ibudcsv)
259 
260  ! Select tracking events
261  call this%tracks%select_events( &
262  this%oc%trackrelease, &
263  this%oc%trackfeatexit, &
264  this%oc%tracktimestep, &
265  this%oc%trackterminate, &
266  this%oc%trackweaksink, &
267  this%oc%trackusertime, &
268  this%oc%tracksubfexit, &
269  this%oc%trackdropped)
270 
271  ! Set up boundary pkgs and pkg-scoped track files
272  nprp = 0
273  do ip = 1, this%bndlist%Count()
274  packobj => getbndfromlist(this%bndlist, ip)
275  select type (packobj)
276  type is (prtprptype)
277  nprp = nprp + 1
278  call packobj%prp_set_pointers(this%ibound, this%mip%izone)
279  call packobj%bnd_ar()
280  call packobj%bnd_ar()
281  if (packobj%itrkout > 0) then
282  call this%tracks%init_file( &
283  packobj%itrkout, &
284  iprp=nprp)
285  end if
286  if (packobj%itrkcsv > 0) then
287  call this%tracks%init_file( &
288  packobj%itrkcsv, &
289  csv=.true., &
290  iprp=nprp)
291  end if
292  class default
293  call packobj%bnd_ar()
294  end select
295  end do
296 
297  ! Set up model-scoped track files
298  if (this%oc%itrkout > 0) &
299  call this%tracks%init_file(this%oc%itrkout)
300  if (this%oc%itrkcsv > 0) &
301  call this%tracks%init_file(this%oc%itrkcsv, csv=.true.)
302 
303  ! Set up the tracking method
304  select type (dis => this%dis)
305  type is (distype)
306  call method_dis%init( &
307  fmi=this%fmi, &
308  events=this%events, &
309  izone=this%mip%izone, &
310  flowja=this%flowja, &
311  porosity=this%mip%porosity, &
312  retfactor=this%mip%retfactor, &
313  tracktimes=this%oc%tracktimes)
314  this%method => method_dis
315  type is (disvtype)
316  call method_disv%init( &
317  fmi=this%fmi, &
318  events=this%events, &
319  izone=this%mip%izone, &
320  flowja=this%flowja, &
321  porosity=this%mip%porosity, &
322  retfactor=this%mip%retfactor, &
323  tracktimes=this%oc%tracktimes)
324  this%method => method_disv
325  end select
326 
327  ! Subscribe track output manager to events
328  call this%events%subscribe(this%tracks)
329 
330  ! Set verbose tracing if requested
331  if (this%oc%dump_event_trace) this%tracks%iout = 0
332  end subroutine prt_ar
333 
334  !> @brief Read and prepare (calls package read and prepare routines)
335  subroutine prt_rp(this)
336  use tdismodule, only: readnewdata
337  ! dummy
338  class(prtmodeltype) :: this
339  ! local
340  class(bndtype), pointer :: packobj
341  integer(I4B) :: ip
342 
343  ! Check with TDIS on whether or not it is time to RP
344  if (.not. readnewdata) return
345 
346  ! Read and prepare
347  if (this%inoc > 0) call this%oc%oc_rp()
348  do ip = 1, this%bndlist%Count()
349  packobj => getbndfromlist(this%bndlist, ip)
350  call packobj%bnd_rp()
351  end do
352  end subroutine prt_rp
353 
354  !> @brief Time step advance (calls package advance subroutines)
355  subroutine prt_ad(this)
356  ! modules
358  ! dummy
359  class(prtmodeltype) :: this
360  class(bndtype), pointer :: packobj
361  ! local
362  integer(I4B) :: irestore
363  integer(I4B) :: ip, n, i
364 
365  ! Reset state variable
366  irestore = 0
367  if (ifailedstepretry > 0) irestore = 1
368 
369  ! Update look-behind mass
370  do n = 1, this%dis%nodes
371  this%massstoold(n) = this%masssto(n)
372  end do
373 
374  ! Advance fmi
375  call this%fmi%fmi_ad()
376 
377  ! Advance
378  do ip = 1, this%bndlist%Count()
379  packobj => getbndfromlist(this%bndlist, ip)
380  call packobj%bnd_ad()
381  if (isimcheck > 0) then
382  call packobj%bnd_ck()
383  end if
384  end do
385  !
386  ! Initialize the flowja array. Flowja is calculated each time,
387  ! even if output is suppressed. (Flowja represents flow of particle
388  ! mass and is positive into a cell. Currently, each particle is assigned
389  ! unit mass.) Flowja is updated continually as particles are tracked
390  ! over the time step and at the end of the time step. The diagonal
391  ! position of the flowja array will contain the flow residual.
392  do i = 1, this%dis%nja
393  this%flowja(i) = dzero
394  end do
395  end subroutine prt_ad
396 
397  !> @brief Calculate intercell flow (flowja)
398  subroutine prt_cq(this, icnvg, isuppress_output)
399  ! modules
400  use sparsemodule, only: csr_diagsum
401  use tdismodule, only: delt
402  use prtprpmodule, only: prtprptype
403  ! dummy
404  class(prtmodeltype) :: this
405  integer(I4B), intent(in) :: icnvg
406  integer(I4B), intent(in) :: isuppress_output
407  ! local
408  integer(I4B) :: i
409  integer(I4B) :: ip
410  class(bndtype), pointer :: packobj
411  real(DP) :: tled
412 
413  ! Flowja is calculated each time, even if output is suppressed.
414  ! Flowja represents flow of particle mass and is positive into a cell.
415  ! Currently, each particle is assigned unit mass.
416  !
417  ! Reciprocal of time step size.
418  tled = done / delt
419  !
420  ! Flowja was updated continually as particles were tracked over the
421  ! time step. At this point, flowja contains the net particle mass
422  ! exchanged between cells during the time step. To convert these to
423  ! flow rates (particle mass per time), divide by the time step size.
424  do i = 1, this%dis%nja
425  this%flowja(i) = this%flowja(i) * tled
426  end do
427 
428  ! Particle mass budget terms
429  call this%prt_cq_budterms()
430 
431  ! Go through packages and call cq routines. Just a formality.
432  do ip = 1, this%bndlist%Count()
433  packobj => getbndfromlist(this%bndlist, ip)
434  call packobj%bnd_cq(this%masssto, this%flowja)
435  end do
436 
437  ! Finalize calculation of flowja by adding face flows to the diagonal.
438  ! This results in the flow residual being stored in the diagonal
439  ! position for each cell.
440  call csr_diagsum(this%dis%con%ia, this%flowja)
441  end subroutine prt_cq
442 
443  !> @brief Calculate particle mass budget terms
444  subroutine prt_cq_budterms(this)
445  ! modules
446  use tdismodule, only: delt
447  use prtprpmodule, only: prtprptype
448  ! dummy
449  class(prtmodeltype) :: this
450  ! local
451  integer(I4B) :: ip
452  class(bndtype), pointer :: packobj
453  integer(I4B) :: n
454  integer(I4B) :: np
455  integer(I4B) :: idiag
456  integer(I4B) :: iprp
457  integer(I4B) :: istatus
458  real(DP) :: tled
459  real(DP) :: ratesto, ratetrm
460  character(len=:), allocatable :: particle_id
461  type(particletype), pointer :: particle
462 
463  call create_particle(particle)
464 
465  ! Reciprocal of time step size.
466  tled = done / delt
467 
468  ! Reset mass and rate arrays
469  do n = 1, this%dis%nodes
470  this%masssto(n) = dzero
471  this%masstrm(n) = dzero
472  this%ratesto(n) = dzero
473  this%ratetrm(n) = dzero
474  end do
475 
476  ! Loop over PRP packages and assign particle mass to the
477  ! appropriate budget term based on the particle status.
478  iprp = 0
479  do ip = 1, this%bndlist%Count()
480  packobj => getbndfromlist(this%bndlist, ip)
481  select type (packobj)
482  type is (prtprptype)
483  do np = 1, packobj%nparticles
484  call packobj%particles%get(particle, this%id, iprp, np)
485  istatus = packobj%particles%istatus(np)
486  particle_id = particle%get_id()
487  if (istatus == active) then
488  ! calculate storage mass
489  n = packobj%particles%itrdomain(np, level_feature)
490  this%masssto(n) = this%masssto(n) + done ! unit mass
491  else if (istatus > active) then
492  if (this%trm_ids%get(particle_id) /= 0) cycle
493  ! calculate terminating mass
494  n = packobj%particles%itrdomain(np, level_feature)
495  this%masstrm(n) = this%masstrm(n) + done ! unit mass
496  call this%trm_ids%add(particle_id, 1) ! mark id terminated
497  end if
498  end do
499  end select
500  end do
501 
502  ! Calculate rates and update flowja
503  do n = 1, this%dis%nodes
504  ratesto = -(this%masssto(n) - this%massstoold(n)) * tled
505  ratetrm = -this%masstrm(n) * tled
506  this%ratesto(n) = ratesto
507  this%ratetrm(n) = ratetrm
508  idiag = this%dis%con%ia(n)
509  this%flowja(idiag) = this%flowja(idiag) + ratesto
510  end do
511 
512  call particle%destroy()
513  deallocate (particle)
514 
515  end subroutine prt_cq_budterms
516 
517  !> @brief Calculate flows and budget
518  !!
519  !! (1) Calculate intercell flows (flowja)
520  !! (2) Calculate package contributions to model budget
521  !!
522  !<
523  subroutine prt_bd(this, icnvg, isuppress_output)
524  ! modules
525  use tdismodule, only: delt
526  use budgetmodule, only: rate_accumulator
527  ! dummy
528  class(prtmodeltype) :: this
529  integer(I4B), intent(in) :: icnvg
530  integer(I4B), intent(in) :: isuppress_output
531  ! local
532  integer(I4B) :: ip
533  class(bndtype), pointer :: packobj
534  real(DP) :: rin
535  real(DP) :: rout
536 
537  ! Budget routines (start by resetting). Sole purpose of this section
538  ! is to add in and outs to model budget. All ins and out for a model
539  ! should be added here to this%budget. In a subsequent exchange call,
540  ! exchange flows might also be added.
541  call this%budget%reset()
542  ! storage term
543  call rate_accumulator(this%ratesto, rin, rout)
544  call this%budget%addentry(rin, rout, delt, budtxt(1), &
545  isuppress_output, ' PRT')
546  ! termination term
547  call rate_accumulator(this%ratetrm, rin, rout)
548  call this%budget%addentry(rin, rout, delt, budtxt(2), &
549  isuppress_output, ' PRT')
550  ! boundary packages
551  do ip = 1, this%bndlist%Count()
552  packobj => getbndfromlist(this%bndlist, ip)
553  call packobj%bnd_bd(this%budget)
554  end do
555  end subroutine prt_bd
556 
557  !> @brief Print and/or save model output
558  subroutine prt_ot(this)
559  use tdismodule, only: tdis_ot, endofperiod
560  ! dummy
561  class(prtmodeltype) :: this
562  ! local
563  integer(I4B) :: idvsave
564  integer(I4B) :: idvprint
565  integer(I4B) :: icbcfl
566  integer(I4B) :: icbcun
567  integer(I4B) :: ibudfl
568  integer(I4B) :: ipflag
569 
570  ! Note: particle tracking output is handled elsewhere
571 
572  ! Set write and print flags
573  idvsave = 0
574  idvprint = 0
575  icbcfl = 0
576  ibudfl = 0
577  if (this%oc%oc_save('CONCENTRATION')) idvsave = 1
578  if (this%oc%oc_print('CONCENTRATION')) idvprint = 1
579  if (this%oc%oc_save('BUDGET')) icbcfl = 1
580  if (this%oc%oc_print('BUDGET')) ibudfl = 1
581  icbcun = this%oc%oc_save_unit('BUDGET')
582 
583  ! Override ibudfl and idvprint flags for nonconvergence
584  ! and end of period
585  ibudfl = this%oc%set_print_flag('BUDGET', 1, endofperiod)
586  idvprint = this%oc%set_print_flag('CONCENTRATION', 1, endofperiod)
587 
588  ! Save and print flows
589  call this%prt_ot_flow(icbcfl, ibudfl, icbcun)
590 
591  ! Save and print dependent variables
592  call this%prt_ot_dv(idvsave, idvprint, ipflag)
593 
594  ! Print budget summaries
595  call this%prt_ot_bdsummary(ibudfl, ipflag)
596 
597  ! Timing Output; if any dependent variables or budgets
598  ! are printed, then ipflag is set to 1.
599  if (ipflag == 1) call tdis_ot(this%iout)
600  end subroutine prt_ot
601 
602  !> @brief Save flows
603  subroutine prt_ot_flow(this, icbcfl, ibudfl, icbcun)
604  use prtprpmodule, only: prtprptype
605  class(prtmodeltype) :: this
606  integer(I4B), intent(in) :: icbcfl
607  integer(I4B), intent(in) :: ibudfl
608  integer(I4B), intent(in) :: icbcun
609  class(bndtype), pointer :: packobj
610  integer(I4B) :: ip
611 
612  ! Save PRT flows
613  call this%prt_ot_saveflow(this%dis%nja, this%flowja, icbcfl, icbcun)
614  do ip = 1, this%bndlist%Count()
615  packobj => getbndfromlist(this%bndlist, ip)
616  call packobj%bnd_ot_model_flows(icbcfl=icbcfl, ibudfl=0, icbcun=icbcun)
617  end do
618 
619  ! Save advanced package flows
620  do ip = 1, this%bndlist%Count()
621  packobj => getbndfromlist(this%bndlist, ip)
622  call packobj%bnd_ot_package_flows(icbcfl=icbcfl, ibudfl=0)
623  end do
624 
625  ! Print PRT flows
626  call this%prt_ot_printflow(ibudfl, this%flowja)
627  do ip = 1, this%bndlist%Count()
628  packobj => getbndfromlist(this%bndlist, ip)
629  call packobj%bnd_ot_model_flows(icbcfl=icbcfl, ibudfl=ibudfl, icbcun=0)
630  end do
631 
632  ! Print advanced package flows
633  do ip = 1, this%bndlist%Count()
634  packobj => getbndfromlist(this%bndlist, ip)
635  call packobj%bnd_ot_package_flows(icbcfl=0, ibudfl=ibudfl)
636  end do
637  end subroutine prt_ot_flow
638 
639  !> @brief Save intercell flows
640  subroutine prt_ot_saveflow(this, nja, flowja, icbcfl, icbcun)
641  ! dummy
642  class(prtmodeltype) :: this
643  integer(I4B), intent(in) :: nja
644  real(DP), dimension(nja), intent(in) :: flowja
645  integer(I4B), intent(in) :: icbcfl
646  integer(I4B), intent(in) :: icbcun
647  ! local
648  integer(I4B) :: ibinun
649  integer(I4B) :: naux
650  real(DP), dimension(0) :: auxrow
651  character(len=LENAUXNAME), dimension(0) :: auxname
652  logical(LGP) :: header_written
653  integer(I4B) :: i, nn
654  real(DP) :: m
655  integer(I4B) :: nsto, ntrm
656  logical(LGP), allocatable :: msto_mask(:), mtrm_mask(:)
657  integer(I4B), allocatable :: msto_nns(:), mtrm_nns(:)
658  real(DP), allocatable :: msto_vals(:), mtrm_vals(:)
659 
660  ! Set unit number for binary output
661  if (this%ipakcb < 0) then
662  ibinun = icbcun
663  elseif (this%ipakcb == 0) then
664  ibinun = 0
665  else
666  ibinun = this%ipakcb
667  end if
668  if (icbcfl == 0) ibinun = 0
669 
670  ! Return if nothing to do
671  if (ibinun == 0) return
672 
673  ! Write mass face flows
674  call this%dis%record_connection_array(flowja, ibinun, this%iout)
675 
676  ! Write mass storage term
677  naux = 0
678  header_written = .false.
679  msto_mask = this%masssto > dzero
680  msto_vals = pack(this%masssto, msto_mask)
681  msto_nns = [(i, i=1, size(this%masssto))]
682  msto_nns = pack(msto_nns, msto_mask)
683  nsto = size(msto_nns)
684  do i = 1, nsto
685  nn = msto_nns(i)
686  m = msto_vals(i)
687  if (.not. header_written) then
688  call this%dis%record_srcdst_list_header(budtxt(1), &
689  'PRT ', &
690  'PRT ', &
691  'PRT ', &
692  'STORAGE ', &
693  naux, auxname, ibinun, &
694  nsto, this%iout)
695  header_written = .true.
696  end if
697  call this%dis%record_mf6_list_entry(ibinun, nn, nn, m, &
698  0, auxrow, &
699  olconv2=.false.)
700  end do
701 
702  ! Write mass termination term
703  header_written = .false.
704  mtrm_mask = this%masstrm > dzero
705  mtrm_vals = pack(this%masstrm, mtrm_mask)
706  mtrm_nns = [(i, i=1, size(this%masstrm))]
707  mtrm_nns = pack(mtrm_nns, mtrm_mask)
708  ntrm = size(mtrm_nns)
709  do i = 1, ntrm
710  nn = mtrm_nns(i)
711  m = mtrm_vals(i)
712  if (.not. header_written) then
713  call this%dis%record_srcdst_list_header(budtxt(2), &
714  'PRT ', &
715  'PRT ', &
716  'PRT ', &
717  'TERMINATION ', &
718  naux, auxname, ibinun, &
719  ntrm, this%iout)
720  header_written = .true.
721  end if
722  call this%dis%record_mf6_list_entry(ibinun, nn, nn, m, &
723  0, auxrow, &
724  olconv2=.false.)
725  end do
726 
727  end subroutine prt_ot_saveflow
728 
729  !> @brief Print intercell flows
730  subroutine prt_ot_printflow(this, ibudfl, flowja)
731  ! modules
732  use tdismodule, only: kper, kstp
733  use constantsmodule, only: lenbigline
734  ! dummy
735  class(prtmodeltype) :: this
736  integer(I4B), intent(in) :: ibudfl
737  real(DP), intent(inout), dimension(:) :: flowja
738  ! local
739  character(len=LENBIGLINE) :: line
740  character(len=30) :: tempstr
741  integer(I4B) :: n, ipos, m
742  real(DP) :: qnm
743  ! formats
744  character(len=*), parameter :: fmtiprflow = &
745  "(/,4x,'CALCULATED INTERCELL FLOW &
746  &FOR PERIOD ', i0, ' STEP ', i0)"
747 
748  ! Write flowja to list file if requested
749  if (ibudfl /= 0 .and. this%iprflow > 0) then
750  write (this%iout, fmtiprflow) kper, kstp
751  do n = 1, this%dis%nodes
752  line = ''
753  call this%dis%noder_to_string(n, tempstr)
754  line = trim(tempstr)//':'
755  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
756  m = this%dis%con%ja(ipos)
757  call this%dis%noder_to_string(m, tempstr)
758  line = trim(line)//' '//trim(tempstr)
759  qnm = flowja(ipos)
760  write (tempstr, '(1pg15.6)') qnm
761  line = trim(line)//' '//trim(adjustl(tempstr))
762  end do
763  write (this%iout, '(a)') trim(line)
764  end do
765  end if
766  end subroutine prt_ot_printflow
767 
768  !> @brief Print dependent variables
769  subroutine prt_ot_dv(this, idvsave, idvprint, ipflag)
770  ! dummy
771  class(prtmodeltype) :: this
772  integer(I4B), intent(in) :: idvsave
773  integer(I4B), intent(in) :: idvprint
774  integer(I4B), intent(inout) :: ipflag
775  ! local
776  class(bndtype), pointer :: packobj
777  integer(I4B) :: ip
778 
779  ! Print advanced package dependent variables
780  do ip = 1, this%bndlist%Count()
781  packobj => getbndfromlist(this%bndlist, ip)
782  call packobj%bnd_ot_dv(idvsave, idvprint)
783  end do
784 
785  ! save head and print head
786  call this%oc%oc_ot(ipflag)
787  end subroutine prt_ot_dv
788 
789  !> @brief Print budget summary
790  subroutine prt_ot_bdsummary(this, ibudfl, ipflag)
791  ! modules
792  use tdismodule, only: kstp, kper, totim, delt
793  ! dummy
794  class(prtmodeltype) :: this
795  integer(I4B), intent(in) :: ibudfl
796  integer(I4B), intent(inout) :: ipflag
797  ! local
798  class(bndtype), pointer :: packobj
799  integer(I4B) :: ip
800 
801  ! Package budget summary
802  do ip = 1, this%bndlist%Count()
803  packobj => getbndfromlist(this%bndlist, ip)
804  call packobj%bnd_ot_bdsummary(kstp, kper, this%iout, ibudfl)
805  end do
806 
807  ! model budget summary
808  call this%budget%finalize_step(delt)
809  if (ibudfl /= 0) then
810  ipflag = 1
811  ! model budget summary
812  call this%budget%budget_ot(kstp, kper, this%iout)
813  end if
814 
815  ! Write to budget csv
816  call this%budget%writecsv(totim)
817  end subroutine prt_ot_bdsummary
818 
819  !> @brief Deallocate
820  subroutine prt_da(this)
821  ! modules
828  ! dummy
829  class(prtmodeltype) :: this
830  ! local
831  integer(I4B) :: ip
832  class(bndtype), pointer :: packobj
833 
834  ! Deallocate idm memory
835  call memorystore_remove(this%name, 'NAM', idm_context)
836  call memorystore_remove(component=this%name, context=idm_context)
837 
838  ! Internal packages
839  call this%dis%dis_da()
840  call this%fmi%fmi_da()
841  call this%mip%mip_da()
842  call this%budget%budget_da()
843  call this%oc%oc_da()
844  deallocate (this%dis)
845  deallocate (this%fmi)
846  deallocate (this%mip)
847  deallocate (this%budget)
848  deallocate (this%oc)
849 
850  ! Method objects
853  call destroy_method_pool()
854 
855  ! Boundary packages
856  do ip = 1, this%bndlist%Count()
857  packobj => getbndfromlist(this%bndlist, ip)
858  call packobj%bnd_da()
859  deallocate (packobj)
860  end do
861 
862  ! Scalars
863  call mem_deallocate(this%infmi)
864  call mem_deallocate(this%inmip)
865  call mem_deallocate(this%inadv)
866  call mem_deallocate(this%indsp)
867  call mem_deallocate(this%inssm)
868  call mem_deallocate(this%inmst)
869  call mem_deallocate(this%inmvt)
870  call mem_deallocate(this%inoc)
871 
872  ! Arrays
873  call mem_deallocate(this%masssto)
874  call mem_deallocate(this%massstoold)
875  call mem_deallocate(this%ratesto)
876  call mem_deallocate(this%masstrm)
877  call mem_deallocate(this%ratetrm)
878 
879  call this%tracks%destroy()
880  deallocate (this%events)
881  deallocate (this%tracks)
882 
883  call this%NumericalModelType%model_da()
884  end subroutine prt_da
885 
886  !> @brief Allocate memory for scalars
887  subroutine allocate_scalars(this, modelname)
888  ! dummy
889  class(prtmodeltype) :: this
890  character(len=*), intent(in) :: modelname
891 
892  ! allocate members from parent class
893  call this%NumericalModelType%allocate_scalars(modelname)
894 
895  ! allocate members that are part of model class
896  call mem_allocate(this%infmi, 'INFMI', this%memoryPath)
897  call mem_allocate(this%inmip, 'INMIP', this%memoryPath)
898  call mem_allocate(this%inmvt, 'INMVT', this%memoryPath)
899  call mem_allocate(this%inmst, 'INMST', this%memoryPath)
900  call mem_allocate(this%inadv, 'INADV', this%memoryPath)
901  call mem_allocate(this%indsp, 'INDSP', this%memoryPath)
902  call mem_allocate(this%inssm, 'INSSM', this%memoryPath)
903  call mem_allocate(this%inoc, 'INOC ', this%memoryPath)
904 
905  this%infmi = 0
906  this%inmip = 0
907  this%inmvt = 0
908  this%inmst = 0
909  this%inadv = 0
910  this%indsp = 0
911  this%inssm = 0
912  this%inoc = 0
913  end subroutine allocate_scalars
914 
915  !> @brief Allocate arrays
916  subroutine allocate_arrays(this)
918  class(prtmodeltype) :: this
919  integer(I4B) :: n
920 
921  ! Allocate arrays in parent type
922  this%nja = this%dis%nja
923  call this%NumericalModelType%allocate_arrays()
924 
925  ! Allocate and initialize arrays
926  call mem_allocate(this%masssto, this%dis%nodes, &
927  'MASSSTO', this%memoryPath)
928  call mem_allocate(this%massstoold, this%dis%nodes, &
929  'MASSSTOOLD', this%memoryPath)
930  call mem_allocate(this%ratesto, this%dis%nodes, &
931  'RATESTO', this%memoryPath)
932  call mem_allocate(this%masstrm, this%dis%nodes, &
933  'MASSTRM', this%memoryPath)
934  call mem_allocate(this%ratetrm, this%dis%nodes, &
935  'RATETRM', this%memoryPath)
936  ! explicit model, so these must be manually allocated
937  call mem_allocate(this%x, this%dis%nodes, 'X', this%memoryPath)
938  call mem_allocate(this%rhs, this%dis%nodes, 'RHS', this%memoryPath)
939  call mem_allocate(this%ibound, this%dis%nodes, 'IBOUND', this%memoryPath)
940  do n = 1, this%dis%nodes
941  this%masssto(n) = dzero
942  this%massstoold(n) = dzero
943  this%ratesto(n) = dzero
944  this%masstrm(n) = dzero
945  this%ratetrm(n) = dzero
946  this%x(n) = dzero
947  this%rhs(n) = dzero
948  this%ibound(n) = 1
949  end do
950  end subroutine allocate_arrays
951 
952  !> @brief Create boundary condition packages for this model
953  subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, &
954  inunit, iout)
955  ! modules
956  use constantsmodule, only: linelength
957  use prtprpmodule, only: prp_create
958  use apimodule, only: api_create
959  ! dummy
960  class(prtmodeltype) :: this
961  character(len=*), intent(in) :: filtyp
962  character(len=LINELENGTH) :: errmsg
963  integer(I4B), intent(in) :: ipakid
964  integer(I4B), intent(in) :: ipaknum
965  character(len=*), intent(in) :: pakname
966  character(len=*), intent(in) :: mempath
967  integer(I4B), intent(in) :: inunit
968  integer(I4B), intent(in) :: iout
969  ! local
970  class(bndtype), pointer :: packobj
971  class(bndtype), pointer :: packobj2
972  integer(I4B) :: ip
973 
974  ! This part creates the package object
975  select case (filtyp)
976  case ('PRP6')
977  call prp_create(packobj, ipakid, ipaknum, inunit, iout, &
978  this%name, pakname, mempath, this%fmi)
979  case ('API6')
980  call api_create(packobj, ipakid, ipaknum, inunit, iout, &
981  this%name, pakname, mempath)
982  case default
983  write (errmsg, *) 'Invalid package type: ', filtyp
984  call store_error(errmsg, terminate=.true.)
985  end select
986 
987  ! Packages is the bndlist that is associated with the parent model
988  ! The following statement puts a pointer to this package in the ipakid
989  ! position of packages.
990  do ip = 1, this%bndlist%Count()
991  packobj2 => getbndfromlist(this%bndlist, ip)
992  if (packobj2%packName == pakname) then
993  write (errmsg, '(a,a)') 'Cannot create package. Package name '// &
994  'already exists: ', trim(pakname)
995  call store_error(errmsg, terminate=.true.)
996  end if
997  end do
998  call addbndtolist(this%bndlist, packobj)
999  end subroutine package_create
1000 
1001  !> @brief Check to make sure required input files have been specified
1002  subroutine ftype_check(this, indis)
1003  ! dummy
1004  class(prtmodeltype) :: this
1005  integer(I4B), intent(in) :: indis
1006  ! local
1007  character(len=LINELENGTH) :: errmsg
1008 
1009  ! Check for DIS(u) and MIP. Stop if not present.
1010  if (indis == 0) then
1011  write (errmsg, '(1x,a)') &
1012  'Discretization (DIS6, DISV6, or DISU6) package not specified.'
1013  call store_error(errmsg)
1014  end if
1015  if (this%inmip == 0) then
1016  write (errmsg, '(1x,a)') &
1017  'Model input (MIP6) package not specified.'
1018  call store_error(errmsg)
1019  end if
1020 
1021  if (count_errors() > 0) then
1022  write (errmsg, '(1x,a)') 'One or more required package(s) not specified.'
1023  call store_error(errmsg)
1024  call store_error_filename(this%filename)
1025  end if
1026  end subroutine ftype_check
1027 
1028  !> @brief Solve the model
1029  subroutine prt_solve(this)
1030  use tdismodule, only: totimc, delt, endofsimulation
1031  use prtprpmodule, only: prtprptype
1034  ! dummy
1035  class(prtmodeltype) :: this
1036  ! local
1037  integer(I4B) :: np, ip
1038  class(bndtype), pointer :: packobj
1039  type(particletype), pointer :: particle
1040  real(DP) :: tmax
1041  integer(I4B) :: iprp
1042 
1043  ! A single particle is reused in the tracking loops
1044  ! to avoid allocating and deallocating it each time.
1045  ! get() and put() retrieve and store particle state.
1046  call create_particle(particle)
1047  ! Loop over PRP packages and particles within them.
1048  iprp = 0
1049  do ip = 1, this%bndlist%Count()
1050  packobj => getbndfromlist(this%bndlist, ip)
1051  select type (packobj)
1052  type is (prtprptype)
1053  iprp = iprp + 1
1054  do np = 1, packobj%nparticles
1055  ! Get the particle from the store
1056  call packobj%particles%get(particle, this%id, iprp, np)
1057  ! If particle is permanently unreleased, cycle.
1058  ! Raise a termination event if we haven't yet.
1059  ! TODO: when we have generic dynamic vectors,
1060  ! consider terminating permanently unreleased
1061  ! in PRP instead of here. For now, status -8
1062  ! indicates the permanently unreleased event
1063  ! is not yet recorded, status 8 it has been.
1064  if (particle%istatus == (-1 * term_unreleased)) then
1065  call this%method%terminate(particle, status=term_unreleased)
1066  call packobj%particles%put(particle, np)
1067  end if
1068  if (particle%istatus > active) cycle ! Skip terminated particles
1069  particle%istatus = active ! Set active status in case of release
1070  ! If the particle was released this time step, emit a release event
1071  if (particle%trelease >= totimc) call this%method%release(particle)
1072  ! Maximum time is the end of the time step or the particle
1073  ! stop time, whichever comes first, unless it's the final
1074  ! time step and the extend option is on, in which case
1075  ! it's just the particle stop time.
1076  if (endofsimulation .and. particle%extend) then
1077  tmax = particle%tstop
1078  else
1079  tmax = min(totimc + delt, particle%tstop)
1080  end if
1081  ! Apply the tracking method until the maximum time.
1082  call this%method%apply(particle, tmax)
1083  ! If the particle timed out, terminate it.
1084  ! "Timed out" means it's still active but
1085  ! - it reached its stop time, or
1086  ! - the simulation is over and not extended.
1087  ! We can't detect timeout within the tracking
1088  ! method because the method just receives the
1089  ! maximum time with no context on what it is.
1090  ! TODO maybe think about changing that?
1091  if (particle%istatus <= active .and. &
1092  (particle%ttrack == particle%tstop .or. &
1093  (endofsimulation .and. .not. particle%extend))) &
1094  call this%method%terminate(particle, status=term_timeout)
1095  ! Return the particle to the store
1096  call packobj%particles%put(particle, np)
1097  end do
1098  end select
1099  end do
1100  call particle%destroy()
1101  deallocate (particle)
1102  end subroutine prt_solve
1103 
1104  !> @brief Source package info and begin to process
1105  subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, &
1106  mempaths, inunits)
1107  ! modules
1110  ! dummy
1111  class(prtmodeltype) :: this
1112  integer(I4B), dimension(:), allocatable, intent(inout) :: bndpkgs
1113  type(characterstringtype), dimension(:), contiguous, &
1114  pointer, intent(inout) :: pkgtypes
1115  type(characterstringtype), dimension(:), contiguous, &
1116  pointer, intent(inout) :: pkgnames
1117  type(characterstringtype), dimension(:), contiguous, &
1118  pointer, intent(inout) :: mempaths
1119  integer(I4B), dimension(:), contiguous, &
1120  pointer, intent(inout) :: inunits
1121  ! local
1122  integer(I4B) :: ipakid, ipaknum
1123  character(len=LENFTYPE) :: pkgtype, bndptype
1124  character(len=LENPACKAGENAME) :: pkgname
1125  character(len=LENMEMPATH) :: mempath
1126  integer(I4B), pointer :: inunit
1127  integer(I4B) :: n
1128 
1129  if (allocated(bndpkgs)) then
1130  ! create stress packages
1131  ipakid = 1
1132  bndptype = ''
1133  do n = 1, size(bndpkgs)
1134  pkgtype = pkgtypes(bndpkgs(n))
1135  pkgname = pkgnames(bndpkgs(n))
1136  mempath = mempaths(bndpkgs(n))
1137  inunit => inunits(bndpkgs(n))
1138 
1139  if (bndptype /= pkgtype) then
1140  ipaknum = 1
1141  bndptype = pkgtype
1142  end if
1143 
1144  call this%package_create(pkgtype, ipakid, ipaknum, pkgname, mempath, &
1145  inunit, this%iout)
1146  ipakid = ipakid + 1
1147  ipaknum = ipaknum + 1
1148  end do
1149 
1150  ! cleanup
1151  deallocate (bndpkgs)
1152  end if
1153 
1154  end subroutine create_bndpkgs
1155 
1156  !> @brief Source package info and begin to process
1157  subroutine create_packages(this)
1158  ! modules
1161  use arrayhandlersmodule, only: expandarray
1162  use memorymanagermodule, only: mem_setptr
1164  use simvariablesmodule, only: idm_context
1165  use budgetmodule, only: budget_cr
1169  use prtmipmodule, only: mip_cr
1170  use prtfmimodule, only: fmi_cr
1171  use prtocmodule, only: oc_cr
1172  ! dummy
1173  class(prtmodeltype) :: this
1174  ! local
1175  type(characterstringtype), dimension(:), contiguous, &
1176  pointer :: pkgtypes => null()
1177  type(characterstringtype), dimension(:), contiguous, &
1178  pointer :: pkgnames => null()
1179  type(characterstringtype), dimension(:), contiguous, &
1180  pointer :: mempaths => null()
1181  integer(I4B), dimension(:), contiguous, &
1182  pointer :: inunits => null()
1183  character(len=LENMEMPATH) :: model_mempath
1184  character(len=LENFTYPE) :: pkgtype
1185  character(len=LENPACKAGENAME) :: pkgname
1186  character(len=LENMEMPATH) :: mempath
1187  integer(I4B), pointer :: inunit
1188  integer(I4B), dimension(:), allocatable :: bndpkgs
1189  integer(I4B) :: n
1190  integer(I4B) :: indis = 0 ! DIS enabled flag
1191  character(len=LENMEMPATH) :: mempathmip = ''
1192  character(len=LENMEMPATH) :: mempathfmi = ''
1193  character(len=LENMEMPATH) :: mempathoc = ''
1194 
1195  ! set input memory paths, input/model and input/model/namfile
1196  model_mempath = create_mem_path(component=this%name, context=idm_context)
1197 
1198  ! set pointers to model path package info
1199  call mem_setptr(pkgtypes, 'PKGTYPES', model_mempath)
1200  call mem_setptr(pkgnames, 'PKGNAMES', model_mempath)
1201  call mem_setptr(mempaths, 'MEMPATHS', model_mempath)
1202  call mem_setptr(inunits, 'INUNITS', model_mempath)
1203 
1204  do n = 1, size(pkgtypes)
1205  ! attributes for this input package
1206  pkgtype = pkgtypes(n)
1207  pkgname = pkgnames(n)
1208  mempath = mempaths(n)
1209  inunit => inunits(n)
1210 
1211  ! create dis package first as it is a prerequisite for other packages
1212  select case (pkgtype)
1213  case ('DIS6')
1214  indis = 1
1215  call dis_cr(this%dis, this%name, mempath, indis, this%iout)
1216  case ('DISV6')
1217  indis = 1
1218  call disv_cr(this%dis, this%name, mempath, indis, this%iout)
1219  case ('DISU6')
1220  indis = 1
1221  call disu_cr(this%dis, this%name, mempath, indis, this%iout)
1222  case ('MIP6')
1223  this%inmip = 1
1224  mempathmip = mempath
1225  case ('FMI6')
1226  this%infmi = 1
1227  mempathfmi = mempath
1228  case ('OC6')
1229  this%inoc = 1
1230  mempathoc = mempath
1231  case ('PRP6')
1232  call expandarray(bndpkgs)
1233  bndpkgs(size(bndpkgs)) = n
1234  case default
1235  call pstop(1, "Unrecognized package type: "//pkgtype)
1236  end select
1237  end do
1238 
1239  ! Create budget manager
1240  call budget_cr(this%budget, this%name)
1241 
1242  ! Create tracking method pools
1243  call create_method_pool()
1246 
1247  ! Create packages that are tied directly to model
1248  call mip_cr(this%mip, this%name, mempathmip, this%inmip, this%iout, this%dis)
1249  call fmi_cr(this%fmi, this%name, mempathfmi, this%infmi, this%iout)
1250  call oc_cr(this%oc, this%name, mempathoc, this%inoc, this%iout)
1251 
1252  ! Check to make sure that required ftype's have been specified
1253  call this%ftype_check(indis)
1254 
1255  ! Create boundary packages
1256  call this%create_bndpkgs(bndpkgs, pkgtypes, pkgnames, mempaths, inunits)
1257  end subroutine create_packages
1258 
1259  !> @brief Write model namfile options to list file
1260  subroutine log_namfile_options(this, found)
1262  class(prtmodeltype) :: this
1263  type(prtnamparamfoundtype), intent(in) :: found
1264 
1265  write (this%iout, '(1x,a)') 'NAMEFILE OPTIONS:'
1266 
1267  if (found%print_input) then
1268  write (this%iout, '(4x,a)') 'STRESS PACKAGE INPUT WILL BE PRINTED '// &
1269  'FOR ALL MODEL STRESS PACKAGES'
1270  end if
1271 
1272  if (found%print_flows) then
1273  write (this%iout, '(4x,a)') 'PACKAGE FLOWS WILL BE PRINTED '// &
1274  'FOR ALL MODEL PACKAGES'
1275  end if
1276 
1277  if (found%save_flows) then
1278  write (this%iout, '(4x,a)') &
1279  'FLOWS WILL BE SAVED TO BUDGET FILE SPECIFIED IN OUTPUT CONTROL'
1280  end if
1281 
1282  write (this%iout, '(1x,a)') 'END NAMEFILE OPTIONS:'
1283  end subroutine log_namfile_options
1284 
1285 end module prtmodule
This module contains the API package methods.
Definition: gwf-api.f90:12
subroutine, public api_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, mempath)
@ brief Create a new package object
Definition: gwf-api.f90:51
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
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
Definition: Budget.f90:632
This module contains simulation constants.
Definition: Constants.f90:9
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
@ mnormal
normal output mode
Definition: Constants.f90:206
integer(i4b), parameter lenpackagename
maximum length of the package name
Definition: Constants.f90:23
integer(i4b), parameter lenpackagetype
maximum length of a package type (DIS6, SFR6, CSUB6, etc.)
Definition: Constants.f90:38
integer(i4b), parameter lenbigline
maximum length of a big line
Definition: Constants.f90:15
real(dp), parameter dhnoflo
real no flow constant
Definition: Constants.f90:93
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:50
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:39
integer(i4b), parameter lenauxname
maximum length of a aux variable
Definition: Constants.f90:35
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
integer(i4b), parameter lenmempath
maximum length of the memory path
Definition: Constants.f90:27
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
Definition: Dis.f90:1
subroutine, public dis_cr(dis, name_model, input_mempath, inunit, iout)
Create a new structured discretization object.
Definition: Dis.f90:99
subroutine, public disu_cr(dis, name_model, input_mempath, inunit, iout)
Create a new unstructured discretization object.
Definition: Disu.f90:127
subroutine, public disv_cr(dis, name_model, input_mempath, inunit, iout)
Create a new discretization by vertices object.
Definition: Disv.f90:111
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
Definition: ErrorUtil.f90:24
A chaining hash map for integers.
Definition: HashTable.f90:7
subroutine, public hash_table_cr(map)
Create a hash table.
Definition: HashTable.f90:46
subroutine, public hash_table_da(map)
Deallocate the hash table.
Definition: HashTable.f90:64
subroutine, public lowcase(word)
Convert to lower case.
subroutine, public parseline(line, nwords, words, inunit, filename)
Parse a line into words.
subroutine, public upcase(word)
Convert to upper case.
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 memorystore_remove(component, subcomponent, context)
Cell-level tracking methods.
subroutine, public create_method_cell_pool()
Create the cell method pool.
subroutine, public destroy_method_cell_pool()
Destroy the cell method pool.
Particle tracking strategies.
Definition: Method.f90:2
@, public level_feature
Definition: Method.f90:41
Model-level tracking methods.
Definition: MethodPool.f90:2
type(methoddisvtype), pointer, public method_disv
Definition: MethodPool.f90:12
type(methoddistype), pointer, public method_dis
Definition: MethodPool.f90:11
subroutine, public create_method_pool()
Create the method pool.
Definition: MethodPool.f90:18
subroutine, public destroy_method_pool()
Destroy the method pool.
Definition: MethodPool.f90:24
Subcell-level tracking methods.
subroutine, public create_method_subcell_pool()
Create the subcell method pool.
subroutine, public destroy_method_subcell_pool()
Destroy the subcell method pool.
@, public release
particle was released
@, public terminate
particle terminated
@ term_timeout
terminated at stop time or end of simulation
Definition: Particle.f90:38
@ term_unreleased
terminated permanently unreleased
Definition: Particle.f90:36
subroutine create_particle(particle)
Create a new particle.
Definition: Particle.f90:145
Particle track output module.
subroutine, public fmi_cr(fmiobj, name_model, input_mempath, inunit, iout)
Create a new PrtFmi object.
Definition: prt-fmi.f90:51
subroutine, public mip_cr(mip, name_model, input_mempath, inunit, iout, dis)
Create a model input object.
Definition: prt-mip.f90:34
Definition: prt.f90:1
integer(i4b), parameter niunit_prt
Definition: prt.f90:122
subroutine prt_ot(this)
Print and/or save model output.
Definition: prt.f90:559
subroutine prt_rp(this)
Read and prepare (calls package read and prepare routines)
Definition: prt.f90:336
subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, mempaths, inunits)
Source package info and begin to process.
Definition: prt.f90:1107
subroutine prt_ar(this)
Allocate and read.
Definition: prt.f90:241
subroutine ftype_check(this, indis)
Check to make sure required input files have been specified.
Definition: prt.f90:1003
subroutine prt_ot_saveflow(this, nja, flowja, icbcfl, icbcun)
Save intercell flows.
Definition: prt.f90:641
subroutine prt_ad(this)
Time step advance (calls package advance subroutines)
Definition: prt.f90:356
subroutine prt_cq(this, icnvg, isuppress_output)
Calculate intercell flow (flowja)
Definition: prt.f90:399
subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, inunit, iout)
Create boundary condition packages for this model.
Definition: prt.f90:955
subroutine prt_ot_flow(this, icbcfl, ibudfl, icbcun)
Save flows.
Definition: prt.f90:604
subroutine allocate_scalars(this, modelname)
Allocate memory for scalars.
Definition: prt.f90:888
subroutine prt_ot_bdsummary(this, ibudfl, ipflag)
Print budget summary.
Definition: prt.f90:791
character(len=lenpackagetype), dimension(prt_nmultipkg), public prt_multipkg
Definition: prt.f90:117
subroutine create_packages(this)
Source package info and begin to process.
Definition: prt.f90:1158
character(len=lenpackagetype), dimension(prt_nbasepkg), public prt_basepkg
Definition: prt.f90:103
integer(i4b), parameter, public prt_nmultipkg
PRT multi package array descriptors.
Definition: prt.f90:116
character(len=lenbudtxt), dimension(nbditems) budtxt
Definition: prt.f90:41
subroutine prt_da(this)
Deallocate.
Definition: prt.f90:821
subroutine, public prt_cr(filename, id, modelname)
Create a new particle tracking model object.
Definition: prt.f90:128
subroutine prt_ot_printflow(this, ibudfl, flowja)
Print intercell flows.
Definition: prt.f90:731
subroutine prt_bd(this, icnvg, isuppress_output)
Calculate flows and budget.
Definition: prt.f90:524
subroutine prt_df(this)
Define packages.
Definition: prt.f90:208
integer(i4b), parameter, public prt_nbasepkg
PRT base package array descriptors.
Definition: prt.f90:102
integer(i4b), parameter nbditems
Definition: prt.f90:40
subroutine allocate_arrays(this)
Allocate arrays.
Definition: prt.f90:917
subroutine log_namfile_options(this, found)
Write model namfile options to list file.
Definition: prt.f90:1261
subroutine prt_cq_budterms(this)
Calculate particle mass budget terms.
Definition: prt.f90:445
subroutine prt_ot_dv(this, idvsave, idvprint, ipflag)
Print dependent variables.
Definition: prt.f90:770
subroutine prt_solve(this)
Solve the model.
Definition: prt.f90:1030
subroutine, public oc_cr(ocobj, name_model, input_mempath, inunit, iout)
@ brief Create an output control object
Definition: prt-oc.f90:52
subroutine, public prp_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, input_mempath, fmi)
Create a new particle release point package.
Definition: prt-prp.f90:103
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:203
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:263
logical(lgp), pointer, public endofperiod
flag indicating end of stress period
Definition: tdis.f90:27
logical(lgp), pointer, public endofsimulation
flag indicating end of simulation
Definition: tdis.f90:28
subroutine, public tdis_ot(iout)
Print simulation time.
Definition: tdis.f90:274
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:32
logical(lgp), pointer, public readnewdata
flag indicating time to read new data
Definition: tdis.f90:26
real(dp), pointer, public totimc
simulation time at start of time step
Definition: tdis.f90:33
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
real(dp), pointer, public delt
length of the current time step
Definition: tdis.f90:29
This module contains version information.
Definition: version.f90:7
subroutine write_listfile_header(iout, cmodel_type, write_sys_command, write_kind_info)
@ brief Write program header
Definition: version.f90:98
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
Structured grid discretization.
Definition: Dis.f90:23
Unstructured grid discretization.
Definition: Disu.f90:28
Vertex grid discretization.
Definition: Disv.f90:24
A generic heterogeneous doubly-linked list.
Definition: List.f90:14
Base type for particle tracking methods.
Definition: Method.f90:58
Particle tracked by the PRT model.
Definition: Particle.f90:57
Output file containing all or some particle pathlines.
Manages particle track output (logging/writing).
Particle tracking (PRT) model.
Definition: prt.f90:45
@ brief Output control for particle tracking models
Definition: prt-oc.f90:21
Particle release point (PRP) package.
Definition: prt-prp.f90:38