MODFLOW 6  version 6.9.0.dev0
USGS Modular Hydrologic Model
geomutilmodule Module Reference

Functions/Subroutines

logical function, public between (x, a, b)
 Check if a value is between two other values (inclusive). More...
 
logical function, public point_in_polygon (x, y, poly, tol)
 Check if a point is within a polygon. More...
 
integer(i4b) function, public get_node (ilay, irow, icol, nlay, nrow, ncol)
 Get node number, given layer, row, and column indices for a structured grid. If any argument is invalid return -1. More...
 
subroutine, public get_ijk (nodenumber, nrow, ncol, nlay, irow, icol, ilay)
 Get row, column and layer indices from node number and grid dimensions. If nodenumber is invalid, irow, icol, and ilay are -1. More...
 
subroutine, public get_jk (nodenumber, ncpl, nlay, icpl, ilay)
 Get layer index and within-layer node index from node number and grid dimensions. If nodenumber is invalid, icpl and ilay are -1. More...
 
pure real(dp) function, dimension(2), public skew (v, s, invert)
 Skew a 2D vector along the x-axis. More...
 
subroutine, public transform (xin, yin, zin, xout, yout, zout, xorigin, yorigin, zorigin, sinrot, cosrot, invert)
 Apply a 3D translation and optional 2D rotation to coordinates. More...
 
subroutine, public compose (xorigin, yorigin, zorigin, sinrot, cosrot, xorigin_new, yorigin_new, zorigin_new, sinrot_new, cosrot_new, invert)
 Compose an affine transform onto an existing one, or remove (invert) it. More...
 
subroutine defaults (xorigin, yorigin, zorigin, sinrot, cosrot, invert, translate, rotate, xorigin_opt, yorigin_opt, zorigin_opt, sinrot_opt, cosrot_opt, invert_opt)
 Process arguments and set defaults. Internal use only. More...
 
real(dp) function, public area (xv, yv, cw)
 Calculate polygon area, with vertices given in CW or CCW order. More...
 
pure real(dp) function, public polygon_extent (xv, yv)
 Calculate the maximum distance between two polygon vertices. More...
 
subroutine, public shared_face (iverts1, iverts2, iface)
 Find the lateral face shared by two cells. More...
 
subroutine, public clamp_bary (alpha, beta, gamma, pad)
 Clamp barycentric coordinates to the interior of a triangle, with optional padding some minimum distance from any face. More...
 

Function/Subroutine Documentation

◆ area()

real(dp) function, public geomutilmodule::area ( real(dp), dimension(:), intent(in)  xv,
real(dp), dimension(:), intent(in)  yv,
logical(lgp), intent(in), optional  cw 
)

Definition at line 363 of file GeomUtil.f90.

364  ! dummy
365  real(DP), dimension(:), intent(in) :: xv
366  real(DP), dimension(:), intent(in) :: yv
367  logical(LGP), intent(in), optional :: cw
368  ! result
369  real(DP) :: a
370  integer(I4B) :: s
371 
372  if (present(cw)) then
373  if (cw) then
374  s = 1
375  else
376  s = -1
377  end if
378  else
379  s = 1
380  end if
381 
382  a = -dhalf * sum(xv(:) * cshift(yv(:), s) - cshift(xv(:), s) * yv(:))
383 

◆ between()

logical function, public geomutilmodule::between ( real(dp), intent(in)  x,
real(dp), intent(in)  a,
real(dp), intent(in)  b 
)

Definition at line 16 of file GeomUtil.f90.

17  real(DP), intent(in) :: x, a, b
18  between = ((x >= a .and. x <= b) .or. (x <= a .and. x >= b))
Here is the caller graph for this function:

◆ clamp_bary()

subroutine, public geomutilmodule::clamp_bary ( real(dp), intent(inout)  alpha,
real(dp), intent(inout)  beta,
real(dp), intent(out)  gamma,
real(dp), intent(in), optional  pad 
)

This routine requires 0 <= tol <= 1/3 and 1 = alpha + beta + gamma.

