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