Subversion Repositories slepc-dev

Rev

Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2771 jroman 1
/*
2
   PS operations: PSSolve(), PSSort(), etc
3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
6
   Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
7
 
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/>.
21
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22
*/
23
 
24
#include <slepc-private/psimpl.h>      /*I "slepcps.h" I*/
25
 
26
#undef __FUNCT__  
27
#define __FUNCT__ "PSGetLeadingDimension"
28
/*@
29
   PSGetLeadingDimension - Returns the leading dimension of the allocated
30
   matrices.
31
 
32
   Not Collective
33
 
34
   Input Parameter:
35
.  ps - the projected system context
36
 
37
   Output Parameter:
38
.  ld - leading dimension (maximum allowed dimension for the matrices)
39
 
40
   Level: advanced
41
 
42
.seealso: PSAllocate(), PSSetDimensions()
43
@*/
44
PetscErrorCode PSGetLeadingDimension(PS ps,PetscInt *ld)
45
{
46
  PetscFunctionBegin;
47
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
48
  if (ld) *ld = ps->ld;
49
  PetscFunctionReturn(0);
50
}
51
 
52
#undef __FUNCT__  
53
#define __FUNCT__ "PSSetState"
54
/*@
55
   PSSetState - Change the state of the PS object.
56
 
57
   Collective on PS
58
 
59
   Input Parameters:
60
+  ps    - the projected system context
61
-  state - the new state
62
 
63
   Notes:
64
   The state indicates that the projected system is in an initial state (raw),
65
   in an intermediate state (such as tridiagonal, Hessenberg or
66
   Hessenberg-triangular), in a condensed state (such as diagonal, Schur or
67
   generalized Schur), or in a sorted condensed state (according to a given
68
   sorting criterion).
69
 
70
   This function is normally used to return to the raw state when the
71
   condensed structure is destroyed.
72
 
73
   Level: advanced
74
 
75
.seealso: PSGetState()
76
@*/
77
PetscErrorCode PSSetState(PS ps,PSStateType state)
78
{
79
  PetscErrorCode ierr;
80
 
81
  PetscFunctionBegin;
82
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
83
  PetscValidLogicalCollectiveEnum(ps,state,2);
84
  switch (state) {
85
    case PS_STATE_RAW:
86
    case PS_STATE_INTERMEDIATE:
87
    case PS_STATE_CONDENSED:
88
    case PS_STATE_SORTED:
89
      if (ps->state<state) { ierr = PetscInfo(ps,"PS state has been increased\n");CHKERRQ(ierr); }
90
      ps->state = state;
91
      break;
92
    default:
93
      SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONG,"Wrong state");
94
  }
95
  PetscFunctionReturn(0);
96
}
97
 
98
#undef __FUNCT__  
99
#define __FUNCT__ "PSGetState"
100
/*@
101
   PSGetState - Returns the current state.
102
 
103
   Not Collective
104
 
105
   Input Parameter:
106
.  ps - the projected system context
107
 
108
   Output Parameter:
109
.  state - current state
110
 
111
   Level: advanced
112
 
113
.seealso: PSSetState()
114
@*/
115
PetscErrorCode PSGetState(PS ps,PSStateType *state)
116
{
117
  PetscFunctionBegin;
118
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
119
  if (state) *state = ps->state;
120
  PetscFunctionReturn(0);
121
}
122
 
123
#undef __FUNCT__  
124
#define __FUNCT__ "PSSetDimensions"
125
/*@
126
   PSSetDimensions - Resize the matrices in the PS object.
127
 
128
   Collective on PS
129
 
130
   Input Parameters:
131
+  ps - the projected system context
132
.  n  - the new size
133
.  l  - number of locked (inactive) leading columns
134
-  k  - intermediate dimension (e.g., position of arrow)
135
 
136
   Note:
137
   The internal arrays are not reallocated.
138
 
139
   Level: advanced
140
 
141
.seealso: PSGetDimensions(), PSAllocate()
142
@*/
143
PetscErrorCode PSSetDimensions(PS ps,PetscInt n,PetscInt l,PetscInt k)
144
{
145
  PetscFunctionBegin;
146
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
147
  PetscValidLogicalCollectiveInt(ps,n,2);
148
  PetscValidLogicalCollectiveInt(ps,l,3);
149
  PetscValidLogicalCollectiveInt(ps,k,4);
150
  if (!ps->ld) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ORDER,"Must call PSAllocate() first");
151
  if (n!=PETSC_IGNORE) {
152
    if (n==PETSC_DECIDE || n==PETSC_DEFAULT) {
153
      ps->n = ps->ld;
154
    } else {
155
      if (n<1 || n>ps->ld) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of n. Must be between 1 and ld");
156
      ps->n = n;
157
    }
158
  }
