subroutine apttlod (ax, ay, az, bx, by, bz, cx, cy, cz, & np, kloc, tol, px, py, pz, wa, wb, wc, nerr) ccbeg. cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc c c SUBROUTINE APTTLOD c c call apttlod (ax, ay, az, bx, by, bz, cx, cy, cz, c & np, kloc, tol, px, py, pz, wa, wb, wc, nerr) c c Version: apttlod Updated 1990 December 3 16:20. c apttlod Originated 1990 February 8 14:30. c c Author: Arthur L. Edwards, LLNL, L-298, Telephone (925) 422-4123. c c c Purpose: To randomly sample np spatial points p = (px, py, pz) from a c uniform distribution over the triangle in 3-D space with c vertices a = (ax, ay, az), b = (bx, by, bz), c = (cx, cy, cz), c in any order around the triangle, and optionally (kloc = 1), to c return the local coordinates wa, wb and wc for each point "p": c c vn = (b - a) X (c - b) = (c - b) X (a - c) = (a - c) X (b - a) c c wa = (vn . (c - b) X (p - c)) / vn**2 c wb = (vn . (a - c) X (p - a)) / vn**2 c wb = (vn . (b - a) X (p - b)) / vn**2 c c p = wa * a + wb * b + wc * c c c where "X" indicates the vector product, and "." indicates the c dot product. c c The relationship of the triangle local coordinates wa, wb and wc c to the quadrangle local coordinates fdk and fdl is as follows: c c wa = 1 - fdk fdk = wb + wc c wb = fdk * (1 - fdl) fdl = wc / (wb + wc) c wc = fdk * fdl c c where fdk is the fractional distance from edge "aa" to edge c "bc", and fdl is the fractional distance from edge "ab" to c edge "ca", and any point "p" is given by: c c p = a + fdk * (b - a) + fdk * fdl * (c - b) c c Flag nerr indicates any input error. c c History: 1990 May 10 16:10. Replaced arguments fdk, fdl with wa, wb, wc, c and made calculation and return of wa, wb and wc optional, c based on new input argument kloc. c 1990 May 11 10:00. Replaced apttlod arguments fdk, fdl with c kloc, twa, twb, twc. c c Input: ax, ay, az, bx, by, bz, cx, cy, cz, np, kloc, tol. c c Output: px, py, pz, wa, wb, wc, nerr. c c Calls: aptslid c c Glossary: c c ax,ay,az Input The x, y, z coordinates of vertex "a" of triangle. c c bx,by,bz Input The x, y, z coordinates of vertex "b" of triangle. c c cx,cy,cz Input The x, y, z coordinates of vertex "c" of triangle. c c kloc Input Indicates local coordinates wa, wb and wc are to be c returned, if 1. Otherwise, 0. c c nerr Output Indicates an input error, if not 0. c 1 if np is not positive. c 2 if kloc is not 0 or 1. c c np Input Size of arrays wa, wb, wc, px, py, pz. c Number of points "p" to sample. c c px,py,pz Output Sampled point "p". Size np. Coordinates may be c truncated to zero, if less than the estimated error c in their calculation, based on tol. c c tol Input Numerical tolerance limit. c On Cray computers, recommend 1.e-5 to 1.e-11. c c wa Output Fractional distance of point "p" to vertex "a" from c edge "bc". Size np. c c wb Output Fractional distance of point "p" to vertex "b" from c edge "ca". Size np. c c wc Output Fractional distance of point "p" to vertex "c" from c edge "ab". Size np. c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ccend. c.... Dimensioned arguments. c---- Cooodinate x of a sampled point "p". dimension px (1) c---- Coordinate y of a sampled point "p". dimension py (1) c---- Coordinate z of a sampled point "p". dimension pz (1) c---- Fractional distance to "a" from "bc". dimension wa (1) c---- Fractional distance to "b" from "ca". dimension wb (1) c---- Fractional distance to "c" from "ab". dimension wc (1) c.... Local variables. c---- Fractional distance from "a" to "bc". common /lapttlod/ fdk (64) c---- Fractional distance from "ab" to "ca". common /lapttlod/ fdl (64) c---- Index in local array. common /lapttlod/ n c---- First index of subset of data. common /lapttlod/ n1 c---- Last index of subset of data. common /lapttlod/ n2 c---- Index in external array. common /lapttlod/ nn c---- Size of current subset of data. common /lapttlod/ ns c---- Estimated error in px. common /lapttlod/ pxerr c---- Estimated error in py. common /lapttlod/ pyerr c---- Estimated error in pz. common /lapttlod/ pzerr cbugc***DEBUG begins. cbug common /lapttlod/ avgx, avgy, avgz, devx, devy, devz cbug common /lapttlod/ avgx2, avgy2, avgz2 cbug common /lapttlod/ avgwa, avgwb, avgwc cbug common /lapttlod/ devwa, devwb, devwc cbug common /lapttlod/ avgwa2, avgwb2, avgwc2 cbug 9901 format (/ 'apttlod sampling from a triangle. np=',i3 / cbug & ' ax,ay,az=',1p3e22.14 / cbug & ' bx,by,bz=',1p3e22.14 / cbug & ' cx,cy,cz=',1p3e22.14) cbug write (3, 9901) np, ax, ay, az, bx, by, bz, cx, cy, cz cbugc***DEBUG ends. c.... initialize. nerr = 0 c.... Test for input errors. if (np .le. 0) then nerr = 1 go to 210 endif if ((kloc .lt. 0) .or. (kloc .gt. 1)) then nerr = 2 go to 210 endif c.... Set up the indices of the first subset of data. n1 = 1 n2 = min (np, 64) c.... Loop over the data subsets. 110 ns = n2 - n1 + 1 c.... Sample ns values of fdk from a linear distribution, with c.... probability 0.0 at vertex "a", probability 2.0 at edge "bc". call aptslid (0.0, 0.0, 1.0, 2.0, ns, fdk, nerr) c.... Sample ns values of fdl from a uniform distribution, with c.... equal probabilities at sides "ab" and "ca". c---- Loop over subset of data. do 120 n = 1, ns fdl(n) = ranf( ) c---- End of loop over subset of data. 120 continue c.... Find the coordinates of the points. c---- Loop over subset of data. do 130 n = 1, ns nn = n + n1 - 1 px(nn) = ax + fdk(n) * (bx - ax) + fdk(n) * fdl(n) * (cx - bx) py(nn) = ay + fdk(n) * (by - ay) + fdk(n) * fdl(n) * (cy - by) pz(nn) = az + fdk(n) * (bz - az) + fdk(n) * fdl(n) * (cz - bz) c---- End of loop over subset of data. 130 continue c.... See if truncation allowed. c---- Truncation to zero allowed. if (tol .gt. 0.0) then c---- Loop over subset of data. do 140 n = 1, ns nn = n + n1 - 1 pxerr = tol * (fdk(n) * abs (bx - ax) + & fdk(n) * fdl(n) * abs (cx - bx)) pyerr = tol * (fdk(n) * abs (by - ay) + & fdk(n) * fdl(n) * abs (cy - by)) pzerr = tol * (fdk(n) * abs (bz - az) + & fdk(n) * fdl(n) * abs (cz - bz)) if (abs (px(nn)) .lt. pxerr) then px(nn) = 0.0 endif if (abs (py(nn)) .lt. pyerr) then py(nn) = 0.0 endif if (abs (pz(nn)) .lt. pzerr) then pz(nn) = 0.0 endif c---- End of loop over subset of data. 140 continue c---- Tested tol. endif c.... See if the local triangular coordinates are to be returned. c---- Find local triangular coordinates. if (kloc .eq. 1) then c---- Loop over subset of data. do 150 n = 1, ns nn = n + n1 - 1 wa(nn) = 1.0 - fdk(n) wb(nn) = fdk(n) * (1.0 - fdl(n)) wc(nn) = fdk(n) * fdl(n) c---- End of loop over subset of data. 150 continue c---- Tested kloc. endif c.... See if all data subsets are done. c---- Do another subset of data. if (n2 .lt. np) then n1 = n2 + 1 n2 = min (np, n1 + 63) go to 110 endif cbugc***DEBUG begins. cbug cbug avgx = 0.0 cbug avgy = 0.0 cbug avgz = 0.0 cbug avgx2 = 0.0 cbug avgy2 = 0.0 cbug avgz2 = 0.0 cbug cbug do 160 n = 1, np cbug avgx = avgx + px(n) cbug avgy = avgy + py(n) cbug avgz = avgz + pz(n) cbug avgx2 = avgx2 + px(n)**2 cbug avgy2 = avgy2 + py(n)**2 cbug avgz2 = avgz2 + pz(n)**2 cbug 160 continue cbug cbug avgx = avgx / np cbug avgy = avgy / np cbug avgz = avgz / np cbug avgx2 = avgx2 / np cbug avgy2 = avgy2 / np cbug avgz2 = avgz2 / np cbug devx = sqrt (avgx2 - avgx**2) cbug devy = sqrt (avgy2 - avgy**2) cbug devz = sqrt (avgz2 - avgz**2) cbug cbug 9902 format (/ 'apttlod results:') cbug 9903 format (i3,' px,py,pz=',1p3e22.14) cbug 9904 format (/ 'apttlod mean and deviation:' / cbug & ' avg(x,y,z)=',1p3e22.14 / cbug & ' dev(x,y,z)=',1p3e22.14) cbug cbug write ( 3, 9902) cbug write ( 3, 9903) (n, px(n), py(n), pz(n), n = 1, np) cbug write ( 3, 9904) avgx, avgy, avgz, devx, devy, devz cbug cbugc---- Local coordinates returned. cbug if (kloc .eq. 1) then cbug cbug avgwa = 0.0 cbug avgwb = 0.0 cbug avgwc = 0.0 cbug avgwa2 = 0.0 cbug avgwb2 = 0.0 cbug avgwc2 = 0.0 cbug cbug do 170 n = 1, np cbug avgwa = avgwa + wa(n) cbug avgwb = avgwb + wb(n) cbug avgwc = avgwc + wc(n) cbug avgwa2 = avgwa2 + wa(n)**2 cbug avgwb2 = avgwb2 + wb(n)**2 cbug avgwc2 = avgwc2 + wc(n)**2 cbug 170 continue cbug cbug avgwa = avgwa / np cbug avgwb = avgwb / np cbug avgwc = avgwc / np cbug avgwa2 = avgwa2 / np cbug avgwb2 = avgwb2 / np cbug avgwc2 = avgwc2 / np cbug devwa = sqrt (avgwa2 - avgwa**2) cbug devwb = sqrt (avgwb2 - avgwb**2) cbug devwc = sqrt (avgwc2 - avgwc**2) cbug cbug 9905 format (i3,' wa,wb,wc=',1p3e22.14) cbug 9906 format (/ 'apttlod mean and deviation:' / cbug & ' avgw(a,b,c)=',1p3e22.14 / cbug & ' devw(a,b,c)=',1p3e22.14) cbug cbug write ( 3, 9905) (n, wa(n), wb(n), wc(n), n = 1, np) cbug write ( 3, 9906) avgwa, avgwb, avgwc, cbug & devwa, devwb, devwc cbug cbugc---- Tested kloc. cbug endif cbugc***DEBUG ends. 210 return c.... End of subroutine apttlod. (+1 line.) end UCRL-WEB-209832