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);
63: PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist));
64: /* Reinitialize function pointers in PCOps structure */
65: PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps)));
66: /* XXX Is this OK?? */
67: pc->modifysubmatrices = NULL;
68: pc->modifysubmatricesP = NULL;
69: /* Call the PCCreate_XXX routine for this particular preconditioner */
70: pc->setupcalled = 0;
72: PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type));
73: PetscCall((*r)(pc));
74: PetscFunctionReturn(PETSC_SUCCESS);
75: }
77: /*@
78: PCGetType - Gets the `PCType` (as a string) from the `PC`
79: context.
81: Not Collective
83: Input Parameter:
84: . pc - the preconditioner context
86: Output Parameter:
87: . type - name of preconditioner method
89: Level: intermediate
91: .seealso: [](ch_ksp), `PC`, `PCType`, `PCSetType()`
92: @*/
93: PetscErrorCode PCGetType(PC pc, PCType *type)
94: {
95: PetscFunctionBegin;
97: PetscAssertPointer(type, 2);
98: *type = ((PetscObject)pc)->type_name;
99: PetscFunctionReturn(PETSC_SUCCESS);
100: }
102: PETSC_INTERN PetscErrorCode PCGetDefaultType_Private(PC, const char *[]);
104: /*@
105: PCSetFromOptions - Sets `PC` options from the options database.
107: Collective
109: Input Parameter:
110: . pc - the preconditioner context
112: Options Database Key:
113: . -pc_type - name of type, for example `bjacobi`
115: Level: advanced
117: Notes:
118: This routine must be called before `PCSetUp()` if the user is to be
119: allowed to set the preconditioner method from the options database.
121: This is called from `KSPSetFromOptions()` so rarely needs to be called directly
123: .seealso: [](ch_ksp), `PC`, `PCSetType()`, `PCType`, `KSPSetFromOptions()`
124: @*/
125: PetscErrorCode PCSetFromOptions(PC pc)
126: {
127: char type[256];
128: const char *def;
129: PetscBool flg;
131: PetscFunctionBegin;
134: PetscCall(PCRegisterAll());
135: if (!((PetscObject)pc)->type_name) {
136: PetscCall(PCGetDefaultType_Private(pc, &def));
137: } else {
138: def = ((PetscObject)pc)->type_name;
139: }
140: PetscObjectOptionsBegin((PetscObject)pc);
142: PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg));
143: if (flg) {
144: PetscCall(PCSetType(pc, type));
145: } else if (!((PetscObject)pc)->type_name && def) {
146: PetscCall(PCSetType(pc, def));
147: }
149: PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg));
150: if (flg) goto skipoptions;
152: PetscCall(PetscOptionsBool("-pc_use_amat", "use Amat (instead of Pmat) to define preconditioner in nested inner solves", "PCSetUseAmat", pc->useAmat, &pc->useAmat, NULL));
154: PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);
156: skipoptions:
157: /* process any options handlers added with PetscObjectAddOptionsHandler() */
158: PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject));
159: PetscOptionsEnd();
160: pc->setfromoptionscalled++;
161: PetscFunctionReturn(PETSC_SUCCESS);
162: }
164: /*@
165: PCSetDM - Sets the `DM` that may be used by some preconditioners
167: Logically Collective
169: Input Parameters:
170: + pc - the preconditioner context
171: - dm - the `DM`, can be `NULL` to remove any current `DM`
173: Level: intermediate
175: Note:
176: Users generally call `KSPSetDM()`, `SNESSetDM()`, or `TSSetDM()` so this is rarely called directly
178: Developer Notes:
179: The routines KSP/SNES/TSSetDM() require `dm` to be non-`NULL`, but this one can be `NULL` since all it does is
180: replace the current `DM`
182: .seealso: [](ch_ksp), `PC`, `DM`, `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`, `SNESSetDM()`, `TSSetDM()`
183: @*/
184: PetscErrorCode PCSetDM(PC pc, DM dm)
185: {
186: PetscFunctionBegin;
188: if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
189: PetscCall(DMDestroy(&pc->dm));
190: pc->dm = dm;
191: PetscFunctionReturn(PETSC_SUCCESS);
192: }
194: /*@
195: PCGetDM - Gets the `DM` that may be used by some preconditioners
197: Not Collective
199: Input Parameter:
200: . pc - the preconditioner context
202: Output Parameter:
203: . dm - the `DM`
205: Level: intermediate
207: .seealso: [](ch_ksp), `PC`, `DM`, `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()`
208: @*/
209: PetscErrorCode PCGetDM(PC pc, DM *dm)
210: {
211: PetscFunctionBegin;
213: *dm = pc->dm;
214: PetscFunctionReturn(PETSC_SUCCESS);
215: }
217: /*@
218: PCSetApplicationContext - Sets the optional user-defined context for the preconditioner
220: Logically Collective
222: Input Parameters:
223: + pc - the `PC` context
224: - ctx - optional user context
226: Level: advanced
228: Fortran Note:
229: This only works when `ctx` is a Fortran derived type (it cannot be a `PetscObject`), we recommend writing a Fortran interface definition for this
230: function that tells the Fortran compiler the derived data type that is passed in as the `ctx` argument. See `PCGetApplicationContext()` for
231: an example.
233: .seealso: [](ch_ksp), `PC`, `PCGetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`, `PetscObjectCompose()`
234: @*/
235: PetscErrorCode PCSetApplicationContext(PC pc, void *ctx)
236: {
237: PetscFunctionBegin;
239: pc->ctx = ctx;
240: PetscFunctionReturn(PETSC_SUCCESS);
241: }
243: /*@
244: PCGetApplicationContext - Gets the user-defined context for the preconditioner set with `PCSetApplicationContext()`
246: Not Collective
248: Input Parameter:
249: . pc - `PC` context
251: Output Parameter:
252: . ctx - user context
254: Level: intermediate
256: Fortran Notes:
257: This only works when the context is a Fortran derived type (it cannot be a `PetscObject`) and you **must** write a Fortran interface definition for this
258: function that tells the Fortran compiler the derived data type that is returned as the `ctx` argument. For example,
259: .vb
260: Interface PCGetApplicationContext
261: Subroutine PCGetApplicationContext(pc,ctx,ierr)
262: #include <petsc/finclude/petscpc.h>
263: use petscpc
264: PC pc
265: type(tUsertype), pointer :: ctx
266: PetscErrorCode ierr
267: End Subroutine
268: End Interface PCGetApplicationContext
269: .ve
271: The prototype for `ctx` must be
272: .vb
273: type(tUsertype), pointer :: ctx
274: .ve
276: .seealso: [](ch_ksp), `PC`, `PCSetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`
277: @*/
278: PetscErrorCode PCGetApplicationContext(PC pc, PeCtx ctx)
279: {
280: PetscFunctionBegin;
282: *(void **)ctx = pc->ctx;
283: PetscFunctionReturn(PETSC_SUCCESS);
284: }