Subversion Repositories slepc-dev

Rev

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
 
28
#include "private/epsimpl.h"
29
#include "private/stimpl.h"
1985 eromero 30
#include "davidson.h"
1756 eromero 31
#include "slepcblaslapack.h"
1619 slepc 32
 
1993 eromero 33
PetscErrorCode EPSView_DAVIDSON(EPS eps,PetscViewer viewer);
34
 
1982 eromero 35
#undef __FUNCT__  
36
#define __FUNCT__ "EPSCreate_DAVIDSON"
37
PetscErrorCode EPSCreate_DAVIDSON(EPS eps) {
38
  PetscErrorCode  ierr;
1985 eromero 39
  EPS_DAVIDSON    *data;
1756 eromero 40
 
1982 eromero 41
  PetscFunctionBegin;
42
 
2000 eromero 43
  ierr = STSetType(eps->OP, STPRECOND); CHKERRQ(ierr);
2020 eromero 44
  ierr = STPrecondSetKSPHasMat(eps->OP, PETSC_FALSE); CHKERRQ(ierr);
1982 eromero 45
 
46
  eps->OP->ops->getbilinearform  = STGetBilinearForm_Default;
47
  eps->ops->solve                = EPSSolve_DAVIDSON;
48
  eps->ops->setup                = EPSSetUp_DAVIDSON;
1992 eromero 49
  eps->ops->destroy              = EPSDestroy_DAVIDSON;
1982 eromero 50
  eps->ops->backtransform        = EPSBackTransform_Default;
51
  eps->ops->computevectors       = EPSComputeVectors_QZ;
1993 eromero 52
  eps->ops->view                 = EPSView_DAVIDSON;
1982 eromero 53
 
1985 eromero 54
  ierr = PetscMalloc(sizeof(EPS_DAVIDSON), &data); CHKERRQ(ierr);
1982 eromero 55
  eps->data = data;
2017 eromero 56
  data->pc = 0;
1982 eromero 57
 
58
  /* Set default values */
59
  ierr = EPSDAVIDSONSetKrylovStart_DAVIDSON(eps, PETSC_FALSE); CHKERRQ(ierr);
60
  ierr = EPSDAVIDSONSetBlockSize_DAVIDSON(eps, 1); CHKERRQ(ierr);
61
  ierr = EPSDAVIDSONSetRestart_DAVIDSON(eps, 6, 0); CHKERRQ(ierr);
62
  ierr = EPSDAVIDSONSetInitialSize_DAVIDSON(eps, 5); CHKERRQ(ierr);
1995 eromero 63
  ierr = EPSDAVIDSONSetFix_DAVIDSON(eps, 0.01); CHKERRQ(ierr);
1982 eromero 64
 
2021 eromero 65
  ierr = dvd_prof_init(); CHKERRQ(ierr);
1982 eromero 66
 
67
  PetscFunctionReturn(0);
68
}
69
 
70
 
1619 slepc 71
#undef __FUNCT__  
1976 eromero 72
#define __FUNCT__ "EPSSetUp_DAVIDSON"
73
PetscErrorCode EPSSetUp_DAVIDSON(EPS eps) {
1619 slepc 74
  PetscErrorCode  ierr;
1985 eromero 75
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 76
  dvdDashboard    *dvd = &data->ddb;
77
  dvdBlackboard   b;
1998 eromero 78
  PetscInt        i,nvecs,nscalars,min_size_V,plusk,bs,initv;
1619 slepc 79
  Mat             A,B;
80
  KSP             ksp;
1867 eromero 81
  PC              pc, pc2;
2021 eromero 82
  PetscTruth      t,ipB,ispositive;
1976 eromero 83
  HarmType_t      harm;
84
  InitType_t      init;
1995 eromero 85
  PetscReal       fix;
1619 slepc 86
 
87
  PetscFunctionBegin;
88
 
89
  /* Setup EPS options and get the problem specification */
2023 eromero 90
  ierr = EPSDAVIDSONGetBlockSize_DAVIDSON(eps, &bs); CHKERRQ(ierr);
91
  if (bs <= 0) bs = 1;
1619 slepc 92
  if(eps->ncv) {
2023 eromero 93
    if (eps->ncv<eps->nev) SETERRQ(PETSC_ERR_SUP,"The value of ncv must be at least nev");
94
  } else if (eps->mpd) eps->ncv = eps->mpd + eps->nev + bs;
95
  else if (eps->nev<500)
96
    eps->ncv = PetscMin(eps->n,PetscMax(2*eps->nev,eps->nev+15))+bs;
97
  else
98
    eps->ncv = PetscMin(eps->n,eps->nev+500)+bs;
99
  if (!eps->mpd) eps->mpd = eps->ncv;
100
  if (eps->mpd > eps->ncv)
101
    SETERRQ(PETSC_ERR_SUP,"The mpd has to be less or equal than ncv");
102
  if (eps->mpd < 2)
103
    SETERRQ(PETSC_ERR_SUP,"The mpd has to be greater than 2");
1976 eromero 104
  if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
105
  if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
106
  if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY))