159
  if (l!=PETSC_IGNORE) {
160
    if (l==PETSC_DECIDE || l==PETSC_DEFAULT) {
161
      ps->l = 0;
162
    } else {
163
      if (l<0 || l>ps->n) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of l. Must be between 0 and n");
164
      ps->l = l;
165
    }
166
  }
167
  if (k!=PETSC_IGNORE) {
168
    if (k==PETSC_DECIDE || k==PETSC_DEFAULT) {
169
      ps->k = ps->n/2;
170
    } else {
171
      if (k<0 || k>ps->n) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_OUTOFRANGE,"Illegal value of k. Must be between 0 and n");
172
      ps->k = k;
173
    }
174
  }
175
  PetscFunctionReturn(0);
176
}
177
 
178
#undef __FUNCT__  
179
#define __FUNCT__ "PSGetDimensions"
180
/*@
181
   PSGetDimensions - Returns the current dimensions.
182
 
183
   Not Collective
184
 
185
   Input Parameter:
186
.  ps - the projected system context
187
 
188
   Output Parameter:
189
.  state - current dimensions
190
 
191
   Level: advanced
192
 
193
.seealso: PSSetDimensions()
194
@*/
195
PetscErrorCode PSGetDimensions(PS ps,PetscInt *n,PetscInt *l,PetscInt *k)
196
{
197
  PetscFunctionBegin;
198
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
199
  if (n) *n = ps->n;
200
  if (l) *l = ps->l;
201
  if (k) *k = ps->k;
202
  PetscFunctionReturn(0);
203
}
204
 
205
#undef __FUNCT__  
206
#define __FUNCT__ "PSGetArray"
207
/*@C
208
   PSGetArray - Returns a pointer to one of the internal arrays used to
209
   represent matrices. You MUST call PSRestoreArray() when you no longer
210
   need to access the array.
211
 
212
   Not Collective
213
 
214
   Input Parameters:
215
+  ps - the projected system context
216
-  m - the requested matrix
217
 
218
   Output Parameter:
219
.  a - pointer to the values
220
 
221
   Level: advanced
222
 
223
.seealso: PSRestoreArray(), PSGetArrayReal()
224
@*/
225
PetscErrorCode PSGetArray(PS ps,PSMatType m,PetscScalar *a[])
226
{
227
  PetscFunctionBegin;
228
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
229
  PetscValidPointer(a,2);
230
  if (m<0 || m>=PS_NUM_MAT) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONG,"Invalid matrix");
231
  if (!ps->ld) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ORDER,"Must call PSAllocate() first");
232
  if (!ps->mat[m]) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONGSTATE,"Requested matrix was not created in this PS");
233
  *a = ps->mat[m];
234
  CHKMEMQ;
235
  PetscFunctionReturn(0);
236
}
237
 
238
#undef __FUNCT__  
239
#define __FUNCT__ "PSRestoreArray"
240
/*@C
241
   PSRestoreArray - Restores the matrix after PSGetArray() was called.
242
 
243
   Not Collective
244
 
245
   Input Parameters:
246
+  ps - the projected system context
247
.  m - the requested matrix
248
-  a - pointer to the values
249
 
250
   Level: advanced
251
 
252
.seealso: PSGetArray(), PSGetArrayReal()
253
@*/
254
PetscErrorCode PSRestoreArray(PS ps,PSMatType m,PetscScalar *a[])
255
{
256
  PetscErrorCode ierr;
257
 
258
  PetscFunctionBegin;
259
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
260
  PetscValidPointer(a,2);
261
  if (m<0 || m>=PS_NUM_MAT) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONG,"Invalid matrix");
262
  CHKMEMQ;
263
  *a = 0;
264
  ierr = PetscObjectStateIncrease((PetscObject)ps);CHKERRQ(ierr);
265
  PetscFunctionReturn(0);
266
}
267
 
268
#undef __FUNCT__  
2775 jroman 269
#define __FUNCT__ "PSGetArrayReal"
270
/*@C
271
   PSGetArrayReal - Returns a pointer to one of the internal arrays used to
272
   represent real matrices. You MUST call PSRestoreArray() when you no longer
273
   need to access the array.
274
 
275
   Not Collective
276
 
277
   Input Parameters:
278
+  ps - the projected system context
279
-  m - the requested matrix
280
 
281
   Output Parameter:
282
.  a - pointer to the values
283
 
284
   Level: advanced
285
 
286
.seealso: PSRestoreArrayReal(), PSGetArray()
287
@*/
288
PetscErrorCode PSGetArrayReal(PS ps,PSMatType m,PetscReal *a[])
289
{
290
  PetscFunctionBegin;
291
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
292
  PetscValidPointer(a,2);
293
  if (m<0 || m>=PS_NUM_MAT) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONG,"Invalid matrix");
