1 2 /* 3 Routines to set PC methods and options. 4 */ 5 6 #include <petsc-private/pcimpl.h> /*I "petscpc.h" I*/ 7 8 PetscBool PCRegisterAllCalled = PETSC_FALSE; 9 /* 10 Contains the list of registered KSP routines 11 */ 12 PetscFunctionList 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,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 = PetscObjectTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr); 64 if (match) PetscFunctionReturn(0); 65 66 ierr = PetscFunctionListFind(((PetscObject)pc)->comm,PCList,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) { 70 ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr); 71 pc->ops->destroy = PETSC_NULL; 72 pc->data = 0; 73 } 74 ierr = PetscFunctionListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr); 75 /* Reinitialize function pointers in PCOps structure */ 76 ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr); 77 /* XXX Is this OK?? */ 78 pc->modifysubmatrices = 0; 79 pc->modifysubmatricesP = 0; 80 /* Call the PCCreate_XXX routine for this particular preconditioner */ 81 pc->setupcalled = 0; 82 ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr); 83 ierr = (*r)(pc);CHKERRQ(ierr); 84 #if defined(PETSC_HAVE_AMS) 85 if (PetscAMSPublishAll) { 86 ierr = PetscObjectAMSPublish((PetscObject)pc);CHKERRQ(ierr); 87 } 88 #endif 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 PCRegisterAllCalled = PETSC_FALSE; 114 PetscFunctionReturn(0); 115 } 116 117 #undef __FUNCT__ 118 #define __FUNCT__ "PCGetType" 119 /*@C 120 PCGetType - Gets the PC method type and name (as a string) from the PC 121 context. 122 123 Not Collective 124 125 Input Parameter: 126 . pc - the preconditioner context 127 128 Output Parameter: 129 . type - name of preconditioner method 130 131 Level: intermediate 132 133 .keywords: PC, get, method, name, type 134 135 .seealso: PCSetType() 136 137 @*/ 138 PetscErrorCode PCGetType(PC pc,PCType *type) 139 { 140 PetscFunctionBegin; 141 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 142 PetscValidPointer(type,2); 143 *type = ((PetscObject)pc)->type_name; 144 PetscFunctionReturn(0); 145 } 146 147 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]); 148 149 #undef __FUNCT__ 150 #define __FUNCT__ "PCSetFromOptions" 151 /*@ 152 PCSetFromOptions - Sets PC options from the options database. 153 This routine must be called before PCSetUp() if the user is to be 154 allowed to set the preconditioner method. 155 156 Collective on PC 157 158 Input Parameter: 159 . pc - the preconditioner context 160 161 Level: developer 162 163 .keywords: PC, set, from, options, database 164 165 .seealso: 166 167 @*/ 168 PetscErrorCode PCSetFromOptions(PC pc) 169 { 170 PetscErrorCode ierr; 171 char type[256]; 172 const char *def; 173 PetscBool flg; 174 175 PetscFunctionBegin; 176 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 177 178 if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 179 ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr); 180 if (!((PetscObject)pc)->type_name) { 181 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 182 } else { 183 def = ((PetscObject)pc)->type_name; 184 } 185 186 ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 187 if (flg) { 188 ierr = PCSetType(pc,type);CHKERRQ(ierr); 189 } else if (!((PetscObject)pc)->type_name) { 190 ierr = PCSetType(pc,def);CHKERRQ(ierr); 191 } 192 193 ierr = PetscOptionsGetInt(((PetscObject)pc)->prefix,"-pc_reuse",&pc->reuse,PETSC_NULL);CHKERRQ(ierr); 194 195 if (pc->ops->setfromoptions) { 196 ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr); 197 } 198 199 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 200 ierr = PetscObjectProcessOptionsHandlers((PetscObject)pc);CHKERRQ(ierr); 201 ierr = PetscOptionsEnd();CHKERRQ(ierr); 202 pc->setfromoptionscalled++; 203 PetscFunctionReturn(0); 204 } 205 206 #undef __FUNCT__ 207 #define __FUNCT__ "PCSetDM" 208 /*@ 209 PCSetDM - Sets the DM that may be used by some preconditioners 210 211 Logically Collective on PC 212 213 Input Parameters: 214 + pc - the preconditioner context 215 - dm - the dm 216 217 Level: intermediate 218 219 220 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM() 221 @*/ 222 PetscErrorCode PCSetDM(PC pc,DM dm) 223 { 224 PetscErrorCode ierr; 225 226 PetscFunctionBegin; 227 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 228 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 229 ierr = DMDestroy(&pc->dm);CHKERRQ(ierr); 230 pc->dm = dm; 231 PetscFunctionReturn(0); 232 } 233 234 #undef __FUNCT__ 235 #define __FUNCT__ "PCGetDM" 236 /*@ 237 PCGetDM - Gets the DM that may be used by some preconditioners 238 239 Not Collective 240 241 Input Parameter: 242 . pc - the preconditioner context 243 244 Output Parameter: 245 . dm - the dm 246 247 Level: intermediate 248 249 250 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 251 @*/ 252 PetscErrorCode PCGetDM(PC pc,DM *dm) 253 { 254 PetscFunctionBegin; 255 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 256 *dm = pc->dm; 257 PetscFunctionReturn(0); 258 } 259 260 #undef __FUNCT__ 261 #define __FUNCT__ "PCSetApplicationContext" 262 /*@ 263 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 264 265 Logically Collective on PC 266 267 Input Parameters: 268 + pc - the PC context 269 - usrP - optional user context 270 271 Level: intermediate 272 273 .keywords: PC, set, application, context 274 275 .seealso: PCGetApplicationContext() 276 @*/ 277 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 278 { 279 PetscFunctionBegin; 280 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 281 pc->user = usrP; 282 PetscFunctionReturn(0); 283 } 284 285 #undef __FUNCT__ 286 #define __FUNCT__ "PCGetApplicationContext" 287 /*@ 288 PCGetApplicationContext - Gets the user-defined context for the linear solver. 289 290 Not Collective 291 292 Input Parameter: 293 . pc - PC context 294 295 Output Parameter: 296 . usrP - user context 297 298 Level: intermediate 299 300 .keywords: PC, get, application, context 301 302 .seealso: PCSetApplicationContext() 303 @*/ 304 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 305 { 306 PetscFunctionBegin; 307 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 308 *(void**)usrP = pc->user; 309 PetscFunctionReturn(0); 310 } 311 312