1 /* 2 Routines to set PC methods and options. 3 */ 4 5 #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 6 #include "petscsys.h" 7 8 PetscTruth PCRegisterAllCalled = PETSC_FALSE; 9 /* 10 Contains the list of registered KSP routines 11 */ 12 PetscFList PCList = 0; 13 14 #undef __FUNCT__ 15 #define __FUNCT__ "PCSetType" 16 /*@C 17 PCSetType - Builds PC for a particular preconditioner. 18 19 Collective on PC 20 21 Input Parameter: 22 + pc - the preconditioner context. 23 - type - a known method 24 25 Options Database Key: 26 . -pc_type <type> - Sets PC type 27 28 Use -help for a list of available methods (for instance, 29 jacobi or bjacobi) 30 31 Notes: 32 See "petsc/include/petscpc.h" for available methods (for instance, 33 PCJACOBI, PCILU, or PCBJACOBI). 34 35 Normally, it is best to use the KSPSetFromOptions() command and 36 then set the PC type from the options database rather than by using 37 this routine. Using the options database provides the user with 38 maximum flexibility in evaluating the many different preconditioners. 39 The PCSetType() routine is provided for those situations where it 40 is necessary to set the preconditioner independently of the command 41 line or options database. This might be the case, for example, when 42 the choice of preconditioner changes during the execution of the 43 program, and the user's application is taking responsibility for 44 choosing the appropriate preconditioner. In other words, this 45 routine is not for beginners. 46 47 Level: intermediate 48 49 .keywords: PC, set, method, type 50 51 .seealso: KSPSetType(), PCType 52 53 @*/ 54 PetscErrorCode PCSetType(PC pc,const PCType type) 55 { 56 PetscErrorCode ierr,(*r)(PC); 57 PetscTruth match; 58 59 PetscFunctionBegin; 60 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 61 PetscValidCharPointer(type,2); 62 63 ierr = PetscTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr); 64 if (match) PetscFunctionReturn(0); 65 66 if (pc->ops->destroy) {ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr);} 67 ierr = PetscFListDestroy(&pc->qlist);CHKERRQ(ierr); 68 pc->data = 0; 69 pc->setupcalled = 0; 70 71 /* Get the function pointers for the method requested */ 72 if (!PCRegisterAllCalled) {ierr = PCRegisterAll(0);CHKERRQ(ierr);} 73 74 /* Determine the PCCreateXXX routine for a particular preconditioner */ 75 ierr = PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);CHKERRQ(ierr); 76 if (!r) SETERRQ1(PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested PC type %s",type); 77 if (pc->data) {ierr = PetscFree(pc->data);CHKERRQ(ierr);} 78 79 pc->ops->setup = (PetscErrorCode (*)(PC)) 0; 80 pc->ops->apply = (PetscErrorCode (*)(PC,Vec,Vec)) 0; 81 pc->ops->applyrichardson = (PetscErrorCode (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0; 82 pc->ops->applyBA = (PetscErrorCode (*)(PC,int,Vec,Vec,Vec)) 0; 83 pc->ops->applytranspose = (PetscErrorCode (*)(PC,Vec,Vec)) 0; 84 pc->ops->applyBAtranspose = (PetscErrorCode (*)(PC,int,Vec,Vec,Vec)) 0; 85 pc->ops->setfromoptions = (PetscErrorCode (*)(PC)) 0; 86 pc->ops->presolve = (PetscErrorCode (*)(PC,KSP,Vec,Vec)) 0; 87 pc->ops->postsolve = (PetscErrorCode (*)(PC,KSP,Vec,Vec)) 0; 88 pc->ops->getfactoredmatrix = (PetscErrorCode (*)(PC,Mat*)) 0; 89 pc->ops->applysymmetricleft = (PetscErrorCode (*)(PC,Vec,Vec)) 0; 90 pc->ops->applysymmetricright = (PetscErrorCode (*)(PC,Vec,Vec)) 0; 91 pc->ops->setuponblocks = (PetscErrorCode (*)(PC)) 0; 92 pc->ops->destroy = (PetscErrorCode (*)(PC)) 0; 93 pc->ops->view = (PetscErrorCode (*)(PC,PetscViewer)) 0; 94 pc->modifysubmatrices = (PetscErrorCode (*)(PC,int,const IS[],const IS[],Mat[],void*)) 0; 95 96 /* Call the PCCreateXXX routine for this particular preconditioner */ 97 ierr = (*r)(pc);CHKERRQ(ierr); 98 99 ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr); 100 PetscFunctionReturn(0); 101 } 102 103 #undef __FUNCT__ 104 #define __FUNCT__ "PCRegisterDestroy" 105 /*@C 106 PCRegisterDestroy - Frees the list of preconditioners that were 107 registered by PCRegisterDynamic(). 108 109 Not Collective 110 111 Level: advanced 112 113 .keywords: PC, register, destroy 114 115 .seealso: PCRegisterAll(), PCRegisterAll() 116 117 @*/ 118 PetscErrorCode PCRegisterDestroy(void) 119 { 120 PetscErrorCode ierr; 121 122 PetscFunctionBegin; 123 if (PCList) { 124 ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr); 125 PCList = 0; 126 } 127 PCRegisterAllCalled = PETSC_FALSE; 128 PetscFunctionReturn(0); 129 } 130 131 #undef __FUNCT__ 132 #define __FUNCT__ "PCGetType" 133 /*@C 134 PCGetType - Gets the PC method type and name (as a string) from the PC 135 context. 136 137 Not Collective 138 139 Input Parameter: 140 . pc - the preconditioner context 141 142 Output Parameter: 143 . name - name of preconditioner 144 145 Level: intermediate 146 147 .keywords: PC, get, method, name, type 148 149 .seealso: PCSetType() 150 151 @*/ 152 PetscErrorCode PCGetType(PC pc,PCType *meth) 153 { 154 PetscFunctionBegin; 155 *meth = (PCType) pc->type_name; 156 PetscFunctionReturn(0); 157 } 158 159 EXTERN PetscErrorCode PCGetDefaultType_Private(PC,const char*[]); 160 161 #undef __FUNCT__ 162 #define __FUNCT__ "PCSetFromOptions" 163 /*@ 164 PCSetFromOptions - Sets PC options from the options database. 165 This routine must be called before PCSetUp() if the user is to be 166 allowed to set the preconditioner method. 167 168 Collective on PC 169 170 Input Parameter: 171 . pc - the preconditioner context 172 173 Level: developer 174 175 .keywords: PC, set, from, options, database 176 177 .seealso: 178 179 @*/ 180 PetscErrorCode PCSetFromOptions(PC pc) 181 { 182 PetscErrorCode ierr; 183 char type[256]; 184 const char *def; 185 PetscTruth flg; 186 187 PetscFunctionBegin; 188 PetscValidHeaderSpecific(pc,PC_COOKIE,1); 189 190 if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 191 ierr = PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr); 192 if (!pc->type_name) { 193 ierr = PCGetDefaultType_Private(pc,&def);CHKERRQ(ierr); 194 } else { 195 def = pc->type_name; 196 } 197 198 ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 199 if (flg) { 200 ierr = PCSetType(pc,type);CHKERRQ(ierr); 201 } else if (!pc->type_name){ 202 ierr = PCSetType(pc,def);CHKERRQ(ierr); 203 } 204 205 if (pc->ops->setfromoptions) { 206 ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr); 207 } 208 ierr = PetscOptionsEnd();CHKERRQ(ierr); 209 #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE) 210 ierr = PCESISetFromOptions(pc);CHKERRQ(ierr); 211 #endif 212 PetscFunctionReturn(0); 213 } 214