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
545 dsic.upv.es!jroman 1
/*
2
      EPS routines related to problem setup.
1376 slepc 3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2116 eromero 6
   Copyright (c) 2002-2010, Universidad Politecnica de Valencia, Spain
1376 slepc 7
 
1672 slepc 8
   This file is part of SLEPc.
9
 
10
   SLEPc is free software: you can redistribute it and/or modify it under  the
11
   terms of version 3 of the GNU Lesser General Public License as published by
12
   the Free Software Foundation.
13
 
14
   SLEPc  is  distributed in the hope that it will be useful, but WITHOUT  ANY
15
   WARRANTY;  without even the implied warranty of MERCHANTABILITY or  FITNESS
16
   FOR  A  PARTICULAR PURPOSE. See the GNU Lesser General Public  License  for
17
   more details.
18
 
19
   You  should have received a copy of the GNU Lesser General  Public  License
20
   along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
1376 slepc 21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
545 dsic.upv.es!jroman 22
*/
1376 slepc 23
 
2414 jroman 24
#include <private/epsimpl.h>       /*I "slepceps.h" I*/
25
#include <private/ipimpl.h>        /*I "slepcip.h" I*/
527 dsic.upv.es!antodo 26
 
27
#undef __FUNCT__  
28
#define __FUNCT__ "EPSSetUp"
29
/*@
30
   EPSSetUp - Sets up all the internal data structures necessary for the
31
   execution of the eigensolver. Then calls STSetUp() for any set-up
32
   operations associated to the ST object.
33
 
34
   Collective on EPS
35
 
36
   Input Parameter:
37
.  eps   - eigenproblem solver context
38
 
39
   Notes:
40
   This function need not be called explicitly in most cases, since EPSSolve()
41
   calls it. It can be useful when one wants to measure the set-up time
42
   separately from the solve time.
43
 
1811 jroman 44
   Level: advanced
45
 
1933 jroman 46
.seealso: EPSCreate(), EPSSolve(), EPSDestroy(), STSetUp(), EPSSetInitialSpace()
527 dsic.upv.es!antodo 47
@*/
48
PetscErrorCode EPSSetUp(EPS eps)
49
{
50
  PetscErrorCode ierr;
51
  Mat            A,B;
1932 jroman 52
  PetscInt       i,k;
2216 jroman 53
  PetscBool      flg,lindep;
2359 jroman 54
  Vec            *newDS;
1932 jroman 55
  PetscReal      norm;
1849 antodo 56
#if defined(PETSC_USE_COMPLEX)
57
  PetscScalar    sigma;
58
#endif
527 dsic.upv.es!antodo 59
 
60
  PetscFunctionBegin;
2213 jroman 61
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
527 dsic.upv.es!antodo 62
  if (eps->setupcalled) PetscFunctionReturn(0);
63
  ierr = PetscLogEventBegin(EPS_SetUp,eps,0,0,0);CHKERRQ(ierr);
64
 
2412 jroman 65
  /* Set default solver type (EPSSetFromOptions was not called) */
1422 slepc 66
  if (!((PetscObject)eps)->type_name) {
1198 slepc 67
    ierr = EPSSetType(eps,EPSKRYLOVSCHUR);CHKERRQ(ierr);
527 dsic.upv.es!antodo 68
  }
2412 jroman 69
  if (!eps->OP) { ierr = EPSGetST(eps,&eps->OP);CHKERRQ(ierr); }
70
  if (!((PetscObject)eps->OP)->type_name) {
71
      ierr = STSetType(eps->OP,STSHIFT);CHKERRQ(ierr);
72
  }
73
  if (!eps->ip) { ierr = EPSGetIP(eps,&eps->ip);CHKERRQ(ierr); }
74
  if (!((PetscObject)eps->ip)->type_name) {
75
    ierr = IPSetDefaultType_Private(eps->ip);CHKERRQ(ierr);
76
  }
2453 eromero 77
  if (!((PetscObject)eps->rand)->type_name) {
78
    ierr = PetscRandomSetFromOptions(eps->rand);CHKERRQ(ierr);
79
  }
691 dsic.upv.es!antodo 80
 
1928 jroman 81
  /* Set problem dimensions */
527 dsic.upv.es!antodo 82
  ierr = STGetOperators(eps->OP,&A,&B);CHKERRQ(ierr);
2350 jroman 83
  if (!A) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_WRONGSTATE,"EPSSetOperators must be called first");
