MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
particlemodule Module Reference

Data Types

type  particletype
 Particle tracked by the PRT model. More...
 
type  particlestoretype
 Structure of arrays to store particles. More...
 

Enumerations

enum  {
  active = 1 , term_boundary = 2 , term_weaksink = 3 , term_no_exits = 5 ,
  term_stopzone = 6 , term_inactive = 7 , term_unreleased = 8 , term_no_exits_sub = 9 ,
  term_timeout = 10
}
 Particle status enumeration. More...
 

Functions/Subroutines

subroutine create_particle (particle)
 Create a new particle. More...
 
subroutine create_particle_store (store, np, mempath)
 Allocate particle store. More...
 
subroutine destroy (this, mempath)
 Destroy particle store after use. More...
 
subroutine destroy_particle (particle)
 Destroy a particle after use. More...
 
subroutine resize (this, np, mempath)
 Reallocate particle storage to the given size. More...
 
subroutine get (this, particle, imdl, iprp, ip)
 Load a particle from the particle store. More...
 
subroutine put (this, particle, ip)
 Save a particle's state to the particle store. More...
 
subroutine transform_coords (this, xorigin, yorigin, zorigin, sinrot, cosrot, invert)
 Transform particle coordinates. More...
 
subroutine reset_transform (this)
 Reset particle coordinate transformation properties. More...
 
subroutine get_model_coords (this, x, y, z)
 Return the particle's model coordinates, inverting any applied transformation if needed. The particle's state is not altered. More...
 
integer function num_stored (this)
 Return the number of particles. More...
 
character(len=:) function, allocatable get_id (this)
 Get a string identifier for the particle. More...
 

Variables

integer, parameter max_level = 4
 Tracking "levels" defined in method modules. Currently only 3 used. More...
 

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Particles begin in status 1 (active) at release time. Status may only increase over time. Status values greater than one imply termination. A particle may terminate for several reasons, all mutually exclusive. A particle's final tracking status will always be greater than one.

Status codes 0-3 and 5-8 correspond directly to MODPATH 7 status codes. Code 4 does not apply to PRT because PRT does not distinguish forwards from backwards tracking. Status code 9 provides more specific, subcell- level information about a particle which terminates due to no outflow. Code 10 distinguishes particles which have "timed out" upon reaching a user-specified stop time or the end of the simulation.

Enumerator
active 
term_boundary 

terminated at a boundary face

term_weaksink 

terminated in a weak sink cell

term_no_exits 

terminated in a cell with no exit face

term_stopzone 

terminated in a cell with a stop zone number

term_inactive 

terminated in an inactive cell

term_unreleased 

terminated permanently unreleased

term_no_exits_sub 

terminated in a subcell with no exit face

term_timeout 

terminated at stop time or end of simulation

Definition at line 29 of file Particle.f90.

Function/Subroutine Documentation

◆ create_particle()

subroutine particlemodule::create_particle ( type(particletype), pointer  particle)

Definition at line 149 of file Particle.f90.

150  type(ParticleType), pointer :: particle !< particle
151  allocate (particle)
152  allocate (particle%history)
Here is the caller graph for this function:

◆ create_particle_store()

subroutine particlemodule::create_particle_store ( type(particlestoretype), pointer  store,
integer(i4b), intent(in)  np,
character(*), intent(in)  mempath 
)
Parameters
[in]npnumber of particles
[in]mempathpath to memory

Definition at line 156 of file Particle.f90.

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)
Here is the caller graph for this function:

◆ destroy()

subroutine particlemodule::destroy ( class(particlestoretype), intent(inout)  this,
character(*), intent(in)  mempath 
)
Parameters
[in,out]thisstore
[in]mempathpath to memory

Definition at line 189 of file Particle.f90.

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)

◆ destroy_particle()

subroutine particlemodule::destroy_particle ( class(particletype), intent(inout)  particle)

Definition at line 220 of file Particle.f90.

221  class(ParticleType), intent(inout) :: particle !< particle
222  deallocate (particle%history)

◆ get()

subroutine particlemodule::get ( class(particlestoretype), intent(inout)  this,
class(particletype), intent(inout)  particle,
integer(i4b), intent(in)  imdl,
integer(i4b), intent(in)  iprp,
integer(i4b), intent(in)  ip 
)

This routine is used to initialize a particle for tracking. The advancing flag and coordinate transformation are reset.

Parameters
[in,out]thisparticle store
[in]imdlindex of model particle originated in
[in]iprpindex of particle release package particle originated in
[in]ipindex into the particle list

Definition at line 264 of file Particle.f90.

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)

◆ get_id()

character(len=:) function, allocatable particlemodule::get_id ( class(particletype), intent(in)  this)

Definition at line 418 of file Particle.f90.

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))

◆ get_model_coords()

subroutine particlemodule::get_model_coords ( class(particletype), intent(in)  this,
real(dp), intent(out)  x,
real(dp), intent(out)  y,
real(dp), intent(out)  z 
)
Parameters
[in]thisparticle
[out]xx coordinate
[out]yy coordinate
[out]zz coordinate

Definition at line 393 of file Particle.f90.

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
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
Here is the call graph for this function:

◆ num_stored()

integer function particlemodule::num_stored ( class(particlestoretype this)

Definition at line 412 of file Particle.f90.

413  class(ParticleStoreType) :: this
414  n = size(this%imdl)

◆ put()

subroutine particlemodule::put ( class(particlestoretype), intent(inout)  this,
class(particletype), intent(in)  particle,
integer(i4b), intent(in)  ip 
)
Parameters
[in,out]thisparticle storage
[in]ipparticle index

Definition at line 305 of file Particle.f90.

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

◆ reset_transform()

subroutine particlemodule::reset_transform ( class(particletype), intent(inout)  this)
Parameters
[in,out]thisparticle

Definition at line 378 of file Particle.f90.

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.

◆ resize()

subroutine particlemodule::resize ( class(particlestoretype), intent(inout)  this,
integer(i4b), intent(in)  np,
character(*), intent(in)  mempath 
)
Parameters
[in,out]thisparticle store
[in]npnumber of particles
[in]mempathpath to memory

Definition at line 226 of file Particle.f90.

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)

◆ transform_coords()

subroutine particlemodule::transform_coords ( class(particletype), intent(inout)  this,
real(dp), intent(in), optional  xorigin,
real(dp), intent(in), optional  yorigin,
real(dp), intent(in), optional  zorigin,
real(dp), intent(in), optional  sinrot,
real(dp), intent(in), optional  cosrot,
logical(lgp), intent(in), optional  invert 
)

Apply a translation and/or rotation to particle coordinates. No rescaling. It's also possible to invert a transformation. Be sure to reset the transformation after using it.

Parameters
[in,out]thisparticle
[in]xoriginx coordinate of origin
[in]yoriginy coordinate of origin
[in]zoriginz coordinate of origin
[in]sinrotsine of rotation angle
[in]cosrotcosine of rotation angle
[in]invertwhether to invert

Definition at line 348 of file Particle.f90.

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.
Here is the call graph for this function:

Variable Documentation

◆ max_level

integer, parameter particlemodule::max_level = 4

Definition at line 13 of file Particle.f90.

13  integer, parameter :: MAX_LEVEL = 4