2023 eromero 107
    SETERRQ(PETSC_ERR_SUP,"Wrong value of eps->which");
108
  if (!(eps->nev + bs <= eps->ncv))
109
    SETERRQ(PETSC_ERR_SUP, "The ncv has to be greater than nev plus blocksize!");
1619 slepc 110
 
1980 eromero 111
  ierr = EPSDAVIDSONGetRestart_DAVIDSON(eps, &min_size_V, &plusk);
112
  CHKERRQ(ierr);
2023 eromero 113
  if (!min_size_V) min_size_V = PetscMin(PetscMax(bs,5), eps->mpd/2);
114
  if (!(min_size_V+bs <= eps->mpd))
115
    SETERRQ(PETSC_ERR_SUP, "The value of minv must be less than mpd minus blocksize");
1998 eromero 116
  ierr = EPSDAVIDSONGetInitialSize_DAVIDSON(eps, &initv); CHKERRQ(ierr);
2023 eromero 117
  if (eps->mpd < initv)
118
    SETERRQ(PETSC_ERR_SUP,"The initv has to be less or equal than mpd");
1619 slepc 119
 
2021 eromero 120
  /* Davidson solvers do not support left eigenvectors */
121
  if (eps->leftvecs) SETERRQ(PETSC_ERR_SUP,"Left vectors not supported in this solver");
122
 
2104 eromero 123
  /* Change the default sigma to inf if necessary */
124
  if (eps->which == EPS_LARGEST_MAGNITUDE || eps->which == EPS_LARGEST_REAL ||
125
      eps->which == EPS_LARGEST_IMAGINARY) {
126
    ierr = STSetDefaultShift(eps->OP, 3e300); CHKERRQ(ierr);
127
  }
128
 
1997 eromero 129
  /* Davidson solvers only support STPRECOND */
2003 eromero 130
  ierr = STSetUp(eps->OP); CHKERRQ(ierr);
1997 eromero 131
  ierr = PetscTypeCompare((PetscObject)eps->OP, STPRECOND, &t); CHKERRQ(ierr);
2177 jroman 132
  if (!t) SETERRQ1(PETSC_ERR_SUP, "%s only works with precond spectral transformation",
2003 eromero 133
    ((PetscObject)eps)->type_name);
2015 eromero 134
 
135
  /* Extract pc from st->ksp */
136
  if (data->pc) { ierr = PCDestroy(data->pc); CHKERRQ(ierr); data->pc = 0; }
1619 slepc 137
  ierr = STGetKSP(eps->OP, &ksp); CHKERRQ(ierr);
138
  ierr = KSPGetPC(ksp, &pc); CHKERRQ(ierr);
1680 slepc 139
  ierr = PetscTypeCompare((PetscObject)pc, PCNONE, &t); CHKERRQ(ierr);
2177 jroman 140
  if (t) {
1680 slepc 141
    pc = 0;
142
  } else {
2015 eromero 143
    ierr = PetscObjectReference((PetscObject)pc); CHKERRQ(ierr);
144
    data->pc = pc;
1872 eromero 145
    ierr = PCCreate(((PetscObject)eps)->comm, &pc2); CHKERRQ(ierr);
1867 eromero 146
    ierr = PCSetType(pc2, PCNONE); CHKERRQ(ierr);
1872 eromero 147
    ierr = KSPSetPC(ksp, pc2); CHKERRQ(ierr);
148
    ierr = PCDestroy(pc2); CHKERRQ(ierr);
1680 slepc 149
  }
