The TELEMAC-MASCARET system  trunk
sd_snf.f
Go to the documentation of this file.
1 ! *****************
2  SUBROUTINE sd_snf
3 ! *****************
4 !
5  &(n,p,ip,ia,ja,a,d,iju,ju,iu,u,umax,il,jl,flag)
6 !
7 !***********************************************************************
8 ! BIEF V6P1 21/08/2010
9 !***********************************************************************
10 !
11 !brief NUMERICAL UT-D-U FACTORISATION OF SPARSE SYMMETRICAL
12 !+ POSITIVE DEFINITE MATRIX.
13 !code
14 !+ COMPRESSED STORAGE OF SPARSE MATRICES
15 !+
16 !+ THE STRICT UPPER TRIANGULAR PORTION OF THE MATRIX U IS STORED IN
17 !+ (IA,JA,A) FORMAT USING THE ARRAYS IU, JU, AND U, EXCEPT THAT AN
18 !+ ADDITIONAL ARRAY IJU IS USED TO REDUCE THE STORAGE REQUIRED FOR JU
19 !+ BY ALLOWING SOME SEQUENCES OF COLUMN INDICES TO CORRESPOND TO MORE
20 !+ THAN ONE ROW. FOR I < N, IJU(I) IS THE INDEX IN JU OF THE FIRST
21 !+ ENTRY FOR THE I-TH ROW; IJU(N) IS THE NUMBER OF ENTRIES IN JU.
22 !+ THUS, THE NUMBER OF ENTRIES IN THE I-TH ROW IS IU(I+1) - IU(I),
23 !+ THE NONZERO ENTRIES OF THE I-TH ROW ARE STORED CONSECUTIVELY IN
24 !+
25 !+ U(IU(I)), U(IU(I)+1), ..., U(IU(I+1)-1),
26 !+
27 !+ AND THE CORRESPONDING COLUMN INDICES ARE STORED CONSECUTIVELY IN
28 !+
29 !+ JU(IJU(I)), JU(IJU(I)+1), ..., JU(IJU(I)+IU(I+1)-IU(I)-1).
30 !+
31 !+ COMPRESSION IN JU OCCURS IN TWO WAYS. FIRST, IF A ROW I WAS MERGED
32 !+ INTO ROW K, AND THE NUMBER OF ELEMENTS MERGED IN FROM (THE TAIL
33 !+ PORTION OF) ROW I IS THE SAME AS THE FINAL LENGTH OF ROW K, THEN
34 !+ THE KTH ROW AND THE TAIL OF ROW I ARE IDENTICAL AND IJU(K) POINTS
35 !+ TO THE START OF THE TAIL. SECOND, IF SOME TAIL PORTION OF THE
36 !+ (K-1)ST ROW IS IDENTICAL TO THE HEAD OF THE KTH ROW, THEN IJU(K)
37 !+ POINTS TO THE START OF THAT TAIL PORTION. FOR EXAMPLE, THE NONZERO
38 !+ STRUCTURE OF THE STRICT UPPER TRIANGULAR PART OF THE MATRIX
39 !+
40 !+ ( D 0 0 0 X X X )
41 !+ ( 0 D 0 X X 0 0 )
42 !+ ( 0 0 D 0 X X 0 )
43 !+ U = ( 0 0 0 D X X 0 )
44 !+ ( 0 0 0 0 D X X )
45 !+ ( 0 0 0 0 0 D X )
46 !+ ( 0 0 0 0 0 0 D )
47 !+
48 !+ WOULD BE STORED AS
49 !+
50 !+ \ 1 2 3 4 5 6 7 8
51 !+ ----+------------------------
52 !+ IU \ 1 4 6 8 10 12 13 13
53 !+ JU \ 5 6 7 4 5 6
54 !+ IJU \ 1 4 5 5 2 3 6 .
55 !+
56 !+ THE DIAGONAL ENTRIES OF U ARE EQUAL TO ONE AND ARE NOT STORED.
57 !
58 !note IMPORTANT : INSPIRED FROM PACKAGE CMLIB3 - YALE UNIVERSITE-YSMP
59 !
60 !history E. RAZAFINDRAKOTO (LNH)
61 !+ 20/11/06
62 !+ V5P7
63 !+
64 !
65 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
66 !+ 13/07/2010
67 !+ V6P0
68 !+ Translation of French comments within the FORTRAN sources into
69 !+ English comments
70 !
71 !history N.DURAND (HRW), S.E.BOURBAN (HRW)
72 !+ 21/08/2010
73 !+ V6P0
74 !+ Creation of DOXYGEN tags for automated documentation and
75 !+ cross-referencing of the FORTRAN sources
76 !
77 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
78 !| A |<--| REAL ONE-DIMENSIONAL ARRAY CONTAINING THE
79 !| | | NONZERO ENTRIES IN (THE UPPER TRIANGLE OF) M,
80 !| | | STORED BY ROWS; DIMENSION =NUMBER OF NONZERO
81 !| | | ENTRIES IN (THE UPPER TRIANGLE OF) M
82 !| D |<--| (D(I),I=K,N) CONTAINS THE K-TH ROW OF U (EXPANDED)
83 !| FLAG |<--| LOGICAL VARIABLE; IF DFLAG = .TRUE., THEN
84 !| | | STORE NONZERO DIAGONAL ELEMENTS AT THE
85 !| | | BEGINNING OF THE ROW
86 !| IA |<--| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING
87 !| | | POINTERS TO DELIMIT ROWS IN JA AND A;
88 !| | | DIMENSION = N+1
89 !| IJU |-->| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING
90 !| | | POINTERS TO THE START OF EACH ROW IN JU; DIMENSION = N
91 !| IL |<--| IL(I) POINTS TO THE FIRST NONZERO ELEMENT IN
92 !| | | COLUMNS K,...,N OF ROW I OF U
93 !| IP |<--| INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN
94 !| | | THE INVERSE OF THE PERMUTATION RETURNED IN P;
95 !| | | DIMENSION = N
96 !| IU |-->| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING
97 !| | | POINTERS TO DELIMIT ROWS IN U; DIMENSION = N+1
98 !| JA |<--| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE
99 !| | | COLUMN INDICES CORRESPONDING TO THE ELEMENTS
100 !| | | OF A; DIMENSION = NUMBER OF NONZERO ENTRIES
101 !| | | IN (THE UPPER TRIANGLE OF) M
102 !| JL |-->| INTEGER ONE-DIMENSIONAL WORK ARRAY; DIMENSION N
103 !| | | DIMENSION = NUMBER OF NONZERO ENTRIES IN THE
104 !| | | UPPER TRIANGLE OF M. JL CONTAINS LISTS OF ROWS
105 !| | | TO BE MERGED INTO UNELIMINATED ROWS --
106 !| | | I GE K => JL(I) IS THE FIRST ROW TO BE
107 !| | | MERGED INTO ROW I
108 !| | | I LT K => JL(I) IS THE ROW FOLLOWING ROW I IN
109 !| | | SOME LIST OF ROWS
110 !| | | IN EITHER CASE, JL(I) = 0 INDICATES THE
111 !| | | END OF A LIST
112 !| JU |-->| INTEGER ONE-DIMENSIONAL ARRAY CONTAINING THE
113 !| | | COLUMN INDICES CORRESPONDING TO THE ELEMENTS
114 !| | | OF U; DIMENSION = JUMAX
115 !| N |-->| ORDER OF THE MATRIX
116 !| P |<--| INTEGER ONE-DIMENSIONAL ARRAY USED TO RETURN
117 !| | | THE PERMUTATION OF THE ROWS AND COLUMNS OF M
118 !| | | CORRESPONDING TO THE MINIMUM DEGREE ORDERING;
119 !| | | DIMENSION = N
120 !| U |<--| REAL ONE-DIMENSIONAL ARRAY CONTAINING THE
121 !| | | NONZERO ENTRIES IN THE STRICT UPPER TRIANGLE
122 !| | | OF U, STORED BY ROWS; DIMENSION = UMAX
123 !| UMAX |-->| DECLARED DIMENSION OF THE ONE-DIMENSIONAL
124 !| | | ARRAY U; UMAX MUST BE AT LEAST THE NUMBER
125 !| | | OF NONZERO ENTRIES IN THE STRICT UPPER TRIANGLE
126 !| | | OF M PLUS FILLIN (IU(N+1)-1 AFTER THE CALL TO SSF)
127 !~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
128 !
129  USE bief, ex_sd_snf => sd_snf
130 !
132  IMPLICIT NONE
133 !
134 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
135 !
136  INTEGER, INTENT(IN) :: N,UMAX
137  INTEGER, INTENT(IN) :: P(n),IP(n),IA(n+1),JA(*),IJU(n),JU(*)
138  INTEGER, INTENT(IN) :: IU(n+1)
139  INTEGER, INTENT(INOUT) :: IL(*),JL(*),FLAG
140  DOUBLE PRECISION, INTENT(IN) :: A(*)
141  DOUBLE PRECISION, INTENT(INOUT) :: D(n),U(umax)
142 !
143 !+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
144 !
145  INTEGER K,JMIN,JMAX,VJ,NEXTI,ILI,MU,I,J,JUMUJ
146  DOUBLE PRECISION DK,UKIDI
147 !
148 !-----------------------------------------------------------------------
149 !
150 !
151 !----CHECKS FOR SUFFICIENT STORAGE FOR U
152 !
153  IF(iu(n+1)-1.GT.umax) GO TO 107
154 !
155 !----INITIALISES
156 !
157  DO k=1,n
158  d(k) = 0
159  jl(k) = 0
160  ENDDO
161 !
162 !----FOR EACH ROW K
163 !
164  DO k=1,n
165 !
166 !------INITIALISES K-TH ROW WITH ELEMENTS NONZERO IN ROW P(K) OF M
167 !
168  jmin = ia(p(k))
169  jmax = ia(p(k)+1) - 1
170  IF(jmin.GT.jmax) GO TO 5
171  DO j=jmin,jmax
172  vj = ip(ja(j))
173  IF (k.LE.vj) d(vj) = a(j)
174  ENDDO ! J
175 !
176 !------MODIFIES K-TH ROW BY ADDING IN THOSE ROWS I WITH U(I,K) NE 0
177 !------FOR EACH ROW I TO BE ADDED IN
178 !
179 5 dk = d(k)
180  i = jl(k)
181 6 IF(i.EQ.0) GO TO 9
182  nexti = jl(i)
183 !
184 !--------COMPUTES MULTIPLIER AND UPDATES DIAGONAL ELEMENT
185 !
186  ili = il(i)
187  ukidi = - u(ili) * d(i)
188  dk = dk + ukidi * u(ili)
189  u(ili) = ukidi
190 !
191 !--------ADDS MULTIPLE OF ROW I TO K-TH ROW ...
192 !
193  jmin = ili + 1
194  jmax = iu(i+1) - 1
195  IF(jmin.GT.jmax) GO TO 8
196  mu = iju(i) - iu(i)
197  DO j=jmin,jmax
198  d(ju(mu+j)) = d(ju(mu+j)) + ukidi * u(j)
199  ENDDO
200 !
201 !--------... AND ADDS I TO ROW LIST FOR NEXT NONZERO ENTRY
202 !
203  il(i) = jmin
204  j = ju(mu+jmin)
205  jl(i) = jl(j)
206  jl(j) = i
207 !
208 8 i = nexti
209  GO TO 6
210 !
211 !------CHECKS FOR 0 PIVOT AND SAVES DIAGONAL ELEMENT
212 !
213 9 IF(dk.EQ.0) GO TO 108
214  d(k) = 1 / dk
215 !
216 !------SAVES NONZERO ENTRIES IN K-TH ROW OF U ...
217 !
218  jmin = iu(k)
219  jmax = iu(k+1) - 1
220  IF(jmin.GT.jmax) cycle
221  mu = iju(k) - jmin
222  DO j=jmin,jmax
223  jumuj = ju(mu+j)
224  u(j) = d(jumuj)
225  d(jumuj) = 0
226  ENDDO
227 !
228 !------... AND ADDS K TO ROW LIST FOR FIRST NONZERO ENTRY IN K-TH ROW
229 !
230  il(k) = jmin
231  i = ju(mu+jmin)
232  jl(k) = jl(i)
233  jl(i) = k
234  ENDDO ! K
235 !
236  flag = 0
237  RETURN
238 !
239 ! ** ERROR -- INSUFFICIENT STORAGE FOR U
240 !
241 107 flag = 7*n + 1
242  RETURN
243 !
244 ! ** ERROR -- 0 PIVOT
245 !
246 108 flag = 8*n + k
247 !
248 !-----------------------------------------------------------------------
249 !
250  RETURN
251  END
subroutine sd_snf(N, P, IP, IA, JA, A, D, IJU, JU, IU, U, UMAX, IL, JL, FLAG)
Definition: sd_snf.f:7
Definition: bief.f:3