The TELEMAC-MASCARET system  trunk
sd_ssf.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE sd_ssf
3 ! *****************
4 !
5  &(n,p,ip,ia,ja,iju,ju,iu,jumax,q,mark,jl,flag)
6 !
7 !***********************************************************************
8 ! BIEF V6P1 21/08/2010
9 !***********************************************************************
10 !
11 !brief SYMBOLIC UT-D-U FACTORISATION OF SPARSE SYMMETRIC MATRIX.
12 !+ COMPRESSED STORAGE OF SPARSE MATRICES.
13 !code
14 !+ IMPORTANT NOTE: INSPIRED FROM PACKAGE CMLIB3 - YALE UNIVERSITE-YSMP
15 !+
16 !+
17 !+ THE STRICT UPPER TRIANGULAR PORTION OF THE MATRIX U IS STORED IN
18 !+ (IA,JA,A) FORMAT USING THE ARRAYS IU, JU, AND U, EXCEPT THAT AN
19 !+ ADDITIONAL ARRAY IJU IS USED TO REDUCE THE STORAGE REQUIRED FOR JU
20 !+ BY ALLOWING SOME SEQUENCES OF COLUMN INDICES TO CORRESPOND TO MORE
21 !+ THAN ONE ROW. FOR I
22 !+ ENTRY FOR THE I-TH ROW; IJU(N) IS THE NUMBER OF ENTRIES IN JU.
23 !+ THUS, THE NUMBER OF ENTRIES IN THE I-TH ROW IS IU(I+1) - IU(I),
24 !+ THE NONZERO ENTRIES OF THE I-TH ROW ARE STORED CONSECUTIVELY IN
25 !+
26 !+ U(IU(I)), U(IU(I)+1), ..., U(IU(I+1)-1),
27 !+
28 !+ AND THE CORRESPONDING COLUMN INDICES ARE STORED CONSECUTIVELY IN
29 !+
30 !+ JU(IJU(I)), JU(IJU(I)+1), ..., JU(IJU(I)+IU(I+1)-IU(I)-1).
31 !+
32 !+ COMPRESSION IN JU OCCURS IN TWO WAYS. FIRST, IF A ROW I WAS MERGED
33 !+ INTO ROW K, AND THE NUMBER OF ELEMENTS MERGED IN FROM (THE TAIL
34 !+ PORTION OF) ROW I IS THE SAME AS THE FINAL LENGTH OF ROW K, THEN
35 !+ THE KTH ROW AND THE TAIL OF ROW I ARE IDENTICAL AND IJU(K) POINTS
36 !+ TO THE START OF THE TAIL. SECOND, IF SOME TAIL PORTION OF THE
37 !+ (K-1)ST ROW IS IDENTICAL TO THE HEAD OF THE KTH ROW, THEN IJU(K)
38 !+ POINTS TO THE START OF THAT TAIL PORTION. FOR EXAMPLE, THE NONZERO
39 !+ STRUCTURE OF THE STRICT UPPER TRIANGULAR PART OF THE MATRIX
40 !+
41 !+ ( D 0 0 0 X X X )
42 !+ ( 0 D 0 X X 0 0 )
43 !+ ( 0 0 D 0 X X 0 )
44 !+ U = ( 0 0 0 D X X 0 )
45 !+ ( 0 0 0 0 D X X )
46 !+ ( 0 0 0 0 0 D X )
47 !+ ( 0 0 0 0 0 0 D )
48 !+
49 !+ WOULD BE STORED AS
50 !+
51 !+ \ 1 2 3 4 5 6 7 8
52 !+ ----+------------------------
53 !+ IU \ 1 4 6 8 10 12 13 13
54 !+ JU \ 5 6 7 4 5 6
55 !+ IJU \ 1 4 5 5 2 3 6 .
56 !+
57 !+ THE DIAGONAL ENTRIES OF U ARE EQUAL TO ONE AND ARE NOT STORED.
58 !
59 !history E. RAZAFINDRAKOTO (LNH)
60 !+ 20/11/06
61 !+ V5P7
62 !+
63 !
64 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
65 !+ 13/07/2010
66 !+ V6P0
67 !+ Translation of French comments within the FORTRAN sources into
68 !+ English comments
69 !
70 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
71 !+ 21/08/2010
72 !+ V6P0
73 !+ Creation of DOXYGEN tags for automated documentation and
74 !+ cross-referencing of the FORTRAN sources
75 !
76 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
77 !| FLAG |<--| LOGICAL VARIABLE; IF DFLAG = .TRUE., THEN
78 !| | | STORE NONZERO DIAGONAL ELEMENTS AT THE
79 !| | | BEGINNING OF THE ROW
80 !| IA |<--| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING
81 !| | | POINTERS TO DELIMIT ROWS IN JA AND A;
82 !| | | DIMENSION = N+1
83 !| IJU |---| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING
84 !| | | POINTERS TO THE START OF EACH ROW IN JU; DIMENSION = N
85 !| IP |<--| INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN
86 !| | | THE INVERSE OF THE PERMUTATION RETURNED IN P;
87 !| | | DIMENSION = N
88 !| IU |---| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING
89 !| | | POINTERS TO DELIMIT ROWS IN U; DIMENSION = N+1
90 !| JA |<--| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE
91 !| | | COLUMN INDICES CORRESPONDING TO THE ELEMENTS
92 !| | | OF A; DIMENSION = NUMBER OF NONZERO ENTRIES
93 !| | | IN (THE UPPER TRIANGLE OF) M
94 !| JL |-->| INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION N
95 !| | | DIMENSION = NUMBER OF NONZERO ENTRIES IN THE
96 !| | | UPPER TRIANGLE OF M. JL CONTAINS LISTS OF ROWS
97 !| | | TO BE MERGED INTO UNELIMINATED ROWS --
98 !| | | I GE K => JL(I) IS THE FIRST ROW TO BE
99 !| | | MERGED INTO ROW I
100 !| | | I LT K => JL(I) IS THE ROW FOLLOWING ROW I IN
101 !| | | SOME LIST OF ROWS
102 !| | | IN EITHER CASE, JL(I) = 0 INDICATES THE
103 !| | | END OF A LIST
104 !| JU |---| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE
105 !| | | COLUMN INDICES CORRESPONDING TO THE ELEMENTS
106 !| | | OF U; DIMENSION = JUMAX
107 !| JUMAX |---| DECLARED DIMENSION OF THE ONE-DIMENSIONAL
108 !| | | ARRAY JU; JUMAX MUST BE AT LEAST THE SIZE
109 !| | | OF U MINUS COMPRESSION (IJU(N) AFTER THE
110 !| | | CALL TO SSF)
111 !| MARK |---| INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION N
112 !| | | THE LAST ROW STORED IN JU FOR WHICH U(MARK(I),I)
113 !| | | NE 0
114 !| N |-->| ORDER OF THE MATRIX
115 !| P |<--| INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN
116 !| | | THE PERMUTATION OF THE ROWS AND COLUMNS OF M
117 !| | | CORRESPONDING TO THE MINIMUM DEGREE ORDERING;
118 !| | | DIMENSION = N
119 !| Q |-->| INTEGER ONE-DIMENSIONAL WORK ARRAY, DIMENSION N
120 !| | | Q CONTAINS AN ORDERED LINKED LIST
121 !| | | REPRESENTATION OF THE NONZERO
122 !| | | STRUCTURE OF THE K-TH ROW OF U --
123 !| | | Q(K) IS THE FIRST COLUMN WITH A NONZERO ENTRY
124 !| | | Q(I) IS THE NEXT COLUMN WITH A NONZERO ENTRY
125 !| | | AFTER COLUMN I
126 !| | | IN EITHER CASE, Q(I) = N+1 INDICATES THE
127 !| | | END OF THE LIST
128 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
129 !
130  USE bief, ex_sd_ssf => sd_ssf
131 !
133  IMPLICIT NONE
134 !
135 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
136 !
137  INTEGER, INTENT(IN) :: N,JUMAX
138  INTEGER, INTENT(INOUT) :: P(n),IP(n),IA(n+1),JA(*),IJU(n),FLAG
139  INTEGER, INTENT(INOUT) :: JU(jumax),IU(n+1),Q(n),MARK(n),JL(n)
140 !
141 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
142 !
143  INTEGER I,J,M,TAG,VJ,QM,JUMIN,JUPTR,K,LUK,LUI,JMIN,JMAX,LMAX
144  LOGICAL CLIQUE
145 !
146 !-----------------------------------------------------------------------
147 !
148 !----INITIALISES
149 !
150 ! JUMIN AND JUPTR ARE THE INDICES IN JU OF THE FIRST AND LAST
151 ! ELEMENTS IN THE LAST ROW SAVED IN JU
152 !
153 ! LUK IS THE NUMBER OF NONZERO ENTRIES IN THE K-TH ROW
154 !
155  jumin = 1
156  juptr = 0
157  iu(1) = 1
158  DO k=1,n
159  mark(k) = 0
160  jl(k) = 0
161  ENDDO
162 !
163 !----FOR EACH ROW K
164 !
165  DO 19 k=1,n
166  luk = 0
167  q(k) = n+1
168 !
169  tag = mark(k)
170  clique = .false.
171  IF(jl(k).NE.0) clique = jl(jl(k)).EQ.0
172 !
173 !------INITIALISES NONZERO STRUCTURE OF K-TH ROW TO ROW P(K) OF M
174 !
175  jmin = ia(p(k))
176  jmax = ia(p(k)+1) - 1
177  IF (jmin.GT.jmax) GO TO 4
178  DO 3 j=jmin,jmax
179  vj = ip(ja(j))
180  IF(vj.LE.k) GO TO 3
181 !
182  qm = k
183 2 m = qm
184  qm = q(m)
185  IF (qm.LT.vj) GO TO 2
186  IF (qm.EQ.vj) GO TO 102
187  luk = luk+1
188  q(m) = vj
189  q(vj) = qm
190  IF (mark(vj).NE.tag) clique = .false.
191 !
192 3 CONTINUE
193 !
194 !------IF EXACTLY ONE ROW IS TO BE MERGED INTO THE K-TH ROW AND THERE IS
195 !------A NONZERO ENTRY IN EVERY COLUMN IN THAT ROW IN WHICH THERE IS A
196 !------NONZERO ENTRY IN ROW P(K) OF M, THEN DOES NOT COMPUTE FILL-IN, JUST
197 !------USES THE COLUMN INDICES FOR THE ROW WHICH WAS TO HAVE BEEN MERGED
198 !
199 4 IF(.NOT.clique) GO TO 5
200  iju(k) = iju(jl(k)) + 1
201  luk = iu(jl(k)+1) - (iu(jl(k))+1)
202  GO TO 17
203 !
204 !------MODIFIES NONZERO STRUCTURE OF K-TH ROW BY COMPUTING FILL-IN
205 !------FOR EACH ROW I TO BE MERGED IN
206 !
207 5 lmax = 0
208  iju(k) = juptr
209 !
210  i = k
211 6 i = jl(i)
212  IF (i.EQ.0) GO TO 10
213 !
214 !--------MERGES ROW I INTO K-TH ROW
215 !
216  lui = iu(i+1) - (iu(i)+1)
217  jmin = iju(i) + 1
218  jmax = iju(i) + lui
219  qm = k
220 !
221  DO 8 j=jmin,jmax
222  vj = ju(j)
223 7 m = qm
224  qm = q(m)
225  IF (qm.LT.vj) GO TO 7
226  IF (qm.EQ.vj) GO TO 8
227  luk = luk+1
228  q(m) = vj
229  q(vj) = qm
230  qm = vj
231 8 CONTINUE
232 !
233 !--------REMEMBERS LENGTH AND POSITION IN JU OF LONGEST ROW MERGED
234 !
235  IF(lui.LE.lmax) GO TO 6
236  lmax = lui
237  iju(k) = jmin
238 !
239  GO TO 6
240 !
241 !------IF THE K-TH ROW IS THE SAME LENGTH AS THE LONGEST ROW MERGED,
242 !------THEN USES THE COLUMN INDICES FOR THAT ROW
243 !
244 10 IF (luk.EQ.lmax) GO TO 17
245 !
246 !------IF THE TAIL OF THE LAST ROW SAVED IN JU IS THE SAME AS THE HEAD
247 !------OF THE K-TH ROW, THEN OVERLAPS THE TWO SETS OF COLUMN INDICES --
248 !--------SEARCHES LAST ROW SAVED FOR FIRST NONZERO ENTRY IN K-TH ROW ...
249 !
250  i = q(k)
251  IF (jumin.GT.juptr) GO TO 12
252  DO 11 jmin=jumin,juptr
253  IF (ju(jmin) < i) GOTO 11
254  IF (ju(jmin) == i) GOTO 13
255  IF (ju(jmin) > i) GOTO 12
256 11 CONTINUE
257 12 GO TO 15
258 !
259 !--------... AND THEN TESTS WHETHER TAIL MATCHES HEAD OF K-TH ROW
260 !
261 13 iju(k) = jmin
262  DO j=jmin,juptr
263  IF (ju(j).NE.i) GO TO 15
264  i = q(i)
265  IF (i.GT.n) GO TO 17
266  ENDDO
267  juptr = jmin - 1
268 !
269 !------SAVES NONZERO STRUCTURE OF K-TH ROW IN JU
270 !
271 15 i = k
272  jumin = juptr + 1
273  juptr = juptr + luk
274  IF (juptr.GT.jumax) GO TO 106
275  DO j=jumin,juptr
276  i = q(i)
277  ju(j) = i
278  mark(i) = k
279  ENDDO
280  iju(k) = jumin
281 !
282 !------ADDS K TO ROW LIST FOR FIRST NONZERO ELEMENT IN K-TH ROW
283 !
284 17 IF(luk.LE.1) GO TO 18
285  i = ju(iju(k))
286  jl(k) = jl(i)
287  jl(i) = k
288 !
289 18 iu(k+1) = iu(k) + luk
290 !
291 19 CONTINUE
292 !
293  flag = 0
294  RETURN
295 !
296 ! ** ERROR -- DUPLICATE ENTRY IN A
297 !
298 102 flag = 2*n + p(k)
299  RETURN
300 !
301 ! ** ERROR -- INSUFFICIENT STORAGE FOR JU
302 !
303 106 flag = 6*n + k
304  RETURN
305  END
subroutine sd_ssf(N, P, IP, IA, JA, IJU, JU, IU, JUMAX, Q, MARK, JL, FLAG)
Definition: sd_ssf.f:7
double precision function q(I)
Definition: q.f:7
Definition: bief.f:3