Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
6 dsic.upv.es!jroman 1
 
2
/*                      
3
       This implements the subspace iteration method for finding the
4
       eigenpairs associtated to the eigenvalues with largest magnitude.
5
*/
6
#include "src/eps/epsimpl.h"
7
 
8
typedef struct {
9
  int        inner;
10
} EPS_SUBSPACE;
11
 
12
#undef __FUNCT__  
13
#define __FUNCT__ "EPSSetUp_SUBSPACE"
14
static int EPSSetUp_SUBSPACE(EPS eps)
15
{
16
  int      ierr;
17
 
18
  PetscFunctionBegin;
19
  ierr = EPSDefaultGetWork(eps,1);CHKERRQ(ierr);
20
  PetscFunctionReturn(0);
21
}
22
 
23
#undef __FUNCT__  
24
#define __FUNCT__ "EPSSetDefaults_SUBSPACE"
25
static int EPSSetDefaults_SUBSPACE(EPS eps)
26
{
27
  int          ierr, N;
28
  EPS_SUBSPACE *subspace = (EPS_SUBSPACE *)eps->data;
29
 
30
  PetscFunctionBegin;
31
  ierr = VecGetSize(eps->vec_initial,&N);CHKERRQ(ierr);
32
  if (eps->ncv) {
33
    if (eps->ncv<eps->nev) SETERRQ(1,"The value of ncv must be at least nev");
34
  }
35
  else eps->ncv = PetscMax(2*eps->nev,eps->nev+8);
36
  if (!eps->max_it) eps->max_it = PetscMax(100,N);
37
  if (!subspace->inner) {
38
    if (eps->ishermitian) subspace->inner = 10;
39
    else                  subspace->inner = 4;
40
  }
41
  if (!eps->tol) eps->tol = 1.e-7;
42
  PetscFunctionReturn(0);
43
}
44
 
