Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
538 dsic.upv.es!jroman 1
/*                      
1707 jroman 2
   Common subroutines for all Krylov-type solvers.
6 dsic.upv.es!jroman 3
 
1376 slepc 4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 6
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
1376 slepc 7
 
1672 slepc 8
   This file is part of SLEPc.
9
 
10
   SLEPc is free software: you can redistribute it and/or modify it under  the
11
   terms of version 3 of the GNU Lesser General Public License as published by
12
   the Free Software Foundation.
13
 
14
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
15
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
16
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
17
   more details.
18
 
19
   You  should have received a copy of the GNU Lesser General  Public  License
20
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6 dsic.upv.es!jroman 22
*/
1376 slepc 23
 
2729 jroman 24
#include <slepc-private/epsimpl.h>
25
#include <slepc-private/slepcimpl.h>
2283 jroman 26
#include <slepcblaslapack.h>
6 dsic.upv.es!jroman 27
 
28
#undef __FUNCT__  
431 dsic.upv.es!antodo 29
#define __FUNCT__ "EPSBasicArnoldi"
538 dsic.upv.es!jroman 30
/*
31
   EPSBasicArnoldi - Computes an m-step Arnoldi factorization. The first k
32
   columns are assumed to be locked and therefore they are not modified. On
33
   exit, the following relation is satisfied:
34
 
35
                    OP * V - V * H = f * e_m^T
36
 
37
   where the columns of V are the Arnoldi vectors (which are B-orthonormal),
591 dsic.upv.es!jroman 38
   H is an upper Hessenberg matrix, f is the residual vector and e_m is
39
   the m-th vector of the canonical basis. The vector f is B-orthogonal to
40
   the columns of V. On exit, beta contains the B-norm of f and the next
41
   Arnoldi vector can be computed as v_{m+1} = f / beta.
538 dsic.upv.es!jroman 42
*/
2216 jroman 43
PetscErrorCode EPSBasicArnoldi(EPS eps,PetscBool trans,PetscScalar *H,PetscInt ldh,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscReal *beta,PetscBool *breakdown)
431 dsic.upv.es!antodo 44
{
476 dsic.upv.es!antodo 45
  PetscErrorCode ierr;
1755 antodo 46
  PetscInt       j,m = *M;
476 dsic.upv.es!antodo 47
  PetscReal      norm;
431 dsic.upv.es!antodo 48
 
49
  PetscFunctionBegin;
574 dsic.upv.es!antodo 50
  for (j=k;j<m-1;j++) {
879 ono.com!jroman 51
    if (trans) { ierr = STApplyTranspose(eps->OP,V[j],V[j+1]);CHKERRQ(ierr); }
52
    else { ierr = STApply(eps->OP,V[j],V[j+1]);CHKERRQ(ierr); }
1755 antodo 53
    ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,j+1,PETSC_NULL,V,V[j+1],H+ldh*j,&norm,breakdown);CHKERRQ(ierr);
1574 slepc 54
    H[j+1+ldh*j] = norm;
1113 slepc 55
    if (*breakdown) {
1049 slepc 56
      *M = j+1;
57
      *beta = norm;
58
      PetscFunctionReturn(0);
828 dsic.upv.es!antodo 59
    } else {
60
      ierr = VecScale(V[j+1],1/norm);CHKERRQ(ierr);
549 dsic.upv.es!antodo 61
    }
431 dsic.upv.es!antodo 62
  }
1600 slepc 63
  if (trans) { ierr = STApplyTranspose(eps->OP,V[m-1],f);CHKERRQ(ierr); }
64
  else { ierr = STApply(eps->OP,V[m-1],f);CHKERRQ(ierr); }
1755 antodo 65
  ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,m,PETSC_NULL,V,f,H+ldh*(m-1),beta,PETSC_NULL);CHKERRQ(ierr);
431 dsic.upv.es!antodo 66
  PetscFunctionReturn(0);
67
}
68
 
