Subversion Repositories slepc-dev

Rev

Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1619 slepc 1
/*
2110 jroman 2
  Method: General Davidson Method (includes GD and JD)
1619 slepc 3
 
4
  References:
5
    - Ernest R. Davidson. Super-matrix methods. Computer Physics Communications,
6
      53:49–60, May 1989.
2110 jroman 7
 
8
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
9
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 10
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
2110 jroman 11
 
12
   This file is part of SLEPc.
13
 
14
   SLEPc is free software: you can redistribute it and/or modify it under  the
15
   terms of version 3 of the GNU Lesser General Public License as published by
16
   the Free Software Foundation.
17
 
18
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
19
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
20
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
21
   more details.
22
 
23
   You  should have received a copy of the GNU Lesser General  Public  License
24
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
25
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1619 slepc 26
*/
27
 
1985 eromero 28
#include "davidson.h"
1619 slepc 29
 
1993 eromero 30
PetscErrorCode EPSView_DAVIDSON(EPS eps,PetscViewer viewer);
31
 
2244 eromero 32
typedef struct {
33
  /**** Solver options ****/
34
  PetscInt blocksize,     /* block size */
35
    initialsize,          /* initial size of V */
36
    minv,                 /* size of V after restarting */
37
    plusk;                /* keep plusk eigenvectors from the last iteration */
38
  PetscBool  ipB;         /* true if V'B*V=I */
39
  PetscInt   method;      /* method for improving the approximate solution */
40
  PetscReal  fix;         /* the fix parameter */
41
  PetscBool  krylovstart; /* true if the starting subspace is a Krylov basis */
42
 
43
  /**** Solver data ****/
44
  dvdDashboard ddb;
45
 
46
  /**** Things to destroy ****/
47
  PetscScalar *wS;
48
  Vec         *wV;
49
  PetscInt    size_wV;
50
} EPS_DAVIDSON;
51
 
1982 eromero 52
#undef __FUNCT__  
53
#define __FUNCT__ "EPSCreate_DAVIDSON"
54
PetscErrorCode EPSCreate_DAVIDSON(EPS eps) {
55
  PetscErrorCode  ierr;
1985 eromero 56
  EPS_DAVIDSON    *data;
1756 eromero 57
 
1982 eromero 58
  PetscFunctionBegin;
59
 
2000 eromero 60
  ierr = STSetType(eps->OP, STPRECOND); CHKERRQ(ierr);
2020 eromero 61
  ierr = STPrecondSetKSPHasMat(eps->OP, PETSC_FALSE); CHKERRQ(ierr);
1982 eromero 62
 
63
  eps->OP->ops->getbilinearform  = STGetBilinearForm_Default;
64
  eps->ops->solve                = EPSSolve_DAVIDSON;
65
  eps->ops->setup                = EPSSetUp_DAVIDSON;
1992 eromero 66
  eps->ops->destroy              = EPSDestroy_DAVIDSON;
1982 eromero 67
  eps->ops->backtransform        = EPSBackTransform_Default;
68
  eps->ops->computevectors       = EPSComputeVectors_QZ;
1993 eromero 69
  eps->ops->view                 = EPSView_DAVIDSON;
1982 eromero 70
 
1985 eromero 71
  ierr = PetscMalloc(sizeof(EPS_DAVIDSON), &data); CHKERRQ(ierr);
1982 eromero 72
  eps->data = data;
73
 
74
  /* Set default values */
75
  ierr = EPSDAVIDSONSetKrylovStart_DAVIDSON(eps, PETSC_FALSE); CHKERRQ(ierr);
76
  ierr = EPSDAVIDSONSetBlockSize_DAVIDSON(eps, 1); CHKERRQ(ierr);
77
  ierr = EPSDAVIDSONSetRestart_DAVIDSON(eps, 6, 0); CHKERRQ(ierr);
78
  ierr = EPSDAVIDSONSetInitialSize_DAVIDSON(eps, 5); CHKERRQ(ierr);
1995 eromero 79
  ierr = EPSDAVIDSONSetFix_DAVIDSON(eps, 0.01); CHKERRQ(ierr);
1982 eromero 80
 
81
  PetscFunctionReturn(0);
82
}
83
 
