xref: /petsc/src/ksp/pc/impls/wb/wb.c (revision bedee52e9ed8e757d168f199e69a2cb4f6f93fb3)
1 #define PETSCKSP_DLL
2 
3 
4 #include "petscpc.h"   /*I "petscpc.h" I*/
5 #include "petscmg.h"   /*I "petscpc.h" I*/
6 #include "petscda.h"   /*I "petscda.h" I*/
7 #include "../src/ksp/pc/impls/mg/mgimpl.h"
8 
9 const char *PCExoticTypes[] = {"face","wirebasket","PCExoticType","PC_Exotic",0};
10 
11 extern PetscErrorCode DAGetWireBasketInterpolation(DA,Mat,Mat*);
12 extern PetscErrorCode DAGetFaceInterpolation(DA,Mat,Mat*);
13 
14 typedef struct {
15   DA           da;
16   PCExoticType type;
17 } PC_Exotic;
18 
19 #undef __FUNCT__
20 #define __FUNCT__ "PCExoticSetType"
21 /*@
22    PCExoticSetType - Sets the type of coarse grid interpolation to use
23 
24    Collective on PC
25 
26    Input Parameters:
27 +  pc - the preconditioner context
28 -  type - either PC_EXOTIC_FACE or PC_EXOTIC_WIREBASKET (defaults to face)
29 
30    Level: intermediate
31 
32 
33 .seealso: PCEXOTIC, PCExoticType()
34 @*/
35 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetType(PC pc,PCExoticType type)
36 {
37   PetscErrorCode ierr,(*f)(PC,PCExoticType);
38 
39   PetscFunctionBegin;
40   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
41   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetType_C",(void (**)(void))&f);CHKERRQ(ierr);
42   if (f) {
43     ierr = (*f)(pc,type);CHKERRQ(ierr);
44   }
45   PetscFunctionReturn(0);
46 }
47 
48 #undef __FUNCT__
49 #define __FUNCT__ "PCExoticSetType_Exotic"
50 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetType_Exotic(PC pc,PCExoticType type)
51 {
52   PC_MG     **mg = (PC_MG**)pc->data;
53   PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
54 
55   PetscFunctionBegin;
56   ctx->type = type;
57   PetscFunctionReturn(0);
58 }
59 
60 #undef __FUNCT__
61 #define __FUNCT__ "PCSetUp_Exotic"
62 PetscErrorCode PCSetUp_Exotic(PC pc)
63 {
64   PetscErrorCode ierr;
65   Mat            A,P;
66   PC_MG          **mg = (PC_MG**)pc->data;
67   PC_Exotic      *ex = (PC_Exotic*) mg[0]->innerctx;
68   DA             da = ex->da;
69 
70   PetscFunctionBegin;
71   ierr = PCGetOperators(pc,PETSC_NULL,&A,PETSC_NULL);CHKERRQ(ierr);
72   if (ex->type == PC_EXOTIC_FACE) {
73     ierr = DAGetFaceInterpolation(da,A,&P);CHKERRQ(ierr);
74   } else if (ex->type == PC_EXOTIC_WIREBASKET) {
75     ierr = DAGetWireBasketInterpolation(da,A,&P);CHKERRQ(ierr);
76   } else SETERRQ1(PETSC_ERR_PLIB,"Unknown exotic coarse space %d",ex->type);
77   ierr = PCMGSetInterpolation(pc,1,P);CHKERRQ(ierr);
78   ierr = MatDestroy(P);CHKERRQ(ierr);
79   ierr = PCSetUp_MG(pc);CHKERRQ(ierr);
80   PetscFunctionReturn(0);
81 }
82 
83 #undef __FUNCT__
84 #define __FUNCT__ "PCDestroy_Exotic"
85 PetscErrorCode PCDestroy_Exotic(PC pc)
86 {
87   PetscErrorCode ierr;
88   PC_MG          **mg = (PC_MG**)pc->data;
89   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
90 
91   PetscFunctionBegin;
92   ierr = DADestroy(ctx->da);CHKERRQ(ierr);
93   ierr = PetscFree(ctx);CHKERRQ(ierr);
94   ierr = PCDestroy_MG(pc);CHKERRQ(ierr);
95   PetscFunctionReturn(0);
96 }
97 
98 #undef __FUNCT__
99 #define __FUNCT__ "PCSetUp_Exotic_Error"
100 PetscErrorCode PCSetUp_Exotic_Error(PC pc)
101 {
102   PetscFunctionBegin;
103   SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You are using the Exotic preconditioner but never called PCExoticSetDA()");
104   PetscFunctionReturn(0);
105 }
106 
107 #undef __FUNCT__
108 #define __FUNCT__ "PCExoticSetDA"
109 /*@
110    PCExoticSetDA - Sets the DA that is to be used by the PCEXOTIC preconditioner
111 
112    Collective on PC
113 
114    Input Parameters:
115 +  pc - the preconditioner context
116 -  da - the da
117 
118    Level: intermediate
119 
120 
121 .seealso: PCEXOTIC, PCExoticType()
122 @*/
123 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetDA(PC pc,DA da)
124 {
125   PetscErrorCode ierr,(*f)(PC,DA);
126 
127   PetscFunctionBegin;
128   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
129   PetscValidHeaderSpecific(da,DM_COOKIE,1);
130   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetDA_C",(void (**)(void))&f);CHKERRQ(ierr);
131   if (f) {
132     ierr = (*f)(pc,da);CHKERRQ(ierr);
133   }
134   PetscFunctionReturn(0);
135 }
136 
137 
138 #undef __FUNCT__
139 #define __FUNCT__ "PCExoticSetDA_Exotic"
140 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetDA_Exotic(PC pc,DA da)
141 {
142   PetscErrorCode ierr;
143   PC_MG          **mg = (PC_MG**)pc->data;
144   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
145 
146   PetscFunctionBegin;
147   ctx->da = da;
148   pc->ops->setup = PCSetUp_Exotic;
149   ierr   = PetscObjectReference((PetscObject)da);CHKERRQ(ierr);
150   PetscFunctionReturn(0);
151 }
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "PCView_Exotic"
155 PetscErrorCode PCView_Exotic(PC pc,PetscViewer viewer)
156 {
157   PC_MG          **mg = (PC_MG**)pc->data;
158   PetscErrorCode ierr;
159   PetscTruth     iascii;
160   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
161 
162   PetscFunctionBegin;
163   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
164   if (iascii) {
165     ierr = PetscViewerASCIIPrintf(viewer,"    Exotic type = %s\n",PCExoticTypes[ctx->type]);CHKERRQ(ierr);
166   }
167   ierr = PCView_MG(pc,viewer);CHKERRQ(ierr);
168   PetscFunctionReturn(0);
169 }
170 
171 #undef __FUNCT__
172 #define __FUNCT__ "PCSetFromOptions_Exotic"
173 PetscErrorCode PCSetFromOptions_Exotic(PC pc)
174 {
175   PetscErrorCode ierr;
176   PetscTruth     flg;
177   PC_MG          **mg = (PC_MG**)pc->data;
178   PCExoticType   mgctype;
179   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
180 
181   PetscFunctionBegin;
182   ierr = PetscOptionsHead("Exotic coarse space options");CHKERRQ(ierr);
183     ierr = PetscOptionsEnum("-pc_exotic_type","face or wirebasket","PCExoticSetType",PCExoticTypes,(PetscEnum)ctx->type,(PetscEnum*)&mgctype,&flg);CHKERRQ(ierr);
184     if (flg) {
185       ierr = PCExoticSetType(pc,mgctype);CHKERRQ(ierr);
186     }
187   ierr = PetscOptionsTail();CHKERRQ(ierr);
188   PetscFunctionReturn(0);
189 }
190 
191 
192 /*MC
193      PCEXOTIC - Two level overlapping Schwarz preconditioner with exotic (non-standard) coarse grid spaces
194 
195      This uses the PCMG infrastructure restricted to two levels and the face and wirebasket based coarse
196    grid spaces. These coarse grid spaces originate in the work of Bramble, Pasiak (Sp) and Schatz, they
197    were generalized slightly in "Domain Decomposition Method for Linear Elasticity", Ph. D. thesis, Barry Smith,
198    New York University, 1990. These were developed in the context of iterative substructuring preconditioners.
199    They were then ingeniously applied as coarse grid spaces for overlapping Schwarz methods by XXXX and Widlund.
200    They refer to them as GDSW (generalized Dryja, Smith, Widlund preconditioners).
201 
202    Options Database: The usual PCMG options are supported, such as -mg_levels_pc_type <type> -mg_coarse_pc_type <type>
203       -pc_mg_type <type>
204 
205 .seealso:  PCMG, PCExoticSetDA(), PCExoticType, PCExoticSetType()
206 
207 M*/
208 
209 EXTERN_C_BEGIN
210 #undef __FUNCT__
211 #define __FUNCT__ "PCCreate_Exotic"
212 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Exotic(PC pc)
213 {
214   PetscErrorCode ierr;
215   PC_Exotic      *ex;
216   PC_MG          **mg;
217 
218   PetscFunctionBegin;
219   ierr = PCSetType(pc,PCMG);CHKERRQ(ierr);
220   ierr = PCMGSetLevels(pc,2,PETSC_NULL);CHKERRQ(ierr);
221   ierr = PCMGSetGalerkin(pc);CHKERRQ(ierr);
222   ierr = PetscNew(PC_Exotic,&ex);CHKERRQ(ierr);
223   ex->type = PC_EXOTIC_FACE;
224   mg = (void*)(PC_MG**)pc->data;
225   mg[0]->innerctx = ex;
226 
227 
228   pc->ops->setfromoptions = PCSetFromOptions_Exotic;
229   pc->ops->view           = PCView_Exotic;
230   pc->ops->destroy        = PCDestroy_Exotic;
231   pc->ops->setup          = PCSetUp_Exotic_Error;
232   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetType_C","PCExoticSetType_Exotic",PCExoticSetType_Exotic);CHKERRQ(ierr);
233   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetDA_C","PCExoticSetDA_Exotic",PCExoticSetDA_Exotic);CHKERRQ(ierr);
234   PetscFunctionReturn(0);
235 }
236 EXTERN_C_END
237