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: #undef __FUNCT__  
 17: /*@C
 18:    PCSetType - Builds PC for a particular preconditioner.

 20:    Collective on PC

 22:    Input Parameter:
 23: +  pc - the preconditioner context.
 24: -  type - a known method

 26:    Options Database Key:
 27: .  -pc_type <type> - Sets PC type

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

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

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

 48:   Level: intermediate

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

 52: .seealso: KSPSetType(), PCType

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


 64:   PetscTypeCompare((PetscObject)pc,type,&match);
 65:   if (match) return(0);

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

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

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

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

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

100:   PetscObjectChangeTypeName((PetscObject)pc,type);
101:   return(0);
102: }

104: #undef __FUNCT__  
106: /*@C
107:    PCRegisterDestroy - Frees the list of preconditioners that were
108:    registered by PCRegisterDynamic().

110:    Not Collective

112:    Level: advanced

114: .keywords: PC, register, destroy

116: .seealso: PCRegisterAll(), PCRegisterAll()

118: @*/
119: int PCRegisterDestroy(void)
120: {

124:   if (PCList) {
125:     PetscFListDestroy(&PCList);
126:     PCList = 0;
127:   }
128:   PCRegisterAllCalled = PETSC_FALSE;
129:   return(0);
130: }

132: #undef __FUNCT__  
134: /*@C
135:    PCGetType - Gets the PC method type and name (as a string) from the PC
136:    context.

138:    Not Collective

140:    Input Parameter:
141: .  pc - the preconditioner context

143:    Output Parameter:
144: .  name - name of preconditioner 

146:    Level: intermediate

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

150: .seealso: PCSetType()

152: @*/
153: int PCGetType(PC pc,PCType *meth)
154: {
156:   *meth = (PCType) pc->type_name;
157:   return(0);
158: }

160: #undef __FUNCT__  
162: /*@
163:    PCSetFromOptions - Sets PC options from the options database.
164:    This routine must be called before PCSetUp() if the user is to be
165:    allowed to set the preconditioner method. 

167:    Collective on PC

169:    Input Parameter:
170: .  pc - the preconditioner context

172:    Level: developer

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

176: .seealso: 

178: @*/
179: int PCSetFromOptions(PC pc)
180: {
181:   int        ierr;
182:   char       type[256],*def;
183:   PetscTruth flg;


188:   if (!PCRegisterAllCalled) {PCRegisterAll(PETSC_NULL);}
189:   PetscOptionsBegin(pc->comm,pc->prefix,"Preconditioner (PC) Options","PC");
190:     if (!pc->type_name) {
191:       PetscTruth ismatshell;
192:       int        size;

194:       /*
195:         Shell matrix (probably) cannot support Bjacobi and ILU
196:       */
197:       MPI_Comm_size(pc->comm,&size);
198:       if (pc->pmat) {
199:         PetscTypeCompare((PetscObject)pc->pmat,MATSHELL,&ismatshell);
200:       } else {
201:         ismatshell = PETSC_FALSE; /* matrix is not yet set, so guess that it will not be MATSHELL */
202:       }
203:       /* 
204:          MATMFFD cannot support BJacobia and ILU
205:       */
206:       if (!ismatshell) {
207:         PetscTypeCompare((PetscObject)pc->pmat,MATMFFD,&ismatshell);
208:       }

210:       if (ismatshell) {
211:         def = PCNONE;
212:         PetscLogInfo(pc,"PCSetOperators:Setting default PC to PCNONE since MATSHELL doesn't supportn
213:     preconditioners (unless defined by the user)n");
214:       } else if (size == 1) {
215:         PetscTypeCompare((PetscObject)pc->pmat,MATSEQSBAIJ,&flg);
216:         if (flg) {
217:           def = PCICC;
218:         } else {
219:           def = PCILU;
220:         }
221:       } else {
222:         def = PCBJACOBI;
223:       }
224:     } else {
225:       def = pc->type_name;
226:     }

228:     PetscOptionsList("-pc_type","Preconditioner","PCSetType",PCList,def,type,256,&flg);
229:     if (flg) {
230:       PCSetType(pc,type);
231:     }
232:     /* option is actually checked in PCSetUp() */
233:     if (pc->nullsp) {
234:       PetscOptionsName("-pc_test_null_space","Is provided null space correct","None",&flg);
235:     }

237:     /*
238:       Set the type if it was never set.
239:     */
240:     if (!pc->type_name) {
241:       PCSetType(pc,def);
242:     }

244:     if (pc->ops->setfromoptions) {
245:       (*pc->ops->setfromoptions)(pc);
246:     }
247:   PetscOptionsEnd();
248: #if defined(__cplusplus) && !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_SINGLE) && defined(PETSC_HAVE_CXX_NAMESPACE)
249:   PCESISetFromOptions(pc);
250: #endif
251:   return(0);
252: }