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
 
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"
2317 jroman 54
PetscErrorCode EPSCreate_DAVIDSON(EPS eps)
55
{
56
  PetscErrorCode ierr;
57
  EPS_DAVIDSON   *data;
1756 eromero 58
 
1982 eromero 59
  PetscFunctionBegin;
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
  PetscFunctionReturn(0);
81
}
82
 
1619 slepc 83
#undef __FUNCT__  
1976 eromero 84
#define __FUNCT__ "EPSSetUp_DAVIDSON"
2317 jroman 85
PetscErrorCode EPSSetUp_DAVIDSON(EPS eps)
86
{
87
  PetscErrorCode ierr;
88
  EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
89
  dvdDashboard   *dvd = &data->ddb;
90
  dvdBlackboard  b;
91
  PetscInt       i,nvecs,nscalars,min_size_V,plusk,bs,initv;
92
  Mat            A,B;
93
  KSP            ksp;
94
  PetscBool      t,ipB,ispositive;
95
  HarmType_t     harm;
96
  InitType_t     init;
97
  PetscReal      fix;
1619 slepc 98
 
99
  PetscFunctionBegin;
100
  /* Setup EPS options and get the problem specification */
2023 eromero 101
  ierr = EPSDAVIDSONGetBlockSize_DAVIDSON(eps, &bs); CHKERRQ(ierr);
102
  if (bs <= 0) bs = 1;
1619 slepc 103
  if(eps->ncv) {
2214 jroman 104
    if (eps->ncv<eps->nev) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The value of ncv must be at least nev");
2023 eromero 105
  } else if (eps->mpd) eps->ncv = eps->mpd + eps->nev + bs;
106
  else if (eps->nev<500)
107
    eps->ncv = PetscMin(eps->n,PetscMax(2*eps->nev,eps->nev+15))+bs;
108
  else
109
    eps->ncv = PetscMin(eps->n,eps->nev+500)+bs;
110
  if (!eps->mpd) eps->mpd = eps->ncv;
111
  if (eps->mpd > eps->ncv)
2214 jroman 112
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The mpd has to be less or equal than ncv");
2023 eromero 113
  if (eps->mpd < 2)
2214 jroman 114
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The mpd has to be greater than 2");
1976 eromero 115
  if (!eps->max_it) eps->max_it = PetscMax(100,2*eps->n/eps->ncv);
116
  if (!eps->which) eps->which = EPS_LARGEST_MAGNITUDE;
117
  if (eps->ishermitian && (eps->which==EPS_LARGEST_IMAGINARY || eps->which==EPS_SMALLEST_IMAGINARY))
2214 jroman 118
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Wrong value of eps->which");
2023 eromero 119
  if (!(eps->nev + bs <= eps->ncv))
2214 jroman 120
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP, "The ncv has to be greater than nev plus blocksize!");
1619 slepc 121
 
1980 eromero 122
  ierr = EPSDAVIDSONGetRestart_DAVIDSON(eps, &min_size_V, &plusk);
123
  CHKERRQ(ierr);
2023 eromero 124
  if (!min_size_V) min_size_V = PetscMin(PetscMax(bs,5), eps->mpd/2);
125
  if (!(min_size_V+bs <= eps->mpd))
2214 jroman 126
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP, "The value of minv must be less than mpd minus blocksize");
1998 eromero 127
  ierr = EPSDAVIDSONGetInitialSize_DAVIDSON(eps, &initv); CHKERRQ(ierr);
2023 eromero 128
  if (eps->mpd < initv)
2214 jroman 129
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"The initv has to be less or equal than mpd");
1619 slepc 130
 
2021 eromero 131
  /* Davidson solvers do not support left eigenvectors */
2214 jroman 132
  if (eps->leftvecs) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Left vectors not supported in this solver");
2021 eromero 133
 
2104 eromero 134
  /* Change the default sigma to inf if necessary */
