MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
Particle.f90
Go to the documentation of this file.
2
3 use kindmodule, only: dp, i4b, lgp
4 use listmodule, only: listtype
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 1-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
149contains
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)
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)
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
475end 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:192
subroutine, public compose(xorigin, yorigin, zorigin, sinrot, cosrot, xorigin_new, yorigin_new, zorigin_new, sinrot_new, cosrot_new, invert)
Compose an affine transform onto an existing one, or remove (invert) it.
Definition GeomUtil.f90:252
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.
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