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