1928 jroman 84
  ierr = MatGetSize(A,&eps->n,PETSC_NULL);CHKERRQ(ierr);
85
  ierr = MatGetLocalSize(A,&eps->nloc,PETSC_NULL);CHKERRQ(ierr);
2410 jroman 86
  ierr = SlepcMatGetVecsTemplate(A,&eps->t,PETSC_NULL);CHKERRQ(ierr);
1928 jroman 87
 
527 dsic.upv.es!antodo 88
  /* Set default problem type */
89
  if (!eps->problem_type) {
90
    if (B==PETSC_NULL) {
91
      ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr);
2348 jroman 92
    } else {
527 dsic.upv.es!antodo 93
      ierr = EPSSetProblemType(eps,EPS_GNHEP);CHKERRQ(ierr);
94
    }
2498 jroman 95
  } else if (!B && eps->isgeneralized) {
96
    ierr = PetscInfo(eps,"Eigenproblem set as generalized but no matrix B was provided; reverting to a standard eigenproblem\n");CHKERRQ(ierr);
97
    eps->isgeneralized = PETSC_FALSE;
98
    eps->problem_type = eps->ishermitian? EPS_HEP: EPS_NHEP;
99
  } else if (B && !eps->isgeneralized) {
2497 jroman 100
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_INCOMP,"Inconsistent EPS state");
527 dsic.upv.es!antodo 101
  }
1849 antodo 102
#if defined(PETSC_USE_COMPLEX)
103
  ierr = STGetShift(eps->OP,&sigma);CHKERRQ(ierr);
2219 jroman 104
  if (eps->ishermitian && PetscImaginaryPart(sigma) != 0.0)
105
    SETERRQ(((PetscObject)eps)->comm,1,"Hermitian problems are not compatible with complex shifts");
1849 antodo 106
#endif
2219 jroman 107
  if (eps->ishermitian && eps->leftvecs)
108
    SETERRQ(((PetscObject)eps)->comm,1,"Requesting left eigenvectors not allowed in Hermitian problems");
527 dsic.upv.es!antodo 109
 
1358 slepc 110
  if (eps->ispositive) {
111
    ierr = STGetBilinearForm(eps->OP,&B);CHKERRQ(ierr);
2380 jroman 112
    ierr = IPSetMatrix(eps->ip,B);CHKERRQ(ierr);
2305 jroman 113
    ierr = MatDestroy(&B);CHKERRQ(ierr);
1358 slepc 114
  } else {
2380 jroman 115
    ierr = IPSetMatrix(eps->ip,PETSC_NULL);CHKERRQ(ierr);
1358 slepc 116
  }
117
 
1928 jroman 118
  if (eps->nev > eps->n) eps->nev = eps->n;
119
  if (eps->ncv > eps->n) eps->ncv = eps->n;
1220 slepc 120
 
1957 jroman 121
  /* initialization of matrix norms */
122
  if (eps->nrma == PETSC_DETERMINE) {
123
    ierr = MatHasOperation(A,MATOP_NORM,&flg);CHKERRQ(ierr);
124
    if (flg) { ierr = MatNorm(A,NORM_INFINITY,&eps->nrma);CHKERRQ(ierr); }
125
    else eps->nrma = 1.0;
126
  }
127
  if (eps->nrmb == PETSC_DETERMINE) {
128
    ierr = MatHasOperation(B,MATOP_NORM,&flg);CHKERRQ(ierr);
129
    if (flg) { ierr = MatNorm(B,NORM_INFINITY,&eps->nrmb);CHKERRQ(ierr); }
130
    else eps->nrmb = 1.0;
131
  }
132
 
133
  /* call specific solver setup */
527 dsic.upv.es!antodo 134
  ierr = (*eps->ops->setup)(eps);CHKERRQ(ierr);
2348 jroman 135
 