1619 slepc 150
 
151
  /* Setup problem specification in dvd */
2015 eromero 152
  ierr = STGetOperators(eps->OP, &A, &B); CHKERRQ(ierr);
1619 slepc 153
  ierr = PetscMemzero(dvd, sizeof(dvdDashboard)); CHKERRQ(ierr);
2177 jroman 154
  dvd->A = A; dvd->B = eps->isgeneralized? B : PETSC_NULL;
2021 eromero 155
  ispositive = eps->ispositive;
1747 eromero 156
  dvd->sA = DVD_MAT_IMPLICIT |
2177 jroman 157
            (eps->ishermitian? DVD_MAT_HERMITIAN : 0) |
158
            ((ispositive && !eps->isgeneralized) ? DVD_MAT_POS_DEF : 0);
1764 eromero 159
  /* Asume -eps_hermitian means hermitian-definite in generalized problems */
2177 jroman 160
  if (!ispositive && !eps->isgeneralized && eps->ishermitian) ispositive = PETSC_TRUE;
161
  if (!eps->isgeneralized)
1747 eromero 162
    dvd->sB = DVD_MAT_IMPLICIT | DVD_MAT_HERMITIAN | DVD_MAT_IDENTITY |
1764 eromero 163
              DVD_MAT_UNITARY | DVD_MAT_POS_DEF;
1747 eromero 164
  else
165
    dvd->sB = DVD_MAT_IMPLICIT |
2177 jroman 166
              (eps->ishermitian? DVD_MAT_HERMITIAN : 0) |
167
              (ispositive? DVD_MAT_POS_DEF : 0);
1976 eromero 168
  ipB = DVD_IS(dvd->sB, DVD_MAT_POS_DEF)?PETSC_TRUE:PETSC_FALSE;
2177 jroman 169
  dvd->sEP = ((!eps->isgeneralized || (eps->isgeneralized && ipB))? DVD_EP_STD : 0) |
170
             (ispositive? DVD_EP_HERMITIAN : 0);
1619 slepc 171
  dvd->nev = eps->nev;
172
  dvd->which = eps->which;
1805 eromero 173
  switch(eps->which) {
174
  case EPS_TARGET_MAGNITUDE:
175
  case EPS_TARGET_REAL:
176
  case EPS_TARGET_IMAGINARY:
177
    dvd->withTarget = PETSC_TRUE;
1883 eromero 178
    dvd->target[0] = eps->target; dvd->target[1] = 1.0;
1805 eromero 179
    break;
1883 eromero 180
 
181
  case EPS_LARGEST_MAGNITUDE:
182
  case EPS_LARGEST_REAL:
183
  case EPS_LARGEST_IMAGINARY: //TODO: think about this case
1805 eromero 184
  default:
1984 eromero 185
    dvd->withTarget = PETSC_TRUE;
1883 eromero 186
    dvd->target[0] = 1.0; dvd->target[1] = 0.0;
187
    break;
188
 
189
  case EPS_SMALLEST_MAGNITUDE:
190
  case EPS_SMALLEST_REAL:
191
  case EPS_SMALLEST_IMAGINARY: //TODO: think about this case
1984 eromero 192
    dvd->withTarget = PETSC_TRUE;
1883 eromero 193
    dvd->target[0] = 0.0; dvd->target[1] = 1.0;
1805 eromero 194
  }
1619 slepc 195
  dvd->tol = eps->tol;
1805 eromero 196
  dvd->eps = eps;
1619 slepc 197
 
1976 eromero 198
  /* Setup the extraction technique */
199
  switch(eps->extraction) {
200
  case 0:
201
  case EPS_RITZ:              harm = DVD_HARM_NONE; break;
202
  case EPS_HARMONIC:          harm = DVD_HARM_RR; break;
203
  case EPS_HARMONIC_RELATIVE: harm = DVD_HARM_RRR; break;
204
  case EPS_HARMONIC_RIGHT:    harm = DVD_HARM_REIGS; break;
205
  case EPS_HARMONIC_LARGEST:  harm = DVD_HARM_LEIGS; break;
206
  default: SETERRQ(PETSC_ERR_SUP,"Unsupported extraction type");
207
  }
