MODFLOW 6  version 6.7.0.dev1
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...
 
enum  {
  release = 0 , exit = 1 , timestep = 2 , terminate = 3 ,
  weaksink = 4 , usertime = 5
}
 Particle event 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 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...
 

Variables

integer, parameter max_level = 4
 Tracking "levels" (1: model, 2: cell, 3: subcell). A level identifies the domain through which a tracking method is responsible for moving a particle. Methods each operate on a particular level, delegating among more methods as appropriate for finer-grained levels. 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 31 of file Particle.f90.

◆ anonymous enum

anonymous enum

A number of events may occur to particles, each of which may (or may not) be of interest to the user. The user selects among events to be reported. A corresponding event code is reported with each record to identify the record's cause.

Records may be identical except for their event code, reflecting the fact that multiple events of interest may occur at any given moment.

Enumerator
release 

particle was released

exit 

particle exited a cell

timestep 

time step ended

terminate 

particle terminated

weaksink 

particle entered a weak sink cell

usertime 

user-specified tracking time

Definition at line 53 of file Particle.f90.

Function/Subroutine Documentation

◆ create_particle()

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

Definition at line 163 of file Particle.f90.

164  type(ParticleType), pointer :: particle !< particle
165  allocate (particle)
166  allocate (particle%idomain(max_level))
167  allocate (particle%iboundary(max_level))

◆ 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 171 of file Particle.f90.

172  type(ParticleStoreType), pointer :: store !< store
173  integer(I4B), intent(in) :: np !< number of particles
174  character(*), intent(in) :: mempath !< path to memory
175 
176  allocate (store)
177  call mem_allocate(store%imdl, np, 'PLIMDL', mempath)
178  call mem_allocate(store%irpt, np, 'PLIRPT', mempath)
179  call mem_allocate(store%iprp, np, 'PLIPRP', mempath)
180  call mem_allocate(store%name, lenboundname, np, 'PLNAME', mempath)
181  call mem_allocate(store%icu, np, 'PLICU', mempath)
182  call mem_allocate(store%ilay, np, 'PLILAY', mempath)
183  call mem_allocate(store%izone, np, 'PLIZONE', mempath)
184  call mem_allocate(store%izp, np, 'PLIZP', mempath)
185  call mem_allocate(store%istatus, np, 'PLISTATUS', mempath)
186  call mem_allocate(store%x, np, 'PLX', mempath)
187  call mem_allocate(store%y, np, 'PLY', mempath)
188  call mem_allocate(store%z, np, 'PLZ', mempath)
189  call mem_allocate(store%trelease, np, 'PLTRELEASE', mempath)
190  call mem_allocate(store%tstop, np, 'PLTSTOP', mempath)
191  call mem_allocate(store%ttrack, np, 'PLTTRACK', mempath)
192  call mem_allocate(store%istopweaksink, np, 'PLISTOPWEAKSINK', mempath)
193  call mem_allocate(store%istopzone, np, 'PLISTOPZONE', mempath)
194  call mem_allocate(store%idrymeth, np, 'PLIDRYMETH', mempath)
195  call mem_allocate(store%ifrctrn, np, 'PLIFRCTRN', mempath)
196  call mem_allocate(store%iexmeth, np, 'PLIEXMETH', mempath)
197  call mem_allocate(store%extol, np, 'PLEXTOL', mempath)
198  call mem_allocate(store%extend, np, 'PLIEXTEND', mempath)
199  call mem_allocate(store%idomain, np, max_level, 'PLIDOMAIN', mempath)
200  call mem_allocate(store%iboundary, np, max_level, 'PLIBOUNDARY', mempath)
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 204 of file Particle.f90.

