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