84
 
1619 slepc 85
#undef __FUNCT__  
1976 eromero 86
#define __FUNCT__ "EPSSetUp_DAVIDSON"
87
PetscErrorCode EPSSetUp_DAVIDSON(EPS eps) {
1619 slepc 88
  PetscErrorCode  ierr;
1985 eromero 89
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 90
  dvdDashboard    *dvd = &data->ddb;
91
  dvdBlackboard   b;
1998 eromero 92
  PetscInt        i,nvecs,nscalars,min_size_V,plusk,bs,initv;
1619 slepc 93
  Mat             A,B;
94
  KSP             ksp;
2216 jroman 95
  PetscBool       t,ipB,ispositive;
1976 eromero 96
  HarmType_t      harm;
97
  InitType_t      init;
1995 eromero 98
  PetscReal       fix;
1619 slepc 99
 
100
  PetscFunctionBegin;
101
 
102
  /* Setup EPS options and get the problem specification */
2023 eromero 103
  ierr = EPSDAVIDSONGetBlockSize_DAVIDSON(eps, &bs); CHKERRQ(ierr);
104
  if (bs <= 0) bs = 1;
1619 slepc 105
  if(eps->ncv) {
2214 jroman 106
    if (eps->ncv<eps->nev) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The value of ncv must be at least nev");
2023 eromero 107
  } else if (eps->mpd) eps->ncv = eps->mpd + eps->nev + bs;
108
  else if (eps->nev<500)
109
    eps->ncv = PetscMin(eps->n,PetscMax(2*eps->nev,eps->nev+15))+bs;
110
  else
111
    eps->ncv = PetscMin(eps->n,eps->nev+500)+bs;
112
  if (!eps->mpd) eps->mpd = eps->ncv;
113
  if (eps->mpd > eps->ncv)
2214 jroman 114
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The mpd has to be less or equal than ncv");
2023 eromero 115
  if (eps->mpd < 2)
2214 jroman 116
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The mpd has to be greater than 2");
1976 eromero 117
  if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
118
  if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
119
  if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY))
2214 jroman 120
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Wrong value of eps->which");
2023 eromero 121
  if (!(eps->nev + bs <= eps->ncv))
2214 jroman 122
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP, "The ncv has to be greater than nev plus blocksize!");
1619 slepc 123
 
1980 eromero 124
  ierr = EPSDAVIDSONGetRestart_DAVIDSON(eps, &min_size_V, &plusk);
125
  CHKERRQ(ierr);
2023 eromero 126
  if (!min_size_V) min_size_V = PetscMin(PetscMax(bs,5), eps->mpd/2);
127
  if (!(min_size_V+bs <= eps->mpd))
2214 jroman 128
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP, "The value of minv must be less than mpd minus blocksize");
1998 eromero 129
  ierr = EPSDAVIDSONGetInitialSize_DAVIDSON(eps, &initv); CHKERRQ(ierr);
2023 eromero 130
  if (eps->mpd < initv)
2214 jroman 131
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The initv has to be less or equal than mpd");
1619 slepc 132
 
2021 eromero 133
  /* Davidson solvers do not support left eigenvectors */
2214 jroman 134
  if (eps->leftvecs) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Left vectors not supported in this solver");
2021 eromero 135
 
2104 eromero 136
  /* Change the default sigma to inf if necessary */
137
  if (eps->which == EPS_LARGEST_MAGNITUDE || eps->which == EPS_LARGEST_REAL ||
138
      eps->which == EPS_LARGEST_IMAGINARY) {
139
    ierr = STSetDefaultShift(eps->OP, 3e300); CHKERRQ(ierr);
140
  }
141
 
1997 eromero 142
  /* Davidson solvers only support STPRECOND */
2003 eromero 143
  ierr = STSetUp(eps->OP); CHKERRQ(ierr);