135
  if (eps->which == EPS_LARGEST_MAGNITUDE || eps->which == EPS_LARGEST_REAL ||
136
      eps->which == EPS_LARGEST_IMAGINARY) {
137
    ierr = STSetDefaultShift(eps->OP, 3e300); CHKERRQ(ierr);
138
  }
139
 
1997 eromero 140
  /* Davidson solvers only support STPRECOND */
2003 eromero 141
  ierr = STSetUp(eps->OP); CHKERRQ(ierr);
1997 eromero 142
  ierr = PetscTypeCompare((PetscObject)eps->OP, STPRECOND, &t); CHKERRQ(ierr);
2214 jroman 143
  if (!t) SETERRQ1(((PetscObject)eps)->comm,PETSC_ERR_SUP, "%s only works with precond spectral transformation",
2003 eromero 144
    ((PetscObject)eps)->type_name);
2015 eromero 145
 
1619 slepc 146
  /* Setup problem specification in dvd */
2015 eromero 147
  ierr = STGetOperators(eps->OP, &A, &B); CHKERRQ(ierr);
1619 slepc 148
  ierr = PetscMemzero(dvd, sizeof(dvdDashboard)); CHKERRQ(ierr);
2177 jroman 149
  dvd->A = A; dvd->B = eps->isgeneralized? B : PETSC_NULL;
2021 eromero 150
  ispositive = eps->ispositive;
1747 eromero 151
  dvd->sA = DVD_MAT_IMPLICIT |
2177 jroman 152
            (eps->ishermitian? DVD_MAT_HERMITIAN : 0) |
2316 jroman 153
            ((ispositive && !eps->isgeneralized) ? DVD_MAT_POS_DEF : 0);
1764 eromero 154
  /* Asume -eps_hermitian means hermitian-definite in generalized problems */
2177 jroman 155
  if (!ispositive && !eps->isgeneralized && eps->ishermitian) ispositive = PETSC_TRUE;
156
  if (!eps->isgeneralized)
1747 eromero 157
    dvd->sB = DVD_MAT_IMPLICIT | DVD_MAT_HERMITIAN | DVD_MAT_IDENTITY |
1764 eromero 158
              DVD_MAT_UNITARY | DVD_MAT_POS_DEF;
1747 eromero 159
  else
160
    dvd->sB = DVD_MAT_IMPLICIT |
2177 jroman 161
              (eps->ishermitian? DVD_MAT_HERMITIAN : 0) |
162
              (ispositive? DVD_MAT_POS_DEF : 0);
1976 eromero 163
  ipB = DVD_IS(dvd->sB, DVD_MAT_POS_DEF)?PETSC_TRUE:PETSC_FALSE;
2177 jroman 164
  dvd->sEP = ((!eps->isgeneralized || (eps->isgeneralized && ipB))? DVD_EP_STD : 0) |
2316 jroman 165
             (ispositive? DVD_EP_HERMITIAN : 0);
1619 slepc 166
  dvd->nev = eps->nev;
167
  dvd->which = eps->which;
1805 eromero 168
  switch(eps->which) {
169
  case EPS_TARGET_MAGNITUDE:
170
  case EPS_TARGET_REAL:
171
  case EPS_TARGET_IMAGINARY:
172
    dvd->withTarget = PETSC_TRUE;
1883 eromero 173
    dvd->target[0] = eps->target; dvd->target[1] = 1.0;
1805 eromero 174
    break;
1883 eromero 175
 
176
  case EPS_LARGEST_MAGNITUDE:
177
  case EPS_LARGEST_REAL:
178
  case EPS_LARGEST_IMAGINARY: //TODO: think about this case
1805 eromero 179
  default:
1984 eromero 180
    dvd->withTarget = PETSC_TRUE;
1883 eromero 181
    dvd->target[0] = 1.0; dvd->target[1] = 0.0;
182
    break;
183
 
184
  case EPS_SMALLEST_MAGNITUDE:
185
  case EPS_SMALLEST_REAL:
186
  case EPS_SMALLEST_IMAGINARY: //TODO: think about this case
1984 eromero 187
    dvd->withTarget = PETSC_TRUE;
1883 eromero 188
    dvd->target[0] = 0.0; dvd->target[1] = 1.0;
1805 eromero 189
  }
