MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
methodcellpollockquadmodule Module Reference

Data Types

type  methodcellpollockquadtype
 

Functions/Subroutines

procedure subroutine, public create_method_cell_quad (method)
 Create a new tracking method. More...
 
subroutine destroy (this)
 Destroy the tracking method. More...
 
subroutine load_mcpq (this, particle, next_level, submethod)
 Load subcell into tracking method. More...
 
subroutine pass_mcpq (this, particle)
 Pass particle to next subcell if there is one, or to the cell face. More...
 
subroutine apply_mcpq (this, particle, tmax)
 Solve the quad-rectangular cell via Pollock's method. More...
 
subroutine load_subcell (this, particle, subcell)
 Load the rectangular subcell from the rectangular cell. More...
 

Function/Subroutine Documentation

◆ apply_mcpq()

subroutine methodcellpollockquadmodule::apply_mcpq ( class(methodcellpollockquadtype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
real(dp), intent(in)  tmax 
)
private

Definition at line 199 of file MethodCellPollockQuad.f90.

200  ! -- dummy
201  class(MethodCellPollockQuadType), intent(inout) :: this
202  type(ParticleType), pointer, intent(inout) :: particle
203  real(DP), intent(in) :: tmax
204  ! -- local
205  double precision :: xOrigin, yOrigin, zOrigin, sinrot, cosrot
206 
207  select type (cell => this%cell)
208  type is (cellrectquadtype)
209  ! -- Update particle state, terminate early if done advancing
210  call this%update(particle, cell%defn)
211  if (.not. particle%advancing) return
212 
213  ! -- If the particle is above the top of the cell (which is presumed to
214  ! -- represent a water table above the cell bottom), pass the particle
215  ! -- vertically and instantaneously to the cell top elevation and save
216  ! -- the particle state to output file(s).
217  if (particle%z > cell%defn%top) then
218  particle%z = cell%defn%top
219  call this%save(particle, reason=1) ! reason=1: cell transition
220  end if
221 
222  ! -- Transform particle location into local cell coordinates,
223  ! translated and rotated but not scaled relative to model.
224  ! Then track particle, transform back to model coordinates,
225  ! and reset transformation (drop accumulated roundoff error)
226  xorigin = cell%xOrigin
227  yorigin = cell%yOrigin
228  zorigin = cell%zOrigin
229  sinrot = cell%sinrot
230  cosrot = cell%cosrot
231  call particle%transform(xorigin, yorigin, zorigin, &
232  sinrot, cosrot)
233  call this%track(particle, 2, tmax) ! kluge, hardwired to level 2
234  call particle%transform(xorigin, yorigin, zorigin, &
235  sinrot, cosrot, invert=.true.)
236  call particle%transform(reset=.true.)
237  end select

◆ create_method_cell_quad()

procedure subroutine, public methodcellpollockquadmodule::create_method_cell_quad ( type(methodcellpollockquadtype), pointer  method)

Definition at line 31 of file MethodCellPollockQuad.f90.

32  ! -- dummy
33  type(MethodCellPollockQuadType), pointer :: method
34  ! -- local
35  type(CellRectQuadType), pointer :: cell
36  type(SubcellRectType), pointer :: subcell
37 
38  allocate (method)
39  call create_cell_rect_quad(cell)
40  method%cell => cell
41  method%type => method%cell%type
42  method%delegates = .true.
43  call create_subcell_rect(subcell)
44  method%subcell => subcell
Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy()

subroutine methodcellpollockquadmodule::destroy ( class(methodcellpollockquadtype), intent(inout)  this)
private

Definition at line 48 of file MethodCellPollockQuad.f90.

49  class(MethodCellPollockQuadType), intent(inout) :: this
50  deallocate (this%type)

◆ load_mcpq()

subroutine methodcellpollockquadmodule::load_mcpq ( class(methodcellpollockquadtype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
integer, intent(in)  next_level,
class(methodtype), intent(inout), pointer  submethod 
)
private

Definition at line 54 of file MethodCellPollockQuad.f90.

55  class(MethodCellPollockQuadType), intent(inout) :: this
56  type(ParticleType), pointer, intent(inout) :: particle
57  integer, intent(in) :: next_level
58  class(MethodType), pointer, intent(inout) :: submethod
59 
60  select type (subcell => this%subcell)
61  type is (subcellrecttype)
62  call this%load_subcell(particle, subcell)
63  end select
64  call method_subcell_plck%init( &
65  cell=this%cell, &
66  subcell=this%subcell, &
67  trackfilectl=this%trackfilectl, &
68  tracktimes=this%tracktimes)
69  submethod => method_subcell_plck

◆ load_subcell()

subroutine methodcellpollockquadmodule::load_subcell ( class(methodcellpollockquadtype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
class(subcellrecttype), intent(inout)  subcell 
)
private

Definition at line 241 of file MethodCellPollockQuad.f90.

242  ! -- dummy
243  class(MethodCellPollockQuadType), intent(inout) :: this
244  type(ParticleType), pointer, intent(inout) :: particle
245  class(SubcellRectType), intent(inout) :: subcell
246  ! -- local
247  double precision :: dx, dy, dz, areax, areay, areaz
248  double precision :: dxprel, dyprel
249  integer :: isc, npolyverts, m1, m2
250  double precision :: qextl1, qextl2, qintl1, qintl2
251  double precision :: factor, term
252 
253  select type (cell => this%cell)
254  type is (cellrectquadtype)
255  factor = done / cell%defn%retfactor
256  factor = factor / cell%defn%porosity
257  npolyverts = cell%defn%npolyverts
258 
259  isc = particle%idomain(3)
260  ! -- Subcells 1, 2, 3, and 4 are Pollock's subcells A, B, C, and D,
261  ! -- respectively
262 
263  dx = cell%dx
264  dy = cell%dy
265  ! -- If not already known, determine subcell number
266  if (isc .le. 0) then
267  dxprel = particle%x / dx
268  dyprel = particle%y / dy
269  if (dxprel .lt. 5d-1) then
270  if (dyprel .lt. 5d-1) then
271  isc = 3
272  else if (dyprel .gt. 5d-1) then
273  isc = 4
274  else
275  ! kluge note: need to resolve this ambiguity based on flow direction
276  call pstop(1, "particle initially on shared subcell edge")
277  end if
278  else if (dxprel .gt. 5d-1) then
279  if (dyprel .lt. 5d-1) then
280  isc = 2
281  else if (dyprel .gt. 5d-1) then
282  isc = 1
283  else
284  ! kluge note: need to resolve this ambiguity based on flow direction
285  call pstop(1, "particle initially on shared subcell edge")
286  end if
287  else
288  ! kluge note: need to resolve this ambiguity based on flow direction
289  call pstop(1, "particle initially on shared subcell edge")
290  end if
291  subcell%isubcell = isc
292  ! kluge note: as a matter of form, do we want to allow
293  ! this subroutine to modify the particle???
294  particle%idomain(3) = isc
295  ! kluge note: initial insubface is not currently being determined
296  end if
297  dx = 5d-1 * dx
298  dy = 5d-1 * dy
299  dz = cell%defn%top - &
300  cell%defn%bot ! kluge note: need to account for partial saturation
301  areax = dy * dz
302  areay = dx * dz
303  areaz = dx * dy
304  qintl1 = cell%qintl(isc)
305  ! qintl list wraps around, so isc+1=5 is ok
306  qintl2 = cell%qintl(isc + 1)
307  qextl1 = cell%qextl1(isc)
308  qextl2 = cell%qextl2(isc)
309  !
310  subcell%dx = dx
311  subcell%dy = dy
312  subcell%dz = dz
313  subcell%sinrot = 0d0
314  subcell%cosrot = 1d0
315  subcell%zOrigin = 0d0
316  select case (isc)
317  case (1)
318  subcell%xOrigin = dx
319  subcell%yOrigin = dy
320  term = factor / areax
321  subcell%vx1 = qintl1 * term
322  subcell%vx2 = -qextl2 * term
323  term = factor / areay
324  subcell%vy1 = -qintl2 * term
325  subcell%vy2 = -qextl1 * term
326  case (2)
327  subcell%xOrigin = dx
328  subcell%yOrigin = 0d0
329  term = factor / areax
330  subcell%vx1 = -qintl2 * term
331  subcell%vx2 = -qextl1 * term
332  term = factor / areay
333  subcell%vy1 = qextl2 * term
334  subcell%vy2 = -qintl1 * term
335  case (3)
336  subcell%xOrigin = 0d0
337  subcell%yOrigin = 0d0
338  term = factor / areax
339  subcell%vx1 = qextl2 * term
340  subcell%vx2 = -qintl1 * term
341  term = factor / areay
342  subcell%vy1 = qextl1 * term
343  subcell%vy2 = qintl2 * term
344  case (4)
345  subcell%xOrigin = 0d0
346  subcell%yOrigin = dy
347  term = factor / areax
348  subcell%vx1 = qextl1 * term
349  subcell%vx2 = qintl2 * term
350  term = factor / areay
351  subcell%vy1 = qintl1 * term
352  subcell%vy2 = -qextl2 * term
353  end select
354  m1 = npolyverts + 2
355  m2 = m1 + 1
356  term = factor / areaz
357  subcell%vz1 = 2.5d-1 * cell%defn%faceflow(m1) * term
358  subcell%vz2 = -2.5d-1 * cell%defn%faceflow(m2) * term
359  end select
Here is the call graph for this function:

◆ pass_mcpq()

subroutine methodcellpollockquadmodule::pass_mcpq ( class(methodcellpollockquadtype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle 
)
private

Definition at line 73 of file MethodCellPollockQuad.f90.

74  ! -- dummy
75  class(MethodCellPollockQuadType), intent(inout) :: this
76  type(ParticleType), pointer, intent(inout) :: particle
77  ! -- local
78  integer :: isc, exitFace, npolyverts, inface, infaceoff
79 
80  select type (cell => this%cell)
81  type is (cellrectquadtype)
82  exitface = particle%iboundary(3)
83  isc = particle%idomain(3)
84  npolyverts = cell%defn%npolyverts
85 
86  select case (exitface) ! kluge note: exitFace uses Dave's iface convention
87  case (0)
88  ! -- Subcell interior (cell interior)
89  inface = -1
90  case (1)
91  select case (isc)
92  case (1)
93  ! -- W face, subcell 1 --> E face, subcell 4 (cell interior)
94  particle%idomain(3) = 4
95  particle%iboundary(3) = 2
96  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
97  case (2)
98  ! -- W face, subcell 2 --> E face, subcell 3 (cell interior)
99  particle%idomain(3) = 3
100  particle%iboundary(3) = 2
101  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
102  case (3)
103  ! -- W face, subcell 3 (cell face)
104  inface = 1 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
105  infaceoff = 0
106  case (4)
107  ! -- W face, subcell 4 (cell face)
108  inface = 2 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
109  infaceoff = -1
110  end select
111  case (2)
112  select case (isc)
113  case (1)
114  ! -- E face, subcell 1 (cell face)
115  inface = 3 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
116  infaceoff = 0
117  case (2)
118  ! -- E face, subcell 2 (cell face)
119  inface = 4 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
120  infaceoff = -1
121  case (3)
122  ! -- E face, subcell 3 --> W face, subcell 2 (cell interior)
123  particle%idomain(3) = 2
124  particle%iboundary(3) = 1
125  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
126  case (4)
127  ! -- E face, subcell 4 --> W face subcell 1 (cell interior)
128  particle%idomain(3) = 1
129  particle%iboundary(3) = 1
130  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
131  end select
132  case (3)
133  select case (isc)
134  case (1)
135  ! -- S face, subcell 1 --> N face, subcell 2 (cell interior)
136  particle%idomain(3) = 2
137  particle%iboundary(3) = 4
138  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
139  case (2)
140  ! -- S face, subcell 2 (cell face)
141  inface = 4 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
142  infaceoff = 0
143  case (3)
144  ! -- S face, subcell 3 (cell face)
145  inface = 1 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
146  infaceoff = -1
147  case (4)
148  ! -- S face, subcell 4 --> N face, subcell 3 (cell interior)
149  particle%idomain(3) = 3
150  particle%iboundary(3) = 4
151  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
152  end select
153  case (4)
154  select case (isc)
155  case (1)
156  ! -- N face, subcell 1 (cell face)
157  inface = 3 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
158  infaceoff = -1
159  case (2)
160  ! -- N face, subcell 2 --> S face, subcell 1 (cell interior)
161  particle%idomain(3) = 1
162  particle%iboundary(3) = 3
163  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
164  case (3)
165  ! -- N face, subcell 3 --> S face, subcell 4 (cell interior)
166  particle%idomain(3) = 4
167  particle%iboundary(3) = 3
168  inface = 0 ! kluge note: want Domain(2) unchanged; Boundary(2) = 0
169  case (4)
170  ! -- N face, subcell 4 (cell face)
171  inface = 2 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
172  infaceoff = 0
173  end select
174  case (5)
175  ! -- Subcell bottom (cell bottom)
176  inface = npolyverts + 2 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
177  case (6)
178  ! -- Subcell top (cell top)
179  inface = npolyverts + 3 ! kluge note: want Domain(2) = -Domain(2); Boundary(2) = inface
180  end select
181  if (inface .eq. -1) then
182  particle%iboundary(2) = 0
183  else if (inface .eq. 0) then
184  particle%iboundary(2) = 0
185  else
186  if ((inface .ge. 1) .and. (inface .le. 4)) then
187  ! -- Account for local cell rotation
188  inface = inface + cell%irvOrigin - 1
189  if (inface .gt. 4) inface = inface - 4
190  inface = cell%irectvert(inface) + infaceoff
191  if (inface .lt. 1) inface = inface + npolyverts
192  end if
193  particle%iboundary(2) = inface
194  end if
195  end select