xref: /petsc/src/ksp/pc/interface/pcset.c (revision 04c3f3b8f563eff258c1de90d4e02d41e6027585)
17d0a6c19SBarry Smith 
24b9ad928SBarry Smith /*
34b9ad928SBarry Smith     Routines to set PC methods and options.
44b9ad928SBarry Smith */
54b9ad928SBarry Smith 
6af0996ceSBarry Smith #include <petsc/private/pcimpl.h> /*I "petscpc.h" I*/
71e25c274SJed Brown #include <petscdm.h>
84b9ad928SBarry Smith 
9ace3abfcSBarry Smith PetscBool PCRegisterAllCalled = PETSC_FALSE;
104b9ad928SBarry Smith /*
11f3b08a26SMatthew G. Knepley    Contains the list of registered PC routines
124b9ad928SBarry Smith */
130a545947SLisandro Dalcin PetscFunctionList PCList = NULL;
144b9ad928SBarry Smith 
154b9ad928SBarry Smith /*@C
16*04c3f3b8SBarry Smith   PCSetType - Builds `PC` for a particular preconditioner type
174b9ad928SBarry Smith 
18c3339decSBarry Smith   Collective
194b9ad928SBarry Smith 
20d8d19677SJose E. Roman   Input Parameters:
21*04c3f3b8SBarry Smith + pc   - the preconditioner context
22*04c3f3b8SBarry Smith - type - a known method, see `PCType` for possible values
234b9ad928SBarry Smith 
244b9ad928SBarry Smith   Options Database Key:
25*04c3f3b8SBarry Smith . -pc_type <type> - Sets `PC` type
264b9ad928SBarry Smith 
274b9ad928SBarry Smith   Notes:
28*04c3f3b8SBarry Smith   Normally, it is best to use the `KSPSetFromOptions()` command and
29*04c3f3b8SBarry Smith   then set the `PC` type from the options database rather than by using
304b9ad928SBarry Smith   this routine.  Using the options database provides the user with
314b9ad928SBarry Smith   maximum flexibility in evaluating the many different preconditioners.
32*04c3f3b8SBarry Smith   The `PCSetType()` routine is provided for those situations where it
334b9ad928SBarry Smith   is necessary to set the preconditioner independently of the command
344b9ad928SBarry Smith   line or options database.  This might be the case, for example, when
354b9ad928SBarry Smith   the choice of preconditioner changes during the execution of the
364b9ad928SBarry Smith   program, and the user's application is taking responsibility for
37*04c3f3b8SBarry Smith   choosing the appropriate preconditioner.
384b9ad928SBarry Smith 
394b9ad928SBarry Smith   Level: intermediate
404b9ad928SBarry Smith 
41*04c3f3b8SBarry Smith   Developer Notes:
42*04c3f3b8SBarry Smith   `PCRegister()` is used to add preconditioner types to `PCList` from which they
43*04c3f3b8SBarry Smith   are accessed by `PCSetType()`.
448f6c3df8SBarry Smith 
45db781477SPatrick Sanan .seealso: `KSPSetType()`, `PCType`, `PCRegister()`, `PCCreate()`, `KSPGetPC()`
464b9ad928SBarry Smith @*/
47d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetType(PC pc, PCType type)
48d71ae5a4SJacob Faibussowitsch {
49ace3abfcSBarry Smith   PetscBool match;
505f80ce2aSJacob Faibussowitsch   PetscErrorCode (*r)(PC);
514b9ad928SBarry Smith 
524b9ad928SBarry Smith   PetscFunctionBegin;
530700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
544f572ea9SToby Isaac   PetscAssertPointer(type, 2);
554b9ad928SBarry Smith 
569566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, type, &match));
573ba16761SJacob Faibussowitsch   if (match) PetscFunctionReturn(PETSC_SUCCESS);
584b9ad928SBarry Smith 
599566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListFind(PCList, type, &r));
605f80ce2aSJacob Faibussowitsch   PetscCheck(r, PetscObjectComm((PetscObject)pc), PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested PC type %s", type);
61a7d21a52SLisandro Dalcin   /* Destroy the previous private PC context */
62dbbe0bcdSBarry Smith   PetscTryTypeMethod(pc, destroy);
630298fd71SBarry Smith   pc->ops->destroy = NULL;
640a545947SLisandro Dalcin   pc->data         = NULL;
65dbbe0bcdSBarry Smith 
669566063dSJacob Faibussowitsch   PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist));
67a7d21a52SLisandro Dalcin   /* Reinitialize function pointers in PCOps structure */
689566063dSJacob Faibussowitsch   PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps)));
69a7d21a52SLisandro Dalcin   /* XXX Is this OK?? */
700a545947SLisandro Dalcin   pc->modifysubmatrices  = NULL;
710a545947SLisandro Dalcin   pc->modifysubmatricesP = NULL;
72a7d21a52SLisandro Dalcin   /* Call the PCCreate_XXX routine for this particular preconditioner */
73a7d21a52SLisandro Dalcin   pc->setupcalled = 0;
742fa5cd67SKarl Rupp 
759566063dSJacob Faibussowitsch   PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type));
769566063dSJacob Faibussowitsch   PetscCall((*r)(pc));
773ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
784b9ad928SBarry Smith }
794b9ad928SBarry Smith 
804b9ad928SBarry Smith /*@C
81*04c3f3b8SBarry Smith   PCGetType - Gets the `PCType` (as a string) from the `PC`
824b9ad928SBarry Smith   context.
834b9ad928SBarry Smith 
844b9ad928SBarry Smith   Not Collective
854b9ad928SBarry Smith 
864b9ad928SBarry Smith   Input Parameter:
874b9ad928SBarry Smith . pc - the preconditioner context
884b9ad928SBarry Smith 
894b9ad928SBarry Smith   Output Parameter:
90c4e43342SLisandro Dalcin . type - name of preconditioner method
914b9ad928SBarry Smith 
924b9ad928SBarry Smith   Level: intermediate
934b9ad928SBarry Smith 
94*04c3f3b8SBarry Smith .seealso: `PC`, `PCType`, `PCSetType()`
954b9ad928SBarry Smith @*/
96d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetType(PC pc, PCType *type)
97d71ae5a4SJacob Faibussowitsch {
984b9ad928SBarry Smith   PetscFunctionBegin;
990700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
1004f572ea9SToby Isaac   PetscAssertPointer(type, 2);
101c4e43342SLisandro Dalcin   *type = ((PetscObject)pc)->type_name;
1023ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1034b9ad928SBarry Smith }
1044b9ad928SBarry Smith 
10509573ac7SBarry Smith extern PetscErrorCode PCGetDefaultType_Private(PC, const char *[]);
106566e8bf2SBarry Smith 
1074b9ad928SBarry Smith /*@
108*04c3f3b8SBarry Smith   PCSetFromOptions - Sets `PC` options from the options database.
1094b9ad928SBarry Smith 
110c3339decSBarry Smith   Collective
1114b9ad928SBarry Smith 
1124b9ad928SBarry Smith   Input Parameter:
1134b9ad928SBarry Smith . pc - the preconditioner context
1144b9ad928SBarry Smith 
115f1580f4eSBarry Smith   Options Database Key:
116*04c3f3b8SBarry Smith . -pc_type - name of type, for example `bjacobi`
117b9ee023eSBarry Smith 
118*04c3f3b8SBarry Smith   Level: advanced
1194b9ad928SBarry Smith 
120*04c3f3b8SBarry Smith   Notes:
121*04c3f3b8SBarry Smith   This routine must be called before `PCSetUp()` if the user is to be
122*04c3f3b8SBarry Smith   allowed to set the preconditioner method from the options database.
1234b9ad928SBarry Smith 
124*04c3f3b8SBarry Smith   This is called from `KSPSetFromOptions()` so rarely needs to be called directly
125*04c3f3b8SBarry Smith 
126*04c3f3b8SBarry Smith .seealso: `PC`, `PCSetType()`, `PCType`, `KSPSetFromOptions()`
1274b9ad928SBarry Smith @*/
128d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions(PC pc)
129d71ae5a4SJacob Faibussowitsch {
1302fc52814SBarry Smith   char        type[256];
1312fc52814SBarry Smith   const char *def;
132ace3abfcSBarry Smith   PetscBool   flg;
1334b9ad928SBarry Smith 
1344b9ad928SBarry Smith   PetscFunctionBegin;
1350700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
1364b9ad928SBarry Smith 
1379566063dSJacob Faibussowitsch   PetscCall(PCRegisterAll());
138d0609cedSBarry Smith   PetscObjectOptionsBegin((PetscObject)pc);
1397adad957SLisandro Dalcin   if (!((PetscObject)pc)->type_name) {
1409566063dSJacob Faibussowitsch     PetscCall(PCGetDefaultType_Private(pc, &def));
1414b9ad928SBarry Smith   } else {
1427adad957SLisandro Dalcin     def = ((PetscObject)pc)->type_name;
1434b9ad928SBarry Smith   }
1444b9ad928SBarry Smith 
1459566063dSJacob Faibussowitsch   PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg));
1464b9ad928SBarry Smith   if (flg) {
1479566063dSJacob Faibussowitsch     PetscCall(PCSetType(pc, type));
1487adad957SLisandro Dalcin   } else if (!((PetscObject)pc)->type_name) {
1499566063dSJacob Faibussowitsch     PetscCall(PCSetType(pc, def));
1504b9ad928SBarry Smith   }
1514b9ad928SBarry Smith 
1529566063dSJacob Faibussowitsch   PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg));
15325c41539SBarry Smith   if (flg) goto skipoptions;
15425c41539SBarry Smith 
1559566063dSJacob Faibussowitsch   PetscCall(PetscOptionsBool("-pc_use_amat", "use Amat (instead of Pmat) to define preconditioner in nested inner solves", "PCSetUseAmat", pc->useAmat, &pc->useAmat, NULL));
156b4813acdSShri Abhyankar 
157dbbe0bcdSBarry Smith   PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject);
1585d973c19SBarry Smith 
15925c41539SBarry Smith skipoptions:
1605d973c19SBarry Smith   /* process any options handlers added with PetscObjectAddOptionsHandler() */
161dbbe0bcdSBarry Smith   PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject));
162d0609cedSBarry Smith   PetscOptionsEnd();
1630c24e6a1SHong Zhang   pc->setfromoptionscalled++;
1643ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1654b9ad928SBarry Smith }
1666c699258SBarry Smith 
1676c699258SBarry Smith /*@
168*04c3f3b8SBarry Smith   PCSetDM - Sets the `DM` that may be used by some preconditioners
1696c699258SBarry Smith 
170c3339decSBarry Smith   Logically Collective
1716c699258SBarry Smith 
1726c699258SBarry Smith   Input Parameters:
1736c699258SBarry Smith + pc - the preconditioner context
174*04c3f3b8SBarry Smith - dm - the `DM`, can be `NULL` to remove any current `DM`
1756c699258SBarry Smith 
1766c699258SBarry Smith   Level: intermediate
1776c699258SBarry Smith 
178*04c3f3b8SBarry Smith   Note:
179*04c3f3b8SBarry Smith   Users generally call  `KSPSetDM()`, `SNESSetDM()`, or `TSSetDM()` so this is rarely called directly
1806c699258SBarry Smith 
181*04c3f3b8SBarry Smith   Developer Notes:
182*04c3f3b8SBarry Smith   The routines KSP/SNES/TSSetDM() require `dm` to be non-`NULL`, but this one can be `NULL` since all it does is
183*04c3f3b8SBarry Smith   replace the current `DM`
184*04c3f3b8SBarry Smith 
185*04c3f3b8SBarry Smith .seealso: `PC`, `DM`, `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`, `SNESSetDM()`, `TSSetDM()`
1866c699258SBarry Smith @*/
187d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetDM(PC pc, DM dm)
188d71ae5a4SJacob Faibussowitsch {
1896c699258SBarry Smith   PetscFunctionBegin;
1900700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
1919566063dSJacob Faibussowitsch   if (dm) PetscCall(PetscObjectReference((PetscObject)dm));
1929566063dSJacob Faibussowitsch   PetscCall(DMDestroy(&pc->dm));
1936c699258SBarry Smith   pc->dm = dm;
1943ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
1956c699258SBarry Smith }
1966c699258SBarry Smith 
1976c699258SBarry Smith /*@
198*04c3f3b8SBarry Smith   PCGetDM - Gets the `DM` that may be used by some preconditioners
1996c699258SBarry Smith 
2003f9fe445SBarry Smith   Not Collective
2016c699258SBarry Smith 
2026c699258SBarry Smith   Input Parameter:
2036c699258SBarry Smith . pc - the preconditioner context
2046c699258SBarry Smith 
2056c699258SBarry Smith   Output Parameter:
206*04c3f3b8SBarry Smith . dm - the `DM`
2076c699258SBarry Smith 
2086c699258SBarry Smith   Level: intermediate
2096c699258SBarry Smith 
210*04c3f3b8SBarry Smith .seealso: `PC`, `DM`, `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()`
2116c699258SBarry Smith @*/
212d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetDM(PC pc, DM *dm)
213d71ae5a4SJacob Faibussowitsch {
2146c699258SBarry Smith   PetscFunctionBegin;
2150700a824SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2166c699258SBarry Smith   *dm = pc->dm;
2173ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2186c699258SBarry Smith }
2196c699258SBarry Smith 
220b07ff414SBarry Smith /*@
221*04c3f3b8SBarry Smith   PCSetApplicationContext - Sets the optional user-defined context for the preconditioner
2221b2093e4SBarry Smith 
223c3339decSBarry Smith   Logically Collective
2241b2093e4SBarry Smith 
2251b2093e4SBarry Smith   Input Parameters:
226*04c3f3b8SBarry Smith + pc   - the `PC` context
2271b2093e4SBarry Smith - usrP - optional user context
2281b2093e4SBarry Smith 
229*04c3f3b8SBarry Smith   Level: advanced
2301b2093e4SBarry Smith 
231*04c3f3b8SBarry Smith .seealso: `PC`, `PCGetApplicationContext()`
2321b2093e4SBarry Smith @*/
233d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetApplicationContext(PC pc, void *usrP)
234d71ae5a4SJacob Faibussowitsch {
2351b2093e4SBarry Smith   PetscFunctionBegin;
2361b2093e4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2371b2093e4SBarry Smith   pc->user = usrP;
2383ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2391b2093e4SBarry Smith }
2401b2093e4SBarry Smith 
241b07ff414SBarry Smith /*@
242*04c3f3b8SBarry Smith   PCGetApplicationContext - Gets the user-defined context for the preconditioner set with `PCSetApplicationContext()`
2431b2093e4SBarry Smith 
2441b2093e4SBarry Smith   Not Collective
2451b2093e4SBarry Smith 
2461b2093e4SBarry Smith   Input Parameter:
247*04c3f3b8SBarry Smith . pc - `PC` context
2481b2093e4SBarry Smith 
2491b2093e4SBarry Smith   Output Parameter:
2501b2093e4SBarry Smith . usrP - user context
2511b2093e4SBarry Smith 
2521b2093e4SBarry Smith   Level: intermediate
2531b2093e4SBarry Smith 
254*04c3f3b8SBarry Smith .seealso: `PC`, `PCSetApplicationContext()`
2551b2093e4SBarry Smith @*/
256d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetApplicationContext(PC pc, void *usrP)
257d71ae5a4SJacob Faibussowitsch {
2581b2093e4SBarry Smith   PetscFunctionBegin;
2591b2093e4SBarry Smith   PetscValidHeaderSpecific(pc, PC_CLASSID, 1);
2601b2093e4SBarry Smith   *(void **)usrP = pc->user;
2613ba16761SJacob Faibussowitsch   PetscFunctionReturn(PETSC_SUCCESS);
2621b2093e4SBarry Smith }
263