1997 eromero 144
  ierr = PetscTypeCompare((PetscObject)eps->OP, STPRECOND, &t); CHKERRQ(ierr);
2214 jroman 145
  if (!t) SETERRQ1(((PetscObject)eps)->comm,PETSC_ERR_SUP, "%s only works with precond spectral transformation",
2003 eromero 146
    ((PetscObject)eps)->type_name);
2015 eromero 147
 
1619 slepc 148
  /* Setup problem specification in dvd */
2015 eromero 149
  ierr = STGetOperators(eps->OP, &A, &B); CHKERRQ(ierr);
1619 slepc 150
  ierr = PetscMemzero(dvd, sizeof(dvdDashboard)); CHKERRQ(ierr);
2177 jroman 151
  dvd->A = A; dvd->B = eps->isgeneralized? B : PETSC_NULL;
2021 eromero 152
  ispositive = eps->ispositive;
1747 eromero 153
  dvd->sA = DVD_MAT_IMPLICIT |
2177 jroman 154
            (eps->ishermitian? DVD_MAT_HERMITIAN : 0) |
155
            ((ispositive && !eps->isgeneralized) ? DVD_MAT_POS_DEF : 0);
1764 eromero 156
  /* Asume -eps_hermitian means hermitian-definite in generalized problems */
2177 jroman 157
  if (!ispositive && !eps->isgeneralized && eps->ishermitian) ispositive = PETSC_TRUE;
158
  if (!eps->isgeneralized)
1747 eromero 159
    dvd->sB = DVD_MAT_IMPLICIT | DVD_MAT_HERMITIAN | DVD_MAT_IDENTITY |
1764 eromero 160
              DVD_MAT_UNITARY | DVD_MAT_POS_DEF;
1747 eromero 161
  else
162
    dvd->sB = DVD_MAT_IMPLICIT |
2177 jroman 163
              (eps->ishermitian? DVD_MAT_HERMITIAN : 0) |
164
              (ispositive? DVD_MAT_POS_DEF : 0);
1976 eromero 165
  ipB = DVD_IS(dvd->sB, DVD_MAT_POS_DEF)?PETSC_TRUE:PETSC_FALSE;
2177 jroman 166
  dvd->sEP = ((!eps->isgeneralized || (eps->isgeneralized && ipB))? DVD_EP_STD : 0) |
167
             (ispositive? DVD_EP_HERMITIAN : 0);
1619 slepc 168
  dvd->nev = eps->nev;
169
  dvd->which = eps->which;
1805 eromero 170
  switch(eps->which) {
171
  case EPS_TARGET_MAGNITUDE:
172
  case EPS_TARGET_REAL:
173
  case EPS_TARGET_IMAGINARY:
174
    dvd->withTarget = PETSC_TRUE;
1883 eromero 175
    dvd->target[0] = eps->target; dvd->target[1] = 1.0;
1805 eromero 176
    break;
1883 eromero 177
 
178
  case EPS_LARGEST_MAGNITUDE:
179
  case EPS_LARGEST_REAL:
180
  case EPS_LARGEST_IMAGINARY: //TODO: think about this case
1805 eromero 181
  default:
1984 eromero 182
    dvd->withTarget = PETSC_TRUE;
1883 eromero 183
    dvd->target[0] = 1.0; dvd->target[1] = 0.0;
184
    break;
185
 
186
  case EPS_SMALLEST_MAGNITUDE:
187
  case EPS_SMALLEST_REAL:
188
  case EPS_SMALLEST_IMAGINARY: //TODO: think about this case
1984 eromero 189
    dvd->withTarget = PETSC_TRUE;
1883 eromero 190
    dvd->target[0] = 0.0; dvd->target[1] = 1.0;
1805 eromero 191
  }
1619 slepc 192
  dvd->tol = eps->tol;
1805 eromero 193
  dvd->eps = eps;
1619 slepc 194
 
1976 eromero 195
  /* Setup the extraction technique */