1619 slepc 190
  dvd->tol = eps->tol;
1805 eromero 191
  dvd->eps = eps;
1619 slepc 192
 
1976 eromero 193
  /* Setup the extraction technique */
2231 jroman 194
  if (!eps->extraction) {
195
    ierr = EPSSetExtraction(eps,EPS_RITZ);CHKERRQ(ierr);
196
  }
1976 eromero 197
  switch(eps->extraction) {
198
  case EPS_RITZ:              harm = DVD_HARM_NONE; break;
199
  case EPS_HARMONIC:          harm = DVD_HARM_RR; break;
200
  case EPS_HARMONIC_RELATIVE: harm = DVD_HARM_RRR; break;
201
  case EPS_HARMONIC_RIGHT:    harm = DVD_HARM_REIGS; break;
202
  case EPS_HARMONIC_LARGEST:  harm = DVD_HARM_LEIGS; break;
2214 jroman 203
  default: SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Unsupported extraction type");
1976 eromero 204
  }
205
 
206
  /* Setup the type of starting subspace */
1980 eromero 207
  ierr = EPSDAVIDSONGetKrylovStart_DAVIDSON(eps, &t); CHKERRQ(ierr);
2177 jroman 208
  init = (!t)? DVD_INITV_CLASSIC : DVD_INITV_KRYLOV;
1976 eromero 209
 
1747 eromero 210
  /* Setup IP */
2177 jroman 211
  if (ipB && dvd->B) {
1975 eromero 212
    ierr = IPSetBilinearForm(eps->ip, dvd->B, IP_INNER_HERMITIAN); CHKERRQ(ierr);
1764 eromero 213
  } else {
1975 eromero 214
    ierr = IPSetBilinearForm(eps->ip, 0, IP_INNER_HERMITIAN); CHKERRQ(ierr);
1764 eromero 215
  }
1747 eromero 216
 
1995 eromero 217
  /* Get the fix parameter */
218
  ierr = EPSDAVIDSONGetFix_DAVIDSON(eps, &fix); CHKERRQ(ierr);
219
 
1989 eromero 220
  /* Orthonormalize the DS */
2188 eromero 221
  ierr = dvd_orthV(eps->ip, PETSC_NULL, 0, PETSC_NULL, 0, eps->DS, 0,
222
                   PetscAbs(eps->nds), PETSC_NULL, 0, eps->rand); CHKERRQ(ierr);
1989 eromero 223
 
1867 eromero 224
  /* Preconfigure dvd */
2244 eromero 225
  ierr = STGetKSP(eps->OP, &ksp); CHKERRQ(ierr);
2023 eromero 226
  ierr = dvd_schm_basic_preconf(dvd, &b, eps->ncv, eps->mpd, min_size_V, bs,
2188 eromero 227
                                initv,
228
                                PetscAbs(eps->nini),
2244 eromero 229
                                plusk, harm,
2317 jroman 230
                                PETSC_NULL, init, eps->trackall);CHKERRQ(ierr);
1619 slepc 231
 
232
  /* Reserve memory */
233
  nvecs = b.max_size_auxV + b.own_vecs;
234
  nscalars = b.own_scalars + b.max_size_auxS;
1975 eromero 235
  ierr = PetscMalloc((nvecs*eps->nloc+nscalars)*sizeof(PetscScalar), &data->wS);
1619 slepc 236
  CHKERRQ(ierr);
237
  ierr = PetscMalloc(nvecs*sizeof(Vec), &data->wV); CHKERRQ(ierr);
1992 eromero 238
  data->size_wV = nvecs;
1619 slepc 239
  for (i=0; i<nvecs; i++) {
1975 eromero 240
    ierr = VecCreateMPIWithArray(((PetscObject)eps)->comm, eps->nloc, PETSC_DECIDE,
2317 jroman 241
                                 data->wS+i*eps->nloc, &data->wV[i]);CHKERRQ(ierr);
1619 slepc 242
  }
