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