Definition at line 484 of file GeomUtil.f90.

485  ! dummy
486  real(DP), intent(inout) :: alpha
487  real(DP), intent(inout) :: beta
488  real(DP), intent(out) :: gamma
489  real(DP), intent(in), optional :: pad
490  ! local
491  real(DP) :: lolimit
492  real(DP) :: hilimit
493  real(DP) :: delta
494  real(DP) :: lpad
495 
496  if (present(pad)) then
497  lpad = pad
498  if (pad < dzero .or. pad > donethird) &
499  call pstop(1, "pad must be between 0 and 1/3, inclusive")
500  else
501  lpad = dzero
502  end if
503 
504  gamma = done - alpha - beta
505  lolimit = lpad
506  hilimit = done - dtwo * lpad
507  ! Check alpha coordinate against lower limit
508  if (alpha < lolimit) then
509  ! Alpha is too low, so nudge alpha to lower limit; this is a move
510  ! parallel to the "alpha axis," which also changes gamma
511  alpha = lolimit
512  gamma = done - alpha - beta
513  ! Check beta coordinate against lower limit (which in this
514  ! case is equivalent to checking gamma coordinate against
515  ! upper limit)
516  if (beta < lolimit) then
517  ! Beta is too low (gamma is too high), so nudge beta to lower limit;
518  ! this is a move parallel to the "beta axis," which also changes gamma
519  beta = lolimit
520  gamma = hilimit
521  ! Check beta coordinate against upper limit (which in this
522  ! case is equivalent to checking gamma coordinate against
523  ! lower limit)
524  else if (beta > hilimit) then
525  ! Beta is too high (gamma is too low), so nudge beta to lower limit;
526  ! this is a move parallel to the "beta axis," which also changes gamma
527  beta = hilimit
528  gamma = lolimit
529  end if
530  end if
531  ! Check beta coordinate against lower limit. (If alpha coordinate
532  ! was nudged to lower limit, beta and gamma coordinates have also
533  ! been adjusted as necessary to place particle within subcell, and
534  ! subsequent checks on beta and gamma will evaluate to false, and
535  ! no further adjustments will be made.)
536  if (beta < lolimit) then
537  ! Beta is too low, so nudge beta to lower limit; this is a move
538  ! parallel to the "beta axis," which also changes gamma
539  beta = lolimit
540  gamma = done - alpha - beta
541  ! Check alpha coordinate against lower limit (which in this
542  ! case is equivalent to checking gamma coordinate against
543  ! upper limit)
544  if (alpha < lolimit) then
545  ! Alpha is too low (gamma is too high), so nudge alpha to lower limit;
546  ! this is a move parallel to the "alpha axis," which also changes gamma
547  alpha = lolimit
548  gamma = hilimit
549  ! Check alpha coordinate against upper limit (which in this
550  ! case is equivalent to checking gamma coordinate against
551  ! lower limit)
552  else if (alpha > hilimit) then
553  ! Alpha is too high (gamma is too low), so nudge alpha to lower limit;
554  ! this is a move parallel to the "alpha axis," which also changes gamma
555  alpha = hilimit
556  gamma = lolimit
557  end if
558  end if
559  ! Check gamma coordinate against lower limit.(If alpha and/or beta
560  ! coordinate was nudged to lower limit, gamma coordinate has also
561  ! been adjusted as necessary to place particle within subcell, and
562  ! subsequent check on gamma will evaluate to false, and no further
563  ! adjustment will be made.)
564  if (gamma < lolimit) then
565  ! Gamma is too low, so nudge gamma to lower limit; this is a move
566  ! parallel to the "gamma axis," which also changes alpha and beta
567  delta = dhalf * (lolimit - gamma)
568  gamma = lpad
569  alpha = alpha - delta
570  beta = beta - delta
571  ! Check beta coordinate against lower limit (which in this
572  ! case is equivalent to checking alpha coordinate against
573  ! upper limit)
574  if (beta < lolimit) then
575  ! Beta is too low (alpha is too high), so nudge beta to lower limit;
576  ! this is a move parallel to the "gamma axis," which also changes alpha
577  beta = lolimit
578  alpha = done - beta - gamma
579  ! Check beta coordinate against upper limit (which in this
580  ! case is equivalent to checking gamma coordinate against
581  ! lower limit)
582  else if (beta > hilimit) then
583  ! Beta is too high (alpha is too low), so nudge beta to lower limit;
584  ! this is a move parallel to the "gamma axis," which also changes alpha
585  beta = hilimit
586  alpha = done - beta - gamma
587  end if
588  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ compose()

