xref: /petsc/src/ksp/pc/impls/galerkin/galerkin.c (revision 4ac220cc4c15565088b3b9dd884b808908403f53)
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;
122a6744ebSBarry Smith } PC_Galerkin;
132a6744ebSBarry Smith 
142a6744ebSBarry Smith static PetscErrorCode PCApply_Galerkin(PC pc,Vec x,Vec y)
152a6744ebSBarry Smith {
162a6744ebSBarry Smith   PetscErrorCode ierr;
172a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
182a6744ebSBarry Smith 
192a6744ebSBarry Smith   PetscFunctionBegin;
202fa5cd67SKarl Rupp   if (jac->R) {
212fa5cd67SKarl Rupp     ierr = MatRestrict(jac->R,x,jac->b);CHKERRQ(ierr);
222fa5cd67SKarl Rupp   } else {
232fa5cd67SKarl Rupp     ierr = MatRestrict(jac->P,x,jac->b);CHKERRQ(ierr);
242fa5cd67SKarl Rupp   }
252a6744ebSBarry Smith   ierr = KSPSolve(jac->ksp,jac->b,jac->x);CHKERRQ(ierr);
262fa5cd67SKarl Rupp   if (jac->P) {
272fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->P,jac->x,y);CHKERRQ(ierr);
282fa5cd67SKarl Rupp   } else {
292fa5cd67SKarl Rupp     ierr = MatInterpolate(jac->R,jac->x,y);CHKERRQ(ierr);
302fa5cd67SKarl Rupp   }
312a6744ebSBarry Smith   PetscFunctionReturn(0);
322a6744ebSBarry Smith }
332a6744ebSBarry Smith 
342a6744ebSBarry Smith static PetscErrorCode PCSetUp_Galerkin(PC pc)
352a6744ebSBarry Smith {
362a6744ebSBarry Smith   PetscErrorCode ierr;
372a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
38ace3abfcSBarry Smith   PetscBool      a;
39906ed7ccSBarry Smith   Vec            *xx,*yy;
402a6744ebSBarry Smith 
412a6744ebSBarry Smith   PetscFunctionBegin;
422a6744ebSBarry Smith   if (!jac->x) {
430298fd71SBarry Smith     ierr = KSPGetOperatorsSet(jac->ksp,&a,NULL);CHKERRQ(ierr);
44ce94432eSBarry Smith     if (!a) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set operator of PCGALERKIN KSP with PCGalerkinGetKSP()/KSPSetOperators()");
452a7a6963SBarry Smith     ierr   = KSPCreateVecs(jac->ksp,1,&xx,1,&yy);CHKERRQ(ierr);
46906ed7ccSBarry Smith     jac->x = *xx;
47906ed7ccSBarry Smith     jac->b = *yy;
48906ed7ccSBarry Smith     ierr   = PetscFree(xx);CHKERRQ(ierr);
49906ed7ccSBarry Smith     ierr   = PetscFree(yy);CHKERRQ(ierr);
502a6744ebSBarry Smith   }
51*4ac220ccSBarry Smith   if (!jac->R && !jac->P) SETERRQ(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_WRONGSTATE,"Must set restriction or interpolation of PCGALERKIN with PCGalerkinSetRestriction()/Interpolation()");
522a6744ebSBarry Smith   /* should check here that sizes of R/P match size of a */
532a6744ebSBarry Smith   PetscFunctionReturn(0);
542a6744ebSBarry Smith }
552a6744ebSBarry Smith 
56a06653b4SBarry Smith static PetscErrorCode PCReset_Galerkin(PC pc)
572a6744ebSBarry Smith {
582a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
592a6744ebSBarry Smith   PetscErrorCode ierr;
602a6744ebSBarry Smith 
612a6744ebSBarry Smith   PetscFunctionBegin;
626bf464f9SBarry Smith   ierr = MatDestroy(&jac->R);CHKERRQ(ierr);
636bf464f9SBarry Smith   ierr = MatDestroy(&jac->P);CHKERRQ(ierr);
646bf464f9SBarry Smith   ierr = VecDestroy(&jac->x);CHKERRQ(ierr);
656bf464f9SBarry Smith   ierr = VecDestroy(&jac->b);CHKERRQ(ierr);
66a06653b4SBarry Smith   ierr = KSPReset(jac->ksp);CHKERRQ(ierr);
67a06653b4SBarry Smith   PetscFunctionReturn(0);
68a06653b4SBarry Smith }
69a06653b4SBarry Smith 
70a06653b4SBarry Smith static PetscErrorCode PCDestroy_Galerkin(PC pc)
71a06653b4SBarry Smith {
72a06653b4SBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
73a06653b4SBarry Smith   PetscErrorCode ierr;
74a06653b4SBarry Smith 
75a06653b4SBarry Smith   PetscFunctionBegin;
76fcfd50ebSBarry Smith   ierr = PCReset_Galerkin(pc);CHKERRQ(ierr);
776bf464f9SBarry Smith   ierr = KSPDestroy(&jac->ksp);CHKERRQ(ierr);
78c31cb41cSBarry Smith   ierr = PetscFree(pc->data);CHKERRQ(ierr);
792a6744ebSBarry Smith   PetscFunctionReturn(0);
802a6744ebSBarry Smith }
812a6744ebSBarry Smith 
822a6744ebSBarry Smith static PetscErrorCode PCView_Galerkin(PC pc,PetscViewer viewer)
832a6744ebSBarry Smith {
842a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
852a6744ebSBarry Smith   PetscErrorCode ierr;
86ace3abfcSBarry Smith   PetscBool      iascii;
872a6744ebSBarry Smith 
882a6744ebSBarry Smith   PetscFunctionBegin;
89251f4c67SDmitry Karpeev   ierr = PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii);CHKERRQ(ierr);
902a6744ebSBarry Smith   if (iascii) {
912a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"Galerkin PC\n");CHKERRQ(ierr);
922a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"KSP on Galerkin follow\n");CHKERRQ(ierr);
932a6744ebSBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"---------------------------------\n");CHKERRQ(ierr);
942a6744ebSBarry Smith   }
952a6744ebSBarry Smith   ierr = KSPView(jac->ksp,viewer);CHKERRQ(ierr);
962a6744ebSBarry Smith   PetscFunctionReturn(0);
972a6744ebSBarry Smith }
982a6744ebSBarry Smith 
991e6b0712SBarry Smith static PetscErrorCode  PCGalerkinGetKSP_Galerkin(PC pc,KSP *ksp)
1002a6744ebSBarry Smith {
1012a6744ebSBarry Smith   PC_Galerkin *jac = (PC_Galerkin*)pc->data;
1022a6744ebSBarry Smith 
1032a6744ebSBarry Smith   PetscFunctionBegin;
1042a6744ebSBarry Smith   *ksp = jac->ksp;
1052a6744ebSBarry Smith   PetscFunctionReturn(0);
1062a6744ebSBarry Smith }
1072a6744ebSBarry Smith 
1081e6b0712SBarry Smith static PetscErrorCode  PCGalerkinSetRestriction_Galerkin(PC pc,Mat R)
1092a6744ebSBarry Smith {
1102a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1112a6744ebSBarry Smith   PetscErrorCode ierr;
1122a6744ebSBarry Smith 
1132a6744ebSBarry Smith   PetscFunctionBegin;
114c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)R);CHKERRQ(ierr);
1156bf464f9SBarry Smith   ierr   = MatDestroy(&jac->R);CHKERRQ(ierr);
1162a6744ebSBarry Smith   jac->R = R;
1172a6744ebSBarry Smith   PetscFunctionReturn(0);
1182a6744ebSBarry Smith }
1192a6744ebSBarry Smith 
1201e6b0712SBarry Smith static PetscErrorCode  PCGalerkinSetInterpolation_Galerkin(PC pc,Mat P)
1212a6744ebSBarry Smith {
1222a6744ebSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
1232a6744ebSBarry Smith   PetscErrorCode ierr;
1242a6744ebSBarry Smith 
1252a6744ebSBarry Smith   PetscFunctionBegin;
126c3122656SLisandro Dalcin   ierr   = PetscObjectReference((PetscObject)P);CHKERRQ(ierr);
1276bf464f9SBarry Smith   ierr   = MatDestroy(&jac->P);CHKERRQ(ierr);
1282a6744ebSBarry Smith   jac->P = P;
1292a6744ebSBarry Smith   PetscFunctionReturn(0);
1302a6744ebSBarry Smith }
1312a6744ebSBarry Smith 
1322a6744ebSBarry Smith /* -------------------------------------------------------------------------------- */
1332a6744ebSBarry Smith /*@
1342a6744ebSBarry Smith    PCGalerkinSetRestriction - Sets the restriction operator for the "Galerkin-type" preconditioner
1352a6744ebSBarry Smith 
136ad4df100SBarry Smith    Logically Collective on PC
1372a6744ebSBarry Smith 
1382a6744ebSBarry Smith    Input Parameter:
1392a6744ebSBarry Smith +  pc - the preconditioner context
1402a6744ebSBarry Smith -  R - the restriction operator
1412a6744ebSBarry Smith 
1422a6744ebSBarry Smith    Notes: Either this or PCGalerkinSetInterpolation() or both must be called
1432a6744ebSBarry Smith 
1442a6744ebSBarry Smith    Level: Intermediate
1452a6744ebSBarry Smith 
1462a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
1472a6744ebSBarry Smith 
1482a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
1492a6744ebSBarry Smith            PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
1502a6744ebSBarry Smith 
1512a6744ebSBarry Smith @*/
1527087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetRestriction(PC pc,Mat R)
1532a6744ebSBarry Smith {
1544ac538c5SBarry Smith   PetscErrorCode ierr;
1552a6744ebSBarry Smith 
1562a6744ebSBarry Smith   PetscFunctionBegin;
1570700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1584ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetRestriction_C",(PC,Mat),(pc,R));CHKERRQ(ierr);
1592a6744ebSBarry Smith   PetscFunctionReturn(0);
1602a6744ebSBarry Smith }
1612a6744ebSBarry Smith 
1622a6744ebSBarry Smith /*@
1632a6744ebSBarry Smith    PCGalerkinSetInterpolation - Sets the interpolation operator for the "Galerkin-type" preconditioner
1642a6744ebSBarry Smith 
165ad4df100SBarry Smith    Logically Collective on PC
1662a6744ebSBarry Smith 
1672a6744ebSBarry Smith    Input Parameter:
1682a6744ebSBarry Smith +  pc - the preconditioner context
1692a6744ebSBarry Smith -  R - the interpolation operator
1702a6744ebSBarry Smith 
1712a6744ebSBarry Smith    Notes: Either this or PCGalerkinSetRestriction() or both must be called
1722a6744ebSBarry Smith 
1732a6744ebSBarry Smith    Level: Intermediate
1742a6744ebSBarry Smith 
1752a6744ebSBarry Smith .keywords: PC, set, Galerkin preconditioner
1762a6744ebSBarry Smith 
1772a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
1782a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinGetKSP()
1792a6744ebSBarry Smith 
1802a6744ebSBarry Smith @*/
1817087cfbeSBarry Smith PetscErrorCode  PCGalerkinSetInterpolation(PC pc,Mat P)
1822a6744ebSBarry Smith {
1834ac538c5SBarry Smith   PetscErrorCode ierr;
1842a6744ebSBarry Smith 
1852a6744ebSBarry Smith   PetscFunctionBegin;
1860700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
1874ac538c5SBarry Smith   ierr = PetscTryMethod(pc,"PCGalerkinSetInterpolation_C",(PC,Mat),(pc,P));CHKERRQ(ierr);
1882a6744ebSBarry Smith   PetscFunctionReturn(0);
1892a6744ebSBarry Smith }
1902a6744ebSBarry Smith 
1912a6744ebSBarry Smith /*@
1922a6744ebSBarry Smith    PCGalerkinGetKSP - Gets the KSP object in the Galerkin PC.
1932a6744ebSBarry Smith 
1942a6744ebSBarry Smith    Not Collective
1952a6744ebSBarry Smith 
1962a6744ebSBarry Smith    Input Parameter:
1972a6744ebSBarry Smith .  pc - the preconditioner context
1982a6744ebSBarry Smith 
1992a6744ebSBarry Smith    Output Parameters:
2002a6744ebSBarry Smith .  ksp - the KSP object
2012a6744ebSBarry Smith 
2022a6744ebSBarry Smith    Level: Intermediate
2032a6744ebSBarry Smith 
2042a6744ebSBarry Smith .keywords: PC, get, Galerkin preconditioner, sub preconditioner
2052a6744ebSBarry Smith 
2062a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PCGALERKIN,
2072a6744ebSBarry Smith            PCGalerkinSetRestriction(), PCGalerkinSetInterpolation()
2082a6744ebSBarry Smith 
2092a6744ebSBarry Smith @*/
2107087cfbeSBarry Smith PetscErrorCode  PCGalerkinGetKSP(PC pc,KSP *ksp)
2112a6744ebSBarry Smith {
2124ac538c5SBarry Smith   PetscErrorCode ierr;
2132a6744ebSBarry Smith 
2142a6744ebSBarry Smith   PetscFunctionBegin;
2150700a824SBarry Smith   PetscValidHeaderSpecific(pc,PC_CLASSID,1);
2162a6744ebSBarry Smith   PetscValidPointer(ksp,2);
2174ac538c5SBarry Smith   ierr = PetscUseMethod(pc,"PCGalerkinGetKSP_C",(PC,KSP*),(pc,ksp));CHKERRQ(ierr);
2182a6744ebSBarry Smith   PetscFunctionReturn(0);
2192a6744ebSBarry Smith }
2202a6744ebSBarry Smith 
221*4ac220ccSBarry Smith static PetscErrorCode PCSetFromOptions_Galerkin(PetscOptionItems *PetscOptionsObject,PC pc)
222*4ac220ccSBarry Smith {
223*4ac220ccSBarry Smith   PC_Galerkin    *jac = (PC_Galerkin*)pc->data;
224*4ac220ccSBarry Smith   PetscErrorCode ierr;
225*4ac220ccSBarry Smith   const char     *prefix;
226*4ac220ccSBarry Smith   PetscBool      flg;
227*4ac220ccSBarry Smith 
228*4ac220ccSBarry Smith   PetscFunctionBegin;
229*4ac220ccSBarry Smith   ierr = KSPGetOptionsPrefix(jac->ksp,&prefix);CHKERRQ(ierr);
230*4ac220ccSBarry Smith   ierr = PetscStrendswith(prefix,"galerkin_",&flg);CHKERRQ(ierr);
231*4ac220ccSBarry Smith   if (!flg) {
232*4ac220ccSBarry Smith     ierr = PCGetOptionsPrefix(pc,&prefix);CHKERRQ(ierr);
233*4ac220ccSBarry Smith     ierr = KSPSetOptionsPrefix(jac->ksp,prefix);CHKERRQ(ierr);
234*4ac220ccSBarry Smith     ierr = KSPAppendOptionsPrefix(jac->ksp,"galerkin_");CHKERRQ(ierr);
235*4ac220ccSBarry Smith   }
236*4ac220ccSBarry Smith 
237*4ac220ccSBarry Smith   ierr = PetscOptionsHead(PetscOptionsObject,"Galerkin options");CHKERRQ(ierr);
238*4ac220ccSBarry Smith   if (jac->ksp) {
239*4ac220ccSBarry Smith     ierr = KSPSetFromOptions(jac->ksp);CHKERRQ(ierr);
240*4ac220ccSBarry Smith   }
241*4ac220ccSBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
242*4ac220ccSBarry Smith   PetscFunctionReturn(0);
243*4ac220ccSBarry Smith }
2442a6744ebSBarry Smith 
2452a6744ebSBarry Smith /* -------------------------------------------------------------------------------------------*/
2462a6744ebSBarry Smith 
2472a6744ebSBarry Smith /*MC
2482a6744ebSBarry Smith      PCGALERKIN - Build (part of) a preconditioner by P S R (where P is often R^T)
2492a6744ebSBarry Smith 
2502a6744ebSBarry Smith $   Use PCGalerkinSetRestriction(pc,R) and/or PCGalerkinSetInterpolation(pc,P) followed by
2517817a140SBarry Smith $   PCGalerkinGetKSP(pc,&ksp); KSPSetOperators(ksp,A,....)
2522a6744ebSBarry Smith 
2532a6744ebSBarry Smith    Level: intermediate
2542a6744ebSBarry Smith 
255b59c8b46SBarry Smith    Developer Note: If KSPSetOperators() has not been called on the inner KSP then PCGALERKIN could use MatRARt() or MatPtAP() to compute
2567817a140SBarry Smith                    the operators automatically.
2577817a140SBarry Smith                    Should there be a prefix for the inner KSP.
2587817a140SBarry Smith                    There is no KSPSetFromOptions_Galerkin() that calls KSPSetFromOptions() on the inner KSP
2597817a140SBarry Smith 
2602a6744ebSBarry Smith .seealso:  PCCreate(), PCSetType(), PCType (for list of available types), PC,
2612a6744ebSBarry Smith            PCSHELL, PCKSP, PCGalerkinSetRestriction(), PCGalerkinSetInterpolation(), PCGalerkinGetKSP()
2622a6744ebSBarry Smith 
2632a6744ebSBarry Smith M*/
2642a6744ebSBarry Smith 
2658cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PCCreate_Galerkin(PC pc)
2662a6744ebSBarry Smith {
2672a6744ebSBarry Smith   PetscErrorCode ierr;
2682a6744ebSBarry Smith   PC_Galerkin    *jac;
2692a6744ebSBarry Smith 
2702a6744ebSBarry Smith   PetscFunctionBegin;
271b00a9115SJed Brown   ierr = PetscNewLog(pc,&jac);CHKERRQ(ierr);
2722fa5cd67SKarl Rupp 
2732a6744ebSBarry Smith   pc->ops->apply           = PCApply_Galerkin;
2742a6744ebSBarry Smith   pc->ops->setup           = PCSetUp_Galerkin;
275a06653b4SBarry Smith   pc->ops->reset           = PCReset_Galerkin;
2762a6744ebSBarry Smith   pc->ops->destroy         = PCDestroy_Galerkin;
2772a6744ebSBarry Smith   pc->ops->view            = PCView_Galerkin;
278*4ac220ccSBarry Smith   pc->ops->setfromoptions  = PCSetFromOptions_Galerkin;
279*4ac220ccSBarry Smith   pc->ops->applyrichardson = NULL;
2802a6744ebSBarry Smith 
281ce94432eSBarry Smith   ierr = KSPCreate(PetscObjectComm((PetscObject)pc),&jac->ksp);CHKERRQ(ierr);
282422a814eSBarry Smith   ierr = KSPSetErrorIfNotConverged(jac->ksp,pc->erroriffailure);CHKERRQ(ierr);
2831cee3971SBarry Smith   ierr = PetscObjectIncrementTabLevel((PetscObject)jac->ksp,(PetscObject)pc,1);CHKERRQ(ierr);
2842a6744ebSBarry Smith 
2852a6744ebSBarry Smith   pc->data = (void*)jac;
2862a6744ebSBarry Smith 
287bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetRestriction_C",PCGalerkinSetRestriction_Galerkin);CHKERRQ(ierr);
288bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinSetInterpolation_C",PCGalerkinSetInterpolation_Galerkin);CHKERRQ(ierr);
289bdf89e91SBarry Smith   ierr = PetscObjectComposeFunction((PetscObject)pc,"PCGalerkinGetKSP_C",PCGalerkinGetKSP_Galerkin);CHKERRQ(ierr);
2902a6744ebSBarry Smith   PetscFunctionReturn(0);
2912a6744ebSBarry Smith }
2922a6744ebSBarry Smith 
293