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"
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__  
1976 eromero 360
#define __FUNCT__ "SLEPcNotImplemented"
2317 jroman 361
PetscErrorCode SLEPcNotImplemented()
362
{
2214 jroman 363
  SETERRQ(PETSC_COMM_WORLD,1, "Do not call this function!");
1619 slepc 364
}
365
 
366
#undef __FUNCT__  
1980 eromero 367
#define __FUNCT__ "EPSDAVIDSONSetKrylovStart_DAVIDSON"
2216 jroman 368
PetscErrorCode EPSDAVIDSONSetKrylovStart_DAVIDSON(EPS eps,PetscBool krylovstart)
1980 eromero 369
{
2317 jroman 370
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1619 slepc 371
 
372
  PetscFunctionBegin;
2213 jroman 373
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 374
  data->krylovstart = krylovstart;
1619 slepc 375
  PetscFunctionReturn(0);
376
}
377
 
1980 eromero 378
#undef __FUNCT__  
379
#define __FUNCT__ "EPSDAVIDSONGetKrylovStart_DAVIDSON"
2216 jroman 380
PetscErrorCode EPSDAVIDSONGetKrylovStart_DAVIDSON(EPS eps,PetscBool *krylovstart)
1980 eromero 381
{
2317 jroman 382
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 383
 
384
  PetscFunctionBegin;
2213 jroman 385
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 386
  *krylovstart = data->krylovstart;
387
  PetscFunctionReturn(0);
388
}
389
 
390
#undef __FUNCT__  
391
#define __FUNCT__ "EPSDAVIDSONSetBlockSize_DAVIDSON"
392
PetscErrorCode EPSDAVIDSONSetBlockSize_DAVIDSON(EPS eps,PetscInt blocksize)
393
{
2317 jroman 394
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 395
 
396
  PetscFunctionBegin;
2213 jroman 397
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 398
  if(blocksize == PETSC_DEFAULT || blocksize == PETSC_DECIDE) blocksize = 1;
399
  if(blocksize <= 0)
2214 jroman 400
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid blocksize value");
1980 eromero 401
  data->blocksize = blocksize;
402
  PetscFunctionReturn(0);
403
}
404
 
405
#undef __FUNCT__  
406
#define __FUNCT__ "EPSDAVIDSONGetBlockSize_DAVIDSON"
407
PetscErrorCode EPSDAVIDSONGetBlockSize_DAVIDSON(EPS eps,PetscInt *blocksize)
408
{
2317 jroman 409
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 410
 
411
  PetscFunctionBegin;
2213 jroman 412
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 413
  *blocksize = data->blocksize;
414
  PetscFunctionReturn(0);
415
}
416
 
417
#undef __FUNCT__  
418
#define __FUNCT__ "EPSDAVIDSONSetRestart_DAVIDSON"
419
PetscErrorCode EPSDAVIDSONSetRestart_DAVIDSON(EPS eps,PetscInt minv,PetscInt plusk)
420
{
2317 jroman 421
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 422
 
423
  PetscFunctionBegin;
2213 jroman 424
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 425
  if(minv == PETSC_DEFAULT || minv == PETSC_DECIDE) minv = 5;
426
  if(minv <= 0)
2214 jroman 427
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid minv value");
1980 eromero 428
  if(plusk == PETSC_DEFAULT || plusk == PETSC_DECIDE) plusk = 5;
1982 eromero 429
  if(plusk < 0)
2214 jroman 430
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid plusk value");
1980 eromero 431
  data->minv = minv;
432
  data->plusk = plusk;
433
  PetscFunctionReturn(0);
434
}
435
 
436
#undef __FUNCT__  
437
#define __FUNCT__ "EPSDAVIDSONGetRestart_DAVIDSON"
438
PetscErrorCode EPSDAVIDSONGetRestart_DAVIDSON(EPS eps,PetscInt *minv,PetscInt *plusk)
439
{
2317 jroman 440
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 441
 
442
  PetscFunctionBegin;
2213 jroman 443
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 444
  *minv = data->minv;
445
  *plusk = data->plusk;
446
  PetscFunctionReturn(0);
447
}
448
 
449
#undef __FUNCT__  
450
#define __FUNCT__ "EPSDAVIDSONGetInitialSize_DAVIDSON"
451
PetscErrorCode EPSDAVIDSONGetInitialSize_DAVIDSON(EPS eps,PetscInt *initialsize)
452
{
2317 jroman 453
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 454
 
455
  PetscFunctionBegin;
2213 jroman 456
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 457
  *initialsize = data->initialsize;
458
  PetscFunctionReturn(0);
459
}
460
 
