xref: /petsc/src/ksp/pc/interface/pcset.c (revision 49abdd8a111d9c2ef7fc48ade253ef64e07f9b37)
14b9ad928SBarry Smith /*
24b9ad928SBarry Smith     Routines to set PC methods and options.
34b9ad928SBarry Smith */
44b9ad928SBarry Smith 
5af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
61e25c274SJed Brown #include <petscdm.h>
74b9ad928SBarry Smith 
8ace3abfcSBarry Smith PetscBool PCRegisterAllCalled = PETSC_FALSE;
94b9ad928SBarry Smith /*
10f3b08a26SMatthew G. Knepley    Contains the list of registered PC routines
114b9ad928SBarry Smith */
120a545947SLisandro Dalcin PetscFunctionList PCList = NULL;
134b9ad928SBarry Smith 
14cc4c1da9SBarry Smith /*@
1504c3f3b8SBarry Smith   PCSetType - Builds `PC` for a particular preconditioner type
164b9ad928SBarry Smith 
17c3339decSBarry Smith   Collective
184b9ad928SBarry Smith 
19d8d19677SJose E. Roman   Input Parameters:
2004c3f3b8SBarry Smith + pc   - the preconditioner context
2104c3f3b8SBarry Smith - type - a known method, see `PCType` for possible values
224b9ad928SBarry Smith 
234b9ad928SBarry Smith   Options Database Key:
2404c3f3b8SBarry Smith . -pc_type <type> - Sets `PC` type
254b9ad928SBarry Smith 
264b9ad928SBarry Smith   Notes:
2704c3f3b8SBarry Smith   Normally, it is best to use the `KSPSetFromOptions()` command and
2804c3f3b8SBarry Smith   then set the `PC` type from the options database rather than by using
294b9ad928SBarry Smith   this routine.  Using the options database provides the user with
304b9ad928SBarry Smith   maximum flexibility in evaluating the many different preconditioners.
3104c3f3b8SBarry Smith   The `PCSetType()` routine is provided for those situations where it
324b9ad928SBarry Smith   is necessary to set the preconditioner independently of the command
334b9ad928SBarry Smith   line or options database.  This might be the case, for example, when
344b9ad928SBarry Smith   the choice of preconditioner changes during the execution of the
354b9ad928SBarry Smith   program, and the user's application is taking responsibility for
3604c3f3b8SBarry Smith   choosing the appropriate preconditioner.
374b9ad928SBarry Smith 
384b9ad928SBarry Smith   Level: intermediate
394b9ad928SBarry Smith 
4004c3f3b8SBarry Smith   Developer Notes:
4104c3f3b8SBarry Smith   `PCRegister()` is used to add preconditioner types to `PCList` from which they
4204c3f3b8SBarry Smith   are accessed by `PCSetType()`.
438f6c3df8SBarry Smith 
44562efe2eSBarry Smith .seealso: [](ch_ksp), `KSPSetType()`, `PCType`, `PCRegister()`, `PCCreate()`, `KSPGetPC()`
454b9ad928SBarry Smith @*/
46d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetType(PC pc, PCType type)
47d71ae5a4SJacob Faibussowitsch {
48ace3abfcSBarry Smith   PetscBool match;
495f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(PC);
504b9ad928SBarry Smith 
514b9ad928SBarry Smith   PetscFunctionBegin;
520700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
534f572ea9SToby Isaac   PetscAssertPointer(type, 2);
544b9ad928SBarry Smith 
559566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, type, &match));
563ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
574b9ad928SBarry Smith 
589566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PCList, type, &r));
595f80ce2aSJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PC type %s", type);
60a7d21a52SLisandro Dalcin   /* Destroy the previous private PC context */
61dbbe0bcdSBarry Smith   PetscTryTypeMethod(pc, destroy);
620298fd71SBarry Smith   pc->ops->destroy = NULL;
630a545947SLisandro Dalcin   pc->data         = NULL;
64dbbe0bcdSBarry Smith 
659566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist));
66a7d21a52SLisandro Dalcin   /* Reinitialize function pointers in PCOps structure */
679566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps)));
68a7d21a52SLisandro Dalcin   /* XXX Is this OK?? */
690a545947SLisandro Dalcin   pc->modifysubmatrices  = NULL;
700a545947SLisandro Dalcin   pc->modifysubmatricesP = NULL;
71a7d21a52SLisandro Dalcin   /* Call the PCCreate_XXX routine for this particular preconditioner */
72a7d21a52SLisandro Dalcin   pc->setupcalled = 0;
732fa5cd67SKarl Rupp 
749566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type));
759566063dSJacob Faibussowitsch   PetscCall((*r)(pc));
763ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
774b9ad928SBarry Smith }
784b9ad928SBarry Smith 
79cc4c1da9SBarry Smith /*@
8004c3f3b8SBarry Smith   PCGetType - Gets the `PCType` (as a string) from the `PC`
814b9ad928SBarry Smith   context.
824b9ad928SBarry Smith 
834b9ad928SBarry Smith   Not Collective
844b9ad928SBarry Smith 
854b9ad928SBarry Smith   Input Parameter:
864b9ad928SBarry Smith . pc - the preconditioner context
874b9ad928SBarry Smith 
884b9ad928SBarry Smith   Output Parameter:
89c4e43342SLisandro Dalcin . type - name of preconditioner method
904b9ad928SBarry Smith 
914b9ad928SBarry Smith   Level: intermediate
924b9ad928SBarry Smith 
93562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCType`, `PCSetType()`
944b9ad928SBarry Smith @*/
95d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetType(PC pc, PCType *type)
96d71ae5a4SJacob Faibussowitsch {
974b9ad928SBarry Smith   PetscFunctionBegin;
980700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
994f572ea9SToby Isaac   PetscAssertPointer(type, 2);
100c4e43342SLisandro Dalcin   *type = ((PetscObject)pc)->type_name;
1013ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1024b9ad928SBarry Smith }
1034b9ad928SBarry Smith 
104b4f8a55aSStefano Zampini PETSC_INTERN PetscErrorCode PCGetDefaultType_Private(PC, const char *[]);
105566e8bf2SBarry Smith 
1064b9ad928SBarry Smith /*@
10704c3f3b8SBarry Smith   PCSetFromOptions - Sets `PC` options from the options database.
1084b9ad928SBarry Smith 
109c3339decSBarry Smith   Collective
1104b9ad928SBarry Smith 
1114b9ad928SBarry Smith   Input Parameter:
1124b9ad928SBarry Smith . pc - the preconditioner context
1134b9ad928SBarry Smith 
114f1580f4eSBarry Smith   Options Database Key:
11504c3f3b8SBarry Smith . -pc_type - name of type, for example `bjacobi`
116b9ee023eSBarry Smith 
11704c3f3b8SBarry Smith   Level: advanced
1184b9ad928SBarry Smith 
11904c3f3b8SBarry Smith   Notes:
12004c3f3b8SBarry Smith   This routine must be called before `PCSetUp()` if the user is to be
12104c3f3b8SBarry Smith   allowed to set the preconditioner method from the options database.
1224b9ad928SBarry Smith 
12304c3f3b8SBarry Smith   This is called from `KSPSetFromOptions()` so rarely needs to be called directly
12404c3f3b8SBarry Smith 
125562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCSetType()`, `PCType`, `KSPSetFromOptions()`
1264b9ad928SBarry Smith @*/
127d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions(PC pc)
128d71ae5a4SJacob Faibussowitsch {
1292fc52814SBarry Smith   char        type[256];
1302fc52814SBarry Smith   const char *def;
131ace3abfcSBarry Smith   PetscBool   flg;
1324b9ad928SBarry Smith 
1334b9ad928SBarry Smith   PetscFunctionBegin;
1340700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
1354b9ad928SBarry Smith 
1369566063dSJacob Faibussowitsch   PetscCall(PCRegisterAll());
1377adad957SLisandro Dalcin   if (!((PetscObject)pc)->type_name) {
1389566063dSJacob Faibussowitsch     PetscCall(PCGetDefaultType_Private(pc, &def));
1394b9ad928SBarry Smith   } else {
1407adad957SLisandro Dalcin     def = ((PetscObject)pc)->type_name;
1414b9ad928SBarry Smith   }
142b4f8a55aSStefano Zampini   PetscObjectOptionsBegin((PetscObject)pc);
1434b9ad928SBarry Smith 
1449566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg));
1454b9ad928SBarry Smith   if (flg) {
1469566063dSJacob Faibussowitsch     PetscCall(PCSetType(pc, type));
147b4f8a55aSStefano Zampini   } else if (!((PetscObject)pc)->type_name && def) {
1489566063dSJacob Faibussowitsch     PetscCall(PCSetType(pc, def));
1494b9ad928SBarry Smith   }
1504b9ad928SBarry Smith 
1519566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg));
15225c41539SBarry Smith   if (flg) goto skipoptions;
15325c41539SBarry Smith 
1549566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_use_amat", "use Amat (instead of Pmat) to define preconditioner in nested inner solves", "PCSetUseAmat", pc->useAmat, &pc->useAmat, NULL));
155b4813acdSShri Abhyankar 
156dbbe0bcdSBarry Smith   PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);
1575d973c19SBarry Smith 
15825c41539SBarry Smith skipoptions:
1595d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
160dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject));
161d0609cedSBarry Smith   PetscOptionsEnd();
1620c24e6a1SHong Zhang   pc->setfromoptionscalled++;
1633ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1644b9ad928SBarry Smith }
1656c699258SBarry Smith 
1666c699258SBarry Smith /*@
16704c3f3b8SBarry Smith   PCSetDM - Sets the `DM` that may be used by some preconditioners
1686c699258SBarry Smith 
169c3339decSBarry Smith   Logically Collective
1706c699258SBarry Smith 
1716c699258SBarry Smith   Input Parameters:
1726c699258SBarry Smith + pc - the preconditioner context
17304c3f3b8SBarry Smith - dm - the `DM`, can be `NULL` to remove any current `DM`
1746c699258SBarry Smith 
1756c699258SBarry Smith   Level: intermediate
1766c699258SBarry Smith 
17704c3f3b8SBarry Smith   Note:
17804c3f3b8SBarry Smith   Users generally call  `KSPSetDM()`, `SNESSetDM()`, or `TSSetDM()` so this is rarely called directly
1796c699258SBarry Smith 
18004c3f3b8SBarry Smith   Developer Notes:
18104c3f3b8SBarry Smith   The routines KSP/SNES/TSSetDM() require `dm` to be non-`NULL`, but this one can be `NULL` since all it does is
18204c3f3b8SBarry Smith   replace the current `DM`
18304c3f3b8SBarry Smith 
184562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `DM`, `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`, `SNESSetDM()`, `TSSetDM()`
1856c699258SBarry Smith @*/
186d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetDM(PC pc, DM dm)
187d71ae5a4SJacob Faibussowitsch {
1886c699258SBarry Smith   PetscFunctionBegin;
1890700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
1909566063dSJacob Faibussowitsch   if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
1919566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&pc->dm));
1926c699258SBarry Smith   pc->dm = dm;
1933ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1946c699258SBarry Smith }
1956c699258SBarry Smith 
1966c699258SBarry Smith /*@
19704c3f3b8SBarry Smith   PCGetDM - Gets the `DM` that may be used by some preconditioners
1986c699258SBarry Smith 
1993f9fe445SBarry Smith   Not Collective
2006c699258SBarry Smith 
2016c699258SBarry Smith   Input Parameter:
2026c699258SBarry Smith . pc - the preconditioner context
2036c699258SBarry Smith 
2046c699258SBarry Smith   Output Parameter:
20504c3f3b8SBarry Smith . dm - the `DM`
2066c699258SBarry Smith 
2076c699258SBarry Smith   Level: intermediate
2086c699258SBarry Smith 
209562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `DM`, `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()`
2106c699258SBarry Smith @*/
211d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetDM(PC pc, DM *dm)
212d71ae5a4SJacob Faibussowitsch {
2136c699258SBarry Smith   PetscFunctionBegin;
2140700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2156c699258SBarry Smith   *dm = pc->dm;
2163ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2176c699258SBarry Smith }
2186c699258SBarry Smith 
219b07ff414SBarry Smith /*@
22004c3f3b8SBarry Smith   PCSetApplicationContext - Sets the optional user-defined context for the preconditioner
2211b2093e4SBarry Smith 
222c3339decSBarry Smith   Logically Collective
2231b2093e4SBarry Smith 
2241b2093e4SBarry Smith   Input Parameters:
22504c3f3b8SBarry Smith + pc  - the `PC` context
226*49abdd8aSBarry Smith - ctx - optional user context
2271b2093e4SBarry Smith 
22804c3f3b8SBarry Smith   Level: advanced
2291b2093e4SBarry Smith 
230562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCGetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`, `PetscObjectCompose()`
2311b2093e4SBarry Smith @*/
232*49abdd8aSBarry Smith PetscErrorCode PCSetApplicationContext(PC pc, void *ctx)
233d71ae5a4SJacob Faibussowitsch {
2341b2093e4SBarry Smith   PetscFunctionBegin;
2351b2093e4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
236*49abdd8aSBarry Smith   pc->ctx = ctx;
2373ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2381b2093e4SBarry Smith }
2391b2093e4SBarry Smith 
240b07ff414SBarry Smith /*@
24104c3f3b8SBarry Smith   PCGetApplicationContext - Gets the user-defined context for the preconditioner set with `PCSetApplicationContext()`
2421b2093e4SBarry Smith 
2431b2093e4SBarry Smith   Not Collective
2441b2093e4SBarry Smith 
2451b2093e4SBarry Smith   Input Parameter:
24604c3f3b8SBarry Smith . pc - `PC` context
2471b2093e4SBarry Smith 
2481b2093e4SBarry Smith   Output Parameter:
249*49abdd8aSBarry Smith . ctx - user context
2501b2093e4SBarry Smith 
2511b2093e4SBarry Smith   Level: intermediate
2521b2093e4SBarry Smith 
253562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCSetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`
2541b2093e4SBarry Smith @*/
255*49abdd8aSBarry Smith PetscErrorCode PCGetApplicationContext(PC pc, void *ctx)
256d71ae5a4SJacob Faibussowitsch {
2571b2093e4SBarry Smith   PetscFunctionBegin;
2581b2093e4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
259*49abdd8aSBarry Smith   *(void **)ctx = pc->ctx;
2603ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2611b2093e4SBarry Smith }
262