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 PetscErrorCode ierr; 192a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 202a6744ebSBarry Smith 212a6744ebSBarry Smith PetscFunctionBegin; 222fa5cd67SKarl Rupp if (jac->R) { 232fa5cd67SKarl Rupp ierr = MatRestrict(jac->R,x,jac->b);CHKERRQ(ierr); 242fa5cd67SKarl Rupp } else { 252fa5cd67SKarl Rupp ierr = MatRestrict(jac->P,x,jac->b);CHKERRQ(ierr); 262fa5cd67SKarl Rupp } 272a6744ebSBarry Smith ierr = KSPSolve(jac->ksp,jac->b,jac->x);CHKERRQ(ierr); 28c0decd05SBarry Smith ierr = KSPCheckSolve(jac->ksp,pc,jac->x);CHKERRQ(ierr); 292fa5cd67SKarl Rupp if (jac->P) { 302fa5cd67SKarl Rupp ierr = MatInterpolate(jac->P,jac->x,y);CHKERRQ(ierr); 312fa5cd67SKarl Rupp } else { 322fa5cd67SKarl Rupp ierr = MatInterpolate(jac->R,jac->x,y);CHKERRQ(ierr); 332fa5cd67SKarl Rupp } 342a6744ebSBarry Smith PetscFunctionReturn(0); 352a6744ebSBarry Smith } 362a6744ebSBarry Smith 372a6744ebSBarry Smith static PetscErrorCode PCSetUp_Galerkin(PC pc) 382a6744ebSBarry Smith { 392a6744ebSBarry Smith PetscErrorCode ierr; 402a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 41ace3abfcSBarry Smith PetscBool a; 42906ed7ccSBarry Smith Vec *xx,*yy; 432a6744ebSBarry Smith 442a6744ebSBarry Smith PetscFunctionBegin; 45b3402f20SBarry Smith if (jac->computeasub) { 46b3402f20SBarry Smith Mat Ap; 47b3402f20SBarry Smith if (!pc->setupcalled) { 48b3402f20SBarry Smith ierr = (*jac->computeasub)(pc,pc->pmat,NULL,&Ap,jac->computeasub_ctx);CHKERRQ(ierr); 49b3402f20SBarry Smith ierr = KSPSetOperators(jac->ksp,Ap,Ap);CHKERRQ(ierr); 50b3402f20SBarry Smith ierr = MatDestroy(&Ap);CHKERRQ(ierr); 51b3402f20SBarry Smith } else { 52b3402f20SBarry Smith ierr = KSPGetOperators(jac->ksp,NULL,&Ap);CHKERRQ(ierr); 53b3402f20SBarry Smith ierr = (*jac->computeasub)(pc,pc->pmat,Ap,NULL,jac->computeasub_ctx);CHKERRQ(ierr); 54b3402f20SBarry Smith } 55b3402f20SBarry Smith } 56b3402f20SBarry Smith 572a6744ebSBarry Smith if (!jac->x) { 580298fd71SBarry Smith ierr = KSPGetOperatorsSet(jac->ksp,&a,NULL);CHKERRQ(ierr); 59ce94432eSBarry Smith if (!a) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()"); 602a7a6963SBarry Smith ierr = KSPCreateVecs(jac->ksp,1,&xx,1,&yy);CHKERRQ(ierr); 61906ed7ccSBarry Smith jac->x = *xx; 62906ed7ccSBarry Smith jac->b = *yy; 63906ed7ccSBarry Smith ierr = PetscFree(xx);CHKERRQ(ierr); 64906ed7ccSBarry Smith ierr = PetscFree(yy);CHKERRQ(ierr); 652a6744ebSBarry Smith } 664ac220ccSBarry Smith if (!jac->R && !jac->P) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction()/Interpolation()"); 672a6744ebSBarry Smith /* should check here that sizes of R/P match size of a */ 68b3402f20SBarry Smith 692a6744ebSBarry Smith PetscFunctionReturn(0); 702a6744ebSBarry Smith } 712a6744ebSBarry Smith 72a06653b4SBarry Smith static PetscErrorCode PCReset_Galerkin(PC pc) 732a6744ebSBarry Smith { 742a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 752a6744ebSBarry Smith PetscErrorCode ierr; 762a6744ebSBarry Smith 772a6744ebSBarry Smith PetscFunctionBegin; 786bf464f9SBarry Smith ierr = MatDestroy(&jac->R);CHKERRQ(ierr); 796bf464f9SBarry Smith ierr = MatDestroy(&jac->P);CHKERRQ(ierr); 806bf464f9SBarry Smith ierr = VecDestroy(&jac->x);CHKERRQ(ierr); 816bf464f9SBarry Smith ierr = VecDestroy(&jac->b);CHKERRQ(ierr); 82a06653b4SBarry Smith ierr = KSPReset(jac->ksp);CHKERRQ(ierr); 83a06653b4SBarry Smith PetscFunctionReturn(0); 84a06653b4SBarry Smith } 85a06653b4SBarry Smith 86a06653b4SBarry Smith static PetscErrorCode PCDestroy_Galerkin(PC pc) 87a06653b4SBarry Smith { 88a06653b4SBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 89a06653b4SBarry Smith PetscErrorCode ierr; 90a06653b4SBarry Smith 91a06653b4SBarry Smith PetscFunctionBegin; 92fcfd50ebSBarry Smith ierr = PCReset_Galerkin(pc);CHKERRQ(ierr); 936bf464f9SBarry Smith ierr = KSPDestroy(&jac->ksp);CHKERRQ(ierr); 94c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 952a6744ebSBarry Smith PetscFunctionReturn(0); 962a6744ebSBarry Smith } 972a6744ebSBarry Smith 982a6744ebSBarry Smith static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer) 992a6744ebSBarry Smith { 1002a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1012a6744ebSBarry Smith PetscErrorCode ierr; 102ace3abfcSBarry Smith PetscBool iascii; 1032a6744ebSBarry Smith 1042a6744ebSBarry Smith PetscFunctionBegin; 105251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1062a6744ebSBarry Smith if (iascii) { 1072a6744ebSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," KSP on Galerkin follow\n");CHKERRQ(ierr); 1082a6744ebSBarry Smith ierr = PetscViewerASCIIPrintf(viewer," ---------------------------------\n");CHKERRQ(ierr); 1092a6744ebSBarry Smith } 1102a6744ebSBarry Smith ierr = KSPView(jac->ksp,viewer);CHKERRQ(ierr); 1112a6744ebSBarry Smith PetscFunctionReturn(0); 1122a6744ebSBarry Smith } 1132a6744ebSBarry Smith 1141e6b0712SBarry Smith static PetscErrorCode PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp) 1152a6744ebSBarry Smith { 1162a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1172a6744ebSBarry Smith 1182a6744ebSBarry Smith PetscFunctionBegin; 1192a6744ebSBarry Smith *ksp = jac->ksp; 1202a6744ebSBarry Smith PetscFunctionReturn(0); 1212a6744ebSBarry Smith } 1222a6744ebSBarry Smith 1231e6b0712SBarry Smith static PetscErrorCode PCGalerkinSetRestriction_Galerkin(PC pc,Mat R) 1242a6744ebSBarry Smith { 1252a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1262a6744ebSBarry Smith PetscErrorCode ierr; 1272a6744ebSBarry Smith 1282a6744ebSBarry Smith PetscFunctionBegin; 129c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)R);CHKERRQ(ierr); 1306bf464f9SBarry Smith ierr = MatDestroy(&jac->R);CHKERRQ(ierr); 1312a6744ebSBarry Smith jac->R = R; 1322a6744ebSBarry Smith PetscFunctionReturn(0); 1332a6744ebSBarry Smith } 1342a6744ebSBarry Smith 1351e6b0712SBarry Smith static PetscErrorCode PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P) 1362a6744ebSBarry Smith { 1372a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1382a6744ebSBarry Smith PetscErrorCode ierr; 1392a6744ebSBarry Smith 1402a6744ebSBarry Smith PetscFunctionBegin; 141c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)P);CHKERRQ(ierr); 1426bf464f9SBarry Smith ierr = MatDestroy(&jac->P);CHKERRQ(ierr); 1432a6744ebSBarry Smith jac->P = P; 1442a6744ebSBarry Smith PetscFunctionReturn(0); 1452a6744ebSBarry Smith } 1462a6744ebSBarry Smith 147b3402f20SBarry Smith static PetscErrorCode PCGalerkinSetComputeSubmatrix_Galerkin(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx) 148b3402f20SBarry Smith { 149b3402f20SBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 150b3402f20SBarry Smith 151b3402f20SBarry Smith PetscFunctionBegin; 152b3402f20SBarry Smith jac->computeasub = computeAsub; 153b3402f20SBarry Smith jac->computeasub_ctx = ctx; 154b3402f20SBarry Smith PetscFunctionReturn(0); 155b3402f20SBarry Smith } 156b3402f20SBarry Smith 1572a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */ 1582a6744ebSBarry Smith /*@ 1592a6744ebSBarry Smith PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner 1602a6744ebSBarry Smith 161ad4df100SBarry Smith Logically Collective on PC 1622a6744ebSBarry Smith 1632a6744ebSBarry Smith Input Parameter: 1642a6744ebSBarry Smith + pc - the preconditioner context 1652a6744ebSBarry Smith - R - the restriction operator 1662a6744ebSBarry Smith 16795452b02SPatrick Sanan Notes: 16895452b02SPatrick Sanan Either this or PCGalerkinSetInterpolation() or both must be called 1692a6744ebSBarry Smith 1702a6744ebSBarry Smith Level: Intermediate 1712a6744ebSBarry Smith 1722a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 1732a6744ebSBarry Smith PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 1742a6744ebSBarry Smith 1752a6744ebSBarry Smith @*/ 1767087cfbeSBarry Smith PetscErrorCode PCGalerkinSetRestriction(PC pc,Mat R) 1772a6744ebSBarry Smith { 1784ac538c5SBarry Smith PetscErrorCode ierr; 1792a6744ebSBarry Smith 1802a6744ebSBarry Smith PetscFunctionBegin; 1810700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1824ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));CHKERRQ(ierr); 1832a6744ebSBarry Smith PetscFunctionReturn(0); 1842a6744ebSBarry Smith } 1852a6744ebSBarry Smith 1862a6744ebSBarry Smith /*@ 1872a6744ebSBarry Smith PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner 1882a6744ebSBarry Smith 189ad4df100SBarry Smith Logically Collective on PC 1902a6744ebSBarry Smith 1912a6744ebSBarry Smith Input Parameter: 1922a6744ebSBarry Smith + pc - the preconditioner context 1932a6744ebSBarry Smith - R - the interpolation operator 1942a6744ebSBarry Smith 19595452b02SPatrick Sanan Notes: 19695452b02SPatrick Sanan Either this or PCGalerkinSetRestriction() or both must be called 1972a6744ebSBarry Smith 1982a6744ebSBarry Smith Level: Intermediate 1992a6744ebSBarry Smith 2002a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 2012a6744ebSBarry Smith PCGalerkinSetRestriction(), PCGalerkinGetKSP() 2022a6744ebSBarry Smith 2032a6744ebSBarry Smith @*/ 2047087cfbeSBarry Smith PetscErrorCode PCGalerkinSetInterpolation(PC pc,Mat P) 2052a6744ebSBarry Smith { 2064ac538c5SBarry Smith PetscErrorCode ierr; 2072a6744ebSBarry Smith 2082a6744ebSBarry Smith PetscFunctionBegin; 2090700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2104ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr); 2112a6744ebSBarry Smith PetscFunctionReturn(0); 2122a6744ebSBarry Smith } 2132a6744ebSBarry Smith 2142a6744ebSBarry Smith /*@ 215b3402f20SBarry Smith PCGalerkinSetComputeSubmatrix - Provide a routine that will be called to compute the Galerkin submatrix 216b3402f20SBarry Smith 217b3402f20SBarry Smith Logically Collective 218b3402f20SBarry Smith 219b3402f20SBarry Smith Input Parameter: 220b3402f20SBarry Smith + pc - the preconditioner context 221b3402f20SBarry Smith . computeAsub - routine that computes the submatrix from the global matrix 222b3402f20SBarry Smith - ctx - context used by the routine, or NULL 223b3402f20SBarry Smith 224b3402f20SBarry Smith Calling sequence of computeAsub: 225b3402f20SBarry Smith $ computeAsub(PC pc,Mat A, Mat Ap, Mat *cAP,void *ctx); 226b3402f20SBarry Smith 227b3402f20SBarry Smith + PC - the Galerkin PC 228b3402f20SBarry Smith . A - the matrix in the Galerkin PC 229b3402f20SBarry Smith . Ap - the computed submatrix from any previous computation, if NULL it has not previously been computed 230b3402f20SBarry Smith . cAp - the submatrix computed by this routine 231b3402f20SBarry Smith - ctx - optional user-defined function context 232b3402f20SBarry Smith 233b3402f20SBarry Smith Level: Intermediate 234b3402f20SBarry Smith 23595452b02SPatrick Sanan Notes: 23695452b02SPatrick Sanan Instead of providing this routine you can call PCGalerkinGetKSP() and then KSPSetOperators() to provide the submatrix, 237b3402f20SBarry Smith but that will not work for multiple KSPSolves with different matrices unless you call it for each solve. 238b3402f20SBarry Smith 239*910cf402Sprj- 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 240b3402f20SBarry Smith matrix and computes its values in cAp. On each subsequent call the routine should up the Ap matrix. 241b3402f20SBarry Smith 24295452b02SPatrick Sanan Developer Notes: 24395452b02SPatrick Sanan If the user does not call this routine nor call PCGalerkinGetKSP() and KSPSetOperators() then PCGalerkin could 244b3402f20SBarry Smith could automatically compute the submatrix via calls to MatGalerkin() or MatRARt() 245b3402f20SBarry Smith 246b3402f20SBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 247b3402f20SBarry Smith PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 248b3402f20SBarry Smith 249b3402f20SBarry Smith @*/ 250b3402f20SBarry Smith PetscErrorCode PCGalerkinSetComputeSubmatrix(PC pc,PetscErrorCode (*computeAsub)(PC,Mat,Mat,Mat*,void*),void *ctx) 251b3402f20SBarry Smith { 252b3402f20SBarry Smith PetscErrorCode ierr; 253b3402f20SBarry Smith 254b3402f20SBarry Smith PetscFunctionBegin; 255b3402f20SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 256b3402f20SBarry Smith ierr = PetscTryMethod(pc,"PCGalerkinSetComputeSubmatrix_C",(PC,PetscErrorCode (*)(PC,Mat,Mat,Mat*,void*),void*),(pc,computeAsub,ctx));CHKERRQ(ierr); 257b3402f20SBarry Smith PetscFunctionReturn(0); 258b3402f20SBarry Smith } 259b3402f20SBarry Smith 260b3402f20SBarry Smith /*@ 2612a6744ebSBarry Smith PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC. 2622a6744ebSBarry Smith 2632a6744ebSBarry Smith Not Collective 2642a6744ebSBarry Smith 2652a6744ebSBarry Smith Input Parameter: 2662a6744ebSBarry Smith . pc - the preconditioner context 2672a6744ebSBarry Smith 2682a6744ebSBarry Smith Output Parameters: 2692a6744ebSBarry Smith . ksp - the KSP object 2702a6744ebSBarry Smith 2712a6744ebSBarry Smith Level: Intermediate 2722a6744ebSBarry Smith 27395452b02SPatrick Sanan Notes: 27495452b02SPatrick Sanan Once you have called this routine you can call KSPSetOperators() on the resulting ksp to provide the operator for the Galerkin problem, 275b3402f20SBarry Smith an alternative is to use PCGalerkinSetComputeSubmatrix() to provide a routine that computes the submatrix as needed. 276b3402f20SBarry Smith 2772a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 278b3402f20SBarry Smith PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinSetComputeSubmatrix() 2792a6744ebSBarry Smith 2802a6744ebSBarry Smith @*/ 2817087cfbeSBarry Smith PetscErrorCode PCGalerkinGetKSP(PC pc,KSP *ksp) 2822a6744ebSBarry Smith { 2834ac538c5SBarry Smith PetscErrorCode ierr; 2842a6744ebSBarry Smith 2852a6744ebSBarry Smith PetscFunctionBegin; 2860700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2872a6744ebSBarry Smith PetscValidPointer(ksp,2); 2884ac538c5SBarry Smith ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr); 2892a6744ebSBarry Smith PetscFunctionReturn(0); 2902a6744ebSBarry Smith } 2912a6744ebSBarry Smith 2924ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc) 2934ac220ccSBarry Smith { 2944ac220ccSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 2954ac220ccSBarry Smith PetscErrorCode ierr; 2964ac220ccSBarry Smith const char *prefix; 2974ac220ccSBarry Smith PetscBool flg; 2984ac220ccSBarry Smith 2994ac220ccSBarry Smith PetscFunctionBegin; 3004ac220ccSBarry Smith ierr = KSPGetOptionsPrefix(jac->ksp,&prefix);CHKERRQ(ierr); 3014ac220ccSBarry Smith ierr = PetscStrendswith(prefix,"galerkin_",&flg);CHKERRQ(ierr); 3024ac220ccSBarry Smith if (!flg) { 3034ac220ccSBarry Smith ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr); 3044ac220ccSBarry Smith ierr = KSPSetOptionsPrefix(jac->ksp,prefix);CHKERRQ(ierr); 3054ac220ccSBarry Smith ierr = KSPAppendOptionsPrefix(jac->ksp,"galerkin_");CHKERRQ(ierr); 3064ac220ccSBarry Smith } 3074ac220ccSBarry Smith 3084ac220ccSBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Galerkin options");CHKERRQ(ierr); 3094ac220ccSBarry Smith if (jac->ksp) { 3104ac220ccSBarry Smith ierr = KSPSetFromOptions(jac->ksp);CHKERRQ(ierr); 3114ac220ccSBarry Smith } 3124ac220ccSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 3134ac220ccSBarry Smith PetscFunctionReturn(0); 3144ac220ccSBarry Smith } 3152a6744ebSBarry Smith 3162a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/ 3172a6744ebSBarry Smith 3182a6744ebSBarry Smith /*MC 3192a6744ebSBarry Smith PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T) 3202a6744ebSBarry Smith 3212a6744ebSBarry Smith $ Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by 3227817a140SBarry Smith $ PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....) 3232a6744ebSBarry Smith 3242a6744ebSBarry Smith Level: intermediate 3252a6744ebSBarry Smith 326b59c8b46SBarry Smith Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute 3277817a140SBarry Smith the operators automatically. 3287817a140SBarry Smith Should there be a prefix for the inner KSP. 3297817a140SBarry Smith There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP 3307817a140SBarry Smith 3312a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 3322a6744ebSBarry Smith PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 3332a6744ebSBarry Smith 3342a6744ebSBarry Smith M*/ 3352a6744ebSBarry Smith 3368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc) 3372a6744ebSBarry Smith { 3382a6744ebSBarry Smith PetscErrorCode ierr; 3392a6744ebSBarry Smith PC_Galerkin *jac; 3402a6744ebSBarry Smith 3412a6744ebSBarry Smith PetscFunctionBegin; 342b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 3432fa5cd67SKarl Rupp 3442a6744ebSBarry Smith pc->ops->apply = PCApply_Galerkin; 3452a6744ebSBarry Smith pc->ops->setup = PCSetUp_Galerkin; 346a06653b4SBarry Smith pc->ops->reset = PCReset_Galerkin; 3472a6744ebSBarry Smith pc->ops->destroy = PCDestroy_Galerkin; 3482a6744ebSBarry Smith pc->ops->view = PCView_Galerkin; 3494ac220ccSBarry Smith pc->ops->setfromoptions = PCSetFromOptions_Galerkin; 3504ac220ccSBarry Smith pc->ops->applyrichardson = NULL; 3512a6744ebSBarry Smith 352ce94432eSBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr); 353422a814eSBarry Smith ierr = KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);CHKERRQ(ierr); 3541cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr); 3552a6744ebSBarry Smith 3562a6744ebSBarry Smith pc->data = (void*)jac; 3572a6744ebSBarry Smith 358bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr); 359bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr); 360bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr); 361b3402f20SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetComputeSubmatrix_C",PCGalerkinSetComputeSubmatrix_Galerkin);CHKERRQ(ierr); 3622a6744ebSBarry Smith PetscFunctionReturn(0); 3632a6744ebSBarry Smith } 3642a6744ebSBarry Smith 365