MODFLOW 6  version 6.7.0.dev1
USGS Modular Hydrologic Model
Particle.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, i4b, lgp
7  implicit none
8  public
9 
10  !> Tracking "levels" (1: model, 2: cell, 3: subcell). A
11  !! level identifies the domain through which a tracking
12  !! method is responsible for moving a particle. Methods
13  !! each operate on a particular level, delegating among
14  !! more methods as appropriate for finer-grained levels.
15  integer, parameter :: max_level = 4
16 
17  !> @brief Particle status enumeration.
18  !!
19  !! Particles begin in status 1 (active) at release time. Status may only
20  !! increase over time. Status values greater than one imply termination.
21  !! A particle may terminate for several reasons, all mutually exclusive.
22  !! A particle's final tracking status will always be greater than one.
23  !!
24  !! Status codes 0-3 and 5-8 correspond directly to MODPATH 7 status codes.
25  !! Code 4 does not apply to PRT because PRT does not distinguish forwards
26  !! from backwards tracking. Status code 9 provides more specific, subcell-
27  !! level information about a particle which terminates due to no outflow.
28  !! Code 10 distinguishes particles which have "timed out" upon reaching a
29  !! user-specified stop time or the end of the simulation.
30  !<
31  enum, bind(C)
32  enumerator :: active = 1
33  enumerator :: term_boundary = 2 !< terminated at a boundary face
34  enumerator :: term_weaksink = 3 !< terminated in a weak sink cell
35  enumerator :: term_no_exits = 5 !< terminated in a cell with no exit face
36  enumerator :: term_stopzone = 6 !< terminated in a cell with a stop zone number
37  enumerator :: term_inactive = 7 !< terminated in an inactive cell
38  enumerator :: term_unreleased = 8 !< terminated permanently unreleased
39  enumerator :: term_no_exits_sub = 9 !< terminated in a subcell with no exit face
40  enumerator :: term_timeout = 10 !< terminated at stop time or end of simulation
41  end enum
42 
43  !> @brief Particle event enumeration.
44  !!
45  !! A number of events may occur to particles, each of which may (or may
46  !! not) be of interest to the user. The user selects among events to be
47  !! reported. A corresponding event code is reported with each record to
48  !! identify the record's cause.
49  !!
50  !! Records may be identical except for their event code, reflecting the
51  !! fact that multiple events of interest may occur at any given moment.
52  !<
53  enum, bind(C)
54  enumerator :: release = 0 !< particle was released
55  enumerator :: exit = 1 !< particle exited a cell
56  enumerator :: timestep = 2 !< time step ended
57  enumerator :: terminate = 3 !< particle terminated
58  enumerator :: weaksink = 4 !< particle entered a weak sink cell
59  enumerator :: usertime = 5 !< user-specified tracking time
60  end enum
61 
62  !> @brief Particle tracked by the PRT model.
63  !!
64  !! Record-type to conveniently shuffle a particle's
65  !! state to/from storage before/after its trajectory
66  !! is solved for each time step.
67  !!
68  !! Particle coordinates may be local to the cell or
69  !! global/model. Routines are provided to convert a
70  !! particle's global coordinates to/from cell-local
71  !! coordinates for tracking through cell subdomains.
72  !!
73  !! Particles are identified by composite key, i.e.,
74  !! combinations of properties imdl, iprp, irpt, and
75  !! trelease. An optional label may be provided, but
76  !! need not be unique
77  !<
79  private
80  ! identity
81  character(len=LENBOUNDNAME), public :: name = '' !< optional particle name
82  integer(I4B), public :: imdl !< index of model the particle originated in
83  integer(I4B), public :: iprp !< index of release package the particle is from
84  integer(I4B), public :: irpt !< index of release point the particle is from
85  integer(I4B), public :: ip !< index of particle in the particle list
86  ! stop criteria
87  integer(I4B), public :: istopweaksink !< weak sink option (0: do not stop, 1: stop)
88  integer(I4B), public :: istopzone !< stop zone number
89  integer(I4B), public :: idrymeth !< dry tracking method
90  ! state
91  integer(I4B), allocatable, public :: idomain(:) !< tracking domain hierarchy ! TODO: rename to itdomain? idomain
92  integer(I4B), allocatable, public :: iboundary(:) !< tracking domain boundaries
93  integer(I4B), public :: icp !< previous cell number (reduced)
94  integer(I4B), public :: icu !< user cell number
95  integer(I4B), public :: ilay !< grid layer
96  integer(I4B), public :: izone !< current zone number
97  integer(I4B), public :: izp !< previous zone number
98  integer(I4B), public :: istatus !< tracking status
99  real(dp), public :: x !< x coordinate
100  real(dp), public :: y !< y coordinate
101  real(dp), public :: z !< z coordinate
102  real(dp), public :: trelease !< release time
103  real(dp), public :: tstop !< stop time
104  real(dp), public :: ttrack !< time tracked so far
105  real(dp), public :: xorigin !< x origin for coordinate transformation from model to local
106  real(dp), public :: yorigin !< y origin for coordinate transformation from model to local
107  real(dp), public :: zorigin !< z origin for coordinate transformation from model to local
108  real(dp), public :: sinrot !< sine of rotation angle for coordinate transformation from model to local
109  real(dp), public :: cosrot !< cosine of rotation angle for coordinate transformation from model to local
110  real(dp), public :: extol !< tolerance for iterative solution of particle exit location and time in generalized Pollock's method
111  logical(LGP), public :: transformed !< whether coordinates have been transformed from model to local
112  logical(LGP), public :: advancing !< whether particle is still being tracked for current time step
113  integer(I4B), public :: ifrctrn !< whether to force solving the particle with the ternary method
114  integer(I4B), public :: iexmeth !< method for iterative solution of particle exit location and time in generalized Pollock's method
115  integer(I4B), public :: iextend !< whether to extend tracking beyond the end of the simulation
116  contains
117  procedure, public :: get_model_coords
118  procedure, public :: transform => transform_coords
119  procedure, public :: reset_transform
120  end type particletype
121 
122  !> @brief Structure of arrays to store particles.
124  private
125  ! identity
126  character(len=LENBOUNDNAME), dimension(:), pointer, public, contiguous :: name !< optional particle label
127  integer(I4B), dimension(:), pointer, public, contiguous :: imdl !< index of model particle originated in
128  integer(I4B), dimension(:), pointer, public, contiguous :: iprp !< index of release package the particle originated in
129  integer(I4B), dimension(:), pointer, public, contiguous :: irpt !< index of release point in the particle release package the particle originated in
130  ! stopping criteria
131  integer(I4B), dimension(:), pointer, public, contiguous :: istopweaksink !< weak sink option: 0 = do not stop, 1 = stop
132  integer(I4B), dimension(:), pointer, public, contiguous :: istopzone !< stop zone number
133  integer(I4B), dimension(:), pointer, public, contiguous :: idrymeth !< stop in dry cells
134  ! state
135  integer(I4B), dimension(:, :), pointer, public, contiguous :: idomain !< array of indices for domains in the tracking domain hierarchy
136  integer(I4B), dimension(:, :), pointer, public, contiguous :: iboundary !< array of indices for tracking domain boundaries
137  integer(I4B), dimension(:), pointer, public, contiguous :: icu !< cell number (user)
138  integer(I4B), dimension(:), pointer, public, contiguous :: ilay !< layer
139  integer(I4B), dimension(:), pointer, public, contiguous :: izone !< current zone number
140  integer(I4B), dimension(:), pointer, public, contiguous :: izp !< previous zone number
141  integer(I4B), dimension(:), pointer, public, contiguous :: istatus !< particle status
142  real(dp), dimension(:), pointer, public, contiguous :: x !< model x coord of particle
143  real(dp), dimension(:), pointer, public, contiguous :: y !< model y coord of particle
144  real(dp), dimension(:), pointer, public, contiguous :: z !< model z coord of particle
145  real(dp), dimension(:), pointer, public, contiguous :: trelease !< particle release time
146  real(dp), dimension(:), pointer, public, contiguous :: tstop !< particle stop time
147  real(dp), dimension(:), pointer, public, contiguous :: ttrack !< current tracking time
148  integer(I4B), dimension(:), pointer, public, contiguous :: ifrctrn !< force ternary method
149  integer(I4B), dimension(:), pointer, public, contiguous :: iexmeth !< method for iterative solution of particle exit location and time in generalized Pollock's method
150  real(dp), dimension(:), pointer, public, contiguous :: extol !< tolerance for iterative solution of particle exit location and time in generalized Pollock's method
151  integer(LGP), dimension(:), pointer, public, contiguous :: extend !< whether to extend tracking beyond the end of the simulation
152  contains
153  procedure, public :: destroy
154  procedure, public :: num_stored
155  procedure, public :: resize
156  procedure, public :: get
157  procedure, public :: put
158  end type particlestoretype
159 
160 contains
161 
162  !> @brief Create a new particle
163  subroutine create_particle(particle)
164  type(particletype), pointer :: particle !< particle
165  allocate (particle)
166  allocate (particle%idomain(max_level))
167  allocate (particle%iboundary(max_level))
168  end subroutine create_particle
169 
170  !> @brief Allocate particle store
171  subroutine create_particle_store(store, np, mempath)
172  type(particlestoretype), pointer :: store !< store
173  integer(I4B), intent(in) :: np !< number of particles
174  character(*), intent(in) :: mempath !< path to memory
175 
176  allocate (store)
177  call mem_allocate(store%imdl, np, 'PLIMDL', mempath)
178  call mem_allocate(store%irpt, np, 'PLIRPT', mempath)
179  call mem_allocate(store%iprp, np, 'PLIPRP', mempath)
180  call mem_allocate(store%name, lenboundname, np, 'PLNAME', mempath)
181  call mem_allocate(store%icu, np, 'PLICU', mempath)
182  call mem_allocate(store%ilay, np, 'PLILAY', mempath)
183  call mem_allocate(store%izone, np, 'PLIZONE', mempath)
184  call mem_allocate(store%izp, np, 'PLIZP', mempath)
185  call mem_allocate(store%istatus, np, 'PLISTATUS', mempath)
186  call mem_allocate(store%x, np, 'PLX', mempath)
187  call mem_allocate(store%y, np, 'PLY', mempath)
188  call mem_allocate(store%z, np, 'PLZ', mempath)
189  call mem_allocate(store%trelease, np, 'PLTRELEASE', mempath)
190  call mem_allocate(store%tstop, np, 'PLTSTOP', mempath)
191  call mem_allocate(store%ttrack, np, 'PLTTRACK', mempath)
192  call mem_allocate(store%istopweaksink, np, 'PLISTOPWEAKSINK', mempath)
193  call mem_allocate(store%istopzone, np, 'PLISTOPZONE', mempath)
194  call mem_allocate(store%idrymeth, np, 'PLIDRYMETH', mempath)
195  call mem_allocate(store%ifrctrn, np, 'PLIFRCTRN', mempath)
196  call mem_allocate(store%iexmeth, np, 'PLIEXMETH', mempath)
197  call mem_allocate(store%extol, np, 'PLEXTOL', mempath)
198  call mem_allocate(store%extend, np, 'PLIEXTEND', mempath)
199  call mem_allocate(store%idomain, np, max_level, 'PLIDOMAIN', mempath)
200  call mem_allocate(store%iboundary, np, max_level, 'PLIBOUNDARY', mempath)
201  end subroutine create_particle_store
202 
203  !> @brief Destroy particle store after use.
204  subroutine destroy(this, mempath)
205  class(particlestoretype), intent(inout) :: this !< store
206  character(*), intent(in) :: mempath !< path to memory
207 
208  call mem_deallocate(this%imdl, 'PLIMDL', mempath)
209  call mem_deallocate(this%iprp, 'PLIPRP', mempath)
210  call mem_deallocate(this%irpt, 'PLIRPT', mempath)
211  call mem_deallocate(this%name, 'PLNAME', mempath)
212  call mem_deallocate(this%icu, 'PLICU', mempath)
213  call mem_deallocate(this%ilay, 'PLILAY', mempath)
214  call mem_deallocate(this%izone, 'PLIZONE', mempath)
215  call mem_deallocate(this%izp, 'PLIZP', mempath)
216  call mem_deallocate(this%istatus, 'PLISTATUS', mempath)
217  call mem_deallocate(this%x, 'PLX', mempath)
218  call mem_deallocate(this%y, 'PLY', mempath)
219  call mem_deallocate(this%z, 'PLZ', mempath)
220  call mem_deallocate(this%trelease, 'PLTRELEASE', mempath)
221  call mem_deallocate(this%tstop, 'PLTSTOP', mempath)
222  call mem_deallocate(this%ttrack, 'PLTTRACK', mempath)
223  call mem_deallocate(this%istopweaksink, 'PLISTOPWEAKSINK', mempath)
224  call mem_deallocate(this%istopzone, 'PLISTOPZONE', mempath)
225  call mem_deallocate(this%idrymeth, 'PLIDRYMETH', mempath)
226  call mem_deallocate(this%ifrctrn, 'PLIFRCTRN', mempath)
227  call mem_deallocate(this%iexmeth, 'PLIEXMETH', mempath)
228  call mem_deallocate(this%extol, 'PLEXTOL', mempath)
229  call mem_deallocate(this%extend, 'PLIEXTEND', mempath)
230  call mem_deallocate(this%idomain, 'PLIDOMAIN', mempath)
231  call mem_deallocate(this%iboundary, 'PLIBOUNDARY', mempath)
232  end subroutine destroy
233 
234  !> @brief Reallocate particle storage to the given size.
235  subroutine resize(this, np, mempath)
236  ! dummy
237  class(particlestoretype), intent(inout) :: this !< particle store
238  integer(I4B), intent(in) :: np !< number of particles
239  character(*), intent(in) :: mempath !< path to memory
240 
241  ! resize arrays
242  call mem_reallocate(this%imdl, np, 'PLIMDL', mempath)
243  call mem_reallocate(this%iprp, np, 'PLIPRP', mempath)
244  call mem_reallocate(this%irpt, np, 'PLIRPT', mempath)
245  call mem_reallocate(this%name, lenboundname, np, 'PLNAME', mempath)
246  call mem_reallocate(this%icu, np, 'PLICU', mempath)
247  call mem_reallocate(this%ilay, np, 'PLILAY', mempath)
248  call mem_reallocate(this%izone, np, 'PLIZONE', mempath)
249  call mem_reallocate(this%izp, np, 'PLIZP', mempath)
250  call mem_reallocate(this%istatus, np, 'PLISTATUS', mempath)
251  call mem_reallocate(this%x, np, 'PLX', mempath)
252  call mem_reallocate(this%y, np, 'PLY', mempath)
253  call mem_reallocate(this%z, np, 'PLZ', mempath)
254  call mem_reallocate(this%trelease, np, 'PLTRELEASE', mempath)
255  call mem_reallocate(this%tstop, np, 'PLTSTOP', mempath)
256  call mem_reallocate(this%ttrack, np, 'PLTTRACK', mempath)
257  call mem_reallocate(this%istopweaksink, np, 'PLISTOPWEAKSINK', mempath)
258  call mem_reallocate(this%istopzone, np, 'PLISTOPZONE', mempath)
259  call mem_reallocate(this%idrymeth, np, 'PLIDRYMETH', mempath)
260  call mem_reallocate(this%ifrctrn, np, 'PLIFRCTRN', mempath)
261  call mem_reallocate(this%iexmeth, np, 'PLIEXMETH', mempath)
262  call mem_reallocate(this%extol, np, 'PLEXTOL', mempath)
263  call mem_reallocate(this%extend, np, 'PLIEXTEND', mempath)
264  call mem_reallocate(this%idomain, np, max_level, 'PLIDOMAIN', mempath)
265  call mem_reallocate(this%iboundary, np, max_level, 'PLIBOUNDARY', mempath)
266  end subroutine resize
267 
268  !> @brief Load a particle from the particle store.
269  !!
270  !! This routine is used to initialize a particle for tracking.
271  !! The advancing flag and coordinate transformation are reset.
272  !<
273  subroutine get(this, particle, imdl, iprp, ip)
274  class(particlestoretype), intent(inout) :: this !< particle store
275  class(particletype), intent(inout) :: particle !< particle
276  integer(I4B), intent(in) :: imdl !< index of model particle originated in
277  integer(I4B), intent(in) :: iprp !< index of particle release package particle originated in
278  integer(I4B), intent(in) :: ip !< index into the particle list
279 
280  call particle%reset_transform()
281  particle%imdl = imdl
282  particle%iprp = iprp
283  particle%irpt = this%irpt(ip)
284  particle%ip = ip
285  particle%name = this%name(ip)
286  particle%istopweaksink = this%istopweaksink(ip)
287  particle%istopzone = this%istopzone(ip)
288  particle%idrymeth = this%idrymeth(ip)
289  particle%icp = 0
290  particle%icu = this%icu(ip)
291  particle%ilay = this%ilay(ip)
292  particle%izone = this%izone(ip)
293  particle%izp = this%izp(ip)
294  particle%istatus = this%istatus(ip)
295  particle%x = this%x(ip)
296  particle%y = this%y(ip)
297  particle%z = this%z(ip)
298  particle%trelease = this%trelease(ip)
299  particle%tstop = this%tstop(ip)
300  particle%ttrack = this%ttrack(ip)
301  particle%advancing = .true.
302  particle%idomain(1:max_level) = &
303  this%idomain(ip, 1:max_level)
304  particle%idomain(1) = imdl
305  particle%iboundary(1:max_level) = &
306  this%iboundary(ip, 1:max_level)
307  particle%ifrctrn = this%ifrctrn(ip)
308  particle%iexmeth = this%iexmeth(ip)
309  particle%extol = this%extol(ip)
310  particle%iextend = this%extend(ip)
311  end subroutine get
312 
313  !> @brief Save a particle's state to the particle store.
314  subroutine put(this, particle, ip)
315  class(particlestoretype), intent(inout) :: this !< particle storage
316  class(particletype), intent(in) :: particle !< particle
317  integer(I4B), intent(in) :: ip !< particle index
318 
319  this%imdl(ip) = particle%imdl
320  this%iprp(ip) = particle%iprp
321  this%irpt(ip) = particle%irpt
322  this%name(ip) = particle%name
323  this%istopweaksink(ip) = particle%istopweaksink
324  this%istopzone(ip) = particle%istopzone
325  this%idrymeth(ip) = particle%idrymeth
326  this%icu(ip) = particle%icu
327  this%ilay(ip) = particle%ilay
328  this%izone(ip) = particle%izone
329  this%izp(ip) = particle%izp
330  this%istatus(ip) = particle%istatus
331  this%x(ip) = particle%x
332  this%y(ip) = particle%y
333  this%z(ip) = particle%z
334  this%trelease(ip) = particle%trelease
335  this%tstop(ip) = particle%tstop
336  this%ttrack(ip) = particle%ttrack
337  this%idomain( &
338  ip, &
339  1:max_level) = &
340  particle%idomain(1:max_level)
341  this%iboundary( &
342  ip, &
343  1:max_level) = &
344  particle%iboundary(1:max_level)
345  this%ifrctrn(ip) = particle%ifrctrn
346  this%iexmeth(ip) = particle%iexmeth
347  this%extol(ip) = particle%extol
348  this%extend(ip) = particle%iextend
349  end subroutine put
350 
351  !> @brief Transform particle coordinates.
352  !!
353  !! Apply a translation and/or rotation to particle coordinates.
354  !! No rescaling. It's also possible to invert a transformation.
355  !! Be sure to reset the transformation after using it.
356  !<
357  subroutine transform_coords(this, xorigin, yorigin, zorigin, &
358  sinrot, cosrot, invert)
359  use geomutilmodule, only: transform, compose
360  class(particletype), intent(inout) :: this !< particle
361  real(DP), intent(in), optional :: xorigin !< x coordinate of origin
362  real(DP), intent(in), optional :: yorigin !< y coordinate of origin
363  real(DP), intent(in), optional :: zorigin !< z coordinate of origin
364  real(DP), intent(in), optional :: sinrot !< sine of rotation angle
365  real(DP), intent(in), optional :: cosrot !< cosine of rotation angle
366  logical(LGP), intent(in), optional :: invert !< whether to invert
367 
368  call transform(this%x, this%y, this%z, &
369  this%x, this%y, this%z, &
370  xorigin, yorigin, zorigin, &
371  sinrot, cosrot, invert)
372 
373  call compose(this%xorigin, this%yorigin, this%zorigin, &
374  this%sinrot, this%cosrot, &
375  xorigin, yorigin, zorigin, &
376  sinrot, cosrot, invert)
377 
378  this%transformed = .true.
379  end subroutine transform_coords
380 
381  !> @brief Reset particle coordinate transformation properties.
382  subroutine reset_transform(this)
383  class(particletype), intent(inout) :: this !< particle
384 
385  this%xorigin = dzero
386  this%yorigin = dzero
387  this%zorigin = dzero
388  this%sinrot = dzero
389  this%cosrot = done
390  this%cosrot = done
391  this%transformed = .false.
392  end subroutine reset_transform
393 
394  !> @brief Return the particle's model coordinates,
395  !! inverting any applied transformation if needed.
396  !! The particle's state is not altered.
397  subroutine get_model_coords(this, x, y, z)
398  use geomutilmodule, only: transform, compose
399  class(particletype), intent(in) :: this !< particle
400  real(DP), intent(out) :: x !< x coordinate
401  real(DP), intent(out) :: y !< y coordinate
402  real(DP), intent(out) :: z !< z coordinate
403 
404  if (this%transformed) then
405  call transform(this%x, this%y, this%z, x, y, z, &
406  this%xorigin, this%yorigin, this%zorigin, &
407  this%sinrot, this%cosrot, invert=.true.)
408  else
409  x = this%x
410  y = this%y
411  z = this%z
412  end if
413  end subroutine get_model_coords
414 
415  !> @brief Return the number of particles.
416  integer function num_stored(this) result(n)
417  class(particlestoretype) :: this
418  n = size(this%imdl)
419  end function num_stored
420 
421 end module particlemodule
This module contains simulation constants.
Definition: Constants.f90:9
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 lenmempath
maximum length of the memory path
Definition: Constants.f90:27
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
subroutine, public transform(xin, yin, zin, xout, yout, zout, xorigin, yorigin, zorigin, sinrot, cosrot, invert)
Apply a 3D translation and optional 2D rotation to coordinates.
Definition: GeomUtil.f90:183
subroutine, public compose(xorigin, yorigin, zorigin, sinrot, cosrot, xorigin_new, yorigin_new, zorigin_new, sinrot_new, cosrot_new, invert)
Apply a 3D translation and 2D rotation to an existing transformation.
Definition: GeomUtil.f90:243
This module defines variable data types.
Definition: kind.f90:8
subroutine get(this, particle, imdl, iprp, ip)
Load a particle from the particle store.
Definition: Particle.f90:274
subroutine resize(this, np, mempath)
Reallocate particle storage to the given size.
Definition: Particle.f90:236
subroutine create_particle_store(store, np, mempath)
Allocate particle store.
Definition: Particle.f90:172
subroutine get_model_coords(this, x, y, z)
Return the particle's model coordinates, inverting any applied transformation if needed....
Definition: Particle.f90:398
integer function num_stored(this)
Return the number of particles.
Definition: Particle.f90:417
subroutine reset_transform(this)
Reset particle coordinate transformation properties.
Definition: Particle.f90:383
@ term_weaksink
terminated in a weak sink cell
Definition: Particle.f90:34
@ term_timeout
terminated at stop time or end of simulation
Definition: Particle.f90:40
@ term_inactive
terminated in an inactive cell
Definition: Particle.f90:37
@ term_no_exits
terminated in a cell with no exit face
Definition: Particle.f90:35
@ term_stopzone
terminated in a cell with a stop zone number
Definition: Particle.f90:36
@ term_no_exits_sub
terminated in a subcell with no exit face
Definition: Particle.f90:39
@ term_unreleased
terminated permanently unreleased
Definition: Particle.f90:38
@ term_boundary
terminated at a boundary face
Definition: Particle.f90:33
subroutine transform_coords(this, xorigin, yorigin, zorigin, sinrot, cosrot, invert)
Transform particle coordinates.
Definition: Particle.f90:359
@ terminate
particle terminated
Definition: Particle.f90:57
@ release
particle was released
Definition: Particle.f90:54
@ usertime
user-specified tracking time
Definition: Particle.f90:59
@ timestep
time step ended
Definition: Particle.f90:56
@ weaksink
particle entered a weak sink cell
Definition: Particle.f90:58
@ exit
particle exited a cell
Definition: Particle.f90:55
subroutine destroy(this, mempath)
Destroy particle store after use.
Definition: Particle.f90:205
subroutine create_particle(particle)
Create a new particle.
Definition: Particle.f90:164
subroutine put(this, particle, ip)
Save a particle's state to the particle store.
Definition: Particle.f90:315
integer, parameter max_level
Tracking "levels" (1: model, 2: cell, 3: subcell). A level identifies the domain through which a trac...
Definition: Particle.f90:15
Structure of arrays to store particles.
Definition: Particle.f90:123
Particle tracked by the PRT model.
Definition: Particle.f90:78