MODFLOW 6  version 6.6.0.dev0
USGS Modular Hydrologic Model
prt-prp.f90
Go to the documentation of this file.
2  use kindmodule, only: dp, i4b, lgp
6  use bndmodule, only: bndtype
8  use tablemodule, only: tabletype, table_cr
14  use prtfmimodule, only: prtfmitype
25  use dismodule, only: distype
26  use disvmodule, only: disvtype
27  use errorutilmodule, only: pstop
28  use mathutilmodule, only: arange, is_close
30 
31  implicit none
32 
33  private
34  public :: prtprptype
35  public :: prp_create
36 
37  character(len=LENFTYPE) :: ftype = 'PRP'
38  character(len=16) :: text = ' PRP'
39 
40  !> @brief Particle release point (PRP) package
41  type, extends(bndtype) :: prtprptype
42  type(prtfmitype), pointer :: fmi => null() !< flow model interface
43  type(particlestoretype), pointer :: particles => null() !< particle store
44  type(trackcontroltype), pointer :: trackctl => null() !< track control
45  type(releasescheduletype), pointer :: schedule !< particle release schedule
46  integer(I4B), pointer :: nreleasepoints => null() !< number of release points
47  integer(I4B), pointer :: nreleasetimes => null() !< number of user-specified particle release times
48  integer(I4B), pointer :: nparticles => null() !< number of particles released
49  integer(I4B), pointer :: istopweaksink => null() !< weak sink option: 0 = no stop, 1 = stop
50  integer(I4B), pointer :: istopzone => null() !< optional stop zone number: 0 = no stop zone
51  integer(I4B), pointer :: idrape => null() !< drape option: 0 = do not drape, 1 = drape to topmost active cell
52  integer(I4B), pointer :: idrymeth => null() !< dry tracking method: 0 = drop, 1 = stop, 2 = stay
53  integer(I4B), pointer :: itrkout => null() !< binary track file
54  integer(I4B), pointer :: itrkhdr => null() !< track header file
55  integer(I4B), pointer :: itrkcsv => null() !< CSV track file
56  integer(I4B), pointer :: irlstls => null() !< release time file
57  integer(I4B), pointer :: ilocalz => null() !< compute z coordinates local to the cell
58  integer(I4B), pointer :: iextend => null() !< extend tracking beyond simulation's end
59  integer(I4B), pointer :: ifrctrn => null() !< force ternary solution for quad grids
60  integer(I4B), pointer :: iexmeth => null() !< method for iterative solution of particle exit location and time in generalized Pollock's method
61  real(dp), pointer :: extol => null() !< tolerance for iterative solution of particle exit location and time in generalized Pollock's method
62  real(dp), pointer :: rttol => null() !< tolerance for coincident particle release times
63  real(dp), pointer :: rtfreq => null() !< frequency for regularly spaced release times
64  real(dp), pointer :: offset => null() !< release time offset
65  real(dp), pointer :: stoptime => null() !< stop time for all release points
66  real(dp), pointer :: stoptraveltime => null() !< stop travel time for all points
67  logical(LGP), pointer :: foundtol => null() !< whether tolerance option was found
68  integer(I4B), pointer, contiguous :: rptnode(:) => null() !< release point reduced nns
69  integer(I4B), pointer, contiguous :: rptzone(:) => null() !< release point zone numbers
70  real(dp), pointer, contiguous :: rptx(:) => null() !< release point x coordinates
71  real(dp), pointer, contiguous :: rpty(:) => null() !< release point y coordinates
72  real(dp), pointer, contiguous :: rptz(:) => null() !< release point z coordinates
73  real(dp), pointer, contiguous :: rptm(:) => null() !< total mass released from point
74  character(len=LENBOUNDNAME), pointer, contiguous :: rptname(:) => null() !< release point names
75  contains
76  procedure :: prp_allocate_arrays
77  procedure :: prp_allocate_scalars
78  procedure :: bnd_ar => prp_ar
79  procedure :: bnd_ad => prp_ad
80  procedure :: bnd_rp => prp_rp
81  procedure :: bnd_cq_simrate => prp_cq_simrate
82  procedure :: bnd_da => prp_da
83  procedure :: define_listlabel
84  procedure :: prp_set_pointers
85  procedure :: bnd_options => prp_options
86  procedure :: read_dimensions => prp_read_dimensions
87  procedure :: prp_read_packagedata
88  procedure :: prp_read_releasetimes
90  procedure :: release
91  procedure :: log_release
93  procedure :: initialize_particle
94  procedure, public :: bnd_obs_supported => prp_obs_supported
95  procedure, public :: bnd_df_obs => prp_df_obs
96  end type prtprptype
97 
98 contains
99 
100  !> @brief Create a new particle release point package
101  subroutine prp_create(packobj, id, ibcnum, inunit, iout, namemodel, &
102  pakname, fmi)
103  ! dummy
104  class(bndtype), pointer :: packobj
105  integer(I4B), intent(in) :: id
106  integer(I4B), intent(in) :: ibcnum
107  integer(I4B), intent(in) :: inunit
108  integer(I4B), intent(in) :: iout
109  character(len=*), intent(in) :: namemodel
110  character(len=*), intent(in) :: pakname
111  type(prtfmitype), pointer :: fmi
112  ! local
113  type(prtprptype), pointer :: prpobj
114  ! formats
115  character(len=*), parameter :: fmtheader = &
116  "(1x, /1x, 'PRP PARTICLE RELEASE POINT PACKAGE', &
117  &' INPUT READ FROM UNIT ', i0, /)"
118 
119  ! allocate the object and assign values to object variables
120  allocate (prpobj)
121  packobj => prpobj
122 
123  ! create name and memory path
124  call packobj%set_names(ibcnum, namemodel, pakname, ftype)
125  prpobj%text = text
126 
127  ! allocate scalars
128  call prpobj%prp_allocate_scalars()
129 
130  ! initialize package
131  call packobj%pack_initialize()
132 
133  packobj%inunit = inunit
134  packobj%iout = iout
135  packobj%id = id
136  packobj%ibcnum = ibcnum
137  packobj%ncolbnd = 4
138  packobj%iscloc = 1
139 
140  ! store pointer to flow model interface
141  prpobj%fmi => fmi
142 
143  ! if prp is enabled, print a message identifying it
144  if (inunit > 0) write (iout, fmtheader) inunit
145  end subroutine prp_create
146 
147  !> @brief Deallocate memory
148  subroutine prp_da(this)
149  class(prtprptype) :: this
150 
151  ! Deallocate parent
152  call this%BndType%bnd_da()
153 
154  ! Deallocate scalars
155  call mem_deallocate(this%ilocalz)
156  call mem_deallocate(this%iextend)
157  call mem_deallocate(this%offset)
158  call mem_deallocate(this%stoptime)
159  call mem_deallocate(this%stoptraveltime)
160  call mem_deallocate(this%istopweaksink)
161  call mem_deallocate(this%istopzone)
162  call mem_deallocate(this%idrape)
163  call mem_deallocate(this%idrymeth)
164  call mem_deallocate(this%nreleasepoints)
165  call mem_deallocate(this%nreleasetimes)
166  call mem_deallocate(this%nparticles)
167  call mem_deallocate(this%itrkout)
168  call mem_deallocate(this%itrkhdr)
169  call mem_deallocate(this%itrkcsv)
170  call mem_deallocate(this%irlstls)
171  call mem_deallocate(this%ifrctrn)
172  call mem_deallocate(this%iexmeth)
173  call mem_deallocate(this%extol)
174  call mem_deallocate(this%rttol)
175  call mem_deallocate(this%rtfreq)
176  call mem_deallocate(this%foundtol)
177 
178  ! Deallocate arrays
179  call mem_deallocate(this%rptx)
180  call mem_deallocate(this%rpty)
181  call mem_deallocate(this%rptz)
182  call mem_deallocate(this%rptnode)
183  call mem_deallocate(this%rptm)
184  call mem_deallocate(this%rptname, 'RPTNAME', this%memoryPath)
185 
186  ! Deallocate particle store, release time and release step selections
187  call this%particles%deallocate(this%memoryPath)
188  call this%schedule%deallocate()
189  deallocate (this%particles)
190  deallocate (this%schedule)
191  end subroutine prp_da
192 
193  !> @ brief Set pointers to model variables
194  subroutine prp_set_pointers(this, ibound, izone, trackctl)
195  class(prtprptype) :: this
196  integer(I4B), dimension(:), pointer, contiguous :: ibound
197  integer(I4B), dimension(:), pointer, contiguous :: izone
198  type(trackcontroltype), pointer :: trackctl
199 
200  this%ibound => ibound
201  this%rptzone => izone
202  this%trackctl => trackctl
203  end subroutine prp_set_pointers
204 
205  !> @brief Allocate arrays
206  subroutine prp_allocate_arrays(this, nodelist, auxvar)
207  ! dummy
208  class(prtprptype) :: this
209  integer(I4B), dimension(:), pointer, contiguous, optional :: nodelist
210  real(DP), dimension(:, :), pointer, contiguous, optional :: auxvar
211  ! local
212  integer(I4B) :: nps
213 
214  ! Allocate particle store, starting with the number
215  ! of release points (arrays resized if/when needed)
217  this%particles, &
218  this%nreleasepoints, &
219  this%memoryPath)
220 
221  ! Allocate arrays
222  call mem_allocate(this%rptx, this%nreleasepoints, 'RPTX', this%memoryPath)
223  call mem_allocate(this%rpty, this%nreleasepoints, 'RPTY', this%memoryPath)
224  call mem_allocate(this%rptz, this%nreleasepoints, 'RPTZ', this%memoryPath)
225  call mem_allocate(this%rptm, this%nreleasepoints, 'RPTMASS', this%memoryPath)
226  call mem_allocate(this%rptnode, this%nreleasepoints, 'RPTNODER', &
227  this%memoryPath)
228  call mem_allocate(this%rptname, lenboundname, this%nreleasepoints, &
229  'RPTNAME', this%memoryPath)
230 
231  ! Initialize arrays
232  do nps = 1, this%nreleasepoints
233  this%rptm(nps) = dzero
234  end do
235  end subroutine prp_allocate_arrays
236 
237  !> @brief Allocate scalars
238  subroutine prp_allocate_scalars(this)
239  class(prtprptype) :: this
240 
241  ! Allocate parent's scalars
242  call this%BndType%allocate_scalars()
243 
244  ! Allocate scalars for this type
245  call mem_allocate(this%ilocalz, 'ILOCALZ', this%memoryPath)
246  call mem_allocate(this%iextend, 'IEXTEND', this%memoryPath)
247  call mem_allocate(this%offset, 'OFFSET', this%memoryPath)
248  call mem_allocate(this%stoptime, 'STOPTIME', this%memoryPath)
249  call mem_allocate(this%stoptraveltime, 'STOPTRAVELTIME', this%memoryPath)
250  call mem_allocate(this%istopweaksink, 'ISTOPWEAKSINK', this%memoryPath)
251  call mem_allocate(this%istopzone, 'ISTOPZONE', this%memoryPath)
252  call mem_allocate(this%idrape, 'IDRAPE', this%memoryPath)
253  call mem_allocate(this%idrymeth, 'IDRYMETH', this%memoryPath)
254  call mem_allocate(this%nreleasepoints, 'NRELEASEPOINTS', this%memoryPath)
255  call mem_allocate(this%nreleasetimes, 'NRELEASETIMES', this%memoryPath)
256  call mem_allocate(this%nparticles, 'NPARTICLES', this%memoryPath)
257  call mem_allocate(this%itrkout, 'ITRKOUT', this%memoryPath)
258  call mem_allocate(this%itrkhdr, 'ITRKHDR', this%memoryPath)
259  call mem_allocate(this%itrkcsv, 'ITRKCSV', this%memoryPath)
260  call mem_allocate(this%irlstls, 'IRLSTLS', this%memoryPath)
261  call mem_allocate(this%ifrctrn, 'IFRCTRN', this%memoryPath)
262  call mem_allocate(this%iexmeth, 'IEXMETH', this%memoryPath)
263  call mem_allocate(this%extol, 'EXTOL', this%memoryPath)
264  call mem_allocate(this%rttol, 'RTTOL', this%memoryPath)
265  call mem_allocate(this%rtfreq, 'RTFREQ', this%memoryPath)
266  call mem_allocate(this%foundtol, 'FOUNDTOL', this%memoryPath)
267 
268  ! Set values
269  this%ilocalz = 0
270  this%iextend = 0
271  this%offset = dzero
272  this%stoptime = huge(1d0)
273  this%stoptraveltime = huge(1d0)
274  this%istopweaksink = 0
275  this%istopzone = 0
276  this%idrape = 0
277  this%idrymeth = 0
278  this%nreleasepoints = 0
279  this%nreleasetimes = 0
280  this%nparticles = 0
281  this%itrkout = 0
282  this%itrkhdr = 0
283  this%itrkcsv = 0
284  this%irlstls = 0
285  this%ifrctrn = 0
286  this%iexmeth = 0
287  this%extol = dzero
288  this%rttol = dsame * dep9
289  this%rtfreq = dzero
290  this%foundtol = .false.
291 
292  end subroutine prp_allocate_scalars
293 
294  !> @ brief Allocate and read period data
295  subroutine prp_ar(this)
296  ! dummy variables
297  class(prtprptype), intent(inout) :: this
298  ! local variables
299  integer(I4B) :: n
300 
301  call this%obs%obs_ar()
302  call this%BndType%allocate_arrays()
303  if (this%inamedbound /= 0) then
304  do n = 1, this%nreleasepoints
305  this%boundname(n) = this%rptname(n)
306  end do
307  end if
308  do n = 1, this%nreleasepoints
309  this%nodelist(n) = this%rptnode(n)
310  end do
311  end subroutine prp_ar
312 
313  !> @brief Advance a time step and release particles if scheduled.
314  subroutine prp_ad(this)
315  class(prtprptype) :: this
316  integer(I4B) :: ip, it
317 
318  ! Notes
319  ! -----
320  ! Each release point can be thought of as
321  ! a gumball machine with infinite supply:
322  ! a point can release an arbitrary number
323  ! of particles, but only one at any time.
324  ! Coincident release times are merged to
325  ! a single time by the release scheduler.
326 
327  ! Reset mass accumulators for this time step.
328  do ip = 1, this%nreleasepoints
329  this%rptm(ip) = dzero
330  end do
331 
332  ! Advance the release schedule and check if
333  ! any releases will be made this time step.
334  call this%schedule%advance()
335  if (.not. this%schedule%any()) return
336 
337  ! Log the schedule to the list file.
338  call this%log_release()
339 
340  ! Expand the particle store. We know from the
341  ! schedule how many particles will be released.
342  call this%particles%resize( &
343  this%particles%num_stored() + &
344  (this%nreleasepoints * this%schedule%count()), &
345  this%memoryPath)
346 
347  ! Release a particle from each point for
348  ! each release time in the current step.
349  do ip = 1, this%nreleasepoints
350  do it = 1, this%schedule%count()
351  call this%release(ip, this%schedule%times(it))
352  end do
353  end do
354  end subroutine prp_ad
355 
356  !> @brief Log the release scheduled for this time step.
357  subroutine log_release(this)
358  class(prtprptype), intent(inout) :: this !< prp
359  if (this%iprpak > 0) then
360  write (this%iout, "(1x,/1x,a,1x,i0)") &
361  'PARTICLE RELEASE FOR PRP', this%ibcnum
362  call this%schedule%log(this%iout)
363  end if
364  end subroutine log_release
365 
366  !> @brief Verify that the release point is in the cell.
367  !!
368  !! Terminate with an error if the release point lies outside the
369  !! given cell, or if the point is above or below the grid top or
370  !! bottom, respectively.
371  !<
372  subroutine validate_release_point(this, ic, x, y, z)
373  class(prtprptype), intent(inout) :: this !< this instance
374  integer(I4B), intent(in) :: ic !< cell index
375  real(DP), intent(in) :: x, y, z !< release point
376  ! local
377  real(DP), allocatable :: polyverts(:, :)
378 
379  call this%fmi%dis%get_polyverts(ic, polyverts)
380  if (.not. point_in_polygon(x, y, polyverts)) then
381  write (errmsg, '(a,g0,a,g0,a,i0)') &
382  'Error: release point (x=', x, ', y=', y, ') is not in cell ', &
383  this%dis%get_nodeuser(ic)
384  call store_error(errmsg, terminate=.false.)
385  call store_error_unit(this%inunit, terminate=.true.)
386  end if
387  if (z > maxval(this%dis%top)) then
388  write (errmsg, '(a,g0,a,g0,a,i0)') &
389  'Error: release point (z=', z, ') is above grid top ', &
390  maxval(this%dis%top)
391  call store_error(errmsg, terminate=.false.)
392  call store_error_unit(this%inunit, terminate=.true.)
393  else if (z < minval(this%dis%bot)) then
394  write (errmsg, '(a,g0,a,g0,a,i0)') &
395  'Error: release point (z=', z, ') is below grid bottom ', &
396  minval(this%dis%bot)
397  call store_error(errmsg, terminate=.false.)
398  call store_error_unit(this%inunit, terminate=.true.)
399  end if
400  deallocate (polyverts)
401  end subroutine validate_release_point
402 
403  !> Release a particle at the specified time.
404  !!
405  !! Releasing a particle entails validating the particle's
406  !! coordinates and settings, transforming its coordinates
407  !! if needed, initializing the particle's initial tracking
408  !! time to the given release time, storing the particle in
409  !! the particle store (from which the PRT model will later
410  !! retrieve it, apply the tracking method, and check it in
411  !! again), and accumulating the particle's mass (the total
412  !! mass released from each release point is calculated for
413  !! budget reporting).
414  !<
415  subroutine release(this, ip, trelease)
416  ! dummy
417  class(prtprptype), intent(inout) :: this !< this instance
418  integer(I4B), intent(in) :: ip !< particle index
419  real(DP), intent(in) :: trelease !< release time
420  ! local
421  integer(I4B) :: np
422  type(particletype), pointer :: particle
423 
424  call this%initialize_particle(particle, ip, trelease)
425 
426  ! Increment cumulative particle count
427  np = this%nparticles + 1
428  this%nparticles = np
429 
430  ! Save the particle to the store
431  call this%particles%save_particle(particle, np)
432  deallocate (particle)
433 
434  ! Accumulate mass for release point
435  this%rptm(ip) = this%rptm(ip) + done
436 
437  end subroutine release
438 
439  subroutine initialize_particle(this, particle, ip, trelease)
440  class(prtprptype), intent(inout) :: this !< this instance
441  type(particletype), pointer, intent(inout) :: particle !< the particle
442  integer(I4B), intent(in) :: ip !< particle index
443  real(DP), intent(in) :: trelease !< release time
444  ! local
445  integer(I4B) :: irow, icol, ilay, icpl
446  integer(I4B) :: ic, icu, ic_old
447  real(DP) :: x, y, z
448  real(DP) :: top, bot, hds
449 
450  ic = this%rptnode(ip)
451  icu = this%dis%get_nodeuser(ic)
452 
453  call create_particle(particle)
454 
455  if (size(this%boundname) /= 0) then
456  particle%name = this%boundname(ip)
457  else
458  particle%name = ''
459  end if
460 
461  particle%irpt = ip
462  particle%istopweaksink = this%istopweaksink
463  particle%istopzone = this%istopzone
464  particle%idrymeth = this%idrymeth
465  particle%icu = icu
466 
467  select type (dis => this%dis)
468  type is (distype)
469  call get_ijk(icu, dis%nrow, dis%ncol, dis%nlay, irow, icol, ilay)
470  type is (disvtype)
471  call get_jk(icu, dis%ncpl, dis%nlay, icpl, ilay)
472  end select
473  particle%ilay = ilay
474  particle%izone = this%rptzone(ic)
475 
476  particle%istatus = 0
477  ! If the cell is inactive, either drape the particle
478  ! to the top-most active cell beneath it if drape is
479  ! enabled, or else terminate permanently unreleased.
480  if (this%ibound(ic) == 0) then
481  ic_old = ic
482  if (this%idrape > 0) then
483  call this%dis%highest_active(ic, this%ibound)
484  if (ic == ic_old .or. this%ibound(ic) == 0) &
485  particle%istatus = 8
486  else
487  particle%istatus = 8
488  end if
489  end if
490 
491  ! Load coordinates and transform if needed
492  x = this%rptx(ip)
493  y = this%rpty(ip)
494  if (this%ilocalz > 0) then
495  top = this%fmi%dis%top(ic)
496  bot = this%fmi%dis%bot(ic)
497  hds = this%fmi%gwfhead(ic)
498  z = bot + this%rptz(ip) * (hds - bot)
499  else
500  z = this%rptz(ip)
501  end if
502 
503  call this%validate_release_point(ic, x, y, z)
504 
505  particle%x = x
506  particle%y = y
507  particle%z = z
508  particle%trelease = trelease
509 
510  ! Set stop time to earlier of STOPTIME and STOPTRAVELTIME
511  if (this%stoptraveltime == huge(1d0)) then
512  particle%tstop = this%stoptime
513  else
514  particle%tstop = particle%trelease + this%stoptraveltime
515  if (this%stoptime < particle%tstop) particle%tstop = this%stoptime
516  end if
517 
518  particle%ttrack = particle%trelease
519  particle%idomain(1) = 0
520  particle%iboundary(1) = 0
521  particle%idomain(2) = ic
522  particle%iboundary(2) = 0
523  particle%idomain(3) = 0
524  particle%iboundary(3) = 0
525  particle%ifrctrn = this%ifrctrn
526  particle%iexmeth = this%iexmeth
527  particle%iextend = this%iextend
528  particle%extol = this%extol
529  end subroutine initialize_particle
530 
531  !> @ brief Read and prepare period data for particle input
532  subroutine prp_rp(this)
533  ! modules
534  use tdismodule, only: kper, nper
535  use inputoutputmodule, only: urword
536  ! dummy variables
537  class(prtprptype), intent(inout) :: this
538  ! local variables
539  integer(I4B) :: ierr
540  logical(LGP) :: is_found
541  logical(LGP) :: end_of_block
542  logical(LGP) :: no_blocks
543  character(len=LINELENGTH) :: line
544  character(len=LINELENGTH), allocatable :: lines(:)
545  ! formats
546  character(len=*), parameter :: fmtblkerr = &
547  "('Looking for BEGIN PERIOD iper. &
548  &Found ', a, ' instead.')"
549  character(len=*), parameter :: fmt_steps = &
550  "(6x,'TIME STEP(S) ',50(I0,' '))" ! 50 limit is similar to STEPS in OC
551  character(len=*), parameter :: fmt_freq = &
552  "(6x,'EVERY ',I0,' TIME STEP(S)')"
553  character(len=*), parameter :: fmt_fracs = &
554  "(6x,50(f10.3,' '))"
555 
556  ! Set ionper to the stress period number for which a new block of data
557  ! will be read.
558  if (this%inunit == 0) return
559 
560  ! get stress period data
561  no_blocks = .false.
562  if (this%ionper < kper) then
563  ! get period block
564  call this%parser%GetBlock('PERIOD', is_found, ierr, &
565  supportopenclose=.true., &
566  blockrequired=.false.)
567  if (is_found) then
568  ! read ionper and check for increasing period numbers
569  call this%read_check_ionper()
570  else
571  ! PERIOD block not found
572  if (ierr < 0) then
573  if (kper == 1) then
574  ! End of file found; no period data for the simulation.
575  no_blocks = .true.
576  else
577  ! End of file found; no more period data.
578  this%ionper = nper + 1
579  end if
580  else
581  ! Found invalid block
582  call this%parser%GetCurrentLine(line)
583  write (errmsg, fmtblkerr) adjustl(trim(line))
584  call store_error(errmsg, terminate=.true.)
585  end if
586  end if
587  end if
588 
589  ! If the user hasn't provided any release settings (neither
590  ! explicit release times, release time frequency, or period
591  ! block release settings), default to a single release at the
592  ! start of the first period's first time step.
593  if (no_blocks .and. &
594  kper == 1 .and. &
595  size(this%schedule%time_select%times) == 0) then
596  allocate (lines(1))
597  line = "FIRST"
598  lines(1) = line
599  call this%schedule%advance(lines=lines)
600  else if (this%ionper == kper) then
601  ! If the current stress period matches the
602  ! block we are reading, parse the setting
603  ! and register it with the schedule.
604  allocate (lines(0))
605  recordloop: do
606  call this%parser%GetNextLine(end_of_block)
607  if (end_of_block) exit recordloop
608  call this%parser%GetCurrentLine(line)
609  call expandarray(lines)
610  lines(size(lines)) = line
611  end do recordloop
612  if (size(lines) > 0) &
613  call this%schedule%advance(lines=lines)
614  deallocate (lines)
615  end if
616 
617  end subroutine prp_rp
618 
619  !> @ brief Calculate flow between package and model.
620  subroutine prp_cq_simrate(this, hnew, flowja, imover)
621  ! modules
622  use tdismodule, only: delt
623  ! dummy variables
624  class(prtprptype) :: this
625  real(DP), dimension(:), intent(in) :: hnew
626  real(DP), dimension(:), intent(inout) :: flowja !< flow between package and model
627  integer(I4B), intent(in) :: imover !< flag indicating if the mover package is active
628  ! local variables
629  integer(I4B) :: i
630  integer(I4B) :: node
631  integer(I4B) :: idiag
632  real(DP) :: rrate
633 
634  ! If no boundaries, skip flow calculations.
635  if (this%nbound <= 0) return
636 
637  ! Loop through each boundary calculating flow.
638  do i = 1, this%nbound
639  node = this%nodelist(i)
640  rrate = dzero
641  ! If cell is no-flow or constant-head, then ignore it.
642  if (node > 0) then
643  ! Calculate the flow rate into the cell.
644  idiag = this%dis%con%ia(node)
645  rrate = this%rptm(i) * (done / delt) ! reciprocal of tstp length
646  flowja(idiag) = flowja(idiag) + rrate
647  end if
648 
649  ! Save simulated value to simvals array.
650  this%simvals(i) = rrate
651  end do
652  end subroutine prp_cq_simrate
653 
654  subroutine define_listlabel(this)
655  class(prtprptype), intent(inout) :: this
656  ! not implemented, not used
657  end subroutine define_listlabel
658 
659  !> @brief Indicates whether observations are supported.
660  logical function prp_obs_supported(this)
661  class(prtprptype) :: this
662  prp_obs_supported = .true.
663  end function prp_obs_supported
664 
665  !> @brief Store supported observations
666  subroutine prp_df_obs(this)
667  ! dummy
668  class(prtprptype) :: this
669  ! local
670  integer(I4B) :: indx
671  call this%obs%StoreObsType('prp', .true., indx)
672  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
673 
674  ! Store obs type and assign procedure pointer
675  ! for to-mvr observation type.
676  call this%obs%StoreObsType('to-mvr', .true., indx)
677  this%obs%obsData(indx)%ProcessIdPtr => defaultobsidprocessor
678  end subroutine prp_df_obs
679 
680  !> @brief Set options specific to PrtPrpType
681  subroutine prp_options(this, option, found)
682  use openspecmodule, only: access, form
683  use constantsmodule, only: maxcharlen, dzero
686  ! dummy
687  class(prtprptype), intent(inout) :: this
688  character(len=*), intent(inout) :: option
689  logical(LGP), intent(inout) :: found
690  ! locals
691  character(len=MAXCHARLEN) :: fname
692  character(len=MAXCHARLEN) :: keyword
693  ! formats
694  character(len=*), parameter :: fmttrkbin = &
695  "(4x, 'PARTICLE TRACKS WILL BE SAVED TO BINARY FILE: ', a, /4x, &
696  &'OPENED ON UNIT: ', I0)"
697  character(len=*), parameter :: fmttrkcsv = &
698  "(4x, 'PARTICLE TRACKS WILL BE SAVED TO CSV FILE: ', a, /4x, &
699  &'OPENED ON UNIT: ', I0)"
700 
701  select case (option)
702  case ('STOPTIME')
703  this%stoptime = this%parser%GetDouble()
704  found = .true.
705  case ('STOPTRAVELTIME')
706  this%stoptraveltime = this%parser%GetDouble()
707  found = .true.
708  case ('STOP_AT_WEAK_SINK')
709  this%istopweaksink = 1
710  found = .true.
711  case ('ISTOPZONE')
712  this%istopzone = this%parser%GetInteger()
713  found = .true.
714  case ('DRAPE')
715  this%idrape = 1
716  found = .true.
717  case ('DRY_TRACKING_METHOD')
718  call this%parser%GetStringCaps(keyword)
719  select case (keyword)
720  case ('DROP')
721  this%idrymeth = 0
722  case ('STOP')
723  this%idrymeth = 1
724  case ('STAY')
725  this%idrymeth = 2
726  case default
727  write (errmsg, '(a, a)') &
728  'Unknown dry tracking method: ', trim(keyword)
729  call store_error(errmsg)
730  write (errmsg, '(a, a)') &
731  'DRY must be "DROP", "STOP" or "STAY"'
732  call store_error(errmsg)
733  call this%parser%StoreErrorUnit()
734  end select
735  found = .true.
736  case ('TRACK')
737  call this%parser%GetStringCaps(keyword)
738  if (keyword == 'FILEOUT') then
739  ! parse filename
740  call this%parser%GetString(fname)
741  ! open binary output file
742  this%itrkout = getunit()
743  call openfile(this%itrkout, this%iout, fname, 'DATA(BINARY)', &
744  form, access, filstat_opt='REPLACE', &
745  mode_opt=mnormal)
746  write (this%iout, fmttrkbin) trim(adjustl(fname)), this%itrkout
747  ! open and write ascii header spec file
748  this%itrkhdr = getunit()
749  fname = trim(fname)//'.hdr'
750  call openfile(this%itrkhdr, this%iout, fname, 'CSV', &
751  filstat_opt='REPLACE', mode_opt=mnormal)
752  write (this%itrkhdr, '(a,/,a)') trackheader, trackdtypes
753  else
754  call store_error('OPTIONAL TRACK KEYWORD MUST BE '// &
755  'FOLLOWED BY FILEOUT')
756  end if
757  found = .true.
758  case ('TRACKCSV')
759  call this%parser%GetStringCaps(keyword)
760  if (keyword == 'FILEOUT') then
761  ! parse filename
762  call this%parser%GetString(fname)
763  ! open CSV output file and write headers
764  this%itrkcsv = getunit()
765  call openfile(this%itrkcsv, this%iout, fname, 'CSV', &
766  filstat_opt='REPLACE')
767  write (this%iout, fmttrkcsv) trim(adjustl(fname)), this%itrkcsv
768  write (this%itrkcsv, '(a)') trackheader
769  else
770  call store_error('OPTIONAL TRACKCSV KEYWORD MUST BE &
771  &FOLLOWED BY FILEOUT')
772  end if
773  found = .true.
774  case ('LOCAL_Z')
775  this%ilocalz = 1
776  found = .true.
777  case ('EXTEND_TRACKING')
778  this%iextend = 1
779  found = .true.
780  case ('EXIT_SOLVE_TOLERANCE')
781  this%extol = this%parser%GetDouble()
782  if (this%extol <= dzero) &
783  call store_error('EXIT_SOLVE_TOLERANCE MUST BE POSITIVE')
784  found = .true.
785  this%foundtol = .true.
786  case ('RELEASE_TIME_TOLERANCE')
787  this%rttol = this%parser%GetDouble()
788  if (this%rttol <= dzero) &
789  call store_error('RELEASE_TIME_TOLERANCE MUST BE POSITIVE')
790  found = .true.
791  case ('RELEASE_TIME_FREQUENCY')
792  this%rtfreq = this%parser%GetDouble()
793  if (this%rtfreq <= dzero) &
794  call store_error('RELEASE_TIME_FREQUENCY MUST BE POSITIVE')
795  found = .true.
796  case ('DEV_FORCETERNARY')
797  call this%parser%DevOpt()
798  this%ifrctrn = 1
799  write (this%iout, '(4x,a)') &
800  'TRACKING WILL BE DONE USING THE TERNARY METHOD REGARDLESS OF CELL TYPE'
801  found = .true.
802  case ('DEV_EXIT_SOLVE_METHOD')
803  call this%parser%DevOpt()
804  this%iexmeth = this%parser%GetInteger()
805  if (.not. (this%iexmeth /= 1 .or. this%iexmeth /= 2)) &
806  call store_error('DEV_EXIT_SOLVE_METHOD MUST BE &
807  &1 (BRENT) OR 2 (CHANDRUPATLA)')
808  found = .true.
809  case default
810  found = .false.
811  end select
812 
813  ! Catch unrecognized options
814  if (.not. found) then
815  errmsg = "UNKNOWN PRP OPTION '"//trim(keyword)//"'."
816  call store_error(errmsg)
817  call this%parser%StoreErrorUnit()
818  end if
819 
820  ! Create release schedule now that we know
821  ! the coincident release time tolerance
822  this%schedule => create_release_schedule(tol=this%rttol)
823 
824  end subroutine prp_options
825 
826  !> @brief Read package dimensions
827  subroutine prp_read_dimensions(this)
828  ! dummy
829  class(prtprptype), intent(inout) :: this
830  ! local
831  character(len=LINELENGTH) :: errmsg, keyword
832  integer(I4B) :: ierr
833  logical :: isfound, endOfBlock
834 
835  if (.not. this%foundtol) &
836  call store_error('EXIT_SOLVE_TOLERANCE MISSING, VALUE REQUIRED')
837 
838  ! get dimension block
839  call this%parser%GetBlock('DIMENSIONS', isfound, ierr, &
840  supportopenclose=.true.)
841 
842  ! parse dimension block if detected
843  if (isfound) then
844  write (this%iout, '(1x,a)') 'PROCESSING PARTICLE INPUT DIMENSIONS'
845  do
846  call this%parser%GetNextLine(endofblock)
847  if (endofblock) exit
848  call this%parser%GetStringCaps(keyword)
849  select case (keyword)
850  case ('NRELEASEPTS')
851  this%nreleasepoints = this%parser%GetInteger()
852  case ('NRELEASETIMES')
853  this%nreleasetimes = this%parser%GetInteger()
854  case default
855  write (errmsg, &
856  '(4x,a,a)') '****ERROR. UNKNOWN PARTICLE INPUT DIMENSION: ', &
857  trim(keyword)
858  call store_error(errmsg)
859  call this%parser%StoreErrorUnit()
860  end select
861  end do
862  write (this%iout, '(1x,a)') 'END OF PARTICLE INPUT DIMENSIONS'
863  else
864  call store_error('ERROR. REQUIRED DIMENSIONS BLOCK NOT FOUND.')
865  end if
866 
867  ! set maxbound and nbound to nreleasepts
868  this%maxbound = this%nreleasepoints
869  this%nbound = this%nreleasepoints
870 
871  ! allocate arrays for prp package
872  call this%prp_allocate_arrays()
873 
874  ! read packagedata and releasetimes blocks
875  call this%prp_read_packagedata()
876  call this%prp_read_releasetimes()
877  call this%prp_load_releasetimefrequency()
878  end subroutine prp_read_dimensions
879 
880  !> @brief Load package data (release points).
881  subroutine prp_read_packagedata(this)
882  ! dummy
883  class(prtprptype), intent(inout) :: this
884  ! local
885  character(len=LINELENGTH) :: cellid
886  character(len=LENBOUNDNAME) :: bndName, bndNameTemp
887  character(len=9) :: cno
888  logical :: isfound
889  logical :: endOfBlock
890  integer(I4B) :: ival
891  integer(I4B) :: n
892  integer(I4B) :: ierr
893  character(len=LENBOUNDNAME), dimension(:), allocatable :: nametxt
894  integer(I4B), dimension(:), allocatable :: nboundchk
895  integer(I4B), dimension(:), allocatable :: noder
896  real(DP), dimension(:), allocatable :: x
897  real(DP), dimension(:), allocatable :: y
898  real(DP), dimension(:), allocatable :: z
899  real(DP), dimension(:), allocatable :: tstop
900  ! format
901  character(len=*), parameter :: fmttend = &
902  "('end time (', G0, ') must be greater than or equal to the &
903  &begin time (', G0, ').')"
904 
905  ! allocate temporary variables
906  allocate (noder(this%nreleasepoints))
907  allocate (x(this%nreleasepoints))
908  allocate (y(this%nreleasepoints))
909  allocate (z(this%nreleasepoints))
910  allocate (tstop(this%nreleasepoints))
911  allocate (nametxt(this%nreleasepoints))
912  allocate (nboundchk(this%nreleasepoints))
913 
914  ! initialize temporary variables
915  do n = 1, this%nreleasepoints
916  nboundchk(n) = 0
917  end do
918 
919  ! read particle release point data
920  ! get particle release points block
921  call this%parser%GetBlock('PACKAGEDATA', isfound, ierr, &
922  supportopenclose=.true.)
923 
924  ! parse block if detected
925  if (isfound) then
926  write (this%iout, '(/1x,a)') 'PROCESSING '//trim(adjustl(this%packName)) &
927  //' PACKAGEDATA'
928  do
929  call this%parser%GetNextLine(endofblock)
930  if (endofblock) exit
931  ival = this%parser%GetInteger()
932  n = ival
933 
934  if (n < 1 .or. n > this%nreleasepoints) then
935  write (errmsg, '(a,1x,i0,a)') &
936  'Release point number must be greater than 0 and less than', &
937  'or equal to', this%nreleasepoints, '.'
938  call store_error(errmsg)
939  cycle
940  end if
941 
942  ! increment nboundchk
943  nboundchk(n) = nboundchk(n) + 1
944 
945  ! node number
946  call this%parser%GetCellid(this%dis%ndim, cellid)
947  noder(n) = this%dis%noder_from_cellid(cellid, this%inunit, this%iout)
948 
949  ! x, y, z coordinates
950  x(n) = this%parser%GetDouble()
951  y(n) = this%parser%GetDouble()
952  z(n) = this%parser%GetDouble()
953 
954  if (this%ilocalz > 0 .and. (z(n) < 0 .or. z(n) > 1)) then
955  call store_error('Local z coordinate must fall in the interval [0, 1]')
956  cycle
957  end if
958 
959  ! set default boundname
960  write (cno, '(i9.9)') n
961  bndname = 'PRP'//cno
962 
963  ! read boundnames from file, if provided
964  if (this%inamedbound /= 0) then
965  call this%parser%GetStringCaps(bndnametemp)
966  if (bndnametemp /= '') &
967  bndname = bndnametemp
968  else
969  bndname = ''
970  end if
971 
972  ! store temp boundnames
973  nametxt(n) = bndname
974  end do
975 
976  write (this%iout, '(1x,a)') &
977  'END OF '//trim(adjustl(this%packName))//' PACKAGEDATA'
978 
979  ! check for duplicate or missing particle release points
980  do n = 1, this%nreleasepoints
981  if (nboundchk(n) == 0) then
982  write (errmsg, '(a,a,1x,i0,a)') 'No data specified for particle ', &
983  'release point', n, '.'
984  call store_error(errmsg)
985  else if (nboundchk(n) > 1) then
986  write (errmsg, '(a,1x,i0,1x,a,1x,i0,1x,a)') &
987  'Data for particle release point', n, 'specified', nboundchk(n), &
988  'times.'
989  call store_error(errmsg)
990  end if
991  end do
992  else
993  call store_error('Required packagedata block not found.')
994  end if
995 
996  ! terminate if any errors were detected
997  if (count_errors() > 0) then
998  call this%parser%StoreErrorUnit()
999  end if
1000 
1001  ! fill particle release point data with data stored in temporary local arrays
1002  do n = 1, this%nreleasepoints
1003  this%rptnode(n) = noder(n)
1004  this%rptx(n) = x(n)
1005  this%rpty(n) = y(n)
1006  this%rptz(n) = z(n)
1007  this%rptname(n) = nametxt(n)
1008  end do
1009 
1010  ! deallocate local storage
1011  deallocate (noder)
1012  deallocate (x)
1013  deallocate (y)
1014  deallocate (z)
1015  deallocate (tstop)
1016  deallocate (nametxt)
1017  deallocate (nboundchk)
1018  end subroutine prp_read_packagedata
1019 
1020  !> @brief Load explicitly specified release times.
1021  subroutine prp_read_releasetimes(this)
1022  ! dummy
1023  class(prtprptype), intent(inout) :: this
1024  ! local
1025  integer(I4B) :: i, ierr
1026  logical(LGP) :: eob, found, success
1027  real(DP) :: t
1028  real(DP), allocatable :: times(:)
1029 
1030  ! get releasetimes block
1031  call this%parser%GetBlock('RELEASETIMES', found, ierr, &
1032  supportopenclose=.true., &
1033  blockrequired=.false.)
1034 
1035  ! raise an error if releasetimes has a dimension
1036  ! but no block was found, otherwise return early
1037  if (.not. found) then
1038  if (this%nreleasetimes <= 0) return
1039  write (errmsg, '(a, i0)') &
1040  "Expected RELEASETIMES with length ", this%nreleasetimes
1041  call store_error(errmsg)
1042  call this%parser%StoreErrorUnit(terminate=.true.)
1043  end if
1044 
1045  ! allocate times array
1046  allocate (times(this%nreleasetimes))
1047 
1048  ! read times from the block
1049  write (this%iout, '(/1x,a)') &
1050  'PROCESSING '//trim(adjustl(this%text))//' RELEASETIMES'
1051  do i = 1, this%nreleasetimes
1052  call this%parser%GetNextLine(eob)
1053  if (eob) exit
1054  call this%parser%TryGetDouble(t, success)
1055  if (.not. success) then
1056  errmsg = "Failed to read double precision value"
1057  call store_error(errmsg)
1058  call this%parser%StoreErrorUnit(terminate=.true.)
1059  end if
1060  times(i) = t
1061  end do
1062 
1063  ! register times with the release schedule
1064  call this%schedule%time_select%extend(times)
1065 
1066  ! make sure times strictly increase
1067  if (.not. this%schedule%time_select%increasing()) then
1068  errmsg = "Release times must strictly increase"
1069  call store_error(errmsg)
1070  call this%parser%StoreErrorUnit(terminate=.true.)
1071  end if
1072 
1073  ! deallocate
1074  deallocate (times)
1075 
1076  end subroutine prp_read_releasetimes
1077 
1078  !> @brief Load regularly spaced release times if configured.
1080  ! modules
1081  use tdismodule, only: totalsimtime
1082  ! dummy
1083  class(prtprptype), intent(inout) :: this
1084  ! local
1085  real(DP), allocatable :: times(:)
1086 
1087  ! check if a release time frequency is configured
1088  if (this%rtfreq <= dzero) return
1089 
1090  ! create array of regularly-spaced release times
1091  times = arange( &
1092  start=dzero, &
1093  stop=totalsimtime, &
1094  step=this%rtfreq)
1095 
1096  ! register times with release schedule
1097  call this%schedule%time_select%extend(times)
1098 
1099  ! make sure times strictly increase
1100  if (.not. this%schedule%time_select%increasing()) then
1101  errmsg = "Release times must strictly increase"
1102  call store_error(errmsg)
1103  call this%parser%StoreErrorUnit(terminate=.true.)
1104  end if
1105 
1106  ! deallocate
1107  deallocate (times)
1108 
1109  end subroutine prp_load_releasetimefrequency
1110 
1111 end module prtprpmodule
This module contains block parser methods.
Definition: BlockParser.f90:7
This module contains the base boundary package.
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dsame
real constant for values that are considered the same based on machine precision
Definition: Constants.f90:122
integer(i4b), parameter linelength
maximum length of a standard line
Definition: Constants.f90:45
@ tabcenter
centered table column
Definition: Constants.f90:172
@ tableft
left justified table column
Definition: Constants.f90:171
@ mnormal
normal output mode
Definition: Constants.f90:206
real(dp), parameter dep3
real constant 1000
Definition: Constants.f90:88
integer(i4b), parameter lenpakloc
maximum length of a package location
Definition: Constants.f90:50
real(dp), parameter dem1
real constant 1e-1
Definition: Constants.f90:103
real(dp), parameter dep9
real constant 1e9
Definition: Constants.f90:90
integer(i4b), parameter lenftype
maximum length of a package type (DIS, WEL, OC, etc.)
Definition: Constants.f90:39
integer(i4b), parameter lenboundname
maximum length of a bound name
Definition: Constants.f90:36
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
integer(i4b), parameter maxcharlen
maximum length of char string
Definition: Constants.f90:47
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
Definition: Dis.f90:1
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
Definition: ErrorUtil.f90:24
logical function, public point_in_polygon(x, y, poly)
Check if a point is within a polygon.
Definition: GeomUtil.f90:27
subroutine, public get_ijk(nodenumber, nrow, ncol, nlay, irow, icol, ilay)
Get row, column and layer indices from node number and grid dimensions. If nodenumber is invalid,...
Definition: GeomUtil.f90:100
subroutine, public get_jk(nodenumber, ncpl, nlay, icpl, ilay)
Get layer index and within-layer node index from node number and grid dimensions. If nodenumber is in...
Definition: GeomUtil.f90:128
integer(i4b) function, public getunit()
Get a free unit number.
subroutine, public openfile(iu, iout, fname, ftype, fmtarg_opt, accarg_opt, filstat_opt, mode_opt)
Open a file.
Definition: InputOutput.f90:30
subroutine, public urword(line, icol, istart, istop, ncode, n, r, iout, in)
Extract a word from a string.
This module defines variable data types.
Definition: kind.f90:8
pure real(dp) function, dimension(:), allocatable, public arange(start, stop, step)
Return reals separated by the given step over the given interval.
Definition: MathUtil.f90:384
pure logical function, public is_close(a, b, rtol, atol, symmetric)
Check if a real value is approximately equal to another.
Definition: MathUtil.f90:46
This module contains the derived type ObsType.
Definition: Obs.f90:127
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
Definition: Obs.f90:246
character(len=20) access
Definition: OpenSpec.f90:7
character(len=20) form
Definition: OpenSpec.f90:7
subroutine, public allocate_particle_store(this, np, mempath)
Create a new particle store.
Definition: Particle.f90:127
subroutine, public create_particle(particle)
Create a new particle.
Definition: Particle.f90:119
subroutine prp_set_pointers(this, ibound, izone, trackctl)
@ brief Set pointers to model variables
Definition: prt-prp.f90:195
subroutine prp_allocate_arrays(this, nodelist, auxvar)
Allocate arrays.
Definition: prt-prp.f90:207
subroutine prp_rp(this)
@ brief Read and prepare period data for particle input
Definition: prt-prp.f90:533
subroutine prp_load_releasetimefrequency(this)
Load regularly spaced release times if configured.
Definition: prt-prp.f90:1080
subroutine prp_cq_simrate(this, hnew, flowja, imover)
@ brief Calculate flow between package and model.
Definition: prt-prp.f90:621
subroutine prp_read_dimensions(this)
Read package dimensions.
Definition: prt-prp.f90:828
character(len=lenftype) ftype
Definition: prt-prp.f90:37
subroutine prp_read_releasetimes(this)
Load explicitly specified release times.
Definition: prt-prp.f90:1022
subroutine prp_df_obs(this)
Store supported observations.
Definition: prt-prp.f90:667
subroutine, public prp_create(packobj, id, ibcnum, inunit, iout, namemodel, pakname, fmi)
Create a new particle release point package.
Definition: prt-prp.f90:103
subroutine define_listlabel(this)
Definition: prt-prp.f90:655
subroutine log_release(this)
Log the release scheduled for this time step.
Definition: prt-prp.f90:358
subroutine prp_ad(this)
Advance a time step and release particles if scheduled.
Definition: prt-prp.f90:315
subroutine prp_allocate_scalars(this)
Allocate scalars.
Definition: prt-prp.f90:239
subroutine initialize_particle(this, particle, ip, trelease)
Definition: prt-prp.f90:440
subroutine prp_da(this)
Deallocate memory.
Definition: prt-prp.f90:149
character(len=16) text
Definition: prt-prp.f90:38
logical function prp_obs_supported(this)
Indicates whether observations are supported.
Definition: prt-prp.f90:661
subroutine prp_ar(this)
@ brief Allocate and read period data
Definition: prt-prp.f90:296
subroutine release(this, ip, trelease)
Release a particle at the specified time.
Definition: prt-prp.f90:416
subroutine prp_read_packagedata(this)
Load package data (release points).
Definition: prt-prp.f90:882
subroutine validate_release_point(this, ic, x, y, z)
Verify that the release point is in the cell.
Definition: prt-prp.f90:373
subroutine prp_options(this, option, found)
Set options specific to PrtPrpType.
Definition: prt-prp.f90:682
Particle release scheduling.
type(releasescheduletype) function, pointer, public create_release_schedule(tol)
Create a new release schedule object.
This module contains simulation methods.
Definition: Sim.f90:10
subroutine, public store_warning(msg, substring)
Store warning message.
Definition: Sim.f90:236
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_unit(iunit, terminate)
Store the file unit number.
Definition: Sim.f90:168
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
character(len=maxcharlen) warnmsg
warning message string
subroutine, public table_cr(this, name, title)
Definition: Table.f90:87
real(dp), pointer, public totalsimtime
time at end of simulation
Definition: tdis.f90:37
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
integer(i4b), pointer, public nper
number of stress period
Definition: tdis.f90:21
type(timeserieslinktype) function, pointer, public gettimeserieslinkfromlist(list, indx)
Get time series link from a list.
character(len= *), parameter, public trackdtypes
Definition: TrackFile.f90:81
character(len= *), parameter, public trackheader
Definition: TrackFile.f90:77
@ brief BndType
Structured grid discretization.
Definition: Dis.f90:23
Vertex grid discretization.
Definition: Disv.f90:24
Structure of arrays to store particles.
Definition: Particle.f90:78
Particle tracked by the PRT model.
Definition: Particle.f90:32
Particle release point (PRP) package.
Definition: prt-prp.f90:41
Particle release scheduling utility.
Manages particle track (i.e. pathline) files.