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