ssilus.f 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. *DECK SSILUS
  2. SUBROUTINE SSILUS (N, NELT, IA, JA, A, ISYM, NL, IL, JL, L, DINV,
  3. + NU, IU, JU, U, NROW, NCOL)
  4. C***BEGIN PROLOGUE SSILUS
  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 SINGLE 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 REAL A(NELT), L(NL), DINV(N), U(NU)
  29. C
  30. C CALL SSILUS( 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 Real 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 Real 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 Real 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 SSILUS 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 real array A. In other words, for each column in the matrix
  90. C put the diagonal entry in A. Then put in the other non-zero
  91. C elements going down the column (except the diagonal) in
  92. C order. The IA array holds the row index for each non-zero.
  93. C The JA array holds the offsets into the IA, A arrays for the
  94. C beginning of each column. That is, IA(JA(ICOL)),
  95. C A(JA(ICOL)) points to the beginning of the ICOL-th column in
  96. C IA and A. IA(JA(ICOL+1)-1), A(JA(ICOL+1)-1) points to the
  97. C end of the ICOL-th column. Note that we always have
  98. C JA(N+1) = NELT+1, where N is the number of columns in the
  99. C matrix and NELT is the number of non-zeros in the matrix.
  100. C
  101. C Here is an example of the SLAP Column storage format for a
  102. C 5x5 Matrix (in the A and IA arrays '|' denotes the end of a
  103. C column):
  104. C
  105. C 5x5 Matrix SLAP Column format for 5x5 matrix on left.
  106. C 1 2 3 4 5 6 7 8 9 10 11
  107. C |11 12 0 0 15| A: 11 21 51 | 22 12 | 33 53 | 44 | 55 15 35
  108. C |21 22 0 0 0| IA: 1 2 5 | 2 1 | 3 5 | 4 | 5 1 3
  109. C | 0 0 33 0 35| JA: 1 4 6 8 9 12
  110. C | 0 0 0 44 0|
  111. C |51 0 53 0 55|
  112. C
  113. C ==================== S L A P Row format ====================
  114. C
  115. C This routine requires that the matrix A be stored in the
  116. C SLAP Row format. In this format the non-zeros are stored
  117. C counting across rows (except for the diagonal entry, which
  118. C must appear first in each "row") and are stored in the real
  119. C array A. In other words, for each row in the matrix put the
  120. C diagonal entry in A. Then put in the other non-zero
  121. C elements going across the row (except the diagonal) in
  122. C order. The JA array holds the column index for each
  123. C non-zero. The IA array holds the offsets into the JA, A
  124. C arrays for the beginning of each row. That is,
  125. C JA(IA(IROW)), A(IA(IROW)) points to the beginning of the
  126. C IROW-th row in JA and A. JA(IA(IROW+1)-1), A(IA(IROW+1)-1)
  127. C points to the end of the IROW-th row. Note that we always
  128. C have IA(N+1) = NELT+1, where N is the number of rows in
  129. C the matrix and NELT is the number of non-zeros in the
  130. C matrix.
  131. C
  132. C Here is an example of the SLAP Row storage format for a 5x5
  133. C Matrix (in the A and JA arrays '|' denotes the end of a row):
  134. C
  135. C 5x5 Matrix SLAP Row format for 5x5 matrix on left.
  136. C 1 2 3 4 5 6 7 8 9 10 11
  137. C |11 12 0 0 15| A: 11 12 15 | 22 21 | 33 35 | 44 | 55 51 53
  138. C |21 22 0 0 0| JA: 1 2 5 | 2 1 | 3 5 | 4 | 5 1 3
  139. C | 0 0 33 0 35| IA: 1 4 6 8 9 12
  140. C | 0 0 0 44 0|
  141. C |51 0 53 0 55|
  142. C
  143. C***SEE ALSO SILUR
  144. C***REFERENCES 1. Gene Golub and Charles Van Loan, Matrix Computations,
  145. C Johns Hopkins University Press, Baltimore, Maryland,
  146. C 1983.
  147. C***ROUTINES CALLED (NONE)
  148. C***REVISION HISTORY (YYMMDD)
  149. C 871119 DATE WRITTEN
  150. C 881213 Previous REVISION DATE
  151. C 890915 Made changes requested at July 1989 CML Meeting. (MKS)
  152. C 890922 Numerous changes to prologue to make closer to SLATEC
  153. C standard. (FNF)
  154. C 890929 Numerous changes to reduce SP/DP differences. (FNF)
  155. C 910411 Prologue converted to Version 4.0 format. (BAB)
  156. C 920511 Added complete declaration section. (WRB)
  157. C 920929 Corrected format of reference. (FNF)
  158. C 930701 Updated CATEGORY section. (FNF, WRB)
  159. C***END PROLOGUE SSILUS
  160. C .. Scalar Arguments ..
  161. INTEGER ISYM, N, NELT, NL, NU
  162. C .. Array Arguments ..
  163. REAL A(NELT), DINV(N), L(NL), U(NU)
  164. INTEGER IA(NELT), IL(NL), IU(NU), JA(NELT), JL(NL), JU(NU),
  165. + NCOL(N), NROW(N)
  166. C .. Local Scalars ..
  167. REAL TEMP
  168. INTEGER I, IBGN, ICOL, IEND, INDX, INDX1, INDX2, INDXC1, INDXC2,
  169. + INDXR1, INDXR2, IROW, ITEMP, J, JBGN, JEND, JTEMP, K, KC,
  170. + KR
  171. C***FIRST EXECUTABLE STATEMENT SSILUS
  172. C
  173. C Count number of elements in each row of the lower triangle.
  174. C
  175. DO 10 I=1,N
  176. NROW(I) = 0
  177. NCOL(I) = 0
  178. 10 CONTINUE
  179. CVD$R NOCONCUR
  180. CVD$R NOVECTOR
  181. DO 30 ICOL = 1, N
  182. JBGN = JA(ICOL)+1
  183. JEND = JA(ICOL+1)-1
  184. IF( JBGN.LE.JEND ) THEN
  185. DO 20 J = JBGN, JEND
  186. IF( IA(J).LT.ICOL ) THEN
  187. NCOL(ICOL) = NCOL(ICOL) + 1
  188. ELSE
  189. NROW(IA(J)) = NROW(IA(J)) + 1
  190. IF( ISYM.NE.0 ) NCOL(IA(J)) = NCOL(IA(J)) + 1
  191. ENDIF
  192. 20 CONTINUE
  193. ENDIF
  194. 30 CONTINUE
  195. JU(1) = 1
  196. IL(1) = 1
  197. DO 40 ICOL = 1, N
  198. IL(ICOL+1) = IL(ICOL) + NROW(ICOL)
  199. JU(ICOL+1) = JU(ICOL) + NCOL(ICOL)
  200. NROW(ICOL) = IL(ICOL)
  201. NCOL(ICOL) = JU(ICOL)
  202. 40 CONTINUE
  203. C
  204. C Copy the matrix A into the L and U structures.
  205. DO 60 ICOL = 1, N
  206. DINV(ICOL) = A(JA(ICOL))
  207. JBGN = JA(ICOL)+1
  208. JEND = JA(ICOL+1)-1
  209. IF( JBGN.LE.JEND ) THEN
  210. DO 50 J = JBGN, JEND
  211. IROW = IA(J)
  212. IF( IROW.LT.ICOL ) THEN
  213. C Part of the upper triangle.
  214. IU(NCOL(ICOL)) = IROW
  215. U(NCOL(ICOL)) = A(J)
  216. NCOL(ICOL) = NCOL(ICOL) + 1
  217. ELSE
  218. C Part of the lower triangle (stored by row).
  219. JL(NROW(IROW)) = ICOL
  220. L(NROW(IROW)) = A(J)
  221. NROW(IROW) = NROW(IROW) + 1
  222. IF( ISYM.NE.0 ) THEN
  223. C Symmetric...Copy lower triangle into upper triangle as well.
  224. IU(NCOL(IROW)) = ICOL
  225. U(NCOL(IROW)) = A(J)
  226. NCOL(IROW) = NCOL(IROW) + 1
  227. ENDIF
  228. ENDIF
  229. 50 CONTINUE
  230. ENDIF
  231. 60 CONTINUE
  232. C
  233. C Sort the rows of L and the columns of U.
  234. DO 110 K = 2, N
  235. JBGN = JU(K)
  236. JEND = JU(K+1)-1
  237. IF( JBGN.LT.JEND ) THEN
  238. DO 80 J = JBGN, JEND-1
  239. DO 70 I = J+1, JEND
  240. IF( IU(J).GT.IU(I) ) THEN
  241. ITEMP = IU(J)
  242. IU(J) = IU(I)
  243. IU(I) = ITEMP
  244. TEMP = U(J)
  245. U(J) = U(I)
  246. U(I) = TEMP
  247. ENDIF
  248. 70 CONTINUE
  249. 80 CONTINUE
  250. ENDIF
  251. IBGN = IL(K)
  252. IEND = IL(K+1)-1
  253. IF( IBGN.LT.IEND ) THEN
  254. DO 100 I = IBGN, IEND-1
  255. DO 90 J = I+1, IEND
  256. IF( JL(I).GT.JL(J) ) THEN
  257. JTEMP = JU(I)
  258. JU(I) = JU(J)
  259. JU(J) = JTEMP
  260. TEMP = L(I)
  261. L(I) = L(J)
  262. L(J) = TEMP
  263. ENDIF
  264. 90 CONTINUE
  265. 100 CONTINUE
  266. ENDIF
  267. 110 CONTINUE
  268. C
  269. C Perform the incomplete LDU decomposition.
  270. DO 300 I=2,N
  271. C
  272. C I-th row of L
  273. INDX1 = IL(I)
  274. INDX2 = IL(I+1) - 1
  275. IF(INDX1 .GT. INDX2) GO TO 200
  276. DO 190 INDX=INDX1,INDX2
  277. IF(INDX .EQ. INDX1) GO TO 180
  278. INDXR1 = INDX1
  279. INDXR2 = INDX - 1
  280. INDXC1 = JU(JL(INDX))
  281. INDXC2 = JU(JL(INDX)+1) - 1
  282. IF(INDXC1 .GT. INDXC2) GO TO 180
  283. 160 KR = JL(INDXR1)
  284. 170 KC = IU(INDXC1)
  285. IF(KR .GT. KC) THEN
  286. INDXC1 = INDXC1 + 1
  287. IF(INDXC1 .LE. INDXC2) GO TO 170
  288. ELSEIF(KR .LT. KC) THEN
  289. INDXR1 = INDXR1 + 1
  290. IF(INDXR1 .LE. INDXR2) GO TO 160
  291. ELSEIF(KR .EQ. KC) THEN
  292. L(INDX) = L(INDX) - L(INDXR1)*DINV(KC)*U(INDXC1)
  293. INDXR1 = INDXR1 + 1
  294. INDXC1 = INDXC1 + 1
  295. IF(INDXR1 .LE. INDXR2 .AND. INDXC1 .LE. INDXC2) GO TO 160
  296. ENDIF
  297. 180 L(INDX) = L(INDX)/DINV(JL(INDX))
  298. 190 CONTINUE
  299. C
  300. C I-th column of U
  301. 200 INDX1 = JU(I)
  302. INDX2 = JU(I+1) - 1
  303. IF(INDX1 .GT. INDX2) GO TO 260
  304. DO 250 INDX=INDX1,INDX2
  305. IF(INDX .EQ. INDX1) GO TO 240
  306. INDXC1 = INDX1
  307. INDXC2 = INDX - 1
  308. INDXR1 = IL(IU(INDX))
  309. INDXR2 = IL(IU(INDX)+1) - 1
  310. IF(INDXR1 .GT. INDXR2) GO TO 240
  311. 210 KR = JL(INDXR1)
  312. 220 KC = IU(INDXC1)
  313. IF(KR .GT. KC) THEN
  314. INDXC1 = INDXC1 + 1
  315. IF(INDXC1 .LE. INDXC2) GO TO 220
  316. ELSEIF(KR .LT. KC) THEN
  317. INDXR1 = INDXR1 + 1
  318. IF(INDXR1 .LE. INDXR2) GO TO 210
  319. ELSEIF(KR .EQ. KC) THEN
  320. U(INDX) = U(INDX) - L(INDXR1)*DINV(KC)*U(INDXC1)
  321. INDXR1 = INDXR1 + 1
  322. INDXC1 = INDXC1 + 1
  323. IF(INDXR1 .LE. INDXR2 .AND. INDXC1 .LE. INDXC2) GO TO 210
  324. ENDIF
  325. 240 U(INDX) = U(INDX)/DINV(IU(INDX))
  326. 250 CONTINUE
  327. C
  328. C I-th diagonal element
  329. 260 INDXR1 = IL(I)
  330. INDXR2 = IL(I+1) - 1
  331. IF(INDXR1 .GT. INDXR2) GO TO 300
  332. INDXC1 = JU(I)
  333. INDXC2 = JU(I+1) - 1
  334. IF(INDXC1 .GT. INDXC2) GO TO 300
  335. 270 KR = JL(INDXR1)
  336. 280 KC = IU(INDXC1)
  337. IF(KR .GT. KC) THEN
  338. INDXC1 = INDXC1 + 1
  339. IF(INDXC1 .LE. INDXC2) GO TO 280
  340. ELSEIF(KR .LT. KC) THEN
  341. INDXR1 = INDXR1 + 1
  342. IF(INDXR1 .LE. INDXR2) GO TO 270
  343. ELSEIF(KR .EQ. KC) THEN
  344. DINV(I) = DINV(I) - L(INDXR1)*DINV(KC)*U(INDXC1)
  345. INDXR1 = INDXR1 + 1
  346. INDXC1 = INDXC1 + 1
  347. IF(INDXR1 .LE. INDXR2 .AND. INDXC1 .LE. INDXC2) GO TO 270
  348. ENDIF
  349. C
  350. 300 CONTINUE
  351. C
  352. C Replace diagonal elements by their inverses.
  353. CVD$ VECTOR
  354. DO 430 I=1,N
  355. DINV(I) = 1.0E0/DINV(I)
  356. 430 CONTINUE
  357. C
  358. RETURN
  359. C------------- LAST LINE OF SSILUS FOLLOWS ----------------------------
  360. END