2231 jroman 196
  if (!eps->extraction) {
197
    ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr);
198
  }
1976 eromero 199
  switch(eps->extraction) {
200
  case EPS_RITZ:              harm = DVD_HARM_NONE; break;
201
  case EPS_HARMONIC:          harm = DVD_HARM_RR; break;
202
  case EPS_HARMONIC_RELATIVE: harm = DVD_HARM_RRR; break;
203
  case EPS_HARMONIC_RIGHT:    harm = DVD_HARM_REIGS; break;
204
  case EPS_HARMONIC_LARGEST:  harm = DVD_HARM_LEIGS; break;
2214 jroman 205
  default: SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Unsupported extraction type");
1976 eromero 206
  }
207
 
208
  /* Setup the type of starting subspace */
1980 eromero 209
  ierr = EPSDAVIDSONGetKrylovStart_DAVIDSON(eps, &t); CHKERRQ(ierr);
2177 jroman 210
  init = (!t)? DVD_INITV_CLASSIC : DVD_INITV_KRYLOV;
1976 eromero 211
 
1747 eromero 212
  /* Setup IP */
2177 jroman 213
  if (ipB && dvd->B) {
1975 eromero 214
    ierr = IPSetBilinearForm(eps->ip, dvd->B, IP_INNER_HERMITIAN); CHKERRQ(ierr);
1764 eromero 215
  } else {
1975 eromero 216
    ierr = IPSetBilinearForm(eps->ip, 0, IP_INNER_HERMITIAN); CHKERRQ(ierr);
1764 eromero 217
  }
1747 eromero 218
 
1995 eromero 219
  /* Get the fix parameter */
220
  ierr = EPSDAVIDSONGetFix_DAVIDSON(eps, &fix); CHKERRQ(ierr);
221
 
1989 eromero 222
  /* Orthonormalize the DS */
2188 eromero 223
  ierr = dvd_orthV(eps->ip, PETSC_NULL, 0, PETSC_NULL, 0, eps->DS, 0,
224
                   PetscAbs(eps->nds), PETSC_NULL, 0, eps->rand); CHKERRQ(ierr);
1989 eromero 225
 
1867 eromero 226
  /* Preconfigure dvd */
2244 eromero 227
  ierr = STGetKSP(eps->OP, &ksp); CHKERRQ(ierr);
2023 eromero 228
  ierr = dvd_schm_basic_preconf(dvd, &b, eps->ncv, eps->mpd, min_size_V, bs,
2188 eromero 229
                                initv,
230
                                PetscAbs(eps->nini),
2244 eromero 231
                                plusk, harm,
2042 eromero 232
                                PETSC_NULL, init, eps->trackall);
1795 eromero 233
  CHKERRQ(ierr);
1619 slepc 234
 
235
  /* Reserve memory */
236
  nvecs = b.max_size_auxV + b.own_vecs;
237
  nscalars = b.own_scalars + b.max_size_auxS;
1975 eromero 238
  ierr = PetscMalloc((nvecs*eps->nloc+nscalars)*sizeof(PetscScalar), &data->wS);
1619 slepc 239
  CHKERRQ(ierr);
240
  ierr = PetscMalloc(nvecs*sizeof(Vec), &data->wV); CHKERRQ(ierr);
1992 eromero 241
  data->size_wV = nvecs;
1619 slepc 242
  for (i=0; i<nvecs; i++) {
1975 eromero 243
    ierr = VecCreateMPIWithArray(((PetscObject)eps)->comm, eps->nloc, PETSC_DECIDE,
244
                                 data->wS+i*eps->nloc, &data->wV[i]);
1619 slepc 245
    CHKERRQ(ierr);
246
  }
247
  b.free_vecs = data->wV;
1975 eromero 248
  b.free_scalars = data->wS + nvecs*eps->nloc;
1619 slepc 249
  dvd->auxV = data->wV + b.own_vecs;
250
  dvd->auxS = b.free_scalars + b.own_scalars;
251
  dvd->size_auxV = b.max_size_auxV;
