MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
methodcellmodule Module Reference

Data Types

type  methodcelltype
 

Functions/Subroutines

subroutine try_pass (this, particle, nextlevel, advancing)
 Try passing the particle to the next subdomain. or to a boundary of this method's tracking domain. More...
 
subroutine assess (this, particle, cell_defn, tmax)
 Check reporting/terminating conditions before tracking the particle across the cell. More...
 
subroutine cellexit (this, particle)
 Particle exits a cell. More...
 
logical(lgp) function forms_cycle (this, particle, event)
 Check if the event forms a cycle in the particle path. More...
 
subroutine store_event (this, particle, event)
 Save the event in the particle's history. Acts like a queue, the oldest event is removed when the event count exceeds the maximum size. More...
 
integer(i4b) function get_level (this)
 Get the cell method's level. More...
 
integer(i4b) function iboundary_to_icellface (this, iboundary)
 Convert an iboundary number to an iface number. More...
 

Function/Subroutine Documentation

◆ assess()

subroutine methodcellmodule::assess ( class(methodcelltype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
type(celldefntype), intent(inout), pointer  cell_defn,
real(dp), intent(in)  tmax 
)
private

Check a number of conditions determining whether to continue tracking the particle or terminate it, as well as whether to record any output data as per selected reporting conditions.

Definition at line 78 of file MethodCell.f90.

79  ! modules
84  ! dummy
85  class(MethodCellType), intent(inout) :: this
86  type(ParticleType), pointer, intent(inout) :: particle
87  type(CellDefnType), pointer, intent(inout) :: cell_defn
88  real(DP), intent(in) :: tmax
89  ! local
90  logical(LGP) :: dry_cell, dry_particle, no_exit_face, stop_zone, weak_sink
91  integer(I4B) :: i
92  real(DP) :: t, ttrackmax
93 
94  dry_cell = cell_defn%isatstat == saturation_dry
95  dry_particle = particle%z > cell_defn%top
96  no_exit_face = cell_defn%inoexitface > 0
97  stop_zone = cell_defn%izone > 0 .and. particle%istopzone == cell_defn%izone
98  weak_sink = cell_defn%iweaksink > 0
99 
100  particle%izone = cell_defn%izone
101  if (stop_zone) then
102  call this%terminate(particle, status=term_stopzone)
103  return
104  end if
105 
106  if (no_exit_face .and. .not. dry_cell) then
107  call this%terminate(particle, status=term_no_exits)
108  return
109  end if
110 
111  if (weak_sink) then
112  if (particle%istopweaksink > 0) then
113  call this%terminate(particle, status=term_weaksink)
114  return
115  else
116  call this%weaksink(particle)
117  end if
118  end if
119 
120  if (dry_cell) then
121  if (particle%idrymeth == 0) then
122  ! drop to cell bottom. handled by pass
123  ! to bottom method, nothing to do here
124  no_exit_face = .false.
125  else if (particle%idrymeth == 1) then
126  ! stop
127  call this%terminate(particle, status=term_inactive)
128  return
129  else if (particle%idrymeth == 2) then
130  ! stay
131  particle%advancing = .false.
132  no_exit_face = .false.
133 
134  ! we might report tracking times
135  ! out of order here, but we want
136  ! the particle termination event
137  ! (if this is the last time step)
138  ! to have the maximum tracking t,
139  ! so we need to keep tabs on it.
140  ttrackmax = totim
141 
142  ! update tracking time to time
143  ! step end time and save record
144  particle%ttrack = totim
145  call this%timestep(particle)
146 
147  ! record user tracking times
148  call this%tracktimes%advance()
149  if (this%tracktimes%any()) then
150  do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
151  t = this%tracktimes%times(i)
152  if (t < totimc) cycle
153  if (t > tmax) exit
154  particle%ttrack = t
155  call this%usertime(particle)
156  if (t > ttrackmax) ttrackmax = t
157  end do
158  end if
159 
160  ! terminate if last period/step
161  if (endofsimulation) then
162  particle%ttrack = ttrackmax
163  call this%terminate(particle, status=term_no_exits)
164  return
165  end if
166  end if
167  else if (dry_particle .and. this%name /= "passtobottom") then
168  if (particle%idrymeth == 0) then
169  ! drop to water table
170  particle%z = cell_defn%top
171  call this%dropped(particle)
172  else if (particle%idrymeth == 1) then
173  ! stop
174  call this%terminate(particle, status=term_inactive)
175  return
176  else if (particle%idrymeth == 2) then
177  ! stay
178  particle%advancing = .false.
179  no_exit_face = .false.
180 
181  ! we might report tracking times
182  ! out of order here, but we want
183  ! the particle termination event
184  ! (if this is the last time step)
185  ! to have the maximum tracking t,
186  ! so we need to keep tabs on it.
187  ttrackmax = totim
188 
189  ! update tracking time to time
190  ! step end time and save record
191  particle%ttrack = totim
192  call this%timestep(particle)
193 
194  ! record user tracking times
195  call this%tracktimes%advance()
196  if (this%tracktimes%any()) then
197  do i = this%tracktimes%selection(1), this%tracktimes%selection(2)
198  t = this%tracktimes%times(i)
199  if (t < totimc) cycle
200  if (t > tmax) exit
201  particle%ttrack = t
202  call this%usertime(particle)
203  if (t > ttrackmax) ttrackmax = t
204  end do
205  end if
206  end if
207  end if
208 
209  if (no_exit_face) then
210  particle%advancing = .false.
211  particle%istatus = term_no_exits
212  call this%terminate(particle)
213  return
214  end if
215 
@, public weaksink
particle entered a weak sink
@, public usertime
user-specified tracking time
@, public terminate
particle terminated
@, public timestep
time step ended
@ term_weaksink
terminated in a weak sink cell
Definition: Particle.f90:32
@ term_inactive
terminated in an inactive cell
Definition: Particle.f90:35
@ term_no_exits
terminated in a cell with no exit face
Definition: Particle.f90:33
@ term_stopzone
terminated in a cell with a stop zone number
Definition: Particle.f90:34
logical(lgp), pointer, public endofsimulation
flag indicating end of simulation
Definition: tdis.f90:31
real(dp), pointer, public totim
time relative to start of simulation
Definition: tdis.f90:35
real(dp), pointer, public totimc
simulation time at start of time step
Definition: tdis.f90:36

◆ cellexit()

subroutine methodcellmodule::cellexit ( class(methodcelltype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle 
)

Definition at line 219 of file MethodCell.f90.

220  class(MethodCellType), intent(inout) :: this
221  type(ParticleType), pointer, intent(inout) :: particle
222  class(ParticleEventType), pointer :: event
223  ! local
224  integer(I4B) :: i, nhist
225  class(*), pointer :: prev
226 
227  allocate (cellexiteventtype :: event)
228  select type (event)
229  type is (cellexiteventtype)
230  event%exit_face = particle%iboundary(level_feature)
231  end select
232  call this%events%broadcast(particle, event)
233  if (particle%icycwin == 0) then
234  deallocate (event)
235  return
236  end if
237  if (this%forms_cycle(particle, event)) then
238  ! print event history
239  print *, "Cyclic pathline detected"
240  nhist = particle%history%Count()
241  do i = 1, nhist
242  prev => particle%history%GetItem(i)
243  select type (prev)
244  class is (particleeventtype)
245  print *, "Back ", nhist - i + 1, ": ", prev%get_text()
246  end select
247  end do
248  print *, "Current :", event%get_text()
249  call pstop(1, 'Cyclic pathline detected, aborting')
250  else
251  call this%store_event(particle, event)
252  end if
Here is the call graph for this function:

◆ forms_cycle()

logical(lgp) function methodcellmodule::forms_cycle ( class(methodcelltype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
class(particleeventtype), intent(in), pointer  event 
)
private

Definition at line 256 of file MethodCell.f90.

257  ! dummy
258  class(MethodCellType), intent(inout) :: this
259  type(ParticleType), pointer, intent(inout) :: particle
260  class(ParticleEventType), pointer, intent(in) :: event
261  ! local
262  class(IteratorType), allocatable :: itr
263  logical(LGP) :: found_cycle
264 
265  found_cycle = .false.
266  select type (event)
267  type is (cellexiteventtype)
268  itr = particle%history%Iterator()
269  do while (itr%has_next())
270  call itr%next()
271  select type (prev => itr%value())
272  class is (cellexiteventtype)
273  if (event%icu == prev%icu .and. &
274  event%ilay == prev%ilay .and. &
275  event%izone == prev%izone .and. &
276  event%exit_face == prev%exit_face .and. &
277  event%exit_face /= 0) then
278  found_cycle = .true.
279  exit
280  end if
281  end select
282  end do
283  type is (subcellexiteventtype)
284  itr = particle%history%Iterator()
285  do while (itr%has_next())
286  call itr%next()
287  select type (prev => itr%value())
288  class is (subcellexiteventtype)
289  if (event%icu == prev%icu .and. &
290  event%ilay == prev%ilay .and. &
291  event%isc == prev%isc .and. &
292  event%exit_face == prev%exit_face .and. &
293  event%exit_face /= 0) then
294  found_cycle = .true.
295  exit
296  end if
297  end select
298  end do
299  end select

◆ get_level()

integer(i4b) function methodcellmodule::get_level ( class(methodcelltype), intent(in)  this)
private

Definition at line 328 of file MethodCell.f90.

329  class(MethodCellType), intent(in) :: this
330  integer(I4B) :: level
331  level = level_feature

◆ iboundary_to_icellface()

integer(i4b) function methodcellmodule::iboundary_to_icellface ( class(methodcelltype), intent(inout)  this,
integer(i4b), intent(in)  iboundary 
)
private

Definition at line 335 of file MethodCell.f90.

336  class(MethodCellType), intent(inout) :: this
337  integer(I4B), intent(in) :: iboundary
338  integer(I4B) :: iface
339  integer(I4B) :: nfaces
340 
341  iface = iboundary
342  nfaces = this%cell%defn%npolyverts + 2
343  if (iface >= nfaces) &
344  ! uncompress and drop wraparound index
345  iface = iface + (this%fmi%max_faces - nfaces) - 1

◆ store_event()

subroutine methodcellmodule::store_event ( class(methodcelltype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
class(particleeventtype), intent(in), pointer  event 
)
private

Definition at line 305 of file MethodCell.f90.

306  ! dummy
307  class(MethodCellType), intent(inout) :: this
308  type(ParticleType), pointer, intent(inout) :: particle
309  class(ParticleEventType), pointer, intent(in) :: event
310  ! local
311  class(*), pointer :: p
312 
313  select type (event)
314  type is (cellexiteventtype)
315  p => event
316  call particle%history%Add(p)
317  if (particle%history%Count() > particle%icycwin) &
318  call particle%history%RemoveNode(1, .true.)
319  type is (subcellexiteventtype)
320  p => event
321  call particle%history%Add(p)
322  if (particle%history%Count() > particle%icycwin) &
323  call particle%history%RemoveNode(1, .true.)
324  end select

◆ try_pass()

subroutine methodcellmodule::try_pass ( class(methodcelltype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
integer(i4b)  nextlevel,
logical(lgp)  advancing 
)
private

If the particle is not advancing, or if it's not at a boundary, nothing happens. Otherwise, raise a cell exit event. Then, if at a net outflow boundary face, or top face of a partially saturated cell, terminate.

Definition at line 38 of file MethodCell.f90.

39  class(MethodCellType), intent(inout) :: this
40  type(ParticleType), pointer, intent(inout) :: particle
41  logical(LGP) :: advancing
42  integer(I4B) :: nextlevel
43  ! local
44  integer(I4B) :: ic, iboundary, icellface
45 
46  if (.not. particle%advancing) then
47  advancing = .false.
48  particle%iboundary = 0
49  return
50  end if
51 
52  call this%pass(particle)
53 
54  iboundary = particle%iboundary(level_feature)
55  icellface = this%iboundary_to_icellface(iboundary)
56  if (icellface <= 0) return
57 
58  ! on a cell face, done advancing. raise an exit event
59  advancing = .false.
60  call this%cellexit(particle)
61 
62  ! assigned boundary face with net outflow? terminate
63  ic = particle%itrdomain(level_feature)
64  if (this%fmi%is_net_out_boundary_face(ic, icellface)) then
65  call this%terminate(particle, status=term_boundary)
66  return
67  end if
68