subroutine, public geomutilmodule::compose ( real(dp)  xorigin,
real(dp)  yorigin,
real(dp)  zorigin,
real(dp)  sinrot,
real(dp)  cosrot,
real(dp), optional  xorigin_new,
real(dp), optional  yorigin_new,
real(dp), optional  zorigin_new,
real(dp), optional  sinrot_new,
real(dp), optional  cosrot_new,
logical(lgp), optional  invert 
)
Parameters
zorigincumulative transform T, origin (in/out)
cosrotcumulative transform T, rotation as (sin, cos) (in/out)
zorigin_newtransform A to compose, origin
cosrot_newtransform A to compose, rotation as (sin, cos)
invertwhether to remove A rather than compose it

Definition at line 247 of file GeomUtil.f90.

252  ! -- dummy
253  real(DP) :: xorigin, yorigin, zorigin !< cumulative transform T, origin (in/out)
254  real(DP) :: sinrot, cosrot !< cumulative transform T, rotation as (sin, cos) (in/out)
255  real(DP), optional :: xorigin_new, yorigin_new, zorigin_new !< transform A to compose, origin
256  real(DP), optional :: sinrot_new, cosrot_new !< transform A to compose, rotation as (sin, cos)
257  logical(LGP), optional :: invert !< whether to remove A rather than compose it
258  ! -- local
259  logical(LGP) :: ltranslate, lrotate, linvert
260  real(DP) :: xa, ya, za, sa, ca !< transform A (origin, then sin/cos of phi)
261  real(DP) :: x0, y0, z0, s0, c0 !< incoming T (origin, then sin/cos of its angle)
262 
263  ! -- Process option arguments and set defaults and flags
264  call defaults(xa, ya, za, sa, ca, linvert, &
265  ltranslate, lrotate, &
266  xorigin_new, yorigin_new, zorigin_new, &
267  sinrot_new, cosrot_new, invert)
268 
269  ! -- Copy existing transformation into working copy
270  x0 = xorigin
271  y0 = yorigin
272  z0 = zorigin
273  s0 = sinrot
274  c0 = cosrot
275 
276  ! -- Given transformations A = (a, phi) and T = (t, alpha)
277  ! -- forward: alpha' = alpha + phi, t' = t + R(alpha) a
278  ! -- inverse: alpha = alpha' - phi, t = t' - R(alpha' - phi) a
279  if (.not. linvert) then
280  if (lrotate) then
281  ! -- alpha' = alpha + phi
282  sinrot = ca * s0 + sa * c0
283  cosrot = ca * c0 - sa * s0
284  end if
285  if (ltranslate) then
286  ! -- t' = t + R(alpha) a, with R(alpha) built from the incoming (s0, c0)
287  xorigin = x0 + (c0 * xa - s0 * ya)
288  yorigin = y0 + (s0 * xa + c0 * ya)
289  zorigin = z0 + za
290  end if
291  else
292  if (lrotate) then
293  ! -- alpha = alpha' - phi
294  ! -- (sinrot, cosrot) now hold R(alpha' - phi)
295  sinrot = ca * s0 - sa * c0
296  cosrot = ca * c0 + sa * s0
297  end if
298  if (ltranslate) then
299  ! -- t = t' - R(alpha' - phi) a. For phi = 0 this is t' - R(alpha') a.
300  ! -- if A carries no rotation, (sinrot, cosrot) still hold R(alpha').
301  xorigin = x0 - (cosrot * xa - sinrot * ya)
302  yorigin = y0 - (sinrot * xa + cosrot * ya)
303  zorigin = z0 - za
304  end if
305  end if
Here is the call graph for this function:
Here is the caller graph for this function:

◆ defaults()

subroutine geomutilmodule::defaults ( real(dp)  xorigin,
real(dp)  yorigin,
real(dp)  zorigin,
real(dp)  sinrot,
real(dp)  cosrot,
logical(lgp)  invert,
logical(lgp)  translate,
logical(lgp)  rotate,
real(dp), optional  xorigin_opt,
real(dp), optional  yorigin_opt,
real(dp), optional  zorigin_opt,
real(dp), optional  sinrot_opt,
real(dp), optional  cosrot_opt,
logical(lgp), optional  invert_opt 
)
private

Definition at line 309 of file GeomUtil.f90.

314  ! -- dummy
315  real(DP) :: xorigin, yorigin, zorigin
316  real(DP) :: sinrot, cosrot
317  logical(LGP) :: invert, translate, rotate
318  real(DP), optional :: xorigin_opt, yorigin_opt, zorigin_opt
319  real(DP), optional :: sinrot_opt, cosrot_opt
320  logical(LGP), optional :: invert_opt
321 
322  translate = .false.
323  xorigin = dzero
324  if (present(xorigin_opt)) then
325  xorigin = xorigin_opt
326  translate = .true.
327  end if
328  yorigin = dzero
329  if (present(yorigin_opt)) then
330  yorigin = yorigin_opt
331  translate = .true.
332  end if
333  zorigin = dzero
334  if (present(zorigin_opt)) then
335  zorigin = zorigin_opt
336  translate = .true.
337  end if
338  rotate = .false.
339  sinrot = dzero
340  cosrot = done
341  if (present(sinrot_opt)) then
342  sinrot = sinrot_opt
343  if (present(cosrot_opt)) then
344  cosrot = cosrot_opt
345  else
346  ! -- If sinrot_opt is specified but cosrot_opt is not,
347  ! -- default to corresponding non-negative cosrot
348  cosrot = dsqrt(done - sinrot * sinrot)
349  end if
350  rotate = .true.
351  else if (present(cosrot_opt)) then
352  cosrot = cosrot_opt
353  ! -- cosrot_opt is specified but sinrot_opt is not, so
354  ! -- default to corresponding non-negative sinrot
355  sinrot = dsqrt(done - cosrot * cosrot)
356  rotate = .true.
357  end if
358  invert = .false.
359  if (present(invert_opt)) invert = invert_opt
Here is the caller graph for this function:

◆ get_ijk()

subroutine, public geomutilmodule::get_ijk ( integer(i4b), intent(in)  nodenumber,
integer(i4b), intent(in)  nrow,
integer(i4b), intent(in)  ncol,
integer(i4b), intent(in)  nlay,
integer(i4b), intent(out)  irow,
integer(i4b), intent(out)  icol,
integer(i4b), intent(out)  ilay 
)

Definition at line 108 of file GeomUtil.f90.

109  ! -- dummy variables
110  integer(I4B), intent(in) :: nodenumber
111  integer(I4B), intent(in) :: nrow
112  integer(I4B), intent(in) :: ncol
113  integer(I4B), intent(in) :: nlay
114  integer(I4B), intent(out) :: irow
115  integer(I4B), intent(out) :: icol
116  integer(I4B), intent(out) :: ilay
117  ! -- local variables
118  integer(I4B) :: nodes
119  integer(I4B) :: ij
120 
121  nodes = nlay * nrow * ncol
122  if (nodenumber < 1 .or. nodenumber > nodes) then
123  irow = -1
124  icol = -1
125  ilay = -1
126  else
127  ilay = (nodenumber - 1) / (ncol * nrow) + 1
128  ij = nodenumber - (ilay - 1) * ncol * nrow
129  irow = (ij - 1) / ncol + 1
130  icol = ij - (irow - 1) * ncol
131  end if
Here is the caller graph for this function:

◆ get_jk()

subroutine, public geomutilmodule::get_jk ( integer(i4b), intent(in)  nodenumber,
integer(i4b), intent(in)  ncpl,
integer(i4b), intent(in)  nlay,
integer(i4b), intent(out)  icpl,
integer(i4b), intent(out)  ilay 
)

Definition at line 136 of file GeomUtil.f90.

137  ! -- dummy variables
138  integer(I4B), intent(in) :: nodenumber
139  integer(I4B), intent(in) :: ncpl
140  integer(I4B), intent(in) :: nlay
141  integer(I4B), intent(out) :: icpl
142  integer(I4B), intent(out) :: ilay
143  ! -- local variables
144  integer(I4B) :: nodes
145 
146  nodes = ncpl * nlay
147  if (nodenumber < 1 .or. nodenumber > nodes) then
148  icpl = -1
149  ilay = -1
150  else
151  ilay = (nodenumber - 1) / ncpl + 1
152  icpl = nodenumber - (ilay - 1) * ncpl
153  end if
Here is the caller graph for this function:

◆ get_node()

integer(i4b) function, public geomutilmodule::get_node ( integer(i4b), intent(in)  ilay,
integer(i4b), intent(in)  irow,
integer(i4b), intent(in)  icol,
integer(i4b), intent(in)  nlay,
integer(i4b), intent(in)  nrow,
integer(i4b), intent(in)  ncol 
)

Definition at line 91 of file GeomUtil.f90.

92  integer(I4B), intent(in) :: ilay, irow, icol, nlay, nrow, ncol
93  integer(I4B) :: get_node
94 
95  if (nlay > 0 .and. nrow > 0 .and. ncol > 0 .and. &
96  ilay > 0 .and. ilay <= nlay .and. &
97  irow > 0 .and. irow <= nrow .and. &
98  icol > 0 .and. icol <= ncol) then
99  get_node = &
100  icol + ncol * (irow - 1) + (ilay - 1) * nrow * ncol
101  else
102  get_node = -1
103  end if
Here is the caller graph for this function:

◆ point_in_polygon()

logical function, public geomutilmodule::point_in_polygon ( real(dp), intent(in)  x,
real(dp), intent(in)  y,
real(dp), dimension(:, :), intent(in), allocatable  poly,
real(dp), intent(in), optional  tol 
)

Vertices and edge points are considered in the polygon. By default, a point must lie exactly on an edge to be considered within the polygon. A tolerance may be specified to instead accept coordinates within tol of an edge.

Adapted from https://stackoverflow.com/a/63436180/6514033,

Parameters
[in]xx point coordinate
[in]yy point coordinate
[in]polypolygon vertices (column-major indexing)
[in]toltolerance (default 0)

Definition at line 30 of file GeomUtil.f90.

31  ! dummy
32  real(DP), intent(in) :: x !< x point coordinate
33  real(DP), intent(in) :: y !< y point coordinate
34  real(DP), allocatable, intent(in) :: poly(:, :) !< polygon vertices (column-major indexing)
35  real(DP), intent(in), optional :: tol !< tolerance (default 0)
36  ! local
37  integer(I4B) :: i, ii, num_verts
38  real(DP) :: xa, xb, ya, yb, c
39  real(DP) :: ltol
40 
41  ltol = dzero
42  if (present(tol)) ltol = tol
43 
44  point_in_polygon = .false.
45  num_verts = size(poly, 2)
46  xa = poly(1, num_verts)
47  ya = poly(2, num_verts)
48 
49  do i = 0, num_verts - 1
50  ii = mod(i, num_verts) + 1
51  xb = poly(1, ii)
52  yb = poly(2, ii)
53 
54  if ((x == xa .and. y == ya) .or. &
55  (x == xb .and. y == yb)) then
56  ! on vertex
57  point_in_polygon = .true.
58  exit
59  else if (ya == yb .and. &
60  abs(y - ya) * abs(xb - xa) <= ltol .and. &
61  between(x, xa, xb)) then
62  ! on (or within tol of) horizontal edge
63  point_in_polygon = .true.
64  exit
65  else if (between(y, ya, yb)) then
66  if ((y == ya .and. yb >= ya) .or. &
67  (y == yb .and. ya >= yb)) then
68  xa = xb
69  ya = yb
70  cycle
71  end if
72  ! cross product
73  c = (xa - x) * (yb - y) - (xb - x) * (ya - y)
74  if (abs(c) <= ltol) then
75  ! on (or within tol of) edge
76  point_in_polygon = .true.
77  exit
78  else if ((ya < yb) .eqv. (c > 0)) then
79  ! ray intersection
80  point_in_polygon = .not. point_in_polygon
81  end if
82  end if
83 
84  xa = xb
85  ya = yb
86  end do
Here is the call graph for this function:
Here is the caller graph for this function:

◆ polygon_extent()

pure real(dp) function, public geomutilmodule::polygon_extent ( real(dp), dimension(:), intent(in)  xv,
real(dp), dimension(:), intent(in)  yv 
)

Definition at line 387 of file GeomUtil.f90.

388  ! dummy
389  real(DP), dimension(:), intent(in) :: xv
390  real(DP), dimension(:), intent(in) :: yv
391  ! result
392  real(DP) :: e
393  ! local
394  integer(I4B) :: i
395  integer(I4B) :: j
396  real(DP) :: dx
397  real(DP) :: dy
398 
399  e = dzero
400  do i = 1, size(xv) - 1
401  do j = i + 1, size(xv)
402  dx = xv(i) - xv(j)
403  dy = yv(i) - yv(j)
404  e = max(e, dx * dx + dy * dy)
405  end do
406  end do
407  e = sqrt(e)
408 
Here is the caller graph for this function:

◆ shared_face()

subroutine, public geomutilmodule::shared_face ( integer(i4b), dimension(:)  iverts1,
integer(i4b), dimension(:)  iverts2,
integer(i4b), intent(out)  iface 
)

Find the lateral (x-y plane) face shared by the given cells. The iface return argument will be 0 if they share no such face, otherwise the index of the shared face in cell 1's vertex array, where face N connects vertex N to vertex N + 1 going clockwise.

Note: assumes the cells are convex and share at most 2 vertices and that both vertex arrays are oriented clockwise.

Definition at line 421 of file GeomUtil.f90.

422  integer(I4B), dimension(:) :: iverts1
423  integer(I4B), dimension(:) :: iverts2
424  integer(I4B), intent(out) :: iface
425  integer(I4B) :: nv1
426  integer(I4B) :: nv2
427  integer(I4B) :: il1, iil1
428  integer(I4B) :: il2, iil2
429  logical(LGP) :: found
430  logical(LGP) :: wrapped
431 
432  iface = 0
433  found = .false.
434  nv1 = size(iverts1)
435  nv2 = size(iverts2)
436  wrapped = iverts1(1) == iverts1(nv1)
437 
438  ! Find a vertex shared by the cells, then check the adjacent faces.
439  ! If the cells share a face, it must be one of these. When looking
440  ! forward in the 1st cell's vertices, look backwards in the 2nd's,
441  ! and vice versa, since a clockwise face in cell 1 must correspond
442  ! to a counter-clockwise face in cell 2.
443  outerloop: do il1 = 1, nv1 - 1
444  do il2 = 1, nv2 - 1
445  if (iverts1(il1) == iverts2(il2)) then
446 
447  iil1 = il1 + 1
448  if (il2 == 1) then
449  iil2 = nv2
450  if (wrapped) iil2 = iil2 - 1
451  else
452  iil2 = il2 - 1
453  end if
454  if (iverts1(iil1) == iverts2(iil2)) then
455  found = .true.
456  iface = il1
457  exit outerloop
458  end if
459 
460  iil2 = il2 + 1
461  if (il1 == 1) then
462  iil1 = nv1
463  if (wrapped) iil1 = iil1 - 1
464  else
465  iil1 = il1 - 1
466  end if
467  if (iverts1(iil1) == iverts2(iil2)) then
468  found = .true.
469  iface = iil1
470  exit outerloop
471  end if
472 
473  end if
474  end do
475  if (found) exit
476  end do outerloop
Here is the caller graph for this function:

◆ skew()

pure real(dp) function, dimension(2), public geomutilmodule::skew ( real(dp), dimension(2), intent(in)  v,
real(dp), dimension(3), intent(in)  s,
logical(lgp), intent(in), optional  invert 
)
Parameters
[in]vvector
[in]sskew matrix entries (top left, top right, bottom right)

Definition at line 157 of file GeomUtil.f90.

158  ! -- dummy
159  real(DP), intent(in) :: v(2) !< vector
160  real(DP), intent(in) :: s(3) !< skew matrix entries (top left, top right, bottom right)
161  logical(LGP), intent(in), optional :: invert
162  real(DP) :: res(2)
163  ! -- local
164  logical(LGP) :: linvert
165  real(DP) :: sxx, sxy, syy
166 
167  ! -- process optional arguments
168  if (present(invert)) then
169  linvert = invert
170  else
171  linvert = .false.
172  end if
173 
174  sxx = s(1)
175  sxy = s(2)
176  syy = s(3)
177  if (.not. linvert) then
178  res(1) = sxx * v(1) + sxy * v(2)
179  res(2) = syy * v(2)
180  else
181  res(2) = v(2) / syy
182  res(1) = (v(1) - sxy * res(2)) / sxx
183  end if
Here is the caller graph for this function:

◆ transform()

subroutine, public geomutilmodule::transform ( real(dp)  xin,
real(dp)  yin,
real(dp)  zin,
real(dp)  xout,
real(dp)  yout,
real(dp)  zout,
real(dp), optional  xorigin,
real(dp), optional  yorigin,
real(dp), optional  zorigin,
real(dp), optional  sinrot,
real(dp), optional  cosrot,
logical(lgp), optional  invert 
)
Parameters
zininput coordinates
zoutoutput coordinates
zoriginorigin coordinates
cosrotsine and cosine of rotation
invertwhether to invert

Definition at line 187 of file GeomUtil.f90.

192  ! -- dummy
193  real(DP) :: xin, yin, zin !< input coordinates
194  real(DP) :: xout, yout, zout !< output coordinates
195  real(DP), optional :: xorigin, yorigin, zorigin !< origin coordinates
196  real(DP), optional :: sinrot, cosrot !< sine and cosine of rotation
197  logical(LGP), optional :: invert !< whether to invert
198  ! -- local
199  logical(LGP) :: ltranslate, lrotate, linvert
200  real(DP) :: x, y
201  real(DP) :: lxorigin, lyorigin, lzorigin
202  real(DP) :: lsinrot, lcosrot
203 
204  ! -- Process option arguments and set defaults and flags
205  call defaults(lxorigin, lyorigin, lzorigin, &
206  lsinrot, lcosrot, linvert, &
207  ltranslate, lrotate, &
208  xorigin, yorigin, zorigin, &
209  sinrot, cosrot, invert)
210 
211  ! -- Apply transformation or its inverse
212  if (.not. linvert) then
213  ! -- Apply transformation to coordinates
214  if (ltranslate) then
215  xout = xin - lxorigin
216  yout = yin - lyorigin
217  zout = zin - lzorigin
218  else
219  xout = lxorigin
220  yout = lyorigin
221  zout = lzorigin
222  end if
223  if (lrotate) then
224  x = xout
225  y = yout
226  xout = x * lcosrot + y * lsinrot
227  yout = -x * lsinrot + y * lcosrot
228  end if
229  else
230  ! -- Apply inverse of transformation to coordinates
231  if (lrotate) then
232  x = xin * lcosrot - yin * lsinrot
233  y = xin * lsinrot + yin * lcosrot
234  else
235  x = xin
236  y = yin
237  end if
238  if (ltranslate) then
239  xout = x + lxorigin
240  yout = y + lyorigin
241  zout = zin + lzorigin
242  end if
243  end if
Here is the call graph for this function:
Here is the caller graph for this function: