MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
particletracksmodule Module Reference

Particle track output module. More...

Data Types

type  particletrackfiletype
 Output file containing all or some particle pathlines. More...
 
type  particletrackeventselectiontype
 Selection of particle events. More...
 
type  particletrackstype
 Manages particle track output (logging/writing). More...
 

Functions/Subroutines

subroutine init_file (this, iun, csv, iprp)
 Initialize a binary or CSV file. More...
 
subroutine destroy (this)
 
subroutine expand_files (this, increment)
 Grow the array of track files. More...
 
subroutine select_events (this, release, cellexit, timestep, terminate, weaksink, usertime)
 Pick events to track. More...
 
logical function is_selected (this, event_code)
 Check if a given event code is selected for tracking. More...
 
logical function should_save (this, particle, file)
 Check whether a particle belongs in a given file i.e. if the file is enabled and its group matches the particle's. More...
 
subroutine, private save_event (iun, particle, event, csv)
 Save an event to a binary or CSV file. More...
 
logical function should_log (this)
 Log output unit valid? More...
 
subroutine, private log_event (iun, particle, event)
 Print a particle event summary. More...
 
subroutine handle_event (this, particle, event)
 Handle a particle event. More...
 

Variables

character(len= *), parameter, public trackheader = 'kper,kstp,imdl,iprp,irpt,ilay,icell,izone,istatus,ireason,trelease,t,x,y,z,name'
 
character(len= *), parameter, public trackdtypes = '<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,<f8,<f8,<f8,<f8,<f8,|S40'
 

Detailed Description

Each particle's track consists of events reported as the particle is advected through the model domain. Events are snapshots of particle state, along with optional metadata, at a particular moment in time.

Particles have no ID property. A particle can be uniquely identified by the unique combination of its release attributes (model, package, position, and time). This is possible because only one particle may be released from a given point at a given time.

This module consumes particle events and is responsible for writing them to one or more track files, binary or CSV, and for logging the events if requested. Each track file is associated with either a PRP package or with the full PRT model (there may only be 1 such latter).

Function/Subroutine Documentation

◆ destroy()

