Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
3 | SLEPc - Scalable Library for Eigenvalue Problem Computations | ||
4 | Copyright (c) 2002-, Universitat Politecnica de Valencia, Spain | ||
5 | |||
6 | This file is part of SLEPc. | ||
7 | SLEPc is distributed under a 2-clause BSD license (see LICENSE). | ||
8 | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | ||
9 | */ | ||
10 | /* | ||
11 | SLEPc eigensolver: "krylovschur" | ||
12 | |||
13 | Method: Krylov-Schur for symmetric-indefinite eigenproblems | ||
14 | */ | ||
15 | #include <slepc/private/epsimpl.h> | ||
16 | #include "krylovschur.h" | ||
17 | |||
18 | 121 | PetscErrorCode EPSSolve_KrylovSchur_Indefinite(EPS eps) | |
19 | { | ||
20 | 121 | EPS_KRYLOVSCHUR *ctx = (EPS_KRYLOVSCHUR*)eps->data; | |
21 | 121 | PetscInt k,l,ld,nv,t,nconv=0; | |
22 | 121 | Mat U,D; | |
23 | 121 | Vec vomega,w=eps->work[0]; | |
24 | 121 | PetscReal *a,*b,beta,beta1=1.0,*omega; | |
25 | 121 | PetscBool breakdown=PETSC_FALSE,symmlost=PETSC_FALSE; | |
26 | |||
27 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
121 | PetscFunctionBegin; |
28 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(DSGetLeadingDimension(eps->ds,&ld)); |
29 | |||
30 | /* Get the starting Lanczos vector */ | ||
31 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(EPSGetStartVector(eps,0,NULL)); |
32 | |||
33 | /* Extract sigma[0] from BV, computed during normalization */ | ||
34 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(DSSetDimensions(eps->ds,1,PETSC_DETERMINE,PETSC_DETERMINE)); |
35 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(BVSetActiveColumns(eps->V,0,1)); |
36 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(DSGetMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega)); |
37 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(BVGetSignature(eps->V,vomega)); |
38 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(DSRestoreMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega)); |
39 | 121 | l = 0; | |
40 | |||
41 | /* Restart loop */ | ||
42 | 121 | while (eps->reason == EPS_CONVERGED_ITERATING) { | |
43 | 6999 | eps->its++; | |
44 | |||
45 | /* Compute an nv-step Lanczos factorization */ | ||
46 | 6999 | nv = PetscMin(eps->nconv+eps->mpd,eps->ncv); | |
47 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSSetDimensions(eps->ds,nv,eps->nconv,eps->nconv+l)); |
48 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSGetArrayReal(eps->ds,DS_MAT_T,&a)); |
49 | 6999 | b = a + ld; | |
50 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSGetArrayReal(eps->ds,DS_MAT_D,&omega)); |
51 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(EPSPseudoLanczos(eps,a,b,omega,eps->nconv+l,&nv,&breakdown,&symmlost,NULL,w)); |
52 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
|
6999 | if (symmlost) { |
53 | ✗ | eps->reason = EPS_DIVERGED_SYMMETRY_LOST; | |
54 | ✗ | if (nv==eps->nconv+l+1) { eps->nconv = nconv; break; } | |
55 | } | ||
56 | 6999 | beta = b[nv-1]; | |
57 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_T,&a)); |
58 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSRestoreArrayReal(eps->ds,DS_MAT_D,&omega)); |
59 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSSetDimensions(eps->ds,nv,eps->nconv,eps->nconv+l)); |
60 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSSetState(eps->ds,l?DS_STATE_RAW:DS_STATE_INTERMEDIATE)); |
61 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(BVSetActiveColumns(eps->V,eps->nconv,nv)); |
62 | |||
63 | /* Solve projected problem */ | ||
64 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSSolve(eps->ds,eps->eigr,eps->eigi)); |
65 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSSort(eps->ds,eps->eigr,eps->eigi,NULL,NULL,NULL)); |
66 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSUpdateExtraRow(eps->ds)); |
67 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSSynchronize(eps->ds,eps->eigr,eps->eigi)); |
68 | |||
69 | /* Check convergence */ | ||
70 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSGetDimensions(eps->ds,NULL,NULL,NULL,&t)); |
71 | #if 0 | ||
72 | /* take into account also left residual */ | ||
73 | PetscCall(BVGetColumn(eps->V,nv,&u)); | ||
74 | PetscCall(VecNorm(u,NORM_2,&beta1)); | ||
75 | PetscCall(BVRestoreColumn(eps->V,nv,&u)); | ||
76 | PetscCall(VecNorm(w,NORM_2,&beta2)); /* w contains B*V[nv] */ | ||
77 | beta1 = PetscMax(beta1,beta2); | ||
78 | #endif | ||
79 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(EPSKrylovConvergence(eps,PETSC_FALSE,eps->nconv,t-eps->nconv,beta*beta1,0.0,1.0,&k)); |
80 |
5/8✓ Branch 0 taken 10 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
6999 | if (!symmlost) PetscCall((*eps->stopping)(eps,eps->its,eps->max_it,k,eps->nev,&eps->reason,eps->stoppingctx)); |
81 | 6999 | nconv = k; | |
82 | |||
83 | /* Update l */ | ||
84 |
3/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10 times.
|
6999 | if (eps->reason != EPS_CONVERGED_ITERATING || breakdown) l = 0; |
85 | else { | ||
86 | 6878 | l = PetscMax(1,(PetscInt)((nv-k)*ctx->keep)); | |
87 | 6878 | l = PetscMin(l,t); | |
88 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(DSGetTruncateSize(eps->ds,k,t,&l)); |
89 | } | ||
90 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
6999 | if (!ctx->lock && l>0) { l += k; k = 0; } /* non-locking variant: reset no. of converged pairs */ |
91 |
6/8✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 8 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 2 times.
|
6999 | if (l) PetscCall(PetscInfo(eps,"Preparing to restart keeping l=%" PetscInt_FMT " vectors\n",l)); |
92 | |||
93 |
2/2✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
|
6999 | if (eps->reason == EPS_CONVERGED_ITERATING) { |
94 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
6878 | PetscCheck(!breakdown,PetscObjectComm((PetscObject)eps),PETSC_ERR_CONV_FAILED,"Breakdown in Indefinite Krylov-Schur (beta=%g)",(double)beta); |
95 | /* Prepare the Rayleigh quotient for restart */ | ||
96 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(DSTruncate(eps->ds,k+l,PETSC_FALSE)); |
97 | } | ||
98 | /* Update the corresponding vectors V(:,idx) = V*Q(:,idx) */ | ||
99 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSGetMat(eps->ds,DS_MAT_Q,&U)); |
100 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(BVMultInPlace(eps->V,U,eps->nconv,k+l)); |
101 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6999 | PetscCall(DSRestoreMat(eps->ds,DS_MAT_Q,&U)); |
102 | |||
103 | /* Move restart vector and update signature */ | ||
104 |
3/4✓ Branch 0 taken 10 times.
✓ Branch 1 taken 10 times.
✓ Branch 2 taken 10 times.
✗ Branch 3 not taken.
|
6999 | if (eps->reason == EPS_CONVERGED_ITERATING && !breakdown) { |
105 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(BVCopyColumn(eps->V,nv,k+l)); |
106 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(BVSetActiveColumns(eps->V,0,k+l)); |
107 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(DSGetMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega)); |
108 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(BVSetSignature(eps->V,vomega)); |
109 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
6878 | PetscCall(DSRestoreMatAndColumn(eps->ds,DS_MAT_D,0,&D,&vomega)); |
110 | } | ||
111 | |||
112 | 6999 | eps->nconv = k; | |
113 |
7/8✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 8 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
✓ Branch 6 taken 2 times.
✓ Branch 7 taken 2 times.
|
7120 | PetscCall(EPSMonitor(eps,eps->its,nconv,eps->eigr,eps->eigi,eps->errest,nv)); |
114 | } | ||
115 |
4/6✓ Branch 0 taken 2 times.
✓ Branch 1 taken 8 times.
✓ Branch 2 taken 2 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 2 times.
|
121 | PetscCall(DSTruncate(eps->ds,eps->nconv,PETSC_TRUE)); |
116 |
6/12✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 2 times.
✓ Branch 4 taken 2 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 2 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 2 times.
|
29 | PetscFunctionReturn(PETSC_SUCCESS); |
117 | } | ||
118 |