136
  /* Build balancing matrix if required */
2412 jroman 137
  if (!eps->balance) eps->balance = EPS_BALANCE_NONE;
2348 jroman 138
  if (!eps->ishermitian && (eps->balance==EPS_BALANCE_ONESIDE || eps->balance==EPS_BALANCE_TWOSIDE)) {
139
    if (!eps->D) {
140
      ierr = VecDuplicate(eps->V[0],&eps->D);CHKERRQ(ierr);
141
    } else {
142
      ierr = VecSet(eps->D,1.0);CHKERRQ(ierr);
143
    }
144
    ierr = EPSBuildBalance_Krylov(eps);CHKERRQ(ierr);
145
    ierr = STSetBalanceMatrix(eps->OP,eps->D);CHKERRQ(ierr);
146
  }
147
 
148
  /* Setup ST */
2330 jroman 149
  ierr = STSetUp(eps->OP);CHKERRQ(ierr);
527 dsic.upv.es!antodo 150
 
1957 jroman 151
  ierr = PetscTypeCompare((PetscObject)eps->OP,STCAYLEY,&flg);CHKERRQ(ierr);
2219 jroman 152
  if (flg && eps->problem_type == EPS_PGNHEP)
2214 jroman 153
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Cayley spectral transformation is not compatible with PGNHEP");
1789 antodo 154
 
2087 jroman 155
  ierr = PetscTypeCompare((PetscObject)eps->OP,STFOLD,&flg);CHKERRQ(ierr);
2219 jroman 156
  if (flg && !eps->ishermitian)
2214 jroman 157
    SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_SUP,"Fold spectral transformation requires a Hermitian problem");
2087 jroman 158
 
527 dsic.upv.es!antodo 159
  if (eps->nds>0) {
160
    if (!eps->ds_ortho) {
1917 jroman 161
      /* allocate memory and copy deflation basis vectors into DS */
2410 jroman 162
      ierr = VecDuplicateVecs(eps->t,eps->nds,&newDS);CHKERRQ(ierr);
1917 jroman 163
      for (i=0;i<eps->nds;i++) {
2359 jroman 164
        ierr = VecCopy(eps->DS[i],newDS[i]);CHKERRQ(ierr);
2305 jroman 165
        ierr = VecDestroy(&eps->DS[i]);CHKERRQ(ierr);
1917 jroman 166
      }
2359 jroman 167
      ierr = PetscFree(eps->DS);CHKERRQ(ierr);
168
      eps->DS = newDS;
1917 jroman 169
      /* orthonormalize vectors in DS */
1954 jroman 170
      k = 0;
171
      for (i=0;i<eps->nds;i++) {
172
        ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,k,PETSC_NULL,eps->DS,eps->DS[k],PETSC_NULL,&norm,&lindep);CHKERRQ(ierr);
2499 jroman 173
        if (norm==0.0 || lindep) {
174
          ierr = PetscInfo(eps,"Linearly dependent deflation vector found, removing...\n");CHKERRQ(ierr);
175
        } else {
1954 jroman 176
          ierr = VecScale(eps->DS[k],1.0/norm);CHKERRQ(ierr);
177
          k++;
178
        }
179
      }
2359 jroman 180
      for (i=k;i<eps->nds;i++) { ierr = VecDestroy(&eps->DS[i]);CHKERRQ(ierr); }
1954 jroman 181
      eps->nds = k;
1917 jroman 182
      eps->ds_ortho = PETSC_TRUE;
527 dsic.upv.es!antodo 183
    }
184
  }
185
  ierr = STCheckNullSpace(eps->OP,eps->nds,eps->DS);CHKERRQ(ierr);
1800 jroman 186
 
1932 jroman 187
  /* process initial vectors */