252
  dvd->size_auxS = b.max_size_auxS;
1805 eromero 253
 
1619 slepc 254
  /* Configure dvd for a basic GD */
2023 eromero 255
  ierr = dvd_schm_basic_conf(dvd, &b, eps->ncv, eps->mpd, min_size_V, bs,
2188 eromero 256
                             initv,
2244 eromero 257
                             PetscAbs(eps->nini), plusk,
1976 eromero 258
                             eps->ip, harm, dvd->withTarget,
1980 eromero 259
                             eps->target, ksp,
2042 eromero 260
                             fix, init, eps->trackall);
1795 eromero 261
  CHKERRQ(ierr);
262
 
1619 slepc 263
  /* Associate the eigenvalues to the EPS */
264
  eps->eigr = dvd->eigr;
265
  eps->eigi = dvd->eigi;
266
  eps->errest = dvd->errest;
1743 eromero 267
  eps->V = dvd->V;
268
 
1619 slepc 269
  PetscFunctionReturn(0);
270
}
271
 
272
 
273
#undef __FUNCT__  
1976 eromero 274
#define __FUNCT__ "EPSSolve_DAVIDSON"
275
PetscErrorCode EPSSolve_DAVIDSON(EPS eps) {
1985 eromero 276
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 277
  dvdDashboard    *d = &data->ddb;
2015 eromero 278
  PetscErrorCode  ierr;
1619 slepc 279
 
280
  PetscFunctionBegin;
281
 
1883 eromero 282
  /* Call the starting routines */
283
  DVD_FL_CALL(d->startList, d);
284
 
1619 slepc 285
  for(eps->its=0; eps->its < eps->max_it; eps->its++) {
1934 eromero 286
    /* Initialize V, if it is needed */
2021 eromero 287
    if (d->size_V == 0) { ierr = d->initV(d); CHKERRQ(ierr); }
1619 slepc 288
 
289
    /* Find the best approximated eigenpairs in V, X */
2021 eromero 290
    ierr = d->calcPairs(d); CHKERRQ(ierr);
1619 slepc 291
 
1934 eromero 292
    /* Expand the subspace */
2021 eromero 293
    ierr = d->updateV(d); CHKERRQ(ierr);
1619 slepc 294
 
1735 eromero 295
    /* Monitor progress */
1750 eromero 296
    eps->nconv = d->nconv;
1993 eromero 297
    EPSMonitor(eps, eps->its+1, eps->nconv, eps->eigr, eps->eigi, eps->errest, d->size_H+d->nconv);
1619 slepc 298
 
1735 eromero 299
    /* Test for convergence */
1750 eromero 300
    if (eps->nconv >= eps->nev) break;
1883 eromero 301
  }
1675 slepc 302
 
1883 eromero 303
  /* Call the ending routines */
304
  DVD_FL_CALL(d->endList, d);
1735 eromero 305
 
306
  if( eps->nconv >= eps->nev ) eps->reason = EPS_CONVERGED_TOL;
1619 slepc 307
  else eps->reason = EPS_DIVERGED_ITS;
308
 
309
  PetscFunctionReturn(0);
310
}
311
 
1992 eromero 312
 
1619 slepc 313
#undef __FUNCT__  
1992 eromero 314
#define __FUNCT__ "EPSDestroy_DAVIDSON"
315
PetscErrorCode EPSDestroy_DAVIDSON(EPS eps) {
316
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
317
  dvdDashboard    *dvd = &data->ddb;
318
  PetscErrorCode  ierr;
319
  PetscInt        i;
320
 
321
  PetscFunctionBegin;
322
 
323
  /* Call step destructors and destroys the list */
324
  DVD_FL_CALL(dvd->destroyList, dvd);
325
  DVD_FL_DEL(dvd->destroyList);
326
  DVD_FL_DEL(dvd->startList);
327
  DVD_FL_DEL(dvd->endList);
328
 
329
  for(i=0; i<data->size_wV; i++) {
330
    ierr = VecDestroy(data->wV[i]); CHKERRQ(ierr);
331
  }
332
  ierr = PetscFree(data->wV);
333
  ierr = PetscFree(data->wS);
334
  ierr = PetscFree(data); CHKERRQ(ierr);
335
 
336
  PetscFunctionReturn(0);
337
}
338
 
