MODFLOW 6  version 6.7.0.dev0
USGS Modular Hydrologic Model
methoddismodule Module Reference

Data Types

type  methoddistype
 

Functions/Subroutines

subroutine, public create_method_dis (method)
 Create a new structured grid (DIS) tracking method. More...
 
subroutine deallocate (this)
 Destructor the tracking method. More...
 
subroutine load_cell (this, ic, cell)
 
subroutine load_dis (this, particle, next_level, submethod)
 Load the cell geometry and tracking method. More...
 
subroutine load_particle (this, cell, particle)
 Load cell properties into the particle, including. More...
 
subroutine update_flowja (this, cell, particle)
 Update cell-cell flows of particle mass. Every particle is currently assigned unit mass. More...
 
subroutine pass_dis (this, particle)
 Pass a particle to the next cell, if there is one. More...
 
subroutine apply_dis (this, particle, tmax)
 Apply the structured tracking method to a particle. More...
 
double precision function get_top (this, iatop)
 Returns a top elevation based on index iatop. More...
 
subroutine load_celldefn (this, ic, defn)
 Loads cell definition from the grid. More...
 
subroutine load_properties (this, ic, defn)
 
subroutine load_neighbors (this, defn)
 Loads face neighbors to cell definition from the grid. Assumes cell index and number of vertices are already loaded. More...
 
subroutine load_flows (this, defn)
 Load flows into the cell definition. These include face, boundary and net distributed flows. Assumes cell index and number of vertices are already loaded. More...
 
subroutine load_face_flows_to_defn (this, defn)
 
subroutine load_boundary_flows_to_defn (this, defn)
 Add boundary flows to the cell definition faceflow array. Assumes cell index and number of vertices are already loaded. More...
 

Function/Subroutine Documentation

◆ apply_dis()

