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
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
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
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
352 dsic.upv.es!antodo 22
*/
1376 slepc 23
 
1521 slepc 24
#include "private/stimpl.h"          /*I "slepcst.h" I*/
352 dsic.upv.es!antodo 25
 
26
typedef struct {
2091 jroman 27
  PetscScalar nu;
28
  PetscTruth  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;
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;
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);
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);
1358 slepc 126
  ierr = MatShellSetOperation(*B,MATOP_MULT,(void(*)(void))STBilinearMatMult_Cayley);CHKERRQ(ierr);  
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
{
134
  ST_CAYLEY   *ctx = (ST_CAYLEY *) st->data;
1778 antodo 135
  PetscInt    j;
352 dsic.upv.es!antodo 136
#ifndef PETSC_USE_COMPLEX
137
  PetscScalar t,i,r;
138
  PetscFunctionBegin;
1778 antodo 139
  PetscValidPointer(eigr,3);
140
  PetscValidPointer(eigi,4);
141
  for (j=0;j<n;j++) {
2091 jroman 142
    if (eigi[j] == 0.0) eigr[j] = (ctx->nu + eigr[j] * st->sigma) / (eigr[j] - 1.0);
1778 antodo 143
    else {
144
      r = eigr[j];
145
      i = eigi[j];
2091 jroman 146
      r = st->sigma * (r * r + i * i - r) + ctx->nu * (r - 1);
147
      i = - st->sigma * i - ctx->nu * i;
1778 antodo 148
      t = i * i + r * (r - 2.0) + 1.0;    
149
      eigr[j] = r / t;
150
      eigi[j] = i / t;    
151
    }
352 dsic.upv.es!antodo 152
  }
153
#else
154
  PetscFunctionBegin;
155
  PetscValidPointer(eigr,2);
1778 antodo 156
  for (j=0;j<n;j++) {
2091 jroman 157
    eigr[j] = (ctx->nu + eigr[j] * st->sigma) / (eigr[j] - 1.0);
1778 antodo 158
  }
352 dsic.upv.es!antodo 159
#endif
160
  PetscFunctionReturn(0);
161
}
162
 
163
#undef __FUNCT__  
1029 slepc 164
#define __FUNCT__ "STPostSolve_Cayley"
165
PetscErrorCode STPostSolve_Cayley(ST st)
352 dsic.upv.es!antodo 166
{
476 dsic.upv.es!antodo 167
  PetscErrorCode ierr;
352 dsic.upv.es!antodo 168
 
169
  PetscFunctionBegin;
1940 jroman 170
  if (st->shift_matrix == ST_MATMODE_INPLACE) {
828 dsic.upv.es!antodo 171
    if (st->B) {
172
      ierr = MatAXPY(st->A,st->sigma,st->B,st->str);CHKERRQ(ierr);
173
    } else {
174
      ierr = MatShift(st->A,st->sigma); CHKERRQ(ierr);
175
    }
352 dsic.upv.es!antodo 176
    st->setupcalled = 0;
177
  }
178
  PetscFunctionReturn(0);
179
}
180
 
