Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/umfpack/demo/umf4hb64.f
3196 views
1
c=======================================================================
2
c== umf4hb =============================================================
3
c=======================================================================
4
5
c-----------------------------------------------------------------------
6
c UMFPACK Version 4.4, Copyright (c) 2005 by Timothy A. Davis. CISE
7
c Dept, Univ. of Florida. All Rights Reserved. See ../Doc/License for
8
c License. web: http://www.cise.ufl.edu/research/sparse/umfpack
9
c-----------------------------------------------------------------------
10
11
c umf4hb64:
12
c read a sparse matrix in the Harwell/Boeing format, factorizes
13
c it, and solves Ax=b. Also saves and loads the factors to/from a
14
c file. Saving to a file is not required, it's just here to
15
c demonstrate how to use this feature of UMFPACK. This program
16
c only works on square RUA-type matrices.
17
c
18
c This is HIGHLY non-portable. It may not work with your C and
19
c FORTRAN compilers. See umf4_f77wrapper.c for more details.
20
c
21
c usage (for example):
22
c
23
c in a Unix shell:
24
c umf4hb64 < HB/arc130.rua
25
26
integer*8
27
$ nzmax, nmax
28
parameter (nzmax = 5000000, nmax = 160000)
29
integer*8
30
$ Ap (nmax), Ai (nzmax), n, nz, totcrd, ptrcrd, i, j, p,
31
$ indcrd, valcrd, rhscrd, ncol, nrow, nrhs, nzrhs, nel,
32
$ numeric, symbolic, status, sys, filenum
33
34
character title*72, key*30, type*3, ptrfmt*16,
35
$ indfmt*16, valfmt*20, rhsfmt*20
36
double precision Ax (nzmax), x (nmax), b (nmax), aij, xj,
37
$ r (nmax), control (20), info (90)
38
character rhstyp*3
39
40
c ----------------------------------------------------------------
41
c read the Harwell/Boeing matrix
42
c ----------------------------------------------------------------
43
44
read (5, 10, err = 998)
45
$ title, key,
46
$ totcrd, ptrcrd, indcrd, valcrd, rhscrd,
47
$ type, nrow, ncol, nz, nel,
48
$ ptrfmt, indfmt, valfmt, rhsfmt
49
if (rhscrd .gt. 0) then
50
c new Harwell/Boeing format:
51
read (5, 20, err = 998) rhstyp, nrhs, nzrhs
52
endif
53
10 format (a72, a8 / 5i14 / a3, 11x, 4i14 / 2a16, 2a20)
54
20 format (a3, 11x, 2i14)
55
56
print *, 'Matrix key: ', key
57
58
n = nrow
59
if (type .ne. 'RUA' .or. nrow .ne. ncol) then
60
print *, 'Error: can only handle square RUA matrices'
61
stop
62
endif
63
if (n .ge. nmax .or. nz .gt. nzmax) then
64
print *, ' Matrix too big!'
65
stop
66
endif
67
68
c read the matrix (1-based)
69
read (5, ptrfmt, err = 998) (Ap (p), p = 1, ncol+1)
70
read (5, indfmt, err = 998) (Ai (p), p = 1, nz)
71
read (5, valfmt, err = 998) (Ax (p), p = 1, nz)
72
73
c ----------------------------------------------------------------
74
c create the right-hand-side, assume x (i) = 1 + i/n
75
c ----------------------------------------------------------------
76
77
do 30 i = 1,n
78
b (i) = 0
79
30 continue
80
c b = A*x
81
do 50 j = 1,n
82
xj = j
83
xj = 1 + xj / n
84
do 40 p = Ap (j), Ap (j+1)-1
85
i = Ai (p)
86
aij = Ax (p)
87
b (i) = b (i) + aij * xj
88
40 continue
89
50 continue
90
91
c ----------------------------------------------------------------
92
c convert from 1-based to 0-based
93
c ----------------------------------------------------------------
94
95
do 60 j = 1, n+1
96
Ap (j) = Ap (j) - 1
97
60 continue
98
do 70 p = 1, nz
99
Ai (p) = Ai (p) - 1
100
70 continue
101
102
c ----------------------------------------------------------------
103
c factor the matrix and save to a file
104
c ----------------------------------------------------------------
105
106
c set default parameters
107
call umf4def (control)
108
109
c print control parameters. set control (1) to 1 to print
110
c error messages only
111
control (1) = 2
112
call umf4pcon (control)
113
114
c pre-order and symbolic analysis
115
call umf4sym (n, n, Ap, Ai, Ax, symbolic, control, info)
116
117
c print statistics computed so far
118
c call umf4pinf (control, info) could also be done.
119
print 80, info (1), info (16),
120
$ (info (21) * info (4)) / 2**20,
121
$ (info (22) * info (4)) / 2**20,
122
$ info (23), info (24), info (25)
123
80 format ('symbolic analysis:',/,
124
$ ' status: ', f5.0, /,
125
$ ' time: ', e10.2, ' (sec)'/,
126
$ ' estimates (upper bound) for numeric LU:', /,
127
$ ' size of LU: ', f10.2, ' (MB)', /,
128
$ ' memory needed: ', f10.2, ' (MB)', /,
129
$ ' flop count: ', e10.2, /
130
$ ' nnz (L): ', f10.0, /
131
$ ' nnz (U): ', f10.0)
132
133
c check umf4sym error condition
134
if (info (1) .lt. 0) then
135
print *, 'Error occurred in umf4sym: ', info (1)
136
stop
137
endif
138
139
c numeric factorization
140
call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info)
141
142
c print statistics for the numeric factorization
143
c call umf4pinf (control, info) could also be done.
144
print 90, info (1), info (66),
145
$ (info (41) * info (4)) / 2**20,
146
$ (info (42) * info (4)) / 2**20,
147
$ info (43), info (44), info (45)
148
90 format ('numeric factorization:',/,
149
$ ' status: ', f5.0, /,
150
$ ' time: ', e10.2, /,
151
$ ' actual numeric LU statistics:', /,
152
$ ' size of LU: ', f10.2, ' (MB)', /,
153
$ ' memory needed: ', f10.2, ' (MB)', /,
154
$ ' flop count: ', e10.2, /
155
$ ' nnz (L): ', f10.0, /
156
$ ' nnz (U): ', f10.0)
157
158
c check umf4num error condition
159
if (info (1) .lt. 0) then
160
print *, 'Error occurred in umf4num: ', info (1)
161
stop
162
endif
163
164
c save the symbolic analysis to the file s0.umf
165
c note that this is not needed until another matrix is
166
c factorized, below.
167
filenum = 0
168
call umf4ssym (symbolic, filenum, status)
169
if (status .lt. 0) then
170
print *, 'Error occurred in umf4ssym: ', status
171
stop
172
endif
173
174
c save the LU factors to the file n0.umf
175
call umf4snum (numeric, filenum, status)
176
if (status .lt. 0) then
177
print *, 'Error occurred in umf4snum: ', status
178
stop
179
endif
180
181
c free the symbolic analysis
182
call umf4fsym (symbolic)
183
184
c free the numeric factorization
185
call umf4fnum (numeric)
186
187
c No LU factors (symbolic or numeric) are in memory at this point.
188
189
c ----------------------------------------------------------------
190
c load the LU factors back in, and solve the system
191
c ----------------------------------------------------------------
192
193
c At this point the program could terminate and load the LU
194
C factors (numeric) from the n0.umf file, and solve the
195
c system (see below). Note that the symbolic object is not
196
c required.
197
198
c load the numeric factorization back in (filename: n0.umf)
199
call umf4lnum (numeric, filenum, status)
200
if (status .lt. 0) then
201
print *, 'Error occurred in umf4lnum: ', status
202
stop
203
endif
204
205
c solve Ax=b, without iterative refinement
206
sys = 0
207
call umf4sol (sys, x, b, numeric, control, info)
208
if (info (1) .lt. 0) then
209
print *, 'Error occurred in umf4sol: ', info (1)
210
stop
211
endif
212
213
c free the numeric factorization
214
call umf4fnum (numeric)
215
216
c No LU factors (symbolic or numeric) are in memory at this point.
217
218
c print final statistics
219
call umf4pinf (control, info)
220
221
c print the residual. x (i) should be 1 + i/n
222
call resid (n, nz, Ap, Ai, Ax, x, b, r)
223
224
c ----------------------------------------------------------------
225
c load the symbolic analysis back in, and factorize a new matrix
226
c ----------------------------------------------------------------
227
228
c Again, the program could terminate here, recreate the matrix,
229
c and refactorize. Note that umf4sym is not called.
230
231
c load the symbolic factorization back in (filename: s0.umf)
232
call umf4lsym (symbolic, filenum, status)
233
if (status .lt. 0) then
234
print *, 'Error occurred in umf4lsym: ', status
235
stop
236
endif
237
238
c arbitrarily change the values of the matrix but not the pattern
239
do 100 p = 1, nz
240
Ax (p) = Ax (p) + 3.14159 / 100.0
241
100 continue
242
243
c numeric factorization of the modified matrix
244
call umf4num (Ap, Ai, Ax, symbolic, numeric, control, info)
245
if (info (1) .lt. 0) then
246
print *, 'Error occurred in umf4num: ', info (1)
247
stop
248
endif
249
250
c free the symbolic analysis
251
call umf4fsym (symbolic)
252
253
c create a new right-hand-side, assume x (i) = 7 - i/n
254
do 110 i = 1,n
255
b (i) = 0
256
110 continue
257
c b = A*x, with the modified matrix A (note that A is now 0-based)
258
do 130 j = 1,n
259
xj = j
260
xj = 7 - xj / n
261
do 120 p = Ap (j) + 1, Ap (j+1)
262
i = Ai (p) + 1
263
aij = Ax (p)
264
b (i) = b (i) + aij * xj
265
120 continue
266
130 continue
267
268
c ----------------------------------------------------------------
269
c solve Ax=b, with iterative refinement
270
c ----------------------------------------------------------------
271
272
sys = 0
273
call umf4solr (sys, Ap, Ai, Ax, x, b, numeric, control, info)
274
if (info (1) .lt. 0) then
275
print *, 'Error occurred in umf4solr: ', info (1)
276
stop
277
endif
278
279
c print the residual. x (i) should be 7 - i/n
280
call resid (n, nz, Ap, Ai, Ax, x, b, r)
281
282
c ----------------------------------------------------------------
283
c solve Ax=b, without iterative refinement, broken into steps
284
c ----------------------------------------------------------------
285
286
c the factorization is PAQ=LU, PRAQ=LU, or P(R\A)Q=LU.
287
288
c x = R*b (or x=R\b, or x=b, as appropriate)
289
call umf4scal (x, b, numeric, status)
290
if (status .lt. 0) then
291
print *, 'Error occurred in umf4scal: ', status
292
stop
293
endif
294
295
c solve P'Lr=x for r (using r as workspace)
296
sys = 3
297
call umf4sol (sys, r, x, numeric, control, info)
298
if (info (1) .lt. 0) then
299
print *, 'Error occurred in umf4sol: ', info (1)
300
stop
301
endif
302
303
c solve UQ'x=r for x
304
sys = 9
305
call umf4sol (sys, x, r, numeric, control, info)
306
if (info (1) .lt. 0) then
307
print *, 'Error occurred in umf4sol: ', info (1)
308
stop
309
endif
310
311
c free the numeric factorization
312
call umf4fnum (numeric)
313
314
c print the residual. x (i) should be 7 - i/n
315
call resid (n, nz, Ap, Ai, Ax, x, b, r)
316
317
stop
318
998 print *, 'Read error: Harwell/Boeing matrix'
319
stop
320
end
321
322
c=======================================================================
323
c== resid ==============================================================
324
c=======================================================================
325
326
c Compute the residual, r = Ax-b, its max-norm, and print the max-norm
327
C Note that A is zero-based.
328
329
subroutine resid (n, nz, Ap, Ai, Ax, x, b, r)
330
integer*8
331
$ n, nz, Ap (n+1), Ai (n), j, i, p
332
double precision Ax (nz), x (n), b (n), r (n), rmax, aij
333
334
do 10 i = 1, n
335
r (i) = -b (i)
336
10 continue
337
338
do 30 j = 1,n
339
do 20 p = Ap (j) + 1, Ap (j+1)
340
i = Ai (p) + 1
341
aij = Ax (p)
342
r (i) = r (i) + aij * x (j)
343
20 continue
344
30 continue
345
346
rmax = 0
347
do 40 i = 1, n
348
rmax = max (rmax, r (i))
349
40 continue
350
351
print *, 'norm (A*x-b): ', rmax
352
return
353
end
354
355