34 integer(I4B) :: itopbotexit = -1, itrifaceexit = -1
47 integer(I4B),
public,
pointer :: zeromethod
65 method%subcell => subcell
66 method%name => method%subcell%type
67 method%delegates = .false.
73 deallocate (this%name)
80 real(DP),
intent(in) :: tmax
82 select type (subcell => this%subcell)
84 call this%track_subcell(subcell, particle, tmax)
96 real(DP),
intent(in) :: tmax
98 real(DP) :: dt, dtexit, texit
99 real(DP) :: t0, t, x, y, z0, z
100 integer(I4B) :: exit_face, exit_soln, event_code, i, isolv
105 if (particle%iexmeth == 0)
then
108 isolv = particle%iexmeth
114 call find_exits(particle, subcell, exit_solutions)
116 exit_z = exit_solutions(1)
117 exit_lateral = exit_solutions(2)
121 if (exit_z%itopbotexit == 0 .and. &
122 exit_lateral%itrifaceexit == 0)
then
129 exit_face = exit_solutions(exit_soln)%iboundary
130 dtexit = exit_solutions(exit_soln)%dt
131 if (dtexit <
dzero)
then
141 call this%tracktimes%advance()
142 if (this%tracktimes%any())
then
143 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
144 t = this%tracktimes%times(i)
146 if (t > texit .or. t > tmax)
exit
149 exit_lateral%rxx, exit_lateral%rxy, &
150 exit_lateral%ryx, exit_lateral%ryy, &
151 exit_lateral%sxx, exit_lateral%sxy, &
152 exit_lateral%syy, exit_z%status, &
153 subcell%x0, subcell%y0, &
154 exit_z%dvdx, exit_z%v, &
155 subcell%vzbot, subcell%ztop, subcell%zbot, &
162 call this%usertime(particle)
169 if (texit .gt. tmax)
then
176 particle%advancing = .false.
186 exit_lateral%rxx, exit_lateral%rxy, &
187 exit_lateral%ryx, exit_lateral%ryy, &
188 exit_lateral%sxx, exit_lateral%sxy, &
189 exit_lateral%syy, exit_z%status, &
190 subcell%x0, subcell%y0, &
191 exit_z%dvdx, exit_z%v, &
192 subcell%vzbot, subcell%ztop, subcell%zbot, &
193 z0, x, y, z, exit_face)
201 call this%timestep(particle)
202 else if (event_code ==
featexit)
then
203 call this%subcellexit(particle)
211 integer(I4B) :: exit_soln
213 if (exit_solutions(1)%itopbotexit == 0)
then
215 else if (exit_solutions(2)%itrifaceexit == 0 .or. &
216 exit_solutions(1)%dt < exit_solutions(2)%dt)
then
230 integer(I4B) :: ntmax
249 integer(I4B) :: isolv
250 integer(I4B) :: itrifaceenter
256 if (particle%iexmeth == 0)
then
259 isolv = particle%iexmeth
262 select type (subcell => domain)
275 subcell%x1, subcell%y1, &
276 subcell%x2, subcell%y2, &
277 subcell%v0x, subcell%v0y, &
278 subcell%v1x, subcell%v1y, &
279 subcell%v2x, subcell%v2y, &
280 particle%x, particle%y, &
281 rxx, rxy, ryx, ryy, &
283 alp0, bet0, alp1, bet1, alp2, bet2, alpi, beti)
292 zirel = (particle%z - subcell%zbot) / subcell%dz
293 if (zirel >
done)
then
295 else if (zirel <
dzero)
then
303 if (itrifaceenter == -1) itrifaceenter = 999
308 exit_solutions(2)%rxx = rxx
309 exit_solutions(2)%rxy = rxy
310 exit_solutions(2)%ryx = ryx
311 exit_solutions(2)%ryy = ryy
312 exit_solutions(2)%sxx = sxx
313 exit_solutions(2)%sxy = sxy
314 exit_solutions(2)%syy = syy
317 if (exit_solutions(1)%itopbotexit /= 0)
then
318 if (exit_solutions(1)%itopbotexit == -1)
then
319 exit_solutions(1)%iboundary = 4
321 exit_solutions(1)%iboundary = 5
326 if (exit_solutions(2)%itrifaceexit /= 0) &
327 exit_solutions(2)%iboundary = exit_solutions(2)%itrifaceexit
333 alp1, bet1, alp2, bet2, alpi, beti) &
335 integer(I4B) :: isolv
337 integer(I4B) :: itrifaceenter
348 solution%dt, solution%alpexit, solution%betexit, &
349 itrifaceenter, solution%itrifaceexit, &
350 alp1, bet1, alp2, bet2, alpi, beti)
351 if (solution%itrifaceexit > 0) solution%status =
ok_exit
355 real(dp),
intent(in) :: v1
356 real(dp),
intent(in) :: v2
357 real(dp),
intent(in) :: dx
358 real(dp),
intent(in) :: xl
362 call calculate_dt(v1, v2, dx, xl, solution%v, solution%dvdx, &
363 solution%dt, solution%status, solution%itopbotexit)
374 dt, status, itopbotexit)
396 integer(I4B) :: status
397 integer(I4B) :: itopbotexit
398 logical(LGP) :: noOutflow
404 if (v2a .lt.
dzero) v2a = -v2a
406 if (v1a .lt.
dzero) v1a = -v1a
409 if (dva .lt.
dzero) dva = -dva
414 if ((v2a .lt. tol) .and. (v1a .lt. tol))
then
426 if (v2a .gt. vv) vv = v2a
428 if (vvv .lt. 1.0d-4)
then
433 if (v1 .gt. zro)
then
437 if (v1 .lt. zrom)
then
449 v = (
done - xl) * v1 + xl * v2
454 if (v1 .lt.
dzero) nooutflow = .false.
455 if (v2 .gt.
dzero) nooutflow = .false.
466 if ((v1 .le.
dzero) .and. (v2 .ge.
dzero))
then
467 if (abs(v) .le.
dzero)
then
469 if (v2 .le.
dzero) v = -v
479 if (vr .le.
dzero)
then
488 if (v1v2 .gt.
dzero)
then
489 if (v .gt.
dzero)
then
493 if (v .lt.
dzero)
then
500 dt = log(abs(vr)) / dvdx
506 izstatus, x0, y0, az, vzi, vzbot, &
507 ztop, zbot, zi, x, y, z, exitface)
517 integer(I4B) :: izstatus
529 integer(I4B),
optional :: exitface
531 integer(I4B) :: lexitface
532 real(DP) :: rot(2, 2), res(2), loc(2)
537 if (
present(exitface))
then
548 if (lexitface .eq. 1)
then
550 else if (lexitface .eq. 2)
then
552 else if (lexitface .eq. 3)
then
557 if (lexitface .eq. 4)
then
559 else if (lexitface .eq. 5)
then
563 if (izstatus .eq. 2)
then
566 else if (izstatus .eq. 1)
then
571 z = zbot + (vzi * dexp(az * dt) - vzbot) / az
577 loc =
skew(loc, (/sxx, sxy, syy/), invert=.true.)
578 rot = reshape((/rxx, rxy, ryx, ryy/), shape(rot))
579 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.
@ ok_exit_constant
exit found, constant velocity
@ ok_exit
exit found using velocity interpolation
@ no_exit_stationary
no exit, zero velocity
@ no_exit_no_outflow
no exit, no outflow
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.
pure logical function, public is_close(a, b, rtol, atol, symmetric)
Check if a real value is approximately equal to another.
Particle tracking strategies.
@, public level_subfeature
type(barycentricexitsolutiontype) function find_lateral_exit(isolv, tol, itrifaceenter, alp1, bet1, alp2, bet2, alpi, beti)
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 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.
type(barycentricexitsolutiontype) function find_vertical_exit(v1, v2, dx, xL)
integer(i4b) function pick_exit(exit_solutions)
Determine earliest exit face.
subroutine find_exits(particle, domain, exit_solutions)
Calculate exit solutions for each coordinate direction.
subroutine, public create_method_subcell_ternary(method)
Create a new ternary subcell tracking method.
subroutine calculate_dt(v1, v2, dx, xL, v, dvdx, dt, status, itopbotexit)
Do calculations related to analytical z solution.
@, public featexit
particle exited a grid feature
@, public usertime
user-specified tracking time
@, public terminate
particle terminated
@, public timestep
time step ended
@ term_no_exits_sub
terminated in a subcell with no exit face
subroutine, public create_subcell_tri(subcell)
Create a new triangular subcell.
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.
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.
Base type for grid cells of a concrete type. Contains a cell-definition which is information shared b...
Base type for exit solutions.
Linear velocity interpolation exit solution.
A generic heterogeneous doubly-linked list.
Abstract base type for subcell tracking methods.
Barycentric velocity interpolation exit solution. Inherit from LinearExitSolutionType to get around a...
Ternary triangular subcell tracking method.
Particle tracked by the PRT model.