Subversion Repositories slepc-dev

Rev

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