Actual source code: shift.c
1: /*
2: Shift spectral transformation, applies (A + sigma I) as operator, or
3: inv(B)(A + sigma B) for generalized problems
5: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
6: SLEPc - Scalable Library for Eigenvalue Problem Computations
7: Copyright (c) 2002-2011, Universitat Politecnica de Valencia, Spain
9: This file is part of SLEPc.
10:
11: SLEPc is free software: you can redistribute it and/or modify it under the
12: terms of version 3 of the GNU Lesser General Public License as published by
13: the Free Software Foundation.
15: SLEPc is distributed in the hope that it will be useful, but WITHOUT ANY
16: WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
17: FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
18: more details.
20: You should have received a copy of the GNU Lesser General Public License
21: along with SLEPc. If not, see <http://www.gnu.org/licenses/>.
22: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
23: */
25: #include <private/stimpl.h> /*I "slepcst.h" I*/
29: PetscErrorCode STApply_Shift(ST st,Vec x,Vec y)
30: {
34: if (st->B) {
35: /* generalized eigenproblem: y = (B^-1 A + sI) x */
36: MatMult(st->A,x,st->w);
37: STAssociatedKSPSolve(st,st->w,y);
38: }
39: else {
40: /* standard eigenproblem: y = (A + sI) x */
41: MatMult(st->A,x,y);
42: }
43: if (st->sigma != 0.0) {
44: VecAXPY(y,st->sigma,x);
45: }
46: return(0);
47: }
51: PetscErrorCode STApplyTranspose_Shift(ST st,Vec x,Vec y)
52: {
56: if (st->B) {
57: /* generalized eigenproblem: y = (A^T B^-T + sI) x */
58: STAssociatedKSPSolveTranspose(st,x,st->w);
59: MatMultTranspose(st->A,st->w,y);
60: }
61: else {
62: /* standard eigenproblem: y = (A^T + sI) x */
63: MatMultTranspose(st->A,x,y);
64: }
65: if (st->sigma != 0.0) {
66: VecAXPY(y,st->sigma,x);
67: }
68: return(0);
69: }
73: PetscErrorCode STBackTransform_Shift(ST st,PetscInt n,PetscScalar *eigr,PetscScalar *eigi)
74: {
75: PetscInt j;
78: for (j=0;j<n;j++) {
79: eigr[j] -= st->sigma;
80: }
81: return(0);
82: }
86: PetscErrorCode STSetUp_Shift(ST st)
87: {
91: if (st->B) {
92: if (!st->ksp) { STGetKSP(st,&st->ksp); }
93: KSPSetOperators(st->ksp,st->B,st->B,DIFFERENT_NONZERO_PATTERN);
94: KSPSetUp(st->ksp);
95: }
96: return(0);
97: }
101: PetscErrorCode STSetFromOptions_Shift(ST st)
102: {
104: PC pc;
105: const PCType pctype;
106: const KSPType ksptype;
109: if (!st->ksp) { STGetKSP(st,&st->ksp); }
110: KSPGetPC(st->ksp,&pc);
111: KSPGetType(st->ksp,&ksptype);
112: PCGetType(pc,&pctype);
113: if (!pctype && !ksptype) {
114: if (st->shift_matrix == ST_MATMODE_SHELL) {
115: /* in shell mode use GMRES with Jacobi as the default */
116: KSPSetType(st->ksp,KSPGMRES);
117: PCSetType(pc,PCJACOBI);
118: } else {
119: /* use direct solver as default */
120: KSPSetType(st->ksp,KSPPREONLY);
121: PCSetType(pc,PCREDUNDANT);
122: }
123: }
124: return(0);
125: }
130: PetscErrorCode STCreate_Shift(ST st)
131: {
133: st->ops->apply = STApply_Shift;
134: st->ops->getbilinearform = STGetBilinearForm_Default;
135: st->ops->applytrans = STApplyTranspose_Shift;
136: st->ops->backtr = STBackTransform_Shift;
137: st->ops->setfromoptions = STSetFromOptions_Shift;
138: st->ops->setup = STSetUp_Shift;
139: return(0);
140: }