243
  b.free_vecs = data->wV;
1975 eromero 244
  b.free_scalars = data->wS + nvecs*eps->nloc;
1619 slepc 245
  dvd->auxV = data->wV + b.own_vecs;
246
  dvd->auxS = b.free_scalars + b.own_scalars;
247
  dvd->size_auxV = b.max_size_auxV;
248
  dvd->size_auxS = b.max_size_auxS;
1805 eromero 249
 
1619 slepc 250
  /* Configure dvd for a basic GD */
2023 eromero 251
  ierr = dvd_schm_basic_conf(dvd, &b, eps->ncv, eps->mpd, min_size_V, bs,
2188 eromero 252
                             initv,
2244 eromero 253
                             PetscAbs(eps->nini), plusk,
1976 eromero 254
                             eps->ip, harm, dvd->withTarget,
1980 eromero 255
                             eps->target, ksp,
2317 jroman 256
                             fix, init, eps->trackall);CHKERRQ(ierr);
1795 eromero 257
 
1619 slepc 258
  /* Associate the eigenvalues to the EPS */
259
  eps->eigr = dvd->eigr;
260
  eps->eigi = dvd->eigi;
261
  eps->errest = dvd->errest;
1743 eromero 262
  eps->V = dvd->V;
1619 slepc 263
  PetscFunctionReturn(0);
264
}
265
 
266
#undef __FUNCT__  
1976 eromero 267
#define __FUNCT__ "EPSSolve_DAVIDSON"
2317 jroman 268
PetscErrorCode EPSSolve_DAVIDSON(EPS eps)
269
{
270
  EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
271
  dvdDashboard   *d = &data->ddb;
272
  PetscErrorCode ierr;
1619 slepc 273
 
274
  PetscFunctionBegin;
1883 eromero 275
  /* Call the starting routines */
276
  DVD_FL_CALL(d->startList, d);
277
 
1619 slepc 278
  for(eps->its=0; eps->its < eps->max_it; eps->its++) {
1934 eromero 279
    /* Initialize V, if it is needed */
2021 eromero 280
    if (d->size_V == 0) { ierr = d->initV(d); CHKERRQ(ierr); }
1619 slepc 281
 
282
    /* Find the best approximated eigenpairs in V, X */
2021 eromero 283
    ierr = d->calcPairs(d); CHKERRQ(ierr);
1619 slepc 284
 
1934 eromero 285
    /* Expand the subspace */
2021 eromero 286
    ierr = d->updateV(d); CHKERRQ(ierr);
1619 slepc 287
 
1735 eromero 288
    /* Monitor progress */
1750 eromero 289
    eps->nconv = d->nconv;
2313 jroman 290
    ierr = EPSMonitor(eps, eps->its+1, eps->nconv, eps->eigr, eps->eigi, eps->errest, d->size_H+d->nconv);CHKERRQ(ierr);
1619 slepc 291
 
1735 eromero 292
    /* Test for convergence */
1750 eromero 293
    if (eps->nconv >= eps->nev) break;
1883 eromero 294
  }
1675 slepc 295
 
1883 eromero 296
  /* Call the ending routines */
297
  DVD_FL_CALL(d->endList, d);
1735 eromero 298
 
299
  if( eps->nconv >= eps->nev ) eps->reason = EPS_CONVERGED_TOL;
1619 slepc 300
  else eps->reason = EPS_DIVERGED_ITS;
301
  PetscFunctionReturn(0);
302
}
303
 
