20 real(dp),
allocatable,
public :: qextl1(:), qextl2(:), qintl(:)
38 method%subcell => subcell
39 method%name => method%subcell%type
40 method%delegates = .false.
46 deallocate (this%name)
54 real(DP),
intent(in) :: tmax
62 select type (subcell => this%subcell)
68 xorigin = subcell%xOrigin
69 yorigin = subcell%yOrigin
70 zorigin = subcell%zOrigin
71 sinrot = subcell%sinrot
72 cosrot = subcell%cosrot
73 call particle%transform(xorigin, yorigin)
74 call this%track_subcell(subcell, particle, tmax)
75 call particle%transform(xorigin, yorigin, invert=.true.)
76 call particle%reset_transform()
92 real(DP),
intent(in) :: tmax
111 integer(I4B) :: statusVX
112 integer(I4B) :: statusVY
113 integer(I4B) :: statusVZ
118 integer(I4B) :: exitFace
119 integer(I4B) :: reason
124 initialx = particle%x / subcell%dx
125 initialy = particle%y / subcell%dy
126 initialz = particle%z / subcell%dz
129 statusvx =
calculate_dt(subcell%vx1, subcell%vx2, subcell%dx, &
130 initialx, vx, dvxdx, dtexitx)
131 statusvy =
calculate_dt(subcell%vy1, subcell%vy2, subcell%dy, &
132 initialy, vy, dvydy, dtexity)
133 statusvz =
calculate_dt(subcell%vz1, subcell%vz2, subcell%dz, &
134 initialz, vz, dvzdz, dtexitz)
138 if ((statusvx .eq. 3) .and. (statusvy .eq. 3) .and. (statusvz .eq. 3))
then
140 particle%advancing = .false.
141 call this%save(particle, reason=3)
148 if ((statusvx .lt. 2) .or. (statusvy .lt. 2) .or. (statusvz .lt. 2))
then
151 if (vx .lt.
dzero)
then
153 else if (vx .gt. 0)
then
157 if (dtexity .lt. dtexit)
then
159 if (vy .lt.
dzero)
then
161 else if (vy .gt.
dzero)
then
166 if (dtexitz .lt. dtexit)
then
168 if (vz .lt.
dzero)
then
170 else if (vz .gt.
dzero)
then
178 texit = particle%ttrack + dtexit
185 call this%tracktimes%advance()
186 if (this%tracktimes%any())
then
187 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
188 t = this%tracktimes%times(i)
189 if (t < particle%ttrack) cycle
190 if (t >= texit .or. t >= tmax)
exit
192 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
193 dt, initialx, subcell%dx, statusvx == 1)
194 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
195 dt, initialy, subcell%dy, statusvy == 1)
196 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
197 dt, initialz, subcell%dz, statusvz == 1)
198 particle%x = x * subcell%dx
199 particle%y = y * subcell%dy
200 particle%z = z * subcell%dz
203 call this%save(particle, reason=5)
207 if (texit .gt. tmax)
then
213 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
214 dt, initialx, subcell%dx, statusvx == 1)
215 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
216 dt, initialy, subcell%dy, statusvy == 1)
217 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
218 dt, initialz, subcell%dz, statusvz == 1)
221 particle%advancing = .false.
229 if ((exitface .eq. 1) .or. (exitface .eq. 2))
then
231 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
232 dt, initialy, subcell%dy, statusvy == 1)
233 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
234 dt, initialz, subcell%dz, statusvz == 1)
235 if (exitface .eq. 2) x =
done
236 else if ((exitface .eq. 3) .or. (exitface .eq. 4))
then
237 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, dt, &
238 initialx, subcell%dx, statusvx == 1)
240 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, dt, &
241 initialz, subcell%dz, statusvz == 1)
242 if (exitface .eq. 4) y =
done
243 else if ((exitface .eq. 5) .or. (exitface .eq. 6))
then
244 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
245 dt, initialx, subcell%dx, statusvx == 1)
246 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
247 dt, initialy, subcell%dy, statusvy == 1)
249 if (exitface .eq. 6) z =
done
251 print *,
"programmer error, invalid exit face", exitface
259 particle%x = x * subcell%dx
260 particle%y = y * subcell%dy
261 particle%z = z * subcell%dz
263 particle%iboundary(3) = exitface
266 if (reason >= 0)
call this%save(particle, reason=reason)
287 integer(I4B) :: status
303 logical(LGP) :: nooutflow
309 if (v2a .lt.
dzero) v2a = -v2a
311 if (v1a .lt.
dzero) v1a = -v1a
314 if (dva .lt.
dzero) dva = -dva
319 if ((v2a .lt. tol) .and. (v1a .lt. tol))
then
330 if (v2a .gt. vv) vv = v2a
332 if (vvv .lt. 1.0d-4)
then
337 if (v1 .gt. zro) dt = (dx - x) / v1
338 if (v1 .lt. zrom) dt = -x / v1
347 v = (
done - xl) * v1 + xl * v2
352 if (v1 .lt.
dzero) nooutflow = .false.
353 if (v2 .gt.
dzero) nooutflow = .false.
363 if ((v1 .le.
dzero) .and. (v2 .ge.
dzero))
then
364 if (abs(v) .le.
dzero)
then
366 if (v2 .le.
dzero) v = -v
376 if (vr .le.
dzero)
then
384 if (v1v2 .gt.
dzero)
then
385 if (v .gt.
dzero) vr = vr2
386 if (v .lt.
dzero) vr = vr1
391 if (dabs(vr) .lt. 1.0d-10)
then
411 pure function new_x(v, dvdx, v1, v2, dt, x, dx, velocity_profile)
result(newx)
413 real(dp),
intent(in) :: v
414 real(dp),
intent(in) :: dvdx
415 real(dp),
intent(in) :: v1
416 real(dp),
intent(in) :: v2
417 real(dp),
intent(in) :: dt
418 real(dp),
intent(in) :: x
419 real(dp),
intent(in) :: dx
420 logical(LGP),
intent(in),
optional :: velocity_profile
423 logical(LGP) :: lprofile
426 if (
present(velocity_profile))
then
427 lprofile = velocity_profile
435 newx = newx + (v1 * dt / dx)
436 else if (v .ne.
dzero)
then
437 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.
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.
subroutine, public create_subcell_rect(subcell)
Create a new rectangular subcell.
Base type for grid cells of a concrete type. Contains a cell-definition which is information shared b...
Base type for particle tracking methods.
Rectangular subcell tracking method.
Particle tracked by the PRT model.