205  class(ParticleStoreType), intent(inout) :: this !< store
206  character(*), intent(in) :: mempath !< path to memory
207 
208  call mem_deallocate(this%imdl, 'PLIMDL', mempath)
209  call mem_deallocate(this%iprp, 'PLIPRP', mempath)
210  call mem_deallocate(this%irpt, 'PLIRPT', mempath)
211  call mem_deallocate(this%name, 'PLNAME', mempath)
212  call mem_deallocate(this%icu, 'PLICU', mempath)
213  call mem_deallocate(this%ilay, 'PLILAY', mempath)
214  call mem_deallocate(this%izone, 'PLIZONE', mempath)
215  call mem_deallocate(this%izp, 'PLIZP', mempath)
216  call mem_deallocate(this%istatus, 'PLISTATUS', mempath)
217  call mem_deallocate(this%x, 'PLX', mempath)
218  call mem_deallocate(this%y, 'PLY', mempath)
219  call mem_deallocate(this%z, 'PLZ', mempath)
220  call mem_deallocate(this%trelease, 'PLTRELEASE', mempath)
221  call mem_deallocate(this%tstop, 'PLTSTOP', mempath)
222  call mem_deallocate(this%ttrack, 'PLTTRACK', mempath)
223  call mem_deallocate(this%istopweaksink, 'PLISTOPWEAKSINK', mempath)
224  call mem_deallocate(this%istopzone, 'PLISTOPZONE', mempath)
225  call mem_deallocate(this%idrymeth, 'PLIDRYMETH', mempath)
226  call mem_deallocate(this%ifrctrn, 'PLIFRCTRN', mempath)
227  call mem_deallocate(this%iexmeth, 'PLIEXMETH', mempath)
228  call mem_deallocate(this%extol, 'PLEXTOL', mempath)
229  call mem_deallocate(this%extend, 'PLIEXTEND', mempath)
230  call mem_deallocate(this%idomain, 'PLIDOMAIN', mempath)
231  call mem_deallocate(this%iboundary, 'PLIBOUNDARY', mempath)

◆ 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 273 of file Particle.f90.

274  class(ParticleStoreType), intent(inout) :: this !< particle store
275  class(ParticleType), intent(inout) :: particle !< particle
276  integer(I4B), intent(in) :: imdl !< index of model particle originated in
277  integer(I4B), intent(in) :: iprp !< index of particle release package particle originated in
278  integer(I4B), intent(in) :: ip !< index into the particle list
279 
280  call particle%reset_transform()
281  particle%imdl = imdl
282  particle%iprp = iprp
283  particle%irpt = this%irpt(ip)
284  particle%ip = ip
285  particle%name = this%name(ip)
286  particle%istopweaksink = this%istopweaksink(ip)
287  particle%istopzone = this%istopzone(ip)
288  particle%idrymeth = this%idrymeth(ip)
289  particle%icp = 0
290  particle%icu = this%icu(ip)
291  particle%ilay = this%ilay(ip)
292  particle%izone = this%izone(ip)
293  particle%izp = this%izp(ip)
294  particle%istatus = this%istatus(ip)
295  particle%x = this%x(ip)
296  particle%y = this%y(ip)
297  particle%z = this%z(ip)
298  particle%trelease = this%trelease(ip)
299  particle%tstop = this%tstop(ip)
300  particle%ttrack = this%ttrack(ip)
301  particle%advancing = .true.
302  particle%idomain(1:max_level) = &
303  this%idomain(ip, 1:max_level)
304  particle%idomain(1) = imdl
305  particle%iboundary(1:max_level) = &
306  this%iboundary(ip, 1:max_level)
307  particle%ifrctrn = this%ifrctrn(ip)
308  particle%iexmeth = this%iexmeth(ip)
309  particle%extol = this%extol(ip)
310  particle%iextend = this%extend(ip)

◆ 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 397 of file Particle.f90.

398  use geomutilmodule, only: transform, compose
399  class(ParticleType), intent(in) :: this !< particle
400  real(DP), intent(out) :: x !< x coordinate
401  real(DP), intent(out) :: y !< y coordinate
402  real(DP), intent(out) :: z !< z coordinate
403 
404  if (this%transformed) then
405  call transform(this%x, this%y, this%z, x, y, z, &
406  this%xorigin, this%yorigin, this%zorigin, &
407  this%sinrot, this%cosrot, invert=.true.)
408  else
409  x = this%x
410  y = this%y
411  z = this%z
412  end if
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 416 of file Particle.f90.

417  class(ParticleStoreType) :: this
418  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 314 of file Particle.f90.

315  class(ParticleStoreType), intent(inout) :: this !< particle storage
316  class(ParticleType), intent(in) :: particle !< particle
317  integer(I4B), intent(in) :: ip !< particle index
318 
319  this%imdl(ip) = particle%imdl
320  this%iprp(ip) = particle%iprp
321  this%irpt(ip) = particle%irpt
322  this%name(ip) = particle%name
323  this%istopweaksink(ip) = particle%istopweaksink
324  this%istopzone(ip) = particle%istopzone
325  this%idrymeth(ip) = particle%idrymeth
326  this%icu(ip) = particle%icu
327  this%ilay(ip) = particle%ilay
328  this%izone(ip) = particle%izone
329  this%izp(ip) = particle%izp
330  this%istatus(ip) = particle%istatus
331  this%x(ip) = particle%x
332  this%y(ip) = particle%y
333  this%z(ip) = particle%z
334  this%trelease(ip) = particle%trelease
335  this%tstop(ip) = particle%tstop
336  this%ttrack(ip) = particle%ttrack
337  this%idomain( &
338  ip, &
339  1:max_level) = &
340  particle%idomain(1:max_level)
341  this%iboundary( &
342  ip, &
343  1:max_level) = &
344  particle%iboundary(1:max_level)
345  this%ifrctrn(ip) = particle%ifrctrn
346  this%iexmeth(ip) = particle%iexmeth
347  this%extol(ip) = particle%extol
348  this%extend(ip) = particle%iextend