181
#undef __FUNCT__  
182
#define __FUNCT__ "STSetUp_Cayley"
476 dsic.upv.es!antodo 183
PetscErrorCode STSetUp_Cayley(ST st)
352 dsic.upv.es!antodo 184
{
476 dsic.upv.es!antodo 185
  PetscErrorCode ierr;
186
  ST_CAYLEY      *ctx = (ST_CAYLEY *) st->data;
352 dsic.upv.es!antodo 187
 
188
  PetscFunctionBegin;
189
 
359 dsic.upv.es!antodo 190
  if (st->mat) { ierr = MatDestroy(st->mat);CHKERRQ(ierr); }
2074 jroman 191
 
192
  /* if the user did not set the shift, use the target value */
193
  if (!st->sigma_set) st->sigma = st->defsigma;
194
 
2091 jroman 195
  if (!ctx->nu_set) { ctx->nu = st->sigma; }
196
  if (ctx->nu == 0.0 &&  st->sigma == 0.0) {
359 dsic.upv.es!antodo 197
    SETERRQ(1,"Values of shift and antishift cannot be zero simultaneously");
198
  }
199
 
352 dsic.upv.es!antodo 200
  switch (st->shift_matrix) {
1940 jroman 201
  case ST_MATMODE_INPLACE:
359 dsic.upv.es!antodo 202
    st->mat = PETSC_NULL;
352 dsic.upv.es!antodo 203
    if (st->sigma != 0.0) {
204
      if (st->B) {
828 dsic.upv.es!antodo 205
        ierr = MatAXPY(st->A,-st->sigma,st->B,st->str);CHKERRQ(ierr);
352 dsic.upv.es!antodo 206
      } else {
828 dsic.upv.es!antodo 207
        ierr = MatShift(st->A,-st->sigma);CHKERRQ(ierr);
352 dsic.upv.es!antodo 208
      }
209
    }
1241 slepc 210
    ierr = KSPSetOperators(st->ksp,st->A,st->A,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
352 dsic.upv.es!antodo 211
    break;
1940 jroman 212
  case ST_MATMODE_SHELL:
352 dsic.upv.es!antodo 213
    ierr = STMatShellCreate(st,&st->mat);CHKERRQ(ierr);
214
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
215
    break;
216
  default:
217
    ierr = MatDuplicate(st->A,MAT_COPY_VALUES,&st->mat);CHKERRQ(ierr);
218
    if (st->sigma != 0.0) {
219
      if (st->B) {
828 dsic.upv.es!antodo 220
        ierr = MatAXPY(st->mat,-st->sigma,st->B,st->str);CHKERRQ(ierr);
352 dsic.upv.es!antodo 221
      } else {
828 dsic.upv.es!antodo 222
        ierr = MatShift(st->mat,-st->sigma);CHKERRQ(ierr);
352 dsic.upv.es!antodo 223
      }
224
    }
1241 slepc 225
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
352 dsic.upv.es!antodo 226
  }
227
  if (st->B) {
228
   if (ctx->w2) { ierr = VecDestroy(ctx->w2);CHKERRQ(ierr); }
229
   ierr = MatGetVecs(st->B,&ctx->w2,PETSC_NULL);CHKERRQ(ierr);
359 dsic.upv.es!antodo 230
  }
352 dsic.upv.es!antodo 231
  ierr = KSPSetUp(st->ksp);CHKERRQ(ierr);
232
  PetscFunctionReturn(0);
233
}
234
 
235
#undef __FUNCT__  
236
#define __FUNCT__ "STSetShift_Cayley"
476 dsic.upv.es!antodo 237
PetscErrorCode STSetShift_Cayley(ST st,PetscScalar newshift)
352 dsic.upv.es!antodo 238
{
476 dsic.upv.es!antodo 239
  PetscErrorCode ierr;
240
  ST_CAYLEY      *ctx = (ST_CAYLEY *) st->data;
1241 slepc 241
  MatStructure   flg;
352 dsic.upv.es!antodo 242
 
243
  PetscFunctionBegin;
2091 jroman 244
  if (!ctx->nu_set) { ctx->nu = newshift; }
245
  if (ctx->nu == 0.0 &&  newshift == 0.0) {
1241 slepc 246
    SETERRQ(1,"Values of shift and antishift cannot be zero simultaneously");
247
  }
352 dsic.upv.es!antodo 248
 
249
  /* Nothing to be done if STSetUp has not been called yet */
250
  if (!st->setupcalled) PetscFunctionReturn(0);
251
 
1241 slepc 252
  /* Check if the new KSP matrix has the same zero structure */
253
  if (st->B && st->str == DIFFERENT_NONZERO_PATTERN && (st->sigma == 0.0 || newshift == 0.0)) {
254
    flg = DIFFERENT_NONZERO_PATTERN;
255
  } else {
256
    flg = SAME_NONZERO_PATTERN;
257
  }
258
 
352 dsic.upv.es!antodo 259
  switch (st->shift_matrix) {
1940 jroman 260
  case ST_MATMODE_INPLACE:
352 dsic.upv.es!antodo 261
    /* Undo previous operations */
262
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 263
      if (st->B) {
264
        ierr = MatAXPY(st->A,st->sigma,st->B,st->str);CHKERRQ(ierr);
265
      } else {
266
        ierr = MatShift(st->A,st->sigma);CHKERRQ(ierr);
267
      }
352 dsic.upv.es!antodo 268
    }
269
    /* Apply new shift */
270
    if (newshift != 0.0) {
828 dsic.upv.es!antodo 271
      if (st->B) {
272
        ierr = MatAXPY(st->A,-newshift,st->B,st->str);CHKERRQ(ierr);
273
      } else {
274
        ierr = MatShift(st->A,-newshift);CHKERRQ(ierr);
275
      }
352 dsic.upv.es!antodo 276
    }
1241 slepc 277
    ierr = KSPSetOperators(st->ksp,st->A,st->A,flg);CHKERRQ(ierr);
352 dsic.upv.es!antodo 278
    break;
1940 jroman 279
  case ST_MATMODE_SHELL:
1241 slepc 280
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);    
352 dsic.upv.es!antodo 281
    break;
282
  default:
354 dsic.upv.es!jroman 283
    ierr = MatCopy(st->A, st->mat,SUBSET_NONZERO_PATTERN); CHKERRQ(ierr);
352 dsic.upv.es!antodo 284
    if (newshift != 0.0) {  
828 dsic.upv.es!antodo 285
      if (st->B) { ierr = MatAXPY(st->mat,-newshift,st->B,st->str);CHKERRQ(ierr); }
286
      else { ierr = MatShift(st->mat,-newshift);CHKERRQ(ierr); }
352 dsic.upv.es!antodo 287
    }
1241 slepc 288
    ierr = KSPSetOperators(st->ksp,st->mat,st->mat,flg);CHKERRQ(ierr);    
352 dsic.upv.es!antodo 289
  }
