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

Data Types

type  methoddisvtype
 

Functions/Subroutines

subroutine, public create_method_disv (method)
 Create a new vertex grid (DISV) tracking method. More...
 
subroutine destroy (this)
 Destroy the tracking method. More...
 
subroutine load_disv (this, particle, next_level, submethod)
 Load the cell and the tracking method. More...
 
subroutine pass_disv (this, particle)
 Pass a particle to the next cell, if there is one. More...
 
subroutine map_neighbor (this, defn, inface, z)
 Map location on cell face to shared cell face of neighbor. More...
 
subroutine apply_disv (this, particle, tmax)
 Apply the DISV-grid method. More...
 
integer(i4b) function get_npolyverts (this, ic)
 Return the number of polygon vertices for a cell in the grid. More...
 
real(dp) function get_top (this, iatop)
 Get top elevation based on index iatop kluge note: not needed??? More...
 
subroutine load_cell_defn (this, ic, defn)
 Load cell definition from the grid. More...
 
subroutine load_nbrs_to_defn (this, defn)
 Loads face neighbors to cell definition from the grid Assumes cell index and number of vertices are already loaded. More...
 
subroutine shared_edgeface (ivlist1, ivlist2, iedgeface)
 Find the edge face shared by two cells. More...
 
subroutine load_flows_to_defn (this, defn)
 Load flows into the cell definition. These include face flows and net distributed flows. Assumes cell index and number of vertices are already loaded. More...
 
subroutine load_boundary_flows_to_defn_rect (this, defn)
 Load boundary flows from the grid into a rectangular cell. Assumes cell index and number of vertices are already loaded. More...
 
subroutine load_boundary_flows_to_defn_rect_quad (this, defn)
 Load boundary flows from the grid into rectangular quadcell. Assumes cell index and number of vertices are already loaded. More...
 
subroutine load_boundary_flows_to_defn_poly (this, defn)
 Load boundary flows from the grid into a polygonal cell. Assumes cell index and number of vertices are already loaded. More...
 
subroutine load_flags_to_defn (this, defn)
 Load 180-degree vertex indicator array and set flags indicating how cell can be represented (kluge: latter needed?). Assumes cell index and number of vertices are already loaded. More...
 

Function/Subroutine Documentation

◆ apply_disv()

subroutine methoddisvmodule::apply_disv ( class(methoddisvtype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle,
real(dp), intent(in)  tmax 
)
private

Definition at line 262 of file MethodDisv.f90.

263  class(MethodDisvType), intent(inout) :: this
264  type(ParticleType), pointer, intent(inout) :: particle
265  real(DP), intent(in) :: tmax
266  call this%track(particle, 1, tmax) ! kluge, hardwired to level 1

◆ create_method_disv()

subroutine, public methoddisvmodule::create_method_disv ( type(methoddisvtype), pointer  method)

Definition at line 44 of file MethodDisv.f90.

45  ! -- dummy
46  type(MethodDisvType), pointer :: method
47  ! -- local
48  type(CellPolyType), pointer :: cell
49 
50  allocate (method)
51  allocate (method%type)
52  allocate (method%zeromethod)
53  call create_cell_poly(cell)
54  method%cell => cell
55  method%type = "disv"
56  method%delegates = .true.
57  method%zeromethod = 0
Here is the call graph for this function:
Here is the caller graph for this function:

◆ destroy()

subroutine methoddisvmodule::destroy ( class(methoddisvtype), intent(inout)  this)
private

Definition at line 61 of file MethodDisv.f90.

62  class(MethodDisvType), intent(inout) :: this
63  deallocate (this%type)

◆ get_npolyverts()

integer(i4b) function methoddisvmodule::get_npolyverts ( class(methoddisvtype), intent(inout)  this,
integer(i4b), intent(in)  ic 
)
private

Definition at line 270 of file MethodDisv.f90.

271  ! -- dummy
272  class(MethodDisvType), intent(inout) :: this
273  integer(I4B), intent(in) :: ic
274  ! -- local
275  integer(I4B) :: icu
276  integer(I4B) :: icu2d
277  integer(I4B) :: ncpl
278  ! -- result
279  integer(I4B) :: npolyverts
280 
281  select type (dis => this%fmi%dis)
282  type is (disvtype)
283  ncpl = dis%get_ncpl()
284  icu = dis%get_nodeuser(ic)
285  icu2d = icu - ((icu - 1) / ncpl) * ncpl ! kluge note: use MOD or MODULO???
286  npolyverts = dis%iavert(icu2d + 1) - dis%iavert(icu2d) - 1
287  if (npolyverts .le. 0) npolyverts = npolyverts + size(dis%javert) ! kluge???
288  end select

◆ get_top()

real(dp) function methoddisvmodule::get_top ( class(methoddisvtype), intent(inout)  this,
integer(i4b), intent(in)  iatop 
)
private

Definition at line 293 of file MethodDisv.f90.

294  ! -- dummy
295  class(MethodDisvType), intent(inout) :: this
296  integer(I4B), intent(in) :: iatop
297  ! -- result
298  real(DP) :: top
299 
300  if (iatop .lt. 0) then
301  top = this%fmi%dis%top(-iatop)
302  else
303  top = this%fmi%dis%bot(iatop)
304  end if

◆ load_boundary_flows_to_defn_poly()

subroutine methoddisvmodule::load_boundary_flows_to_defn_poly ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 626 of file MethodDisv.f90.

627  ! -- dummy
628  class(MethodDisvType), intent(inout) :: this
629  type(CellDefnType), intent(inout) :: defn
630  ! -- local
631  integer(I4B) :: ic
632  integer(I4B) :: npolyverts
633  integer(I4B) :: ioffset
634  integer(I4B) :: iv
635 
636  ic = defn%icell
637  npolyverts = defn%npolyverts
638 
639  ! kluge note: hardwired for max 8 polygon faces plus top and bottom for now
640  ioffset = (ic - 1) * 10
641  do iv = 1, npolyverts
642  ! kluge note: should these be additive (seems so)???
643  defn%faceflow(iv) = &
644  defn%faceflow(iv) + &
645  this%fmi%BoundaryFlows(ioffset + iv)
646  end do
647  defn%faceflow(npolyverts + 1) = defn%faceflow(1)
648  defn%faceflow(npolyverts + 2) = &
649  defn%faceflow(npolyverts + 2) + &
650  this%fmi%BoundaryFlows(ioffset + 9)
651  defn%faceflow(npolyverts + 3) = &
652  defn%faceflow(npolyverts + 3) + &
653  this%fmi%BoundaryFlows(ioffset + 10)
654 

◆ load_boundary_flows_to_defn_rect()

subroutine methoddisvmodule::load_boundary_flows_to_defn_rect ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 518 of file MethodDisv.f90.

519  ! -- dummy
520  class(MethodDisvType), intent(inout) :: this
521  type(CellDefnType), intent(inout) :: defn
522  ! -- local
523  integer(I4B) :: ic
524  integer(I4B) :: npolyverts
525  integer(I4B) :: ioffset
526 
527  ic = defn%icell
528  npolyverts = defn%npolyverts
529 
530  ! kluge note - assignment of BoundaryFlows to faceflow below assumes vertex 1
531  ! is at upper left of rectangular cell, and BoundaryFlows use old iface order
532  ! ioffset = (ic - 1)*6
533  ioffset = (ic - 1) * 10
534  ! kluge note: should these be additive (seems so)???
535  defn%faceflow(1) = defn%faceflow(1) + &
536  this%fmi%BoundaryFlows(ioffset + 4)
537  defn%faceflow(2) = defn%faceflow(2) + &
538  this%fmi%BoundaryFlows(ioffset + 2)
539  defn%faceflow(3) = defn%faceflow(3) + &
540  this%fmi%BoundaryFlows(ioffset + 3)
541  defn%faceflow(4) = defn%faceflow(4) + &
542  this%fmi%BoundaryFlows(ioffset + 1)
543  defn%faceflow(5) = defn%faceflow(1)
544  defn%faceflow(6) = defn%faceflow(6) + &
545  this%fmi%BoundaryFlows(ioffset + 9)
546  defn%faceflow(7) = defn%faceflow(7) + &
547  this%fmi%BoundaryFlows(ioffset + 10)
548 

◆ load_boundary_flows_to_defn_rect_quad()

subroutine methoddisvmodule::load_boundary_flows_to_defn_rect_quad ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 553 of file MethodDisv.f90.

554  ! -- dummy
555  class(MethodDisvType), intent(inout) :: this
556  type(CellDefnType), intent(inout) :: defn
557  ! -- local
558  integer(I4B) :: ic
559  integer(I4B) :: npolyverts
560  integer(I4B) :: m
561  integer(I4B) :: n
562  integer(I4B) :: nn
563  integer(I4B) :: ioffset
564  integer(I4B) :: nbf
565  integer(I4B) :: m1
566  integer(I4B) :: m2
567  integer(I4B) :: mdiff
568  real(DP) :: qbf
569  integer(I4B) :: irectvert(5) ! kluge
570 
571  ic = defn%icell
572  npolyverts = defn%npolyverts
573 
574  ! kluge note - assignment of BoundaryFlows to faceflow below assumes vertex 1
575  ! is at upper left of rectangular cell, and BoundaryFlows use old iface order
576  ! ioffset = (ic - 1)*6
577  ioffset = (ic - 1) * 10
578  ! -- Polygon faces in positions 1 through npolyverts
579  do n = 1, 4
580  if (n .eq. 2) then
581  nbf = 4
582  else if (n .eq. 4) then
583  nbf = 1
584  else
585  nbf = n
586  end if
587  qbf = this%fmi%BoundaryFlows(ioffset + nbf)
588  nn = 0 ! kluge ...
589  do m = 1, npolyverts
590  if (.not. defn%ispv180(m)) then
591  nn = nn + 1
592  irectvert(nn) = m
593  end if
594  end do
595  irectvert(5) = irectvert(1) ! ... kluge
596  m1 = irectvert(n)
597  m2 = irectvert(n + 1)
598  if (m2 .lt. m1) m2 = m2 + npolyverts
599  mdiff = m2 - m1
600  if (mdiff .eq. 1) then
601  ! -- Assign BoundaryFlow to corresponding polygon face
602  defn%faceflow(m1) = defn%faceflow(m1) + qbf
603  else
604  ! -- Split BoundaryFlow between two faces on quad-refined edge
605  qbf = 5d-1 * qbf
606  defn%faceflow(m1) = defn%faceflow(m1) + qbf
607  defn%faceflow(m1 + 1) = defn%faceflow(m1 + 1) + qbf
608  end if
609  end do
610  ! -- Wrap around to 1 in position npolyverts+1
611  m = npolyverts + 1
612  defn%faceflow(m) = defn%faceflow(1)
613  ! -- Bottom in position npolyverts+2
614  m = m + 1
615  defn%faceflow(m) = defn%faceflow(m) + &
616  this%fmi%BoundaryFlows(ioffset + 9)
617  ! -- Top in position npolyverts+3
618  m = m + 1
619  defn%faceflow(m) = defn%faceflow(m) + &
620  this%fmi%BoundaryFlows(ioffset + 10)
621 

◆ load_cell_defn()

subroutine methoddisvmodule::load_cell_defn ( class(methoddisvtype), intent(inout)  this,
integer(i4b), intent(in)  ic,
type(celldefntype), intent(inout), pointer  defn 
)
private

Definition at line 308 of file MethodDisv.f90.

309  ! -- dummy
310  class(MethodDisvType), intent(inout) :: this
311  integer(I4B), intent(in) :: ic
312  type(CellDefnType), pointer, intent(inout) :: defn
313  ! -- local
314  real(DP) :: top
315  real(DP) :: bot
316  real(DP) :: sat
317 
318  ! -- Load basic cell properties
319  defn%icell = ic
320  defn%npolyverts = this%get_npolyverts(ic)
321  defn%iatop = get_iatop(this%fmi%dis%get_ncpl(), &
322  this%fmi%dis%get_nodeuser(ic))
323  top = this%fmi%dis%top(ic)
324  bot = this%fmi%dis%bot(ic)
325  sat = this%fmi%gwfsat(ic)
326  top = bot + sat * (top - bot)
327  defn%top = top
328  defn%bot = bot
329  defn%sat = sat
330  defn%porosity = this%porosity(ic)
331  defn%retfactor = this%retfactor(ic)
332  defn%izone = this%izone(ic)
333 
334  ! -- Load polygon vertices
335  call this%fmi%dis%get_polyverts( &
336  defn%icell, &
337  defn%polyvert, &
338  closed=.true.)
339 
340  ! -- Load face neighbors
341  call this%load_nbrs_to_defn(defn)
342 
343  ! -- Load 180-degree indicator
344  call this%load_flags_to_defn(defn)
345 
346  ! -- Load flows (assumes face neighbors already loaded)
347  call this%load_flows_to_defn(defn)
Here is the call graph for this function:

◆ load_disv()

subroutine methoddisvmodule::load_disv ( class(methoddisvtype), 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 67 of file MethodDisv.f90.

68  use cellmodule
69  use cellrectmodule
71  use cellutilmodule
72  ! -- dummy
73  class(MethodDisvType), intent(inout) :: this
74  type(ParticleType), pointer, intent(inout) :: particle
75  integer(I4B), intent(in) :: next_level
76  class(MethodType), pointer, intent(inout) :: submethod
77  ! -- local
78  integer(I4B) :: ic
79  class(CellType), pointer :: base
80  type(CellRectType), pointer :: rect
81  type(CellRectQuadType), pointer :: quad
82 
83  select type (cell => this%cell)
84  type is (cellpolytype)
85  ! load cell definition
86  ic = particle%idomain(next_level) ! kluge note: is cell number always known coming in?
87  call this%load_cell_defn(ic, cell%defn)
88  if (this%fmi%ibdgwfsat0(ic) == 0) then ! kluge note: use cellDefn%sat == DZERO here instead?
89  ! -- Cell is active but dry, so select and initialize pass-to-bottom
90  ! -- cell method and set cell method pointer
91  call method_cell_ptb%init( &
92  cell=this%cell, &
93  trackfilectl=this%trackfilectl, &
94  tracktimes=this%tracktimes)
95  submethod => method_cell_ptb
96  else
97  ! -- Select and initialize cell method and set cell method pointer
98  if (cell%defn%can_be_rect) then
99  call cell_poly_to_rect(cell, rect)
100  base => rect
101  call method_cell_plck%init( &
102  cell=base, &
103  trackfilectl=this%trackfilectl, &
104  tracktimes=this%tracktimes)
105  submethod => method_cell_plck
106  else if (cell%defn%can_be_quad) then
107  call cell_poly_to_quad(cell, quad)
108  base => quad
109  call method_cell_quad%init( &
110  cell=base, &
111  trackfilectl=this%trackfilectl, &
112  tracktimes=this%tracktimes)
113  submethod => method_cell_quad
114  else
115  call method_cell_tern%init( &
116  cell=this%cell, &
117  trackfilectl=this%trackfilectl, &
118  tracktimes=this%tracktimes)
119  submethod => method_cell_tern
120  method_cell_tern%zeromethod = this%zeromethod
121  end if
122  end if
123  end select
subroutine, public cell_poly_to_rect(poly, rect)
Convert CellPoly representation to CellRect if possible.
Definition: CellUtil.f90:13
subroutine, public cell_poly_to_quad(poly, quad)
Convert CellPoly representation to CellRectQuad if possible.
Definition: CellUtil.f90:115
Here is the call graph for this function:

◆ load_flags_to_defn()

subroutine methoddisvmodule::load_flags_to_defn ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout), pointer  defn 
)
private