◆ reset_transform()

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

Definition at line 382 of file Particle.f90.

383  class(ParticleType), intent(inout) :: this !< particle
384 
385  this%xorigin = dzero
386  this%yorigin = dzero
387  this%zorigin = dzero
388  this%sinrot = dzero
389  this%cosrot = done
390  this%cosrot = done
391  this%transformed = .false.

◆ 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 235 of file Particle.f90.

236  ! dummy
237  class(ParticleStoreType), intent(inout) :: this !< particle store
238  integer(I4B), intent(in) :: np !< number of particles
239  character(*), intent(in) :: mempath !< path to memory
240 
241  ! resize arrays
242  call mem_reallocate(this%imdl, np, 'PLIMDL', mempath)
243  call mem_reallocate(this%iprp, np, 'PLIPRP', mempath)
244  call mem_reallocate(this%irpt, np, 'PLIRPT', mempath)
245  call mem_reallocate(this%name, lenboundname, np, 'PLNAME', mempath)
246  call mem_reallocate(this%icu, np, 'PLICU', mempath)
247  call mem_reallocate(this%ilay, np, 'PLILAY', mempath)
248  call mem_reallocate(this%izone, np, 'PLIZONE', mempath)
249  call mem_reallocate(this%izp, np, 'PLIZP', mempath)
250  call mem_reallocate(this%istatus, np, 'PLISTATUS', mempath)
251  call mem_reallocate(this%x, np, 'PLX', mempath)
252  call mem_reallocate(this%y, np, 'PLY', mempath)
253  call mem_reallocate(this%z, np, 'PLZ', mempath)
254  call mem_reallocate(this%trelease, np, 'PLTRELEASE', mempath)
255  call mem_reallocate(this%tstop, np, 'PLTSTOP', mempath)
256  call mem_reallocate(this%ttrack, np, 'PLTTRACK', mempath)
257  call mem_reallocate(this%istopweaksink, np, 'PLISTOPWEAKSINK', mempath)
258  call mem_reallocate(this%istopzone, np, 'PLISTOPZONE', mempath)
259  call mem_reallocate(this%idrymeth, np, 'PLIDRYMETH', mempath)
260  call mem_reallocate(this%ifrctrn, np, 'PLIFRCTRN', mempath)
261  call mem_reallocate(this%iexmeth, np, 'PLIEXMETH', mempath)
262  call mem_reallocate(this%extol, np, 'PLEXTOL', mempath)
263  call mem_reallocate(this%extend, np, 'PLIEXTEND', mempath)
264  call mem_reallocate(this%idomain, np, max_level, 'PLIDOMAIN', mempath)
265  call mem_reallocate(this%iboundary, np, max_level, 'PLIBOUNDARY', mempath)

◆ 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 357 of file Particle.f90.

359  use geomutilmodule, only: transform, compose
360  class(ParticleType), intent(inout) :: this !< particle
361  real(DP), intent(in), optional :: xorigin !< x coordinate of origin
362  real(DP), intent(in), optional :: yorigin !< y coordinate of origin
363  real(DP), intent(in), optional :: zorigin !< z coordinate of origin
364  real(DP), intent(in), optional :: sinrot !< sine of rotation angle
365  real(DP), intent(in), optional :: cosrot !< cosine of rotation angle
366  logical(LGP), intent(in), optional :: invert !< whether to invert
367 
368  call transform(this%x, this%y, this%z, &
369  this%x, this%y, this%z, &
370  xorigin, yorigin, zorigin, &
371  sinrot, cosrot, invert)
372 
373  call compose(this%xorigin, this%yorigin, this%zorigin, &
374  this%sinrot, this%cosrot, &
375  xorigin, yorigin, zorigin, &
376  sinrot, cosrot, invert)
377 
378  this%transformed = .true.
Here is the call graph for this function:

Variable Documentation

◆ max_level

integer, parameter particlemodule::max_level = 4

Definition at line 15 of file Particle.f90.

15  integer, parameter :: MAX_LEVEL = 4