Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/umfpack/demo/umf4zhb.f
3196 views
1
c=======================================================================
2
c== umf4zhb ============================================================
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 umf4zhb:
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 CUA-type matrices.
17
c
18
c This is HIGHLY non-portable. It may not work with your C and
19
c FORTRAN compilers. See umf4z_f77wrapper.c for more details.
20
c
21
c usage (for example):
22
c
23
c in a Unix shell:
24
c umf4zhb < HB/arc130.cua
25
26
integer
27
$ nzmax, nmax
28
parameter (nzmax = 5000000, nmax = 160000)
29
integer
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),
37
$ control (20), info (90)
38
complex*16 AA (nzmax), XX (nmax), BB (nmax), r (nmax), aij, xj
39
double precision Az (nmax), xz (nmax), bz (nmax), xi, xr
40
character rhstyp*3
41
42
c ----------------------------------------------------------------
43
c read the Harwell/Boeing matrix
44
c ----------------------------------------------------------------
45
46
read (5, 10, err = 998)
47
$ title, key,
48
$ totcrd, ptrcrd, indcrd, valcrd, rhscrd,
49
$ type, nrow, ncol, nz, nel,
50
$ ptrfmt, indfmt, valfmt, rhsfmt
51
if (rhscrd .gt. 0) then
52
c new Harwell/Boeing format:
53
read (5, 20, err = 998) rhstyp, nrhs, nzrhs
54
endif
55
10 format (a72, a8 / 5i14 / a3, 11x, 4i14 / 2a16, 2a20)
56
20 format (a3, 11x, 2i14)
57
58
print *, 'Matrix key: ', key
59
60
n = nrow
61
if (type .ne. 'CUA' .or. nrow .ne. ncol) then
62
print *, 'Error: can only handle square CUA matrices'
63
stop
64
endif
65
if (n .ge. nmax .or. nz .gt. nzmax) then
66
print *, ' Matrix too big!'
67
stop
68
endif
69
70
c read the matrix (1-based)
71
read (5, ptrfmt, err = 998) (Ap (p), p = 1, ncol+1)
72
read (5, indfmt, err = 998) (Ai (p), p = 1, nz)
73
read (5, valfmt, err = 998) (AA (p), p = 1, nz)
74
75
do 15 p = 1, nz
76
Ax (p) = dble (AA (p))
77
Az (p) = imag (AA (p))
78
15 continue
79
80
c ----------------------------------------------------------------
81
c create the right-hand-side, assume
82
c x (i) = (1 + i/n), (n + i/100)
83
c ----------------------------------------------------------------
84
85
do 30 i = 1,n
86
BB (i) = 0
87
30 continue
88
c b = A*x
89
do 50 j = 1,n
90
xr = j
91
xi = n
92
xi = xi + xr/100
93
xr = 1 + xr / n
94
xj = dcmplx (xr, xi)
95
do 40 p = Ap (j), Ap (j+1)-1
96
i = Ai (p)
97
aij = AA (p)
98
BB (i) = BB (i) + aij * xj
99
40 continue
100
50 continue
101
do 32 i = 1,n
102
b (i) = dble (BB (i))
103
bz (i) = imag (BB (i))
104
32 continue
105
106
c ----------------------------------------------------------------
107
c convert from 1-based to 0-based
108
c ----------------------------------------------------------------
109
110
do 60 j = 1, n+1
111
Ap (j) = Ap (j) - 1
112
60 continue
113
do 70 p = 1, nz
114
Ai (p) = Ai (p) - 1
115
70 continue
116
117
c ----------------------------------------------------------------
118
c factor the matrix and save to a file
119
c ----------------------------------------------------------------
120
121
c set default parameters
122
call umf4zdef (control)
123
124
c print control parameters. set control (1) to 1 to print
125
c error messages only
126
control (1) = 2
127
call umf4zpcon (control)
128
129
c pre-order and symbolic analysis
130
call umf4zsym (n, n, Ap, Ai, Ax, Az, symbolic, control, info)
131
132
c print statistics computed so far
133
c call umf4zpinf (control, info) could also be done.
134
print 80, info (1), info (16),
135
$ (info (21) * info (4)) / 2**20,
136
$ (info (22) * info (4)) / 2**20,
137
$ info (23), info (24), info (25)
138
80 format ('symbolic analysis:',/,
139
$ ' status: ', f5.0, /,
140
$ ' time: ', e10.2, ' (sec)'/,
141
$ ' estimates (upper bound) for numeric LU:', /,
142
$ ' size of LU: ', f10.2, ' (MB)', /,
143
$ ' memory needed: ', f10.2, ' (MB)', /,
144
$ ' flop count: ', e10.2, /
145
$ ' nnz (L): ', f10.0, /
146
$ ' nnz (U): ', f10.0)
147
148
c check umf4zsym error condition
149
if (info (1) .lt. 0) then
150
print *, 'Error occurred in umf4zsym: ', info (1)
151
stop
152
endif
153
154
c numeric factorization
155
call umf4znum (Ap, Ai, Ax, Az, symbolic, numeric, control, info)
156
157
c print statistics for the numeric factorization
158
c call umf4zpinf (control, info) could also be done.
159
print 90, info (1), info (66),
160
$ (info (41) * info (4)) / 2**20,
161
$ (info (42) * info (4)) / 2**20,
162
$ info (43), info (44), info (45)
163
90 format ('numeric factorization:',/,
164
$ ' status: ', f5.0, /,
165
$ ' time: ', e10.2, /,
166
$ ' actual numeric LU statistics:', /,
167
$ ' size of LU: ', f10.2, ' (MB)', /,
168
$ ' memory needed: ', f10.2, ' (MB)', /,
169
$ ' flop count: ', e10.2, /
170
$ ' nnz (L): ', f10.0, /
171
$ ' nnz (U): ', f10.0)
172
173
c check umf4znum error condition
174
if (info (1) .lt. 0) then
175
print *, 'Error occurred in umf4znum: ', info (1)
176
stop
177
endif
178
179
c save the symbolic analysis to the file s42.umf
180
c note that this is not needed until another matrix is
181
c factorized, below.
182
filenum = 42
183
call umf4zssym (symbolic, filenum, status)
184
if (status .lt. 0) then
185
print *, 'Error occurred in umf4zssym: ', status
186
stop
187
endif
188
189
c save the LU factors to the file n0.umf
190
call umf4zsnum (numeric, filenum, status)
191
if (status .lt. 0) then
192
print *, 'Error occurred in umf4zsnum: ', status
193
stop
194
endif
195
196
c free the symbolic analysis
197
call umf4zfsym (symbolic)
198
199
c free the numeric factorization
200
call umf4zfnum (numeric)
201
202
c No LU factors (symbolic or numeric) are in memory at this point.
203
204
c ----------------------------------------------------------------
205
c load the LU factors back in, and solve the system
206
c ----------------------------------------------------------------
207
208
c At this point the program could terminate and load the LU
209
C factors (numeric) from the n0.umf file, and solve the
210
c system (see below). Note that the symbolic object is not
211
c required.
212
213
c load the numeric factorization back in (filename: n0.umf)
214
call umf4zlnum (numeric, filenum, status)
215
if (status .lt. 0) then
216
print *, 'Error occurred in umf4zlnum: ', status
217
stop
218
endif
219
220
c solve Ax=b, without iterative refinement
221
sys = 0
222
call umf4zsol (sys, x, xz, b, bz, numeric, control, info)
223
if (info (1) .lt. 0) then
224
print *, 'Error occurred in umf4zsol: ', info (1)
225
stop
226
endif
227
do 33 i = 1,n
228
XX (i) = dcmplx (x (i), xz (i))
229
33 continue
230
231
c free the numeric factorization
232
call umf4zfnum (numeric)
233
234
c No LU factors (symbolic or numeric) are in memory at this point.
235
236
c print final statistics
237
call umf4zpinf (control, info)
238
239
c print the residual. x (i) should be 1 + i/n
240
call resid (n, nz, Ap, Ai, AA, XX, BB, r)
241
242
stop
243
998 print *, 'Read error: Harwell/Boeing matrix'
244
stop
245
end
246
247
c=======================================================================
248
c== resid ==============================================================
249
c=======================================================================
250
251
c Compute the residual, r = Ax-b, its max-norm, and print the max-norm
252
C Note that A is zero-based.
253
254
subroutine resid (n, nz, Ap, Ai, A, x, b, r)
255
integer
256
$ n, nz, Ap (n+1), Ai (n), j, i, p
257
complex*16 A (nz), x (n), b (n), r (n), aij
258
double precision rmax
259
260
do 10 i = 1, n
261
r (i) = -b (i)
262
10 continue
263
264
do 30 j = 1,n
265
do 20 p = Ap (j) + 1, Ap (j+1)
266
i = Ai (p) + 1
267
aij = A (p)
268
r (i) = r (i) + aij * x (j)
269
20 continue
270
30 continue
271
272
rmax = 0
273
do 40 i = 1, n
274
rmax = max (rmax, abs (r (i)))
275
40 continue
276
277
print *, 'norm (A*x-b): ', rmax
278
return
279
end
280
281