21 real(dp),
allocatable,
public :: qextl1(:), qextl2(:), qintl(:)
39 method%subcell => subcell
40 method%name => method%subcell%type
41 method%delegates = .false.
47 deallocate (this%name)
55 real(DP),
intent(in) :: tmax
63 select type (subcell => this%subcell)
69 xorigin = subcell%xOrigin
70 yorigin = subcell%yOrigin
71 zorigin = subcell%zOrigin
72 sinrot = subcell%sinrot
73 cosrot = subcell%cosrot
74 call particle%transform(xorigin, yorigin)
75 call this%track_subcell(subcell, particle, tmax)
76 call particle%transform(xorigin, yorigin, invert=.true.)
95 real(DP),
intent(in) :: tmax
114 integer(I4B) :: statusVX
115 integer(I4B) :: statusVY
116 integer(I4B) :: statusVZ
121 integer(I4B) :: exitFace
122 integer(I4B) :: event_code
127 initialx = particle%x / subcell%dx
128 initialy = particle%y / subcell%dy
129 initialz = particle%z / subcell%dz
132 statusvx =
calculate_dt(subcell%vx1, subcell%vx2, subcell%dx, &
133 initialx, vx, dvxdx, dtexitx)
134 statusvy =
calculate_dt(subcell%vy1, subcell%vy2, subcell%dy, &
135 initialy, vy, dvydy, dtexity)
136 statusvz =
calculate_dt(subcell%vz1, subcell%vz2, subcell%dz, &
137 initialz, vz, dvzdz, dtexitz)
141 if ((statusvx .eq. 3) .and. (statusvy .eq. 3) .and. (statusvz .eq. 3))
then
152 if ((statusvx .eq. 2) .and. (statusvy .eq. 2) .and. (statusvz .eq. 2) .and. &
161 if ((statusvx .lt. 2) .or. (statusvy .lt. 2) .or. (statusvz .lt. 2))
then
164 if (vx .lt.
dzero)
then
166 else if (vx .gt. 0)
then
170 if (dtexity .lt. dtexit)
then
172 if (vy .lt.
dzero)
then
174 else if (vy .gt.
dzero)
then
179 if (dtexitz .lt. dtexit)
then
181 if (vz .lt.
dzero)
then
183 else if (vz .gt.
dzero)
then
191 texit = particle%ttrack + dtexit
198 call this%tracktimes%advance()
199 if (this%tracktimes%any())
then
200 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
201 t = this%tracktimes%times(i)
202 if (t < particle%ttrack) cycle
203 if (t >= texit .or. t >= tmax)
exit
205 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
206 dt, initialx, subcell%dx, statusvx == 1)
207 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
208 dt, initialy, subcell%dy, statusvy == 1)
209 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
210 dt, initialz, subcell%dz, statusvz == 1)
211 particle%x = x * subcell%dx
212 particle%y = y * subcell%dy
213 particle%z = z * subcell%dz
216 call this%usertime(particle)
220 if (texit .gt. tmax)
then
226 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
227 dt, initialx, subcell%dx, statusvx == 1)
228 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
229 dt, initialy, subcell%dy, statusvy == 1)
230 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
231 dt, initialz, subcell%dz, statusvz == 1)
234 particle%advancing = .false.
242 if ((exitface .eq. 1) .or. (exitface .eq. 2))
then
244 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
245 dt, initialy, subcell%dy, statusvy == 1)
246 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
247 dt, initialz, subcell%dz, statusvz == 1)
248 if (exitface .eq. 2) x =
done
249 else if ((exitface .eq. 3) .or. (exitface .eq. 4))
then
250 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, dt, &
251 initialx, subcell%dx, statusvx == 1)
253 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, dt, &
254 initialz, subcell%dz, statusvz == 1)
255 if (exitface .eq. 4) y =
done
256 else if ((exitface .eq. 5) .or. (exitface .eq. 6))
then
257 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
258 dt, initialx, subcell%dx, statusvx == 1)
259 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
260 dt, initialy, subcell%dy, statusvy == 1)
262 if (exitface .eq. 6) z =
done
264 print *,
"programmer error, invalid exit face", exitface
272 particle%x = x * subcell%dx
273 particle%y = y * subcell%dy
274 particle%z = z * subcell%dz
280 call this%timestep(particle)
281 else if (event_code ==
featexit)
then
282 call this%subcellexit(particle)
304 integer(I4B) :: status
320 logical(LGP) :: nooutflow
326 if (v2a .lt.
dzero) v2a = -v2a
328 if (v1a .lt.
dzero) v1a = -v1a
331 if (dva .lt.
dzero) dva = -dva
336 if ((v2a .lt. tol) .and. (v1a .lt. tol))
then
347 if (v2a .gt. vv) vv = v2a
349 if (vvv .lt. 1.0d-4)
then
354 if (v1 .gt. zro) dt = (dx - x) / v1
355 if (v1 .lt. zrom) dt = -x / v1
364 v = (
done - xl) * v1 + xl * v2
369 if (v1 .lt.
dzero) nooutflow = .false.
370 if (v2 .gt.
dzero) nooutflow = .false.
380 if ((v1 .le.
dzero) .and. (v2 .ge.
dzero))
then
381 if (abs(v) .le.
dzero)
then
383 if (v2 .le.
dzero) v = -v
393 if (vr .le.
dzero)
then
401 if (v1v2 .gt.
dzero)
then
402 if (v .gt.
dzero) vr = vr2
403 if (v .lt.
dzero) vr = vr1
408 if (dabs(vr) .lt. 1.0d-10)
then
428 pure function new_x(v, dvdx, v1, v2, dt, x, dx, velocity_profile)
result(newx)
430 real(dp),
intent(in) :: v
431 real(dp),
intent(in) :: dvdx
432 real(dp),
intent(in) :: v1
433 real(dp),
intent(in) :: v2
434 real(dp),
intent(in) :: dt
435 real(dp),
intent(in) :: x
436 real(dp),
intent(in) :: dx
437 logical(LGP),
intent(in),
optional :: velocity_profile
440 logical(LGP) :: lprofile
443 if (
present(velocity_profile))
then
444 lprofile = velocity_profile
452 newx = newx + (v1 * dt / dx)
453 else if (v .ne.
dzero)
then
454 newx = newx + (v * (exp(dvdx * dt) -
done) / dvdx / dx)
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.
Particle tracking strategies.
@, public level_subfeature
pure real(dp) function new_x(v, dvdx, v1, v2, dt, x, dx, velocity_profile)
Update a cell-local coordinate based on a time increment.
integer(i4b) function, public calculate_dt(v1, v2, dx, xL, v, dvdx, dt)
Calculate particle travel time to exit and exit status.
subroutine track_subcell(this, subcell, particle, tmax)
Track a particle across a rectangular subcell using Pollock's method.
subroutine, public create_method_subcell_pollock(method)
Create a new Pollock's subcell method.
subroutine apply_msp(this, particle, tmax)
Apply Pollock's method to a rectangular subcell.
@, public featexit
particle exited a grid feature
@, public timestep
time step ended
@ term_timeout
terminated at stop time or end of simulation
@ term_no_exits_sub
terminated in a subcell with no exit face
subroutine, public create_subcell_rect(subcell)
Create a new rectangular subcell.
logical(lgp), pointer, public endofsimulation
flag indicating end of simulation
Base type for grid cells of a concrete type. Contains a cell-definition which is information shared b...
Rectangular subcell tracking method.
Particle tracked by the PRT model.