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