304
#undef __FUNCT__  
1992 eromero 305
#define __FUNCT__ "EPSDestroy_DAVIDSON"
2317 jroman 306
PetscErrorCode EPSDestroy_DAVIDSON(EPS eps)
307
{
308
  EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
309
  dvdDashboard   *dvd = &data->ddb;
310
  PetscErrorCode ierr;
311
  PetscInt       i;
1992 eromero 312
 
313
  PetscFunctionBegin;
314
  /* Call step destructors and destroys the list */
315
  DVD_FL_CALL(dvd->destroyList, dvd);
316
  DVD_FL_DEL(dvd->destroyList);
317
  DVD_FL_DEL(dvd->startList);
318
  DVD_FL_DEL(dvd->endList);
319
 
320
  for(i=0; i<data->size_wV; i++) {
2305 jroman 321
    ierr = VecDestroy(&data->wV[i]); CHKERRQ(ierr);
1992 eromero 322
  }
2307 jroman 323
  ierr = PetscFree(data->wV);CHKERRQ(ierr);
324
  ierr = PetscFree(data->wS);CHKERRQ(ierr);
325
  ierr = PetscFree(data);CHKERRQ(ierr);
1992 eromero 326
  PetscFunctionReturn(0);
327
}
328
 
1993 eromero 329
#undef __FUNCT__  
330
#define __FUNCT__ "EPSView_DAVIDSON"
331
PetscErrorCode EPSView_DAVIDSON(EPS eps,PetscViewer viewer)
332
{
2317 jroman 333
  PetscErrorCode ierr;
334
  PetscBool      isascii, opb;
335
  PetscInt       opi, opi0;
336
  const char*    name;
1993 eromero 337
 
338
  PetscFunctionBegin;
339
  name = ((PetscObject)eps)->type_name;
2215 jroman 340
  ierr = PetscTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isascii);CHKERRQ(ierr);
1993 eromero 341
  if (!isascii) {
2214 jroman 342
    SETERRQ2(((PetscObject)eps)->comm,1,"Viewer type %s not supported for %s",((PetscObject)viewer)->type_name,name);
1993 eromero 343
  }
344
 
345
  ierr = EPSDAVIDSONGetBlockSize_DAVIDSON(eps, &opi); CHKERRQ(ierr);
346
  ierr = PetscViewerASCIIPrintf(viewer,"block size: %d\n", opi);CHKERRQ(ierr);
347
  ierr = EPSDAVIDSONGetKrylovStart_DAVIDSON(eps, &opb); CHKERRQ(ierr);
2177 jroman 348
  if(!opb) {
1993 eromero 349
    ierr = PetscViewerASCIIPrintf(viewer,"type of the initial subspace: non-Krylov\n");CHKERRQ(ierr);
350
  } else {
351
    ierr = PetscViewerASCIIPrintf(viewer,"type of the initial subspace: Krylov\n");CHKERRQ(ierr);
352
  }
353
  ierr = EPSDAVIDSONGetRestart_DAVIDSON(eps, &opi, &opi0); CHKERRQ(ierr);
354
  ierr = PetscViewerASCIIPrintf(viewer,"size of the subspace after restarting: %d\n", opi);CHKERRQ(ierr);
355
  ierr = PetscViewerASCIIPrintf(viewer,"number of vectors after restarting from the previous iteration: %d\n", opi0);CHKERRQ(ierr);
356
  PetscFunctionReturn(0);
357
}
358
 
1992 eromero 359
#undef __FUNCT__  
1980 eromero 360
#define __FUNCT__ "EPSDAVIDSONSetKrylovStart_DAVIDSON"
2216 jroman 361
PetscErrorCode EPSDAVIDSONSetKrylovStart_DAVIDSON(EPS eps,PetscBool krylovstart)
1980 eromero 362
{
2317 jroman 363
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 364
 
365
  PetscFunctionBegin;
2213 jroman 366
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 367
  data->krylovstart = krylovstart;
1619 slepc 368
  PetscFunctionReturn(0);
369
}
370
 
1980 eromero 371
#undef __FUNCT__  
372
#define __FUNCT__ "EPSDAVIDSONGetKrylovStart_DAVIDSON"
2216 jroman 373
PetscErrorCode EPSDAVIDSONGetKrylovStart_DAVIDSON(EPS eps,PetscBool *krylovstart)
1980 eromero 374
{
2317 jroman 375
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 376
 
377
  PetscFunctionBegin;
2213 jroman 378
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 379
  *krylovstart = data->krylovstart;
380
  PetscFunctionReturn(0);
381
}
382
 
