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); 62dbbe0bcdSBarry Smith 639566063dSJacob Faibussowitsch PetscCall(PetscFunctionListDestroy(&((PetscObject)pc)->qlist)); 64a7d21a52SLisandro Dalcin /* Reinitialize function pointers in PCOps structure */ 659566063dSJacob Faibussowitsch PetscCall(PetscMemzero(pc->ops, sizeof(struct _PCOps))); 66a7d21a52SLisandro Dalcin /* XXX Is this OK?? */ 670a545947SLisandro Dalcin pc->modifysubmatrices = NULL; 680a545947SLisandro Dalcin pc->modifysubmatricesP = NULL; 69a7d21a52SLisandro Dalcin /* Call the PCCreate_XXX routine for this particular preconditioner */ 70*371d2eb7SMartin Diehl pc->setupcalled = PETSC_FALSE; 712fa5cd67SKarl Rupp 729566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)pc, type)); 739566063dSJacob Faibussowitsch PetscCall((*r)(pc)); 743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 754b9ad928SBarry Smith } 764b9ad928SBarry Smith 77cc4c1da9SBarry Smith /*@ 7804c3f3b8SBarry Smith PCGetType - Gets the `PCType` (as a string) from the `PC` 794b9ad928SBarry Smith context. 804b9ad928SBarry Smith 814b9ad928SBarry Smith Not Collective 824b9ad928SBarry Smith 834b9ad928SBarry Smith Input Parameter: 844b9ad928SBarry Smith . pc - the preconditioner context 854b9ad928SBarry Smith 864b9ad928SBarry Smith Output Parameter: 87c4e43342SLisandro Dalcin . type - name of preconditioner method 884b9ad928SBarry Smith 894b9ad928SBarry Smith Level: intermediate 904b9ad928SBarry Smith 91562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCType`, `PCSetType()` 924b9ad928SBarry Smith @*/ 93d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetType(PC pc, PCType *type) 94d71ae5a4SJacob Faibussowitsch { 954b9ad928SBarry Smith PetscFunctionBegin; 960700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 974f572ea9SToby Isaac PetscAssertPointer(type, 2); 98c4e43342SLisandro Dalcin *type = ((PetscObject)pc)->type_name; 993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1004b9ad928SBarry Smith } 1014b9ad928SBarry Smith 102b4f8a55aSStefano Zampini PETSC_INTERN PetscErrorCode PCGetDefaultType_Private(PC, const char *[]); 103566e8bf2SBarry Smith 1044b9ad928SBarry Smith /*@ 10504c3f3b8SBarry Smith PCSetFromOptions - Sets `PC` options from the options database. 1064b9ad928SBarry Smith 107c3339decSBarry Smith Collective 1084b9ad928SBarry Smith 1094b9ad928SBarry Smith Input Parameter: 1104b9ad928SBarry Smith . pc - the preconditioner context 1114b9ad928SBarry Smith 112f1580f4eSBarry Smith Options Database Key: 11304c3f3b8SBarry Smith . -pc_type - name of type, for example `bjacobi` 114b9ee023eSBarry Smith 11504c3f3b8SBarry Smith Level: advanced 1164b9ad928SBarry Smith 11704c3f3b8SBarry Smith Notes: 11804c3f3b8SBarry Smith This routine must be called before `PCSetUp()` if the user is to be 11904c3f3b8SBarry Smith allowed to set the preconditioner method from the options database. 1204b9ad928SBarry Smith 12104c3f3b8SBarry Smith This is called from `KSPSetFromOptions()` so rarely needs to be called directly 12204c3f3b8SBarry Smith 123562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCSetType()`, `PCType`, `KSPSetFromOptions()` 1244b9ad928SBarry Smith @*/ 125d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetFromOptions(PC pc) 126d71ae5a4SJacob Faibussowitsch { 1272fc52814SBarry Smith char type[256]; 1282fc52814SBarry Smith const char *def; 129ace3abfcSBarry Smith PetscBool flg; 1304b9ad928SBarry Smith 1314b9ad928SBarry Smith PetscFunctionBegin; 1320700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1334b9ad928SBarry Smith 1349566063dSJacob Faibussowitsch PetscCall(PCRegisterAll()); 1357adad957SLisandro Dalcin if (!((PetscObject)pc)->type_name) { 1369566063dSJacob Faibussowitsch PetscCall(PCGetDefaultType_Private(pc, &def)); 1374b9ad928SBarry Smith } else { 1387adad957SLisandro Dalcin def = ((PetscObject)pc)->type_name; 1394b9ad928SBarry Smith } 140b4f8a55aSStefano Zampini PetscObjectOptionsBegin((PetscObject)pc); 1414b9ad928SBarry Smith 1429566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-pc_type", "Preconditioner", "PCSetType", PCList, def, type, 256, &flg)); 1434b9ad928SBarry Smith if (flg) { 1449566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, type)); 145b4f8a55aSStefano Zampini } else if (!((PetscObject)pc)->type_name && def) { 1469566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, def)); 1474b9ad928SBarry Smith } 1484b9ad928SBarry Smith 1499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &flg)); 15025c41539SBarry Smith if (flg) goto skipoptions; 15125c41539SBarry Smith 1529566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-pc_use_amat", "use Amat (instead of Pmat) to define preconditioner in nested inner solves", "PCSetUseAmat", pc->useAmat, &pc->useAmat, NULL)); 153b4813acdSShri Abhyankar 154dbbe0bcdSBarry Smith PetscTryTypeMethod(pc, setfromoptions, PetscOptionsObject); 1555d973c19SBarry Smith 15625c41539SBarry Smith skipoptions: 1575d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 158dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)pc, PetscOptionsObject)); 159d0609cedSBarry Smith PetscOptionsEnd(); 1600c24e6a1SHong Zhang pc->setfromoptionscalled++; 1613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1624b9ad928SBarry Smith } 1636c699258SBarry Smith 1646c699258SBarry Smith /*@ 16504c3f3b8SBarry Smith PCSetDM - Sets the `DM` that may be used by some preconditioners 1666c699258SBarry Smith 167c3339decSBarry Smith Logically Collective 1686c699258SBarry Smith 1696c699258SBarry Smith Input Parameters: 1706c699258SBarry Smith + pc - the preconditioner context 17104c3f3b8SBarry Smith - dm - the `DM`, can be `NULL` to remove any current `DM` 1726c699258SBarry Smith 1736c699258SBarry Smith Level: intermediate 1746c699258SBarry Smith 17504c3f3b8SBarry Smith Note: 17604c3f3b8SBarry Smith Users generally call `KSPSetDM()`, `SNESSetDM()`, or `TSSetDM()` so this is rarely called directly 1776c699258SBarry Smith 17804c3f3b8SBarry Smith Developer Notes: 17904c3f3b8SBarry Smith The routines KSP/SNES/TSSetDM() require `dm` to be non-`NULL`, but this one can be `NULL` since all it does is 18004c3f3b8SBarry Smith replace the current `DM` 18104c3f3b8SBarry Smith 182562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `DM`, `PCGetDM()`, `KSPSetDM()`, `KSPGetDM()`, `SNESSetDM()`, `TSSetDM()` 1836c699258SBarry Smith @*/ 184d71ae5a4SJacob Faibussowitsch PetscErrorCode PCSetDM(PC pc, DM dm) 185d71ae5a4SJacob Faibussowitsch { 1866c699258SBarry Smith PetscFunctionBegin; 1870700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 1889566063dSJacob Faibussowitsch if (dm) PetscCall(PetscObjectReference((PetscObject)dm)); 1899566063dSJacob Faibussowitsch PetscCall(DMDestroy(&pc->dm)); 1906c699258SBarry Smith pc->dm = dm; 1913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1926c699258SBarry Smith } 1936c699258SBarry Smith 1946c699258SBarry Smith /*@ 19504c3f3b8SBarry Smith PCGetDM - Gets the `DM` that may be used by some preconditioners 1966c699258SBarry Smith 1973f9fe445SBarry Smith Not Collective 1986c699258SBarry Smith 1996c699258SBarry Smith Input Parameter: 2006c699258SBarry Smith . pc - the preconditioner context 2016c699258SBarry Smith 2026c699258SBarry Smith Output Parameter: 20304c3f3b8SBarry Smith . dm - the `DM` 2046c699258SBarry Smith 2056c699258SBarry Smith Level: intermediate 2066c699258SBarry Smith 207562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `DM`, `PCSetDM()`, `KSPSetDM()`, `KSPGetDM()` 2086c699258SBarry Smith @*/ 209d71ae5a4SJacob Faibussowitsch PetscErrorCode PCGetDM(PC pc, DM *dm) 210d71ae5a4SJacob Faibussowitsch { 2116c699258SBarry Smith PetscFunctionBegin; 2120700a824SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 2136c699258SBarry Smith *dm = pc->dm; 2143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2156c699258SBarry Smith } 2166c699258SBarry Smith 217b07ff414SBarry Smith /*@ 21804c3f3b8SBarry Smith PCSetApplicationContext - Sets the optional user-defined context for the preconditioner 2191b2093e4SBarry Smith 220c3339decSBarry Smith Logically Collective 2211b2093e4SBarry Smith 2221b2093e4SBarry Smith Input Parameters: 22304c3f3b8SBarry Smith + pc - the `PC` context 22449abdd8aSBarry Smith - ctx - optional user context 2251b2093e4SBarry Smith 22604c3f3b8SBarry Smith Level: advanced 2271b2093e4SBarry Smith 228ce78bad3SBarry Smith Fortran Note: 229ce78bad3SBarry Smith This only works when `ctx` is a Fortran derived type (it cannot be a `PetscObject`), we recommend writing a Fortran interface definition for this 230ce78bad3SBarry Smith function that tells the Fortran compiler the derived data type that is passed in as the `ctx` argument. See `PCGetApplicationContext()` for 231ce78bad3SBarry Smith an example. 232ce78bad3SBarry Smith 233562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCGetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()`, `PetscObjectCompose()` 2341b2093e4SBarry Smith @*/ 23549abdd8aSBarry Smith PetscErrorCode PCSetApplicationContext(PC pc, void *ctx) 236d71ae5a4SJacob Faibussowitsch { 2371b2093e4SBarry Smith PetscFunctionBegin; 2381b2093e4SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 23949abdd8aSBarry Smith pc->ctx = ctx; 2403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2411b2093e4SBarry Smith } 2421b2093e4SBarry Smith 243b07ff414SBarry Smith /*@ 24404c3f3b8SBarry Smith PCGetApplicationContext - Gets the user-defined context for the preconditioner set with `PCSetApplicationContext()` 2451b2093e4SBarry Smith 2461b2093e4SBarry Smith Not Collective 2471b2093e4SBarry Smith 2481b2093e4SBarry Smith Input Parameter: 24904c3f3b8SBarry Smith . pc - `PC` context 2501b2093e4SBarry Smith 2511b2093e4SBarry Smith Output Parameter: 25249abdd8aSBarry Smith . ctx - user context 2531b2093e4SBarry Smith 2541b2093e4SBarry Smith Level: intermediate 2551b2093e4SBarry Smith 256ce78bad3SBarry Smith Fortran Notes: 257ce78bad3SBarry Smith This only works when the context is a Fortran derived type (it cannot be a `PetscObject`) and you **must** write a Fortran interface definition for this 258ce78bad3SBarry Smith function that tells the Fortran compiler the derived data type that is returned as the `ctx` argument. For example, 259ce78bad3SBarry Smith .vb 260ce78bad3SBarry Smith Interface PCGetApplicationContext 261ce78bad3SBarry Smith Subroutine PCGetApplicationContext(pc,ctx,ierr) 262ce78bad3SBarry Smith #include <petsc/finclude/petscpc.h> 263ce78bad3SBarry Smith use petscpc 264ce78bad3SBarry Smith PC pc 265ce78bad3SBarry Smith type(tUsertype), pointer :: ctx 266ce78bad3SBarry Smith PetscErrorCode ierr 267ce78bad3SBarry Smith End Subroutine 268ce78bad3SBarry Smith End Interface PCGetApplicationContext 269ce78bad3SBarry Smith .ve 270ce78bad3SBarry Smith 271bfe80ac4SPierre Jolivet The prototype for `ctx` must be 272ce78bad3SBarry Smith .vb 273ce78bad3SBarry Smith type(tUsertype), pointer :: ctx 274ce78bad3SBarry Smith .ve 275ce78bad3SBarry Smith 276562efe2eSBarry Smith .seealso: [](ch_ksp), `PC`, `PCSetApplicationContext()`, `KSPSetApplicationContext()`, `KSPGetApplicationContext()` 2771b2093e4SBarry Smith @*/ 278ce78bad3SBarry Smith PetscErrorCode PCGetApplicationContext(PC pc, PeCtx ctx) 279d71ae5a4SJacob Faibussowitsch { 2801b2093e4SBarry Smith PetscFunctionBegin; 2811b2093e4SBarry Smith PetscValidHeaderSpecific(pc, PC_CLASSID, 1); 28249abdd8aSBarry Smith *(void **)ctx = pc->ctx; 2833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2841b2093e4SBarry Smith } 285