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 PC routines 12 */ 13 PetscFunctionList PCList = NULL; 14 15 /*@C 16 PCSetType - Builds PC for a particular preconditioner type 17 18 Collective on PC 19 20 Input Parameters: 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 .seealso: `KSPSetType()`, `PCType`, `PCRegister()`, `PCCreate()`, `KSPGetPC()` 52 53 @*/ 54 PetscErrorCode PCSetType(PC pc,PCType type) 55 { 56 PetscBool match; 57 PetscErrorCode (*r)(PC); 58 59 PetscFunctionBegin; 60 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 61 PetscValidCharPointer(type,2); 62 63 PetscCall(PetscObjectTypeCompare((PetscObject)pc,type,&match)); 64 if (match) PetscFunctionReturn(0); 65 66 PetscCall(PetscFunctionListFind(PCList,type,&r)); 67 PetscCheck(r,PetscObjectComm((PetscObject)pc),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 PetscCall((*pc->ops->destroy)(pc)); 71 pc->ops->destroy = NULL; 72 pc->data = NULL; 73 } 74 PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist)); 75 /* Reinitialize function pointers in PCOps structure */ 76 PetscCall(PetscMemzero(pc->ops,sizeof(struct _PCOps))); 77 /* XXX Is this OK?? */ 78 pc->modifysubmatrices = NULL; 79 pc->modifysubmatricesP = NULL; 80 /* Call the PCCreate_XXX routine for this particular preconditioner */ 81 pc->setupcalled = 0; 82 83 PetscCall(PetscObjectChangeTypeName((PetscObject)pc,type)); 84 PetscCall((*r)(pc)); 85 PetscFunctionReturn(0); 86 } 87 88 /*@C 89 PCGetType - Gets the PC method type and name (as a string) from the PC 90 context. 91 92 Not Collective 93 94 Input Parameter: 95 . pc - the preconditioner context 96 97 Output Parameter: 98 . type - name of preconditioner method 99 100 Level: intermediate 101 102 .seealso: `PCSetType()` 103 104 @*/ 105 PetscErrorCode PCGetType(PC pc,PCType *type) 106 { 107 PetscFunctionBegin; 108 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 109 PetscValidPointer(type,2); 110 *type = ((PetscObject)pc)->type_name; 111 PetscFunctionReturn(0); 112 } 113 114 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]); 115 116 /*@ 117 PCSetFromOptions - Sets PC options from the options database. 118 This routine must be called before PCSetUp() if the user is to be 119 allowed to set the preconditioner method. 120 121 Collective on PC 122 123 Input Parameter: 124 . pc - the preconditioner context 125 126 Options Database: 127 . -pc_use_amat true,false - see PCSetUseAmat() 128 129 Level: developer 130 131 .seealso: `PCSetUseAmat()` 132 133 @*/ 134 PetscErrorCode PCSetFromOptions(PC pc) 135 { 136 char type[256]; 137 const char *def; 138 PetscBool flg; 139 140 PetscFunctionBegin; 141 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 142 143 PetscCall(PCRegisterAll()); 144 PetscObjectOptionsBegin((PetscObject)pc); 145 if (!((PetscObject)pc)->type_name) { 146 PetscCall(PCGetDefaultType_Private(pc,&def)); 147 } else { 148 def = ((PetscObject)pc)->type_name; 149 } 150 151 PetscCall(PetscOptionsFList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg)); 152 if (flg) { 153 PetscCall(PCSetType(pc,type)); 154 } else if (!((PetscObject)pc)->type_name) { 155 PetscCall(PCSetType(pc,def)); 156 } 157 158 PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&flg)); 159 if (flg) goto skipoptions; 160 161 PetscCall(PetscOptionsBool("-pc_use_amat","use Amat (instead of Pmat) to define preconditioner in nested inner solves","PCSetUseAmat",pc->useAmat,&pc->useAmat,NULL)); 162 163 if (pc->ops->setfromoptions) { 164 PetscCall((*pc->ops->setfromoptions)(PetscOptionsObject,pc)); 165 } 166 167 skipoptions: 168 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 169 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc)); 170 PetscOptionsEnd(); 171 pc->setfromoptionscalled++; 172 PetscFunctionReturn(0); 173 } 174 175 /*@ 176 PCSetDM - Sets the DM that may be used by some preconditioners 177 178 Logically Collective on PC 179 180 Input Parameters: 181 + pc - the preconditioner context 182 - dm - the dm, can be NULL 183 184 Level: intermediate 185 186 Developer Notes: 187 The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is 188 replace the current DM 189 190 .seealso: `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()` 191 @*/ 192 PetscErrorCode PCSetDM(PC pc,DM dm) 193 { 194 PetscFunctionBegin; 195 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 196 if (dm) PetscCall(PetscObjectReference((PetscObject)dm)); 197 PetscCall(DMDestroy(&pc->dm)); 198 pc->dm = dm; 199 PetscFunctionReturn(0); 200 } 201 202 /*@ 203 PCGetDM - Gets the DM that may be used by some preconditioners 204 205 Not Collective 206 207 Input Parameter: 208 . pc - the preconditioner context 209 210 Output Parameter: 211 . dm - the dm 212 213 Level: intermediate 214 215 .seealso: `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()` 216 @*/ 217 PetscErrorCode PCGetDM(PC pc,DM *dm) 218 { 219 PetscFunctionBegin; 220 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 221 *dm = pc->dm; 222 PetscFunctionReturn(0); 223 } 224 225 /*@ 226 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 227 228 Logically Collective on PC 229 230 Input Parameters: 231 + pc - the PC context 232 - usrP - optional user context 233 234 Level: intermediate 235 236 .seealso: `PCGetApplicationContext()` 237 @*/ 238 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 239 { 240 PetscFunctionBegin; 241 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 242 pc->user = usrP; 243 PetscFunctionReturn(0); 244 } 245 246 /*@ 247 PCGetApplicationContext - Gets the user-defined context for the linear solver. 248 249 Not Collective 250 251 Input Parameter: 252 . pc - PC context 253 254 Output Parameter: 255 . usrP - user context 256 257 Level: intermediate 258 259 .seealso: `PCSetApplicationContext()` 260 @*/ 261 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 262 { 263 PetscFunctionBegin; 264 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 265 *(void**)usrP = pc->user; 266 PetscFunctionReturn(0); 267 } 268