Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/parpack/pcnaup2.f
5213 views
1
c\BeginDoc
2
c
3
c\Name: pcnaup2
4
c
5
c Message Passing Layer: MPI
6
c
7
c\Description:
8
c Intermediate level interface called by pcnaupd.
9
c
10
c\Usage:
11
c call pcnaup2
12
c ( COMM, IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD,
13
c ISHIFT, MXITER, V, LDV, H, LDH, RITZ, BOUNDS,
14
c Q, LDQ, WORKL, IPNTR, WORKD, RWORK, INFO )
15
c
16
c\Arguments
17
c
18
c COMM, IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in pcnaupd.
19
c MODE, ISHIFT, MXITER: see the definition of IPARAM in pcnaupd.
20
c
21
c NP Integer. (INPUT/OUTPUT)
22
c Contains the number of implicit shifts to apply during
23
c each Arnoldi iteration.
24
c If ISHIFT=1, NP is adjusted dynamically at each iteration
25
c to accelerate convergence and prevent stagnation.
26
c This is also roughly equal to the number of matrix-vector
27
c products (involving the operator OP) per Arnoldi iteration.
28
c The logic for adjusting is contained within the current
29
c subroutine.
30
c If ISHIFT=0, NP is the number of shifts the user needs
31
c to provide via reverse comunication. 0 < NP < NCV-NEV.
32
c NP may be less than NCV-NEV since a leading block of the current
33
c upper Hessenberg matrix has split off and contains "unwanted"
34
c Ritz values.
35
c Upon termination of the IRA iteration, NP contains the number
36
c of "converged" wanted Ritz values.
37
c
38
c IUPD Integer. (INPUT)
39
c IUPD .EQ. 0: use explicit restart instead implicit update.
40
c IUPD .NE. 0: use implicit update.
41
c
42
c V Complex N by (NEV+NP) array. (INPUT/OUTPUT)
43
c The Arnoldi basis vectors are returned in the first NEV
44
c columns of V.
45
c
46
c LDV Integer. (INPUT)
47
c Leading dimension of V exactly as declared in the calling
48
c program.
49
c
50
c H Complex (NEV+NP) by (NEV+NP) array. (OUTPUT)
51
c H is used to store the generated upper Hessenberg matrix
52
c
53
c LDH Integer. (INPUT)
54
c Leading dimension of H exactly as declared in the calling
55
c program.
56
c
57
c RITZ Complex array of length NEV+NP. (OUTPUT)
58
c RITZ(1:NEV) contains the computed Ritz values of OP.
59
c
60
c BOUNDS Complex array of length NEV+NP. (OUTPUT)
61
c BOUNDS(1:NEV) contain the error bounds corresponding to
62
c the computed Ritz values.
63
c
64
c Q Complex (NEV+NP) by (NEV+NP) array. (WORKSPACE)
65
c Private (replicated) work array used to accumulate the
66
c rotation in the shift application step.
67
c
68
c LDQ Integer. (INPUT)
69
c Leading dimension of Q exactly as declared in the calling
70
c program.
71
c
72
c WORKL Complex work array of length at least
73
c (NEV+NP)**2 + 3*(NEV+NP). (WORKSPACE)
74
c Private (replicated) array on each PE or array allocated on
75
c the front end. It is used in shifts calculation, shifts
76
c application and convergence checking.
77
c
78
c
79
c IPNTR Integer array of length 3. (OUTPUT)
80
c Pointer to mark the starting locations in the WORKD for
81
c vectors used by the Arnoldi iteration.
82
c -------------------------------------------------------------
83
c IPNTR(1): pointer to the current operand vector X.
84
c IPNTR(2): pointer to the current result vector Y.
85
c IPNTR(3): pointer to the vector B * X when used in the
86
c shift-and-invert mode. X is the current operand.
87
c -------------------------------------------------------------
88
c
89
c WORKD Complex work array of length 3*N. (WORKSPACE)
90
c Distributed array to be used in the basic Arnoldi iteration
91
c for reverse communication. The user should not use WORKD
92
c as temporary workspace during the iteration !!!!!!!!!!
93
c See Data Distribution Note in PCNAUPD.
94
c
95
c RWORK Real work array of length NEV+NP ( WORKSPACE)
96
c Private (replicated) array on each PE or array allocated on
97
c the front end.
98
c
99
c INFO Integer. (INPUT/OUTPUT)
100
c If INFO .EQ. 0, a randomly initial residual vector is used.
101
c If INFO .NE. 0, RESID contains the initial residual vector,
102
c possibly from a previous run.
103
c Error flag on output.
104
c = 0: Normal return.
105
c = 1: Maximum number of iterations taken.
106
c All possible eigenvalues of OP has been found.
107
c NP returns the number of converged Ritz values.
108
c = 2: No shifts could be applied.
109
c = -8: Error return from LAPACK eigenvalue calculation;
110
c This should never happen.
111
c = -9: Starting vector is zero.
112
c = -9999: Could not build an Arnoldi factorization.
113
c Size that was built in returned in NP.
114
c
115
c\EndDoc
116
c
117
c-----------------------------------------------------------------------
118
c
119
c\BeginLib
120
c
121
c\Local variables:
122
c xxxxxx Complex
123
c
124
c\References:
125
c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
126
c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
127
c pp 357-385.
128
c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
129
c Restarted Arnoldi Iteration", Rice University Technical Report
130
c TR95-13, Department of Computational and Applied Mathematics.
131
c
132
c\Routines called:
133
c pcgetv0 Parallel ARPACK initial vector generation routine.
134
c pcnaitr Parallel ARPACK Arnoldi factorization routine.
135
c pcnapps Parallel ARPACK application of implicit shifts routine.
136
c pcneigh Parallel ARPACK compute Ritz values and error bounds routine.
137
c pcngets Parallel ARPACK reorder Ritz values and error bounds routine.
138
c csortc ARPACK sorting routine.
139
c pivout Parallel ARPACK utility routine that prints integers.
140
c second ARPACK utility routine for timing.
141
c pcmout Parallel ARPACK utility routine that prints matrices
142
c pcvout Parallel ARPACK utility routine that prints vectors.
143
c psvout ARPACK utility routine that prints vectors.
144
c pslamch ScaLAPACK routine that determines machine constants.
145
c slapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully.
146
c ccopy Level 1 BLAS that copies one vector to another .
147
c cdotc Level 1 BLAS that computes the scalar product of two vectors.
148
c cswap Level 1 BLAS that swaps two vectors.
149
c pscnorm2 Parallel version of Level 1 BLAS that computes the norm of a vector.
150
c
151
c\Author
152
c Danny Sorensen Phuong Vu
153
c Richard Lehoucq CRPC / Rice University
154
c Dept. of Computational & Houston, Texas
155
c Applied Mathematics
156
c Rice University
157
c Houston, Texas
158
c
159
c FILE: naup2.F SID: 1.6 DATE OF SID: 06/01/00 RELEASE: 1
160
c
161
c\Remarks
162
c 1. None
163
c
164
c\EndLib
165
c
166
c-----------------------------------------------------------------------
167
c
168
subroutine pcnaup2
169
& ( comm, ido, bmat, n, which, nev, np, tol, resid, mode, iupd,
170
& ishift, mxiter, v, ldv, h, ldh, ritz, bounds,
171
& q, ldq, workl, ipntr, workd, rwork, info )
172
c
173
include 'mpif.h'
174
c
175
c %---------------%
176
c | MPI Variables |
177
c %---------------%
178
c
179
integer comm
180
c
181
c %----------------------------------------------------%
182
c | Include files for debugging and timing information |
183
c %----------------------------------------------------%
184
c
185
include 'debug.h'
186
include 'stat.h'
187
c
188
c %------------------%
189
c | Scalar Arguments |
190
c %------------------%
191
c
192
character bmat*1, which*2
193
integer ido, info, ishift, iupd, mode, ldh, ldq, ldv, mxiter,
194
& n, nev, np
195
Real
196
& tol
197
c
198
c %-----------------%
199
c | Array Arguments |
200
c %-----------------%
201
c
202
integer ipntr(13)
203
Complex
204
& bounds(nev+np), h(ldh,nev+np), q(ldq,nev+np),
205
& resid(n), ritz(nev+np), v(ldv,nev+np),
206
& workd(3*n), workl( (nev+np)*(nev+np+3) )
207
Real
208
& rwork(nev+np)
209
c
210
c %------------%
211
c | Parameters |
212
c %------------%
213
c
214
Complex
215
& one, zero
216
Real
217
& rzero
218
parameter (one = (1.0, 0.0) , zero = (0.0, 0.0) ,
219
& rzero = 0.0 )
220
c
221
c %---------------%
222
c | Local Scalars |
223
c %---------------%
224
c
225
logical cnorm, getv0, initv , update, ushift
226
integer ierr , iter , kplusp, msglvl, nconv,
227
& nevbef, nev0 , np0 , nptemp, i ,
228
& j
229
Complex
230
& cmpnorm
231
Real
232
& rnorm, eps23, rtemp
233
character wprime*2
234
c
235
save cnorm, getv0, initv , update, ushift,
236
& rnorm, iter , kplusp, msglvl, nconv,
237
& nevbef, nev0 , np0, eps23
238
c
239
240
Real
241
& cmpnorm_buf
242
c
243
c %-----------------------%
244
c | Local array arguments |
245
c %-----------------------%
246
c
247
integer kp(3)
248
c
249
c %----------------------%
250
c | External Subroutines |
251
c %----------------------%
252
c
253
external ccopy, pcgetv0, pcnaitr, pcneigh, pcngets, pcnapps,
254
& csortc, cswap, pcmout, pcvout, pivout, second
255
c
256
c %--------------------%
257
c | External functions |
258
c %--------------------%
259
c
260
Complex
261
& cdotc
262
Real
263
& pscnorm2, pslamch10, slapy2
264
external cdotc, pscnorm2, pslamch10, slapy2
265
c
266
c %---------------------%
267
c | Intrinsic Functions |
268
c %---------------------%
269
c
270
intrinsic aimag, real , min, max, sqrt
271
c
272
c %-----------------------%
273
c | Executable Statements |
274
c %-----------------------%
275
c
276
if (ido .eq. 0) then
277
c
278
call second (t0)
279
c
280
msglvl = mcaup2
281
c
282
nev0 = nev
283
np0 = np
284
c
285
c %-------------------------------------%
286
c | kplusp is the bound on the largest |
287
c | Lanczos factorization built. |
288
c | nconv is the current number of |
289
c | "converged" eigenvalues. |
290
c | iter is the counter on the current |
291
c | iteration step. |
292
c %-------------------------------------%
293
c
294
kplusp = nev + np
295
nconv = 0
296
iter = 0
297
c
298
c %---------------------------------%
299
c | Get machine dependent constant. |
300
c %---------------------------------%
301
c
302
eps23 = pslamch10(comm, 'Epsilon-Machine')
303
eps23 = eps23**(2.0 / 3.0 )
304
c
305
c %---------------------------------------%
306
c | Set flags for computing the first NEV |
307
c | steps of the Arnoldi factorization. |
308
c %---------------------------------------%
309
c
310
getv0 = .true.
311
update = .false.
312
ushift = .false.
313
cnorm = .false.
314
c
315
if (info .ne. 0) then
316
c
317
c %--------------------------------------------%
318
c | User provides the initial residual vector. |
319
c %--------------------------------------------%
320
c
321
initv = .true.
322
info = 0
323
else
324
initv = .false.
325
end if
326
end if
327
c
328
c %---------------------------------------------%
329
c | Get a possibly random starting vector and |
330
c | force it into the range of the operator OP. |
331
c %---------------------------------------------%
332
c
333
10 continue
334
c
335
if (getv0) then
336
call pcgetv0 (comm, ido, bmat, 1, initv, n, 1, v, ldv,
337
& resid, rnorm, ipntr, workd, workl, info)
338
c
339
if (ido .ne. 99) go to 9000
340
c
341
if (rnorm .eq. rzero) then
342
c
343
c %-----------------------------------------%
344
c | The initial vector is zero. Error exit. |
345
c %-----------------------------------------%
346
c
347
info = -9
348
go to 1100
349
end if
350
getv0 = .false.
351
ido = 0
352
end if
353
c
354
c %-----------------------------------%
355
c | Back from reverse communication : |
356
c | continue with update step |
357
c %-----------------------------------%
358
c
359
if (update) go to 20
360
c
361
c %-------------------------------------------%
362
c | Back from computing user specified shifts |
363
c %-------------------------------------------%
364
c
365
if (ushift) go to 50
366
c
367
c %-------------------------------------%
368
c | Back from computing residual norm |
369
c | at the end of the current iteration |
370
c %-------------------------------------%
371
c
372
if (cnorm) go to 100
373
c
374
c %----------------------------------------------------------%
375
c | Compute the first NEV steps of the Arnoldi factorization |
376
c %----------------------------------------------------------%
377
c
378
call pcnaitr (comm, ido, bmat, n, 0, nev, mode,
379
& resid, rnorm, v, ldv,
380
& h, ldh, ipntr, workd, workl, info)
381
c
382
c
383
if (ido .ne. 99) go to 9000
384
c
385
if (info .gt. 0) then
386
np = info
387
mxiter = iter
388
info = -9999
389
go to 1200
390
end if
391
c
392
c %--------------------------------------------------------------%
393
c | |
394
c | M A I N ARNOLDI I T E R A T I O N L O O P |
395
c | Each iteration implicitly restarts the Arnoldi |
396
c | factorization in place. |
397
c | |
398
c %--------------------------------------------------------------%
399
c
400
1000 continue
401
c
402
iter = iter + 1
403
c
404
if (msglvl .gt. 0) then
405
call pivout (comm, logfil, 1, [iter], ndigit,
406
& '_naup2: **** Start of major iteration number ****')
407
end if
408
c
409
c %-----------------------------------------------------------%
410
c | Compute NP additional steps of the Arnoldi factorization. |
411
c | Adjust NP since NEV might have been updated by last call |
412
c | to the shift application routine pcnapps. |
413
c %-----------------------------------------------------------%
414
c
415
np = kplusp - nev
416
c
417
if (msglvl .gt. 1) then
418
call pivout (comm, logfil, 1, [nev], ndigit,
419
& '_naup2: The length of the current Arnoldi factorization')
420
call pivout (comm, logfil, 1, [np], ndigit,
421
& '_naup2: Extend the Arnoldi factorization by')
422
end if
423
c
424
c %-----------------------------------------------------------%
425
c | Compute NP additional steps of the Arnoldi factorization. |
426
c %-----------------------------------------------------------%
427
c
428
ido = 0
429
20 continue
430
update = .true.
431
c
432
call pcnaitr (comm, ido, bmat, n, nev, np, mode,
433
& resid, rnorm, v, ldv,
434
& h, ldh, ipntr, workd, workl, info)
435
c
436
if (ido .ne. 99) go to 9000
437
c
438
if (info .gt. 0) then
439
np = info
440
mxiter = iter
441
info = -9999
442
go to 1200
443
end if
444
update = .false.
445
c
446
if (msglvl .gt. 1) then
447
call psvout (comm, logfil, 1, [rnorm], ndigit,
448
& '_naup2: Corresponding B-norm of the residual')
449
end if
450
c
451
c %--------------------------------------------------------%
452
c | Compute the eigenvalues and corresponding error bounds |
453
c | of the current upper Hessenberg matrix. |
454
c %--------------------------------------------------------%
455
c
456
call pcneigh ( comm, rnorm, kplusp, h, ldh, ritz, bounds,
457
& q, ldq, workl, rwork, ierr)
458
c
459
if (ierr .ne. 0) then
460
info = -8
461
go to 1200
462
end if
463
c
464
c %---------------------------------------------------%
465
c | Select the wanted Ritz values and their bounds |
466
c | to be used in the convergence test. |
467
c | The wanted part of the spectrum and corresponding |
468
c | error bounds are in the last NEV loc. of RITZ, |
469
c | and BOUNDS respectively. |
470
c %---------------------------------------------------%
471
c
472
nev = nev0
473
np = np0
474
c
475
c %--------------------------------------------------%
476
c | Make a copy of Ritz values and the corresponding |
477
c | Ritz estimates obtained from pcneigh. |
478
c %--------------------------------------------------%
479
c
480
call ccopy(kplusp,ritz,1,workl(kplusp**2+1),1)
481
call ccopy(kplusp,bounds,1,workl(kplusp**2+kplusp+1),1)
482
c
483
c %---------------------------------------------------%
484
c | Select the wanted Ritz values and their bounds |
485
c | to be used in the convergence test. |
486
c | The wanted part of the spectrum and corresponding |
487
c | bounds are in the last NEV loc. of RITZ |
488
c | BOUNDS respectively. |
489
c %---------------------------------------------------%
490
c
491
call pcngets ( comm, ishift, which, nev, np, ritz,
492
& bounds)
493
c
494
c %------------------------------------------------------------%
495
c | Convergence test: currently we use the following criteria. |
496
c | The relative accuracy of a Ritz value is considered |
497
c | acceptable if: |
498
c | |
499
c | error_bounds(i) .le. tol*max(eps23, magnitude_of_ritz(i)). |
500
c | |
501
c %------------------------------------------------------------%
502
c
503
nconv = 0
504
c
505
do 25 i = 1, nev
506
rtemp = max( eps23, slapy2( real (ritz(np+i)),
507
& aimag(ritz(np+i)) ) )
508
if ( slapy2(real (bounds(np+i)),aimag(bounds(np+i)))
509
& .le. tol*rtemp ) then
510
nconv = nconv + 1
511
end if
512
25 continue
513
c
514
if (msglvl .gt. 2) then
515
kp(1) = nev
516
kp(2) = np
517
kp(3) = nconv
518
call pivout (comm, logfil, 3, kp, ndigit,
519
& '_naup2: NEV, NP, NCONV are')
520
call pcvout (comm, logfil, kplusp, ritz, ndigit,
521
& '_naup2: The eigenvalues of H')
522
call pcvout (comm, logfil, kplusp, bounds, ndigit,
523
& '_naup2: Ritz estimates of the current NCV Ritz values')
524
end if
525
c
526
c %---------------------------------------------------------%
527
c | Count the number of unwanted Ritz values that have zero |
528
c | Ritz estimates. If any Ritz estimates are equal to zero |
529
c | then a leading block of H of order equal to at least |
530
c | the number of Ritz values with zero Ritz estimates has |
531
c | split off. None of these Ritz values may be removed by |
532
c | shifting. Decrease NP the number of shifts to apply. If |
533
c | no shifts may be applied, then prepare to exit |
534
c %---------------------------------------------------------%
535
c
536
nptemp = np
537
do 30 j=1, nptemp
538
if (bounds(j) .eq. zero) then
539
np = np - 1
540
nev = nev + 1
541
end if
542
30 continue
543
c
544
if ( (nconv .ge. nev0) .or.
545
& (iter .gt. mxiter) .or.
546
& (np .eq. 0) ) then
547
c
548
if (msglvl .gt. 4) then
549
call pcvout(comm, logfil, kplusp,
550
& workl(kplusp**2+1), ndigit,
551
& '_naup2: Eigenvalues computed by _neigh:')
552
call pcvout(comm, logfil, kplusp,
553
& workl(kplusp**2+kplusp+1), ndigit,
554
& '_naup2: Ritz eistmates computed by _neigh:')
555
end if
556
c
557
c %------------------------------------------------%
558
c | Prepare to exit. Put the converged Ritz values |
559
c | and corresponding bounds in RITZ(1:NCONV) and |
560
c | BOUNDS(1:NCONV) respectively. Then sort. Be |
561
c | careful when NCONV > NP |
562
c %------------------------------------------------%
563
c
564
c %------------------------------------------%
565
c | Use h( 3,1 ) as storage to communicate |
566
c | rnorm to pcneupd if needed |
567
c %------------------------------------------%
568
c
569
h(3,1) = cmplx(rnorm,rzero)
570
c
571
c %----------------------------------------------%
572
c | Sort Ritz values so that converged Ritz |
573
c | values appear within the first NEV locations |
574
c | of ritz and bounds, and the most desired one |
575
c | appears at the front. |
576
c %----------------------------------------------%
577
c
578
if (which .eq. 'LM') wprime = 'SM'
579
if (which .eq. 'SM') wprime = 'LM'
580
if (which .eq. 'LR') wprime = 'SR'
581
if (which .eq. 'SR') wprime = 'LR'
582
if (which .eq. 'LI') wprime = 'SI'
583
if (which .eq. 'SI') wprime = 'LI'
584
c
585
call csortc(wprime, .true., kplusp, ritz, bounds)
586
c
587
c %--------------------------------------------------%
588
c | Scale the Ritz estimate of each Ritz value |
589
c | by 1 / max(eps23, magnitude of the Ritz value). |
590
c %--------------------------------------------------%
591
c
592
do 35 j = 1, nev0
593
rtemp = max( eps23, slapy2( real (ritz(j)),
594
& aimag(ritz(j)) ) )
595
bounds(j) = bounds(j)/rtemp
596
35 continue
597
c
598
c %---------------------------------------------------%
599
c | Sort the Ritz values according to the scaled Ritz |
600
c | estimates. This will push all the converged ones |
601
c | towards the front of ritz, bounds (in the case |
602
c | when NCONV < NEV.) |
603
c %---------------------------------------------------%
604
c
605
wprime = 'LM'
606
call csortc(wprime, .true., nev0, bounds, ritz)
607
c
608
c %----------------------------------------------%
609
c | Scale the Ritz estimate back to its original |
610
c | value. |
611
c %----------------------------------------------%
612
c
613
do 40 j = 1, nev0
614
rtemp = max( eps23, slapy2( real (ritz(j)),
615
& aimag(ritz(j)) ) )
616
bounds(j) = bounds(j)*rtemp
617
40 continue
618
c
619
c %-----------------------------------------------%
620
c | Sort the converged Ritz values again so that |
621
c | the "threshold" value appears at the front of |
622
c | ritz and bound. |
623
c %-----------------------------------------------%
624
c
625
call csortc(which, .true., nconv, ritz, bounds)
626
c
627
if (msglvl .gt. 1) then
628
call pcvout (comm, logfil, kplusp, ritz, ndigit,
629
& '_naup2: Sorted eigenvalues')
630
call pcvout (comm, logfil, kplusp, bounds, ndigit,
631
& '_naup2: Sorted ritz estimates.')
632
end if
633
c
634
c %------------------------------------%
635
c | Max iterations have been exceeded. |
636
c %------------------------------------%
637
c
638
if (iter .gt. mxiter .and. nconv .lt. nev0) info = 1
639
c
640
c %---------------------%
641
c | No shifts to apply. |
642
c %---------------------%
643
c
644
if (np .eq. 0 .and. nconv .lt. nev0) info = 2
645
c
646
np = nconv
647
go to 1100
648
c
649
else if ( (nconv .lt. nev0) .and. (ishift .eq. 1) ) then
650
c
651
c %-------------------------------------------------%
652
c | Do not have all the requested eigenvalues yet. |
653
c | To prevent possible stagnation, adjust the size |
654
c | of NEV. |
655
c %-------------------------------------------------%
656
c
657
nevbef = nev
658
nev = nev + min(nconv, np/2)
659
if (nev .eq. 1 .and. kplusp .ge. 6) then
660
nev = kplusp / 2
661
else if (nev .eq. 1 .and. kplusp .gt. 3) then
662
nev = 2
663
end if
664
np = kplusp - nev
665
c
666
c %---------------------------------------%
667
c | If the size of NEV was just increased |
668
c | resort the eigenvalues. |
669
c %---------------------------------------%
670
c
671
if (nevbef .lt. nev)
672
& call pcngets (comm, ishift, which, nev, np, ritz,
673
& bounds)
674
c
675
end if
676
c
677
if (msglvl .gt. 0) then
678
call pivout (comm, logfil, 1, [nconv], ndigit,
679
& '_naup2: no. of "converged" Ritz values at this iter.')
680
if (msglvl .gt. 1) then
681
kp(1) = nev
682
kp(2) = np
683
call pivout (comm, logfil, 2, kp, ndigit,
684
& '_naup2: NEV and NP are')
685
call pcvout (comm, logfil, nev, ritz(np+1), ndigit,
686
& '_naup2: "wanted" Ritz values ')
687
call pcvout (comm, logfil, nev, bounds(np+1), ndigit,
688
& '_naup2: Ritz estimates of the "wanted" values ')
689
end if
690
end if
691
c
692
if (ishift .eq. 0) then
693
c
694
c %-------------------------------------------------------%
695
c | User specified shifts: pop back out to get the shifts |
696
c | and return them in the first 2*NP locations of WORKL. |
697
c %-------------------------------------------------------%
698
c
699
ushift = .true.
700
ido = 3
701
go to 9000
702
end if
703
50 continue
704
ushift = .false.
705
c
706
if ( ishift .ne. 1 ) then
707
c
708
c %----------------------------------%
709
c | Move the NP shifts from WORKL to |
710
c | RITZ, to free up WORKL |
711
c | for non-exact shift case. |
712
c %----------------------------------%
713
c
714
call ccopy (np, workl, 1, ritz, 1)
715
end if
716
c
717
if (msglvl .gt. 2) then
718
call pivout (comm, logfil, 1, [np], ndigit,
719
& '_naup2: The number of shifts to apply ')
720
call pcvout (comm, logfil, np, ritz, ndigit,
721
& '_naup2: values of the shifts')
722
if ( ishift .eq. 1 )
723
& call pcvout (comm, logfil, np, bounds, ndigit,
724
& '_naup2: Ritz estimates of the shifts')
725
end if
726
c
727
c %---------------------------------------------------------%
728
c | Apply the NP implicit shifts by QR bulge chasing. |
729
c | Each shift is applied to the whole upper Hessenberg |
730
c | matrix H. |
731
c | The first 2*N locations of WORKD are used as workspace. |
732
c %---------------------------------------------------------%
733
c
734
call pcnapps(comm, n, nev, np, ritz, v, ldv,
735
& h, ldh, resid, q, ldq, workl, workd)
736
c
737
c %---------------------------------------------%
738
c | Compute the B-norm of the updated residual. |
739
c | Keep B*RESID in WORKD(1:N) to be used in |
740
c | the first step of the next call to pcnaitr. |
741
c %---------------------------------------------%
742
c
743
cnorm = .true.
744
call second (t2)
745
if (bmat .eq. 'G') then
746
nbx = nbx + 1
747
call ccopy (n, resid, 1, workd(n+1), 1)
748
ipntr(1) = n + 1
749
ipntr(2) = 1
750
ido = 2
751
c
752
c %----------------------------------%
753
c | Exit in order to compute B*RESID |
754
c %----------------------------------%
755
c
756
go to 9000
757
else if (bmat .eq. 'I') then
758
call ccopy (n, resid, 1, workd, 1)
759
end if
760
c
761
100 continue
762
c
763
c %----------------------------------%
764
c | Back from reverse communication; |
765
c | WORKD(1:N) := B*RESID |
766
c %----------------------------------%
767
c
768
if (bmat .eq. 'G') then
769
call second (t3)
770
tmvbx = tmvbx + (t3 - t2)
771
end if
772
c
773
if (bmat .eq. 'G') then
774
cmpnorm_buf = cdotc (n, resid, 1, workd, 1)
775
call MPI_ALLREDUCE( cmpnorm_buf, cmpnorm, 1,
776
& MPI_COMPLEX, MPI_SUM, comm, ierr )
777
rnorm = sqrt(slapy2(real (cmpnorm),aimag(cmpnorm)))
778
else if (bmat .eq. 'I') then
779
rnorm = pscnorm2(comm, n, resid, 1)
780
end if
781
cnorm = .false.
782
c
783
if (msglvl .gt. 2) then
784
call psvout (comm, logfil, 1, [rnorm], ndigit,
785
& '_naup2: B-norm of residual for compressed factorization')
786
call pcmout (comm, logfil, nev, nev, h, ldh, ndigit,
787
& '_naup2: Compressed upper Hessenberg matrix H')
788
end if
789
c
790
go to 1000
791
c
792
c %---------------------------------------------------------------%
793
c | |
794
c | E N D O F M A I N I T E R A T I O N L O O P |
795
c | |
796
c %---------------------------------------------------------------%
797
c
798
1100 continue
799
c
800
mxiter = iter
801
nev = nconv
802
c
803
1200 continue
804
ido = 99
805
c
806
c %------------%
807
c | Error Exit |
808
c %------------%
809
c
810
call second (t1)
811
tcaup2 = t1 - t0
812
c
813
9000 continue
814
c
815
c %----------------%
816
c | End of pcnaup2 |
817
c %----------------%
818
c
819
return
820
end
821
822