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 if (PetscAMSPublishAll) { 87 ierr = PetscObjectAMSPublish((PetscObject)pc);CHKERRQ(ierr); 88 } 89 PetscFunctionReturn(0); 90 } 91 92 #undef __FUNCT__ 93 #define __FUNCT__ "PCRegisterDestroy" 94 /*@ 95 PCRegisterDestroy - Frees the list of preconditioners that were 96 registered by PCRegisterDynamic(). 97 98 Not Collective 99 100 Level: advanced 101 102 .keywords: PC, register, destroy 103 104 .seealso: PCRegisterAll(), PCRegisterAll() 105 106 @*/ 107 PetscErrorCode PCRegisterDestroy(void) 108 { 109 PetscErrorCode ierr; 110 111 PetscFunctionBegin; 112 ierr = PetscFunctionListDestroy(&PCList);CHKERRQ(ierr); 113 114 PCRegisterAllCalled = PETSC_FALSE; 115 PetscFunctionReturn(0); 116 } 117 118 #undef __FUNCT__ 119 #define __FUNCT__ "PCGetType" 120 /*@C 121 PCGetType - Gets the PC method type and name (as a string) from the PC 122 context. 123 124 Not Collective 125 126 Input Parameter: 127 . pc - the preconditioner context 128 129 Output Parameter: 130 . type - name of preconditioner method 131 132 Level: intermediate 133 134 .keywords: PC, get, method, name, type 135 136 .seealso: PCSetType() 137 138 @*/ 139 PetscErrorCode PCGetType(PC pc,PCType *type) 140 { 141 PetscFunctionBegin; 142 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 143 PetscValidPointer(type,2); 144 *type = ((PetscObject)pc)->type_name; 145 PetscFunctionReturn(0); 146 } 147 148 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]); 149 150 #undef __FUNCT__ 151 #define __FUNCT__ "PCSetFromOptions" 152 /*@ 153 PCSetFromOptions - Sets PC options from the options database. 154 This routine must be called before PCSetUp() if the user is to be 155 allowed to set the preconditioner method. 156 157 Collective on PC 158 159 Input Parameter: 160 . pc - the preconditioner context 161 162 Level: developer 163 164 .keywords: PC, set, from, options, database 165 166 .seealso: 167 168 @*/ 169 PetscErrorCode PCSetFromOptions(PC pc) 170 { 171 PetscErrorCode ierr; 172 char type[256]; 173 const char *def; 174 PetscBool flg; 175 176 PetscFunctionBegin; 177 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 178 179 if (!PCRegisterAllCalled) {ierr = PCRegisterAll(NULL);CHKERRQ(ierr);} 180 ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr); 181 if (!((PetscObject)pc)->type_name) { 182 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 183 } else { 184 def = ((PetscObject)pc)->type_name; 185 } 186 187 ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 188 if (flg) { 189 ierr = PCSetType(pc,type);CHKERRQ(ierr); 190 } else if (!((PetscObject)pc)->type_name) { 191 ierr = PCSetType(pc,def);CHKERRQ(ierr); 192 } 193 194 ierr = PetscOptionsGetInt(((PetscObject)pc)->prefix,"-pc_reuse",&pc->reuse,NULL);CHKERRQ(ierr); 195 196 if (pc->ops->setfromoptions) { 197 ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr); 198 } 199 200 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 201 ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr); 202 ierr = PetscOptionsEnd();CHKERRQ(ierr); 203 pc->setfromoptionscalled++; 204 PetscFunctionReturn(0); 205 } 206 207 #undef __FUNCT__ 208 #define __FUNCT__ "PCSetDM" 209 /*@ 210 PCSetDM - Sets the DM that may be used by some preconditioners 211 212 Logically Collective on PC 213 214 Input Parameters: 215 + pc - the preconditioner context 216 - dm - the dm 217 218 Level: intermediate 219 220 221 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM() 222 @*/ 223 PetscErrorCode PCSetDM(PC pc,DM dm) 224 { 225 PetscErrorCode ierr; 226 227 PetscFunctionBegin; 228 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 229 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 230 ierr = DMDestroy(&pc->dm);CHKERRQ(ierr); 231 pc->dm = dm; 232 PetscFunctionReturn(0); 233 } 234 235 #undef __FUNCT__ 236 #define __FUNCT__ "PCGetDM" 237 /*@ 238 PCGetDM - Gets the DM that may be used by some preconditioners 239 240 Not Collective 241 242 Input Parameter: 243 . pc - the preconditioner context 244 245 Output Parameter: 246 . dm - the dm 247 248 Level: intermediate 249 250 251 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 252 @*/ 253 PetscErrorCode PCGetDM(PC pc,DM *dm) 254 { 255 PetscFunctionBegin; 256 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 257 *dm = pc->dm; 258 PetscFunctionReturn(0); 259 } 260 261 #undef __FUNCT__ 262 #define __FUNCT__ "PCSetApplicationContext" 263 /*@ 264 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 265 266 Logically Collective on PC 267 268 Input Parameters: 269 + pc - the PC context 270 - usrP - optional user context 271 272 Level: intermediate 273 274 .keywords: PC, set, application, context 275 276 .seealso: PCGetApplicationContext() 277 @*/ 278 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 279 { 280 PetscFunctionBegin; 281 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 282 pc->user = usrP; 283 PetscFunctionReturn(0); 284 } 285 286 #undef __FUNCT__ 287 #define __FUNCT__ "PCGetApplicationContext" 288 /*@ 289 PCGetApplicationContext - Gets the user-defined context for the linear solver. 290 291 Not Collective 292 293 Input Parameter: 294 . pc - PC context 295 296 Output Parameter: 297 . usrP - user context 298 299 Level: intermediate 300 301 .keywords: PC, get, application, context 302 303 .seealso: PCSetApplicationContext() 304 @*/ 305 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 306 { 307 PetscFunctionBegin; 308 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 309 *(void**)usrP = pc->user; 310 PetscFunctionReturn(0); 311 } 312 313