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
6
   Copyright (c) 2002-2009, 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
 
1521 slepc 24
#include "private/epsimpl.h"   /*I "slepceps.h" I*/
527 dsic.upv.es!antodo 25
 
26
#undef __FUNCT__  
27
#define __FUNCT__ "EPSSetUp"
28
/*@
29
   EPSSetUp - Sets up all the internal data structures necessary for the
30
   execution of the eigensolver. Then calls STSetUp() for any set-up
31
   operations associated to the ST object.
32
 
33
   Collective on EPS
34
 
35
   Input Parameter:
36
.  eps   - eigenproblem solver context
37
 
38
   Level: advanced
39
 
40
   Notes:
41
   This function need not be called explicitly in most cases, since EPSSolve()
42
   calls it. It can be useful when one wants to measure the set-up time
43
   separately from the solve time.
44
 
45
   This function sets a random initial vector if none has been provided.
46
 
47
.seealso: EPSCreate(), EPSSolve(), EPSDestroy(), STSetUp()
48
@*/
49
PetscErrorCode EPSSetUp(EPS eps)
50
{
51
  PetscErrorCode ierr;
1385 slepc 52
  Vec            v0,w0;  
527 dsic.upv.es!antodo 53
  Mat            A,B;
1220 slepc 54
  PetscInt       N;
1789 antodo 55
  PetscTruth     isCayley;
527 dsic.upv.es!antodo 56
 
57
  PetscFunctionBegin;
58
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
59
 
60
  if (eps->setupcalled) PetscFunctionReturn(0);
61
 
62
  ierr = PetscLogEventBegin(EPS_SetUp,eps,0,0,0);CHKERRQ(ierr);
63
 
64
  /* Set default solver type */
1422 slepc 65
  if (!((PetscObject)eps)->type_name) {
1198 slepc 66
    ierr = EPSSetType(eps,EPSKRYLOVSCHUR);CHKERRQ(ierr);
527 dsic.upv.es!antodo 67
  }
691 dsic.upv.es!antodo 68
 
527 dsic.upv.es!antodo 69
  ierr = STGetOperators(eps->OP,&A,&B);CHKERRQ(ierr);
70
  /* Set default problem type */
71
  if (!eps->problem_type) {
72
    if (B==PETSC_NULL) {
73
      ierr = EPSSetProblemType(eps,EPS_NHEP);CHKERRQ(ierr);
74
    }
75
    else {
76
      ierr = EPSSetProblemType(eps,EPS_GNHEP);CHKERRQ(ierr);
77
    }
78
  } else if ((B && !eps->isgeneralized) || (!B && eps->isgeneralized)) {
79
    SETERRQ(0,"Warning: Inconsistent EPS state");
80
  }
81
 
1358 slepc 82
  if (eps->ispositive) {
83
    ierr = STGetBilinearForm(eps->OP,&B);CHKERRQ(ierr);
84
    ierr = IPSetBilinearForm(eps->ip,B,IPINNER_HERMITIAN);CHKERRQ(ierr);
85
    ierr = MatDestroy(B);CHKERRQ(ierr);
86
  } else {
87
    ierr = IPSetBilinearForm(eps->ip,PETSC_NULL,IPINNER_HERMITIAN);CHKERRQ(ierr);
88
  }
89
 
1385 slepc 90
  /* Create random initial vectors if not set */
780 dsic.upv.es!jroman 91
  /* right */
1385 slepc 92
  ierr = EPSGetInitialVector(eps,&v0);CHKERRQ(ierr);
93
  if (!v0) {
94
    ierr = MatGetVecs(A,&v0,PETSC_NULL);CHKERRQ(ierr);
95
    ierr = SlepcVecSetRandom(v0);CHKERRQ(ierr);
96
    eps->vec_initial = v0;
527 dsic.upv.es!antodo 97
  }
780 dsic.upv.es!jroman 98
  /* left */
1385 slepc 99
  ierr = EPSGetLeftInitialVector(eps,&w0);CHKERRQ(ierr);
100
  if (!w0) {
101
    ierr = MatGetVecs(A,PETSC_NULL,&w0);CHKERRQ(ierr);
102
    ierr = SlepcVecSetRandom(w0);CHKERRQ(ierr);
103
    eps->vec_initial_left = w0;
780 dsic.upv.es!jroman 104
  }
527 dsic.upv.es!antodo 105
 
1385 slepc 106
  ierr = VecGetSize(eps->vec_initial,&N);CHKERRQ(ierr);
1220 slepc 107
  if (eps->nev > N) eps->nev = N;
108
  if (eps->ncv > N) eps->ncv = N;
109
 
527 dsic.upv.es!antodo 110
  ierr = (*eps->ops->setup)(eps);CHKERRQ(ierr);
543 dsic.upv.es!jroman 111
  ierr = STSetUp(eps->OP); CHKERRQ(ierr);
527 dsic.upv.es!antodo 112
 
1789 antodo 113
  ierr = PetscTypeCompare((PetscObject)eps->OP,STCAYLEY,&isCayley);CHKERRQ(ierr);
114
  if (isCayley && eps->problem_type == EPS_PGNHEP) {
115
    SETERRQ(PETSC_ERR_SUP,"Cayley spectral transformation is not compatible with PGNHEP");
116
  }
117
 
527 dsic.upv.es!antodo 118
  if (eps->nds>0) {
119
    if (!eps->ds_ortho) {
120
      /* orthonormalize vectors in DS if necessary */
1755 antodo 121
      ierr = IPQRDecomposition(eps->ip,eps->DS,0,eps->nds,PETSC_NULL,0);CHKERRQ(ierr);
527 dsic.upv.es!antodo 122
    }
1755 antodo 123
    ierr = IPOrthogonalize(eps->ip,0,PETSC_NULL,eps->nds,PETSC_NULL,eps->DS,eps->vec_initial,PETSC_NULL,PETSC_NULL,PETSC_NULL);CHKERRQ(ierr);
527 dsic.upv.es!antodo 124
  }
125
 
126
  ierr = STCheckNullSpace(eps->OP,eps->nds,eps->DS);CHKERRQ(ierr);
1800 jroman 127
 
128
  /* Build balancing matrix if required */
129
  if (!eps->balance) eps->balance = EPSBALANCE_NONE;
1804 jroman 130
  if (!eps->ishermitian && (eps->balance==EPSBALANCE_ONESIDE || eps->balance==EPSBALANCE_TWOSIDE)) {
1800 jroman 131
    if (!eps->D) {
132
      ierr = VecDuplicate(eps->vec_initial,&eps->D);CHKERRQ(ierr);
133
    }
134
    ierr = EPSBuildBalance_Krylov(eps);CHKERRQ(ierr);
1804 jroman 135
    ierr = STSetBalanceMatrix(eps->OP,eps->D);CHKERRQ(ierr);
1800 jroman 136
  }
137
 
527 dsic.upv.es!antodo 138
  ierr = PetscLogEventEnd(EPS_SetUp,eps,0,0,0);CHKERRQ(ierr);
139
  eps->setupcalled = 1;
140
  PetscFunctionReturn(0);
141
}
142
 
143
#undef __FUNCT__  
144
#define __FUNCT__ "EPSSetInitialVector"
145
/*@
1385 slepc 146
   EPSSetInitialVector - Sets the initial vector from which the
147
   eigensolver starts to iterate.
527 dsic.upv.es!antodo 148
 
149
   Collective on EPS and Vec
150
 
151
   Input Parameters:
152
+  eps - the eigensolver context
153
-  vec - the vector
154
 
155
   Level: intermediate
156
 
1385 slepc 157
.seealso: EPSGetInitialVector(), EPSSetLeftInitialVector()
527 dsic.upv.es!antodo 158
 
159
@*/
160
PetscErrorCode EPSSetInitialVector(EPS eps,Vec vec)
161
{
162
  PetscErrorCode ierr;
163
 
164
  PetscFunctionBegin;
165
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
166
  PetscValidHeaderSpecific(vec,VEC_COOKIE,2);
167
  PetscCheckSameComm(eps,1,vec,2);
1279 slepc 168
  ierr = PetscObjectReference((PetscObject)vec);CHKERRQ(ierr);
1385 slepc 169
  if (eps->vec_initial) {
170
    ierr = VecDestroy(eps->vec_initial); CHKERRQ(ierr);
527 dsic.upv.es!antodo 171
  }
1385 slepc 172
  eps->vec_initial = vec;
527 dsic.upv.es!antodo 173
  PetscFunctionReturn(0);
174
}
175
 
176
#undef __FUNCT__  
1385 slepc 177
#define __FUNCT__ "EPSGetInitialVector"
527 dsic.upv.es!antodo 178
/*@
1385 slepc 179
   EPSGetInitialVector - Gets the initial vector associated with the
180
   eigensolver; if the vector was not set it will return a 0 pointer or
181
   a vector randomly generated by EPSSetUp().
527 dsic.upv.es!antodo 182
 
1385 slepc 183
   Not collective, but vector is shared by all processors that share the EPS
527 dsic.upv.es!antodo 184
 
185
   Input Parameter:
186
.  eps - the eigensolver context
187
 
188
   Output Parameter:
189
.  vec - the vector
190
 
191
   Level: intermediate
192
 
1385 slepc 193
.seealso: EPSSetInitialVector(), EPSGetLeftInitialVector()
527 dsic.upv.es!antodo 194
 
195
@*/
1385 slepc 196
PetscErrorCode EPSGetInitialVector(EPS eps,Vec *vec)
527 dsic.upv.es!antodo 197
{
198
  PetscFunctionBegin;
199
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1385 slepc 200
  PetscValidPointer(vec,2);
201
  *vec = eps->vec_initial;
527 dsic.upv.es!antodo 202
  PetscFunctionReturn(0);
203
}
204
 
205
#undef __FUNCT__  
780 dsic.upv.es!jroman 206
#define __FUNCT__ "EPSSetLeftInitialVector"
207
/*@
1385 slepc 208
   EPSSetLeftInitialVector - Sets the initial vector from which the eigensolver
209
   starts to iterate, corresponding to the left recurrence (two-sided solvers).
780 dsic.upv.es!jroman 210
 
211
   Collective on EPS and Vec
212
 
213
   Input Parameters:
214
+  eps - the eigensolver context
215
-  vec - the vector
216
 
217
   Level: intermediate
218
 
1385 slepc 219
.seealso: EPSGetLeftInitialVector(), EPSSetInitialVector()
780 dsic.upv.es!jroman 220
 
221
@*/
222
PetscErrorCode EPSSetLeftInitialVector(EPS eps,Vec vec)
223
{
224
  PetscErrorCode ierr;
225
 
226
  PetscFunctionBegin;
227
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
228
  PetscValidHeaderSpecific(vec,VEC_COOKIE,2);
229
  PetscCheckSameComm(eps,1,vec,2);
1295 slepc 230
  ierr = PetscObjectReference((PetscObject)vec);CHKERRQ(ierr);
1385 slepc 231
  if (eps->vec_initial_left) {
232
    ierr = VecDestroy(eps->vec_initial_left); CHKERRQ(ierr);
780 dsic.upv.es!jroman 233
  }
1385 slepc 234
  eps->vec_initial_left = vec;
780 dsic.upv.es!jroman 235
  PetscFunctionReturn(0);
236
}
237
 
238
#undef __FUNCT__  
239
#define __FUNCT__ "EPSGetLeftInitialVector"
240
/*@
1385 slepc 241
   EPSGetLeftInitialVector - Gets the left initial vector associated with the
242
   eigensolver; if the vector was not set it will return a 0 pointer or
243
   a vector randomly generated by EPSSetUp().
780 dsic.upv.es!jroman 244
 
245
   Not collective, but vector is shared by all processors that share the EPS
246
 
1385 slepc 247
   Input Parameter:
248
.  eps - the eigensolver context
780 dsic.upv.es!jroman 249
 
250
   Output Parameter:
251
.  vec - the vector
252
 
253
   Level: intermediate
254
 
1385 slepc 255
.seealso: EPSSetLeftInitialVector(), EPSGetLeftInitialVector()
780 dsic.upv.es!jroman 256
 
257
@*/
1385 slepc 258
PetscErrorCode EPSGetLeftInitialVector(EPS eps,Vec *vec)
780 dsic.upv.es!jroman 259
{
260
  PetscFunctionBegin;
261
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1385 slepc 262
  PetscValidPointer(vec,2);
263
  *vec = eps->vec_initial_left;
780 dsic.upv.es!jroman 264
  PetscFunctionReturn(0);
265
}
266
 
267
#undef __FUNCT__  
527 dsic.upv.es!antodo 268
#define __FUNCT__ "EPSSetOperators"
269
/*@
270
   EPSSetOperators - Sets the matrices associated with the eigenvalue problem.
271
 
272
   Collective on EPS and Mat
273
 
274
   Input Parameters:
275
+  eps - the eigenproblem solver context
276
.  A  - the matrix associated with the eigensystem
277
-  B  - the second matrix in the case of generalized eigenproblems
278
 
279
   Notes:
280
   To specify a standard eigenproblem, use PETSC_NULL for parameter B.
281
 
282
   Level: beginner
283
 
284
.seealso: EPSSolve(), EPSGetST(), STGetOperators()
285
@*/
286
PetscErrorCode EPSSetOperators(EPS eps,Mat A,Mat B)
287
{
288
  PetscErrorCode ierr;
982 slepc 289
  PetscInt       m,n;
527 dsic.upv.es!antodo 290
 
291
  PetscFunctionBegin;
292
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
293
  PetscValidHeaderSpecific(A,MAT_COOKIE,2);
294
  if (B) PetscValidHeaderSpecific(B,MAT_COOKIE,3);
1014 slepc 295
  PetscCheckSameComm(eps,1,A,2);
296
  if (B) PetscCheckSameComm(eps,1,B,3);
527 dsic.upv.es!antodo 297
 
298
  /* Check for square matrices */
299
  ierr = MatGetSize(A,&m,&n);CHKERRQ(ierr);
300
  if (m!=n) { SETERRQ(1,"A is a non-square matrix"); }
301
  if (B) {
302
    ierr = MatGetSize(B,&m,&n);CHKERRQ(ierr);
303
    if (m!=n) { SETERRQ(1,"B is a non-square matrix"); }
304
  }
305
 
306
  ierr = STSetOperators(eps->OP,A,B);CHKERRQ(ierr);
307
  eps->setupcalled = 0;  /* so that next solve call will call setup */
780 dsic.upv.es!jroman 308
 
309
  /* Destroy randomly generated initial vectors */
1385 slepc 310
  if (eps->vec_initial) {
311
    ierr = VecDestroy(eps->vec_initial);CHKERRQ(ierr);
312
    eps->vec_initial = PETSC_NULL;
527 dsic.upv.es!antodo 313
  }
1385 slepc 314
  if (eps->vec_initial_left) {
315
    ierr = VecDestroy(eps->vec_initial_left);CHKERRQ(ierr);
316
    eps->vec_initial_left = PETSC_NULL;
317
  }
527 dsic.upv.es!antodo 318
 
319
  PetscFunctionReturn(0);
320
}
321
 
1516 slepc 322
#undef __FUNCT__
323
#define __FUNCT__ "EPSGetOperators"
324
/*@
325
   EPSGetOperators - Gets the matrices associated with the eigensystem.
326
 
327
   Collective on EPS and Mat
328
 
329
   Input Parameter:
330
.  eps - the EPS context
331
 
332
   Output Parameters:
333
+  A  - the matrix associated with the eigensystem
334
-  B  - the second matrix in the case of generalized eigenproblems
335
 
336
   Level: intermediate
337
 
338
.seealso: EPSSolve(), EPSGetST(), STGetOperators(), STSetOperators()
339
@*/
340
PetscErrorCode EPSGetOperators(EPS eps, Mat *A, Mat *B)
341
{
342
  PetscErrorCode ierr;
343
  ST             st;
344
 
345
  PetscFunctionBegin;
346
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
347
  if (A) PetscValidPointer(A,2);
348
  if (B) PetscValidPointer(B,3);
349
  ierr = EPSGetST(eps,&st);CHKERRQ(ierr);
350
  ierr = STGetOperators(st,A,B);CHKERRQ(ierr);
351
  PetscFunctionReturn(0);
352
}
353
 
527 dsic.upv.es!antodo 354
#undef __FUNCT__  
355
#define __FUNCT__ "EPSAttachDeflationSpace"
356
/*@
357
   EPSAttachDeflationSpace - Add vectors to the basis of the deflation space.
358
 
359
   Not Collective
360
 
361
   Input Parameter:
362
+  eps   - the eigenproblem solver context
363
.  n     - number of vectors to add
364
.  ds    - set of basis vectors of the deflation space
365
-  ortho - PETSC_TRUE if basis vectors of deflation space are orthonormal
366
 
367
   Notes:
368
   When a deflation space is given, the eigensolver seeks the eigensolution
369
   in the restriction of the problem to the orthogonal complement of this
370
   space. This can be used for instance in the case that an invariant
371
   subspace is known beforehand (such as the nullspace of the matrix).
372
 
373
   The basis vectors can be provided all at once or incrementally with
374
   several calls to EPSAttachDeflationSpace().
375
 
376
   Use a value of PETSC_TRUE for parameter ortho if all the vectors passed
377
   in are known to be mutually orthonormal.
378
 
379
   Level: intermediate
380
 
381
.seealso: EPSRemoveDeflationSpace()
382
@*/
1509 slepc 383
PetscErrorCode EPSAttachDeflationSpace(EPS eps,PetscInt n,Vec *ds,PetscTruth ortho)
527 dsic.upv.es!antodo 384
{
385
  PetscErrorCode ierr;
1755 antodo 386
  PetscInt       i,nloc;
387
  Vec            *newds;
388
  PetscScalar    *pV;
527 dsic.upv.es!antodo 389
 
390
  PetscFunctionBegin;
391
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
1755 antodo 392
  if (n<=0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE, "Argument 2 out of range");
393
  /* allocate space for previous and new vectors */
394
  ierr = PetscMalloc((n+eps->nds)*sizeof(Vec), &newds);CHKERRQ(ierr);
395
  ierr = VecGetLocalSize(ds[0],&nloc);CHKERRQ(ierr);
396
  ierr = PetscMalloc((n+eps->nds)*nloc*sizeof(PetscScalar),&pV);CHKERRQ(ierr);
397
  for (i=0;i<n+eps->nds;i++) {
398
    ierr = VecCreateMPIWithArray(((PetscObject)eps)->comm,nloc,PETSC_DECIDE,pV+i*nloc,&newds[i]);CHKERRQ(ierr);
527 dsic.upv.es!antodo 399
  }
1755 antodo 400
  /* copy and free previous vectors */
527 dsic.upv.es!antodo 401
  if (eps->nds > 0) {
1755 antodo 402
    ierr = VecGetArray(eps->DS[0],&pV);CHKERRQ(ierr);
403
    for (i=0;i<eps->nds;i++) {
404
      ierr = VecCopy(eps->DS[i],newds[i]);CHKERRQ(ierr);
405
      ierr = VecDestroy(eps->DS[i]);CHKERRQ(ierr);
406
    }
407
    ierr = PetscFree(pV);CHKERRQ(ierr);
408
    ierr = PetscFree(eps->DS);CHKERRQ(ierr);
527 dsic.upv.es!antodo 409
  }
1755 antodo 410
  /* copy new vectors */
411
  eps->DS = newds;
527 dsic.upv.es!antodo 412
  for (i=0; i<n; i++) {
413
    ierr = VecCopy(ds[i],eps->DS[i + eps->nds]);CHKERRQ(ierr);
414
  }
415
  eps->nds += n;
416
  if (!ortho) eps->ds_ortho = PETSC_FALSE;
417
  eps->setupcalled = 0;
418
  PetscFunctionReturn(0);
419
}
420
 
421
#undef __FUNCT__  
422
#define __FUNCT__ "EPSRemoveDeflationSpace"
423
/*@
424
   EPSRemoveDeflationSpace - Removes the deflation space.
425
 
426
   Not Collective
427
 
428
   Input Parameter:
429
.  eps   - the eigenproblem solver context
430
 
431
   Level: intermediate
432
 
433
.seealso: EPSAttachDeflationSpace()
434
@*/
435
PetscErrorCode EPSRemoveDeflationSpace(EPS eps)
436
{
437
  PetscErrorCode ierr;
1695 slepc 438
  PetscInt       i;
1755 antodo 439
  PetscScalar    *pV;
527 dsic.upv.es!antodo 440
 
441
  PetscFunctionBegin;
442
  PetscValidHeaderSpecific(eps,EPS_COOKIE,1);
443
  if (eps->nds > 0) {
1755 antodo 444
    ierr = VecGetArray(eps->DS[0],&pV);CHKERRQ(ierr);
1695 slepc 445
    for (i=0;i<eps->nds;i++) {
446
      ierr = VecDestroy(eps->DS[i]);CHKERRQ(ierr);
447
    }
1755 antodo 448
    ierr = PetscFree(pV);CHKERRQ(ierr);
1695 slepc 449
    ierr = PetscFree(eps->DS);CHKERRQ(ierr);
527 dsic.upv.es!antodo 450
  }
451
  eps->ds_ortho = PETSC_TRUE;
452
  eps->setupcalled = 0;
453
  PetscFunctionReturn(0);
454
}