xref: /petsc/src/ksp/pc/impls/eisens/eisen.c (revision 4b9ad92859ccb93b5e851e53cb8c4c04ac10e155)
1*4b9ad928SBarry Smith /*$Id: eisen.c,v 1.113 2001/08/06 21:16:28 bsmith Exp $*/
2*4b9ad928SBarry Smith 
3*4b9ad928SBarry Smith /*
4*4b9ad928SBarry Smith    Defines a  Eisenstat trick SSOR  preconditioner. This uses about
5*4b9ad928SBarry Smith  %50 of the usual amount of floating point ops used for SSOR + Krylov
6*4b9ad928SBarry Smith  method. But it requires actually solving the preconditioned problem
7*4b9ad928SBarry Smith  with both left and right preconditioning.
8*4b9ad928SBarry Smith */
9*4b9ad928SBarry Smith #include "src/ksp/pc/pcimpl.h"           /*I "petscpc.h" I*/
10*4b9ad928SBarry Smith 
11*4b9ad928SBarry Smith typedef struct {
12*4b9ad928SBarry Smith   Mat        shell,A;
13*4b9ad928SBarry Smith   Vec        b,diag;     /* temporary storage for true right hand side */
14*4b9ad928SBarry Smith   PetscReal  omega;
15*4b9ad928SBarry Smith   PetscTruth usediag;    /* indicates preconditioner should include diagonal scaling*/
16*4b9ad928SBarry Smith } PC_Eisenstat;
17*4b9ad928SBarry Smith 
18*4b9ad928SBarry Smith 
19*4b9ad928SBarry Smith #undef __FUNCT__
20*4b9ad928SBarry Smith #define __FUNCT__ "PCMult_Eisenstat"
21*4b9ad928SBarry Smith static int PCMult_Eisenstat(Mat mat,Vec b,Vec x)
22*4b9ad928SBarry Smith {
23*4b9ad928SBarry Smith   int          ierr;
24*4b9ad928SBarry Smith   PC           pc;
25*4b9ad928SBarry Smith   PC_Eisenstat *eis;
26*4b9ad928SBarry Smith 
27*4b9ad928SBarry Smith   PetscFunctionBegin;
28*4b9ad928SBarry Smith   ierr = MatShellGetContext(mat,(void **)&pc);CHKERRQ(ierr);
29*4b9ad928SBarry Smith   eis = (PC_Eisenstat*)pc->data;
30*4b9ad928SBarry Smith   ierr = MatRelax(eis->A,b,eis->omega,SOR_EISENSTAT,0.0,1,1,x);CHKERRQ(ierr);
31*4b9ad928SBarry Smith   PetscFunctionReturn(0);
32*4b9ad928SBarry Smith }
33*4b9ad928SBarry Smith 
34*4b9ad928SBarry Smith #undef __FUNCT__
35*4b9ad928SBarry Smith #define __FUNCT__ "PCApply_Eisenstat"
36*4b9ad928SBarry Smith static int PCApply_Eisenstat(PC pc,Vec x,Vec y)
37*4b9ad928SBarry Smith {
38*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat*)pc->data;
39*4b9ad928SBarry Smith   int          ierr;
40*4b9ad928SBarry Smith 
41*4b9ad928SBarry Smith   PetscFunctionBegin;
42*4b9ad928SBarry Smith   if (eis->usediag)  {ierr = VecPointwiseMult(x,eis->diag,y);CHKERRQ(ierr);}
43*4b9ad928SBarry Smith   else               {ierr = VecCopy(x,y);CHKERRQ(ierr);}
44*4b9ad928SBarry Smith   PetscFunctionReturn(0);
45*4b9ad928SBarry Smith }
46*4b9ad928SBarry Smith 
47*4b9ad928SBarry Smith #undef __FUNCT__
48*4b9ad928SBarry Smith #define __FUNCT__ "PCPre_Eisenstat"
49*4b9ad928SBarry Smith static int PCPre_Eisenstat(PC pc,KSP ksp,Vec x,Vec b)
50*4b9ad928SBarry Smith {
51*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat*)pc->data;
52*4b9ad928SBarry Smith   PetscTruth   nonzero;
53*4b9ad928SBarry Smith   int          ierr;
54*4b9ad928SBarry Smith 
55*4b9ad928SBarry Smith   PetscFunctionBegin;
56*4b9ad928SBarry Smith   if (pc->mat != pc->pmat) SETERRQ(PETSC_ERR_SUP,"Cannot have different mat and pmat");
57*4b9ad928SBarry Smith 
58*4b9ad928SBarry Smith   /* swap shell matrix and true matrix */
59*4b9ad928SBarry Smith   eis->A    = pc->mat;
60*4b9ad928SBarry Smith   pc->mat   = eis->shell;
61*4b9ad928SBarry Smith 
62*4b9ad928SBarry Smith   if (!eis->b) {
63*4b9ad928SBarry Smith     ierr = VecDuplicate(b,&eis->b);CHKERRQ(ierr);
64*4b9ad928SBarry Smith     PetscLogObjectParent(pc,eis->b);
65*4b9ad928SBarry Smith   }
66*4b9ad928SBarry Smith 
67*4b9ad928SBarry Smith   /* save true b, other option is to swap pointers */
68*4b9ad928SBarry Smith   ierr = VecCopy(b,eis->b);CHKERRQ(ierr);
69*4b9ad928SBarry Smith 
70*4b9ad928SBarry Smith   /* if nonzero initial guess, modify x */
71*4b9ad928SBarry Smith   ierr = KSPGetInitialGuessNonzero(ksp,&nonzero);CHKERRQ(ierr);
72*4b9ad928SBarry Smith   if (nonzero) {
73*4b9ad928SBarry Smith     ierr = MatRelax(eis->A,x,eis->omega,SOR_APPLY_UPPER,0.0,1,1,x);CHKERRQ(ierr);
74*4b9ad928SBarry Smith   }
75*4b9ad928SBarry Smith 
76*4b9ad928SBarry Smith   /* modify b by (L + D)^{-1} */
77*4b9ad928SBarry Smith   ierr =   MatRelax(eis->A,b,eis->omega,(MatSORType)(SOR_ZERO_INITIAL_GUESS |
78*4b9ad928SBarry Smith                                         SOR_FORWARD_SWEEP),0.0,1,1,b);CHKERRQ(ierr);
79*4b9ad928SBarry Smith   PetscFunctionReturn(0);
80*4b9ad928SBarry Smith }
81*4b9ad928SBarry Smith 
82*4b9ad928SBarry Smith #undef __FUNCT__
83*4b9ad928SBarry Smith #define __FUNCT__ "PCPost_Eisenstat"
84*4b9ad928SBarry Smith static int PCPost_Eisenstat(PC pc,KSP ksp,Vec x,Vec b)
85*4b9ad928SBarry Smith {
86*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat*)pc->data;
87*4b9ad928SBarry Smith   int          ierr;
88*4b9ad928SBarry Smith 
89*4b9ad928SBarry Smith   PetscFunctionBegin;
90*4b9ad928SBarry Smith   ierr =   MatRelax(eis->A,x,eis->omega,(MatSORType)(SOR_ZERO_INITIAL_GUESS |
91*4b9ad928SBarry Smith                                  SOR_BACKWARD_SWEEP),0.0,1,1,x);CHKERRQ(ierr);
92*4b9ad928SBarry Smith   pc->mat = eis->A;
93*4b9ad928SBarry Smith   /* get back true b */
94*4b9ad928SBarry Smith   ierr = VecCopy(eis->b,b);CHKERRQ(ierr);
95*4b9ad928SBarry Smith   PetscFunctionReturn(0);
96*4b9ad928SBarry Smith }
97*4b9ad928SBarry Smith 
98*4b9ad928SBarry Smith #undef __FUNCT__
99*4b9ad928SBarry Smith #define __FUNCT__ "PCDestroy_Eisenstat"
100*4b9ad928SBarry Smith static int PCDestroy_Eisenstat(PC pc)
101*4b9ad928SBarry Smith {
102*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat *)pc->data;
103*4b9ad928SBarry Smith   int          ierr;
104*4b9ad928SBarry Smith 
105*4b9ad928SBarry Smith   PetscFunctionBegin;
106*4b9ad928SBarry Smith   if (eis->b)     {ierr = VecDestroy(eis->b);CHKERRQ(ierr);}
107*4b9ad928SBarry Smith   if (eis->shell) {ierr = MatDestroy(eis->shell);CHKERRQ(ierr);}
108*4b9ad928SBarry Smith   if (eis->diag)  {ierr = VecDestroy(eis->diag);CHKERRQ(ierr);}
109*4b9ad928SBarry Smith   ierr = PetscFree(eis);CHKERRQ(ierr);
110*4b9ad928SBarry Smith   PetscFunctionReturn(0);
111*4b9ad928SBarry Smith }
112*4b9ad928SBarry Smith 
113*4b9ad928SBarry Smith #undef __FUNCT__
114*4b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions_Eisenstat"
115*4b9ad928SBarry Smith static int PCSetFromOptions_Eisenstat(PC pc)
116*4b9ad928SBarry Smith {
117*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat*)pc->data;
118*4b9ad928SBarry Smith   int        ierr;
119*4b9ad928SBarry Smith   PetscTruth flg;
120*4b9ad928SBarry Smith 
121*4b9ad928SBarry Smith   PetscFunctionBegin;
122*4b9ad928SBarry Smith   ierr = PetscOptionsHead("Eisenstat SSOR options");CHKERRQ(ierr);
123*4b9ad928SBarry Smith     ierr = PetscOptionsReal("-pc_eisenstat_omega","Relaxation factor 0 < omega < 2","PCEisenstatSetOmega",eis->omega,&eis->omega,0);CHKERRQ(ierr);
124*4b9ad928SBarry Smith     ierr = PetscOptionsName("-pc_eisenstat_no_diagonal_scaling","Do not use standard diagonal scaling","PCEisenstatNoDiagonalScaling",&flg);CHKERRQ(ierr);
125*4b9ad928SBarry Smith     if (flg) {
126*4b9ad928SBarry Smith       ierr = PCEisenstatNoDiagonalScaling(pc);CHKERRQ(ierr);
127*4b9ad928SBarry Smith     }
128*4b9ad928SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
129*4b9ad928SBarry Smith   PetscFunctionReturn(0);
130*4b9ad928SBarry Smith }
131*4b9ad928SBarry Smith 
132*4b9ad928SBarry Smith #undef __FUNCT__
133*4b9ad928SBarry Smith #define __FUNCT__ "PCView_Eisenstat"
134*4b9ad928SBarry Smith static int PCView_Eisenstat(PC pc,PetscViewer viewer)
135*4b9ad928SBarry Smith {
136*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat*)pc->data;
137*4b9ad928SBarry Smith   int          ierr;
138*4b9ad928SBarry Smith   PetscTruth   isascii;
139*4b9ad928SBarry Smith 
140*4b9ad928SBarry Smith   PetscFunctionBegin;
141*4b9ad928SBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&isascii);CHKERRQ(ierr);
142*4b9ad928SBarry Smith   if (isascii) {
143*4b9ad928SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Eisenstat: omega = %g\n",eis->omega);CHKERRQ(ierr);
144*4b9ad928SBarry Smith     if (eis->usediag) {
145*4b9ad928SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"Eisenstat: Using diagonal scaling (default)\n");CHKERRQ(ierr);
146*4b9ad928SBarry Smith     } else {
147*4b9ad928SBarry Smith       ierr = PetscViewerASCIIPrintf(viewer,"Eisenstat: Not using diagonal scaling\n");CHKERRQ(ierr);
148*4b9ad928SBarry Smith     }
149*4b9ad928SBarry Smith   } else {
150*4b9ad928SBarry Smith     SETERRQ1(1,"Viewer type %s not supported for Eisenstat PC",((PetscObject)viewer)->type_name);
151*4b9ad928SBarry Smith   }
152*4b9ad928SBarry Smith   PetscFunctionReturn(0);
153*4b9ad928SBarry Smith }
154*4b9ad928SBarry Smith 
155*4b9ad928SBarry Smith #undef __FUNCT__
156*4b9ad928SBarry Smith #define __FUNCT__ "PCSetUp_Eisenstat"
157*4b9ad928SBarry Smith static int PCSetUp_Eisenstat(PC pc)
158*4b9ad928SBarry Smith {
159*4b9ad928SBarry Smith   int          ierr,M,N,m,n;
160*4b9ad928SBarry Smith   PC_Eisenstat *eis = (PC_Eisenstat*)pc->data;
161*4b9ad928SBarry Smith 
162*4b9ad928SBarry Smith   PetscFunctionBegin;
163*4b9ad928SBarry Smith   if (!pc->setupcalled) {
164*4b9ad928SBarry Smith     ierr = MatGetSize(pc->mat,&M,&N);CHKERRQ(ierr);
165*4b9ad928SBarry Smith     ierr = MatGetLocalSize(pc->mat,&m,&n);CHKERRQ(ierr);
166*4b9ad928SBarry Smith     ierr = MatCreateShell(pc->comm,m,N,M,N,(void*)pc,&eis->shell);CHKERRQ(ierr);
167*4b9ad928SBarry Smith     PetscLogObjectParent(pc,eis->shell);
168*4b9ad928SBarry Smith     ierr = MatShellSetOperation(eis->shell,MATOP_MULT,(void(*)(void))PCMult_Eisenstat);CHKERRQ(ierr);
169*4b9ad928SBarry Smith   }
170*4b9ad928SBarry Smith   if (!eis->usediag) PetscFunctionReturn(0);
171*4b9ad928SBarry Smith   if (!pc->setupcalled) {
172*4b9ad928SBarry Smith     ierr = VecDuplicate(pc->vec,&eis->diag);CHKERRQ(ierr);
173*4b9ad928SBarry Smith     PetscLogObjectParent(pc,eis->diag);
174*4b9ad928SBarry Smith   }
175*4b9ad928SBarry Smith   ierr = MatGetDiagonal(pc->pmat,eis->diag);CHKERRQ(ierr);
176*4b9ad928SBarry Smith   PetscFunctionReturn(0);
177*4b9ad928SBarry Smith }
178*4b9ad928SBarry Smith 
179*4b9ad928SBarry Smith /* --------------------------------------------------------------------*/
180*4b9ad928SBarry Smith 
181*4b9ad928SBarry Smith EXTERN_C_BEGIN
182*4b9ad928SBarry Smith #undef __FUNCT__
183*4b9ad928SBarry Smith #define __FUNCT__ "PCEisenstatSetOmega_Eisenstat"
184*4b9ad928SBarry Smith int PCEisenstatSetOmega_Eisenstat(PC pc,PetscReal omega)
185*4b9ad928SBarry Smith {
186*4b9ad928SBarry Smith   PC_Eisenstat  *eis;
187*4b9ad928SBarry Smith 
188*4b9ad928SBarry Smith   PetscFunctionBegin;
189*4b9ad928SBarry Smith   if (omega >= 2.0 || omega <= 0.0) SETERRQ(PETSC_ERR_ARG_OUTOFRANGE,"Relaxation out of range");
190*4b9ad928SBarry Smith   eis = (PC_Eisenstat*)pc->data;
191*4b9ad928SBarry Smith   eis->omega = omega;
192*4b9ad928SBarry Smith   PetscFunctionReturn(0);
193*4b9ad928SBarry Smith }
194*4b9ad928SBarry Smith EXTERN_C_END
195*4b9ad928SBarry Smith 
196*4b9ad928SBarry Smith EXTERN_C_BEGIN
197*4b9ad928SBarry Smith #undef __FUNCT__
198*4b9ad928SBarry Smith #define __FUNCT__ "PCEisenstatNoDiagonalScaling_Eisenstat"
199*4b9ad928SBarry Smith int PCEisenstatNoDiagonalScaling_Eisenstat(PC pc)
200*4b9ad928SBarry Smith {
201*4b9ad928SBarry Smith   PC_Eisenstat *eis;
202*4b9ad928SBarry Smith 
203*4b9ad928SBarry Smith   PetscFunctionBegin;
204*4b9ad928SBarry Smith   eis = (PC_Eisenstat*)pc->data;
205*4b9ad928SBarry Smith   eis->usediag = PETSC_FALSE;
206*4b9ad928SBarry Smith   PetscFunctionReturn(0);
207*4b9ad928SBarry Smith }
208*4b9ad928SBarry Smith EXTERN_C_END
209*4b9ad928SBarry Smith 
210*4b9ad928SBarry Smith #undef __FUNCT__
211*4b9ad928SBarry Smith #define __FUNCT__ "PCEisenstatSetOmega"
212*4b9ad928SBarry Smith /*@
213*4b9ad928SBarry Smith    PCEisenstatSetOmega - Sets the SSOR relaxation coefficient, omega,
214*4b9ad928SBarry Smith    to use with Eisenstat's trick (where omega = 1.0 by default).
215*4b9ad928SBarry Smith 
216*4b9ad928SBarry Smith    Collective on PC
217*4b9ad928SBarry Smith 
218*4b9ad928SBarry Smith    Input Parameters:
219*4b9ad928SBarry Smith +  pc - the preconditioner context
220*4b9ad928SBarry Smith -  omega - relaxation coefficient (0 < omega < 2)
221*4b9ad928SBarry Smith 
222*4b9ad928SBarry Smith    Options Database Key:
223*4b9ad928SBarry Smith .  -pc_eisenstat_omega <omega> - Sets omega
224*4b9ad928SBarry Smith 
225*4b9ad928SBarry Smith    Notes:
226*4b9ad928SBarry Smith    The Eisenstat trick implementation of SSOR requires about 50% of the
227*4b9ad928SBarry Smith    usual amount of floating point operations used for SSOR + Krylov method;
228*4b9ad928SBarry Smith    however, the preconditioned problem must be solved with both left
229*4b9ad928SBarry Smith    and right preconditioning.
230*4b9ad928SBarry Smith 
231*4b9ad928SBarry Smith    To use SSOR without the Eisenstat trick, employ the PCSOR preconditioner,
232*4b9ad928SBarry Smith    which can be chosen with the database options
233*4b9ad928SBarry Smith $    -pc_type  sor  -pc_sor_symmetric
234*4b9ad928SBarry Smith 
235*4b9ad928SBarry Smith    Level: intermediate
236*4b9ad928SBarry Smith 
237*4b9ad928SBarry Smith .keywords: PC, Eisenstat, set, SOR, SSOR, relaxation, omega
238*4b9ad928SBarry Smith 
239*4b9ad928SBarry Smith .seealso: PCSORSetOmega()
240*4b9ad928SBarry Smith @*/
241*4b9ad928SBarry Smith int PCEisenstatSetOmega(PC pc,PetscReal omega)
242*4b9ad928SBarry Smith {
243*4b9ad928SBarry Smith   int ierr,(*f)(PC,PetscReal);
244*4b9ad928SBarry Smith 
245*4b9ad928SBarry Smith   PetscFunctionBegin;
246*4b9ad928SBarry Smith   PetscValidHeaderSpecific(pc,PC_COOKIE);
247*4b9ad928SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCEisenstatSetOmega_C",(void (**)(void))&f);CHKERRQ(ierr);
248*4b9ad928SBarry Smith   if (f) {
249*4b9ad928SBarry Smith     ierr = (*f)(pc,omega);CHKERRQ(ierr);
250*4b9ad928SBarry Smith   }
251*4b9ad928SBarry Smith   PetscFunctionReturn(0);
252*4b9ad928SBarry Smith }
253*4b9ad928SBarry Smith 
254*4b9ad928SBarry Smith #undef __FUNCT__
255*4b9ad928SBarry Smith #define __FUNCT__ "PCEisenstatNoDiagonalScaling"
256*4b9ad928SBarry Smith /*@
257*4b9ad928SBarry Smith    PCEisenstatNoDiagonalScaling - Causes the Eisenstat preconditioner
258*4b9ad928SBarry Smith    not to do additional diagonal preconditioning. For matrices with a constant
259*4b9ad928SBarry Smith    along the diagonal, this may save a small amount of work.
260*4b9ad928SBarry Smith 
261*4b9ad928SBarry Smith    Collective on PC
262*4b9ad928SBarry Smith 
263*4b9ad928SBarry Smith    Input Parameter:
264*4b9ad928SBarry Smith .  pc - the preconditioner context
265*4b9ad928SBarry Smith 
266*4b9ad928SBarry Smith    Options Database Key:
267*4b9ad928SBarry Smith .  -pc_eisenstat_no_diagonal_scaling - Activates PCEisenstatNoDiagonalScaling()
268*4b9ad928SBarry Smith 
269*4b9ad928SBarry Smith    Level: intermediate
270*4b9ad928SBarry Smith 
271*4b9ad928SBarry Smith    Note:
272*4b9ad928SBarry Smith      If you use the KPSSetDiagonalScaling() or -ksp_diagonal_scale option then you will
273*4b9ad928SBarry Smith    likley want to use this routine since it will save you some unneeded flops.
274*4b9ad928SBarry Smith 
275*4b9ad928SBarry Smith .keywords: PC, Eisenstat, use, diagonal, scaling, SSOR
276*4b9ad928SBarry Smith 
277*4b9ad928SBarry Smith .seealso: PCEisenstatSetOmega()
278*4b9ad928SBarry Smith @*/
279*4b9ad928SBarry Smith int PCEisenstatNoDiagonalScaling(PC pc)
280*4b9ad928SBarry Smith {
281*4b9ad928SBarry Smith   int ierr,(*f)(PC);
282*4b9ad928SBarry Smith 
283*4b9ad928SBarry Smith   PetscFunctionBegin;
284*4b9ad928SBarry Smith   PetscValidHeaderSpecific(pc,PC_COOKIE);
285*4b9ad928SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCEisenstatNoDiagonalScaling_C",(void (**)(void))&f);CHKERRQ(ierr);
286*4b9ad928SBarry Smith   if (f) {
287*4b9ad928SBarry Smith     ierr = (*f)(pc);CHKERRQ(ierr);
288*4b9ad928SBarry Smith   }
289*4b9ad928SBarry Smith   PetscFunctionReturn(0);
290*4b9ad928SBarry Smith }
291*4b9ad928SBarry Smith 
292*4b9ad928SBarry Smith /* --------------------------------------------------------------------*/
293*4b9ad928SBarry Smith 
294*4b9ad928SBarry Smith /*MC
295*4b9ad928SBarry Smith      PCEISENSTAT - An implementation of SSOR (symmetric successive over relaxation, symmetric Gauss-Seidel)
296*4b9ad928SBarry Smith            preconditioning that incorporates Eisenstat's trick to reduce the amount of computation needed.
297*4b9ad928SBarry Smith 
298*4b9ad928SBarry Smith    Options Database Keys:
299*4b9ad928SBarry Smith +  -pc_eisenstat_omega <omega> - Sets omega
300*4b9ad928SBarry Smith -  -pc_eisenstat_no_diagonal_scaling - Activates PCEisenstatNoDiagonalScaling()
301*4b9ad928SBarry Smith 
302*4b9ad928SBarry Smith    Level: beginner
303*4b9ad928SBarry Smith 
304*4b9ad928SBarry Smith   Concepts: SOR, preconditioners, Gauss-Seidel, Eisenstat's trick
305*4b9ad928SBarry Smith 
306*4b9ad928SBarry Smith    Notes: Only implemented for the SeqAIJ matrix format.
307*4b9ad928SBarry Smith           Not a true parallel SOR, in parallel this implementation corresponds to block
308*4b9ad928SBarry Smith           Jacobi with SOR on each block.
309*4b9ad928SBarry Smith 
310*4b9ad928SBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
311*4b9ad928SBarry Smith            PCEisenstatNoDiagonalScaling(), PCEisenstatSetOmega(), PCSOR
312*4b9ad928SBarry Smith M*/
313*4b9ad928SBarry Smith 
314*4b9ad928SBarry Smith EXTERN_C_BEGIN
315*4b9ad928SBarry Smith #undef __FUNCT__
316*4b9ad928SBarry Smith #define __FUNCT__ "PCCreate_Eisenstat"
317*4b9ad928SBarry Smith int PCCreate_Eisenstat(PC pc)
318*4b9ad928SBarry Smith {
319*4b9ad928SBarry Smith   int          ierr;
320*4b9ad928SBarry Smith   PC_Eisenstat *eis;
321*4b9ad928SBarry Smith 
322*4b9ad928SBarry Smith   PetscFunctionBegin;
323*4b9ad928SBarry Smith   ierr = PetscNew(PC_Eisenstat,&eis);CHKERRQ(ierr);
324*4b9ad928SBarry Smith   PetscLogObjectMemory(pc,sizeof(PC_Eisenstat));
325*4b9ad928SBarry Smith 
326*4b9ad928SBarry Smith   pc->ops->apply           = PCApply_Eisenstat;
327*4b9ad928SBarry Smith   pc->ops->presolve        = PCPre_Eisenstat;
328*4b9ad928SBarry Smith   pc->ops->postsolve       = PCPost_Eisenstat;
329*4b9ad928SBarry Smith   pc->ops->applyrichardson = 0;
330*4b9ad928SBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Eisenstat;
331*4b9ad928SBarry Smith   pc->ops->destroy         = PCDestroy_Eisenstat;
332*4b9ad928SBarry Smith   pc->ops->view            = PCView_Eisenstat;
333*4b9ad928SBarry Smith   pc->ops->setup           = PCSetUp_Eisenstat;
334*4b9ad928SBarry Smith 
335*4b9ad928SBarry Smith   pc->data           = (void*)eis;
336*4b9ad928SBarry Smith   eis->omega         = 1.0;
337*4b9ad928SBarry Smith   eis->b             = 0;
338*4b9ad928SBarry Smith   eis->diag          = 0;
339*4b9ad928SBarry Smith   eis->usediag       = PETSC_TRUE;
340*4b9ad928SBarry Smith 
341*4b9ad928SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCEisenstatSetOmega_C","PCEisenstatSetOmega_Eisenstat",
342*4b9ad928SBarry Smith                     PCEisenstatSetOmega_Eisenstat);CHKERRQ(ierr);
343*4b9ad928SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCEisenstatNoDiagonalScaling_C",
344*4b9ad928SBarry Smith                     "PCEisenstatNoDiagonalScaling_Eisenstat",
345*4b9ad928SBarry Smith                     PCEisenstatNoDiagonalScaling_Eisenstat);CHKERRQ(ierr);
346*4b9ad928SBarry Smith  PetscFunctionReturn(0);
347*4b9ad928SBarry Smith }
348*4b9ad928SBarry Smith EXTERN_C_END
349