MODFLOW 6  version 6.7.0.dev2
USGS Modular Hydrologic Model
ParticleEvents.f90
Go to the documentation of this file.
2  use kindmodule, only: dp, i4b, lgp
11  implicit none
12 
13  private
14 
15  type, public, abstract :: particleeventconsumertype
16  contains
17  procedure(handle_event), deferred :: handle_event
19 
21  class(particleeventconsumertype), pointer :: consumer => null()
22  contains
23  procedure, public :: subscribe
24  procedure, public :: unsubscribe
25  procedure :: dispatch
26  procedure :: destroy
27  ! particle events
28  procedure, public :: release
29  procedure, public :: cellexit
30  procedure, public :: timestep
31  procedure, public :: terminate
32  procedure, public :: weaksink
33  procedure, public :: usertime
35 
36  abstract interface
37  subroutine handle_event(this, particle, event)
39  class(particleeventconsumertype), intent(inout) :: this
40  type(particletype), pointer, intent(in) :: particle
41  class(particleeventtype), pointer, intent(in) :: event
42  end subroutine handle_event
43  end interface
44 
45 contains
46  !> @brief Subscribe a consumer to the dispatcher.
47  subroutine subscribe(this, consumer)
48  class(particleeventdispatchertype), intent(inout) :: this
49  class(particleeventconsumertype), target, intent(inout) :: consumer
50  this%consumer => consumer
51  end subroutine subscribe
52 
53  !> @brief Unsubscribe the consumer from the dispatcher.
54  subroutine unsubscribe(this)
55  class(particleeventdispatchertype), intent(inout) :: this
56  if (associated(this%consumer)) then
57  deallocate (this%consumer)
58  this%consumer => null()
59  end if
60  end subroutine unsubscribe
61 
62  !> @brief Dispatch an event. Internal use only.
63  subroutine dispatch(this, particle, event)
64  use tdismodule, only: kper, kstp, totimc
65  ! dummy
66  class(particleeventdispatchertype), intent(inout) :: this
67  type(particletype), pointer, intent(inout) :: particle
68  class(particleeventtype), pointer, intent(inout) :: event
69  ! local
70  integer(I4B) :: per, stp
71 
72  per = kper
73  stp = kstp
74 
75  ! If tracking time falls exactly on a boundary between time steps,
76  ! report the previous time step for this datum. This is to follow
77  ! MP7's behavior, and because the particle will have been tracked
78  ! up to this instant under the previous time step's conditions, so
79  ! the time step we're about to start shouldn't get "credit" for it.
80  if (particle%ttrack == totimc .and. (per > 1 .or. stp > 1)) then
81  if (stp > 1) then
82  stp = stp - 1
83  else if (per > 1) then
84  per = per - 1
85  stp = 1
86  end if
87  end if
88 
89  event%particle => particle
90  event%time = particle%ttrack
91  event%kper = per
92  event%kstp = stp
93  call this%consumer%handle_event(particle, event)
94  deallocate (event)
95  end subroutine dispatch
96 
97  !> @brief Destroy the dispatcher.
98  subroutine destroy(this)
99  class(particleeventdispatchertype), intent(inout) :: this
100  if (associated(this%consumer)) &
101  deallocate (this%consumer)
102  end subroutine destroy
103 
104  !> @brief Particle is released.
105  subroutine release(this, particle)
106  class(particleeventdispatchertype), intent(inout) :: this
107  type(particletype), pointer, intent(inout) :: particle
108  class(particleeventtype), pointer :: event
109 
110  allocate (releaseeventtype :: event)
111  call this%dispatch(particle, event)
112  end subroutine release
113 
114  !> @brief Particle exits a cell.
115  subroutine cellexit(this, particle)
116  class(particleeventdispatchertype), intent(inout) :: this
117  type(particletype), pointer, intent(inout) :: particle
118  class(particleeventtype), pointer :: event
119 
120  allocate (cellexiteventtype :: event)
121  call this%dispatch(particle, event)
122  end subroutine cellexit
123 
124  !> @brief Particle terminates.
125  subroutine terminate(this, particle, status)
126  class(particleeventdispatchertype), intent(inout) :: this
127  type(particletype), pointer, intent(inout) :: particle
128  integer(I4B), intent(in), optional :: status
129  class(particleeventtype), pointer :: event
130 
131  particle%advancing = .false.
132  if (present(status)) particle%istatus = status
133  allocate (terminationeventtype :: event)
134  call this%dispatch(particle, event)
135  end subroutine terminate
136 
137  !> @brief Time step ends.
138  subroutine timestep(this, particle)
139  class(particleeventdispatchertype), intent(inout) :: this
140  type(particletype), pointer, intent(inout) :: particle
141  class(particleeventtype), pointer :: event
142 
143  allocate (timestepeventtype :: event)
144  call this%dispatch(particle, event)
145  end subroutine timestep
146 
147  !> @brief Particle leaves a weak sink.
148  subroutine weaksink(this, particle)
149  class(particleeventdispatchertype), intent(inout) :: this
150  type(particletype), pointer, intent(inout) :: particle
151  class(particleeventtype), pointer :: event
152 
153  allocate (weaksinkeventtype :: event)
154  call this%dispatch(particle, event)
155  end subroutine weaksink
156 
157  !> @brief User-defined tracking time occurs.
158  subroutine usertime(this, particle)
159  class(particleeventdispatchertype), intent(inout) :: this
160  type(particletype), pointer, intent(inout) :: particle
161  class(particleeventtype), pointer :: event
162 
163  allocate (usertimeeventtype :: event)
164  call this%dispatch(particle, event)
165  end subroutine usertime
166 
167 end module particleeventsmodule
This module defines variable data types.
Definition: kind.f90:8
subroutine usertime(this, particle)
User-defined tracking time occurs.
subroutine weaksink(this, particle)
Particle leaves a weak sink.
subroutine subscribe(this, consumer)
Subscribe a consumer to the dispatcher.
subroutine unsubscribe(this)
Unsubscribe the consumer from the dispatcher.
subroutine terminate(this, particle, status)
Particle terminates.
subroutine release(this, particle)
Particle is released.
subroutine cellexit(this, particle)
Particle exits a cell.
subroutine dispatch(this, particle, event)
Dispatch an event. Internal use only.
subroutine timestep(this, particle)
Time step ends.
subroutine destroy(this)
Destroy the dispatcher.
real(dp), pointer, public totimc
simulation time at start of time step
Definition: tdis.f90:33
integer(i4b), pointer, public kstp
current time step number
Definition: tdis.f90:24
integer(i4b), pointer, public kper
current stress period number
Definition: tdis.f90:23
Base type for particle events.
Particle tracked by the PRT model.
Definition: Particle.f90:59