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