38 subroutine try_pass(this, particle, nextlevel, advancing)
41 logical(LGP) :: advancing
42 integer(I4B) :: nextlevel
44 integer(I4B) :: ic, iboundary, icellface
46 if (.not. particle%advancing)
then
48 particle%iboundary = 0
52 call this%pass(particle)
55 icellface = this%iboundary_to_icellface(iboundary)
56 if (icellface <= 0)
return
60 call this%cellexit(particle)
64 if (this%fmi%is_net_out_boundary_face(ic, icellface))
then
78 subroutine assess(this, particle, cell_defn, tmax)
88 real(DP),
intent(in) :: tmax
90 logical(LGP) :: dry_cell, dry_particle, no_exit_face, stop_zone, weak_sink
92 real(DP) :: t, ttrackmax
95 dry_particle = particle%z > cell_defn%top
96 no_exit_face = cell_defn%inoexitface > 0
97 stop_zone = cell_defn%izone > 0 .and. particle%istopzone == cell_defn%izone
98 weak_sink = cell_defn%iweaksink > 0
100 particle%izone = cell_defn%izone
106 if (no_exit_face .and. .not. dry_cell)
then
112 if (particle%istopweaksink > 0)
then
116 call this%weaksink(particle)
121 if (particle%idrymeth == 0)
then
124 no_exit_face = .false.
125 else if (particle%idrymeth == 1)
then
129 else if (particle%idrymeth == 2)
then
131 particle%advancing = .false.
132 no_exit_face = .false.
144 particle%ttrack =
totim
145 call this%timestep(particle)
148 call this%tracktimes%advance()
149 if (this%tracktimes%any())
then
150 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
151 t = this%tracktimes%times(i)
155 call this%usertime(particle)
156 if (t > ttrackmax) ttrackmax = t
162 particle%ttrack = ttrackmax
167 else if (dry_particle .and. this%name /=
"passtobottom")
then
168 if (particle%idrymeth == 0)
then
170 particle%z = cell_defn%top
171 call this%dropped(particle)
172 else if (particle%idrymeth == 1)
then
176 else if (particle%idrymeth == 2)
then
178 particle%advancing = .false.
179 no_exit_face = .false.
191 particle%ttrack =
totim
192 call this%timestep(particle)
195 call this%tracktimes%advance()
196 if (this%tracktimes%any())
then
197 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
198 t = this%tracktimes%times(i)
202 call this%usertime(particle)
203 if (t > ttrackmax) ttrackmax = t
209 if (no_exit_face)
then
210 particle%advancing = .false.
212 call this%terminate(particle)
224 integer(I4B) :: i, nhist
225 class(*),
pointer :: prev
232 call this%events%broadcast(particle, event)
233 if (particle%icycwin == 0)
then
237 if (this%forms_cycle(particle, event))
then
239 print *,
"Cyclic pathline detected"
240 nhist = particle%history%Count()
242 prev => particle%history%GetItem(i)
245 print *,
"Back ", nhist - i + 1,
": ", prev%get_text()
248 print *,
"Current :", event%get_text()
249 call pstop(1,
'Cyclic pathline detected, aborting')
251 call this%store_event(particle, event)
263 logical(LGP) :: found_cycle
265 found_cycle = .false.
268 itr = particle%history%Iterator()
269 do while (itr%has_next())
271 select type (prev => itr%value())
273 if (event%icu == prev%icu .and. &
274 event%ilay == prev%ilay .and. &
275 event%izone == prev%izone .and. &
276 event%exit_face == prev%exit_face .and. &
277 event%exit_face /= 0)
then
284 itr = particle%history%Iterator()
285 do while (itr%has_next())
287 select type (prev => itr%value())
289 if (event%icu == prev%icu .and. &
290 event%ilay == prev%ilay .and. &
291 event%isc == prev%isc .and. &
292 event%exit_face == prev%exit_face .and. &
293 event%exit_face /= 0)
then
311 class(*),
pointer :: p
316 call particle%history%Add(p)
317 if (particle%history%Count() > particle%icycwin) &
318 call particle%history%RemoveNode(1, .true.)
321 call particle%history%Add(p)
322 if (particle%history%Count() > particle%icycwin) &
323 call particle%history%RemoveNode(1, .true.)
330 integer(I4B) :: level
337 integer(I4B),
intent(in) :: iboundary
338 integer(I4B) :: iface
339 integer(I4B) :: nfaces
342 nfaces = this%cell%defn%npolyverts + 2
343 if (iface >= nfaces) &
345 iface = iface + (this%fmi%max_faces - nfaces) - 1
This module contains simulation constants.
real(dp), parameter dzero
real constant zero
real(dp), parameter done
real constant 1
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
This module defines variable data types.
logical(lgp) function forms_cycle(this, particle, event)
Check if the event forms a cycle in the particle path.
subroutine try_pass(this, particle, nextlevel, advancing)
Try passing the particle to the next subdomain. or to a boundary of this method's tracking domain.
integer(i4b) function iboundary_to_icellface(this, iboundary)
Convert an iboundary number to an iface number.
subroutine store_event(this, particle, event)
Save the event in the particle's history. Acts like a queue, the oldest event is removed when the eve...
subroutine cellexit(this, particle)
Particle exits a cell.
integer(i4b) function get_level(this)
Get the cell method's level.
Particle tracking strategies.
@, public weaksink
particle entered a weak sink
@, public usertime
user-specified tracking time
@, public terminate
particle terminated
@, public timestep
time step ended
@ term_weaksink
terminated in a weak sink cell
@ term_inactive
terminated in an inactive cell
@ term_no_exits
terminated in a cell with no exit face
@ term_stopzone
terminated in a cell with a stop zone number
@ term_boundary
terminated at a boundary face
logical(lgp), pointer, public endofsimulation
flag indicating end of simulation
real(dp), pointer, public totim
time relative to start of simulation
real(dp), pointer, public totimc
simulation time at start of time step
Base grid cell definition.
Base type for particle tracking methods.
Base type for particle events.
Particle tracked by the PRT model.