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) PetscCall((*pc->ops->setfromoptions)(PetscOptionsObject,pc)); 164 165 skipoptions: 166 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 167 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc)); 168 PetscOptionsEnd(); 169 pc->setfromoptionscalled++; 170 PetscFunctionReturn(0); 171 } 172 173 /*@ 174 PCSetDM - Sets the DM that may be used by some preconditioners 175 176 Logically Collective on PC 177 178 Input Parameters: 179 + pc - the preconditioner context 180 - dm - the dm, can be NULL 181 182 Level: intermediate 183 184 Developer Notes: 185 The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is 186 replace the current DM 187 188 .seealso: `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()` 189 @*/ 190 PetscErrorCode PCSetDM(PC pc,DM dm) 191 { 192 PetscFunctionBegin; 193 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 194 if (dm) PetscCall(PetscObjectReference((PetscObject)dm)); 195 PetscCall(DMDestroy(&pc->dm)); 196 pc->dm = dm; 197 PetscFunctionReturn(0); 198 } 199 200 /*@ 201 PCGetDM - Gets the DM that may be used by some preconditioners 202 203 Not Collective 204 205 Input Parameter: 206 . pc - the preconditioner context 207 208 Output Parameter: 209 . dm - the dm 210 211 Level: intermediate 212 213 .seealso: `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()` 214 @*/ 215 PetscErrorCode PCGetDM(PC pc,DM *dm) 216 { 217 PetscFunctionBegin; 218 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 219 *dm = pc->dm; 220 PetscFunctionReturn(0); 221 } 222 223 /*@ 224 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 225 226 Logically Collective on PC 227 228 Input Parameters: 229 + pc - the PC context 230 - usrP - optional user context 231 232 Level: intermediate 233 234 .seealso: `PCGetApplicationContext()` 235 @*/ 236 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 237 { 238 PetscFunctionBegin; 239 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 240 pc->user = usrP; 241 PetscFunctionReturn(0); 242 } 243 244 /*@ 245 PCGetApplicationContext - Gets the user-defined context for the linear solver. 246 247 Not Collective 248 249 Input Parameter: 250 . pc - PC context 251 252 Output Parameter: 253 . usrP - user context 254 255 Level: intermediate 256 257 .seealso: `PCSetApplicationContext()` 258 @*/ 259 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 260 { 261 PetscFunctionBegin; 262 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 263 *(void**)usrP = pc->user; 264 PetscFunctionReturn(0); 265 } 266