188
  if (eps->nini<0) {
189
    eps->nini = -eps->nini;
2219 jroman 190
    if (eps->nini>eps->ncv) SETERRQ(((PetscObject)eps)->comm,1,"The number of initial vectors is larger than ncv");
1932 jroman 191
    k = 0;
192
    for (i=0;i<eps->nini;i++) {
193
      ierr = VecCopy(eps->IS[i],eps->V[k]);CHKERRQ(ierr);
2305 jroman 194
      ierr = VecDestroy(&eps->IS[i]);CHKERRQ(ierr);
1932 jroman 195
      ierr = IPOrthogonalize(eps->ip,eps->nds,eps->DS,k,PETSC_NULL,eps->V,eps->V[k],PETSC_NULL,&norm,&lindep);CHKERRQ(ierr);
2499 jroman 196
      if (norm==0.0 || lindep) {
197
        ierr = PetscInfo(eps,"Linearly dependent initial vector found, removing...\n");CHKERRQ(ierr);
198
      } else {
1932 jroman 199
        ierr = VecScale(eps->V[k],1.0/norm);CHKERRQ(ierr);
200
        k++;
201
      }
202
    }
203
    eps->nini = k;
204
    ierr = PetscFree(eps->IS);CHKERRQ(ierr);
205
  }
1937 jroman 206
  if (eps->ninil<0) {
2499 jroman 207
    if (!eps->leftvecs) {
208
      ierr = PetscInfo(eps,"Ignoring initial left vectors\n");CHKERRQ(ierr);
209
    } else {
1937 jroman 210
      eps->ninil = -eps->ninil;
2219 jroman 211
      if (eps->ninil>eps->ncv) SETERRQ(((PetscObject)eps)->comm,1,"The number of initial left vectors is larger than ncv");
1937 jroman 212
      k = 0;
213
      for (i=0;i<eps->ninil;i++) {
214
        ierr = VecCopy(eps->ISL[i],eps->W[k]);CHKERRQ(ierr);
2305 jroman 215
        ierr = VecDestroy(&eps->ISL[i]);CHKERRQ(ierr);
1937 jroman 216
        ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,k,PETSC_NULL,eps->W,eps->W[k],PETSC_NULL,&norm,&lindep);CHKERRQ(ierr);
2499 jroman 217
        if (norm==0.0 || lindep) {
218
          ierr = PetscInfo(eps,"Linearly dependent initial left vector found, removing...\n");CHKERRQ(ierr);
219
        } else {
1937 jroman 220
          ierr = VecScale(eps->W[k],1.0/norm);CHKERRQ(ierr);
221
          k++;
222
        }
223
      }
224
      eps->ninil = k;
225
      ierr = PetscFree(eps->ISL);CHKERRQ(ierr);
226
    }
227
  }
1932 jroman 228
 
527 dsic.upv.es!antodo 229
  ierr = PetscLogEventEnd(EPS_SetUp,eps,0,0,0);CHKERRQ(ierr);
230
  eps->setupcalled = 1;
231
  PetscFunctionReturn(0);
232
}
233
 
234
#undef __FUNCT__  
235
#define __FUNCT__ "EPSSetOperators"
236
/*@
237
   EPSSetOperators - Sets the matrices associated with the eigenvalue problem.
238
 
239
   Collective on EPS and Mat
240
 
241
   Input Parameters:
242
+  eps - the eigenproblem solver context
243
.  A  - the matrix associated with the eigensystem
244
-  B  - the second matrix in the case of generalized eigenproblems
245
 
246
   Notes:
247
   To specify a standard eigenproblem, use PETSC_NULL for parameter B.
248
 
2348 jroman 249
   It must be called after EPSSetUp(). If it is called again after EPSSetUp() then
250
   the EPS object is reset.
251
 
527 dsic.upv.es!antodo 252
   Level: beginner
253
 
2348 jroman 254
.seealso: EPSSolve(), EPSSetUp(), EPSReset(), EPSGetST(), STGetOperators()
527 dsic.upv.es!antodo 255
@*/
256
PetscErrorCode EPSSetOperators(EPS eps,Mat A,Mat B)
257
{
258
  PetscErrorCode ierr;
1928 jroman 259
  PetscInt       m,n,m0;
527 dsic.upv.es!antodo 260
 
261
  PetscFunctionBegin;
2213 jroman 262
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
263
  PetscValidHeaderSpecific(A,MAT_CLASSID,2);
264
  if (B) PetscValidHeaderSpecific(B,MAT_CLASSID,3);
1014 slepc 265
  PetscCheckSameComm(eps,1,A,2);
266
  if (B) PetscCheckSameComm(eps,1,B,3);
527 dsic.upv.es!antodo 267
 
268
  /* Check for square matrices */
269
  ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
2219 jroman 270
  if (m!=n) SETERRQ(((PetscObject)eps)->comm,1,"A is a non-square matrix");
527 dsic.upv.es!antodo 271
  if (B) {
1928 jroman 272
    ierr = MatGetSize(B,&m0,&n);CHKERRQ(ierr);
2219 jroman 273
    if (m0!=n) SETERRQ(((PetscObject)eps)->comm,1,"B is a non-square matrix");
274
    if (m!=m0) SETERRQ(((PetscObject)eps)->comm,1,"Dimensions of A and B do not match");
527 dsic.upv.es!antodo 275
  }
276
 
2348 jroman 277
  if (eps->setupcalled) { ierr = EPSReset(eps);CHKERRQ(ierr); }
2371 jroman 278
  if (!eps->OP) { ierr = EPSGetST(eps,&eps->OP);CHKERRQ(ierr); }
527 dsic.upv.es!antodo 279
  ierr = STSetOperators(eps->OP,A,B);CHKERRQ(ierr);
280
  PetscFunctionReturn(0);
281
}
282
 