383
#undef __FUNCT__  
384
#define __FUNCT__ "EPSDAVIDSONSetBlockSize_DAVIDSON"
385
PetscErrorCode EPSDAVIDSONSetBlockSize_DAVIDSON(EPS eps,PetscInt blocksize)
386
{
2317 jroman 387
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 388
 
389
  PetscFunctionBegin;
2213 jroman 390
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 391
  if(blocksize == PETSC_DEFAULT || blocksize == PETSC_DECIDE) blocksize = 1;
392
  if(blocksize <= 0)
2214 jroman 393
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid blocksize value");
1980 eromero 394
  data->blocksize = blocksize;
395
  PetscFunctionReturn(0);
396
}
397
 
398
#undef __FUNCT__  
399
#define __FUNCT__ "EPSDAVIDSONGetBlockSize_DAVIDSON"
400
PetscErrorCode EPSDAVIDSONGetBlockSize_DAVIDSON(EPS eps,PetscInt *blocksize)
401
{
2317 jroman 402
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 403
 
404
  PetscFunctionBegin;
2213 jroman 405
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 406
  *blocksize = data->blocksize;
407
  PetscFunctionReturn(0);
408
}
409
 
410
#undef __FUNCT__  
411
#define __FUNCT__ "EPSDAVIDSONSetRestart_DAVIDSON"
412
PetscErrorCode EPSDAVIDSONSetRestart_DAVIDSON(EPS eps,PetscInt minv,PetscInt plusk)
413
{
2317 jroman 414
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 415
 
416
  PetscFunctionBegin;
2213 jroman 417
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 418
  if(minv == PETSC_DEFAULT || minv == PETSC_DECIDE) minv = 5;
419
  if(minv <= 0)
2214 jroman 420
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid minv value");
1980 eromero 421
  if(plusk == PETSC_DEFAULT || plusk == PETSC_DECIDE) plusk = 5;
1982 eromero 422
  if(plusk < 0)
2214 jroman 423
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid plusk value");
1980 eromero 424
  data->minv = minv;
425
  data->plusk = plusk;
426
  PetscFunctionReturn(0);
427
}
428
 
429
#undef __FUNCT__  
430
#define __FUNCT__ "EPSDAVIDSONGetRestart_DAVIDSON"
431
PetscErrorCode EPSDAVIDSONGetRestart_DAVIDSON(EPS eps,PetscInt *minv,PetscInt *plusk)
432
{
2317 jroman 433
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 434
 
435
  PetscFunctionBegin;
2213 jroman 436
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 437
  *minv = data->minv;
438
  *plusk = data->plusk;
439
  PetscFunctionReturn(0);
440
}
441
 
442
#undef __FUNCT__  
443
#define __FUNCT__ "EPSDAVIDSONGetInitialSize_DAVIDSON"
444
PetscErrorCode EPSDAVIDSONGetInitialSize_DAVIDSON(EPS eps,PetscInt *initialsize)
445
{
2317 jroman 446
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 447
 
448
  PetscFunctionBegin;
2213 jroman 449
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 450
  *initialsize = data->initialsize;
451
  PetscFunctionReturn(0);
452
}
453
 
454
#undef __FUNCT__  
455
#define __FUNCT__ "EPSDAVIDSONSetInitialSize_DAVIDSON"
456
PetscErrorCode EPSDAVIDSONSetInitialSize_DAVIDSON(EPS eps,PetscInt initialsize)
457
{
2317 jroman 458
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 459
 
460
  PetscFunctionBegin;
2213 jroman 461
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 462
  if(initialsize == PETSC_DEFAULT || initialsize == PETSC_DECIDE) initialsize = 5;
463
  if(initialsize <= 0)
2214 jroman 464
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid initial size value");
1980 eromero 465
  data->initialsize = initialsize;
466
  PetscFunctionReturn(0);
467
}
468
 
