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