MODFLOW 6 version 6.9.0.dev0
USGS Modular Hydrologic Model
Loading...
Searching...
No Matches
geomutilmodule Module Reference

Functions/Subroutines

logical function, public between (x, a, b)
 Check if a value is between two other values (inclusive).
logical function, public point_in_polygon (x, y, poly, tol)
 Check if a point is within a polygon.
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.
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.
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.
pure real(dp) function, dimension(2), public skew (v, s, invert)
 Skew a 2D vector along the x-axis.
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.
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.
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.
real(dp) function, public area (xv, yv, cw)
 Calculate polygon area, with vertices given in CW or CCW order.
pure real(dp) function, public polygon_extent (xv, yv)
 Calculate the maximum distance between two polygon vertices.
subroutine, public shared_face (iverts1, iverts2, iface)
 Find the lateral face shared by two cells.
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.

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
Here is the caller graph for this function:

◆ 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 call graph for this function:
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 call graph for this function:
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: