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: The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is 194 replace the current DM 195 196 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM() 197 @*/ 198 PetscErrorCode PCSetDM(PC pc,DM dm) 199 { 200 PetscErrorCode ierr; 201 202 PetscFunctionBegin; 203 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 204 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 205 ierr = DMDestroy(&pc->dm);CHKERRQ(ierr); 206 pc->dm = dm; 207 PetscFunctionReturn(0); 208 } 209 210 /*@ 211 PCGetDM - Gets the DM that may be used by some preconditioners 212 213 Not Collective 214 215 Input Parameter: 216 . pc - the preconditioner context 217 218 Output Parameter: 219 . dm - the dm 220 221 Level: intermediate 222 223 224 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 225 @*/ 226 PetscErrorCode PCGetDM(PC pc,DM *dm) 227 { 228 PetscFunctionBegin; 229 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 230 *dm = pc->dm; 231 PetscFunctionReturn(0); 232 } 233 234 /*@ 235 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 236 237 Logically Collective on PC 238 239 Input Parameters: 240 + pc - the PC context 241 - usrP - optional user context 242 243 Level: intermediate 244 245 .keywords: PC, set, application, context 246 247 .seealso: PCGetApplicationContext() 248 @*/ 249 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 250 { 251 PetscFunctionBegin; 252 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 253 pc->user = usrP; 254 PetscFunctionReturn(0); 255 } 256 257 /*@ 258 PCGetApplicationContext - Gets the user-defined context for the linear solver. 259 260 Not Collective 261 262 Input Parameter: 263 . pc - PC context 264 265 Output Parameter: 266 . usrP - user context 267 268 Level: intermediate 269 270 .keywords: PC, get, application, context 271 272 .seealso: PCSetApplicationContext() 273 @*/ 274 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 275 { 276 PetscFunctionBegin; 277 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 278 *(void**)usrP = pc->user; 279 PetscFunctionReturn(0); 280 } 281 282