1995 eromero 469
#undef __FUNCT__  
470
#define __FUNCT__ "EPSDAVIDSONGetFix_DAVIDSON"
471
PetscErrorCode EPSDAVIDSONGetFix_DAVIDSON(EPS eps,PetscReal *fix)
472
{
2317 jroman 473
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 474
 
1995 eromero 475
  PetscFunctionBegin;
2213 jroman 476
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1995 eromero 477
  *fix = data->fix;
478
  PetscFunctionReturn(0);
479
}
480
 
481
#undef __FUNCT__  
482
#define __FUNCT__ "EPSDAVIDSONSetFix_DAVIDSON"
483
PetscErrorCode EPSDAVIDSONSetFix_DAVIDSON(EPS eps,PetscReal fix)
484
{
2317 jroman 485
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1995 eromero 486
 
487
  PetscFunctionBegin;
2213 jroman 488
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1995 eromero 489
  if(fix == PETSC_DEFAULT || fix == PETSC_DECIDE) fix = 0.01;
490
  if(fix < 0.0)
2214 jroman 491
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid fix value");
1995 eromero 492
  data->fix = fix;
493
  PetscFunctionReturn(0);
494
}
495
 
1619 slepc 496
#undef __FUNCT__  
1756 eromero 497
#define __FUNCT__ "EPSComputeVectors_QZ"
498
/*
499
  EPSComputeVectors_QZ - Compute eigenvectors from the vectors
500
  provided by the eigensolver. This version is intended for solvers
501
  that provide Schur vectors from the QZ decompositon. Given the partial
502
  Schur decomposition OP*V=V*T, the following steps are performed:
503
      1) compute eigenvectors of (S,T): S*Z=T*Z*D
504
      2) compute eigenvectors of OP: X=V*Z
505
  If left eigenvectors are required then also do Z'*Tl=D*Z', Y=W*Z
506
 */
507
PetscErrorCode EPSComputeVectors_QZ(EPS eps)
508
{
2317 jroman 509
  PetscErrorCode ierr;
510
  EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
511
  dvdDashboard   *d = &data->ddb;
512
  PetscScalar    *pX, *auxS;
513
  PetscInt       size_auxS;
2022 eromero 514
 
1756 eromero 515
  PetscFunctionBegin;
1968 eromero 516
  /* Compute the eigenvectors associated to (cS, cT) */
517
  ierr = PetscMalloc(sizeof(PetscScalar)*d->nconv*d->nconv, &pX); CHKERRQ(ierr);
518
  size_auxS = 11*d->nconv + 4*d->nconv*d->nconv;
519
  ierr = PetscMalloc(sizeof(PetscScalar)*size_auxS, &auxS); CHKERRQ(ierr);
520
  ierr = dvd_compute_eigenvectors(d->nconv, d->cS, d->ldcS, d->cT, d->ldcT,
521
                                  pX, d->nconv, PETSC_NULL, 0, auxS,
522
                                  size_auxS, PETSC_FALSE); CHKERRQ(ierr);
1756 eromero 523
 
1762 eromero 524
  /* pX[i] <- pX[i] / ||pX[i]|| */
2317 jroman 525
  ierr = SlepcDenseNorm(pX, d->nconv, d->nconv, d->nconv, d->ceigi);CHKERRQ(ierr);
1762 eromero 526
 
1756 eromero 527
  /* V <- cX * pX */
528
  ierr = SlepcUpdateVectorsZ(eps->V, 0.0, 1.0, d->cX, d->size_cX, pX,
529
                             d->nconv, d->nconv, d->nconv); CHKERRQ(ierr);
530
 
531
  ierr = PetscFree(pX); CHKERRQ(ierr);
532
  ierr = PetscFree(auxS); CHKERRQ(ierr);
533
 
534
  eps->evecsavailable = PETSC_TRUE;
535
  PetscFunctionReturn(0);
536
}