339
 
1993 eromero 340
#undef __FUNCT__  
341
#define __FUNCT__ "EPSView_DAVIDSON"
342
PetscErrorCode EPSView_DAVIDSON(EPS eps,PetscViewer viewer)
343
{
344
  PetscErrorCode  ierr;
2216 jroman 345
  PetscBool       isascii;
1993 eromero 346
  PetscInt        opi, opi0;
2216 jroman 347
  PetscBool       opb;
1993 eromero 348
  const char*     name;
349
 
350
  PetscFunctionBegin;
351
 
352
  name = ((PetscObject)eps)->type_name;
2215 jroman 353
  ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
1993 eromero 354
  if (!isascii) {
2214 jroman 355
    SETERRQ2(((PetscObject)eps)->comm,1,"Viewer type %s not supported for %s",((PetscObject)viewer)->type_name,name);
1993 eromero 356
  }
357
 
358
  ierr = EPSDAVIDSONGetBlockSize_DAVIDSON(eps, &opi); CHKERRQ(ierr);
359
  ierr = PetscViewerASCIIPrintf(viewer,"block size: %d\n", opi);CHKERRQ(ierr);
360
  ierr = EPSDAVIDSONGetKrylovStart_DAVIDSON(eps, &opb); CHKERRQ(ierr);
2177 jroman 361
  if(!opb) {
1993 eromero 362
    ierr = PetscViewerASCIIPrintf(viewer,"type of the initial subspace: non-Krylov\n");CHKERRQ(ierr);
363
  } else {
364
    ierr = PetscViewerASCIIPrintf(viewer,"type of the initial subspace: Krylov\n");CHKERRQ(ierr);
365
  }
366
  ierr = EPSDAVIDSONGetRestart_DAVIDSON(eps, &opi, &opi0); CHKERRQ(ierr);
367
  ierr = PetscViewerASCIIPrintf(viewer,"size of the subspace after restarting: %d\n", opi);CHKERRQ(ierr);
368
  ierr = PetscViewerASCIIPrintf(viewer,"number of vectors after restarting from the previous iteration: %d\n", opi0);CHKERRQ(ierr);
369
 
370
  PetscFunctionReturn(0);
371
}
372
 
373
 
1992 eromero 374
#undef __FUNCT__  
1976 eromero 375
#define __FUNCT__ "SLEPcNotImplemented"
376
PetscErrorCode SLEPcNotImplemented() {
2214 jroman 377
  SETERRQ(PETSC_COMM_WORLD,1, "Do not call this function!");
1619 slepc 378
}
379
 
2012 eromero 380
 
1619 slepc 381
#undef __FUNCT__  
1980 eromero 382
#define __FUNCT__ "EPSDAVIDSONSetKrylovStart_DAVIDSON"
2216 jroman 383
PetscErrorCode EPSDAVIDSONSetKrylovStart_DAVIDSON(EPS eps,PetscBool krylovstart)
1980 eromero 384
{
1985 eromero 385
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 386
 
387
  PetscFunctionBegin;
2213 jroman 388
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 389
 
390
  data->krylovstart = krylovstart;
391
 
1619 slepc 392
  PetscFunctionReturn(0);
393
}
394
 
1980 eromero 395
#undef __FUNCT__  
396
#define __FUNCT__ "EPSDAVIDSONGetKrylovStart_DAVIDSON"
2216 jroman 397
PetscErrorCode EPSDAVIDSONGetKrylovStart_DAVIDSON(EPS eps,PetscBool *krylovstart)
1980 eromero 398
{
1985 eromero 399
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 400
 
401
  PetscFunctionBegin;
2213 jroman 402
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 403
 
404
  *krylovstart = data->krylovstart;
405
 
406
  PetscFunctionReturn(0);
407
}
408
 
409
#undef __FUNCT__  
410
#define __FUNCT__ "EPSDAVIDSONSetBlockSize_DAVIDSON"
411
PetscErrorCode EPSDAVIDSONSetBlockSize_DAVIDSON(EPS eps,PetscInt blocksize)
412
{
1985 eromero 413
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 414
 
415
  PetscFunctionBegin;
2213 jroman 416
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 417
 
418
  if(blocksize == PETSC_DEFAULT || blocksize == PETSC_DECIDE) blocksize = 1;
419
  if(blocksize <= 0)
2214 jroman 420
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid blocksize value");
1980 eromero 421
  data->blocksize = blocksize;
422
 
423
  PetscFunctionReturn(0);
424
}
425
 
426
#undef __FUNCT__  
427
#define __FUNCT__ "EPSDAVIDSONGetBlockSize_DAVIDSON"
428
PetscErrorCode EPSDAVIDSONGetBlockSize_DAVIDSON(EPS eps,PetscInt *blocksize)
429
{
1985 eromero 430
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 431
 
432
  PetscFunctionBegin;
2213 jroman 433
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 434
 
435
  *blocksize = data->blocksize;
436
 
437
  PetscFunctionReturn(0);
438
}
439
 
440
#undef __FUNCT__  
441
#define __FUNCT__ "EPSDAVIDSONSetRestart_DAVIDSON"
442
PetscErrorCode EPSDAVIDSONSetRestart_DAVIDSON(EPS eps,PetscInt minv,PetscInt plusk)
443
{
1985 eromero 444
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 445
 
446
  PetscFunctionBegin;
2213 jroman 447
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 448
 
449
  if(minv == PETSC_DEFAULT || minv == PETSC_DECIDE) minv = 5;
450
  if(minv <= 0)
2214 jroman 451
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid minv value");
1980 eromero 452
  if(plusk == PETSC_DEFAULT || plusk == PETSC_DECIDE) plusk = 5;
1982 eromero 453
  if(plusk < 0)
2214 jroman 454
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid plusk value");
1980 eromero 455
  data->minv = minv;
456
  data->plusk = plusk;
457
 
458
  PetscFunctionReturn(0);
459
}
460
 
461
#undef __FUNCT__  
462
#define __FUNCT__ "EPSDAVIDSONGetRestart_DAVIDSON"
463
PetscErrorCode EPSDAVIDSONGetRestart_DAVIDSON(EPS eps,PetscInt *minv,PetscInt *plusk)
464
{
1985 eromero 465
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 466
 
467
  PetscFunctionBegin;
2213 jroman 468
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 469
 
470
  *minv = data->minv;
471
  *plusk = data->plusk;
472
 
473
  PetscFunctionReturn(0);
474
}
475
 
476
#undef __FUNCT__  
477
#define __FUNCT__ "EPSDAVIDSONGetInitialSize_DAVIDSON"
478
PetscErrorCode EPSDAVIDSONGetInitialSize_DAVIDSON(EPS eps,PetscInt *initialsize)
479
{
1985 eromero 480
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 481
 
482
  PetscFunctionBegin;
2213 jroman 483
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 484
 
485
  *initialsize = data->initialsize;
486
 
487
  PetscFunctionReturn(0);
488
}
489
 
490
#undef __FUNCT__  
491
#define __FUNCT__ "EPSDAVIDSONSetInitialSize_DAVIDSON"
492
PetscErrorCode EPSDAVIDSONSetInitialSize_DAVIDSON(EPS eps,PetscInt initialsize)
493
{
1985 eromero 494
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 495
 
496
  PetscFunctionBegin;
2213 jroman 497
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 498
 
499
  if(initialsize == PETSC_DEFAULT || initialsize == PETSC_DECIDE) initialsize = 5;
500
  if(initialsize <= 0)
2214 jroman 501
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid initial size value");
1980 eromero 502
  data->initialsize = initialsize;
503
 
504
  PetscFunctionReturn(0);
505
}
506
 
