Actual source code: pcset.c


  2: /*
  3:     Routines to set PC methods and options.
  4: */

  6: #include <petsc/private/pcimpl.h>
  7: #include <petscdm.h>

  9: PetscBool PCRegisterAllCalled = PETSC_FALSE;
 10: /*
 11:    Contains the list of registered PC routines
 12: */
 13: PetscFunctionList PCList = NULL;

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

 18:    Collective

 20:    Input Parameters:
 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 KSPSetFromOptions() 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:   Developer Note: PCRegister() is used to add preconditioner types to PCList from which they
 49:   are accessed by PCSetType().

 51: .seealso: `KSPSetType()`, `PCType`, `PCRegister()`, `PCCreate()`, `KSPGetPC()`

 53: @*/
 54: PetscErrorCode PCSetType(PC pc, PCType type)
 55: {
 56:   PetscBool match;
 57:   PetscErrorCode (*r)(PC);

 59:   PetscFunctionBegin;

 63:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, type, &match));
 64:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

 66:   PetscCall(PetscFunctionListFind(PCList, type, &r));
 67:   PetscCheck(r, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PC type %s", type);
 68:   /* Destroy the previous private PC context */
 69:   PetscTryTypeMethod(pc, destroy);
 70:   pc->ops->destroy = NULL;
 71:   pc->data         = NULL;

 73:   PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist));
 74:   /* Reinitialize function pointers in PCOps structure */
 75:   PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps)));
 76:   /* XXX Is this OK?? */
 77:   pc->modifysubmatrices  = NULL;
 78:   pc->modifysubmatricesP = NULL;
 79:   /* Call the PCCreate_XXX routine for this particular preconditioner */
 80:   pc->setupcalled = 0;

 82:   PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type));
 83:   PetscCall((*r)(pc));
 84:   PetscFunctionReturn(PETSC_SUCCESS);
 85: }

 87: /*@C
 88:    PCGetType - Gets the PC method type and name (as a string) from the PC
 89:    context.

 91:    Not Collective

 93:    Input Parameter:
 94: .  pc - the preconditioner context

 96:    Output Parameter:
 97: .  type - name of preconditioner method

 99:    Level: intermediate

101: .seealso: `PCSetType()`

103: @*/
104: PetscErrorCode PCGetType(PC pc, PCType *type)
105: {
106:   PetscFunctionBegin;
109:   *type = ((PetscObject)pc)->type_name;
110:   PetscFunctionReturn(PETSC_SUCCESS);
111: }

113: extern PetscErrorCode PCGetDefaultType_Private(PC, const char *[]);

115: /*@
116:    PCSetFromOptions - Sets PC options from the options database.
117:    This routine must be called before PCSetUp() if the user is to be
118:    allowed to set the preconditioner method.

120:    Collective

122:    Input Parameter:
123: .  pc - the preconditioner context

125:    Options Database Key:
126: .   -pc_use_amat true,false - see PCSetUseAmat()

128:    Level: developer

130: .seealso: `PCSetUseAmat()`

132: @*/
133: PetscErrorCode PCSetFromOptions(PC pc)
134: {
135:   char        type[256];
136:   const char *def;
137:   PetscBool   flg;

139:   PetscFunctionBegin;

142:   PetscCall(PCRegisterAll());
143:   PetscObjectOptionsBegin((PetscObject)pc);
144:   if (!((PetscObject)pc)->type_name) {
145:     PetscCall(PCGetDefaultType_Private(pc, &def));
146:   } else {
147:     def = ((PetscObject)pc)->type_name;
148:   }

150:   PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg));
151:   if (flg) {
152:     PetscCall(PCSetType(pc, type));
153:   } else if (!((PetscObject)pc)->type_name) {
154:     PetscCall(PCSetType(pc, def));
155:   }

157:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg));
158:   if (flg) goto skipoptions;

160:   PetscCall(PetscOptionsBool("-pc_use_amat", "use Amat (instead of Pmat) to define preconditioner in nested inner solves", "PCSetUseAmat", pc->useAmat, &pc->useAmat, NULL));

162:   PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);

164: skipoptions:
165:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
166:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject));
167:   PetscOptionsEnd();
168:   pc->setfromoptionscalled++;
169:   PetscFunctionReturn(PETSC_SUCCESS);
170: }

172: /*@
173:    PCSetDM - Sets the DM that may be used by some preconditioners

175:    Logically Collective

177:    Input Parameters:
178: +  pc - the preconditioner context
179: -  dm - the dm, can be NULL

181:    Level: intermediate

183:    Developer Note:
184:     The routines KSP/SNES/TSSetDM() require the dm to be non-NULL, but this one can be NULL since all it does is
185:     replace the current DM

187: .seealso: `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`
188: @*/
189: PetscErrorCode PCSetDM(PC pc, DM dm)
190: {
191:   PetscFunctionBegin;
193:   if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
194:   PetscCall(DMDestroy(&pc->dm));
195:   pc->dm = dm;
196:   PetscFunctionReturn(PETSC_SUCCESS);
197: }

199: /*@
200:    PCGetDM - Gets the DM that may be used by some preconditioners

202:    Not Collective

204:    Input Parameter:
205: . pc - the preconditioner context

207:    Output Parameter:
208: .  dm - the dm

210:    Level: intermediate

212: .seealso: `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()`
213: @*/
214: PetscErrorCode PCGetDM(PC pc, DM *dm)
215: {
216:   PetscFunctionBegin;
218:   *dm = pc->dm;
219:   PetscFunctionReturn(PETSC_SUCCESS);
220: }

222: /*@
223:    PCSetApplicationContext - Sets the optional user-defined context for the linear solver.

225:    Logically Collective

227:    Input Parameters:
228: +  pc - the PC context
229: -  usrP - optional user context

231:    Level: intermediate

233: .seealso: `PCGetApplicationContext()`
234: @*/
235: PetscErrorCode PCSetApplicationContext(PC pc, void *usrP)
236: {
237:   PetscFunctionBegin;
239:   pc->user = usrP;
240:   PetscFunctionReturn(PETSC_SUCCESS);
241: }

243: /*@
244:    PCGetApplicationContext - Gets the user-defined context for the linear solver.

246:    Not Collective

248:    Input Parameter:
249: .  pc - PC context

251:    Output Parameter:
252: .  usrP - user context

254:    Level: intermediate

256: .seealso: `PCSetApplicationContext()`
257: @*/
258: PetscErrorCode PCGetApplicationContext(PC pc, void *usrP)
259: {
260:   PetscFunctionBegin;
262:   *(void **)usrP = pc->user;
263:   PetscFunctionReturn(PETSC_SUCCESS);
264: }