69
#undef __FUNCT__  
2059 jroman 70
#define __FUNCT__ "EPSKrylovConvergence"
71
/*
72
   EPSKrylovConvergence - Implements the loop that checks for convergence
73
   in Krylov methods.
74
 
75
   Input Parameters:
76
     eps   - the eigensolver; some error estimates are updated in eps->errest
2804 jroman 77
     getall - whether all residuals must be computed
2059 jroman 78
     kini  - initial value of k (the loop variable)
79
     nits  - number of iterations of the loop
80
     V     - set of basis vectors (used only if trueresidual is activated)
81
     nv    - number of vectors to process (dimension of Q, columns of V)
82
     beta  - norm of f (the residual vector of the Arnoldi/Lanczos factorization)
83
     corrf - correction factor for residual estimates (only in harmonic KS)
84
 
85
   Output Parameters:
86
     kout  - the first index where the convergence test failed
87
*/
2818 jroman 88
PetscErrorCode EPSKrylovConvergence(EPS eps,PetscBool getall,PetscInt kini,PetscInt nits,Vec *V,PetscInt nv,PetscReal beta,PetscReal corrf,PetscInt *kout)
2059 jroman 89
{
90
  PetscErrorCode ierr;
2811 jroman 91
  PetscInt       k,newk,marker,ld;
92
  PetscScalar    re,im,*Z,*X;
2059 jroman 93
  PetscReal      resnorm;
2811 jroman 94
  PetscBool      isshift;
2059 jroman 95
 
96
  PetscFunctionBegin;
2811 jroman 97
  ierr = PSGetLeadingDimension(eps->ps,&ld);CHKERRQ(ierr);
2823 jroman 98
  ierr = PetscObjectTypeCompare((PetscObject)eps->OP,STSHIFT,&isshift);CHKERRQ(ierr);
2059 jroman 99
  marker = -1;
2804 jroman 100
  getall = getall | eps->trackall;
2059 jroman 101
  for (k=kini;k<kini+nits;k++) {
102
    /* eigenvalue */
103
    re = eps->eigr[k];
104
    im = eps->eigi[k];
105
    if (eps->trueres || isshift) {
106
      ierr = STBackTransform(eps->OP,1,&re,&im);CHKERRQ(ierr);
107
    }
2811 jroman 108
    newk = k;
109
    ierr = PSVectors(eps->ps,PS_MAT_X,&newk,&resnorm);CHKERRQ(ierr);
110
    resnorm *= beta;
2059 jroman 111
    if (eps->trueres) {
2811 jroman 112
      ierr = PSGetArray(eps->ps,PS_MAT_X,&X);CHKERRQ(ierr);
2818 jroman 113
      Z = X+k*ld;
2059 jroman 114
      ierr = EPSComputeTrueResidual(eps,re,im,Z,V,nv,&resnorm);CHKERRQ(ierr);
2811 jroman 115
      ierr = PSRestoreArray(eps->ps,PS_MAT_X,&X);CHKERRQ(ierr);
2059 jroman 116
    }
117
    else resnorm *= corrf;
118
    /* error estimate */
2070 jroman 119
    ierr = (*eps->conv_func)(eps,re,im,resnorm,&eps->errest[k],eps->conv_ctx);CHKERRQ(ierr);
120
    if (marker==-1 && eps->errest[k] >= eps->tol) marker = k;
2811 jroman 121
    if (newk==k+1) { eps->errest[k+1] = eps->errest[k]; k++; }
2804 jroman 122
    if (marker!=-1 && !getall) break;
2059 jroman 123
  }
124
  if (marker!=-1) k = marker;
125
  *kout = k;
126
  PetscFunctionReturn(0);
127
}
128
 
129
#undef __FUNCT__  
1707 jroman 130
#define __FUNCT__ "EPSFullLanczos"
1484 slepc 131
/*
1707 jroman 132
   EPSFullLanczos - Computes an m-step Lanczos factorization with full
133
   reorthogonalization.  At each Lanczos step, the corresponding Lanczos
134
   vector is orthogonalized with respect to all previous Lanczos vectors.
135
   This is equivalent to computing an m-step Arnoldi factorization and
136
   exploting symmetry of the operator.
1484 slepc 137
 
1707 jroman 138
   The first k columns are assumed to be locked and therefore they are
139
   not modified. On exit, the following relation is satisfied:
1484 slepc 140
 
1707 jroman 141
                    OP * V - V * T = f * e_m^T
1484 slepc 142
 
1707 jroman 143
   where the columns of V are the Lanczos vectors (which are B-orthonormal),
144
   T is a real symmetric tridiagonal matrix, f is the residual vector and e_m
145
   is the m-th vector of the canonical basis. The tridiagonal is stored as
146
   two arrays: alpha contains the diagonal elements, beta the off-diagonal.
147
   The vector f is B-orthogonal to the columns of V. On exit, the last element
148
   of beta contains the B-norm of f and the next Lanczos vector can be
149
   computed as v_{m+1} = f / beta(end).
1484 slepc 150
 
151
*/
2216 jroman 152
PetscErrorCode EPSFullLanczos(EPS eps,PetscReal *alpha,PetscReal *beta,Vec *V,PetscInt k,PetscInt *M,Vec f,PetscBool *breakdown)
1484 slepc 153
{
154
  PetscErrorCode ierr;
1707 jroman 155
  PetscInt       j,m = *M;
156
  PetscReal      norm;
1755 antodo 157
  PetscScalar    *hwork,lhwork[100];
1484 slepc 158
 
159
  PetscFunctionBegin;
1755 antodo 160
  if (m > 100) {
1707 jroman 161
    ierr = PetscMalloc((eps->nds+m)*sizeof(PetscScalar),&hwork);CHKERRQ(ierr);
162
  } else {
163
    hwork = lhwork;
1484 slepc 164
  }
165
 
1707 jroman 166
  for (j=k;j<m-1;j++) {
167
    ierr = STApply(eps->OP,V[j],V[j+1]);CHKERRQ(ierr);
1755 antodo 168
    ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,j+1,PETSC_NULL,V,V[j+1],hwork,&norm,breakdown);CHKERRQ(ierr);
2818 jroman 169
    alpha[j] = PetscRealPart(hwork[j]);
170
    beta[j] = norm;
1707 jroman 171
    if (*breakdown) {
172
      *M = j+1;
1755 antodo 173
      if (m > 100) {
1707 jroman 174
        ierr = PetscFree(hwork);CHKERRQ(ierr);
175
      }
176
      PetscFunctionReturn(0);
1083 slepc 177
    } else {
1707 jroman 178
      ierr = VecScale(V[j+1],1.0/norm);CHKERRQ(ierr);
1083 slepc 179
    }
431 dsic.upv.es!antodo 180
  }
1707 jroman 181
  ierr = STApply(eps->OP,V[m-1],f);CHKERRQ(ierr);
1755 antodo 182
  ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,m,PETSC_NULL,V,f,hwork,&norm,PETSC_NULL);CHKERRQ(ierr);
2818 jroman 183
  alpha[m-1] = PetscRealPart(hwork[m-1]);
184
  beta[m-1] = norm;
431 dsic.upv.es!antodo 185
 
1755 antodo 186
  if (m > 100) {
1707 jroman 187
    ierr = PetscFree(hwork);CHKERRQ(ierr);
1484 slepc 188
  }
431 dsic.upv.es!antodo 189
  PetscFunctionReturn(0);
190
}
191
 
1083 slepc 192