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
5  use simvariablesmodule, only: errmsg
10  use errorutilmodule, only: pstop
11  implicit none
12  public
13 
14  !> Tracking "levels" defined in method modules. Currently only 3 used.
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 tracked by the PRT model.
44  !!
45  !! Record-type to conveniently shuffle a particle's
46  !! state to/from storage before/after its trajectory
47  !! is solved for each time step.
48  !!
49  !! Particle coordinates may be local to the cell or
50  !! global/model. Routines are provided to convert a
51  !! particle's global coordinates to/from cell-local
52  !! coordinates for tracking through cell subdomains.
53  !!
54  !! Particles are identified by composite key, i.e.,
55  !! combinations of properties imdl, iprp, irpt, and
56  !! trelease. An optional label may be provided, but
57  !! need not be unique.
58  !!
59  !! Particles carry a coordinate transform along with
60  !! themselves, instead of just letting the tracking
61  !! methods handle transforms, because we may need to
62  !! report an event at any time in model coordinates.
63  !<
65  private
66  ! identity
67  character(len=LENBOUNDNAME), public :: name = '' !< optional particle name
68  integer(I4B), public :: imdl !< index of model the particle originated in
69  integer(I4B), public :: iprp !< index of release package the particle is from
70  integer(I4B), public :: irpt !< index of release point the particle is from
71  integer(I4B), public :: ip !< index of particle in the particle list
72  ! options
73  logical(LGP), public :: extend !< whether to extend tracking beyond the end of the simulation
74  logical(LGP), public :: frctrn !< whether to force solving the particle with the ternary method
75  integer(I4B), public :: istopweaksink !< weak sink option (0: do not stop, 1: stop)
76  integer(I4B), public :: istopzone !< stop zone number
77  integer(I4B), public :: idrymeth !< dry tracking method
78  integer(I4B), public :: iexmeth !< method for iterative solution of particle exit location and time in generalized Pollock's method
79  integer(I4B), public :: icycwin !< cycle detection window size
80  real(dp), public :: extol !< tolerance for iterative solution of particle exit location and time in generalized Pollock's method
81  ! state
82  integer(I4B), public :: itrdomain(max_level) !< tracking domain indices
83  integer(I4B), public :: iboundary(max_level) !< tracking domain boundary indices
84  integer(I4B), public :: icu !< user cell number
85  integer(I4B), public :: ilay !< grid layer
86  integer(I4B), public :: izone !< current zone number
87  integer(I4B), public :: istatus !< tracking status
88  real(dp), public :: x !< x coordinate
89  real(dp), public :: y !< y coordinate
90  real(dp), public :: z !< z coordinate
91  real(dp), public :: trelease !< release time
92  real(dp), public :: tstop !< stop time
93  real(dp), public :: ttrack !< time tracked so far
94  real(dp), public :: xorigin !< x origin for coordinate transformation from model to local
95  real(dp), public :: yorigin !< y origin for coordinate transformation from model to local
96  real(dp), public :: zorigin !< z origin for coordinate transformation from model to local
97  real(dp), public :: sinrot !< sine of rotation angle for coordinate transformation from model to local
98  real(dp), public :: cosrot !< cosine of rotation angle for coordinate transformation from model to local
99  logical(LGP), public :: transformed !< whether coordinates have been transformed from model to local
100  logical(LGP), public :: advancing !< whether particle is still being tracked for current time step
101  type(listtype), public, pointer :: history !< history of particle positions (for cycle detection)
102  contains
103  procedure, public :: destroy => destroy_particle
104  procedure, public :: get_model_coords
105  procedure, public :: transform => transform_coords
106  procedure, public :: reset_transform
107  procedure, public :: get_id
108  end type particletype
109 
110  !> @brief Structure of arrays to store particles.
112  private
113  ! identity
114  character(len=LENBOUNDNAME), dimension(:), pointer, public, contiguous :: name !< optional particle label
115  integer(I4B), dimension(:), pointer, public, contiguous :: imdl !< index of model particle originated in
116  integer(I4B), dimension(:), pointer, public, contiguous :: iprp !< index of release package the particle originated in
117  integer(I4B), dimension(:), pointer, public, contiguous :: irpt !< index of release point in the particle release package the particle originated in
118  ! options
119  logical(LGP), dimension(:), pointer, public, contiguous :: extend !< whether to extend tracking beyond the end of the simulation
120  logical(LGP), dimension(:), pointer, public, contiguous :: frctrn !< force ternary method
121  integer(I4B), dimension(:), pointer, public, contiguous :: istopweaksink !< weak sink option: 0 = do not stop, 1 = stop
122  integer(I4B), dimension(:), pointer, public, contiguous :: istopzone !< stop zone number
123  integer(I4B), dimension(:), pointer, public, contiguous :: idrymeth !< stop in dry cells
124  integer(I4B), dimension(:), pointer, public, contiguous :: iexmeth !< method for iterative solution of particle exit location and time in generalized Pollock's method
125  integer(I4B), dimension(:), pointer, public, contiguous :: icycwin !< cycle detection window size
126  real(dp), dimension(:), pointer, public, contiguous :: extol !< tolerance for iterative solution of particle exit location and time in generalized Pollock's method
127  ! state
128  integer(I4B), dimension(:, :), pointer, public, contiguous :: itrdomain !< array of indices for domains in the tracking domain hierarchy
129  integer(I4B), dimension(:, :), pointer, public, contiguous :: iboundary !< array of indices for tracking domain boundaries
130  integer(I4B), dimension(:), pointer, public, contiguous :: icu !< cell number (user)
131  integer(I4B), dimension(:), pointer, public, contiguous :: ilay !< layer
132  integer(I4B), dimension(:), pointer, public, contiguous :: izone !< current zone number
133  integer(I4B), dimension(:), pointer, public, contiguous :: istatus !< particle status
134  real(dp), dimension(:), pointer, public, contiguous :: x !< model x coord of particle
135  real(dp), dimension(:), pointer, public, contiguous :: y !< model y coord of particle
136  real(dp), dimension(:), pointer, public, contiguous :: z !< model z coord of particle
137  real(dp), dimension(:), pointer, public, contiguous :: trelease !< particle release time
138  real(dp), dimension(:), pointer, public, contiguous :: tstop !< particle stop time
139  real(dp), dimension(:), pointer, public, contiguous :: ttrack !< current tracking time
140  contains
141  procedure, public :: destroy
142  procedure, public :: num_stored
143  procedure, public :: resize
144  procedure, public :: get
145  procedure, public :: put
146  procedure, public :: copy_from
147  end type particlestoretype
148 
149 contains
150 
151  !> @brief Create a new particle
152  subroutine create_particle(particle)
153  type(particletype), pointer :: particle !< particle
154  allocate (particle)
155  allocate (particle%history)
156  end subroutine create_particle
157 
158  !> @brief Allocate particle store
159  subroutine create_particle_store(store, np, mempath)
160  type(particlestoretype), pointer :: store !< store
161  integer(I4B), intent(in) :: np !< number of particles
162  character(*), intent(in) :: mempath !< path to memory
163 
164  allocate (store)
165  call mem_allocate(store%imdl, np, 'PLIMDL', mempath)
166  call mem_allocate(store%irpt, np, 'PLIRPT', mempath)
167  call mem_allocate(store%iprp, np, 'PLIPRP', mempath)
168  call mem_allocate(store%name, lenboundname, np, 'PLNAME', mempath)
169  call mem_allocate(store%icu, np, 'PLICU', mempath)
170  call mem_allocate(store%ilay, np, 'PLILAY', mempath)
171  call mem_allocate(store%izone, np, 'PLIZONE', mempath)
172  call mem_allocate(store%istatus, np, 'PLISTATUS', mempath)
173  call mem_allocate(store%x, np, 'PLX', mempath)
174  call mem_allocate(store%y, np, 'PLY', mempath)
175  call mem_allocate(store%z, np, 'PLZ', mempath)
176  call mem_allocate(store%trelease, np, 'PLTRELEASE', mempath)
177  call mem_allocate(store%tstop, np, 'PLTSTOP', mempath)
178  call mem_allocate(store%ttrack, np, 'PLTTRACK', mempath)
179  call mem_allocate(store%istopweaksink, np, 'PLISTOPWEAKSINK', mempath)
180  call mem_allocate(store%istopzone, np, 'PLISTOPZONE', mempath)
181  call mem_allocate(store%idrymeth, np, 'PLIDRYMETH', mempath)
182  call mem_allocate(store%frctrn, np, 'PLFRCTRN', mempath)
183  call mem_allocate(store%iexmeth, np, 'PLIEXMETH', mempath)
184  call mem_allocate(store%extol, np, 'PLEXTOL', mempath)
185  call mem_allocate(store%extend, np, 'PLEXTEND', mempath)
186  call mem_allocate(store%icycwin, np, 'PLICYCWIN', mempath)
187  call mem_allocate(store%itrdomain, np, max_level, 'PLIDOMAIN', mempath)
188  call mem_allocate(store%iboundary, np, max_level, 'PLIBOUNDARY', mempath)
189  end subroutine create_particle_store
190 
191  !> @brief Destroy particle store after use.
192  subroutine destroy(this, mempath)
193  class(particlestoretype), intent(inout) :: this !< store
194  character(*), intent(in) :: mempath !< path to memory
195 
196  call mem_deallocate(this%imdl, 'PLIMDL', mempath)
197  call mem_deallocate(this%iprp, 'PLIPRP', mempath)
198  call mem_deallocate(this%irpt, 'PLIRPT', mempath)
199  call mem_deallocate(this%name, 'PLNAME', mempath)
200  call mem_deallocate(this%icu, 'PLICU', mempath)
201  call mem_deallocate(this%ilay, 'PLILAY', mempath)
202  call mem_deallocate(this%izone, 'PLIZONE', mempath)
203  call mem_deallocate(this%istatus, 'PLISTATUS', mempath)
204  call mem_deallocate(this%x, 'PLX', mempath)
205  call mem_deallocate(this%y, 'PLY', mempath)
206  call mem_deallocate(this%z, 'PLZ', mempath)
207  call mem_deallocate(this%trelease, 'PLTRELEASE', mempath)
208  call mem_deallocate(this%tstop, 'PLTSTOP', mempath)
209  call mem_deallocate(this%ttrack, 'PLTTRACK', mempath)
210  call mem_deallocate(this%istopweaksink, 'PLISTOPWEAKSINK', mempath)
211  call mem_deallocate(this%istopzone, 'PLISTOPZONE', mempath)
212  call mem_deallocate(this%idrymeth, 'PLIDRYMETH', mempath)
213  call mem_deallocate(this%frctrn, 'PLFRCTRN', mempath)
214  call mem_deallocate(this%iexmeth, 'PLIEXMETH', mempath)
215  call mem_deallocate(this%extol, 'PLEXTOL', mempath)
216  call mem_deallocate(this%extend, 'PLEXTEND', mempath)
217  call mem_deallocate(this%icycwin, 'PLICYCWIN', mempath)
218  call mem_deallocate(this%itrdomain, 'PLIDOMAIN', mempath)
219  call mem_deallocate(this%iboundary, 'PLIBOUNDARY', mempath)
220  end subroutine destroy
221 
222  !> @brief Destroy a particle after use.
223  subroutine destroy_particle(particle)
224  class(particletype), intent(inout) :: particle !< particle
225  deallocate (particle%history)
226  end subroutine destroy_particle
227 
228  !> @brief Reallocate particle storage to the given size.
229  subroutine resize(this, np, mempath)
230  ! dummy
231  class(particlestoretype), intent(inout) :: this !< particle store
232  integer(I4B), intent(in) :: np !< number of particles
233  character(*), intent(in) :: mempath !< path to memory
234 
235  call mem_reallocate(this%imdl, np, 'PLIMDL', mempath)
236  call mem_reallocate(this%iprp, np, 'PLIPRP', mempath)
237  call mem_reallocate(this%irpt, np, 'PLIRPT', mempath)
238  call mem_reallocate(this%name, lenboundname, np, 'PLNAME', mempath)
239  call mem_reallocate(this%icu, np, 'PLICU', mempath)
240  call mem_reallocate(this%ilay, np, 'PLILAY', mempath)
241  call mem_reallocate(this%izone, np, 'PLIZONE', mempath)
242  call mem_reallocate(this%istatus, np, 'PLISTATUS', mempath)
243  call mem_reallocate(this%x, np, 'PLX', mempath)
244  call mem_reallocate(this%y, np, 'PLY', mempath)
245  call mem_reallocate(this%z, np, 'PLZ', mempath)
246  call mem_reallocate(this%trelease, np, 'PLTRELEASE', mempath)
247  call mem_reallocate(this%tstop, np, 'PLTSTOP', mempath)
248  call mem_reallocate(this%ttrack, np, 'PLTTRACK', mempath)
249  call mem_reallocate(this%istopweaksink, np, 'PLISTOPWEAKSINK', mempath)
250  call mem_reallocate(this%istopzone, np, 'PLISTOPZONE', mempath)
251  call mem_reallocate(this%idrymeth, np, 'PLIDRYMETH', mempath)
252  call mem_reallocate(this%frctrn, np, 'PLFRCTRN', mempath)
253  call mem_reallocate(this%iexmeth, np, 'PLIEXMETH', mempath)
254  call mem_reallocate(this%extol, np, 'PLEXTOL', mempath)
255  call mem_reallocate(this%extend, np, 'PLEXTEND', mempath)
256  call mem_reallocate(this%icycwin, np, 'PLICYCWIN', mempath)
257  call mem_reallocate(this%itrdomain, np, max_level, 'PLIDOMAIN', mempath)
258  call mem_reallocate(this%iboundary, np, max_level, 'PLIBOUNDARY', mempath)
259  end subroutine resize
260 
261  !> @brief Load a particle from the particle store.
262  !!
263  !! This routine is used to initialize a particle for tracking.
264  !! The advancing flag and coordinate transformation are reset.
265  !<
266  subroutine get(this, particle, imdl, iprp, ip)
267  class(particlestoretype), intent(inout) :: this !< particle store
268  class(particletype), intent(inout) :: particle !< particle
269  integer(I4B), intent(in) :: imdl !< index of model particle originated in
270  integer(I4B), intent(in) :: iprp !< index of particle release package particle originated in
271  integer(I4B), intent(in) :: ip !< index into the particle list
272 
273  call particle%reset_transform()
274  call particle%history%Clear()
275  particle%imdl = imdl
276  particle%iprp = iprp
277  particle%irpt = this%irpt(ip)
278  particle%ip = ip
279  particle%name = this%name(ip)
280  particle%istopweaksink = this%istopweaksink(ip)
281  particle%istopzone = this%istopzone(ip)
282  particle%idrymeth = this%idrymeth(ip)
283  particle%icu = this%icu(ip)
284  particle%ilay = this%ilay(ip)
285  particle%izone = this%izone(ip)
286  particle%istatus = this%istatus(ip)
287  particle%x = this%x(ip)
288  particle%y = this%y(ip)
289  particle%z = this%z(ip)
290  particle%trelease = this%trelease(ip)
291  particle%tstop = this%tstop(ip)
292  particle%ttrack = this%ttrack(ip)
293  particle%advancing = .true.
294  particle%itrdomain(1:max_level) = &
295  this%itrdomain(ip, 1:max_level)
296  particle%itrdomain(1) = imdl
297  particle%iboundary(1:max_level) = &
298  this%iboundary(ip, 1:max_level)
299  particle%frctrn = this%frctrn(ip)
300  particle%iexmeth = this%iexmeth(ip)
301  particle%extol = this%extol(ip)
302  particle%extend = this%extend(ip)
303  particle%icycwin = this%icycwin(ip)
304  end subroutine get
305 
306  !> @brief Save a particle's state to the particle store.
307  subroutine put(this, particle, ip)
308  class(particlestoretype), intent(inout) :: this !< particle storage
309  class(particletype), intent(in) :: particle !< particle
310  integer(I4B), intent(in) :: ip !< particle index
311 
312  this%imdl(ip) = particle%imdl
313  this%iprp(ip) = particle%iprp
314  this%irpt(ip) = particle%irpt
315  this%name(ip) = particle%name
316  this%istopweaksink(ip) = particle%istopweaksink
317  this%istopzone(ip) = particle%istopzone
318  this%idrymeth(ip) = particle%idrymeth
319  this%icu(ip) = particle%icu
320  this%ilay(ip) = particle%ilay
321  this%izone(ip) = particle%izone
322  this%istatus(ip) = particle%istatus
323  this%x(ip) = particle%x
324  this%y(ip) = particle%y
325  this%z(ip) = particle%z
326  this%trelease(ip) = particle%trelease
327  this%tstop(ip) = particle%tstop
328  this%ttrack(ip) = particle%ttrack
329  this%itrdomain( &
330  ip, &
331  1:max_level) = &
332  particle%itrdomain(1:max_level)
333  this%iboundary( &
334  ip, &
335  1:max_level) = &
336  particle%iboundary(1:max_level)
337  this%frctrn(ip) = particle%frctrn
338  this%iexmeth(ip) = particle%iexmeth
339  this%extol(ip) = particle%extol
340  this%extend(ip) = particle%extend
341  this%icycwin(ip) = particle%icycwin
342  end subroutine put
343 
344  !> @brief Copy all particle state from source to this store.
345  !! The two particle stores must already be of the same size.
346  subroutine copy_from(this, source)
347  ! dummy
348  class(particlestoretype), intent(inout) :: this
349  class(particlestoretype), intent(in) :: source
350  ! local
351  integer(I4B) :: np
352 
353  np = source%num_stored()
354 
355  if (this%num_stored() /= np) then
356  write (errmsg, '(a,i0,a,i0,a)') &
357  'Cannot copy particle store, size mismatch (source=', np, &
358  ', dest=', this%num_stored(), ')'
359  call pstop(1, errmsg)
360  end if
361 
362  this%name(:) = source%name(:)
363  this%imdl(:) = source%imdl(:)
364  this%iprp(:) = source%iprp(:)
365  this%irpt(:) = source%irpt(:)
366  this%extend(:) = source%extend(:)
367  this%frctrn(:) = source%frctrn(:)
368  this%istopweaksink(:) = source%istopweaksink(:)
369  this%istopzone(:) = source%istopzone(:)
370  this%idrymeth(:) = source%idrymeth(:)
371  this%iexmeth(:) = source%iexmeth(:)
372  this%icycwin(:) = source%icycwin(:)
373  this%extol(:) = source%extol(:)
374  this%itrdomain(:, :) = source%itrdomain(:, :)
375  this%iboundary(:, :) = source%iboundary(:, :)
376  this%icu(:) = source%icu(:)
377  this%ilay(:) = source%ilay(:)
378  this%izone(:) = source%izone(:)
379  this%istatus(:) = source%istatus(:)
380  this%x(:) = source%x(:)
381  this%y(:) = source%y(:)
382  this%z(:) = source%z(:)
383  this%trelease(:) = source%trelease(:)
384  this%tstop(:) = source%tstop(:)
385  this%ttrack(:) = source%ttrack(:)
386  end subroutine copy_from
387 
388  !> @brief Transform particle coordinates.
389  !!
390  !! Apply a translation and/or rotation to particle coordinates.
391  !! No rescaling. It's also possible to invert a transformation.
392  !! Be sure to reset the transformation after using it.
393  !<
394  subroutine transform_coords(this, xorigin, yorigin, zorigin, &
395  sinrot, cosrot, invert)
396  use geomutilmodule, only: transform, compose
397  class(particletype), intent(inout) :: this !< particle
398  real(DP), intent(in), optional :: xorigin !< x coordinate of origin
399  real(DP), intent(in), optional :: yorigin !< y coordinate of origin
400  real(DP), intent(in), optional :: zorigin !< z coordinate of origin
401  real(DP), intent(in), optional :: sinrot !< sine of rotation angle
402  real(DP), intent(in), optional :: cosrot !< cosine of rotation angle
403  logical(LGP), intent(in), optional :: invert !< whether to invert
404 
405  call transform(this%x, this%y, this%z, &
406  this%x, this%y, this%z, &
407  xorigin, yorigin, zorigin, &
408  sinrot, cosrot, invert)
409 
410  ! Compose is needed only because we have to untransform
411  ! coordinates: we may need to report a particle event
412  ! at any point in the tracking method hierarchy, so we
413  ! need to know how to map the particle position back to
414  ! model coords from coords local to the current domain.
415  call compose(this%xorigin, this%yorigin, this%zorigin, &
416  this%sinrot, this%cosrot, &
417  xorigin, yorigin, zorigin, &
418  sinrot, cosrot, invert)
419 
420  this%transformed = .true.
421  end subroutine transform_coords
422 
423  !> @brief Reset particle coordinate transformation properties.
424  subroutine reset_transform(this)
425  class(particletype), intent(inout) :: this !< particle
426 
427  this%xorigin = dzero
428  this%yorigin = dzero
429  this%zorigin = dzero
430  this%sinrot = dzero
431  this%cosrot = done
432  this%cosrot = done
433  this%transformed = .false.
434  end subroutine reset_transform
435 
436  !> @brief Return the particle's model coordinates,
437  !! inverting any applied transformation if needed.
438  !! The particle's state is not altered.
439  subroutine get_model_coords(this, x, y, z)
440  use geomutilmodule, only: transform, compose
441  class(particletype), intent(in) :: this !< particle
442  real(DP), intent(out) :: x !< x coordinate
443  real(DP), intent(out) :: y !< y coordinate
444  real(DP), intent(out) :: z !< z coordinate
445 
446  if (this%transformed) then
447  call transform(this%x, this%y, this%z, x, y, z, &
448  this%xorigin, this%yorigin, this%zorigin, &
449  this%sinrot, this%cosrot, invert=.true.)
450  else
451  x = this%x
452  y = this%y
453  z = this%z
454  end if
455  end subroutine get_model_coords
456 
457  !> @brief Return the number of particles.
458  integer function num_stored(this) result(n)
459  class(particlestoretype) :: this
460  n = size(this%imdl)
461  end function num_stored
462 
463  !> @brief Get a string identifier for the particle.
464  function get_id(this) result(str)
465  class(particletype), intent(in) :: this
466  character(len=:), allocatable :: str
467  ! local
468  character(len=LINELENGTH) :: temp
469 
470  write (temp, '(I0,1a,I0,1a,I0,1a,G0)') &
471  this%imdl, this%iprp, this%irpt, this%trelease
472  str = trim(adjustl(temp))
473  end function get_id
474 
475 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 pstop(status, message)
Stop the program, optionally specifying an error status code.
Definition: ErrorUtil.f90:24
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:267
subroutine copy_from(this, source)
Copy all particle state from source to this store. The two particle stores must already be of the sam...
Definition: Particle.f90:347
subroutine resize(this, np, mempath)
Reallocate particle storage to the given size.
Definition: Particle.f90:230
subroutine create_particle_store(store, np, mempath)
Allocate particle store.
Definition: Particle.f90:160
character(len=:) function, allocatable get_id(this)
Get a string identifier for the particle.
Definition: Particle.f90:465
subroutine get_model_coords(this, x, y, z)
Return the particle's model coordinates, inverting any applied transformation if needed....
Definition: Particle.f90:440
integer function num_stored(this)
Return the number of particles.
Definition: Particle.f90:459
subroutine reset_transform(this)
Reset particle coordinate transformation properties.
Definition: Particle.f90:425
@ 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:396
subroutine destroy(this, mempath)
Destroy particle store after use.
Definition: Particle.f90:193
subroutine create_particle(particle)
Create a new particle.
Definition: Particle.f90:153
subroutine put(this, particle, ip)
Save a particle's state to the particle store.
Definition: Particle.f90:308
integer, parameter max_level
Tracking "levels" defined in method modules. Currently only 3 used.
Definition: Particle.f90:15
subroutine destroy_particle(particle)
Destroy a particle after use.
Definition: Particle.f90:224
This module contains simulation variables.
Definition: SimVariables.f90:9
character(len=maxcharlen) errmsg
error message string
A generic heterogeneous doubly-linked list.
Definition: List.f90:14
Structure of arrays to store particles.
Definition: Particle.f90:111
Particle tracked by the PRT model.
Definition: Particle.f90:64