294
  if (!ps->ld) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ORDER,"Must call PSAllocate() first");
295
  if (!ps->rmat[m]) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONGSTATE,"Requested matrix was not created in this PS");
296
  *a = ps->rmat[m];
297
  CHKMEMQ;
298
  PetscFunctionReturn(0);
299
}
300
 
301
#undef __FUNCT__  
302
#define __FUNCT__ "PSRestoreArrayReal"
303
/*@C
304
   PSRestoreArrayReal - Restores the matrix after PSGetArrayReal() was called.
305
 
306
   Not Collective
307
 
308
   Input Parameters:
309
+  ps - the projected system context
310
.  m - the requested matrix
311
-  a - pointer to the values
312
 
313
   Level: advanced
314
 
315
.seealso: PSGetArrayReal(), PSGetArray()
316
@*/
317
PetscErrorCode PSRestoreArrayReal(PS ps,PSMatType m,PetscReal *a[])
318
{
319
  PetscErrorCode ierr;
320
 
321
  PetscFunctionBegin;
322
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
323
  PetscValidPointer(a,2);
324
  if (m<0 || m>=PS_NUM_MAT) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ARG_WRONG,"Invalid matrix");
325
  CHKMEMQ;
326
  *a = 0;
327
  ierr = PetscObjectStateIncrease((PetscObject)ps);CHKERRQ(ierr);
328
  PetscFunctionReturn(0);
329
}
330
 
331
#undef __FUNCT__  
2771 jroman 332
#define __FUNCT__ "PSSolve"
333
/*@
334
   PSSolve - Solves the problem.
335
 
336
   Not Collective
337
 
338
   Input Parameters:
339
+  ps   - the projected system context
340
.  eigr - array to store the computed eigenvalues (real part)
341
-  eigi - array to store the computed eigenvalues (imaginary part)
342
 
343
   Note:
344
   This call brings the projected system to condensed form. No ordering
345
   is enforced, call PSSort() later if you want the solution sorted.
346
 
347
   Level: advanced
348
 
349
.seealso: PSSort()
350
@*/
351
PetscErrorCode PSSolve(PS ps,PetscScalar *eigr,PetscScalar *eigi)
352
{
353
  PetscErrorCode ierr;
354
 
355
  PetscFunctionBegin;
356
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
2775 jroman 357
  PetscValidPointer(eigr,2);
2771 jroman 358
  if (!ps->ld) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ORDER,"Must call PSAllocate() first");
359
  if (!ps->ops->solve) SETERRQ1(((PetscObject)ps)->comm,PETSC_ERR_SUP,"PS type %s",((PetscObject)ps)->type_name);
360
  ierr = PetscLogEventBegin(PS_Solve,ps,0,0,0);CHKERRQ(ierr);
361
  ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
362
  ierr = (*ps->ops->solve)(ps,eigr,eigi);CHKERRQ(ierr);
363
  ierr = PetscFPTrapPop();CHKERRQ(ierr);
364
  ierr = PetscLogEventEnd(PS_Solve,ps,0,0,0);CHKERRQ(ierr);
365
  ps->state = PS_STATE_CONDENSED;
366
  ierr = PetscObjectStateIncrease((PetscObject)ps);CHKERRQ(ierr);
367
  PetscFunctionReturn(0);
368
}
369
 
370
#undef __FUNCT__  
371
#define __FUNCT__ "PSCond"
372
/*@C
373
   PSCond - Compute the inf-norm condition number of the first matrix
374
   as cond(A) = norm(A)*norm(inv(A)).
375
 
376
   Not Collective
377
 
378
   Input Parameters:
379
+  ps - the projected system context
380
-  cond - the computed condition number
381
 
382
   Level: advanced
383
 
384
.seealso: PSSolve()
385
@*/
386
PetscErrorCode PSCond(PS ps,PetscReal *cond)
387
{
388
  PetscErrorCode ierr;
389
 
390
  PetscFunctionBegin;
391
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
2775 jroman 392
  PetscValidPointer(cond,2);
2771 jroman 393
  if (!ps->ops->cond) SETERRQ1(((PetscObject)ps)->comm,PETSC_ERR_SUP,"PS type %s",((PetscObject)ps)->type_name);
394
  ierr = PetscLogEventBegin(PS_Other,ps,0,0,0);CHKERRQ(ierr);
395
  ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
396
  ierr = (*ps->ops->cond)(ps,cond);CHKERRQ(ierr);
397
  ierr = PetscFPTrapPop();CHKERRQ(ierr);
398
  ierr = PetscLogEventEnd(PS_Other,ps,0,0,0);CHKERRQ(ierr);
399
  PetscFunctionReturn(0);
400
}
401
 
402
#undef __FUNCT__  
403
#define __FUNCT__ "PSSort"
404
/*@C
405
   PSSort - Reorders the condensed form computed by PSSolve() according to
406
   a given sorting criterion.
407
 
408
   Not Collective
409
 
410
   Input Parameters:
411
+  ps - the projected system context
412
.  eigr - array to store the sorted eigenvalues (real part)
413
-  eigi - array to store the sorted eigenvalues (imaginary part)
414
 
415
   Level: advanced
416
 
417
.seealso: PSSolve()
418
@*/
419
PetscErrorCode PSSort(PS ps,PetscScalar *eigr,PetscScalar *eigi,PetscErrorCode (*comp_func)(PetscScalar,PetscScalar,PetscScalar,PetscScalar,PetscInt*,void*),void *comp_ctx)
420
{
421
  PetscErrorCode ierr;
422
 
423
  PetscFunctionBegin;
424
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
2775 jroman 425
  PetscValidPointer(eigr,2);
2771 jroman 426
  if (ps->state!=PS_STATE_CONDENSED) SETERRQ(((PetscObject)ps)->comm,PETSC_ERR_ORDER,"Must call PSSolve() first");
427
  if (!ps->ops->sort) SETERRQ1(((PetscObject)ps)->comm,PETSC_ERR_SUP,"PS type %s",((PetscObject)ps)->type_name);
428
  ierr = PetscLogEventBegin(PS_Sort,ps,0,0,0);CHKERRQ(ierr);
429
  ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
430
  ierr = (*ps->ops->sort)(ps,eigr,eigi,comp_func,comp_ctx);CHKERRQ(ierr);
431
  ierr = PetscFPTrapPop();CHKERRQ(ierr);
432
  ierr = PetscLogEventEnd(PS_Sort,ps,0,0,0);CHKERRQ(ierr);
433
  ps->state = PS_STATE_SORTED;
434
  ierr = PetscObjectStateIncrease((PetscObject)ps);CHKERRQ(ierr);
435
  PetscFunctionReturn(0);
436
}
437
 
2772 jroman 438
#undef __FUNCT__  
439
#define __FUNCT__ "PSTranslateHarmonic"
440
/*@C
441
   PSTranslateHarmonic - Computes a translation of the projected matrix.
442
 
443
   Not Collective
444
 
445
   Input Parameters:
2773 jroman 446
+  ps      - the projected system context
447
.  tau     - the translation amount
448
.  beta    - last component of vector b
449
-  recover - boolean flag to indicate whether to recover or not
2772 jroman 450
 
2773 jroman 451
   Output Parameters:
452
+  g       - the computed vector (optional)
453
-  gamma   - scale factor (optional)
454
 
2772 jroman 455
   Notes:
456
   This function is intended for use in the context of Krylov methods only.
457
   It computes a translation of a Krylov decomposition in order to extract
458
   eigenpair approximations by harmonic Rayleigh-Ritz.
2773 jroman 459
   The matrix is updated as A + g*b' where g = (A-tau*eye(n))'\b and
2772 jroman 460
   vector b is assumed to be beta*e_n^T.
461
 
2773 jroman 462
   The gamma factor is defined as sqrt(1+g'*g) and can be interpreted as
463
   the factor by which the residual of the Krylov decomposition is scaled.
464
 
465
   If the recover flag is activated, the computed translation undoes the
466
   translation done previously. In that case, parameter tau is ignored.
467
 
2772 jroman 468
   Level: developer
469
@*/
2774 jroman 470
PetscErrorCode PSTranslateHarmonic(PS ps,PetscScalar tau,PetscReal beta,PetscBool recover,PetscScalar *g,PetscReal *gamma)
2772 jroman 471
{
472
  PetscErrorCode ierr;
473
 
474
  PetscFunctionBegin;
475
  PetscValidHeaderSpecific(ps,PS_CLASSID,1);
476
  if (!ps->ops->translate) SETERRQ1(((PetscObject)ps)->comm,PETSC_ERR_SUP,"PS type %s",((PetscObject)ps)->type_name);
477
  ierr = PetscLogEventBegin(PS_Other,ps,0,0,0);CHKERRQ(ierr);
478
  ierr = PetscFPTrapPush(PETSC_FP_TRAP_OFF);CHKERRQ(ierr);
2773 jroman 479
  ierr = (*ps->ops->translate)(ps,tau,beta,recover,g,gamma);CHKERRQ(ierr);
2772 jroman 480
  ierr = PetscFPTrapPop();CHKERRQ(ierr);
481
  ierr = PetscLogEventEnd(PS_Other,ps,0,0,0);CHKERRQ(ierr);
482
  ps->state = PS_STATE_RAW;
483
  ierr = PetscObjectStateIncrease((PetscObject)ps);CHKERRQ(ierr);
484
  PetscFunctionReturn(0);
485
}
486