208
 
209
  /* Setup the type of starting subspace */
1980 eromero 210
  ierr = EPSDAVIDSONGetKrylovStart_DAVIDSON(eps, &t); CHKERRQ(ierr);
2177 jroman 211
  init = (!t)? DVD_INITV_CLASSIC : DVD_INITV_KRYLOV;
1976 eromero 212
 
1747 eromero 213
  /* Setup IP */
2177 jroman 214
  if (ipB && dvd->B) {
1975 eromero 215
    ierr = IPSetBilinearForm(eps->ip, dvd->B, IP_INNER_HERMITIAN); CHKERRQ(ierr);
1764 eromero 216
  } else {
1975 eromero 217
    ierr = IPSetBilinearForm(eps->ip, 0, IP_INNER_HERMITIAN); CHKERRQ(ierr);
1764 eromero 218
  }
1747 eromero 219
 
1995 eromero 220
  /* Get the fix parameter */
221
  ierr = EPSDAVIDSONGetFix_DAVIDSON(eps, &fix); CHKERRQ(ierr);
222
 
1989 eromero 223
  /* Orthonormalize the DS */
2188 eromero 224
  ierr = dvd_orthV(eps->ip, PETSC_NULL, 0, PETSC_NULL, 0, eps->DS, 0,
225
                   PetscAbs(eps->nds), PETSC_NULL, 0, eps->rand); CHKERRQ(ierr);
1989 eromero 226
 
1867 eromero 227
  /* Preconfigure dvd */
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),
1976 eromero 231
                                plusk, pc, 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,
257
                             PetscAbs(eps->nini), plusk, pc,
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
  KSP             ksp;
279
  PetscErrorCode  ierr;
1619 slepc 280
 
281
  PetscFunctionBegin;
282
 
1883 eromero 283
  /* Call the starting routines */
284
  DVD_FL_CALL(d->startList, d);
285
 
1619 slepc 286
  for(eps->its=0; eps->its < eps->max_it; eps->its++) {
1934 eromero 287
    /* Initialize V, if it is needed */
2021 eromero 288
    if (d->size_V == 0) { ierr = d->initV(d); CHKERRQ(ierr); }
1619 slepc 289
 
290
    /* Find the best approximated eigenpairs in V, X */
2021 eromero 291
    ierr = d->calcPairs(d); CHKERRQ(ierr);
1619 slepc 292
 
1934 eromero 293
    /* Expand the subspace */
2021 eromero 294
    ierr = d->updateV(d); CHKERRQ(ierr);
1619 slepc 295
 
1735 eromero 296
    /* Monitor progress */
1750 eromero 297
    eps->nconv = d->nconv;
1993 eromero 298
    EPSMonitor(eps, eps->its+1, eps->nconv, eps->eigr, eps->eigi, eps->errest, d->size_H+d->nconv);
1619 slepc 299
 
1735 eromero 300
    /* Test for convergence */
1750 eromero 301
    if (eps->nconv >= eps->nev) break;
1883 eromero 302
  }
1675 slepc 303
 
1883 eromero 304
  /* Call the ending routines */
305
  DVD_FL_CALL(d->endList, d);
1735 eromero 306
 
307
  if( eps->nconv >= eps->nev ) eps->reason = EPS_CONVERGED_TOL;
1619 slepc 308
  else eps->reason = EPS_DIVERGED_ITS;
309
 
2015 eromero 310
  /* Merge the pc extracted from st->ksp in EPSSetUp_DAVIDSON */
311
  if (data->pc) {
312
    ierr = STGetKSP(eps->OP, &ksp); CHKERRQ(ierr);
313
    ierr = KSPSetPC(ksp, data->pc); CHKERRQ(ierr);
314
    ierr = PCDestroy(data->pc); CHKERRQ(ierr);
315
    data->pc = 0;
316
  }
317
 
