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.
107 class(MethodSubcellPollockType),
intent(inout) :: this
108 class(SubcellRectType),
intent(in) :: subcell
109 type(ParticleType),
pointer,
intent(inout) :: particle
110 real(DP),
intent(in) :: tmax
112 real(DP) :: dt, dtexit, texit
113 real(DP) :: t, x, y, z
114 real(DP) :: t0, x0, y0, z0
115 integer(I4B) :: i, exit_face, exit_soln
116 type(LinearExitSolutionType) :: exit_solutions(3)
117 type(LinearExitSolutionType) :: exit_x, exit_y, exit_z
123 call find_exits(particle, subcell, exit_solutions, x0, y0, z0)
124 exit_x = exit_solutions(1)
125 exit_y = exit_solutions(2)
126 exit_z = exit_solutions(3)
129 exit_soln = pick_exit(exit_solutions)
130 if (exit_soln == 0)
then
134 exit_face = exit_solutions(exit_soln)%iboundary
135 dtexit = exit_solutions(exit_soln)%dt
137 texit = particle%ttrack + dtexit
150 if (all([exit_solutions%status] >= no_exit_stationary))
then
159 call this%tracktimes%advance()
160 if (this%tracktimes%any())
then
161 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
162 t = this%tracktimes%times(i)
163 if (t < particle%ttrack) cycle
164 if (t > texit .or. t > tmax)
exit
166 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
167 dt, x0, subcell%dx, exit_x%status == 1)
168 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
169 dt, y0, subcell%dy, exit_y%status == 1)
170 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
171 dt, z0, subcell%dz, exit_z%status == 1)
172 particle%x = x * subcell%dx
173 particle%y = y * subcell%dy
174 particle%z = z * subcell%dz
177 call this%usertime(particle)
183 if (texit .gt. tmax)
then
186 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
187 dt, x0, subcell%dx, exit_x%status == 1)
188 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
189 dt, y0, subcell%dy, exit_y%status == 1)
190 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
191 dt, z0, subcell%dz, exit_z%status == 1)
194 particle%advancing = .false.
195 particle%x = x * subcell%dx
196 particle%y = y * subcell%dy
197 particle%z = z * subcell%dz
199 particle%iboundary(level_subfeature) = exit_face
200 call this%timestep(particle)
209 if ((exit_face .eq. 1) .or. (exit_face .eq. 2))
then
211 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
212 dt, y0, subcell%dy, exit_y%status == 1)
213 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
214 dt, z0, subcell%dz, exit_z%status == 1)
215 if (exit_face .eq. 2) x = done
216 else if ((exit_face .eq. 3) .or. (exit_face .eq. 4))
then
217 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, dt, &
218 x0, subcell%dx, exit_x%status == 1)
220 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, dt, &
221 z0, subcell%dz, exit_z%status == 1)
222 if (exit_face .eq. 4) y = done
223 else if ((exit_face .eq. 5) .or. (exit_face .eq. 6))
then
224 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
225 dt, x0, subcell%dx, exit_x%status == 1)
226 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
227 dt, y0, subcell%dy, exit_y%status == 1)
229 if (exit_face .eq. 6) z = done
231 print *,
"programmer error, invalid exit face", exit_face
234 particle%x = x * subcell%dx
235 particle%y = y * subcell%dy
236 particle%z = z * subcell%dz
238 particle%iboundary(level_subfeature) = exit_face
239 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