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