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