1995 eromero 507
#undef __FUNCT__  
508
#define __FUNCT__ "EPSDAVIDSONGetFix_DAVIDSON"
509
PetscErrorCode EPSDAVIDSONGetFix_DAVIDSON(EPS eps,PetscReal *fix)
510
{
511
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 512
 
1995 eromero 513
  PetscFunctionBegin;
2213 jroman 514
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1995 eromero 515
 
516
  *fix = data->fix;
517
 
518
  PetscFunctionReturn(0);
519
}
520
 
521
#undef __FUNCT__  
522
#define __FUNCT__ "EPSDAVIDSONSetFix_DAVIDSON"
523
PetscErrorCode EPSDAVIDSONSetFix_DAVIDSON(EPS eps,PetscReal fix)
524
{
525
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
526
 
527
  PetscFunctionBegin;
2213 jroman 528
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1995 eromero 529
 
530
  if(fix == PETSC_DEFAULT || fix == PETSC_DECIDE) fix = 0.01;
531
  if(fix < 0.0)
2214 jroman 532
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid fix value");
1995 eromero 533
  data->fix = fix;
534
 
535
  PetscFunctionReturn(0);
536
}
537
 
538
 
1619 slepc 539
#undef __FUNCT__  
1756 eromero 540
#define __FUNCT__ "EPSComputeVectors_QZ"
541
/*
542
  EPSComputeVectors_QZ - Compute eigenvectors from the vectors
543
  provided by the eigensolver. This version is intended for solvers
544
  that provide Schur vectors from the QZ decompositon. Given the partial
545
  Schur decomposition OP*V=V*T, the following steps are performed:
546
      1) compute eigenvectors of (S,T): S*Z=T*Z*D
547
      2) compute eigenvectors of OP: X=V*Z
548
  If left eigenvectors are required then also do Z'*Tl=D*Z', Y=W*Z
549
 */
550
PetscErrorCode EPSComputeVectors_QZ(EPS eps)
551
{
552
  PetscErrorCode  ierr;
1985 eromero 553
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1756 eromero 554
  dvdDashboard    *d = &data->ddb;
1968 eromero 555
  PetscScalar     *pX, *auxS;
556
  PetscInt        size_auxS;
2022 eromero 557
 
1756 eromero 558
  PetscFunctionBegin;
1619 slepc 559
 
1968 eromero 560
  /* Compute the eigenvectors associated to (cS, cT) */
561
  ierr = PetscMalloc(sizeof(PetscScalar)*d->nconv*d->nconv, &pX); CHKERRQ(ierr);
562
  size_auxS = 11*d->nconv + 4*d->nconv*d->nconv;
563
  ierr = PetscMalloc(sizeof(PetscScalar)*size_auxS, &auxS); CHKERRQ(ierr);
564
  ierr = dvd_compute_eigenvectors(d->nconv, d->cS, d->ldcS, d->cT, d->ldcT,
565
                                  pX, d->nconv, PETSC_NULL, 0, auxS,
566
                                  size_auxS, PETSC_FALSE); CHKERRQ(ierr);
1756 eromero 567
 
1762 eromero 568
  /* pX[i] <- pX[i] / ||pX[i]|| */
1968 eromero 569
  ierr = SlepcDenseNorm(pX, d->nconv, d->nconv, d->nconv, d->ceigi);
1965 eromero 570
  CHKERRQ(ierr);
1762 eromero 571
 
1756 eromero 572
  /* V <- cX * pX */
573
  ierr = SlepcUpdateVectorsZ(eps->V, 0.0, 1.0, d->cX, d->size_cX, pX,
574
                             d->nconv, d->nconv, d->nconv); CHKERRQ(ierr);
575
 
576
  ierr = PetscFree(pX); CHKERRQ(ierr);
577
  ierr = PetscFree(auxS); CHKERRQ(ierr);
578
 
579
  eps->evecsavailable = PETSC_TRUE;
580
 
581
  PetscFunctionReturn(0);
582
}