dsilus.f 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361
  1. *DECK DSILUS
  2. SUBROUTINE DSILUS (N, NELT, IA, JA, A, ISYM, NL, IL, JL, L, DINV,
  3. + NU, IU, JU, U, NROW, NCOL)
  4. C***BEGIN PROLOGUE DSILUS
  5. C***PURPOSE Incomplete LU Decomposition Preconditioner SLAP Set Up.
  6. C Routine to generate the incomplete LDU decomposition of a
  7. C matrix. The unit lower triangular factor L is stored by
  8. C rows and the unit upper triangular factor U is stored by
  9. C columns. The inverse of the diagonal matrix D is stored.
  10. C No fill in is allowed.
  11. C***LIBRARY SLATEC (SLAP)
  12. C***CATEGORY D2E
  13. C***TYPE DOUBLE PRECISION (SSILUS-S, DSILUS-D)
  14. C***KEYWORDS INCOMPLETE LU FACTORIZATION, ITERATIVE PRECONDITION,
  15. C NON-SYMMETRIC LINEAR SYSTEM, SLAP, SPARSE
  16. C***AUTHOR Greenbaum, Anne, (Courant Institute)
  17. C Seager, Mark K., (LLNL)
  18. C Lawrence Livermore National Laboratory
  19. C PO BOX 808, L-60
  20. C Livermore, CA 94550 (510) 423-3141
  21. C seager@llnl.gov
  22. C***DESCRIPTION
  23. C
  24. C *Usage:
  25. C INTEGER N, NELT, IA(NELT), JA(NELT), ISYM
  26. C INTEGER NL, IL(NL), JL(NL), NU, IU(NU), JU(NU)
  27. C INTEGER NROW(N), NCOL(N)
  28. C DOUBLE PRECISION A(NELT), L(NL), DINV(N), U(NU)
  29. C
  30. C CALL DSILUS( N, NELT, IA, JA, A, ISYM, NL, IL, JL, L,
  31. C $ DINV, NU, IU, JU, U, NROW, NCOL )
  32. C
  33. C *Arguments:
  34. C N :IN Integer
  35. C Order of the Matrix.
  36. C NELT :IN Integer.
  37. C Number of elements in arrays IA, JA, and A.
  38. C IA :IN Integer IA(NELT).
  39. C JA :IN Integer JA(NELT).
  40. C A :IN Double Precision A(NELT).
  41. C These arrays should hold the matrix A in the SLAP Column
  42. C format. See "Description", below.
  43. C ISYM :IN Integer.
  44. C Flag to indicate symmetric storage format.
  45. C If ISYM=0, all non-zero entries of the matrix are stored.
  46. C If ISYM=1, the matrix is symmetric, and only the lower
  47. C triangle of the matrix is stored.
  48. C NL :OUT Integer.
  49. C Number of non-zeros in the L array.
  50. C IL :OUT Integer IL(NL).
  51. C JL :OUT Integer JL(NL).
  52. C L :OUT Double Precision L(NL).
  53. C IL, JL, L contain the unit lower triangular factor of the
  54. C incomplete decomposition of some matrix stored in SLAP
  55. C Row format. The Diagonal of ones *IS* stored. See
  56. C "DESCRIPTION", below for more details about the SLAP format.
  57. C NU :OUT Integer.
  58. C Number of non-zeros in the U array.
  59. C IU :OUT Integer IU(NU).
  60. C JU :OUT Integer JU(NU).
  61. C U :OUT Double Precision U(NU).
  62. C IU, JU, U contain the unit upper triangular factor of the
  63. C incomplete decomposition of some matrix stored in SLAP
  64. C Column format. The Diagonal of ones *IS* stored. See
  65. C "Description", below for more details about the SLAP
  66. C format.
  67. C NROW :WORK Integer NROW(N).
  68. C NROW(I) is the number of non-zero elements in the I-th row
  69. C of L.
  70. C NCOL :WORK Integer NCOL(N).
  71. C NCOL(I) is the number of non-zero elements in the I-th
  72. C column of U.
  73. C
  74. C *Description
  75. C IL, JL, L should contain the unit lower triangular factor of
  76. C the incomplete decomposition of the A matrix stored in SLAP
  77. C Row format. IU, JU, U should contain the unit upper factor
  78. C of the incomplete decomposition of the A matrix stored in
  79. C SLAP Column format This ILU factorization can be computed by
  80. C the DSILUS routine. The diagonals (which are all one's) are
  81. C stored.
  82. C
  83. C =================== S L A P Column format ==================
  84. C
  85. C This routine requires that the matrix A be stored in the
  86. C SLAP Column format. In this format the non-zeros are stored
  87. C counting down columns (except for the diagonal entry, which
  88. C must appear first in each "column") and are stored in the
  89. C double precision array A. In other words, for each column
  90. C in the matrix put the diagonal entry in A. Then put in the
  91. C other non-zero elements going down the column (except the
  92. C diagonal) in order. The IA array holds the row index for
  93. C each non-zero. The JA array holds the offsets into the IA,
  94. C A arrays for the beginning of each column. That is,
  95. C IA(JA(ICOL)), A(JA(ICOL)) points to the beginning of the
  96. C ICOL-th column in IA and A. IA(JA(ICOL+1)-1),
  97. C A(JA(ICOL+1)-1) points to the end of the ICOL-th column.
  98. C Note that we always have JA(N+1) = NELT+1, where N is the
  99. C number of columns in the matrix and NELT is the number of
  100. C non-zeros in the matrix.
  101. C
  102. C Here is an example of the SLAP Column storage format for a
  103. C 5x5 Matrix (in the A and IA arrays '|' denotes the end of a
  104. C column):
  105. C
  106. C 5x5 Matrix SLAP Column format for 5x5 matrix on left.
  107. C 1 2 3 4 5 6 7 8 9 10 11
  108. C |11 12 0 0 15| A: 11 21 51 | 22 12 | 33 53 | 44 | 55 15 35
  109. C |21 22 0 0 0| IA: 1 2 5 | 2 1 | 3 5 | 4 | 5 1 3
  110. C | 0 0 33 0 35| JA: 1 4 6 8 9 12
  111. C | 0 0 0 44 0|
  112. C |51 0 53 0 55|
  113. C
  114. C ==================== S L A P Row format ====================
  115. C
  116. C This routine requires that the matrix A be stored in the
  117. C SLAP Row format. In this format the non-zeros are stored
  118. C counting across rows (except for the diagonal entry, which
  119. C must appear first in each "row") and are stored in the
  120. C double precision array A. In other words, for each row in
  121. C the matrix put the diagonal entry in A. Then put in the
  122. C other non-zero elements going across the row (except the
  123. C diagonal) in order. The JA array holds the column index for
  124. C each non-zero. The IA array holds the offsets into the JA,
  125. C A arrays for the beginning of each row. That is,
  126. C JA(IA(IROW)),A(IA(IROW)) are the first elements of the IROW-
  127. C th row in JA and A, and JA(IA(IROW+1)-1), A(IA(IROW+1)-1)
  128. C are the last elements of the IROW-th row. Note that we
  129. C always have IA(N+1) = NELT+1, where N is the number of rows
  130. C in the matrix and NELT is the number of non-zeros in the
  131. C matrix.
  132. C
  133. C Here is an example of the SLAP Row storage format for a 5x5
  134. C Matrix (in the A and JA arrays '|' denotes the end of a row):
  135. C
  136. C 5x5 Matrix SLAP Row format for 5x5 matrix on left.
  137. C 1 2 3 4 5 6 7 8 9 10 11
  138. C |11 12 0 0 15| A: 11 12 15 | 22 21 | 33 35 | 44 | 55 51 53
  139. C |21 22 0 0 0| JA: 1 2 5 | 2 1 | 3 5 | 4 | 5 1 3
  140. C | 0 0 33 0 35| IA: 1 4 6 8 9 12
  141. C | 0 0 0 44 0|
  142. C |51 0 53 0 55|
  143. C
  144. C***SEE ALSO SILUR
  145. C***REFERENCES 1. Gene Golub and Charles Van Loan, Matrix Computations,
  146. C Johns Hopkins University Press, Baltimore, Maryland,
  147. C 1983.
  148. C***ROUTINES CALLED (NONE)
  149. C***REVISION HISTORY (YYMMDD)
  150. C 890404 DATE WRITTEN
  151. C 890404 Previous REVISION DATE
  152. C 890915 Made changes requested at July 1989 CML Meeting. (MKS)
  153. C 890922 Numerous changes to prologue to make closer to SLATEC
  154. C standard. (FNF)
  155. C 890929 Numerous changes to reduce SP/DP differences. (FNF)
  156. C 910411 Prologue converted to Version 4.0 format. (BAB)
  157. C 920511 Added complete declaration section. (WRB)
  158. C 920929 Corrected format of reference. (FNF)
  159. C 930701 Updated CATEGORY section. (FNF, WRB)
  160. C***END PROLOGUE DSILUS
  161. C .. Scalar Arguments ..
  162. INTEGER ISYM, N, NELT, NL, NU
  163. C .. Array Arguments ..
  164. DOUBLE PRECISION A(NELT), DINV(N), L(NL), U(NU)
  165. INTEGER IA(NELT), IL(NL), IU(NU), JA(NELT), JL(NL), JU(NU),
  166. + NCOL(N), NROW(N)
  167. C .. Local Scalars ..
  168. DOUBLE PRECISION TEMP
  169. INTEGER I, IBGN, ICOL, IEND, INDX, INDX1, INDX2, INDXC1, INDXC2,
  170. + INDXR1, INDXR2, IROW, ITEMP, J, JBGN, JEND, JTEMP, K, KC,
  171. + KR
  172. C***FIRST EXECUTABLE STATEMENT DSILUS
  173. C
  174. C Count number of elements in each row of the lower triangle.
  175. C
  176. DO 10 I=1,N
  177. NROW(I) = 0
  178. NCOL(I) = 0
  179. 10 CONTINUE
  180. CVD$R NOCONCUR
  181. CVD$R NOVECTOR
  182. DO 30 ICOL = 1, N
  183. JBGN = JA(ICOL)+1
  184. JEND = JA(ICOL+1)-1
  185. IF( JBGN.LE.JEND ) THEN
  186. DO 20 J = JBGN, JEND
  187. IF( IA(J).LT.ICOL ) THEN
  188. NCOL(ICOL) = NCOL(ICOL) + 1
  189. ELSE
  190. NROW(IA(J)) = NROW(IA(J)) + 1
  191. IF( ISYM.NE.0 ) NCOL(IA(J)) = NCOL(IA(J)) + 1
  192. ENDIF
  193. 20 CONTINUE
  194. ENDIF
  195. 30 CONTINUE
  196. JU(1) = 1
  197. IL(1) = 1
  198. DO 40 ICOL = 1, N
  199. IL(ICOL+1) = IL(ICOL) + NROW(ICOL)
  200. JU(ICOL+1) = JU(ICOL) + NCOL(ICOL)
  201. NROW(ICOL) = IL(ICOL)
  202. NCOL(ICOL) = JU(ICOL)
  203. 40 CONTINUE
  204. C
  205. C Copy the matrix A into the L and U structures.
  206. DO 60 ICOL = 1, N
  207. DINV(ICOL) = A(JA(ICOL))
  208. JBGN = JA(ICOL)+1
  209. JEND = JA(ICOL+1)-1
  210. IF( JBGN.LE.JEND ) THEN
  211. DO 50 J = JBGN, JEND
  212. IROW = IA(J)
  213. IF( IROW.LT.ICOL ) THEN
  214. C Part of the upper triangle.
  215. IU(NCOL(ICOL)) = IROW
  216. U(NCOL(ICOL)) = A(J)
  217. NCOL(ICOL) = NCOL(ICOL) + 1
  218. ELSE
  219. C Part of the lower triangle (stored by row).
  220. JL(NROW(IROW)) = ICOL
  221. L(NROW(IROW)) = A(J)
  222. NROW(IROW) = NROW(IROW) + 1
  223. IF( ISYM.NE.0 ) THEN
  224. C Symmetric...Copy lower triangle into upper triangle as well.
  225. IU(NCOL(IROW)) = ICOL
  226. U(NCOL(IROW)) = A(J)
  227. NCOL(IROW) = NCOL(IROW) + 1
  228. ENDIF
  229. ENDIF
  230. 50 CONTINUE
  231. ENDIF
  232. 60 CONTINUE
  233. C
  234. C Sort the rows of L and the columns of U.
  235. DO 110 K = 2, N
  236. JBGN = JU(K)
  237. JEND = JU(K+1)-1
  238. IF( JBGN.LT.JEND ) THEN
  239. DO 80 J = JBGN, JEND-1
  240. DO 70 I = J+1, JEND
  241. IF( IU(J).GT.IU(I) ) THEN
  242. ITEMP = IU(J)
  243. IU(J) = IU(I)
  244. IU(I) = ITEMP
  245. TEMP = U(J)
  246. U(J) = U(I)
  247. U(I) = TEMP
  248. ENDIF
  249. 70 CONTINUE
  250. 80 CONTINUE
  251. ENDIF
  252. IBGN = IL(K)
  253. IEND = IL(K+1)-1
  254. IF( IBGN.LT.IEND ) THEN
  255. DO 100 I = IBGN, IEND-1
  256. DO 90 J = I+1, IEND
  257. IF( JL(I).GT.JL(J) ) THEN
  258. JTEMP = JU(I)
  259. JU(I) = JU(J)
  260. JU(J) = JTEMP
  261. TEMP = L(I)
  262. L(I) = L(J)
  263. L(J) = TEMP
  264. ENDIF
  265. 90 CONTINUE
  266. 100 CONTINUE
  267. ENDIF
  268. 110 CONTINUE
  269. C
  270. C Perform the incomplete LDU decomposition.
  271. DO 300 I=2,N
  272. C
  273. C I-th row of L
  274. INDX1 = IL(I)
  275. INDX2 = IL(I+1) - 1
  276. IF(INDX1 .GT. INDX2) GO TO 200
  277. DO 190 INDX=INDX1,INDX2
  278. IF(INDX .EQ. INDX1) GO TO 180
  279. INDXR1 = INDX1
  280. INDXR2 = INDX - 1
  281. INDXC1 = JU(JL(INDX))
  282. INDXC2 = JU(JL(INDX)+1) - 1
  283. IF(INDXC1 .GT. INDXC2) GO TO 180
  284. 160 KR = JL(INDXR1)
  285. 170 KC = IU(INDXC1)
  286. IF(KR .GT. KC) THEN
  287. INDXC1 = INDXC1 + 1
  288. IF(INDXC1 .LE. INDXC2) GO TO 170
  289. ELSEIF(KR .LT. KC) THEN
  290. INDXR1 = INDXR1 + 1
  291. IF(INDXR1 .LE. INDXR2) GO TO 160
  292. ELSEIF(KR .EQ. KC) THEN
  293. L(INDX) = L(INDX) - L(INDXR1)*DINV(KC)*U(INDXC1)
  294. INDXR1 = INDXR1 + 1
  295. INDXC1 = INDXC1 + 1
  296. IF(INDXR1 .LE. INDXR2 .AND. INDXC1 .LE. INDXC2) GO TO 160
  297. ENDIF
  298. 180 L(INDX) = L(INDX)/DINV(JL(INDX))
  299. 190 CONTINUE
  300. C
  301. C I-th column of U
  302. 200 INDX1 = JU(I)
  303. INDX2 = JU(I+1) - 1
  304. IF(INDX1 .GT. INDX2) GO TO 260
  305. DO 250 INDX=INDX1,INDX2
  306. IF(INDX .EQ. INDX1) GO TO 240
  307. INDXC1 = INDX1
  308. INDXC2 = INDX - 1
  309. INDXR1 = IL(IU(INDX))
  310. INDXR2 = IL(IU(INDX)+1) - 1
  311. IF(INDXR1 .GT. INDXR2) GO TO 240
  312. 210 KR = JL(INDXR1)
  313. 220 KC = IU(INDXC1)
  314. IF(KR .GT. KC) THEN
  315. INDXC1 = INDXC1 + 1
  316. IF(INDXC1 .LE. INDXC2) GO TO 220
  317. ELSEIF(KR .LT. KC) THEN
  318. INDXR1 = INDXR1 + 1
  319. IF(INDXR1 .LE. INDXR2) GO TO 210
  320. ELSEIF(KR .EQ. KC) THEN
  321. U(INDX) = U(INDX) - L(INDXR1)*DINV(KC)*U(INDXC1)
  322. INDXR1 = INDXR1 + 1
  323. INDXC1 = INDXC1 + 1
  324. IF(INDXR1 .LE. INDXR2 .AND. INDXC1 .LE. INDXC2) GO TO 210
  325. ENDIF
  326. 240 U(INDX) = U(INDX)/DINV(IU(INDX))
  327. 250 CONTINUE
  328. C
  329. C I-th diagonal element
  330. 260 INDXR1 = IL(I)
  331. INDXR2 = IL(I+1) - 1
  332. IF(INDXR1 .GT. INDXR2) GO TO 300
  333. INDXC1 = JU(I)
  334. INDXC2 = JU(I+1) - 1
  335. IF(INDXC1 .GT. INDXC2) GO TO 300
  336. 270 KR = JL(INDXR1)
  337. 280 KC = IU(INDXC1)
  338. IF(KR .GT. KC) THEN
  339. INDXC1 = INDXC1 + 1
  340. IF(INDXC1 .LE. INDXC2) GO TO 280
  341. ELSEIF(KR .LT. KC) THEN
  342. INDXR1 = INDXR1 + 1
  343. IF(INDXR1 .LE. INDXR2) GO TO 270
  344. ELSEIF(KR .EQ. KC) THEN
  345. DINV(I) = DINV(I) - L(INDXR1)*DINV(KC)*U(INDXC1)
  346. INDXR1 = INDXR1 + 1
  347. INDXC1 = INDXC1 + 1
  348. IF(INDXR1 .LE. INDXR2 .AND. INDXC1 .LE. INDXC2) GO TO 270
  349. ENDIF
  350. C
  351. 300 CONTINUE
  352. C
  353. C Replace diagonal elements by their inverses.
  354. CVD$ VECTOR
  355. DO 430 I=1,N
  356. DINV(I) = 1.0D0/DINV(I)
  357. 430 CONTINUE
  358. C
  359. RETURN
  360. C------------- LAST LINE OF DSILUS FOLLOWS ----------------------------
  361. END