MODFLOW 6  version 6.5.0.dev2
MODFLOW 6 Code Documentation
CellRectQuad.f90
Go to the documentation of this file.
2 
3  use cellmodule, only: celltype
5  implicit none
6 
7  private
8  public :: cellrectquadtype
9  public :: create_cell_rect_quad
10 
11  type, extends(celltype) :: cellrectquadtype
12  double precision :: dx ! dimension of cell in local x direction
13  double precision :: dy ! dimension of cell in local y direction
14  double precision :: dz ! dimension of cell in z direction
15 
16  double precision :: sinrot ! sine of rotation angle for local (x, y)
17  double precision :: cosrot ! cosine of rotation angle for local (x, y)
18 
19  integer :: irvorigin ! origin rectangle vertex
20  double precision :: xorigin ! model x origin for local (x, y)
21  double precision :: yorigin ! model y origin for local (x, y)
22  double precision :: zorigin ! model z origin for local z
23 
24  double precision :: qextl1(4), qextl2(4), qintl(5) ! external and internal subcell flows for the cell
25  integer, allocatable :: irectvert(:) ! list of indices of the rectangle vertices
26  integer, allocatable :: ipv4irv(:, :) ! list of the polygon vertex indices that correspond to the rectangle vertex indices
27  double precision, allocatable :: rectflow(:, :) ! flow(s) for each rectangle face
28  contains
29  procedure :: destroy => destroy_cell_rect_quad ! destructor for the cell
30  procedure :: init_from ! initializes the cell from an existing cell
31 
32  procedure :: load_irectvert ! loads list of indices of the rectangle vertices
33  procedure :: get_irectvertsw ! gets index of southwest rectangle vertex
34  procedure :: get_rectdimensionsrotation ! gets rectangular dimensions and rotation
35 
36  procedure :: get_rectflow ! returns a rectangle face flow
37  procedure :: face_is_refined ! returns whether a rectangle face is refined
38  end type cellrectquadtype
39 
40 contains
41 
42  !> @brief Create a new rectangular-quad cell
43  subroutine create_cell_rect_quad(cell)
44  type(cellrectquadtype), pointer :: cell
45  allocate (cell)
46  call create_defn(cell%defn)
47  allocate (cell%irectvert(5))
48  allocate (cell%ipv4irv(2, 4))
49  allocate (cell%rectflow(2, 4))
50  allocate (cell%type)
51  cell%type = 'rectquad'
52  end subroutine create_cell_rect_quad
53 
54  !> @brief Destroy the rectangular-quad cell
55  subroutine destroy_cell_rect_quad(this)
56  class(cellrectquadtype), intent(inout) :: this
57  deallocate (this%defn)
58  deallocate (this%irectvert)
59  deallocate (this%type)
60  end subroutine destroy_cell_rect_quad
61 
62  !> @brief Initialize a rectangular-quad cell from another cell
63  subroutine init_from(this, defn)
64  class(cellrectquadtype), intent(inout) :: this
65  type(celldefntype), pointer :: defn
66  this%defn => defn
67  call this%load_irectvert()
68  end subroutine init_from
69 
70  !> @brief Load local polygon vertex indices
71  !!
72  !! Loads local polygon vertex indices of the four rectangle
73  !! vertices of a rectangular-quad cell. Todo: rename?
74  !<
75  subroutine load_irectvert(this)
76  ! -- dummy
77  class(cellrectquadtype), intent(inout) :: this
78  ! -- local
79  integer :: npolyverts, n, m
80 
81  npolyverts = this%defn%get_npolyverts()
82 
83  n = 0
84  do m = 1, npolyverts
85  if (.not. this%defn%get_ispv180(m)) then
86  n = n + 1
87  this%irectvert(n) = m
88  this%ipv4irv(1, n) = m
89  this%rectflow(1, n) = this%defn%get_faceflow(m)
90  this%ipv4irv(2, n) = 0
91  this%rectflow(2, n) = 0d0
92  else
93  if (n .ne. 0) then
94  this%ipv4irv(2, n) = m
95  this%rectflow(2, n) = this%defn%get_faceflow(m)
96  end if
97  end if
98  end do
99 
100  ! Wrap around for convenience
101  this%irectvert(5) = this%irectvert(1)
102  end subroutine load_irectvert
103 
104  !> @brief Get index of SW rectangle vertex
105  !!
106  !! Return the index (1, 2, 3, or 4) of the southwest
107  !! rectangle vertex of a rectangular-quad cell
108  !<
109  function get_irectvertsw(this) result(irv1)
110  ! -- dummy
111  class(cellrectquadtype), intent(inout) :: this
112  integer :: irv1
113  ! -- local
114  integer :: irv, irv2, irv4, ipv1, ipv2, ipv4
115  integer, dimension(4) :: irvnxt = (/2, 3, 4, 1/) ! kluge???
116  double precision :: x1, y1, x2, y2, x4, y4
117 
118  ! -- Find the "southwest" rectangle vertex by finding the vertex formed
119  ! -- either by (1) a rectangle edge over which x decreases (going
120  ! -- clockwise) followed by an edge over which x does not increase, or by
121  ! -- (2) a rectangle edge over which y does not decrease (again going
122  ! -- clockwise) followed by a rectangle edge over which y increases. In
123  ! -- the end, ipv1 is the index (1, 2, 3, or 4) of the southwest
124  ! -- rectangle vertex.
125  do irv = 1, 4
126  irv4 = irv
127  irv1 = irvnxt(irv4)
128  ipv4 = this%irectvert(irv4)
129  ipv1 = this%irectvert(irv1)
130  x4 = this%defn%polyvert(1, ipv4)
131  y4 = this%defn%polyvert(2, ipv4)
132  x1 = this%defn%polyvert(1, ipv1)
133  y1 = this%defn%polyvert(2, ipv1)
134  if (x1 .lt. x4) then
135  irv2 = irvnxt(irv1)
136  ipv2 = this%irectvert(irv2)
137  x2 = this%defn%polyvert(1, ipv2)
138  if (x2 .le. x1) return
139  else if (y1 .ge. y4) then
140  irv2 = irvnxt(irv1)
141  ipv2 = this%irectvert(irv2)
142  y2 = this%defn%polyvert(2, ipv2)
143  if (y2 .gt. y1) return
144  end if
145  end do
146  end function get_irectvertsw
147 
148  !> @brief Get rectangular cell dimensions and rotation
149  !!
150  !! Compute rectangular dimensions and rotation of
151  !! the cell using the specified rectangle vertex
152  !! as the origin
153  !<
154  subroutine get_rectdimensionsrotation(this, irv1, xOrigin, yOrigin, zOrigin, &
155  dx, dy, dz, sinrot, cosrot)
156  ! -- dummy
157  class(cellrectquadtype), intent(inout) :: this
158  integer :: irv1
159  double precision :: xOrigin, yOrigin, zOrigin, dx, dy, dz, sinrot, cosrot
160  ! -- local
161  integer :: irv2, irv4, ipv1, ipv2, ipv4
162  integer, dimension(4) :: irvnxt = (/2, 3, 4, 1/) ! kluge???
163  double precision :: x1, y1, x2, y2, x4, y4, dx2, dy2, dx4, dy4
164 
165  ! -- Get rectangle vertex neighbors irv2 and irv4
166  irv2 = irvnxt(irv1)
167  irv4 = irvnxt(irvnxt(irv2)) ! kluge
168 
169  ! -- Get model coordinates at irv1, irv2, and irv4
170  ipv1 = this%irectvert(irv1)
171  x1 = this%defn%polyvert(1, ipv1)
172  y1 = this%defn%polyvert(2, ipv1)
173  ipv2 = this%irectvert(irv2)
174  x2 = this%defn%polyvert(1, ipv2)
175  y2 = this%defn%polyvert(2, ipv2)
176  ipv4 = this%irectvert(irv4)
177  x4 = this%defn%polyvert(1, ipv4)
178  y4 = this%defn%polyvert(2, ipv4)
179 
180  ! -- Compute rectangle dimensions
181  xorigin = x1
182  yorigin = y1
183  zorigin = this%defn%bot
184  dx2 = x2 - xorigin
185  dy2 = y2 - yorigin
186  dx4 = x4 - xorigin
187  dy4 = y4 - yorigin
188  dx = dsqrt(dx4 * dx4 + dy4 * dy4)
189  dy = dsqrt(dx2 * dx2 + dy2 * dy2)
190  dz = this%defn%top - zorigin ! kluge note: need to account for partial saturation
191 
192  ! -- Compute sine and cosine of rotation angle (angle between "southern"
193  ! -- rectangle side irv1-irv4 and the model x axis)
194  sinrot = dy4 / dx
195  cosrot = dx4 / dx
196  end subroutine get_rectdimensionsrotation
197 
198  !> @brief Return a rectangle face flow
199  function get_rectflow(this, iq, irv) result(rectflow)
200  class(cellrectquadtype), intent(inout) :: this
201  integer :: iq, irv
202  double precision :: rectflow
203  rectflow = this%rectflow(iq, irv)
204  end function get_rectflow
205 
206  !> @brief Return whether a rectangle face is refined
207  function face_is_refined(this, i) result(is_refined)
208  ! -- dummy
209  class(cellrectquadtype), intent(inout) :: this
210  integer :: i !< face index
211  logical :: is_refined
212 
213  if (this%ipv4irv(2, i) .ne. 0) then
214  is_refined = .true.
215  else
216  is_refined = .false.
217  end if
218  end function face_is_refined
219 
220 end module cellrectquadmodule
subroutine, public create_defn(cellDefn)
Create a new cell definition object.
Definition: CellDefn.f90:42
subroutine, public create_cell_rect_quad(cell)
Create a new rectangular-quad cell.
logical function face_is_refined(this, i)
Return whether a rectangle face is refined.
integer function get_irectvertsw(this)
Get index of SW rectangle vertex.
subroutine init_from(this, defn)
Initialize a rectangular-quad cell from another cell.
subroutine destroy_cell_rect_quad(this)
Destroy the rectangular-quad cell.
subroutine get_rectdimensionsrotation(this, irv1, xOrigin, yOrigin, zOrigin, dx, dy, dz, sinrot, cosrot)
Get rectangular cell dimensions and rotation.
double precision function get_rectflow(this, iq, irv)
Return a rectangle face flow.
subroutine load_irectvert(this)
Load local polygon vertex indices.
Base grid cell definition.
Definition: CellDefn.f90:10
Base type for grid cells of a concrete type. Contains a cell-definition which is information shared b...
Definition: Cell.f90:10