1516 slepc 283
#undef __FUNCT__
284
#define __FUNCT__ "EPSGetOperators"
285
/*@
286
   EPSGetOperators - Gets the matrices associated with the eigensystem.
287
 
288
   Collective on EPS and Mat
289
 
290
   Input Parameter:
291
.  eps - the EPS context
292
 
293
   Output Parameters:
294
+  A  - the matrix associated with the eigensystem
295
-  B  - the second matrix in the case of generalized eigenproblems
296
 
297
   Level: intermediate
298
 
299
.seealso: EPSSolve(), EPSGetST(), STGetOperators(), STSetOperators()
300
@*/
2331 jroman 301
PetscErrorCode EPSGetOperators(EPS eps,Mat *A,Mat *B)
1516 slepc 302
{
303
  PetscErrorCode ierr;
304
  ST             st;
305
 
306
  PetscFunctionBegin;
2213 jroman 307
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
1516 slepc 308
  if (A) PetscValidPointer(A,2);
309
  if (B) PetscValidPointer(B,3);
310
  ierr = EPSGetST(eps,&st);CHKERRQ(ierr);
311
  ierr = STGetOperators(st,A,B);CHKERRQ(ierr);
312
  PetscFunctionReturn(0);
313
}
314
 
527 dsic.upv.es!antodo 315
#undef __FUNCT__  
1926 jroman 316
#define __FUNCT__ "EPSSetDeflationSpace"
527 dsic.upv.es!antodo 317
/*@
1926 jroman 318
   EPSSetDeflationSpace - Specify a basis of vectors that constitute
1917 jroman 319
   the deflation space.
527 dsic.upv.es!antodo 320
 
1811 jroman 321
   Collective on EPS and Vec
527 dsic.upv.es!antodo 322
 
323
   Input Parameter:
324
+  eps   - the eigenproblem solver context
1917 jroman 325
.  n     - number of vectors
326
-  ds    - set of basis vectors of the deflation space
527 dsic.upv.es!antodo 327
 
328
   Notes:
329
   When a deflation space is given, the eigensolver seeks the eigensolution
330
   in the restriction of the problem to the orthogonal complement of this
331
   space. This can be used for instance in the case that an invariant
332
   subspace is known beforehand (such as the nullspace of the matrix).
333
 
1926 jroman 334
   Basis vectors set by a previous call to EPSSetDeflationSpace() are
1917 jroman 335
   replaced.
527 dsic.upv.es!antodo 336
 
1917 jroman 337
   The vectors do not need to be mutually orthonormal, since they are explicitly
338
   orthonormalized internally.
527 dsic.upv.es!antodo 339
 
1932 jroman 340
   These vectors persist from one EPSSolve() call to the other, use
341
   EPSRemoveDeflationSpace() to eliminate them.
342
 
527 dsic.upv.es!antodo 343
   Level: intermediate
344
 
345
.seealso: EPSRemoveDeflationSpace()
346
@*/
1926 jroman 347
PetscErrorCode EPSSetDeflationSpace(EPS eps,PetscInt n,Vec *ds)
527 dsic.upv.es!antodo 348
{
349
  PetscErrorCode ierr;
1917 jroman 350
  PetscInt       i;
527 dsic.upv.es!antodo 351
 
352
  PetscFunctionBegin;
2213 jroman 353
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2326 jroman 354
  PetscValidLogicalCollectiveInt(eps,n,2);
2436 jroman 355
  if (n<0) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Argument n out of range");
1917 jroman 356
 
357
  /* free previous vectors */
358
  ierr = EPSRemoveDeflationSpace(eps);CHKERRQ(ierr);
359
 
360
  /* get references of passed vectors */
2436 jroman 361
  if (n>0) {
362
    ierr = PetscMalloc(n*sizeof(Vec),&eps->DS);CHKERRQ(ierr);
363
    for (i=0;i<n;i++) {
364
      ierr = PetscObjectReference((PetscObject)ds[i]);CHKERRQ(ierr);
365
      eps->DS[i] = ds[i];
366
    }
367
    eps->setupcalled = 0;
368
    eps->ds_ortho = PETSC_FALSE;
527 dsic.upv.es!antodo 369
  }
1917 jroman 370
 
371
  eps->nds = n;
527 dsic.upv.es!antodo 372
  PetscFunctionReturn(0);
373
}
374
 