Definition at line 660 of file MethodDisv.f90.

661  ! -- dummy
662  class(MethodDisvType), intent(inout) :: this
663  type(CellDefnType), pointer, intent(inout) :: defn
664  ! -- local
665  integer(I4B) :: npolyverts
666  integer(I4B) :: m
667  integer(I4B) :: m0
668  integer(I4B) :: m1
669  integer(I4B) :: m2
670  integer(I4B) :: ic
671  integer(I4B) :: num90
672  integer(I4B) :: num180
673  integer(I4B) :: numacute
674  real(DP) :: x0
675  real(DP) :: y0
676  real(DP) :: x1
677  real(DP) :: y1
678  real(DP) :: x2
679  real(DP) :: y2
680  real(DP) :: epsang
681  real(DP) :: epslen
682  real(DP) :: s0x
683  real(DP) :: s0y
684  real(DP) :: &
685  s0mag, s2x, s2y, s2mag, sinang, dotprod
686  logical(LGP) last180
687 
688  ic = defn%icell
689  npolyverts = defn%npolyverts
690 
691  ! -- expand ispv180 array if needed
692  if (size(defn%ispv180) < npolyverts + 3) &
693  call expandarray(defn%ispv180, npolyverts + 1)
694 
695  ! -- Load 180-degree indicator.
696  ! -- Also, set flags that indicate how cell can be represented.
697  defn%ispv180(1:npolyverts + 1) = .false.
698  defn%can_be_rect = .false.
699  defn%can_be_quad = .false.
700  epsang = 1d-3 ! kluge hardwire, and using one value for all angles
701  epslen = 1d-3 ! kluge hardwire
702  num90 = 0
703  num180 = 0
704  numacute = 0
705  last180 = .false.
706  ! kluge note: assumes non-self-intersecting polygon;
707  ! no checks for self-intersection (e.g., star)
708  do m = 1, npolyverts
709  m1 = m
710  if (m1 .eq. 1) then
711  m0 = npolyverts
712  m2 = 2
713  else if (m1 .eq. npolyverts) then
714  m0 = npolyverts - 1
715  m2 = 1
716  else
717  m0 = m1 - 1
718  m2 = m1 + 1
719  end if
720  x0 = defn%polyvert(1, m0)
721  y0 = defn%polyvert(2, m0)
722  x1 = defn%polyvert(1, m1)
723  y1 = defn%polyvert(2, m1)
724  x2 = defn%polyvert(1, m2)
725  y2 = defn%polyvert(2, m2)
726  s0x = x0 - x1
727  s0y = y0 - y1
728  s0mag = dsqrt(s0x * s0x + s0y * s0y)
729  s2x = x2 - x1
730  s2y = y2 - y1
731  s2mag = dsqrt(s2x * s2x + s2y * s2y)
732  sinang = (s0x * s2y - s0y * s2x) / (s0mag * s2mag)
733  ! kluge note: is it better to check in terms of angle rather than sin{angle}???
734  if (dabs(sinang) .lt. epsang) then
735  dotprod = s0x * s2x + s0y * s2y
736  if (dotprod .gt. 0d0) then
737  print *, "Cell ", ic, " has a zero angle" ! kluge
738  print *, " (tolerance epsang = ", epsang, ")"
739  call pstop(1)
740  else
741  if (last180) then
742  print *, "Cell ", ic, &
743  " has consecutive 180-deg angles - not supported" ! kluge
744  print *, " (tolerance epsang = ", epsang, ")"
745  call pstop(1)
746  else if (dabs((s2mag - s0mag) / max(s2mag, s0mag)) .gt. epslen) then
747  print *, "Cell ", ic, &
748  " has a non-bisecting 180-deg vertex - not supported" ! kluge
749  print *, " (tolerance epslen = ", epslen, ")"
750  call pstop(1)
751  end if
752  ! kluge note: want to evaluate 180-deg vertex using one criterion implemented in
753  ! one place (procedure) to avoid potential disparities between multiple checks
754  num180 = num180 + 1
755  last180 = .true.
756  defn%ispv180(m) = .true.
757  end if
758  else if (sinang .gt. 0d0) then
759  numacute = numacute + 1
760  if (dabs(1d0 - sinang) .lt. epsang) num90 = num90 + 1
761  last180 = .false.
762  else
763  print *, "Cell ", ic, &
764  " has an obtuse angle and so is nonconvex" ! kluge
765  print *, " (tolerance epsang = ", epsang, ")"
766  call pstop(1)
767  end if
768  end do
769  if ((num90 .ne. 4) .and. (num180 .ne. 0)) then
770  print *, "Cell ", ic, &
771  " is a non-rectangle with a 180-deg angle - not supported" ! kluge
772  print *, " (tolerance epsang = ", epsang, ")"
773  call pstop(1)
774  end if
775  ! -- List of 180-degree indicators wraps around for convenience
776  defn%ispv180(npolyverts + 1) = defn%ispv180(1)
777  !
778  if (num90 .eq. 4) then
779  if (num180 .eq. 0) then
780  defn%can_be_rect = .true.
781  else
782  defn%can_be_quad = .true.
783  end if
784  end if
785 
Here is the call graph for this function:

◆ load_flows_to_defn()

subroutine methoddisvmodule::load_flows_to_defn ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout)  defn 
)
private

Definition at line 466 of file MethodDisv.f90.

467  ! -- dummy
468  class(MethodDisvType), intent(inout) :: this
469  type(CellDefnType), intent(inout) :: defn
470  ! -- local
471  integer(I4B) :: ic
472  integer(I4B) :: npolyverts
473  integer(I4B) :: m
474  integer(I4B) :: n
475 
476  ic = defn%icell
477  npolyverts = defn%npolyverts
478 
479  ! -- expand faceflow array if needed
480  if (size(defn%faceflow) < npolyverts + 3) &
481  call expandarray(defn%faceflow, npolyverts + 3)
482 
483  ! -- Load face flows. Note that the faceflow array
484  ! -- does not get reallocated if it is already allocated
485  ! -- to a size greater than or equal to npolyverts+3.
486  defn%faceflow = 0d0
487 
488  ! -- As with polygon nbrs, polygon face flows wrap around for
489  ! -- convenience at position npolyverts+1, and bot and top flows
490  ! -- are tacked on the end of the list
491  do m = 1, npolyverts + 3
492  n = defn%facenbr(m)
493  if (n > 0) &
494  defn%faceflow(m) = this%fmi%gwfflowja(this%fmi%dis%con%ia(ic) + n)
495  end do
496  call this%load_boundary_flows_to_defn_poly(defn)
497  ! -- Set inoexitface flag
498  defn%inoexitface = 1
499  do m = 1, npolyverts + 3 ! kluge note: can be streamlined with above code
500  if (defn%faceflow(m) < 0d0) defn%inoexitface = 0
501  end do
502 
503  ! -- Add up net distributed flow
504  defn%distflow = this%fmi%SourceFlows(ic) + this%fmi%SinkFlows(ic) + &
505  this%fmi%StorageFlows(ic)
506 
507  ! -- Set weak sink flag
508  if (this%fmi%SinkFlows(ic) .ne. 0d0) then
509  defn%iweaksink = 1
510  else
511  defn%iweaksink = 0
512  end if
513 

◆ load_nbrs_to_defn()

subroutine methoddisvmodule::load_nbrs_to_defn ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout), pointer  defn 
)
private

Definition at line 352 of file MethodDisv.f90.

353  ! -- dummy
354  class(MethodDisvType), intent(inout) :: this
355  type(CellDefnType), pointer, intent(inout) :: defn
356  ! -- local
357  integer(I4B) :: ic
358  integer(I4B) :: npolyverts
359  integer(I4B) :: ic1
360  integer(I4B) :: ic2
361  integer(I4B) :: icu1
362  integer(I4B) :: icu2
363  integer(I4B) :: j1
364  integer(I4B) :: j2
365  integer(I4B) :: k1
366  integer(I4B) :: k2
367  integer(I4B) :: iloc
368  integer(I4B) :: ipos
369  integer(I4B) :: istart1
370  integer(I4B) :: istart2
371  integer(I4B) :: istop1
372  integer(I4B) :: istop2
373  integer(I4B) :: iedgeface
374  integer(I4B) :: ncpl
375 
376  ic = defn%icell
377  npolyverts = defn%npolyverts
378 
379  ! -- expand facenbr array if needed
380  if (size(defn%facenbr) < npolyverts + 3) &
381  call expandarray(defn%facenbr, npolyverts + 3)
382 
383  select type (dis => this%fmi%dis)
384  type is (disvtype)
385  ! -- Load face neighbors.
386  defn%facenbr = 0
387  ic1 = ic
388  icu1 = dis%get_nodeuser(ic1)
389  ncpl = dis%get_ncpl()
390  call get_jk(icu1, ncpl, dis%nlay, j1, k1)
391  istart1 = dis%iavert(j1)
392  istop1 = dis%iavert(j1 + 1) - 1
393  do iloc = 1, dis%con%ia(ic1 + 1) - dis%con%ia(ic1) - 1
394  ipos = dis%con%ia(ic1) + iloc
395  if (dis%con%mask(ipos) == 0) cycle ! kluge note: need mask here???
396  ic2 = dis%con%ja(ipos)
397  icu2 = dis%get_nodeuser(ic2)
398  call get_jk(icu2, ncpl, dis%nlay, j2, k2)
399  istart2 = dis%iavert(j2)
400  istop2 = dis%iavert(j2 + 1) - 1
401  call shared_edgeface(dis%javert(istart1:istop1), &
402  dis%javert(istart2:istop2), &
403  iedgeface)
404  if (iedgeface /= 0) then
405 
406  ! -- Edge (polygon) face neighbor
407  defn%facenbr(iedgeface) = int(iloc, 1)
408  else
409  if (k2 > k1) then
410  ! -- Bottom face neighbor
411  defn%facenbr(npolyverts + 2) = int(iloc, 1)
412  else if (k2 < k1) then
413  ! -- Top face neighbor
414  defn%facenbr(npolyverts + 3) = int(iloc, 1)
415  else
416  call pstop(1, "k2 should be <> k1, since no shared edge face")
417  end if
418  end if
419  end do
420  end select
421  ! -- List of edge (polygon) faces wraps around
422  defn%facenbr(npolyverts + 1) = defn%facenbr(1)
423 
Here is the call graph for this function:

◆ map_neighbor()

subroutine methoddisvmodule::map_neighbor ( class(methoddisvtype), intent(inout)  this,
type(celldefntype), intent(inout), pointer  defn,
integer(i4b), intent(inout)  inface,
double precision, intent(inout)  z 
)

Definition at line 192 of file MethodDisv.f90.

193  ! dummy
194  class(MethodDisvType), intent(inout) :: this
195  type(CellDefnType), pointer, intent(inout) :: defn
196  integer(I4B), intent(inout) :: inface
197  double precision, intent(inout) :: z
198  ! local
199  integer(I4B) :: icin
200  integer(I4B) :: npolyvertsin
201  integer(I4B) :: ic
202  integer(I4B) :: npolyverts
203  integer(I4B) :: inbr
204  integer(I4B) :: inbrnbr
205  integer(I4B) :: j
206  integer(I4B) :: m
207  real(DP) :: zrel
208  real(DP) :: topfrom
209  real(DP) :: botfrom
210  real(DP) :: top
211  real(DP) :: bot
212  real(DP) :: sat
213  type(CellDefnType), pointer :: cd
214 
215  ! -- Map to shared cell face of neighbor
216  inbr = defn%facenbr(inface)
217  if (inbr .eq. 0) then ! kluge note: redundant check
218  ! -- Exterior face; no neighbor to map to
219  inface = -1 ! kluge???
220  else
221  ! -- Load definition for neighbor cell (neighbor with shared face)
222  icin = defn%icell
223  j = this%fmi%dis%con%ia(icin)
224  ic = this%fmi%dis%con%ja(j + inbr)
225  call create_defn(cd)
226  ! kluge note: really only need to load facenbr and npolyverts for this
227  call this%load_cell_defn(ic, cd) ! kluge
228  npolyvertsin = defn%npolyverts
229  npolyverts = cd%npolyverts
230  if (inface .eq. npolyvertsin + 2) then
231  ! -- Exits through bot, enters through top
232  inface = npolyverts + 3
233  else if (inface .eq. npolyvertsin + 3) then
234  ! -- Exits through top, enters through bot
235  inface = npolyverts + 2
236  else
237  ! -- Exits and enters through shared polygon face
238  j = this%fmi%dis%con%ia(ic)
239  ! kluge note: use shared_edge in DisvGeom to find shared polygon face???
240  do m = 1, npolyverts + 3
241  inbrnbr = cd%facenbr(m)
242  if (this%fmi%dis%con%ja(j + inbrnbr) .eq. icin) then
243  inface = m
244  exit
245  end if
246  end do
247  ! -- Map z between cells
248  topfrom = defn%top
249  botfrom = defn%bot
250  zrel = (z - botfrom) / (topfrom - botfrom)
251  ! kluge note: use PRT model's DIS instead of fmi's???
252  top = this%fmi%dis%top(ic)
253  bot = this%fmi%dis%bot(ic)
254  sat = this%fmi%gwfsat(ic)
255  z = bot + zrel * sat * (top - bot)
256  end if
257  deallocate (cd)
258  end if
Here is the call graph for this function:

