12a6744ebSBarry Smith 22a6744ebSBarry Smith /* 32a6744ebSBarry Smith Defines a preconditioner defined by R^T S R 42a6744ebSBarry Smith */ 5af0996ceSBarry Smith #include <petsc/private/pcimpl.h> 6c6db04a5SJed Brown #include <petscksp.h> /*I "petscksp.h" I*/ 72a6744ebSBarry Smith 82a6744ebSBarry Smith typedef struct { 92a6744ebSBarry Smith KSP ksp; 102a6744ebSBarry Smith Mat R,P; 112a6744ebSBarry Smith Vec b,x; 12b3402f20SBarry Smith PetscErrorCode (*computeasub)(PC,Mat,Mat,Mat*,void*); 13b3402f20SBarry Smith void *computeasub_ctx; 142a6744ebSBarry Smith } PC_Galerkin; 152a6744ebSBarry Smith 162a6744ebSBarry Smith static PetscErrorCode PCApply_Galerkin(PC pc,Vec x,Vec y) 172a6744ebSBarry Smith { 182a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 192a6744ebSBarry Smith 202a6744ebSBarry Smith PetscFunctionBegin; 212fa5cd67SKarl Rupp if (jac->R) { 225f80ce2aSJacob Faibussowitsch CHKERRQ(MatRestrict(jac->R,x,jac->b)); 232fa5cd67SKarl Rupp } else { 245f80ce2aSJacob Faibussowitsch CHKERRQ(MatRestrict(jac->P,x,jac->b)); 252fa5cd67SKarl Rupp } 265f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSolve(jac->ksp,jac->b,jac->x)); 275f80ce2aSJacob Faibussowitsch CHKERRQ(KSPCheckSolve(jac->ksp,pc,jac->x)); 282fa5cd67SKarl Rupp if (jac->P) { 295f80ce2aSJacob Faibussowitsch CHKERRQ(MatInterpolate(jac->P,jac->x,y)); 302fa5cd67SKarl Rupp } else { 315f80ce2aSJacob Faibussowitsch CHKERRQ(MatInterpolate(jac->R,jac->x,y)); 322fa5cd67SKarl Rupp } 332a6744ebSBarry Smith PetscFunctionReturn(0); 342a6744ebSBarry Smith } 352a6744ebSBarry Smith 362a6744ebSBarry Smith static PetscErrorCode PCSetUp_Galerkin(PC pc) 372a6744ebSBarry Smith { 382a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 39ace3abfcSBarry Smith PetscBool a; 40906ed7ccSBarry Smith Vec *xx,*yy; 412a6744ebSBarry Smith 422a6744ebSBarry Smith PetscFunctionBegin; 43b3402f20SBarry Smith if (jac->computeasub) { 44b3402f20SBarry Smith Mat Ap; 45b3402f20SBarry Smith if (!pc->setupcalled) { 465f80ce2aSJacob Faibussowitsch CHKERRQ((*jac->computeasub)(pc,pc->pmat,NULL,&Ap,jac->computeasub_ctx)); 475f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetOperators(jac->ksp,Ap,Ap)); 485f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&Ap)); 49b3402f20SBarry Smith } else { 505f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetOperators(jac->ksp,NULL,&Ap)); 515f80ce2aSJacob Faibussowitsch CHKERRQ((*jac->computeasub)(pc,pc->pmat,Ap,NULL,jac->computeasub_ctx)); 52b3402f20SBarry Smith } 53b3402f20SBarry Smith } 54b3402f20SBarry Smith 552a6744ebSBarry Smith if (!jac->x) { 565f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetOperatorsSet(jac->ksp,&a,NULL)); 57*28b400f6SJacob Faibussowitsch PetscCheck(a,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()"); 585f80ce2aSJacob Faibussowitsch CHKERRQ(KSPCreateVecs(jac->ksp,1,&xx,1,&yy)); 59906ed7ccSBarry Smith jac->x = *xx; 60906ed7ccSBarry Smith jac->b = *yy; 615f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(xx)); 625f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(yy)); 632a6744ebSBarry Smith } 642c71b3e2SJacob Faibussowitsch PetscCheckFalse(!jac->R && !jac->P,PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction()/Interpolation()"); 652a6744ebSBarry Smith /* should check here that sizes of R/P match size of a */ 66b3402f20SBarry Smith 672a6744ebSBarry Smith PetscFunctionReturn(0); 682a6744ebSBarry Smith } 692a6744ebSBarry Smith 70a06653b4SBarry Smith static PetscErrorCode PCReset_Galerkin(PC pc) 712a6744ebSBarry Smith { 722a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 732a6744ebSBarry Smith 742a6744ebSBarry Smith PetscFunctionBegin; 755f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&jac->R)); 765f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&jac->P)); 775f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&jac->x)); 785f80ce2aSJacob Faibussowitsch CHKERRQ(VecDestroy(&jac->b)); 795f80ce2aSJacob Faibussowitsch CHKERRQ(KSPReset(jac->ksp)); 80a06653b4SBarry Smith PetscFunctionReturn(0); 81a06653b4SBarry Smith } 82a06653b4SBarry Smith 83a06653b4SBarry Smith static PetscErrorCode PCDestroy_Galerkin(PC pc) 84a06653b4SBarry Smith { 85a06653b4SBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 86a06653b4SBarry Smith 87a06653b4SBarry Smith PetscFunctionBegin; 885f80ce2aSJacob Faibussowitsch CHKERRQ(PCReset_Galerkin(pc)); 895f80ce2aSJacob Faibussowitsch CHKERRQ(KSPDestroy(&jac->ksp)); 905f80ce2aSJacob Faibussowitsch CHKERRQ(PetscFree(pc->data)); 912a6744ebSBarry Smith PetscFunctionReturn(0); 922a6744ebSBarry Smith } 932a6744ebSBarry Smith 942a6744ebSBarry Smith static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer) 952a6744ebSBarry Smith { 962a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 97ace3abfcSBarry Smith PetscBool iascii; 982a6744ebSBarry Smith 992a6744ebSBarry Smith PetscFunctionBegin; 1005f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 1012a6744ebSBarry Smith if (iascii) { 1025f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," KSP on Galerkin follow\n")); 1035f80ce2aSJacob Faibussowitsch CHKERRQ(PetscViewerASCIIPrintf(viewer," ---------------------------------\n")); 1042a6744ebSBarry Smith } 1055f80ce2aSJacob Faibussowitsch CHKERRQ(KSPView(jac->ksp,viewer)); 1062a6744ebSBarry Smith PetscFunctionReturn(0); 1072a6744ebSBarry Smith } 1082a6744ebSBarry Smith 1091e6b0712SBarry Smith static PetscErrorCode PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp) 1102a6744ebSBarry Smith { 1112a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1122a6744ebSBarry Smith 1132a6744ebSBarry Smith PetscFunctionBegin; 1142a6744ebSBarry Smith *ksp = jac->ksp; 1152a6744ebSBarry Smith PetscFunctionReturn(0); 1162a6744ebSBarry Smith } 1172a6744ebSBarry Smith 1181e6b0712SBarry Smith static PetscErrorCode PCGalerkinSetRestriction_Galerkin(PC pc,Mat R) 1192a6744ebSBarry Smith { 1202a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1212a6744ebSBarry Smith 1222a6744ebSBarry Smith PetscFunctionBegin; 1235f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)R)); 1245f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&jac->R)); 1252a6744ebSBarry Smith jac->R = R; 1262a6744ebSBarry Smith PetscFunctionReturn(0); 1272a6744ebSBarry Smith } 1282a6744ebSBarry Smith 1291e6b0712SBarry Smith static PetscErrorCode PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P) 1302a6744ebSBarry Smith { 1312a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1322a6744ebSBarry Smith 1332a6744ebSBarry Smith PetscFunctionBegin; 1345f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectReference((PetscObject)P)); 1355f80ce2aSJacob Faibussowitsch CHKERRQ(MatDestroy(&jac->P)); 1362a6744ebSBarry Smith jac->P = P; 1372a6744ebSBarry Smith PetscFunctionReturn(0); 1382a6744ebSBarry Smith } 1392a6744ebSBarry Smith 140b3402f20SBarry Smith static PetscErrorCode PCGalerkinSetComputeSubmatrix_Galerkin(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx) 141b3402f20SBarry Smith { 142b3402f20SBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 143b3402f20SBarry Smith 144b3402f20SBarry Smith PetscFunctionBegin; 145b3402f20SBarry Smith jac->computeasub = computeAsub; 146b3402f20SBarry Smith jac->computeasub_ctx = ctx; 147b3402f20SBarry Smith PetscFunctionReturn(0); 148b3402f20SBarry Smith } 149b3402f20SBarry Smith 1502a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */ 1512a6744ebSBarry Smith /*@ 1522a6744ebSBarry Smith PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner 1532a6744ebSBarry Smith 154ad4df100SBarry Smith Logically Collective on PC 1552a6744ebSBarry Smith 156d8d19677SJose E. Roman Input Parameters: 1572a6744ebSBarry Smith + pc - the preconditioner context 1582a6744ebSBarry Smith - R - the restriction operator 1592a6744ebSBarry Smith 16095452b02SPatrick Sanan Notes: 16195452b02SPatrick Sanan Either this or PCGalerkinSetInterpolation() or both must be called 1622a6744ebSBarry Smith 1632a6744ebSBarry Smith Level: Intermediate 1642a6744ebSBarry Smith 1652a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 1662a6744ebSBarry Smith PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 1672a6744ebSBarry Smith 1682a6744ebSBarry Smith @*/ 1697087cfbeSBarry Smith PetscErrorCode PCGalerkinSetRestriction(PC pc,Mat R) 1702a6744ebSBarry Smith { 1712a6744ebSBarry Smith PetscFunctionBegin; 1720700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R))); 1742a6744ebSBarry Smith PetscFunctionReturn(0); 1752a6744ebSBarry Smith } 1762a6744ebSBarry Smith 1772a6744ebSBarry Smith /*@ 1782a6744ebSBarry Smith PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner 1792a6744ebSBarry Smith 180ad4df100SBarry Smith Logically Collective on PC 1812a6744ebSBarry Smith 182d8d19677SJose E. Roman Input Parameters: 1832a6744ebSBarry Smith + pc - the preconditioner context 1842a6744ebSBarry Smith - R - the interpolation operator 1852a6744ebSBarry Smith 18695452b02SPatrick Sanan Notes: 18795452b02SPatrick Sanan Either this or PCGalerkinSetRestriction() or both must be called 1882a6744ebSBarry Smith 1892a6744ebSBarry Smith Level: Intermediate 1902a6744ebSBarry Smith 1912a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 1922a6744ebSBarry Smith PCGalerkinSetRestriction(), PCGalerkinGetKSP() 1932a6744ebSBarry Smith 1942a6744ebSBarry Smith @*/ 1957087cfbeSBarry Smith PetscErrorCode PCGalerkinSetInterpolation(PC pc,Mat P) 1962a6744ebSBarry Smith { 1972a6744ebSBarry Smith PetscFunctionBegin; 1980700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1995f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P))); 2002a6744ebSBarry Smith PetscFunctionReturn(0); 2012a6744ebSBarry Smith } 2022a6744ebSBarry Smith 2032a6744ebSBarry Smith /*@ 204b3402f20SBarry Smith PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix 205b3402f20SBarry Smith 206b3402f20SBarry Smith Logically Collective 207b3402f20SBarry Smith 208d8d19677SJose E. Roman Input Parameters: 209b3402f20SBarry Smith + pc - the preconditioner context 210b3402f20SBarry Smith . computeAsub - routine that computes the submatrix from the global matrix 211b3402f20SBarry Smith - ctx - context used by the routine, or NULL 212b3402f20SBarry Smith 213b3402f20SBarry Smith Calling sequence of computeAsub: 214b3402f20SBarry Smith $ computeAsub(PC pc,Mat A, Mat Ap, Mat *cAP,void *ctx); 215b3402f20SBarry Smith 216b3402f20SBarry Smith + PC - the Galerkin PC 217b3402f20SBarry Smith . A - the matrix in the Galerkin PC 218b3402f20SBarry Smith . Ap - the computed submatrix from any previous computation, if NULL it has not previously been computed 219b3402f20SBarry Smith . cAp - the submatrix computed by this routine 220b3402f20SBarry Smith - ctx - optional user-defined function context 221b3402f20SBarry Smith 222b3402f20SBarry Smith Level: Intermediate 223b3402f20SBarry Smith 22495452b02SPatrick Sanan Notes: 22595452b02SPatrick Sanan Instead of providing this routine you can call PCGalerkinGetKSP() and then KSPSetOperators() to provide the submatrix, 226b3402f20SBarry Smith but that will not work for multiple KSPSolves with different matrices unless you call it for each solve. 227b3402f20SBarry Smith 228910cf402Sprj- This routine is called each time the outer matrix is changed. In the first call the Ap argument is NULL and the routine should create the 229b3402f20SBarry Smith matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix. 230b3402f20SBarry Smith 23195452b02SPatrick Sanan Developer Notes: 23295452b02SPatrick Sanan If the user does not call this routine nor call PCGalerkinGetKSP() and KSPSetOperators() then PCGalerkin could 233b3402f20SBarry Smith could automatically compute the submatrix via calls to MatGalerkin() or MatRARt() 234b3402f20SBarry Smith 235b3402f20SBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 236b3402f20SBarry Smith PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 237b3402f20SBarry Smith 238b3402f20SBarry Smith @*/ 239b3402f20SBarry Smith PetscErrorCode PCGalerkinSetComputeSubmatrix(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx) 240b3402f20SBarry Smith { 241b3402f20SBarry Smith PetscFunctionBegin; 242b3402f20SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscTryMethod(pc,"PCGalerkinSetComputeSubmatrix_C",(PC,PetscErrorCode (*)(PC,Mat,Mat,Mat*,void*),void*),(pc,computeAsub,ctx))); 244b3402f20SBarry Smith PetscFunctionReturn(0); 245b3402f20SBarry Smith } 246b3402f20SBarry Smith 247b3402f20SBarry Smith /*@ 2482a6744ebSBarry Smith PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC. 2492a6744ebSBarry Smith 2502a6744ebSBarry Smith Not Collective 2512a6744ebSBarry Smith 2522a6744ebSBarry Smith Input Parameter: 2532a6744ebSBarry Smith . pc - the preconditioner context 2542a6744ebSBarry Smith 2552a6744ebSBarry Smith Output Parameters: 2562a6744ebSBarry Smith . ksp - the KSP object 2572a6744ebSBarry Smith 2582a6744ebSBarry Smith Level: Intermediate 2592a6744ebSBarry Smith 26095452b02SPatrick Sanan Notes: 26195452b02SPatrick Sanan Once you have called this routine you can call KSPSetOperators() on the resulting ksp to provide the operator for the Galerkin problem, 262b3402f20SBarry Smith an alternative is to use PCGalerkinSetComputeSubmatrix() to provide a routine that computes the submatrix as needed. 263b3402f20SBarry Smith 2642a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 265b3402f20SBarry Smith PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinSetComputeSubmatrix() 2662a6744ebSBarry Smith 2672a6744ebSBarry Smith @*/ 2687087cfbeSBarry Smith PetscErrorCode PCGalerkinGetKSP(PC pc,KSP *ksp) 2692a6744ebSBarry Smith { 2702a6744ebSBarry Smith PetscFunctionBegin; 2710700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2722a6744ebSBarry Smith PetscValidPointer(ksp,2); 2735f80ce2aSJacob Faibussowitsch CHKERRQ(PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp))); 2742a6744ebSBarry Smith PetscFunctionReturn(0); 2752a6744ebSBarry Smith } 2762a6744ebSBarry Smith 2774ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc) 2784ac220ccSBarry Smith { 2794ac220ccSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 2804ac220ccSBarry Smith const char *prefix; 2814ac220ccSBarry Smith PetscBool flg; 2824ac220ccSBarry Smith 2834ac220ccSBarry Smith PetscFunctionBegin; 2845f80ce2aSJacob Faibussowitsch CHKERRQ(KSPGetOptionsPrefix(jac->ksp,&prefix)); 2855f80ce2aSJacob Faibussowitsch CHKERRQ(PetscStrendswith(prefix,"galerkin_",&flg)); 2864ac220ccSBarry Smith if (!flg) { 2875f80ce2aSJacob Faibussowitsch CHKERRQ(PCGetOptionsPrefix(pc,&prefix)); 2885f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetOptionsPrefix(jac->ksp,prefix)); 2895f80ce2aSJacob Faibussowitsch CHKERRQ(KSPAppendOptionsPrefix(jac->ksp,"galerkin_")); 2904ac220ccSBarry Smith } 2914ac220ccSBarry Smith 2925f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsHead(PetscOptionsObject,"Galerkin options")); 2934ac220ccSBarry Smith if (jac->ksp) { 2945f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetFromOptions(jac->ksp)); 2954ac220ccSBarry Smith } 2965f80ce2aSJacob Faibussowitsch CHKERRQ(PetscOptionsTail()); 2974ac220ccSBarry Smith PetscFunctionReturn(0); 2984ac220ccSBarry Smith } 2992a6744ebSBarry Smith 3002a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/ 3012a6744ebSBarry Smith 3022a6744ebSBarry Smith /*MC 3032a6744ebSBarry Smith PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T) 3042a6744ebSBarry Smith 3052a6744ebSBarry Smith $ Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by 3067817a140SBarry Smith $ PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....) 3072a6744ebSBarry Smith 3082a6744ebSBarry Smith Level: intermediate 3092a6744ebSBarry Smith 310b59c8b46SBarry Smith Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute 3117817a140SBarry Smith the operators automatically. 3127817a140SBarry Smith Should there be a prefix for the inner KSP. 3137817a140SBarry Smith There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP 3147817a140SBarry Smith 3152a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 3162a6744ebSBarry Smith PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 3172a6744ebSBarry Smith 3182a6744ebSBarry Smith M*/ 3192a6744ebSBarry Smith 3208cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc) 3212a6744ebSBarry Smith { 3222a6744ebSBarry Smith PC_Galerkin *jac; 3232a6744ebSBarry Smith 3242a6744ebSBarry Smith PetscFunctionBegin; 3255f80ce2aSJacob Faibussowitsch CHKERRQ(PetscNewLog(pc,&jac)); 3262fa5cd67SKarl Rupp 3272a6744ebSBarry Smith pc->ops->apply = PCApply_Galerkin; 3282a6744ebSBarry Smith pc->ops->setup = PCSetUp_Galerkin; 329a06653b4SBarry Smith pc->ops->reset = PCReset_Galerkin; 3302a6744ebSBarry Smith pc->ops->destroy = PCDestroy_Galerkin; 3312a6744ebSBarry Smith pc->ops->view = PCView_Galerkin; 3324ac220ccSBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Galerkin; 3334ac220ccSBarry Smith pc->ops->applyrichardson = NULL; 3342a6744ebSBarry Smith 3355f80ce2aSJacob Faibussowitsch CHKERRQ(KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp)); 3365f80ce2aSJacob Faibussowitsch CHKERRQ(KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure)); 3375f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1)); 3382a6744ebSBarry Smith 3392a6744ebSBarry Smith pc->data = (void*)jac; 3402a6744ebSBarry Smith 3415f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin)); 3425f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin)); 3435f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin)); 3445f80ce2aSJacob Faibussowitsch CHKERRQ(PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetComputeSubmatrix_C",PCGalerkinSetComputeSubmatrix_Galerkin)); 3452a6744ebSBarry Smith PetscFunctionReturn(0); 3462a6744ebSBarry Smith } 347