375
#undef __FUNCT__  
376
#define __FUNCT__ "EPSRemoveDeflationSpace"
377
/*@
378
   EPSRemoveDeflationSpace - Removes the deflation space.
379
 
1811 jroman 380
   Collective on EPS
527 dsic.upv.es!antodo 381
 
382
   Input Parameter:
383
.  eps   - the eigenproblem solver context
384
 
385
   Level: intermediate
386
 
1926 jroman 387
.seealso: EPSSetDeflationSpace()
527 dsic.upv.es!antodo 388
@*/
389
PetscErrorCode EPSRemoveDeflationSpace(EPS eps)
390
{
391
  PetscErrorCode ierr;
392
 
393
  PetscFunctionBegin;
2213 jroman 394
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2410 jroman 395
  ierr = VecDestroyVecs(eps->nds,&eps->DS);CHKERRQ(ierr);
1917 jroman 396
  eps->nds = 0;
527 dsic.upv.es!antodo 397
  eps->setupcalled = 0;
1917 jroman 398
  eps->ds_ortho = PETSC_FALSE;
527 dsic.upv.es!antodo 399
  PetscFunctionReturn(0);
400
}
1932 jroman 401
 
402
#undef __FUNCT__  
403
#define __FUNCT__ "EPSSetInitialSpace"
404
/*@
405
   EPSSetInitialSpace - Specify a basis of vectors that constitute the initial
406
   space, that is, the subspace from which the solver starts to iterate.
407
 
408
   Collective on EPS and Vec
409
 
410
   Input Parameter:
411
+  eps   - the eigenproblem solver context
412
.  n     - number of vectors
413
-  is    - set of basis vectors of the initial space
414
 
415
   Notes:
416
   Some solvers start to iterate on a single vector (initial vector). In that case,
417
   the other vectors are ignored.
418
 
419
   In contrast to EPSSetDeflationSpace(), these vectors do not persist from one
420
   EPSSolve() call to the other, so the initial space should be set every time.
421
 
422
   The vectors do not need to be mutually orthonormal, since they are explicitly
423
   orthonormalized internally.
424
 
1937 jroman 425
   Common usage of this function is when the user can provide a rough approximation
426
   of the wanted eigenspace. Then, convergence may be faster.
427
 
1932 jroman 428
   Level: intermediate
429
 
1937 jroman 430
.seealso: EPSSetInitialSpaceLeft(), EPSSetDeflationSpace()
1932 jroman 431
@*/
432
PetscErrorCode EPSSetInitialSpace(EPS eps,PetscInt n,Vec *is)
433
{
434
  PetscErrorCode ierr;
435
  PetscInt       i;
436
 
437
  PetscFunctionBegin;
2213 jroman 438
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2326 jroman 439
  PetscValidLogicalCollectiveInt(eps,n,2);
2214 jroman 440
  if (n<0) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Argument n cannot be negative");
1932 jroman 441
 
442
  /* free previous non-processed vectors */
443
  if (eps->nini<0) {
444
    for (i=0;i<-eps->nini;i++) {
2305 jroman 445
      ierr = VecDestroy(&eps->IS[i]);CHKERRQ(ierr);
1932 jroman 446
    }
447
    ierr = PetscFree(eps->IS);CHKERRQ(ierr);
448
  }
449
 
450
  /* get references of passed vectors */
2436 jroman 451
  if (n>0) {
452
    ierr = PetscMalloc(n*sizeof(Vec),&eps->IS);CHKERRQ(ierr);
453
    for (i=0;i<n;i++) {
454
      ierr = PetscObjectReference((PetscObject)is[i]);CHKERRQ(ierr);
455
      eps->IS[i] = is[i];
456
    }
457
    eps->setupcalled = 0;
1932 jroman 458
  }
459
 
460
  eps->nini = -n;
461
  PetscFunctionReturn(0);
462
}
463
 