◆ pass_disv()

subroutine methoddisvmodule::pass_disv ( class(methoddisvtype), intent(inout)  this,
type(particletype), intent(inout), pointer  particle 
)

Definition at line 127 of file MethodDisv.f90.

128  ! -- modules
129  use disvmodule, only: disvtype
130  ! -- dummy
131  class(MethodDisvType), intent(inout) :: this
132  type(ParticleType), pointer, intent(inout) :: particle
133  ! -- local
134  integer(I4B) :: inface
135  integer(I4B) :: ipos
136  integer(I4B) :: ic
137  integer(I4B) :: icu
138  integer(I4B) :: inbr
139  integer(I4B) :: idiag
140  integer(I4B) :: icpl
141  integer(I4B) :: ilay
142  real(DP) :: z
143 
144  inface = particle%iboundary(2)
145  z = particle%z
146 
147  select type (cell => this%cell)
148  type is (cellpolytype)
149  select type (dis => this%fmi%dis)
150  type is (disvtype)
151  inbr = cell%defn%facenbr(inface)
152  if (inbr .eq. 0) then
153  ! -- Exterior face; no neighbor to map to
154  ! particle%idomain(1) = 0
155  ! particle%idomain(2) = 0 ! kluge note: "has_exited" attribute instead???
156  ! particle%idomain(1) = -abs(particle%idomain(1)) ! kluge???
157  ! particle%idomain(2) = -abs(particle%idomain(2)) ! kluge???
158  particle%istatus = 2 ! kluge note, todo: use -2 to check for transfer to another model???
159  particle%advancing = .false.
160  call this%save(particle, reason=3) ! reason=3: termination
161  ! particle%iboundary(2) = -1
162  else
163  idiag = dis%con%ia(cell%defn%icell)
164  ipos = idiag + inbr
165  ic = dis%con%ja(ipos) ! kluge note, todo: use PRT model's DIS instead of fmi's??
166  particle%idomain(2) = ic
167 
168  ! compute and set user node number and layer on particle
169  icu = dis%get_nodeuser(ic)
170  call get_jk(icu, dis%ncpl, dis%nlay, icpl, ilay)
171  particle%icu = icu
172  particle%ilay = ilay
173 
174  call this%map_neighbor(cell%defn, inface, z)
175  particle%iboundary(2) = inface
176  particle%idomain(3:) = 0
177  particle%iboundary(3:) = 0
178  particle%z = z
179  ! -- Update cell-cell flows of particle mass.
180  ! Every particle is currently assigned unit mass.
181  ! -- leaving old cell
182  this%flowja(ipos) = this%flowja(ipos) - done
183  ! -- entering new cell
184  this%flowja(dis%con%isym(ipos)) &
185  = this%flowja(dis%con%isym(ipos)) + done
186  end if
187  end select
188  end select
Vertex grid discretization.
Definition: Disv.f90:24
Here is the call graph for this function:

