Actual source code: pcset.c

  1: /*$Id: pcset.c,v 1.118 2001/08/21 21:03:13 bsmith Exp $*/
  2: /*
  3:     Routines to set PC methods and options.
  4: */

 6:  #include src/sles/pc/pcimpl.h
 7:  #include petscsys.h

  9: PetscTruth PCRegisterAllCalled = PETSC_FALSE;
 10: /*
 11:    Contains the list of registered KSP routines
 12: */
 13: PetscFList PCList = 0;

 15: /*@C
 16:    PCSetType - Builds PC for a particular preconditioner.

 18:    Collective on PC

 20:    Input Parameter:
 21: +  pc - the preconditioner context.
 22: -  type - a known method

 24:    Options Database Key:
 25: .  -pc_type <type> - Sets PC type

 27:    Use -help for a list of available methods (for instance,
 28:    jacobi or bjacobi)

 30:   Notes:
 31:   See "petsc/include/petscpc.h" for available methods (for instance,
 32:   PCJACOBI, PCILU, or PCBJACOBI).

 34:   Normally, it is best to use the SLESSetFromOptions() 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.

 46:   Level: intermediate

 48: .keywords: PC, set, method, type

 50: .seealso: KSPSetType(), PCType

 52: @*/
 53: int PCSetType(PC pc,PCType type)
 54: {
 55:   int        ierr,(*r)(PC);
 56:   PetscTruth match;


 62:   PetscTypeCompare((PetscObject)pc,type,&match);
 63:   if (match) return(0);

 65:   if (pc->ops->destroy) { (*pc->ops->destroy)(pc);}
 66:   PetscFListDestroy(&pc->qlist);
 67:   pc->data        = 0;
 68:   pc->setupcalled = 0;

 70:   /* Get the function pointers for the method requested */
 71:   if (!PCRegisterAllCalled) {PCRegisterAll(0);}

 73:   /* Determine the PCCreateXXX routine for a particular preconditioner */
 74:    PetscFListFind(pc->comm,PCList,type,(void (**)(void)) &r);
 75:   if (!r) SETERRQ1(1,"Unable to find requested PC type %s",type);
 76:   if (pc->data) {PetscFree(pc->data);}

 78:   pc->ops->destroy             = (int (*)(PC)) 0;
 79:   pc->ops->view                = (int (*)(PC,PetscViewer)) 0;
 80:   pc->ops->apply               = (int (*)(PC,Vec,Vec)) 0;
 81:   pc->ops->setup               = (int (*)(PC)) 0;
 82:   pc->ops->applyrichardson     = (int (*)(PC,Vec,Vec,Vec,PetscReal,PetscReal,PetscReal,int)) 0;
 83:   pc->ops->applyBA             = (int (*)(PC,int,Vec,Vec,Vec)) 0;
 84:   pc->ops->setfromoptions      = (int (*)(PC)) 0;
 85:   pc->ops->applytranspose      = (int (*)(PC,Vec,Vec)) 0;
 86:   pc->ops->applyBAtranspose    = (int (*)(PC,int,Vec,Vec,Vec)) 0;
 87:   pc->ops->presolve            = (int (*)(PC,KSP,Vec,Vec)) 0;
 88:   pc->ops->postsolve           = (int (*)(PC,KSP,Vec,Vec)) 0;
 89:   pc->ops->getfactoredmatrix   = (int (*)(PC,Mat*)) 0;
 90:   pc->ops->applysymmetricleft  = (int (*)(PC,Vec,Vec)) 0;
 91:   pc->ops->applysymmetricright = (int (*)(PC,Vec,Vec)) 0;
 92:   pc->ops->setuponblocks       = (int (*)(PC)) 0;
 93:   pc->modifysubmatrices   = (int (*)(PC,int,IS*,IS*,Mat*,void*)) 0;

 95:   /* Call the PCCreateXXX routine for this particular preconditioner */
 96:   (*r)(pc);

 98:   PetscObjectChangeTypeName((PetscObject)pc,type);
 99:   return(0);
100: }

102: /*@C
103:    PCRegisterDestroy - Frees the list of preconditioners that were
104:    registered by PCRegisterDynamic().

106:    Not Collective

108:    Level: advanced

110: .keywords: PC, register, destroy

112: .seealso: PCRegisterAll(), PCRegisterAll()

114: @*/
115: int PCRegisterDestroy(void)
116: {

120:   if (PCList) {
121:     PetscFListDestroy(&PCList);
122:     PCList = 0;
123:   }
124:   PCRegisterAllCalled = PETSC_FALSE;
125:   return(0);
126: }

128: /*@C
129:    PCGetType - Gets the PC method type and name (as a string) from the PC
130:    context.

132:    Not Collective

134:    Input Parameter:
135: .  pc - the preconditioner context

137:    Output Parameter:
138: .  name - name of preconditioner 

140:    Level: intermediate

142: .keywords: PC, get, method, name, type

144: .seealso: PCSetType()

146: @*/
147: int PCGetType(PC pc,PCType *meth)
148: {
150:   *meth = (PCType) pc->type_name;
151:   return(0);
152: }

154: /*@
155:    PCSetFromOptions - Sets PC options from the options database.
156:    This routine must be called before PCSetUp() if the user is to be
157:    allowed to set the preconditioner method. 

159:    Collective on PC

161:    Input Parameter:
162: .  pc - the preconditioner context

164:    Level: developer

166: .keywords: PC, set, from, options, database

168: .seealso: 

170: @*/
171: int PCSetFromOptions(PC pc)
172: {
173:   int        ierr;
174:   char       type[256],*def;
175:   PetscTruth flg;


180:   if (!PCRegisterAllCalled) {PCRegisterAll(PETSC_NULL);}
181:   PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");
182:     if (!pc->type_name) {
183:       PetscTruth ismatshell;
184:       int        size;

186:       /*
187:         Shell matrix (probably) cannot support Bjacobi and ILU
188:       */
189:       MPI_Comm_size(pc->comm,&size);
190:       if (pc->pmat) {
191:         PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);
192:       } else {
193:         ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */
194:       }
195:       /* 
196:          MATMFFD cannot support BJacobia and ILU
197:       */
198:       if (!ismatshell) {
199:         PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);
200:       }

202:       if (ismatshell) {
203:         def = PCNONE;
204:         PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't supportn
205:     preconditioners (unless defined by the user)n");
206:       } else if (size == 1) {
207:         def = PCILU;
208:       } else {
209:         def = PCBJACOBI;
210:       }
211:     } else {
212:       def = pc->type_name;
213:     }

215:     PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);
216:     if (flg) {
217:       PCSetType(pc,type);
218:     }
219:     /* option is actually checked in PCSetUp() */
220:     if (pc->nullsp) {
221:       PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);
222:     }

224:     /*
225:       Set the type if it was never set.
226:     */
227:     if (!pc->type_name) {
228:       PCSetType(pc,def);
229:     }

231:     if (pc->ops->setfromoptions) {
232:       (*pc->ops->setfromoptions)(pc);
233:     }
234:   PetscOptionsEnd();
235: #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_MATSINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
236:   PCESISetFromOptions(pc);
237: #endif
238:   return(0);
239: }