xref: /petsc/src/ksp/pc/impls/wb/wb.c (revision 7233f9f0e87c6c606c06fb4f2dbb983a766128a5)
1174b6946SBarry Smith #define PETSCKSP_DLL
2174b6946SBarry Smith 
3174b6946SBarry Smith 
4174b6946SBarry Smith #include "petscpc.h"   /*I "petscpc.h" I*/
5174b6946SBarry Smith #include "petscmg.h"   /*I "petscpc.h" I*/
6174b6946SBarry Smith #include "petscda.h"   /*I "petscda.h" I*/
7*7233f9f0SBarry Smith #include "../src/ksp/pc/impls/mg/mgimpl.h"
8*7233f9f0SBarry Smith 
9*7233f9f0SBarry Smith const char *PCExoticTypes[] = {"face","wirebasket","PCExoticType","PC_Exotic",0};
10174b6946SBarry Smith 
11174b6946SBarry Smith extern PetscErrorCode DAGetWireBasketInterpolation(DA,Mat,Mat*);
123639cd1fSBarry Smith extern PetscErrorCode DAGetFaceInterpolation(DA,Mat,Mat*);
13174b6946SBarry Smith 
14*7233f9f0SBarry Smith typedef struct {
15*7233f9f0SBarry Smith   DA           da;
16*7233f9f0SBarry Smith   PCExoticType type;
17*7233f9f0SBarry Smith } PC_Exotic;
18*7233f9f0SBarry Smith 
19174b6946SBarry Smith #undef __FUNCT__
20*7233f9f0SBarry Smith #define __FUNCT__ "PCExoticSetType"
21*7233f9f0SBarry Smith /*@
22*7233f9f0SBarry Smith    PCExoticSetType - Sets the type of coarse grid interpolation to use
23*7233f9f0SBarry Smith 
24*7233f9f0SBarry Smith    Collective on PC
25*7233f9f0SBarry Smith 
26*7233f9f0SBarry Smith    Input Parameters:
27*7233f9f0SBarry Smith +  pc - the preconditioner context
28*7233f9f0SBarry Smith -  type - either PC_EXOTIC_FACE or PC_EXOTIC_WIREBASKET (defaults to face)
29*7233f9f0SBarry Smith 
30*7233f9f0SBarry Smith    Level: intermediate
31*7233f9f0SBarry Smith 
32*7233f9f0SBarry Smith 
33*7233f9f0SBarry Smith .seealso: PCEXOTIC, PCExoticType()
34*7233f9f0SBarry Smith @*/
35*7233f9f0SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetType(PC pc,PCExoticType type)
36*7233f9f0SBarry Smith {
37*7233f9f0SBarry Smith   PetscErrorCode ierr,(*f)(PC,PCExoticType);
38*7233f9f0SBarry Smith 
39*7233f9f0SBarry Smith   PetscFunctionBegin;
40*7233f9f0SBarry Smith   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
41*7233f9f0SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetType_C",(void (**)(void))&f);CHKERRQ(ierr);
42*7233f9f0SBarry Smith   if (f) {
43*7233f9f0SBarry Smith     ierr = (*f)(pc,type);CHKERRQ(ierr);
44*7233f9f0SBarry Smith   }
45*7233f9f0SBarry Smith   PetscFunctionReturn(0);
46*7233f9f0SBarry Smith }
47*7233f9f0SBarry Smith 
48*7233f9f0SBarry Smith #undef __FUNCT__
49*7233f9f0SBarry Smith #define __FUNCT__ "PCExoticSetType_Exotic"
50*7233f9f0SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetType_Exotic(PC pc,PCExoticType type)
51*7233f9f0SBarry Smith {
52*7233f9f0SBarry Smith   PC_MG     **mg = (PC_MG**)pc->data;
53*7233f9f0SBarry Smith   PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx
54*7233f9f0SBarry Smith 
55*7233f9f0SBarry Smith   PetscFunctionBegin;
56*7233f9f0SBarry Smith   ctx->type = type;
57*7233f9f0SBarry Smith   PetscFunctionReturn(0);
58*7233f9f0SBarry Smith }
59*7233f9f0SBarry Smith 
60*7233f9f0SBarry Smith #undef __FUNCT__
61*7233f9f0SBarry Smith #define __FUNCT__ "PCSetUp_Exotic"
62*7233f9f0SBarry Smith PetscErrorCode PCSetUp_Exotic(PC pc)
63174b6946SBarry Smith {
64174b6946SBarry Smith   PetscErrorCode ierr;
65174b6946SBarry Smith   Mat            A,P;
66*7233f9f0SBarry Smith   PC_MG          **mg = (PC_MG**)pc->data;
67*7233f9f0SBarry Smith   PC_Exotic      *ex = (PC_Exotic*) mg[0]->innerctx;
68*7233f9f0SBarry Smith   DA             da = ex->da;
69174b6946SBarry Smith 
70174b6946SBarry Smith   PetscFunctionBegin;
71174b6946SBarry Smith   ierr = PCGetOperators(pc,PETSC_NULL,&A,PETSC_NULL);CHKERRQ(ierr);
72*7233f9f0SBarry Smith   if (ex->type == PC_EXOTIC_FACE) {
733639cd1fSBarry Smith     ierr = DAGetFaceInterpolation(da,A,&P);CHKERRQ(ierr);
74*7233f9f0SBarry Smith   } else if (ex->type == PC_EXOTIC_WIREBASKET) {
75*7233f9f0SBarry Smith     ierr = DAGetWireBasketInterpolation(da,A,&P);CHKERRQ(ierr);
76*7233f9f0SBarry Smith   } else SETERRQ1(PETSC_ERR_PLIB,"Unknown exotic coarse space %d",ex->type);
77174b6946SBarry Smith   ierr = PCMGSetInterpolation(pc,1,P);CHKERRQ(ierr);
78174b6946SBarry Smith   ierr = MatDestroy(P);CHKERRQ(ierr);
79*7233f9f0SBarry Smith   ierr = PCSetUp_MG(pc);CHKERRQ(ierr);
80174b6946SBarry Smith   PetscFunctionReturn(0);
81174b6946SBarry Smith }
82174b6946SBarry Smith 
83174b6946SBarry Smith #undef __FUNCT__
84*7233f9f0SBarry Smith #define __FUNCT__ "PCDestroy_Exotic"
85*7233f9f0SBarry Smith PetscErrorCode PCDestroy_Exotic(PC pc)
86174b6946SBarry Smith {
87174b6946SBarry Smith   PetscErrorCode ierr;
88*7233f9f0SBarry Smith   PC_MG          **mg = (PC_MG**)pc->data;
89*7233f9f0SBarry Smith   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx
90174b6946SBarry Smith 
91174b6946SBarry Smith   PetscFunctionBegin;
92*7233f9f0SBarry Smith   ierr = DADestroy(ctx->da);CHKERRQ(ierr);
93*7233f9f0SBarry Smith   ierr = PetscFree(ctx);CHKERRQ(ierr);
94*7233f9f0SBarry Smith   ierr = PCDestroy_MG(pc);CHKERRQ(ierr);
95174b6946SBarry Smith   PetscFunctionReturn(0);
96174b6946SBarry Smith }
97174b6946SBarry Smith 
98174b6946SBarry Smith #undef __FUNCT__
99*7233f9f0SBarry Smith #define __FUNCT__ "PCSetUp_Exotic_Error"
100*7233f9f0SBarry Smith PetscErrorCode PCSetUp_Exotic_Error(PC pc)
101174b6946SBarry Smith {
102174b6946SBarry Smith   PetscFunctionBegin;
103*7233f9f0SBarry Smith   SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You are using the Exotic preconditioner but never called PCExoticSetDA()");
104174b6946SBarry Smith   PetscFunctionReturn(0);
105174b6946SBarry Smith }
106174b6946SBarry Smith 
107174b6946SBarry Smith #undef __FUNCT__
108*7233f9f0SBarry Smith #define __FUNCT__ "PCExoticSetDA"
109*7233f9f0SBarry Smith /*@
110*7233f9f0SBarry Smith    PCExoticSetDA - Sets the DA that is to be used by the PCEXOTIC preconditioner
111*7233f9f0SBarry Smith 
112*7233f9f0SBarry Smith    Collective on PC
113*7233f9f0SBarry Smith 
114*7233f9f0SBarry Smith    Input Parameters:
115*7233f9f0SBarry Smith +  pc - the preconditioner context
116*7233f9f0SBarry Smith -  da - the da
117*7233f9f0SBarry Smith 
118*7233f9f0SBarry Smith    Level: intermediate
119*7233f9f0SBarry Smith 
120*7233f9f0SBarry Smith 
121*7233f9f0SBarry Smith .seealso: PCEXOTIC, PCExoticType()
122*7233f9f0SBarry Smith @*/
123*7233f9f0SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetDA(PC pc,DA da)
124174b6946SBarry Smith {
125*7233f9f0SBarry Smith   PetscErrorCode ierr,(*f)(PC,DA);
126174b6946SBarry Smith 
127174b6946SBarry Smith   PetscFunctionBegin;
128174b6946SBarry Smith   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
129174b6946SBarry Smith   PetscValidHeaderSpecific(da,DM_COOKIE,1);
130*7233f9f0SBarry Smith   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetDA_C",(void (**)(void))&f);CHKERRQ(ierr);
131*7233f9f0SBarry Smith   if (f) {
132*7233f9f0SBarry Smith     ierr = (*f)(pc,da);CHKERRQ(ierr);
133*7233f9f0SBarry Smith   }
134*7233f9f0SBarry Smith   PetscFunctionReturn(0);
135*7233f9f0SBarry Smith }
136174b6946SBarry Smith 
137*7233f9f0SBarry Smith 
138*7233f9f0SBarry Smith #undef __FUNCT__
139*7233f9f0SBarry Smith #define __FUNCT__ "PCExoticSetDA_Exotic"
140*7233f9f0SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetDA_Exotic(PC pc,DA da)
141*7233f9f0SBarry Smith {
142*7233f9f0SBarry Smith   PetscErrorCode ierr;
143*7233f9f0SBarry Smith   PC_MG          **mg = (PC_MG**)pc->data;
144*7233f9f0SBarry Smith   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx
145*7233f9f0SBarry Smith 
146*7233f9f0SBarry Smith   PetscFunctionBegin;
147*7233f9f0SBarry Smith   ctx->da = da;
148*7233f9f0SBarry Smith   pc->ops->setup = PCSetUp_Exotic;
149174b6946SBarry Smith   ierr   = PetscObjectReference((PetscObject)da);CHKERRQ(ierr);
150174b6946SBarry Smith   PetscFunctionReturn(0);
151174b6946SBarry Smith }
152174b6946SBarry Smith 
153*7233f9f0SBarry Smith #undef __FUNCT__
154*7233f9f0SBarry Smith #define __FUNCT__ "PCView_Exotic"
155*7233f9f0SBarry Smith PetscErrorCode PCView_Exotic(PC pc,PetscViewer viewer)
156*7233f9f0SBarry Smith {
157*7233f9f0SBarry Smith   PC_MG          **mg = (PC_MG**)pc->data;
158*7233f9f0SBarry Smith   PetscErrorCode ierr;
159*7233f9f0SBarry Smith   PetscTruth     iascii;
160*7233f9f0SBarry Smith   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx
161*7233f9f0SBarry Smith 
162*7233f9f0SBarry Smith   PetscFunctionBegin;
163*7233f9f0SBarry Smith   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
164*7233f9f0SBarry Smith   if (iascii) {
165*7233f9f0SBarry Smith     ierr = PetscViewerASCIIPrintf(viewer,"    Exotic type = %s\n",PCExoticTypes[ctx->type]);CHKERRQ(ierr);
166*7233f9f0SBarry Smith   }
167*7233f9f0SBarry Smith   ierr = PCView_MG(pc,viewer);CHKERRQ(ierr);
168*7233f9f0SBarry Smith   PetscFunctionReturn(0);
169*7233f9f0SBarry Smith }
170*7233f9f0SBarry Smith 
171*7233f9f0SBarry Smith #undef __FUNCT__
172*7233f9f0SBarry Smith #define __FUNCT__ "PCSetFromOptions_Exotic"
173*7233f9f0SBarry Smith PetscErrorCode PCSetFromOptions_Exotic(PC pc)
174*7233f9f0SBarry Smith {
175*7233f9f0SBarry Smith   PetscErrorCode ierr;
176*7233f9f0SBarry Smith   PetscTruth     flg;
177*7233f9f0SBarry Smith   PC_MG          **mg = (PC_MG**)pc->data;
178*7233f9f0SBarry Smith   PCExoticType   mgctype;
179*7233f9f0SBarry Smith   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx
180*7233f9f0SBarry Smith 
181*7233f9f0SBarry Smith   PetscFunctionBegin;
182*7233f9f0SBarry Smith   ierr = PetscOptionsHead("Exotic coarse space options");CHKERRQ(ierr);
183*7233f9f0SBarry Smith     ierr = PetscOptionsEnum("-pc_exotic_type","face or wirebasket","PCExoticSetType",PCExoticTypes,(PetscEnum)ctx->type,(PetscEnum*)&mgctype,&flg);CHKERRQ(ierr);
184*7233f9f0SBarry Smith     if (flg) {
185*7233f9f0SBarry Smith       ierr = PCExoticSetType(pc,mgctype);CHKERRQ(ierr);
186*7233f9f0SBarry Smith     }
187*7233f9f0SBarry Smith   ierr = PetscOptionsTail();CHKERRQ(ierr);
188*7233f9f0SBarry Smith   PetscFunctionReturn(0);
189*7233f9f0SBarry Smith }
190*7233f9f0SBarry Smith 
191174b6946SBarry Smith 
192174b6946SBarry Smith /*MC
193*7233f9f0SBarry Smith      PCEXOTIC - Two level overlapping Schwarz preconditioner with exotic (non-standard) coarse grid spaces
194174b6946SBarry Smith 
195*7233f9f0SBarry Smith      This uses the PCMG infrastructure restricted to two levels and the face and wirebasket based coarse
196*7233f9f0SBarry Smith    grid spaces. These coarse grid spaces originate in the work of Bramble, Pasiak (Sp) and Schatz, they
197*7233f9f0SBarry Smith    were generalized slightly in "Domain Decomposition Method for Linear Elasticity", Ph. D. thesis, Barry Smith,
198*7233f9f0SBarry Smith    New York University, 1990. These were developed in the context of iterative substructuring preconditioners.
199*7233f9f0SBarry Smith    They were then ingeniously applied as coarse grid spaces for overlapping Schwarz methods by XXXX and Widlund.
200*7233f9f0SBarry Smith    They refer to them as GDSW (generalized Dryja, Smith, Widlund preconditioners).
201*7233f9f0SBarry Smith 
202*7233f9f0SBarry Smith    Options Database: The usual PCMG options are supported, such as -mg_levels_pc_type <type> -mg_coarse_pc_type <type>
203*7233f9f0SBarry Smith       -pc_mg_type <type>
204*7233f9f0SBarry Smith 
205*7233f9f0SBarry Smith .seealso:  PCMG, PCExoticSetDA(), PCExoticType, PCExoticSetType()
206174b6946SBarry Smith 
207174b6946SBarry Smith M*/
208174b6946SBarry Smith 
209174b6946SBarry Smith EXTERN_C_BEGIN
210174b6946SBarry Smith #undef __FUNCT__
211*7233f9f0SBarry Smith #define __FUNCT__ "PCCreate_Exotic"
212*7233f9f0SBarry Smith PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Exotic(PC pc)
213174b6946SBarry Smith {
214174b6946SBarry Smith   PetscErrorCode ierr;
215*7233f9f0SBarry Smith   PC_Exotic      *ex;
216*7233f9f0SBarry Smith   PC_MG          **mg;
217174b6946SBarry Smith 
218174b6946SBarry Smith   PetscFunctionBegin;
219174b6946SBarry Smith   ierr = PCSetType(pc,PCMG);CHKERRQ(ierr);
220174b6946SBarry Smith   ierr = PCMGSetLevels(pc,2,PETSC_NULL);CHKERRQ(ierr);
221174b6946SBarry Smith   ierr = PCMGSetGalerkin(pc);CHKERRQ(ierr);
222*7233f9f0SBarry Smith   ierr = PetscNew(PC_Exotic,&ex);CHKERRQ(ierr);
223*7233f9f0SBarry Smith   ex->type = PC_EXOTIC_FACE;
224*7233f9f0SBarry Smith   mg = (void*)(PC_MG**)pc->data;
225*7233f9f0SBarry Smith   mg[0]->innerctx = ex;
226*7233f9f0SBarry Smith 
227*7233f9f0SBarry Smith 
228*7233f9f0SBarry Smith   pc->ops->setfromoptions = PCSetFromOptions_Exotic;
229*7233f9f0SBarry Smith   pc->ops->view           = PCView_Exotic;
230*7233f9f0SBarry Smith   pc->ops->destroy        = PCDestroy_Exotic;
231*7233f9f0SBarry Smith   pc->ops->setup          = PCSetUp_Exotic_Error;
232*7233f9f0SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetType_C","PCExoticSetType_Exotic",PCExoticSetType_Exotic);CHKERRQ(ierr);
233*7233f9f0SBarry Smith   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetDA_C","PCExoticSetDA_Exotic",PCExoticSetDA_Exotic);CHKERRQ(ierr);
234174b6946SBarry Smith   PetscFunctionReturn(0);
235174b6946SBarry Smith }
236174b6946SBarry Smith EXTERN_C_END
237