subroutine methoddismodule::apply_dis ( class(methoddistype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
real(dp), intent(in)  tmax 
)
private

Definition at line 314 of file MethodDis.f90.

315  class(MethodDisType), intent(inout) :: this
316  type(ParticleType), pointer, intent(inout) :: particle
317  real(DP), intent(in) :: tmax
318 
319  call this%track(particle, 1, tmax)

◆ create_method_dis()

subroutine, public methoddismodule::create_method_dis ( type(methoddistype), pointer  method)

Definition at line 43 of file MethodDis.f90.

44  ! dummy
45  type(MethodDisType), pointer :: method
46  ! local
47  type(CellRectType), pointer :: cell
48 
49  allocate (method)
50  allocate (method%name)
51  call create_cell_rect(cell)
52  method%cell => cell
53  method%name = "dis"
54  method%delegates = .true.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ deallocate()

subroutine methoddismodule::deallocate ( class(methoddistype), intent(inout)  this)
private

Definition at line 58 of file MethodDis.f90.

59  class(MethodDisType), intent(inout) :: this
60  deallocate (this%name)

◆ get_top()

double precision function methoddismodule::get_top ( class(methoddistype), intent(inout)  this,
integer, intent(in)  iatop 
)
private

Definition at line 323 of file MethodDis.f90.

324  class(MethodDisType), intent(inout) :: this
325  integer, intent(in) :: iatop
326  double precision :: top
327 
328  if (iatop .lt. 0) then
329  top = this%fmi%dis%top(-iatop)
330  else
331  top = this%fmi%dis%bot(iatop)
332  end if

◆ load_boundary_flows_to_defn()

subroutine methoddismodule::load_boundary_flows_to_defn ( class(methoddistype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 507 of file MethodDis.f90.

508  ! dummy
509  class(MethodDisType), intent(inout) :: this
510  type(CellDefnType), intent(inout) :: defn
511  ! local
512  integer(I4B) :: ioffset
513 
514  ioffset = (defn%icell - 1) * max_poly_cells
515  defn%faceflow(1) = defn%faceflow(1) + &
516  this%fmi%BoundaryFlows(ioffset + 1)
517  defn%faceflow(2) = defn%faceflow(2) + &
518  this%fmi%BoundaryFlows(ioffset + 2)
519  defn%faceflow(3) = defn%faceflow(3) + &
520  this%fmi%BoundaryFlows(ioffset + 3)
521  defn%faceflow(4) = defn%faceflow(4) + &
522  this%fmi%BoundaryFlows(ioffset + 4)
523  defn%faceflow(5) = defn%faceflow(1)
524  defn%faceflow(6) = defn%faceflow(6) + &
525  this%fmi%BoundaryFlows(ioffset + 9)
526  defn%faceflow(7) = defn%faceflow(7) + &
527  this%fmi%BoundaryFlows(ioffset + 10)

◆ load_cell()

subroutine methoddismodule::load_cell ( class(methoddistype), intent(inout)  this,
integer(i4b), intent(in)  ic,
type(cellrecttype), intent(inout)  cell 
)
private

Definition at line 63 of file MethodDis.f90.

64  ! dummy
65  class(MethodDisType), intent(inout) :: this
66  integer(I4B), intent(in) :: ic
67  type(CellRectType), intent(inout) :: cell
68  ! local
69  integer(I4B) :: icu
70  integer(I4B) :: irow
71  integer(I4B) :: jcol
72  integer(I4B) :: klay
73  real(DP) :: areax
74  real(DP) :: areay
75  real(DP) :: areaz
76  real(DP) :: dx
77  real(DP) :: dy
78  real(DP) :: dz
79  real(DP) :: factor
80  real(DP) :: term
81 
82  select type (dis => this%fmi%dis)
83  type is (distype)
84  icu = dis%get_nodeuser(ic)
85 
86  call get_ijk(icu, dis%nrow, dis%ncol, dis%nlay, &
87  irow, jcol, klay)
88 
89  dx = dis%delr(jcol)
90  dy = dis%delc(irow)
91  dz = cell%defn%top - cell%defn%bot
92 
93  cell%dx = dx
94  cell%dy = dy
95  cell%dz = dz
96  cell%sinrot = dzero
97  cell%cosrot = done
98  cell%xOrigin = cell%defn%polyvert(1, 1)
99  cell%yOrigin = cell%defn%polyvert(2, 1)
100  cell%zOrigin = cell%defn%bot
101  cell%ipvOrigin = 1
102 
103  factor = done / cell%defn%retfactor
104  factor = factor / cell%defn%porosity
105 
106  areaz = dx * dy
107  term = factor / areaz
108 
109  cell%vz1 = cell%defn%faceflow(6) * term
110  cell%vz2 = -cell%defn%faceflow(7) * term
111 
112  if (this%fmi%ibdgwfsat0(ic) == 0) then
113  cell%vx1 = dzero
114  cell%vx2 = dzero
115  cell%vy1 = dzero
116  cell%vy2 = dzero
117  cell%vz1 = dzero
118  cell%vz2 = dzero
119  return
120  end if
121 
122  areax = dy * dz
123  term = factor / areax
124  cell%vx1 = cell%defn%faceflow(1) * term
125  cell%vx2 = -cell%defn%faceflow(3) * term
126 
127  areay = dx * dz
128  term = factor / areay
129  cell%vy1 = cell%defn%faceflow(4) * term
130  cell%vy2 = -cell%defn%faceflow(2) * term
131 
132  end select
Here is the call graph for this function:

◆ load_celldefn()

subroutine methoddismodule::load_celldefn ( class(methoddistype), intent(inout)  this,
integer(i4b), intent(in)  ic,
type(celldefntype), intent(inout), pointer  defn 
)
private

Definition at line 336 of file MethodDis.f90.

337  ! dummy
338  class(MethodDisType), intent(inout) :: this
339  integer(I4B), intent(in) :: ic
340  type(CellDefnType), pointer, intent(inout) :: defn
341 
342  ! Load basic cell properties
343  call this%load_properties(ic, defn)
344 
345  ! Load cell polygon vertices
346  call this%fmi%dis%get_polyverts( &
347  defn%icell, &
348  defn%polyvert, &
349  closed=.true.)
350  call this%load_neighbors(defn)
351 
352  ! Load 180 degree face indicators
353  defn%ispv180(1:defn%npolyverts + 1) = .false.
354 
355  call this%load_flows(defn)
356 

◆ load_dis()

subroutine methoddismodule::load_dis ( class(methoddistype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
integer(i4b), intent(in)  next_level,
class(methodtype), intent(inout), pointer  submethod 
)
private

Definition at line 136 of file MethodDis.f90.

137  ! dummy
138  class(MethodDisType), intent(inout) :: this
139  type(ParticleType), pointer, intent(inout) :: particle
140  integer(I4B), intent(in) :: next_level
141  class(MethodType), pointer, intent(inout) :: submethod
142  ! local
143  integer(I4B) :: ic
144 
145  select type (cell => this%cell)
146  type is (cellrecttype)
147  ic = particle%idomain(next_level)
148  call this%load_celldefn(ic, cell%defn)
149  call this%load_cell(ic, cell)
150  if (this%fmi%ibdgwfsat0(ic) == 0) then
151  call method_cell_ptb%init( &
152  fmi=this%fmi, &
153  cell=this%cell, &
154  trackctl=this%trackctl, &
155  tracktimes=this%tracktimes)
156  submethod => method_cell_ptb
157  else
158  call method_cell_plck%init( &
159  fmi=this%fmi, &
160  cell=this%cell, &
161  trackctl=this%trackctl, &
162  tracktimes=this%tracktimes)
163  submethod => method_cell_plck
164  end if
165  end select

◆ load_face_flows_to_defn()

subroutine methoddismodule::load_face_flows_to_defn ( class(methoddistype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 486 of file MethodDis.f90.

487  ! dummy
488  class(MethodDisType), intent(inout) :: this
489  type(CellDefnType), intent(inout) :: defn
490  ! local
491  integer(I4B) :: m, n, nfaces
492  real(DP) :: q
493 
494  nfaces = defn%npolyverts + 3
495  do m = 1, nfaces
496  n = defn%facenbr(m)
497  if (n > 0) then
498  q = this%fmi%gwfflowja(this%fmi%dis%con%ia(defn%icell) + n)
499  defn%faceflow(m) = defn%faceflow(m) + q
500  end if
501  if (defn%faceflow(m) < dzero) defn%inoexitface = 0
502  end do

◆ load_flows()

subroutine methoddismodule::load_flows ( class(methoddistype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 460 of file MethodDis.f90.

461  class(MethodDisType), intent(inout) :: this
462  type(CellDefnType), intent(inout) :: defn
463 
464  ! Load face flows, including boundary flows. As with cell verts,
465  ! the face flow array wraps around. Top and bottom flows make up
466  ! the last two elements, respectively, for size npolyverts + 3.
467  ! If there is no flow through any face, set a no-exit-face flag.
468  defn%faceflow = dzero
469  defn%inoexitface = 1
470  call this%load_boundary_flows_to_defn(defn)
471  call this%load_face_flows_to_defn(defn)
472 
473  ! Add up net distributed flow
474  defn%distflow = this%fmi%SourceFlows(defn%icell) + &
475  this%fmi%SinkFlows(defn%icell) + &
476  this%fmi%StorageFlows(defn%icell)
477 
478  ! Set weak sink flag
479  if (this%fmi%SinkFlows(defn%icell) .ne. dzero) then
480  defn%iweaksink = 1
481  else
482  defn%iweaksink = 0
483  end if

◆ load_neighbors()

subroutine methoddismodule::load_neighbors ( class(methoddistype), intent(inout)  this,
type(celldefntype), intent(inout), pointer  defn 
)
private

Definition at line 391 of file MethodDis.f90.

392  ! dummy
393  class(MethodDisType), intent(inout) :: this
394  type(CellDefnType), pointer, intent(inout) :: defn
395  ! local
396  integer(I4B) :: ic1
397  integer(I4B) :: ic2
398  integer(I4B) :: icu1
399  integer(I4B) :: icu2
400  integer(I4B) :: j1
401  integer(I4B) :: iloc
402  integer(I4B) :: ipos
403  integer(I4B) :: irow1
404  integer(I4B) :: irow2
405  integer(I4B) :: jcol1
406  integer(I4B) :: jcol2
407  integer(I4B) :: klay1
408  integer(I4B) :: klay2
409  integer(I4B) :: iedgeface
410 
411  select type (dis => this%fmi%dis)
412  type is (distype)
413  ! Load face neighbors
414  defn%facenbr = 0
415  ic1 = defn%icell
416  icu1 = dis%get_nodeuser(ic1)
417  call get_ijk(icu1, dis%nrow, dis%ncol, dis%nlay, &
418  irow1, jcol1, klay1)
419  call get_jk(icu1, dis%get_ncpl(), dis%nlay, j1, klay1)
420  do iloc = 1, dis%con%ia(ic1 + 1) - dis%con%ia(ic1) - 1
421  ipos = dis%con%ia(ic1) + iloc
422  ! mask could become relevant if PRT uses interface model
423  if (dis%con%mask(ipos) == 0) cycle
424  ic2 = dis%con%ja(ipos)
425  icu2 = dis%get_nodeuser(ic2)
426  call get_ijk(icu2, dis%nrow, dis%ncol, dis%nlay, &
427  irow2, jcol2, klay2)
428  if (klay2 == klay1) then
429  ! Edge (polygon) face neighbor
430  if (irow2 > irow1) then
431  ! Neighbor to the S
432  iedgeface = 4
433  else if (jcol2 > jcol1) then
434  ! Neighbor to the E
435  iedgeface = 3
436  else if (irow2 < irow1) then
437  ! Neighbor to the N
438  iedgeface = 2
439  else
440  ! Neighbor to the W
441  iedgeface = 1
442  end if
443  defn%facenbr(iedgeface) = int(iloc, 1)
444  else if (klay2 > klay1) then
445  ! Bottom face neighbor
446  defn%facenbr(defn%npolyverts + 2) = int(iloc, 1)
447  else
448  ! Top face neighbor
449  defn%facenbr(defn%npolyverts + 3) = int(iloc, 1)
450  end if
451  end do
452  end select
453  ! List of edge (polygon) faces wraps around
454  defn%facenbr(defn%npolyverts + 1) = defn%facenbr(1)
Here is the call graph for this function:

◆ load_particle()

subroutine methoddismodule::load_particle ( class(methoddistype), intent(inout)  this,
type(cellrecttype), intent(inout), pointer  cell,
type(particletype), intent(inout), pointer  particle 
)
private

Definition at line 170 of file MethodDis.f90.

171  ! dummy
172  class(MethodDisType), intent(inout) :: this
173  type(CellRectType), pointer, intent(inout) :: cell
174  type(ParticleType), pointer, intent(inout) :: particle
175  ! local
176  integer(I4B) :: ic
177  integer(I4B) :: icu
178  integer(I4B) :: ilay
179  integer(I4B) :: irow
180  integer(I4B) :: icol
181  integer(I4B) :: inface
182  integer(I4B) :: idiag
183  integer(I4B) :: inbr
184  integer(I4B) :: ipos
185  real(DP) :: z
186  real(DP) :: zrel
187  real(DP) :: topfrom
188  real(DP) :: botfrom
189  real(DP) :: top
190  real(DP) :: bot
191  real(DP) :: sat
192 
193  select type (dis => this%fmi%dis)
194  type is (distype)
195  ! compute reduced/user node numbers and layer
196  inface = particle%iboundary(2)
197  inbr = cell%defn%facenbr(inface)
198  idiag = this%fmi%dis%con%ia(cell%defn%icell)
199  ipos = idiag + inbr
200  ic = dis%con%ja(ipos)
201  icu = dis%get_nodeuser(ic)
202  call get_ijk(icu, dis%nrow, dis%ncol, dis%nlay, &
203  irow, icol, ilay)
204 
205  ! if returning to a cell through the bottom
206  ! face after previously leaving it through
207  ! that same face, we've entered a cycle
208  ! as can occur e.g. in wells. terminate
209  ! in the previous cell.
210  if (ic == particle%icp .and. inface == 7 .and. ilay < particle%ilay) then
211  particle%advancing = .false.
212  particle%idomain(2) = particle%icp
213  particle%istatus = 2
214  particle%izone = particle%izp
215  call this%save(particle, reason=3)
216  return
217  else
218  particle%icp = particle%idomain(2)
219  particle%izp = particle%izone
220  end if
221 
222  ! update node numbers and layer
223  particle%idomain(2) = ic
224  particle%icu = icu
225  particle%ilay = ilay
226 
227  ! map/set particle entry face
228  if (inface .eq. 1) then
229  inface = 3
230  else if (inface .eq. 2) then
231  inface = 4
232  else if (inface .eq. 3) then
233  inface = 1
234  else if (inface .eq. 4) then
235  inface = 2
236  else if (inface .eq. 6) then
237  inface = 7
238  else if (inface .eq. 7) then
239  inface = 6
240  end if
241  particle%iboundary(2) = inface
242 
243  ! map z between cells
244  z = particle%z
245  if (inface < 5) then
246  topfrom = cell%defn%top
247  botfrom = cell%defn%bot
248  zrel = (z - botfrom) / (topfrom - botfrom)
249  top = dis%top(ic)
250  bot = dis%bot(ic)
251  sat = this%fmi%gwfsat(ic)
252  z = bot + zrel * sat * (top - bot)
253  end if
254  particle%z = z
255  end select
Here is the call graph for this function:

◆ load_properties()

subroutine methoddismodule::load_properties ( class(methoddistype), intent(inout)  this,
integer(i4b), intent(in)  ic,
type(celldefntype), intent(inout), pointer  defn 
)
private

Definition at line 359 of file MethodDis.f90.

360  ! dummy
361  class(MethodDisType), intent(inout) :: this
362  integer(I4B), intent(in) :: ic
363  type(CellDefnType), pointer, intent(inout) :: defn
364  ! local
365  integer(I4B) :: irow, icol, ilay, icu
366 
367  defn%icell = ic
368  defn%npolyverts = 4 ! rectangular cell always has 4 vertices
369  defn%iatop = get_iatop(this%fmi%dis%get_ncpl(), &
370  this%fmi%dis%get_nodeuser(ic))
371  defn%top = this%fmi%dis%bot(ic) + &
372  this%fmi%gwfsat(ic) * &
373  (this%fmi%dis%top(ic) - this%fmi%dis%bot(ic))
374  defn%bot = this%fmi%dis%bot(ic)
375  defn%sat = this%fmi%gwfsat(ic)
376  defn%porosity = this%porosity(ic)
377  defn%retfactor = this%retfactor(ic)
378  select type (dis => this%fmi%dis)
379  type is (distype)
380  icu = dis%get_nodeuser(ic)
381  call get_ijk(icu, dis%nrow, dis%ncol, dis%nlay, irow, icol, ilay)
382  defn%ilay = ilay
383  end select
384  defn%izone = this%izone(ic)
385  defn%can_be_rect = .true.
386  defn%can_be_quad = .false.
Here is the call graph for this function:

◆ pass_dis()

subroutine methoddismodule::pass_dis ( class(methoddistype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle 
)
private

Definition at line 285 of file MethodDis.f90.

286  ! dummy
287  class(MethodDisType), intent(inout) :: this
288  type(ParticleType), pointer, intent(inout) :: particle
289  ! local
290  type(CellRectType), pointer :: cell
291 
292  select type (c => this%cell)
293  type is (cellrecttype)
294  cell => c
295  ! If the entry face has no neighbors it's a
296  ! boundary face, so terminate the particle.
297  ! todo AMP: reconsider when multiple models supported
298  if (cell%defn%facenbr(particle%iboundary(2)) .eq. 0) then
299  particle%istatus = 2
300  particle%advancing = .false.
301  call this%save(particle, reason=3)
302  else
303  ! Update old to new cell properties
304  call this%load_particle(cell, particle)
305  if (.not. particle%advancing) return
306 
307  ! Update intercell mass flows
308  call this%update_flowja(cell, particle)
309  end if
310  end select

◆ update_flowja()

subroutine methoddismodule::update_flowja ( class(methoddistype), intent(inout)  this,
type(cellrecttype), intent(inout), pointer  cell,
type(particletype), intent(inout), pointer  particle 
)
private

Definition at line 260 of file MethodDis.f90.

261  ! dummy
262  class(MethodDisType), intent(inout) :: this
263  type(CellRectType), pointer, intent(inout) :: cell
264  type(ParticleType), pointer, intent(inout) :: particle
265  ! local
266  integer(I4B) :: idiag
267  integer(I4B) :: inbr
268  integer(I4B) :: inface
269  integer(I4B) :: ipos
270 
271  inface = particle%iboundary(2)
272  inbr = cell%defn%facenbr(inface)
273  idiag = this%fmi%dis%con%ia(cell%defn%icell)
274  ipos = idiag + inbr
275 
276  ! leaving old cell
277  this%flowja(ipos) = this%flowja(ipos) - done
278 
279  ! entering new cell
280  this%flowja(this%fmi%dis%con%isym(ipos)) &
281  = this%flowja(this%fmi%dis%con%isym(ipos)) + done