Subversion Repositories slepc-dev

Rev

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

Rev Author Line No. Line
778 dsic.upv.es!antodo 1
/*
804 dsic.upv.es!antodo 2
    Folding spectral transformation, applies (A + sigma I)^2 as operator, or
3
    inv(B)(A + sigma I)^2 for generalized problems
1376 slepc 4
 
5
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6
      SLEPc - Scalable Library for Eigenvalue Problem Computations
7
      Copyright (c) 2002-2007, Universidad Politecnica de Valencia, Spain
8
 
9
      This file is part of SLEPc. See the README file for conditions of use
10
      and additional information.
11
   - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
778 dsic.upv.es!antodo 12
*/
1376 slepc 13
 
778 dsic.upv.es!antodo 14
#include "src/st/stimpl.h"          /*I "slepcst.h" I*/
15
 
16
typedef struct {
17
  PetscTruth  left;
18
  Vec         w2;
19
} ST_FOLD;
20
 
21
#undef __FUNCT__  
22
#define __FUNCT__ "STApply_Fold"
23
PetscErrorCode STApply_Fold(ST st,Vec x,Vec y)
24
{
25
  PetscErrorCode ierr;
26
  ST_FOLD        *ctx = (ST_FOLD *) st->data;
27
 
28
  PetscFunctionBegin;
29
  if (st->B) {
804 dsic.upv.es!antodo 30
    /* generalized eigenproblem: y = (B^-1 A + sI)^2 x */
828 dsic.upv.es!antodo 31
    ierr = MatMult(st->A,x,st->w);CHKERRQ(ierr);
32
    ierr = STAssociatedKSPSolve(st,st->w,ctx->w2);CHKERRQ(ierr);
778 dsic.upv.es!antodo 33
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 34
      ierr = VecAXPY(ctx->w2,-st->sigma,x);CHKERRQ(ierr);
778 dsic.upv.es!antodo 35
    }
828 dsic.upv.es!antodo 36
    ierr = MatMult(st->A,ctx->w2,st->w);CHKERRQ(ierr);
37
    ierr = STAssociatedKSPSolve(st,st->w,y);CHKERRQ(ierr);
38
    if (st->sigma != 0.0) {
39
      ierr = VecAXPY(y,-st->sigma,ctx->w2);CHKERRQ(ierr);
40
    }
778 dsic.upv.es!antodo 41
  } else {
804 dsic.upv.es!antodo 42
    /* standard eigenproblem: y = (A + sI)^2 x */
778 dsic.upv.es!antodo 43
    ierr = MatMult(st->A,x,st->w);CHKERRQ(ierr);
44
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 45
      ierr = VecAXPY(st->w,-st->sigma,x);CHKERRQ(ierr);
778 dsic.upv.es!antodo 46
    }
47
    ierr = MatMult(st->A,st->w,y);CHKERRQ(ierr);
48
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 49
      ierr = VecAXPY(y,-st->sigma,st->w);CHKERRQ(ierr);
778 dsic.upv.es!antodo 50
    }
51
  }
52
  PetscFunctionReturn(0);
53
}
54
 
55
#undef __FUNCT__  
813 dsic.upv.es!antodo 56
#define __FUNCT__ "STApplyTranspose_Fold"
57
PetscErrorCode STApplyTranspose_Fold(ST st,Vec x,Vec y)
58
{
59
  PetscErrorCode ierr;
60
  ST_FOLD        *ctx = (ST_FOLD *) st->data;
61
 
62
  PetscFunctionBegin;
63
  if (st->B) {
64
    /* generalized eigenproblem: y = (A^T B^-T + sI)^2 x */
828 dsic.upv.es!antodo 65
    ierr = STAssociatedKSPSolveTranspose(st,x,st->w);CHKERRQ(ierr);
66
    ierr = MatMult(st->A,st->w,ctx->w2);CHKERRQ(ierr);
813 dsic.upv.es!antodo 67
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 68
      ierr = VecAXPY(ctx->w2,-st->sigma,x);CHKERRQ(ierr);
813 dsic.upv.es!antodo 69
    }
828 dsic.upv.es!antodo 70
    ierr = STAssociatedKSPSolveTranspose(st,ctx->w2,st->w);CHKERRQ(ierr);
71
    ierr = MatMult(st->A,st->w,y);CHKERRQ(ierr);
72
    if (st->sigma != 0.0) {
73
      ierr = VecAXPY(y,-st->sigma,ctx->w2);CHKERRQ(ierr);
74
    }
813 dsic.upv.es!antodo 75
  } else {
76
    /* standard eigenproblem: y = (A^T + sI)^2 x */
77
    ierr = MatMultTranspose(st->A,x,st->w);CHKERRQ(ierr);
78
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 79
      ierr = VecAXPY(st->w,-st->sigma,x);CHKERRQ(ierr);
813 dsic.upv.es!antodo 80
    }
81
    ierr = MatMultTranspose(st->A,st->w,y);CHKERRQ(ierr);
82
    if (st->sigma != 0.0) {
828 dsic.upv.es!antodo 83
      ierr = VecAXPY(y,-st->sigma,st->w);CHKERRQ(ierr);
813 dsic.upv.es!antodo 84
    }
85
  }
86
  PetscFunctionReturn(0);
87
}
88
 
89
#undef __FUNCT__  
778 dsic.upv.es!antodo 90
#define __FUNCT__ "STBackTransform_Fold"
91
PetscErrorCode STBackTransform_Fold(ST st,PetscScalar *eigr,PetscScalar *eigi)
92
{
93
  ST_FOLD *ctx = (ST_FOLD *) st->data;
94
  PetscFunctionBegin;
95
  PetscValidScalarPointer(eigr,2);
96
  PetscValidScalarPointer(eigi,3);
97
#if !defined(PETSC_USE_COMPLEX)
98
  if (*eigi == 0) {
99
#endif
100
    if (ctx->left) *eigr = st->sigma - PetscSqrtScalar(*eigr);
101
    else *eigr = st->sigma + PetscSqrtScalar(*eigr);
102
#if !defined(PETSC_USE_COMPLEX)
103
  } else {
104
    PetscScalar r,x,y;
105
    r = PetscSqrtScalar(*eigr * *eigr + *eigi * *eigi);
106
    x = PetscSqrtScalar((r + *eigr) / 2);
107
    y = PetscSqrtScalar((r - *eigr) / 2);
108
    if (*eigi < 0) y = - y;
109
    if (ctx->left) {
110
      *eigr = st->sigma - x;
111
      *eigi = - y;
112
    } else {
113
      *eigr = st->sigma + x;
114
      *eigi = y;
115
    }
116
  }
117
#endif
118
  PetscFunctionReturn(0);
119
}
120
 
121
#undef __FUNCT__  
122
#define __FUNCT__ "STSetUp_Fold"
123
PetscErrorCode STSetUp_Fold(ST st)
124
{
125
  PetscErrorCode ierr;
126
  ST_FOLD        *ctx = (ST_FOLD *) st->data;
127
 
128
  PetscFunctionBegin;
129
  if (st->B) {
130
    ierr = KSPSetOperators(st->ksp,st->B,st->B,DIFFERENT_NONZERO_PATTERN);CHKERRQ(ierr);
131
    ierr = KSPSetUp(st->ksp);CHKERRQ(ierr);
132
    if (ctx->w2) { ierr = VecDestroy(ctx->w2);CHKERRQ(ierr); }
133
    ierr = MatGetVecs(st->B,&ctx->w2,PETSC_NULL);CHKERRQ(ierr);
134
  }
135
  PetscFunctionReturn(0);
136
}
137
 
138
EXTERN_C_BEGIN
139
#undef __FUNCT__  
140
#define __FUNCT__ "STFoldSetLeftSide_Fold"
141
PetscErrorCode STFoldSetLeftSide_Fold(ST st,PetscTruth left)
142
{
143
  ST_FOLD *ctx = (ST_FOLD *) st->data;
144
 
145
  PetscFunctionBegin;
146
  ctx->left = left;
147
  PetscFunctionReturn(0);
148
}
149
EXTERN_C_END
150
 
151
#undef __FUNCT__  
152
#define __FUNCT__ "STFoldSetLeftSide"
153
/*@
154
   STFoldSetLeftSide - Sets a flag to compute eigenvalues on the left side of shift.
155
 
156
   Collective on ST
157
 
158
   Input Parameters:
159
+  st  - the spectral transformation context
160
-  left - if true compute eigenvalues on the left side
161
 
162
   Options Database Key:
163
.  -st_fold_leftside - Sets the value of the flag
164
 
165
   Level: intermediate
166
 
167
.seealso: STSetShift()
168
@*/
169
PetscErrorCode STFoldSetLeftSide(ST st,PetscTruth left)
170
{
171
  PetscErrorCode ierr, (*f)(ST,PetscTruth);
172
 
173
  PetscFunctionBegin;
174
  PetscValidHeaderSpecific(st,ST_COOKIE,1);
175
  ierr = PetscObjectQueryFunction((PetscObject)st,"STFoldSetLeftSide_C",(void (**)(void))&f);CHKERRQ(ierr);
176
  if (f) {
177
    ierr = (*f)(st,left);CHKERRQ(ierr);
178
  }
179
  PetscFunctionReturn(0);
180
}
181
 
182
#undef __FUNCT__  
183
#define __FUNCT__ "STView_Fold"
184
PetscErrorCode STView_Fold(ST st,PetscViewer viewer)
185
{
186
  PetscErrorCode ierr;
187
  ST_FOLD        *ctx = (ST_FOLD *) st->data;
188
 
189
  PetscFunctionBegin;
190
  if (ctx->left) {
191
    ierr = PetscViewerASCIIPrintf(viewer,"  computing eigenvalues on left side of shift\n");CHKERRQ(ierr);
192
  }  
193
  if (st->B) {
194
    ierr = STView_Default(st,viewer);CHKERRQ(ierr);
195
  }
196
  PetscFunctionReturn(0);
197
}
198
 
199
#undef __FUNCT__  
200
#define __FUNCT__ "STSetFromOptions_Fold"
201
PetscErrorCode STSetFromOptions_Fold(ST st)
202
{
203
  PetscErrorCode ierr;
204
  ST_FOLD      *ctx = (ST_FOLD *) st->data;
205
 
206
  PetscFunctionBegin;
207
  ierr = PetscOptionsHead("ST Fold Options");CHKERRQ(ierr);
830 dsic.upv.es!antodo 208
  ierr = PetscOptionsTruth("-st_fold_leftside","Compute eigenvalues on left side of shift","STFoldSetLeftSide",ctx->left,&ctx->left,PETSC_NULL); CHKERRQ(ierr);
778 dsic.upv.es!antodo 209
  ierr = PetscOptionsTail();CHKERRQ(ierr);
210
  PetscFunctionReturn(0);
211
}
212
 
213
#undef __FUNCT__  
214
#define __FUNCT__ "STDestroy_Fold"
215
PetscErrorCode STDestroy_Fold(ST st)
216
{
217
  PetscErrorCode ierr;
218
  ST_FOLD        *ctx = (ST_FOLD *) st->data;
219
 
220
  PetscFunctionBegin;
221
  if (ctx->w2) { ierr = VecDestroy(ctx->w2);CHKERRQ(ierr); }
222
  ierr = PetscFree(ctx);CHKERRQ(ierr);
223
  PetscFunctionReturn(0);
224
}
225
 
226
EXTERN_C_BEGIN
227
#undef __FUNCT__  
228
#define __FUNCT__ "STCreate_Fold"
229
PetscErrorCode STCreate_Fold(ST st)
230
{
231
  PetscErrorCode ierr;
232
  ST_FOLD        *ctx;
233
 
234
  PetscFunctionBegin;
235
 
236
  ierr = PetscNew(ST_FOLD,&ctx); CHKERRQ(ierr);
237
  PetscLogObjectMemory(st,sizeof(ST_FOLD));
238
  st->data                = (void *) ctx;
239
 
1358 slepc 240
  st->ops->apply           = STApply_Fold;
241
  st->ops->getbilinearform = STGetBilinearForm_Default;
242
  st->ops->applytrans      = STApplyTranspose_Fold;
243
  st->ops->backtr          = STBackTransform_Fold;
244
  st->ops->setup           = STSetUp_Fold;
245
  st->ops->view            = STView_Fold;
246
  st->ops->setfromoptions  = STSetFromOptions_Fold;
247
  st->ops->destroy         = STDestroy_Fold;
248
  st->checknullspace       = 0;
778 dsic.upv.es!antodo 249
 
250
  ctx->left            = PETSC_FALSE;
251
 
252
  ierr = PetscObjectComposeFunctionDynamic((PetscObject)st,"STFoldSetLeftSide_C","STFoldSetLeftSide_Fold",
253
                    STFoldSetLeftSide_Fold);CHKERRQ(ierr);
254
 
255
  PetscFunctionReturn(0);
256
}
257
EXTERN_C_END
258