290
  st->sigma = newshift;
291
  ierr = KSPSetUp(st->ksp);CHKERRQ(ierr);
292
  PetscFunctionReturn(0);
293
}
294
 
295
#undef __FUNCT__  
359 dsic.upv.es!antodo 296
#define __FUNCT__ "STSetFromOptions_Cayley"
476 dsic.upv.es!antodo 297
PetscErrorCode STSetFromOptions_Cayley(ST st)
298
{
299
  PetscErrorCode ierr;
2091 jroman 300
  PetscScalar    nu;
476 dsic.upv.es!antodo 301
  PetscTruth     flg;
302
  ST_CAYLEY      *ctx = (ST_CAYLEY *) st->data;
2005 eromero 303
  PC             pc;
304
  const PCType   pctype;
305
  const KSPType  ksptype;
359 dsic.upv.es!antodo 306
 
307
  PetscFunctionBegin;
2005 eromero 308
 
309
  ierr = KSPGetPC(st->ksp,&pc);CHKERRQ(ierr);
310
  ierr = KSPGetType(st->ksp,&ksptype);CHKERRQ(ierr);
311
  ierr = PCGetType(pc,&pctype);CHKERRQ(ierr);
312
  if (!pctype && !ksptype) {
313
    if (st->shift_matrix == ST_MATMODE_SHELL) {
314
      /* in shell mode use GMRES with Jacobi as the default */
315
      ierr = KSPSetType(st->ksp,KSPGMRES);CHKERRQ(ierr);
316
      ierr = PCSetType(pc,PCJACOBI);CHKERRQ(ierr);
317
    } else {
318
      /* use direct solver as default */
319
      ierr = KSPSetType(st->ksp,KSPPREONLY);CHKERRQ(ierr);
320
      ierr = PCSetType(pc,PCREDUNDANT);CHKERRQ(ierr);
321
    }
322
  }
323
 
2102 eromero 324
  ierr = PetscOptionsBegin(((PetscObject)st)->comm,((PetscObject)st)->prefix,"ST Cayley Options","ST");CHKERRQ(ierr);
2091 jroman 325
  ierr = PetscOptionsScalar("-st_cayley_antishift","Value of the antishift","STCayleySetAntishift",ctx->nu,&nu,&flg); CHKERRQ(ierr);
359 dsic.upv.es!antodo 326
  if (flg) {
2091 jroman 327
    ierr = STCayleySetAntishift(st,nu);CHKERRQ(ierr);
359 dsic.upv.es!antodo 328
  }
2102 eromero 329
  ierr = PetscOptionsEnd();CHKERRQ(ierr);
359 dsic.upv.es!antodo 330
  PetscFunctionReturn(0);
331
}
332
 
333
EXTERN_C_BEGIN
334
#undef __FUNCT__  
335
#define __FUNCT__ "STCayleySetAntishift_Cayley"
476 dsic.upv.es!antodo 336
PetscErrorCode STCayleySetAntishift_Cayley(ST st,PetscScalar newshift)
359 dsic.upv.es!antodo 337
{
338
  ST_CAYLEY *ctx = (ST_CAYLEY *) st->data;
339
 
340
  PetscFunctionBegin;
2091 jroman 341
  ctx->nu = newshift;
342
  ctx->nu_set = PETSC_TRUE;
359 dsic.upv.es!antodo 343
  PetscFunctionReturn(0);
344
}
345
EXTERN_C_END
346
 
347
#undef __FUNCT__  
352 dsic.upv.es!antodo 348
#define __FUNCT__ "STCayleySetAntishift"
553 dsic.upv.es!jroman 349
/*@
350
   STCayleySetAntishift - Sets the value of the anti-shift for the Cayley
351
   spectral transformation.
352
 
353
   Collective on ST
354
 
355
   Input Parameters:
356
+  st  - the spectral transformation context
2091 jroman 357
-  nu  - the anti-shift
553 dsic.upv.es!jroman 358
 
359
   Options Database Key:
2090 jroman 360
.  -st_cayley_antishift - Sets the value of the anti-shift
553 dsic.upv.es!jroman 361
 
362
   Level: intermediate
363
 
364
   Note:
365
   In the generalized Cayley transform, the operator can be expressed as
2091 jroman 366
   OP = inv(A - sigma B)*(A + nu B). This function sets the value of nu.
553 dsic.upv.es!jroman 367
   Use STSetShift() for setting sigma.
368
 
369
.seealso: STSetShift()
370
@*/
2091 jroman 371
PetscErrorCode STCayleySetAntishift(ST st,PetscScalar nu)
352 dsic.upv.es!antodo 372
{
476 dsic.upv.es!antodo 373
  PetscErrorCode ierr, (*f)(ST,PetscScalar);
359 dsic.upv.es!antodo 374
 
375
  PetscFunctionBegin;
376
  PetscValidHeaderSpecific(st,ST_COOKIE,1);
377
  ierr = PetscObjectQueryFunction((PetscObject)st,"STCayleySetAntishift_C",(void (**)(void))&f);CHKERRQ(ierr);
378
  if (f) {
2091 jroman 379
    ierr = (*f)(st,nu);CHKERRQ(ierr);
359 dsic.upv.es!antodo 380
  }
381
  PetscFunctionReturn(0);
382
}
383
 
384
#undef __FUNCT__  
385
#define __FUNCT__ "STView_Cayley"
476 dsic.upv.es!antodo 386
PetscErrorCode STView_Cayley(ST st,PetscViewer viewer)
359 dsic.upv.es!antodo 387
{
476 dsic.upv.es!antodo 388
  PetscErrorCode ierr;
389
  ST_CAYLEY      *ctx = (ST_CAYLEY *) st->data;
352 dsic.upv.es!antodo 390
 
391
  PetscFunctionBegin;
359 dsic.upv.es!antodo 392
#if !defined(PETSC_USE_COMPLEX)
2091 jroman 393
  ierr = PetscViewerASCIIPrintf(viewer,"  antishift: %g\n",ctx->nu);CHKERRQ(ierr);
359 dsic.upv.es!antodo 394
#else
2091 jroman 395
  ierr = PetscViewerASCIIPrintf(viewer,"  antishift: %g+%g i\n",PetscRealPart(ctx->nu),PetscImaginaryPart(ctx->nu));CHKERRQ(ierr);
359 dsic.upv.es!antodo 396
#endif
438 dsic.upv.es!antodo 397
  ierr = STView_Default(st,viewer);CHKERRQ(ierr);
352 dsic.upv.es!antodo 398
  PetscFunctionReturn(0);
399
}
400
 
401
#undef __FUNCT__  
402
#define __FUNCT__ "STDestroy_Cayley"
476 dsic.upv.es!antodo 403
PetscErrorCode STDestroy_Cayley(ST st)
352 dsic.upv.es!antodo 404
{
476 dsic.upv.es!antodo 405
  PetscErrorCode ierr;
406
  ST_CAYLEY      *ctx = (ST_CAYLEY *) st->data;
352 dsic.upv.es!antodo 407
 
408
  PetscFunctionBegin;
409
  if (ctx->w2) { ierr = VecDestroy(ctx->w2);CHKERRQ(ierr); }
410
  ierr = PetscFree(ctx);CHKERRQ(ierr);
1925 jroman 411
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)st,"STCayleySetAntishift_C","",PETSC_NULL);CHKERRQ(ierr);
352 dsic.upv.es!antodo 412
  PetscFunctionReturn(0);
413
}
414
 
415
EXTERN_C_BEGIN
416
#undef __FUNCT__  
417
#define __FUNCT__ "STCreate_Cayley"
476 dsic.upv.es!antodo 418
PetscErrorCode STCreate_Cayley(ST st)
352 dsic.upv.es!antodo 419
{
476 dsic.upv.es!antodo 420
  PetscErrorCode ierr;
421
  ST_CAYLEY      *ctx;
352 dsic.upv.es!antodo 422
 
423
  PetscFunctionBegin;
424
  ierr = PetscNew(ST_CAYLEY,&ctx); CHKERRQ(ierr);
425
  PetscLogObjectMemory(st,sizeof(ST_CAYLEY));
1358 slepc 426
  st->data                 = (void *) ctx;
352 dsic.upv.es!antodo 427
 
1358 slepc 428
  st->ops->apply           = STApply_Cayley;
429
  st->ops->getbilinearform = STGetBilinearForm_Cayley;
430
  st->ops->applytrans      = STApplyTranspose_Cayley;
431
  st->ops->postsolve       = STPostSolve_Cayley;
432
  st->ops->backtr          = STBackTransform_Cayley;
433
  st->ops->setfromoptions  = STSetFromOptions_Cayley;
434
  st->ops->setup           = STSetUp_Cayley;
435
  st->ops->setshift        = STSetShift_Cayley;
436
  st->ops->destroy         = STDestroy_Cayley;
437
  st->ops->view            = STView_Cayley;
352 dsic.upv.es!antodo 438
 
2091 jroman 439
  st->checknullspace       = STCheckNullSpace_Default;
352 dsic.upv.es!antodo 440
 
2091 jroman 441
  ctx->nu                  = 0.0;
442
  ctx->nu_set              = PETSC_FALSE;
352 dsic.upv.es!antodo 443
 
1925 jroman 444
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)st,"STCayleySetAntishift_C","STCayleySetAntishift_Cayley",STCayleySetAntishift_Cayley);CHKERRQ(ierr);
359 dsic.upv.es!antodo 445
 
352 dsic.upv.es!antodo 446
  PetscFunctionReturn(0);
447
}
448
EXTERN_C_END
449