Anasazi Version of the Day
Loading...
Searching...
No Matches
mydsaup2.f
1c @HEADER
2c *****************************************************************************
3c Anasazi: Block Eigensolvers Package
4c
5c Copyright 2004 NTESS and the Anasazi contributors.
6c SPDX-License-Identifier: BSD-3-Clause
7c *****************************************************************************
8c @HEADER
9
10c This software is a result of the research described in the report
11c
12c "A comparison of algorithms for modal analysis in the absence
13c of a sparse direct method", P. Arbenz, R. Lehoucq, and U. Hetmaniuk,
14c Sandia National Laboratories, Technical report SAND2003-1028J.
15c
16c It is based on the Epetra, AztecOO, and ML packages defined in the Trilinos
17c framework ( http://trilinos.org/ ).
18c-----------------------------------------------------------------------
19c\BeginDoc
20c
21c\Name: mydsaup2
22c
23c\Description:
24c Intermediate level interface called by dsaupd.
25c
26c\Usage:
27c call mydsaup2
28c ( IDO, BMAT, N, WHICH, NEV, NP, TOL, RESID, MODE, IUPD,
29c ISHIFT, MXITER, V, LDV, H, LDH, RITZ, BOUNDS, Q, LDQ, WORKL,
30c IPNTR, WORKD, INFO, VERBOSE, USRCHK, UNCONV )
31c
32c\Arguments
33c
34c IDO, BMAT, N, WHICH, NEV, TOL, RESID: same as defined in dsaupd.
35c MODE, ISHIFT, MXITER: see the definition of IPARAM in dsaupd.
36c
37c NP Integer. (INPUT/OUTPUT)
38c Contains the number of implicit shifts to apply during
39c each Arnoldi/Lanczos iteration.
40c If ISHIFT=1, NP is adjusted dynamically at each iteration
41c to accelerate convergence and prevent stagnation.
42c This is also roughly equal to the number of matrix-vector
43c products (involving the operator OP) per Arnoldi iteration.
44c The logic for adjusting is contained within the current
45c subroutine.
46c If ISHIFT=0, NP is the number of shifts the user needs
47c to provide via reverse comunication. 0 < NP < NCV-NEV.
48c NP may be less than NCV-NEV since a leading block of the current
49c upper Tridiagonal matrix has split off and contains "unwanted"
50c Ritz values.
51c Upon termination of the IRA iteration, NP contains the number
52c of "converged" wanted Ritz values.
53c
54c IUPD Integer. (INPUT)
55c IUPD .EQ. 0: use explicit restart instead implicit update.
56c IUPD .NE. 0: use implicit update.
57c
58c V Double precision N by (NEV+NP) array. (INPUT/OUTPUT)
59c The Lanczos basis vectors.
60c
61c LDV Integer. (INPUT)
62c Leading dimension of V exactly as declared in the calling
63c program.
64c
65c H Double precision (NEV+NP) by 2 array. (OUTPUT)
66c H is used to store the generated symmetric tridiagonal matrix
67c The subdiagonal is stored in the first column of H starting
68c at H(2,1). The main diagonal is stored in the second column
69c of H starting at H(1,2). If dsaup2 converges store the
70c B-norm of the final residual vector in H(1,1).
71c
72c LDH Integer. (INPUT)
73c Leading dimension of H exactly as declared in the calling
74c program.
75c
76c RITZ Double precision array of length NEV+NP. (OUTPUT)
77c RITZ(1:NEV) contains the computed Ritz values of OP.
78c
79c BOUNDS Double precision array of length NEV+NP. (OUTPUT)
80c BOUNDS(1:NEV) contain the error bounds corresponding to RITZ.
81c
82c Q Double precision (NEV+NP) by (NEV+NP) array. (WORKSPACE)
83c Private (replicated) work array used to accumulate the
84c rotation in the shift application step.
85c
86c LDQ Integer. (INPUT)
87c Leading dimension of Q exactly as declared in the calling
88c program.
89c
90c WORKL Double precision array of length at least 3*(NEV+NP). (INPUT/WORKSPACE)
91c Private (replicated) array on each PE or array allocated on
92c the front end. It is used in the computation of the
93c tridiagonal eigenvalue problem, the calculation and
94c application of the shifts and convergence checking.
95c If ISHIFT .EQ. O and IDO .EQ. 3, the first NP locations
96c of WORKL are used in reverse communication to hold the user
97c supplied shifts.
98c
99c IPNTR Integer array of length 3. (OUTPUT)
100c Pointer to mark the starting locations in the WORKD for
101c vectors used by the Lanczos iteration.
102c -------------------------------------------------------------
103c IPNTR(1): pointer to the current operand vector X.
104c IPNTR(2): pointer to the current result vector Y.
105c IPNTR(3): pointer to the vector B * X when used in one of
106c the spectral transformation modes. X is the current
107c operand.
108c -------------------------------------------------------------
109c
110c WORKD Double precision work array of length 3*N. (REVERSE COMMUNICATION)
111c Distributed array to be used in the basic Lanczos iteration
112c for reverse communication. The user should not use WORKD
113c as temporary workspace during the iteration !!!!!!!!!!
114c See Data Distribution Note in dsaupd.
115c
116c INFO Integer. (INPUT/OUTPUT)
117c If INFO .EQ. 0, a randomly initial residual vector is used.
118c If INFO .NE. 0, RESID contains the initial residual vector,
119c possibly from a previous run.
120c Error flag on output.
121c = 0: Normal return.
122c = 1: All possible eigenvalues of OP has been found.
123c NP returns the size of the invariant subspace
124c spanning the operator OP.
125c = 2: No shifts could be applied.
126c = -8: Error return from trid. eigenvalue calculation;
127c This should never happen.
128c = -9: Starting vector is zero.
129c = -9999: Could not build an Lanczos factorization.
130c Size that was built in returned in NP.
131c
132c VERBOSE : Flag to print out the status of the computation per iteration
133c
134c USRCHK Integer. (INPUT) A nonzero value implies that reverse
135c communication is done so that the user can check convergence.
136c
137c UNCONV Integer. (INPUT) Only used if USRCHK is not equal to zero.
138c
139c\EndDoc
140c
141c-----------------------------------------------------------------------
142c
143c\BeginLib
144c
145c\References:
146c 1. D.C. Sorensen, "Implicit Application of Polynomial Filters in
147c a k-Step Arnoldi Method", SIAM J. Matr. Anal. Apps., 13 (1992),
148c pp 357-385.
149c 2. R.B. Lehoucq, "Analysis and Implementation of an Implicitly
150c Restarted Arnoldi Iteration", Rice University Technical Report
151c TR95-13, Department of Computational and Applied Mathematics.
152c 3. B.N. Parlett, "The Symmetric Eigenvalue Problem". Prentice-Hall,
153c 1980.
154c 4. B.N. Parlett, B. Nour-Omid, "Towards a Black Box Lanczos Program",
155c Computer Physics Communications, 53 (1989), pp 169-179.
156c 5. B. Nour-Omid, B.N. Parlett, T. Ericson, P.S. Jensen, "How to
157c Implement the Spectral Transformation", Math. Comp., 48 (1987),
158c pp 663-673.
159c 6. R.G. Grimes, J.G. Lewis and H.D. Simon, "A Shifted Block Lanczos
160c Algorithm for Solving Sparse Symmetric Generalized Eigenproblems",
161c SIAM J. Matr. Anal. Apps., January (1993).
162c 7. L. Reichel, W.B. Gragg, "Algorithm 686: FORTRAN Subroutines
163c for Updating the QR decomposition", ACM TOMS, December 1990,
164c Volume 16 Number 4, pp 369-377.
165c
166c\Routines called:
167c dgetv0 ARPACK initial vector generation routine.
168c dsaitr ARPACK Lanczos factorization routine.
169c dsapps ARPACK application of implicit shifts routine.
170c dsconv ARPACK convergence of Ritz values routine.
171c dseigt ARPACK compute Ritz values and error bounds routine.
172c dsgets ARPACK reorder Ritz values and error bounds routine.
173c dsortr ARPACK sorting routine.
174c ivout ARPACK utility routine that prints integers.
175c second ARPACK utility routine for timing.
176c dvout ARPACK utility routine that prints vectors.
177c dlamch LAPACK routine that determines machine constants.
178c dcopy Level 1 BLAS that copies one vector to another.
179c ddot Level 1 BLAS that computes the scalar product of two vectors.
180c dnrm2 Level 1 BLAS that computes the norm of a vector.
181c dscal Level 1 BLAS that scales a vector.
182c dswap Level 1 BLAS that swaps two vectors.
183c
184c\Author
185c Danny Sorensen Phuong Vu
186c Richard Lehoucq CRPC / Rice University
187c Dept. of Computational & Houston, Texas
188c Applied Mathematics
189c Rice University
190c Houston, Texas
191c
192c\Revision history:
193c 12/15/93: Version ' 2.4'
194c xx/xx/95: Version ' 2.4'. (R.B. Lehoucq)
195c
196c\SCCS Information: @(#)
197c FILE: saup2.F SID: 2.7 DATE OF SID: 5/19/98 RELEASE: 2
198c
199c\EndLib
200c
201c-----------------------------------------------------------------------
202c
203 subroutine mydsaup2
204 & ( ido, bmat, n, which, nev, np, tol, resid, mode, iupd,
205 & ishift, mxiter, v, ldv, h, ldh, ritz, bounds,
206 & q, ldq, workl, ipntr, workd, info, verbose, usrchk, unconv )
207c
208c %----------------------------------------------------%
209c | Include files for debugging and timing information |
210c %----------------------------------------------------%
211c
212 include 'debug.h'
213 include 'stat.h'
214c
215c %------------------%
216c | Scalar Arguments |
217c %------------------%
218c
219 character bmat*1, which*2
220 integer ido, info, ishift, iupd, ldh, ldq, ldv, mxiter,
221 & n, mode, nev, np
222 integer verbose, urschk, unconv
223 double precision
224 & tol
225c
226c %-----------------%
227c | Array Arguments |
228c %-----------------%
229c
230 integer ipntr(3)
231 double precision
232 & bounds(nev+np), h(ldh,2), q(ldq,nev+np), resid(n),
233 & ritz(nev+np), v(ldv,nev+np), workd(3*n),
234 & workl(3*(nev+np))
235c
236c %------------%
237c | Parameters |
238c %------------%
239c
240 double precision
241 & one, zero
242 parameter(one = 1.0d+0, zero = 0.0d+0)
243c
244c %---------------%
245c | Local Scalars |
246c %---------------%
247c
248 character wprime*2
249 logical cnorm, getv0, initv, update, ushift
250 logical cnvchk
251 integer ierr, iter, j, kplusp, msglvl, nconv, nevbef, nev0,
252 & np0, nptemp, nevd2, nevm2, kp(3)
253 double precision
254 & rnorm, temp, eps23
255 save cnorm, getv0, initv, update, ushift,
256 & iter, kplusp, msglvl, nconv, nev0, np0,
257 & rnorm, eps23, cnvchk
258c
259c %----------------------%
260c | External Subroutines |
261c %----------------------%
262c
263 external dcopy, dgetv0, dsaitr, dscal, dsconv, dseigt, dsgets,
264 & dsapps, dsortr, dvout, ivout, second, dswap
265c
266c %--------------------%
267c | External Functions |
268c %--------------------%
269c
270 double precision
271 & ddot, dnrm2, dlamch
272 external ddot, dnrm2, dlamch
273c
274c %---------------------%
275c | Intrinsic Functions |
276c %---------------------%
277c
278 intrinsic min
279c
280c %-----------------------%
281c | Executable Statements |
282c %-----------------------%
283c
284 if (ido .eq. 0) then
285c
286c %-------------------------------%
287c | Initialize timing statistics |
288c | & message level for debugging |
289c %-------------------------------%
290c
291 call second (t0)
292 msglvl = msaup2
293c
294c %---------------------------------%
295c | Set machine dependent constant. |
296c %---------------------------------%
297c
298 eps23 = dlamch('Epsilon-Machine')
299 eps23 = eps23**(2.0d+0/3.0d+0)
300c
301c %-------------------------------------%
302c | nev0 and np0 are integer variables |
303c | hold the initial values of NEV & NP |
304c %-------------------------------------%
305c
306 nev0 = nev
307 np0 = np
308c
309c %-------------------------------------%
310c | kplusp is the bound on the largest |
311c | Lanczos factorization built. |
312c | nconv is the current number of |
313c | "converged" eigenvlues. |
314c | iter is the counter on the current |
315c | iteration step. |
316c %-------------------------------------%
317c
318 kplusp = nev0 + np0
319 nconv = 0
320 iter = 0
321c
322c %--------------------------------------------%
323c | Set flags for computing the first NEV steps |
324c | of the Lanczos factorization. |
325c %--------------------------------------------%
326c
327 getv0 = .true.
328 update = .false.
329 ushift = .false.
330 cnorm = .false.
331 cnvchk = .false.
332c
333 if (info .ne. 0) then
334c
335c %--------------------------------------------%
336c | User provides the initial residual vector. |
337c %--------------------------------------------%
338c
339 initv = .true.
340 info = 0
341 else
342 initv = .false.
343 end if
344 end if
345c
346c %---------------------------------------------%
347c | Get a possibly random starting vector and |
348c | force it into the range of the operator OP. |
349c %---------------------------------------------%
350c
351 10 continue
352c
353 if (getv0) then
354 call dgetv0 (ido, bmat, 1, initv, n, 1, v, ldv, resid, rnorm,
355 & ipntr, workd, info)
356c
357 if (ido .ne. 99) go to 9000
358c
359 if (rnorm .eq. zero) then
360c
361c %-----------------------------------------%
362c | The initial vector is zero. Error exit. |
363c %-----------------------------------------%
364c
365 info = -9
366 go to 1200
367 end if
368 getv0 = .false.
369 ido = 0
370 end if
371c
372c %------------------------------------------------------------%
373c | Back from reverse communication: continue with update step |
374c %------------------------------------------------------------%
375c
376 if (update) go to 20
377c
378c %-------------------------------------------%
379c | Back from computing user specified shifts |
380c %-------------------------------------------%
381c
382 if (ushift) go to 50
383c
384c %-------------------------------------%
385c | Back from computing residual norm |
386c | at the end of the current iteration |
387c %-------------------------------------%
388c
389 if (cnorm) go to 100
390c
391c %---------------------------------%
392c | Back from checking convergence. |
393c %---------------------------------%
394c
395 if (cnvchk) go to 110
396c
397c %----------------------------------------------------------%
398c | Compute the first NEV steps of the Lanczos factorization |
399c %----------------------------------------------------------%
400c
401 call dsaitr (ido, bmat, n, 0, nev0, mode, resid, rnorm, v, ldv,
402 & h, ldh, ipntr, workd, info)
403c
404c %---------------------------------------------------%
405c | ido .ne. 99 implies use of reverse communication |
406c | to compute operations involving OP and possibly B |
407c %---------------------------------------------------%
408c
409 if (ido .ne. 99) go to 9000
410c
411 if (info .gt. 0) then
412c
413c %-----------------------------------------------------%
414c | dsaitr was unable to build an Lanczos factorization |
415c | of length NEV0. INFO is returned with the size of |
416c | the factorization built. Exit main loop. |
417c %-----------------------------------------------------%
418c
419 np = info
420 mxiter = iter
421 info = -9999
422 go to 1200
423 end if
424c
425c %--------------------------------------------------------------%
426c | |
427c | M A I N LANCZOS I T E R A T I O N L O O P |
428c | Each iteration implicitly restarts the Lanczos |
429c | factorization in place. |
430c | |
431c %--------------------------------------------------------------%
432c
433 1000 continue
434c
435 iter = iter + 1
436c
437 if (verbose .gt. 0) then
438 write(*,*)' Iteration ',iter,
439 & ' - Number of converged eigenvalues ',nconv
440 end if
441c
442 if (msglvl .gt. 0) then
443 call ivout (logfil, 1, iter, ndigit,
444 & '_saup2: **** Start of major iteration number ****')
445 end if
446 if (msglvl .gt. 1) then
447 call ivout (logfil, 1, nev, ndigit,
448 & '_saup2: The length of the current Lanczos factorization')
449 call ivout (logfil, 1, np, ndigit,
450 & '_saup2: Extend the Lanczos factorization by')
451 end if
452c
453c %------------------------------------------------------------%
454c | Compute NP additional steps of the Lanczos factorization. |
455c %------------------------------------------------------------%
456c
457 ido = 0
458 20 continue
459 update = .true.
460c
461 call dsaitr (ido, bmat, n, nev, np, mode, resid, rnorm, v,
462 & ldv, h, ldh, ipntr, workd, info)
463c
464c %---------------------------------------------------%
465c | ido .ne. 99 implies use of reverse communication |
466c | to compute operations involving OP and possibly B |
467c %---------------------------------------------------%
468c
469 if (ido .ne. 99) go to 9000
470c
471 if (info .gt. 0) then
472c
473c %-----------------------------------------------------%
474c | dsaitr was unable to build an Lanczos factorization |
475c | of length NEV0+NP0. INFO is returned with the size |
476c | of the factorization built. Exit main loop. |
477c %-----------------------------------------------------%
478c
479 np = info
480 mxiter = iter
481 info = -9999
482 go to 1200
483 end if
484 update = .false.
485c
486 if (msglvl .gt. 1) then
487 call dvout (logfil, 1, rnorm, ndigit,
488 & '_saup2: Current B-norm of residual for factorization')
489 end if
490c
491c %--------------------------------------------------------%
492c | Compute the eigenvalues and corresponding error bounds |
493c | of the current symmetric tridiagonal matrix. |
494c %--------------------------------------------------------%
495c
496 call dseigt (rnorm, kplusp, h, ldh, ritz, bounds, workl, ierr)
497c
498 if (ierr .ne. 0) then
499 info = -8
500 go to 1200
501 end if
502c
503c %----------------------------------------------------%
504c | Make a copy of eigenvalues and corresponding error |
505c | bounds obtained from _seigt. |
506c %----------------------------------------------------%
507c
508 call dcopy(kplusp, ritz, 1, workl(kplusp+1), 1)
509 call dcopy(kplusp, bounds, 1, workl(2*kplusp+1), 1)
510c
511c %---------------------------------------------------%
512c | Select the wanted Ritz values and their bounds |
513c | to be used in the convergence test. |
514c | The selection is based on the requested number of |
515c | eigenvalues instead of the current NEV and NP to |
516c | prevent possible misconvergence. |
517c | * Wanted Ritz values := RITZ(NP+1:NEV+NP) |
518c | * Shifts := RITZ(1:NP) := WORKL(1:NP) |
519c %---------------------------------------------------%
520c
521 nev = nev0
522 np = np0
523 call dsgets (ishift, which, nev, np, ritz, bounds, workl)
524c
525c %-------------------%
526c | Convergence test. |
527c %-------------------%
528c
529 call dcopy (nev, bounds(np+1), 1, workl(np+1), 1)
530 if (usrchk .eq. zero) then
531 call dsconv (nev, ritz(np+1), workl(np+1), tol, nconv)
532 else
533c
534c %--------------------------------------------------%
535c | reverse communication so that the user can check |
536c | convergence. |
537c %--------------------------------------------------%
538c
539 cnvchk = .true.
540 ido = 4
541 go to 9000
542 end if
543c
544 110 continue
545c
546c %------------------------------------%
547c | Back from reverse communication; |
548c %------------------------------------%
549c
550 if (usrchk .ne. zero) then
551 nconv = unconv
552 cnvchk = .false.
553 end if
554c
555 if (msglvl .gt. 2) then
556 kp(1) = nev
557 kp(2) = np
558 kp(3) = nconv
559 call ivout (logfil, 3, kp, ndigit,
560 & '_saup2: NEV, NP, NCONV are')
561 call dvout (logfil, kplusp, ritz, ndigit,
562 & '_saup2: The eigenvalues of H')
563 call dvout (logfil, kplusp, bounds, ndigit,
564 & '_saup2: Ritz estimates of the current NCV Ritz values')
565 end if
566c
567c %---------------------------------------------------------%
568c | Count the number of unwanted Ritz values that have zero |
569c | Ritz estimates. If any Ritz estimates are equal to zero |
570c | then a leading block of H of order equal to at least |
571c | the number of Ritz values with zero Ritz estimates has |
572c | split off. None of these Ritz values may be removed by |
573c | shifting. Decrease NP the number of shifts to apply. If |
574c | no shifts may be applied, then prepare to exit |
575c %---------------------------------------------------------%
576c
577 nptemp = np
578 do 30 j=1, nptemp
579 if (bounds(j) .eq. zero) then
580 np = np - 1
581 nev = nev + 1
582 end if
583 30 continue
584c
585 if ( (nconv .ge. nev0) .or.
586 & (iter .gt. mxiter) .or.
587 & (np .eq. 0) ) then
588c
589c %------------------------------------------------%
590c | Prepare to exit. Put the converged Ritz values |
591c | and corresponding bounds in RITZ(1:NCONV) and |
592c | BOUNDS(1:NCONV) respectively. Then sort. Be |
593c | careful when NCONV > NP since we don't want to |
594c | swap overlapping locations. |
595c %------------------------------------------------%
596c
597 if (which .eq. 'BE') then
598c
599c %-----------------------------------------------------%
600c | Both ends of the spectrum are requested. |
601c | Sort the eigenvalues into algebraically decreasing |
602c | order first then swap low end of the spectrum next |
603c | to high end in appropriate locations. |
604c | NOTE: when np < floor(nev/2) be careful not to swap |
605c | overlapping locations. |
606c %-----------------------------------------------------%
607c
608 wprime = 'SA'
609 call dsortr (wprime, .true., kplusp, ritz, bounds)
610 nevd2 = nev0 / 2
611 nevm2 = nev0 - nevd2
612 if ( nev .gt. 1 ) then
613 call dswap ( min(nevd2,np), ritz(nevm2+1), 1,
614 & ritz( max(kplusp-nevd2+1,kplusp-np+1) ), 1)
615 call dswap ( min(nevd2,np), bounds(nevm2+1), 1,
616 & bounds( max(kplusp-nevd2+1,kplusp-np+1)), 1)
617 end if
618c
619 else
620c
621c %--------------------------------------------------%
622c | LM, SM, LA, SA case. |
623c | Sort the eigenvalues of H into the an order that |
624c | is opposite to WHICH, and apply the resulting |
625c | order to BOUNDS. The eigenvalues are sorted so |
626c | that the wanted part are always within the first |
627c | NEV locations. |
628c %--------------------------------------------------%
629c
630 if (which .eq. 'LM') wprime = 'SM'
631 if (which .eq. 'SM') wprime = 'LM'
632 if (which .eq. 'LA') wprime = 'SA'
633 if (which .eq. 'SA') wprime = 'LA'
634c
635 call dsortr (wprime, .true., kplusp, ritz, bounds)
636c
637 end if
638c
639c %--------------------------------------------------%
640c | Scale the Ritz estimate of each Ritz value |
641c | by 1 / max(eps23,magnitude of the Ritz value). |
642c %--------------------------------------------------%
643c
644 do 35 j = 1, nev0
645 temp = max( eps23, abs(ritz(j)) )
646 bounds(j) = bounds(j)/temp
647 35 continue
648c
649c %----------------------------------------------------%
650c | Sort the Ritz values according to the scaled Ritz |
651c | esitmates. This will push all the converged ones |
652c | towards the front of ritzr, ritzi, bounds |
653c | (in the case when NCONV < NEV.) |
654c %----------------------------------------------------%
655c
656 wprime = 'LA'
657 call dsortr(wprime, .true., nev0, bounds, ritz)
658c
659c %----------------------------------------------%
660c | Scale the Ritz estimate back to its original |
661c | value. |
662c %----------------------------------------------%
663c
664 do 40 j = 1, nev0
665 temp = max( eps23, abs(ritz(j)) )
666 bounds(j) = bounds(j)*temp
667 40 continue
668c
669c %--------------------------------------------------%
670c | Sort the "converged" Ritz values again so that |
671c | the "threshold" values and their associated Ritz |
672c | estimates appear at the appropriate position in |
673c | ritz and bound. |
674c %--------------------------------------------------%
675c
676 if (which .eq. 'BE') then
677c
678c %------------------------------------------------%
679c | Sort the "converged" Ritz values in increasing |
680c | order. The "threshold" values are in the |
681c | middle. |
682c %------------------------------------------------%
683c
684 wprime = 'LA'
685 call dsortr(wprime, .true., nconv, ritz, bounds)
686c
687 else
688c
689c %----------------------------------------------%
690c | In LM, SM, LA, SA case, sort the "converged" |
691c | Ritz values according to WHICH so that the |
692c | "threshold" value appears at the front of |
693c | ritz. |
694c %----------------------------------------------%
695
696 call dsortr(which, .true., nconv, ritz, bounds)
697c
698 end if
699c
700c %------------------------------------------%
701c | Use h( 1,1 ) as storage to communicate |
702c | rnorm to _seupd if needed |
703c %------------------------------------------%
704c
705 h(1,1) = rnorm
706c
707 if (msglvl .gt. 1) then
708 call dvout (logfil, kplusp, ritz, ndigit,
709 & '_saup2: Sorted Ritz values.')
710 call dvout (logfil, kplusp, bounds, ndigit,
711 & '_saup2: Sorted ritz estimates.')
712 end if
713c
714c %------------------------------------%
715c | Max iterations have been exceeded. |
716c %------------------------------------%
717c
718 if (iter .gt. mxiter .and. nconv .lt. nev) info = 1
719c
720c %---------------------%
721c | No shifts to apply. |
722c %---------------------%
723c
724 if (np .eq. 0 .and. nconv .lt. nev0) info = 2
725c
726 np = nconv
727 go to 1100
728c
729 else if (nconv .lt. nev .and. ishift .eq. 1) then
730c
731c %---------------------------------------------------%
732c | Do not have all the requested eigenvalues yet. |
733c | To prevent possible stagnation, adjust the number |
734c | of Ritz values and the shifts. |
735c %---------------------------------------------------%
736c
737 nevbef = nev
738 nev = nev + min(nconv, np/2)
739 if (nev .eq. 1 .and. kplusp .ge. 6) then
740 nev = kplusp / 2
741 else if (nev .eq. 1 .and. kplusp .gt. 2) then
742 nev = 2
743 end if
744 np = kplusp - nev
745c
746c %---------------------------------------%
747c | If the size of NEV was just increased |
748c | resort the eigenvalues. |
749c %---------------------------------------%
750c
751 if (nevbef .lt. nev)
752 & call dsgets (ishift, which, nev, np, ritz, bounds,
753 & workl)
754c
755 end if
756c
757 if (msglvl .gt. 0) then
758 call ivout (logfil, 1, nconv, ndigit,
759 & '_saup2: no. of "converged" Ritz values at this iter.')
760 if (msglvl .gt. 1) then
761 kp(1) = nev
762 kp(2) = np
763 call ivout (logfil, 2, kp, ndigit,
764 & '_saup2: NEV and NP are')
765 call dvout (logfil, nev, ritz(np+1), ndigit,
766 & '_saup2: "wanted" Ritz values.')
767 call dvout (logfil, nev, bounds(np+1), ndigit,
768 & '_saup2: Ritz estimates of the "wanted" values ')
769 end if
770 end if
771
772c
773 if (ishift .eq. 0) then
774c
775c %-----------------------------------------------------%
776c | User specified shifts: reverse communication to |
777c | compute the shifts. They are returned in the first |
778c | NP locations of WORKL. |
779c %-----------------------------------------------------%
780c
781 ushift = .true.
782 ido = 3
783 go to 9000
784 end if
785c
786 50 continue
787c
788c %------------------------------------%
789c | Back from reverse communication; |
790c | User specified shifts are returned |
791c | in WORKL(1:*NP) |
792c %------------------------------------%
793c
794 ushift = .false.
795c
796c
797c %---------------------------------------------------------%
798c | Move the NP shifts to the first NP locations of RITZ to |
799c | free up WORKL. This is for the non-exact shift case; |
800c | in the exact shift case, dsgets already handles this. |
801c %---------------------------------------------------------%
802c
803 if (ishift .eq. 0) call dcopy (np, workl, 1, ritz, 1)
804c
805 if (msglvl .gt. 2) then
806 call ivout (logfil, 1, np, ndigit,
807 & '_saup2: The number of shifts to apply ')
808 call dvout (logfil, np, workl, ndigit,
809 & '_saup2: shifts selected')
810 if (ishift .eq. 1) then
811 call dvout (logfil, np, bounds, ndigit,
812 & '_saup2: corresponding Ritz estimates')
813 end if
814 end if
815c
816c %---------------------------------------------------------%
817c | Apply the NP0 implicit shifts by QR bulge chasing. |
818c | Each shift is applied to the entire tridiagonal matrix. |
819c | The first 2*N locations of WORKD are used as workspace. |
820c | After dsapps is done, we have a Lanczos |
821c | factorization of length NEV. |
822c %---------------------------------------------------------%
823c
824 call dsapps (n, nev, np, ritz, v, ldv, h, ldh, resid, q, ldq,
825 & workd)
826c
827c %---------------------------------------------%
828c | Compute the B-norm of the updated residual. |
829c | Keep B*RESID in WORKD(1:N) to be used in |
830c | the first step of the next call to dsaitr. |
831c %---------------------------------------------%
832c
833 cnorm = .true.
834 call second (t2)
835 if (bmat .eq. 'G') then
836 nbx = nbx + 1
837 call dcopy (n, resid, 1, workd(n+1), 1)
838 ipntr(1) = n + 1
839 ipntr(2) = 1
840 ido = 2
841c
842c %----------------------------------%
843c | Exit in order to compute B*RESID |
844c %----------------------------------%
845c
846 go to 9000
847 else if (bmat .eq. 'I') then
848 call dcopy (n, resid, 1, workd, 1)
849 end if
850c
851 100 continue
852c
853c %----------------------------------%
854c | Back from reverse communication; |
855c | WORKD(1:N) := B*RESID |
856c %----------------------------------%
857c
858 if (bmat .eq. 'G') then
859 call second (t3)
860 tmvbx = tmvbx + (t3 - t2)
861 end if
862c
863 if (bmat .eq. 'G') then
864 rnorm = ddot(n, resid, 1, workd, 1)
865 rnorm = sqrt(abs(rnorm))
866 else if (bmat .eq. 'I') then
867 rnorm = dnrm2(n, resid, 1)
868 end if
869 cnorm = .false.
870 130 continue
871c
872 if (msglvl .gt. 2) then
873 call dvout (logfil, 1, rnorm, ndigit,
874 & '_saup2: B-norm of residual for NEV factorization')
875 call dvout (logfil, nev, h(1,2), ndigit,
876 & '_saup2: main diagonal of compressed H matrix')
877 call dvout (logfil, nev-1, h(2,1), ndigit,
878 & '_saup2: subdiagonal of compressed H matrix')
879 end if
880c
881 go to 1000
882c
883c %---------------------------------------------------------------%
884c | |
885c | E N D O F M A I N I T E R A T I O N L O O P |
886c | |
887c %---------------------------------------------------------------%
888c
889 1100 continue
890c
891 mxiter = iter
892 nev = nconv
893c
894 1200 continue
895 ido = 99
896c
897c %------------%
898c | Error exit |
899c %------------%
900c
901 call second (t1)
902 tsaup2 = t1 - t0
903c
904 9000 continue
905 return
906c
907c %---------------%
908c | End of dsaup2 |
909c %---------------%
910c
911 end