Actual source code: pcset.c

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

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

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

 14: /*@
 15:   PCSetType - Builds `PC` for a particular preconditioner type

 17:   Collective

 19:   Input Parameters:
 20: + pc   - the preconditioner context
 21: - type - a known method, see `PCType` for possible values

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

 26:   Notes:
 27:   Normally, it is best to use the `KSPSetFromOptions()` command and
 28:   then set the `PC` type from the options database rather than by using
 29:   this routine.  Using the options database provides the user with
 30:   maximum flexibility in evaluating the many different preconditioners.
 31:   The `PCSetType()` routine is provided for those situations where it
 32:   is necessary to set the preconditioner independently of the command
 33:   line or options database.  This might be the case, for example, when
 34:   the choice of preconditioner changes during the execution of the
 35:   program, and the user's application is taking responsibility for
 36:   choosing the appropriate preconditioner.

 38:   Level: intermediate

 40:   Developer Notes:
 41:   `PCRegister()` is used to add preconditioner types to `PCList` from which they
 42:   are accessed by `PCSetType()`.

 44: .seealso: [](ch_ksp), `KSPSetType()`, `PCType`, `PCRegister()`, `PCCreate()`, `KSPGetPC()`
 45: @*/
 46: PetscErrorCode PCSetType(PC pc, PCType type)
 47: {
 48:   PetscBool match;
 49:   PetscErrorCode (*r)(PC);

 51:   PetscFunctionBegin;
 53:   PetscAssertPointer(type, 2);

 55:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, type, &match));
 56:   if (match) PetscFunctionReturn(PETSC_SUCCESS);

 58:   PetscCall(PetscFunctionListFind(PCList, type, &r));
 59:   PetscCheck(r, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PC type %s", type);
 60:   /* Destroy the previous private PC context */
 61:   PetscTryTypeMethod(pc, destroy);
 62:   pc->ops->destroy = NULL;
 63:   pc->data         = NULL;

 65:   PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist));
 66:   /* Reinitialize function pointers in PCOps structure */
 67:   PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps)));
 68:   /* XXX Is this OK?? */
 69:   pc->modifysubmatrices  = NULL;
 70:   pc->modifysubmatricesP = NULL;
 71:   /* Call the PCCreate_XXX routine for this particular preconditioner */
 72:   pc->setupcalled = 0;

 74:   PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type));
 75:   PetscCall((*r)(pc));
 76:   PetscFunctionReturn(PETSC_SUCCESS);
 77: }

 79: /*@
 80:   PCGetType - Gets the `PCType` (as a string) from the `PC`
 81:   context.

 83:   Not Collective

 85:   Input Parameter:
 86: . pc - the preconditioner context

 88:   Output Parameter:
 89: . type - name of preconditioner method

 91:   Level: intermediate

 93: .seealso: [](ch_ksp), `PC`, `PCType`, `PCSetType()`
 94: @*/
 95: PetscErrorCode PCGetType(PC pc, PCType *type)
 96: {
 97:   PetscFunctionBegin;
 99:   PetscAssertPointer(type, 2);
100:   *type = ((PetscObject)pc)->type_name;
101:   PetscFunctionReturn(PETSC_SUCCESS);
102: }

104: PETSC_INTERN PetscErrorCode PCGetDefaultType_Private(PC, const char *[]);

