1*4b9ad928SBarry Smith /*$Id: pcset.c,v 1.118 2001/08/21 21:03:13 bsmith Exp $*/ 2*4b9ad928SBarry Smith /* 3*4b9ad928SBarry Smith Routines to set PC methods and options. 4*4b9ad928SBarry Smith */ 5*4b9ad928SBarry Smith 6*4b9ad928SBarry Smith #include "src/ksp/pc/pcimpl.h" /*I "petscpc.h" I*/ 7*4b9ad928SBarry Smith #include "petscsys.h" 8*4b9ad928SBarry Smith 9*4b9ad928SBarry Smith PetscTruth PCRegisterAllCalled = PETSC_FALSE; 10*4b9ad928SBarry Smith /* 11*4b9ad928SBarry Smith Contains the list of registered KSP routines 12*4b9ad928SBarry Smith */ 13*4b9ad928SBarry Smith PetscFList PCList = 0; 14*4b9ad928SBarry Smith 15*4b9ad928SBarry Smith #undef __FUNCT__ 16*4b9ad928SBarry Smith #define __FUNCT__ "PCSetType" 17*4b9ad928SBarry Smith /*@C 18*4b9ad928SBarry Smith PCSetType - Builds PC for a particular preconditioner. 19*4b9ad928SBarry Smith 20*4b9ad928SBarry Smith Collective on PC 21*4b9ad928SBarry Smith 22*4b9ad928SBarry Smith Input Parameter: 23*4b9ad928SBarry Smith + pc - the preconditioner context. 24*4b9ad928SBarry Smith - type - a known method 25*4b9ad928SBarry Smith 26*4b9ad928SBarry Smith Options Database Key: 27*4b9ad928SBarry Smith . -pc_type <type> - Sets PC type 28*4b9ad928SBarry Smith 29*4b9ad928SBarry Smith Use -help for a list of available methods (for instance, 30*4b9ad928SBarry Smith jacobi or bjacobi) 31*4b9ad928SBarry Smith 32*4b9ad928SBarry Smith Notes: 33*4b9ad928SBarry Smith See "petsc/include/petscpc.h" for available methods (for instance, 34*4b9ad928SBarry Smith PCJACOBI, PCILU, or PCBJACOBI). 35*4b9ad928SBarry Smith 36*4b9ad928SBarry Smith Normally, it is best to use the KSPSetFromOptions() command and 37*4b9ad928SBarry Smith then set the PC type from the options database rather than by using 38*4b9ad928SBarry Smith this routine. Using the options database provides the user with 39*4b9ad928SBarry Smith maximum flexibility in evaluating the many different preconditioners. 40*4b9ad928SBarry Smith The PCSetType() routine is provided for those situations where it 41*4b9ad928SBarry Smith is necessary to set the preconditioner independently of the command 42*4b9ad928SBarry Smith line or options database. This might be the case, for example, when 43*4b9ad928SBarry Smith the choice of preconditioner changes during the execution of the 44*4b9ad928SBarry Smith program, and the user's application is taking responsibility for 45*4b9ad928SBarry Smith choosing the appropriate preconditioner. In other words, this 46*4b9ad928SBarry Smith routine is not for beginners. 47*4b9ad928SBarry Smith 48*4b9ad928SBarry Smith Level: intermediate 49*4b9ad928SBarry Smith 50*4b9ad928SBarry Smith .keywords: PC, set, method, type 51*4b9ad928SBarry Smith 52*4b9ad928SBarry Smith .seealso: KSPSetType(), PCType 53*4b9ad928SBarry Smith 54*4b9ad928SBarry Smith @*/ 55*4b9ad928SBarry Smith int PCSetType(PC pc,PCType type) 56*4b9ad928SBarry Smith { 57*4b9ad928SBarry Smith int ierr,(*r)(PC); 58*4b9ad928SBarry Smith PetscTruth match; 59*4b9ad928SBarry Smith 60*4b9ad928SBarry Smith PetscFunctionBegin; 61*4b9ad928SBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE); 62*4b9ad928SBarry Smith PetscValidCharPointer(type); 63*4b9ad928SBarry Smith 64*4b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)pc,type,&match);CHKERRQ(ierr); 65*4b9ad928SBarry Smith if (match) PetscFunctionReturn(0); 66*4b9ad928SBarry Smith 67*4b9ad928SBarry Smith if (pc->ops->destroy) {ierr = (*pc->ops->destroy)(pc);CHKERRQ(ierr);} 68*4b9ad928SBarry Smith ierr = PetscFListDestroy(&pc->qlist);CHKERRQ(ierr); 69*4b9ad928SBarry Smith pc->data = 0; 70*4b9ad928SBarry Smith pc->setupcalled = 0; 71*4b9ad928SBarry Smith 72*4b9ad928SBarry Smith /* Get the function pointers for the method requested */ 73*4b9ad928SBarry Smith if (!PCRegisterAllCalled) {ierr = PCRegisterAll(0);CHKERRQ(ierr);} 74*4b9ad928SBarry Smith 75*4b9ad928SBarry Smith /* Determine the PCCreateXXX routine for a particular preconditioner */ 76*4b9ad928SBarry Smith ierr = PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);CHKERRQ(ierr); 77*4b9ad928SBarry Smith if (!r) SETERRQ1(1,"Unable to find requested PC type %s",type); 78*4b9ad928SBarry Smith if (pc->data) {ierr = PetscFree(pc->data);CHKERRQ(ierr);} 79*4b9ad928SBarry Smith 80*4b9ad928SBarry Smith pc->ops->destroy = (int (*)(PC)) 0; 81*4b9ad928SBarry Smith pc->ops->view = (int (*)(PC,PetscViewer)) 0; 82*4b9ad928SBarry Smith pc->ops->apply = (int (*)(PC,Vec,Vec)) 0; 83*4b9ad928SBarry Smith pc->ops->setup = (int (*)(PC)) 0; 84*4b9ad928SBarry Smith pc->ops->applyrichardson = (int (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0; 85*4b9ad928SBarry Smith pc->ops->applyBA = (int (*)(PC,int,Vec,Vec,Vec)) 0; 86*4b9ad928SBarry Smith pc->ops->setfromoptions = (int (*)(PC)) 0; 87*4b9ad928SBarry Smith pc->ops->applytranspose = (int (*)(PC,Vec,Vec)) 0; 88*4b9ad928SBarry Smith pc->ops->applyBAtranspose = (int (*)(PC,int,Vec,Vec,Vec)) 0; 89*4b9ad928SBarry Smith pc->ops->presolve = (int (*)(PC,KSP,Vec,Vec)) 0; 90*4b9ad928SBarry Smith pc->ops->postsolve = (int (*)(PC,KSP,Vec,Vec)) 0; 91*4b9ad928SBarry Smith pc->ops->getfactoredmatrix = (int (*)(PC,Mat*)) 0; 92*4b9ad928SBarry Smith pc->ops->applysymmetricleft = (int (*)(PC,Vec,Vec)) 0; 93*4b9ad928SBarry Smith pc->ops->applysymmetricright = (int (*)(PC,Vec,Vec)) 0; 94*4b9ad928SBarry Smith pc->ops->setuponblocks = (int (*)(PC)) 0; 95*4b9ad928SBarry Smith pc->modifysubmatrices = (int (*)(PC,int,const IS[],const IS[],Mat[],void*)) 0; 96*4b9ad928SBarry Smith 97*4b9ad928SBarry Smith /* Call the PCCreateXXX routine for this particular preconditioner */ 98*4b9ad928SBarry Smith ierr = (*r)(pc);CHKERRQ(ierr); 99*4b9ad928SBarry Smith 100*4b9ad928SBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)pc,type);CHKERRQ(ierr); 101*4b9ad928SBarry Smith PetscFunctionReturn(0); 102*4b9ad928SBarry Smith } 103*4b9ad928SBarry Smith 104*4b9ad928SBarry Smith #undef __FUNCT__ 105*4b9ad928SBarry Smith #define __FUNCT__ "PCRegisterDestroy" 106*4b9ad928SBarry Smith /*@C 107*4b9ad928SBarry Smith PCRegisterDestroy - Frees the list of preconditioners that were 108*4b9ad928SBarry Smith registered by PCRegisterDynamic(). 109*4b9ad928SBarry Smith 110*4b9ad928SBarry Smith Not Collective 111*4b9ad928SBarry Smith 112*4b9ad928SBarry Smith Level: advanced 113*4b9ad928SBarry Smith 114*4b9ad928SBarry Smith .keywords: PC, register, destroy 115*4b9ad928SBarry Smith 116*4b9ad928SBarry Smith .seealso: PCRegisterAll(), PCRegisterAll() 117*4b9ad928SBarry Smith 118*4b9ad928SBarry Smith @*/ 119*4b9ad928SBarry Smith int PCRegisterDestroy(void) 120*4b9ad928SBarry Smith { 121*4b9ad928SBarry Smith int ierr; 122*4b9ad928SBarry Smith 123*4b9ad928SBarry Smith PetscFunctionBegin; 124*4b9ad928SBarry Smith if (PCList) { 125*4b9ad928SBarry Smith ierr = PetscFListDestroy(&PCList);CHKERRQ(ierr); 126*4b9ad928SBarry Smith PCList = 0; 127*4b9ad928SBarry Smith } 128*4b9ad928SBarry Smith PCRegisterAllCalled = PETSC_FALSE; 129*4b9ad928SBarry Smith PetscFunctionReturn(0); 130*4b9ad928SBarry Smith } 131*4b9ad928SBarry Smith 132*4b9ad928SBarry Smith #undef __FUNCT__ 133*4b9ad928SBarry Smith #define __FUNCT__ "PCGetType" 134*4b9ad928SBarry Smith /*@C 135*4b9ad928SBarry Smith PCGetType - Gets the PC method type and name (as a string) from the PC 136*4b9ad928SBarry Smith context. 137*4b9ad928SBarry Smith 138*4b9ad928SBarry Smith Not Collective 139*4b9ad928SBarry Smith 140*4b9ad928SBarry Smith Input Parameter: 141*4b9ad928SBarry Smith . pc - the preconditioner context 142*4b9ad928SBarry Smith 143*4b9ad928SBarry Smith Output Parameter: 144*4b9ad928SBarry Smith . name - name of preconditioner 145*4b9ad928SBarry Smith 146*4b9ad928SBarry Smith Level: intermediate 147*4b9ad928SBarry Smith 148*4b9ad928SBarry Smith .keywords: PC, get, method, name, type 149*4b9ad928SBarry Smith 150*4b9ad928SBarry Smith .seealso: PCSetType() 151*4b9ad928SBarry Smith 152*4b9ad928SBarry Smith @*/ 153*4b9ad928SBarry Smith int PCGetType(PC pc,PCType *meth) 154*4b9ad928SBarry Smith { 155*4b9ad928SBarry Smith PetscFunctionBegin; 156*4b9ad928SBarry Smith *meth = (PCType) pc->type_name; 157*4b9ad928SBarry Smith PetscFunctionReturn(0); 158*4b9ad928SBarry Smith } 159*4b9ad928SBarry Smith 160*4b9ad928SBarry Smith #undef __FUNCT__ 161*4b9ad928SBarry Smith #define __FUNCT__ "PCSetFromOptions" 162*4b9ad928SBarry Smith /*@ 163*4b9ad928SBarry Smith PCSetFromOptions - Sets PC options from the options database. 164*4b9ad928SBarry Smith This routine must be called before PCSetUp() if the user is to be 165*4b9ad928SBarry Smith allowed to set the preconditioner method. 166*4b9ad928SBarry Smith 167*4b9ad928SBarry Smith Collective on PC 168*4b9ad928SBarry Smith 169*4b9ad928SBarry Smith Input Parameter: 170*4b9ad928SBarry Smith . pc - the preconditioner context 171*4b9ad928SBarry Smith 172*4b9ad928SBarry Smith Level: developer 173*4b9ad928SBarry Smith 174*4b9ad928SBarry Smith .keywords: PC, set, from, options, database 175*4b9ad928SBarry Smith 176*4b9ad928SBarry Smith .seealso: 177*4b9ad928SBarry Smith 178*4b9ad928SBarry Smith @*/ 179*4b9ad928SBarry Smith int PCSetFromOptions(PC pc) 180*4b9ad928SBarry Smith { 181*4b9ad928SBarry Smith int ierr; 182*4b9ad928SBarry Smith char type[256],*def; 183*4b9ad928SBarry Smith PetscTruth flg; 184*4b9ad928SBarry Smith 185*4b9ad928SBarry Smith PetscFunctionBegin; 186*4b9ad928SBarry Smith PetscValidHeaderSpecific(pc,PC_COOKIE); 187*4b9ad928SBarry Smith 188*4b9ad928SBarry Smith if (!PCRegisterAllCalled) {ierr = PCRegisterAll(PETSC_NULL);CHKERRQ(ierr);} 189*4b9ad928SBarry Smith ierr = PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");CHKERRQ(ierr); 190*4b9ad928SBarry Smith if (!pc->type_name) { 191*4b9ad928SBarry Smith PetscTruth ismatshell; 192*4b9ad928SBarry Smith int size; 193*4b9ad928SBarry Smith 194*4b9ad928SBarry Smith /* 195*4b9ad928SBarry Smith Shell matrix (probably) cannot support Bjacobi and ILU 196*4b9ad928SBarry Smith */ 197*4b9ad928SBarry Smith ierr = MPI_Comm_size(pc->comm,&size);CHKERRQ(ierr); 198*4b9ad928SBarry Smith if (pc->pmat) { 199*4b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);CHKERRQ(ierr); 200*4b9ad928SBarry Smith } else { 201*4b9ad928SBarry Smith ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */ 202*4b9ad928SBarry Smith } 203*4b9ad928SBarry Smith /* 204*4b9ad928SBarry Smith MATMFFD cannot support BJacobia and ILU 205*4b9ad928SBarry Smith */ 206*4b9ad928SBarry Smith if (!ismatshell) { 207*4b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);CHKERRQ(ierr); 208*4b9ad928SBarry Smith } 209*4b9ad928SBarry Smith 210*4b9ad928SBarry Smith if (ismatshell) { 211*4b9ad928SBarry Smith def = PCNONE; 212*4b9ad928SBarry Smith PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't support\n\ 213*4b9ad928SBarry Smith preconditioners (unless defined by the user)\n"); 214*4b9ad928SBarry Smith } else if (size == 1) { 215*4b9ad928SBarry Smith ierr = PetscTypeCompare((PetscObject)pc->pmat,MATSEQSBAIJ,&flg);CHKERRQ(ierr); 216*4b9ad928SBarry Smith if (flg) { 217*4b9ad928SBarry Smith def = PCICC; 218*4b9ad928SBarry Smith } else { 219*4b9ad928SBarry Smith def = PCILU; 220*4b9ad928SBarry Smith } 221*4b9ad928SBarry Smith } else { 222*4b9ad928SBarry Smith def = PCBJACOBI; 223*4b9ad928SBarry Smith } 224*4b9ad928SBarry Smith } else { 225*4b9ad928SBarry Smith def = pc->type_name; 226*4b9ad928SBarry Smith } 227*4b9ad928SBarry Smith 228*4b9ad928SBarry Smith ierr = PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);CHKERRQ(ierr); 229*4b9ad928SBarry Smith if (flg) { 230*4b9ad928SBarry Smith ierr = PCSetType(pc,type);CHKERRQ(ierr); 231*4b9ad928SBarry Smith } 232*4b9ad928SBarry Smith 233*4b9ad928SBarry Smith ierr = PetscOptionsName("-pc_constant_null_space","Add constant null space to preconditioner","PCNullSpaceAttach",&flg);CHKERRQ(ierr); 234*4b9ad928SBarry Smith if (flg) { 235*4b9ad928SBarry Smith MatNullSpace nsp; 236*4b9ad928SBarry Smith 237*4b9ad928SBarry Smith ierr = MatNullSpaceCreate(pc->comm,1,0,0,&nsp);CHKERRQ(ierr); 238*4b9ad928SBarry Smith ierr = PCNullSpaceAttach(pc,nsp);CHKERRQ(ierr); 239*4b9ad928SBarry Smith ierr = MatNullSpaceDestroy(nsp);CHKERRQ(ierr); 240*4b9ad928SBarry Smith } 241*4b9ad928SBarry Smith 242*4b9ad928SBarry Smith 243*4b9ad928SBarry Smith /* option is actually checked in PCSetUp() */ 244*4b9ad928SBarry Smith if (pc->nullsp) { 245*4b9ad928SBarry Smith ierr = PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);CHKERRQ(ierr); 246*4b9ad928SBarry Smith } 247*4b9ad928SBarry Smith 248*4b9ad928SBarry Smith /* 249*4b9ad928SBarry Smith Set the type if it was never set. 250*4b9ad928SBarry Smith */ 251*4b9ad928SBarry Smith if (!pc->type_name) { 252*4b9ad928SBarry Smith ierr = PCSetType(pc,def);CHKERRQ(ierr); 253*4b9ad928SBarry Smith } 254*4b9ad928SBarry Smith 255*4b9ad928SBarry Smith 256*4b9ad928SBarry Smith 257*4b9ad928SBarry Smith if (pc->ops->setfromoptions) { 258*4b9ad928SBarry Smith ierr = (*pc->ops->setfromoptions)(pc);CHKERRQ(ierr); 259*4b9ad928SBarry Smith } 260*4b9ad928SBarry Smith ierr = PetscOptionsEnd();CHKERRQ(ierr); 261*4b9ad928SBarry Smith #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE) 262*4b9ad928SBarry Smith ierr = PCESISetFromOptions(pc);CHKERRQ(ierr); 263*4b9ad928SBarry Smith #endif 264*4b9ad928SBarry Smith PetscFunctionReturn(0); 265*4b9ad928SBarry Smith } 266