1619 slepc 318
  PetscFunctionReturn(0);
319
}
320
 
1992 eromero 321
 
1619 slepc 322
#undef __FUNCT__  
1992 eromero 323
#define __FUNCT__ "EPSDestroy_DAVIDSON"
324
PetscErrorCode EPSDestroy_DAVIDSON(EPS eps) {
325
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
326
  dvdDashboard    *dvd = &data->ddb;
327
  PetscErrorCode  ierr;
328
  PetscInt        i;
329
 
330
  PetscFunctionBegin;
331
 
332
  /* Call step destructors and destroys the list */
333
  DVD_FL_CALL(dvd->destroyList, dvd);
334
  DVD_FL_DEL(dvd->destroyList);
335
  DVD_FL_DEL(dvd->startList);
336
  DVD_FL_DEL(dvd->endList);
337
 
338
  for(i=0; i<data->size_wV; i++) {
339
    ierr = VecDestroy(data->wV[i]); CHKERRQ(ierr);
340
  }
341
  ierr = PetscFree(data->wV);
342
  ierr = PetscFree(data->wS);
343
  ierr = PetscFree(data); CHKERRQ(ierr);
344
 
345
  PetscFunctionReturn(0);
346
}
347
 
348
 
1993 eromero 349
#undef __FUNCT__  
350
#define __FUNCT__ "EPSView_DAVIDSON"
351
PetscErrorCode EPSView_DAVIDSON(EPS eps,PetscViewer viewer)
352
{
353
  PetscErrorCode  ierr;
354
  PetscTruth      isascii;
355
  PetscInt        opi, opi0;
356
  PetscTruth      opb;
357
  const char*     name;
358
 
359
  PetscFunctionBegin;
360
 
361
  name = ((PetscObject)eps)->type_name;
362
  ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
363
  if (!isascii) {
364
    SETERRQ2(1,"Viewer type %s not supported for %s",((PetscObject)viewer)->type_name,name);
365
  }
366
 
367
  ierr = EPSDAVIDSONGetBlockSize_DAVIDSON(eps, &opi); CHKERRQ(ierr);
368
  ierr = PetscViewerASCIIPrintf(viewer,"block size: %d\n", opi);CHKERRQ(ierr);
369
  ierr = EPSDAVIDSONGetKrylovStart_DAVIDSON(eps, &opb); CHKERRQ(ierr);
2177 jroman 370
  if(!opb) {
1993 eromero 371
    ierr = PetscViewerASCIIPrintf(viewer,"type of the initial subspace: non-Krylov\n");CHKERRQ(ierr);
372
  } else {
373
    ierr = PetscViewerASCIIPrintf(viewer,"type of the initial subspace: Krylov\n");CHKERRQ(ierr);
374
  }
375
  ierr = EPSDAVIDSONGetRestart_DAVIDSON(eps, &opi, &opi0); CHKERRQ(ierr);
376
  ierr = PetscViewerASCIIPrintf(viewer,"size of the subspace after restarting: %d\n", opi);CHKERRQ(ierr);
377
  ierr = PetscViewerASCIIPrintf(viewer,"number of vectors after restarting from the previous iteration: %d\n", opi0);CHKERRQ(ierr);
378
 
379
  PetscFunctionReturn(0);
380
}
381
 
382
 
1992 eromero 383
#undef __FUNCT__  
1976 eromero 384
#define __FUNCT__ "SLEPcNotImplemented"
385
PetscErrorCode SLEPcNotImplemented() {
1619 slepc 386
  SETERRQ(1, "Not call this function!");
387
}
388
 
2012 eromero 389
 
1619 slepc 390
#undef __FUNCT__  
1980 eromero 391
#define __FUNCT__ "EPSDAVIDSONSetKrylovStart_DAVIDSON"
392
PetscErrorCode EPSDAVIDSONSetKrylovStart_DAVIDSON(EPS eps,PetscTruth krylovstart)
393
{
1985 eromero 394
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 395
 
396
  PetscFunctionBegin;
1980 eromero 397
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
398
 
399
  data->krylovstart = krylovstart;
400
 
1619 slepc 401
  PetscFunctionReturn(0);
402
}
403
 
