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