Actual source code: wb.c
1: #define PETSCKSP_DLL
4: #include petscpc.h
5: #include petscmg.h
6: #include petscda.h
7: #include ../src/ksp/pc/impls/mg/mgimpl.h
9: const char *PCExoticTypes[] = {"face","wirebasket","PCExoticType","PC_Exotic",0};
14: typedef struct {
15: DA da;
16: PCExoticType type;
17: Mat P; /* the interpolation matrix */
18: } PC_Exotic;
22: /*@
23: PCExoticSetType - Sets the type of coarse grid interpolation to use
25: Collective on PC
27: Input Parameters:
28: + pc - the preconditioner context
29: - type - either PC_EXOTIC_FACE or PC_EXOTIC_WIREBASKET (defaults to face)
31: Level: intermediate
34: .seealso: PCEXOTIC, PCExoticType()
35: @*/
36: PetscErrorCode PCExoticSetType(PC pc,PCExoticType type)
37: {
38: PetscErrorCode ierr,(*f)(PC,PCExoticType);
42: PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetType_C",(void (**)(void))&f);
43: if (f) {
44: (*f)(pc,type);
45: }
46: return(0);
47: }
51: PetscErrorCode PCExoticSetType_Exotic(PC pc,PCExoticType type)
52: {
53: PC_MG **mg = (PC_MG**)pc->data;
54: PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
57: ctx->type = type;
58: return(0);
59: }
63: PetscErrorCode PCSetUp_Exotic(PC pc)
64: {
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;
73: PCGetOperators(pc,PETSC_NULL,&A,PETSC_NULL);
74: if (ex->type == PC_EXOTIC_FACE) {
75: DAGetFaceInterpolation(da,A,reuse,&ex->P);
76: } else if (ex->type == PC_EXOTIC_WIREBASKET) {
77: DAGetWireBasketInterpolation(da,A,reuse,&ex->P);
78: } else SETERRQ1(PETSC_ERR_PLIB,"Unknown exotic coarse space %d",ex->type);
79: PCMGSetInterpolation(pc,1,ex->P);
80: PCSetUp_MG(pc);
81: return(0);
82: }
86: PetscErrorCode PCDestroy_Exotic(PC pc)
87: {
89: PC_MG **mg = (PC_MG**)pc->data;
90: PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
93: if (ctx->da) {DADestroy(ctx->da);}
94: if (ctx->P) {MatDestroy(ctx->P);}
95: PetscFree(ctx);
96: PCDestroy_MG(pc);
97: return(0);
98: }
102: PetscErrorCode PCSetUp_Exotic_Error(PC pc)
103: {
105: SETERRQ(PETSC_ERR_ARG_WRONGSTATE,"You are using the Exotic preconditioner but never called PCExoticSetDA()");
106: return(0);
107: }
111: /*@
112: PCExoticSetDA - Sets the DA that is to be used by the PCEXOTIC preconditioner
114: Collective on PC
116: Input Parameters:
117: + pc - the preconditioner context
118: - da - the da
120: Level: intermediate
123: .seealso: PCEXOTIC, PCExoticType()
124: @*/
125: PetscErrorCode PCExoticSetDA(PC pc,DA da)
126: {
127: PetscErrorCode ierr,(*f)(PC,DA);
132: PetscObjectQueryFunction((PetscObject)pc,"PCExoticSetDA_C",(void (**)(void))&f);
133: if (f) {
134: (*f)(pc,da);
135: }
136: return(0);
137: }
142: PetscErrorCode PCExoticSetDA_Exotic(PC pc,DA da)
143: {
145: PC_MG **mg = (PC_MG**)pc->data;
146: PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
149: ctx->da = da;
150: pc->ops->setup = PCSetUp_Exotic;
151: PetscObjectReference((PetscObject)da);
152: return(0);
153: }
157: PetscErrorCode PCView_Exotic(PC pc,PetscViewer viewer)
158: {
159: PC_MG **mg = (PC_MG**)pc->data;
161: PetscTruth iascii;
162: PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
165: PetscTypeCompare((PetscObject)viewer,PETSC_VIEWER_ASCII,&iascii);
166: if (iascii) {
167: PetscViewerASCIIPrintf(viewer," Exotic type = %s\n",PCExoticTypes[ctx->type]);
168: }
169: PCView_MG(pc,viewer);
170: return(0);
171: }
175: PetscErrorCode PCSetFromOptions_Exotic(PC pc)
176: {
178: PetscTruth flg;
179: PC_MG **mg = (PC_MG**)pc->data;
180: PCExoticType mgctype;
181: PC_Exotic *ctx = (PC_Exotic*) mg[0]->innerctx;
184: PetscOptionsHead("Exotic coarse space options");
185: PetscOptionsEnum("-pc_exotic_type","face or wirebasket","PCExoticSetType",PCExoticTypes,(PetscEnum)ctx->type,(PetscEnum*)&mgctype,&flg);
186: if (flg) {
187: PCExoticSetType(pc,mgctype);
188: }
189: PetscOptionsTail();
190: return(0);
191: }
194: /*MC
195: PCEXOTIC - Two level overlapping Schwarz preconditioner with exotic (non-standard) coarse grid spaces
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
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>
229: Level: advanced
231: .seealso: PCMG, PCExoticSetDA(), PCExoticType, PCExoticSetType()
232: M*/
237: PetscErrorCode PCCreate_Exotic(PC pc)
238: {
240: PC_Exotic *ex;
241: PC_MG **mg;
244: PCSetType(pc,PCMG);
245: PCMGSetLevels(pc,2,PETSC_NULL);
246: PCMGSetGalerkin(pc);
247: PetscNew(PC_Exotic,&ex);\
248: ex->type = PC_EXOTIC_FACE;
249: mg = (PC_MG**) pc->data;
250: mg[0]->innerctx = ex;
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: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetType_C","PCExoticSetType_Exotic",PCExoticSetType_Exotic);
258: PetscObjectComposeFunctionDynamic((PetscObject)pc,"PCExoticSetDA_C","PCExoticSetDA_Exotic",PCExoticSetDA_Exotic);
259: return(0);
260: }