1980 eromero 404
#undef __FUNCT__  
405
#define __FUNCT__ "EPSDAVIDSONGetKrylovStart_DAVIDSON"
406
PetscErrorCode EPSDAVIDSONGetKrylovStart_DAVIDSON(EPS eps,PetscTruth *krylovstart)
407
{
1985 eromero 408
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 409
 
410
  PetscFunctionBegin;
411
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
412
 
413
  *krylovstart = data->krylovstart;
414
 
415
  PetscFunctionReturn(0);
416
}
417
 
418
#undef __FUNCT__  
419
#define __FUNCT__ "EPSDAVIDSONSetBlockSize_DAVIDSON"
420
PetscErrorCode EPSDAVIDSONSetBlockSize_DAVIDSON(EPS eps,PetscInt blocksize)
421
{
1985 eromero 422
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 423
 
424
  PetscFunctionBegin;
425
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
426
 
427
  if(blocksize == PETSC_DEFAULT || blocksize == PETSC_DECIDE) blocksize = 1;
428
  if(blocksize <= 0)
429
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid blocksize value");
430
  data->blocksize = blocksize;
431
 
432
  PetscFunctionReturn(0);
433
}
434
 
435
#undef __FUNCT__  
436
#define __FUNCT__ "EPSDAVIDSONGetBlockSize_DAVIDSON"
437
PetscErrorCode EPSDAVIDSONGetBlockSize_DAVIDSON(EPS eps,PetscInt *blocksize)
438
{
1985 eromero 439
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 440
 
441
  PetscFunctionBegin;
442
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
443
 
444
  *blocksize = data->blocksize;
445
 
446
  PetscFunctionReturn(0);
447
}
448
 
449
#undef __FUNCT__  
450
#define __FUNCT__ "EPSDAVIDSONSetRestart_DAVIDSON"
451
PetscErrorCode EPSDAVIDSONSetRestart_DAVIDSON(EPS eps,PetscInt minv,PetscInt plusk)
452
{
1985 eromero 453
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 454
 
455
  PetscFunctionBegin;
456
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
457
 
458
  if(minv == PETSC_DEFAULT || minv == PETSC_DECIDE) minv = 5;
459
  if(minv <= 0)
460
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid minv value");
461
  if(plusk == PETSC_DEFAULT || plusk == PETSC_DECIDE) plusk = 5;
1982 eromero 462
  if(plusk < 0)
1980 eromero 463
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid plusk value");
464
  data->minv = minv;
465
  data->plusk = plusk;
466
 
467
  PetscFunctionReturn(0);
468
}
469
 
470
#undef __FUNCT__  
471
#define __FUNCT__ "EPSDAVIDSONGetRestart_DAVIDSON"
472
PetscErrorCode EPSDAVIDSONGetRestart_DAVIDSON(EPS eps,PetscInt *minv,PetscInt *plusk)
473
{
1985 eromero 474
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 475
 
476
  PetscFunctionBegin;
477
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
478
 
479
  *minv = data->minv;
480
  *plusk = data->plusk;
481
 
482
  PetscFunctionReturn(0);
483
}
484
 
485
#undef __FUNCT__  
486
#define __FUNCT__ "EPSDAVIDSONGetInitialSize_DAVIDSON"
487
PetscErrorCode EPSDAVIDSONGetInitialSize_DAVIDSON(EPS eps,PetscInt *initialsize)
488
{
1985 eromero 489
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 490
 
491
  PetscFunctionBegin;
492
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
493
 
494
  *initialsize = data->initialsize;
495
 
496
  PetscFunctionReturn(0);
497
}
498
 
499
#undef __FUNCT__  
500
#define __FUNCT__ "EPSDAVIDSONSetInitialSize_DAVIDSON"
501
PetscErrorCode EPSDAVIDSONSetInitialSize_DAVIDSON(EPS eps,PetscInt initialsize)
502
{
1985 eromero 503
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 504
 
505
  PetscFunctionBegin;
506
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
507
 
508
  if(initialsize == PETSC_DEFAULT || initialsize == PETSC_DECIDE) initialsize = 5;
509
  if(initialsize <= 0)
1995 eromero 510
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid initial size value");
1980 eromero 511
  data->initialsize = initialsize;
512
 
513
  PetscFunctionReturn(0);
514
}
515
 
