Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
352 dsic.upv.es!antodo 1
/*
354 dsic.upv.es!jroman 2
      Implements the Cayley spectral transform.
1376 slepc 3
 
4
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1672 slepc 5
   SLEPc - Scalable Library for Eigenvalue Problem Computations
2575 eromero 6
   Copyright (c) 2002-2011, Universitat 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
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
352 dsic.upv.es!antodo 22
*/
1376 slepc 23
 
2283 jroman 24
#include <private/stimpl.h>          /*I "slepcst.h" I*/
352 dsic.upv.es!antodo 25
 
26
typedef struct {
2091 jroman 27
  PetscScalar nu;
2216 jroman 28
  PetscBool   nu_set;
352 dsic.upv.es!antodo 29
  Vec         w2;
30
} ST_CAYLEY;
31
 
32
#undef __FUNCT__  
33
#define __FUNCT__ "STApply_Cayley"
476 dsic.upv.es!antodo 34
PetscErrorCode STApply_Cayley(ST st,Vec x,Vec y)
352 dsic.upv.es!antodo 35
{
476 dsic.upv.es!antodo 36
  PetscErrorCode ierr;
2331 jroman 37
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
2091 jroman 38
  PetscScalar    nu = ctx->nu;
352 dsic.upv.es!antodo 39
 
354 dsic.upv.es!jroman 40
  PetscFunctionBegin;
2091 jroman 41
  if (st->shift_matrix == ST_MATMODE_INPLACE) { nu = nu + st->sigma; };
352 dsic.upv.es!antodo 42
 
43
  if (st->B) {
44
    /* generalized eigenproblem: y = (A - sB)^-1 (A + tB)x */
45
    ierr = MatMult(st->A,x,st->w);CHKERRQ(ierr);
46
    ierr = MatMult(st->B,x,ctx->w2);CHKERRQ(ierr);
2091 jroman 47
    ierr = VecAXPY(st->w,nu,ctx->w2);CHKERRQ(ierr);    
352 dsic.upv.es!antodo 48
    ierr = STAssociatedKSPSolve(st,st->w,y);CHKERRQ(ierr);
49
  }
50
  else {
51
    /* standard eigenproblem: y = (A - sI)^-1 (A + tI)x */
52
    ierr = MatMult(st->A,x,st->w);CHKERRQ(ierr);
2091 jroman 53
    ierr = VecAXPY(st->w,nu,x);CHKERRQ(ierr);
352 dsic.upv.es!antodo 54
    ierr = STAssociatedKSPSolve(st,st->w,y);CHKERRQ(ierr);
55
  }
56
  PetscFunctionReturn(0);
57
}
58
 
59
#undef __FUNCT__  
780 dsic.upv.es!jroman 60
#define __FUNCT__ "STApplyTranspose_Cayley"
61
PetscErrorCode STApplyTranspose_Cayley(ST st,Vec x,Vec y)
62
{
63
  PetscErrorCode ierr;
2331 jroman 64
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
2091 jroman 65
  PetscScalar    nu = ctx->nu;
780 dsic.upv.es!jroman 66
 
67
  PetscFunctionBegin;
2091 jroman 68
  if (st->shift_matrix == ST_MATMODE_INPLACE) { nu = nu + st->sigma; };
780 dsic.upv.es!jroman 69
 
70
  if (st->B) {
71
    /* generalized eigenproblem: y = (A + tB)^T (A - sB)^-T x */
1796 jroman 72
    ierr = STAssociatedKSPSolveTranspose(st,x,st->w);CHKERRQ(ierr);
73
    ierr = MatMultTranspose(st->A,st->w,y);CHKERRQ(ierr);
74
    ierr = MatMultTranspose(st->B,st->w,ctx->w2);CHKERRQ(ierr);
2091 jroman 75
    ierr = VecAXPY(y,nu,ctx->w2);CHKERRQ(ierr);    
780 dsic.upv.es!jroman 76
  }
77
  else {
78
    /* standard eigenproblem: y =  (A + tI)^T (A - sI)^-T x */
1796 jroman 79
    ierr = STAssociatedKSPSolveTranspose(st,x,st->w);CHKERRQ(ierr);
80
    ierr = MatMultTranspose(st->A,st->w,y);CHKERRQ(ierr);
2091 jroman 81
    ierr = VecAXPY(y,nu,st->w);CHKERRQ(ierr);
780 dsic.upv.es!jroman 82
  }
83
  PetscFunctionReturn(0);
84
}
85
 
