1 2 /* 3 Routines to set PC methods and options. 4 */ 5 6 #include <petsc-private/pcimpl.h> /*I "petscpc.h" I*/ 7 #include <petscdm.h> 8 9 PetscBool PCRegisterAllCalled = PETSC_FALSE; 10 /* 11 Contains the list of registered KSP routines 12 */ 13 PetscFunctionList PCList = 0; 14 15 #undef __FUNCT__ 16 #define __FUNCT__ "PCSetType" 17 /*@C 18 PCSetType - Builds PC for a particular preconditioner. 19 20 Collective on PC 21 22 Input Parameter: 23 + pc - the preconditioner context. 24 - type - a known method 25 26 Options Database Key: 27 . -pc_type <type> - Sets PC type 28 29 Use -help for a list of available methods (for instance, 30 jacobi or bjacobi) 31 32 Notes: 33 See "petsc/include/petscpc.h" for available methods (for instance, 34 PCJACOBI, PCILU, or PCBJACOBI). 35 36 Normally, it is best to use the KSPSetFromOptions() command and 37 then set the PC type from the options database rather than by using 38 this routine. Using the options database provides the user with 39 maximum flexibility in evaluating the many different preconditioners. 40 The PCSetType() routine is provided for those situations where it 41 is necessary to set the preconditioner independently of the command 42 line or options database. This might be the case, for example, when 43 the choice of preconditioner changes during the execution of the 44 program, and the user's application is taking responsibility for 45 choosing the appropriate preconditioner. In other words, this 46 routine is not for beginners. 47 48 Level: intermediate 49 50 .keywords: PC, set, method, type 51 52 .seealso: KSPSetType(), PCType 53 54 @*/ 55 PetscErrorCode PCSetType(PC pc,PCType type) 56 { 57 PetscErrorCode ierr,(*r)(PC); 58 PetscBool match; 59 60 PetscFunctionBegin; 61 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 62 PetscValidCharPointer(type,2); 63 64 ierr = PetscObjectTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr); 65 if (match) PetscFunctionReturn(0); 66 67 ierr = PetscFunctionListFind(PetscObjectComm((PetscObject)pc),PCList,type,PETSC_TRUE,(void (**)(void)) &r);CHKERRQ(ierr); 68 if (!r) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type); 69 /* Destroy the previous private PC context */ 70 if (pc->ops->destroy) { 71 ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr); 72 pc->ops->destroy = NULL; 73 pc->data = 0; 74 } 75 ierr = PetscFunctionListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr); 76 /* Reinitialize function pointers in PCOps structure */ 77 ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr); 78 /* XXX Is this OK?? */ 79 pc->modifysubmatrices = 0; 80 pc->modifysubmatricesP = 0; 81 /* Call the PCCreate_XXX routine for this particular preconditioner */ 82 pc->setupcalled = 0; 83 84 ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr); 85 ierr = (*r)(pc);CHKERRQ(ierr); 86 PetscFunctionReturn(0); 87 } 88 89 #undef __FUNCT__ 90 #define __FUNCT__ "PCRegisterDestroy" 91 /*@ 92 PCRegisterDestroy - Frees the list of preconditioners that were 93 registered by PCRegisterDynamic(). 94 95 Not Collective 96 97 Level: advanced 98 99 .keywords: PC, register, destroy 100 101 .seealso: PCRegisterAll(), PCRegisterAll() 102 103 @*/ 104 PetscErrorCode PCRegisterDestroy(void) 105 { 106 PetscErrorCode ierr; 107 108 PetscFunctionBegin; 109 ierr = PetscFunctionListDestroy(&PCList);CHKERRQ(ierr); 110 111 PCRegisterAllCalled = PETSC_FALSE; 112 PetscFunctionReturn(0); 113 } 114 115 #undef __FUNCT__ 116 #define __FUNCT__ "PCGetType" 117 /*@C 118 PCGetType - Gets the PC method type and name (as a string) from the PC 119 context. 120 121 Not Collective 122 123 Input Parameter: 124 . pc - the preconditioner context 125 126 Output Parameter: 127 . type - name of preconditioner method 128 129 Level: intermediate 130 131 .keywords: PC, get, method, name, type 132 133 .seealso: PCSetType() 134 135 @*/ 136 PetscErrorCode PCGetType(PC pc,PCType *type) 137 { 138 PetscFunctionBegin; 139 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 140 PetscValidPointer(type,2); 141 *type = ((PetscObject)pc)->type_name; 142 PetscFunctionReturn(0); 143 } 144 145 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]); 146 147 #undef __FUNCT__ 148 #define __FUNCT__ "PCSetFromOptions" 149 /*@ 150 PCSetFromOptions - Sets PC options from the options database. 151 This routine must be called before PCSetUp() if the user is to be 152 allowed to set the preconditioner method. 153 154 Collective on PC 155 156 Input Parameter: 157 . pc - the preconditioner context 158 159 Level: developer 160 161 .keywords: PC, set, from, options, database 162 163 .seealso: 164 165 @*/ 166 PetscErrorCode PCSetFromOptions(PC pc) 167 { 168 PetscErrorCode ierr; 169 char type[256]; 170 const char *def; 171 PetscBool flg; 172 173 PetscFunctionBegin; 174 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 175 176 if (!PCRegisterAllCalled) {ierr = PCRegisterAll(NULL);CHKERRQ(ierr);} 177 ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr); 178 if (!((PetscObject)pc)->type_name) { 179 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 180 } else { 181 def = ((PetscObject)pc)->type_name; 182 } 183 184 ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 185 if (flg) { 186 ierr = PCSetType(pc,type);CHKERRQ(ierr); 187 } else if (!((PetscObject)pc)->type_name) { 188 ierr = PCSetType(pc,def);CHKERRQ(ierr); 189 } 190 191 ierr = PetscOptionsGetInt(((PetscObject)pc)->prefix,"-pc_reuse",&pc->reuse,NULL);CHKERRQ(ierr); 192 193 if (pc->ops->setfromoptions) { 194 ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr); 195 } 196 197 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 198 ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr); 199 ierr = PetscOptionsEnd();CHKERRQ(ierr); 200 pc->setfromoptionscalled++; 201 PetscFunctionReturn(0); 202 } 203 204 #undef __FUNCT__ 205 #define __FUNCT__ "PCSetDM" 206 /*@ 207 PCSetDM - Sets the DM that may be used by some preconditioners 208 209 Logically Collective on PC 210 211 Input Parameters: 212 + pc - the preconditioner context 213 - dm - the dm 214 215 Level: intermediate 216 217 218 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM() 219 @*/ 220 PetscErrorCode PCSetDM(PC pc,DM dm) 221 { 222 PetscErrorCode ierr; 223 224 PetscFunctionBegin; 225 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 226 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 227 ierr = DMDestroy(&pc->dm);CHKERRQ(ierr); 228 pc->dm = dm; 229 PetscFunctionReturn(0); 230 } 231 232 #undef __FUNCT__ 233 #define __FUNCT__ "PCGetDM" 234 /*@ 235 PCGetDM - Gets the DM that may be used by some preconditioners 236 237 Not Collective 238 239 Input Parameter: 240 . pc - the preconditioner context 241 242 Output Parameter: 243 . dm - the dm 244 245 Level: intermediate 246 247 248 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 249 @*/ 250 PetscErrorCode PCGetDM(PC pc,DM *dm) 251 { 252 PetscFunctionBegin; 253 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 254 *dm = pc->dm; 255 PetscFunctionReturn(0); 256 } 257 258 #undef __FUNCT__ 259 #define __FUNCT__ "PCSetApplicationContext" 260 /*@ 261 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 262 263 Logically Collective on PC 264 265 Input Parameters: 266 + pc - the PC context 267 - usrP - optional user context 268 269 Level: intermediate 270 271 .keywords: PC, set, application, context 272 273 .seealso: PCGetApplicationContext() 274 @*/ 275 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 276 { 277 PetscFunctionBegin; 278 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 279 pc->user = usrP; 280 PetscFunctionReturn(0); 281 } 282 283 #undef __FUNCT__ 284 #define __FUNCT__ "PCGetApplicationContext" 285 /*@ 286 PCGetApplicationContext - Gets the user-defined context for the linear solver. 287 288 Not Collective 289 290 Input Parameter: 291 . pc - PC context 292 293 Output Parameter: 294 . usrP - user context 295 296 Level: intermediate 297 298 .keywords: PC, get, application, context 299 300 .seealso: PCSetApplicationContext() 301 @*/ 302 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 303 { 304 PetscFunctionBegin; 305 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 306 *(void**)usrP = pc->user; 307 PetscFunctionReturn(0); 308 } 309 310