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 KSP routines 12 */ 13 PetscFunctionList PCList = 0; 14 15 #undef __FUNCT__ 16 #define __FUNCT__ "PCSetType" 17 /*@C 18 PCSetType - Builds PC for a particular preconditioner type 19 20 Collective on PC 21 22 Input Parameter: 23 + pc - the preconditioner context. 24 - type - a known method 25 26 Options Database Key: 27 . -pc_type <type> - Sets PC type 28 29 Use -help for a list of available methods (for instance, 30 jacobi or bjacobi) 31 32 Notes: 33 See "petsc/include/petscpc.h" for available methods (for instance, 34 PCJACOBI, PCILU, or PCBJACOBI). 35 36 Normally, it is best to use the KSPSetFromOptions() command and 37 then set the PC type from the options database rather than by using 38 this routine. Using the options database provides the user with 39 maximum flexibility in evaluating the many different preconditioners. 40 The PCSetType() routine is provided for those situations where it 41 is necessary to set the preconditioner independently of the command 42 line or options database. This might be the case, for example, when 43 the choice of preconditioner changes during the execution of the 44 program, and the user's application is taking responsibility for 45 choosing the appropriate preconditioner. In other words, this 46 routine is not for beginners. 47 48 Level: intermediate 49 50 Developer Note: PCRegister() is used to add preconditioner types to PCList from which they 51 are accessed by PCSetType(). 52 53 .keywords: PC, set, method, type 54 55 .seealso: KSPSetType(), PCType, PCRegister(), PCCreate(), KSPGetPC() 56 57 @*/ 58 PetscErrorCode PCSetType(PC pc,PCType type) 59 { 60 PetscErrorCode ierr,(*r)(PC); 61 PetscBool match; 62 63 PetscFunctionBegin; 64 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 65 PetscValidCharPointer(type,2); 66 67 ierr = PetscObjectTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr); 68 if (match) PetscFunctionReturn(0); 69 70 ierr = PetscFunctionListFind(PCList,type,&r);CHKERRQ(ierr); 71 if (!r) SETERRQ1(PetscObjectComm((PetscObject)pc),PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type); 72 /* Destroy the previous private PC context */ 73 if (pc->ops->destroy) { 74 ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr); 75 pc->ops->destroy = NULL; 76 pc->data = 0; 77 } 78 ierr = PetscFunctionListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr); 79 /* Reinitialize function pointers in PCOps structure */ 80 ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr); 81 /* XXX Is this OK?? */ 82 pc->modifysubmatrices = 0; 83 pc->modifysubmatricesP = 0; 84 /* Call the PCCreate_XXX routine for this particular preconditioner */ 85 pc->setupcalled = 0; 86 87 ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr); 88 ierr = (*r)(pc);CHKERRQ(ierr); 89 PetscFunctionReturn(0); 90 } 91 92 #undef __FUNCT__ 93 #define __FUNCT__ "PCGetType" 94 /*@C 95 PCGetType - Gets the PC method type and name (as a string) from the PC 96 context. 97 98 Not Collective 99 100 Input Parameter: 101 . pc - the preconditioner context 102 103 Output Parameter: 104 . type - name of preconditioner method 105 106 Level: intermediate 107 108 .keywords: PC, get, method, name, type 109 110 .seealso: PCSetType() 111 112 @*/ 113 PetscErrorCode PCGetType(PC pc,PCType *type) 114 { 115 PetscFunctionBegin; 116 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 117 PetscValidPointer(type,2); 118 *type = ((PetscObject)pc)->type_name; 119 PetscFunctionReturn(0); 120 } 121 122 extern PetscErrorCode PCGetDefaultType_Private(PC,const char*[]); 123 124 #undef __FUNCT__ 125 #define __FUNCT__ "PCSetFromOptions" 126 /*@ 127 PCSetFromOptions - Sets PC options from the options database. 128 This routine must be called before PCSetUp() if the user is to be 129 allowed to set the preconditioner method. 130 131 Collective on PC 132 133 Input Parameter: 134 . pc - the preconditioner context 135 136 Options Database: 137 . -pc_use_amat true,false see PCSetUseAmat() 138 139 Level: developer 140 141 .keywords: PC, set, from, options, database 142 143 .seealso: PCSetUseAmat() 144 145 @*/ 146 PetscErrorCode PCSetFromOptions(PC pc) 147 { 148 PetscErrorCode ierr; 149 char type[256]; 150 const char *def; 151 PetscBool flg; 152 153 PetscFunctionBegin; 154 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 155 156 ierr = PCRegisterAll();CHKERRQ(ierr); 157 ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr); 158 if (!((PetscObject)pc)->type_name) { 159 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 160 } else { 161 def = ((PetscObject)pc)->type_name; 162 } 163 164 ierr = PetscOptionsFList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 165 if (flg) { 166 ierr = PCSetType(pc,type);CHKERRQ(ierr); 167 } else if (!((PetscObject)pc)->type_name) { 168 ierr = PCSetType(pc,def);CHKERRQ(ierr); 169 } 170 171 ierr = PetscObjectTypeCompare((PetscObject)pc,PCNONE,&flg);CHKERRQ(ierr); 172 if (flg) goto skipoptions; 173 174 ierr = PetscOptionsBool("-pc_use_amat","use Amat (instead of Pmat) to define preconditioner in nested inner solves","PCSetUseAmat",pc->useAmat,&pc->useAmat,NULL);CHKERRQ(ierr); 175 176 if (pc->ops->setfromoptions) { 177 ierr = (*pc->ops->setfromoptions)(PetscOptionsObject,pc);CHKERRQ(ierr); 178 } 179 180 skipoptions: 181 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 182 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc);CHKERRQ(ierr); 183 ierr = PetscOptionsEnd();CHKERRQ(ierr); 184 pc->setfromoptionscalled++; 185 PetscFunctionReturn(0); 186 } 187 188 #undef __FUNCT__ 189 #define __FUNCT__ "PCSetDM" 190 /*@ 191 PCSetDM - Sets the DM that may be used by some preconditioners 192 193 Logically Collective on PC 194 195 Input Parameters: 196 + pc - the preconditioner context 197 - dm - the dm, can be NULL 198 199 Level: intermediate 200 201 Developer Notes: The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is 202 replace the current DM 203 204 .seealso: PCGetDM(), KSPSetDM(), KSPGetDM() 205 @*/ 206 PetscErrorCode PCSetDM(PC pc,DM dm) 207 { 208 PetscErrorCode ierr; 209 210 PetscFunctionBegin; 211 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 212 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 213 ierr = DMDestroy(&pc->dm);CHKERRQ(ierr); 214 pc->dm = dm; 215 PetscFunctionReturn(0); 216 } 217 218 #undef __FUNCT__ 219 #define __FUNCT__ "PCGetDM" 220 /*@ 221 PCGetDM - Gets the DM that may be used by some preconditioners 222 223 Not Collective 224 225 Input Parameter: 226 . pc - the preconditioner context 227 228 Output Parameter: 229 . dm - the dm 230 231 Level: intermediate 232 233 234 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 235 @*/ 236 PetscErrorCode PCGetDM(PC pc,DM *dm) 237 { 238 PetscFunctionBegin; 239 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 240 *dm = pc->dm; 241 PetscFunctionReturn(0); 242 } 243 244 #undef __FUNCT__ 245 #define __FUNCT__ "PCSetApplicationContext" 246 /*@ 247 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 248 249 Logically Collective on PC 250 251 Input Parameters: 252 + pc - the PC context 253 - usrP - optional user context 254 255 Level: intermediate 256 257 .keywords: PC, set, application, context 258 259 .seealso: PCGetApplicationContext() 260 @*/ 261 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 262 { 263 PetscFunctionBegin; 264 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 265 pc->user = usrP; 266 PetscFunctionReturn(0); 267 } 268 269 #undef __FUNCT__ 270 #define __FUNCT__ "PCGetApplicationContext" 271 /*@ 272 PCGetApplicationContext - Gets the user-defined context for the linear solver. 273 274 Not Collective 275 276 Input Parameter: 277 . pc - PC context 278 279 Output Parameter: 280 . usrP - user context 281 282 Level: intermediate 283 284 .keywords: PC, get, application, context 285 286 .seealso: PCSetApplicationContext() 287 @*/ 288 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 289 { 290 PetscFunctionBegin; 291 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 292 *(void**)usrP = pc->user; 293 PetscFunctionReturn(0); 294 } 295 296