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