1995 eromero 516
#undef __FUNCT__  
517
#define __FUNCT__ "EPSDAVIDSONGetFix_DAVIDSON"
518
PetscErrorCode EPSDAVIDSONGetFix_DAVIDSON(EPS eps,PetscReal *fix)
519
{
520
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 521
 
1995 eromero 522
  PetscFunctionBegin;
523
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
524
 
525
  *fix = data->fix;
526
 
527
  PetscFunctionReturn(0);
528
}
529
 
530
#undef __FUNCT__  
531
#define __FUNCT__ "EPSDAVIDSONSetFix_DAVIDSON"
532
PetscErrorCode EPSDAVIDSONSetFix_DAVIDSON(EPS eps,PetscReal fix)
533
{
534
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
535
 
536
  PetscFunctionBegin;
537
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
538
 
539
  if(fix == PETSC_DEFAULT || fix == PETSC_DECIDE) fix = 0.01;
540
  if(fix < 0.0)
541
    SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Invalid fix value");
542
  data->fix = fix;
543
 
544
  PetscFunctionReturn(0);
545
}
546
 
547
 
1619 slepc 548
#undef __FUNCT__  
1756 eromero 549
#define __FUNCT__ "EPSComputeVectors_QZ"
550
/*
551
  EPSComputeVectors_QZ - Compute eigenvectors from the vectors
552
  provided by the eigensolver. This version is intended for solvers
553
  that provide Schur vectors from the QZ decompositon. Given the partial
554
  Schur decomposition OP*V=V*T, the following steps are performed:
555
      1) compute eigenvectors of (S,T): S*Z=T*Z*D
556
      2) compute eigenvectors of OP: X=V*Z
557
  If left eigenvectors are required then also do Z'*Tl=D*Z', Y=W*Z
558
 */
559
PetscErrorCode EPSComputeVectors_QZ(EPS eps)
560
{
561
  PetscErrorCode  ierr;
1985 eromero 562
  EPS_DAVIDSON    *data = (EPS_DAVIDSON*)eps->data;
1756 eromero 563
  dvdDashboard    *d = &data->ddb;
1968 eromero 564
  PetscScalar     *pX, *auxS;
565
  PetscInt        size_auxS;
2022 eromero 566
 
1756 eromero 567
  PetscFunctionBegin;
1619 slepc 568
 
1968 eromero 569
  /* Compute the eigenvectors associated to (cS, cT) */
570
  ierr = PetscMalloc(sizeof(PetscScalar)*d->nconv*d->nconv, &pX); CHKERRQ(ierr);
571
  size_auxS = 11*d->nconv + 4*d->nconv*d->nconv;
572
  ierr = PetscMalloc(sizeof(PetscScalar)*size_auxS, &auxS); CHKERRQ(ierr);
573
  ierr = dvd_compute_eigenvectors(d->nconv, d->cS, d->ldcS, d->cT, d->ldcT,
574
                                  pX, d->nconv, PETSC_NULL, 0, auxS,
575
                                  size_auxS, PETSC_FALSE); CHKERRQ(ierr);
1756 eromero 576
 
1762 eromero 577
  /* pX[i] <- pX[i] / ||pX[i]|| */
1968 eromero 578
  ierr = SlepcDenseNorm(pX, d->nconv, d->nconv, d->nconv, d->ceigi);
1965 eromero 579
  CHKERRQ(ierr);
1762 eromero 580
 
1756 eromero 581
  /* V <- cX * pX */
582
  ierr = SlepcUpdateVectorsZ(eps->V, 0.0, 1.0, d->cX, d->size_cX, pX,
583
                             d->nconv, d->nconv, d->nconv); CHKERRQ(ierr);
584
 
585
  ierr = PetscFree(pX); CHKERRQ(ierr);
586
  ierr = PetscFree(auxS); CHKERRQ(ierr);
587
 
588
  eps->evecsavailable = PETSC_TRUE;
589
 
590
  PetscFunctionReturn(0);
591
}