MODFLOW 6  version 6.8.0.dev0
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(explicitmodeltype) :: 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  class(*), pointer :: p
252 
253  ! Set up basic packages
254  call this%fmi%fmi_ar(this%ibound)
255  if (this%inmip > 0) call this%mip%mip_ar()
256 
257  ! Set up output control and budget
258  call this%oc%oc_ar(this%dis, dhnoflo)
259  call this%budget%set_ibudcsv(this%oc%ibudcsv)
260 
261  ! Select tracking events
262  call this%tracks%select_events( &
263  this%oc%trackrelease, &
264  this%oc%trackfeatexit, &
265  this%oc%tracktimestep, &
266  this%oc%trackterminate, &
267  this%oc%trackweaksink, &
268  this%oc%trackusertime, &
269  this%oc%tracksubfexit, &
270  this%oc%trackdropped)
271 
272  ! Set up boundary pkgs and pkg-scoped track files
273  nprp = 0
274  do ip = 1, this%bndlist%Count()
275  packobj => getbndfromlist(this%bndlist, ip)
276  select type (packobj)
277  type is (prtprptype)
278  nprp = nprp + 1
279  call packobj%prp_set_pointers(this%ibound, this%mip%izone)
280  call packobj%bnd_ar()
281  call packobj%bnd_ar()
282  if (packobj%itrkout > 0) then
283  call this%tracks%init_file( &
284  packobj%itrkout, &
285  iprp=nprp)
286  end if
287  if (packobj%itrkcsv > 0) then
288  call this%tracks%init_file( &
289  packobj%itrkcsv, &
290  csv=.true., &
291  iprp=nprp)
292  end if
293  class default
294  call packobj%bnd_ar()
295  end select
296  end do
297 
298  ! Set up model-scoped track files
299  if (this%oc%itrkout > 0) &
300  call this%tracks%init_file(this%oc%itrkout)
301  if (this%oc%itrkcsv > 0) &
302  call this%tracks%init_file(this%oc%itrkcsv, csv=.true.)
303 
304  ! Set up the tracking method
305  select type (dis => this%dis)
306  type is (distype)
307  call method_dis%init( &
308  fmi=this%fmi, &
309  events=this%events, &
310  izone=this%mip%izone, &
311  flowja=this%flowja, &
312  porosity=this%mip%porosity, &
313  retfactor=this%mip%retfactor, &
314  tracktimes=this%oc%tracktimes)
315  this%method => method_dis
316  type is (disvtype)
317  call method_disv%init( &
318  fmi=this%fmi, &
319  events=this%events, &
320  izone=this%mip%izone, &
321  flowja=this%flowja, &
322  porosity=this%mip%porosity, &
323  retfactor=this%mip%retfactor, &
324  tracktimes=this%oc%tracktimes)
325  this%method => method_disv
326  end select
327 
328  ! Subscribe particle track output manager to events
329  p => this%tracks
330  call this%events%subscribe(write_particle_event, p)
331 
332  ! Set verbose tracing if requested
333  if (this%oc%dump_event_trace) this%tracks%iout = 0
334  end subroutine prt_ar
335 
336  !> @brief Read and prepare (calls package read and prepare routines)
337  subroutine prt_rp(this)
338  use tdismodule, only: readnewdata
339  ! dummy
340  class(prtmodeltype) :: this
341  ! local
342  class(bndtype), pointer :: packobj
343  integer(I4B) :: ip
344 
345  ! Check with TDIS on whether or not it is time to RP
346  if (.not. readnewdata) return
347 
348  ! Read and prepare
349  if (this%inoc > 0) call this%oc%oc_rp()
350  do ip = 1, this%bndlist%Count()
351  packobj => getbndfromlist(this%bndlist, ip)
352  call packobj%bnd_rp()
353  end do
354  end subroutine prt_rp
355 
356  !> @brief Time step advance (calls package advance subroutines)
357  subroutine prt_ad(this)
358  ! modules
360  ! dummy
361  class(prtmodeltype) :: this
362  class(bndtype), pointer :: packobj
363  ! local
364  integer(I4B) :: irestore
365  integer(I4B) :: ip, n, i
366 
367  ! Reset state variable
368  irestore = 0
369  if (ifailedstepretry > 0) irestore = 1
370 
371  ! Update look-behind mass
372  do n = 1, this%dis%nodes
373  this%massstoold(n) = this%masssto(n)
374  end do
375 
376  ! Advance fmi
377  call this%fmi%fmi_ad()
378 
379  ! Advance
380  do ip = 1, this%bndlist%Count()
381  packobj => getbndfromlist(this%bndlist, ip)
382  call packobj%bnd_ad()
383  if (isimcheck > 0) then
384  call packobj%bnd_ck()
385  end if
386  end do
387  !
388  ! Initialize the flowja array. Flowja is calculated each time,
389  ! even if output is suppressed. (Flowja represents flow of particle
390  ! mass and is positive into a cell. Currently, each particle is assigned
391  ! unit mass.) Flowja is updated continually as particles are tracked
392  ! over the time step and at the end of the time step. The diagonal
393  ! position of the flowja array will contain the flow residual.
394  do i = 1, this%dis%nja
395  this%flowja(i) = dzero
396  end do
397  end subroutine prt_ad
398 
399  !> @brief Calculate intercell flow (flowja)
400  subroutine prt_cq(this, icnvg, isuppress_output)
401  ! modules
402  use sparsemodule, only: csr_diagsum
403  use tdismodule, only: delt
404  use prtprpmodule, only: prtprptype
405  ! dummy
406  class(prtmodeltype) :: this
407  integer(I4B), intent(in) :: icnvg
408  integer(I4B), intent(in) :: isuppress_output
409  ! local
410  integer(I4B) :: i
411  integer(I4B) :: ip
412  class(bndtype), pointer :: packobj
413  real(DP) :: tled
414 
415  ! Flowja is calculated each time, even if output is suppressed.
416  ! Flowja represents flow of particle mass and is positive into a cell.
417  ! Currently, each particle is assigned unit mass.
418  !
419  ! Reciprocal of time step size.
420  tled = done / delt
421  !
422  ! Flowja was updated continually as particles were tracked over the
423  ! time step. At this point, flowja contains the net particle mass
424  ! exchanged between cells during the time step. To convert these to
425  ! flow rates (particle mass per time), divide by the time step size.
426  do i = 1, this%dis%nja
427  this%flowja(i) = this%flowja(i) * tled
428  end do
429 
430  ! Particle mass budget terms
431  call this%prt_cq_budterms()
432 
433  ! Go through packages and call cq routines. Just a formality.
434  do ip = 1, this%bndlist%Count()
435  packobj => getbndfromlist(this%bndlist, ip)
436  call packobj%bnd_cq(this%masssto, this%flowja)
437  end do
438 
439  ! Finalize calculation of flowja by adding face flows to the diagonal.
440  ! This results in the flow residual being stored in the diagonal
441  ! position for each cell.
442  call csr_diagsum(this%dis%con%ia, this%flowja)
443  end subroutine prt_cq
444 
445  !> @brief Calculate particle mass budget terms
446  subroutine prt_cq_budterms(this)
447  ! modules
448  use tdismodule, only: delt
449  use prtprpmodule, only: prtprptype
450  ! dummy
451  class(prtmodeltype) :: this
452  ! local
453  integer(I4B) :: ip
454  class(bndtype), pointer :: packobj
455  integer(I4B) :: n
456  integer(I4B) :: np
457  integer(I4B) :: idiag
458  integer(I4B) :: iprp
459  integer(I4B) :: istatus
460  real(DP) :: tled
461  real(DP) :: ratesto, ratetrm
462  character(len=:), allocatable :: particle_id
463  type(particletype), pointer :: particle
464 
465  call create_particle(particle)
466 
467  ! Reciprocal of time step size.
468  tled = done / delt
469 
470  ! Reset mass and rate arrays
471  do n = 1, this%dis%nodes
472  this%masssto(n) = dzero
473  this%masstrm(n) = dzero
474  this%ratesto(n) = dzero
475  this%ratetrm(n) = dzero
476  end do
477 
478  ! Loop over PRP packages and assign particle mass to the
479  ! appropriate budget term based on the particle status.
480  iprp = 0
481  do ip = 1, this%bndlist%Count()
482  packobj => getbndfromlist(this%bndlist, ip)
483  select type (packobj)
484  type is (prtprptype)
485  do np = 1, packobj%nparticles
486  call packobj%particles%get(particle, this%id, iprp, np)
487  istatus = packobj%particles%istatus(np)
488  particle_id = particle%get_id()
489  if (istatus == active) then
490  ! calculate storage mass
491  n = packobj%particles%itrdomain(np, level_feature)
492  this%masssto(n) = this%masssto(n) + done ! unit mass
493  else if (istatus > active) then
494  if (this%trm_ids%get(particle_id) /= 0) cycle
495  ! calculate terminating mass
496  n = packobj%particles%itrdomain(np, level_feature)
497  this%masstrm(n) = this%masstrm(n) + done ! unit mass
498  call this%trm_ids%add(particle_id, 1) ! mark id terminated
499  end if
500  end do
501  end select
502  end do
503 
504  ! Calculate rates and update flowja
505  do n = 1, this%dis%nodes
506  ratesto = -(this%masssto(n) - this%massstoold(n)) * tled
507  ratetrm = -this%masstrm(n) * tled
508  this%ratesto(n) = ratesto
509  this%ratetrm(n) = ratetrm
510  idiag = this%dis%con%ia(n)
511  this%flowja(idiag) = this%flowja(idiag) + ratesto
512  end do
513 
514  call particle%destroy()
515  deallocate (particle)
516 
517  end subroutine prt_cq_budterms
518 
519  !> @brief Calculate flows and budget
520  !!
521  !! (1) Calculate intercell flows (flowja)
522  !! (2) Calculate package contributions to model budget
523  !!
524  !<
525  subroutine prt_bd(this, icnvg, isuppress_output)
526  ! modules
527  use tdismodule, only: delt
528  use budgetmodule, only: rate_accumulator
529  ! dummy
530  class(prtmodeltype) :: this
531  integer(I4B), intent(in) :: icnvg
532  integer(I4B), intent(in) :: isuppress_output
533  ! local
534  integer(I4B) :: ip
535  class(bndtype), pointer :: packobj
536  real(DP) :: rin
537  real(DP) :: rout
538 
539  ! Budget routines (start by resetting). Sole purpose of this section
540  ! is to add in and outs to model budget. All ins and out for a model
541  ! should be added here to this%budget. In a subsequent exchange call,
542  ! exchange flows might also be added.
543  call this%budget%reset()
544  ! storage term
545  call rate_accumulator(this%ratesto, rin, rout)
546  call this%budget%addentry(rin, rout, delt, budtxt(1), &
547  isuppress_output, ' PRT')
548  ! termination term
549  call rate_accumulator(this%ratetrm, rin, rout)
550  call this%budget%addentry(rin, rout, delt, budtxt(2), &
551  isuppress_output, ' PRT')
552  ! boundary packages
553  do ip = 1, this%bndlist%Count()
554  packobj => getbndfromlist(this%bndlist, ip)
555  call packobj%bnd_bd(this%budget)
556  end do
557  end subroutine prt_bd
558 
559  !> @brief Print and/or save model output
560  subroutine prt_ot(this)
561  use tdismodule, only: tdis_ot, endofperiod
562  ! dummy
563  class(prtmodeltype) :: this
564  ! local
565  integer(I4B) :: idvsave
566  integer(I4B) :: idvprint
567  integer(I4B) :: icbcfl
568  integer(I4B) :: icbcun
569  integer(I4B) :: ibudfl
570  integer(I4B) :: ipflag
571 
572  ! Note: particle tracking output is handled elsewhere
573 
574  ! Set write and print flags
575  idvsave = 0
576  idvprint = 0
577  icbcfl = 0
578  ibudfl = 0
579  if (this%oc%oc_save('CONCENTRATION')) idvsave = 1
580  if (this%oc%oc_print('CONCENTRATION')) idvprint = 1
581  if (this%oc%oc_save('BUDGET')) icbcfl = 1
582  if (this%oc%oc_print('BUDGET')) ibudfl = 1
583  icbcun = this%oc%oc_save_unit('BUDGET')
584 
585  ! Override ibudfl and idvprint flags for nonconvergence
586  ! and end of period
587  ibudfl = this%oc%set_print_flag('BUDGET', 1, endofperiod)
588  idvprint = this%oc%set_print_flag('CONCENTRATION', 1, endofperiod)
589 
590  ! Save and print flows
591  call this%prt_ot_flow(icbcfl, ibudfl, icbcun)
592 
593  ! Save and print dependent variables
594  call this%prt_ot_dv(idvsave, idvprint, ipflag)
595 
596  ! Print budget summaries
597  call this%prt_ot_bdsummary(ibudfl, ipflag)
598 
599  ! Timing Output; if any dependent variables or budgets
600  ! are printed, then ipflag is set to 1.
601  if (ipflag == 1) call tdis_ot(this%iout)
602  end subroutine prt_ot
603 
604  !> @brief Save flows
605  subroutine prt_ot_flow(this, icbcfl, ibudfl, icbcun)
606  use prtprpmodule, only: prtprptype
607  class(prtmodeltype) :: this
608  integer(I4B), intent(in) :: icbcfl
609  integer(I4B), intent(in) :: ibudfl
610  integer(I4B), intent(in) :: icbcun
611  class(bndtype), pointer :: packobj
612  integer(I4B) :: ip
613 
614  ! Save PRT flows
615  call this%prt_ot_saveflow(this%dis%nja, this%flowja, icbcfl, icbcun)
616  do ip = 1, this%bndlist%Count()
617  packobj => getbndfromlist(this%bndlist, ip)
618  call packobj%bnd_ot_model_flows(icbcfl=icbcfl, ibudfl=0, icbcun=icbcun)
619  end do
620 
621  ! Save advanced package flows
622  do ip = 1, this%bndlist%Count()
623  packobj => getbndfromlist(this%bndlist, ip)
624  call packobj%bnd_ot_package_flows(icbcfl=icbcfl, ibudfl=0)
625  end do
626 
627  ! Print PRT flows
628  call this%prt_ot_printflow(ibudfl, this%flowja)
629  do ip = 1, this%bndlist%Count()
630  packobj => getbndfromlist(this%bndlist, ip)
631  call packobj%bnd_ot_model_flows(icbcfl=icbcfl, ibudfl=ibudfl, icbcun=0)
632  end do
633 
634  ! Print advanced package flows
635  do ip = 1, this%bndlist%Count()
636  packobj => getbndfromlist(this%bndlist, ip)
637  call packobj%bnd_ot_package_flows(icbcfl=0, ibudfl=ibudfl)
638  end do
639  end subroutine prt_ot_flow
640 
641  !> @brief Save intercell flows
642  subroutine prt_ot_saveflow(this, nja, flowja, icbcfl, icbcun)
643  ! dummy
644  class(prtmodeltype) :: this
645  integer(I4B), intent(in) :: nja
646  real(DP), dimension(nja), intent(in) :: flowja
647  integer(I4B), intent(in) :: icbcfl
648  integer(I4B), intent(in) :: icbcun
649  ! local
650  integer(I4B) :: ibinun
651  integer(I4B) :: naux
652  real(DP), dimension(0) :: auxrow
653  character(len=LENAUXNAME), dimension(0) :: auxname
654  logical(LGP) :: header_written
655  integer(I4B) :: i, nn
656  real(DP) :: m
657  integer(I4B) :: nsto, ntrm
658  logical(LGP), allocatable :: msto_mask(:), mtrm_mask(:)
659  integer(I4B), allocatable :: msto_nns(:), mtrm_nns(:)
660  real(DP), allocatable :: msto_vals(:), mtrm_vals(:)
661 
662  ! Set unit number for binary output
663  if (this%ipakcb < 0) then
664  ibinun = icbcun
665  elseif (this%ipakcb == 0) then
666  ibinun = 0
667  else
668  ibinun = this%ipakcb
669  end if
670  if (icbcfl == 0) ibinun = 0
671 
672  ! Return if nothing to do
673  if (ibinun == 0) return
674 
675  ! Write mass face flows
676  call this%dis%record_connection_array(flowja, ibinun, this%iout)
677 
678  ! Write mass storage term
679  naux = 0
680  header_written = .false.
681  msto_mask = this%masssto > dzero
682  msto_vals = pack(this%masssto, msto_mask)
683  msto_nns = [(i, i=1, size(this%masssto))]
684  msto_nns = pack(msto_nns, msto_mask)
685  nsto = size(msto_nns)
686  do i = 1, nsto
687  nn = msto_nns(i)
688  m = msto_vals(i)
689  if (.not. header_written) then
690  call this%dis%record_srcdst_list_header(budtxt(1), &
691  'PRT ', &
692  'PRT ', &
693  'PRT ', &
694  'STORAGE ', &
695  naux, auxname, ibinun, &
696  nsto, this%iout)
697  header_written = .true.
698  end if
699  call this%dis%record_mf6_list_entry(ibinun, nn, nn, m, &
700  0, auxrow, &
701  olconv2=.false.)
702  end do
703 
704  ! Write mass termination term
705  header_written = .false.
706  mtrm_mask = this%masstrm > dzero
707  mtrm_vals = pack(this%masstrm, mtrm_mask)
708  mtrm_nns = [(i, i=1, size(this%masstrm))]
709  mtrm_nns = pack(mtrm_nns, mtrm_mask)
710  ntrm = size(mtrm_nns)
711  do i = 1, ntrm
712  nn = mtrm_nns(i)
713  m = mtrm_vals(i)
714  if (.not. header_written) then
715  call this%dis%record_srcdst_list_header(budtxt(2), &
716  'PRT ', &
717  'PRT ', &
718  'PRT ', &
719  'TERMINATION ', &
720  naux, auxname, ibinun, &
721  ntrm, this%iout)
722  header_written = .true.
723  end if
724  call this%dis%record_mf6_list_entry(ibinun, nn, nn, m, &
725  0, auxrow, &
726  olconv2=.false.)
727  end do
728 
729  end subroutine prt_ot_saveflow
730 
731  !> @brief Print intercell flows
732  subroutine prt_ot_printflow(this, ibudfl, flowja)
733  ! modules
734  use tdismodule, only: kper, kstp
735  use constantsmodule, only: lenbigline
736  ! dummy
737  class(prtmodeltype) :: this
738  integer(I4B), intent(in) :: ibudfl
739  real(DP), intent(inout), dimension(:) :: flowja
740  ! local
741  character(len=LENBIGLINE) :: line
742  character(len=30) :: tempstr
743  integer(I4B) :: n, ipos, m
744  real(DP) :: qnm
745  ! formats
746  character(len=*), parameter :: fmtiprflow = &
747  "(/,4x,'CALCULATED INTERCELL FLOW &
748  &FOR PERIOD ', i0, ' STEP ', i0)"
749 
750  ! Write flowja to list file if requested
751  if (ibudfl /= 0 .and. this%iprflow > 0) then
752  write (this%iout, fmtiprflow) kper, kstp
753  do n = 1, this%dis%nodes
754  line = ''
755  call this%dis%noder_to_string(n, tempstr)
756  line = trim(tempstr)//':'
757  do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
758  m = this%dis%con%ja(ipos)
759  call this%dis%noder_to_string(m, tempstr)
760  line = trim(line)//' '//trim(tempstr)
761  qnm = flowja(ipos)
762  write (tempstr, '(1pg15.6)') qnm
763  line = trim(line)//' '//trim(adjustl(tempstr))
764  end do
765  write (this%iout, '(a)') trim(line)
766  end do
767  end if
768  end subroutine prt_ot_printflow
769 
770  !> @brief Print dependent variables
771  subroutine prt_ot_dv(this, idvsave, idvprint, ipflag)
772  ! dummy
773  class(prtmodeltype) :: this
774  integer(I4B), intent(in) :: idvsave
775  integer(I4B), intent(in) :: idvprint
776  integer(I4B), intent(inout) :: ipflag
777  ! local
778  class(bndtype), pointer :: packobj
779  integer(I4B) :: ip
780 
781  ! Print advanced package dependent variables
782  do ip = 1, this%bndlist%Count()
783  packobj => getbndfromlist(this%bndlist, ip)
784  call packobj%bnd_ot_dv(idvsave, idvprint)
785  end do
786 
787  ! save head and print head
788  call this%oc%oc_ot(ipflag)
789  end subroutine prt_ot_dv
790 
791  !> @brief Print budget summary
792  subroutine prt_ot_bdsummary(this, ibudfl, ipflag)
793  ! modules
794  use tdismodule, only: kstp, kper, totim, delt
795  ! dummy
796  class(prtmodeltype) :: this
797  integer(I4B), intent(in) :: ibudfl
798  integer(I4B), intent(inout) :: ipflag
799  ! local
800  class(bndtype), pointer :: packobj
801  integer(I4B) :: ip
802 
803  ! Package budget summary
804  do ip = 1, this%bndlist%Count()
805  packobj => getbndfromlist(this%bndlist, ip)
806  call packobj%bnd_ot_bdsummary(kstp, kper, this%iout, ibudfl)
807  end do
808 
809  ! model budget summary
810  call this%budget%finalize_step(delt)
811  if (ibudfl /= 0) then
812  ipflag = 1
813  ! model budget summary
814  call this%budget%budget_ot(kstp, kper, this%iout)
815  end if
816 
817  ! Write to budget csv
818  call this%budget%writecsv(totim)
819  end subroutine prt_ot_bdsummary
820 
821  !> @brief Deallocate
822  subroutine prt_da(this)
823  ! modules
830  ! dummy
831  class(prtmodeltype) :: this
832  ! local
833  integer(I4B) :: ip
834  class(bndtype), pointer :: packobj
835 
836  ! Deallocate idm memory
837  call memorystore_remove(this%name, 'NAM', idm_context)
838  call memorystore_remove(component=this%name, context=idm_context)
839 
840  ! Internal packages
841  call this%dis%dis_da()
842  call this%fmi%fmi_da()
843  call this%mip%mip_da()
844  call this%budget%budget_da()
845  call this%oc%oc_da()
846  deallocate (this%dis)
847  deallocate (this%fmi)
848  deallocate (this%mip)
849  deallocate (this%budget)
850  deallocate (this%oc)
851 
852  ! Method objects
855  call destroy_method_pool()
856 
857  ! Boundary packages
858  do ip = 1, this%bndlist%Count()
859  packobj => getbndfromlist(this%bndlist, ip)
860  call packobj%bnd_da()
861  deallocate (packobj)
862  end do
863 
864  ! Scalars
865  call mem_deallocate(this%infmi)
866  call mem_deallocate(this%inmip)
867  call mem_deallocate(this%inadv)
868  call mem_deallocate(this%indsp)
869  call mem_deallocate(this%inssm)
870  call mem_deallocate(this%inmst)
871  call mem_deallocate(this%inmvt)
872  call mem_deallocate(this%inoc)
873 
874  ! Arrays
875  call mem_deallocate(this%masssto)
876  call mem_deallocate(this%massstoold)
877  call mem_deallocate(this%ratesto)
878  call mem_deallocate(this%masstrm)
879  call mem_deallocate(this%ratetrm)
880 
881  call this%tracks%destroy()
882  deallocate (this%events)
883  deallocate (this%tracks)
884 
885  call this%ExplicitModelType%model_da()
886  end subroutine prt_da
887 
888  !> @brief Allocate memory for scalars
889  subroutine allocate_scalars(this, modelname)
890  ! dummy
891  class(prtmodeltype) :: this
892  character(len=*), intent(in) :: modelname
893 
894  ! allocate members from parent class
895  call this%ExplicitModelType%allocate_scalars(modelname)
896 
897  ! allocate members that are part of model class
898  call mem_allocate(this%infmi, 'INFMI', this%memoryPath)
899  call mem_allocate(this%inmip, 'INMIP', this%memoryPath)
900  call mem_allocate(this%inmvt, 'INMVT', this%memoryPath)
901  call mem_allocate(this%inmst, 'INMST', this%memoryPath)
902  call mem_allocate(this%inadv, 'INADV', this%memoryPath)
903  call mem_allocate(this%indsp, 'INDSP', this%memoryPath)
904  call mem_allocate(this%inssm, 'INSSM', this%memoryPath)
905  call mem_allocate(this%inoc, 'INOC ', this%memoryPath)
906 
907  this%infmi = 0
908  this%inmip = 0
909  this%inmvt = 0
910  this%inmst = 0
911  this%inadv = 0
912  this%indsp = 0
913  this%inssm = 0
914  this%inoc = 0
915  end subroutine allocate_scalars
916 
917  !> @brief Allocate arrays
918  subroutine allocate_arrays(this)
920  class(prtmodeltype) :: this
921  integer(I4B) :: n
922 
923  ! Allocate arrays in parent type (ibound, flowja, nja)
924  call this%ExplicitModelType%allocate_arrays()
925 
926  ! Allocate and initialize PRT-specific arrays
927  call mem_allocate(this%masssto, this%dis%nodes, &
928  'MASSSTO', this%memoryPath)
929  call mem_allocate(this%massstoold, this%dis%nodes, &
930  'MASSSTOOLD', this%memoryPath)
931  call mem_allocate(this%ratesto, this%dis%nodes, &
932  'RATESTO', this%memoryPath)
933  call mem_allocate(this%masstrm, this%dis%nodes, &
934  'MASSTRM', this%memoryPath)
935  call mem_allocate(this%ratetrm, this%dis%nodes, &
936  'RATETRM', this%memoryPath)
937  do n = 1, this%dis%nodes
938  this%masssto(n) = dzero
939  this%massstoold(n) = dzero
940  this%ratesto(n) = dzero
941  this%masstrm(n) = dzero
942  this%ratetrm(n) = dzero
943  end do
944  end subroutine allocate_arrays
945 
946  !> @brief Create boundary condition packages for this model
947  subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, &
948  inunit, iout)
949  ! modules
950  use constantsmodule, only: linelength
951  use prtprpmodule, only: prp_create
952  use apimodule, only: api_create
953  ! dummy
954  class(prtmodeltype) :: this
955  character(len=*), intent(in) :: filtyp
956  character(len=LINELENGTH) :: errmsg
957  integer(I4B), intent(in) :: ipakid
958  integer(I4B), intent(in) :: ipaknum
959  character(len=*), intent(in) :: pakname
960  character(len=*), intent(in) :: mempath
961  integer(I4B), intent(in) :: inunit
962  integer(I4B), intent(in) :: iout
963  ! local
964  class(bndtype), pointer :: packobj
965  class(bndtype), pointer :: packobj2
966  integer(I4B) :: ip
967 
968  ! This part creates the package object
969  select case (filtyp)
970  case ('PRP6')
971  call prp_create(packobj, ipakid, ipaknum, inunit, iout, &
972  this%name, pakname, mempath, this%fmi)
973  case ('API6')
974  call api_create(packobj, ipakid, ipaknum, inunit, iout, &
975  this%name, pakname, mempath)
976  case default
977  write (errmsg, *) 'Invalid package type: ', filtyp
978  call store_error(errmsg, terminate=.true.)
979  end select
980 
981  ! Packages is the bndlist that is associated with the parent model
982  ! The following statement puts a pointer to this package in the ipakid
983  ! position of packages.
984  do ip = 1, this%bndlist%Count()
985  packobj2 => getbndfromlist(this%bndlist, ip)
986  if (packobj2%packName == pakname) then
987  write (errmsg, '(a,a)') 'Cannot create package. Package name '// &
988  'already exists: ', trim(pakname)
989  call store_error(errmsg, terminate=.true.)
990  end if
991  end do
992  call addbndtolist(this%bndlist, packobj)
993  end subroutine package_create
994 
995  !> @brief Check to make sure required input files have been specified
996  subroutine ftype_check(this, indis)
997  ! dummy
998  class(prtmodeltype) :: this
999  integer(I4B), intent(in) :: indis
1000  ! local
1001  character(len=LINELENGTH) :: errmsg
1002 
1003  ! Check for DIS(u) and MIP. Stop if not present.
1004  if (indis == 0) then
1005  write (errmsg, '(1x,a)') &
1006  'Discretization (DIS6, DISV6, or DISU6) package not specified.'
1007  call store_error(errmsg)
1008  end if
1009  if (this%inmip == 0) then
1010  write (errmsg, '(1x,a)') &
1011  'Model input (MIP6) package not specified.'
1012  call store_error(errmsg)
1013  end if
1014 
1015  if (count_errors() > 0) then
1016  write (errmsg, '(1x,a)') 'One or more required package(s) not specified.'
1017  call store_error(errmsg)
1018  call store_error_filename(this%filename)
1019  end if
1020  end subroutine ftype_check
1021 
1022  !> @brief Solve the model
1023  subroutine prt_solve(this)
1024  use tdismodule, only: totimc, delt, endofsimulation
1025  use prtprpmodule, only: prtprptype
1028  ! dummy
1029  class(prtmodeltype) :: this
1030  ! local
1031  integer(I4B) :: np, ip
1032  class(bndtype), pointer :: packobj
1033  type(particletype), pointer :: particle
1034  real(DP) :: tmax
1035  integer(I4B) :: iprp
1036 
1037  ! A single particle is reused in the tracking loops
1038  ! to avoid allocating and deallocating it each time.
1039  ! get() and put() retrieve and store particle state.
1040  call create_particle(particle)
1041  ! Loop over PRP packages and particles within them.
1042  iprp = 0
1043  do ip = 1, this%bndlist%Count()
1044  packobj => getbndfromlist(this%bndlist, ip)
1045  select type (packobj)
1046  type is (prtprptype)
1047  iprp = iprp + 1
1048  do np = 1, packobj%nparticles
1049  ! Get the particle from the store
1050  call packobj%particles%get(particle, this%id, iprp, np)
1051  ! If particle is permanently unreleased, cycle.
1052  ! Raise a termination event if we haven't yet.
1053  ! TODO: when we have generic dynamic vectors,
1054  ! consider terminating permanently unreleased
1055  ! in PRP instead of here. For now, status -8
1056  ! indicates the permanently unreleased event
1057  ! is not yet recorded, status 8 it has been.
1058  if (particle%istatus == (-1 * term_unreleased)) then
1059  call this%method%terminate(particle, status=term_unreleased)
1060  call packobj%particles%put(particle, np)
1061  end if
1062  if (particle%istatus > active) cycle ! Skip terminated particles
1063  particle%istatus = active ! Set active status in case of release
1064  ! If the particle was released this time step, emit a release event
1065  if (particle%trelease >= totimc) call this%method%release(particle)
1066  ! Maximum time is the end of the time step or the particle
1067  ! stop time, whichever comes first, unless it's the final
1068  ! time step and the extend option is on, in which case
1069  ! it's just the particle stop time.
1070  if (endofsimulation .and. particle%extend) then
1071  tmax = particle%tstop
1072  else
1073  tmax = min(totimc + delt, particle%tstop)
1074  end if
1075  ! Apply the tracking method until the maximum time.
1076  call this%method%apply(particle, tmax)
1077  ! If the particle timed out, terminate it.
1078  ! "Timed out" means it's still active but
1079  ! - it reached its stop time, or
1080  ! - the simulation is over.
1081  ! We can't detect timeout within the tracking
1082  ! method because the method just receives the
1083  ! maximum time with no context on what it is.
1084  ! TODO maybe think about changing that?
1085  if (particle%istatus <= active .and. &
1086  (particle%ttrack == particle%tstop .or. endofsimulation)) &
1087  call this%method%terminate(particle, status=term_timeout)
1088  ! Return the particle to the store
1089  call packobj%particles%put(particle, np)
1090  end do
1091  end select
1092  end do
1093  call particle%destroy()
1094  deallocate (particle)
1095  end subroutine prt_solve
1096 
1097  !> @brief Source package info and begin to process
1098  subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, &
1099  mempaths, inunits)
1100  ! modules
1103  ! dummy
1104  class(prtmodeltype) :: this
1105  integer(I4B), dimension(:), allocatable, intent(inout) :: bndpkgs
1106  type(characterstringtype), dimension(:), contiguous, &
1107  pointer, intent(inout) :: pkgtypes
1108  type(characterstringtype), dimension(:), contiguous, &
1109  pointer, intent(inout) :: pkgnames
1110  type(characterstringtype), dimension(:), contiguous, &
1111  pointer, intent(inout) :: mempaths
1112  integer(I4B), dimension(:), contiguous, &
1113  pointer, intent(inout) :: inunits
1114  ! local
1115  integer(I4B) :: ipakid, ipaknum
1116  character(len=LENFTYPE) :: pkgtype, bndptype
1117  character(len=LENPACKAGENAME) :: pkgname
1118  character(len=LENMEMPATH) :: mempath
1119  integer(I4B), pointer :: inunit
1120  integer(I4B) :: n
1121 
1122  if (allocated(bndpkgs)) then
1123  ! create stress packages
1124  ipakid = 1
1125  bndptype = ''
1126  do n = 1, size(bndpkgs)
1127  pkgtype = pkgtypes(bndpkgs(n))
1128  pkgname = pkgnames(bndpkgs(n))
1129  mempath = mempaths(bndpkgs(n))
1130  inunit => inunits(bndpkgs(n))
1131 
1132  if (bndptype /= pkgtype) then
1133  ipaknum = 1
1134  bndptype = pkgtype
1135  end if
1136 
1137  call this%package_create(pkgtype, ipakid, ipaknum, pkgname, mempath, &
1138  inunit, this%iout)
1139  ipakid = ipakid + 1
1140  ipaknum = ipaknum + 1
1141  end do
1142 
1143  ! cleanup
1144  deallocate (bndpkgs)
1145  end if
1146 
1147  end subroutine create_bndpkgs
1148 
1149  !> @brief Source package info and begin to process
1150  subroutine create_packages(this)
1151  ! modules
1154  use arrayhandlersmodule, only: expandarray
1155  use memorymanagermodule, only: mem_setptr
1157  use simvariablesmodule, only: idm_context
1158  use budgetmodule, only: budget_cr
1162  use prtmipmodule, only: mip_cr
1163  use prtfmimodule, only: fmi_cr
1164  use prtocmodule, only: oc_cr
1165  ! dummy
1166  class(prtmodeltype) :: this
1167  ! local
1168  type(characterstringtype), dimension(:), contiguous, &
1169  pointer :: pkgtypes => null()
1170  type(characterstringtype), dimension(:), contiguous, &
1171  pointer :: pkgnames => null()
1172  type(characterstringtype), dimension(:), contiguous, &
1173  pointer :: mempaths => null()
1174  integer(I4B), dimension(:), contiguous, &
1175  pointer :: inunits => null()
1176  character(len=LENMEMPATH) :: model_mempath
1177  character(len=LENFTYPE) :: pkgtype
1178  character(len=LENPACKAGENAME) :: pkgname
1179  character(len=LENMEMPATH) :: mempath
1180  integer(I4B), pointer :: inunit
1181  integer(I4B), dimension(:), allocatable :: bndpkgs
1182  integer(I4B) :: n
1183  integer(I4B) :: indis = 0 ! DIS enabled flag
1184  character(len=LENMEMPATH) :: mempathmip = ''
1185  character(len=LENMEMPATH) :: mempathfmi = ''
1186  character(len=LENMEMPATH) :: mempathoc = ''
1187 
1188  ! set input memory paths, input/model and input/model/namfile
1189  model_mempath = create_mem_path(component=this%name, context=idm_context)
1190 
1191  ! set pointers to model path package info
1192  call mem_setptr(pkgtypes, 'PKGTYPES', model_mempath)
1193  call mem_setptr(pkgnames, 'PKGNAMES', model_mempath)
1194  call mem_setptr(mempaths, 'MEMPATHS', model_mempath)
1195  call mem_setptr(inunits, 'INUNITS', model_mempath)
1196 
1197  do n = 1, size(pkgtypes)
1198  ! attributes for this input package
1199  pkgtype = pkgtypes(n)
1200  pkgname = pkgnames(n)
1201  mempath = mempaths(n)
1202  inunit => inunits(n)
1203 
1204  ! create dis package first as it is a prerequisite for other packages
1205  select case (pkgtype)
1206  case ('DIS6')
1207  indis = 1
1208  call dis_cr(this%dis, this%name, mempath, indis, this%iout)
1209  case ('DISV6')
1210  indis = 1
1211  call disv_cr(this%dis, this%name, mempath, indis, this%iout)
1212  case ('DISU6')
1213  indis = 1
1214  call disu_cr(this%dis, this%name, mempath, indis, this%iout)
1215  case ('MIP6')
1216  this%inmip = 1
1217  mempathmip = mempath
1218  case ('FMI6')
1219  this%infmi = 1
1220  mempathfmi = mempath
1221  case ('OC6')
1222  this%inoc = 1
1223  mempathoc = mempath
1224  case ('PRP6')
1225  call expandarray(bndpkgs)
1226  bndpkgs(size(bndpkgs)) = n
1227  case default
1228  call pstop(1, "Unrecognized package type: "//pkgtype)
1229  end select
1230  end do
1231 
1232  ! Create budget manager
1233  call budget_cr(this%budget, this%name)
1234 
1235  ! Create tracking method pools
1236  call create_method_pool()
1239 
1240  ! Create packages that are tied directly to model
1241  call mip_cr(this%mip, this%name, mempathmip, this%inmip, this%iout, this%dis)
1242  call fmi_cr(this%fmi, this%name, mempathfmi, this%infmi, this%iout)
1243  call oc_cr(this%oc, this%name, mempathoc, this%inoc, this%iout)
1244 
1245  ! Check to make sure that required ftype's have been specified
1246  call this%ftype_check(indis)
1247 
1248  ! Create boundary packages
1249  call this%create_bndpkgs(bndpkgs, pkgtypes, pkgnames, mempaths, inunits)
1250  end subroutine create_packages
1251 
1252  !> @brief Write model namfile options to list file
1253  subroutine log_namfile_options(this, found)
1255  class(prtmodeltype) :: this
1256  type(prtnamparamfoundtype), intent(in) :: found
1257 
1258  write (this%iout, '(1x,a)') 'NAMEFILE OPTIONS:'
1259 
1260  if (found%print_input) then
1261  write (this%iout, '(4x,a)') 'STRESS PACKAGE INPUT WILL BE PRINTED '// &
1262  'FOR ALL MODEL STRESS PACKAGES'
1263  end if
1264 
1265  if (found%print_flows) then
1266  write (this%iout, '(4x,a)') 'PACKAGE FLOWS WILL BE PRINTED '// &
1267  'FOR ALL MODEL PACKAGES'
1268  end if
1269 
1270  if (found%save_flows) then
1271  write (this%iout, '(4x,a)') &
1272  'FLOWS WILL BE SAVED TO BUDGET FILE SPECIFIED IN OUTPUT CONTROL'
1273  end if
1274 
1275  write (this%iout, '(1x,a)') 'END NAMEFILE OPTIONS:'
1276  end subroutine log_namfile_options
1277 
1278 end module prtmodule
Event handler interface. Handlers may signal to the dispatching caller whether they have handled the ...
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:160
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
Models that solve themselves.
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:150
Particle track output module.
logical(lgp) function, public write_particle_event(context, particle, event)
Write a particle event to files for which the particle is eligible, and print the event to output uni...
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:561
subroutine prt_rp(this)
Read and prepare (calls package read and prepare routines)
Definition: prt.f90:338
subroutine create_bndpkgs(this, bndpkgs, pkgtypes, pkgnames, mempaths, inunits)
Source package info and begin to process.
Definition: prt.f90:1100
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:997
subroutine prt_ot_saveflow(this, nja, flowja, icbcfl, icbcun)
Save intercell flows.
Definition: prt.f90:643
subroutine prt_ad(this)
Time step advance (calls package advance subroutines)
Definition: prt.f90:358
subroutine prt_cq(this, icnvg, isuppress_output)
Calculate intercell flow (flowja)
Definition: prt.f90:401
subroutine package_create(this, filtyp, ipakid, ipaknum, pakname, mempath, inunit, iout)
Create boundary condition packages for this model.
Definition: prt.f90:949
subroutine prt_ot_flow(this, icbcfl, ibudfl, icbcun)
Save flows.
Definition: prt.f90:606
subroutine allocate_scalars(this, modelname)
Allocate memory for scalars.
Definition: prt.f90:890
subroutine prt_ot_bdsummary(this, ibudfl, ipflag)
Print budget summary.
Definition: prt.f90:793
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:1151
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:823
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:733
subroutine prt_bd(this, icnvg, isuppress_output)
Calculate flows and budget.
Definition: prt.f90:526
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:919
subroutine log_namfile_options(this, found)
Write model namfile options to list file.
Definition: prt.f90:1254
subroutine prt_cq_budterms(this)
Calculate particle mass budget terms.
Definition: prt.f90:447
subroutine prt_ot_dv(this, idvsave, idvprint, ipflag)
Print dependent variables.
Definition: prt.f90:772
subroutine prt_solve(this)
Solve the model.
Definition: prt.f90:1024
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:106
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:16
@ 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
Base type for models that solve themselves.
A generic heterogeneous doubly-linked list.
Definition: List.f90:14
Base type for particle tracking methods.
Definition: Method.f90:58
Dispatcher for particle events. Consumers subscribe handlers to the dispatcher. Events may be dispatc...
Particle tracked by the PRT model.
Definition: Particle.f90:62
Output file containing all or some particle pathlines.
Particle track output manager. Handles printing as well as writing to files. One output unit can be c...
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:39