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