45
#undef __FUNCT__  
46
#define __FUNCT__ "EPSSolve_SUBSPACE"
47
static int  EPSSolve_SUBSPACE(EPS eps,int *its)
48
{
49
  int          ierr, i, j, k, maxit=eps->max_it, ncv = eps->ncv;
50
  Vec          w;
51
  PetscReal    relerr, tol=eps->tol;
52
  PetscScalar  alpha, *H, *S;
53
  EPS_SUBSPACE *subspace = (EPS_SUBSPACE *)eps->data;
54
 
55
  PetscFunctionBegin;
56
  w  = eps->work[0];
57
  ierr = PetscMalloc(ncv*ncv*sizeof(PetscScalar),&H);CHKERRQ(ierr);
58
  ierr = PetscMalloc(ncv*ncv*sizeof(PetscScalar),&S);CHKERRQ(ierr);
59
 
60
  /* Build Z from initial vector */
61
  ierr = VecCopy(eps->vec_initial,eps->V[0]);CHKERRQ(ierr);
62
  for (k=1; k<ncv; k++) {
63
    ierr = STApply(eps->OP,eps->V[k-1],eps->V[k]); CHKERRQ(ierr);
64
  }
65
  /* QR-Factorize V R = Z */
66
  ierr = EPSQRDecomposition(eps,0,ncv,PETSC_NULL,ncv);CHKERRQ(ierr);
67
 
68
  i = 0;
69
  *its = 0;
70
 
71
  while (*its<maxit) {
72
 
73
    /* Y = OP^inner V */
74
    for (k=i;k<ncv;k++) {
75
      for (j=i;j<subspace->inner;j++) {
76
        ierr = STApply(eps->OP,eps->V[k],w);CHKERRQ(ierr);
77
        ierr = VecCopy(w,eps->V[k]);CHKERRQ(ierr);
78
      }
79
    }
80
 
81
    /* QR-Factorize V R = Y */
82
    ierr = EPSQRDecomposition(eps,i,ncv,PETSC_NULL,ncv);CHKERRQ(ierr);
83
 
84
    /* compute the projected matrix, H = V^* A V */
85
    for (j=i;j<ncv;j++) {
86
      ierr = STApply(eps->OP,eps->V[j],w);CHKERRQ(ierr);
87
      for (k=i;k<ncv;k++) {
88
        ierr = VecDot(w,eps->V[k],H+(k-i)+(ncv-i)*(j-i));CHKERRQ(ierr);
89
      }
90
    }
91
 
92
    /* solve the reduced problem, compute the
93
       eigendecomposition H = S Theta S^* */
94
    ierr = EPSDenseNHEP(ncv-i,H,eps->eigr+i,eps->eigi+i,S);CHKERRQ(ierr);
95
 
96
    /* update V = V S */
97
    ierr = EPSReverseProjection(eps,i,ncv-i,S);CHKERRQ(ierr);
98
 
99
    /* check eigenvalue convergence */
100
    for (j=i;j<ncv;j++) {
101
      ierr = STApply(eps->OP,eps->V[j],w);CHKERRQ(ierr);
102
      alpha = -eps->eigr[j];
103
      ierr = VecAXPY(&alpha,eps->V[j],w);CHKERRQ(ierr);
104
      ierr = VecNorm(w,NORM_2,&relerr);CHKERRQ(ierr);
105
      eps->errest[j] = relerr;
106
    }
107
 
108
    /* lock converged Ritz pairs */
109
    eps->nconv = i;
110
    for (j=i;j<ncv;j++) {
111
      if (eps->errest[j]<tol) {
112
        if (j>eps->nconv) {
113
          ierr = EPSSwapEigenpairs(eps,eps->nconv,j);CHKERRQ(ierr);
114
        }
115
        eps->nconv = eps->nconv + 1;
116
      }
117
    }
118
    i = eps->nconv;
119
 
120
    *its = *its + 1;
121
    EPSMonitorEstimates(eps,*its,eps->nconv,eps->errest,ncv);
122
    EPSMonitorValues(eps,*its,eps->nconv,eps->eigr,PETSC_NULL,ncv);
123
 
124
    if (eps->nconv>=eps->nev) break;
125
 
126
  }
127
 
128
  ierr = PetscFree(H);CHKERRQ(ierr);
129
  ierr = PetscFree(S);CHKERRQ(ierr);
130
 
131
  if( *its==maxit ) *its = *its - 1;
132
  eps->its = *its;
133
  if( eps->nconv == eps->nev ) eps->reason = EPS_CONVERGED_TOL;
134
  else eps->reason = EPS_DIVERGED_ITS;
135
#if defined(PETSC_USE_COMPLEX)
136
  for (i=0;i<eps->nconv;i++) eps->eigi[i]=0.0;
137
#endif
138
 
139
  PetscFunctionReturn(0);
140
}
141
 
142
#undef __FUNCT__  
143
#define __FUNCT__ "EPSView_SUBSPACE"
144
static int EPSView_SUBSPACE(EPS eps,PetscViewer viewer)
145
{
146
  EPS_SUBSPACE *subspace = (EPS_SUBSPACE *) eps->data;
147
  int          ierr;
148
  PetscTruth   isascii;
149
 
150
  PetscFunctionBegin;
151
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
152
  if (!isascii) {
153
    SETERRQ1(1,"Viewer type %s not supported for EPSSUBSPACE",((PetscObject)viewer)->type_name);
154
  }
155
  ierr = PetscViewerASCIIPrintf(viewer,"number of inner iterations: %d\n",subspace->inner);CHKERRQ(ierr);
156
  PetscFunctionReturn(0);
157
}
158
 
