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 PetscErrorCode ierr; 137 char type[256]; 138 const char *def; 139 PetscBool flg; 140 141 PetscFunctionBegin; 142 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 143 144 PetscCall(PCRegisterAll()); 145 ierr = PetscObjectOptionsBegin((PetscObject)pc);PetscCall(ierr); 146 if (!((PetscObject)pc)->type_name) { 147 PetscCall(PCGetDefaultType_Private(pc,&def)); 148 } else { 149 def = ((PetscObject)pc)->type_name; 150 } 151 152 PetscCall(PetscOptionsFList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg)); 153 if (flg) { 154 PetscCall(PCSetType(pc,type)); 155 } else if (!((PetscObject)pc)->type_name) { 156 PetscCall(PCSetType(pc,def)); 157 } 158 159 PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&flg)); 160 if (flg) goto skipoptions; 161 162 PetscCall(PetscOptionsBool("-pc_use_amat","use Amat (instead of Pmat) to define preconditioner in nested inner solves","PCSetUseAmat",pc->useAmat,&pc->useAmat,NULL)); 163 164 if (pc->ops->setfromoptions) { 165 PetscCall((*pc->ops->setfromoptions)(PetscOptionsObject,pc)); 166 } 167 168 skipoptions: 169 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 170 PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc)); 171 ierr = PetscOptionsEnd();PetscCall(ierr); 172 pc->setfromoptionscalled++; 173 PetscFunctionReturn(0); 174 } 175 176 /*@ 177 PCSetDM - Sets the DM that may be used by some preconditioners 178 179 Logically Collective on PC 180 181 Input Parameters: 182 + pc - the preconditioner context 183 - dm - the dm, can be NULL 184 185 Level: intermediate 186 187 Developer Notes: 188 The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is 189 replace the current DM 190 191 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM() 192 @*/ 193 PetscErrorCode PCSetDM(PC pc,DM dm) 194 { 195 PetscFunctionBegin; 196 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 197 if (dm) PetscCall(PetscObjectReference((PetscObject)dm)); 198 PetscCall(DMDestroy(&pc->dm)); 199 pc->dm = dm; 200 PetscFunctionReturn(0); 201 } 202 203 /*@ 204 PCGetDM - Gets the DM that may be used by some preconditioners 205 206 Not Collective 207 208 Input Parameter: 209 . pc - the preconditioner context 210 211 Output Parameter: 212 . dm - the dm 213 214 Level: intermediate 215 216 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 217 @*/ 218 PetscErrorCode PCGetDM(PC pc,DM *dm) 219 { 220 PetscFunctionBegin; 221 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 222 *dm = pc->dm; 223 PetscFunctionReturn(0); 224 } 225 226 /*@ 227 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 228 229 Logically Collective on PC 230 231 Input Parameters: 232 + pc - the PC context 233 - usrP - optional user context 234 235 Level: intermediate 236 237 .seealso: PCGetApplicationContext() 238 @*/ 239 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 240 { 241 PetscFunctionBegin; 242 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 243 pc->user = usrP; 244 PetscFunctionReturn(0); 245 } 246 247 /*@ 248 PCGetApplicationContext - Gets the user-defined context for the linear solver. 249 250 Not Collective 251 252 Input Parameter: 253 . pc - PC context 254 255 Output Parameter: 256 . usrP - user context 257 258 Level: intermediate 259 260 .seealso: PCSetApplicationContext() 261 @*/ 262 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 263 { 264 PetscFunctionBegin; 265 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 266 *(void**)usrP = pc->user; 267 PetscFunctionReturn(0); 268 } 269