1937 jroman 464
#undef __FUNCT__  
465
#define __FUNCT__ "EPSSetInitialSpaceLeft"
466
/*@
467
   EPSSetInitialSpaceLeft - Specify a basis of vectors that constitute the initial
468
   left space, that is, the subspace from which the solver starts to iterate for
469
   building the left subspace (in methods that work with two subspaces).
1932 jroman 470
 
1937 jroman 471
   Collective on EPS and Vec
472
 
473
   Input Parameter:
474
+  eps   - the eigenproblem solver context
475
.  n     - number of vectors
476
-  is    - set of basis vectors of the initial left space
477
 
478
   Notes:
479
   Some solvers start to iterate on a single vector (initial left vector). In that case,
480
   the other vectors are ignored.
481
 
482
   In contrast to EPSSetDeflationSpace(), these vectors do not persist from one
483
   EPSSolve() call to the other, so the initial left space should be set every time.
484
 
485
   The vectors do not need to be mutually orthonormal, since they are explicitly
486
   orthonormalized internally.
487
 
488
   Common usage of this function is when the user can provide a rough approximation
489
   of the wanted left eigenspace. Then, convergence may be faster.
490
 
491
   Level: intermediate
492
 
493
.seealso: EPSSetInitialSpace(), EPSSetDeflationSpace()
494
@*/
495
PetscErrorCode EPSSetInitialSpaceLeft(EPS eps,PetscInt n,Vec *is)
496
{
497
  PetscErrorCode ierr;
498
  PetscInt       i;
499
 
500
  PetscFunctionBegin;
2213 jroman 501
  PetscValidHeaderSpecific(eps,EPS_CLASSID,1);
2326 jroman 502
  PetscValidLogicalCollectiveInt(eps,n,2);
2214 jroman 503
  if (n<0) SETERRQ(((PetscObject)eps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Argument n cannot be negative");
1937 jroman 504
 
505
  /* free previous non-processed vectors */
506
  if (eps->ninil<0) {
507
    for (i=0;i<-eps->ninil;i++) {
2305 jroman 508
      ierr = VecDestroy(&eps->ISL[i]);CHKERRQ(ierr);
1937 jroman 509
    }
510
    ierr = PetscFree(eps->ISL);CHKERRQ(ierr);
511
  }
512
 
513
  /* get references of passed vectors */
2436 jroman 514
  if (n>0) {
515
    ierr = PetscMalloc(n*sizeof(Vec),&eps->ISL);CHKERRQ(ierr);
516
    for (i=0;i<n;i++) {
517
      ierr = PetscObjectReference((PetscObject)is[i]);CHKERRQ(ierr);
518
      eps->ISL[i] = is[i];
519
    }
520
    eps->setupcalled = 0;
1937 jroman 521
  }
522
 
523
  eps->ninil = -n;
524
  PetscFunctionReturn(0);
525
}
526