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