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