Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/parpack/pdgetv0.f
5192 views
1
c-----------------------------------------------------------------------
2
c\BeginDoc
3
c
4
c\Name: pdgetv0
5
c
6
c Message Passing Layer: MPI
7
c
8
c\Description:
9
c Generate a random initial residual vector for the Arnoldi process.
10
c Force the residual vector to be in the range of the operator OP.
11
c
12
c\Usage:
13
c call pdgetv0
14
c ( COMM, IDO, BMAT, ITRY, INITV, N, J, V, LDV, RESID, RNORM,
15
c IPNTR, WORKD, WORKL, IERR )
16
c
17
c\Arguments
18
c COMM MPI Communicator for the processor grid. (INPUT)
19
c
20
c IDO Integer. (INPUT/OUTPUT)
21
c Reverse communication flag. IDO must be zero on the first
22
c call to pdgetv0.
23
c -------------------------------------------------------------
24
c IDO = 0: first call to the reverse communication interface
25
c IDO = -1: compute Y = OP * X where
26
c IPNTR(1) is the pointer into WORKD for X,
27
c IPNTR(2) is the pointer into WORKD for Y.
28
c This is for the initialization phase to force the
29
c starting vector into the range of OP.
30
c IDO = 2: compute Y = B * X where
31
c IPNTR(1) is the pointer into WORKD for X,
32
c IPNTR(2) is the pointer into WORKD for Y.
33
c IDO = 99: done
34
c -------------------------------------------------------------
35
c
36
c BMAT Character*1. (INPUT)
37
c BMAT specifies the type of the matrix B in the (generalized)
38
c eigenvalue problem A*x = lambda*B*x.
39
c B = 'I' -> standard eigenvalue problem A*x = lambda*x
40
c B = 'G' -> generalized eigenvalue problem A*x = lambda*B*x
41
c
42
c ITRY Integer. (INPUT)
43
c ITRY counts the number of times that pdgetv0 is called.
44
c It should be set to 1 on the initial call to pdgetv0.
45
c
46
c INITV Logical variable. (INPUT)
47
c .TRUE. => the initial residual vector is given in RESID.
48
c .FALSE. => generate a random initial residual vector.
49
c
50
c N Integer. (INPUT)
51
c Dimension of the problem.
52
c
53
c J Integer. (INPUT)
54
c Index of the residual vector to be generated, with respect to
55
c the Arnoldi process. J > 1 in case of a "restart".
56
c
57
c V Double precision N by J array. (INPUT)
58
c The first J-1 columns of V contain the current Arnoldi basis
59
c if this is a "restart".
60
c
61
c LDV Integer. (INPUT)
62
c Leading dimension of V exactly as declared in the calling
63
c program.
64
c
65
c RESID Double precision array of length N. (INPUT/OUTPUT)
66
c Initial residual vector to be generated. If RESID is
67
c provided, force RESID into the range of the operator OP.
68
c
69
c RNORM Double precision scalar. (OUTPUT)
70
c B-norm of the generated residual.
71
c
72
c IPNTR Integer array of length 3. (OUTPUT)
73
c
74
c WORKD Double precision work array of length 2*N. (REVERSE COMMUNICATION).
75
c On exit, WORK(1:N) = B*RESID to be used in SSAITR.
76
c
77
c WORKL Double precision work space used for Gram Schmidt orthogonalization
78
c
79
c IERR Integer. (OUTPUT)
80
c = 0: Normal exit.
81
c = -1: Cannot generate a nontrivial restarted residual vector
82
c in the range of the operator OP.
83
c
84
c\EndDoc
85
c
86
c-----------------------------------------------------------------------
87
c
88
c\BeginLib
89
c
90
c\Local variables:
91
c xxxxxx real
92
c
93
c\References:
94
c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
95
c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
96
c pp 357-385.
97
c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
98
c Restarted Arnoldi Iteration", Rice University Technical Report
99
c TR95-13, Department of Computational and Applied Mathematics.
100
c
101
c\Routines called:
102
c second ARPACK utility routine for timing.
103
c pdvout Parallel ARPACK utility routine for vector output.
104
c pdlarnv Parallel wrapper for LAPACK routine dlarnv (generates a random vector).
105
c dgemv Level 2 BLAS routine for matrix vector multiplication.
106
c dcopy Level 1 BLAS that copies one vector to another.
107
c ddot Level 1 BLAS that computes the scalar product of two vectors.
108
c pdnorm2 Parallel version of Level 1 BLAS that computes the norm of a vector.
109
c
110
c\Author
111
c Danny Sorensen Phuong Vu
112
c Richard Lehoucq Cray Research, Inc. &
113
c Dept. of Computational & CRPC / Rice University
114
c Applied Mathematics Houston, Texas
115
c Rice University
116
c Houston, Texas
117
c
118
c\Parallel Modifications
119
c Kristi Maschhoff
120
c
121
c\Revision history:
122
c Starting Point: Serial Code FILE: getv0.F SID: 2.3
123
c
124
c\SCCS Information:
125
c FILE: getv0.F SID: 1.4 DATE OF SID: 3/19/97
126
c
127
c\EndLib
128
c
129
c-----------------------------------------------------------------------
130
c
131
subroutine pdgetv0
132
& ( comm, ido, bmat, itry, initv, n, j, v, ldv, resid, rnorm,
133
& ipntr, workd, workl, ierr )
134
c
135
include 'mpif.h'
136
c
137
c %---------------%
138
c | MPI Variables |
139
c %---------------%
140
c
141
integer comm
142
c
143
c %----------------------------------------------------%
144
c | Include files for debugging and timing information |
145
c %----------------------------------------------------%
146
c
147
include 'debug.h'
148
include 'stat.h'
149
c
150
c %------------------%
151
c | Scalar Arguments |
152
c %------------------%
153
c
154
character bmat*1
155
logical initv
156
integer ido, ierr, itry, j, ldv, n
157
Double precision
158
& rnorm
159
c
160
c %-----------------%
161
c | Array Arguments |
162
c %-----------------%
163
c
164
integer ipntr(3)
165
Double precision
166
& resid(n), v(ldv,j), workd(2*n), workl(2*j)
167
c
168
c %------------%
169
c | Parameters |
170
c %------------%
171
c
172
Double precision
173
& one, zero
174
parameter (one = 1.0, zero = 0.0)
175
c
176
c %------------------------%
177
c | Local Scalars & Arrays |
178
c %------------------------%
179
c
180
logical first, inits, orth
181
integer idist, iseed(4), iter, msglvl, jj
182
Double precision
183
& rnorm0
184
save first, iseed, inits, iter, msglvl, orth, rnorm0
185
c
186
Double precision
187
& rnorm_buf
188
c
189
c %----------------------%
190
c | External Subroutines |
191
c %----------------------%
192
c
193
external pdlarnv, pdvout, dcopy, dgemv, second
194
c
195
c %--------------------%
196
c | External Functions |
197
c %--------------------%
198
c
199
Double precision
200
& ddot, pdnorm2
201
external ddot, pdnorm2
202
c
203
c %---------------------%
204
c | Intrinsic Functions |
205
c %---------------------%
206
c
207
intrinsic abs, sqrt
208
c
209
c %-----------------%
210
c | Data Statements |
211
c %-----------------%
212
c
213
data inits /.true./
214
c
215
c %-----------------------%
216
c | Executable Statements |
217
c %-----------------------%
218
c
219
c
220
c %-----------------------------------%
221
c | Initialize the seed of the LAPACK |
222
c | random number generator |
223
c %-----------------------------------%
224
c
225
if (inits) then
226
iseed(1) = 1
227
iseed(2) = 3
228
iseed(3) = 5
229
iseed(4) = 7
230
inits = .false.
231
end if
232
c
233
if (ido .eq. 0) then
234
c
235
c %-------------------------------%
236
c | Initialize timing statistics |
237
c | & message level for debugging |
238
c %-------------------------------%
239
c
240
call second (t0)
241
msglvl = mgetv0
242
c
243
ierr = 0
244
iter = 0
245
first = .FALSE.
246
orth = .FALSE.
247
c
248
c %-----------------------------------------------------%
249
c | Possibly generate a random starting vector in RESID |
250
c | Use a LAPACK random number generator used by the |
251
c | matrix generation routines. |
252
c | idist = 1: uniform (0,1) distribution; |
253
c | idist = 2: uniform (-1,1) distribution; |
254
c | idist = 3: normal (0,1) distribution; |
255
c %-----------------------------------------------------%
256
c
257
if (.not.initv) then
258
idist = 2
259
call pdlarnv (comm, idist, iseed, n, resid)
260
end if
261
c
262
c %----------------------------------------------------------%
263
c | Force the starting vector into the range of OP to handle |
264
c | the generalized problem when B is possibly (singular). |
265
c %----------------------------------------------------------%
266
c
267
call second (t2)
268
if (bmat .eq. 'G') then
269
nopx = nopx + 1
270
ipntr(1) = 1
271
ipntr(2) = n + 1
272
call dcopy (n, resid, 1, workd, 1)
273
ido = -1
274
go to 9000
275
end if
276
end if
277
c
278
c %-----------------------------------------%
279
c | Back from computing OP*(initial-vector) |
280
c %-----------------------------------------%
281
c
282
if (first) go to 20
283
c
284
c %-----------------------------------------------%
285
c | Back from computing B*(orthogonalized-vector) |
286
c %-----------------------------------------------%
287
c
288
if (orth) go to 40
289
c
290
call second (t3)
291
tmvopx = tmvopx + (t3 - t2)
292
c
293
c %------------------------------------------------------%
294
c | Starting vector is now in the range of OP; r = OP*r; |
295
c | Compute B-norm of starting vector. |
296
c %------------------------------------------------------%
297
c
298
call second (t2)
299
first = .TRUE.
300
if (bmat .eq. 'G') then
301
nbx = nbx + 1
302
call dcopy (n, workd(n+1), 1, resid, 1)
303
ipntr(1) = n + 1
304
ipntr(2) = 1
305
ido = 2
306
go to 9000
307
else if (bmat .eq. 'I') then
308
call dcopy (n, resid, 1, workd, 1)
309
end if
310
c
311
20 continue
312
c
313
if (bmat .eq. 'G') then
314
call second (t3)
315
tmvbx = tmvbx + (t3 - t2)
316
endif
317
c
318
first = .FALSE.
319
if (bmat .eq. 'G') then
320
rnorm_buf = ddot (n, resid, 1, workd, 1)
321
call MPI_ALLREDUCE( rnorm_buf, rnorm0, 1,
322
& MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr )
323
rnorm0 = sqrt(abs(rnorm0))
324
else if (bmat .eq. 'I') then
325
rnorm0 = pdnorm2( comm, n, resid, 1 )
326
end if
327
rnorm = rnorm0
328
c
329
c %---------------------------------------------%
330
c | Exit if this is the very first Arnoldi step |
331
c %---------------------------------------------%
332
c
333
if (j .eq. 1) go to 50
334
c
335
c %----------------------------------------------------------------
336
c | Otherwise need to B-orthogonalize the starting vector against |
337
c | the current Arnoldi basis using Gram-Schmidt with iter. ref. |
338
c | This is the case where an invariant subspace is encountered |
339
c | in the middle of the Arnoldi factorization. |
340
c | |
341
c | s = V^{T}*B*r; r = r - V*s; |
342
c | |
343
c | Stopping criteria used for iter. ref. is discussed in |
344
c | Parlett's book, page 107 and in Gragg & Reichel TOMS paper. |
345
c %---------------------------------------------------------------%
346
c
347
orth = .TRUE.
348
30 continue
349
c
350
call dgemv ('T', n, j-1, one, v, ldv, workd, 1,
351
& zero, workl(j+1), 1)
352
call MPI_ALLREDUCE( workl(j+1), workl, j-1,
353
& MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
354
call dgemv ('N', n, j-1, -one, v, ldv, workl, 1,
355
& one, resid, 1)
356
c
357
c %----------------------------------------------------------%
358
c | Compute the B-norm of the orthogonalized starting vector |
359
c %----------------------------------------------------------%
360
c
361
call second (t2)
362
if (bmat .eq. 'G') then
363
nbx = nbx + 1
364
call dcopy (n, resid, 1, workd(n+1), 1)
365
ipntr(1) = n + 1
366
ipntr(2) = 1
367
ido = 2
368
go to 9000
369
else if (bmat .eq. 'I') then
370
call dcopy (n, resid, 1, workd, 1)
371
end if
372
c
373
40 continue
374
c
375
if (bmat .eq. 'G') then
376
call second (t3)
377
tmvbx = tmvbx + (t3 - t2)
378
endif
379
c
380
if (bmat .eq. 'G') then
381
rnorm_buf = ddot (n, resid, 1, workd, 1)
382
call MPI_ALLREDUCE( rnorm_buf, rnorm, 1,
383
& MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr )
384
rnorm = sqrt(abs(rnorm))
385
else if (bmat .eq. 'I') then
386
rnorm = pdnorm2( comm, n, resid, 1 )
387
end if
388
c
389
c %--------------------------------------%
390
c | Check for further orthogonalization. |
391
c %--------------------------------------%
392
c
393
if (msglvl .gt. 2) then
394
call pdvout (comm, logfil, 1, [rnorm0], ndigit,
395
& '_getv0: re-orthonalization ; rnorm0 is')
396
call pdvout (comm, logfil, 1, [rnorm], ndigit,
397
& '_getv0: re-orthonalization ; rnorm is')
398
end if
399
c
400
if (rnorm .gt. 0.717*rnorm0) go to 50
401
c
402
iter = iter + 1
403
if (iter .le. 1) then
404
c
405
c %-----------------------------------%
406
c | Perform iterative refinement step |
407
c %-----------------------------------%
408
c
409
rnorm0 = rnorm
410
go to 30
411
else
412
c
413
c %------------------------------------%
414
c | Iterative refinement step "failed" |
415
c %------------------------------------%
416
c
417
do 45 jj = 1, n
418
resid(jj) = zero
419
45 continue
420
rnorm = zero
421
ierr = -1
422
end if
423
c
424
50 continue
425
c
426
if (msglvl .gt. 0) then
427
call pdvout (comm, logfil, 1, [rnorm], ndigit,
428
& '_getv0: B-norm of initial / restarted starting vector')
429
end if
430
if (msglvl .gt. 2) then
431
call pdvout (comm, logfil, n, resid, ndigit,
432
& '_getv0: initial / restarted starting vector')
433
end if
434
ido = 99
435
c
436
call second (t1)
437
tgetv0 = tgetv0 + (t1 - t0)
438
c
439
9000 continue
440
return
441
c
442
c %----------------%
443
c | End of pdgetv0 |
444
c %----------------%
445
c
446
end
447
448