xref: /petsc/src/ksp/pc/impls/galerkin/galerkin.c (revision 2fa5cd679192b9b390e47ae2d0650965e6b1d9fa)
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;
22*2fa5cd67SKarl Rupp   if (jac->R) {
23*2fa5cd67SKarl Rupp     ierr = MatRestrict(jac->R,x,jac->b);CHKERRQ(ierr);
24*2fa5cd67SKarl Rupp   } else {
25*2fa5cd67SKarl Rupp     ierr = MatRestrict(jac->P,x,jac->b);CHKERRQ(ierr);
26*2fa5cd67SKarl Rupp   }
272a6744ebSBarry Smith   ierr = KSPSolve(jac->ksp,jac->b,jac->x);CHKERRQ(ierr);
28*2fa5cd67SKarl Rupp   if (jac->P) {
29*2fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->P,jac->x,y);CHKERRQ(ierr);
30*2fa5cd67SKarl Rupp   } else {
31*2fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->R,jac->x,y);CHKERRQ(ierr);
32*2fa5cd67SKarl 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) {
47906ed7ccSBarry Smith     ierr = KSPGetOperatorsSet(jac->ksp,&a,PETSC_NULL);CHKERRQ(ierr);
48e7e72b3dSBarry Smith     if (!a) SETERRQ(((PetscObject)pc)->comm,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   }
557817a140SBarry Smith   if (!jac->R && !jac->P) SETERRQ(((PetscObject)pc)->comm,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 EXTERN_C_BEGIN
1102a6744ebSBarry Smith #undef __FUNCT__
1112a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinGetKSP_Galerkin"
1127087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp)
1132a6744ebSBarry Smith {
1142a6744ebSBarry Smith   PC_Galerkin *jac = (PC_Galerkin*)pc->data;
1152a6744ebSBarry Smith 
1162a6744ebSBarry Smith   PetscFunctionBegin;
1172a6744ebSBarry Smith   *ksp = jac->ksp;
1182a6744ebSBarry Smith   PetscFunctionReturn(0);
1192a6744ebSBarry Smith }
1202a6744ebSBarry Smith EXTERN_C_END
1212a6744ebSBarry Smith 
1222a6744ebSBarry Smith EXTERN_C_BEGIN
1232a6744ebSBarry Smith #undef __FUNCT__
1242a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinSetRestriction_Galerkin"
1257087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetRestriction_Galerkin(PC pc,Mat R)
1262a6744ebSBarry Smith {
1272a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1282a6744ebSBarry Smith   PetscErrorCode ierr;
1292a6744ebSBarry Smith 
1302a6744ebSBarry Smith   PetscFunctionBegin;
131c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)R);CHKERRQ(ierr);
1326bf464f9SBarry Smith   ierr   = MatDestroy(&jac->R);CHKERRQ(ierr);
1332a6744ebSBarry Smith   jac->R = R;
1342a6744ebSBarry Smith   PetscFunctionReturn(0);
1352a6744ebSBarry Smith }
1362a6744ebSBarry Smith EXTERN_C_END
1372a6744ebSBarry Smith 
1382a6744ebSBarry Smith EXTERN_C_BEGIN
1392a6744ebSBarry Smith #undef __FUNCT__
1402a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinSetInterpolation_Galerkin"
1417087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P)
1422a6744ebSBarry Smith {
1432a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1442a6744ebSBarry Smith   PetscErrorCode ierr;
1452a6744ebSBarry Smith 
1462a6744ebSBarry Smith   PetscFunctionBegin;
147c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)P);CHKERRQ(ierr);
1486bf464f9SBarry Smith   ierr   = MatDestroy(&jac->P);CHKERRQ(ierr);
1492a6744ebSBarry Smith   jac->P = P;
1502a6744ebSBarry Smith   PetscFunctionReturn(0);
1512a6744ebSBarry Smith }
1522a6744ebSBarry Smith EXTERN_C_END
1532a6744ebSBarry Smith 
1542a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */
1552a6744ebSBarry Smith #undef __FUNCT__
1562a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinSetRestriction"
1572a6744ebSBarry Smith /*@
1582a6744ebSBarry Smith    PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner
1592a6744ebSBarry Smith 
160ad4df100SBarry Smith    Logically Collective on PC
1612a6744ebSBarry Smith 
1622a6744ebSBarry Smith    Input Parameter:
1632a6744ebSBarry Smith +  pc - the preconditioner context
1642a6744ebSBarry Smith -  R - the restriction operator
1652a6744ebSBarry Smith 
1662a6744ebSBarry Smith    Notes: Either this or PCGalerkinSetInterpolation() or both must be called
1672a6744ebSBarry Smith 
1682a6744ebSBarry Smith    Level: Intermediate
1692a6744ebSBarry Smith 
1702a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
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 #undef __FUNCT__
187e5c8efcbSJed Brown #define __FUNCT__ "PCGalerkinSetInterpolation"
1882a6744ebSBarry Smith /*@
1892a6744ebSBarry Smith    PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner
1902a6744ebSBarry Smith 
191ad4df100SBarry Smith    Logically Collective on PC
1922a6744ebSBarry Smith 
1932a6744ebSBarry Smith    Input Parameter:
1942a6744ebSBarry Smith +  pc - the preconditioner context
1952a6744ebSBarry Smith -  R - the interpolation operator
1962a6744ebSBarry Smith 
1972a6744ebSBarry Smith    Notes: Either this or PCGalerkinSetRestriction() or both must be called
1982a6744ebSBarry Smith 
1992a6744ebSBarry Smith    Level: Intermediate
2002a6744ebSBarry Smith 
2012a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
2022a6744ebSBarry Smith 
2032a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2042a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
2052a6744ebSBarry Smith 
2062a6744ebSBarry Smith @*/
2077087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
2082a6744ebSBarry Smith {
2094ac538c5SBarry Smith   PetscErrorCode ierr;
2102a6744ebSBarry Smith 
2112a6744ebSBarry Smith   PetscFunctionBegin;
2120700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2134ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr);
2142a6744ebSBarry Smith   PetscFunctionReturn(0);
2152a6744ebSBarry Smith }
2162a6744ebSBarry Smith 
2172a6744ebSBarry Smith #undef __FUNCT__
2182a6744ebSBarry Smith #define __FUNCT__ "PCGalerkinGetKSP"
2192a6744ebSBarry Smith /*@
2202a6744ebSBarry Smith    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
2212a6744ebSBarry Smith 
2222a6744ebSBarry Smith    Not Collective
2232a6744ebSBarry Smith 
2242a6744ebSBarry Smith    Input Parameter:
2252a6744ebSBarry Smith .  pc - the preconditioner context
2262a6744ebSBarry Smith 
2272a6744ebSBarry Smith    Output Parameters:
2282a6744ebSBarry Smith .  ksp - the KSP object
2292a6744ebSBarry Smith 
2302a6744ebSBarry Smith    Level: Intermediate
2312a6744ebSBarry Smith 
2322a6744ebSBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
2332a6744ebSBarry Smith 
2342a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2352a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation()
2362a6744ebSBarry Smith 
2372a6744ebSBarry Smith @*/
2387087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
2392a6744ebSBarry Smith {
2404ac538c5SBarry Smith   PetscErrorCode ierr;
2412a6744ebSBarry Smith 
2422a6744ebSBarry Smith   PetscFunctionBegin;
2430700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2442a6744ebSBarry Smith   PetscValidPointer(ksp,2);
2454ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
2462a6744ebSBarry Smith   PetscFunctionReturn(0);
2472a6744ebSBarry Smith }
2482a6744ebSBarry Smith 
2492a6744ebSBarry Smith 
2502a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/
2512a6744ebSBarry Smith 
2522a6744ebSBarry Smith /*MC
2532a6744ebSBarry Smith      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
2542a6744ebSBarry Smith 
2552a6744ebSBarry Smith $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
2567817a140SBarry Smith $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
2572a6744ebSBarry Smith 
2582a6744ebSBarry Smith    Level: intermediate
2592a6744ebSBarry Smith 
2607817a140SBarry Smith    Developer Note: If KSPSetOperators() has not been called then PCGALERKIN could use MatRARt() or MatPtAP() to compute
2617817a140SBarry Smith                    the operators automatically.
2627817a140SBarry Smith                    Should there be a prefix for the inner KSP.
2637817a140SBarry Smith                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
2647817a140SBarry Smith 
2652a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
2662a6744ebSBarry Smith            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
2672a6744ebSBarry Smith 
2682a6744ebSBarry Smith M*/
2692a6744ebSBarry Smith 
2702a6744ebSBarry Smith EXTERN_C_BEGIN
2712a6744ebSBarry Smith #undef __FUNCT__
2722a6744ebSBarry Smith #define __FUNCT__ "PCCreate_Galerkin"
2737087cfbeSBarry Smith PetscErrorCode  PCCreate_Galerkin(PC pc)
2742a6744ebSBarry Smith {
2752a6744ebSBarry Smith   PetscErrorCode ierr;
2762a6744ebSBarry Smith   PC_Galerkin    *jac;
2772a6744ebSBarry Smith 
2782a6744ebSBarry Smith   PetscFunctionBegin;
27938f2d2fdSLisandro Dalcin   ierr = PetscNewLog(pc,PC_Galerkin,&jac);CHKERRQ(ierr);
280*2fa5cd67SKarl Rupp 
2812a6744ebSBarry Smith   pc->ops->apply           = PCApply_Galerkin;
2822a6744ebSBarry Smith   pc->ops->setup           = PCSetUp_Galerkin;
283a06653b4SBarry Smith   pc->ops->reset           = PCReset_Galerkin;
2842a6744ebSBarry Smith   pc->ops->destroy         = PCDestroy_Galerkin;
2852a6744ebSBarry Smith   pc->ops->view            = PCView_Galerkin;
2862a6744ebSBarry Smith   pc->ops->applyrichardson = 0;
2872a6744ebSBarry Smith 
2887adad957SLisandro Dalcin   ierr = KSPCreate(((PetscObject)pc)->comm,&jac->ksp);CHKERRQ(ierr);
2891cee3971SBarry Smith   ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
2902a6744ebSBarry Smith 
2912a6744ebSBarry Smith   pc->data = (void*)jac;
2922a6744ebSBarry Smith 
2932a6744ebSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCGalerkinSetRestriction_C","PCGalerkinSetRestriction_Galerkin",
2942a6744ebSBarry Smith                                            PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr);
2952a6744ebSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCGalerkinSetInterpolation_C","PCGalerkinSetInterpolation_Galerkin",
2962a6744ebSBarry Smith                                            PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr);
2972a6744ebSBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCGalerkinGetKSP_C","PCGalerkinGetKSP_Galerkin",
2982a6744ebSBarry Smith                                            PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr);
2992a6744ebSBarry Smith   PetscFunctionReturn(0);
3002a6744ebSBarry Smith }
3012a6744ebSBarry Smith EXTERN_C_END
3022a6744ebSBarry Smith 
303