xref: /petsc/src/ksp/pc/impls/wb/wb.c (revision 5d00a290c924ab1b2c83000ba3a0ae1df9cca2e4)
1 #define PETSCKSP_DLL
2 
3 
4 #include "petscpc.h"   /*I "petscpc.h" I*/
5 #include "petscmg.h"   /*I "petscmg.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, Pasciak  and Schatz, "The Construction
197    of Preconditioners for Elliptic Problems by Substructing IV", Mathematics of Computation, volume 53 pages 1--24, 1989.
198    They were generalized slightly in "Domain Decomposition Method for Linear Elasticity", Ph. D. thesis, Barry Smith,
199    New York University, 1990. They were then explored in great detail in Dryja, Smith, Widlund, "Schwarz Analysis
200    of Iterative Substructuring Methods for Elliptic Problems in Three Dimensions, SIAM Journal on Numerical
201    Analysis, volume 31. pages 1662-1694, 1994. These were developed in the context of iterative substructuring preconditioners.
202    They were then ingeniously applied as coarse grid spaces for overlapping Schwarz methods by Dohrmann and Widlund.
203    They refer to them as GDSW (generalized Dryja, Smith, Widlund preconditioners). See, for example,
204    Clark R. Dohrmann, Axel Klawonn, and Olof B. Widlund. Extending theory for domain decomposition algorithms to irregular subdomains. In Ulrich Langer, Marco
205    Discacciati, David Keyes, Olof Widlund, and Walter Zulehner, editors, Proceedings
206    of the 17th International Conference on Domain Decomposition Methods in
207    Science and Engineering, held in Strobl, Austria, July 3-7, 2006, number 60 in
208    Springer-Verlag, Lecture Notes in Computational Science and Engineering, pages 255-261, 2007.
209    Clark R. Dohrmann, Axel Klawonn, and Olof B. Widlund. A family of energy min-
210    imizing coarse spaces for overlapping Schwarz preconditioners. In Ulrich Langer,
211    Marco Discacciati, David Keyes, OlofWidlund, andWalter Zulehner, editors, Proceedings
212    of the 17th International Conference on Domain Decomposition Methods
213    in Science and Engineering, held in Strobl, Austria, July 3-7, 2006, number 60 in
214    Springer-Verlag, Lecture Notes in Computational Science and Engineering, pages 247-254, 2007
215    Clark R. Dohrmann, Axel Klawonn, and Olof B. Widlund. Domain decomposition
216    for less regular subdomains: Overlapping Schwarz in two dimensions. SIAM J.
217    Numer. Anal., 46(4):2153-2168, 2008.
218    Clark R. Dohrmann and Olof B. Widlund. An overlapping Schwarz
219    algorithm for almost incompressible elasticity. Technical Report
220    TR2008-912, Department of Computer Science, Courant Institute
221    of Mathematical Sciences, New York University, May 2008. URL:
222    http://cs.nyu.edu/csweb/Research/TechReports/TR2008-912/TR2008-912.pdf
223 
224    Options Database: The usual PCMG options are supported, such as -mg_levels_pc_type <type> -mg_coarse_pc_type <type>
225       -pc_mg_type <type>
226 
227 .seealso:  PCMG, PCExoticSetDA(), PCExoticType, PCExoticSetType()
228 
229 M*/
230 
231 EXTERN_C_BEGIN
232 #undef __FUNCT__
233 #define __FUNCT__ "PCCreate_Exotic"
234 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Exotic(PC pc)
235 {
236   PetscErrorCode ierr;
237   PC_Exotic      *ex;
238   PC_MG          **mg;
239 
240   PetscFunctionBegin;
241   ierr = PCSetType(pc,PCMG);CHKERRQ(ierr);
242   ierr = PCMGSetLevels(pc,2,PETSC_NULL);CHKERRQ(ierr);
243   ierr = PCMGSetGalerkin(pc);CHKERRQ(ierr);
244   ierr = PetscNew(PC_Exotic,&ex);CHKERRQ(ierr);
245   ex->type = PC_EXOTIC_FACE;
246   mg = (void*)(PC_MG**)pc->data;
247   mg[0]->innerctx = ex;
248 
249 
250   pc->ops->setfromoptions = PCSetFromOptions_Exotic;
251   pc->ops->view           = PCView_Exotic;
252   pc->ops->destroy        = PCDestroy_Exotic;
253   pc->ops->setup          = PCSetUp_Exotic_Error;
254   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetType_C","PCExoticSetType_Exotic",PCExoticSetType_Exotic);CHKERRQ(ierr);
255   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetDA_C","PCExoticSetDA_Exotic",PCExoticSetDA_Exotic);CHKERRQ(ierr);
256   PetscFunctionReturn(0);
257 }
258 EXTERN_C_END
259