106: /*@
107:   PCSetFromOptions - Sets `PC` options from the options database.

109:   Collective

111:   Input Parameter:
112: . pc - the preconditioner context

114:   Options Database Key:
115: . -pc_type - name of type, for example `bjacobi`

117:   Level: advanced

119:   Notes:
120:   This routine must be called before `PCSetUp()` if the user is to be
121:   allowed to set the preconditioner method from the options database.

123:   This is called from `KSPSetFromOptions()` so rarely needs to be called directly

125: .seealso: [](ch_ksp), `PC`, `PCSetType()`, `PCType`, `KSPSetFromOptions()`
126: @*/
127: PetscErrorCode PCSetFromOptions(PC pc)
128: {
129:   char        type[256];
130:   const char *def;
131:   PetscBool   flg;

133:   PetscFunctionBegin;

136:   PetscCall(PCRegisterAll());
137:   if (!((PetscObject)pc)->type_name) {
138:     PetscCall(PCGetDefaultType_Private(pc, &def));
139:   } else {
140:     def = ((PetscObject)pc)->type_name;
141:   }
142:   PetscObjectOptionsBegin((PetscObject)pc);

144:   PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg));
145:   if (flg) {
146:     PetscCall(PCSetType(pc, type));
147:   } else if (!((PetscObject)pc)->type_name && def) {
148:     PetscCall(PCSetType(pc, def));
149:   }

151:   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg));
152:   if (flg) goto skipoptions;

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

156:   PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);

158: skipoptions:
159:   /* process any options handlers added with PetscObjectAddOptionsHandler() */
160:   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject));
161:   PetscOptionsEnd();
162:   pc->setfromoptionscalled++;
163:   PetscFunctionReturn(PETSC_SUCCESS);
164: }

166: /*@
167:   PCSetDM - Sets the `DM` that may be used by some preconditioners

169:   Logically Collective

171:   Input Parameters:
172: + pc - the preconditioner context
173: - dm - the `DM`, can be `NULL` to remove any current `DM`

175:   Level: intermediate

177:   Note:
178:   Users generally call  `KSPSetDM()`, `SNESSetDM()`, or `TSSetDM()` so this is rarely called directly

180:   Developer Notes:
181:   The routines KSP/SNES/TSSetDM() require `dm` to be non-`NULL`, but this one can be `NULL` since all it does is
182:   replace the current `DM`

184: .seealso: [](ch_ksp), `PC`, `DM`, `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`, `SNESSetDM()`, `TSSetDM()`
185: @*/
186: PetscErrorCode PCSetDM(PC pc, DM dm)
187: {
188:   PetscFunctionBegin;
190:   if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
191:   PetscCall(DMDestroy(&pc->dm));
192:   pc->dm = dm;
193:   PetscFunctionReturn(PETSC_SUCCESS);
194: }

196: /*@
197:   PCGetDM - Gets the `DM` that may be used by some preconditioners

199:   Not Collective

201:   Input Parameter:
202: . pc - the preconditioner context

204:   Output Parameter:
205: . dm - the `DM`

207:   Level: intermediate

209: .seealso: [](ch_ksp), `PC`, `DM`, `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()`
210: @*/
211: PetscErrorCode PCGetDM(PC pc, DM *dm)
212: {
213:   PetscFunctionBegin;
215:   *dm = pc->dm;
216:   PetscFunctionReturn(PETSC_SUCCESS);
217: }

219: /*@
220:   PCSetApplicationContext - Sets the optional user-defined context for the preconditioner

222:   Logically Collective

224:   Input Parameters:
225: + pc  - the `PC` context
226: - ctx - optional user context

228:   Level: advanced

230: .seealso: [](ch_ksp), `PC`, `PCGetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`, `PetscObjectCompose()`
231: @*/
232: PetscErrorCode PCSetApplicationContext(PC pc, void *ctx)
233: {
234:   PetscFunctionBegin;
236:   pc->ctx = ctx;
237:   PetscFunctionReturn(PETSC_SUCCESS);
238: }

240: /*@
241:   PCGetApplicationContext - Gets the user-defined context for the preconditioner set with `PCSetApplicationContext()`

243:   Not Collective

245:   Input Parameter:
246: . pc - `PC` context

248:   Output Parameter:
249: . ctx - user context

251:   Level: intermediate

253: .seealso: [](ch_ksp), `PC`, `PCSetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`
254: @*/
255: PetscErrorCode PCGetApplicationContext(PC pc, void *ctx)
256: {
257:   PetscFunctionBegin;
259:   *(void **)ctx = pc->ctx;
260:   PetscFunctionReturn(PETSC_SUCCESS);
261: }