MODFLOW 6  version 6.8.0.dev0
USGS Modular Hydrologic Model
MethodCellPollock.f90
Go to the documentation of this file.
2 
3  use kindmodule, only: dp, i4b
4  use constantsmodule, only: done, dzero
11  use particlemodule, only: particletype
12  implicit none
13 
14  private
15  public :: methodcellpollocktype
17 
19  type(methodsubcellpollocktype), pointer :: method_subcell_plck => null()
20  contains
21  procedure, public :: apply => apply_mcp
22  procedure, public :: deallocate => destroy_mcp
23  procedure, public :: load => load_mcp
24  procedure, public :: load_subcell
25  procedure, public :: pass => pass_mcp
26  end type methodcellpollocktype
27 
28 contains
29 
30  !> @brief Create a tracking method
31  subroutine create_method_cell_pollock(method)
32  ! dummy
33  type(methodcellpollocktype), pointer :: method
34  ! local
35  type(cellrecttype), pointer :: cell
36  type(subcellrecttype), pointer :: subcell
37 
38  allocate (method)
39  call create_cell_rect(cell)
40  method%cell => cell
41  method%name => method%cell%type
42  method%delegates = .true.
43  call create_subcell_rect(subcell)
44  method%subcell => subcell
45 
46  ! Create subcell method this method can delegate to
47  call create_method_subcell_pollock(method%method_subcell_plck)
48  end subroutine create_method_cell_pollock
49 
50  !> @brief Destroy the tracking method
51  subroutine destroy_mcp(this)
52  class(methodcellpollocktype), intent(inout) :: this
53  deallocate (this%name)
54 
55  ! Deallocate owned subcell method
56  call this%method_subcell_plck%deallocate()
57  deallocate (this%method_subcell_plck)
58  end subroutine destroy_mcp
59 
60  !> @brief Load subcell tracking method
61  subroutine load_mcp(this, particle, next_level, submethod)
62  ! modules
63  use subcellmodule, only: subcelltype
64  ! dummy
65  class(methodcellpollocktype), intent(inout) :: this
66  type(particletype), pointer, intent(inout) :: particle
67  integer, intent(in) :: next_level
68  class(methodtype), pointer, intent(inout) :: submethod
69 
70  select type (subcell => this%subcell)
71  type is (subcellrecttype)
72  call this%load_subcell(particle, subcell)
73  end select
74  call this%method_subcell_plck%init( &
75  fmi=this%fmi, &
76  cell=this%cell, &
77  subcell=this%subcell, &
78  events=this%events, &
79  tracktimes=this%tracktimes)
80  submethod => this%method_subcell_plck
81  particle%itrdomain(next_level) = 1
82  end subroutine load_mcp
83 
84  !> @brief Having exited the lone subcell, pass the particle to the cell face
85  !! In this case the lone subcell is the cell.
86  subroutine pass_mcp(this, particle)
87  ! dummy
88  class(methodcellpollocktype), intent(inout) :: this
89  type(particletype), pointer, intent(inout) :: particle
90  ! local
91  integer(I4B) :: exitface
92  integer(I4B) :: entryface
93 
94  exitface = particle%iboundary(level_subfeature)
95  ! Map subcell exit face to cell face
96  select case (exitface) ! note: exitFace uses Dave's iface convention
97  case (0)
98  entryface = -1
99  case (1)
100  entryface = 1
101  case (2)
102  entryface = 3
103  case (3)
104  entryface = 4
105  case (4)
106  entryface = 2
107  case (5)
108  entryface = 6 ! note: inface=5 same as inface=1 due to wraparound
109  case (6)
110  entryface = 7
111  end select
112  if (entryface .eq. -1) then
113  particle%iboundary(level_feature) = 0
114  else
115  if ((entryface .ge. 1) .and. (entryface .le. 4)) then
116  ! Account for local cell rotation
117  select type (cell => this%cell)
118  type is (cellrecttype)
119  entryface = entryface + cell%ipvOrigin - 1
120  end select
121  if (entryface .gt. 4) entryface = entryface - 4
122  end if
123  particle%iboundary(level_feature) = entryface
124  end if
125  end subroutine pass_mcp
126 
127  !> @brief Apply Pollock's method to a rectangular cell
128  subroutine apply_mcp(this, particle, tmax)
129  ! dummy
130  class(methodcellpollocktype), intent(inout) :: this
131  type(particletype), pointer, intent(inout) :: particle
132  real(DP), intent(in) :: tmax
133  ! local
134  real(DP) :: xOrigin
135  real(DP) :: yOrigin
136  real(DP) :: zOrigin
137  real(DP) :: sinrot
138  real(DP) :: cosrot
139 
140  select type (cell => this%cell)
141  type is (cellrecttype)
142  call this%assess(particle, this%cell%defn, tmax)
143  if (.not. particle%advancing) return
144 
145  ! Transform model coordinates to local cell coordinates
146  ! (translated/rotated but not scaled relative to model),
147  ! track the particle over the cell, then transform back.
148  xorigin = cell%xOrigin
149  yorigin = cell%yOrigin
150  zorigin = cell%zOrigin
151  sinrot = cell%sinrot
152  cosrot = cell%cosrot
153  call particle%transform(xorigin, yorigin, zorigin, &
154  sinrot, cosrot)
155  call this%track(particle, 2, tmax)
156  call particle%transform(xorigin, yorigin, zorigin, &
157  sinrot, cosrot, invert=.true.)
158  call particle%reset_transform()
159  end select
160  end subroutine apply_mcp
161 
162  !> @brief Loads the lone rectangular subcell from the rectangular cell
163  subroutine load_subcell(this, particle, subcell) !
164  ! dummy
165  class(methodcellpollocktype), intent(inout) :: this
166  type(particletype), pointer, intent(inout) :: particle
167  type(subcellrecttype), intent(inout) :: subcell
168 
169  select type (cell => this%cell)
170  type is (cellrecttype)
171  ! Set cell/subcell numbers
172  subcell%icell = cell%defn%icell
173  subcell%isubcell = 1
174 
175  ! Subcell calculations will be done in local subcell coordinates
176  subcell%dx = cell%dx
177  subcell%dy = cell%dy
178  subcell%dz = cell%dz
179  subcell%sinrot = dzero
180  subcell%cosrot = done
181  subcell%xOrigin = dzero
182  subcell%yOrigin = dzero
183  subcell%zOrigin = dzero
184 
185  ! Set subcell edge velocities
186  subcell%vx1 = cell%vx1 ! cell velocities already account for retfactor and porosity
187  subcell%vx2 = cell%vx2
188  subcell%vy1 = cell%vy1
189  subcell%vy2 = cell%vy2
190  subcell%vz1 = cell%vz1
191  subcell%vz2 = cell%vz2
192  end select
193  end subroutine load_subcell
194 
195 end module methodcellpollockmodule
subroutine, public create_cell_rect(cell)
Create a new rectangular cell.
Definition: CellRect.f90:40
This module contains simulation constants.
Definition: Constants.f90:9
real(dp), parameter dzero
real constant zero
Definition: Constants.f90:65
real(dp), parameter done
real constant 1
Definition: Constants.f90:76
This module defines variable data types.
Definition: kind.f90:8
subroutine pass_mcp(this, particle)
Having exited the lone subcell, pass the particle to the cell face In this case the lone subcell is t...
procedure subroutine, public create_method_cell_pollock(method)
Create a tracking method.
subroutine load_subcell(this, particle, subcell)
Loads the lone rectangular subcell from the rectangular cell.
subroutine destroy_mcp(this)
Destroy the tracking method.
subroutine load_mcp(this, particle, next_level, submethod)
Load subcell tracking method.
subroutine apply_mcp(this, particle, tmax)
Apply Pollock's method to a rectangular cell.
Particle tracking strategies.
Definition: Method.f90:2
@, public level_feature
Definition: Method.f90:41
@, public level_subfeature
Definition: Method.f90:42
subroutine, public create_method_subcell_pollock(method)
Create a new Pollock's subcell method.
subroutine, public create_subcell_rect(subcell)
Create a new rectangular subcell.
Definition: SubcellRect.f90:28
Base type for particle tracking methods.
Definition: Method.f90:58
Particle tracked by the PRT model.
Definition: Particle.f90:62
A subcell of a cell.
Definition: Subcell.f90:10