20 real(dp),
allocatable,
public :: qextl1(:), qextl2(:), qintl(:)
38 method%subcell => subcell
39 method%type => method%subcell%type
40 method%delegates = .false.
46 deallocate (this%type)
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.)
91 real(DP),
intent(in) :: tmax
110 integer(I4B) :: statusVX
111 integer(I4B) :: statusVY
112 integer(I4B) :: statusVZ
117 integer(I4B) :: exitFace
118 integer(I4B) :: reason
123 initialx = particle%x / subcell%dx
124 initialy = particle%y / subcell%dy
125 initialz = particle%z / subcell%dz
128 statusvx =
calculate_dt(subcell%vx1, subcell%vx2, subcell%dx, &
129 initialx, vx, dvxdx, dtexitx)
130 statusvy =
calculate_dt(subcell%vy1, subcell%vy2, subcell%dy, &
131 initialy, vy, dvydy, dtexity)
132 statusvz =
calculate_dt(subcell%vz1, subcell%vz2, subcell%dz, &
133 initialz, vz, dvzdz, dtexitz)
137 if ((statusvx .eq. 3) .and. (statusvy .eq. 3) .and. (statusvz .eq. 3))
then
139 particle%advancing = .false.
140 call this%save(particle, reason=3)
147 if ((statusvx .lt. 2) .or. (statusvy .lt. 2) .or. (statusvz .lt. 2))
then
150 if (vx .lt.
dzero)
then
152 else if (vx .gt. 0)
then
156 if (dtexity .lt. dtexit)
then
158 if (vy .lt.
dzero)
then
160 else if (vy .gt.
dzero)
then
165 if (dtexitz .lt. dtexit)
then
167 if (vz .lt.
dzero)
then
169 else if (vz .gt.
dzero)
then
177 texit = particle%ttrack + dtexit
184 call this%tracktimes%advance()
185 if (this%tracktimes%any())
then
186 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
187 t = this%tracktimes%times(i)
188 if (t < particle%ttrack) cycle
189 if (t >= texit .or. t >= tmax)
exit
191 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
192 dt, initialx, subcell%dx, statusvx == 1)
193 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
194 dt, initialy, subcell%dy, statusvy == 1)
195 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
196 dt, initialz, subcell%dz, statusvz == 1)
197 particle%x = x * subcell%dx
198 particle%y = y * subcell%dy
199 particle%z = z * subcell%dz
202 call this%save(particle, reason=5)
206 if (texit .gt. tmax)
then
212 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
213 dt, initialx, subcell%dx, statusvx == 1)
214 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
215 dt, initialy, subcell%dy, statusvy == 1)
216 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
217 dt, initialz, subcell%dz, statusvz == 1)
220 particle%advancing = .false.
228 if ((exitface .eq. 1) .or. (exitface .eq. 2))
then
230 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
231 dt, initialy, subcell%dy, statusvy == 1)
232 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, &
233 dt, initialz, subcell%dz, statusvz == 1)
234 if (exitface .eq. 2) x =
done
235 else if ((exitface .eq. 3) .or. (exitface .eq. 4))
then
236 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, dt, &
237 initialx, subcell%dx, statusvx == 1)
239 z =
new_x(vz, dvzdz, subcell%vz1, subcell%vz2, dt, &
240 initialz, subcell%dz, statusvz == 1)
241 if (exitface .eq. 4) y =
done
242 else if ((exitface .eq. 5) .or. (exitface .eq. 6))
then
243 x =
new_x(vx, dvxdx, subcell%vx1, subcell%vx2, &
244 dt, initialx, subcell%dx, statusvx == 1)
245 y =
new_x(vy, dvydy, subcell%vy1, subcell%vy2, &
246 dt, initialy, subcell%dy, statusvy == 1)
248 if (exitface .eq. 6) z =
done
250 print *,
"programmer error, invalid exit face", exitface
258 particle%x = x * subcell%dx
259 particle%y = y * subcell%dy
260 particle%z = z * subcell%dz
262 particle%iboundary(3) = exitface
265 if (reason >= 0)
call this%save(particle, reason=reason)
286 integer(I4B) :: status
302 logical(LGP) :: nooutflow
308 if (v2a .lt.
dzero) v2a = -v2a
310 if (v1a .lt.
dzero) v1a = -v1a
313 if (dva .lt.
dzero) dva = -dva
318 if ((v2a .lt. tol) .and. (v1a .lt. tol))
then
329 if (v2a .gt. vv) vv = v2a
331 if (vvv .lt. 1.0d-4)
then
336 if (v1 .gt. zro) dt = (dx - x) / v1
337 if (v1 .lt. zrom) dt = -x / v1
346 v = (
done - xl) * v1 + xl * v2
351 if (v1 .lt.
dzero) nooutflow = .false.
352 if (v2 .gt.
dzero) nooutflow = .false.
362 if ((v1 .le.
dzero) .and. (v2 .ge.
dzero))
then
363 if (abs(v) .le.
dzero)
then
365 if (v2 .le.
dzero) v = -v
375 if (vr .le.
dzero)
then
383 if (v1v2 .gt.
dzero)
then
384 if (v .gt.
dzero) vr = vr2
385 if (v .lt.
dzero) vr = vr1
390 if (dabs(vr) .lt. 1.0d-10)
then
410 pure function new_x(v, dvdx, v1, v2, dt, x, dx, velocity_profile)
result(newx)
412 real(dp),
intent(in) :: v
413 real(dp),
intent(in) :: dvdx
414 real(dp),
intent(in) :: v1
415 real(dp),
intent(in) :: v2
416 real(dp),
intent(in) :: dt
417 real(dp),
intent(in) :: x
418 real(dp),
intent(in) :: dx
419 logical(LGP),
intent(in),
optional :: velocity_profile
422 logical(LGP) :: lprofile
425 if (
present(velocity_profile))
then
426 lprofile = velocity_profile
434 newx = newx + (v1 * dt / dx)
435 else if (v .ne.
dzero)
then
436 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.