xref: /petsc/src/ksp/pc/impls/wb/wb.c (revision 82094794e2b9d059cc8370a7dbd4702a5e945ede)
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,MatReuse,Mat*);
12 extern PetscErrorCode DAGetFaceInterpolation(DA,Mat,MatReuse,Mat*);
13 
14 typedef struct {
15   DA           da;
16   PCExoticType type;
17   Mat          P;      /* the interpolation matrix */
18 } PC_Exotic;
19 
20 #undef __FUNCT__
21 #define __FUNCT__ "PCExoticSetType"
22 /*@
23    PCExoticSetType - Sets the type of coarse grid interpolation to use
24 
25    Collective on PC
26 
27    Input Parameters:
28 +  pc - the preconditioner context
29 -  type - either PC_EXOTIC_FACE or PC_EXOTIC_WIREBASKET (defaults to face)
30 
31    Notes: The face based interpolation has 1 degree of freedom per face and ignores the
32      edge and vertex values completely in the coarse problem. For any seven point
33      stencil the interpolation of a constant on all faces into the interior is that constant.
34 
35      The wirebasket interpolation has 1 degree of freedom per vertex, per edge and
36      per face. A constant on the subdomain boundary is interpolated as that constant
37      in the interior of the domain.
38 
39      The coarse grid matrix is obtained via the Galerkin computation A_c = R A R^T, hence
40      if A is nonsingular A_c is also nonsingular.
41 
42      Both interpolations are suitable for only scalar problems.
43 
44    Level: intermediate
45 
46 
47 .seealso: PCEXOTIC, PCExoticType()
48 @*/
49 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetType(PC pc,PCExoticType type)
50 {
51   PetscErrorCode ierr,(*f)(PC,PCExoticType);
52 
53   PetscFunctionBegin;
54   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
55   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetType_C",(void (**)(void))&f);CHKERRQ(ierr);
56   if (f) {
57     ierr = (*f)(pc,type);CHKERRQ(ierr);
58   }
59   PetscFunctionReturn(0);
60 }
61 
62 #undef __FUNCT__
63 #define __FUNCT__ "PCExoticSetType_Exotic"
64 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetType_Exotic(PC pc,PCExoticType type)
65 {
66   PC_MG     **mg = (PC_MG**)pc->data;
67   PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
68 
69   PetscFunctionBegin;
70   ctx->type = type;
71   PetscFunctionReturn(0);
72 }
73 
74 #undef __FUNCT__
75 #define __FUNCT__ "PCSetUp_Exotic"
76 PetscErrorCode PCSetUp_Exotic(PC pc)
77 {
78   PetscErrorCode ierr;
79   Mat            A;
80   PC_MG          **mg = (PC_MG**)pc->data;
81   PC_Exotic      *ex = (PC_Exotic*) mg[0]->innerctx;
82   DA             da = ex->da;
83   MatReuse       reuse = (ex->P) ? MAT_REUSE_MATRIX : MAT_INITIAL_MATRIX;
84 
85   PetscFunctionBegin;
86   ierr = PCGetOperators(pc,PETSC_NULL,&A,PETSC_NULL);CHKERRQ(ierr);
87   if (ex->type == PC_EXOTIC_FACE) {
88     ierr = DAGetFaceInterpolation(da,A,reuse,&ex->P);CHKERRQ(ierr);
89   } else if (ex->type == PC_EXOTIC_WIREBASKET) {
90     ierr = DAGetWireBasketInterpolation(da,A,reuse,&ex->P);CHKERRQ(ierr);
91   } else SETERRQ1(PETSC_ERR_PLIB,"Unknown exotic coarse space %d",ex->type);
92   ierr = PCMGSetInterpolation(pc,1,ex->P);CHKERRQ(ierr);
93   ierr = PCSetUp_MG(pc);CHKERRQ(ierr);
94   PetscFunctionReturn(0);
95 }
96 
97 #undef __FUNCT__
98 #define __FUNCT__ "PCDestroy_Exotic"
99 PetscErrorCode PCDestroy_Exotic(PC pc)
100 {
101   PetscErrorCode ierr;
102   PC_MG          **mg = (PC_MG**)pc->data;
103   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
104 
105   PetscFunctionBegin;
106   if (ctx->da) {ierr = DADestroy(ctx->da);CHKERRQ(ierr);}
107   if (ctx->P) {ierr = MatDestroy(ctx->P);CHKERRQ(ierr);}
108   ierr = PetscFree(ctx);CHKERRQ(ierr);
109   ierr = PCDestroy_MG(pc);CHKERRQ(ierr);
110   PetscFunctionReturn(0);
111 }
112 
113 #undef __FUNCT__
114 #define __FUNCT__ "PCSetUp_Exotic_Error"
115 PetscErrorCode PCSetUp_Exotic_Error(PC pc)
116 {
117   PetscFunctionBegin;
118   SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You are using the Exotic preconditioner but never called PCExoticSetDA()");
119   PetscFunctionReturn(0);
120 }
121 
122 #undef __FUNCT__
123 #define __FUNCT__ "PCExoticSetDA"
124 /*@
125    PCExoticSetDA - Sets the DA that is to be used by the PCEXOTIC preconditioner
126 
127    Collective on PC
128 
129    Input Parameters:
130 +  pc - the preconditioner context
131 -  da - the da
132 
133    Level: intermediate
134 
135 
136 .seealso: PCEXOTIC, PCExoticType()
137 @*/
138 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetDA(PC pc,DA da)
139 {
140   PetscErrorCode ierr,(*f)(PC,DA);
141 
142   PetscFunctionBegin;
143   PetscValidHeaderSpecific(pc,PC_COOKIE,1);
144   PetscValidHeaderSpecific(da,DM_COOKIE,1);
145   ierr = PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetDA_C",(void (**)(void))&f);CHKERRQ(ierr);
146   if (f) {
147     ierr = (*f)(pc,da);CHKERRQ(ierr);
148   }
149   PetscFunctionReturn(0);
150 }
151 
152 
153 #undef __FUNCT__
154 #define __FUNCT__ "PCExoticSetDA_Exotic"
155 PetscErrorCode PETSCKSP_DLLEXPORT PCExoticSetDA_Exotic(PC pc,DA da)
156 {
157   PetscErrorCode ierr;
158   PC_MG          **mg = (PC_MG**)pc->data;
159   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
160 
161   PetscFunctionBegin;
162   ctx->da = da;
163   pc->ops->setup = PCSetUp_Exotic;
164   ierr   = PetscObjectReference((PetscObject)da);CHKERRQ(ierr);
165   PetscFunctionReturn(0);
166 }
167 
168 #undef __FUNCT__
169 #define __FUNCT__ "PCView_Exotic"
170 PetscErrorCode PCView_Exotic(PC pc,PetscViewer viewer)
171 {
172   PC_MG          **mg = (PC_MG**)pc->data;
173   PetscErrorCode ierr;
174   PetscTruth     iascii;
175   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
176 
177   PetscFunctionBegin;
178   ierr = PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);CHKERRQ(ierr);
179   if (iascii) {
180     ierr = PetscViewerASCIIPrintf(viewer,"    Exotic type = %s\n",PCExoticTypes[ctx->type]);CHKERRQ(ierr);
181   }
182   ierr = PCView_MG(pc,viewer);CHKERRQ(ierr);
183   PetscFunctionReturn(0);
184 }
185 
186 #undef __FUNCT__
187 #define __FUNCT__ "PCSetFromOptions_Exotic"
188 PetscErrorCode PCSetFromOptions_Exotic(PC pc)
189 {
190   PetscErrorCode ierr;
191   PetscTruth     flg;
192   PC_MG          **mg = (PC_MG**)pc->data;
193   PCExoticType   mgctype;
194   PC_Exotic      *ctx = (PC_Exotic*) mg[0]->innerctx;
195 
196   PetscFunctionBegin;
197   ierr = PetscOptionsHead("Exotic coarse space options");CHKERRQ(ierr);
198     ierr = PetscOptionsEnum("-pc_exotic_type","face or wirebasket","PCExoticSetType",PCExoticTypes,(PetscEnum)ctx->type,(PetscEnum*)&mgctype,&flg);CHKERRQ(ierr);
199     if (flg) {
200       ierr = PCExoticSetType(pc,mgctype);CHKERRQ(ierr);
201     }
202   ierr = PetscOptionsTail();CHKERRQ(ierr);
203   PetscFunctionReturn(0);
204 }
205 
206 
207 /*MC
208      PCEXOTIC - Two level overlapping Schwarz preconditioner with exotic (non-standard) coarse grid spaces
209 
210      This uses the PCMG infrastructure restricted to two levels and the face and wirebasket based coarse
211    grid spaces. These coarse grid spaces originate in the work of Bramble, Pasciak  and Schatz, "The Construction
212    of Preconditioners for Elliptic Problems by Substructing IV", Mathematics of Computation, volume 53 pages 1--24, 1989.
213    They were generalized slightly in "Domain Decomposition Method for Linear Elasticity", Ph. D. thesis, Barry Smith,
214    New York University, 1990. They were then explored in great detail in Dryja, Smith, Widlund, "Schwarz Analysis
215    of Iterative Substructuring Methods for Elliptic Problems in Three Dimensions, SIAM Journal on Numerical
216    Analysis, volume 31. pages 1662-1694, 1994. These were developed in the context of iterative substructuring preconditioners.
217    They were then ingeniously applied as coarse grid spaces for overlapping Schwarz methods by Dohrmann and Widlund.
218    They refer to them as GDSW (generalized Dryja, Smith, Widlund preconditioners). See, for example,
219    Clark R. Dohrmann, Axel Klawonn, and Olof B. Widlund. Extending theory for domain decomposition algorithms to irregular subdomains. In Ulrich Langer, Marco
220    Discacciati, David Keyes, Olof Widlund, and Walter Zulehner, editors, Proceedings
221    of the 17th International Conference on Domain Decomposition Methods in
222    Science and Engineering, held in Strobl, Austria, July 3-7, 2006, number 60 in
223    Springer-Verlag, Lecture Notes in Computational Science and Engineering, pages 255-261, 2007.
224    Clark R. Dohrmann, Axel Klawonn, and Olof B. Widlund. A family of energy min-
225    imizing coarse spaces for overlapping Schwarz preconditioners. In Ulrich Langer,
226    Marco Discacciati, David Keyes, OlofWidlund, andWalter Zulehner, editors, Proceedings
227    of the 17th International Conference on Domain Decomposition Methods
228    in Science and Engineering, held in Strobl, Austria, July 3-7, 2006, number 60 in
229    Springer-Verlag, Lecture Notes in Computational Science and Engineering, pages 247-254, 2007
230    Clark R. Dohrmann, Axel Klawonn, and Olof B. Widlund. Domain decomposition
231    for less regular subdomains: Overlapping Schwarz in two dimensions. SIAM J.
232    Numer. Anal., 46(4):2153-2168, 2008.
233    Clark R. Dohrmann and Olof B. Widlund. An overlapping Schwarz
234    algorithm for almost incompressible elasticity. Technical Report
235    TR2008-912, Department of Computer Science, Courant Institute
236    of Mathematical Sciences, New York University, May 2008. URL:
237    http://cs.nyu.edu/csweb/Research/TechReports/TR2008-912/TR2008-912.pdf
238 
239    Options Database: The usual PCMG options are supported, such as -mg_levels_pc_type <type> -mg_coarse_pc_type <type>
240       -pc_mg_type <type>
241 
242    Level: advanced
243 
244 .seealso:  PCMG, PCExoticSetDA(), PCExoticType, PCExoticSetType()
245 M*/
246 
247 EXTERN_C_BEGIN
248 #undef __FUNCT__
249 #define __FUNCT__ "PCCreate_Exotic"
250 PetscErrorCode PETSCKSP_DLLEXPORT PCCreate_Exotic(PC pc)
251 {
252   PetscErrorCode ierr;
253   PC_Exotic      *ex;
254   PC_MG          **mg;
255 
256   PetscFunctionBegin;
257   ierr = PCSetType(pc,PCMG);CHKERRQ(ierr);
258   ierr = PCMGSetLevels(pc,2,PETSC_NULL);CHKERRQ(ierr);
259   ierr = PCMGSetGalerkin(pc);CHKERRQ(ierr);
260   ierr = PetscNew(PC_Exotic,&ex);CHKERRQ(ierr);\
261   ex->type = PC_EXOTIC_FACE;
262   mg = (PC_MG**) pc->data;
263   mg[0]->innerctx = ex;
264 
265 
266   pc->ops->setfromoptions = PCSetFromOptions_Exotic;
267   pc->ops->view           = PCView_Exotic;
268   pc->ops->destroy        = PCDestroy_Exotic;
269   pc->ops->setup          = PCSetUp_Exotic_Error;
270   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetType_C","PCExoticSetType_Exotic",PCExoticSetType_Exotic);CHKERRQ(ierr);
271   ierr = PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetDA_C","PCExoticSetDA_Exotic",PCExoticSetDA_Exotic);CHKERRQ(ierr);
272   PetscFunctionReturn(0);
273 }
274 EXTERN_C_END
275