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: }