22 integer(I4B),
public,
pointer :: zeromethod
40 method%subcell => subcell
41 method%name => method%subcell%type
42 method%delegates = .false.
48 deallocate (this%name)
55 real(DP),
intent(in) :: tmax
57 select type (subcell => this%subcell)
59 call this%track_subcell(subcell, particle, tmax)
69 real(DP),
intent(in) :: tmax
71 integer(I4B) :: exitFace
121 integer(I4B) :: izstatus
122 integer(I4B) :: itopbotexit
123 integer(I4B) :: ntmax
124 integer(I4B) :: isolv
125 integer(I4B) :: itrifaceenter
126 integer(I4B) :: itrifaceexit
131 integer(I4B) :: reason
135 if (particle%iexmeth == 0)
then
138 isolv = particle%iexmeth
164 vzbot = subcell%vzbot
165 vztop = subcell%vztop
178 v0x, v0y, v1x, v1y, v2x, v2y, &
180 rxx, rxy, ryx, ryy, &
182 alp0, bet0, alp1, bet1, alp2, bet2, alpi, beti)
190 zirel = (zi - zbot) / dz
192 az, dtexitz, izstatus, &
197 itrifaceenter = particle%iboundary(3) - 1
198 if (itrifaceenter == -1) itrifaceenter = 999
200 dtexitxy, alpexit, betexit, &
201 itrifaceenter, itrifaceexit, &
202 alp1, bet1, alp2, bet2, alpi, beti)
206 if (itopbotexit == 0 .and. itrifaceexit == 0)
then
208 particle%advancing = .false.
209 call this%save(particle, reason=3)
217 if (itrifaceexit /= 0)
then
219 exitface = itrifaceexit
221 else if (dtexitz < dtexitxy)
then
223 if (itopbotexit == -1)
then
230 texit = particle%ttrack + dtexit
237 call this%tracktimes%advance()
238 if (this%tracktimes%any())
then
239 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
240 t = this%tracktimes%times(i)
241 if (t < particle%ttrack) cycle
242 if (t >= texit .or. t >= tmax)
exit
245 izstatus, x0, y0, az, vzi, vzbot, &
246 ztop, zbot, zi, x, y, z)
252 call this%save(particle, reason=5)
259 if (texit .gt. tmax)
then
266 particle%advancing = .false.
276 izstatus, x0, y0, az, vzi, vzbot, &
277 ztop, zbot, zi, x, y, z, exitface)
282 particle%iboundary(3) = exitface
283 call this%save(particle, reason=reason)
294 dt, status, itopbotexit)
316 integer(I4B) :: status
317 integer(I4B) :: itopbotexit
318 logical(LGP) :: noOutflow
324 if (v2a .lt.
dzero) v2a = -v2a
326 if (v1a .lt.
dzero) v1a = -v1a
329 if (dva .lt.
dzero) dva = -dva
334 if ((v2a .lt. tol) .and. (v1a .lt. tol))
then
346 if (v2a .gt. vv) vv = v2a
348 if (vvv .lt. 1.0d-4)
then
353 if (v1 .gt. zro)
then
357 if (v1 .lt. zrom)
then
369 v = (
done - xl) * v1 + xl * v2
374 if (v1 .lt.
dzero) nooutflow = .false.
375 if (v2 .gt.
dzero) nooutflow = .false.
386 if ((v1 .le.
dzero) .and. (v2 .ge.
dzero))
then
387 if (abs(v) .le.
dzero)
then
389 if (v2 .le.
dzero) v = -v
399 if (vr .le.
dzero)
then
408 if (v1v2 .gt.
dzero)
then
409 if (v .gt.
dzero)
then
413 if (v .lt.
dzero)
then
426 izstatus, x0, y0, az, vzi, vzbot, &
427 ztop, zbot, zi, x, y, z, exitFace)
437 integer(I4B) :: izstatus
449 integer(I4B),
optional :: exitFace
451 integer(I4B) :: lexitface
452 real(DP) :: rot(2, 2), res(2), loc(2)
457 if (
present(exitface))
then
468 if (lexitface .eq. 1)
then
470 else if (lexitface .eq. 2)
then
472 else if (lexitface .eq. 3)
then
477 if (lexitface .eq. 4)
then
479 else if (lexitface .eq. 5)
then
483 if (izstatus .eq. 2)
then
486 else if (izstatus .eq. 1)
then
491 z = zbot + (vzi * dexp(az * dt) - vzbot) / az
497 loc =
skew(loc, (/sxx, sxy, syy/), invert=.true.)
498 rot = reshape((/rxx, rxy, ryx, ryy/), shape(rot))
499 res = matmul(rot, loc)
This module contains simulation constants.
real(dp), parameter dsame
real constant for values that are considered the same based on machine precision
real(dp), parameter dep3
real constant 1000
real(dp), parameter donethird
real constant 1/3
real(dp), parameter dhalf
real constant 1/2
real(dp), parameter dzero
real constant zero
real(dp), parameter dtwo
real constant 2
real(dp), parameter done
real constant 1
subroutine pstop(status, message)
Stop the program, optionally specifying an error status code.
subroutine, public clamp_bary(alpha, beta, gamma, pad)
Clamp barycentric coordinates to the interior of a triangle, with optional padding some minimum dista...
pure real(dp) function, dimension(2), public skew(v, s, invert)
Skew a 2D vector along the x-axis.
This module defines variable data types.
Particle tracking strategies.
subroutine track_subcell(this, subcell, particle, tmax)
Track a particle across a triangular subcell.
subroutine apply_mst(this, particle, tmax)
Apply the ternary subcell tracking method.
subroutine, public create_method_subcell_ternary(method)
Create a new ternary subcell tracking method.
subroutine calculate_xyz_position(dt, rxx, rxy, ryx, ryy, sxx, sxy, syy, izstatus, x0, y0, az, vzi, vzbot, ztop, zbot, zi, x, y, z, exitFace)
Calculate the particle's local unscaled xyz coordinates after dt.
subroutine calculate_dt(v1, v2, dx, xL, v, dvdx, dt, status, itopbotexit)
Do calculations related to analytical z solution.
subroutine, public create_subcell_tri(subcell)
Create a new triangular subcell.
subroutine, public canonical(x0, y0, x1, y1, x2, y2, v0x, v0y, v1x, v1y, v2x, v2y, xi, yi, rxx, rxy, ryx, ryy, sxx, sxy, syy, alp0, bet0, alp1, bet1, alp2, bet2, alpi, beti)
Set coordinates to "canonical" configuration.
subroutine, public traverse_triangle(isolv, tol, texit, alpexit, betexit, itrifaceenter, itrifaceexit, alp1, bet1, alp2, bet2, alpi, beti)
Traverse triangular cell.
subroutine, public step_analytical(t, alp, bet)
Step (evaluate) analytically depending on case.
Base type for grid cells of a concrete type. Contains a cell-definition which is information shared b...
Base type for particle tracking methods.
Ternary triangular subcell tracking method.
Particle tracked by the PRT model.