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.
101 class(MethodSubcellPollockType),
intent(inout) :: this
102 class(SubcellRectType),
intent(in) :: subcell
103 type(ParticleType),
pointer,
intent(inout) :: particle
104 real(DP),
intent(in) :: tmax
106 real(DP) :: dt, dtexit, texit
107 real(DP) :: t, x, y, z
108 real(DP) :: t0, x0, y0, z0
109 integer(I4B) :: i, exit_face, exit_soln
110 type(LinearExitSolutionType) :: exit_x, exit_y, exit_z
113 x0 = particle%x / subcell%dx
114 y0 = particle%y / subcell%dy
115 z0 = particle%z / subcell%dz
118 call this%find_exits(particle, subcell)
119 exit_x = this%exit_solutions(1)
120 exit_y = this%exit_solutions(2)
121 exit_z = this%exit_solutions(3)
124 exit_soln = this%pick_exit(particle)
125 if (exit_soln == 0)
then
129 exit_face = this%exit_solutions(exit_soln)%iboundary
130 dtexit = this%exit_solutions(exit_soln)%dt
132 texit = particle%ttrack + dtexit
145 if (all([this%exit_solutions%status] >= no_exit_stationary))
then
154 call this%tracktimes%advance()
155 if (this%tracktimes%any())
then
156 do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
157 t = this%tracktimes%times(i)
158 if (t < particle%ttrack) cycle
159 if (t > texit .or. t > tmax)
exit
161 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
162 dt, x0, subcell%dx, exit_x%status == 1)
163 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
164 dt, y0, subcell%dy, exit_y%status == 1)
165 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
166 dt, z0, subcell%dz, exit_z%status == 1)
167 particle%x = x * subcell%dx
168 particle%y = y * subcell%dy
169 particle%z = z * subcell%dz
172 call this%usertime(particle)
178 if (texit .gt. tmax)
then
181 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
182 dt, x0, subcell%dx, exit_x%status == 1)
183 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
184 dt, y0, subcell%dy, exit_y%status == 1)
185 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
186 dt, z0, subcell%dz, exit_z%status == 1)
189 particle%advancing = .false.
190 particle%x = x * subcell%dx
191 particle%y = y * subcell%dy
192 particle%z = z * subcell%dz
194 particle%iboundary(level_subfeature) = exit_face
195 call this%timestep(particle)
204 if ((exit_face .eq. 1) .or. (exit_face .eq. 2))
then
206 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
207 dt, y0, subcell%dy, exit_y%status == 1)
208 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, &
209 dt, z0, subcell%dz, exit_z%status == 1)
210 if (exit_face .eq. 2) x = done
211 else if ((exit_face .eq. 3) .or. (exit_face .eq. 4))
then
212 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, dt, &
213 x0, subcell%dx, exit_x%status == 1)
215 z = new_x(exit_z%v, exit_z%dvdx, subcell%vz1, subcell%vz2, dt, &
216 z0, subcell%dz, exit_z%status == 1)
217 if (exit_face .eq. 4) y = done
218 else if ((exit_face .eq. 5) .or. (exit_face .eq. 6))
then
219 x = new_x(exit_x%v, exit_x%dvdx, subcell%vx1, subcell%vx2, &
220 dt, x0, subcell%dx, exit_x%status == 1)
221 y = new_x(exit_y%v, exit_y%dvdx, subcell%vy1, subcell%vy2, &
222 dt, y0, subcell%dy, exit_y%status == 1)
224 if (exit_face .eq. 6) z = done
226 print *,
"programmer error, invalid exit face", exit_face
229 particle%x = x * subcell%dx
230 particle%y = y * subcell%dy
231 particle%z = z * subcell%dz
233 particle%iboundary(level_subfeature) = exit_face
234 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