◆ shared_edgeface()

subroutine methoddisvmodule::shared_edgeface ( integer(i4b), dimension(:)  ivlist1,
integer(i4b), dimension(:)  ivlist2,
integer(i4b), intent(out)  iedgeface 
)
private

Find the shared edge face of cell1 shared by cell1 and cell2. isharedface will return with 0 if there is no shared edge face. Proceed forward through ivlist1 and backward through ivlist2 as a clockwise face in cell1 must correspond to a counter clockwise face in cell2.

kluge note: based on DisvGeom shared_edge

Definition at line 436 of file MethodDisv.f90.

437  integer(I4B), dimension(:) :: ivlist1
438  integer(I4B), dimension(:) :: ivlist2
439  integer(I4B), intent(out) :: iedgeface
440  integer(I4B) :: nv1
441  integer(I4B) :: nv2
442  integer(I4B) :: il1
443  integer(I4B) :: il2
444  logical(LGP) :: found
445 
446  found = .false.
447  nv1 = size(ivlist1)
448  nv2 = size(ivlist2)
449  iedgeface = 0
450  outerloop: do il1 = 1, nv1 - 1
451  do il2 = nv2, 2, -1
452  if (ivlist1(il1) == ivlist2(il2) .and. &
453  ivlist1(il1 + 1) == ivlist2(il2 - 1)) then
454  found = .true.
455  iedgeface = il1
456  exit outerloop
457  end if
458  end do
459  if (found) exit
460  end do outerloop
Here is the caller graph for this function: