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