86
#undef __FUNCT__  
1358 slepc 87
#define __FUNCT__ "STBilinearMatMult_Cayley"
88
PetscErrorCode STBilinearMatMult_Cayley(Mat B,Vec x,Vec y)
352 dsic.upv.es!antodo 89
{
476 dsic.upv.es!antodo 90
  PetscErrorCode ierr;
1358 slepc 91
  ST             st;
92
  ST_CAYLEY      *ctx;
2091 jroman 93
  PetscScalar    nu;
352 dsic.upv.es!antodo 94
 
354 dsic.upv.es!jroman 95
  PetscFunctionBegin;
1358 slepc 96
  ierr = MatShellGetContext(B,(void**)&st);CHKERRQ(ierr);
2331 jroman 97
  ctx = (ST_CAYLEY*)st->data;
2091 jroman 98
  nu = ctx->nu;
1358 slepc 99
 
2091 jroman 100
  if (st->shift_matrix == ST_MATMODE_INPLACE) { nu = nu + st->sigma; };
352 dsic.upv.es!antodo 101
 
102
  if (st->B) {
103
    /* generalized eigenproblem: y = (A + tB)x */
354 dsic.upv.es!jroman 104
    ierr = MatMult(st->A,x,y);CHKERRQ(ierr);
352 dsic.upv.es!antodo 105
    ierr = MatMult(st->B,x,ctx->w2);CHKERRQ(ierr);
2091 jroman 106
    ierr = VecAXPY(y,nu,ctx->w2);CHKERRQ(ierr);    
352 dsic.upv.es!antodo 107
  }
108
  else {
109
    /* standard eigenproblem: y = (A + tI)x */
354 dsic.upv.es!jroman 110
    ierr = MatMult(st->A,x,y);CHKERRQ(ierr);
2091 jroman 111
    ierr = VecAXPY(y,nu,x);CHKERRQ(ierr);
352 dsic.upv.es!antodo 112
  }
113
  PetscFunctionReturn(0);
114
}
115
 
116
#undef __FUNCT__  
1358 slepc 117
#define __FUNCT__ "STGetBilinearForm_Cayley"
118
PetscErrorCode STGetBilinearForm_Cayley(ST st,Mat *B)
119
{
120
  PetscErrorCode ierr;
121
  PetscInt       n,m;
122
 
123
  PetscFunctionBegin;
124
  ierr = MatGetLocalSize(st->B,&n,&m);CHKERRQ(ierr);
1422 slepc 125
  ierr = MatCreateShell(((PetscObject)st)->comm,n,m,PETSC_DETERMINE,PETSC_DETERMINE,st,B);CHKERRQ(ierr);
2317 jroman 126
  ierr = MatShellSetOperation(*B,MATOP_MULT,(void(*)(void))STBilinearMatMult_Cayley);CHKERRQ(ierr);
1358 slepc 127
  PetscFunctionReturn(0);
128
}
129
 
130
#undef __FUNCT__  
352 dsic.upv.es!antodo 131
#define __FUNCT__ "STBackTransform_Cayley"
1779 antodo 132
PetscErrorCode STBackTransform_Cayley(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
352 dsic.upv.es!antodo 133
{
2331 jroman 134
  ST_CAYLEY   *ctx = (ST_CAYLEY*)st->data;
1778 antodo 135
  PetscInt    j;
2320 jroman 136
#if !defined(PETSC_USE_COMPLEX)
352 dsic.upv.es!antodo 137
  PetscScalar t,i,r;
2317 jroman 138
#endif
139
 
352 dsic.upv.es!antodo 140
  PetscFunctionBegin;
2320 jroman 141
#if !defined(PETSC_USE_COMPLEX)
1778 antodo 142
  for (j=0;j<n;j++) {
2091 jroman 143
    if (eigi[j] == 0.0) eigr[j] = (ctx->nu + eigr[j] * st->sigma) / (eigr[j] - 1.0);
1778 antodo 144
    else {
145
      r = eigr[j];
146
      i = eigi[j];
2091 jroman 147
      r = st->sigma * (r * r + i * i - r) + ctx->nu * (r - 1);
148
      i = - st->sigma * i - ctx->nu * i;
1778 antodo 149
      t = i * i + r * (r - 2.0) + 1.0;    
150
      eigr[j] = r / t;
151
      eigi[j] = i / t;    
152
    }
352 dsic.upv.es!antodo 153
  }
154
#else
1778 antodo 155
  for (j=0;j<n;j++) {
2091 jroman 156
    eigr[j] = (ctx->nu + eigr[j] * st->sigma) / (eigr[j] - 1.0);
1778 antodo 157
  }
352 dsic.upv.es!antodo 158
#endif
159
  PetscFunctionReturn(0);
160
}
161
 
162
#undef __FUNCT__  
1029 slepc 163
#define __FUNCT__ "STPostSolve_Cayley"
164
PetscErrorCode STPostSolve_Cayley(ST st)
352 dsic.upv.es!antodo 165
{
476 dsic.upv.es!antodo 166
  PetscErrorCode ierr;
352 dsic.upv.es!antodo 167
 
168
  PetscFunctionBegin;
1940 jroman 169
  if (st->shift_matrix == ST_MATMODE_INPLACE) {
828 dsic.upv.es!antodo 170
    if (st->B) {
171
      ierr = MatAXPY(st->A,st->sigma,st->B,st->str);CHKERRQ(ierr);
2654 jroman 172
    } else {
173
      ierr = MatShift(st->A,st->sigma);CHKERRQ(ierr);
828 dsic.upv.es!antodo 174
    }
352 dsic.upv.es!antodo 175
    st->setupcalled = 0;
176
  }
177
  PetscFunctionReturn(0);
178
}
179
 
180
#undef __FUNCT__  
181
#define __FUNCT__ "STSetUp_Cayley"
476 dsic.upv.es!antodo 182
PetscErrorCode STSetUp_Cayley(ST st)
352 dsic.upv.es!antodo 183
{
476 dsic.upv.es!antodo 184
  PetscErrorCode ierr;
2331 jroman 185
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
352 dsic.upv.es!antodo 186
 
187
  PetscFunctionBegin;
2305 jroman 188
  ierr = MatDestroy(&st->mat);CHKERRQ(ierr);
2074 jroman 189
 
190
  /* if the user did not set the shift, use the target value */
191
  if (!st->sigma_set) st->sigma = st->defsigma;
192
 
2091 jroman 193
  if (!ctx->nu_set) { ctx->nu = st->sigma; }
194
  if (ctx->nu == 0.0 &&  st->sigma == 0.0) {
2214 jroman 195
    SETERRQ(((PetscObject)st)->comm,1,"Values of shift and antishift cannot be zero simultaneously");
359 dsic.upv.es!antodo 196
  }
197
 
2364 jroman 198
  if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
352 dsic.upv.es!antodo 199
  switch (st->shift_matrix) {
1940 jroman 200
  case ST_MATMODE_INPLACE:
359 dsic.upv.es!antodo 201
    st->mat = PETSC_NULL;
352 dsic.upv.es!antodo 202
    if (st->sigma != 0.0) {
203
      if (st->B) {
828 dsic.upv.es!antodo 204
        ierr = MatAXPY(st->A,-st->sigma,st->B,st->str);CHKERRQ(ierr);
352 dsic.upv.es!antodo 205
      } else {
828 dsic.upv.es!antodo 206
        ierr = MatShift(st->A,-st->sigma);CHKERRQ(ierr);
352 dsic.upv.es!antodo 207
      }
208
    }
1241 slepc 209
    ierr = KSPSetOperators(st->ksp,st->A,st->A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
352 dsic.upv.es!antodo 210
    break;
1940 jroman 211
  case ST_MATMODE_SHELL:
352 dsic.upv.es!antodo 212
    ierr = STMatShellCreate(st,&st->mat);CHKERRQ(ierr);
213
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
214
    break;
215
  default:
216
    ierr = MatDuplicate(st->A,MAT_COPY_VALUES,&st->mat);CHKERRQ(ierr);
217
    if (st->sigma != 0.0) {
218
      if (st->B) {
828 dsic.upv.es!antodo 219
        ierr = MatAXPY(st->mat,-st->sigma,st->B,st->str);CHKERRQ(ierr);
352 dsic.upv.es!antodo 220
      } else {
828 dsic.upv.es!antodo 221
        ierr = MatShift(st->mat,-st->sigma);CHKERRQ(ierr);
352 dsic.upv.es!antodo 222
      }
223
    }
1241 slepc 224
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
352 dsic.upv.es!antodo 225
  }
226
  if (st->B) {
2305 jroman 227
    ierr = VecDestroy(&ctx->w2);CHKERRQ(ierr);
228
    ierr = MatGetVecs(st->B,&ctx->w2,PETSC_NULL);CHKERRQ(ierr);
359 dsic.upv.es!antodo 229
  }
352 dsic.upv.es!antodo 230
  ierr = KSPSetUp(st->ksp);CHKERRQ(ierr);
231
  PetscFunctionReturn(0);
232
}
233
 
234
#undef __FUNCT__  
235
#define __FUNCT__ "STSetShift_Cayley"
476 dsic.upv.es!antodo 236
PetscErrorCode STSetShift_Cayley(ST st,PetscScalar newshift)
352 dsic.upv.es!antodo 237
{
476 dsic.upv.es!antodo 238
  PetscErrorCode ierr;
2331 jroman 239
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
1241 slepc 240
  MatStructure   flg;
352 dsic.upv.es!antodo 241
 
242
  PetscFunctionBegin;
2091 jroman 243
  if (!ctx->nu_set) { ctx->nu = newshift; }
244
  if (ctx->nu == 0.0 &&  newshift == 0.0) {
2214 jroman 245
    SETERRQ(((PetscObject)st)->comm,1,"Values of shift and antishift cannot be zero simultaneously");
1241 slepc 246
  }
352 dsic.upv.es!antodo 247
 
248
  /* Nothing to be done if STSetUp has not been called yet */
249
  if (!st->setupcalled) PetscFunctionReturn(0);
250
 
1241 slepc 251
  /* Check if the new KSP matrix has the same zero structure */
252
  if (st->B && st->str == DIFFERENT_NONZERO_PATTERN && (st->sigma == 0.0 || newshift == 0.0)) {
253
    flg = DIFFERENT_NONZERO_PATTERN;
254
  } else {
255
    flg = SAME_NONZERO_PATTERN;
256
  }
257
 
352 dsic.upv.es!antodo 258
  switch (st->shift_matrix) {
1940 jroman 259
  case ST_MATMODE_INPLACE:
352 dsic.upv.es!antodo 260
    /* Undo previous operations */
261
    if (st->sigma != 0.0) {
2654 jroman 262
      if (st->B) {
828 dsic.upv.es!antodo 263
        ierr = MatAXPY(st->A,st->sigma,st->B,st->str);CHKERRQ(ierr);
264
      } else {
265
        ierr = MatShift(st->A,st->sigma);CHKERRQ(ierr);
266
      }
352 dsic.upv.es!antodo 267
    }
268
    /* Apply new shift */
269
    if (newshift != 0.0) {
2654 jroman 270
      if (st->B) {
828 dsic.upv.es!antodo 271
        ierr = MatAXPY(st->A,-newshift,st->B,st->str);CHKERRQ(ierr);
272
      } else {
273
        ierr = MatShift(st->A,-newshift);CHKERRQ(ierr);
274
      }
352 dsic.upv.es!antodo 275
    }
1241 slepc 276
    ierr = KSPSetOperators(st->ksp,st->A,st->A,flg);CHKERRQ(ierr);
352 dsic.upv.es!antodo 277
    break;
1940 jroman 278
  case ST_MATMODE_SHELL:
2654 jroman 279
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
352 dsic.upv.es!antodo 280
    break;
281
  default:
2654 jroman 282
    ierr = MatCopy(st->A,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
352 dsic.upv.es!antodo 283
    if (newshift != 0.0) {  
828 dsic.upv.es!antodo 284
      if (st->B) { ierr = MatAXPY(st->mat,-newshift,st->B,st->str);CHKERRQ(ierr); }
285
      else { ierr = MatShift(st->mat,-newshift);CHKERRQ(ierr); }
352 dsic.upv.es!antodo 286
    }
1241 slepc 287
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,flg);CHKERRQ(ierr);    
352 dsic.upv.es!antodo 288
  }
289
  st->sigma = newshift;
290
  ierr = KSPSetUp(st->ksp);CHKERRQ(ierr);
291
  PetscFunctionReturn(0);
292
}
293
 
294
#undef __FUNCT__  
359 dsic.upv.es!antodo 295
#define __FUNCT__ "STSetFromOptions_Cayley"
476 dsic.upv.es!antodo 296
PetscErrorCode STSetFromOptions_Cayley(ST st)
297
{
298
  PetscErrorCode ierr;
2091 jroman 299
  PetscScalar    nu;
2216 jroman 300
  PetscBool      flg;
2331 jroman 301
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
2005 eromero 302
  PC             pc;
303
  const PCType   pctype;
304
  const KSPType  ksptype;
359 dsic.upv.es!antodo 305
 
306
  PetscFunctionBegin;
2364 jroman 307
  if (!st->ksp) { ierr = STGetKSP(st,&st->ksp);CHKERRQ(ierr); }
2005 eromero 308
  ierr = KSPGetPC(st->ksp,&pc);CHKERRQ(ierr);
309
  ierr = KSPGetType(st->ksp,&ksptype);CHKERRQ(ierr);
310
  ierr = PCGetType(pc,&pctype);CHKERRQ(ierr);
311
  if (!pctype && !ksptype) {
312
    if (st->shift_matrix == ST_MATMODE_SHELL) {
313
      /* in shell mode use GMRES with Jacobi as the default */
314
      ierr = KSPSetType(st->ksp,KSPGMRES);CHKERRQ(ierr);
315
      ierr = PCSetType(pc,PCJACOBI);CHKERRQ(ierr);
316
    } else {
317
      /* use direct solver as default */
318
      ierr = KSPSetType(st->ksp,KSPPREONLY);CHKERRQ(ierr);
319
      ierr = PCSetType(pc,PCREDUNDANT);CHKERRQ(ierr);
320
    }
321
  }
322
 
2384 jroman 323
  ierr = PetscOptionsHead("ST Cayley Options");CHKERRQ(ierr);
2330 jroman 324
  ierr = PetscOptionsScalar("-st_cayley_antishift","Value of the antishift","STCayleySetAntishift",ctx->nu,&nu,&flg);CHKERRQ(ierr);
359 dsic.upv.es!antodo 325
  if (flg) {
2091 jroman 326
    ierr = STCayleySetAntishift(st,nu);CHKERRQ(ierr);
359 dsic.upv.es!antodo 327
  }
2384 jroman 328
  ierr = PetscOptionsTail();CHKERRQ(ierr);
359 dsic.upv.es!antodo 329
  PetscFunctionReturn(0);
330
}
331
 
332
EXTERN_C_BEGIN
333
#undef __FUNCT__  
334
#define __FUNCT__ "STCayleySetAntishift_Cayley"
476 dsic.upv.es!antodo 335
PetscErrorCode STCayleySetAntishift_Cayley(ST st,PetscScalar newshift)
359 dsic.upv.es!antodo 336
{
2331 jroman 337
  ST_CAYLEY *ctx = (ST_CAYLEY*)st->data;
359 dsic.upv.es!antodo 338
 
339
  PetscFunctionBegin;
2348 jroman 340
  ctx->nu     = newshift;
2091 jroman 341
  ctx->nu_set = PETSC_TRUE;
359 dsic.upv.es!antodo 342
  PetscFunctionReturn(0);
343
}
344
EXTERN_C_END
345
 
346
#undef __FUNCT__  
352 dsic.upv.es!antodo 347
#define __FUNCT__ "STCayleySetAntishift"
553 dsic.upv.es!jroman 348
/*@
349
   STCayleySetAntishift - Sets the value of the anti-shift for the Cayley
350
   spectral transformation.
351
 
2328 jroman 352
   Logically Collective on ST
553 dsic.upv.es!jroman 353
 
354
   Input Parameters:
355
+  st  - the spectral transformation context
2091 jroman 356
-  nu  - the anti-shift
553 dsic.upv.es!jroman 357
 
358
   Options Database Key:
2090 jroman 359
.  -st_cayley_antishift - Sets the value of the anti-shift
553 dsic.upv.es!jroman 360
 
361
   Level: intermediate
362
 
363
   Note:
364
   In the generalized Cayley transform, the operator can be expressed as
2091 jroman 365
   OP = inv(A - sigma B)*(A + nu B). This function sets the value of nu.
553 dsic.upv.es!jroman 366
   Use STSetShift() for setting sigma.
367
 
2325 jroman 368
.seealso: STSetShift(), STCayleyGetAntishift()
553 dsic.upv.es!jroman 369
@*/
2091 jroman 370
PetscErrorCode STCayleySetAntishift(ST st,PetscScalar nu)
352 dsic.upv.es!antodo 371
{
2221 jroman 372
  PetscErrorCode ierr;
359 dsic.upv.es!antodo 373
 
374
  PetscFunctionBegin;
2213 jroman 375
  PetscValidHeaderSpecific(st,ST_CLASSID,1);
2326 jroman 376
  PetscValidLogicalCollectiveScalar(st,nu,2);
2221 jroman 377
  ierr = PetscTryMethod(st,"STCayleySetAntishift_C",(ST,PetscScalar),(st,nu));CHKERRQ(ierr);
359 dsic.upv.es!antodo 378
  PetscFunctionReturn(0);
379
}
2325 jroman 380
EXTERN_C_BEGIN
381
#undef __FUNCT__  
382
#define __FUNCT__ "STCayleyGetAntishift_Cayley"
383
PetscErrorCode STCayleyGetAntishift_Cayley(ST st,PetscScalar *nu)
384
{
2331 jroman 385
  ST_CAYLEY *ctx = (ST_CAYLEY*)st->data;
359 dsic.upv.es!antodo 386
 
2325 jroman 387
  PetscFunctionBegin;
388
  *nu = ctx->nu;
389
  PetscFunctionReturn(0);
390
}
391
EXTERN_C_END
392
 
359 dsic.upv.es!antodo 393
#undef __FUNCT__  
2325 jroman 394
#define __FUNCT__ "STCayleyGetAntishift"
395
/*@
396
   STCayleyGetAntishift - Gets the value of the anti-shift used in the Cayley
397
   spectral transformation.
398
 
2328 jroman 399
   Not Collective
2325 jroman 400
 
401
   Input Parameter:
402
.  st  - the spectral transformation context
403
 
404
   Output Parameter:
405
.  nu  - the anti-shift
406
 
407
   Level: intermediate
408
 
409
.seealso: STGetShift(), STCayleySetAntishift()
410
@*/
411
PetscErrorCode STCayleyGetAntishift(ST st,PetscScalar *nu)
412
{
413
  PetscErrorCode ierr;
414
 
415
  PetscFunctionBegin;
416
  PetscValidHeaderSpecific(st,ST_CLASSID,1);
2326 jroman 417
  PetscValidScalarPointer(nu,2);
2325 jroman 418
  ierr = PetscTryMethod(st,"STCayleyGetAntishift_C",(ST,PetscScalar*),(st,nu));CHKERRQ(ierr);
419
  PetscFunctionReturn(0);
420
}
421
 
422
#undef __FUNCT__  
359 dsic.upv.es!antodo 423
#define __FUNCT__ "STView_Cayley"
476 dsic.upv.es!antodo 424
PetscErrorCode STView_Cayley(ST st,PetscViewer viewer)
359 dsic.upv.es!antodo 425
{
476 dsic.upv.es!antodo 426
  PetscErrorCode ierr;
2331 jroman 427
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
352 dsic.upv.es!antodo 428
 
429
  PetscFunctionBegin;
359 dsic.upv.es!antodo 430
#if !defined(PETSC_USE_COMPLEX)
2394 jroman 431
  ierr = PetscViewerASCIIPrintf(viewer,"  Cayley: antishift: %G\n",ctx->nu);CHKERRQ(ierr);
359 dsic.upv.es!antodo 432
#else
2394 jroman 433
  ierr = PetscViewerASCIIPrintf(viewer,"  Cayley: antishift: %G+%G i\n",PetscRealPart(ctx->nu),PetscImaginaryPart(ctx->nu));CHKERRQ(ierr);
359 dsic.upv.es!antodo 434
#endif
352 dsic.upv.es!antodo 435
  PetscFunctionReturn(0);
436
}
437
 
438
#undef __FUNCT__  
2348 jroman 439
#define __FUNCT__ "STReset_Cayley"
440
PetscErrorCode STReset_Cayley(ST st)
441
{
442
  PetscErrorCode ierr;
443
  ST_CAYLEY      *ctx = (ST_CAYLEY*)st->data;
444
 
445
  PetscFunctionBegin;
446
  ierr = VecDestroy(&ctx->w2);CHKERRQ(ierr);
447
  PetscFunctionReturn(0);
448
}
449
 
450
#undef __FUNCT__  
352 dsic.upv.es!antodo 451
#define __FUNCT__ "STDestroy_Cayley"
476 dsic.upv.es!antodo 452
PetscErrorCode STDestroy_Cayley(ST st)
352 dsic.upv.es!antodo 453
{
476 dsic.upv.es!antodo 454
  PetscErrorCode ierr;
352 dsic.upv.es!antodo 455
 
456
  PetscFunctionBegin;
2348 jroman 457
  ierr = PetscFree(st->data);CHKERRQ(ierr);
1925 jroman 458
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)st,"STCayleySetAntishift_C","",PETSC_NULL);CHKERRQ(ierr);
352 dsic.upv.es!antodo 459
  PetscFunctionReturn(0);
460
}
461
 
462
EXTERN_C_BEGIN
463
#undef __FUNCT__  
464
#define __FUNCT__ "STCreate_Cayley"
476 dsic.upv.es!antodo 465
PetscErrorCode STCreate_Cayley(ST st)
352 dsic.upv.es!antodo 466
{
476 dsic.upv.es!antodo 467
  PetscErrorCode ierr;
352 dsic.upv.es!antodo 468
 
469
  PetscFunctionBegin;
2329 jroman 470
  ierr = PetscNewLog(st,ST_CAYLEY,&st->data);CHKERRQ(ierr);
1358 slepc 471
  st->ops->apply           = STApply_Cayley;
472
  st->ops->getbilinearform = STGetBilinearForm_Cayley;
473
  st->ops->applytrans      = STApplyTranspose_Cayley;
474
  st->ops->postsolve       = STPostSolve_Cayley;
475
  st->ops->backtr          = STBackTransform_Cayley;
476
  st->ops->setfromoptions  = STSetFromOptions_Cayley;
477
  st->ops->setup           = STSetUp_Cayley;
478
  st->ops->setshift        = STSetShift_Cayley;
479
  st->ops->destroy         = STDestroy_Cayley;
2348 jroman 480
  st->ops->reset           = STReset_Cayley;
1358 slepc 481
  st->ops->view            = STView_Cayley;
2333 jroman 482
  st->ops->checknullspace  = STCheckNullSpace_Default;
1925 jroman 483
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)st,"STCayleySetAntishift_C","STCayleySetAntishift_Cayley",STCayleySetAntishift_Cayley);CHKERRQ(ierr);
352 dsic.upv.es!antodo 484
  PetscFunctionReturn(0);
485
}
486
EXTERN_C_END
487