This subroutine consists partly of code written by David W. Pollock of the USGS for MODPATH 7. PRT's authors take responsibility for its application in this context and for any modifications or errors.
98 class(MethodSubcellPollockType),
intent(inout) :: this
99 class(SubcellRectType),
intent(in) :: subcell
100 type(ParticleType),
pointer,
intent(inout) :: particle
101 real(DP),
intent(in) :: tmax
103 real(DP) :: dt, dtexit, texit
104 real(DP) :: t, x, y, z
105 real(DP) :: t0, x0, y0, z0
106 integer(I4B) :: i, exit_face, exit_soln
107 type(LinearExitSolutionType) :: exit_solutions(3)
108 type(LinearExitSolutionType) :: exit_x, exit_y, exit_z
113 call find_exits(particle, subcell, exit_solutions, x0, y0, z0)
114 exit_x = exit_solutions(1)
115 exit_y = exit_solutions(2)
116 exit_z = exit_solutions(3)
119 exit_soln = pick_exit(exit_solutions)
120 if (exit_soln == 0)
then
124 exit_face = exit_solutions(exit_soln)%iboundary
125 dtexit = exit_solutions(exit_soln)%dt
127 texit = particle%ttrack + dtexit
140 if (all([exit_solutions%status] >= no_exit_stationary))
then
149 call this%tracktimes%advance()
150 if (this%tracktimes%any())
then
151 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
152 t = this%tracktimes%times(i)
153 if (t < particle%ttrack) cycle
154 if (t > texit .or. t > tmax)
exit
156 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
157 dt, x0, subcell%dx, exit_x%status == 1)
158 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
159 dt, y0, subcell%dy, exit_y%status == 1)
160 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
161 dt, z0, subcell%dz, exit_z%status == 1)
162 particle%x = x * subcell%dx
163 particle%y = y * subcell%dy
164 particle%z = z * subcell%dz
167 call this%usertime(particle)
173 if (texit .gt. tmax)
then
176 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
177 dt, x0, subcell%dx, exit_x%status == 1)
178 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
179 dt, y0, subcell%dy, exit_y%status == 1)
180 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
181 dt, z0, subcell%dz, exit_z%status == 1)
184 particle%advancing = .false.
185 particle%x = x * subcell%dx
186 particle%y = y * subcell%dy
187 particle%z = z * subcell%dz
189 particle%iboundary(level_subfeature) = exit_face
190 call this%timestep(particle)
199 if ((exit_face .eq. 1) .or. (exit_face .eq. 2))
then
201 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
202 dt, y0, subcell%dy, exit_y%status == 1)
203 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
204 dt, z0, subcell%dz, exit_z%status == 1)
205 if (exit_face .eq. 2) x = done
206 else if ((exit_face .eq. 3) .or. (exit_face .eq. 4))
then
207 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, dt, &
208 x0, subcell%dx, exit_x%status == 1)
210 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, dt, &
211 z0, subcell%dz, exit_z%status == 1)
212 if (exit_face .eq. 4) y = done
213 else if ((exit_face .eq. 5) .or. (exit_face .eq. 6))
then
214 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
215 dt, x0, subcell%dx, exit_x%status == 1)
216 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
217 dt, y0, subcell%dy, exit_y%status == 1)
219 if (exit_face .eq. 6) z = done
221 print *,
"programmer error, invalid exit face", exit_face
224 particle%x = x * subcell%dx
225 particle%y = y * subcell%dy
226 particle%z = z * subcell%dz
228 particle%iboundary(level_subfeature) = exit_face
229 call this%subcellexit(particle)
@, 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