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