12a6744ebSBarry Smith 22a6744ebSBarry Smith /* 32a6744ebSBarry Smith Defines a preconditioner defined by R^T S R 42a6744ebSBarry Smith */ 507475bc1SBarry 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; 122a6744ebSBarry Smith } PC_Galerkin; 132a6744ebSBarry Smith 142a6744ebSBarry Smith #undef __FUNCT__ 152a6744ebSBarry Smith #define __FUNCT__ "PCApply_Galerkin" 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); 282fa5cd67SKarl Rupp if (jac->P) { 292fa5cd67SKarl Rupp ierr = MatInterpolate(jac->P,jac->x,y);CHKERRQ(ierr); 302fa5cd67SKarl Rupp } else { 312fa5cd67SKarl Rupp ierr = MatInterpolate(jac->R,jac->x,y);CHKERRQ(ierr); 322fa5cd67SKarl Rupp } 332a6744ebSBarry Smith PetscFunctionReturn(0); 342a6744ebSBarry Smith } 352a6744ebSBarry Smith 362a6744ebSBarry Smith #undef __FUNCT__ 372a6744ebSBarry Smith #define __FUNCT__ "PCSetUp_Galerkin" 382a6744ebSBarry Smith static PetscErrorCode PCSetUp_Galerkin(PC pc) 392a6744ebSBarry Smith { 402a6744ebSBarry Smith PetscErrorCode ierr; 412a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 42ace3abfcSBarry Smith PetscBool a; 43906ed7ccSBarry Smith Vec *xx,*yy; 442a6744ebSBarry Smith 452a6744ebSBarry Smith PetscFunctionBegin; 462a6744ebSBarry Smith if (!jac->x) { 470298fd71SBarry Smith ierr = KSPGetOperatorsSet(jac->ksp,&a,NULL);CHKERRQ(ierr); 48ce94432eSBarry Smith if (!a) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()"); 49906ed7ccSBarry Smith ierr = KSPGetVecs(jac->ksp,1,&xx,1,&yy);CHKERRQ(ierr); 50906ed7ccSBarry Smith jac->x = *xx; 51906ed7ccSBarry Smith jac->b = *yy; 52906ed7ccSBarry Smith ierr = PetscFree(xx);CHKERRQ(ierr); 53906ed7ccSBarry Smith ierr = PetscFree(yy);CHKERRQ(ierr); 542a6744ebSBarry Smith } 55ce94432eSBarry Smith if (!jac->R && !jac->P) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction/Interpolation()"); 562a6744ebSBarry Smith /* should check here that sizes of R/P match size of a */ 572a6744ebSBarry Smith PetscFunctionReturn(0); 582a6744ebSBarry Smith } 592a6744ebSBarry Smith 602a6744ebSBarry Smith #undef __FUNCT__ 61a06653b4SBarry Smith #define __FUNCT__ "PCReset_Galerkin" 62a06653b4SBarry Smith static PetscErrorCode PCReset_Galerkin(PC pc) 632a6744ebSBarry Smith { 642a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 652a6744ebSBarry Smith PetscErrorCode ierr; 662a6744ebSBarry Smith 672a6744ebSBarry Smith PetscFunctionBegin; 686bf464f9SBarry Smith ierr = MatDestroy(&jac->R);CHKERRQ(ierr); 696bf464f9SBarry Smith ierr = MatDestroy(&jac->P);CHKERRQ(ierr); 706bf464f9SBarry Smith ierr = VecDestroy(&jac->x);CHKERRQ(ierr); 716bf464f9SBarry Smith ierr = VecDestroy(&jac->b);CHKERRQ(ierr); 72a06653b4SBarry Smith ierr = KSPReset(jac->ksp);CHKERRQ(ierr); 73a06653b4SBarry Smith PetscFunctionReturn(0); 74a06653b4SBarry Smith } 75a06653b4SBarry Smith 76a06653b4SBarry Smith #undef __FUNCT__ 77a06653b4SBarry Smith #define __FUNCT__ "PCDestroy_Galerkin" 78a06653b4SBarry Smith static PetscErrorCode PCDestroy_Galerkin(PC pc) 79a06653b4SBarry Smith { 80a06653b4SBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 81a06653b4SBarry Smith PetscErrorCode ierr; 82a06653b4SBarry Smith 83a06653b4SBarry Smith PetscFunctionBegin; 84fcfd50ebSBarry Smith ierr = PCReset_Galerkin(pc);CHKERRQ(ierr); 856bf464f9SBarry Smith ierr = KSPDestroy(&jac->ksp);CHKERRQ(ierr); 86c31cb41cSBarry Smith ierr = PetscFree(pc->data);CHKERRQ(ierr); 872a6744ebSBarry Smith PetscFunctionReturn(0); 882a6744ebSBarry Smith } 892a6744ebSBarry Smith 902a6744ebSBarry Smith #undef __FUNCT__ 912a6744ebSBarry Smith #define __FUNCT__ "PCView_Galerkin" 922a6744ebSBarry Smith static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer) 932a6744ebSBarry Smith { 942a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 952a6744ebSBarry Smith PetscErrorCode ierr; 96ace3abfcSBarry Smith PetscBool iascii; 972a6744ebSBarry Smith 982a6744ebSBarry Smith PetscFunctionBegin; 99251f4c67SDmitry Karpeev ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr); 1002a6744ebSBarry Smith if (iascii) { 1012a6744ebSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"Galerkin PC\n");CHKERRQ(ierr); 1022a6744ebSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"KSP on Galerkin follow\n");CHKERRQ(ierr); 1032a6744ebSBarry Smith ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr); 1042a6744ebSBarry Smith } 1052a6744ebSBarry Smith ierr = KSPView(jac->ksp,viewer);CHKERRQ(ierr); 1062a6744ebSBarry Smith PetscFunctionReturn(0); 1072a6744ebSBarry Smith } 1082a6744ebSBarry Smith 1092a6744ebSBarry Smith #undef __FUNCT__ 1102a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinGetKSP_Galerkin" 1111e6b0712SBarry Smith static PetscErrorCode PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp) 1122a6744ebSBarry Smith { 1132a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1142a6744ebSBarry Smith 1152a6744ebSBarry Smith PetscFunctionBegin; 1162a6744ebSBarry Smith *ksp = jac->ksp; 1172a6744ebSBarry Smith PetscFunctionReturn(0); 1182a6744ebSBarry Smith } 1192a6744ebSBarry Smith 1202a6744ebSBarry Smith #undef __FUNCT__ 1212a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinSetRestriction_Galerkin" 1221e6b0712SBarry Smith static PetscErrorCode PCGalerkinSetRestriction_Galerkin(PC pc,Mat R) 1232a6744ebSBarry Smith { 1242a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1252a6744ebSBarry Smith PetscErrorCode ierr; 1262a6744ebSBarry Smith 1272a6744ebSBarry Smith PetscFunctionBegin; 128c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)R);CHKERRQ(ierr); 1296bf464f9SBarry Smith ierr = MatDestroy(&jac->R);CHKERRQ(ierr); 1302a6744ebSBarry Smith jac->R = R; 1312a6744ebSBarry Smith PetscFunctionReturn(0); 1322a6744ebSBarry Smith } 1332a6744ebSBarry Smith 1342a6744ebSBarry Smith #undef __FUNCT__ 1352a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinSetInterpolation_Galerkin" 1361e6b0712SBarry Smith static PetscErrorCode PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P) 1372a6744ebSBarry Smith { 1382a6744ebSBarry Smith PC_Galerkin *jac = (PC_Galerkin*)pc->data; 1392a6744ebSBarry Smith PetscErrorCode ierr; 1402a6744ebSBarry Smith 1412a6744ebSBarry Smith PetscFunctionBegin; 142c3122656SLisandro Dalcin ierr = PetscObjectReference((PetscObject)P);CHKERRQ(ierr); 1436bf464f9SBarry Smith ierr = MatDestroy(&jac->P);CHKERRQ(ierr); 1442a6744ebSBarry Smith jac->P = P; 1452a6744ebSBarry Smith PetscFunctionReturn(0); 1462a6744ebSBarry Smith } 1472a6744ebSBarry Smith 1482a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */ 1492a6744ebSBarry Smith #undef __FUNCT__ 1502a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinSetRestriction" 1512a6744ebSBarry Smith /*@ 1522a6744ebSBarry Smith PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner 1532a6744ebSBarry Smith 154ad4df100SBarry Smith Logically Collective on PC 1552a6744ebSBarry Smith 1562a6744ebSBarry Smith Input Parameter: 1572a6744ebSBarry Smith + pc - the preconditioner context 1582a6744ebSBarry Smith - R - the restriction operator 1592a6744ebSBarry Smith 1602a6744ebSBarry Smith Notes: Either this or PCGalerkinSetInterpolation() or both must be called 1612a6744ebSBarry Smith 1622a6744ebSBarry Smith Level: Intermediate 1632a6744ebSBarry Smith 1642a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner 1652a6744ebSBarry Smith 1662a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 1672a6744ebSBarry Smith PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 1682a6744ebSBarry Smith 1692a6744ebSBarry Smith @*/ 1707087cfbeSBarry Smith PetscErrorCode PCGalerkinSetRestriction(PC pc,Mat R) 1712a6744ebSBarry Smith { 1724ac538c5SBarry Smith PetscErrorCode ierr; 1732a6744ebSBarry Smith 1742a6744ebSBarry Smith PetscFunctionBegin; 1750700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 1764ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));CHKERRQ(ierr); 1772a6744ebSBarry Smith PetscFunctionReturn(0); 1782a6744ebSBarry Smith } 1792a6744ebSBarry Smith 1802a6744ebSBarry Smith #undef __FUNCT__ 181e5c8efcbSJed Brown #define __FUNCT__ "PCGalerkinSetInterpolation" 1822a6744ebSBarry Smith /*@ 1832a6744ebSBarry Smith PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner 1842a6744ebSBarry Smith 185ad4df100SBarry Smith Logically Collective on PC 1862a6744ebSBarry Smith 1872a6744ebSBarry Smith Input Parameter: 1882a6744ebSBarry Smith + pc - the preconditioner context 1892a6744ebSBarry Smith - R - the interpolation operator 1902a6744ebSBarry Smith 1912a6744ebSBarry Smith Notes: Either this or PCGalerkinSetRestriction() or both must be called 1922a6744ebSBarry Smith 1932a6744ebSBarry Smith Level: Intermediate 1942a6744ebSBarry Smith 1952a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner 1962a6744ebSBarry Smith 1972a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 1982a6744ebSBarry Smith PCGalerkinSetRestriction(), PCGalerkinGetKSP() 1992a6744ebSBarry Smith 2002a6744ebSBarry Smith @*/ 2017087cfbeSBarry Smith PetscErrorCode PCGalerkinSetInterpolation(PC pc,Mat P) 2022a6744ebSBarry Smith { 2034ac538c5SBarry Smith PetscErrorCode ierr; 2042a6744ebSBarry Smith 2052a6744ebSBarry Smith PetscFunctionBegin; 2060700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2074ac538c5SBarry Smith ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr); 2082a6744ebSBarry Smith PetscFunctionReturn(0); 2092a6744ebSBarry Smith } 2102a6744ebSBarry Smith 2112a6744ebSBarry Smith #undef __FUNCT__ 2122a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinGetKSP" 2132a6744ebSBarry Smith /*@ 2142a6744ebSBarry Smith PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC. 2152a6744ebSBarry Smith 2162a6744ebSBarry Smith Not Collective 2172a6744ebSBarry Smith 2182a6744ebSBarry Smith Input Parameter: 2192a6744ebSBarry Smith . pc - the preconditioner context 2202a6744ebSBarry Smith 2212a6744ebSBarry Smith Output Parameters: 2222a6744ebSBarry Smith . ksp - the KSP object 2232a6744ebSBarry Smith 2242a6744ebSBarry Smith Level: Intermediate 2252a6744ebSBarry Smith 2262a6744ebSBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner 2272a6744ebSBarry Smith 2282a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN, 2292a6744ebSBarry Smith PCGalerkinSetRestriction(), PCGalerkinSetInterpolation() 2302a6744ebSBarry Smith 2312a6744ebSBarry Smith @*/ 2327087cfbeSBarry Smith PetscErrorCode PCGalerkinGetKSP(PC pc,KSP *ksp) 2332a6744ebSBarry Smith { 2344ac538c5SBarry Smith PetscErrorCode ierr; 2352a6744ebSBarry Smith 2362a6744ebSBarry Smith PetscFunctionBegin; 2370700a824SBarry Smith PetscValidHeaderSpecific(pc,PC_CLASSID,1); 2382a6744ebSBarry Smith PetscValidPointer(ksp,2); 2394ac538c5SBarry Smith ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr); 2402a6744ebSBarry Smith PetscFunctionReturn(0); 2412a6744ebSBarry Smith } 2422a6744ebSBarry Smith 2432a6744ebSBarry Smith 2442a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/ 2452a6744ebSBarry Smith 2462a6744ebSBarry Smith /*MC 2472a6744ebSBarry Smith PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T) 2482a6744ebSBarry Smith 2492a6744ebSBarry Smith $ Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by 2507817a140SBarry Smith $ PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....) 2512a6744ebSBarry Smith 2522a6744ebSBarry Smith Level: intermediate 2532a6744ebSBarry Smith 2547817a140SBarry Smith Developer Note: If KSPSetOperators() has not been called then PCGALERKIN could use MatRARt() or MatPtAP() to compute 2557817a140SBarry Smith the operators automatically. 2567817a140SBarry Smith Should there be a prefix for the inner KSP. 2577817a140SBarry Smith There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP 2587817a140SBarry Smith 2592a6744ebSBarry Smith .seealso: PCCreate(), PCSetType(), PCType (for list of available types), PC, 2602a6744ebSBarry Smith PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP() 2612a6744ebSBarry Smith 2622a6744ebSBarry Smith M*/ 2632a6744ebSBarry Smith 2642a6744ebSBarry Smith #undef __FUNCT__ 2652a6744ebSBarry Smith #define __FUNCT__ "PCCreate_Galerkin" 2668cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc) 2672a6744ebSBarry Smith { 2682a6744ebSBarry Smith PetscErrorCode ierr; 2692a6744ebSBarry Smith PC_Galerkin *jac; 2702a6744ebSBarry Smith 2712a6744ebSBarry Smith PetscFunctionBegin; 272*b00a9115SJed Brown ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr); 2732fa5cd67SKarl Rupp 2742a6744ebSBarry Smith pc->ops->apply = PCApply_Galerkin; 2752a6744ebSBarry Smith pc->ops->setup = PCSetUp_Galerkin; 276a06653b4SBarry Smith pc->ops->reset = PCReset_Galerkin; 2772a6744ebSBarry Smith pc->ops->destroy = PCDestroy_Galerkin; 2782a6744ebSBarry Smith pc->ops->view = PCView_Galerkin; 2792a6744ebSBarry Smith pc->ops->applyrichardson = 0; 2802a6744ebSBarry Smith 281ce94432eSBarry Smith ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr); 2821cee3971SBarry Smith ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr); 2832a6744ebSBarry Smith 2842a6744ebSBarry Smith pc->data = (void*)jac; 2852a6744ebSBarry Smith 286bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr); 287bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr); 288bdf89e91SBarry Smith ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr); 2892a6744ebSBarry Smith PetscFunctionReturn(0); 2902a6744ebSBarry Smith } 2912a6744ebSBarry Smith 292