Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/mathlibs/src/parpack/pdneigh.f
5213 views
1
c-----------------------------------------------------------------------
2
c\BeginDoc
3
c
4
c\Name: pdneigh
5
c
6
c Message Passing Layer: MPI
7
c
8
c\Description:
9
c Compute the eigenvalues of the current upper Hessenberg matrix
10
c and the corresponding Ritz estimates given the current residual norm.
11
c
12
c\Usage:
13
c call pdneigh
14
c ( COMM, RNORM, N, H, LDH, RITZR, RITZI, BOUNDS, Q, LDQ, WORKL, IERR )
15
c
16
c\Arguments
17
c COMM MPI Communicator for the processor grid. (INPUT)
18
c
19
c RNORM Double precision scalar. (INPUT)
20
c Residual norm corresponding to the current upper Hessenberg
21
c matrix H.
22
c
23
c N Integer. (INPUT)
24
c Size of the matrix H.
25
c
26
c H Double precision N by N array. (INPUT)
27
c H contains the current upper Hessenberg matrix.
28
c
29
c LDH Integer. (INPUT)
30
c Leading dimension of H exactly as declared in the calling
31
c program.
32
c
33
c RITZR, Double precision arrays of length N. (OUTPUT)
34
c RITZI On output, RITZR(1:N) (resp. RITZI(1:N)) contains the real
35
c (respectively imaginary) parts of the eigenvalues of H.
36
c
37
c BOUNDS Double precision array of length N. (OUTPUT)
38
c On output, BOUNDS contains the Ritz estimates associated with
39
c the eigenvalues RITZR and RITZI. This is equal to RNORM
40
c times the last components of the eigenvectors corresponding
41
c to the eigenvalues in RITZR and RITZI.
42
c
43
c Q Double precision N by N array. (WORKSPACE)
44
c Workspace needed to store the eigenvectors of H.
45
c
46
c LDQ Integer. (INPUT)
47
c Leading dimension of Q exactly as declared in the calling
48
c program.
49
c
50
c WORKL Double precision work array of length N**2 + 3*N. (WORKSPACE)
51
c Private (replicated) array on each PE or array allocated on
52
c the front end. This is needed to keep the full Schur form
53
c of H and also in the calculation of the eigenvectors of H.
54
c
55
c IERR Integer. (OUTPUT)
56
c Error exit flag from dlaqrb or dtrevc.
57
c
58
c\EndDoc
59
c
60
c-----------------------------------------------------------------------
61
c
62
c\BeginLib
63
c
64
c\Local variables:
65
c xxxxxx real
66
c
67
c\Routines called:
68
c dlaqrb ARPACK routine to compute the real Schur form of an
69
c upper Hessenberg matrix and last row of the Schur vectors.
70
c second ARPACK utility routine for timing.
71
c dmout ARPACK utility routine that prints matrices
72
c dvout ARPACK utility routine that prints vectors.
73
c dlacpy LAPACK matrix copy routine.
74
c dlapy2 LAPACK routine to compute sqrt(x**2+y**2) carefully.
75
c dtrevc LAPACK routine to compute the eigenvectors of a matrix
76
c in upper quasi-triangular form
77
c dgemv Level 2 BLAS routine for matrix vector multiplication.
78
c dcopy Level 1 BLAS that copies one vector to another .
79
c dnrm2 Level 1 BLAS that computes the norm of a vector.
80
c dscal Level 1 BLAS that scales a vector.
81
c
82
c
83
c\Author
84
c Danny Sorensen Phuong Vu
85
c Richard Lehoucq Cray Research, Inc. &
86
c Dept. of Computational & CRPC / Rice University
87
c Applied Mathematics Houston, Texas
88
c Rice University
89
c Houston, Texas
90
c
91
c\Parallel Modifications
92
c Kristi Maschhoff
93
c
94
c\Revision history:
95
c Starting Point: Serial Code FILE: neigh.F SID: 2.2
96
c
97
c\SCCS Information:
98
c FILE: neigh.F SID: 1.2 DATE OF SID: 2/22/96
99
c
100
c\Remarks
101
c None
102
c
103
c\EndLib
104
c
105
c-----------------------------------------------------------------------
106
c
107
subroutine pdneigh ( comm, rnorm, n, h, ldh, ritzr, ritzi, bounds,
108
& q, ldq, workl, ierr)
109
c
110
c %--------------------%
111
c | MPI Communicator |
112
c %--------------------%
113
c
114
integer comm
115
c
116
c %----------------------------------------------------%
117
c | Include files for debugging and timing information |
118
c %----------------------------------------------------%
119
c
120
include 'debug.h'
121
include 'stat.h'
122
c
123
c %------------------%
124
c | Scalar Arguments |
125
c %------------------%
126
c
127
integer ierr, n, ldh, ldq
128
Double precision
129
& rnorm
130
c
131
c %-----------------%
132
c | Array Arguments |
133
c %-----------------%
134
c
135
Double precision
136
& bounds(n), h(ldh,n), q(ldq,n), ritzi(n), ritzr(n),
137
& workl(n*(n+3))
138
c
139
c %------------%
140
c | Parameters |
141
c %------------%
142
c
143
Double precision
144
& one, zero
145
parameter (one = 1.0, zero = 0.0)
146
c
147
c %------------------------%
148
c | Local Scalars & Arrays |
149
c %------------------------%
150
c
151
logical select(1)
152
integer i, iconj, msglvl
153
Double precision
154
& temp, vl(1)
155
c
156
c %----------------------%
157
c | External Subroutines |
158
c %----------------------%
159
c
160
external dcopy, dlacpy, dlaqrb, dtrevc, pdvout, second
161
c
162
c %--------------------%
163
c | External Functions |
164
c %--------------------%
165
c
166
Double precision
167
& dlapy2, dnrm2
168
external dlapy2, dnrm2
169
c
170
c %---------------------%
171
c | Intrinsic Functions |
172
c %---------------------%
173
c
174
intrinsic abs
175
c
176
c %-----------------------%
177
c | Executable Statements |
178
c %-----------------------%
179
c
180
c
181
c %-------------------------------%
182
c | Initialize timing statistics |
183
c | & message level for debugging |
184
c %-------------------------------%
185
c
186
call second (t0)
187
msglvl = mneigh
188
c
189
if (msglvl .gt. 2) then
190
call pdmout (comm, logfil, n, n, h, ldh, ndigit,
191
& '_neigh: Entering upper Hessenberg matrix H ')
192
end if
193
c
194
c %-----------------------------------------------------------%
195
c | 1. Compute the eigenvalues, the last components of the |
196
c | corresponding Schur vectors and the full Schur form T |
197
c | of the current upper Hessenberg matrix H. |
198
c | dlaqrb returns the full Schur form of H in WORKL(1:N**2) |
199
c | and the last components of the Schur vectors in BOUNDS. |
200
c %-----------------------------------------------------------%
201
c
202
call dlacpy ('All', n, n, h, ldh, workl, n)
203
call dlaqrb (.true., n, 1, n, workl, n, ritzr, ritzi, bounds,
204
& ierr)
205
if (ierr .ne. 0) go to 9000
206
c
207
if (msglvl .gt. 1) then
208
call pdvout (comm, logfil, n, bounds, ndigit,
209
& '_neigh: last row of the Schur matrix for H')
210
end if
211
c
212
c %-----------------------------------------------------------%
213
c | 2. Compute the eigenvectors of the full Schur form T and |
214
c | apply the last components of the Schur vectors to get |
215
c | the last components of the corresponding eigenvectors. |
216
c | Remember that if the i-th and (i+1)-st eigenvalues are |
217
c | complex conjugate pairs, then the real & imaginary part |
218
c | of the eigenvector components are split across adjacent |
219
c | columns of Q. |
220
c %-----------------------------------------------------------%
221
c
222
call dtrevc ('R', 'A', select, n, workl, n, vl, n, q, ldq,
223
& n, n, workl(n*n+1), ierr)
224
c
225
if (ierr .ne. 0) go to 9000
226
c
227
c %------------------------------------------------%
228
c | Scale the returning eigenvectors so that their |
229
c | euclidean norms are all one. LAPACK subroutine |
230
c | dtrevc returns each eigenvector normalized so |
231
c | that the element of largest magnitude has |
232
c | magnitude 1; here the magnitude of a complex |
233
c | number (x,y) is taken to be |x| + |y|. |
234
c %------------------------------------------------%
235
c
236
iconj = 0
237
do 10 i=1, n
238
if ( abs( ritzi(i) ) .le. zero ) then
239
c
240
c %----------------------%
241
c | Real eigenvalue case |
242
c %----------------------%
243
c
244
temp = dnrm2( n, q(1,i), 1 )
245
call dscal ( n, one / temp, q(1,i), 1 )
246
else
247
c
248
c %-------------------------------------------%
249
c | Complex conjugate pair case. Note that |
250
c | since the real and imaginary part of |
251
c | the eigenvector are stored in consecutive |
252
c | columns, we further normalize by the |
253
c | square root of two. |
254
c %-------------------------------------------%
255
c
256
if (iconj .eq. 0) then
257
temp = dlapy2( dnrm2( n, q(1,i), 1 ),
258
& dnrm2( n, q(1,i+1), 1 ) )
259
call dscal ( n, one / temp, q(1,i), 1 )
260
call dscal ( n, one / temp, q(1,i+1), 1 )
261
iconj = 1
262
else
263
iconj = 0
264
end if
265
end if
266
10 continue
267
c
268
call dgemv ('T', n, n, one, q, ldq, bounds, 1, zero, workl, 1)
269
c
270
if (msglvl .gt. 1) then
271
call pdvout (comm, logfil, n, workl, ndigit,
272
& '_neigh: Last row of the eigenvector matrix for H')
273
end if
274
c
275
c %----------------------------%
276
c | Compute the Ritz estimates |
277
c %----------------------------%
278
c
279
iconj = 0
280
do 20 i = 1, n
281
if ( abs( ritzi(i) ) .le. zero ) then
282
c
283
c %----------------------%
284
c | Real eigenvalue case |
285
c %----------------------%
286
c
287
bounds(i) = rnorm * abs( workl(i) )
288
else
289
c
290
c %-------------------------------------------%
291
c | Complex conjugate pair case. Note that |
292
c | since the real and imaginary part of |
293
c | the eigenvector are stored in consecutive |
294
c | columns, we need to take the magnitude |
295
c | of the last components of the two vectors |
296
c %-------------------------------------------%
297
c
298
if (iconj .eq. 0) then
299
bounds(i) = rnorm * dlapy2( workl(i), workl(i+1) )
300
bounds(i+1) = bounds(i)
301
iconj = 1
302
else
303
iconj = 0
304
end if
305
end if
306
20 continue
307
c
308
if (msglvl .gt. 2) then
309
call pdvout (comm, logfil, n, ritzr, ndigit,
310
& '_neigh: Real part of the eigenvalues of H')
311
call pdvout (comm, logfil, n, ritzi, ndigit,
312
& '_neigh: Imaginary part of the eigenvalues of H')
313
call pdvout (comm, logfil, n, bounds, ndigit,
314
& '_neigh: Ritz estimates for the eigenvalues of H')
315
end if
316
c
317
call second (t1)
318
tneigh = tneigh + (t1 - t0)
319
c
320
9000 continue
321
return
322
c
323
c %----------------%
324
c | End of pdneigh |
325
c %----------------%
326
c
327
end
328
329