159
#undef __FUNCT__  
160
#define __FUNCT__ "EPSSetFromOptions_SUBSPACE"
161
static int EPSSetFromOptions_SUBSPACE(EPS eps)
162
{
163
  EPS_SUBSPACE *subspace = (EPS_SUBSPACE *)eps->data;
164
  int          ierr,val;
165
  PetscTruth   flg;
166
 
167
  PetscFunctionBegin;
168
  ierr = PetscOptionsHead("SUBSPACE options");CHKERRQ(ierr);
169
    val = subspace->inner;
170
    ierr = PetscOptionsInt("-eps_subspace_inner","Number of inner iterations","EPSSubspaceSetInner",val,&val,&flg);CHKERRQ(ierr);
171
    if (flg) {ierr = EPSSubspaceSetInner(eps,val);CHKERRQ(ierr);}
172
  ierr = PetscOptionsTail();CHKERRQ(ierr);
173
  PetscFunctionReturn(0);
174
}
175
 
176
EXTERN_C_BEGIN
177
#undef __FUNCT__  
178
#define __FUNCT__ "EPSSubspaceSetInner_SUBSPACE"
179
int EPSSubspaceSetInner_SUBSPACE(EPS eps,int val)
180
{
181
  EPS_SUBSPACE   *subspace;
182
 
183
  PetscFunctionBegin;
184
  subspace        = (EPS_SUBSPACE *) eps->data;
185
  subspace->inner = val;
186
  PetscFunctionReturn(0);
187
}
188
EXTERN_C_END
189
 
190
#undef __FUNCT__  
191
#define __FUNCT__ "EPSSubspaceSetInner"
192
/*@
193
   EPSSubspaceSetInner - Sets the number of inner iterations performed by
194
   the Subspace Iteration method.
195
 
196
   Collective on EPS
197
 
198
   Input Parameters:
199
+  eps - the eigenproblem solver context
200
-  val - number of iterations to perform
201
 
202
   Options Database Key:
203
.  -eps_subspace_inner - Sets the value of the inner iterations
204
 
205
   Notes:
206
   This value specifies how many matrix-vector products have to be carried
207
   out in the Subspace Iteration method between the orthogonalization steps.
208
 
209
   The default value is 10 for Hermitian problems and 4 for non-Hermitian ones.
210
 
211
   Level: advanced
212
 
213
@*/
214
int EPSSubspaceSetInner(EPS eps,int val)
215
{
216
  int ierr, (*f)(EPS,int);
217
 
218
  PetscFunctionBegin;
25 dsic.upv.es!jroman 219
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
6 dsic.upv.es!jroman 220
  ierr = PetscObjectQueryFunction((PetscObject)eps,"EPSSubspaceSetInner_C",(void (**)(void))&f);CHKERRQ(ierr);
221
  if (f) {
222
    ierr = (*f)(eps,val);CHKERRQ(ierr);
223
  }
224
  PetscFunctionReturn(0);
225
}
226
 
227
EXTERN_C_BEGIN
228
#undef __FUNCT__  
229
#define __FUNCT__ "EPSCreate_SUBSPACE"
230
int EPSCreate_SUBSPACE(EPS eps)
231
{
232
  EPS_SUBSPACE *subspace;
233
  int          ierr;
234
 
235
  PetscFunctionBegin;
236
  ierr = PetscNew(EPS_SUBSPACE,&subspace);CHKERRQ(ierr);
237
  PetscMemzero(subspace,sizeof(EPS_SUBSPACE));
238
  PetscLogObjectMemory(eps,sizeof(EPS_SUBSPACE));
239
  eps->data                      = (void *) subspace;
240
  eps->ops->setup                = EPSSetUp_SUBSPACE;
241
  eps->ops->setdefaults          = EPSSetDefaults_SUBSPACE;
242
  eps->ops->solve                = EPSSolve_SUBSPACE;
243
  eps->ops->destroy              = EPSDefaultDestroy;
244
  eps->ops->setfromoptions       = EPSSetFromOptions_SUBSPACE;
245
  eps->ops->view                 = EPSView_SUBSPACE;
246
 
247
  subspace->inner = 0;
248
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)eps,"EPSSubspaceSetInner_C","EPSSubspaceSetInner_SUBSPACE",EPSSubspaceSetInner_SUBSPACE);CHKERRQ(ierr);
249
 
250
  PetscFunctionReturn(0);
251
}
252
EXTERN_C_END
253