subroutine particletracksmodule::destroy ( class(particletrackstype this)

Definition at line 112 of file ParticleTracks.f90.

113  class(ParticleTracksType) :: this
114  if (allocated(this%files)) deallocate (this%files)

◆ expand_files()

subroutine particletracksmodule::expand_files ( class(particletrackstype this,
integer(i4b), intent(in), optional  increment 
)

Definition at line 118 of file ParticleTracks.f90.

119  ! dummy
120  class(ParticleTracksType) :: this
121  integer(I4B), optional, intent(in) :: increment
122  ! local
123  integer(I4B) :: inclocal
124  integer(I4B) :: isize
125  integer(I4B) :: newsize
126  type(ParticleTrackFileType), allocatable, dimension(:) :: temp
127 
128  if (present(increment)) then
129  inclocal = increment
130  else
131  inclocal = 1
132  end if
133 
134  if (allocated(this%files)) then
135  isize = size(this%files)
136  newsize = isize + inclocal
137  allocate (temp(newsize))
138  temp(1:isize) = this%files
139  deallocate (this%files)
140  call move_alloc(temp, this%files)
141  else
142  allocate (this%files(inclocal))
143  end if

◆ handle_event()

subroutine particletracksmodule::handle_event ( class(particletrackstype), intent(inout)  this,
type(particletype), intent(in), pointer  particle,
class(particleeventtype), intent(in), pointer  event 
)

Definition at line 289 of file ParticleTracks.f90.

290  ! dummy
291  class(ParticleTracksType), intent(inout) :: this
292  type(ParticleType), pointer, intent(in) :: particle
293  class(ParticleEventType), pointer, intent(in) :: event
294  ! local
295  integer(I4B) :: i
296  type(ParticleTrackFileType) :: file
297 
298  if (this%should_log()) &
299  call log_event(this%iout, particle, event)
300 
301  if (this%is_selected(event%get_code())) then
302  do i = 1, this%ntrackfiles
303  file = this%files(i)
304  if (this%should_save(particle, file)) &
305  call save_event(file%iun, particle, event, csv=file%csv)
306  end do
307  end if
Here is the call graph for this function:

◆ init_file()

subroutine particletracksmodule::init_file ( class(particletrackstype this,
integer(i4b), intent(in)  iun,
logical(lgp), intent(in), optional  csv,
integer(i4b), intent(in), optional  iprp 
)

Definition at line 89 of file ParticleTracks.f90.

90  ! dummy
91  class(ParticleTracksType) :: this
92  integer(I4B), intent(in) :: iun
93  logical(LGP), intent(in), optional :: csv
94  integer(I4B), intent(in), optional :: iprp
95  ! local
96  type(ParticleTrackFileType), pointer :: file
97 
98  if (.not. allocated(this%files)) then
99  allocate (this%files(1))
100  else
101  call this%expand_files(increment=1)
102  end if
103 
104  allocate (file)
105  file%iun = iun
106  if (present(csv)) file%csv = csv
107  if (present(iprp)) file%iprp = iprp
108  this%ntrackfiles = size(this%files)
109  this%files(this%ntrackfiles) = file

◆ is_selected()

logical function particletracksmodule::is_selected ( class(particletrackstype), intent(inout)  this,
integer(i4b), intent(in)  event_code 
)

Definition at line 170 of file ParticleTracks.f90.

171  class(ParticleTracksType), intent(inout) :: this
172  integer(I4B), intent(in) :: event_code
173 
174  selected = (this%selected%release .and. event_code == 0) .or. &
175  (this%selected%cellexit .and. event_code == 1) .or. &
176  (this%selected%timestep .and. event_code == 2) .or. &
177  (this%selected%terminate .and. event_code == 3) .or. &
178  (this%selected%weaksink .and. event_code == 4) .or. &
179  (this%selected%usertime .and. event_code == 5)

◆ log_event()

subroutine, private particletracksmodule::log_event ( integer(i4b), intent(in)  iun,
type(particletype), intent(in), pointer  particle,
class(particleeventtype), intent(in), pointer  event 
)
private

Definition at line 259 of file ParticleTracks.f90.

260  integer(I4B), intent(in) :: iun
261  type(ParticleType), pointer, intent(in) :: particle
262  class(ParticleEventType), pointer, intent(in) :: event
263  ! local
264  character(len=:), allocatable :: particlename
265 
266  particlename = trim(adjustl(particle%name))
267  if (len_trim(particlename) == 0) particlename = 'anonymous'
268 
269  if (iun >= 0) &
270  write (iun, '(*(G0))') &
271  'Particle (Model: ', particle%imdl, &
272  ', Package: ', particle%iprp, &
273  ', Point: ', particle%irpt, ' [', particlename, ']', &
274  ', Time: ', particle%trelease, &
275  ') ', event%get_str(), &
276  ' in (Layer: ', particle%ilay, &
277  ', Cell: ', particle%icu, &
278  ', Zone: ', particle%izone, &
279  ') at (X: ', particle%x, &
280  ', Y: ', particle%y, &
281  ', Z: ', particle%z, &
282  ', Time: ', particle%ttrack, &
283  ', Period: ', event%kper, &
284  ', Timestep: ', event%kstp, &
285  ') with (Status: ', particle%istatus, ')'
Here is the caller graph for this function:

◆ save_event()

subroutine, private particletracksmodule::save_event ( integer(i4b), intent(in)  iun,
type(particletype), intent(in), pointer  particle,
class(particleeventtype), intent(in), pointer  event,
logical(lgp), intent(in)  csv 
)
private

Definition at line 193 of file ParticleTracks.f90.

194  ! dummy
195  integer(I4B), intent(in) :: iun
196  type(ParticleType), pointer, intent(in) :: particle
197  class(ParticleEventType), pointer, intent(in) :: event
198  logical(LGP), intent(in) :: csv
199  ! local
200  real(DP) :: x, y, z
201  integer(I4B) :: status
202 
203  ! Convert from cell-local to model coordinates if needed
204  call particle%get_model_coords(x, y, z)
205 
206  ! Set status
207  if (particle%istatus .lt. 0) then
208  status = active
209  else
210  status = particle%istatus
211  end if
212 
213  if (csv) then
214  write (iun, '(*(G0,:,","))') &
215  event%kper, &
216  event%kstp, &
217  particle%imdl, &
218  particle%iprp, &
219  particle%irpt, &
220  particle%ilay, &
221  particle%icu, &
222  particle%izone, &
223  status, &
224  event%get_code(), &
225  particle%trelease, &
226  particle%ttrack, &
227  x, &
228  y, &
229  z, &
230  trim(adjustl(particle%name))
231  else
232  write (iun) &
233  event%kper, &
234  event%kstp, &
235  particle%imdl, &
236  particle%iprp, &
237  particle%irpt, &
238  particle%ilay, &
239  particle%icu, &
240  particle%izone, &
241  status, &
242  event%get_code(), &
243  particle%trelease, &
244  particle%ttrack, &
245  x, &
246  y, &
247  z, &
248  particle%name
249  end if
Here is the caller graph for this function:

◆ select_events()

subroutine particletracksmodule::select_events ( class(particletrackstype this,
logical(lgp), intent(in)  release,
logical(lgp), intent(in)  cellexit,
logical(lgp), intent(in)  timestep,
logical(lgp), intent(in)  terminate,
logical(lgp), intent(in)  weaksink,
logical(lgp), intent(in)  usertime 
)

Definition at line 147 of file ParticleTracks.f90.

154  class(ParticleTracksType) :: this
155  logical(LGP), intent(in) :: release
156  logical(LGP), intent(in) :: cellexit
157  logical(LGP), intent(in) :: timestep
158  logical(LGP), intent(in) :: terminate
159  logical(LGP), intent(in) :: weaksink
160  logical(LGP), intent(in) :: usertime
161  this%selected%release = release
162  this%selected%cellexit = cellexit
163  this%selected%timestep = timestep
164  this%selected%terminate = terminate
165  this%selected%weaksink = weaksink
166  this%selected%usertime = usertime

◆ should_log()

logical function particletracksmodule::should_log ( class(particletrackstype), intent(inout)  this)

Definition at line 253 of file ParticleTracks.f90.

254  class(ParticleTracksType), intent(inout) :: this
255  should_log = this%iout >= 0

◆ should_save()

logical function particletracksmodule::should_save ( class(particletrackstype), intent(inout)  this,
type(particletype), intent(in), pointer  particle,
type(particletrackfiletype), intent(in)  file 
)

Definition at line 184 of file ParticleTracks.f90.

185  class(ParticleTracksType), intent(inout) :: this
186  type(ParticleType), pointer, intent(in) :: particle
187  type(ParticleTrackFileType), intent(in) :: file
188  save = (file%iun > 0 .and. &
189  (file%iprp == -1 .or. file%iprp == particle%iprp))

Variable Documentation

◆ trackdtypes

character(len=*), parameter, public particletracksmodule::trackdtypes = '<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,<f8,<f8,<f8,<f8,<f8,|S40'

Definition at line 38 of file ParticleTracks.f90.

38  character(len=*), parameter, public :: TRACKDTYPES = &
39  '<i4,<i4,<i4,<i4,<i4,<i4,<i4,<i4,&
40  &<i4,<i4,<f8,<f8,<f8,<f8,<f8,|S40'

◆ trackheader

character(len=*), parameter, public particletracksmodule::trackheader = 'kper,kstp,imdl,iprp,irpt,ilay,icell,izone,istatus,ireason,trelease,t,x,y,z,name'

Definition at line 34 of file ParticleTracks.f90.

34  character(len=*), parameter, public :: TRACKHEADER = &
35  'kper,kstp,imdl,iprp,irpt,ilay,icell,izone,&
36  &istatus,ireason,trelease,t,x,y,z,name'