1af0996ceSBarry Smith #include <petsc/private/snesimpl.h> /*I "petscsnes.h" I*/ 207475bc1SBarry Smith #include <petscdmshell.h> 3d96771aaSLisandro Dalcin #include <petscdraw.h> 4a01aa210SMatthew G. Knepley #include <petscds.h> 534b4d3a8SMatthew G. Knepley #include <petscdmadaptor.h> 606fc46c8SMatthew G. Knepley #include <petscconvest.h> 79b94acceSBarry Smith 8ace3abfcSBarry Smith PetscBool SNESRegisterAllCalled = PETSC_FALSE; 90298fd71SBarry Smith PetscFunctionList SNESList = NULL; 108ba1e511SMatthew Knepley 118ba1e511SMatthew Knepley /* Logging support */ 1222c6f798SBarry Smith PetscClassId SNES_CLASSID, DMSNES_CLASSID; 13e3ed9ee7SBarry Smith PetscLogEvent SNES_Solve, SNES_Setup, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14a09944afSBarry Smith 15e113a28aSBarry Smith /*@ 16e113a28aSBarry Smith SNESSetErrorIfNotConverged - Causes SNESSolve() to generate an error if the solver has not converged. 17e113a28aSBarry Smith 183f9fe445SBarry Smith Logically Collective on SNES 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21e113a28aSBarry Smith + snes - iterative context obtained from SNESCreate() 22e113a28aSBarry Smith - flg - PETSC_TRUE indicates you want the error generated 23e113a28aSBarry Smith 24e113a28aSBarry Smith Options database keys: 2567b8a455SSatish Balay . -snes_error_if_not_converged <true,false> - cause an immediate error condition and stop the program if the solver does not converge 26e113a28aSBarry Smith 27e113a28aSBarry Smith Level: intermediate 28e113a28aSBarry Smith 29e113a28aSBarry Smith Notes: 30e113a28aSBarry Smith Normally PETSc continues if a linear solver fails to converge, you can call SNESGetConvergedReason() after a SNESSolve() 31e113a28aSBarry Smith to determine if it has converged. 32e113a28aSBarry Smith 33db781477SPatrick Sanan .seealso: `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 34e113a28aSBarry Smith @*/ 357087cfbeSBarry Smith PetscErrorCode SNESSetErrorIfNotConverged(SNES snes,PetscBool flg) 36e113a28aSBarry Smith { 37e113a28aSBarry Smith PetscFunctionBegin; 38e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 39acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flg,2); 40e113a28aSBarry Smith snes->errorifnotconverged = flg; 41e113a28aSBarry Smith PetscFunctionReturn(0); 42e113a28aSBarry Smith } 43e113a28aSBarry Smith 44e113a28aSBarry Smith /*@ 45e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 46e113a28aSBarry Smith 47e113a28aSBarry Smith Not Collective 48e113a28aSBarry Smith 49e113a28aSBarry Smith Input Parameter: 50e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 51e113a28aSBarry Smith 52e113a28aSBarry Smith Output Parameter: 53e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 54e113a28aSBarry Smith 55e113a28aSBarry Smith Level: intermediate 56e113a28aSBarry Smith 57db781477SPatrick Sanan .seealso: `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 58e113a28aSBarry Smith @*/ 597087cfbeSBarry Smith PetscErrorCode SNESGetErrorIfNotConverged(SNES snes,PetscBool *flag) 60e113a28aSBarry Smith { 61e113a28aSBarry Smith PetscFunctionBegin; 62e113a28aSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 63534a8f05SLisandro Dalcin PetscValidBoolPointer(flag,2); 64e113a28aSBarry Smith *flag = snes->errorifnotconverged; 65e113a28aSBarry Smith PetscFunctionReturn(0); 66e113a28aSBarry Smith } 67e113a28aSBarry Smith 684fc747eaSLawrence Mitchell /*@ 694fc747eaSLawrence Mitchell SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 704fc747eaSLawrence Mitchell 714fc747eaSLawrence Mitchell Logically Collective on SNES 724fc747eaSLawrence Mitchell 734fc747eaSLawrence Mitchell Input Parameters: 744fc747eaSLawrence Mitchell + snes - the shell SNES 754fc747eaSLawrence Mitchell - flg - is the residual computed? 764fc747eaSLawrence Mitchell 774fc747eaSLawrence Mitchell Level: advanced 784fc747eaSLawrence Mitchell 79db781477SPatrick Sanan .seealso: `SNESGetAlwaysComputesFinalResidual()` 804fc747eaSLawrence Mitchell @*/ 814fc747eaSLawrence Mitchell PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 824fc747eaSLawrence Mitchell { 834fc747eaSLawrence Mitchell PetscFunctionBegin; 844fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 854fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 864fc747eaSLawrence Mitchell PetscFunctionReturn(0); 874fc747eaSLawrence Mitchell } 884fc747eaSLawrence Mitchell 894fc747eaSLawrence Mitchell /*@ 904fc747eaSLawrence Mitchell SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 914fc747eaSLawrence Mitchell 924fc747eaSLawrence Mitchell Logically Collective on SNES 934fc747eaSLawrence Mitchell 944fc747eaSLawrence Mitchell Input Parameter: 954fc747eaSLawrence Mitchell . snes - the shell SNES 964fc747eaSLawrence Mitchell 974fc747eaSLawrence Mitchell Output Parameter: 984fc747eaSLawrence Mitchell . flg - is the residual computed? 994fc747eaSLawrence Mitchell 1004fc747eaSLawrence Mitchell Level: advanced 1014fc747eaSLawrence Mitchell 102db781477SPatrick Sanan .seealso: `SNESSetAlwaysComputesFinalResidual()` 1034fc747eaSLawrence Mitchell @*/ 1044fc747eaSLawrence Mitchell PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 1054fc747eaSLawrence Mitchell { 1064fc747eaSLawrence Mitchell PetscFunctionBegin; 1074fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1084fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1094fc747eaSLawrence Mitchell PetscFunctionReturn(0); 1104fc747eaSLawrence Mitchell } 1114fc747eaSLawrence Mitchell 112e725d27bSBarry Smith /*@ 113bf388a1fSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 1144936397dSBarry Smith in the functions domain. For example, negative pressure. 1154936397dSBarry Smith 1163f9fe445SBarry Smith Logically Collective on SNES 1174936397dSBarry Smith 1184936397dSBarry Smith Input Parameters: 1196a388c36SPeter Brune . snes - the SNES context 1204936397dSBarry Smith 12128529972SSatish Balay Level: advanced 1224936397dSBarry Smith 123db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction` 1244936397dSBarry Smith @*/ 1257087cfbeSBarry Smith PetscErrorCode SNESSetFunctionDomainError(SNES snes) 1264936397dSBarry Smith { 1274936397dSBarry Smith PetscFunctionBegin; 1280700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1295f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates input vector is not in the function domain"); 1304936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1314936397dSBarry Smith PetscFunctionReturn(0); 1324936397dSBarry Smith } 1334936397dSBarry Smith 1346a388c36SPeter Brune /*@ 13507b62357SFande Kong SNESSetJacobianDomainError - tells SNES that computeJacobian does not make sense any more. For example there is a negative element transformation. 13607b62357SFande Kong 13707b62357SFande Kong Logically Collective on SNES 13807b62357SFande Kong 13907b62357SFande Kong Input Parameters: 14007b62357SFande Kong . snes - the SNES context 14107b62357SFande Kong 14207b62357SFande Kong Level: advanced 14307b62357SFande Kong 144db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()` 14507b62357SFande Kong @*/ 14607b62357SFande Kong PetscErrorCode SNESSetJacobianDomainError(SNES snes) 14707b62357SFande Kong { 14807b62357SFande Kong PetscFunctionBegin; 14907b62357SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1505f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"User code indicates computeJacobian does not make sense"); 15107b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 15207b62357SFande Kong PetscFunctionReturn(0); 15307b62357SFande Kong } 15407b62357SFande Kong 15507b62357SFande Kong /*@ 156b351a90bSFande Kong SNESSetCheckJacobianDomainError - if or not to check jacobian domain error after each Jacobian evaluation. By default, we check Jacobian domain error 157b351a90bSFande Kong in the debug mode, and do not check it in the optimized mode. 158b351a90bSFande Kong 159b351a90bSFande Kong Logically Collective on SNES 160b351a90bSFande Kong 161b351a90bSFande Kong Input Parameters: 162a2b725a8SWilliam Gropp + snes - the SNES context 163a2b725a8SWilliam Gropp - flg - indicates if or not to check jacobian domain error after each Jacobian evaluation 164b351a90bSFande Kong 165b351a90bSFande Kong Level: advanced 166b351a90bSFande Kong 167db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 168b351a90bSFande Kong @*/ 169b351a90bSFande Kong PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) 170b351a90bSFande Kong { 171b351a90bSFande Kong PetscFunctionBegin; 172b351a90bSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 173b351a90bSFande Kong snes->checkjacdomainerror = flg; 174b351a90bSFande Kong PetscFunctionReturn(0); 175b351a90bSFande Kong } 176b351a90bSFande Kong 177b351a90bSFande Kong /*@ 1788383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 1798383d7d7SFande Kong 1808383d7d7SFande Kong Logically Collective on SNES 1818383d7d7SFande Kong 1828383d7d7SFande Kong Input Parameters: 1838383d7d7SFande Kong . snes - the SNES context 1848383d7d7SFande Kong 1858383d7d7SFande Kong Output Parameters: 1868383d7d7SFande Kong . flg - PETSC_FALSE indicates that we don't check jacobian domain errors after each Jacobian evaluation 1878383d7d7SFande Kong 1888383d7d7SFande Kong Level: advanced 1898383d7d7SFande Kong 190db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 1918383d7d7SFande Kong @*/ 1928383d7d7SFande Kong PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) 1938383d7d7SFande Kong { 1948383d7d7SFande Kong PetscFunctionBegin; 1958383d7d7SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 196534a8f05SLisandro Dalcin PetscValidBoolPointer(flg,2); 1978383d7d7SFande Kong *flg = snes->checkjacdomainerror; 1988383d7d7SFande Kong PetscFunctionReturn(0); 1998383d7d7SFande Kong } 2008383d7d7SFande Kong 2018383d7d7SFande Kong /*@ 202c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 2036a388c36SPeter Brune 2046a388c36SPeter Brune Logically Collective on SNES 2056a388c36SPeter Brune 2066a388c36SPeter Brune Input Parameters: 2076a388c36SPeter Brune . snes - the SNES context 2086a388c36SPeter Brune 2096a388c36SPeter Brune Output Parameters: 210bf388a1fSBarry Smith . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 2116a388c36SPeter Brune 2126a388c36SPeter Brune Level: advanced 2136a388c36SPeter Brune 214db781477SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 2156a388c36SPeter Brune @*/ 2166a388c36SPeter Brune PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 2176a388c36SPeter Brune { 2186a388c36SPeter Brune PetscFunctionBegin; 2196a388c36SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 220534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror,2); 2216a388c36SPeter Brune *domainerror = snes->domainerror; 2226a388c36SPeter Brune PetscFunctionReturn(0); 2236a388c36SPeter Brune } 2246a388c36SPeter Brune 22507b62357SFande Kong /*@ 22607b62357SFande Kong SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to SNESComputeJacobian; 22707b62357SFande Kong 22807b62357SFande Kong Logically Collective on SNES 22907b62357SFande Kong 23007b62357SFande Kong Input Parameters: 23107b62357SFande Kong . snes - the SNES context 23207b62357SFande Kong 23307b62357SFande Kong Output Parameters: 23407b62357SFande Kong . domainerror - Set to PETSC_TRUE if there's a jacobian domain error; PETSC_FALSE otherwise. 23507b62357SFande Kong 23607b62357SFande Kong Level: advanced 23707b62357SFande Kong 238c2e3fba1SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 23907b62357SFande Kong @*/ 24007b62357SFande Kong PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) 24107b62357SFande Kong { 24207b62357SFande Kong PetscFunctionBegin; 24307b62357SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 244534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror,2); 24507b62357SFande Kong *domainerror = snes->jacobiandomainerror; 24607b62357SFande Kong PetscFunctionReturn(0); 24707b62357SFande Kong } 24807b62357SFande Kong 24955849f57SBarry Smith /*@C 25055849f57SBarry Smith SNESLoad - Loads a SNES that has been stored in binary with SNESView(). 25155849f57SBarry Smith 25255849f57SBarry Smith Collective on PetscViewer 25355849f57SBarry Smith 25455849f57SBarry Smith Input Parameters: 25555849f57SBarry Smith + newdm - the newly loaded SNES, this needs to have been created with SNESCreate() or 25655849f57SBarry Smith some related function before a call to SNESLoad(). 25755849f57SBarry Smith - viewer - binary file viewer, obtained from PetscViewerBinaryOpen() 25855849f57SBarry Smith 25955849f57SBarry Smith Level: intermediate 26055849f57SBarry Smith 26155849f57SBarry Smith Notes: 26255849f57SBarry Smith The type is determined by the data in the file, any type set into the SNES before this call is ignored. 26355849f57SBarry Smith 26455849f57SBarry Smith Notes for advanced users: 26555849f57SBarry Smith Most users should not need to know the details of the binary storage 26655849f57SBarry Smith format, since SNESLoad() and TSView() completely hide these details. 26755849f57SBarry Smith But for anyone who's interested, the standard binary matrix storage 26855849f57SBarry Smith format is 26955849f57SBarry Smith .vb 27055849f57SBarry Smith has not yet been determined 27155849f57SBarry Smith .ve 27255849f57SBarry Smith 273db781477SPatrick Sanan .seealso: `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()` 27455849f57SBarry Smith @*/ 2752d53ad75SBarry Smith PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 27655849f57SBarry Smith { 27755849f57SBarry Smith PetscBool isbinary; 278060da220SMatthew G. Knepley PetscInt classid; 27955849f57SBarry Smith char type[256]; 28055849f57SBarry Smith KSP ksp; 2812d53ad75SBarry Smith DM dm; 2822d53ad75SBarry Smith DMSNES dmsnes; 28355849f57SBarry Smith 28455849f57SBarry Smith PetscFunctionBegin; 2852d53ad75SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28655849f57SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 2879566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 2885f80ce2aSJacob Faibussowitsch PetscCheck(isbinary,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONG,"Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 28955849f57SBarry Smith 2909566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer,&classid,1,NULL,PETSC_INT)); 2915f80ce2aSJacob Faibussowitsch PetscCheck(classid == SNES_FILE_CLASSID,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Not SNES next in file"); 2929566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer,type,256,NULL,PETSC_CHAR)); 2939566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 2942d53ad75SBarry Smith if (snes->ops->load) { 2959566063dSJacob Faibussowitsch PetscCall((*snes->ops->load)(snes,viewer)); 296f2c2a1b9SBarry Smith } 2979566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 2989566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&dmsnes)); 2999566063dSJacob Faibussowitsch PetscCall(DMSNESLoad(dmsnes,viewer)); 3009566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 3019566063dSJacob Faibussowitsch PetscCall(KSPLoad(ksp,viewer)); 30255849f57SBarry Smith PetscFunctionReturn(0); 30355849f57SBarry Smith } 3046a388c36SPeter Brune 3059804daf3SBarry Smith #include <petscdraw.h> 306e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 307e04113cfSBarry Smith #include <petscviewersaws.h> 308bfb97211SBarry Smith #endif 3098404b7f3SBarry Smith 310fe2efc57SMark /*@C 311fe2efc57SMark SNESViewFromOptions - View from Options 312fe2efc57SMark 313fe2efc57SMark Collective on SNES 314fe2efc57SMark 315fe2efc57SMark Input Parameters: 316fe2efc57SMark + A - the application ordering context 317736c3998SJose E. Roman . obj - Optional object 318736c3998SJose E. Roman - name - command line option 319fe2efc57SMark 320fe2efc57SMark Level: intermediate 321db781477SPatrick Sanan .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 322fe2efc57SMark @*/ 323fe2efc57SMark PetscErrorCode SNESViewFromOptions(SNES A,PetscObject obj,const char name[]) 324fe2efc57SMark { 325fe2efc57SMark PetscFunctionBegin; 326fe2efc57SMark PetscValidHeaderSpecific(A,SNES_CLASSID,1); 3279566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A,obj,name)); 328fe2efc57SMark PetscFunctionReturn(0); 329fe2efc57SMark } 330fe2efc57SMark 331789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES,Vec,Mat,Mat,void*); 332789d8953SBarry Smith 3337e2c5f70SBarry Smith /*@C 3349b94acceSBarry Smith SNESView - Prints the SNES data structure. 3359b94acceSBarry Smith 3364c49b128SBarry Smith Collective on SNES 337fee21e36SBarry Smith 338c7afd0dbSLois Curfman McInnes Input Parameters: 339c7afd0dbSLois Curfman McInnes + SNES - the SNES context 340c7afd0dbSLois Curfman McInnes - viewer - visualization context 341c7afd0dbSLois Curfman McInnes 3429b94acceSBarry Smith Options Database Key: 343c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 3449b94acceSBarry Smith 3459b94acceSBarry Smith Notes: 3469b94acceSBarry Smith The available visualization contexts include 347b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 348b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 349c8a8ba5cSLois Curfman McInnes output where only the first processor opens 350c8a8ba5cSLois Curfman McInnes the file. All other processors send their 351c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3529b94acceSBarry Smith 353052bf0daSPierre Jolivet The available formats include 354052bf0daSPierre Jolivet + PETSC_VIEWER_DEFAULT - standard output (default) 355052bf0daSPierre Jolivet - PETSC_VIEWER_ASCII_INFO_DETAIL - more verbose output for SNESNASM 356052bf0daSPierre Jolivet 3573e081fefSLois Curfman McInnes The user can open an alternative visualization context with 358b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 3599b94acceSBarry Smith 360595c91d4SBarry Smith In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer). 361595c91d4SBarry Smith 36236851e7fSLois Curfman McInnes Level: beginner 36336851e7fSLois Curfman McInnes 364db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()` 3659b94acceSBarry Smith @*/ 3667087cfbeSBarry Smith PetscErrorCode SNESView(SNES snes,PetscViewer viewer) 3679b94acceSBarry Smith { 368fa9f3622SBarry Smith SNESKSPEW *kctx; 36994b7f48cSBarry Smith KSP ksp; 3707f1410a3SPeter Brune SNESLineSearch linesearch; 37172a02f06SBarry Smith PetscBool iascii,isstring,isbinary,isdraw; 3722d53ad75SBarry Smith DMSNES dmsnes; 373e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 374536b137fSBarry Smith PetscBool issaws; 375bfb97211SBarry Smith #endif 3769b94acceSBarry Smith 3773a40ed3dSBarry Smith PetscFunctionBegin; 3780700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3793050cee2SBarry Smith if (!viewer) { 3809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&viewer)); 3813050cee2SBarry Smith } 3820700a824SBarry Smith PetscValidHeaderSpecific(viewer,PETSC_VIEWER_CLASSID,2); 383c9780b6fSBarry Smith PetscCheckSameComm(snes,1,viewer,2); 38474679c65SBarry Smith 3859566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&iascii)); 3869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSTRING,&isstring)); 3879566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERBINARY,&isbinary)); 3889566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERDRAW,&isdraw)); 389e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 3909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERSAWS,&issaws)); 391bfb97211SBarry Smith #endif 39232077d6dSBarry Smith if (iascii) { 393dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3948404b7f3SBarry Smith DM dm; 3958404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES,Vec,Mat,Mat,void*); 3968404b7f3SBarry Smith void *ctx; 397789d8953SBarry Smith const char *pre = ""; 398dc0571f2SMatthew G. Knepley 3999566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes,viewer)); 400fce1e034SJed Brown if (!snes->setupcalled) { 4019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," SNES has not been set up so information may be incomplete\n")); 402fce1e034SJed Brown } 403e7788613SBarry Smith if (snes->ops->view) { 4049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 4059566063dSJacob Faibussowitsch PetscCall((*snes->ops->view)(snes,viewer)); 4069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 4070ef38995SBarry Smith } 40863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n",snes->max_its,snes->max_funcs)); 4099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," tolerances: relative=%g, absolute=%g, solution=%g\n",(double)snes->rtol,(double)snes->abstol,(double)snes->stol)); 410efd4aadfSBarry Smith if (snes->usesksp) { 41163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," total number of linear solver iterations=%" PetscInt_FMT "\n",snes->linear_its)); 412efd4aadfSBarry Smith } 41363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," total number of function evaluations=%" PetscInt_FMT "\n",snes->nfuncs)); 4149566063dSJacob Faibussowitsch PetscCall(SNESGetNormSchedule(snes, &normschedule)); 4159566063dSJacob Faibussowitsch if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer," norm schedule %s\n",SNESNormSchedules[normschedule])); 41617fe4bdfSPeter Brune if (snes->gridsequence) { 41763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," total number of grid sequence refinements=%" PetscInt_FMT "\n",snes->gridsequence)); 41817fe4bdfSPeter Brune } 4199b94acceSBarry Smith if (snes->ksp_ewconv) { 420fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 4219b94acceSBarry Smith if (kctx) { 42263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n",kctx->version)); 4239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," rtol_0=%g, rtol_max=%g, threshold=%g\n",(double)kctx->rtol_0,(double)kctx->rtol_max,(double)kctx->threshold)); 4249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," gamma=%g, alpha=%g, alpha2=%g\n",(double)kctx->gamma,(double)kctx->alpha,(double)kctx->alpha2)); 4259b94acceSBarry Smith } 4269b94acceSBarry Smith } 427eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 4289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Preconditioned is never rebuilt\n")); 429eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 43063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n",snes->lagpreconditioner)); 431eb1f6c34SBarry Smith } 432eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 4339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is never rebuilt\n")); 434eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 43563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n",snes->lagjacobian)); 436eb1f6c34SBarry Smith } 4379566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 4389566063dSJacob Faibussowitsch PetscCall(DMSNESGetJacobian(dm,&cJ,&ctx)); 439789d8953SBarry Smith if (snes->mf_operator) { 4409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing\n")); 441789d8953SBarry Smith pre = "Preconditioning "; 442789d8953SBarry Smith } 4438404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 4449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences one column at a time\n",pre)); 4458404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 4469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using finite differences with coloring\n",pre)); 447789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 448789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 449789d8953SBarry Smith MatFDColoring fdcoloring; 4509566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm,"DMDASNES_FDCOLORING",(PetscObject*)&fdcoloring)); 451789d8953SBarry Smith if (fdcoloring) { 4529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using colored finite differences on a DMDA\n",pre)); 453789d8953SBarry Smith } else { 4549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," %sJacobian is built using a DMDA local Jacobian\n",pre)); 455789d8953SBarry Smith } 456789d8953SBarry Smith } else if (snes->mf) { 4579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 4588404b7f3SBarry Smith } 4590f5bd95cSBarry Smith } else if (isstring) { 460317d6ea6SBarry Smith const char *type; 4619566063dSJacob Faibussowitsch PetscCall(SNESGetType(snes,&type)); 4629566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSPrintf(viewer," SNESType: %-7.7s",type)); 4639566063dSJacob Faibussowitsch if (snes->ops->view) PetscCall((*snes->ops->view)(snes,viewer)); 46455849f57SBarry Smith } else if (isbinary) { 46555849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 46655849f57SBarry Smith MPI_Comm comm; 46755849f57SBarry Smith PetscMPIInt rank; 46855849f57SBarry Smith char type[256]; 46955849f57SBarry Smith 4709566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes,&comm)); 4719566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm,&rank)); 472dd400576SPatrick Sanan if (rank == 0) { 4739566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer,&classid,1,PETSC_INT)); 4749566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type,((PetscObject)snes)->type_name,sizeof(type))); 4759566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer,type,sizeof(type),PETSC_CHAR)); 47655849f57SBarry Smith } 47755849f57SBarry Smith if (snes->ops->view) { 4789566063dSJacob Faibussowitsch PetscCall((*snes->ops->view)(snes,viewer)); 47955849f57SBarry Smith } 48072a02f06SBarry Smith } else if (isdraw) { 48172a02f06SBarry Smith PetscDraw draw; 48272a02f06SBarry Smith char str[36]; 48389fd9fafSBarry Smith PetscReal x,y,bottom,h; 48472a02f06SBarry Smith 4859566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw)); 4869566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCurrentPoint(draw,&x,&y)); 4879566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(str,"SNES: ",sizeof(str))); 4889566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(str,((PetscObject)snes)->type_name,sizeof(str))); 4899566063dSJacob Faibussowitsch PetscCall(PetscDrawStringBoxed(draw,x,y,PETSC_DRAW_BLUE,PETSC_DRAW_BLACK,str,NULL,&h)); 49089fd9fafSBarry Smith bottom = y - h; 4919566063dSJacob Faibussowitsch PetscCall(PetscDrawPushCurrentPoint(draw,x,bottom)); 492c4646bacSPeter Brune if (snes->ops->view) { 4939566063dSJacob Faibussowitsch PetscCall((*snes->ops->view)(snes,viewer)); 494c4646bacSPeter Brune } 495e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 496536b137fSBarry Smith } else if (issaws) { 497d45a07a7SBarry Smith PetscMPIInt rank; 4982657e9d9SBarry Smith const char *name; 499d45a07a7SBarry Smith 5009566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)snes,&name)); 5019566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD,&rank)); 502dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 503d45a07a7SBarry Smith char dir[1024]; 504d45a07a7SBarry Smith 5059566063dSJacob Faibussowitsch PetscCall(PetscObjectViewSAWs((PetscObject)snes,viewer)); 5069566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/its",name)); 5072657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,&snes->iter,1,SAWs_READ,SAWs_INT)); 508bfb97211SBarry Smith if (!snes->conv_hist) { 5099566063dSJacob Faibussowitsch PetscCall(SNESSetConvergenceHistory(snes,NULL,NULL,PETSC_DECIDE,PETSC_TRUE)); 510bfb97211SBarry Smith } 5119566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir,1024,"/PETSc/Objects/%s/conv_hist",name)); 5122657e9d9SBarry Smith PetscStackCallSAWs(SAWs_Register,(dir,snes->conv_hist,10,SAWs_READ,SAWs_DOUBLE)); 513f05ece33SBarry Smith } 514bfb97211SBarry Smith #endif 51572a02f06SBarry Smith } 51672a02f06SBarry Smith if (snes->linesearch) { 5179566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 5189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5199566063dSJacob Faibussowitsch PetscCall(SNESLineSearchView(linesearch, viewer)); 5209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 52119bcc07fSBarry Smith } 522efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 5239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5249566063dSJacob Faibussowitsch PetscCall(SNESView(snes->npc, viewer)); 5259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5264a0c5b0cSMatthew G Knepley } 5279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5289566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm,&dmsnes)); 5299566063dSJacob Faibussowitsch PetscCall(DMSNESView(dmsnes, viewer)); 5309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5312c155ee1SBarry Smith if (snes->usesksp) { 5329566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 5339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5349566063dSJacob Faibussowitsch PetscCall(KSPView(ksp,viewer)); 5359566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5362c155ee1SBarry Smith } 53772a02f06SBarry Smith if (isdraw) { 53872a02f06SBarry Smith PetscDraw draw; 5399566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer,0,&draw)); 5409566063dSJacob Faibussowitsch PetscCall(PetscDrawPopCurrentPoint(draw)); 5417f1410a3SPeter Brune } 5423a40ed3dSBarry Smith PetscFunctionReturn(0); 5439b94acceSBarry Smith } 5449b94acceSBarry Smith 54576b2cf59SMatthew Knepley /* 54676b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 54776b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 54876b2cf59SMatthew Knepley */ 54976b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 550a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5516849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 55276b2cf59SMatthew Knepley 553ac226902SBarry Smith /*@C 55476b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 55576b2cf59SMatthew Knepley 55676b2cf59SMatthew Knepley Not Collective 55776b2cf59SMatthew Knepley 55876b2cf59SMatthew Knepley Input Parameter: 55976b2cf59SMatthew Knepley . snescheck - function that checks for options 56076b2cf59SMatthew Knepley 56176b2cf59SMatthew Knepley Level: developer 56276b2cf59SMatthew Knepley 563db781477SPatrick Sanan .seealso: `SNESSetFromOptions()` 56476b2cf59SMatthew Knepley @*/ 5657087cfbeSBarry Smith PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 56676b2cf59SMatthew Knepley { 56776b2cf59SMatthew Knepley PetscFunctionBegin; 56863a3b9bcSJacob Faibussowitsch PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 56976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 57076b2cf59SMatthew Knepley PetscFunctionReturn(0); 57176b2cf59SMatthew Knepley } 57276b2cf59SMatthew Knepley 57325acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES,Vec,Mat*); 574aa3661deSLisandro Dalcin 575ace3abfcSBarry Smith static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 576aa3661deSLisandro Dalcin { 577aa3661deSLisandro Dalcin Mat J; 578895c21f2SBarry Smith MatNullSpace nullsp; 579aa3661deSLisandro Dalcin 580aa3661deSLisandro Dalcin PetscFunctionBegin; 5810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 582aa3661deSLisandro Dalcin 58398613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 58498613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5859566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A ? A : B, NULL,&snes->vec_func)); 58698613b67SLisandro Dalcin } 58798613b67SLisandro Dalcin 588aa3661deSLisandro Dalcin if (version == 1) { 5899566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes,&J)); 5909566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 5919566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 5921e2ae407SBarry Smith /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 593aa3661deSLisandro Dalcin } else if (version == 2) { 5945f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"SNESSetFunction() must be called first"); 595570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 5969566063dSJacob Faibussowitsch PetscCall(SNESDefaultMatrixFreeCreate2(snes,snes->vec_func,&J)); 597aa3661deSLisandro Dalcin #else 5982479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 599aa3661deSLisandro Dalcin #endif 6002479783cSJose E. Roman } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 601aa3661deSLisandro Dalcin 602895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 603895c21f2SBarry Smith if (snes->jacobian) { 6049566063dSJacob Faibussowitsch PetscCall(MatGetNullSpace(snes->jacobian,&nullsp)); 605895c21f2SBarry Smith if (nullsp) { 6069566063dSJacob Faibussowitsch PetscCall(MatSetNullSpace(J,nullsp)); 607895c21f2SBarry Smith } 608895c21f2SBarry Smith } 609895c21f2SBarry Smith 61063a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 611d3462f78SMatthew Knepley if (hasOperator) { 6123232da50SPeter Brune 613aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 614aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 6159566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL)); 616aa3661deSLisandro Dalcin } else { 617aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 6183232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 619b552625fSStefano Zampini if (snes->npcside == PC_LEFT && snes->npc) { 6209566063dSJacob Faibussowitsch if (!snes->jacobian) PetscCall(SNESSetJacobian(snes,J,NULL,NULL,NULL)); 621172a4300SPeter Brune } else { 622789d8953SBarry Smith KSP ksp; 623789d8953SBarry Smith PC pc; 624789d8953SBarry Smith PetscBool match; 625789d8953SBarry Smith 6269566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,J,J,MatMFFDComputeJacobian,NULL)); 627aa3661deSLisandro Dalcin /* Force no preconditioner */ 6289566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 6299566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp,&pc)); 6302698c518SLisandro Dalcin PetscCall(PetscObjectTypeCompareAny((PetscObject)pc,&match,PCSHELL,PCH2OPUS,"")); 631aa3661deSLisandro Dalcin if (!match) { 6329566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 6339566063dSJacob Faibussowitsch PetscCall(PCSetType(pc,PCNONE)); 634aa3661deSLisandro Dalcin } 635aa3661deSLisandro Dalcin } 636789d8953SBarry Smith } 6379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 638aa3661deSLisandro Dalcin PetscFunctionReturn(0); 639aa3661deSLisandro Dalcin } 640aa3661deSLisandro Dalcin 641dfe15315SJed Brown static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine,Mat Restrict,Vec Rscale,Mat Inject,DM dmcoarse,void *ctx) 642dfe15315SJed Brown { 643dfe15315SJed Brown SNES snes = (SNES)ctx; 6440298fd71SBarry Smith Vec Xfine,Xfine_named = NULL,Xcoarse; 645dfe15315SJed Brown 646dfe15315SJed Brown PetscFunctionBegin; 64716ebb321SJed Brown if (PetscLogPrintInfo) { 64816ebb321SJed Brown PetscInt finelevel,coarselevel,fineclevel,coarseclevel; 6499566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmfine,&finelevel)); 6509566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmfine,&fineclevel)); 6519566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmcoarse,&coarselevel)); 6529566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmcoarse,&coarseclevel)); 65363a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(dmfine,"Restricting SNES solution vector from level %" PetscInt_FMT "-%" PetscInt_FMT " to level %" PetscInt_FMT "-%" PetscInt_FMT "\n",finelevel,fineclevel,coarselevel,coarseclevel)); 65416ebb321SJed Brown } 655dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 656dfe15315SJed Brown else { 6579566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named)); 658dfe15315SJed Brown Xfine = Xfine_named; 659dfe15315SJed Brown } 6609566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse)); 661907f5c5aSLawrence Mitchell if (Inject) { 6629566063dSJacob Faibussowitsch PetscCall(MatRestrict(Inject,Xfine,Xcoarse)); 663907f5c5aSLawrence Mitchell } else { 6649566063dSJacob Faibussowitsch PetscCall(MatRestrict(Restrict,Xfine,Xcoarse)); 6659566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Xcoarse,Xcoarse,Rscale)); 666907f5c5aSLawrence Mitchell } 6679566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dmcoarse,"SNESVecSol",&Xcoarse)); 6689566063dSJacob Faibussowitsch if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine,"SNESVecSol",&Xfine_named)); 669dfe15315SJed Brown PetscFunctionReturn(0); 670dfe15315SJed Brown } 671dfe15315SJed Brown 67216ebb321SJed Brown static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm,DM dmc,void *ctx) 67316ebb321SJed Brown { 67416ebb321SJed Brown PetscFunctionBegin; 6759566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmc,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,ctx)); 67616ebb321SJed Brown PetscFunctionReturn(0); 67716ebb321SJed Brown } 67816ebb321SJed Brown 679a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 680a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 68123ee1639SBarry Smith static PetscErrorCode KSPComputeOperators_SNES(KSP ksp,Mat A,Mat B,void *ctx) 682caa4e7f2SJed Brown { 683caa4e7f2SJed Brown SNES snes = (SNES)ctx; 6840298fd71SBarry Smith Vec X,Xnamed = NULL; 685dfe15315SJed Brown DM dmsave; 6864e269d77SPeter Brune void *ctxsave; 68725ce1634SJed Brown PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*) = NULL; 688caa4e7f2SJed Brown 689caa4e7f2SJed Brown PetscFunctionBegin; 690dfe15315SJed Brown dmsave = snes->dm; 6919566063dSJacob Faibussowitsch PetscCall(KSPGetDM(ksp,&snes->dm)); 692dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 693dfe15315SJed Brown else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ 6949566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed)); 695dfe15315SJed Brown X = Xnamed; 6969566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes,NULL,NULL,&jac,&ctxsave)); 6974e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 6988d359177SBarry Smith if (jac == SNESComputeJacobianDefaultColor) { 6999566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,NULL,NULL,SNESComputeJacobianDefaultColor,NULL)); 700dfe15315SJed Brown } 7014e269d77SPeter Brune } 7024dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 7034dde8bb0SMatthew G. Knepley { 7044dde8bb0SMatthew G. Knepley DMSNES sdm; 7054e269d77SPeter Brune 7069566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 7074dde8bb0SMatthew G. Knepley if (!sdm->ops->computejacobian) { 7089566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 7094dde8bb0SMatthew G. Knepley } 7104dde8bb0SMatthew G. Knepley } 7112b93b426SMatthew G. Knepley /* Compute the operators */ 7129566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes,X,A,B)); 7132b93b426SMatthew G. Knepley /* Put the previous context back */ 7148d359177SBarry Smith if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) { 7159566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,NULL,NULL,jac,ctxsave)); 7164e269d77SPeter Brune } 7174e269d77SPeter Brune 7189566063dSJacob Faibussowitsch if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm,"SNESVecSol",&Xnamed)); 719dfe15315SJed Brown snes->dm = dmsave; 720caa4e7f2SJed Brown PetscFunctionReturn(0); 721caa4e7f2SJed Brown } 722caa4e7f2SJed Brown 7236cab3a1bSJed Brown /*@ 7246cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 7256cab3a1bSJed Brown 7266cab3a1bSJed Brown Collective 7276cab3a1bSJed Brown 7284165533cSJose E. Roman Input Parameter: 7296cab3a1bSJed Brown . snes - snes to configure 7306cab3a1bSJed Brown 7316cab3a1bSJed Brown Level: developer 7326cab3a1bSJed Brown 733db781477SPatrick Sanan .seealso: `SNESSetUp()` 7346cab3a1bSJed Brown @*/ 7356cab3a1bSJed Brown PetscErrorCode SNESSetUpMatrices(SNES snes) 7366cab3a1bSJed Brown { 7376cab3a1bSJed Brown DM dm; 738942e3340SBarry Smith DMSNES sdm; 7396cab3a1bSJed Brown 7406cab3a1bSJed Brown PetscFunctionBegin; 7419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 7429566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 74358b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7446cab3a1bSJed Brown Mat J; 7456cab3a1bSJed Brown void *functx; 7469566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes,&J)); 7479566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 7489566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7499566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,NULL,NULL,&functx)); 7509566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,J,J,NULL,NULL)); 7519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 752caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7536cab3a1bSJed Brown Mat J,B; 7549566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes,&J)); 7559566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J,((PetscObject)snes)->prefix)); 7569566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7579566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm,&B)); 75806f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7599566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,J,B,NULL,NULL)); 7609566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 762caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7631ba9b98eSMatthew G. Knepley PetscDS prob; 7646cab3a1bSJed Brown Mat J, B; 7651ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7661ba9b98eSMatthew G. Knepley 7676cab3a1bSJed Brown J = snes->jacobian; 7689566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 7699566063dSJacob Faibussowitsch if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 7709566063dSJacob Faibussowitsch if (J) PetscCall(PetscObjectReference((PetscObject) J)); 7719566063dSJacob Faibussowitsch else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 7729566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 7739566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 7749566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 7766cab3a1bSJed Brown } 777caa4e7f2SJed Brown { 778caa4e7f2SJed Brown KSP ksp; 7799566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 7809566063dSJacob Faibussowitsch PetscCall(KSPSetComputeOperators(ksp,KSPComputeOperators_SNES,snes)); 7819566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes)); 782caa4e7f2SJed Brown } 7836cab3a1bSJed Brown PetscFunctionReturn(0); 7846cab3a1bSJed Brown } 7856cab3a1bSJed Brown 7865e7c47f3SMatthew G. Knepley static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) 7875e7c47f3SMatthew G. Knepley { 7885e7c47f3SMatthew G. Knepley PetscInt i; 7895e7c47f3SMatthew G. Knepley 7905e7c47f3SMatthew G. Knepley PetscFunctionBegin; 7915e7c47f3SMatthew G. Knepley if (!snes->pauseFinal) PetscFunctionReturn(0); 7925e7c47f3SMatthew G. Knepley for (i = 0; i < snes->numbermonitors; ++i) { 7935e7c47f3SMatthew G. Knepley PetscViewerAndFormat *vf = (PetscViewerAndFormat *) snes->monitorcontext[i]; 7945e7c47f3SMatthew G. Knepley PetscDraw draw; 7955e7c47f3SMatthew G. Knepley PetscReal lpause; 7965e7c47f3SMatthew G. Knepley 7975e7c47f3SMatthew G. Knepley if (!vf) continue; 7985e7c47f3SMatthew G. Knepley if (vf->lg) { 7995e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 8005e7c47f3SMatthew G. Knepley if (((PetscObject) vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 8019566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 8029566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 8039566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 8049566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 8059566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 8065e7c47f3SMatthew G. Knepley } else { 8075e7c47f3SMatthew G. Knepley PetscBool isdraw; 8085e7c47f3SMatthew G. Knepley 8095e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 8105e7c47f3SMatthew G. Knepley if (((PetscObject) vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 8119566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject) vf->viewer, PETSCVIEWERDRAW, &isdraw)); 8125e7c47f3SMatthew G. Knepley if (!isdraw) continue; 8139566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 8149566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 8159566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 8169566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 8179566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 8185e7c47f3SMatthew G. Knepley } 8195e7c47f3SMatthew G. Knepley } 8205e7c47f3SMatthew G. Knepley PetscFunctionReturn(0); 8215e7c47f3SMatthew G. Knepley } 8225e7c47f3SMatthew G. Knepley 823fde5950dSBarry Smith /*@C 824fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 825fde5950dSBarry Smith 826fde5950dSBarry Smith Collective on SNES 827fde5950dSBarry Smith 828fde5950dSBarry Smith Input Parameters: 829fde5950dSBarry Smith + snes - SNES object you wish to monitor 830fde5950dSBarry Smith . name - the monitor type one is seeking 831fde5950dSBarry Smith . help - message indicating what monitoring is done 832fde5950dSBarry Smith . manual - manual page for the monitor 833fde5950dSBarry Smith . monitor - the monitor function 834fde5950dSBarry Smith - monitorsetup - a function that is called once ONLY if the user selected this monitor that may set additional features of the SNES or PetscViewer objects 835fde5950dSBarry Smith 836fde5950dSBarry Smith Level: developer 837fde5950dSBarry Smith 838db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 839db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 840db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 841db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 842c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 843db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 844db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 845fde5950dSBarry Smith @*/ 846d43b4f6eSBarry Smith PetscErrorCode SNESMonitorSetFromOptions(SNES snes,const char name[],const char help[], const char manual[],PetscErrorCode (*monitor)(SNES,PetscInt,PetscReal,PetscViewerAndFormat*),PetscErrorCode (*monitorsetup)(SNES,PetscViewerAndFormat*)) 847fde5950dSBarry Smith { 848fde5950dSBarry Smith PetscViewer viewer; 849fde5950dSBarry Smith PetscViewerFormat format; 850fde5950dSBarry Smith PetscBool flg; 851fde5950dSBarry Smith 852fde5950dSBarry Smith PetscFunctionBegin; 8539566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,name,&viewer,&format,&flg)); 854fde5950dSBarry Smith if (flg) { 855d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 8569566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer,format,&vf)); 8579566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 858fde5950dSBarry Smith if (monitorsetup) { 8599566063dSJacob Faibussowitsch PetscCall((*monitorsetup)(snes,vf)); 860fde5950dSBarry Smith } 8619566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes,(PetscErrorCode (*)(SNES,PetscInt,PetscReal,void*))monitor,vf,(PetscErrorCode (*)(void**))PetscViewerAndFormatDestroy)); 862fde5950dSBarry Smith } 863fde5950dSBarry Smith PetscFunctionReturn(0); 864fde5950dSBarry Smith } 865fde5950dSBarry Smith 8660f0abf79SStefano Zampini PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW* kctx, MPI_Comm comm, const char* prefix) 8670f0abf79SStefano Zampini { 8680f0abf79SStefano Zampini PetscFunctionBegin; 8690f0abf79SStefano Zampini PetscOptionsBegin(comm,prefix,"Eisenstat and Walker type forcing options","KSP"); 8700f0abf79SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version","Version 1, 2 or 3",NULL,kctx->version,&kctx->version,NULL)); 8710f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0","0 <= rtol0 < 1",NULL,kctx->rtol_0,&kctx->rtol_0,NULL)); 8720f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax","0 <= rtolmax < 1",NULL,kctx->rtol_max,&kctx->rtol_max,NULL)); 8730f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma","0 <= gamma <= 1",NULL,kctx->gamma,&kctx->gamma,NULL)); 8740f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha","1 < alpha <= 2",NULL,kctx->alpha,&kctx->alpha,NULL)); 8750f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2","alpha2",NULL,kctx->alpha2,&kctx->alpha2,NULL)); 8760f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold","0 < threshold < 1",NULL,kctx->threshold,&kctx->threshold,NULL)); 8770f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1","p1",NULL,kctx->v4_p1,&kctx->v4_p1,NULL)); 8780f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2","p2",NULL,kctx->v4_p2,&kctx->v4_p2,NULL)); 8790f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3","p3",NULL,kctx->v4_p3,&kctx->v4_p3,NULL)); 8800f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1","Scaling when rk-1 in [p2,p3)",NULL,kctx->v4_m1,&kctx->v4_m1,NULL)); 8810f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2","Scaling when rk-1 in [p3,+infty)",NULL,kctx->v4_m2,&kctx->v4_m2,NULL)); 8820f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3","Threshold for successive rtol (0.1 in Eq.7)",NULL,kctx->v4_m3,&kctx->v4_m3,NULL)); 8830f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4","Adaptation scaling (0.5 in Eq.7)",NULL,kctx->v4_m4,&kctx->v4_m4,NULL)); 8840f0abf79SStefano Zampini PetscOptionsEnd(); 8850f0abf79SStefano Zampini PetscFunctionReturn(0); 8860f0abf79SStefano Zampini } 8870f0abf79SStefano Zampini 8889b94acceSBarry Smith /*@ 88994b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 8909b94acceSBarry Smith 891c7afd0dbSLois Curfman McInnes Collective on SNES 892c7afd0dbSLois Curfman McInnes 8939b94acceSBarry Smith Input Parameter: 8949b94acceSBarry Smith . snes - the SNES context 8959b94acceSBarry Smith 89636851e7fSLois Curfman McInnes Options Database Keys: 897722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 89882738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 89982738288SBarry Smith of the change in the solution between steps 90070441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 901b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 902e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 903be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 904b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 905b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 9064839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 907ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 908a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 9093d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 910e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 9113d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 912b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 913f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 914f362779dSJed Brown default SNESConvergedDefault(). skip SNESConvergedSkip() means continue iterating until max_it or some other criterion is reached, saving expense 915f362779dSJed Brown of convergence test. correct_pressure SNESConvergedCorrectPressure() has special handling of a pressure null space. 916fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 917fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 918fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 919fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 9204619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 921459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 9225e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 923e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 924e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 9255968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 926b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 927e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 928e62ac41dSBarry Smith . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one computed via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 929e62ac41dSBarry Smith - -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian. 93082738288SBarry Smith 93182738288SBarry Smith Options Database for Eisenstat-Walker method: 932fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 9334b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 93436851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 93536851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 93636851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 93736851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 93836851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 93936851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 94082738288SBarry Smith 94111ca99fdSLois Curfman McInnes Notes: 942ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 943ec5066bdSBarry Smith 944ec5066bdSBarry Smith Notes: 945a5b23f4aSJose E. Roman SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 946ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 94783e2fdc7SBarry Smith 94836851e7fSLois Curfman McInnes Level: beginner 94936851e7fSLois Curfman McInnes 950db781477SPatrick Sanan .seealso: `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9519b94acceSBarry Smith @*/ 9527087cfbeSBarry Smith PetscErrorCode SNESSetFromOptions(SNES snes) 9539b94acceSBarry Smith { 9548afaa268SBarry Smith PetscBool flg,pcset,persist,set; 955d8f46077SPeter Brune PetscInt i,indx,lag,grids; 95604d7464bSBarry Smith const char *deft = SNESNEWTONLS; 957649ef022SMatthew Knepley const char *convtests[] = {"default","skip","correct_pressure"}; 95885385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9590f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 960c40d0f55SPeter Brune PCSide pcside; 961a64e098fSPeter Brune const char *optionsprefix; 9629b94acceSBarry Smith 9633a40ed3dSBarry Smith PetscFunctionBegin; 9640700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 9659566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 966d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 967639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9689566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type","Nonlinear solver method","SNESSetType",SNESList,deft,type,256,&flg)); 969d64ed03dSBarry Smith if (flg) { 9709566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes,type)); 9717adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9729566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes,deft)); 973d64ed03dSBarry Smith } 9749566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol","Stop if step length less than","SNESSetTolerances",snes->stol,&snes->stol,NULL)); 9759566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol","Stop if function norm less than","SNESSetTolerances",snes->abstol,&snes->abstol,NULL)); 976186905e3SBarry Smith 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol","Stop if decrease in function norm less than","SNESSetTolerances",snes->rtol,&snes->rtol,NULL)); 9789566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance","Stop if residual norm increases by this factor","SNESSetDivergenceTolerance",snes->divtol,&snes->divtol,NULL)); 9799566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it","Maximum iterations","SNESSetTolerances",snes->max_its,&snes->max_its,NULL)); 9809566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs","Maximum function evaluations","SNESSetTolerances",snes->max_funcs,&snes->max_funcs,NULL)); 9819566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail","Maximum nonlinear step failures","SNESSetMaxNonlinearStepFailures",snes->maxFailures,&snes->maxFailures,NULL)); 9829566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail","Maximum failures in linear solves allowed","SNESSetMaxLinearSolveFailures",snes->maxLinearSolveFailures,&snes->maxLinearSolveFailures,NULL)); 9839566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged","Generate error if solver does not converge","SNESSetErrorIfNotConverged",snes->errorifnotconverged,&snes->errorifnotconverged,NULL)); 9849566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration","Force SNESSolve() to take at least one iteration","SNESSetForceIteration",snes->forceiteration,&snes->forceiteration,NULL)); 9859566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error","Check Jacobian domain error after Jacobian evaluation","SNESCheckJacobianDomainError",snes->checkjacdomainerror,&snes->checkjacdomainerror,NULL)); 98685385478SLisandro Dalcin 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner","How often to rebuild preconditioner","SNESSetLagPreconditioner",snes->lagpreconditioner,&lag,&flg)); 988a8054027SBarry Smith if (flg) { 9895f80ce2aSJacob Faibussowitsch PetscCheck(lag != -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the preconditioner must be built as least once, perhaps you mean -2"); 9909566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes,lag)); 991a8054027SBarry Smith } 9929566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists","Preconditioner lagging through multiple SNES solves","SNESSetLagPreconditionerPersists",snes->lagjac_persist,&persist,&flg)); 99337ec4e1aSPeter Brune if (flg) { 9949566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditionerPersists(snes,persist)); 99537ec4e1aSPeter Brune } 9969566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian","How often to rebuild Jacobian","SNESSetLagJacobian",snes->lagjacobian,&lag,&flg)); 997e35cf81dSBarry Smith if (flg) { 9985f80ce2aSJacob Faibussowitsch PetscCheck(lag != -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Cannot set the lag to -1 from the command line since the Jacobian must be built as least once, perhaps you mean -2"); 9999566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes,lag)); 1000e35cf81dSBarry Smith } 10019566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists","Jacobian lagging through multiple SNES solves","SNESSetLagJacobianPersists",snes->lagjac_persist,&persist,&flg)); 100237ec4e1aSPeter Brune if (flg) { 10039566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobianPersists(snes,persist)); 100437ec4e1aSPeter Brune } 100537ec4e1aSPeter Brune 10069566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence","Use grid sequencing to generate initial guess","SNESSetGridSequence",snes->gridsequence,&grids,&flg)); 1007efd51863SBarry Smith if (flg) { 10089566063dSJacob Faibussowitsch PetscCall(SNESSetGridSequence(snes,grids)); 1009efd51863SBarry Smith } 1010a8054027SBarry Smith 10119566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test","Convergence test","SNESSetConvergenceTest",convtests,sizeof(convtests)/sizeof(char*),"default",&indx,&flg)); 101285385478SLisandro Dalcin if (flg) { 101385385478SLisandro Dalcin switch (indx) { 10149566063dSJacob Faibussowitsch case 0: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedDefault,NULL,NULL)); break; 10159566063dSJacob Faibussowitsch case 1: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedSkip,NULL,NULL)); break; 10169566063dSJacob Faibussowitsch case 2: PetscCall(SNESSetConvergenceTest(snes,SNESConvergedCorrectPressure,NULL,NULL)); break; 101785385478SLisandro Dalcin } 101885385478SLisandro Dalcin } 101985385478SLisandro Dalcin 10209566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule","SNES Norm schedule","SNESSetNormSchedule",SNESNormSchedules,5,"function",&indx,&flg)); 10219566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes,(SNESNormSchedule)indx)); 1022fdacfa88SPeter Brune 10239566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type","SNES Norm schedule","SNESSetFunctionType",SNESFunctionTypes,2,"unpreconditioned",&indx,&flg)); 10249566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes,(SNESFunctionType)indx)); 1025186905e3SBarry Smith 102685385478SLisandro Dalcin kctx = (SNESKSPEW*)snes->kspconvctx; 102785385478SLisandro Dalcin 10289566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew","Use Eisentat-Walker linear system convergence test","SNESKSPSetUseEW",snes->ksp_ewconv,&snes->ksp_ewconv,NULL)); 1029186905e3SBarry Smith 10300f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix)); 10310f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix,sizeof(ewprefix),"%s%s",optionsprefix ? optionsprefix : "","snes_")); 10320f0abf79SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx,PetscObjectComm((PetscObject)snes),ewprefix)); 10330f0abf79SStefano Zampini 10349566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_ksp_ew_version","Version 1, 2 or 3","SNESKSPSetParametersEW",kctx->version,&kctx->version,NULL)); 10359566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0","0 <= rtol0 < 1","SNESKSPSetParametersEW",kctx->rtol_0,&kctx->rtol_0,NULL)); 10369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax","0 <= rtolmax < 1","SNESKSPSetParametersEW",kctx->rtol_max,&kctx->rtol_max,NULL)); 10379566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma","0 <= gamma <= 1","SNESKSPSetParametersEW",kctx->gamma,&kctx->gamma,NULL)); 10389566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha","1 < alpha <= 2","SNESKSPSetParametersEW",kctx->alpha,&kctx->alpha,NULL)); 10399566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2","alpha2","SNESKSPSetParametersEW",kctx->alpha2,&kctx->alpha2,NULL)); 10409566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold","0 < threshold < 1","SNESKSPSetParametersEW",kctx->threshold,&kctx->threshold,NULL)); 1041186905e3SBarry Smith 104290d69ab7SBarry Smith flg = PETSC_FALSE; 10439566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel","Remove all monitors","SNESMonitorCancel",flg,&flg,&set)); 10449566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1045eabae89aSBarry Smith 10469566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor","Monitor norm of function","SNESMonitorDefault",SNESMonitorDefault,SNESMonitorDefaultSetUp)); 10479566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_short","Monitor norm of function with fewer digits","SNESMonitorDefaultShort",SNESMonitorDefaultShort,NULL)); 10489566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_range","Monitor range of elements of function","SNESMonitorRange",SNESMonitorRange,NULL)); 1049eabae89aSBarry Smith 10509566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_ratio","Monitor ratios of the norm of function for consecutive steps","SNESMonitorRatio",SNESMonitorRatio,SNESMonitorRatioSetUp)); 10519566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_field","Monitor norm of function (split into fields)","SNESMonitorDefaultField",SNESMonitorDefaultField,NULL)); 10529566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution","View solution at each iteration","SNESMonitorSolution",SNESMonitorSolution,NULL)); 10539566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_solution_update","View correction at each iteration","SNESMonitorSolutionUpdate",SNESMonitorSolutionUpdate,NULL)); 10549566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_residual","View residual at each iteration","SNESMonitorResidual",SNESMonitorResidual,NULL)); 10559566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_jacupdate_spectrum","Print the change in the spectrum of the Jacobian","SNESMonitorJacUpdateSpectrum",SNESMonitorJacUpdateSpectrum,NULL)); 10569566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes,"-snes_monitor_fields","Monitor norm of function per field","SNESMonitorSet",SNESMonitorFields,NULL)); 10579566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10582db13446SMatthew G. Knepley 10599566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python","Use Python function","SNESMonitorSet",NULL,monfilename,sizeof(monfilename),&flg)); 10609566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes,monfilename)); 10615180491cSLisandro Dalcin 106290d69ab7SBarry Smith flg = PETSC_FALSE; 10639566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range","Plot function range at each iteration","SNESMonitorLGRange",flg,&flg,NULL)); 1064459f5d12SBarry Smith if (flg) { 1065459f5d12SBarry Smith PetscViewer ctx; 1066e24b481bSBarry Smith 10679566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,NULL,PETSC_DECIDE,PETSC_DECIDE,400,300,&ctx)); 10689566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes,SNESMonitorLGRange,ctx,(PetscErrorCode (*)(void**))PetscViewerDestroy)); 1069459f5d12SBarry Smith } 10702e7541e6SPeter Brune 107190d69ab7SBarry Smith flg = PETSC_FALSE; 10729566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel","Remove all converged reason viewers","SNESConvergedReasonViewCancel",flg,&flg,&set)); 10739566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1074c4421ceaSFande Kong 1075c4421ceaSFande Kong flg = PETSC_FALSE; 10769566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd","Use finite differences (slow) to compute Jacobian","SNESComputeJacobianDefault",flg,&flg,NULL)); 10774b27c08aSLois Curfman McInnes if (flg) { 10786cab3a1bSJed Brown void *functx; 1079b1f624c7SBarry Smith DM dm; 1080b1f624c7SBarry Smith DMSNES sdm; 10819566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 10829566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 1083b1f624c7SBarry Smith sdm->jacobianctx = NULL; 10849566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,NULL,NULL,&functx)); 10859566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefault,functx)); 10869566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Setting default finite difference Jacobian matrix\n")); 10879b94acceSBarry Smith } 1088639f9d9dSBarry Smith 108944848bc4SPeter Brune flg = PETSC_FALSE; 10909566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function","Use finite differences (slow) to compute function from user objective","SNESObjectiveComputeFunctionDefaultFD",flg,&flg,NULL)); 109197584545SPeter Brune if (flg) { 10929566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes,NULL,SNESObjectiveComputeFunctionDefaultFD,NULL)); 109397584545SPeter Brune } 109497584545SPeter Brune 109597584545SPeter Brune flg = PETSC_FALSE; 10969566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color","Use finite differences with coloring to compute Jacobian","SNESComputeJacobianDefaultColor",flg,&flg,NULL)); 109744848bc4SPeter Brune if (flg) { 1098c52e227fSPeter Brune DM dm; 1099c52e227fSPeter Brune DMSNES sdm; 11009566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 11019566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 1102aace71b7SPeter Brune sdm->jacobianctx = NULL; 11039566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,snes->jacobian,snes->jacobian_pre,SNESComputeJacobianDefaultColor,NULL)); 11049566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Setting default finite difference coloring Jacobian matrix\n")); 110544848bc4SPeter Brune } 110644848bc4SPeter Brune 1107aa3661deSLisandro Dalcin flg = PETSC_FALSE; 11089566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator","Use a Matrix-Free Jacobian with user-provided preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf_operator,&flg)); 1109d8f46077SPeter Brune if (flg && snes->mf_operator) { 1110a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1111d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1112a8248277SBarry Smith } 1113aa3661deSLisandro Dalcin flg = PETSC_FALSE; 11149566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf","Use a Matrix-Free Jacobian with no preconditioner matrix","SNESSetUseMatrixFree",PETSC_FALSE,&snes->mf,&flg)); 1115d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 11169566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version","Matrix-Free routines version 1 or 2","None",snes->mf_version,&snes->mf_version,NULL)); 1117d28543b3SPeter Brune 1118c40d0f55SPeter Brune flg = PETSC_FALSE; 11199566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes,&pcside)); 11209566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side","SNES nonlinear preconditioner side","SNESSetNPCSide",PCSides,(PetscEnum)pcside,(PetscEnum*)&pcside,&flg)); 11219566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes,pcside)); 1122c40d0f55SPeter Brune 1123e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 11248a70d858SHong Zhang /* 11258a70d858SHong Zhang Publish convergence information using SAWs 11268a70d858SHong Zhang */ 11278a70d858SHong Zhang flg = PETSC_FALSE; 11289566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws","Publish SNES progress using SAWs","SNESMonitorSet",flg,&flg,NULL)); 11298a70d858SHong Zhang if (flg) { 11308a70d858SHong Zhang void *ctx; 11319566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes,&ctx)); 11329566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes,SNESMonitorSAWs,ctx,SNESMonitorSAWsDestroy)); 11338a70d858SHong Zhang } 11348a70d858SHong Zhang #endif 11358a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1136b90c6cbeSBarry Smith { 1137b90c6cbeSBarry Smith PetscBool set; 1138b90c6cbeSBarry Smith flg = PETSC_FALSE; 11399566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block","Block for SAWs at end of SNESSolve","PetscObjectSAWsBlock",((PetscObject)snes)->amspublishblock,&flg,&set)); 1140b90c6cbeSBarry Smith if (set) { 11419566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes,flg)); 1142b90c6cbeSBarry Smith } 1143b90c6cbeSBarry Smith } 1144b90c6cbeSBarry Smith #endif 1145b90c6cbeSBarry Smith 114676b2cf59SMatthew Knepley for (i = 0; i < numberofsetfromoptions; i++) { 11479566063dSJacob Faibussowitsch PetscCall((*othersetfromoptions[i])(snes)); 114876b2cf59SMatthew Knepley } 114976b2cf59SMatthew Knepley 1150e7788613SBarry Smith if (snes->ops->setfromoptions) { 11519566063dSJacob Faibussowitsch PetscCall((*snes->ops->setfromoptions)(PetscOptionsObject,snes)); 1152639f9d9dSBarry Smith } 11535d973c19SBarry Smith 11545d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 11559566063dSJacob Faibussowitsch PetscCall(PetscObjectProcessOptionsHandlers(PetscOptionsObject,(PetscObject)snes)); 1156d0609cedSBarry Smith PetscOptionsEnd(); 11574bbc92c1SBarry Smith 1158d8d34be6SBarry Smith if (snes->linesearch) { 11599566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11609566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1161d8d34be6SBarry Smith } 11629e764e56SPeter Brune 11636aa5e7e9SBarry Smith if (snes->usesksp) { 11649566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp)); 11659566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp,snes->jacobian,snes->jacobian_pre)); 11669566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11676aa5e7e9SBarry Smith } 11686991f827SBarry Smith 1169b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11709566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11719566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options,optionsprefix, "-npc_snes_type", &pcset)); 1172efd4aadfSBarry Smith if (pcset && (!snes->npc)) { 11739566063dSJacob Faibussowitsch PetscCall(SNESGetNPC(snes, &snes->npc)); 117451e86f29SPeter Brune } 1175b5badacbSBarry Smith if (snes->npc) { 11769566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 1177b5badacbSBarry Smith } 1178b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 1179b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 1180b3cd9a81SMatthew G. Knepley } 1181b3cd9a81SMatthew G. Knepley 1182b3cd9a81SMatthew G. Knepley /*@ 1183b3cd9a81SMatthew G. Knepley SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options 1184b3cd9a81SMatthew G. Knepley 1185b3cd9a81SMatthew G. Knepley Collective on SNES 1186b3cd9a81SMatthew G. Knepley 1187b3cd9a81SMatthew G. Knepley Input Parameter: 1188b3cd9a81SMatthew G. Knepley . snes - the SNES context 1189b3cd9a81SMatthew G. Knepley 1190b3cd9a81SMatthew G. Knepley Level: beginner 1191b3cd9a81SMatthew G. Knepley 1192db781477SPatrick Sanan .seealso: `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1193b3cd9a81SMatthew G. Knepley @*/ 1194b3cd9a81SMatthew G. Knepley PetscErrorCode SNESResetFromOptions(SNES snes) 1195b3cd9a81SMatthew G. Knepley { 1196b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11979566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11983a40ed3dSBarry Smith PetscFunctionReturn(0); 11999b94acceSBarry Smith } 12009b94acceSBarry Smith 1201bb9467b5SJed Brown /*@C 1202d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1203d25893d9SBarry Smith the nonlinear solvers. 1204d25893d9SBarry Smith 1205d25893d9SBarry Smith Logically Collective on SNES 1206d25893d9SBarry Smith 1207d25893d9SBarry Smith Input Parameters: 1208d25893d9SBarry Smith + snes - the SNES context 1209d25893d9SBarry Smith . compute - function to compute the context 1210d25893d9SBarry Smith - destroy - function to destroy the context 1211d25893d9SBarry Smith 1212d25893d9SBarry Smith Level: intermediate 1213d25893d9SBarry Smith 1214bb9467b5SJed Brown Notes: 1215bb9467b5SJed Brown This function is currently not available from Fortran. 1216bb9467b5SJed Brown 1217db781477SPatrick Sanan .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 1218d25893d9SBarry Smith @*/ 1219d25893d9SBarry Smith PetscErrorCode SNESSetComputeApplicationContext(SNES snes,PetscErrorCode (*compute)(SNES,void**),PetscErrorCode (*destroy)(void**)) 1220d25893d9SBarry Smith { 1221d25893d9SBarry Smith PetscFunctionBegin; 1222d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1223d25893d9SBarry Smith snes->ops->usercompute = compute; 1224d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1225d25893d9SBarry Smith PetscFunctionReturn(0); 1226d25893d9SBarry Smith } 1227a847f771SSatish Balay 1228b07ff414SBarry Smith /*@ 12299b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 12309b94acceSBarry Smith the nonlinear solvers. 12319b94acceSBarry Smith 12323f9fe445SBarry Smith Logically Collective on SNES 1233fee21e36SBarry Smith 1234c7afd0dbSLois Curfman McInnes Input Parameters: 1235c7afd0dbSLois Curfman McInnes + snes - the SNES context 1236c7afd0dbSLois Curfman McInnes - usrP - optional user context 1237c7afd0dbSLois Curfman McInnes 123836851e7fSLois Curfman McInnes Level: intermediate 123936851e7fSLois Curfman McInnes 124095452b02SPatrick Sanan Fortran Notes: 124195452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1242daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1243daf670e6SBarry Smith 1244db781477SPatrick Sanan .seealso: `SNESGetApplicationContext()` 12459b94acceSBarry Smith @*/ 12467087cfbeSBarry Smith PetscErrorCode SNESSetApplicationContext(SNES snes,void *usrP) 12479b94acceSBarry Smith { 1248b07ff414SBarry Smith KSP ksp; 12491b2093e4SBarry Smith 12503a40ed3dSBarry Smith PetscFunctionBegin; 12510700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 12529566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 12539566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp,usrP)); 12549b94acceSBarry Smith snes->user = usrP; 12553a40ed3dSBarry Smith PetscFunctionReturn(0); 12569b94acceSBarry Smith } 125774679c65SBarry Smith 1258b07ff414SBarry Smith /*@ 12599b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 12609b94acceSBarry Smith nonlinear solvers. 12619b94acceSBarry Smith 1262c7afd0dbSLois Curfman McInnes Not Collective 1263c7afd0dbSLois Curfman McInnes 12649b94acceSBarry Smith Input Parameter: 12659b94acceSBarry Smith . snes - SNES context 12669b94acceSBarry Smith 12679b94acceSBarry Smith Output Parameter: 12689b94acceSBarry Smith . usrP - user context 12699b94acceSBarry Smith 127095452b02SPatrick Sanan Fortran Notes: 127195452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1272daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1273daf670e6SBarry Smith 127436851e7fSLois Curfman McInnes Level: intermediate 127536851e7fSLois Curfman McInnes 1276db781477SPatrick Sanan .seealso: `SNESSetApplicationContext()` 12779b94acceSBarry Smith @*/ 1278e71120c6SJed Brown PetscErrorCode SNESGetApplicationContext(SNES snes,void *usrP) 12799b94acceSBarry Smith { 12803a40ed3dSBarry Smith PetscFunctionBegin; 12810700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1282e71120c6SJed Brown *(void**)usrP = snes->user; 12833a40ed3dSBarry Smith PetscFunctionReturn(0); 12849b94acceSBarry Smith } 128574679c65SBarry Smith 12869b94acceSBarry Smith /*@ 1287ec5066bdSBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian. 12883565c898SBarry Smith 12893565c898SBarry Smith Collective on SNES 12903565c898SBarry Smith 12913565c898SBarry Smith Input Parameters: 12923565c898SBarry Smith + snes - SNES context 12934ddffce6SLisandro Dalcin . mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12944ddffce6SLisandro Dalcin - mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 12953565c898SBarry Smith 12963565c898SBarry Smith Options Database: 12973565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 1298ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator 1299ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1300ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 13013565c898SBarry Smith 13023565c898SBarry Smith Level: intermediate 13033565c898SBarry Smith 1304ec5066bdSBarry Smith Notes: 1305a5b23f4aSJose E. Roman SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 1306ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 1307ec5066bdSBarry Smith 1308db781477SPatrick Sanan .seealso: `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 13093565c898SBarry Smith @*/ 13103565c898SBarry Smith PetscErrorCode SNESSetUseMatrixFree(SNES snes,PetscBool mf_operator,PetscBool mf) 13113565c898SBarry Smith { 13123565c898SBarry Smith PetscFunctionBegin; 13133565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 131488b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf_operator,2); 131588b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes,mf,3); 13164ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 13173565c898SBarry Smith snes->mf_operator = mf_operator; 13183565c898SBarry Smith PetscFunctionReturn(0); 13193565c898SBarry Smith } 13203565c898SBarry Smith 13213565c898SBarry Smith /*@ 1322ec5066bdSBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian. 13233565c898SBarry Smith 13243565c898SBarry Smith Collective on SNES 13253565c898SBarry Smith 13263565c898SBarry Smith Input Parameter: 13273565c898SBarry Smith . snes - SNES context 13283565c898SBarry Smith 13293565c898SBarry Smith Output Parameters: 13304ddffce6SLisandro Dalcin + mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 13314ddffce6SLisandro Dalcin - mf - use matrix-free for both the Amat and Pmat used by SNESSetJacobian(), both the Amat and Pmat set in SNESSetJacobian() will be ignored 13323565c898SBarry Smith 13333565c898SBarry Smith Options Database: 13343565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 13353565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 13363565c898SBarry Smith 13373565c898SBarry Smith Level: intermediate 13383565c898SBarry Smith 1339db781477SPatrick Sanan .seealso: `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 13403565c898SBarry Smith @*/ 13413565c898SBarry Smith PetscErrorCode SNESGetUseMatrixFree(SNES snes,PetscBool *mf_operator,PetscBool *mf) 13423565c898SBarry Smith { 13433565c898SBarry Smith PetscFunctionBegin; 13443565c898SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13453565c898SBarry Smith if (mf) *mf = snes->mf; 13463565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13473565c898SBarry Smith PetscFunctionReturn(0); 13483565c898SBarry Smith } 13493565c898SBarry Smith 13503565c898SBarry Smith /*@ 1351c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1352c8228a4eSBarry Smith at this time. 13539b94acceSBarry Smith 1354c7afd0dbSLois Curfman McInnes Not Collective 1355c7afd0dbSLois Curfman McInnes 13569b94acceSBarry Smith Input Parameter: 13579b94acceSBarry Smith . snes - SNES context 13589b94acceSBarry Smith 13599b94acceSBarry Smith Output Parameter: 13609b94acceSBarry Smith . iter - iteration number 13619b94acceSBarry Smith 1362c8228a4eSBarry Smith Notes: 1363c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1364c8228a4eSBarry Smith 1365c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 136608405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 136708405cd6SLois Curfman McInnes .vb 136808405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 136908405cd6SLois Curfman McInnes if (!(it % 2)) { 137008405cd6SLois Curfman McInnes [compute Jacobian here] 137108405cd6SLois Curfman McInnes } 137208405cd6SLois Curfman McInnes .ve 1373c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 137408405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1375c8228a4eSBarry Smith 1376c04deec6SBarry Smith After the SNES solve is complete this will return the number of nonlinear iterations used. 1377c04deec6SBarry Smith 137836851e7fSLois Curfman McInnes Level: intermediate 137936851e7fSLois Curfman McInnes 1380db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()` 13819b94acceSBarry Smith @*/ 13827087cfbeSBarry Smith PetscErrorCode SNESGetIterationNumber(SNES snes,PetscInt *iter) 13839b94acceSBarry Smith { 13843a40ed3dSBarry Smith PetscFunctionBegin; 13850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 13864482741eSBarry Smith PetscValidIntPointer(iter,2); 13879b94acceSBarry Smith *iter = snes->iter; 13883a40ed3dSBarry Smith PetscFunctionReturn(0); 13899b94acceSBarry Smith } 139074679c65SBarry Smith 1391360c497dSPeter Brune /*@ 1392360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1393360c497dSPeter Brune 1394360c497dSPeter Brune Not Collective 1395360c497dSPeter Brune 1396d8d19677SJose E. Roman Input Parameters: 1397a2b725a8SWilliam Gropp + snes - SNES context 1398a2b725a8SWilliam Gropp - iter - iteration number 1399360c497dSPeter Brune 1400360c497dSPeter Brune Level: developer 1401360c497dSPeter Brune 1402db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()` 1403360c497dSPeter Brune @*/ 1404360c497dSPeter Brune PetscErrorCode SNESSetIterationNumber(SNES snes,PetscInt iter) 1405360c497dSPeter Brune { 1406360c497dSPeter Brune PetscFunctionBegin; 1407360c497dSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14089566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1409360c497dSPeter Brune snes->iter = iter; 14109566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 1411360c497dSPeter Brune PetscFunctionReturn(0); 1412360c497dSPeter Brune } 1413360c497dSPeter Brune 14149b94acceSBarry Smith /*@ 1415b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 14169b94acceSBarry Smith attempted by the nonlinear solver. 14179b94acceSBarry Smith 1418c7afd0dbSLois Curfman McInnes Not Collective 1419c7afd0dbSLois Curfman McInnes 14209b94acceSBarry Smith Input Parameter: 14219b94acceSBarry Smith . snes - SNES context 14229b94acceSBarry Smith 14239b94acceSBarry Smith Output Parameter: 14249b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 14259b94acceSBarry Smith 1426c96a6f78SLois Curfman McInnes Notes: 1427c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1428c96a6f78SLois Curfman McInnes 142936851e7fSLois Curfman McInnes Level: intermediate 143036851e7fSLois Curfman McInnes 1431db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1432db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 14339b94acceSBarry Smith @*/ 14347087cfbeSBarry Smith PetscErrorCode SNESGetNonlinearStepFailures(SNES snes,PetscInt *nfails) 14359b94acceSBarry Smith { 14363a40ed3dSBarry Smith PetscFunctionBegin; 14370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14384482741eSBarry Smith PetscValidIntPointer(nfails,2); 143950ffb88aSMatthew Knepley *nfails = snes->numFailures; 144050ffb88aSMatthew Knepley PetscFunctionReturn(0); 144150ffb88aSMatthew Knepley } 144250ffb88aSMatthew Knepley 144350ffb88aSMatthew Knepley /*@ 1444b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 144550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 144650ffb88aSMatthew Knepley 144750ffb88aSMatthew Knepley Not Collective 144850ffb88aSMatthew Knepley 144950ffb88aSMatthew Knepley Input Parameters: 145050ffb88aSMatthew Knepley + snes - SNES context 145150ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 145250ffb88aSMatthew Knepley 145350ffb88aSMatthew Knepley Level: intermediate 145450ffb88aSMatthew Knepley 1455db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1456db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 145750ffb88aSMatthew Knepley @*/ 14587087cfbeSBarry Smith PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 145950ffb88aSMatthew Knepley { 146050ffb88aSMatthew Knepley PetscFunctionBegin; 14610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 146250ffb88aSMatthew Knepley snes->maxFailures = maxFails; 146350ffb88aSMatthew Knepley PetscFunctionReturn(0); 146450ffb88aSMatthew Knepley } 146550ffb88aSMatthew Knepley 146650ffb88aSMatthew Knepley /*@ 1467b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 146850ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 146950ffb88aSMatthew Knepley 147050ffb88aSMatthew Knepley Not Collective 147150ffb88aSMatthew Knepley 147250ffb88aSMatthew Knepley Input Parameter: 147350ffb88aSMatthew Knepley . snes - SNES context 147450ffb88aSMatthew Knepley 147550ffb88aSMatthew Knepley Output Parameter: 147650ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 147750ffb88aSMatthew Knepley 147850ffb88aSMatthew Knepley Level: intermediate 147950ffb88aSMatthew Knepley 1480db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1481db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 148258ebbce7SBarry Smith 148350ffb88aSMatthew Knepley @*/ 14847087cfbeSBarry Smith PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 148550ffb88aSMatthew Knepley { 148650ffb88aSMatthew Knepley PetscFunctionBegin; 14870700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 14884482741eSBarry Smith PetscValidIntPointer(maxFails,2); 148950ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14903a40ed3dSBarry Smith PetscFunctionReturn(0); 14919b94acceSBarry Smith } 1492a847f771SSatish Balay 14932541af92SBarry Smith /*@ 14942541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 14952541af92SBarry Smith done by SNES. 14962541af92SBarry Smith 14972541af92SBarry Smith Not Collective 14982541af92SBarry Smith 14992541af92SBarry Smith Input Parameter: 15002541af92SBarry Smith . snes - SNES context 15012541af92SBarry Smith 15022541af92SBarry Smith Output Parameter: 15032541af92SBarry Smith . nfuncs - number of evaluations 15042541af92SBarry Smith 15052541af92SBarry Smith Level: intermediate 15062541af92SBarry Smith 150795452b02SPatrick Sanan Notes: 150895452b02SPatrick Sanan Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1509971e163fSPeter Brune 1510db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 15112541af92SBarry Smith @*/ 15127087cfbeSBarry Smith PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 15132541af92SBarry Smith { 15142541af92SBarry Smith PetscFunctionBegin; 15150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15162541af92SBarry Smith PetscValidIntPointer(nfuncs,2); 15172541af92SBarry Smith *nfuncs = snes->nfuncs; 15182541af92SBarry Smith PetscFunctionReturn(0); 15192541af92SBarry Smith } 15202541af92SBarry Smith 15213d4c4710SBarry Smith /*@ 15223d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 15233d4c4710SBarry Smith linear solvers. 15243d4c4710SBarry Smith 15253d4c4710SBarry Smith Not Collective 15263d4c4710SBarry Smith 15273d4c4710SBarry Smith Input Parameter: 15283d4c4710SBarry Smith . snes - SNES context 15293d4c4710SBarry Smith 15303d4c4710SBarry Smith Output Parameter: 15313d4c4710SBarry Smith . nfails - number of failed solves 15323d4c4710SBarry Smith 15339d85da0cSMatthew G. Knepley Level: intermediate 15349d85da0cSMatthew G. Knepley 15359d85da0cSMatthew G. Knepley Options Database Keys: 15369d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15379d85da0cSMatthew G. Knepley 15383d4c4710SBarry Smith Notes: 15393d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 15403d4c4710SBarry Smith 1541db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 15423d4c4710SBarry Smith @*/ 15437087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveFailures(SNES snes,PetscInt *nfails) 15443d4c4710SBarry Smith { 15453d4c4710SBarry Smith PetscFunctionBegin; 15460700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 15473d4c4710SBarry Smith PetscValidIntPointer(nfails,2); 15483d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15493d4c4710SBarry Smith PetscFunctionReturn(0); 15503d4c4710SBarry Smith } 15513d4c4710SBarry Smith 15523d4c4710SBarry Smith /*@ 15533d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 15543d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 15553d4c4710SBarry Smith 15563f9fe445SBarry Smith Logically Collective on SNES 15573d4c4710SBarry Smith 15583d4c4710SBarry Smith Input Parameters: 15593d4c4710SBarry Smith + snes - SNES context 15603d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15613d4c4710SBarry Smith 15623d4c4710SBarry Smith Level: intermediate 15633d4c4710SBarry Smith 15649d85da0cSMatthew G. Knepley Options Database Keys: 15659d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15669d85da0cSMatthew G. Knepley 156795452b02SPatrick Sanan Notes: 156895452b02SPatrick Sanan By default this is 0; that is SNES returns on the first failed linear solve 15693d4c4710SBarry Smith 1570db781477SPatrick Sanan .seealso: `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15713d4c4710SBarry Smith @*/ 15727087cfbeSBarry Smith PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 15733d4c4710SBarry Smith { 15743d4c4710SBarry Smith PetscFunctionBegin; 15750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1576c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxFails,2); 15773d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15783d4c4710SBarry Smith PetscFunctionReturn(0); 15793d4c4710SBarry Smith } 15803d4c4710SBarry Smith 15813d4c4710SBarry Smith /*@ 15823d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 15833d4c4710SBarry Smith are allowed before SNES terminates 15843d4c4710SBarry Smith 15853d4c4710SBarry Smith Not Collective 15863d4c4710SBarry Smith 15873d4c4710SBarry Smith Input Parameter: 15883d4c4710SBarry Smith . snes - SNES context 15893d4c4710SBarry Smith 15903d4c4710SBarry Smith Output Parameter: 15913d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15923d4c4710SBarry Smith 15933d4c4710SBarry Smith Level: intermediate 15943d4c4710SBarry Smith 159595452b02SPatrick Sanan Notes: 159695452b02SPatrick Sanan By default this is 1; that is SNES returns on the first failed linear solve 15973d4c4710SBarry Smith 1598db781477SPatrick Sanan .seealso: `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15993d4c4710SBarry Smith @*/ 16007087cfbeSBarry Smith PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 16013d4c4710SBarry Smith { 16023d4c4710SBarry Smith PetscFunctionBegin; 16030700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16043d4c4710SBarry Smith PetscValidIntPointer(maxFails,2); 16053d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 16063d4c4710SBarry Smith PetscFunctionReturn(0); 16073d4c4710SBarry Smith } 16083d4c4710SBarry Smith 1609c96a6f78SLois Curfman McInnes /*@ 1610b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1611c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1612c96a6f78SLois Curfman McInnes 1613c7afd0dbSLois Curfman McInnes Not Collective 1614c7afd0dbSLois Curfman McInnes 1615c96a6f78SLois Curfman McInnes Input Parameter: 1616c96a6f78SLois Curfman McInnes . snes - SNES context 1617c96a6f78SLois Curfman McInnes 1618c96a6f78SLois Curfman McInnes Output Parameter: 1619c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1620c96a6f78SLois Curfman McInnes 1621c96a6f78SLois Curfman McInnes Notes: 1622971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1623c96a6f78SLois Curfman McInnes 1624010be392SBarry Smith If the linear solver fails inside the SNESSolve() the iterations for that call to the linear solver are not included. If you wish to count them 1625010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1626010be392SBarry Smith 162736851e7fSLois Curfman McInnes Level: intermediate 162836851e7fSLois Curfman McInnes 1629db781477SPatrick Sanan .seealso: `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1630c96a6f78SLois Curfman McInnes @*/ 16317087cfbeSBarry Smith PetscErrorCode SNESGetLinearSolveIterations(SNES snes,PetscInt *lits) 1632c96a6f78SLois Curfman McInnes { 16333a40ed3dSBarry Smith PetscFunctionBegin; 16340700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16354482741eSBarry Smith PetscValidIntPointer(lits,2); 1636c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 16373a40ed3dSBarry Smith PetscFunctionReturn(0); 1638c96a6f78SLois Curfman McInnes } 1639c96a6f78SLois Curfman McInnes 1640971e163fSPeter Brune /*@ 1641971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1642971e163fSPeter Brune are reset every time SNESSolve() is called. 1643971e163fSPeter Brune 1644971e163fSPeter Brune Logically Collective on SNES 1645971e163fSPeter Brune 1646d8d19677SJose E. Roman Input Parameters: 1647971e163fSPeter Brune + snes - SNES context 1648971e163fSPeter Brune - reset - whether to reset the counters or not 1649971e163fSPeter Brune 1650971e163fSPeter Brune Notes: 1651fa19ca70SBarry Smith This defaults to PETSC_TRUE 1652971e163fSPeter Brune 1653971e163fSPeter Brune Level: developer 1654971e163fSPeter Brune 1655db781477SPatrick Sanan .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1656971e163fSPeter Brune @*/ 1657971e163fSPeter Brune PetscErrorCode SNESSetCountersReset(SNES snes,PetscBool reset) 1658971e163fSPeter Brune { 1659971e163fSPeter Brune PetscFunctionBegin; 1660971e163fSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1661971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes,reset,2); 1662971e163fSPeter Brune snes->counters_reset = reset; 1663971e163fSPeter Brune PetscFunctionReturn(0); 1664971e163fSPeter Brune } 1665971e163fSPeter Brune 16662999313aSBarry Smith /*@ 16672999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 16682999313aSBarry Smith 16692999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 16702999313aSBarry Smith 16712999313aSBarry Smith Input Parameters: 16722999313aSBarry Smith + snes - the SNES context 16732999313aSBarry Smith - ksp - the KSP context 16742999313aSBarry Smith 16752999313aSBarry Smith Notes: 16762999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 16772999313aSBarry Smith so this routine is rarely needed. 16782999313aSBarry Smith 16792999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 16802999313aSBarry Smith decreased by one. 16812999313aSBarry Smith 16822999313aSBarry Smith Level: developer 16832999313aSBarry Smith 1684db781477SPatrick Sanan .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16852999313aSBarry Smith @*/ 16867087cfbeSBarry Smith PetscErrorCode SNESSetKSP(SNES snes,KSP ksp) 16872999313aSBarry Smith { 16882999313aSBarry Smith PetscFunctionBegin; 16890700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 16900700a824SBarry Smith PetscValidHeaderSpecific(ksp,KSP_CLASSID,2); 16912999313aSBarry Smith PetscCheckSameComm(snes,1,ksp,2); 16929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16939566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16942999313aSBarry Smith snes->ksp = ksp; 16952999313aSBarry Smith PetscFunctionReturn(0); 16962999313aSBarry Smith } 16972999313aSBarry Smith 16989b94acceSBarry Smith /* -----------------------------------------------------------*/ 169952baeb72SSatish Balay /*@ 17009b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 17019b94acceSBarry Smith 1702d083f849SBarry Smith Collective 1703c7afd0dbSLois Curfman McInnes 1704c7afd0dbSLois Curfman McInnes Input Parameters: 1705906ed7ccSBarry Smith . comm - MPI communicator 17069b94acceSBarry Smith 17079b94acceSBarry Smith Output Parameter: 17089b94acceSBarry Smith . outsnes - the new SNES context 17099b94acceSBarry Smith 1710c7afd0dbSLois Curfman McInnes Options Database Keys: 1711c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1712c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1713c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1714c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1715c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1716c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1717c1f60f51SBarry Smith 171836851e7fSLois Curfman McInnes Level: beginner 171936851e7fSLois Curfman McInnes 172095452b02SPatrick Sanan Developer Notes: 172195452b02SPatrick Sanan SNES always creates a KSP object even though many SNES methods do not use it. This is 1722efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1723efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1724efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1725efd4aadfSBarry Smith by help messages about meaningless SNES options. 1726efd4aadfSBarry Smith 1727efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1728efd4aadfSBarry Smith be fixed. 1729efd4aadfSBarry Smith 1730db781477SPatrick Sanan .seealso: `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 1731a8054027SBarry Smith 17329b94acceSBarry Smith @*/ 17337087cfbeSBarry Smith PetscErrorCode SNESCreate(MPI_Comm comm,SNES *outsnes) 17349b94acceSBarry Smith { 17359b94acceSBarry Smith SNES snes; 1736fa9f3622SBarry Smith SNESKSPEW *kctx; 173737fcc0dbSBarry Smith 17383a40ed3dSBarry Smith PetscFunctionBegin; 1739ed1caa07SMatthew Knepley PetscValidPointer(outsnes,2); 17400298fd71SBarry Smith *outsnes = NULL; 17419566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 17428ba1e511SMatthew Knepley 17439566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes,SNES_CLASSID,"SNES","Nonlinear solver","SNES",comm,SNESDestroy,SNESView)); 17447adad957SLisandro Dalcin 17458d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17462c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 174788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17489b94acceSBarry Smith snes->max_its = 50; 17499750a799SBarry Smith snes->max_funcs = 10000; 17509b94acceSBarry Smith snes->norm = 0.0; 1751c1e67a49SFande Kong snes->xnorm = 0.0; 1752c1e67a49SFande Kong snes->ynorm = 0.0; 1753365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17546c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17553a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17563a2046daSBarry Smith snes->rtol = 1.e-5; 17573a2046daSBarry Smith #else 1758b4874afaSBarry Smith snes->rtol = 1.e-8; 17593a2046daSBarry Smith #endif 1760b4874afaSBarry Smith snes->ttol = 0.0; 17613a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17623a2046daSBarry Smith snes->abstol = 1.e-25; 17633a2046daSBarry Smith #else 176470441072SBarry Smith snes->abstol = 1.e-50; 17653a2046daSBarry Smith #endif 17667cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 17677cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 17687cd0ae37SLisandro Dalcin #else 1769c60f73f4SPeter Brune snes->stol = 1.e-8; 17707cd0ae37SLisandro Dalcin #endif 17713a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17723a2046daSBarry Smith snes->deltatol = 1.e-6; 17733a2046daSBarry Smith #else 17744b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 17753a2046daSBarry Smith #endif 1776e37c518bSBarry Smith snes->divtol = 1.e4; 1777e37c518bSBarry Smith snes->rnorm0 = 0; 17789b94acceSBarry Smith snes->nfuncs = 0; 177950ffb88aSMatthew Knepley snes->numFailures = 0; 178050ffb88aSMatthew Knepley snes->maxFailures = 1; 17817a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1782e35cf81dSBarry Smith snes->lagjacobian = 1; 178337ec4e1aSPeter Brune snes->jac_iter = 0; 178437ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1785a8054027SBarry Smith snes->lagpreconditioner = 1; 178637ec4e1aSPeter Brune snes->pre_iter = 0; 178737ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1788639f9d9dSBarry Smith snes->numbermonitors = 0; 1789c4421ceaSFande Kong snes->numberreasonviews = 0; 17909e5d0892SLisandro Dalcin snes->data = NULL; 17914dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1792186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17936f24a144SLois Curfman McInnes snes->nwork = 0; 17949e5d0892SLisandro Dalcin snes->work = NULL; 179558c9b817SLisandro Dalcin snes->nvwork = 0; 17969e5d0892SLisandro Dalcin snes->vwork = NULL; 1797758f92a0SBarry Smith snes->conv_hist_len = 0; 1798758f92a0SBarry Smith snes->conv_hist_max = 0; 17990298fd71SBarry Smith snes->conv_hist = NULL; 18000298fd71SBarry Smith snes->conv_hist_its = NULL; 1801758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1802971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1803e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1804184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1805efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1806b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1807c40d0f55SPeter Brune 1808d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1809d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1810d8f46077SPeter Brune snes->mf_version = 1; 1811d8f46077SPeter Brune 18123d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 18133d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 18143d4c4710SBarry Smith 1815349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 181676bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1817349187a7SBarry Smith 18184fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 18194fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 18204fc747eaSLawrence Mitchell 18219b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 18229566063dSJacob Faibussowitsch PetscCall(PetscNewLog(snes,&kctx)); 1823f5af7f23SKarl Rupp 18249b94acceSBarry Smith snes->kspconvctx = (void*)kctx; 18259b94acceSBarry Smith kctx->version = 2; 18260f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 18279b94acceSBarry Smith this was too large for some test cases */ 182875567043SBarry Smith kctx->rtol_last = 0.0; 18290f0abf79SStefano Zampini kctx->rtol_max = 0.9; 18309b94acceSBarry Smith kctx->gamma = 1.0; 18310f0abf79SStefano Zampini kctx->alpha = 0.5*(1.0 + PetscSqrtReal(5.0)); 183271f87433Sdalcinl kctx->alpha2 = kctx->alpha; 18330f0abf79SStefano Zampini kctx->threshold = 0.1; 183475567043SBarry Smith kctx->lresid_last = 0.0; 183575567043SBarry Smith kctx->norm_last = 0.0; 18369b94acceSBarry Smith 18370f0abf79SStefano Zampini kctx->rk_last = 0.0; 18380f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 18390f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 18400f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 18410f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 18420f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 18430f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 18440f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 18450f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 18460f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 18470f0abf79SStefano Zampini 18489b94acceSBarry Smith *outsnes = snes; 18493a40ed3dSBarry Smith PetscFunctionReturn(0); 18509b94acceSBarry Smith } 18519b94acceSBarry Smith 185288f0584fSBarry Smith /*MC 1853411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 185488f0584fSBarry Smith 185588f0584fSBarry Smith Synopsis: 1856411c0326SBarry Smith #include "petscsnes.h" 1857411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 185888f0584fSBarry Smith 18591843f636SBarry Smith Collective on snes 18601843f636SBarry Smith 186188f0584fSBarry Smith Input Parameters: 186288f0584fSBarry Smith + snes - the SNES context 186388f0584fSBarry Smith . x - state at which to evaluate residual 186488f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 186588f0584fSBarry Smith 186688f0584fSBarry Smith Output Parameter: 186788f0584fSBarry Smith . f - vector to put residual (function value) 186888f0584fSBarry Smith 1869878cb397SSatish Balay Level: intermediate 1870878cb397SSatish Balay 1871db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()` 187288f0584fSBarry Smith M*/ 187388f0584fSBarry Smith 18749b94acceSBarry Smith /*@C 18759b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 18769b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 18779b94acceSBarry Smith equations. 18789b94acceSBarry Smith 18793f9fe445SBarry Smith Logically Collective on SNES 1880fee21e36SBarry Smith 1881c7afd0dbSLois Curfman McInnes Input Parameters: 1882c7afd0dbSLois Curfman McInnes + snes - the SNES context 18836b7fb656SBarry Smith . r - vector to store function values, may be NULL 1884f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1885c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18860298fd71SBarry Smith function evaluation routine (may be NULL) 18879b94acceSBarry Smith 18889b94acceSBarry Smith Notes: 18899b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 18909b94acceSBarry Smith $ f'(x) x = -f(x), 1891c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 18929b94acceSBarry Smith 189336851e7fSLois Curfman McInnes Level: beginner 189436851e7fSLois Curfman McInnes 1895db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18969b94acceSBarry Smith @*/ 1897f8b49ee9SBarry Smith PetscErrorCode SNESSetFunction(SNES snes,Vec r,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 18989b94acceSBarry Smith { 18996cab3a1bSJed Brown DM dm; 19006cab3a1bSJed Brown 19013a40ed3dSBarry Smith PetscFunctionBegin; 19020700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1903d2a683ecSLisandro Dalcin if (r) { 1904d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r,VEC_CLASSID,2); 1905d2a683ecSLisandro Dalcin PetscCheckSameComm(snes,1,r,2); 19069566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 19079566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 190885385478SLisandro Dalcin snes->vec_func = r; 1909d2a683ecSLisandro Dalcin } 19109566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 19119566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm,f,ctx)); 1912bbc1464cSBarry Smith if (f == SNESPicardComputeFunction) { 19139566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx)); 1914bbc1464cSBarry Smith } 19153a40ed3dSBarry Smith PetscFunctionReturn(0); 19169b94acceSBarry Smith } 19179b94acceSBarry Smith 1918e4ed7901SPeter Brune /*@C 1919e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1920e4ed7901SPeter Brune function norm at the initialization of the method. In some 1921e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1922e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1923e4ed7901SPeter Brune to SNESComputeFunction in that case. 1924e4ed7901SPeter Brune 1925e4ed7901SPeter Brune Logically Collective on SNES 1926e4ed7901SPeter Brune 1927e4ed7901SPeter Brune Input Parameters: 1928e4ed7901SPeter Brune + snes - the SNES context 1929e4ed7901SPeter Brune - f - vector to store function value 1930e4ed7901SPeter Brune 1931e4ed7901SPeter Brune Notes: 1932e4ed7901SPeter Brune This should not be modified during the solution procedure. 1933e4ed7901SPeter Brune 1934e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1935e4ed7901SPeter Brune 1936e4ed7901SPeter Brune Level: developer 1937e4ed7901SPeter Brune 1938db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1939e4ed7901SPeter Brune @*/ 1940e4ed7901SPeter Brune PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1941e4ed7901SPeter Brune { 1942e4ed7901SPeter Brune Vec vec_func; 1943e4ed7901SPeter Brune 1944e4ed7901SPeter Brune PetscFunctionBegin; 1945e4ed7901SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1946e4ed7901SPeter Brune PetscValidHeaderSpecific(f,VEC_CLASSID,2); 1947e4ed7901SPeter Brune PetscCheckSameComm(snes,1,f,2); 1948efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1949902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1950902f982fSPeter Brune PetscFunctionReturn(0); 1951902f982fSPeter Brune } 19529566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,&vec_func,NULL,NULL)); 19539566063dSJacob Faibussowitsch PetscCall(VecCopy(f,vec_func)); 1954f5af7f23SKarl Rupp 1955217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1956e4ed7901SPeter Brune PetscFunctionReturn(0); 1957e4ed7901SPeter Brune } 1958e4ed7901SPeter Brune 1959534ebe21SPeter Brune /*@ 1960a5b23f4aSJose E. Roman SNESSetNormSchedule - Sets the SNESNormSchedule used in convergence and monitoring 1961534ebe21SPeter Brune of the SNES method. 1962534ebe21SPeter Brune 1963534ebe21SPeter Brune Logically Collective on SNES 1964534ebe21SPeter Brune 1965534ebe21SPeter Brune Input Parameters: 1966534ebe21SPeter Brune + snes - the SNES context 1967365a6726SPeter Brune - normschedule - the frequency of norm computation 1968534ebe21SPeter Brune 1969517f1916SMatthew G. Knepley Options Database Key: 197067b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1971517f1916SMatthew G. Knepley 1972534ebe21SPeter Brune Notes: 1973365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1974534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1975534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1976a5b23f4aSJose E. Roman (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 1977534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1978534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1979534ebe21SPeter Brune their solution. 1980534ebe21SPeter Brune 1981534ebe21SPeter Brune Level: developer 1982534ebe21SPeter Brune 1983db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1984534ebe21SPeter Brune @*/ 1985365a6726SPeter Brune PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1986534ebe21SPeter Brune { 1987534ebe21SPeter Brune PetscFunctionBegin; 1988534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 1989365a6726SPeter Brune snes->normschedule = normschedule; 1990534ebe21SPeter Brune PetscFunctionReturn(0); 1991534ebe21SPeter Brune } 1992534ebe21SPeter Brune 1993534ebe21SPeter Brune /*@ 1994a5b23f4aSJose E. Roman SNESGetNormSchedule - Gets the SNESNormSchedule used in convergence and monitoring 1995534ebe21SPeter Brune of the SNES method. 1996534ebe21SPeter Brune 1997534ebe21SPeter Brune Logically Collective on SNES 1998534ebe21SPeter Brune 1999534ebe21SPeter Brune Input Parameters: 2000534ebe21SPeter Brune + snes - the SNES context 2001365a6726SPeter Brune - normschedule - the type of the norm used 2002534ebe21SPeter Brune 2003534ebe21SPeter Brune Level: advanced 2004534ebe21SPeter Brune 2005db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2006534ebe21SPeter Brune @*/ 2007365a6726SPeter Brune PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 2008534ebe21SPeter Brune { 2009534ebe21SPeter Brune PetscFunctionBegin; 2010534ebe21SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2011365a6726SPeter Brune *normschedule = snes->normschedule; 2012534ebe21SPeter Brune PetscFunctionReturn(0); 2013534ebe21SPeter Brune } 2014534ebe21SPeter Brune 2015c5ce4427SMatthew G. Knepley /*@ 2016c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 2017c5ce4427SMatthew G. Knepley 2018c5ce4427SMatthew G. Knepley Logically Collective on SNES 2019c5ce4427SMatthew G. Knepley 2020c5ce4427SMatthew G. Knepley Input Parameters: 2021c5ce4427SMatthew G. Knepley + snes - the SNES context 2022c5ce4427SMatthew G. Knepley 2023c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 2024c5ce4427SMatthew G. Knepley 2025c5ce4427SMatthew G. Knepley Level: developer 2026c5ce4427SMatthew G. Knepley 2027db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2028c5ce4427SMatthew G. Knepley @*/ 2029c5ce4427SMatthew G. Knepley PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 2030c5ce4427SMatthew G. Knepley { 2031c5ce4427SMatthew G. Knepley PetscFunctionBegin; 2032c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2033c5ce4427SMatthew G. Knepley snes->norm = norm; 2034c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 2035c5ce4427SMatthew G. Knepley } 2036c5ce4427SMatthew G. Knepley 2037c5ce4427SMatthew G. Knepley /*@ 2038c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 2039c5ce4427SMatthew G. Knepley 2040c5ce4427SMatthew G. Knepley Not Collective 2041c5ce4427SMatthew G. Knepley 2042c5ce4427SMatthew G. Knepley Input Parameter: 2043c5ce4427SMatthew G. Knepley . snes - the SNES context 2044c5ce4427SMatthew G. Knepley 2045c5ce4427SMatthew G. Knepley Output Parameter: 2046c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 2047c5ce4427SMatthew G. Knepley 2048c5ce4427SMatthew G. Knepley Level: developer 2049c5ce4427SMatthew G. Knepley 2050db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2051c5ce4427SMatthew G. Knepley @*/ 2052c5ce4427SMatthew G. Knepley PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 2053c5ce4427SMatthew G. Knepley { 2054c5ce4427SMatthew G. Knepley PetscFunctionBegin; 2055c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2056dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 2057c5ce4427SMatthew G. Knepley *norm = snes->norm; 2058c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 2059c5ce4427SMatthew G. Knepley } 2060c5ce4427SMatthew G. Knepley 2061c1e67a49SFande Kong /*@ 2062c1e67a49SFande Kong SNESGetUpdateNorm - Gets the last computed norm of the Newton update 2063c1e67a49SFande Kong 2064c1e67a49SFande Kong Not Collective 2065c1e67a49SFande Kong 2066c1e67a49SFande Kong Input Parameter: 2067c1e67a49SFande Kong . snes - the SNES context 2068c1e67a49SFande Kong 2069c1e67a49SFande Kong Output Parameter: 2070c1e67a49SFande Kong . ynorm - the last computed update norm 2071c1e67a49SFande Kong 2072c1e67a49SFande Kong Level: developer 2073c1e67a49SFande Kong 2074db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2075c1e67a49SFande Kong @*/ 2076c1e67a49SFande Kong PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2077c1e67a49SFande Kong { 2078c1e67a49SFande Kong PetscFunctionBegin; 2079c1e67a49SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2080dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 2081c1e67a49SFande Kong *ynorm = snes->ynorm; 2082c1e67a49SFande Kong PetscFunctionReturn(0); 2083c1e67a49SFande Kong } 2084c1e67a49SFande Kong 2085c1e67a49SFande Kong /*@ 20864591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2087c1e67a49SFande Kong 2088c1e67a49SFande Kong Not Collective 2089c1e67a49SFande Kong 2090c1e67a49SFande Kong Input Parameter: 2091c1e67a49SFande Kong . snes - the SNES context 2092c1e67a49SFande Kong 2093c1e67a49SFande Kong Output Parameter: 2094c1e67a49SFande Kong . xnorm - the last computed solution norm 2095c1e67a49SFande Kong 2096c1e67a49SFande Kong Level: developer 2097c1e67a49SFande Kong 2098db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2099c1e67a49SFande Kong @*/ 2100c1e67a49SFande Kong PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2101c1e67a49SFande Kong { 2102c1e67a49SFande Kong PetscFunctionBegin; 2103c1e67a49SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2104dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2105c1e67a49SFande Kong *xnorm = snes->xnorm; 2106c1e67a49SFande Kong PetscFunctionReturn(0); 2107c1e67a49SFande Kong } 2108c1e67a49SFande Kong 210947073ea2SPeter Brune /*@C 2110a5b23f4aSJose E. Roman SNESSetFunctionType - Sets the SNESNormSchedule used in convergence and monitoring 211147073ea2SPeter Brune of the SNES method. 211247073ea2SPeter Brune 211347073ea2SPeter Brune Logically Collective on SNES 211447073ea2SPeter Brune 211547073ea2SPeter Brune Input Parameters: 211647073ea2SPeter Brune + snes - the SNES context 211747073ea2SPeter Brune - normschedule - the frequency of norm computation 211847073ea2SPeter Brune 211947073ea2SPeter Brune Notes: 212047073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 212147073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 212247073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 2123a5b23f4aSJose E. Roman (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 212447073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 212547073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 212647073ea2SPeter Brune their solution. 212747073ea2SPeter Brune 212847073ea2SPeter Brune Level: developer 212947073ea2SPeter Brune 2130db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 213147073ea2SPeter Brune @*/ 213247073ea2SPeter Brune PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 213347073ea2SPeter Brune { 213447073ea2SPeter Brune PetscFunctionBegin; 213547073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 213647073ea2SPeter Brune snes->functype = type; 213747073ea2SPeter Brune PetscFunctionReturn(0); 213847073ea2SPeter Brune } 213947073ea2SPeter Brune 214047073ea2SPeter Brune /*@C 2141a5b23f4aSJose E. Roman SNESGetFunctionType - Gets the SNESNormSchedule used in convergence and monitoring 214247073ea2SPeter Brune of the SNES method. 214347073ea2SPeter Brune 214447073ea2SPeter Brune Logically Collective on SNES 214547073ea2SPeter Brune 214647073ea2SPeter Brune Input Parameters: 214747073ea2SPeter Brune + snes - the SNES context 214847073ea2SPeter Brune - normschedule - the type of the norm used 214947073ea2SPeter Brune 215047073ea2SPeter Brune Level: advanced 215147073ea2SPeter Brune 2152db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 215347073ea2SPeter Brune @*/ 215447073ea2SPeter Brune PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 215547073ea2SPeter Brune { 215647073ea2SPeter Brune PetscFunctionBegin; 215747073ea2SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 215847073ea2SPeter Brune *type = snes->functype; 2159534ebe21SPeter Brune PetscFunctionReturn(0); 2160534ebe21SPeter Brune } 2161534ebe21SPeter Brune 2162bf388a1fSBarry Smith /*MC 2163be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 2164bf388a1fSBarry Smith 2165bf388a1fSBarry Smith Synopsis: 2166aaa7dc30SBarry Smith #include <petscsnes.h> 2167be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2168bf388a1fSBarry Smith 21691843f636SBarry Smith Collective on snes 21701843f636SBarry Smith 21711843f636SBarry Smith Input Parameters: 2172bf388a1fSBarry Smith + X - solution vector 2173bf388a1fSBarry Smith . B - RHS vector 2174bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2175bf388a1fSBarry Smith 21761843f636SBarry Smith Output Parameter: 21771843f636SBarry Smith . X - solution vector 21781843f636SBarry Smith 2179878cb397SSatish Balay Level: intermediate 2180878cb397SSatish Balay 2181db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetNGS()` 2182bf388a1fSBarry Smith M*/ 2183bf388a1fSBarry Smith 2184c79ef259SPeter Brune /*@C 2185be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2186c79ef259SPeter Brune use with composed nonlinear solvers. 2187c79ef259SPeter Brune 2188c79ef259SPeter Brune Input Parameters: 2189c79ef259SPeter Brune + snes - the SNES context 2190be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 2191c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 21920298fd71SBarry Smith smoother evaluation routine (may be NULL) 2193c79ef259SPeter Brune 2194c79ef259SPeter Brune Notes: 2195be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 2196c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 2197c79ef259SPeter Brune 2198d28543b3SPeter Brune Level: intermediate 2199c79ef259SPeter Brune 2200db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeNGS()` 2201c79ef259SPeter Brune @*/ 2202be95d8f1SBarry Smith PetscErrorCode SNESSetNGS(SNES snes,PetscErrorCode (*f)(SNES,Vec,Vec,void*),void *ctx) 22036cab3a1bSJed Brown { 22046cab3a1bSJed Brown DM dm; 22056cab3a1bSJed Brown 2206646217ecSPeter Brune PetscFunctionBegin; 22076cab3a1bSJed Brown PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 22089566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 22099566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm,f,ctx)); 2210646217ecSPeter Brune PetscFunctionReturn(0); 2211646217ecSPeter Brune } 2212646217ecSPeter Brune 2213bbc1464cSBarry Smith /* 2214bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2215bbc1464cSBarry Smith changed during the KSPSolve() 2216bbc1464cSBarry Smith */ 2217bbc1464cSBarry Smith PetscErrorCode SNESPicardComputeMFFunction(SNES snes,Vec x,Vec f,void *ctx) 2218bbc1464cSBarry Smith { 2219bbc1464cSBarry Smith DM dm; 2220bbc1464cSBarry Smith DMSNES sdm; 2221bbc1464cSBarry Smith 2222bbc1464cSBarry Smith PetscFunctionBegin; 22239566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 22249566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 22255f80ce2aSJacob Faibussowitsch PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 2226bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2227bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2228bbc1464cSBarry Smith PetscStackPush("SNES Picard user function"); 22299566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx)); 2230bbc1464cSBarry Smith PetscStackPop; 22319566063dSJacob Faibussowitsch PetscCall(VecScale(f,-1.0)); 2232bbc1464cSBarry Smith if (!snes->picard) { 22330df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 22349566063dSJacob Faibussowitsch PetscCall(MatDuplicate(snes->jacobian_pre,MAT_DO_NOT_COPY_VALUES,&snes->picard)); 2235bbc1464cSBarry Smith } 2236bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 22379566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx)); 2238bbc1464cSBarry Smith PetscStackPop; 22399566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard,x,f,f)); 2240bbc1464cSBarry Smith } else { 2241bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 22429566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->picard,snes->picard,sdm->pctx)); 2243bbc1464cSBarry Smith PetscStackPop; 22449566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard,x,f)); 2245bbc1464cSBarry Smith } 2246bbc1464cSBarry Smith PetscFunctionReturn(0); 2247bbc1464cSBarry Smith } 2248bbc1464cSBarry Smith 224925acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeFunction(SNES snes,Vec x,Vec f,void *ctx) 22508b0a5094SBarry Smith { 2251e03ab78fSPeter Brune DM dm; 2252942e3340SBarry Smith DMSNES sdm; 22536cab3a1bSJed Brown 22548b0a5094SBarry Smith PetscFunctionBegin; 22559566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 22569566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 22575f80ce2aSJacob Faibussowitsch PetscCheck(sdm->ops->computepjacobian,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetPicard() to provide Picard Jacobian."); 22588b0a5094SBarry Smith /* A(x)*x - b(x) */ 2259bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 226025acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user function"); 22619566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computepfunction)(snes,x,f,sdm->pctx)); 226225acbd8eSLisandro Dalcin PetscStackPop; 22639566063dSJacob Faibussowitsch PetscCall(VecScale(f,-1.0)); 226425acbd8eSLisandro Dalcin PetscStackPush("SNES Picard user Jacobian"); 22659566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx)); 226625acbd8eSLisandro Dalcin PetscStackPop; 22679566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre,x,f,f)); 2268bbc1464cSBarry Smith } else { 2269bbc1464cSBarry Smith PetscStackPush("SNES Picard user Jacobian"); 22709566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computepjacobian)(snes,x,snes->jacobian,snes->jacobian_pre,sdm->pctx)); 2271bbc1464cSBarry Smith PetscStackPop; 22729566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre,x,f)); 2273bbc1464cSBarry Smith } 22748b0a5094SBarry Smith PetscFunctionReturn(0); 22758b0a5094SBarry Smith } 22768b0a5094SBarry Smith 227725acbd8eSLisandro Dalcin PetscErrorCode SNESPicardComputeJacobian(SNES snes,Vec x1,Mat J,Mat B,void *ctx) 22788b0a5094SBarry Smith { 22798b0a5094SBarry Smith PetscFunctionBegin; 2280e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2281bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 22829566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J,MAT_FINAL_ASSEMBLY)); 22839566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J,MAT_FINAL_ASSEMBLY)); 22848b0a5094SBarry Smith PetscFunctionReturn(0); 22858b0a5094SBarry Smith } 22868b0a5094SBarry Smith 22878b0a5094SBarry Smith /*@C 2288bbc1464cSBarry Smith SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22898b0a5094SBarry Smith 22908b0a5094SBarry Smith Logically Collective on SNES 22918b0a5094SBarry Smith 22928b0a5094SBarry Smith Input Parameters: 22938b0a5094SBarry Smith + snes - the SNES context 22946b7fb656SBarry Smith . r - vector to store function values, may be NULL 22956b7fb656SBarry Smith . bp - function evaluation routine, may be NULL 22966b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2297e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 22986b7fb656SBarry Smith . J - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence 22996b7fb656SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 23008b0a5094SBarry Smith 23018b0a5094SBarry Smith Notes: 23026b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2303f450aa47SBarry Smith an approximate Newton solver. This interface is provided to allow porting/testing a previous Picard based code in PETSc before converting it to approximate Newton. 2304f450aa47SBarry Smith 23058b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 23068b0a5094SBarry Smith 23076b7fb656SBarry Smith $ Solves the equation A(x) x = bp(x) - b via the defect correction algorithm A(x^{n}) (x^{n+1} - x^{n}) = bp(x^{n}) + b - A(x^{n})x^{n} 23086b7fb656SBarry Smith $ Note that when an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 23098b0a5094SBarry Smith 23108b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 23118b0a5094SBarry Smith 23120d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 23136b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 23148b0a5094SBarry Smith 23158b0a5094SBarry Smith There is some controversity over the definition of a Picard iteration for nonlinear systems but almost everyone agrees that it involves a linear solve and some 23168b0a5094SBarry Smith believe it is the iteration A(x^{n}) x^{n+1} = b(x^{n}) hence we use the name Picard. If anyone has an authoritative reference that defines the Picard iteration 23178b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 23188b0a5094SBarry Smith 23196b7fb656SBarry Smith When used with -snes_mf_operator this will run matrix-free Newton's method where the matrix-vector product is of the true Jacobian of A(x)x - bp(x) -b. 23206b7fb656SBarry Smith 23216b7fb656SBarry Smith When used with -snes_fd this will compute the true Jacobian (very slowly one column at at time) and thus represent Newton's method. 23226b7fb656SBarry Smith 23236b7fb656SBarry Smith When used with -snes_fd_coloring this will compute the Jacobian via coloring and thus represent a faster implementation of Newton's method. But the 23246b7fb656SBarry Smith the nonzero structure of the Jacobian is, in general larger than that of the Picard matrix A so you must provide in A the needed nonzero structure for the correct 23256b7fb656SBarry Smith coloring. When using DMDA this may mean creating the matrix A with DMCreateMatrix() using a wider stencil than strictly needed for A or with a DMDA_STENCIL_BOX. 23266b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2327bbc1464cSBarry Smith 2328f450aa47SBarry Smith Level: intermediate 23298b0a5094SBarry Smith 2330db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 23318b0a5094SBarry Smith @*/ 2332bbc1464cSBarry Smith PetscErrorCode SNESSetPicard(SNES snes,Vec r,PetscErrorCode (*bp)(SNES,Vec,Vec,void*),Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 23338b0a5094SBarry Smith { 2334e03ab78fSPeter Brune DM dm; 2335e03ab78fSPeter Brune 23368b0a5094SBarry Smith PetscFunctionBegin; 23378b0a5094SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23389566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23399566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm,bp,J,ctx)); 23409566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm,SNESPicardComputeMFFunction,ctx)); 23419566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes,r,SNESPicardComputeFunction,ctx)); 23429566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes,Amat,Pmat,SNESPicardComputeJacobian,ctx)); 23438b0a5094SBarry Smith PetscFunctionReturn(0); 23448b0a5094SBarry Smith } 23458b0a5094SBarry Smith 23467971a8bfSPeter Brune /*@C 23477971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 23487971a8bfSPeter Brune 23497971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 23507971a8bfSPeter Brune 23517971a8bfSPeter Brune Input Parameter: 23527971a8bfSPeter Brune . snes - the SNES context 23537971a8bfSPeter Brune 2354d8d19677SJose E. Roman Output Parameters: 23550298fd71SBarry Smith + r - the function (or NULL) 2356f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2357e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2358e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2359f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 23600298fd71SBarry Smith - ctx - the function context (or NULL) 23617971a8bfSPeter Brune 23627971a8bfSPeter Brune Level: advanced 23637971a8bfSPeter Brune 2364db781477SPatrick Sanan .seealso: `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 23657971a8bfSPeter Brune @*/ 2366d1e9a80fSBarry Smith PetscErrorCode SNESGetPicard(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 23677971a8bfSPeter Brune { 23687971a8bfSPeter Brune DM dm; 23697971a8bfSPeter Brune 23707971a8bfSPeter Brune PetscFunctionBegin; 23717971a8bfSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 23729566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,r,NULL,NULL)); 23739566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes,Amat,Pmat,NULL,NULL)); 23749566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 23759566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm,f,J,ctx)); 23767971a8bfSPeter Brune PetscFunctionReturn(0); 23777971a8bfSPeter Brune } 23787971a8bfSPeter Brune 2379d25893d9SBarry Smith /*@C 2380d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2381d25893d9SBarry Smith 2382d25893d9SBarry Smith Logically Collective on SNES 2383d25893d9SBarry Smith 2384d25893d9SBarry Smith Input Parameters: 2385d25893d9SBarry Smith + snes - the SNES context 2386d25893d9SBarry Smith . func - function evaluation routine 2387d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 23880298fd71SBarry Smith function evaluation routine (may be NULL) 2389d25893d9SBarry Smith 2390d25893d9SBarry Smith Calling sequence of func: 2391d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2392d25893d9SBarry Smith 2393d25893d9SBarry Smith . f - function vector 2394d25893d9SBarry Smith - ctx - optional user-defined function context 2395d25893d9SBarry Smith 2396d25893d9SBarry Smith Level: intermediate 2397d25893d9SBarry Smith 2398db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2399d25893d9SBarry Smith @*/ 2400d25893d9SBarry Smith PetscErrorCode SNESSetComputeInitialGuess(SNES snes,PetscErrorCode (*func)(SNES,Vec,void*),void *ctx) 2401d25893d9SBarry Smith { 2402d25893d9SBarry Smith PetscFunctionBegin; 2403d25893d9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2404d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2405d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2406d25893d9SBarry Smith PetscFunctionReturn(0); 2407d25893d9SBarry Smith } 2408d25893d9SBarry Smith 24093ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 24101096aae1SMatthew Knepley /*@C 24111096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 24121096aae1SMatthew Knepley it assumes a zero right hand side. 24131096aae1SMatthew Knepley 24143f9fe445SBarry Smith Logically Collective on SNES 24151096aae1SMatthew Knepley 24161096aae1SMatthew Knepley Input Parameter: 24171096aae1SMatthew Knepley . snes - the SNES context 24181096aae1SMatthew Knepley 24191096aae1SMatthew Knepley Output Parameter: 24200298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 24211096aae1SMatthew Knepley 24221096aae1SMatthew Knepley Level: intermediate 24231096aae1SMatthew Knepley 2424db781477SPatrick Sanan .seealso: `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 24251096aae1SMatthew Knepley @*/ 24267087cfbeSBarry Smith PetscErrorCode SNESGetRhs(SNES snes,Vec *rhs) 24271096aae1SMatthew Knepley { 24281096aae1SMatthew Knepley PetscFunctionBegin; 24290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24301096aae1SMatthew Knepley PetscValidPointer(rhs,2); 243185385478SLisandro Dalcin *rhs = snes->vec_rhs; 24321096aae1SMatthew Knepley PetscFunctionReturn(0); 24331096aae1SMatthew Knepley } 24341096aae1SMatthew Knepley 24359b94acceSBarry Smith /*@ 2436bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 24379b94acceSBarry Smith 2438c7afd0dbSLois Curfman McInnes Collective on SNES 2439c7afd0dbSLois Curfman McInnes 24409b94acceSBarry Smith Input Parameters: 2441c7afd0dbSLois Curfman McInnes + snes - the SNES context 2442c7afd0dbSLois Curfman McInnes - x - input vector 24439b94acceSBarry Smith 24449b94acceSBarry Smith Output Parameter: 24453638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 24469b94acceSBarry Smith 24471bffabb2SLois Curfman McInnes Notes: 244836851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 2449bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 245036851e7fSLois Curfman McInnes 245136851e7fSLois Curfman McInnes Level: developer 245236851e7fSLois Curfman McInnes 2453db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 24549b94acceSBarry Smith @*/ 24557087cfbeSBarry Smith PetscErrorCode SNESComputeFunction(SNES snes,Vec x,Vec y) 24569b94acceSBarry Smith { 24576cab3a1bSJed Brown DM dm; 2458942e3340SBarry Smith DMSNES sdm; 24599b94acceSBarry Smith 24603a40ed3dSBarry Smith PetscFunctionBegin; 24610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 24620700a824SBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 24630700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2464c9780b6fSBarry Smith PetscCheckSameComm(snes,1,x,2); 2465c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,3); 24669566063dSJacob Faibussowitsch PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2467184914b5SBarry Smith 24689566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 24699566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 247032f3f7c2SPeter Brune if (sdm->ops->computefunction) { 247194db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 24729566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0)); 247394db00ebSBarry Smith } 24749566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2475d64ed03dSBarry Smith PetscStackPush("SNES user function"); 24768ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24778ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 24789566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computefunction)(snes,x,y,sdm->functionctx)); 2479d64ed03dSBarry Smith PetscStackPop; 24809566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 248194db00ebSBarry Smith if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) { 24829566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0)); 248394db00ebSBarry Smith } 2484c90fad12SPeter Brune } else if (snes->vec_rhs) { 24859566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 2486644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 248785385478SLisandro Dalcin if (snes->vec_rhs) { 24889566063dSJacob Faibussowitsch PetscCall(VecAXPY(y,-1.0,snes->vec_rhs)); 24893ab0aad5SBarry Smith } 2490ae3c334cSLois Curfman McInnes snes->nfuncs++; 2491422a814eSBarry Smith /* 2492422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2493422a814eSBarry Smith propagate the value to all processes 2494422a814eSBarry Smith */ 2495422a814eSBarry Smith if (snes->domainerror) { 24969566063dSJacob Faibussowitsch PetscCall(VecSetInf(y)); 2497422a814eSBarry Smith } 24983a40ed3dSBarry Smith PetscFunctionReturn(0); 24999b94acceSBarry Smith } 25009b94acceSBarry Smith 2501c79ef259SPeter Brune /*@ 2502bbc1464cSBarry Smith SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction(). 2503bbc1464cSBarry Smith 2504bbc1464cSBarry Smith Collective on SNES 2505bbc1464cSBarry Smith 2506bbc1464cSBarry Smith Input Parameters: 2507bbc1464cSBarry Smith + snes - the SNES context 2508bbc1464cSBarry Smith - x - input vector 2509bbc1464cSBarry Smith 2510bbc1464cSBarry Smith Output Parameter: 2511bbc1464cSBarry Smith . y - function vector, as set by SNESSetMFFunction() 2512bbc1464cSBarry Smith 2513bbc1464cSBarry Smith Notes: 2514bbc1464cSBarry Smith SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF() 2515bbc1464cSBarry Smith so users would not generally call this routine themselves. 2516bbc1464cSBarry Smith 2517bbc1464cSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve() 2518bbc1464cSBarry Smith while SNESComputeFunction() does. As such, this routine cannot be used with MatMFFDSetBase() with a provided F function value even if it applies the 2519bbc1464cSBarry Smith same function as SNESComputeFunction() if a SNESSolve() right hand side vector is use because the two functions difference would include this right hand side function. 2520bbc1464cSBarry Smith 2521bbc1464cSBarry Smith Level: developer 2522bbc1464cSBarry Smith 2523db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2524bbc1464cSBarry Smith @*/ 2525bbc1464cSBarry Smith PetscErrorCode SNESComputeMFFunction(SNES snes,Vec x,Vec y) 2526bbc1464cSBarry Smith { 2527bbc1464cSBarry Smith DM dm; 2528bbc1464cSBarry Smith DMSNES sdm; 2529bbc1464cSBarry Smith 2530bbc1464cSBarry Smith PetscFunctionBegin; 2531bbc1464cSBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2532bbc1464cSBarry Smith PetscValidHeaderSpecific(x,VEC_CLASSID,2); 2533bbc1464cSBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,3); 2534bbc1464cSBarry Smith PetscCheckSameComm(snes,1,x,2); 2535bbc1464cSBarry Smith PetscCheckSameComm(snes,1,y,3); 25369566063dSJacob Faibussowitsch PetscCall(VecValidValues(x,2,PETSC_TRUE)); 2537bbc1464cSBarry Smith 25389566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 25399566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 25409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval,snes,x,y,0)); 25419566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2542bbc1464cSBarry Smith PetscStackPush("SNES user function"); 2543bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2544bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 25459566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computemffunction)(snes,x,y,sdm->mffunctionctx)); 2546bbc1464cSBarry Smith PetscStackPop; 25479566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 25489566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval,snes,x,y,0)); 2549bbc1464cSBarry Smith snes->nfuncs++; 2550bbc1464cSBarry Smith /* 2551bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2552bbc1464cSBarry Smith propagate the value to all processes 2553bbc1464cSBarry Smith */ 2554bbc1464cSBarry Smith if (snes->domainerror) { 25559566063dSJacob Faibussowitsch PetscCall(VecSetInf(y)); 2556bbc1464cSBarry Smith } 2557bbc1464cSBarry Smith PetscFunctionReturn(0); 2558bbc1464cSBarry Smith } 2559bbc1464cSBarry Smith 2560bbc1464cSBarry Smith /*@ 2561be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2562c79ef259SPeter Brune 2563c79ef259SPeter Brune Collective on SNES 2564c79ef259SPeter Brune 2565c79ef259SPeter Brune Input Parameters: 2566c79ef259SPeter Brune + snes - the SNES context 2567c79ef259SPeter Brune . x - input vector 2568c79ef259SPeter Brune - b - rhs vector 2569c79ef259SPeter Brune 2570c79ef259SPeter Brune Output Parameter: 2571c79ef259SPeter Brune . x - new solution vector 2572c79ef259SPeter Brune 2573c79ef259SPeter Brune Notes: 2574be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2575c79ef259SPeter Brune implementations, so most users would not generally call this routine 2576c79ef259SPeter Brune themselves. 2577c79ef259SPeter Brune 2578c79ef259SPeter Brune Level: developer 2579c79ef259SPeter Brune 2580db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESComputeFunction()` 2581c79ef259SPeter Brune @*/ 2582be95d8f1SBarry Smith PetscErrorCode SNESComputeNGS(SNES snes,Vec b,Vec x) 2583646217ecSPeter Brune { 25846cab3a1bSJed Brown DM dm; 2585942e3340SBarry Smith DMSNES sdm; 2586646217ecSPeter Brune 2587646217ecSPeter Brune PetscFunctionBegin; 2588646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 2589064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x,VEC_CLASSID,3); 2590064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 2591064a246eSJacob Faibussowitsch PetscCheckSameComm(snes,1,x,3); 2592064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes,1,b,2); 25939566063dSJacob Faibussowitsch if (b) PetscCall(VecValidValues(b,2,PETSC_TRUE)); 25949566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval,snes,x,b,0)); 25959566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 25969566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 259722c6f798SBarry Smith if (sdm->ops->computegs) { 25989566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2599be95d8f1SBarry Smith PetscStackPush("SNES user NGS"); 26009566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computegs)(snes,x,b,sdm->gsctx)); 2601646217ecSPeter Brune PetscStackPop; 26029566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 2603be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 26049566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval,snes,x,b,0)); 2605646217ecSPeter Brune PetscFunctionReturn(0); 2606646217ecSPeter Brune } 2607646217ecSPeter Brune 2608e885f1abSBarry Smith PetscErrorCode SNESTestJacobian(SNES snes) 2609e885f1abSBarry Smith { 261012837594SBarry Smith Mat A,B,C,D,jacobian; 2611e885f1abSBarry Smith Vec x = snes->vec_sol,f = snes->vec_func; 2612e885f1abSBarry Smith PetscReal nrm,gnorm; 261381e7118cSBarry Smith PetscReal threshold = 1.e-5; 26140e276705SLisandro Dalcin MatType mattype; 2615e885f1abSBarry Smith PetscInt m,n,M,N; 2616e885f1abSBarry Smith void *functx; 26172cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE,threshold_print = PETSC_FALSE,test = PETSC_FALSE,flg,istranspose; 26183325ff46SBarry Smith PetscViewer viewer,mviewer; 2619e885f1abSBarry Smith MPI_Comm comm; 2620e885f1abSBarry Smith PetscInt tabs; 262112837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 26223325ff46SBarry Smith PetscViewerFormat format; 2623e885f1abSBarry Smith 2624e885f1abSBarry Smith PetscFunctionBegin; 2625d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 26269566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian","Compare hand-coded and finite difference Jacobians","None",&test)); 26279566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold,NULL)); 26289566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_view","View difference between hand-coded and finite difference Jacobians element entries","None",&mviewer,&format,&complete_print)); 262918d89885SKarl Rupp if (!complete_print) { 26309566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display","-snes_test_jacobian_view","3.13",NULL)); 26319566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_display","Display difference between hand-coded and finite difference Jacobians","None",&mviewer,&format,&complete_print)); 263218d89885SKarl Rupp } 263318d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 26349566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold","-snes_test_jacobian","3.13","-snes_test_jacobian accepts an optional threshold (since v3.10)")); 26359566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian_display_threshold", "Display difference between hand-coded and finite difference Jacobians which exceed input threshold", "None", threshold, &threshold, &threshold_print)); 2636d0609cedSBarry Smith PetscOptionsEnd(); 2637e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2638e885f1abSBarry Smith 26399566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes,&comm)); 26409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm,&viewer)); 26419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 26429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 26439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian -------------\n")); 264412837594SBarry Smith if (!complete_print && !directionsprinted) { 26459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 26469566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 264712837594SBarry Smith } 264812837594SBarry Smith if (!directionsprinted) { 26499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 26509566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 265112837594SBarry Smith directionsprinted = PETSC_TRUE; 2652e885f1abSBarry Smith } 26533325ff46SBarry Smith if (complete_print) { 26549566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(mviewer,format)); 2655e885f1abSBarry Smith } 2656e885f1abSBarry Smith 26579566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian,MATMFFD,&flg)); 265812837594SBarry Smith if (!flg) jacobian = snes->jacobian; 265912837594SBarry Smith else jacobian = snes->jacobian_pre; 266012837594SBarry Smith 2661a82339d0SMatthew G. Knepley if (!x) { 26629566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2663a82339d0SMatthew G. Knepley } else { 26649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) x)); 2665a82339d0SMatthew G. Knepley } 2666a82339d0SMatthew G. Knepley if (!f) { 26679566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2668a82339d0SMatthew G. Knepley } else { 26699566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) f)); 2670a82339d0SMatthew G. Knepley } 2671a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 26729566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes,x,f)); 26739566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 26749566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes,SNESKSPTRANSPOSEONLY,&istranspose)); 267512837594SBarry Smith while (jacobian) { 26762cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 26772cd624f9SStefano Zampini 26782cd624f9SStefano Zampini if (istranspose) { 26799566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian,&JT)); 26802cd624f9SStefano Zampini Jsave = jacobian; 26812cd624f9SStefano Zampini jacobian = JT; 26822cd624f9SStefano Zampini } 26839566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPISBAIJ,"")); 268412837594SBarry Smith if (flg) { 268512837594SBarry Smith A = jacobian; 26869566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 268712837594SBarry Smith } else { 26889566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian,MATAIJ,&A)); 268912837594SBarry Smith } 2690e885f1abSBarry Smith 26919566063dSJacob Faibussowitsch PetscCall(MatGetType(A,&mattype)); 26929566063dSJacob Faibussowitsch PetscCall(MatGetSize(A,&M,&N)); 26939566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A,&m,&n)); 26949566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&B)); 26959566063dSJacob Faibussowitsch PetscCall(MatSetType(B,mattype)); 26969566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B,m,n,M,N)); 26979566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B,A,A)); 26989566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 26999566063dSJacob Faibussowitsch PetscCall(MatSetOption(B,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); 2700e885f1abSBarry Smith 27019566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,NULL,NULL,&functx)); 27029566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes,x,B,B,functx)); 270312837594SBarry Smith 27049566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B,MAT_COPY_VALUES,&D)); 27059566063dSJacob Faibussowitsch PetscCall(MatAYPX(D,-1.0,A,DIFFERENT_NONZERO_PATTERN)); 27069566063dSJacob Faibussowitsch PetscCall(MatNorm(D,NORM_FROBENIUS,&nrm)); 27079566063dSJacob Faibussowitsch PetscCall(MatNorm(A,NORM_FROBENIUS,&gnorm)); 27089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 270912837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 27109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n",(double)(nrm/gnorm),(double)nrm)); 271112837594SBarry Smith 2712e885f1abSBarry Smith if (complete_print) { 27139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded Jacobian ----------\n")); 27149566063dSJacob Faibussowitsch PetscCall(MatView(A,mviewer)); 27159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Finite difference Jacobian ----------\n")); 27169566063dSJacob Faibussowitsch PetscCall(MatView(B,mviewer)); 2717e885f1abSBarry Smith } 2718e885f1abSBarry Smith 2719df10fb39SFande Kong if (threshold_print || complete_print) { 2720e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2721e885f1abSBarry Smith PetscScalar *cvals; 2722e885f1abSBarry Smith const PetscInt *bcols; 2723e885f1abSBarry Smith const PetscScalar *bvals; 2724e885f1abSBarry Smith 27259566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A),&C)); 27269566063dSJacob Faibussowitsch PetscCall(MatSetType(C,mattype)); 27279566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C,m,n,M,N)); 27289566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C,A,A)); 27299566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 27309566063dSJacob Faibussowitsch PetscCall(MatSetOption(C,MAT_NEW_NONZERO_ALLOCATION_ERR,PETSC_FALSE)); 27310e276705SLisandro Dalcin 27329566063dSJacob Faibussowitsch PetscCall(MatAYPX(B,-1.0,A,DIFFERENT_NONZERO_PATTERN)); 27339566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B,&Istart,&Iend)); 2734e885f1abSBarry Smith 2735e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 27369566063dSJacob Faibussowitsch PetscCall(MatGetRow(B,row,&bncols,&bcols,&bvals)); 27379566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols,&ccols,bncols,&cvals)); 2738e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 273923a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2740e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2741e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2742e885f1abSBarry Smith cncols += 1; 2743e885f1abSBarry Smith } 2744e885f1abSBarry Smith } 2745e885f1abSBarry Smith if (cncols) { 27469566063dSJacob Faibussowitsch PetscCall(MatSetValues(C,1,&row,cncols,ccols,cvals,INSERT_VALUES)); 2747e885f1abSBarry Smith } 27489566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B,row,&bncols,&bcols,&bvals)); 27499566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols,cvals)); 2750e885f1abSBarry Smith } 27519566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C,MAT_FINAL_ASSEMBLY)); 27529566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C,MAT_FINAL_ASSEMBLY)); 27539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n",(double)threshold)); 27549566063dSJacob Faibussowitsch PetscCall(MatView(C,complete_print ? mviewer : viewer)); 27559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2756e885f1abSBarry Smith } 27579566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 27589566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 27599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 27602cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 276112837594SBarry Smith if (jacobian != snes->jacobian_pre) { 276212837594SBarry Smith jacobian = snes->jacobian_pre; 27639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer," ---------- Testing Jacobian for preconditioner -------------\n")); 276412837594SBarry Smith } 276512837594SBarry Smith else jacobian = NULL; 276612837594SBarry Smith } 27679566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 27683325ff46SBarry Smith if (complete_print) { 27699566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(mviewer)); 27703325ff46SBarry Smith } 27719566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 27729566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer,tabs)); 2773e885f1abSBarry Smith PetscFunctionReturn(0); 2774e885f1abSBarry Smith } 2775e885f1abSBarry Smith 277662fef451SLois Curfman McInnes /*@ 2777bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 277862fef451SLois Curfman McInnes 2779d083f849SBarry Smith Collective on SNES 2780c7afd0dbSLois Curfman McInnes 278162fef451SLois Curfman McInnes Input Parameters: 2782c7afd0dbSLois Curfman McInnes + snes - the SNES context 2783c7afd0dbSLois Curfman McInnes - x - input vector 278462fef451SLois Curfman McInnes 278562fef451SLois Curfman McInnes Output Parameters: 2786c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2787d1e9a80fSBarry Smith - B - optional preconditioning matrix 2788fee21e36SBarry Smith 2789e35cf81dSBarry Smith Options Database Keys: 279067b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 279167b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2792455a5933SJed Brown . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one compute via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 2793455a5933SJed Brown . -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian 2794693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2795693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2796693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27974c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 279894d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2799a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2800c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2801c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2802c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2803a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2804a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2805c01495d3SJed Brown 280662fef451SLois Curfman McInnes Notes: 280762fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 280862fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 280962fef451SLois Curfman McInnes 281095452b02SPatrick Sanan Developer Notes: 281195452b02SPatrick Sanan This has duplicative ways of checking the accuracy of the user provided Jacobian (see the options above). This is for historical reasons, the routine SNESTestJacobian() use to used 2812e885f1abSBarry Smith for with the SNESType of test that has been removed. 2813e885f1abSBarry Smith 281436851e7fSLois Curfman McInnes Level: developer 281536851e7fSLois Curfman McInnes 2816db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 281762fef451SLois Curfman McInnes @*/ 2818d1e9a80fSBarry Smith PetscErrorCode SNESComputeJacobian(SNES snes,Vec X,Mat A,Mat B) 28199b94acceSBarry Smith { 2820ace3abfcSBarry Smith PetscBool flag; 28216cab3a1bSJed Brown DM dm; 2822942e3340SBarry Smith DMSNES sdm; 2823e0e3a89bSBarry Smith KSP ksp; 28243a40ed3dSBarry Smith 28253a40ed3dSBarry Smith PetscFunctionBegin; 28260700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 28270700a824SBarry Smith PetscValidHeaderSpecific(X,VEC_CLASSID,2); 2828c9780b6fSBarry Smith PetscCheckSameComm(snes,1,X,2); 28299566063dSJacob Faibussowitsch PetscCall(VecValidValues(X,2,PETSC_TRUE)); 28309566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 28319566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 28323232da50SPeter Brune 28335f80ce2aSJacob Faibussowitsch PetscCheck(sdm->ops->computejacobian,PetscObjectComm((PetscObject)snes),PETSC_ERR_USER,"Must call SNESSetJacobian(), DMSNESSetJacobian(), DMDASNESSetJacobianLocal(), etc"); 2834ebd3b9afSBarry Smith 2835ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2836ebd3b9afSBarry Smith 2837fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2838fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2839f5af7f23SKarl Rupp 28409566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2841fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 28429566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is -1\n")); 28439566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag)); 2844ebd3b9afSBarry Smith if (flag) { 28459566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 28469566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2847ebd3b9afSBarry Smith } 2848e35cf81dSBarry Smith PetscFunctionReturn(0); 284937ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 285063a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagjacobian,snes->iter)); 28519566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A,MATMFFD,&flag)); 2852ebd3b9afSBarry Smith if (flag) { 28539566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 28549566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2855ebd3b9afSBarry Smith } 2856e35cf81dSBarry Smith PetscFunctionReturn(0); 2857e35cf81dSBarry Smith } 2858efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 28599566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A,MAT_FINAL_ASSEMBLY)); 28609566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A,MAT_FINAL_ASSEMBLY)); 2861d728fb7dSPeter Brune PetscFunctionReturn(0); 2862d728fb7dSPeter Brune } 2863e35cf81dSBarry Smith 28649566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval,snes,X,A,B)); 28659566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2866d64ed03dSBarry Smith PetscStackPush("SNES user Jacobian function"); 28679566063dSJacob Faibussowitsch PetscCall((*sdm->ops->computejacobian)(snes,X,A,B,sdm->jacobianctx)); 2868d64ed03dSBarry Smith PetscStackPop; 28699566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 28709566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval,snes,X,A,B)); 287128d58a37SPierre Jolivet 287228d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 28739566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B,"__SNES_latest_X",(PetscObject)X)); 2874a8054027SBarry Smith 2875e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 28769566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 28773b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 28789566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Rebuilding preconditioner exactly once since lag is -2\n")); 28799566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE)); 28803b4f5425SBarry Smith snes->lagpreconditioner = -1; 28813b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 28829566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is -1\n")); 28839566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE)); 288437ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 288563a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n",snes->lagpreconditioner,snes->iter)); 28869566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_TRUE)); 2887d1e9a80fSBarry Smith } else { 28889566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes,"Rebuilding preconditioner\n")); 28899566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp,PETSC_FALSE)); 2890a8054027SBarry Smith } 2891a8054027SBarry Smith 28929566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 28936d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 289494ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 289594ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2896693365a8SJed Brown { 2897693365a8SJed Brown PetscBool flag = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_operator = PETSC_FALSE; 28989566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit",NULL,NULL,&flag)); 28999566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw",NULL,NULL,&flag_draw)); 29009566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_explicit_draw_contour",NULL,NULL,&flag_contour)); 29019566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject) snes)->options,((PetscObject)snes)->prefix,"-snes_compare_operator",NULL,NULL,&flag_operator)); 2902693365a8SJed Brown if (flag || flag_draw || flag_contour) { 29030298fd71SBarry Smith Mat Bexp_mine = NULL,Bexp,FDexp; 2904693365a8SJed Brown PetscViewer vdraw,vstdout; 29056b3a5b13SJed Brown PetscBool flg; 2906693365a8SJed Brown if (flag_operator) { 29079566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A,MATAIJ,&Bexp_mine)); 2908693365a8SJed Brown Bexp = Bexp_mine; 2909693365a8SJed Brown } else { 2910693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 29119566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B,&flg,MATSEQAIJ,MATMPIAIJ,MATSEQDENSE,MATMPIDENSE,MATSEQBAIJ,MATMPIBAIJ,MATSEQSBAIJ,MATMPIBAIJ,"")); 291294ab13aaSBarry Smith if (flg) Bexp = B; 2913693365a8SJed Brown else { 2914693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 29159566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B,MATAIJ,&Bexp_mine)); 2916693365a8SJed Brown Bexp = Bexp_mine; 2917693365a8SJed Brown } 2918693365a8SJed Brown } 29199566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp,MATSAME,MAT_INITIAL_MATRIX,&FDexp)); 29209566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes,X,FDexp,FDexp,NULL)); 29219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout)); 2922693365a8SJed Brown if (flag_draw || flag_contour) { 29239566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Explicit Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw)); 29249566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 29250298fd71SBarry Smith } else vdraw = NULL; 29269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit %s\n",flag_operator ? "Jacobian" : "preconditioning Jacobian")); 29279566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp,vstdout)); 29289566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp,vdraw)); 29299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"Finite difference Jacobian\n")); 29309566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp,vstdout)); 29319566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp,vdraw)); 29329566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp,-1.0,Bexp,SAME_NONZERO_PATTERN)); 29339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian\n")); 29349566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp,vstdout)); 2935693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 29369566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 29379566063dSJacob Faibussowitsch PetscCall(MatView(FDexp,vdraw)); 29389566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2939693365a8SJed Brown } 29409566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 29419566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29429566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 29439566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2944693365a8SJed Brown } 2945693365a8SJed Brown } 29464c30e9fbSJed Brown { 29476719d8e4SJed Brown PetscBool flag = PETSC_FALSE,flag_display = PETSC_FALSE,flag_draw = PETSC_FALSE,flag_contour = PETSC_FALSE,flag_threshold = PETSC_FALSE; 29486719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON,threshold_rtol = 10*PETSC_SQRT_MACHINE_EPSILON; 29499566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring",NULL,NULL,&flag)); 29509566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_display",NULL,NULL,&flag_display)); 29519566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw",NULL,NULL,&flag_draw)); 29529566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_draw_contour",NULL,NULL,&flag_contour)); 29539566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold",NULL,NULL,&flag_threshold)); 295427b0f280SBarry Smith if (flag_threshold) { 29559566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_rtol",&threshold_rtol,NULL)); 29569566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_compare_coloring_threshold_atol",&threshold_atol,NULL)); 295727b0f280SBarry Smith } 29586719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 29594c30e9fbSJed Brown Mat Bfd; 29604c30e9fbSJed Brown PetscViewer vdraw,vstdout; 2961335efc43SPeter Brune MatColoring coloring; 29624c30e9fbSJed Brown ISColoring iscoloring; 29634c30e9fbSJed Brown MatFDColoring matfdcoloring; 29644c30e9fbSJed Brown PetscErrorCode (*func)(SNES,Vec,Vec,void*); 29654c30e9fbSJed Brown void *funcctx; 29666719d8e4SJed Brown PetscReal norm1,norm2,normmax; 29674c30e9fbSJed Brown 29689566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B,MAT_DO_NOT_COPY_VALUES,&Bfd)); 29699566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd,&coloring)); 29709566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring,MATCOLORINGSL)); 29719566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 29729566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring,&iscoloring)); 29739566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 29749566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd,iscoloring,&matfdcoloring)); 29759566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29769566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd,iscoloring,matfdcoloring)); 29779566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 29784c30e9fbSJed Brown 29794c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 29809566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,NULL,&func,&funcctx)); 29819566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring,(PetscErrorCode (*)(void))func,funcctx)); 29829566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring,((PetscObject)snes)->prefix)); 29839566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring,"coloring_")); 29849566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29859566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd,matfdcoloring,X,snes)); 29869566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 29874c30e9fbSJed Brown 29889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes),&vstdout)); 29894c30e9fbSJed Brown if (flag_draw || flag_contour) { 29909566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes),NULL,"Colored Jacobians",PETSC_DECIDE,PETSC_DECIDE,300,300,&vdraw)); 29919566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 29920298fd71SBarry Smith } else vdraw = NULL; 29939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"Explicit preconditioning Jacobian\n")); 29949566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B,vstdout)); 29959566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B,vdraw)); 29969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"Colored Finite difference Jacobian\n")); 29979566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd,vstdout)); 29989566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd,vdraw)); 29999566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd,-1.0,B,SAME_NONZERO_PATTERN)); 30009566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd,NORM_1,&norm1)); 30019566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd,NORM_FROBENIUS,&norm2)); 30029566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd,NORM_MAX,&normmax)); 30039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n",(double)norm1,(double)norm2,(double)normmax)); 30049566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd,vstdout)); 30054c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 30069566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw,PETSC_VIEWER_DRAW_CONTOUR)); 30079566063dSJacob Faibussowitsch PetscCall(MatView(Bfd,vdraw)); 30089566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 30094c30e9fbSJed Brown } 30109566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 30116719d8e4SJed Brown 30126719d8e4SJed Brown if (flag_threshold) { 30136719d8e4SJed Brown PetscInt bs,rstart,rend,i; 30149566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B,&bs)); 30159566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B,&rstart,&rend)); 30166719d8e4SJed Brown for (i=rstart; i<rend; i++) { 30176719d8e4SJed Brown const PetscScalar *ba,*ca; 30186719d8e4SJed Brown const PetscInt *bj,*cj; 30196719d8e4SJed Brown PetscInt bn,cn,j,maxentrycol = -1,maxdiffcol = -1,maxrdiffcol = -1; 30206719d8e4SJed Brown PetscReal maxentry = 0,maxdiff = 0,maxrdiff = 0; 30219566063dSJacob Faibussowitsch PetscCall(MatGetRow(B,i,&bn,&bj,&ba)); 30229566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd,i,&cn,&cj,&ca)); 30235f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn,((PetscObject)A)->comm,PETSC_ERR_PLIB,"Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 30246719d8e4SJed Brown for (j=0; j<bn; j++) { 30256719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 30266719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 30276719d8e4SJed Brown maxentrycol = bj[j]; 30286719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 30296719d8e4SJed Brown } 30306719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 30316719d8e4SJed Brown maxdiffcol = bj[j]; 30326719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 30336719d8e4SJed Brown } 30346719d8e4SJed Brown if (rdiff > maxrdiff) { 30356719d8e4SJed Brown maxrdiffcol = bj[j]; 30366719d8e4SJed Brown maxrdiff = rdiff; 30376719d8e4SJed Brown } 30386719d8e4SJed Brown } 30396719d8e4SJed Brown if (maxrdiff > 1) { 304063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"row %" PetscInt_FMT " (maxentry=%g at %" PetscInt_FMT ", maxdiff=%g at %" PetscInt_FMT ", maxrdiff=%g at %" PetscInt_FMT "):",i,(double)maxentry,maxentrycol,(double)maxdiff,maxdiffcol,(double)maxrdiff,maxrdiffcol)); 30416719d8e4SJed Brown for (j=0; j<bn; j++) { 30426719d8e4SJed Brown PetscReal rdiff; 30436719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol*PetscAbsScalar(ba[j])); 30446719d8e4SJed Brown if (rdiff > 1) { 304563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout," (%" PetscInt_FMT ",%g:%g)",bj[j],(double)PetscRealPart(ba[j]),(double)PetscRealPart(ca[j]))); 30466719d8e4SJed Brown } 30476719d8e4SJed Brown } 304863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout,"\n")); 30496719d8e4SJed Brown } 30509566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B,i,&bn,&bj,&ba)); 30519566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd,i,&cn,&cj,&ca)); 30526719d8e4SJed Brown } 30536719d8e4SJed Brown } 30549566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 30559566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 30564c30e9fbSJed Brown } 30574c30e9fbSJed Brown } 30583a40ed3dSBarry Smith PetscFunctionReturn(0); 30599b94acceSBarry Smith } 30609b94acceSBarry Smith 3061bf388a1fSBarry Smith /*MC 3062411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 3063bf388a1fSBarry Smith 3064bf388a1fSBarry Smith Synopsis: 3065411c0326SBarry Smith #include "petscsnes.h" 3066411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3067bf388a1fSBarry Smith 30681843f636SBarry Smith Collective on snes 30691843f636SBarry Smith 30701843f636SBarry Smith Input Parameters: 30711843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 3072bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 3073bf388a1fSBarry Smith 30741843f636SBarry Smith Output Parameters: 30751843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 30761843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 30771843f636SBarry Smith 3078878cb397SSatish Balay Level: intermediate 3079878cb397SSatish Balay 3080db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 3081bf388a1fSBarry Smith M*/ 3082bf388a1fSBarry Smith 30839b94acceSBarry Smith /*@C 30849b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 3085044dda88SLois Curfman McInnes location to store the matrix. 30869b94acceSBarry Smith 3087d083f849SBarry Smith Logically Collective on SNES 3088c7afd0dbSLois Curfman McInnes 30899b94acceSBarry Smith Input Parameters: 3090c7afd0dbSLois Curfman McInnes + snes - the SNES context 3091e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3092e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 3093411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 3094c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 30950298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 30969b94acceSBarry Smith 30979b94acceSBarry Smith Notes: 3098e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 309916913363SBarry Smith each matrix. 310016913363SBarry Smith 3101895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 3102895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 3103895c21f2SBarry Smith 31048d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 3105a8a26c1eSJed Brown must be a MatFDColoring. 3106a8a26c1eSJed Brown 3107c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3108c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 3109c3cc8fd1SJed Brown 311036851e7fSLois Curfman McInnes Level: beginner 311136851e7fSLois Curfman McInnes 3112db781477SPatrick Sanan .seealso: `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`, 3113db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 31149b94acceSBarry Smith @*/ 3115d1e9a80fSBarry Smith PetscErrorCode SNESSetJacobian(SNES snes,Mat Amat,Mat Pmat,PetscErrorCode (*J)(SNES,Vec,Mat,Mat,void*),void *ctx) 31169b94acceSBarry Smith { 31176cab3a1bSJed Brown DM dm; 31183a7fca6bSBarry Smith 31193a40ed3dSBarry Smith PetscFunctionBegin; 31200700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3121e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat,MAT_CLASSID,2); 3122e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat,MAT_CLASSID,3); 3123e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes,1,Amat,2); 3124e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes,1,Pmat,3); 31259566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 31269566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm,J,ctx)); 3127e5d3d808SBarry Smith if (Amat) { 31289566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 31299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 3130f5af7f23SKarl Rupp 3131e5d3d808SBarry Smith snes->jacobian = Amat; 31323a7fca6bSBarry Smith } 3133e5d3d808SBarry Smith if (Pmat) { 31349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 31359566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 3136f5af7f23SKarl Rupp 3137e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 31383a7fca6bSBarry Smith } 31393a40ed3dSBarry Smith PetscFunctionReturn(0); 31409b94acceSBarry Smith } 314162fef451SLois Curfman McInnes 3142c2aafc4cSSatish Balay /*@C 3143b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3144b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3145b4fd4287SBarry Smith 3146c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 3147c7afd0dbSLois Curfman McInnes 3148b4fd4287SBarry Smith Input Parameter: 3149b4fd4287SBarry Smith . snes - the nonlinear solver context 3150b4fd4287SBarry Smith 3151b4fd4287SBarry Smith Output Parameters: 3152e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3153e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3154411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 31550298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3156fee21e36SBarry Smith 315736851e7fSLois Curfman McInnes Level: advanced 315836851e7fSLois Curfman McInnes 3159db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3160b4fd4287SBarry Smith @*/ 3161d1e9a80fSBarry Smith PetscErrorCode SNESGetJacobian(SNES snes,Mat *Amat,Mat *Pmat,PetscErrorCode (**J)(SNES,Vec,Mat,Mat,void*),void **ctx) 3162b4fd4287SBarry Smith { 31636cab3a1bSJed Brown DM dm; 3164942e3340SBarry Smith DMSNES sdm; 31656cab3a1bSJed Brown 31663a40ed3dSBarry Smith PetscFunctionBegin; 31670700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3168e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3169e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 31709566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 31719566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 3172f8b49ee9SBarry Smith if (J) *J = sdm->ops->computejacobian; 31736cab3a1bSJed Brown if (ctx) *ctx = sdm->jacobianctx; 31743a40ed3dSBarry Smith PetscFunctionReturn(0); 3175b4fd4287SBarry Smith } 3176b4fd4287SBarry Smith 317758b371f3SBarry Smith static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 317858b371f3SBarry Smith { 317958b371f3SBarry Smith DM dm; 318058b371f3SBarry Smith DMSNES sdm; 318158b371f3SBarry Smith 318258b371f3SBarry Smith PetscFunctionBegin; 31839566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 31849566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 318558b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 318658b371f3SBarry Smith DM dm; 318758b371f3SBarry Smith PetscBool isdense,ismf; 318858b371f3SBarry Smith 31899566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 31909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&isdense,MATSEQDENSE,MATMPIDENSE,MATDENSE,NULL)); 31919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre,&ismf,MATMFFD,MATSHELL,NULL)); 319258b371f3SBarry Smith if (isdense) { 31939566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefault,NULL)); 319458b371f3SBarry Smith } else if (!ismf) { 31959566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm,SNESComputeJacobianDefaultColor,NULL)); 319658b371f3SBarry Smith } 319758b371f3SBarry Smith } 319858b371f3SBarry Smith PetscFunctionReturn(0); 319958b371f3SBarry Smith } 320058b371f3SBarry Smith 32019b94acceSBarry Smith /*@ 32029b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3203272ac6f2SLois Curfman McInnes of a nonlinear solver. 32049b94acceSBarry Smith 3205fee21e36SBarry Smith Collective on SNES 3206fee21e36SBarry Smith 3207c7afd0dbSLois Curfman McInnes Input Parameters: 320870e92668SMatthew Knepley . snes - the SNES context 3209c7afd0dbSLois Curfman McInnes 3210272ac6f2SLois Curfman McInnes Notes: 3211272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 3212272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 3213272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 3214272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 3215272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3216272ac6f2SLois Curfman McInnes 321736851e7fSLois Curfman McInnes Level: advanced 321836851e7fSLois Curfman McInnes 3219db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 32209b94acceSBarry Smith @*/ 32217087cfbeSBarry Smith PetscErrorCode SNESSetUp(SNES snes) 32229b94acceSBarry Smith { 32236cab3a1bSJed Brown DM dm; 3224942e3340SBarry Smith DMSNES sdm; 3225c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 32266e2a1849SPeter Brune void *lsprectx,*lspostctx; 32276b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch,Vec,Vec,PetscBool*,void*); 32286b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch,Vec,Vec,Vec,PetscBool*,PetscBool*,void*); 32296e2a1849SPeter Brune PetscErrorCode (*func)(SNES,Vec,Vec,void*); 32306e2a1849SPeter Brune Vec f,fpc; 32316e2a1849SPeter Brune void *funcctx; 3232d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES,Vec,Mat,Mat,void*); 32331eb13d49SPeter Brune void *jacctx,*appctx; 323432b97717SPeter Brune Mat j,jpre; 32353a40ed3dSBarry Smith 32363a40ed3dSBarry Smith PetscFunctionBegin; 32370700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 32384dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 32399566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Setup,snes,0,0,0)); 32409b94acceSBarry Smith 32417adad957SLisandro Dalcin if (!((PetscObject)snes)->type_name) { 32429566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes,SNESNEWTONLS)); 324385385478SLisandro Dalcin } 324485385478SLisandro Dalcin 32459566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,&snes->vec_func,NULL,NULL)); 324658c9b817SLisandro Dalcin 32479566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 32489566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm,&sdm)); 32495f80ce2aSJacob Faibussowitsch PetscCheck(sdm->ops->computefunction,PetscObjectComm((PetscObject)dm),PETSC_ERR_ARG_WRONGSTATE,"Function never provided to SNES object"); 32509566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 325158b371f3SBarry Smith 32526cab3a1bSJed Brown if (!snes->vec_func) { 32539566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm,&snes->vec_func)); 3254214df951SJed Brown } 3255efd51863SBarry Smith 325622d28d08SBarry Smith if (!snes->ksp) { 32579566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &snes->ksp)); 325822d28d08SBarry Smith } 3259b710008aSBarry Smith 3260d8d34be6SBarry Smith if (snes->linesearch) { 32619566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 32629566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch,SNESComputeFunction)); 3263d8d34be6SBarry Smith } 32649e764e56SPeter Brune 3265b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3266172a4300SPeter Brune snes->mf = PETSC_TRUE; 3267172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3268172a4300SPeter Brune } 3269d8f46077SPeter Brune 3270efd4aadfSBarry Smith if (snes->npc) { 32716e2a1849SPeter Brune /* copy the DM over */ 32729566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 32739566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc,dm)); 32746e2a1849SPeter Brune 32759566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes,&f,&func,&funcctx)); 32769566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f,&fpc)); 32779566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc,fpc,func,funcctx)); 32789566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes,&j,&jpre,&jac,&jacctx)); 32799566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc,j,jpre,jac,jacctx)); 32809566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes,&appctx)); 32819566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc,appctx)); 32829566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 32836e2a1849SPeter Brune 32846e2a1849SPeter Brune /* copy the function pointers over */ 32859566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes,(PetscObject)snes->npc)); 32866e2a1849SPeter Brune 32876e2a1849SPeter Brune /* default to 1 iteration */ 32889566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc,0.0,0.0,0.0,1,snes->npc->max_funcs)); 3289efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 32909566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_FINAL_ONLY)); 3291a9936a0cSPeter Brune } else { 32929566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc,SNES_NORM_NONE)); 3293a9936a0cSPeter Brune } 32949566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 32956e2a1849SPeter Brune 32966e2a1849SPeter Brune /* copy the line search context over */ 3297d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 32989566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes,&linesearch)); 32999566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc,&pclinesearch)); 33009566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch,&precheck,&lsprectx)); 33019566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch,&postcheck,&lspostctx)); 33029566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch,precheck,lsprectx)); 33039566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch,postcheck,lspostctx)); 33049566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 33056e2a1849SPeter Brune } 3306d8d34be6SBarry Smith } 330732b97717SPeter Brune if (snes->mf) { 33089566063dSJacob Faibussowitsch PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 330932b97717SPeter Brune } 331032b97717SPeter Brune if (snes->ops->usercompute && !snes->user) { 33119566063dSJacob Faibussowitsch PetscCall((*snes->ops->usercompute)(snes,(void**)&snes->user)); 331232b97717SPeter Brune } 33136e2a1849SPeter Brune 331437ec4e1aSPeter Brune snes->jac_iter = 0; 331537ec4e1aSPeter Brune snes->pre_iter = 0; 331637ec4e1aSPeter Brune 3317410397dcSLisandro Dalcin if (snes->ops->setup) { 33189566063dSJacob Faibussowitsch PetscCall((*snes->ops->setup)(snes)); 3319410397dcSLisandro Dalcin } 332058c9b817SLisandro Dalcin 33219566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 332258b371f3SBarry Smith 3323b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 33246c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3325d8d34be6SBarry Smith if (snes->linesearch) { 33269566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes,&linesearch)); 33279566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch,SNESComputeFunctionDefaultNPC)); 33286c67d002SPeter Brune } 33296c67d002SPeter Brune } 3330d8d34be6SBarry Smith } 33319566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Setup,snes,0,0,0)); 33327aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 33333a40ed3dSBarry Smith PetscFunctionReturn(0); 33349b94acceSBarry Smith } 33359b94acceSBarry Smith 333637596af1SLisandro Dalcin /*@ 333737596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 333837596af1SLisandro Dalcin 333937596af1SLisandro Dalcin Collective on SNES 334037596af1SLisandro Dalcin 334137596af1SLisandro Dalcin Input Parameter: 334237596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 334337596af1SLisandro Dalcin 3344d25893d9SBarry Smith Level: intermediate 3345d25893d9SBarry Smith 334695452b02SPatrick Sanan Notes: 334795452b02SPatrick Sanan Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 334837596af1SLisandro Dalcin 3349db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 335037596af1SLisandro Dalcin @*/ 335137596af1SLisandro Dalcin PetscErrorCode SNESReset(SNES snes) 335237596af1SLisandro Dalcin { 335337596af1SLisandro Dalcin PetscFunctionBegin; 335437596af1SLisandro Dalcin PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3355d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 33569566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void**)&snes->user)); 33570298fd71SBarry Smith snes->user = NULL; 3358d25893d9SBarry Smith } 3359efd4aadfSBarry Smith if (snes->npc) { 33609566063dSJacob Faibussowitsch PetscCall(SNESReset(snes->npc)); 33618a23116dSBarry Smith } 33628a23116dSBarry Smith 336337596af1SLisandro Dalcin if (snes->ops->reset) { 33649566063dSJacob Faibussowitsch PetscCall((*snes->ops->reset)(snes)); 336537596af1SLisandro Dalcin } 33669e764e56SPeter Brune if (snes->ksp) { 33679566063dSJacob Faibussowitsch PetscCall(KSPReset(snes->ksp)); 33689e764e56SPeter Brune } 33699e764e56SPeter Brune 33709e764e56SPeter Brune if (snes->linesearch) { 33719566063dSJacob Faibussowitsch PetscCall(SNESLineSearchReset(snes->linesearch)); 33729e764e56SPeter Brune } 33739e764e56SPeter Brune 33749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 33759566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 33769566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 33779566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 33789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 33799566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 33809566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 33819566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork,&snes->work)); 33829566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork,&snes->vwork)); 3383f5af7f23SKarl Rupp 338440fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 338540fdac6aSLawrence Mitchell 338637596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 338737596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 338837596af1SLisandro Dalcin PetscFunctionReturn(0); 338937596af1SLisandro Dalcin } 339037596af1SLisandro Dalcin 339152baeb72SSatish Balay /*@ 3392c4421ceaSFande Kong SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object. 3393c4421ceaSFande Kong 3394c4421ceaSFande Kong Collective on SNES 3395c4421ceaSFande Kong 3396c4421ceaSFande Kong Input Parameter: 3397c4421ceaSFande Kong . snes - iterative context obtained from SNESCreate() 3398c4421ceaSFande Kong 3399c4421ceaSFande Kong Level: intermediate 3400c4421ceaSFande Kong 3401db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3402c4421ceaSFande Kong @*/ 3403c4421ceaSFande Kong PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3404c4421ceaSFande Kong { 3405c4421ceaSFande Kong PetscInt i; 3406c4421ceaSFande Kong 3407c4421ceaSFande Kong PetscFunctionBegin; 3408c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3409c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews; i++) { 3410c4421ceaSFande Kong if (snes->reasonviewdestroy[i]) { 34119566063dSJacob Faibussowitsch PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3412c4421ceaSFande Kong } 3413c4421ceaSFande Kong } 3414c4421ceaSFande Kong snes->numberreasonviews = 0; 3415c4421ceaSFande Kong PetscFunctionReturn(0); 3416c4421ceaSFande Kong } 3417c4421ceaSFande Kong 34181fb7b255SJunchao Zhang /*@C 34199b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 34209b94acceSBarry Smith with SNESCreate(). 34219b94acceSBarry Smith 3422c7afd0dbSLois Curfman McInnes Collective on SNES 3423c7afd0dbSLois Curfman McInnes 34249b94acceSBarry Smith Input Parameter: 34259b94acceSBarry Smith . snes - the SNES context 34269b94acceSBarry Smith 342736851e7fSLois Curfman McInnes Level: beginner 342836851e7fSLois Curfman McInnes 3429db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSolve()` 34309b94acceSBarry Smith @*/ 34316bf464f9SBarry Smith PetscErrorCode SNESDestroy(SNES *snes) 34329b94acceSBarry Smith { 34333a40ed3dSBarry Smith PetscFunctionBegin; 34346bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 34356bf464f9SBarry Smith PetscValidHeaderSpecific((*snes),SNES_CLASSID,1); 34369e5d0892SLisandro Dalcin if (--((PetscObject)(*snes))->refct > 0) {*snes = NULL; PetscFunctionReturn(0);} 3437d4bb536fSBarry Smith 34389566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 34399566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 34406b8b9a38SLisandro Dalcin 3441e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 34429566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 34439566063dSJacob Faibussowitsch if ((*snes)->ops->destroy) PetscCall((*((*snes))->ops->destroy)((*snes))); 34446d4c513bSLisandro Dalcin 34459566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,*snes)); 34469566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 34479566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 34489566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 34496b8b9a38SLisandro Dalcin 34509566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 34516bf464f9SBarry Smith if ((*snes)->ops->convergeddestroy) { 34529566063dSJacob Faibussowitsch PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 34536b8b9a38SLisandro Dalcin } 3454071fcb05SBarry Smith if ((*snes)->conv_hist_alloc) { 34559566063dSJacob Faibussowitsch PetscCall(PetscFree2((*snes)->conv_hist,(*snes)->conv_hist_its)); 345658c9b817SLisandro Dalcin } 34579566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 34589566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 34599566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 34603a40ed3dSBarry Smith PetscFunctionReturn(0); 34619b94acceSBarry Smith } 34629b94acceSBarry Smith 34639b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 34649b94acceSBarry Smith 3465a8054027SBarry Smith /*@ 3466a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3467a8054027SBarry Smith 34683f9fe445SBarry Smith Logically Collective on SNES 3469a8054027SBarry Smith 3470a8054027SBarry Smith Input Parameters: 3471a8054027SBarry Smith + snes - the SNES context 3472d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 34733b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3474a8054027SBarry Smith 3475a8054027SBarry Smith Options Database Keys: 34763d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34773d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34783d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34793d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3480a8054027SBarry Smith 3481a8054027SBarry Smith Notes: 3482a8054027SBarry Smith The default is 1 34833d5a8a6aSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3484d8e291bfSBarry Smith 3485d8e291bfSBarry Smith SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves. 3486a8054027SBarry Smith 3487a8054027SBarry Smith Level: intermediate 3488a8054027SBarry Smith 3489db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3490db781477SPatrick Sanan `SNESSetLagJacobianPersists()` 3491a8054027SBarry Smith 3492a8054027SBarry Smith @*/ 34937087cfbeSBarry Smith PetscErrorCode SNESSetLagPreconditioner(SNES snes,PetscInt lag) 3494a8054027SBarry Smith { 3495a8054027SBarry Smith PetscFunctionBegin; 34960700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 34975f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 34985f80ce2aSJacob Faibussowitsch PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3499c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3500a8054027SBarry Smith snes->lagpreconditioner = lag; 3501a8054027SBarry Smith PetscFunctionReturn(0); 3502a8054027SBarry Smith } 3503a8054027SBarry Smith 3504efd51863SBarry Smith /*@ 3505efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3506efd51863SBarry Smith 3507efd51863SBarry Smith Logically Collective on SNES 3508efd51863SBarry Smith 3509efd51863SBarry Smith Input Parameters: 3510efd51863SBarry Smith + snes - the SNES context 3511efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3512efd51863SBarry Smith 3513efd51863SBarry Smith Options Database Keys: 351467b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3515efd51863SBarry Smith 3516efd51863SBarry Smith Level: intermediate 3517efd51863SBarry Smith 3518c0df2a02SJed Brown Notes: 3519c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3520c0df2a02SJed Brown 3521db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3522efd51863SBarry Smith 3523efd51863SBarry Smith @*/ 3524efd51863SBarry Smith PetscErrorCode SNESSetGridSequence(SNES snes,PetscInt steps) 3525efd51863SBarry Smith { 3526efd51863SBarry Smith PetscFunctionBegin; 3527efd51863SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3528efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes,steps,2); 3529efd51863SBarry Smith snes->gridsequence = steps; 3530efd51863SBarry Smith PetscFunctionReturn(0); 3531efd51863SBarry Smith } 3532efd51863SBarry Smith 3533fa19ca70SBarry Smith /*@ 3534fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3535fa19ca70SBarry Smith 3536fa19ca70SBarry Smith Logically Collective on SNES 3537fa19ca70SBarry Smith 3538fa19ca70SBarry Smith Input Parameter: 3539fa19ca70SBarry Smith . snes - the SNES context 3540fa19ca70SBarry Smith 3541fa19ca70SBarry Smith Output Parameter: 3542fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3543fa19ca70SBarry Smith 3544fa19ca70SBarry Smith Options Database Keys: 354567b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3546fa19ca70SBarry Smith 3547fa19ca70SBarry Smith Level: intermediate 3548fa19ca70SBarry Smith 3549fa19ca70SBarry Smith Notes: 3550fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3551fa19ca70SBarry Smith 3552db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3553fa19ca70SBarry Smith 3554fa19ca70SBarry Smith @*/ 3555fa19ca70SBarry Smith PetscErrorCode SNESGetGridSequence(SNES snes,PetscInt *steps) 3556fa19ca70SBarry Smith { 3557fa19ca70SBarry Smith PetscFunctionBegin; 3558fa19ca70SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3559fa19ca70SBarry Smith *steps = snes->gridsequence; 3560fa19ca70SBarry Smith PetscFunctionReturn(0); 3561fa19ca70SBarry Smith } 3562fa19ca70SBarry Smith 3563a8054027SBarry Smith /*@ 3564a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3565a8054027SBarry Smith 35663f9fe445SBarry Smith Not Collective 3567a8054027SBarry Smith 3568a8054027SBarry Smith Input Parameter: 3569a8054027SBarry Smith . snes - the SNES context 3570a8054027SBarry Smith 3571a8054027SBarry Smith Output Parameter: 3572a8054027SBarry Smith . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 35733b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3574a8054027SBarry Smith 3575a8054027SBarry Smith Options Database Keys: 35763d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35773d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35783d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35793d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3580a8054027SBarry Smith 3581a8054027SBarry Smith Notes: 3582a8054027SBarry Smith The default is 1 3583a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3584a8054027SBarry Smith 3585a8054027SBarry Smith Level: intermediate 3586a8054027SBarry Smith 3587db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3588a8054027SBarry Smith 3589a8054027SBarry Smith @*/ 35907087cfbeSBarry Smith PetscErrorCode SNESGetLagPreconditioner(SNES snes,PetscInt *lag) 3591a8054027SBarry Smith { 3592a8054027SBarry Smith PetscFunctionBegin; 35930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3594a8054027SBarry Smith *lag = snes->lagpreconditioner; 3595a8054027SBarry Smith PetscFunctionReturn(0); 3596a8054027SBarry Smith } 3597a8054027SBarry Smith 3598e35cf81dSBarry Smith /*@ 3599e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3600e35cf81dSBarry Smith often the preconditioner is rebuilt. 3601e35cf81dSBarry Smith 36023f9fe445SBarry Smith Logically Collective on SNES 3603e35cf81dSBarry Smith 3604e35cf81dSBarry Smith Input Parameters: 3605e35cf81dSBarry Smith + snes - the SNES context 3606e35cf81dSBarry Smith - lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3607fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3608e35cf81dSBarry Smith 3609e35cf81dSBarry Smith Options Database Keys: 36103d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36113d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36123d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36133d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3614e35cf81dSBarry Smith 3615e35cf81dSBarry Smith Notes: 3616e35cf81dSBarry Smith The default is 1 3617e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3618fe3ffe1eSBarry Smith If -1 is used before the very first nonlinear solve the CODE WILL FAIL! because no Jacobian is used, use -2 to indicate you want it recomputed 3619fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3620e35cf81dSBarry Smith 3621e35cf81dSBarry Smith Level: intermediate 3622e35cf81dSBarry Smith 3623db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3624e35cf81dSBarry Smith 3625e35cf81dSBarry Smith @*/ 36267087cfbeSBarry Smith PetscErrorCode SNESSetLagJacobian(SNES snes,PetscInt lag) 3627e35cf81dSBarry Smith { 3628e35cf81dSBarry Smith PetscFunctionBegin; 36290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 36305f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag must be -2, -1, 1 or greater"); 36315f80ce2aSJacob Faibussowitsch PetscCheck(lag,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Lag cannot be 0"); 3632c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,lag,2); 3633e35cf81dSBarry Smith snes->lagjacobian = lag; 3634e35cf81dSBarry Smith PetscFunctionReturn(0); 3635e35cf81dSBarry Smith } 3636e35cf81dSBarry Smith 3637e35cf81dSBarry Smith /*@ 3638e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3639e35cf81dSBarry Smith 36403f9fe445SBarry Smith Not Collective 3641e35cf81dSBarry Smith 3642e35cf81dSBarry Smith Input Parameter: 3643e35cf81dSBarry Smith . snes - the SNES context 3644e35cf81dSBarry Smith 3645e35cf81dSBarry Smith Output Parameter: 3646e35cf81dSBarry Smith . lag - -1 indicates NEVER rebuild, 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 3647e35cf81dSBarry Smith the Jacobian is built etc. 3648e35cf81dSBarry Smith 3649e35cf81dSBarry Smith Notes: 3650e35cf81dSBarry Smith The default is 1 36513d5a8a6aSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3652e35cf81dSBarry Smith 3653e35cf81dSBarry Smith Level: intermediate 3654e35cf81dSBarry Smith 3655db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3656e35cf81dSBarry Smith 3657e35cf81dSBarry Smith @*/ 36587087cfbeSBarry Smith PetscErrorCode SNESGetLagJacobian(SNES snes,PetscInt *lag) 3659e35cf81dSBarry Smith { 3660e35cf81dSBarry Smith PetscFunctionBegin; 36610700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3662e35cf81dSBarry Smith *lag = snes->lagjacobian; 3663e35cf81dSBarry Smith PetscFunctionReturn(0); 3664e35cf81dSBarry Smith } 3665e35cf81dSBarry Smith 366637ec4e1aSPeter Brune /*@ 366737ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 366837ec4e1aSPeter Brune 366937ec4e1aSPeter Brune Logically collective on SNES 367037ec4e1aSPeter Brune 3671d8d19677SJose E. Roman Input Parameters: 367237ec4e1aSPeter Brune + snes - the SNES context 36739d7e2deaSPeter Brune - flg - jacobian lagging persists if true 367437ec4e1aSPeter Brune 367537ec4e1aSPeter Brune Options Database Keys: 36763d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36773d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36783d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36793d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 36803d5a8a6aSBarry Smith 368195452b02SPatrick Sanan Notes: 368295452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 368337ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 368437ec4e1aSPeter Brune timesteps may present huge efficiency gains. 368537ec4e1aSPeter Brune 368637ec4e1aSPeter Brune Level: developer 368737ec4e1aSPeter Brune 3688db781477SPatrick Sanan .seealso: `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 368937ec4e1aSPeter Brune 369037ec4e1aSPeter Brune @*/ 369137ec4e1aSPeter Brune PetscErrorCode SNESSetLagJacobianPersists(SNES snes,PetscBool flg) 369237ec4e1aSPeter Brune { 369337ec4e1aSPeter Brune PetscFunctionBegin; 369437ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 369537ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 369637ec4e1aSPeter Brune snes->lagjac_persist = flg; 369737ec4e1aSPeter Brune PetscFunctionReturn(0); 369837ec4e1aSPeter Brune } 369937ec4e1aSPeter Brune 370037ec4e1aSPeter Brune /*@ 3701d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 370237ec4e1aSPeter Brune 370337ec4e1aSPeter Brune Logically Collective on SNES 370437ec4e1aSPeter Brune 3705d8d19677SJose E. Roman Input Parameters: 370637ec4e1aSPeter Brune + snes - the SNES context 37079d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 370837ec4e1aSPeter Brune 370937ec4e1aSPeter Brune Options Database Keys: 37103d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 37113d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 37123d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 37133d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 371437ec4e1aSPeter Brune 371595452b02SPatrick Sanan Notes: 371695452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 371737ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 371837ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 371937ec4e1aSPeter Brune 372037ec4e1aSPeter Brune Level: developer 372137ec4e1aSPeter Brune 3722db781477SPatrick Sanan .seealso: `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 372337ec4e1aSPeter Brune 372437ec4e1aSPeter Brune @*/ 372537ec4e1aSPeter Brune PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes,PetscBool flg) 372637ec4e1aSPeter Brune { 372737ec4e1aSPeter Brune PetscFunctionBegin; 372837ec4e1aSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 372937ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes,flg,2); 373037ec4e1aSPeter Brune snes->lagpre_persist = flg; 373137ec4e1aSPeter Brune PetscFunctionReturn(0); 373237ec4e1aSPeter Brune } 373337ec4e1aSPeter Brune 37349b94acceSBarry Smith /*@ 3735be5caee7SBarry Smith SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3736be5caee7SBarry Smith 3737be5caee7SBarry Smith Logically Collective on SNES 3738be5caee7SBarry Smith 3739be5caee7SBarry Smith Input Parameters: 3740be5caee7SBarry Smith + snes - the SNES context 3741be5caee7SBarry Smith - force - PETSC_TRUE require at least one iteration 3742be5caee7SBarry Smith 3743be5caee7SBarry Smith Options Database Keys: 3744be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3745be5caee7SBarry Smith 3746be5caee7SBarry Smith Notes: 3747be5caee7SBarry Smith This is used sometimes with TS to prevent TS from detecting a false steady state solution 3748be5caee7SBarry Smith 3749be5caee7SBarry Smith Level: intermediate 3750be5caee7SBarry Smith 3751db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3752be5caee7SBarry Smith @*/ 3753be5caee7SBarry Smith PetscErrorCode SNESSetForceIteration(SNES snes,PetscBool force) 3754be5caee7SBarry Smith { 3755be5caee7SBarry Smith PetscFunctionBegin; 3756be5caee7SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3757be5caee7SBarry Smith snes->forceiteration = force; 3758be5caee7SBarry Smith PetscFunctionReturn(0); 3759be5caee7SBarry Smith } 3760be5caee7SBarry Smith 376185216dc7SFande Kong /*@ 376285216dc7SFande Kong SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 376385216dc7SFande Kong 376485216dc7SFande Kong Logically Collective on SNES 376585216dc7SFande Kong 376685216dc7SFande Kong Input Parameters: 376785216dc7SFande Kong . snes - the SNES context 376885216dc7SFande Kong 376985216dc7SFande Kong Output Parameter: 377085216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 377185216dc7SFande Kong 377206dd6b0eSSatish Balay Level: intermediate 377306dd6b0eSSatish Balay 3774db781477SPatrick Sanan .seealso: `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 377585216dc7SFande Kong @*/ 377685216dc7SFande Kong PetscErrorCode SNESGetForceIteration(SNES snes,PetscBool *force) 377785216dc7SFande Kong { 377885216dc7SFande Kong PetscFunctionBegin; 377985216dc7SFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 378085216dc7SFande Kong *force = snes->forceiteration; 378185216dc7SFande Kong PetscFunctionReturn(0); 378285216dc7SFande Kong } 3783be5caee7SBarry Smith 3784be5caee7SBarry Smith /*@ 3785d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 37869b94acceSBarry Smith 37873f9fe445SBarry Smith Logically Collective on SNES 3788c7afd0dbSLois Curfman McInnes 37899b94acceSBarry Smith Input Parameters: 3790c7afd0dbSLois Curfman McInnes + snes - the SNES context 379170441072SBarry Smith . abstol - absolute convergence tolerance 379233174efeSLois Curfman McInnes . rtol - relative convergence tolerance 37935358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 379433174efeSLois Curfman McInnes . maxit - maximum number of iterations 3795e71169deSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit) 3796fee21e36SBarry Smith 379733174efeSLois Curfman McInnes Options Database Keys: 379870441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3799c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3800c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3801c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3802c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 38039b94acceSBarry Smith 3804d7a720efSLois Curfman McInnes Notes: 38059b94acceSBarry Smith The default maximum number of iterations is 50. 38069b94acceSBarry Smith The default maximum number of function evaluations is 1000. 38079b94acceSBarry Smith 380836851e7fSLois Curfman McInnes Level: intermediate 380936851e7fSLois Curfman McInnes 3810db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 38119b94acceSBarry Smith @*/ 38127087cfbeSBarry Smith PetscErrorCode SNESSetTolerances(SNES snes,PetscReal abstol,PetscReal rtol,PetscReal stol,PetscInt maxit,PetscInt maxf) 38139b94acceSBarry Smith { 38143a40ed3dSBarry Smith PetscFunctionBegin; 38150700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3816c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,abstol,2); 3817c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol,3); 3818c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,stol,4); 3819c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxit,5); 3820c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,maxf,6); 3821c5eb9154SBarry Smith 3822ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 38235f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Absolute tolerance %g must be non-negative",(double)abstol); 3824ab54825eSJed Brown snes->abstol = abstol; 3825ab54825eSJed Brown } 3826ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 38275f80ce2aSJacob Faibussowitsch PetscCheck(rtol >= 0.0 && 1.0 > rtol,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Relative tolerance %g must be non-negative and less than 1.0",(double)rtol); 3828ab54825eSJed Brown snes->rtol = rtol; 3829ab54825eSJed Brown } 3830ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 38315f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Step tolerance %g must be non-negative",(double)stol); 3832c60f73f4SPeter Brune snes->stol = stol; 3833ab54825eSJed Brown } 3834ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 383563a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of iterations %" PetscInt_FMT " must be non-negative",maxit); 3836ab54825eSJed Brown snes->max_its = maxit; 3837ab54825eSJed Brown } 3838ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 383963a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_OUTOFRANGE,"Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative",maxf); 3840ab54825eSJed Brown snes->max_funcs = maxf; 3841ab54825eSJed Brown } 384288976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 38433a40ed3dSBarry Smith PetscFunctionReturn(0); 38449b94acceSBarry Smith } 38459b94acceSBarry Smith 3846e4d06f11SPatrick Farrell /*@ 3847e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3848e4d06f11SPatrick Farrell 3849e4d06f11SPatrick Farrell Logically Collective on SNES 3850e4d06f11SPatrick Farrell 3851e4d06f11SPatrick Farrell Input Parameters: 3852e4d06f11SPatrick Farrell + snes - the SNES context 3853e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3854e4d06f11SPatrick Farrell 3855e4d06f11SPatrick Farrell Options Database Keys: 3856a2b725a8SWilliam Gropp . -snes_divergence_tolerance <divtol> - Sets divtol 3857e4d06f11SPatrick Farrell 3858e4d06f11SPatrick Farrell Notes: 3859e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3860e4d06f11SPatrick Farrell 3861e4d06f11SPatrick Farrell Level: intermediate 3862e4d06f11SPatrick Farrell 3863db781477SPatrick Sanan .seealso: `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3864e4d06f11SPatrick Farrell @*/ 3865e4d06f11SPatrick Farrell PetscErrorCode SNESSetDivergenceTolerance(SNES snes,PetscReal divtol) 3866e4d06f11SPatrick Farrell { 3867e4d06f11SPatrick Farrell PetscFunctionBegin; 3868e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3869e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes,divtol,2); 3870e4d06f11SPatrick Farrell 3871e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3872e4d06f11SPatrick Farrell snes->divtol = divtol; 3873e4d06f11SPatrick Farrell } 3874e4d06f11SPatrick Farrell else { 3875e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3876e4d06f11SPatrick Farrell } 3877e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3878e4d06f11SPatrick Farrell } 3879e4d06f11SPatrick Farrell 38809b94acceSBarry Smith /*@ 388133174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 388233174efeSLois Curfman McInnes 3883c7afd0dbSLois Curfman McInnes Not Collective 3884c7afd0dbSLois Curfman McInnes 388533174efeSLois Curfman McInnes Input Parameters: 3886c7afd0dbSLois Curfman McInnes + snes - the SNES context 388785385478SLisandro Dalcin . atol - absolute convergence tolerance 388833174efeSLois Curfman McInnes . rtol - relative convergence tolerance 388933174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 389033174efeSLois Curfman McInnes of the change in the solution between steps 389133174efeSLois Curfman McInnes . maxit - maximum number of iterations 3892c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3893fee21e36SBarry Smith 389433174efeSLois Curfman McInnes Notes: 38950298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 389633174efeSLois Curfman McInnes 389736851e7fSLois Curfman McInnes Level: intermediate 389836851e7fSLois Curfman McInnes 3899db781477SPatrick Sanan .seealso: `SNESSetTolerances()` 390033174efeSLois Curfman McInnes @*/ 39017087cfbeSBarry Smith PetscErrorCode SNESGetTolerances(SNES snes,PetscReal *atol,PetscReal *rtol,PetscReal *stol,PetscInt *maxit,PetscInt *maxf) 390233174efeSLois Curfman McInnes { 39033a40ed3dSBarry Smith PetscFunctionBegin; 39040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 390585385478SLisandro Dalcin if (atol) *atol = snes->abstol; 390633174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3907c60f73f4SPeter Brune if (stol) *stol = snes->stol; 390833174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 390933174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 39103a40ed3dSBarry Smith PetscFunctionReturn(0); 391133174efeSLois Curfman McInnes } 391233174efeSLois Curfman McInnes 3913e4d06f11SPatrick Farrell /*@ 3914e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3915e4d06f11SPatrick Farrell 3916e4d06f11SPatrick Farrell Not Collective 3917e4d06f11SPatrick Farrell 3918e4d06f11SPatrick Farrell Input Parameters: 3919e4d06f11SPatrick Farrell + snes - the SNES context 3920e4d06f11SPatrick Farrell - divtol - divergence tolerance 3921e4d06f11SPatrick Farrell 3922e4d06f11SPatrick Farrell Level: intermediate 3923e4d06f11SPatrick Farrell 3924db781477SPatrick Sanan .seealso: `SNESSetDivergenceTolerance()` 3925e4d06f11SPatrick Farrell @*/ 3926e4d06f11SPatrick Farrell PetscErrorCode SNESGetDivergenceTolerance(SNES snes,PetscReal *divtol) 3927e4d06f11SPatrick Farrell { 3928e4d06f11SPatrick Farrell PetscFunctionBegin; 3929e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3930e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3931e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3932e4d06f11SPatrick Farrell } 3933e4d06f11SPatrick Farrell 393433174efeSLois Curfman McInnes /*@ 39359b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 39369b94acceSBarry Smith 39373f9fe445SBarry Smith Logically Collective on SNES 3938fee21e36SBarry Smith 3939c7afd0dbSLois Curfman McInnes Input Parameters: 3940c7afd0dbSLois Curfman McInnes + snes - the SNES context 3941c7afd0dbSLois Curfman McInnes - tol - tolerance 3942c7afd0dbSLois Curfman McInnes 39439b94acceSBarry Smith Options Database Key: 3944c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 39459b94acceSBarry Smith 394636851e7fSLois Curfman McInnes Level: intermediate 394736851e7fSLois Curfman McInnes 3948db781477SPatrick Sanan .seealso: `SNESSetTolerances()` 39499b94acceSBarry Smith @*/ 39507087cfbeSBarry Smith PetscErrorCode SNESSetTrustRegionTolerance(SNES snes,PetscReal tol) 39519b94acceSBarry Smith { 39523a40ed3dSBarry Smith PetscFunctionBegin; 39530700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 3954c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,tol,2); 39559b94acceSBarry Smith snes->deltatol = tol; 39563a40ed3dSBarry Smith PetscFunctionReturn(0); 39579b94acceSBarry Smith } 39589b94acceSBarry Smith 39596ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES,PetscInt,PetscReal*); 39606ba87a44SLisandro Dalcin 39617087cfbeSBarry Smith PetscErrorCode SNESMonitorLGRange(SNES snes,PetscInt n,PetscReal rnorm,void *monctx) 3962b271bb04SBarry Smith { 3963b271bb04SBarry Smith PetscDrawLG lg; 3964b271bb04SBarry Smith PetscReal x,y,per; 3965b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3966b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3967b271bb04SBarry Smith PetscDraw draw; 3968b271bb04SBarry Smith 3969459f5d12SBarry Smith PetscFunctionBegin; 39704d4332d5SBarry Smith PetscValidHeaderSpecific(v,PETSC_VIEWER_CLASSID,4); 39719566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v,0,&lg)); 39729566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 39739566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg,&draw)); 39749566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw,"Residual norm")); 3975b271bb04SBarry Smith x = (PetscReal)n; 397677b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 397794c9c6d3SKarl Rupp else y = -15.0; 39789566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 39796934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39809566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39819566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3982b271bb04SBarry Smith } 3983b271bb04SBarry Smith 39849566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v,1,&lg)); 39859566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 39869566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg,&draw)); 39879566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw,"% elemts > .2*max elemt")); 39889566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes,n,&per)); 3989b271bb04SBarry Smith x = (PetscReal)n; 3990b271bb04SBarry Smith y = 100.0*per; 39919566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 39926934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39939566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39949566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3995b271bb04SBarry Smith } 3996b271bb04SBarry Smith 39979566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v,2,&lg)); 39989566063dSJacob Faibussowitsch if (!n) {prev = rnorm;PetscCall(PetscDrawLGReset(lg));} 39999566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg,&draw)); 40009566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm")); 4001b271bb04SBarry Smith x = (PetscReal)n; 4002b271bb04SBarry Smith y = (prev - rnorm)/prev; 40039566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 40046934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 40059566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 40069566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 4007b271bb04SBarry Smith } 4008b271bb04SBarry Smith 40099566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v,3,&lg)); 40109566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 40119566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg,&draw)); 40129566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw,"(norm -oldnorm)/oldnorm*(% > .2 max)")); 4013b271bb04SBarry Smith x = (PetscReal)n; 4014b271bb04SBarry Smith y = (prev - rnorm)/(prev*per); 4015b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 40169566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg,&x,&y)); 4017b271bb04SBarry Smith } 40186934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 40199566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 40209566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 4021b271bb04SBarry Smith } 4022b271bb04SBarry Smith prev = rnorm; 4023b271bb04SBarry Smith PetscFunctionReturn(0); 4024b271bb04SBarry Smith } 4025b271bb04SBarry Smith 4026228d79bcSJed Brown /*@ 4027228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 4028228d79bcSJed Brown 4029228d79bcSJed Brown Collective on SNES 4030228d79bcSJed Brown 4031228d79bcSJed Brown Input Parameters: 4032228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 4033228d79bcSJed Brown . iter - iteration number 4034228d79bcSJed Brown - rnorm - relative norm of the residual 4035228d79bcSJed Brown 4036228d79bcSJed Brown Notes: 4037228d79bcSJed Brown This routine is called by the SNES implementations. 4038228d79bcSJed Brown It does not typically need to be called by the user. 4039228d79bcSJed Brown 4040228d79bcSJed Brown Level: developer 4041228d79bcSJed Brown 4042db781477SPatrick Sanan .seealso: `SNESMonitorSet()` 4043228d79bcSJed Brown @*/ 40447a03ce2fSLisandro Dalcin PetscErrorCode SNESMonitor(SNES snes,PetscInt iter,PetscReal rnorm) 40457a03ce2fSLisandro Dalcin { 40467a03ce2fSLisandro Dalcin PetscInt i,n = snes->numbermonitors; 40477a03ce2fSLisandro Dalcin 40487a03ce2fSLisandro Dalcin PetscFunctionBegin; 40499566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 40507a03ce2fSLisandro Dalcin for (i=0; i<n; i++) { 40519566063dSJacob Faibussowitsch PetscCall((*snes->monitor[i])(snes,iter,rnorm,snes->monitorcontext[i])); 40527a03ce2fSLisandro Dalcin } 40539566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 40547a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 40557a03ce2fSLisandro Dalcin } 40567a03ce2fSLisandro Dalcin 40579b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 40589b94acceSBarry Smith 4059bf388a1fSBarry Smith /*MC 4060bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 4061bf388a1fSBarry Smith 4062bf388a1fSBarry Smith Synopsis: 4063aaa7dc30SBarry Smith #include <petscsnes.h> 4064bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 4065bf388a1fSBarry Smith 40661843f636SBarry Smith Collective on snes 40671843f636SBarry Smith 40681843f636SBarry Smith Input Parameters: 4069bf388a1fSBarry Smith + snes - the SNES context 4070bf388a1fSBarry Smith . its - iteration number 4071bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 4072bf388a1fSBarry Smith - mctx - [optional] monitoring context 4073bf388a1fSBarry Smith 4074878cb397SSatish Balay Level: advanced 4075878cb397SSatish Balay 4076db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorGet()` 4077bf388a1fSBarry Smith M*/ 4078bf388a1fSBarry Smith 40799b94acceSBarry Smith /*@C 4080a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 40819b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 40829b94acceSBarry Smith progress. 40839b94acceSBarry Smith 40843f9fe445SBarry Smith Logically Collective on SNES 4085fee21e36SBarry Smith 4086c7afd0dbSLois Curfman McInnes Input Parameters: 4087c7afd0dbSLois Curfman McInnes + snes - the SNES context 40886e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 4089b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 40900298fd71SBarry Smith monitor routine (use NULL if no context is desired) 4091b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 40920298fd71SBarry Smith (may be NULL) 40939b94acceSBarry Smith 40949665c990SLois Curfman McInnes Options Database Keys: 4095a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 4096798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 4097cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 4098c7afd0dbSLois Curfman McInnes been hardwired into a code by 4099a6570f20SBarry Smith calls to SNESMonitorSet(), but 4100c7afd0dbSLois Curfman McInnes does not cancel those set via 4101c7afd0dbSLois Curfman McInnes the options database. 41029665c990SLois Curfman McInnes 4103639f9d9dSBarry Smith Notes: 41046bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 4105a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 41066bc08f3fSLois Curfman McInnes order in which they were set. 4107639f9d9dSBarry Smith 410895452b02SPatrick Sanan Fortran Notes: 410995452b02SPatrick Sanan Only a single monitor function can be set for each SNES object 4110025f1a04SBarry Smith 411136851e7fSLois Curfman McInnes Level: intermediate 411236851e7fSLois Curfman McInnes 4113db781477SPatrick Sanan .seealso: `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 41149b94acceSBarry Smith @*/ 41156e4dcb14SBarry Smith PetscErrorCode SNESMonitorSet(SNES snes,PetscErrorCode (*f)(SNES,PetscInt,PetscReal,void*),void *mctx,PetscErrorCode (*monitordestroy)(void**)) 41169b94acceSBarry Smith { 4117b90d0a6eSBarry Smith PetscInt i; 411878064530SBarry Smith PetscBool identical; 4119b90d0a6eSBarry Smith 41203a40ed3dSBarry Smith PetscFunctionBegin; 41210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4122b90d0a6eSBarry Smith for (i=0; i<snes->numbermonitors;i++) { 41239566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,mctx,monitordestroy,(PetscErrorCode (*)(void))snes->monitor[i],snes->monitorcontext[i],snes->monitordestroy[i],&identical)); 412478064530SBarry Smith if (identical) PetscFunctionReturn(0); 4125649052a6SBarry Smith } 41265f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many monitors set"); 41276e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4128b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4129639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void*)mctx; 41303a40ed3dSBarry Smith PetscFunctionReturn(0); 41319b94acceSBarry Smith } 41329b94acceSBarry Smith 4133a278d85bSSatish Balay /*@ 4134a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 41355cd90555SBarry Smith 41363f9fe445SBarry Smith Logically Collective on SNES 4137c7afd0dbSLois Curfman McInnes 41385cd90555SBarry Smith Input Parameters: 41395cd90555SBarry Smith . snes - the SNES context 41405cd90555SBarry Smith 41411a480d89SAdministrator Options Database Key: 4142a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4143a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 4144c7afd0dbSLois Curfman McInnes set via the options database 41455cd90555SBarry Smith 41465cd90555SBarry Smith Notes: 41475cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 41485cd90555SBarry Smith 414936851e7fSLois Curfman McInnes Level: intermediate 415036851e7fSLois Curfman McInnes 4151db781477SPatrick Sanan .seealso: `SNESMonitorDefault()`, `SNESMonitorSet()` 41525cd90555SBarry Smith @*/ 41537087cfbeSBarry Smith PetscErrorCode SNESMonitorCancel(SNES snes) 41545cd90555SBarry Smith { 4155d952e501SBarry Smith PetscInt i; 4156d952e501SBarry Smith 41575cd90555SBarry Smith PetscFunctionBegin; 41580700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4159d952e501SBarry Smith for (i=0; i<snes->numbermonitors; i++) { 4160d952e501SBarry Smith if (snes->monitordestroy[i]) { 41619566063dSJacob Faibussowitsch PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4162d952e501SBarry Smith } 4163d952e501SBarry Smith } 41645cd90555SBarry Smith snes->numbermonitors = 0; 41655cd90555SBarry Smith PetscFunctionReturn(0); 41665cd90555SBarry Smith } 41675cd90555SBarry Smith 4168bf388a1fSBarry Smith /*MC 4169bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4170bf388a1fSBarry Smith 4171bf388a1fSBarry Smith Synopsis: 4172aaa7dc30SBarry Smith #include <petscsnes.h> 4173bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4174bf388a1fSBarry Smith 41751843f636SBarry Smith Collective on snes 41761843f636SBarry Smith 41771843f636SBarry Smith Input Parameters: 4178bf388a1fSBarry Smith + snes - the SNES context 4179bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4180bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4181bf388a1fSBarry Smith . gnorm - 2-norm of current step 41821843f636SBarry Smith . f - 2-norm of function 41831843f636SBarry Smith - cctx - [optional] convergence context 41841843f636SBarry Smith 41851843f636SBarry Smith Output Parameter: 41861843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4187bf388a1fSBarry Smith 4188878cb397SSatish Balay Level: intermediate 4189bf388a1fSBarry Smith 4190db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4191bf388a1fSBarry Smith M*/ 4192bf388a1fSBarry Smith 41939b94acceSBarry Smith /*@C 41949b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 41959b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 41969b94acceSBarry Smith 41973f9fe445SBarry Smith Logically Collective on SNES 4198fee21e36SBarry Smith 4199c7afd0dbSLois Curfman McInnes Input Parameters: 4200c7afd0dbSLois Curfman McInnes + snes - the SNES context 4201bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 42020298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 4203cf90aa19SBarry Smith - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 42049b94acceSBarry Smith 420536851e7fSLois Curfman McInnes Level: advanced 420636851e7fSLois Curfman McInnes 4207db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 42089b94acceSBarry Smith @*/ 4209bf388a1fSBarry Smith PetscErrorCode SNESSetConvergenceTest(SNES snes,PetscErrorCode (*SNESConvergenceTestFunction)(SNES,PetscInt,PetscReal,PetscReal,PetscReal,SNESConvergedReason*,void*),void *cctx,PetscErrorCode (*destroy)(void*)) 42109b94acceSBarry Smith { 42113a40ed3dSBarry Smith PetscFunctionBegin; 42120700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4213e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 42147f7931b9SBarry Smith if (snes->ops->convergeddestroy) { 42159566063dSJacob Faibussowitsch PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 42167f7931b9SBarry Smith } 4217bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 42187f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 421985385478SLisandro Dalcin snes->cnvP = cctx; 42203a40ed3dSBarry Smith PetscFunctionReturn(0); 42219b94acceSBarry Smith } 42229b94acceSBarry Smith 422352baeb72SSatish Balay /*@ 4224184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 4225184914b5SBarry Smith 4226184914b5SBarry Smith Not Collective 4227184914b5SBarry Smith 4228184914b5SBarry Smith Input Parameter: 4229184914b5SBarry Smith . snes - the SNES context 4230184914b5SBarry Smith 4231184914b5SBarry Smith Output Parameter: 42324d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4233184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 4234184914b5SBarry Smith 42356a4d7782SBarry Smith Options Database: 42366a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 42376a4d7782SBarry Smith 4238184914b5SBarry Smith Level: intermediate 4239184914b5SBarry Smith 424095452b02SPatrick Sanan Notes: 424195452b02SPatrick Sanan Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 4242184914b5SBarry Smith 4243db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason` 4244184914b5SBarry Smith @*/ 42457087cfbeSBarry Smith PetscErrorCode SNESGetConvergedReason(SNES snes,SNESConvergedReason *reason) 4246184914b5SBarry Smith { 4247184914b5SBarry Smith PetscFunctionBegin; 42480700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 42494482741eSBarry Smith PetscValidPointer(reason,2); 4250184914b5SBarry Smith *reason = snes->reason; 4251184914b5SBarry Smith PetscFunctionReturn(0); 4252184914b5SBarry Smith } 4253184914b5SBarry Smith 4254c4421ceaSFande Kong /*@C 4255c4421ceaSFande Kong SNESGetConvergedReasonString - Return a human readable string for snes converged reason 4256c4421ceaSFande Kong 4257c4421ceaSFande Kong Not Collective 4258c4421ceaSFande Kong 4259c4421ceaSFande Kong Input Parameter: 4260c4421ceaSFande Kong . snes - the SNES context 4261c4421ceaSFande Kong 4262c4421ceaSFande Kong Output Parameter: 4263c4421ceaSFande Kong . strreason - a human readable string that describes SNES converged reason 4264c4421ceaSFande Kong 426599c90e12SSatish Balay Level: beginner 4266c4421ceaSFande Kong 4267db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()` 4268c4421ceaSFande Kong @*/ 4269c4421ceaSFande Kong PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char** strreason) 4270c4421ceaSFande Kong { 4271c4421ceaSFande Kong PetscFunctionBegin; 4272c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4273dadcf809SJacob Faibussowitsch PetscValidPointer(strreason,2); 4274c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 4275c4421ceaSFande Kong PetscFunctionReturn(0); 4276c4421ceaSFande Kong } 4277c4421ceaSFande Kong 427833866048SMatthew G. Knepley /*@ 427933866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 428033866048SMatthew G. Knepley 428133866048SMatthew G. Knepley Not Collective 428233866048SMatthew G. Knepley 428333866048SMatthew G. Knepley Input Parameters: 428433866048SMatthew G. Knepley + snes - the SNES context 428533866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 428633866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 428733866048SMatthew G. Knepley 428833866048SMatthew G. Knepley Level: intermediate 428933866048SMatthew G. Knepley 4290db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 429133866048SMatthew G. Knepley @*/ 429233866048SMatthew G. Knepley PetscErrorCode SNESSetConvergedReason(SNES snes,SNESConvergedReason reason) 429333866048SMatthew G. Knepley { 429433866048SMatthew G. Knepley PetscFunctionBegin; 429533866048SMatthew G. Knepley PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 429633866048SMatthew G. Knepley snes->reason = reason; 429733866048SMatthew G. Knepley PetscFunctionReturn(0); 429833866048SMatthew G. Knepley } 429933866048SMatthew G. Knepley 4300c9005455SLois Curfman McInnes /*@ 4301c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4302c9005455SLois Curfman McInnes 43033f9fe445SBarry Smith Logically Collective on SNES 4304fee21e36SBarry Smith 4305c7afd0dbSLois Curfman McInnes Input Parameters: 4306c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 43078c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4308cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4309758f92a0SBarry Smith . na - size of a and its 431064731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4311758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4312c7afd0dbSLois Curfman McInnes 4313308dcc3eSBarry Smith Notes: 43140298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4315308dcc3eSBarry Smith default array of length 10000 is allocated. 4316308dcc3eSBarry Smith 4317c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4318c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4319c9005455SLois Curfman McInnes during the section of code that is being timed. 4320c9005455SLois Curfman McInnes 432136851e7fSLois Curfman McInnes Level: intermediate 432236851e7fSLois Curfman McInnes 4323db781477SPatrick Sanan .seealso: `SNESGetConvergenceHistory()` 4324758f92a0SBarry Smith 4325c9005455SLois Curfman McInnes @*/ 43267087cfbeSBarry Smith PetscErrorCode SNESSetConvergenceHistory(SNES snes,PetscReal a[],PetscInt its[],PetscInt na,PetscBool reset) 4327c9005455SLois Curfman McInnes { 43283a40ed3dSBarry Smith PetscFunctionBegin; 43290700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4330064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a,2); 4331a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its,3); 43327a1ec6d4SBarry Smith if (!a) { 4333308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 43349566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na,&a,na,&its)); 4335071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4336308dcc3eSBarry Smith } 4337c9005455SLois Curfman McInnes snes->conv_hist = a; 4338758f92a0SBarry Smith snes->conv_hist_its = its; 4339115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4340a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4341758f92a0SBarry Smith snes->conv_hist_reset = reset; 4342758f92a0SBarry Smith PetscFunctionReturn(0); 4343758f92a0SBarry Smith } 4344758f92a0SBarry Smith 4345308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4346c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4347c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 434899e0435eSBarry Smith 43498cc058d9SJed Brown PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4350308dcc3eSBarry Smith { 4351308dcc3eSBarry Smith mxArray *mat; 4352308dcc3eSBarry Smith PetscInt i; 4353308dcc3eSBarry Smith PetscReal *ar; 4354308dcc3eSBarry Smith 4355308dcc3eSBarry Smith PetscFunctionBegin; 4356308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len,1,mxREAL); 4357308dcc3eSBarry Smith ar = (PetscReal*) mxGetData(mat); 4358f5af7f23SKarl Rupp for (i=0; i<snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4359308dcc3eSBarry Smith PetscFunctionReturn(mat); 4360308dcc3eSBarry Smith } 4361308dcc3eSBarry Smith #endif 4362308dcc3eSBarry Smith 43630c4c9dddSBarry Smith /*@C 4364758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4365758f92a0SBarry Smith 43663f9fe445SBarry Smith Not Collective 4367758f92a0SBarry Smith 4368758f92a0SBarry Smith Input Parameter: 4369758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 4370758f92a0SBarry Smith 4371758f92a0SBarry Smith Output Parameters: 4372a2b725a8SWilliam Gropp + a - array to hold history 4373758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4374758f92a0SBarry Smith negative if not converged) for each solve. 4375758f92a0SBarry Smith - na - size of a and its 4376758f92a0SBarry Smith 4377758f92a0SBarry Smith Notes: 4378758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4379758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4380758f92a0SBarry Smith 4381758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4382758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4383758f92a0SBarry Smith during the section of code that is being timed. 4384758f92a0SBarry Smith 4385758f92a0SBarry Smith Level: intermediate 4386758f92a0SBarry Smith 4387db781477SPatrick Sanan .seealso: `SNESSetConvergenceHistory()` 4388758f92a0SBarry Smith 4389758f92a0SBarry Smith @*/ 43907087cfbeSBarry Smith PetscErrorCode SNESGetConvergenceHistory(SNES snes,PetscReal *a[],PetscInt *its[],PetscInt *na) 4391758f92a0SBarry Smith { 4392758f92a0SBarry Smith PetscFunctionBegin; 43930700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4394758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4395758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4396115dd874SBarry Smith if (na) *na = (PetscInt) snes->conv_hist_len; 43973a40ed3dSBarry Smith PetscFunctionReturn(0); 4398c9005455SLois Curfman McInnes } 4399c9005455SLois Curfman McInnes 4400ac226902SBarry Smith /*@C 440176b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4402eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 44037e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 440476b2cf59SMatthew Knepley 44053f9fe445SBarry Smith Logically Collective on SNES 440676b2cf59SMatthew Knepley 440776b2cf59SMatthew Knepley Input Parameters: 4408a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4409a2b725a8SWilliam Gropp - func - The function 441076b2cf59SMatthew Knepley 441176b2cf59SMatthew Knepley Calling sequence of func: 4412a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 441376b2cf59SMatthew Knepley 441476b2cf59SMatthew Knepley . step - The current step of the iteration 441576b2cf59SMatthew Knepley 4416fe97e370SBarry Smith Level: advanced 4417fe97e370SBarry Smith 44186b7fb656SBarry Smith Note: 44196b7fb656SBarry Smith This is NOT what one uses to update the ghost points before a function evaluation, that should be done at the beginning of your FormFunction() 4420fe97e370SBarry Smith This is not used by most users. 442176b2cf59SMatthew Knepley 44226b7fb656SBarry Smith There are a varity of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 44236b7fb656SBarry Smith 4424db781477SPatrick Sanan .seealso `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4425db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 442676b2cf59SMatthew Knepley @*/ 44277087cfbeSBarry Smith PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 442876b2cf59SMatthew Knepley { 442976b2cf59SMatthew Knepley PetscFunctionBegin; 44300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID,1); 4431e7788613SBarry Smith snes->ops->update = func; 443276b2cf59SMatthew Knepley PetscFunctionReturn(0); 443376b2cf59SMatthew Knepley } 443476b2cf59SMatthew Knepley 44359b94acceSBarry Smith /* 44369b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 44379b94acceSBarry Smith positive parameter delta. 44389b94acceSBarry Smith 44399b94acceSBarry Smith Input Parameters: 4440c7afd0dbSLois Curfman McInnes + snes - the SNES context 44419b94acceSBarry Smith . y - approximate solution of linear system 44429b94acceSBarry Smith . fnorm - 2-norm of current function 4443c7afd0dbSLois Curfman McInnes - delta - trust region size 44449b94acceSBarry Smith 44459b94acceSBarry Smith Output Parameters: 4446c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 44479b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 44489b94acceSBarry Smith region, and exceeds zero otherwise. 4449c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 44509b94acceSBarry Smith 44519b94acceSBarry Smith Note: 445204d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 44539b94acceSBarry Smith is set to be the maximum allowable step size. 44549b94acceSBarry Smith 44559b94acceSBarry Smith */ 4456dfbe8321SBarry Smith PetscErrorCode SNESScaleStep_Private(SNES snes,Vec y,PetscReal *fnorm,PetscReal *delta,PetscReal *gpnorm,PetscReal *ynorm) 44579b94acceSBarry Smith { 4458064f8208SBarry Smith PetscReal nrm; 4459ea709b57SSatish Balay PetscScalar cnorm; 44603a40ed3dSBarry Smith 44613a40ed3dSBarry Smith PetscFunctionBegin; 44620700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 44630700a824SBarry Smith PetscValidHeaderSpecific(y,VEC_CLASSID,2); 4464c9780b6fSBarry Smith PetscCheckSameComm(snes,1,y,2); 4465184914b5SBarry Smith 44669566063dSJacob Faibussowitsch PetscCall(VecNorm(y,NORM_2,&nrm)); 4467064f8208SBarry Smith if (nrm > *delta) { 4468064f8208SBarry Smith nrm = *delta/nrm; 4469064f8208SBarry Smith *gpnorm = (1.0 - nrm)*(*fnorm); 4470064f8208SBarry Smith cnorm = nrm; 44719566063dSJacob Faibussowitsch PetscCall(VecScale(y,cnorm)); 44729b94acceSBarry Smith *ynorm = *delta; 44739b94acceSBarry Smith } else { 44749b94acceSBarry Smith *gpnorm = 0.0; 4475064f8208SBarry Smith *ynorm = nrm; 44769b94acceSBarry Smith } 44773a40ed3dSBarry Smith PetscFunctionReturn(0); 44789b94acceSBarry Smith } 44799b94acceSBarry Smith 448091f3e32bSBarry Smith /*@C 448119a666eeSBarry Smith SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 44822a359c20SBarry Smith 44832a359c20SBarry Smith Collective on SNES 44842a359c20SBarry Smith 44852a359c20SBarry Smith Parameter: 44862a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 44872a359c20SBarry Smith - viewer - the viewer to display the reason 44882a359c20SBarry Smith 44892a359c20SBarry Smith Options Database Keys: 4490ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4491ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4492eafd5ff0SAlex Lindsay 449319a666eeSBarry Smith Notes: 449419a666eeSBarry Smith To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 449519a666eeSBarry Smith use PETSC_VIEWER_FAILED to only display a reason if it fails. 44962a359c20SBarry Smith 44972a359c20SBarry Smith Level: beginner 44982a359c20SBarry Smith 4499db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonViewFromOptions()`, 4500db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 45012a359c20SBarry Smith 45022a359c20SBarry Smith @*/ 450319a666eeSBarry Smith PetscErrorCode SNESConvergedReasonView(SNES snes,PetscViewer viewer) 45042a359c20SBarry Smith { 450575cca76cSMatthew G. Knepley PetscViewerFormat format; 45062a359c20SBarry Smith PetscBool isAscii; 45072a359c20SBarry Smith 45082a359c20SBarry Smith PetscFunctionBegin; 450919a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 45109566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer,PETSCVIEWERASCII,&isAscii)); 45112a359c20SBarry Smith if (isAscii) { 45129566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 45139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer,((PetscObject)snes)->tablevel)); 451475cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 451575cca76cSMatthew G. Knepley DM dm; 451675cca76cSMatthew G. Knepley Vec u; 451775cca76cSMatthew G. Knepley PetscDS prob; 451875cca76cSMatthew G. Knepley PetscInt Nf, f; 451995cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 452095cbbfd3SMatthew G. Knepley void **exactCtx; 452175cca76cSMatthew G. Knepley PetscReal error; 452275cca76cSMatthew G. Knepley 45239566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45249566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 45259566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 45269566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 45279566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 45289566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 45299566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 45309566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 45319566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 453263a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 453375cca76cSMatthew G. Knepley } 4534eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 45352a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 453663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter)); 45372a359c20SBarry Smith } else { 453863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter)); 45392a359c20SBarry Smith } 4540eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 45412a359c20SBarry Smith if (((PetscObject) snes)->prefix) { 454263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear %s solve did not converge due to %s iterations %" PetscInt_FMT "\n",((PetscObject) snes)->prefix,SNESConvergedReasons[snes->reason],snes->iter)); 45432a359c20SBarry Smith } else { 454463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer,"Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n",SNESConvergedReasons[snes->reason],snes->iter)); 45452a359c20SBarry Smith } 45462a359c20SBarry Smith } 45479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer,((PetscObject)snes)->tablevel)); 45482a359c20SBarry Smith } 45492a359c20SBarry Smith PetscFunctionReturn(0); 45502a359c20SBarry Smith } 45512a359c20SBarry Smith 4552c4421ceaSFande Kong /*@C 4553c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4554c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4555c4421ceaSFande Kong 4556c4421ceaSFande Kong Logically Collective on SNES 4557c4421ceaSFande Kong 4558c4421ceaSFande Kong Input Parameters: 4559c4421ceaSFande Kong + snes - the SNES context 4560c4421ceaSFande Kong . f - the snes converged reason view function 4561c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4562c4421ceaSFande Kong snes converged reason view routine (use NULL if no context is desired) 4563c4421ceaSFande Kong - reasonviewdestroy - [optional] routine that frees reasonview context 4564c4421ceaSFande Kong (may be NULL) 4565c4421ceaSFande Kong 4566c4421ceaSFande Kong Options Database Keys: 4567c4421ceaSFande Kong + -snes_converged_reason - sets a default SNESConvergedReasonView() 4568c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4569c4421ceaSFande Kong been hardwired into a code by 4570c4421ceaSFande Kong calls to SNESConvergedReasonViewSet(), but 4571c4421ceaSFande Kong does not cancel those set via 4572c4421ceaSFande Kong the options database. 4573c4421ceaSFande Kong 4574c4421ceaSFande Kong Notes: 4575c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4576c4421ceaSFande Kong SNESConvergedReasonViewSet() multiple times; all will be called in the 4577c4421ceaSFande Kong order in which they were set. 4578c4421ceaSFande Kong 4579c4421ceaSFande Kong Level: intermediate 4580c4421ceaSFande Kong 4581db781477SPatrick Sanan .seealso: `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4582c4421ceaSFande Kong @*/ 4583c4421ceaSFande Kong PetscErrorCode SNESConvergedReasonViewSet(SNES snes,PetscErrorCode (*f)(SNES,void*),void *vctx,PetscErrorCode (*reasonviewdestroy)(void**)) 4584c4421ceaSFande Kong { 4585c4421ceaSFande Kong PetscInt i; 4586c4421ceaSFande Kong PetscBool identical; 4587c4421ceaSFande Kong 4588c4421ceaSFande Kong PetscFunctionBegin; 4589c4421ceaSFande Kong PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4590c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews;i++) { 45919566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode (*)(void))f,vctx,reasonviewdestroy,(PetscErrorCode (*)(void))snes->reasonview[i],snes->reasonviewcontext[i],snes->reasonviewdestroy[i],&identical)); 4592c4421ceaSFande Kong if (identical) PetscFunctionReturn(0); 4593c4421ceaSFande Kong } 45945f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Too many SNES reasonview set"); 4595c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4596c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4597c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void*)vctx; 4598c4421ceaSFande Kong PetscFunctionReturn(0); 4599c4421ceaSFande Kong } 4600c4421ceaSFande Kong 460191f3e32bSBarry Smith /*@ 460219a666eeSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4603c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 46042a359c20SBarry Smith 46052a359c20SBarry Smith Collective on SNES 46062a359c20SBarry Smith 46072a359c20SBarry Smith Input Parameters: 46082a359c20SBarry Smith . snes - the SNES object 46092a359c20SBarry Smith 46102a359c20SBarry Smith Level: intermediate 46112a359c20SBarry Smith 4612db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 461319a666eeSBarry Smith 46142a359c20SBarry Smith @*/ 461519a666eeSBarry Smith PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 46162a359c20SBarry Smith { 46172a359c20SBarry Smith PetscViewer viewer; 46182a359c20SBarry Smith PetscBool flg; 46192a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 46202a359c20SBarry Smith PetscViewerFormat format; 4621c4421ceaSFande Kong PetscInt i; 46222a359c20SBarry Smith 46232a359c20SBarry Smith PetscFunctionBegin; 46242a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 46252a359c20SBarry Smith incall = PETSC_TRUE; 4626c4421ceaSFande Kong 4627c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 4628c4421ceaSFande Kong for (i=0; i<snes->numberreasonviews; i++) { 46299566063dSJacob Faibussowitsch PetscCall((*snes->reasonview[i])(snes,snes->reasonviewcontext[i])); 4630c4421ceaSFande Kong } 4631c4421ceaSFande Kong 4632c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 46339566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_converged_reason",&viewer,&format,&flg)); 46342a359c20SBarry Smith if (flg) { 46359566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer,format)); 46369566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes,viewer)); 46379566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 46389566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 46392a359c20SBarry Smith } 46402a359c20SBarry Smith incall = PETSC_FALSE; 46412a359c20SBarry Smith PetscFunctionReturn(0); 46422a359c20SBarry Smith } 46432a359c20SBarry Smith 4644487a658cSBarry Smith /*@ 4645f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4646f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 46479b94acceSBarry Smith 4648c7afd0dbSLois Curfman McInnes Collective on SNES 4649c7afd0dbSLois Curfman McInnes 4650b2002411SLois Curfman McInnes Input Parameters: 4651c7afd0dbSLois Curfman McInnes + snes - the SNES context 46520298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 465385385478SLisandro Dalcin - x - the solution vector. 46549b94acceSBarry Smith 4655b2002411SLois Curfman McInnes Notes: 46568ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 46576b7fb656SBarry Smith for the nonlinear solve prior to calling SNESSolve(). In particular, 46588ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 46598ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 46608ddd3da0SLois Curfman McInnes 466136851e7fSLois Curfman McInnes Level: beginner 466236851e7fSLois Curfman McInnes 4663db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4664db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4665db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 46669b94acceSBarry Smith @*/ 46677087cfbeSBarry Smith PetscErrorCode SNESSolve(SNES snes,Vec b,Vec x) 46689b94acceSBarry Smith { 4669ace3abfcSBarry Smith PetscBool flg; 4670efd51863SBarry Smith PetscInt grid; 46710298fd71SBarry Smith Vec xcreated = NULL; 4672caa4e7f2SJed Brown DM dm; 4673052efed2SBarry Smith 46743a40ed3dSBarry Smith PetscFunctionBegin; 46750700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 4676a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x,VEC_CLASSID,3); 4677a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes,1,x,3); 46780700a824SBarry Smith if (b) PetscValidHeaderSpecific(b,VEC_CLASSID,2); 467985385478SLisandro Dalcin if (b) PetscCheckSameComm(snes,1,b,2); 468085385478SLisandro Dalcin 468134b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 468206fc46c8SMatthew G. Knepley { 468306fc46c8SMatthew G. Knepley PetscViewer viewer; 468406fc46c8SMatthew G. Knepley PetscViewerFormat format; 46857c88af5aSMatthew G. Knepley PetscInt num; 468606fc46c8SMatthew G. Knepley PetscBool flg; 468706fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 468806fc46c8SMatthew G. Knepley 468906fc46c8SMatthew G. Knepley if (!incall) { 469034b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 46919566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject) snes),((PetscObject)snes)->options, ((PetscObject) snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 469206fc46c8SMatthew G. Knepley if (flg) { 469306fc46c8SMatthew G. Knepley PetscConvEst conv; 469446079b62SMatthew G. Knepley DM dm; 469546079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 469646079b62SMatthew G. Knepley PetscInt Nf; 469706fc46c8SMatthew G. Knepley 469806fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 46999566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 47009566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 47019566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 47029566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject) snes), &conv)); 47039566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject) snes)); 47049566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 47059566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 47069566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 47079566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 47089566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 47099566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 47109566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 47119566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 47129566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 471306fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 471406fc46c8SMatthew G. Knepley } 471534b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4716b2588ea6SMatthew G. Knepley num = 1; 47179566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_initial", &num, &flg)); 471834b4d3a8SMatthew G. Knepley if (flg) { 471934b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 472034b4d3a8SMatthew G. Knepley 472134b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 47229566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 47239566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 47249566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 47259566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 47269566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 47279566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 47289566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 472934b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 473034b4d3a8SMatthew G. Knepley } 47317c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 47327c88af5aSMatthew G. Knepley num = 0; 47339566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject) snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 47347c88af5aSMatthew G. Knepley if (num) { 47357c88af5aSMatthew G. Knepley DMAdaptor adaptor; 47367c88af5aSMatthew G. Knepley 47377c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 47389566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 47399566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 47409566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 47419566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 47429566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 47439566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 47449566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 47457c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 47467c88af5aSMatthew G. Knepley } 474706fc46c8SMatthew G. Knepley } 474806fc46c8SMatthew G. Knepley } 474941e867a5SStefano Zampini if (!x) { x = snes->vec_sol; } 4750caa4e7f2SJed Brown if (!x) { 47519566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 47529566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm,&xcreated)); 4753a69afd8bSBarry Smith x = xcreated; 4754a69afd8bSBarry Smith } 47559566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view_pre")); 4756f05ece33SBarry Smith 47579566063dSJacob Faibussowitsch for (grid=0; grid<snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4758efd51863SBarry Smith for (grid=0; grid<snes->gridsequence+1; grid++) { 4759efd51863SBarry Smith 476085385478SLisandro Dalcin /* set solution vector */ 47619566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 47629566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 476385385478SLisandro Dalcin snes->vec_sol = x; 47649566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 4765caa4e7f2SJed Brown 4766caa4e7f2SJed Brown /* set affine vector if provided */ 47679566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 47689566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 476985385478SLisandro Dalcin snes->vec_rhs = b; 477085385478SLisandro Dalcin 47715f80ce2aSJacob Faibussowitsch if (snes->vec_rhs) PetscCheck(snes->vec_func != snes->vec_rhs,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Right hand side vector cannot be function vector"); 47725f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be function vector"); 47735f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol,PETSC_COMM_SELF,PETSC_ERR_ARG_IDN,"Solution vector cannot be right hand side vector"); 4774154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 47759566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_sol_update)); 47769566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->vec_sol_update)); 4777154060b5SMatthew G. Knepley } 47789566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm,snes->vec_sol)); 47799566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 47803f149594SLisandro Dalcin 47817eee914bSBarry Smith if (!grid) { 47827eee914bSBarry Smith if (snes->ops->computeinitialguess) { 47839566063dSJacob Faibussowitsch PetscCall((*snes->ops->computeinitialguess)(snes,snes->vec_sol,snes->initialguessP)); 4784d25893d9SBarry Smith } 4785dd568438SSatish Balay } 4786d25893d9SBarry Smith 4787abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 4788971e163fSPeter Brune if (snes->counters_reset) {snes->nfuncs = 0; snes->linear_its = 0; snes->numFailures = 0;} 4789d5e45103SBarry Smith 47909566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve,snes,0,0,0)); 47919566063dSJacob Faibussowitsch PetscCall((*snes->ops->solve)(snes)); 47929566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve,snes,0,0,0)); 47935f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason,PETSC_COMM_SELF,PETSC_ERR_PLIB,"Internal error, solver returned without setting converged reason"); 4794422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 47953f149594SLisandro Dalcin 479637ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 479737ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 479837ec4e1aSPeter Brune 47999566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes),((PetscObject)snes)->options,((PetscObject)snes)->prefix,"-snes_test_local_min",NULL,NULL,&flg)); 48009566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4801c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 48029566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 48035968eb51SBarry Smith 48045f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0,PetscObjectComm((PetscObject)snes),PETSC_ERR_NOT_CONVERGED,"SNESSolve has not converged"); 48059c8e83a9SBarry Smith if (snes->reason < 0) break; 4806efd51863SBarry Smith if (grid < snes->gridsequence) { 4807efd51863SBarry Smith DM fine; 4808efd51863SBarry Smith Vec xnew; 4809efd51863SBarry Smith Mat interp; 4810efd51863SBarry Smith 48119566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm,PetscObjectComm((PetscObject)snes),&fine)); 48125f80ce2aSJacob Faibussowitsch PetscCheck(fine,PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_INCOMP,"DMRefine() did not perform any refinement, cannot continue grid sequencing"); 48139566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm,fine,&interp,NULL)); 48149566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine,&xnew)); 48159566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp,x,xnew)); 48169566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm,interp,fine)); 48179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4818efd51863SBarry Smith x = xnew; 4819efd51863SBarry Smith 48209566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 48219566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes,fine)); 48229566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 48239566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 48249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4825efd51863SBarry Smith } 4826efd51863SBarry Smith } 48279566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes,NULL,"-snes_view")); 48289566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol,(PetscObject)snes,"-snes_view_solution")); 48299566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 48309566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 48313f7e2da0SPeter Brune 48329566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 48339566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 48343a40ed3dSBarry Smith PetscFunctionReturn(0); 48359b94acceSBarry Smith } 48369b94acceSBarry Smith 48379b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 48389b94acceSBarry Smith 483982bf6240SBarry Smith /*@C 48404b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 48419b94acceSBarry Smith 4842fee21e36SBarry Smith Collective on SNES 4843fee21e36SBarry Smith 4844c7afd0dbSLois Curfman McInnes Input Parameters: 4845c7afd0dbSLois Curfman McInnes + snes - the SNES context 4846454a90a3SBarry Smith - type - a known method 4847c7afd0dbSLois Curfman McInnes 4848c7afd0dbSLois Curfman McInnes Options Database Key: 4849454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 485004d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4851ae12b187SLois Curfman McInnes 48529b94acceSBarry Smith Notes: 4853e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 485404d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4855c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4856a2b725a8SWilliam Gropp - SNESNEWTONTR - Newton's method with trust region 4857c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 48589b94acceSBarry Smith 4859ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4860ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4861ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4862ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4863ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4864ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4865ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4866ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4867ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4868b0a32e0cSBarry Smith appropriate method. 486936851e7fSLois Curfman McInnes 487095452b02SPatrick Sanan Developer Notes: 487195452b02SPatrick Sanan SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 48728f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 48738f6c3df8SBarry Smith 487436851e7fSLois Curfman McInnes Level: intermediate 4875a703fe33SLois Curfman McInnes 4876db781477SPatrick Sanan .seealso: `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 4877435da068SBarry Smith 48789b94acceSBarry Smith @*/ 487919fd82e9SBarry Smith PetscErrorCode SNESSetType(SNES snes,SNESType type) 48809b94acceSBarry Smith { 4881ace3abfcSBarry Smith PetscBool match; 48825f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 48833a40ed3dSBarry Smith 48843a40ed3dSBarry Smith PetscFunctionBegin; 48850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 48864482741eSBarry Smith PetscValidCharPointer(type,2); 488782bf6240SBarry Smith 48889566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes,type,&match)); 48890f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 489092ff6ae8SBarry Smith 48919566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList,type,&r)); 48925f80ce2aSJacob Faibussowitsch PetscCheck(r,PETSC_COMM_SELF,PETSC_ERR_ARG_UNKNOWN_TYPE,"Unable to find requested SNES type %s",type); 489375396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4894*a958fbfcSStefano Zampini if (snes->ops->destroy) PetscCall((*snes->ops->destroy)(snes)); 489575396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 48969e5d0892SLisandro Dalcin snes->ops->setup = NULL; 48979e5d0892SLisandro Dalcin snes->ops->solve = NULL; 48989e5d0892SLisandro Dalcin snes->ops->view = NULL; 48999e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 49009e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 49017fe760d5SStefano Zampini 49027fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 49039566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 49047fe760d5SStefano Zampini 490575396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 490675396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4907f5af7f23SKarl Rupp 49089566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes,type)); 49099566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 49103a40ed3dSBarry Smith PetscFunctionReturn(0); 49119b94acceSBarry Smith } 49129b94acceSBarry Smith 49139b94acceSBarry Smith /*@C 49149a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 49159b94acceSBarry Smith 4916c7afd0dbSLois Curfman McInnes Not Collective 4917c7afd0dbSLois Curfman McInnes 49189b94acceSBarry Smith Input Parameter: 49194b0e389bSBarry Smith . snes - nonlinear solver context 49209b94acceSBarry Smith 49219b94acceSBarry Smith Output Parameter: 49223a7fca6bSBarry Smith . type - SNES method (a character string) 49239b94acceSBarry Smith 492436851e7fSLois Curfman McInnes Level: intermediate 492536851e7fSLois Curfman McInnes 49269b94acceSBarry Smith @*/ 492719fd82e9SBarry Smith PetscErrorCode SNESGetType(SNES snes,SNESType *type) 49289b94acceSBarry Smith { 49293a40ed3dSBarry Smith PetscFunctionBegin; 49300700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49314482741eSBarry Smith PetscValidPointer(type,2); 49327adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 49333a40ed3dSBarry Smith PetscFunctionReturn(0); 49349b94acceSBarry Smith } 49359b94acceSBarry Smith 49363cd8a7caSMatthew G. Knepley /*@ 49373cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 49383cd8a7caSMatthew G. Knepley 4939d083f849SBarry Smith Logically Collective on SNES 49403cd8a7caSMatthew G. Knepley 49413cd8a7caSMatthew G. Knepley Input Parameters: 49423cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 49433cd8a7caSMatthew G. Knepley - u - the solution vector 49443cd8a7caSMatthew G. Knepley 49453cd8a7caSMatthew G. Knepley Level: beginner 49463cd8a7caSMatthew G. Knepley 49473cd8a7caSMatthew G. Knepley @*/ 49483cd8a7caSMatthew G. Knepley PetscErrorCode SNESSetSolution(SNES snes, Vec u) 49493cd8a7caSMatthew G. Knepley { 49503cd8a7caSMatthew G. Knepley DM dm; 49513cd8a7caSMatthew G. Knepley 49523cd8a7caSMatthew G. Knepley PetscFunctionBegin; 49533cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49543cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 49559566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) u)); 49569566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 49573cd8a7caSMatthew G. Knepley 49583cd8a7caSMatthew G. Knepley snes->vec_sol = u; 49593cd8a7caSMatthew G. Knepley 49609566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49619566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 49623cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 49633cd8a7caSMatthew G. Knepley } 49643cd8a7caSMatthew G. Knepley 496552baeb72SSatish Balay /*@ 49669b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4967c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 49689b94acceSBarry Smith 4969c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4970c7afd0dbSLois Curfman McInnes 49719b94acceSBarry Smith Input Parameter: 49729b94acceSBarry Smith . snes - the SNES context 49739b94acceSBarry Smith 49749b94acceSBarry Smith Output Parameter: 49759b94acceSBarry Smith . x - the solution 49769b94acceSBarry Smith 497770e92668SMatthew Knepley Level: intermediate 497836851e7fSLois Curfman McInnes 4979db781477SPatrick Sanan .seealso: `SNESGetSolutionUpdate()`, `SNESGetFunction()` 49809b94acceSBarry Smith @*/ 49817087cfbeSBarry Smith PetscErrorCode SNESGetSolution(SNES snes,Vec *x) 49829b94acceSBarry Smith { 49833a40ed3dSBarry Smith PetscFunctionBegin; 49840700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 49854482741eSBarry Smith PetscValidPointer(x,2); 498685385478SLisandro Dalcin *x = snes->vec_sol; 498770e92668SMatthew Knepley PetscFunctionReturn(0); 498870e92668SMatthew Knepley } 498970e92668SMatthew Knepley 499052baeb72SSatish Balay /*@ 49919b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 49929b94acceSBarry Smith stored. 49939b94acceSBarry Smith 4994c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4995c7afd0dbSLois Curfman McInnes 49969b94acceSBarry Smith Input Parameter: 49979b94acceSBarry Smith . snes - the SNES context 49989b94acceSBarry Smith 49999b94acceSBarry Smith Output Parameter: 50009b94acceSBarry Smith . x - the solution update 50019b94acceSBarry Smith 500236851e7fSLois Curfman McInnes Level: advanced 500336851e7fSLois Curfman McInnes 5004db781477SPatrick Sanan .seealso: `SNESGetSolution()`, `SNESGetFunction()` 50059b94acceSBarry Smith @*/ 50067087cfbeSBarry Smith PetscErrorCode SNESGetSolutionUpdate(SNES snes,Vec *x) 50079b94acceSBarry Smith { 50083a40ed3dSBarry Smith PetscFunctionBegin; 50090700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 50104482741eSBarry Smith PetscValidPointer(x,2); 501185385478SLisandro Dalcin *x = snes->vec_sol_update; 50123a40ed3dSBarry Smith PetscFunctionReturn(0); 50139b94acceSBarry Smith } 50149b94acceSBarry Smith 50159b94acceSBarry Smith /*@C 50163638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 50179b94acceSBarry Smith 5018a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 5019c7afd0dbSLois Curfman McInnes 50209b94acceSBarry Smith Input Parameter: 50219b94acceSBarry Smith . snes - the SNES context 50229b94acceSBarry Smith 5023d8d19677SJose E. Roman Output Parameters: 50240298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 5025f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 50260298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 50279b94acceSBarry Smith 502836851e7fSLois Curfman McInnes Level: advanced 502936851e7fSLois Curfman McInnes 503004edfde5SBarry Smith Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 503104edfde5SBarry Smith 5032db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 50339b94acceSBarry Smith @*/ 5034f8b49ee9SBarry Smith PetscErrorCode SNESGetFunction(SNES snes,Vec *r,PetscErrorCode (**f)(SNES,Vec,Vec,void*),void **ctx) 50359b94acceSBarry Smith { 50366cab3a1bSJed Brown DM dm; 5037a63bb30eSJed Brown 50383a40ed3dSBarry Smith PetscFunctionBegin; 50390700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5040a63bb30eSJed Brown if (r) { 5041a63bb30eSJed Brown if (!snes->vec_func) { 5042a63bb30eSJed Brown if (snes->vec_rhs) { 50439566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs,&snes->vec_func)); 5044a63bb30eSJed Brown } else if (snes->vec_sol) { 50459566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol,&snes->vec_func)); 5046a63bb30eSJed Brown } else if (snes->dm) { 50479566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm,&snes->vec_func)); 5048a63bb30eSJed Brown } 5049a63bb30eSJed Brown } 5050a63bb30eSJed Brown *r = snes->vec_func; 5051a63bb30eSJed Brown } 50529566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 50539566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm,f,ctx)); 50543a40ed3dSBarry Smith PetscFunctionReturn(0); 50559b94acceSBarry Smith } 50569b94acceSBarry Smith 5057c79ef259SPeter Brune /*@C 5058be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 5059c79ef259SPeter Brune 5060c79ef259SPeter Brune Input Parameter: 5061c79ef259SPeter Brune . snes - the SNES context 5062c79ef259SPeter Brune 5063d8d19677SJose E. Roman Output Parameters: 5064be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 50650298fd71SBarry Smith - ctx - the function context (or NULL) 5066c79ef259SPeter Brune 5067c79ef259SPeter Brune Level: advanced 5068c79ef259SPeter Brune 5069db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetFunction()` 5070c79ef259SPeter Brune @*/ 5071c79ef259SPeter Brune 5072be95d8f1SBarry Smith PetscErrorCode SNESGetNGS (SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void*), void ** ctx) 5073646217ecSPeter Brune { 50746cab3a1bSJed Brown DM dm; 50756cab3a1bSJed Brown 5076646217ecSPeter Brune PetscFunctionBegin; 5077646217ecSPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 50789566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes,&dm)); 50799566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm,f,ctx)); 5080646217ecSPeter Brune PetscFunctionReturn(0); 5081646217ecSPeter Brune } 5082646217ecSPeter Brune 50833c7409f5SSatish Balay /*@C 50843c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 5085d850072dSLois Curfman McInnes SNES options in the database. 50863c7409f5SSatish Balay 50873f9fe445SBarry Smith Logically Collective on SNES 5088fee21e36SBarry Smith 5089d8d19677SJose E. Roman Input Parameters: 5090c7afd0dbSLois Curfman McInnes + snes - the SNES context 5091c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5092c7afd0dbSLois Curfman McInnes 5093d850072dSLois Curfman McInnes Notes: 5094a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5095c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5096d850072dSLois Curfman McInnes 509736851e7fSLois Curfman McInnes Level: advanced 509836851e7fSLois Curfman McInnes 5099db781477SPatrick Sanan .seealso: `SNESSetFromOptions()` 51003c7409f5SSatish Balay @*/ 51017087cfbeSBarry Smith PetscErrorCode SNESSetOptionsPrefix(SNES snes,const char prefix[]) 51023c7409f5SSatish Balay { 51033a40ed3dSBarry Smith PetscFunctionBegin; 51040700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 51059566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes,prefix)); 51069566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp)); 510735f5d045SPeter Brune if (snes->linesearch) { 51089566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes,&snes->linesearch)); 51099566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch,prefix)); 511035f5d045SPeter Brune } 51119566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp,prefix)); 51123a40ed3dSBarry Smith PetscFunctionReturn(0); 51133c7409f5SSatish Balay } 51143c7409f5SSatish Balay 51153c7409f5SSatish Balay /*@C 5116f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5117d850072dSLois Curfman McInnes SNES options in the database. 51183c7409f5SSatish Balay 51193f9fe445SBarry Smith Logically Collective on SNES 5120fee21e36SBarry Smith 5121c7afd0dbSLois Curfman McInnes Input Parameters: 5122c7afd0dbSLois Curfman McInnes + snes - the SNES context 5123c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5124c7afd0dbSLois Curfman McInnes 5125d850072dSLois Curfman McInnes Notes: 5126a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5127c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5128d850072dSLois Curfman McInnes 512936851e7fSLois Curfman McInnes Level: advanced 513036851e7fSLois Curfman McInnes 5131db781477SPatrick Sanan .seealso: `SNESGetOptionsPrefix()` 51323c7409f5SSatish Balay @*/ 51337087cfbeSBarry Smith PetscErrorCode SNESAppendOptionsPrefix(SNES snes,const char prefix[]) 51343c7409f5SSatish Balay { 51353a40ed3dSBarry Smith PetscFunctionBegin; 51360700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 51379566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes,prefix)); 51389566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes,&snes->ksp)); 513935f5d045SPeter Brune if (snes->linesearch) { 51409566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes,&snes->linesearch)); 51419566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch,prefix)); 514235f5d045SPeter Brune } 51439566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp,prefix)); 51443a40ed3dSBarry Smith PetscFunctionReturn(0); 51453c7409f5SSatish Balay } 51463c7409f5SSatish Balay 51479ab63eb5SSatish Balay /*@C 51483c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 51493c7409f5SSatish Balay SNES options in the database. 51503c7409f5SSatish Balay 5151c7afd0dbSLois Curfman McInnes Not Collective 5152c7afd0dbSLois Curfman McInnes 51533c7409f5SSatish Balay Input Parameter: 51543c7409f5SSatish Balay . snes - the SNES context 51553c7409f5SSatish Balay 51563c7409f5SSatish Balay Output Parameter: 51573c7409f5SSatish Balay . prefix - pointer to the prefix string used 51583c7409f5SSatish Balay 515995452b02SPatrick Sanan Notes: 516095452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 51619ab63eb5SSatish Balay sufficient length to hold the prefix. 51629ab63eb5SSatish Balay 516336851e7fSLois Curfman McInnes Level: advanced 516436851e7fSLois Curfman McInnes 5165db781477SPatrick Sanan .seealso: `SNESAppendOptionsPrefix()` 51663c7409f5SSatish Balay @*/ 51677087cfbeSBarry Smith PetscErrorCode SNESGetOptionsPrefix(SNES snes,const char *prefix[]) 51683c7409f5SSatish Balay { 51693a40ed3dSBarry Smith PetscFunctionBegin; 51700700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 51719566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes,prefix)); 51723a40ed3dSBarry Smith PetscFunctionReturn(0); 51733c7409f5SSatish Balay } 51743c7409f5SSatish Balay 51753cea93caSBarry Smith /*@C 51761c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 51771c84c290SBarry Smith 51781c84c290SBarry Smith Not collective 51791c84c290SBarry Smith 51801c84c290SBarry Smith Input Parameters: 51811c84c290SBarry Smith + name_solver - name of a new user-defined solver 51821c84c290SBarry Smith - routine_create - routine to create method context 51831c84c290SBarry Smith 51841c84c290SBarry Smith Notes: 51851c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 51861c84c290SBarry Smith 51871c84c290SBarry Smith Sample usage: 51881c84c290SBarry Smith .vb 5189bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 51901c84c290SBarry Smith .ve 51911c84c290SBarry Smith 51921c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 51931c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 51941c84c290SBarry Smith or at runtime via the option 51951c84c290SBarry Smith $ -snes_type my_solver 51961c84c290SBarry Smith 51971c84c290SBarry Smith Level: advanced 51981c84c290SBarry Smith 51991c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 52001c84c290SBarry Smith 5201db781477SPatrick Sanan .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()` 52023cea93caSBarry Smith 52037f6c08e0SMatthew Knepley Level: advanced 52043cea93caSBarry Smith @*/ 5205bdf89e91SBarry Smith PetscErrorCode SNESRegister(const char sname[],PetscErrorCode (*function)(SNES)) 5206b2002411SLois Curfman McInnes { 5207b2002411SLois Curfman McInnes PetscFunctionBegin; 52089566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 52099566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList,sname,function)); 5210b2002411SLois Curfman McInnes PetscFunctionReturn(0); 5211b2002411SLois Curfman McInnes } 5212da9b6338SBarry Smith 52137087cfbeSBarry Smith PetscErrorCode SNESTestLocalMin(SNES snes) 5214da9b6338SBarry Smith { 521577431f27SBarry Smith PetscInt N,i,j; 5216da9b6338SBarry Smith Vec u,uh,fh; 5217da9b6338SBarry Smith PetscScalar value; 5218da9b6338SBarry Smith PetscReal norm; 5219da9b6338SBarry Smith 5220da9b6338SBarry Smith PetscFunctionBegin; 52219566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes,&u)); 52229566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u,&uh)); 52239566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u,&fh)); 5224da9b6338SBarry Smith 5225da9b6338SBarry Smith /* currently only works for sequential */ 52269566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"Testing FormFunction() for local min\n")); 52279566063dSJacob Faibussowitsch PetscCall(VecGetSize(u,&N)); 5228da9b6338SBarry Smith for (i=0; i<N; i++) { 52299566063dSJacob Faibussowitsch PetscCall(VecCopy(u,uh)); 523063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes),"i = %" PetscInt_FMT "\n",i)); 5231da9b6338SBarry Smith for (j=-10; j<11; j++) { 52328b49ba18SBarry Smith value = PetscSign(j)*PetscExpReal(PetscAbs(j)-10.0); 52339566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh,i,value,ADD_VALUES)); 52349566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes,uh,fh)); 52359566063dSJacob Faibussowitsch PetscCall(VecNorm(fh,NORM_2,&norm)); 523663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes)," j norm %" PetscInt_FMT " %18.16e\n",j,(double)norm)); 5237da9b6338SBarry Smith value = -value; 52389566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh,i,value,ADD_VALUES)); 5239da9b6338SBarry Smith } 5240da9b6338SBarry Smith } 52419566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 52429566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 5243da9b6338SBarry Smith PetscFunctionReturn(0); 5244da9b6338SBarry Smith } 524571f87433Sdalcinl 524671f87433Sdalcinl /*@ 5247fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 524871f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 524971f87433Sdalcinl Newton method. 525071f87433Sdalcinl 52513f9fe445SBarry Smith Logically Collective on SNES 525271f87433Sdalcinl 525371f87433Sdalcinl Input Parameters: 525471f87433Sdalcinl + snes - SNES context 525571f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 525671f87433Sdalcinl 525764ba62caSBarry Smith Options Database: 525864ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 525964ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 526064ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 526164ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 526264ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 526364ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 526464ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 526564ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 526664ba62caSBarry Smith 526771f87433Sdalcinl Notes: 526871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 526971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 527071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 527171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 527271f87433Sdalcinl solver. 527371f87433Sdalcinl 527471f87433Sdalcinl Level: advanced 527571f87433Sdalcinl 527671f87433Sdalcinl Reference: 527771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 527871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 527971f87433Sdalcinl 5280db781477SPatrick Sanan .seealso: `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 528171f87433Sdalcinl @*/ 52827087cfbeSBarry Smith PetscErrorCode SNESKSPSetUseEW(SNES snes,PetscBool flag) 528371f87433Sdalcinl { 528471f87433Sdalcinl PetscFunctionBegin; 52850700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5286acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes,flag,2); 528771f87433Sdalcinl snes->ksp_ewconv = flag; 528871f87433Sdalcinl PetscFunctionReturn(0); 528971f87433Sdalcinl } 529071f87433Sdalcinl 529171f87433Sdalcinl /*@ 5292fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 529371f87433Sdalcinl for computing relative tolerance for linear solvers within an 529471f87433Sdalcinl inexact Newton method. 529571f87433Sdalcinl 529671f87433Sdalcinl Not Collective 529771f87433Sdalcinl 529871f87433Sdalcinl Input Parameter: 529971f87433Sdalcinl . snes - SNES context 530071f87433Sdalcinl 530171f87433Sdalcinl Output Parameter: 530271f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 530371f87433Sdalcinl 530471f87433Sdalcinl Notes: 530571f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 530671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 530771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 530871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 530971f87433Sdalcinl solver. 531071f87433Sdalcinl 531171f87433Sdalcinl Level: advanced 531271f87433Sdalcinl 531371f87433Sdalcinl Reference: 531471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 531571f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 531671f87433Sdalcinl 5317db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 531871f87433Sdalcinl @*/ 53197087cfbeSBarry Smith PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 532071f87433Sdalcinl { 532171f87433Sdalcinl PetscFunctionBegin; 53220700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5323534a8f05SLisandro Dalcin PetscValidBoolPointer(flag,2); 532471f87433Sdalcinl *flag = snes->ksp_ewconv; 532571f87433Sdalcinl PetscFunctionReturn(0); 532671f87433Sdalcinl } 532771f87433Sdalcinl 532871f87433Sdalcinl /*@ 5329fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 533071f87433Sdalcinl convergence criteria for the linear solvers within an inexact 533171f87433Sdalcinl Newton method. 533271f87433Sdalcinl 53333f9fe445SBarry Smith Logically Collective on SNES 533471f87433Sdalcinl 533571f87433Sdalcinl Input Parameters: 533671f87433Sdalcinl + snes - SNES context 53370f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 533871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 533971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 534071f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 534171f87433Sdalcinl (0 <= gamma2 <= 1) 534271f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 534371f87433Sdalcinl . alpha2 - power for safeguard 534471f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 534571f87433Sdalcinl 534671f87433Sdalcinl Note: 534771f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 534871f87433Sdalcinl 534971f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 535071f87433Sdalcinl 535171f87433Sdalcinl Level: advanced 535271f87433Sdalcinl 535371f87433Sdalcinl Reference: 535471f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 535571f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 535671f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 535771f87433Sdalcinl 5358db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 535971f87433Sdalcinl @*/ 5360f5af7f23SKarl Rupp PetscErrorCode SNESKSPSetParametersEW(SNES snes,PetscInt version,PetscReal rtol_0,PetscReal rtol_max,PetscReal gamma,PetscReal alpha,PetscReal alpha2,PetscReal threshold) 536171f87433Sdalcinl { 5362fa9f3622SBarry Smith SNESKSPEW *kctx; 53635fd66863SKarl Rupp 536471f87433Sdalcinl PetscFunctionBegin; 53650700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5366fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 53675f80ce2aSJacob Faibussowitsch PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 5368c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes,version,2); 5369c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_0,3); 5370c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,rtol_max,4); 5371c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,gamma,5); 5372c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha,6); 5373c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,alpha2,7); 5374c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes,threshold,8); 537571f87433Sdalcinl 537671f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 537771f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 537871f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 537971f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 538071f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 538171f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 538271f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 538371f87433Sdalcinl 53840f0abf79SStefano Zampini PetscCheck(kctx->version >= 1 && kctx->version <= 4,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1 to 4 are supported: %" PetscInt_FMT,kctx->version); 53850b121fc5SBarry Smith PetscCheck(kctx->rtol_0 >= 0.0 && kctx->rtol_0 < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_0 < 1.0: %g",(double)kctx->rtol_0); 53860b121fc5SBarry Smith PetscCheck(kctx->rtol_max >= 0.0 && kctx->rtol_max < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= rtol_max (%g) < 1.0",(double)kctx->rtol_max); 53870b121fc5SBarry Smith PetscCheck(kctx->gamma >= 0.0 && kctx->gamma <= 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 <= gamma (%g) <= 1.0",(double)kctx->gamma); 53880b121fc5SBarry Smith PetscCheck(kctx->alpha > 1.0 && kctx->alpha <= 2.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"1.0 < alpha (%g) <= 2.0",(double)kctx->alpha); 53890b121fc5SBarry Smith PetscCheck(kctx->threshold > 0.0 && kctx->threshold < 1.0,PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"0.0 < threshold (%g) < 1.0",(double)kctx->threshold); 539071f87433Sdalcinl PetscFunctionReturn(0); 539171f87433Sdalcinl } 539271f87433Sdalcinl 539371f87433Sdalcinl /*@ 5394fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 539571f87433Sdalcinl convergence criteria for the linear solvers within an inexact 539671f87433Sdalcinl Newton method. 539771f87433Sdalcinl 539871f87433Sdalcinl Not Collective 539971f87433Sdalcinl 540097bb3fdcSJose E. Roman Input Parameter: 54016b867d5aSJose E. Roman . snes - SNES context 540271f87433Sdalcinl 540371f87433Sdalcinl Output Parameters: 54040f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 540571f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 540671f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5407bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 540871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 540971f87433Sdalcinl . alpha2 - power for safeguard 541071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 541171f87433Sdalcinl 541271f87433Sdalcinl Level: advanced 541371f87433Sdalcinl 5414db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 541571f87433Sdalcinl @*/ 5416bf388a1fSBarry Smith PetscErrorCode SNESKSPGetParametersEW(SNES snes,PetscInt *version,PetscReal *rtol_0,PetscReal *rtol_max,PetscReal *gamma,PetscReal *alpha,PetscReal *alpha2,PetscReal *threshold) 541771f87433Sdalcinl { 5418fa9f3622SBarry Smith SNESKSPEW *kctx; 54195fd66863SKarl Rupp 542071f87433Sdalcinl PetscFunctionBegin; 54210700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5422fa9f3622SBarry Smith kctx = (SNESKSPEW*)snes->kspconvctx; 54235f80ce2aSJacob Faibussowitsch PetscCheck(kctx,PETSC_COMM_SELF,PETSC_ERR_ARG_WRONGSTATE,"No Eisenstat-Walker context existing"); 542471f87433Sdalcinl if (version) *version = kctx->version; 542571f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 542671f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 542771f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 542871f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 542971f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 543071f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 543171f87433Sdalcinl PetscFunctionReturn(0); 543271f87433Sdalcinl } 543371f87433Sdalcinl 5434d5378b5fSDmitry Karpeev PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 543571f87433Sdalcinl { 5436fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 543771f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT,stol; 543871f87433Sdalcinl 543971f87433Sdalcinl PetscFunctionBegin; 5440d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 544130058271SDmitry Karpeev if (!snes->iter) { 544230058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 54439566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func,NORM_2,&kctx->norm_first)); 54440f0abf79SStefano Zampini } else { 544571f87433Sdalcinl if (kctx->version == 1) { 54460f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last)/kctx->norm_last; 544785ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last,kctx->alpha2); 544871f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 544971f87433Sdalcinl } else if (kctx->version == 2) { 545085ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 545185ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last,kctx->alpha); 545271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol,stol); 545371f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 545485ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm/kctx->norm_last,kctx->alpha); 545571f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 545685ec1a3cSBarry Smith stol = kctx->gamma*PetscPowReal(kctx->rtol_last,kctx->alpha); 545771f87433Sdalcinl stol = PetscMax(rtol,stol); 545871f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 545971f87433Sdalcinl /* safeguard: avoid oversolving */ 546030058271SDmitry Karpeev stol = kctx->gamma*(kctx->norm_first*snes->rtol)/snes->norm; 546171f87433Sdalcinl stol = PetscMax(rtol,stol); 546271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0,stol); 54630f0abf79SStefano Zampini } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 54640f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 54650f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 54660f0abf79SStefano Zampini PetscReal rk = ared / pred; 54670f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2.*kctx->v4_p1; 54680f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 54690f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 54700f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 54710f0abf79SStefano Zampini 54720f0abf79SStefano Zampini if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 && 54730f0abf79SStefano Zampini kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) { 54740f0abf79SStefano Zampini rtol = kctx->v4_m4 * kctx->rtol_last; 54750f0abf79SStefano Zampini //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g) (AD)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 54760f0abf79SStefano Zampini } else { 54770f0abf79SStefano Zampini //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 547871f87433Sdalcinl } 54790f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 54800f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 54810f0abf79SStefano Zampini kctx->rk_last = rk; 54820f0abf79SStefano Zampini } else SETERRQ(PETSC_COMM_SELF,PETSC_ERR_ARG_OUTOFRANGE,"Only versions 1-4 are supported: %" PetscInt_FMT,kctx->version); 54830f0abf79SStefano Zampini } 54840f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 548571f87433Sdalcinl rtol = PetscMin(rtol,kctx->rtol_max); 54869566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp,rtol,PETSC_DEFAULT,PETSC_DEFAULT,PETSC_DEFAULT)); 548763a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes,"iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n",snes->iter,kctx->version,(double)rtol)); 548871f87433Sdalcinl PetscFunctionReturn(0); 548971f87433Sdalcinl } 549071f87433Sdalcinl 5491d5378b5fSDmitry Karpeev PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 549271f87433Sdalcinl { 5493fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW*)snes->kspconvctx; 549471f87433Sdalcinl PCSide pcside; 549571f87433Sdalcinl Vec lres; 549671f87433Sdalcinl 549771f87433Sdalcinl PetscFunctionBegin; 5498d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 54999566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp,&kctx->rtol_last,NULL,NULL,NULL)); 550071dbe336SPeter Brune kctx->norm_last = snes->norm; 55010f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 55024f00ce20SMatthew G. Knepley PC pc; 55030f0abf79SStefano Zampini PetscBool getRes; 55044f00ce20SMatthew G. Knepley 55059566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp,&pc)); 55060f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc,PCNONE,&getRes)); 55070f0abf79SStefano Zampini if (!getRes) { 55080f0abf79SStefano Zampini KSPNormType normtype; 55090f0abf79SStefano Zampini 55100f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp,&normtype)); 55110f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 55120f0abf79SStefano Zampini } 55139566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp,&pcside)); 55140f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 55159566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp,&kctx->lresid_last)); 551671f87433Sdalcinl } else { 551771f87433Sdalcinl /* KSP residual is preconditioned residual */ 551871f87433Sdalcinl /* compute true linear residual norm */ 55190f0abf79SStefano Zampini Mat J; 55200f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp,&J,NULL)); 55219566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b,&lres)); 55220f0abf79SStefano Zampini PetscCall(MatMult(J,x,lres)); 55239566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres,-1.0,b)); 55249566063dSJacob Faibussowitsch PetscCall(VecNorm(lres,NORM_2,&kctx->lresid_last)); 55259566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 552671f87433Sdalcinl } 552771f87433Sdalcinl } 552871f87433Sdalcinl PetscFunctionReturn(0); 552971f87433Sdalcinl } 553071f87433Sdalcinl 5531d4211eb9SBarry Smith /*@ 5532d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 5533d4211eb9SBarry Smith 5534d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 5535d4211eb9SBarry Smith 5536d4211eb9SBarry Smith Input Parameter: 5537d4211eb9SBarry Smith . snes - the SNES context 5538d4211eb9SBarry Smith 5539d4211eb9SBarry Smith Output Parameter: 5540d4211eb9SBarry Smith . ksp - the KSP context 5541d4211eb9SBarry Smith 5542d4211eb9SBarry Smith Notes: 5543d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 5544d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5545d4211eb9SBarry Smith PC contexts as well. 5546d4211eb9SBarry Smith 5547d4211eb9SBarry Smith Level: beginner 5548d4211eb9SBarry Smith 5549db781477SPatrick Sanan .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5550d4211eb9SBarry Smith @*/ 5551d4211eb9SBarry Smith PetscErrorCode SNESGetKSP(SNES snes,KSP *ksp) 555271f87433Sdalcinl { 555371f87433Sdalcinl PetscFunctionBegin; 5554d4211eb9SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5555d4211eb9SBarry Smith PetscValidPointer(ksp,2); 5556d4211eb9SBarry Smith 5557d4211eb9SBarry Smith if (!snes->ksp) { 55589566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes),&snes->ksp)); 55599566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp,(PetscObject)snes,1)); 55609566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->ksp)); 5561d4211eb9SBarry Smith 55629566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPreSolve_SNESEW,snes)); 55639566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp,(PetscErrorCode (*)(KSP,Vec,Vec,void*))KSPPostSolve_SNESEW,snes)); 5564a5c2985bSBarry Smith 55659566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 55669566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp,((PetscObject)snes)->options)); 5567d4211eb9SBarry Smith } 5568d4211eb9SBarry Smith *ksp = snes->ksp; 556971f87433Sdalcinl PetscFunctionReturn(0); 557071f87433Sdalcinl } 55716c699258SBarry Smith 5572af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 55736c699258SBarry Smith /*@ 55742a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 55756c699258SBarry Smith 55763f9fe445SBarry Smith Logically Collective on SNES 55776c699258SBarry Smith 55786c699258SBarry Smith Input Parameters: 55792a808120SBarry Smith + snes - the nonlinear solver context 55802a808120SBarry Smith - dm - the dm, cannot be NULL 55816c699258SBarry Smith 5582e03a659cSJed Brown Notes: 5583e03a659cSJed Brown A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5584e03a659cSJed Brown even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5585e03a659cSJed Brown problems using the same function space. 5586e03a659cSJed Brown 55876c699258SBarry Smith Level: intermediate 55886c699258SBarry Smith 5589db781477SPatrick Sanan .seealso: `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 55906c699258SBarry Smith @*/ 55917087cfbeSBarry Smith PetscErrorCode SNESSetDM(SNES snes,DM dm) 55926c699258SBarry Smith { 5593345fed2cSBarry Smith KSP ksp; 5594942e3340SBarry Smith DMSNES sdm; 55956c699258SBarry Smith 55966c699258SBarry Smith PetscFunctionBegin; 55970700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 55982a808120SBarry Smith PetscValidHeaderSpecific(dm,DM_CLASSID,2); 55999566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5600942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 560151f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 56029566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm,dm)); 56039566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm,&sdm)); 5604f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 56056cab3a1bSJed Brown } 56069566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm,DMCoarsenHook_SNESVecSol,DMRestrictHook_SNESVecSol,snes)); 56079566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 56086cab3a1bSJed Brown } 56096c699258SBarry Smith snes->dm = dm; 5610116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5611f5af7f23SKarl Rupp 56129566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes,&ksp)); 56139566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp,dm)); 56149566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp,PETSC_FALSE)); 5615efd4aadfSBarry Smith if (snes->npc) { 56169566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc,snes->dm)); 56179566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes,snes->npcside)); 56182c155ee1SBarry Smith } 56196c699258SBarry Smith PetscFunctionReturn(0); 56206c699258SBarry Smith } 56216c699258SBarry Smith 56226c699258SBarry Smith /*@ 56236c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 56246c699258SBarry Smith 56253f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 56266c699258SBarry Smith 56276c699258SBarry Smith Input Parameter: 56286c699258SBarry Smith . snes - the preconditioner context 56296c699258SBarry Smith 56306c699258SBarry Smith Output Parameter: 56316c699258SBarry Smith . dm - the dm 56326c699258SBarry Smith 56336c699258SBarry Smith Level: intermediate 56346c699258SBarry Smith 5635db781477SPatrick Sanan .seealso: `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 56366c699258SBarry Smith @*/ 56377087cfbeSBarry Smith PetscErrorCode SNESGetDM(SNES snes,DM *dm) 56386c699258SBarry Smith { 56396c699258SBarry Smith PetscFunctionBegin; 56400700a824SBarry Smith PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 56416cab3a1bSJed Brown if (!snes->dm) { 56429566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes),&snes->dm)); 5643116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 56446cab3a1bSJed Brown } 56456c699258SBarry Smith *dm = snes->dm; 56466c699258SBarry Smith PetscFunctionReturn(0); 56476c699258SBarry Smith } 56480807856dSBarry Smith 564931823bd8SMatthew G Knepley /*@ 5650be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 565131823bd8SMatthew G Knepley 565231823bd8SMatthew G Knepley Collective on SNES 565331823bd8SMatthew G Knepley 565431823bd8SMatthew G Knepley Input Parameters: 565531823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 565631823bd8SMatthew G Knepley - pc - the preconditioner object 565731823bd8SMatthew G Knepley 565831823bd8SMatthew G Knepley Notes: 5659be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 566031823bd8SMatthew G Knepley to configure it using the API). 566131823bd8SMatthew G Knepley 566231823bd8SMatthew G Knepley Level: developer 566331823bd8SMatthew G Knepley 5664db781477SPatrick Sanan .seealso: `SNESGetNPC()`, `SNESHasNPC()` 566531823bd8SMatthew G Knepley @*/ 5666be95d8f1SBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES pc) 566731823bd8SMatthew G Knepley { 566831823bd8SMatthew G Knepley PetscFunctionBegin; 566931823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 567031823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 567131823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 56729566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) pc)); 56739566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5674efd4aadfSBarry Smith snes->npc = pc; 56759566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 567631823bd8SMatthew G Knepley PetscFunctionReturn(0); 567731823bd8SMatthew G Knepley } 567831823bd8SMatthew G Knepley 567931823bd8SMatthew G Knepley /*@ 5680be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 568131823bd8SMatthew G Knepley 5682951fe5abSBarry Smith Not Collective; but any changes to the obtained SNES object must be applied collectively 568331823bd8SMatthew G Knepley 568431823bd8SMatthew G Knepley Input Parameter: 568531823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 568631823bd8SMatthew G Knepley 568731823bd8SMatthew G Knepley Output Parameter: 568831823bd8SMatthew G Knepley . pc - preconditioner context 568931823bd8SMatthew G Knepley 5690b5badacbSBarry Smith Options Database: 5691b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5692b5badacbSBarry Smith 569395452b02SPatrick Sanan Notes: 5694b5badacbSBarry Smith If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5695be95d8f1SBarry Smith 5696951fe5abSBarry Smith The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5697951fe5abSBarry Smith SNES during SNESSetUp() 5698951fe5abSBarry Smith 569931823bd8SMatthew G Knepley Level: developer 570031823bd8SMatthew G Knepley 5701db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 570231823bd8SMatthew G Knepley @*/ 5703be95d8f1SBarry Smith PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 570431823bd8SMatthew G Knepley { 5705a64e098fSPeter Brune const char *optionsprefix; 570631823bd8SMatthew G Knepley 570731823bd8SMatthew G Knepley PetscFunctionBegin; 570831823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 570931823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5710efd4aadfSBarry Smith if (!snes->npc) { 57119566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes),&snes->npc)); 57129566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc,(PetscObject)snes,1)); 57139566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes,(PetscObject)snes->npc)); 57149566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes,&optionsprefix)); 57159566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc,optionsprefix)); 57169566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc,"npc_")); 57179566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc,PETSC_FALSE)); 571831823bd8SMatthew G Knepley } 5719efd4aadfSBarry Smith *pc = snes->npc; 572031823bd8SMatthew G Knepley PetscFunctionReturn(0); 572131823bd8SMatthew G Knepley } 572231823bd8SMatthew G Knepley 57233ad1a0b9SPatrick Farrell /*@ 57243ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 57253ad1a0b9SPatrick Farrell 57263ad1a0b9SPatrick Farrell Not Collective 57273ad1a0b9SPatrick Farrell 57283ad1a0b9SPatrick Farrell Input Parameter: 57293ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 57303ad1a0b9SPatrick Farrell 57313ad1a0b9SPatrick Farrell Output Parameter: 57323ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 57333ad1a0b9SPatrick Farrell 57343ad1a0b9SPatrick Farrell Level: developer 57353ad1a0b9SPatrick Farrell 5736db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESGetNPC()` 57373ad1a0b9SPatrick Farrell @*/ 57383ad1a0b9SPatrick Farrell PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 57393ad1a0b9SPatrick Farrell { 57403ad1a0b9SPatrick Farrell PetscFunctionBegin; 57413ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5742efd4aadfSBarry Smith *has_npc = (PetscBool) (snes->npc ? PETSC_TRUE : PETSC_FALSE); 57433ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 57443ad1a0b9SPatrick Farrell } 57453ad1a0b9SPatrick Farrell 5746c40d0f55SPeter Brune /*@ 5747be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5748c40d0f55SPeter Brune 5749c40d0f55SPeter Brune Logically Collective on SNES 5750c40d0f55SPeter Brune 5751c40d0f55SPeter Brune Input Parameter: 5752c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5753c40d0f55SPeter Brune 5754c40d0f55SPeter Brune Output Parameter: 5755c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5756c40d0f55SPeter Brune .vb 57572d547940SBarry Smith PC_LEFT - left preconditioning 57582d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5759c40d0f55SPeter Brune .ve 5760c40d0f55SPeter Brune 5761c40d0f55SPeter Brune Options Database Keys: 576267b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5763c40d0f55SPeter Brune 576495452b02SPatrick Sanan Notes: 576595452b02SPatrick Sanan SNESNRICHARDSON and SNESNCG only support left preconditioning. 57662d547940SBarry Smith 5767c40d0f55SPeter Brune Level: intermediate 5768c40d0f55SPeter Brune 5769db781477SPatrick Sanan .seealso: `SNESGetNPCSide()`, `KSPSetPCSide()` 5770c40d0f55SPeter Brune @*/ 5771be95d8f1SBarry Smith PetscErrorCode SNESSetNPCSide(SNES snes,PCSide side) 5772c40d0f55SPeter Brune { 5773c40d0f55SPeter Brune PetscFunctionBegin; 5774c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5775c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes,side,2); 5776b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 577754c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT),PetscObjectComm((PetscObject)snes),PETSC_ERR_ARG_WRONG,"Only PC_LEFT and PC_RIGHT are supported"); 5778efd4aadfSBarry Smith snes->npcside = side; 5779c40d0f55SPeter Brune PetscFunctionReturn(0); 5780c40d0f55SPeter Brune } 5781c40d0f55SPeter Brune 5782c40d0f55SPeter Brune /*@ 5783be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5784c40d0f55SPeter Brune 5785c40d0f55SPeter Brune Not Collective 5786c40d0f55SPeter Brune 5787c40d0f55SPeter Brune Input Parameter: 5788c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5789c40d0f55SPeter Brune 5790c40d0f55SPeter Brune Output Parameter: 5791c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5792c40d0f55SPeter Brune .vb 57932d547940SBarry Smith PC_LEFT - left preconditioning 57942d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5795c40d0f55SPeter Brune .ve 5796c40d0f55SPeter Brune 5797c40d0f55SPeter Brune Level: intermediate 5798c40d0f55SPeter Brune 5799db781477SPatrick Sanan .seealso: `SNESSetNPCSide()`, `KSPGetPCSide()` 5800c40d0f55SPeter Brune @*/ 5801be95d8f1SBarry Smith PetscErrorCode SNESGetNPCSide(SNES snes,PCSide *side) 5802c40d0f55SPeter Brune { 5803c40d0f55SPeter Brune PetscFunctionBegin; 5804c40d0f55SPeter Brune PetscValidHeaderSpecific(snes,SNES_CLASSID,1); 5805c40d0f55SPeter Brune PetscValidPointer(side,2); 5806efd4aadfSBarry Smith *side = snes->npcside; 5807c40d0f55SPeter Brune PetscFunctionReturn(0); 5808c40d0f55SPeter Brune } 5809c40d0f55SPeter Brune 58109e764e56SPeter Brune /*@ 58117601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 58129e764e56SPeter Brune 58139e764e56SPeter Brune Collective on SNES 58149e764e56SPeter Brune 58159e764e56SPeter Brune Input Parameters: 58169e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 58179e764e56SPeter Brune - linesearch - the linesearch object 58189e764e56SPeter Brune 58199e764e56SPeter Brune Notes: 58207601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 58219e764e56SPeter Brune to configure it using the API). 58229e764e56SPeter Brune 58239e764e56SPeter Brune Level: developer 58249e764e56SPeter Brune 5825db781477SPatrick Sanan .seealso: `SNESGetLineSearch()` 58269e764e56SPeter Brune @*/ 58277601faf0SJed Brown PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 58289e764e56SPeter Brune { 58299e764e56SPeter Brune PetscFunctionBegin; 58309e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5831f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 58329e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 58339566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject) linesearch)); 58349566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5835f5af7f23SKarl Rupp 58369e764e56SPeter Brune snes->linesearch = linesearch; 5837f5af7f23SKarl Rupp 58389566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 58399e764e56SPeter Brune PetscFunctionReturn(0); 58409e764e56SPeter Brune } 58419e764e56SPeter Brune 5842a34ceb2aSJed Brown /*@ 58437601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 58448141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 58459e764e56SPeter Brune 58469e764e56SPeter Brune Not Collective 58479e764e56SPeter Brune 58489e764e56SPeter Brune Input Parameter: 58499e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 58509e764e56SPeter Brune 58519e764e56SPeter Brune Output Parameter: 58529e764e56SPeter Brune . linesearch - linesearch context 58539e764e56SPeter Brune 5854162e0bf5SPeter Brune Level: beginner 58559e764e56SPeter Brune 5856db781477SPatrick Sanan .seealso: `SNESSetLineSearch()`, `SNESLineSearchCreate()` 58579e764e56SPeter Brune @*/ 58587601faf0SJed Brown PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 58599e764e56SPeter Brune { 58609e764e56SPeter Brune const char *optionsprefix; 58619e764e56SPeter Brune 58629e764e56SPeter Brune PetscFunctionBegin; 58639e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 58649e764e56SPeter Brune PetscValidPointer(linesearch, 2); 58659e764e56SPeter Brune if (!snes->linesearch) { 58669566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 58679566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 58689566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 58699566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 58709566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject) snes->linesearch, (PetscObject) snes, 1)); 58719566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 58729e764e56SPeter Brune } 58739e764e56SPeter Brune *linesearch = snes->linesearch; 58749e764e56SPeter Brune PetscFunctionReturn(0); 58759e764e56SPeter Brune } 5876