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 /*@C 16 PCSetType - Builds PC for a particular preconditioner type 17 18 Collective on PC 19 20 Input Parameter: 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 PetscErrorCode ierr,(*r)(PC); 57 PetscBool match; 58 59 PetscFunctionBegin; 60 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 61 PetscValidCharPointer(type,2); 62 63 ierr = PetscObjectTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr); 64 if (match) PetscFunctionReturn(0); 65 66 ierr = PetscFunctionListFind(PCList,type,&r);CHKERRQ(ierr); 67 if (!r) SETERRQ1(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 ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr); 71 pc->ops->destroy = NULL; 72 pc->data = 0; 73 } 74 ierr = PetscFunctionListDestroy(&((PetscObject)pc)->qlist);CHKERRQ(ierr); 75 /* Reinitialize function pointers in PCOps structure */ 76 ierr = PetscMemzero(pc->ops,sizeof(struct _PCOps));CHKERRQ(ierr); 77 /* XXX Is this OK?? */ 78 pc->modifysubmatrices = 0; 79 pc->modifysubmatricesP = 0; 80 /* Call the PCCreate_XXX routine for this particular preconditioner */ 81 pc->setupcalled = 0; 82 83 ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr); 84 ierr = (*r)(pc);CHKERRQ(ierr); 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 ierr = PCRegisterAll();CHKERRQ(ierr); 145 ierr = PetscObjectOptionsBegin((PetscObject)pc);CHKERRQ(ierr); 146 if (!((PetscObject)pc)->type_name) { 147 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 148 } else { 149 def = ((PetscObject)pc)->type_name; 150 } 151 152 ierr = PetscOptionsFList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 153 if (flg) { 154 ierr = PCSetType(pc,type);CHKERRQ(ierr); 155 } else if (!((PetscObject)pc)->type_name) { 156 ierr = PCSetType(pc,def);CHKERRQ(ierr); 157 } 158 159 ierr = PetscObjectTypeCompare((PetscObject)pc,PCNONE,&flg);CHKERRQ(ierr); 160 if (flg) goto skipoptions; 161 162 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); 163 164 if (pc->ops->setfromoptions) { 165 ierr = (*pc->ops->setfromoptions)(PetscOptionsObject,pc);CHKERRQ(ierr); 166 } 167 168 skipoptions: 169 /* process any options handlers added with PetscObjectAddOptionsHandler() */ 170 ierr = PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)pc);CHKERRQ(ierr); 171 ierr = PetscOptionsEnd();CHKERRQ(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 PetscErrorCode ierr; 196 197 PetscFunctionBegin; 198 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 199 if (dm) {ierr = PetscObjectReference((PetscObject)dm);CHKERRQ(ierr);} 200 ierr = DMDestroy(&pc->dm);CHKERRQ(ierr); 201 pc->dm = dm; 202 PetscFunctionReturn(0); 203 } 204 205 /*@ 206 PCGetDM - Gets the DM that may be used by some preconditioners 207 208 Not Collective 209 210 Input Parameter: 211 . pc - the preconditioner context 212 213 Output Parameter: 214 . dm - the dm 215 216 Level: intermediate 217 218 219 .seealso: PCSetDM(), KSPSetDM(), KSPGetDM() 220 @*/ 221 PetscErrorCode PCGetDM(PC pc,DM *dm) 222 { 223 PetscFunctionBegin; 224 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 225 *dm = pc->dm; 226 PetscFunctionReturn(0); 227 } 228 229 /*@ 230 PCSetApplicationContext - Sets the optional user-defined context for the linear solver. 231 232 Logically Collective on PC 233 234 Input Parameters: 235 + pc - the PC context 236 - usrP - optional user context 237 238 Level: intermediate 239 240 .seealso: PCGetApplicationContext() 241 @*/ 242 PetscErrorCode PCSetApplicationContext(PC pc,void *usrP) 243 { 244 PetscFunctionBegin; 245 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 246 pc->user = usrP; 247 PetscFunctionReturn(0); 248 } 249 250 /*@ 251 PCGetApplicationContext - Gets the user-defined context for the linear solver. 252 253 Not Collective 254 255 Input Parameter: 256 . pc - PC context 257 258 Output Parameter: 259 . usrP - user context 260 261 Level: intermediate 262 263 .seealso: PCSetApplicationContext() 264 @*/ 265 PetscErrorCode PCGetApplicationContext(PC pc,void *usrP) 266 { 267 PetscFunctionBegin; 268 PetscValidHeaderSpecific(pc,PC_CLASSID,1); 269 *(void**)usrP = pc->user; 270 PetscFunctionReturn(0); 271 } 272 273