461
#undef __FUNCT__  
462
#define __FUNCT__ "EPSDAVIDSONSetInitialSize_DAVIDSON"
463
PetscErrorCode EPSDAVIDSONSetInitialSize_DAVIDSON(EPS eps,PetscInt initialsize)
464
{
2317 jroman 465
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 466
 
467
  PetscFunctionBegin;
2213 jroman 468
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1980 eromero 469
  if(initialsize == PETSC_DEFAULT || initialsize == PETSC_DECIDE) initialsize = 5;
470
  if(initialsize <= 0)
2214 jroman 471
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid initial size value");
1980 eromero 472
  data->initialsize = initialsize;
473
  PetscFunctionReturn(0);
474
}
475
 
1995 eromero 476
#undef __FUNCT__  
477
#define __FUNCT__ "EPSDAVIDSONGetFix_DAVIDSON"
478
PetscErrorCode EPSDAVIDSONGetFix_DAVIDSON(EPS eps,PetscReal *fix)
479
{
2317 jroman 480
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1980 eromero 481
 
1995 eromero 482
  PetscFunctionBegin;
2213 jroman 483
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1995 eromero 484
  *fix = data->fix;
485
  PetscFunctionReturn(0);
486
}
487
 
488
#undef __FUNCT__  
489
#define __FUNCT__ "EPSDAVIDSONSetFix_DAVIDSON"
490
PetscErrorCode EPSDAVIDSONSetFix_DAVIDSON(EPS eps,PetscReal fix)
491
{
2317 jroman 492
  EPS_DAVIDSON *data = (EPS_DAVIDSON*)eps->data;
1995 eromero 493
 
494
  PetscFunctionBegin;
2213 jroman 495
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1995 eromero 496
  if(fix == PETSC_DEFAULT || fix == PETSC_DECIDE) fix = 0.01;
497
  if(fix < 0.0)
2214 jroman 498
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Invalid fix value");
1995 eromero 499
  data->fix = fix;
500
  PetscFunctionReturn(0);
501
}
502
 
1619 slepc 503
#undef __FUNCT__  
1756 eromero 504
#define __FUNCT__ "EPSComputeVectors_QZ"
505
/*
506
  EPSComputeVectors_QZ - Compute eigenvectors from the vectors
507
  provided by the eigensolver. This version is intended for solvers
508
  that provide Schur vectors from the QZ decompositon. Given the partial
509
  Schur decomposition OP*V=V*T, the following steps are performed:
510
      1) compute eigenvectors of (S,T): S*Z=T*Z*D
511
      2) compute eigenvectors of OP: X=V*Z
512
  If left eigenvectors are required then also do Z'*Tl=D*Z', Y=W*Z
513
 */
514
PetscErrorCode EPSComputeVectors_QZ(EPS eps)
515
{
2317 jroman 516
  PetscErrorCode ierr;
517
  EPS_DAVIDSON   *data = (EPS_DAVIDSON*)eps->data;
518
  dvdDashboard   *d = &data->ddb;
519
  PetscScalar    *pX, *auxS;
520
  PetscInt       size_auxS;
2022 eromero 521
 
1756 eromero 522
  PetscFunctionBegin;
1968 eromero 523
  /* Compute the eigenvectors associated to (cS, cT) */
524
  ierr = PetscMalloc(sizeof(PetscScalar)*d->nconv*d->nconv, &pX); CHKERRQ(ierr);
525
  size_auxS = 11*d->nconv + 4*d->nconv*d->nconv;
526
  ierr = PetscMalloc(sizeof(PetscScalar)*size_auxS, &auxS); CHKERRQ(ierr);
527
  ierr = dvd_compute_eigenvectors(d->nconv, d->cS, d->ldcS, d->cT, d->ldcT,
528
                                  pX, d->nconv, PETSC_NULL, 0, auxS,
529
                                  size_auxS, PETSC_FALSE); CHKERRQ(ierr);
1756 eromero 530
 
1762 eromero 531
  /* pX[i] <- pX[i] / ||pX[i]|| */
2317 jroman 532
  ierr = SlepcDenseNorm(pX, d->nconv, d->nconv, d->nconv, d->ceigi);CHKERRQ(ierr);
1762 eromero 533
 
1756 eromero 534
  /* V <- cX * pX */
535
  ierr = SlepcUpdateVectorsZ(eps->V, 0.0, 1.0, d->cX, d->size_cX, pX,
536
                             d->nconv, d->nconv, d->nconv); CHKERRQ(ierr);
537
 
538
  ierr = PetscFree(pX); CHKERRQ(ierr);
539
  ierr = PetscFree(auxS); CHKERRQ(ierr);
540
 
541
  eps->evecsavailable = PETSC_TRUE;
542
  PetscFunctionReturn(0);
543
}