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 @*/ 359371c9d4SSatish Balay PetscErrorCode SNESSetErrorIfNotConverged(SNES snes, PetscBool flg) { 36e113a28aSBarry Smith PetscFunctionBegin; 37e113a28aSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 38acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flg, 2); 39e113a28aSBarry Smith snes->errorifnotconverged = flg; 40e113a28aSBarry Smith PetscFunctionReturn(0); 41e113a28aSBarry Smith } 42e113a28aSBarry Smith 43e113a28aSBarry Smith /*@ 44e113a28aSBarry Smith SNESGetErrorIfNotConverged - Will SNESSolve() generate an error if the solver does not converge? 45e113a28aSBarry Smith 46e113a28aSBarry Smith Not Collective 47e113a28aSBarry Smith 48e113a28aSBarry Smith Input Parameter: 49e113a28aSBarry Smith . snes - iterative context obtained from SNESCreate() 50e113a28aSBarry Smith 51e113a28aSBarry Smith Output Parameter: 52e113a28aSBarry Smith . flag - PETSC_TRUE if it will generate an error, else PETSC_FALSE 53e113a28aSBarry Smith 54e113a28aSBarry Smith Level: intermediate 55e113a28aSBarry Smith 56db781477SPatrick Sanan .seealso: `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 57e113a28aSBarry Smith @*/ 589371c9d4SSatish Balay PetscErrorCode SNESGetErrorIfNotConverged(SNES snes, PetscBool *flag) { 59e113a28aSBarry Smith PetscFunctionBegin; 60e113a28aSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 61534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 62e113a28aSBarry Smith *flag = snes->errorifnotconverged; 63e113a28aSBarry Smith PetscFunctionReturn(0); 64e113a28aSBarry Smith } 65e113a28aSBarry Smith 664fc747eaSLawrence Mitchell /*@ 674fc747eaSLawrence Mitchell SNESSetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 684fc747eaSLawrence Mitchell 694fc747eaSLawrence Mitchell Logically Collective on SNES 704fc747eaSLawrence Mitchell 714fc747eaSLawrence Mitchell Input Parameters: 724fc747eaSLawrence Mitchell + snes - the shell SNES 734fc747eaSLawrence Mitchell - flg - is the residual computed? 744fc747eaSLawrence Mitchell 754fc747eaSLawrence Mitchell Level: advanced 764fc747eaSLawrence Mitchell 77db781477SPatrick Sanan .seealso: `SNESGetAlwaysComputesFinalResidual()` 784fc747eaSLawrence Mitchell @*/ 799371c9d4SSatish Balay PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) { 804fc747eaSLawrence Mitchell PetscFunctionBegin; 814fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 824fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 834fc747eaSLawrence Mitchell PetscFunctionReturn(0); 844fc747eaSLawrence Mitchell } 854fc747eaSLawrence Mitchell 864fc747eaSLawrence Mitchell /*@ 874fc747eaSLawrence Mitchell SNESGetAlwaysComputesFinalResidual - does the SNES always compute the residual at the final solution? 884fc747eaSLawrence Mitchell 894fc747eaSLawrence Mitchell Logically Collective on SNES 904fc747eaSLawrence Mitchell 914fc747eaSLawrence Mitchell Input Parameter: 924fc747eaSLawrence Mitchell . snes - the shell SNES 934fc747eaSLawrence Mitchell 944fc747eaSLawrence Mitchell Output Parameter: 954fc747eaSLawrence Mitchell . flg - is the residual computed? 964fc747eaSLawrence Mitchell 974fc747eaSLawrence Mitchell Level: advanced 984fc747eaSLawrence Mitchell 99db781477SPatrick Sanan .seealso: `SNESSetAlwaysComputesFinalResidual()` 1004fc747eaSLawrence Mitchell @*/ 1019371c9d4SSatish Balay PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) { 1024fc747eaSLawrence Mitchell PetscFunctionBegin; 1034fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1044fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1054fc747eaSLawrence Mitchell PetscFunctionReturn(0); 1064fc747eaSLawrence Mitchell } 1074fc747eaSLawrence Mitchell 108e725d27bSBarry Smith /*@ 109bf388a1fSBarry Smith SNESSetFunctionDomainError - tells SNES that the input vector to your SNESFunction is not 110f0b84518SBarry Smith in the functions domain. For example, a step with negative pressure. 1114936397dSBarry Smith 1123f9fe445SBarry Smith Logically Collective on SNES 1134936397dSBarry Smith 1144936397dSBarry Smith Input Parameters: 1156a388c36SPeter Brune . snes - the SNES context 1164936397dSBarry Smith 11728529972SSatish Balay Level: advanced 1184936397dSBarry Smith 119f0b84518SBarry Smith Note: 120f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 121f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 122f0b84518SBarry Smith 123f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`, 124f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 1254936397dSBarry Smith @*/ 1269371c9d4SSatish Balay PetscErrorCode SNESSetFunctionDomainError(SNES snes) { 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 /*@ 135f0b84518SBarry Smith SNESSetJacobianDomainError - tells SNES that computeJacobian does not make sense at the proposed step. 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 144f0b84518SBarry Smith Note: 145f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 146f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 147f0b84518SBarry Smith 148f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`, 149f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 15007b62357SFande Kong @*/ 1519371c9d4SSatish Balay PetscErrorCode SNESSetJacobianDomainError(SNES snes) { 15207b62357SFande Kong PetscFunctionBegin; 15307b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1545f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates computeJacobian does not make sense"); 15507b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 15607b62357SFande Kong PetscFunctionReturn(0); 15707b62357SFande Kong } 15807b62357SFande Kong 15907b62357SFande Kong /*@ 160b351a90bSFande Kong SNESSetCheckJacobianDomainError - if or not to check jacobian domain error after each Jacobian evaluation. By default, we check Jacobian domain error 161b351a90bSFande Kong in the debug mode, and do not check it in the optimized mode. 162b351a90bSFande Kong 163b351a90bSFande Kong Logically Collective on SNES 164b351a90bSFande Kong 165b351a90bSFande Kong Input Parameters: 166a2b725a8SWilliam Gropp + snes - the SNES context 167a2b725a8SWilliam Gropp - flg - indicates if or not to check jacobian domain error after each Jacobian evaluation 168b351a90bSFande Kong 169b351a90bSFande Kong Level: advanced 170b351a90bSFande Kong 171db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 172b351a90bSFande Kong @*/ 1739371c9d4SSatish Balay PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) { 174b351a90bSFande Kong PetscFunctionBegin; 175b351a90bSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 176b351a90bSFande Kong snes->checkjacdomainerror = flg; 177b351a90bSFande Kong PetscFunctionReturn(0); 178b351a90bSFande Kong } 179b351a90bSFande Kong 180b351a90bSFande Kong /*@ 1818383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 1828383d7d7SFande Kong 1838383d7d7SFande Kong Logically Collective on SNES 1848383d7d7SFande Kong 1858383d7d7SFande Kong Input Parameters: 1868383d7d7SFande Kong . snes - the SNES context 1878383d7d7SFande Kong 1888383d7d7SFande Kong Output Parameters: 1898383d7d7SFande Kong . flg - PETSC_FALSE indicates that we don't check jacobian domain errors after each Jacobian evaluation 1908383d7d7SFande Kong 1918383d7d7SFande Kong Level: advanced 1928383d7d7SFande Kong 193db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 1948383d7d7SFande Kong @*/ 1959371c9d4SSatish Balay PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) { 1968383d7d7SFande Kong PetscFunctionBegin; 1978383d7d7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 198534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 1998383d7d7SFande Kong *flg = snes->checkjacdomainerror; 2008383d7d7SFande Kong PetscFunctionReturn(0); 2018383d7d7SFande Kong } 2028383d7d7SFande Kong 2038383d7d7SFande Kong /*@ 204c77b2880SPeter Brune SNESGetFunctionDomainError - Gets the status of the domain error after a call to SNESComputeFunction; 2056a388c36SPeter Brune 2066a388c36SPeter Brune Logically Collective on SNES 2076a388c36SPeter Brune 2086a388c36SPeter Brune Input Parameters: 2096a388c36SPeter Brune . snes - the SNES context 2106a388c36SPeter Brune 2116a388c36SPeter Brune Output Parameters: 212bf388a1fSBarry Smith . domainerror - Set to PETSC_TRUE if there's a domain error; PETSC_FALSE otherwise. 2136a388c36SPeter Brune 2146a388c36SPeter Brune Level: advanced 2156a388c36SPeter Brune 216db781477SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 2176a388c36SPeter Brune @*/ 2189371c9d4SSatish Balay PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) { 2196a388c36SPeter Brune PetscFunctionBegin; 2206a388c36SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 221534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 2226a388c36SPeter Brune *domainerror = snes->domainerror; 2236a388c36SPeter Brune PetscFunctionReturn(0); 2246a388c36SPeter Brune } 2256a388c36SPeter Brune 22607b62357SFande Kong /*@ 22707b62357SFande Kong SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to SNESComputeJacobian; 22807b62357SFande Kong 22907b62357SFande Kong Logically Collective on SNES 23007b62357SFande Kong 23107b62357SFande Kong Input Parameters: 23207b62357SFande Kong . snes - the SNES context 23307b62357SFande Kong 23407b62357SFande Kong Output Parameters: 23507b62357SFande Kong . domainerror - Set to PETSC_TRUE if there's a jacobian domain error; PETSC_FALSE otherwise. 23607b62357SFande Kong 23707b62357SFande Kong Level: advanced 23807b62357SFande Kong 239c2e3fba1SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 24007b62357SFande Kong @*/ 2419371c9d4SSatish Balay PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) { 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 @*/ 2759371c9d4SSatish Balay PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) { 27655849f57SBarry Smith PetscBool isbinary; 277060da220SMatthew G. Knepley PetscInt classid; 27855849f57SBarry Smith char type[256]; 27955849f57SBarry Smith KSP ksp; 2802d53ad75SBarry Smith DM dm; 2812d53ad75SBarry Smith DMSNES dmsnes; 28255849f57SBarry Smith 28355849f57SBarry Smith PetscFunctionBegin; 2842d53ad75SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 28555849f57SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2869566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 2875f80ce2aSJacob Faibussowitsch PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 28855849f57SBarry Smith 2899566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 2905f80ce2aSJacob Faibussowitsch PetscCheck(classid == SNES_FILE_CLASSID, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Not SNES next in file"); 2919566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 2929566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 293dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, load, viewer); 2949566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 2959566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &dmsnes)); 2969566063dSJacob Faibussowitsch PetscCall(DMSNESLoad(dmsnes, viewer)); 2979566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 2989566063dSJacob Faibussowitsch PetscCall(KSPLoad(ksp, viewer)); 29955849f57SBarry Smith PetscFunctionReturn(0); 30055849f57SBarry Smith } 3016a388c36SPeter Brune 3029804daf3SBarry Smith #include <petscdraw.h> 303e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 304e04113cfSBarry Smith #include <petscviewersaws.h> 305bfb97211SBarry Smith #endif 3068404b7f3SBarry Smith 307fe2efc57SMark /*@C 308fe2efc57SMark SNESViewFromOptions - View from Options 309fe2efc57SMark 310fe2efc57SMark Collective on SNES 311fe2efc57SMark 312fe2efc57SMark Input Parameters: 313fe2efc57SMark + A - the application ordering context 314736c3998SJose E. Roman . obj - Optional object 315736c3998SJose E. Roman - name - command line option 316fe2efc57SMark 317fe2efc57SMark Level: intermediate 318db781477SPatrick Sanan .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 319fe2efc57SMark @*/ 3209371c9d4SSatish Balay PetscErrorCode SNESViewFromOptions(SNES A, PetscObject obj, const char name[]) { 321fe2efc57SMark PetscFunctionBegin; 322fe2efc57SMark PetscValidHeaderSpecific(A, SNES_CLASSID, 1); 3239566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 324fe2efc57SMark PetscFunctionReturn(0); 325fe2efc57SMark } 326fe2efc57SMark 327789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES, Vec, Mat, Mat, void *); 328789d8953SBarry Smith 3297e2c5f70SBarry Smith /*@C 3309b94acceSBarry Smith SNESView - Prints the SNES data structure. 3319b94acceSBarry Smith 3324c49b128SBarry Smith Collective on SNES 333fee21e36SBarry Smith 334c7afd0dbSLois Curfman McInnes Input Parameters: 335c7afd0dbSLois Curfman McInnes + SNES - the SNES context 336c7afd0dbSLois Curfman McInnes - viewer - visualization context 337c7afd0dbSLois Curfman McInnes 3389b94acceSBarry Smith Options Database Key: 339c8a8ba5cSLois Curfman McInnes . -snes_view - Calls SNESView() at end of SNESSolve() 3409b94acceSBarry Smith 3419b94acceSBarry Smith Notes: 3429b94acceSBarry Smith The available visualization contexts include 343b0a32e0cSBarry Smith + PETSC_VIEWER_STDOUT_SELF - standard output (default) 344b0a32e0cSBarry Smith - PETSC_VIEWER_STDOUT_WORLD - synchronized standard 345c8a8ba5cSLois Curfman McInnes output where only the first processor opens 346c8a8ba5cSLois Curfman McInnes the file. All other processors send their 347c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3489b94acceSBarry Smith 349052bf0daSPierre Jolivet The available formats include 350052bf0daSPierre Jolivet + PETSC_VIEWER_DEFAULT - standard output (default) 351052bf0daSPierre Jolivet - PETSC_VIEWER_ASCII_INFO_DETAIL - more verbose output for SNESNASM 352052bf0daSPierre Jolivet 3533e081fefSLois Curfman McInnes The user can open an alternative visualization context with 354b0a32e0cSBarry Smith PetscViewerASCIIOpen() - output to a specified file. 3559b94acceSBarry Smith 356595c91d4SBarry Smith In the debugger you can do "call SNESView(snes,0)" to display the SNES solver. (The same holds for any PETSc object viewer). 357595c91d4SBarry Smith 35836851e7fSLois Curfman McInnes Level: beginner 35936851e7fSLois Curfman McInnes 360db781477SPatrick Sanan .seealso: `PetscViewerASCIIOpen()` 3619b94acceSBarry Smith @*/ 3629371c9d4SSatish Balay PetscErrorCode SNESView(SNES snes, PetscViewer viewer) { 363fa9f3622SBarry Smith SNESKSPEW *kctx; 36494b7f48cSBarry Smith KSP ksp; 3657f1410a3SPeter Brune SNESLineSearch linesearch; 36672a02f06SBarry Smith PetscBool iascii, isstring, isbinary, isdraw; 3672d53ad75SBarry Smith DMSNES dmsnes; 368e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 369536b137fSBarry Smith PetscBool issaws; 370bfb97211SBarry Smith #endif 3719b94acceSBarry Smith 3723a40ed3dSBarry Smith PetscFunctionBegin; 3730700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 374*48a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &viewer)); 3750700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 376c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, viewer, 2); 37774679c65SBarry Smith 3789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3799566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 3809566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 3819566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 382e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 3839566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 384bfb97211SBarry Smith #endif 38532077d6dSBarry Smith if (iascii) { 386dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3878404b7f3SBarry Smith DM dm; 3888404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES, Vec, Mat, Mat, void *); 3898404b7f3SBarry Smith void *ctx; 390789d8953SBarry Smith const char *pre = ""; 391dc0571f2SMatthew G. Knepley 3929566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes, viewer)); 393*48a46eb9SPierre Jolivet if (!snes->setupcalled) PetscCall(PetscViewerASCIIPrintf(viewer, " SNES has not been set up so information may be incomplete\n")); 394e7788613SBarry Smith if (snes->ops->view) { 3959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 396dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, view, viewer); 3979566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 3980ef38995SBarry Smith } 39963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n", snes->max_its, snes->max_funcs)); 4009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerances: relative=%g, absolute=%g, solution=%g\n", (double)snes->rtol, (double)snes->abstol, (double)snes->stol)); 401*48a46eb9SPierre Jolivet if (snes->usesksp) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of linear solver iterations=%" PetscInt_FMT "\n", snes->linear_its)); 40263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " total number of function evaluations=%" PetscInt_FMT "\n", snes->nfuncs)); 4039566063dSJacob Faibussowitsch PetscCall(SNESGetNormSchedule(snes, &normschedule)); 4049566063dSJacob Faibussowitsch if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer, " norm schedule %s\n", SNESNormSchedules[normschedule])); 405*48a46eb9SPierre Jolivet if (snes->gridsequence) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of grid sequence refinements=%" PetscInt_FMT "\n", snes->gridsequence)); 4069b94acceSBarry Smith if (snes->ksp_ewconv) { 407fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 4089b94acceSBarry Smith if (kctx) { 40963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n", kctx->version)); 4109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " rtol_0=%g, rtol_max=%g, threshold=%g\n", (double)kctx->rtol_0, (double)kctx->rtol_max, (double)kctx->threshold)); 4119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " gamma=%g, alpha=%g, alpha2=%g\n", (double)kctx->gamma, (double)kctx->alpha, (double)kctx->alpha2)); 4129b94acceSBarry Smith } 4139b94acceSBarry Smith } 414eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 4159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is never rebuilt\n")); 416eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 41763a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n", snes->lagpreconditioner)); 418eb1f6c34SBarry Smith } 419eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 4209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is never rebuilt\n")); 421eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 42263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n", snes->lagjacobian)); 423eb1f6c34SBarry Smith } 4249566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4259566063dSJacob Faibussowitsch PetscCall(DMSNESGetJacobian(dm, &cJ, &ctx)); 426789d8953SBarry Smith if (snes->mf_operator) { 4279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing\n")); 428789d8953SBarry Smith pre = "Preconditioning "; 429789d8953SBarry Smith } 4308404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 4319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences one column at a time\n", pre)); 4328404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 4339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences with coloring\n", pre)); 434789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 435789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 436789d8953SBarry Smith MatFDColoring fdcoloring; 4379566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 438789d8953SBarry Smith if (fdcoloring) { 4399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using colored finite differences on a DMDA\n", pre)); 440789d8953SBarry Smith } else { 4419566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using a DMDA local Jacobian\n", pre)); 442789d8953SBarry Smith } 443789d8953SBarry Smith } else if (snes->mf) { 4449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 4458404b7f3SBarry Smith } 4460f5bd95cSBarry Smith } else if (isstring) { 447317d6ea6SBarry Smith const char *type; 4489566063dSJacob Faibussowitsch PetscCall(SNESGetType(snes, &type)); 4499566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSPrintf(viewer, " SNESType: %-7.7s", type)); 450dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 45155849f57SBarry Smith } else if (isbinary) { 45255849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 45355849f57SBarry Smith MPI_Comm comm; 45455849f57SBarry Smith PetscMPIInt rank; 45555849f57SBarry Smith char type[256]; 45655849f57SBarry Smith 4579566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 4589566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 459dd400576SPatrick Sanan if (rank == 0) { 4609566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 4619566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type, ((PetscObject)snes)->type_name, sizeof(type))); 4629566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, type, sizeof(type), PETSC_CHAR)); 46355849f57SBarry Smith } 464dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 46572a02f06SBarry Smith } else if (isdraw) { 46672a02f06SBarry Smith PetscDraw draw; 46772a02f06SBarry Smith char str[36]; 46889fd9fafSBarry Smith PetscReal x, y, bottom, h; 46972a02f06SBarry Smith 4709566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 4719566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 4729566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(str, "SNES: ", sizeof(str))); 4739566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(str, ((PetscObject)snes)->type_name, sizeof(str))); 4749566063dSJacob Faibussowitsch PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLUE, PETSC_DRAW_BLACK, str, NULL, &h)); 47589fd9fafSBarry Smith bottom = y - h; 4769566063dSJacob Faibussowitsch PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 477dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 478e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 479536b137fSBarry Smith } else if (issaws) { 480d45a07a7SBarry Smith PetscMPIInt rank; 4812657e9d9SBarry Smith const char *name; 482d45a07a7SBarry Smith 4839566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)snes, &name)); 4849566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 485dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 486d45a07a7SBarry Smith char dir[1024]; 487d45a07a7SBarry Smith 4889566063dSJacob Faibussowitsch PetscCall(PetscObjectViewSAWs((PetscObject)snes, viewer)); 4899566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name)); 490792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, &snes->iter, 1, SAWs_READ, SAWs_INT)); 491*48a46eb9SPierre Jolivet if (!snes->conv_hist) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, PETSC_DECIDE, PETSC_TRUE)); 4929566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/conv_hist", name)); 493792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, snes->conv_hist, 10, SAWs_READ, SAWs_DOUBLE)); 494f05ece33SBarry Smith } 495bfb97211SBarry Smith #endif 49672a02f06SBarry Smith } 49772a02f06SBarry Smith if (snes->linesearch) { 4989566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 4999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5009566063dSJacob Faibussowitsch PetscCall(SNESLineSearchView(linesearch, viewer)); 5019566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 50219bcc07fSBarry Smith } 503efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 5049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5059566063dSJacob Faibussowitsch PetscCall(SNESView(snes->npc, viewer)); 5069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5074a0c5b0cSMatthew G Knepley } 5089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5099566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &dmsnes)); 5109566063dSJacob Faibussowitsch PetscCall(DMSNESView(dmsnes, viewer)); 5119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5122c155ee1SBarry Smith if (snes->usesksp) { 5139566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 5149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5159566063dSJacob Faibussowitsch PetscCall(KSPView(ksp, viewer)); 5169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5172c155ee1SBarry Smith } 51872a02f06SBarry Smith if (isdraw) { 51972a02f06SBarry Smith PetscDraw draw; 5209566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 5219566063dSJacob Faibussowitsch PetscCall(PetscDrawPopCurrentPoint(draw)); 5227f1410a3SPeter Brune } 5233a40ed3dSBarry Smith PetscFunctionReturn(0); 5249b94acceSBarry Smith } 5259b94acceSBarry Smith 52676b2cf59SMatthew Knepley /* 52776b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 52876b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 52976b2cf59SMatthew Knepley */ 53076b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 531a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5326849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 53376b2cf59SMatthew Knepley 534ac226902SBarry Smith /*@C 53576b2cf59SMatthew Knepley SNESAddOptionsChecker - Adds an additional function to check for SNES options. 53676b2cf59SMatthew Knepley 53776b2cf59SMatthew Knepley Not Collective 53876b2cf59SMatthew Knepley 53976b2cf59SMatthew Knepley Input Parameter: 54076b2cf59SMatthew Knepley . snescheck - function that checks for options 54176b2cf59SMatthew Knepley 54276b2cf59SMatthew Knepley Level: developer 54376b2cf59SMatthew Knepley 544db781477SPatrick Sanan .seealso: `SNESSetFromOptions()` 54576b2cf59SMatthew Knepley @*/ 5469371c9d4SSatish Balay PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) { 54776b2cf59SMatthew Knepley PetscFunctionBegin; 54863a3b9bcSJacob Faibussowitsch PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 54976b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 55076b2cf59SMatthew Knepley PetscFunctionReturn(0); 55176b2cf59SMatthew Knepley } 55276b2cf59SMatthew Knepley 55325acbd8eSLisandro Dalcin PETSC_INTERN PetscErrorCode SNESDefaultMatrixFreeCreate2(SNES, Vec, Mat *); 554aa3661deSLisandro Dalcin 5559371c9d4SSatish Balay static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) { 556aa3661deSLisandro Dalcin Mat J; 557895c21f2SBarry Smith MatNullSpace nullsp; 558aa3661deSLisandro Dalcin 559aa3661deSLisandro Dalcin PetscFunctionBegin; 5600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 561aa3661deSLisandro Dalcin 56298613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 56398613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5649566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A ? A : B, NULL, &snes->vec_func)); 56598613b67SLisandro Dalcin } 56698613b67SLisandro Dalcin 567aa3661deSLisandro Dalcin if (version == 1) { 5689566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 5699566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 5709566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 5711e2ae407SBarry Smith /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 572aa3661deSLisandro Dalcin } else if (version == 2) { 5735f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "SNESSetFunction() must be called first"); 574570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 5759566063dSJacob Faibussowitsch PetscCall(SNESDefaultMatrixFreeCreate2(snes, snes->vec_func, &J)); 576aa3661deSLisandro Dalcin #else 5772479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 578aa3661deSLisandro Dalcin #endif 5792479783cSJose E. Roman } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 580aa3661deSLisandro Dalcin 581895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 582895c21f2SBarry Smith if (snes->jacobian) { 5839566063dSJacob Faibussowitsch PetscCall(MatGetNullSpace(snes->jacobian, &nullsp)); 5841baa6e33SBarry Smith if (nullsp) PetscCall(MatSetNullSpace(J, nullsp)); 585895c21f2SBarry Smith } 586895c21f2SBarry Smith 58763a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 588d3462f78SMatthew Knepley if (hasOperator) { 589aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 590aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 5919566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 592aa3661deSLisandro Dalcin } else { 593aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 5943232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 595b552625fSStefano Zampini if (snes->npcside == PC_LEFT && snes->npc) { 5969566063dSJacob Faibussowitsch if (!snes->jacobian) PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 597172a4300SPeter Brune } else { 598789d8953SBarry Smith KSP ksp; 599789d8953SBarry Smith PC pc; 600789d8953SBarry Smith PetscBool match; 601789d8953SBarry Smith 6029566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL)); 603aa3661deSLisandro Dalcin /* Force no preconditioner */ 6049566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 6059566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 6062698c518SLisandro Dalcin PetscCall(PetscObjectTypeCompareAny((PetscObject)pc, &match, PCSHELL, PCH2OPUS, "")); 607aa3661deSLisandro Dalcin if (!match) { 6089566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 6099566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, PCNONE)); 610aa3661deSLisandro Dalcin } 611aa3661deSLisandro Dalcin } 612789d8953SBarry Smith } 6139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 614aa3661deSLisandro Dalcin PetscFunctionReturn(0); 615aa3661deSLisandro Dalcin } 616aa3661deSLisandro Dalcin 6179371c9d4SSatish Balay static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine, Mat Restrict, Vec Rscale, Mat Inject, DM dmcoarse, void *ctx) { 618dfe15315SJed Brown SNES snes = (SNES)ctx; 6190298fd71SBarry Smith Vec Xfine, Xfine_named = NULL, Xcoarse; 620dfe15315SJed Brown 621dfe15315SJed Brown PetscFunctionBegin; 62216ebb321SJed Brown if (PetscLogPrintInfo) { 62316ebb321SJed Brown PetscInt finelevel, coarselevel, fineclevel, coarseclevel; 6249566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmfine, &finelevel)); 6259566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmfine, &fineclevel)); 6269566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmcoarse, &coarselevel)); 6279566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmcoarse, &coarseclevel)); 62863a3b9bcSJacob 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)); 62916ebb321SJed Brown } 630dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 631dfe15315SJed Brown else { 6329566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 633dfe15315SJed Brown Xfine = Xfine_named; 634dfe15315SJed Brown } 6359566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 636907f5c5aSLawrence Mitchell if (Inject) { 6379566063dSJacob Faibussowitsch PetscCall(MatRestrict(Inject, Xfine, Xcoarse)); 638907f5c5aSLawrence Mitchell } else { 6399566063dSJacob Faibussowitsch PetscCall(MatRestrict(Restrict, Xfine, Xcoarse)); 6409566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Xcoarse, Xcoarse, Rscale)); 641907f5c5aSLawrence Mitchell } 6429566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 6439566063dSJacob Faibussowitsch if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 644dfe15315SJed Brown PetscFunctionReturn(0); 645dfe15315SJed Brown } 646dfe15315SJed Brown 6479371c9d4SSatish Balay static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm, DM dmc, void *ctx) { 64816ebb321SJed Brown PetscFunctionBegin; 6499566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmc, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, ctx)); 65016ebb321SJed Brown PetscFunctionReturn(0); 65116ebb321SJed Brown } 65216ebb321SJed Brown 653a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 654a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 6559371c9d4SSatish Balay static PetscErrorCode KSPComputeOperators_SNES(KSP ksp, Mat A, Mat B, void *ctx) { 656caa4e7f2SJed Brown SNES snes = (SNES)ctx; 6570298fd71SBarry Smith Vec X, Xnamed = NULL; 658dfe15315SJed Brown DM dmsave; 6594e269d77SPeter Brune void *ctxsave; 66025ce1634SJed Brown PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL; 661caa4e7f2SJed Brown 662caa4e7f2SJed Brown PetscFunctionBegin; 663dfe15315SJed Brown dmsave = snes->dm; 6649566063dSJacob Faibussowitsch PetscCall(KSPGetDM(ksp, &snes->dm)); 665dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 6669371c9d4SSatish Balay else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ PetscCall(DMGetNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 667dfe15315SJed Brown X = Xnamed; 6689566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, &ctxsave)); 6694e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 670*48a46eb9SPierre Jolivet if (jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, SNESComputeJacobianDefaultColor, NULL)); 6714e269d77SPeter Brune } 6724dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 6734dde8bb0SMatthew G. Knepley { 6744dde8bb0SMatthew G. Knepley DMSNES sdm; 6754e269d77SPeter Brune 6769566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 677*48a46eb9SPierre Jolivet if (!sdm->ops->computejacobian) PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 6784dde8bb0SMatthew G. Knepley } 6792b93b426SMatthew G. Knepley /* Compute the operators */ 6809566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, A, B)); 6812b93b426SMatthew G. Knepley /* Put the previous context back */ 682*48a46eb9SPierre Jolivet if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, jac, ctxsave)); 6834e269d77SPeter Brune 6849566063dSJacob Faibussowitsch if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 685dfe15315SJed Brown snes->dm = dmsave; 686caa4e7f2SJed Brown PetscFunctionReturn(0); 687caa4e7f2SJed Brown } 688caa4e7f2SJed Brown 6896cab3a1bSJed Brown /*@ 6906cab3a1bSJed Brown SNESSetUpMatrices - ensures that matrices are available for SNES, to be called by SNESSetUp_XXX() 6916cab3a1bSJed Brown 6926cab3a1bSJed Brown Collective 6936cab3a1bSJed Brown 6944165533cSJose E. Roman Input Parameter: 6956cab3a1bSJed Brown . snes - snes to configure 6966cab3a1bSJed Brown 6976cab3a1bSJed Brown Level: developer 6986cab3a1bSJed Brown 699db781477SPatrick Sanan .seealso: `SNESSetUp()` 7006cab3a1bSJed Brown @*/ 7019371c9d4SSatish Balay PetscErrorCode SNESSetUpMatrices(SNES snes) { 7026cab3a1bSJed Brown DM dm; 703942e3340SBarry Smith DMSNES sdm; 7046cab3a1bSJed Brown 7056cab3a1bSJed Brown PetscFunctionBegin; 7069566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 7079566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 70858b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7096cab3a1bSJed Brown Mat J; 7106cab3a1bSJed Brown void *functx; 7119566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7129566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7139566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7149566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 7159566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, NULL, NULL)); 7169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 717caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7186cab3a1bSJed Brown Mat J, B; 7199566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7209566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7219566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7229566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 72306f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7249566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, B, NULL, NULL)); 7259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 727caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7281ba9b98eSMatthew G. Knepley PetscDS prob; 7296cab3a1bSJed Brown Mat J, B; 7301ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7311ba9b98eSMatthew G. Knepley 7326cab3a1bSJed Brown J = snes->jacobian; 7339566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 7349566063dSJacob Faibussowitsch if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 7359566063dSJacob Faibussowitsch if (J) PetscCall(PetscObjectReference((PetscObject)J)); 7369566063dSJacob Faibussowitsch else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 7379566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 7389566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 7399566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7409566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 7416cab3a1bSJed Brown } 742caa4e7f2SJed Brown { 743caa4e7f2SJed Brown KSP ksp; 7449566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 7459566063dSJacob Faibussowitsch PetscCall(KSPSetComputeOperators(ksp, KSPComputeOperators_SNES, snes)); 7469566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 747caa4e7f2SJed Brown } 7486cab3a1bSJed Brown PetscFunctionReturn(0); 7496cab3a1bSJed Brown } 7506cab3a1bSJed Brown 7519371c9d4SSatish Balay static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) { 7525e7c47f3SMatthew G. Knepley PetscInt i; 7535e7c47f3SMatthew G. Knepley 7545e7c47f3SMatthew G. Knepley PetscFunctionBegin; 7555e7c47f3SMatthew G. Knepley if (!snes->pauseFinal) PetscFunctionReturn(0); 7565e7c47f3SMatthew G. Knepley for (i = 0; i < snes->numbermonitors; ++i) { 7575e7c47f3SMatthew G. Knepley PetscViewerAndFormat *vf = (PetscViewerAndFormat *)snes->monitorcontext[i]; 7585e7c47f3SMatthew G. Knepley PetscDraw draw; 7595e7c47f3SMatthew G. Knepley PetscReal lpause; 7605e7c47f3SMatthew G. Knepley 7615e7c47f3SMatthew G. Knepley if (!vf) continue; 7625e7c47f3SMatthew G. Knepley if (vf->lg) { 7635e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 7645e7c47f3SMatthew G. Knepley if (((PetscObject)vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 7659566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 7669566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7679566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7689566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7699566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7705e7c47f3SMatthew G. Knepley } else { 7715e7c47f3SMatthew G. Knepley PetscBool isdraw; 7725e7c47f3SMatthew G. Knepley 7735e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 7745e7c47f3SMatthew G. Knepley if (((PetscObject)vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 7759566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &isdraw)); 7765e7c47f3SMatthew G. Knepley if (!isdraw) continue; 7779566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 7789566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7799566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7809566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7819566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7825e7c47f3SMatthew G. Knepley } 7835e7c47f3SMatthew G. Knepley } 7845e7c47f3SMatthew G. Knepley PetscFunctionReturn(0); 7855e7c47f3SMatthew G. Knepley } 7865e7c47f3SMatthew G. Knepley 787fde5950dSBarry Smith /*@C 788fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 789fde5950dSBarry Smith 790fde5950dSBarry Smith Collective on SNES 791fde5950dSBarry Smith 792fde5950dSBarry Smith Input Parameters: 793fde5950dSBarry Smith + snes - SNES object you wish to monitor 794fde5950dSBarry Smith . name - the monitor type one is seeking 795fde5950dSBarry Smith . help - message indicating what monitoring is done 796fde5950dSBarry Smith . manual - manual page for the monitor 797fde5950dSBarry Smith . monitor - the monitor function 798fde5950dSBarry 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 799fde5950dSBarry Smith 800fde5950dSBarry Smith Level: developer 801fde5950dSBarry Smith 802db781477SPatrick Sanan .seealso: `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 803db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 804db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 805db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 806c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 807db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 808db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 809fde5950dSBarry Smith @*/ 8109371c9d4SSatish Balay PetscErrorCode SNESMonitorSetFromOptions(SNES snes, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNES, PetscInt, PetscReal, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(SNES, PetscViewerAndFormat *)) { 811fde5950dSBarry Smith PetscViewer viewer; 812fde5950dSBarry Smith PetscViewerFormat format; 813fde5950dSBarry Smith PetscBool flg; 814fde5950dSBarry Smith 815fde5950dSBarry Smith PetscFunctionBegin; 8169566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, name, &viewer, &format, &flg)); 817fde5950dSBarry Smith if (flg) { 818d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 8199566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 8209566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 8211baa6e33SBarry Smith if (monitorsetup) PetscCall((*monitorsetup)(snes, vf)); 8229566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 823fde5950dSBarry Smith } 824fde5950dSBarry Smith PetscFunctionReturn(0); 825fde5950dSBarry Smith } 826fde5950dSBarry Smith 8279371c9d4SSatish Balay PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, MPI_Comm comm, const char *prefix) { 8280f0abf79SStefano Zampini PetscFunctionBegin; 8290f0abf79SStefano Zampini PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP"); 8300f0abf79SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", NULL, kctx->version, &kctx->version, NULL)); 8310f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", NULL, kctx->rtol_0, &kctx->rtol_0, NULL)); 8320f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", NULL, kctx->rtol_max, &kctx->rtol_max, NULL)); 8330f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", NULL, kctx->gamma, &kctx->gamma, NULL)); 8340f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", NULL, kctx->alpha, &kctx->alpha, NULL)); 8350f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL)); 8360f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", NULL, kctx->threshold, &kctx->threshold, NULL)); 8370f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL)); 8380f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL)); 8390f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL)); 8400f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL)); 8410f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL)); 8420f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL)); 8430f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL)); 8440f0abf79SStefano Zampini PetscOptionsEnd(); 8450f0abf79SStefano Zampini PetscFunctionReturn(0); 8460f0abf79SStefano Zampini } 8470f0abf79SStefano Zampini 8489b94acceSBarry Smith /*@ 84994b7f48cSBarry Smith SNESSetFromOptions - Sets various SNES and KSP parameters from user options. 8509b94acceSBarry Smith 851c7afd0dbSLois Curfman McInnes Collective on SNES 852c7afd0dbSLois Curfman McInnes 8539b94acceSBarry Smith Input Parameter: 8549b94acceSBarry Smith . snes - the SNES context 8559b94acceSBarry Smith 85636851e7fSLois Curfman McInnes Options Database Keys: 857722329fbSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, SNESType for complete list 85882738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 85982738288SBarry Smith of the change in the solution between steps 86070441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 861b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 862e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 863be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 864b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 865b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8664839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 867ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 868a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8693d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 870e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 8713d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 872b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 873f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 874f362779dSJed Brown default SNESConvergedDefault(). skip SNESConvergedSkip() means continue iterating until max_it or some other criterion is reached, saving expense 875f362779dSJed Brown of convergence test. correct_pressure SNESConvergedCorrectPressure() has special handling of a pressure null space. 876fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 877fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 878fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 879fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 8804619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 881459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 8825e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 883e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 884e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 8855968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 886b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 887e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 888e62ac41dSBarry 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. 889e62ac41dSBarry 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. 89082738288SBarry Smith 89182738288SBarry Smith Options Database for Eisenstat-Walker method: 892fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 8934b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 89436851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 89536851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 89636851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 89736851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 89836851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 89936851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 90082738288SBarry Smith 90111ca99fdSLois Curfman McInnes Notes: 902ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 903ec5066bdSBarry Smith 904ec5066bdSBarry Smith Notes: 905a5b23f4aSJose E. Roman SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 906ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 90783e2fdc7SBarry Smith 90836851e7fSLois Curfman McInnes Level: beginner 90936851e7fSLois Curfman McInnes 910db781477SPatrick Sanan .seealso: `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9119b94acceSBarry Smith @*/ 9129371c9d4SSatish Balay PetscErrorCode SNESSetFromOptions(SNES snes) { 9138afaa268SBarry Smith PetscBool flg, pcset, persist, set; 914d8f46077SPeter Brune PetscInt i, indx, lag, grids; 91504d7464bSBarry Smith const char *deft = SNESNEWTONLS; 916649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 91785385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9180f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 919c40d0f55SPeter Brune PCSide pcside; 920a64e098fSPeter Brune const char *optionsprefix; 9219b94acceSBarry Smith 9223a40ed3dSBarry Smith PetscFunctionBegin; 9230700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9249566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 925d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 926639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9279566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 928d64ed03dSBarry Smith if (flg) { 9299566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9307adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9319566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 932d64ed03dSBarry Smith } 9339566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9349566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 935186905e3SBarry Smith 9369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9379566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9389566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9399566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9409566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9419566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9429566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9439566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9449566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 94585385478SLisandro Dalcin 9469566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 947a8054027SBarry Smith if (flg) { 9485f80ce2aSJacob 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"); 9499566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 950a8054027SBarry Smith } 9519566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9521baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9539566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 954e35cf81dSBarry Smith if (flg) { 9555f80ce2aSJacob 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"); 9569566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 957e35cf81dSBarry Smith } 9589566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9591baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 96037ec4e1aSPeter Brune 9619566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9621baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 963a8054027SBarry Smith 9649566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg)); 96585385478SLisandro Dalcin if (flg) { 96685385478SLisandro Dalcin switch (indx) { 9679566063dSJacob Faibussowitsch case 0: PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); break; 9689566063dSJacob Faibussowitsch case 1: PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); break; 9699566063dSJacob Faibussowitsch case 2: PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); break; 97085385478SLisandro Dalcin } 97185385478SLisandro Dalcin } 97285385478SLisandro Dalcin 9739566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 9749566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 975fdacfa88SPeter Brune 9769566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 9779566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 978186905e3SBarry Smith 97985385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 98085385478SLisandro Dalcin 9819566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 982186905e3SBarry Smith 9830f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 9840f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 9850f0abf79SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)snes), ewprefix)); 9860f0abf79SStefano Zampini 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_ksp_ew_version", "Version 1, 2 or 3", "SNESKSPSetParametersEW", kctx->version, &kctx->version, NULL)); 9889566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0", "0 <= rtol0 < 1", "SNESKSPSetParametersEW", kctx->rtol_0, &kctx->rtol_0, NULL)); 9899566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax", "0 <= rtolmax < 1", "SNESKSPSetParametersEW", kctx->rtol_max, &kctx->rtol_max, NULL)); 9909566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma", "0 <= gamma <= 1", "SNESKSPSetParametersEW", kctx->gamma, &kctx->gamma, NULL)); 9919566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha", "1 < alpha <= 2", "SNESKSPSetParametersEW", kctx->alpha, &kctx->alpha, NULL)); 9929566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2", "alpha2", "SNESKSPSetParametersEW", kctx->alpha2, &kctx->alpha2, NULL)); 9939566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold", "0 < threshold < 1", "SNESKSPSetParametersEW", kctx->threshold, &kctx->threshold, NULL)); 994186905e3SBarry Smith 99590d69ab7SBarry Smith flg = PETSC_FALSE; 9969566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 9979566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 998eabae89aSBarry Smith 9999566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 10009566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10019566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1002eabae89aSBarry Smith 10039566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10049566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10059566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10069566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10079566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10089566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10099566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10109566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10112db13446SMatthew G. Knepley 10129566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10139566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10145180491cSLisandro Dalcin 101590d69ab7SBarry Smith flg = PETSC_FALSE; 10169566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1017459f5d12SBarry Smith if (flg) { 1018459f5d12SBarry Smith PetscViewer ctx; 1019e24b481bSBarry Smith 10209566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10219566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1022459f5d12SBarry Smith } 10232e7541e6SPeter Brune 102490d69ab7SBarry Smith flg = PETSC_FALSE; 10259566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10269566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1027c4421ceaSFande Kong 1028c4421ceaSFande Kong flg = PETSC_FALSE; 10299566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10304b27c08aSLois Curfman McInnes if (flg) { 10316cab3a1bSJed Brown void *functx; 1032b1f624c7SBarry Smith DM dm; 10339566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1034800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10359566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10369566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10379566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10389b94acceSBarry Smith } 1039639f9d9dSBarry Smith 104044848bc4SPeter Brune flg = PETSC_FALSE; 10419566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10421baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 104397584545SPeter Brune 104497584545SPeter Brune flg = PETSC_FALSE; 10459566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 104644848bc4SPeter Brune if (flg) { 1047c52e227fSPeter Brune DM dm; 10489566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1049800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10509566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10519566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 105244848bc4SPeter Brune } 105344848bc4SPeter Brune 1054aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10559566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1056d8f46077SPeter Brune if (flg && snes->mf_operator) { 1057a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1058d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1059a8248277SBarry Smith } 1060aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10619566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1062d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10639566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1064d28543b3SPeter Brune 1065c40d0f55SPeter Brune flg = PETSC_FALSE; 10669566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 10679566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 10689566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1069c40d0f55SPeter Brune 1070e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 10718a70d858SHong Zhang /* 10728a70d858SHong Zhang Publish convergence information using SAWs 10738a70d858SHong Zhang */ 10748a70d858SHong Zhang flg = PETSC_FALSE; 10759566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 10768a70d858SHong Zhang if (flg) { 10778a70d858SHong Zhang void *ctx; 10789566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 10799566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 10808a70d858SHong Zhang } 10818a70d858SHong Zhang #endif 10828a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1083b90c6cbeSBarry Smith { 1084b90c6cbeSBarry Smith PetscBool set; 1085b90c6cbeSBarry Smith flg = PETSC_FALSE; 10869566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 10871baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1088b90c6cbeSBarry Smith } 1089b90c6cbeSBarry Smith #endif 1090b90c6cbeSBarry Smith 1091*48a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 109276b2cf59SMatthew Knepley 1093dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 10945d973c19SBarry Smith 10955d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1096dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1097d0609cedSBarry Smith PetscOptionsEnd(); 10984bbc92c1SBarry Smith 1099d8d34be6SBarry Smith if (snes->linesearch) { 11009566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11019566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1102d8d34be6SBarry Smith } 11039e764e56SPeter Brune 11046aa5e7e9SBarry Smith if (snes->usesksp) { 11059566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11069566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11079566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11086aa5e7e9SBarry Smith } 11096991f827SBarry Smith 1110b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11119566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11129566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 1113*48a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11141baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1115b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 1116b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 1117b3cd9a81SMatthew G. Knepley } 1118b3cd9a81SMatthew G. Knepley 1119b3cd9a81SMatthew G. Knepley /*@ 1120b3cd9a81SMatthew G. Knepley SNESResetFromOptions - Sets various SNES and KSP parameters from user options ONLY if the SNES was previously set from options 1121b3cd9a81SMatthew G. Knepley 1122b3cd9a81SMatthew G. Knepley Collective on SNES 1123b3cd9a81SMatthew G. Knepley 1124b3cd9a81SMatthew G. Knepley Input Parameter: 1125b3cd9a81SMatthew G. Knepley . snes - the SNES context 1126b3cd9a81SMatthew G. Knepley 1127b3cd9a81SMatthew G. Knepley Level: beginner 1128b3cd9a81SMatthew G. Knepley 1129db781477SPatrick Sanan .seealso: `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1130b3cd9a81SMatthew G. Knepley @*/ 11319371c9d4SSatish Balay PetscErrorCode SNESResetFromOptions(SNES snes) { 1132b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11339566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11343a40ed3dSBarry Smith PetscFunctionReturn(0); 11359b94acceSBarry Smith } 11369b94acceSBarry Smith 1137bb9467b5SJed Brown /*@C 1138d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1139d25893d9SBarry Smith the nonlinear solvers. 1140d25893d9SBarry Smith 1141d25893d9SBarry Smith Logically Collective on SNES 1142d25893d9SBarry Smith 1143d25893d9SBarry Smith Input Parameters: 1144d25893d9SBarry Smith + snes - the SNES context 1145d25893d9SBarry Smith . compute - function to compute the context 1146d25893d9SBarry Smith - destroy - function to destroy the context 1147d25893d9SBarry Smith 1148d25893d9SBarry Smith Level: intermediate 1149d25893d9SBarry Smith 1150bb9467b5SJed Brown Notes: 1151bb9467b5SJed Brown This function is currently not available from Fortran. 1152bb9467b5SJed Brown 1153db781477SPatrick Sanan .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 1154d25893d9SBarry Smith @*/ 11559371c9d4SSatish Balay PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) { 1156d25893d9SBarry Smith PetscFunctionBegin; 1157d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1158d25893d9SBarry Smith snes->ops->usercompute = compute; 1159d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1160d25893d9SBarry Smith PetscFunctionReturn(0); 1161d25893d9SBarry Smith } 1162a847f771SSatish Balay 1163b07ff414SBarry Smith /*@ 11649b94acceSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for 11659b94acceSBarry Smith the nonlinear solvers. 11669b94acceSBarry Smith 11673f9fe445SBarry Smith Logically Collective on SNES 1168fee21e36SBarry Smith 1169c7afd0dbSLois Curfman McInnes Input Parameters: 1170c7afd0dbSLois Curfman McInnes + snes - the SNES context 1171c7afd0dbSLois Curfman McInnes - usrP - optional user context 1172c7afd0dbSLois Curfman McInnes 117336851e7fSLois Curfman McInnes Level: intermediate 117436851e7fSLois Curfman McInnes 117595452b02SPatrick Sanan Fortran Notes: 117695452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1177daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1178daf670e6SBarry Smith 1179db781477SPatrick Sanan .seealso: `SNESGetApplicationContext()` 11809b94acceSBarry Smith @*/ 11819371c9d4SSatish Balay PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) { 1182b07ff414SBarry Smith KSP ksp; 11831b2093e4SBarry Smith 11843a40ed3dSBarry Smith PetscFunctionBegin; 11850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 11869566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 11879566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 11889b94acceSBarry Smith snes->user = usrP; 11893a40ed3dSBarry Smith PetscFunctionReturn(0); 11909b94acceSBarry Smith } 119174679c65SBarry Smith 1192b07ff414SBarry Smith /*@ 11939b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 11949b94acceSBarry Smith nonlinear solvers. 11959b94acceSBarry Smith 1196c7afd0dbSLois Curfman McInnes Not Collective 1197c7afd0dbSLois Curfman McInnes 11989b94acceSBarry Smith Input Parameter: 11999b94acceSBarry Smith . snes - SNES context 12009b94acceSBarry Smith 12019b94acceSBarry Smith Output Parameter: 12029b94acceSBarry Smith . usrP - user context 12039b94acceSBarry Smith 120495452b02SPatrick Sanan Fortran Notes: 120595452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1206daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1207daf670e6SBarry Smith 120836851e7fSLois Curfman McInnes Level: intermediate 120936851e7fSLois Curfman McInnes 1210db781477SPatrick Sanan .seealso: `SNESSetApplicationContext()` 12119b94acceSBarry Smith @*/ 12129371c9d4SSatish Balay PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) { 12133a40ed3dSBarry Smith PetscFunctionBegin; 12140700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1215e71120c6SJed Brown *(void **)usrP = snes->user; 12163a40ed3dSBarry Smith PetscFunctionReturn(0); 12179b94acceSBarry Smith } 121874679c65SBarry Smith 12199b94acceSBarry Smith /*@ 1220ec5066bdSBarry Smith SNESSetUseMatrixFree - indicates that SNES should use matrix free finite difference matrix vector products internally to apply the Jacobian. 12213565c898SBarry Smith 12223565c898SBarry Smith Collective on SNES 12233565c898SBarry Smith 12243565c898SBarry Smith Input Parameters: 12253565c898SBarry Smith + snes - SNES context 12264ddffce6SLisandro Dalcin . mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12274ddffce6SLisandro 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 12283565c898SBarry Smith 12293565c898SBarry Smith Options Database: 12303565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 1231ec5066bdSBarry Smith . -snes_mf_operator - use matrix free only for the mat operator 1232ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1233ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12343565c898SBarry Smith 12353565c898SBarry Smith Level: intermediate 12363565c898SBarry Smith 1237ec5066bdSBarry Smith Notes: 1238a5b23f4aSJose E. Roman SNES supports three approaches for computing (approximate) Jacobians: user provided via SNESSetJacobian(), matrix free, and computing explicitly with 1239ec5066bdSBarry Smith finite differences and coloring using MatFDColoring. It is also possible to use automatic differentiation and the MatFDColoring object. 1240ec5066bdSBarry Smith 1241db781477SPatrick Sanan .seealso: `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12423565c898SBarry Smith @*/ 12439371c9d4SSatish Balay PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) { 12443565c898SBarry Smith PetscFunctionBegin; 12453565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 124688b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 124788b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12484ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12493565c898SBarry Smith snes->mf_operator = mf_operator; 12503565c898SBarry Smith PetscFunctionReturn(0); 12513565c898SBarry Smith } 12523565c898SBarry Smith 12533565c898SBarry Smith /*@ 1254ec5066bdSBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix free finite difference matrix vector products to apply the Jacobian. 12553565c898SBarry Smith 12563565c898SBarry Smith Collective on SNES 12573565c898SBarry Smith 12583565c898SBarry Smith Input Parameter: 12593565c898SBarry Smith . snes - SNES context 12603565c898SBarry Smith 12613565c898SBarry Smith Output Parameters: 12624ddffce6SLisandro Dalcin + mf_operator - use matrix-free only for the Amat used by SNESSetJacobian(), this means the user provided Pmat will continue to be used 12634ddffce6SLisandro 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 12643565c898SBarry Smith 12653565c898SBarry Smith Options Database: 12663565c898SBarry Smith + -snes_mf - use matrix free for both the mat and pmat operator 12673565c898SBarry Smith - -snes_mf_operator - use matrix free only for the mat operator 12683565c898SBarry Smith 12693565c898SBarry Smith Level: intermediate 12703565c898SBarry Smith 1271db781477SPatrick Sanan .seealso: `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 12723565c898SBarry Smith @*/ 12739371c9d4SSatish Balay PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) { 12743565c898SBarry Smith PetscFunctionBegin; 12753565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12763565c898SBarry Smith if (mf) *mf = snes->mf; 12773565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 12783565c898SBarry Smith PetscFunctionReturn(0); 12793565c898SBarry Smith } 12803565c898SBarry Smith 12813565c898SBarry Smith /*@ 1282c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1283c8228a4eSBarry Smith at this time. 12849b94acceSBarry Smith 1285c7afd0dbSLois Curfman McInnes Not Collective 1286c7afd0dbSLois Curfman McInnes 12879b94acceSBarry Smith Input Parameter: 12889b94acceSBarry Smith . snes - SNES context 12899b94acceSBarry Smith 12909b94acceSBarry Smith Output Parameter: 12919b94acceSBarry Smith . iter - iteration number 12929b94acceSBarry Smith 1293c8228a4eSBarry Smith Notes: 1294c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1295c8228a4eSBarry Smith 1296c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 129708405cd6SLois Curfman McInnes Jacobian at each SNES iteration). For example, the code 129808405cd6SLois Curfman McInnes .vb 129908405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 130008405cd6SLois Curfman McInnes if (!(it % 2)) { 130108405cd6SLois Curfman McInnes [compute Jacobian here] 130208405cd6SLois Curfman McInnes } 130308405cd6SLois Curfman McInnes .ve 1304c8228a4eSBarry Smith can be used in your ComputeJacobian() function to cause the Jacobian to be 130508405cd6SLois Curfman McInnes recomputed every second SNES iteration. 1306c8228a4eSBarry Smith 1307c04deec6SBarry Smith After the SNES solve is complete this will return the number of nonlinear iterations used. 1308c04deec6SBarry Smith 130936851e7fSLois Curfman McInnes Level: intermediate 131036851e7fSLois Curfman McInnes 1311db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()` 13129b94acceSBarry Smith @*/ 13139371c9d4SSatish Balay PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) { 13143a40ed3dSBarry Smith PetscFunctionBegin; 13150700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13164482741eSBarry Smith PetscValidIntPointer(iter, 2); 13179b94acceSBarry Smith *iter = snes->iter; 13183a40ed3dSBarry Smith PetscFunctionReturn(0); 13199b94acceSBarry Smith } 132074679c65SBarry Smith 1321360c497dSPeter Brune /*@ 1322360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1323360c497dSPeter Brune 1324360c497dSPeter Brune Not Collective 1325360c497dSPeter Brune 1326d8d19677SJose E. Roman Input Parameters: 1327a2b725a8SWilliam Gropp + snes - SNES context 1328a2b725a8SWilliam Gropp - iter - iteration number 1329360c497dSPeter Brune 1330360c497dSPeter Brune Level: developer 1331360c497dSPeter Brune 1332db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()` 1333360c497dSPeter Brune @*/ 13349371c9d4SSatish Balay PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) { 1335360c497dSPeter Brune PetscFunctionBegin; 1336360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13379566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1338360c497dSPeter Brune snes->iter = iter; 13399566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 1340360c497dSPeter Brune PetscFunctionReturn(0); 1341360c497dSPeter Brune } 1342360c497dSPeter Brune 13439b94acceSBarry Smith /*@ 1344b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13459b94acceSBarry Smith attempted by the nonlinear solver. 13469b94acceSBarry Smith 1347c7afd0dbSLois Curfman McInnes Not Collective 1348c7afd0dbSLois Curfman McInnes 13499b94acceSBarry Smith Input Parameter: 13509b94acceSBarry Smith . snes - SNES context 13519b94acceSBarry Smith 13529b94acceSBarry Smith Output Parameter: 13539b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13549b94acceSBarry Smith 1355c96a6f78SLois Curfman McInnes Notes: 1356c96a6f78SLois Curfman McInnes This counter is reset to zero for each successive call to SNESSolve(). 1357c96a6f78SLois Curfman McInnes 135836851e7fSLois Curfman McInnes Level: intermediate 135936851e7fSLois Curfman McInnes 1360db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1361db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 13629b94acceSBarry Smith @*/ 13639371c9d4SSatish Balay PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) { 13643a40ed3dSBarry Smith PetscFunctionBegin; 13650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13664482741eSBarry Smith PetscValidIntPointer(nfails, 2); 136750ffb88aSMatthew Knepley *nfails = snes->numFailures; 136850ffb88aSMatthew Knepley PetscFunctionReturn(0); 136950ffb88aSMatthew Knepley } 137050ffb88aSMatthew Knepley 137150ffb88aSMatthew Knepley /*@ 1372b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 137350ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 137450ffb88aSMatthew Knepley 137550ffb88aSMatthew Knepley Not Collective 137650ffb88aSMatthew Knepley 137750ffb88aSMatthew Knepley Input Parameters: 137850ffb88aSMatthew Knepley + snes - SNES context 137950ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 138050ffb88aSMatthew Knepley 138150ffb88aSMatthew Knepley Level: intermediate 138250ffb88aSMatthew Knepley 1383db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1384db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 138550ffb88aSMatthew Knepley @*/ 13869371c9d4SSatish Balay PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) { 138750ffb88aSMatthew Knepley PetscFunctionBegin; 13880700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 138950ffb88aSMatthew Knepley snes->maxFailures = maxFails; 139050ffb88aSMatthew Knepley PetscFunctionReturn(0); 139150ffb88aSMatthew Knepley } 139250ffb88aSMatthew Knepley 139350ffb88aSMatthew Knepley /*@ 1394b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 139550ffb88aSMatthew Knepley attempted by the nonlinear solver before it gives up. 139650ffb88aSMatthew Knepley 139750ffb88aSMatthew Knepley Not Collective 139850ffb88aSMatthew Knepley 139950ffb88aSMatthew Knepley Input Parameter: 140050ffb88aSMatthew Knepley . snes - SNES context 140150ffb88aSMatthew Knepley 140250ffb88aSMatthew Knepley Output Parameter: 140350ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 140450ffb88aSMatthew Knepley 140550ffb88aSMatthew Knepley Level: intermediate 140650ffb88aSMatthew Knepley 1407db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1408db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 140958ebbce7SBarry Smith 141050ffb88aSMatthew Knepley @*/ 14119371c9d4SSatish Balay PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) { 141250ffb88aSMatthew Knepley PetscFunctionBegin; 14130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14144482741eSBarry Smith PetscValidIntPointer(maxFails, 2); 141550ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14163a40ed3dSBarry Smith PetscFunctionReturn(0); 14179b94acceSBarry Smith } 1418a847f771SSatish Balay 14192541af92SBarry Smith /*@ 14202541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 14212541af92SBarry Smith done by SNES. 14222541af92SBarry Smith 14232541af92SBarry Smith Not Collective 14242541af92SBarry Smith 14252541af92SBarry Smith Input Parameter: 14262541af92SBarry Smith . snes - SNES context 14272541af92SBarry Smith 14282541af92SBarry Smith Output Parameter: 14292541af92SBarry Smith . nfuncs - number of evaluations 14302541af92SBarry Smith 14312541af92SBarry Smith Level: intermediate 14322541af92SBarry Smith 143395452b02SPatrick Sanan Notes: 143495452b02SPatrick Sanan Reset every time SNESSolve is called unless SNESSetCountersReset() is used. 1435971e163fSPeter Brune 1436db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14372541af92SBarry Smith @*/ 14389371c9d4SSatish Balay PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) { 14392541af92SBarry Smith PetscFunctionBegin; 14400700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14412541af92SBarry Smith PetscValidIntPointer(nfuncs, 2); 14422541af92SBarry Smith *nfuncs = snes->nfuncs; 14432541af92SBarry Smith PetscFunctionReturn(0); 14442541af92SBarry Smith } 14452541af92SBarry Smith 14463d4c4710SBarry Smith /*@ 14473d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14483d4c4710SBarry Smith linear solvers. 14493d4c4710SBarry Smith 14503d4c4710SBarry Smith Not Collective 14513d4c4710SBarry Smith 14523d4c4710SBarry Smith Input Parameter: 14533d4c4710SBarry Smith . snes - SNES context 14543d4c4710SBarry Smith 14553d4c4710SBarry Smith Output Parameter: 14563d4c4710SBarry Smith . nfails - number of failed solves 14573d4c4710SBarry Smith 14589d85da0cSMatthew G. Knepley Level: intermediate 14599d85da0cSMatthew G. Knepley 14609d85da0cSMatthew G. Knepley Options Database Keys: 14619d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14629d85da0cSMatthew G. Knepley 14633d4c4710SBarry Smith Notes: 14643d4c4710SBarry Smith This counter is reset to zero for each successive call to SNESSolve(). 14653d4c4710SBarry Smith 1466db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 14673d4c4710SBarry Smith @*/ 14689371c9d4SSatish Balay PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) { 14693d4c4710SBarry Smith PetscFunctionBegin; 14700700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14713d4c4710SBarry Smith PetscValidIntPointer(nfails, 2); 14723d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 14733d4c4710SBarry Smith PetscFunctionReturn(0); 14743d4c4710SBarry Smith } 14753d4c4710SBarry Smith 14763d4c4710SBarry Smith /*@ 14773d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 14783d4c4710SBarry Smith allowed before SNES returns with a diverged reason of SNES_DIVERGED_LINEAR_SOLVE 14793d4c4710SBarry Smith 14803f9fe445SBarry Smith Logically Collective on SNES 14813d4c4710SBarry Smith 14823d4c4710SBarry Smith Input Parameters: 14833d4c4710SBarry Smith + snes - SNES context 14843d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 14853d4c4710SBarry Smith 14863d4c4710SBarry Smith Level: intermediate 14873d4c4710SBarry Smith 14889d85da0cSMatthew G. Knepley Options Database Keys: 14899d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14909d85da0cSMatthew G. Knepley 149195452b02SPatrick Sanan Notes: 149295452b02SPatrick Sanan By default this is 0; that is SNES returns on the first failed linear solve 14933d4c4710SBarry Smith 1494db781477SPatrick Sanan .seealso: `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 14953d4c4710SBarry Smith @*/ 14969371c9d4SSatish Balay PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) { 14973d4c4710SBarry Smith PetscFunctionBegin; 14980700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1499c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15003d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15013d4c4710SBarry Smith PetscFunctionReturn(0); 15023d4c4710SBarry Smith } 15033d4c4710SBarry Smith 15043d4c4710SBarry Smith /*@ 15053d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 15063d4c4710SBarry Smith are allowed before SNES terminates 15073d4c4710SBarry Smith 15083d4c4710SBarry Smith Not Collective 15093d4c4710SBarry Smith 15103d4c4710SBarry Smith Input Parameter: 15113d4c4710SBarry Smith . snes - SNES context 15123d4c4710SBarry Smith 15133d4c4710SBarry Smith Output Parameter: 15143d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15153d4c4710SBarry Smith 15163d4c4710SBarry Smith Level: intermediate 15173d4c4710SBarry Smith 151895452b02SPatrick Sanan Notes: 151995452b02SPatrick Sanan By default this is 1; that is SNES returns on the first failed linear solve 15203d4c4710SBarry Smith 1521db781477SPatrick Sanan .seealso: `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15223d4c4710SBarry Smith @*/ 15239371c9d4SSatish Balay PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) { 15243d4c4710SBarry Smith PetscFunctionBegin; 15250700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15263d4c4710SBarry Smith PetscValidIntPointer(maxFails, 2); 15273d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15283d4c4710SBarry Smith PetscFunctionReturn(0); 15293d4c4710SBarry Smith } 15303d4c4710SBarry Smith 1531c96a6f78SLois Curfman McInnes /*@ 1532b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1533c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1534c96a6f78SLois Curfman McInnes 1535c7afd0dbSLois Curfman McInnes Not Collective 1536c7afd0dbSLois Curfman McInnes 1537c96a6f78SLois Curfman McInnes Input Parameter: 1538c96a6f78SLois Curfman McInnes . snes - SNES context 1539c96a6f78SLois Curfman McInnes 1540c96a6f78SLois Curfman McInnes Output Parameter: 1541c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1542c96a6f78SLois Curfman McInnes 1543c96a6f78SLois Curfman McInnes Notes: 1544971e163fSPeter Brune This counter is reset to zero for each successive call to SNESSolve() unless SNESSetCountersReset() is used. 1545c96a6f78SLois Curfman McInnes 1546010be392SBarry 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 1547010be392SBarry Smith then call KSPGetIterationNumber() after the failed solve. 1548010be392SBarry Smith 154936851e7fSLois Curfman McInnes Level: intermediate 155036851e7fSLois Curfman McInnes 1551db781477SPatrick Sanan .seealso: `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1552c96a6f78SLois Curfman McInnes @*/ 15539371c9d4SSatish Balay PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) { 15543a40ed3dSBarry Smith PetscFunctionBegin; 15550700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15564482741eSBarry Smith PetscValidIntPointer(lits, 2); 1557c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 15583a40ed3dSBarry Smith PetscFunctionReturn(0); 1559c96a6f78SLois Curfman McInnes } 1560c96a6f78SLois Curfman McInnes 1561971e163fSPeter Brune /*@ 1562971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1563971e163fSPeter Brune are reset every time SNESSolve() is called. 1564971e163fSPeter Brune 1565971e163fSPeter Brune Logically Collective on SNES 1566971e163fSPeter Brune 1567d8d19677SJose E. Roman Input Parameters: 1568971e163fSPeter Brune + snes - SNES context 1569971e163fSPeter Brune - reset - whether to reset the counters or not 1570971e163fSPeter Brune 1571971e163fSPeter Brune Notes: 1572fa19ca70SBarry Smith This defaults to PETSC_TRUE 1573971e163fSPeter Brune 1574971e163fSPeter Brune Level: developer 1575971e163fSPeter Brune 1576db781477SPatrick Sanan .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1577971e163fSPeter Brune @*/ 15789371c9d4SSatish Balay PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) { 1579971e163fSPeter Brune PetscFunctionBegin; 1580971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1581971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1582971e163fSPeter Brune snes->counters_reset = reset; 1583971e163fSPeter Brune PetscFunctionReturn(0); 1584971e163fSPeter Brune } 1585971e163fSPeter Brune 15862999313aSBarry Smith /*@ 15872999313aSBarry Smith SNESSetKSP - Sets a KSP context for the SNES object to use 15882999313aSBarry Smith 15892999313aSBarry Smith Not Collective, but the SNES and KSP objects must live on the same MPI_Comm 15902999313aSBarry Smith 15912999313aSBarry Smith Input Parameters: 15922999313aSBarry Smith + snes - the SNES context 15932999313aSBarry Smith - ksp - the KSP context 15942999313aSBarry Smith 15952999313aSBarry Smith Notes: 15962999313aSBarry Smith The SNES object already has its KSP object, you can obtain with SNESGetKSP() 15972999313aSBarry Smith so this routine is rarely needed. 15982999313aSBarry Smith 15992999313aSBarry Smith The KSP object that is already in the SNES object has its reference count 16002999313aSBarry Smith decreased by one. 16012999313aSBarry Smith 16022999313aSBarry Smith Level: developer 16032999313aSBarry Smith 1604db781477SPatrick Sanan .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16052999313aSBarry Smith @*/ 16069371c9d4SSatish Balay PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) { 16072999313aSBarry Smith PetscFunctionBegin; 16080700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16090700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16102999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16119566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16129566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16132999313aSBarry Smith snes->ksp = ksp; 16142999313aSBarry Smith PetscFunctionReturn(0); 16152999313aSBarry Smith } 16162999313aSBarry Smith 16179b94acceSBarry Smith /* -----------------------------------------------------------*/ 161852baeb72SSatish Balay /*@ 16199b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 16209b94acceSBarry Smith 1621d083f849SBarry Smith Collective 1622c7afd0dbSLois Curfman McInnes 1623c7afd0dbSLois Curfman McInnes Input Parameters: 1624906ed7ccSBarry Smith . comm - MPI communicator 16259b94acceSBarry Smith 16269b94acceSBarry Smith Output Parameter: 16279b94acceSBarry Smith . outsnes - the new SNES context 16289b94acceSBarry Smith 1629c7afd0dbSLois Curfman McInnes Options Database Keys: 1630c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1631c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1632c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1633c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1634c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1635c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1636c1f60f51SBarry Smith 163736851e7fSLois Curfman McInnes Level: beginner 163836851e7fSLois Curfman McInnes 163995452b02SPatrick Sanan Developer Notes: 164095452b02SPatrick Sanan SNES always creates a KSP object even though many SNES methods do not use it. This is 1641efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1642efd4aadfSBarry Smith particular method does use KSP and regulates if the information about the KSP is printed 1643efd4aadfSBarry Smith in SNESView(). TSSetFromOptions() does call SNESSetFromOptions() which can lead to users being confused 1644efd4aadfSBarry Smith by help messages about meaningless SNES options. 1645efd4aadfSBarry Smith 1646efd4aadfSBarry Smith SNES always creates the snes->kspconvctx even though it is used by only one type. This should 1647efd4aadfSBarry Smith be fixed. 1648efd4aadfSBarry Smith 1649db781477SPatrick Sanan .seealso: `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 1650a8054027SBarry Smith 16519b94acceSBarry Smith @*/ 16529371c9d4SSatish Balay PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) { 16539b94acceSBarry Smith SNES snes; 1654fa9f3622SBarry Smith SNESKSPEW *kctx; 165537fcc0dbSBarry Smith 16563a40ed3dSBarry Smith PetscFunctionBegin; 1657ed1caa07SMatthew Knepley PetscValidPointer(outsnes, 2); 16580298fd71SBarry Smith *outsnes = NULL; 16599566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 16608ba1e511SMatthew Knepley 16619566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 16627adad957SLisandro Dalcin 16638d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 16642c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 166588976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 16669b94acceSBarry Smith snes->max_its = 50; 16679750a799SBarry Smith snes->max_funcs = 10000; 16689b94acceSBarry Smith snes->norm = 0.0; 1669c1e67a49SFande Kong snes->xnorm = 0.0; 1670c1e67a49SFande Kong snes->ynorm = 0.0; 1671365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 16726c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 16733a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16743a2046daSBarry Smith snes->rtol = 1.e-5; 16753a2046daSBarry Smith #else 1676b4874afaSBarry Smith snes->rtol = 1.e-8; 16773a2046daSBarry Smith #endif 1678b4874afaSBarry Smith snes->ttol = 0.0; 16793a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16803a2046daSBarry Smith snes->abstol = 1.e-25; 16813a2046daSBarry Smith #else 168270441072SBarry Smith snes->abstol = 1.e-50; 16833a2046daSBarry Smith #endif 16847cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 16857cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 16867cd0ae37SLisandro Dalcin #else 1687c60f73f4SPeter Brune snes->stol = 1.e-8; 16887cd0ae37SLisandro Dalcin #endif 16893a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16903a2046daSBarry Smith snes->deltatol = 1.e-6; 16913a2046daSBarry Smith #else 16924b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 16933a2046daSBarry Smith #endif 1694e37c518bSBarry Smith snes->divtol = 1.e4; 1695e37c518bSBarry Smith snes->rnorm0 = 0; 16969b94acceSBarry Smith snes->nfuncs = 0; 169750ffb88aSMatthew Knepley snes->numFailures = 0; 169850ffb88aSMatthew Knepley snes->maxFailures = 1; 16997a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1700e35cf81dSBarry Smith snes->lagjacobian = 1; 170137ec4e1aSPeter Brune snes->jac_iter = 0; 170237ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1703a8054027SBarry Smith snes->lagpreconditioner = 1; 170437ec4e1aSPeter Brune snes->pre_iter = 0; 170537ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1706639f9d9dSBarry Smith snes->numbermonitors = 0; 1707c4421ceaSFande Kong snes->numberreasonviews = 0; 17089e5d0892SLisandro Dalcin snes->data = NULL; 17094dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1710186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17116f24a144SLois Curfman McInnes snes->nwork = 0; 17129e5d0892SLisandro Dalcin snes->work = NULL; 171358c9b817SLisandro Dalcin snes->nvwork = 0; 17149e5d0892SLisandro Dalcin snes->vwork = NULL; 1715758f92a0SBarry Smith snes->conv_hist_len = 0; 1716758f92a0SBarry Smith snes->conv_hist_max = 0; 17170298fd71SBarry Smith snes->conv_hist = NULL; 17180298fd71SBarry Smith snes->conv_hist_its = NULL; 1719758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1720971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1721e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1722184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1723efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1724b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1725c40d0f55SPeter Brune 1726d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1727d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1728d8f46077SPeter Brune snes->mf_version = 1; 1729d8f46077SPeter Brune 17303d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17313d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17323d4c4710SBarry Smith 1733349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 173476bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1735349187a7SBarry Smith 17364fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17374fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17384fc747eaSLawrence Mitchell 17399b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17409566063dSJacob Faibussowitsch PetscCall(PetscNewLog(snes, &kctx)); 1741f5af7f23SKarl Rupp 17429b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17439b94acceSBarry Smith kctx->version = 2; 17440f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17459b94acceSBarry Smith this was too large for some test cases */ 174675567043SBarry Smith kctx->rtol_last = 0.0; 17470f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17489b94acceSBarry Smith kctx->gamma = 1.0; 17490f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 175071f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17510f0abf79SStefano Zampini kctx->threshold = 0.1; 175275567043SBarry Smith kctx->lresid_last = 0.0; 175375567043SBarry Smith kctx->norm_last = 0.0; 17549b94acceSBarry Smith 17550f0abf79SStefano Zampini kctx->rk_last = 0.0; 17560f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 17570f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 17580f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 17590f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 17600f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 17610f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 17620f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 17630f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 17640f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 17650f0abf79SStefano Zampini 17669b94acceSBarry Smith *outsnes = snes; 17673a40ed3dSBarry Smith PetscFunctionReturn(0); 17689b94acceSBarry Smith } 17699b94acceSBarry Smith 177088f0584fSBarry Smith /*MC 1771411c0326SBarry Smith SNESFunction - Functional form used to convey the nonlinear function to be solved by SNES 177288f0584fSBarry Smith 177388f0584fSBarry Smith Synopsis: 1774411c0326SBarry Smith #include "petscsnes.h" 1775411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 177688f0584fSBarry Smith 17771843f636SBarry Smith Collective on snes 17781843f636SBarry Smith 177988f0584fSBarry Smith Input Parameters: 178088f0584fSBarry Smith + snes - the SNES context 178188f0584fSBarry Smith . x - state at which to evaluate residual 178288f0584fSBarry Smith - ctx - optional user-defined function context, passed in with SNESSetFunction() 178388f0584fSBarry Smith 178488f0584fSBarry Smith Output Parameter: 178588f0584fSBarry Smith . f - vector to put residual (function value) 178688f0584fSBarry Smith 1787878cb397SSatish Balay Level: intermediate 1788878cb397SSatish Balay 1789db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()` 179088f0584fSBarry Smith M*/ 179188f0584fSBarry Smith 17929b94acceSBarry Smith /*@C 17939b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 17949b94acceSBarry Smith vector for use by the SNES routines in solving systems of nonlinear 17959b94acceSBarry Smith equations. 17969b94acceSBarry Smith 17973f9fe445SBarry Smith Logically Collective on SNES 1798fee21e36SBarry Smith 1799c7afd0dbSLois Curfman McInnes Input Parameters: 1800c7afd0dbSLois Curfman McInnes + snes - the SNES context 18016b7fb656SBarry Smith . r - vector to store function values, may be NULL 1802f8b49ee9SBarry Smith . f - function evaluation routine; see SNESFunction for calling sequence details 1803c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18040298fd71SBarry Smith function evaluation routine (may be NULL) 18059b94acceSBarry Smith 18069b94acceSBarry Smith Notes: 18079b94acceSBarry Smith The Newton-like methods typically solve linear systems of the form 18089b94acceSBarry Smith $ f'(x) x = -f(x), 1809c7afd0dbSLois Curfman McInnes where f'(x) denotes the Jacobian matrix and f(x) is the function. 18109b94acceSBarry Smith 181136851e7fSLois Curfman McInnes Level: beginner 181236851e7fSLois Curfman McInnes 1813db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18149b94acceSBarry Smith @*/ 18159371c9d4SSatish Balay PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) { 18166cab3a1bSJed Brown DM dm; 18176cab3a1bSJed Brown 18183a40ed3dSBarry Smith PetscFunctionBegin; 18190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1820d2a683ecSLisandro Dalcin if (r) { 1821d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1822d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18239566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18249566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 182585385478SLisandro Dalcin snes->vec_func = r; 1826d2a683ecSLisandro Dalcin } 18279566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18289566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 1829*48a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18303a40ed3dSBarry Smith PetscFunctionReturn(0); 18319b94acceSBarry Smith } 18329b94acceSBarry Smith 1833e4ed7901SPeter Brune /*@C 1834e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1835e4ed7901SPeter Brune function norm at the initialization of the method. In some 1836e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1837e4ed7901SPeter Brune SNESSolve. This function allows one to avoid a redundant call 1838e4ed7901SPeter Brune to SNESComputeFunction in that case. 1839e4ed7901SPeter Brune 1840e4ed7901SPeter Brune Logically Collective on SNES 1841e4ed7901SPeter Brune 1842e4ed7901SPeter Brune Input Parameters: 1843e4ed7901SPeter Brune + snes - the SNES context 1844e4ed7901SPeter Brune - f - vector to store function value 1845e4ed7901SPeter Brune 1846e4ed7901SPeter Brune Notes: 1847e4ed7901SPeter Brune This should not be modified during the solution procedure. 1848e4ed7901SPeter Brune 1849e4ed7901SPeter Brune This is used extensively in the SNESFAS hierarchy and in nonlinear preconditioning. 1850e4ed7901SPeter Brune 1851e4ed7901SPeter Brune Level: developer 1852e4ed7901SPeter Brune 1853db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1854e4ed7901SPeter Brune @*/ 18559371c9d4SSatish Balay PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) { 1856e4ed7901SPeter Brune Vec vec_func; 1857e4ed7901SPeter Brune 1858e4ed7901SPeter Brune PetscFunctionBegin; 1859e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1860e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1861e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1862efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1863902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1864902f982fSPeter Brune PetscFunctionReturn(0); 1865902f982fSPeter Brune } 18669566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 18679566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1868f5af7f23SKarl Rupp 1869217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1870e4ed7901SPeter Brune PetscFunctionReturn(0); 1871e4ed7901SPeter Brune } 1872e4ed7901SPeter Brune 1873534ebe21SPeter Brune /*@ 1874a5b23f4aSJose E. Roman SNESSetNormSchedule - Sets the SNESNormSchedule used in convergence and monitoring 1875534ebe21SPeter Brune of the SNES method. 1876534ebe21SPeter Brune 1877534ebe21SPeter Brune Logically Collective on SNES 1878534ebe21SPeter Brune 1879534ebe21SPeter Brune Input Parameters: 1880534ebe21SPeter Brune + snes - the SNES context 1881365a6726SPeter Brune - normschedule - the frequency of norm computation 1882534ebe21SPeter Brune 1883517f1916SMatthew G. Knepley Options Database Key: 188467b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1885517f1916SMatthew G. Knepley 1886534ebe21SPeter Brune Notes: 1887365a6726SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 1888534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1889534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1890a5b23f4aSJose E. Roman (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 1891534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1892534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1893534ebe21SPeter Brune their solution. 1894534ebe21SPeter Brune 1895534ebe21SPeter Brune Level: developer 1896534ebe21SPeter Brune 1897db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1898534ebe21SPeter Brune @*/ 18999371c9d4SSatish Balay PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) { 1900534ebe21SPeter Brune PetscFunctionBegin; 1901534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1902365a6726SPeter Brune snes->normschedule = normschedule; 1903534ebe21SPeter Brune PetscFunctionReturn(0); 1904534ebe21SPeter Brune } 1905534ebe21SPeter Brune 1906534ebe21SPeter Brune /*@ 1907a5b23f4aSJose E. Roman SNESGetNormSchedule - Gets the SNESNormSchedule used in convergence and monitoring 1908534ebe21SPeter Brune of the SNES method. 1909534ebe21SPeter Brune 1910534ebe21SPeter Brune Logically Collective on SNES 1911534ebe21SPeter Brune 1912534ebe21SPeter Brune Input Parameters: 1913534ebe21SPeter Brune + snes - the SNES context 1914365a6726SPeter Brune - normschedule - the type of the norm used 1915534ebe21SPeter Brune 1916534ebe21SPeter Brune Level: advanced 1917534ebe21SPeter Brune 1918db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1919534ebe21SPeter Brune @*/ 19209371c9d4SSatish Balay PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) { 1921534ebe21SPeter Brune PetscFunctionBegin; 1922534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1923365a6726SPeter Brune *normschedule = snes->normschedule; 1924534ebe21SPeter Brune PetscFunctionReturn(0); 1925534ebe21SPeter Brune } 1926534ebe21SPeter Brune 1927c5ce4427SMatthew G. Knepley /*@ 1928c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1929c5ce4427SMatthew G. Knepley 1930c5ce4427SMatthew G. Knepley Logically Collective on SNES 1931c5ce4427SMatthew G. Knepley 1932c5ce4427SMatthew G. Knepley Input Parameters: 1933c5ce4427SMatthew G. Knepley + snes - the SNES context 1934c5ce4427SMatthew G. Knepley 1935c5ce4427SMatthew G. Knepley - normschedule - the frequency of norm computation 1936c5ce4427SMatthew G. Knepley 1937c5ce4427SMatthew G. Knepley Level: developer 1938c5ce4427SMatthew G. Knepley 1939db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1940c5ce4427SMatthew G. Knepley @*/ 19419371c9d4SSatish Balay PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) { 1942c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1943c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1944c5ce4427SMatthew G. Knepley snes->norm = norm; 1945c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1946c5ce4427SMatthew G. Knepley } 1947c5ce4427SMatthew G. Knepley 1948c5ce4427SMatthew G. Knepley /*@ 1949c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1950c5ce4427SMatthew G. Knepley 1951c5ce4427SMatthew G. Knepley Not Collective 1952c5ce4427SMatthew G. Knepley 1953c5ce4427SMatthew G. Knepley Input Parameter: 1954c5ce4427SMatthew G. Knepley . snes - the SNES context 1955c5ce4427SMatthew G. Knepley 1956c5ce4427SMatthew G. Knepley Output Parameter: 1957c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1958c5ce4427SMatthew G. Knepley 1959c5ce4427SMatthew G. Knepley Level: developer 1960c5ce4427SMatthew G. Knepley 1961db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1962c5ce4427SMatthew G. Knepley @*/ 19639371c9d4SSatish Balay PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) { 1964c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1965c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1966dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 1967c5ce4427SMatthew G. Knepley *norm = snes->norm; 1968c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1969c5ce4427SMatthew G. Knepley } 1970c5ce4427SMatthew G. Knepley 1971c1e67a49SFande Kong /*@ 1972c1e67a49SFande Kong SNESGetUpdateNorm - Gets the last computed norm of the Newton update 1973c1e67a49SFande Kong 1974c1e67a49SFande Kong Not Collective 1975c1e67a49SFande Kong 1976c1e67a49SFande Kong Input Parameter: 1977c1e67a49SFande Kong . snes - the SNES context 1978c1e67a49SFande Kong 1979c1e67a49SFande Kong Output Parameter: 1980c1e67a49SFande Kong . ynorm - the last computed update norm 1981c1e67a49SFande Kong 1982c1e67a49SFande Kong Level: developer 1983c1e67a49SFande Kong 1984db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 1985c1e67a49SFande Kong @*/ 19869371c9d4SSatish Balay PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) { 1987c1e67a49SFande Kong PetscFunctionBegin; 1988c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1989dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 1990c1e67a49SFande Kong *ynorm = snes->ynorm; 1991c1e67a49SFande Kong PetscFunctionReturn(0); 1992c1e67a49SFande Kong } 1993c1e67a49SFande Kong 1994c1e67a49SFande Kong /*@ 19954591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 1996c1e67a49SFande Kong 1997c1e67a49SFande Kong Not Collective 1998c1e67a49SFande Kong 1999c1e67a49SFande Kong Input Parameter: 2000c1e67a49SFande Kong . snes - the SNES context 2001c1e67a49SFande Kong 2002c1e67a49SFande Kong Output Parameter: 2003c1e67a49SFande Kong . xnorm - the last computed solution norm 2004c1e67a49SFande Kong 2005c1e67a49SFande Kong Level: developer 2006c1e67a49SFande Kong 2007db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2008c1e67a49SFande Kong @*/ 20099371c9d4SSatish Balay PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) { 2010c1e67a49SFande Kong PetscFunctionBegin; 2011c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2012dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2013c1e67a49SFande Kong *xnorm = snes->xnorm; 2014c1e67a49SFande Kong PetscFunctionReturn(0); 2015c1e67a49SFande Kong } 2016c1e67a49SFande Kong 201747073ea2SPeter Brune /*@C 2018a5b23f4aSJose E. Roman SNESSetFunctionType - Sets the SNESNormSchedule used in convergence and monitoring 201947073ea2SPeter Brune of the SNES method. 202047073ea2SPeter Brune 202147073ea2SPeter Brune Logically Collective on SNES 202247073ea2SPeter Brune 202347073ea2SPeter Brune Input Parameters: 202447073ea2SPeter Brune + snes - the SNES context 202547073ea2SPeter Brune - normschedule - the frequency of norm computation 202647073ea2SPeter Brune 202747073ea2SPeter Brune Notes: 202847073ea2SPeter Brune Only certain SNES methods support certain SNESNormSchedules. Most require evaluation 202947073ea2SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 203047073ea2SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 2031a5b23f4aSJose E. Roman (SNESNGS) and the like do not require the norm of the function to be computed, and therefore 203247073ea2SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 203347073ea2SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 203447073ea2SPeter Brune their solution. 203547073ea2SPeter Brune 203647073ea2SPeter Brune Level: developer 203747073ea2SPeter Brune 2038db781477SPatrick Sanan .seealso: `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 203947073ea2SPeter Brune @*/ 20409371c9d4SSatish Balay PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) { 204147073ea2SPeter Brune PetscFunctionBegin; 204247073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 204347073ea2SPeter Brune snes->functype = type; 204447073ea2SPeter Brune PetscFunctionReturn(0); 204547073ea2SPeter Brune } 204647073ea2SPeter Brune 204747073ea2SPeter Brune /*@C 2048a5b23f4aSJose E. Roman SNESGetFunctionType - Gets the SNESNormSchedule used in convergence and monitoring 204947073ea2SPeter Brune of the SNES method. 205047073ea2SPeter Brune 205147073ea2SPeter Brune Logically Collective on SNES 205247073ea2SPeter Brune 205347073ea2SPeter Brune Input Parameters: 205447073ea2SPeter Brune + snes - the SNES context 205547073ea2SPeter Brune - normschedule - the type of the norm used 205647073ea2SPeter Brune 205747073ea2SPeter Brune Level: advanced 205847073ea2SPeter Brune 2059db781477SPatrick Sanan .seealso: `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 206047073ea2SPeter Brune @*/ 20619371c9d4SSatish Balay PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) { 206247073ea2SPeter Brune PetscFunctionBegin; 206347073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 206447073ea2SPeter Brune *type = snes->functype; 2065534ebe21SPeter Brune PetscFunctionReturn(0); 2066534ebe21SPeter Brune } 2067534ebe21SPeter Brune 2068bf388a1fSBarry Smith /*MC 2069be95d8f1SBarry Smith SNESNGSFunction - function used to convey a Gauss-Seidel sweep on the nonlinear function 2070bf388a1fSBarry Smith 2071bf388a1fSBarry Smith Synopsis: 2072aaa7dc30SBarry Smith #include <petscsnes.h> 2073be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2074bf388a1fSBarry Smith 20751843f636SBarry Smith Collective on snes 20761843f636SBarry Smith 20771843f636SBarry Smith Input Parameters: 2078bf388a1fSBarry Smith + X - solution vector 2079bf388a1fSBarry Smith . B - RHS vector 2080bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2081bf388a1fSBarry Smith 20821843f636SBarry Smith Output Parameter: 20831843f636SBarry Smith . X - solution vector 20841843f636SBarry Smith 2085878cb397SSatish Balay Level: intermediate 2086878cb397SSatish Balay 2087db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetNGS()` 2088bf388a1fSBarry Smith M*/ 2089bf388a1fSBarry Smith 2090c79ef259SPeter Brune /*@C 2091be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2092c79ef259SPeter Brune use with composed nonlinear solvers. 2093c79ef259SPeter Brune 2094c79ef259SPeter Brune Input Parameters: 2095c79ef259SPeter Brune + snes - the SNES context 2096be95d8f1SBarry Smith . f - function evaluation routine to apply Gauss-Seidel see SNESNGSFunction 2097c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 20980298fd71SBarry Smith smoother evaluation routine (may be NULL) 2099c79ef259SPeter Brune 2100c79ef259SPeter Brune Notes: 2101be95d8f1SBarry Smith The NGS routines are used by the composed nonlinear solver to generate 2102c79ef259SPeter Brune a problem appropriate update to the solution, particularly FAS. 2103c79ef259SPeter Brune 2104d28543b3SPeter Brune Level: intermediate 2105c79ef259SPeter Brune 2106db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeNGS()` 2107c79ef259SPeter Brune @*/ 21089371c9d4SSatish Balay PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) { 21096cab3a1bSJed Brown DM dm; 21106cab3a1bSJed Brown 2111646217ecSPeter Brune PetscFunctionBegin; 21126cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21139566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21149566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 2115646217ecSPeter Brune PetscFunctionReturn(0); 2116646217ecSPeter Brune } 2117646217ecSPeter Brune 2118bbc1464cSBarry Smith /* 2119bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2120bbc1464cSBarry Smith changed during the KSPSolve() 2121bbc1464cSBarry Smith */ 21229371c9d4SSatish Balay PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) { 2123bbc1464cSBarry Smith DM dm; 2124bbc1464cSBarry Smith DMSNES sdm; 2125bbc1464cSBarry Smith 2126bbc1464cSBarry Smith PetscFunctionBegin; 21279566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21289566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2129bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2130bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2131792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21329566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 21330df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2134ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2135792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21369566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2137bbc1464cSBarry Smith } else { 2138792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21399566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2140bbc1464cSBarry Smith } 2141bbc1464cSBarry Smith PetscFunctionReturn(0); 2142bbc1464cSBarry Smith } 2143bbc1464cSBarry Smith 21449371c9d4SSatish Balay PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) { 2145e03ab78fSPeter Brune DM dm; 2146942e3340SBarry Smith DMSNES sdm; 21476cab3a1bSJed Brown 21488b0a5094SBarry Smith PetscFunctionBegin; 21499566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21509566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 21518b0a5094SBarry Smith /* A(x)*x - b(x) */ 2152bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2153792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21549566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 2155792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 21569566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2157bbc1464cSBarry Smith } else { 2158792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 21599566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2160bbc1464cSBarry Smith } 21618b0a5094SBarry Smith PetscFunctionReturn(0); 21628b0a5094SBarry Smith } 21638b0a5094SBarry Smith 21649371c9d4SSatish Balay PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) { 21658b0a5094SBarry Smith PetscFunctionBegin; 2166e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2167bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 21689566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 21699566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 21708b0a5094SBarry Smith PetscFunctionReturn(0); 21718b0a5094SBarry Smith } 21728b0a5094SBarry Smith 21738b0a5094SBarry Smith /*@C 2174bbc1464cSBarry Smith SNESSetPicard - Use SNES to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 21758b0a5094SBarry Smith 21768b0a5094SBarry Smith Logically Collective on SNES 21778b0a5094SBarry Smith 21788b0a5094SBarry Smith Input Parameters: 21798b0a5094SBarry Smith + snes - the SNES context 21806b7fb656SBarry Smith . r - vector to store function values, may be NULL 21816b7fb656SBarry Smith . bp - function evaluation routine, may be NULL 21826b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2183e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 21846b7fb656SBarry Smith . J - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence 21856b7fb656SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 21868b0a5094SBarry Smith 21878b0a5094SBarry Smith Notes: 21886b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2189f450aa47SBarry 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. 2190f450aa47SBarry Smith 21918b0a5094SBarry Smith One can call SNESSetPicard() or SNESSetFunction() (and possibly SNESSetJacobian()) but cannot call both 21928b0a5094SBarry Smith 21936b7fb656SBarry 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} 21946b7fb656SBarry 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. 21958b0a5094SBarry Smith 21968b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 21978b0a5094SBarry Smith 21980d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 21996b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22008b0a5094SBarry Smith 22018b0a5094SBarry 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 22028b0a5094SBarry 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 22038b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22048b0a5094SBarry Smith 22056b7fb656SBarry 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. 22066b7fb656SBarry Smith 22076b7fb656SBarry 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. 22086b7fb656SBarry Smith 22096b7fb656SBarry 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 22106b7fb656SBarry 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 22116b7fb656SBarry 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. 22126b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2213bbc1464cSBarry Smith 2214f450aa47SBarry Smith Level: intermediate 22158b0a5094SBarry Smith 2216db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22178b0a5094SBarry Smith @*/ 22189371c9d4SSatish Balay 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) { 2219e03ab78fSPeter Brune DM dm; 2220e03ab78fSPeter Brune 22218b0a5094SBarry Smith PetscFunctionBegin; 22228b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22239566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22249566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22259566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22269566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22279566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22288b0a5094SBarry Smith PetscFunctionReturn(0); 22298b0a5094SBarry Smith } 22308b0a5094SBarry Smith 22317971a8bfSPeter Brune /*@C 22327971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22337971a8bfSPeter Brune 22347971a8bfSPeter Brune Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 22357971a8bfSPeter Brune 22367971a8bfSPeter Brune Input Parameter: 22377971a8bfSPeter Brune . snes - the SNES context 22387971a8bfSPeter Brune 2239d8d19677SJose E. Roman Output Parameters: 22400298fd71SBarry Smith + r - the function (or NULL) 2241f8b49ee9SBarry Smith . f - the function (or NULL); see SNESFunction for calling sequence details 2242e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2243e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2244f8b49ee9SBarry Smith . J - the function for matrix evaluation (or NULL); see SNESJacobianFunction for calling sequence details 22450298fd71SBarry Smith - ctx - the function context (or NULL) 22467971a8bfSPeter Brune 22477971a8bfSPeter Brune Level: advanced 22487971a8bfSPeter Brune 2249db781477SPatrick Sanan .seealso: `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 22507971a8bfSPeter Brune @*/ 22519371c9d4SSatish Balay 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) { 22527971a8bfSPeter Brune DM dm; 22537971a8bfSPeter Brune 22547971a8bfSPeter Brune PetscFunctionBegin; 22557971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22569566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 22579566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 22589566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22599566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 22607971a8bfSPeter Brune PetscFunctionReturn(0); 22617971a8bfSPeter Brune } 22627971a8bfSPeter Brune 2263d25893d9SBarry Smith /*@C 2264d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2265d25893d9SBarry Smith 2266d25893d9SBarry Smith Logically Collective on SNES 2267d25893d9SBarry Smith 2268d25893d9SBarry Smith Input Parameters: 2269d25893d9SBarry Smith + snes - the SNES context 2270d25893d9SBarry Smith . func - function evaluation routine 2271d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 22720298fd71SBarry Smith function evaluation routine (may be NULL) 2273d25893d9SBarry Smith 2274d25893d9SBarry Smith Calling sequence of func: 2275d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2276d25893d9SBarry Smith 2277d25893d9SBarry Smith . f - function vector 2278d25893d9SBarry Smith - ctx - optional user-defined function context 2279d25893d9SBarry Smith 2280d25893d9SBarry Smith Level: intermediate 2281d25893d9SBarry Smith 2282db781477SPatrick Sanan .seealso: `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2283d25893d9SBarry Smith @*/ 22849371c9d4SSatish Balay PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx) { 2285d25893d9SBarry Smith PetscFunctionBegin; 2286d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2287d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2288d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2289d25893d9SBarry Smith PetscFunctionReturn(0); 2290d25893d9SBarry Smith } 2291d25893d9SBarry Smith 22923ab0aad5SBarry Smith /* --------------------------------------------------------------- */ 22931096aae1SMatthew Knepley /*@C 22941096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 22951096aae1SMatthew Knepley it assumes a zero right hand side. 22961096aae1SMatthew Knepley 22973f9fe445SBarry Smith Logically Collective on SNES 22981096aae1SMatthew Knepley 22991096aae1SMatthew Knepley Input Parameter: 23001096aae1SMatthew Knepley . snes - the SNES context 23011096aae1SMatthew Knepley 23021096aae1SMatthew Knepley Output Parameter: 23030298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 23041096aae1SMatthew Knepley 23051096aae1SMatthew Knepley Level: intermediate 23061096aae1SMatthew Knepley 2307db781477SPatrick Sanan .seealso: `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23081096aae1SMatthew Knepley @*/ 23099371c9d4SSatish Balay PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) { 23101096aae1SMatthew Knepley PetscFunctionBegin; 23110700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23121096aae1SMatthew Knepley PetscValidPointer(rhs, 2); 231385385478SLisandro Dalcin *rhs = snes->vec_rhs; 23141096aae1SMatthew Knepley PetscFunctionReturn(0); 23151096aae1SMatthew Knepley } 23161096aae1SMatthew Knepley 23179b94acceSBarry Smith /*@ 2318bf388a1fSBarry Smith SNESComputeFunction - Calls the function that has been set with SNESSetFunction(). 23199b94acceSBarry Smith 2320c7afd0dbSLois Curfman McInnes Collective on SNES 2321c7afd0dbSLois Curfman McInnes 23229b94acceSBarry Smith Input Parameters: 2323c7afd0dbSLois Curfman McInnes + snes - the SNES context 2324c7afd0dbSLois Curfman McInnes - x - input vector 23259b94acceSBarry Smith 23269b94acceSBarry Smith Output Parameter: 23273638b69dSLois Curfman McInnes . y - function vector, as set by SNESSetFunction() 23289b94acceSBarry Smith 23291bffabb2SLois Curfman McInnes Notes: 233036851e7fSLois Curfman McInnes SNESComputeFunction() is typically used within nonlinear solvers 2331bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 233236851e7fSLois Curfman McInnes 233336851e7fSLois Curfman McInnes Level: developer 233436851e7fSLois Curfman McInnes 2335db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 23369b94acceSBarry Smith @*/ 23379371c9d4SSatish Balay PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) { 23386cab3a1bSJed Brown DM dm; 2339942e3340SBarry Smith DMSNES sdm; 23409b94acceSBarry Smith 23413a40ed3dSBarry Smith PetscFunctionBegin; 23420700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23430700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 23440700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2345c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2346c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 23479566063dSJacob Faibussowitsch PetscCall(VecValidValues(x, 2, PETSC_TRUE)); 2348184914b5SBarry Smith 23499566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23509566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 235132f3f7c2SPeter Brune if (sdm->ops->computefunction) { 2352*48a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 23539566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 23548ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 23558ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2356800f99ffSJeremy L Thompson { 2357800f99ffSJeremy L Thompson void *ctx; 2358800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2359800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2360800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2361800f99ffSJeremy L Thompson } 23629566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 2363*48a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2364c90fad12SPeter Brune } else if (snes->vec_rhs) { 23659566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 2366644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 23671baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2368ae3c334cSLois Curfman McInnes snes->nfuncs++; 2369422a814eSBarry Smith /* 2370422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2371422a814eSBarry Smith propagate the value to all processes 2372422a814eSBarry Smith */ 23731baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 23743a40ed3dSBarry Smith PetscFunctionReturn(0); 23759b94acceSBarry Smith } 23769b94acceSBarry Smith 2377c79ef259SPeter Brune /*@ 2378bbc1464cSBarry Smith SNESComputeMFFunction - Calls the function that has been set with SNESSetMFFunction(). 2379bbc1464cSBarry Smith 2380bbc1464cSBarry Smith Collective on SNES 2381bbc1464cSBarry Smith 2382bbc1464cSBarry Smith Input Parameters: 2383bbc1464cSBarry Smith + snes - the SNES context 2384bbc1464cSBarry Smith - x - input vector 2385bbc1464cSBarry Smith 2386bbc1464cSBarry Smith Output Parameter: 2387bbc1464cSBarry Smith . y - function vector, as set by SNESSetMFFunction() 2388bbc1464cSBarry Smith 2389bbc1464cSBarry Smith Notes: 2390bbc1464cSBarry Smith SNESComputeMFFunction() is used within the matrix vector products called by the matrix created with MatCreateSNESMF() 2391bbc1464cSBarry Smith so users would not generally call this routine themselves. 2392bbc1464cSBarry Smith 2393bbc1464cSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with SNESSolve() 2394bbc1464cSBarry Smith while SNESComputeFunction() does. As such, this routine cannot be used with MatMFFDSetBase() with a provided F function value even if it applies the 2395bbc1464cSBarry 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. 2396bbc1464cSBarry Smith 2397bbc1464cSBarry Smith Level: developer 2398bbc1464cSBarry Smith 2399db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2400bbc1464cSBarry Smith @*/ 24019371c9d4SSatish Balay PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) { 2402bbc1464cSBarry Smith DM dm; 2403bbc1464cSBarry Smith DMSNES sdm; 2404bbc1464cSBarry Smith 2405bbc1464cSBarry Smith PetscFunctionBegin; 2406bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2407bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2408bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2409bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2410bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 24119566063dSJacob Faibussowitsch PetscCall(VecValidValues(x, 2, PETSC_TRUE)); 2412bbc1464cSBarry Smith 24139566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24149566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24159566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24169566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2417bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2418bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2419792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24209566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24219566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2422bbc1464cSBarry Smith snes->nfuncs++; 2423bbc1464cSBarry Smith /* 2424bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2425bbc1464cSBarry Smith propagate the value to all processes 2426bbc1464cSBarry Smith */ 24271baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 2428bbc1464cSBarry Smith PetscFunctionReturn(0); 2429bbc1464cSBarry Smith } 2430bbc1464cSBarry Smith 2431bbc1464cSBarry Smith /*@ 2432be95d8f1SBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with SNESSetNGS(). 2433c79ef259SPeter Brune 2434c79ef259SPeter Brune Collective on SNES 2435c79ef259SPeter Brune 2436c79ef259SPeter Brune Input Parameters: 2437c79ef259SPeter Brune + snes - the SNES context 2438c79ef259SPeter Brune . x - input vector 2439c79ef259SPeter Brune - b - rhs vector 2440c79ef259SPeter Brune 2441c79ef259SPeter Brune Output Parameter: 2442c79ef259SPeter Brune . x - new solution vector 2443c79ef259SPeter Brune 2444c79ef259SPeter Brune Notes: 2445be95d8f1SBarry Smith SNESComputeNGS() is typically used within composed nonlinear solver 2446c79ef259SPeter Brune implementations, so most users would not generally call this routine 2447c79ef259SPeter Brune themselves. 2448c79ef259SPeter Brune 2449c79ef259SPeter Brune Level: developer 2450c79ef259SPeter Brune 2451db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESComputeFunction()` 2452c79ef259SPeter Brune @*/ 24539371c9d4SSatish Balay PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) { 24546cab3a1bSJed Brown DM dm; 2455942e3340SBarry Smith DMSNES sdm; 2456646217ecSPeter Brune 2457646217ecSPeter Brune PetscFunctionBegin; 2458646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2459064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2460064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2461064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2462064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 24639566063dSJacob Faibussowitsch if (b) PetscCall(VecValidValues(b, 2, PETSC_TRUE)); 24649566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 24659566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24669566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 246722c6f798SBarry Smith if (sdm->ops->computegs) { 24689566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2469792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 24709566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 2471be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 24729566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 2473646217ecSPeter Brune PetscFunctionReturn(0); 2474646217ecSPeter Brune } 2475646217ecSPeter Brune 24769371c9d4SSatish Balay PetscErrorCode SNESTestJacobian(SNES snes) { 247712837594SBarry Smith Mat A, B, C, D, jacobian; 2478e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2479e885f1abSBarry Smith PetscReal nrm, gnorm; 248081e7118cSBarry Smith PetscReal threshold = 1.e-5; 24810e276705SLisandro Dalcin MatType mattype; 2482e885f1abSBarry Smith PetscInt m, n, M, N; 2483e885f1abSBarry Smith void *functx; 24842cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 24853325ff46SBarry Smith PetscViewer viewer, mviewer; 2486e885f1abSBarry Smith MPI_Comm comm; 2487e885f1abSBarry Smith PetscInt tabs; 248812837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 24893325ff46SBarry Smith PetscViewerFormat format; 2490e885f1abSBarry Smith 2491e885f1abSBarry Smith PetscFunctionBegin; 2492d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 24939566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 24949566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 24959566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 249618d89885SKarl Rupp if (!complete_print) { 24979566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 24989566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_display", "Display difference between hand-coded and finite difference Jacobians", "None", &mviewer, &format, &complete_print)); 249918d89885SKarl Rupp } 250018d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 25019566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 25029566063dSJacob 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)); 2503d0609cedSBarry Smith PetscOptionsEnd(); 2504e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2505e885f1abSBarry Smith 25069566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 251112837594SBarry Smith if (!complete_print && !directionsprinted) { 25129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 251412837594SBarry Smith } 251512837594SBarry Smith if (!directionsprinted) { 25169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 251812837594SBarry Smith directionsprinted = PETSC_TRUE; 2519e885f1abSBarry Smith } 25201baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2521e885f1abSBarry Smith 25229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 252312837594SBarry Smith if (!flg) jacobian = snes->jacobian; 252412837594SBarry Smith else jacobian = snes->jacobian_pre; 252512837594SBarry Smith 2526a82339d0SMatthew G. Knepley if (!x) { 25279566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2528a82339d0SMatthew G. Knepley } else { 25299566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2530a82339d0SMatthew G. Knepley } 2531a82339d0SMatthew G. Knepley if (!f) { 25329566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2533a82339d0SMatthew G. Knepley } else { 25349566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2535a82339d0SMatthew G. Knepley } 2536a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 25379566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 25389566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 25399566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 254012837594SBarry Smith while (jacobian) { 25412cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 25422cd624f9SStefano Zampini 25432cd624f9SStefano Zampini if (istranspose) { 25449566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 25452cd624f9SStefano Zampini Jsave = jacobian; 25462cd624f9SStefano Zampini jacobian = JT; 25472cd624f9SStefano Zampini } 25489566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 254912837594SBarry Smith if (flg) { 255012837594SBarry Smith A = jacobian; 25519566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 255212837594SBarry Smith } else { 25539566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 255412837594SBarry Smith } 2555e885f1abSBarry Smith 25569566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 25579566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 25589566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 25599566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 25609566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 25619566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 25629566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 25639566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 25649566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2565e885f1abSBarry Smith 25669566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 25679566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 256812837594SBarry Smith 25699566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 25709566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 25719566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 25729566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 25739566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 257412837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 25759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 257612837594SBarry Smith 2577e885f1abSBarry Smith if (complete_print) { 25789566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 25799566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 25809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 25819566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2582e885f1abSBarry Smith } 2583e885f1abSBarry Smith 2584df10fb39SFande Kong if (threshold_print || complete_print) { 2585e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2586e885f1abSBarry Smith PetscScalar *cvals; 2587e885f1abSBarry Smith const PetscInt *bcols; 2588e885f1abSBarry Smith const PetscScalar *bvals; 2589e885f1abSBarry Smith 25909566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 25919566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 25929566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 25939566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 25949566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 25959566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 25960e276705SLisandro Dalcin 25979566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 25989566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2599e885f1abSBarry Smith 2600e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26019566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26029566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2603e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 260423a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2605e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2606e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2607e885f1abSBarry Smith cncols += 1; 2608e885f1abSBarry Smith } 2609e885f1abSBarry Smith } 2610*48a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26119566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26129566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2613e885f1abSBarry Smith } 26149566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26159566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26179566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26189566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2619e885f1abSBarry Smith } 26209566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26219566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 26232cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 262412837594SBarry Smith if (jacobian != snes->jacobian_pre) { 262512837594SBarry Smith jacobian = snes->jacobian_pre; 26269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 26279371c9d4SSatish Balay } else jacobian = NULL; 262812837594SBarry Smith } 26299566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 26301baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 26319566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 26329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 2633e885f1abSBarry Smith PetscFunctionReturn(0); 2634e885f1abSBarry Smith } 2635e885f1abSBarry Smith 263662fef451SLois Curfman McInnes /*@ 2637bf388a1fSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with SNESSetJacobian(). 263862fef451SLois Curfman McInnes 2639d083f849SBarry Smith Collective on SNES 2640c7afd0dbSLois Curfman McInnes 264162fef451SLois Curfman McInnes Input Parameters: 2642c7afd0dbSLois Curfman McInnes + snes - the SNES context 2643c7afd0dbSLois Curfman McInnes - x - input vector 264462fef451SLois Curfman McInnes 264562fef451SLois Curfman McInnes Output Parameters: 2646c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2647d1e9a80fSBarry Smith - B - optional preconditioning matrix 2648fee21e36SBarry Smith 2649e35cf81dSBarry Smith Options Database Keys: 265067b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 265167b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2652455a5933SJed 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. 2653455a5933SJed 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 2654693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2655693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2656693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 26574c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 265894d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2659a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2660c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2661c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2662c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2663a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2664a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2665c01495d3SJed Brown 266662fef451SLois Curfman McInnes Notes: 266762fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 266862fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 266962fef451SLois Curfman McInnes 267095452b02SPatrick Sanan Developer Notes: 267195452b02SPatrick 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 2672e885f1abSBarry Smith for with the SNESType of test that has been removed. 2673e885f1abSBarry Smith 267436851e7fSLois Curfman McInnes Level: developer 267536851e7fSLois Curfman McInnes 2676db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 267762fef451SLois Curfman McInnes @*/ 26789371c9d4SSatish Balay PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) { 2679ace3abfcSBarry Smith PetscBool flag; 26806cab3a1bSJed Brown DM dm; 2681942e3340SBarry Smith DMSNES sdm; 2682e0e3a89bSBarry Smith KSP ksp; 26833a40ed3dSBarry Smith 26843a40ed3dSBarry Smith PetscFunctionBegin; 26850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 26860700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2687c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 26889566063dSJacob Faibussowitsch PetscCall(VecValidValues(X, 2, PETSC_TRUE)); 26899566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 26909566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 26913232da50SPeter Brune 2692ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2693fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2694fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2695f5af7f23SKarl Rupp 26969566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2697fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 26989566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 26999566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2700ebd3b9afSBarry Smith if (flag) { 27019566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27029566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2703ebd3b9afSBarry Smith } 2704e35cf81dSBarry Smith PetscFunctionReturn(0); 270537ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 270663a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27079566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2708ebd3b9afSBarry Smith if (flag) { 27099566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27109566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2711ebd3b9afSBarry Smith } 2712e35cf81dSBarry Smith PetscFunctionReturn(0); 2713e35cf81dSBarry Smith } 2714efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27159566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27169566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2717d728fb7dSPeter Brune PetscFunctionReturn(0); 2718d728fb7dSPeter Brune } 2719e35cf81dSBarry Smith 27209566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27219566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2722800f99ffSJeremy L Thompson { 2723800f99ffSJeremy L Thompson void *ctx; 2724800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2725800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2726800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2727800f99ffSJeremy L Thompson } 27289566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 27299566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 273028d58a37SPierre Jolivet 273128d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 27329566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2733a8054027SBarry Smith 2734e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 27359566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 27363b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 27379566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 27389566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 27393b4f5425SBarry Smith snes->lagpreconditioner = -1; 27403b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 27419566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 27429566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 274337ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 274463a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 27459566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2746d1e9a80fSBarry Smith } else { 27479566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 27489566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2749a8054027SBarry Smith } 2750a8054027SBarry Smith 27519566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 27526d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 275394ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 275494ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2755693365a8SJed Brown { 2756693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 27579566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 27589566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 27599566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 27609566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2761693365a8SJed Brown if (flag || flag_draw || flag_contour) { 27620298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2763693365a8SJed Brown PetscViewer vdraw, vstdout; 27646b3a5b13SJed Brown PetscBool flg; 2765693365a8SJed Brown if (flag_operator) { 27669566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2767693365a8SJed Brown Bexp = Bexp_mine; 2768693365a8SJed Brown } else { 2769693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 27709566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 277194ab13aaSBarry Smith if (flg) Bexp = B; 2772693365a8SJed Brown else { 2773693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 27749566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2775693365a8SJed Brown Bexp = Bexp_mine; 2776693365a8SJed Brown } 2777693365a8SJed Brown } 27789566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 27799566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 27809566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2781693365a8SJed Brown if (flag_draw || flag_contour) { 27829566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 27839566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 27840298fd71SBarry Smith } else vdraw = NULL; 27859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 27869566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 27879566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 27889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 27899566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 27909566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 27919566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 27929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 27939566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2794693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 27959566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 27969566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 27979566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2798693365a8SJed Brown } 27999566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28009566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28019566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28029566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2803693365a8SJed Brown } 2804693365a8SJed Brown } 28054c30e9fbSJed Brown { 28066719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28076719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28089566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28099566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28109566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28119566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28129566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 281327b0f280SBarry Smith if (flag_threshold) { 28149566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 281627b0f280SBarry Smith } 28176719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28184c30e9fbSJed Brown Mat Bfd; 28194c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2820335efc43SPeter Brune MatColoring coloring; 28214c30e9fbSJed Brown ISColoring iscoloring; 28224c30e9fbSJed Brown MatFDColoring matfdcoloring; 28234c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 28244c30e9fbSJed Brown void *funcctx; 28256719d8e4SJed Brown PetscReal norm1, norm2, normmax; 28264c30e9fbSJed Brown 28279566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 28289566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 28299566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 28309566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 28319566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 28329566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 28339566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 28349566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28359566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 28369566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 28374c30e9fbSJed Brown 28384c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 28399566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 28409566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 28419566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 28429566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 28439566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28449566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 28459566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 28464c30e9fbSJed Brown 28479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 28484c30e9fbSJed Brown if (flag_draw || flag_contour) { 28499566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28509566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28510298fd71SBarry Smith } else vdraw = NULL; 28529566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 28539566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 28549566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 28559566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 28569566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 28579566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 28589566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 28599566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 28609566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 28619566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 28629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 28639566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 28644c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 28659566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28669566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 28679566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 28684c30e9fbSJed Brown } 28699566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28706719d8e4SJed Brown 28716719d8e4SJed Brown if (flag_threshold) { 28726719d8e4SJed Brown PetscInt bs, rstart, rend, i; 28739566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 28749566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 28756719d8e4SJed Brown for (i = rstart; i < rend; i++) { 28766719d8e4SJed Brown const PetscScalar *ba, *ca; 28776719d8e4SJed Brown const PetscInt *bj, *cj; 28786719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 28796719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 28809566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 28819566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 28825f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 28836719d8e4SJed Brown for (j = 0; j < bn; j++) { 28846719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 28856719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 28866719d8e4SJed Brown maxentrycol = bj[j]; 28876719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 28886719d8e4SJed Brown } 28896719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 28906719d8e4SJed Brown maxdiffcol = bj[j]; 28916719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 28926719d8e4SJed Brown } 28936719d8e4SJed Brown if (rdiff > maxrdiff) { 28946719d8e4SJed Brown maxrdiffcol = bj[j]; 28956719d8e4SJed Brown maxrdiff = rdiff; 28966719d8e4SJed Brown } 28976719d8e4SJed Brown } 28986719d8e4SJed Brown if (maxrdiff > 1) { 289963a3b9bcSJacob 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)); 29006719d8e4SJed Brown for (j = 0; j < bn; j++) { 29016719d8e4SJed Brown PetscReal rdiff; 29026719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 2903*48a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29046719d8e4SJed Brown } 290563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29066719d8e4SJed Brown } 29079566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29089566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29096719d8e4SJed Brown } 29106719d8e4SJed Brown } 29119566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29129566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29134c30e9fbSJed Brown } 29144c30e9fbSJed Brown } 29153a40ed3dSBarry Smith PetscFunctionReturn(0); 29169b94acceSBarry Smith } 29179b94acceSBarry Smith 2918bf388a1fSBarry Smith /*MC 2919411c0326SBarry Smith SNESJacobianFunction - Function used to convey the nonlinear Jacobian of the function to be solved by SNES 2920bf388a1fSBarry Smith 2921bf388a1fSBarry Smith Synopsis: 2922411c0326SBarry Smith #include "petscsnes.h" 2923411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2924bf388a1fSBarry Smith 29251843f636SBarry Smith Collective on snes 29261843f636SBarry Smith 29271843f636SBarry Smith Input Parameters: 29281843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 2929bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2930bf388a1fSBarry Smith 29311843f636SBarry Smith Output Parameters: 29321843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 29331843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 29341843f636SBarry Smith 2935878cb397SSatish Balay Level: intermediate 2936878cb397SSatish Balay 2937db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 2938bf388a1fSBarry Smith M*/ 2939bf388a1fSBarry Smith 29409b94acceSBarry Smith /*@C 29419b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2942044dda88SLois Curfman McInnes location to store the matrix. 29439b94acceSBarry Smith 2944d083f849SBarry Smith Logically Collective on SNES 2945c7afd0dbSLois Curfman McInnes 29469b94acceSBarry Smith Input Parameters: 2947c7afd0dbSLois Curfman McInnes + snes - the SNES context 2948e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2949e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2950411c0326SBarry Smith . J - Jacobian evaluation routine (if NULL then SNES retains any previously set value), see SNESJacobianFunction for details 2951c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 29520298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 29539b94acceSBarry Smith 29549b94acceSBarry Smith Notes: 2955e5d3d808SBarry Smith If the Amat matrix and Pmat matrix are different you must call MatAssemblyBegin/End() on 295616913363SBarry Smith each matrix. 295716913363SBarry Smith 2958895c21f2SBarry Smith If you know the operator Amat has a null space you can use MatSetNullSpace() and MatSetTransposeNullSpace() to supply the null 2959895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2960895c21f2SBarry Smith 29618d359177SBarry Smith If using SNESComputeJacobianDefaultColor() to assemble a Jacobian, the ctx argument 2962a8a26c1eSJed Brown must be a MatFDColoring. 2963a8a26c1eSJed Brown 2964c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2965c3cc8fd1SJed Brown example is to use the "Picard linearization" which only differentiates through the highest order parts of each term. 2966c3cc8fd1SJed Brown 296736851e7fSLois Curfman McInnes Level: beginner 296836851e7fSLois Curfman McInnes 2969db781477SPatrick Sanan .seealso: `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`, 2970db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 29719b94acceSBarry Smith @*/ 29729371c9d4SSatish Balay PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) { 29736cab3a1bSJed Brown DM dm; 29743a7fca6bSBarry Smith 29753a40ed3dSBarry Smith PetscFunctionBegin; 29760700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2977e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 2978e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 2979e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 2980e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 29819566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 29829566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 2983e5d3d808SBarry Smith if (Amat) { 29849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 29859566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 2986f5af7f23SKarl Rupp 2987e5d3d808SBarry Smith snes->jacobian = Amat; 29883a7fca6bSBarry Smith } 2989e5d3d808SBarry Smith if (Pmat) { 29909566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 29919566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 2992f5af7f23SKarl Rupp 2993e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 29943a7fca6bSBarry Smith } 29953a40ed3dSBarry Smith PetscFunctionReturn(0); 29969b94acceSBarry Smith } 299762fef451SLois Curfman McInnes 2998c2aafc4cSSatish Balay /*@C 2999b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3000b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3001b4fd4287SBarry Smith 3002c7afd0dbSLois Curfman McInnes Not Collective, but Mat object will be parallel if SNES object is 3003c7afd0dbSLois Curfman McInnes 3004b4fd4287SBarry Smith Input Parameter: 3005b4fd4287SBarry Smith . snes - the nonlinear solver context 3006b4fd4287SBarry Smith 3007b4fd4287SBarry Smith Output Parameters: 3008e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3009e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3010411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 30110298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3012fee21e36SBarry Smith 301336851e7fSLois Curfman McInnes Level: advanced 301436851e7fSLois Curfman McInnes 3015db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3016b4fd4287SBarry Smith @*/ 30179371c9d4SSatish Balay PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) { 30186cab3a1bSJed Brown DM dm; 30196cab3a1bSJed Brown 30203a40ed3dSBarry Smith PetscFunctionBegin; 30210700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3022e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3023e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 30249566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3025800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 30263a40ed3dSBarry Smith PetscFunctionReturn(0); 3027b4fd4287SBarry Smith } 3028b4fd4287SBarry Smith 30299371c9d4SSatish Balay static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) { 303058b371f3SBarry Smith DM dm; 303158b371f3SBarry Smith DMSNES sdm; 303258b371f3SBarry Smith 303358b371f3SBarry Smith PetscFunctionBegin; 30349566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30359566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 303658b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 303758b371f3SBarry Smith DM dm; 303858b371f3SBarry Smith PetscBool isdense, ismf; 303958b371f3SBarry Smith 30409566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30419566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 30429566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 304358b371f3SBarry Smith if (isdense) { 30449566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 304558b371f3SBarry Smith } else if (!ismf) { 30469566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 304758b371f3SBarry Smith } 304858b371f3SBarry Smith } 304958b371f3SBarry Smith PetscFunctionReturn(0); 305058b371f3SBarry Smith } 305158b371f3SBarry Smith 30529b94acceSBarry Smith /*@ 30539b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3054272ac6f2SLois Curfman McInnes of a nonlinear solver. 30559b94acceSBarry Smith 3056fee21e36SBarry Smith Collective on SNES 3057fee21e36SBarry Smith 3058c7afd0dbSLois Curfman McInnes Input Parameters: 305970e92668SMatthew Knepley . snes - the SNES context 3060c7afd0dbSLois Curfman McInnes 3061272ac6f2SLois Curfman McInnes Notes: 3062272ac6f2SLois Curfman McInnes For basic use of the SNES solvers the user need not explicitly call 3063272ac6f2SLois Curfman McInnes SNESSetUp(), since these actions will automatically occur during 3064272ac6f2SLois Curfman McInnes the call to SNESSolve(). However, if one wishes to control this 3065272ac6f2SLois Curfman McInnes phase separately, SNESSetUp() should be called after SNESCreate() 3066272ac6f2SLois Curfman McInnes and optional routines of the form SNESSetXXX(), but before SNESSolve(). 3067272ac6f2SLois Curfman McInnes 306836851e7fSLois Curfman McInnes Level: advanced 306936851e7fSLois Curfman McInnes 3070db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 30719b94acceSBarry Smith @*/ 30729371c9d4SSatish Balay PetscErrorCode SNESSetUp(SNES snes) { 30736cab3a1bSJed Brown DM dm; 3074942e3340SBarry Smith DMSNES sdm; 3075c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 30766e2a1849SPeter Brune void *lsprectx, *lspostctx; 30776b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 30786b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 30796e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 30806e2a1849SPeter Brune Vec f, fpc; 30816e2a1849SPeter Brune void *funcctx; 3082d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 30831eb13d49SPeter Brune void *jacctx, *appctx; 308432b97717SPeter Brune Mat j, jpre; 30853a40ed3dSBarry Smith 30863a40ed3dSBarry Smith PetscFunctionBegin; 30870700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 30884dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 30899566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Setup, snes, 0, 0, 0)); 30909b94acceSBarry Smith 3091*48a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 309285385478SLisandro Dalcin 30939566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 309458c9b817SLisandro Dalcin 30959566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30969566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 30979566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 309858b371f3SBarry Smith 3099*48a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3100efd51863SBarry Smith 3101*48a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3102b710008aSBarry Smith 3103d8d34be6SBarry Smith if (snes->linesearch) { 31049566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31059566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3106d8d34be6SBarry Smith } 31079e764e56SPeter Brune 3108b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3109172a4300SPeter Brune snes->mf = PETSC_TRUE; 3110172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3111172a4300SPeter Brune } 3112d8f46077SPeter Brune 3113efd4aadfSBarry Smith if (snes->npc) { 31146e2a1849SPeter Brune /* copy the DM over */ 31159566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31169566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 31176e2a1849SPeter Brune 31189566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 31199566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 31209566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 31219566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 31229566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 31239566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 31249566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 31259566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 31266e2a1849SPeter Brune 31276e2a1849SPeter Brune /* copy the function pointers over */ 31289566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 31296e2a1849SPeter Brune 31306e2a1849SPeter Brune /* default to 1 iteration */ 31319566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3132efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 31339566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3134a9936a0cSPeter Brune } else { 31359566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3136a9936a0cSPeter Brune } 31379566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 31386e2a1849SPeter Brune 31396e2a1849SPeter Brune /* copy the line search context over */ 3140d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 31419566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 31429566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 31439566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 31449566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 31459566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 31469566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 31479566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 31486e2a1849SPeter Brune } 3149d8d34be6SBarry Smith } 31501baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 3151*48a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 31526e2a1849SPeter Brune 315337ec4e1aSPeter Brune snes->jac_iter = 0; 315437ec4e1aSPeter Brune snes->pre_iter = 0; 315537ec4e1aSPeter Brune 3156dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 315758c9b817SLisandro Dalcin 31589566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 315958b371f3SBarry Smith 3160b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 31616c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3162d8d34be6SBarry Smith if (snes->linesearch) { 31639566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 31649566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 31656c67d002SPeter Brune } 31666c67d002SPeter Brune } 3167d8d34be6SBarry Smith } 31689566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Setup, snes, 0, 0, 0)); 31697aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 31703a40ed3dSBarry Smith PetscFunctionReturn(0); 31719b94acceSBarry Smith } 31729b94acceSBarry Smith 317337596af1SLisandro Dalcin /*@ 317437596af1SLisandro Dalcin SNESReset - Resets a SNES context to the snessetupcalled = 0 state and removes any allocated Vecs and Mats 317537596af1SLisandro Dalcin 317637596af1SLisandro Dalcin Collective on SNES 317737596af1SLisandro Dalcin 317837596af1SLisandro Dalcin Input Parameter: 317937596af1SLisandro Dalcin . snes - iterative context obtained from SNESCreate() 318037596af1SLisandro Dalcin 3181d25893d9SBarry Smith Level: intermediate 3182d25893d9SBarry Smith 318395452b02SPatrick Sanan Notes: 318495452b02SPatrick Sanan Also calls the application context destroy routine set with SNESSetComputeApplicationContext() 318537596af1SLisandro Dalcin 3186db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 318737596af1SLisandro Dalcin @*/ 31889371c9d4SSatish Balay PetscErrorCode SNESReset(SNES snes) { 318937596af1SLisandro Dalcin PetscFunctionBegin; 319037596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3191d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 31929566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 31930298fd71SBarry Smith snes->user = NULL; 3194d25893d9SBarry Smith } 31951baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 31968a23116dSBarry Smith 3197dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 31981baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 31999e764e56SPeter Brune 32001baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32019e764e56SPeter Brune 32029566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32039566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32069566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32079566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32099566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32109566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3211f5af7f23SKarl Rupp 321240fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 321340fdac6aSLawrence Mitchell 321437596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 321537596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 321637596af1SLisandro Dalcin PetscFunctionReturn(0); 321737596af1SLisandro Dalcin } 321837596af1SLisandro Dalcin 321952baeb72SSatish Balay /*@ 3220c4421ceaSFande Kong SNESConvergedReasonViewCancel - Clears all the reasonview functions for a SNES object. 3221c4421ceaSFande Kong 3222c4421ceaSFande Kong Collective on SNES 3223c4421ceaSFande Kong 3224c4421ceaSFande Kong Input Parameter: 3225c4421ceaSFande Kong . snes - iterative context obtained from SNESCreate() 3226c4421ceaSFande Kong 3227c4421ceaSFande Kong Level: intermediate 3228c4421ceaSFande Kong 3229db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3230c4421ceaSFande Kong @*/ 32319371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) { 3232c4421ceaSFande Kong PetscInt i; 3233c4421ceaSFande Kong 3234c4421ceaSFande Kong PetscFunctionBegin; 3235c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3236c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 3237*48a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3238c4421ceaSFande Kong } 3239c4421ceaSFande Kong snes->numberreasonviews = 0; 3240c4421ceaSFande Kong PetscFunctionReturn(0); 3241c4421ceaSFande Kong } 3242c4421ceaSFande Kong 32431fb7b255SJunchao Zhang /*@C 32449b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 32459b94acceSBarry Smith with SNESCreate(). 32469b94acceSBarry Smith 3247c7afd0dbSLois Curfman McInnes Collective on SNES 3248c7afd0dbSLois Curfman McInnes 32499b94acceSBarry Smith Input Parameter: 32509b94acceSBarry Smith . snes - the SNES context 32519b94acceSBarry Smith 325236851e7fSLois Curfman McInnes Level: beginner 325336851e7fSLois Curfman McInnes 3254db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSolve()` 32559b94acceSBarry Smith @*/ 32569371c9d4SSatish Balay PetscErrorCode SNESDestroy(SNES *snes) { 32573a40ed3dSBarry Smith PetscFunctionBegin; 32586bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 32596bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 32609371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 32619371c9d4SSatish Balay *snes = NULL; 32629371c9d4SSatish Balay PetscFunctionReturn(0); 32639371c9d4SSatish Balay } 3264d4bb536fSBarry Smith 32659566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 32669566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 32676b8b9a38SLisandro Dalcin 3268e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 32699566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3270dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 32716d4c513bSLisandro Dalcin 32729566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 32739566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 32749566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 32759566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 32766b8b9a38SLisandro Dalcin 32779566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 3278*48a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 3279*48a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 32809566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 32819566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 32829566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 32833a40ed3dSBarry Smith PetscFunctionReturn(0); 32849b94acceSBarry Smith } 32859b94acceSBarry Smith 32869b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 32879b94acceSBarry Smith 3288a8054027SBarry Smith /*@ 3289a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3290a8054027SBarry Smith 32913f9fe445SBarry Smith Logically Collective on SNES 3292a8054027SBarry Smith 3293a8054027SBarry Smith Input Parameters: 3294a8054027SBarry Smith + snes - the SNES context 3295d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 32963b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3297a8054027SBarry Smith 3298a8054027SBarry Smith Options Database Keys: 32993d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33003d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33013d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33023d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3303a8054027SBarry Smith 3304a8054027SBarry Smith Notes: 3305a8054027SBarry Smith The default is 1 33063d5a8a6aSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagPreconditionerPersists() was called 3307d8e291bfSBarry Smith 3308d8e291bfSBarry Smith SNESSetLagPreconditionerPersists() allows using the same uniform lagging (for example every second solve) across multiple solves. 3309a8054027SBarry Smith 3310a8054027SBarry Smith Level: intermediate 3311a8054027SBarry Smith 3312db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3313db781477SPatrick Sanan `SNESSetLagJacobianPersists()` 3314a8054027SBarry Smith 3315a8054027SBarry Smith @*/ 33169371c9d4SSatish Balay PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) { 3317a8054027SBarry Smith PetscFunctionBegin; 33180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 33195f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 33205f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3321c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3322a8054027SBarry Smith snes->lagpreconditioner = lag; 3323a8054027SBarry Smith PetscFunctionReturn(0); 3324a8054027SBarry Smith } 3325a8054027SBarry Smith 3326efd51863SBarry Smith /*@ 3327efd51863SBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that SNES does 3328efd51863SBarry Smith 3329efd51863SBarry Smith Logically Collective on SNES 3330efd51863SBarry Smith 3331efd51863SBarry Smith Input Parameters: 3332efd51863SBarry Smith + snes - the SNES context 3333efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3334efd51863SBarry Smith 3335efd51863SBarry Smith Options Database Keys: 333667b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3337efd51863SBarry Smith 3338efd51863SBarry Smith Level: intermediate 3339efd51863SBarry Smith 3340c0df2a02SJed Brown Notes: 3341c0df2a02SJed Brown Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3342c0df2a02SJed Brown 3343db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3344efd51863SBarry Smith 3345efd51863SBarry Smith @*/ 33469371c9d4SSatish Balay PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) { 3347efd51863SBarry Smith PetscFunctionBegin; 3348efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3349efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3350efd51863SBarry Smith snes->gridsequence = steps; 3351efd51863SBarry Smith PetscFunctionReturn(0); 3352efd51863SBarry Smith } 3353efd51863SBarry Smith 3354fa19ca70SBarry Smith /*@ 3355fa19ca70SBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that SNES does 3356fa19ca70SBarry Smith 3357fa19ca70SBarry Smith Logically Collective on SNES 3358fa19ca70SBarry Smith 3359fa19ca70SBarry Smith Input Parameter: 3360fa19ca70SBarry Smith . snes - the SNES context 3361fa19ca70SBarry Smith 3362fa19ca70SBarry Smith Output Parameter: 3363fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3364fa19ca70SBarry Smith 3365fa19ca70SBarry Smith Options Database Keys: 336667b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3367fa19ca70SBarry Smith 3368fa19ca70SBarry Smith Level: intermediate 3369fa19ca70SBarry Smith 3370fa19ca70SBarry Smith Notes: 3371fa19ca70SBarry Smith Use SNESGetSolution() to extract the fine grid solution after grid sequencing. 3372fa19ca70SBarry Smith 3373db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3374fa19ca70SBarry Smith 3375fa19ca70SBarry Smith @*/ 33769371c9d4SSatish Balay PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) { 3377fa19ca70SBarry Smith PetscFunctionBegin; 3378fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3379fa19ca70SBarry Smith *steps = snes->gridsequence; 3380fa19ca70SBarry Smith PetscFunctionReturn(0); 3381fa19ca70SBarry Smith } 3382fa19ca70SBarry Smith 3383a8054027SBarry Smith /*@ 3384a8054027SBarry Smith SNESGetLagPreconditioner - Indicates how often the preconditioner is rebuilt 3385a8054027SBarry Smith 33863f9fe445SBarry Smith Not Collective 3387a8054027SBarry Smith 3388a8054027SBarry Smith Input Parameter: 3389a8054027SBarry Smith . snes - the SNES context 3390a8054027SBarry Smith 3391a8054027SBarry Smith Output Parameter: 3392a8054027SBarry 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 33933b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3394a8054027SBarry Smith 3395a8054027SBarry Smith Options Database Keys: 33963d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33973d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33983d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33993d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3400a8054027SBarry Smith 3401a8054027SBarry Smith Notes: 3402a8054027SBarry Smith The default is 1 3403a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3404a8054027SBarry Smith 3405a8054027SBarry Smith Level: intermediate 3406a8054027SBarry Smith 3407db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3408a8054027SBarry Smith 3409a8054027SBarry Smith @*/ 34109371c9d4SSatish Balay PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) { 3411a8054027SBarry Smith PetscFunctionBegin; 34120700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3413a8054027SBarry Smith *lag = snes->lagpreconditioner; 3414a8054027SBarry Smith PetscFunctionReturn(0); 3415a8054027SBarry Smith } 3416a8054027SBarry Smith 3417e35cf81dSBarry Smith /*@ 3418e35cf81dSBarry Smith SNESSetLagJacobian - Determines when the Jacobian is rebuilt in the nonlinear solve. See SNESSetLagPreconditioner() for determining how 3419e35cf81dSBarry Smith often the preconditioner is rebuilt. 3420e35cf81dSBarry Smith 34213f9fe445SBarry Smith Logically Collective on SNES 3422e35cf81dSBarry Smith 3423e35cf81dSBarry Smith Input Parameters: 3424e35cf81dSBarry Smith + snes - the SNES context 3425e35cf81dSBarry 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 3426fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3427e35cf81dSBarry Smith 3428e35cf81dSBarry Smith Options Database Keys: 34293d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34303d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34313d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34323d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3433e35cf81dSBarry Smith 3434e35cf81dSBarry Smith Notes: 3435e35cf81dSBarry Smith The default is 1 3436e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3437fe3ffe1eSBarry 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 3438fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3439e35cf81dSBarry Smith 3440e35cf81dSBarry Smith Level: intermediate 3441e35cf81dSBarry Smith 3442db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3443e35cf81dSBarry Smith 3444e35cf81dSBarry Smith @*/ 34459371c9d4SSatish Balay PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) { 3446e35cf81dSBarry Smith PetscFunctionBegin; 34470700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 34485f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 34495f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3450c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3451e35cf81dSBarry Smith snes->lagjacobian = lag; 3452e35cf81dSBarry Smith PetscFunctionReturn(0); 3453e35cf81dSBarry Smith } 3454e35cf81dSBarry Smith 3455e35cf81dSBarry Smith /*@ 3456e35cf81dSBarry Smith SNESGetLagJacobian - Indicates how often the Jacobian is rebuilt. See SNESGetLagPreconditioner() to determine when the preconditioner is rebuilt 3457e35cf81dSBarry Smith 34583f9fe445SBarry Smith Not Collective 3459e35cf81dSBarry Smith 3460e35cf81dSBarry Smith Input Parameter: 3461e35cf81dSBarry Smith . snes - the SNES context 3462e35cf81dSBarry Smith 3463e35cf81dSBarry Smith Output Parameter: 3464e35cf81dSBarry 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 3465e35cf81dSBarry Smith the Jacobian is built etc. 3466e35cf81dSBarry Smith 3467e35cf81dSBarry Smith Notes: 3468e35cf81dSBarry Smith The default is 1 34693d5a8a6aSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or SNESSetLagJacobianPersists() was called. 3470e35cf81dSBarry Smith 3471e35cf81dSBarry Smith Level: intermediate 3472e35cf81dSBarry Smith 3473db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3474e35cf81dSBarry Smith 3475e35cf81dSBarry Smith @*/ 34769371c9d4SSatish Balay PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) { 3477e35cf81dSBarry Smith PetscFunctionBegin; 34780700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3479e35cf81dSBarry Smith *lag = snes->lagjacobian; 3480e35cf81dSBarry Smith PetscFunctionReturn(0); 3481e35cf81dSBarry Smith } 3482e35cf81dSBarry Smith 348337ec4e1aSPeter Brune /*@ 348437ec4e1aSPeter Brune SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple solves 348537ec4e1aSPeter Brune 348637ec4e1aSPeter Brune Logically collective on SNES 348737ec4e1aSPeter Brune 3488d8d19677SJose E. Roman Input Parameters: 348937ec4e1aSPeter Brune + snes - the SNES context 34909d7e2deaSPeter Brune - flg - jacobian lagging persists if true 349137ec4e1aSPeter Brune 349237ec4e1aSPeter Brune Options Database Keys: 34933d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34943d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34953d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34963d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 34973d5a8a6aSBarry Smith 349895452b02SPatrick Sanan Notes: 349995452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 350037ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 350137ec4e1aSPeter Brune timesteps may present huge efficiency gains. 350237ec4e1aSPeter Brune 350337ec4e1aSPeter Brune Level: developer 350437ec4e1aSPeter Brune 3505db781477SPatrick Sanan .seealso: `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 350637ec4e1aSPeter Brune 350737ec4e1aSPeter Brune @*/ 35089371c9d4SSatish Balay PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) { 350937ec4e1aSPeter Brune PetscFunctionBegin; 351037ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 351137ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 351237ec4e1aSPeter Brune snes->lagjac_persist = flg; 351337ec4e1aSPeter Brune PetscFunctionReturn(0); 351437ec4e1aSPeter Brune } 351537ec4e1aSPeter Brune 351637ec4e1aSPeter Brune /*@ 3517d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 351837ec4e1aSPeter Brune 351937ec4e1aSPeter Brune Logically Collective on SNES 352037ec4e1aSPeter Brune 3521d8d19677SJose E. Roman Input Parameters: 352237ec4e1aSPeter Brune + snes - the SNES context 35239d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 352437ec4e1aSPeter Brune 352537ec4e1aSPeter Brune Options Database Keys: 35263d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35273d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35283d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35293d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 353037ec4e1aSPeter Brune 353195452b02SPatrick Sanan Notes: 353295452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 353337ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 353437ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 353537ec4e1aSPeter Brune 353637ec4e1aSPeter Brune Level: developer 353737ec4e1aSPeter Brune 3538db781477SPatrick Sanan .seealso: `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 353937ec4e1aSPeter Brune 354037ec4e1aSPeter Brune @*/ 35419371c9d4SSatish Balay PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) { 354237ec4e1aSPeter Brune PetscFunctionBegin; 354337ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 354437ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 354537ec4e1aSPeter Brune snes->lagpre_persist = flg; 354637ec4e1aSPeter Brune PetscFunctionReturn(0); 354737ec4e1aSPeter Brune } 354837ec4e1aSPeter Brune 35499b94acceSBarry Smith /*@ 3550be5caee7SBarry Smith SNESSetForceIteration - force SNESSolve() to take at least one iteration regardless of the initial residual norm 3551be5caee7SBarry Smith 3552be5caee7SBarry Smith Logically Collective on SNES 3553be5caee7SBarry Smith 3554be5caee7SBarry Smith Input Parameters: 3555be5caee7SBarry Smith + snes - the SNES context 3556be5caee7SBarry Smith - force - PETSC_TRUE require at least one iteration 3557be5caee7SBarry Smith 3558be5caee7SBarry Smith Options Database Keys: 3559be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3560be5caee7SBarry Smith 3561be5caee7SBarry Smith Notes: 3562be5caee7SBarry Smith This is used sometimes with TS to prevent TS from detecting a false steady state solution 3563be5caee7SBarry Smith 3564be5caee7SBarry Smith Level: intermediate 3565be5caee7SBarry Smith 3566db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3567be5caee7SBarry Smith @*/ 35689371c9d4SSatish Balay PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) { 3569be5caee7SBarry Smith PetscFunctionBegin; 3570be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3571be5caee7SBarry Smith snes->forceiteration = force; 3572be5caee7SBarry Smith PetscFunctionReturn(0); 3573be5caee7SBarry Smith } 3574be5caee7SBarry Smith 357585216dc7SFande Kong /*@ 357685216dc7SFande Kong SNESGetForceIteration - Whether or not to force SNESSolve() take at least one iteration regardless of the initial residual norm 357785216dc7SFande Kong 357885216dc7SFande Kong Logically Collective on SNES 357985216dc7SFande Kong 358085216dc7SFande Kong Input Parameters: 358185216dc7SFande Kong . snes - the SNES context 358285216dc7SFande Kong 358385216dc7SFande Kong Output Parameter: 358485216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 358585216dc7SFande Kong 358606dd6b0eSSatish Balay Level: intermediate 358706dd6b0eSSatish Balay 3588db781477SPatrick Sanan .seealso: `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 358985216dc7SFande Kong @*/ 35909371c9d4SSatish Balay PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) { 359185216dc7SFande Kong PetscFunctionBegin; 359285216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 359385216dc7SFande Kong *force = snes->forceiteration; 359485216dc7SFande Kong PetscFunctionReturn(0); 359585216dc7SFande Kong } 3596be5caee7SBarry Smith 3597be5caee7SBarry Smith /*@ 3598d7a720efSLois Curfman McInnes SNESSetTolerances - Sets various parameters used in convergence tests. 35999b94acceSBarry Smith 36003f9fe445SBarry Smith Logically Collective on SNES 3601c7afd0dbSLois Curfman McInnes 36029b94acceSBarry Smith Input Parameters: 3603c7afd0dbSLois Curfman McInnes + snes - the SNES context 360470441072SBarry Smith . abstol - absolute convergence tolerance 360533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 36065358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 360733174efeSLois Curfman McInnes . maxit - maximum number of iterations 3608e71169deSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit) 3609fee21e36SBarry Smith 361033174efeSLois Curfman McInnes Options Database Keys: 361170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3612c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3613c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3614c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3615c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 36169b94acceSBarry Smith 3617d7a720efSLois Curfman McInnes Notes: 36189b94acceSBarry Smith The default maximum number of iterations is 50. 36199b94acceSBarry Smith The default maximum number of function evaluations is 1000. 36209b94acceSBarry Smith 362136851e7fSLois Curfman McInnes Level: intermediate 362236851e7fSLois Curfman McInnes 3623db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 36249b94acceSBarry Smith @*/ 36259371c9d4SSatish Balay PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) { 36263a40ed3dSBarry Smith PetscFunctionBegin; 36270700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3628c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3629c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3630c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3631c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3632c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3633c5eb9154SBarry Smith 3634ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 36355f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3636ab54825eSJed Brown snes->abstol = abstol; 3637ab54825eSJed Brown } 3638ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 36395f80ce2aSJacob 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); 3640ab54825eSJed Brown snes->rtol = rtol; 3641ab54825eSJed Brown } 3642ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 36435f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3644c60f73f4SPeter Brune snes->stol = stol; 3645ab54825eSJed Brown } 3646ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 364763a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3648ab54825eSJed Brown snes->max_its = maxit; 3649ab54825eSJed Brown } 3650ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 365163a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3652ab54825eSJed Brown snes->max_funcs = maxf; 3653ab54825eSJed Brown } 365488976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 36553a40ed3dSBarry Smith PetscFunctionReturn(0); 36569b94acceSBarry Smith } 36579b94acceSBarry Smith 3658e4d06f11SPatrick Farrell /*@ 3659e4d06f11SPatrick Farrell SNESSetDivergenceTolerance - Sets the divergence tolerance used for the SNES divergence test. 3660e4d06f11SPatrick Farrell 3661e4d06f11SPatrick Farrell Logically Collective on SNES 3662e4d06f11SPatrick Farrell 3663e4d06f11SPatrick Farrell Input Parameters: 3664e4d06f11SPatrick Farrell + snes - the SNES context 3665e4d06f11SPatrick Farrell - divtol - the divergence tolerance. Use -1 to deactivate the test. 3666e4d06f11SPatrick Farrell 3667e4d06f11SPatrick Farrell Options Database Keys: 3668a2b725a8SWilliam Gropp . -snes_divergence_tolerance <divtol> - Sets divtol 3669e4d06f11SPatrick Farrell 3670e4d06f11SPatrick Farrell Notes: 3671e4d06f11SPatrick Farrell The default divergence tolerance is 1e4. 3672e4d06f11SPatrick Farrell 3673e4d06f11SPatrick Farrell Level: intermediate 3674e4d06f11SPatrick Farrell 3675db781477SPatrick Sanan .seealso: `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3676e4d06f11SPatrick Farrell @*/ 36779371c9d4SSatish Balay PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) { 3678e4d06f11SPatrick Farrell PetscFunctionBegin; 3679e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3680e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3681e4d06f11SPatrick Farrell 3682e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3683e4d06f11SPatrick Farrell snes->divtol = divtol; 36849371c9d4SSatish Balay } else { 3685e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3686e4d06f11SPatrick Farrell } 3687e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3688e4d06f11SPatrick Farrell } 3689e4d06f11SPatrick Farrell 36909b94acceSBarry Smith /*@ 369133174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 369233174efeSLois Curfman McInnes 3693c7afd0dbSLois Curfman McInnes Not Collective 3694c7afd0dbSLois Curfman McInnes 369533174efeSLois Curfman McInnes Input Parameters: 3696c7afd0dbSLois Curfman McInnes + snes - the SNES context 369785385478SLisandro Dalcin . atol - absolute convergence tolerance 369833174efeSLois Curfman McInnes . rtol - relative convergence tolerance 369933174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 370033174efeSLois Curfman McInnes of the change in the solution between steps 370133174efeSLois Curfman McInnes . maxit - maximum number of iterations 3702c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3703fee21e36SBarry Smith 370433174efeSLois Curfman McInnes Notes: 37050298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 370633174efeSLois Curfman McInnes 370736851e7fSLois Curfman McInnes Level: intermediate 370836851e7fSLois Curfman McInnes 3709db781477SPatrick Sanan .seealso: `SNESSetTolerances()` 371033174efeSLois Curfman McInnes @*/ 37119371c9d4SSatish Balay PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) { 37123a40ed3dSBarry Smith PetscFunctionBegin; 37130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 371485385478SLisandro Dalcin if (atol) *atol = snes->abstol; 371533174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3716c60f73f4SPeter Brune if (stol) *stol = snes->stol; 371733174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 371833174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 37193a40ed3dSBarry Smith PetscFunctionReturn(0); 372033174efeSLois Curfman McInnes } 372133174efeSLois Curfman McInnes 3722e4d06f11SPatrick Farrell /*@ 3723e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3724e4d06f11SPatrick Farrell 3725e4d06f11SPatrick Farrell Not Collective 3726e4d06f11SPatrick Farrell 3727e4d06f11SPatrick Farrell Input Parameters: 3728e4d06f11SPatrick Farrell + snes - the SNES context 3729e4d06f11SPatrick Farrell - divtol - divergence tolerance 3730e4d06f11SPatrick Farrell 3731e4d06f11SPatrick Farrell Level: intermediate 3732e4d06f11SPatrick Farrell 3733db781477SPatrick Sanan .seealso: `SNESSetDivergenceTolerance()` 3734e4d06f11SPatrick Farrell @*/ 37359371c9d4SSatish Balay PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) { 3736e4d06f11SPatrick Farrell PetscFunctionBegin; 3737e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3738e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3739e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3740e4d06f11SPatrick Farrell } 3741e4d06f11SPatrick Farrell 374233174efeSLois Curfman McInnes /*@ 37439b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 37449b94acceSBarry Smith 37453f9fe445SBarry Smith Logically Collective on SNES 3746fee21e36SBarry Smith 3747c7afd0dbSLois Curfman McInnes Input Parameters: 3748c7afd0dbSLois Curfman McInnes + snes - the SNES context 3749c7afd0dbSLois Curfman McInnes - tol - tolerance 3750c7afd0dbSLois Curfman McInnes 37519b94acceSBarry Smith Options Database Key: 3752c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 37539b94acceSBarry Smith 375436851e7fSLois Curfman McInnes Level: intermediate 375536851e7fSLois Curfman McInnes 3756db781477SPatrick Sanan .seealso: `SNESSetTolerances()` 37579b94acceSBarry Smith @*/ 37589371c9d4SSatish Balay PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) { 37593a40ed3dSBarry Smith PetscFunctionBegin; 37600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3761c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 37629b94acceSBarry Smith snes->deltatol = tol; 37633a40ed3dSBarry Smith PetscFunctionReturn(0); 37649b94acceSBarry Smith } 37659b94acceSBarry Smith 37666ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 37676ba87a44SLisandro Dalcin 37689371c9d4SSatish Balay PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) { 3769b271bb04SBarry Smith PetscDrawLG lg; 3770b271bb04SBarry Smith PetscReal x, y, per; 3771b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3772b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3773b271bb04SBarry Smith PetscDraw draw; 3774b271bb04SBarry Smith 3775459f5d12SBarry Smith PetscFunctionBegin; 37764d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 37779566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 37789566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 37799566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 37809566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3781b271bb04SBarry Smith x = (PetscReal)n; 378277b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 378394c9c6d3SKarl Rupp else y = -15.0; 37849566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 37856934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 37869566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 37879566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3788b271bb04SBarry Smith } 3789b271bb04SBarry Smith 37909566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 37919566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 37929566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 37939566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "% elemts > .2*max elemt")); 37949566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3795b271bb04SBarry Smith x = (PetscReal)n; 3796b271bb04SBarry Smith y = 100.0 * per; 37979566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 37986934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 37999566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38009566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3801b271bb04SBarry Smith } 3802b271bb04SBarry Smith 38039566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 38049371c9d4SSatish Balay if (!n) { 38059371c9d4SSatish Balay prev = rnorm; 38069371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 38079371c9d4SSatish Balay } 38089566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38099566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3810b271bb04SBarry Smith x = (PetscReal)n; 3811b271bb04SBarry Smith y = (prev - rnorm) / prev; 38129566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38136934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38149566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38159566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3816b271bb04SBarry Smith } 3817b271bb04SBarry Smith 38189566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 38199566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38209566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38219566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3822b271bb04SBarry Smith x = (PetscReal)n; 3823b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3824b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 38259566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3826b271bb04SBarry Smith } 38276934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38289566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38299566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3830b271bb04SBarry Smith } 3831b271bb04SBarry Smith prev = rnorm; 3832b271bb04SBarry Smith PetscFunctionReturn(0); 3833b271bb04SBarry Smith } 3834b271bb04SBarry Smith 3835228d79bcSJed Brown /*@ 3836228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3837228d79bcSJed Brown 3838228d79bcSJed Brown Collective on SNES 3839228d79bcSJed Brown 3840228d79bcSJed Brown Input Parameters: 3841228d79bcSJed Brown + snes - nonlinear solver context obtained from SNESCreate() 3842228d79bcSJed Brown . iter - iteration number 3843228d79bcSJed Brown - rnorm - relative norm of the residual 3844228d79bcSJed Brown 3845228d79bcSJed Brown Notes: 3846228d79bcSJed Brown This routine is called by the SNES implementations. 3847228d79bcSJed Brown It does not typically need to be called by the user. 3848228d79bcSJed Brown 3849228d79bcSJed Brown Level: developer 3850228d79bcSJed Brown 3851db781477SPatrick Sanan .seealso: `SNESMonitorSet()` 3852228d79bcSJed Brown @*/ 38539371c9d4SSatish Balay PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) { 38547a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 38557a03ce2fSLisandro Dalcin 38567a03ce2fSLisandro Dalcin PetscFunctionBegin; 38579566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 3858*48a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 38599566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 38607a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 38617a03ce2fSLisandro Dalcin } 38627a03ce2fSLisandro Dalcin 38639b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 38649b94acceSBarry Smith 3865bf388a1fSBarry Smith /*MC 3866bf388a1fSBarry Smith SNESMonitorFunction - functional form passed to SNESMonitorSet() to monitor convergence of nonlinear solver 3867bf388a1fSBarry Smith 3868bf388a1fSBarry Smith Synopsis: 3869aaa7dc30SBarry Smith #include <petscsnes.h> 3870bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3871bf388a1fSBarry Smith 38721843f636SBarry Smith Collective on snes 38731843f636SBarry Smith 38741843f636SBarry Smith Input Parameters: 3875bf388a1fSBarry Smith + snes - the SNES context 3876bf388a1fSBarry Smith . its - iteration number 3877bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3878bf388a1fSBarry Smith - mctx - [optional] monitoring context 3879bf388a1fSBarry Smith 3880878cb397SSatish Balay Level: advanced 3881878cb397SSatish Balay 3882db781477SPatrick Sanan .seealso: `SNESMonitorSet()`, `SNESMonitorGet()` 3883bf388a1fSBarry Smith M*/ 3884bf388a1fSBarry Smith 38859b94acceSBarry Smith /*@C 3886a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 38879b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 38889b94acceSBarry Smith progress. 38899b94acceSBarry Smith 38903f9fe445SBarry Smith Logically Collective on SNES 3891fee21e36SBarry Smith 3892c7afd0dbSLois Curfman McInnes Input Parameters: 3893c7afd0dbSLois Curfman McInnes + snes - the SNES context 38946e4dcb14SBarry Smith . f - the monitor function, see SNESMonitorFunction for the calling sequence 3895b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 38960298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3897b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 38980298fd71SBarry Smith (may be NULL) 38999b94acceSBarry Smith 39009665c990SLois Curfman McInnes Options Database Keys: 3901a6570f20SBarry Smith + -snes_monitor - sets SNESMonitorDefault() 3902798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 3903cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3904c7afd0dbSLois Curfman McInnes been hardwired into a code by 3905a6570f20SBarry Smith calls to SNESMonitorSet(), but 3906c7afd0dbSLois Curfman McInnes does not cancel those set via 3907c7afd0dbSLois Curfman McInnes the options database. 39089665c990SLois Curfman McInnes 3909639f9d9dSBarry Smith Notes: 39106bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3911a6570f20SBarry Smith SNESMonitorSet() multiple times; all will be called in the 39126bc08f3fSLois Curfman McInnes order in which they were set. 3913639f9d9dSBarry Smith 391495452b02SPatrick Sanan Fortran Notes: 391595452b02SPatrick Sanan Only a single monitor function can be set for each SNES object 3916025f1a04SBarry Smith 391736851e7fSLois Curfman McInnes Level: intermediate 391836851e7fSLois Curfman McInnes 3919db781477SPatrick Sanan .seealso: `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 39209b94acceSBarry Smith @*/ 39219371c9d4SSatish Balay PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) { 3922b90d0a6eSBarry Smith PetscInt i; 392378064530SBarry Smith PetscBool identical; 3924b90d0a6eSBarry Smith 39253a40ed3dSBarry Smith PetscFunctionBegin; 39260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3927b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 39289566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 392978064530SBarry Smith if (identical) PetscFunctionReturn(0); 3930649052a6SBarry Smith } 39315f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 39326e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3933b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3934639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 39353a40ed3dSBarry Smith PetscFunctionReturn(0); 39369b94acceSBarry Smith } 39379b94acceSBarry Smith 3938a278d85bSSatish Balay /*@ 3939a6570f20SBarry Smith SNESMonitorCancel - Clears all the monitor functions for a SNES object. 39405cd90555SBarry Smith 39413f9fe445SBarry Smith Logically Collective on SNES 3942c7afd0dbSLois Curfman McInnes 39435cd90555SBarry Smith Input Parameters: 39445cd90555SBarry Smith . snes - the SNES context 39455cd90555SBarry Smith 39461a480d89SAdministrator Options Database Key: 3947a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3948a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3949c7afd0dbSLois Curfman McInnes set via the options database 39505cd90555SBarry Smith 39515cd90555SBarry Smith Notes: 39525cd90555SBarry Smith There is no way to clear one specific monitor from a SNES object. 39535cd90555SBarry Smith 395436851e7fSLois Curfman McInnes Level: intermediate 395536851e7fSLois Curfman McInnes 3956db781477SPatrick Sanan .seealso: `SNESMonitorDefault()`, `SNESMonitorSet()` 39575cd90555SBarry Smith @*/ 39589371c9d4SSatish Balay PetscErrorCode SNESMonitorCancel(SNES snes) { 3959d952e501SBarry Smith PetscInt i; 3960d952e501SBarry Smith 39615cd90555SBarry Smith PetscFunctionBegin; 39620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3963d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 3964*48a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 3965d952e501SBarry Smith } 39665cd90555SBarry Smith snes->numbermonitors = 0; 39675cd90555SBarry Smith PetscFunctionReturn(0); 39685cd90555SBarry Smith } 39695cd90555SBarry Smith 3970bf388a1fSBarry Smith /*MC 3971bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3972bf388a1fSBarry Smith 3973bf388a1fSBarry Smith Synopsis: 3974aaa7dc30SBarry Smith #include <petscsnes.h> 3975bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3976bf388a1fSBarry Smith 39771843f636SBarry Smith Collective on snes 39781843f636SBarry Smith 39791843f636SBarry Smith Input Parameters: 3980bf388a1fSBarry Smith + snes - the SNES context 3981bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3982bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 3983bf388a1fSBarry Smith . gnorm - 2-norm of current step 39841843f636SBarry Smith . f - 2-norm of function 39851843f636SBarry Smith - cctx - [optional] convergence context 39861843f636SBarry Smith 39871843f636SBarry Smith Output Parameter: 39881843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 3989bf388a1fSBarry Smith 3990878cb397SSatish Balay Level: intermediate 3991bf388a1fSBarry Smith 3992db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 3993bf388a1fSBarry Smith M*/ 3994bf388a1fSBarry Smith 39959b94acceSBarry Smith /*@C 39969b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 39979b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 39989b94acceSBarry Smith 39993f9fe445SBarry Smith Logically Collective on SNES 4000fee21e36SBarry Smith 4001c7afd0dbSLois Curfman McInnes Input Parameters: 4002c7afd0dbSLois Curfman McInnes + snes - the SNES context 4003bf388a1fSBarry Smith . SNESConvergenceTestFunction - routine to test for convergence 40040298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 4005cf90aa19SBarry Smith - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 40069b94acceSBarry Smith 400736851e7fSLois Curfman McInnes Level: advanced 400836851e7fSLois Curfman McInnes 4009db781477SPatrick Sanan .seealso: `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 40109b94acceSBarry Smith @*/ 40119371c9d4SSatish Balay PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) { 40123a40ed3dSBarry Smith PetscFunctionBegin; 40130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4014e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 40151baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4016bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 40177f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 401885385478SLisandro Dalcin snes->cnvP = cctx; 40193a40ed3dSBarry Smith PetscFunctionReturn(0); 40209b94acceSBarry Smith } 40219b94acceSBarry Smith 402252baeb72SSatish Balay /*@ 4023184914b5SBarry Smith SNESGetConvergedReason - Gets the reason the SNES iteration was stopped. 4024184914b5SBarry Smith 4025184914b5SBarry Smith Not Collective 4026184914b5SBarry Smith 4027184914b5SBarry Smith Input Parameter: 4028184914b5SBarry Smith . snes - the SNES context 4029184914b5SBarry Smith 4030184914b5SBarry Smith Output Parameter: 40314d0a8057SBarry Smith . reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 4032184914b5SBarry Smith manual pages for the individual convergence tests for complete lists 4033184914b5SBarry Smith 40346a4d7782SBarry Smith Options Database: 40356a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 40366a4d7782SBarry Smith 4037184914b5SBarry Smith Level: intermediate 4038184914b5SBarry Smith 403995452b02SPatrick Sanan Notes: 404095452b02SPatrick Sanan Should only be called after the call the SNESSolve() is complete, if it is called earlier it returns the value SNES__CONVERGED_ITERATING. 4041184914b5SBarry Smith 4042db781477SPatrick Sanan .seealso: `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason` 4043184914b5SBarry Smith @*/ 40449371c9d4SSatish Balay PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) { 4045184914b5SBarry Smith PetscFunctionBegin; 40460700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 40474482741eSBarry Smith PetscValidPointer(reason, 2); 4048184914b5SBarry Smith *reason = snes->reason; 4049184914b5SBarry Smith PetscFunctionReturn(0); 4050184914b5SBarry Smith } 4051184914b5SBarry Smith 4052c4421ceaSFande Kong /*@C 4053c4421ceaSFande Kong SNESGetConvergedReasonString - Return a human readable string for snes converged reason 4054c4421ceaSFande Kong 4055c4421ceaSFande Kong Not Collective 4056c4421ceaSFande Kong 4057c4421ceaSFande Kong Input Parameter: 4058c4421ceaSFande Kong . snes - the SNES context 4059c4421ceaSFande Kong 4060c4421ceaSFande Kong Output Parameter: 4061c4421ceaSFande Kong . strreason - a human readable string that describes SNES converged reason 4062c4421ceaSFande Kong 406399c90e12SSatish Balay Level: beginner 4064c4421ceaSFande Kong 4065db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()` 4066c4421ceaSFande Kong @*/ 40679371c9d4SSatish Balay PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) { 4068c4421ceaSFande Kong PetscFunctionBegin; 4069c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4070dadcf809SJacob Faibussowitsch PetscValidPointer(strreason, 2); 4071c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 4072c4421ceaSFande Kong PetscFunctionReturn(0); 4073c4421ceaSFande Kong } 4074c4421ceaSFande Kong 407533866048SMatthew G. Knepley /*@ 407633866048SMatthew G. Knepley SNESSetConvergedReason - Sets the reason the SNES iteration was stopped. 407733866048SMatthew G. Knepley 407833866048SMatthew G. Knepley Not Collective 407933866048SMatthew G. Knepley 408033866048SMatthew G. Knepley Input Parameters: 408133866048SMatthew G. Knepley + snes - the SNES context 408233866048SMatthew G. Knepley - reason - negative value indicates diverged, positive value converged, see SNESConvergedReason or the 408333866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 408433866048SMatthew G. Knepley 408533866048SMatthew G. Knepley Level: intermediate 408633866048SMatthew G. Knepley 4087db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 408833866048SMatthew G. Knepley @*/ 40899371c9d4SSatish Balay PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) { 409033866048SMatthew G. Knepley PetscFunctionBegin; 409133866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 409233866048SMatthew G. Knepley snes->reason = reason; 409333866048SMatthew G. Knepley PetscFunctionReturn(0); 409433866048SMatthew G. Knepley } 409533866048SMatthew G. Knepley 4096c9005455SLois Curfman McInnes /*@ 4097c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4098c9005455SLois Curfman McInnes 40993f9fe445SBarry Smith Logically Collective on SNES 4100fee21e36SBarry Smith 4101c7afd0dbSLois Curfman McInnes Input Parameters: 4102c7afd0dbSLois Curfman McInnes + snes - iterative context obtained from SNESCreate() 41038c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4104cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4105758f92a0SBarry Smith . na - size of a and its 410664731454SLois Curfman McInnes - reset - PETSC_TRUE indicates each new nonlinear solve resets the history counter to zero, 4107758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4108c7afd0dbSLois Curfman McInnes 4109308dcc3eSBarry Smith Notes: 41100298fd71SBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' PETSC_DECIDE or PETSC_DEFAULT then a 4111308dcc3eSBarry Smith default array of length 10000 is allocated. 4112308dcc3eSBarry Smith 4113c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4114c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4115c9005455SLois Curfman McInnes during the section of code that is being timed. 4116c9005455SLois Curfman McInnes 411736851e7fSLois Curfman McInnes Level: intermediate 411836851e7fSLois Curfman McInnes 4119db781477SPatrick Sanan .seealso: `SNESGetConvergenceHistory()` 4120758f92a0SBarry Smith 4121c9005455SLois Curfman McInnes @*/ 41229371c9d4SSatish Balay PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) { 41233a40ed3dSBarry Smith PetscFunctionBegin; 41240700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4125064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a, 2); 4126a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its, 3); 41277a1ec6d4SBarry Smith if (!a) { 4128308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 41299566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4130071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4131308dcc3eSBarry Smith } 4132c9005455SLois Curfman McInnes snes->conv_hist = a; 4133758f92a0SBarry Smith snes->conv_hist_its = its; 4134115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4135a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4136758f92a0SBarry Smith snes->conv_hist_reset = reset; 4137758f92a0SBarry Smith PetscFunctionReturn(0); 4138758f92a0SBarry Smith } 4139758f92a0SBarry Smith 4140308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4141c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4142c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 414399e0435eSBarry Smith 41449371c9d4SSatish Balay PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) { 4145308dcc3eSBarry Smith mxArray *mat; 4146308dcc3eSBarry Smith PetscInt i; 4147308dcc3eSBarry Smith PetscReal *ar; 4148308dcc3eSBarry Smith 4149308dcc3eSBarry Smith PetscFunctionBegin; 4150308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4151308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4152f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 4153308dcc3eSBarry Smith PetscFunctionReturn(mat); 4154308dcc3eSBarry Smith } 4155308dcc3eSBarry Smith #endif 4156308dcc3eSBarry Smith 41570c4c9dddSBarry Smith /*@C 4158758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4159758f92a0SBarry Smith 41603f9fe445SBarry Smith Not Collective 4161758f92a0SBarry Smith 4162758f92a0SBarry Smith Input Parameter: 4163758f92a0SBarry Smith . snes - iterative context obtained from SNESCreate() 4164758f92a0SBarry Smith 4165758f92a0SBarry Smith Output Parameters: 4166a2b725a8SWilliam Gropp + a - array to hold history 4167758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4168758f92a0SBarry Smith negative if not converged) for each solve. 4169758f92a0SBarry Smith - na - size of a and its 4170758f92a0SBarry Smith 4171758f92a0SBarry Smith Notes: 4172758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4173758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4174758f92a0SBarry Smith 4175758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4176758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4177758f92a0SBarry Smith during the section of code that is being timed. 4178758f92a0SBarry Smith 4179758f92a0SBarry Smith Level: intermediate 4180758f92a0SBarry Smith 4181db781477SPatrick Sanan .seealso: `SNESSetConvergenceHistory()` 4182758f92a0SBarry Smith 4183758f92a0SBarry Smith @*/ 41849371c9d4SSatish Balay PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) { 4185758f92a0SBarry Smith PetscFunctionBegin; 41860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4187758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4188758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4189115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 41903a40ed3dSBarry Smith PetscFunctionReturn(0); 4191c9005455SLois Curfman McInnes } 4192c9005455SLois Curfman McInnes 4193ac226902SBarry Smith /*@C 419476b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4195eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 41967e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 419776b2cf59SMatthew Knepley 41983f9fe445SBarry Smith Logically Collective on SNES 419976b2cf59SMatthew Knepley 420076b2cf59SMatthew Knepley Input Parameters: 4201a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4202a2b725a8SWilliam Gropp - func - The function 420376b2cf59SMatthew Knepley 420476b2cf59SMatthew Knepley Calling sequence of func: 4205a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 420676b2cf59SMatthew Knepley 420776b2cf59SMatthew Knepley . step - The current step of the iteration 420876b2cf59SMatthew Knepley 4209fe97e370SBarry Smith Level: advanced 4210fe97e370SBarry Smith 42116b7fb656SBarry Smith Note: 42126b7fb656SBarry 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() 4213fe97e370SBarry Smith This is not used by most users. 421476b2cf59SMatthew Knepley 42156b7fb656SBarry 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. 42166b7fb656SBarry Smith 4217db781477SPatrick Sanan .seealso `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4218db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 421976b2cf59SMatthew Knepley @*/ 42209371c9d4SSatish Balay PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) { 422176b2cf59SMatthew Knepley PetscFunctionBegin; 42220700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4223e7788613SBarry Smith snes->ops->update = func; 422476b2cf59SMatthew Knepley PetscFunctionReturn(0); 422576b2cf59SMatthew Knepley } 422676b2cf59SMatthew Knepley 42279b94acceSBarry Smith /* 42289b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 42299b94acceSBarry Smith positive parameter delta. 42309b94acceSBarry Smith 42319b94acceSBarry Smith Input Parameters: 4232c7afd0dbSLois Curfman McInnes + snes - the SNES context 42339b94acceSBarry Smith . y - approximate solution of linear system 42349b94acceSBarry Smith . fnorm - 2-norm of current function 4235c7afd0dbSLois Curfman McInnes - delta - trust region size 42369b94acceSBarry Smith 42379b94acceSBarry Smith Output Parameters: 4238c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 42399b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 42409b94acceSBarry Smith region, and exceeds zero otherwise. 4241c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 42429b94acceSBarry Smith 42439b94acceSBarry Smith Note: 424404d7464bSBarry Smith For non-trust region methods such as SNESNEWTONLS, the parameter delta 42459b94acceSBarry Smith is set to be the maximum allowable step size. 42469b94acceSBarry Smith 42479b94acceSBarry Smith */ 42489371c9d4SSatish Balay PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm) { 4249064f8208SBarry Smith PetscReal nrm; 4250ea709b57SSatish Balay PetscScalar cnorm; 42513a40ed3dSBarry Smith 42523a40ed3dSBarry Smith PetscFunctionBegin; 42530700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42540700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 2); 4255c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 2); 4256184914b5SBarry Smith 42579566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 4258064f8208SBarry Smith if (nrm > *delta) { 4259064f8208SBarry Smith nrm = *delta / nrm; 4260064f8208SBarry Smith *gpnorm = (1.0 - nrm) * (*fnorm); 4261064f8208SBarry Smith cnorm = nrm; 42629566063dSJacob Faibussowitsch PetscCall(VecScale(y, cnorm)); 42639b94acceSBarry Smith *ynorm = *delta; 42649b94acceSBarry Smith } else { 42659b94acceSBarry Smith *gpnorm = 0.0; 4266064f8208SBarry Smith *ynorm = nrm; 42679b94acceSBarry Smith } 42683a40ed3dSBarry Smith PetscFunctionReturn(0); 42699b94acceSBarry Smith } 42709b94acceSBarry Smith 427191f3e32bSBarry Smith /*@C 427219a666eeSBarry Smith SNESConvergedReasonView - Displays the reason a SNES solve converged or diverged to a viewer 42732a359c20SBarry Smith 42742a359c20SBarry Smith Collective on SNES 42752a359c20SBarry Smith 42762a359c20SBarry Smith Parameter: 42772a359c20SBarry Smith + snes - iterative context obtained from SNESCreate() 42782a359c20SBarry Smith - viewer - the viewer to display the reason 42792a359c20SBarry Smith 42802a359c20SBarry Smith Options Database Keys: 4281ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4282ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4283eafd5ff0SAlex Lindsay 428419a666eeSBarry Smith Notes: 428519a666eeSBarry Smith To change the format of the output call PetscViewerPushFormat(viewer,format) before this call. Use PETSC_VIEWER_DEFAULT for the default, 428619a666eeSBarry Smith use PETSC_VIEWER_FAILED to only display a reason if it fails. 42872a359c20SBarry Smith 42882a359c20SBarry Smith Level: beginner 42892a359c20SBarry Smith 4290db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonViewFromOptions()`, 4291db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 42922a359c20SBarry Smith 42932a359c20SBarry Smith @*/ 42949371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) { 429575cca76cSMatthew G. Knepley PetscViewerFormat format; 42962a359c20SBarry Smith PetscBool isAscii; 42972a359c20SBarry Smith 42982a359c20SBarry Smith PetscFunctionBegin; 429919a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 43009566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 43012a359c20SBarry Smith if (isAscii) { 43029566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 43039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 430475cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 430575cca76cSMatthew G. Knepley DM dm; 430675cca76cSMatthew G. Knepley Vec u; 430775cca76cSMatthew G. Knepley PetscDS prob; 430875cca76cSMatthew G. Knepley PetscInt Nf, f; 430995cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 431095cbbfd3SMatthew G. Knepley void **exactCtx; 431175cca76cSMatthew G. Knepley PetscReal error; 431275cca76cSMatthew G. Knepley 43139566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 43149566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 43159566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 43169566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 43179566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 43189566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 43199566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 43209566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 43219566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 432263a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 432375cca76cSMatthew G. Knepley } 4324eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 43252a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 432663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 43272a359c20SBarry Smith } else { 432863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 43292a359c20SBarry Smith } 4330eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 43312a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 433263a3b9bcSJacob 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)); 43332a359c20SBarry Smith } else { 433463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 43352a359c20SBarry Smith } 43362a359c20SBarry Smith } 43379566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 43382a359c20SBarry Smith } 43392a359c20SBarry Smith PetscFunctionReturn(0); 43402a359c20SBarry Smith } 43412a359c20SBarry Smith 4342c4421ceaSFande Kong /*@C 4343c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4344c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4345c4421ceaSFande Kong 4346c4421ceaSFande Kong Logically Collective on SNES 4347c4421ceaSFande Kong 4348c4421ceaSFande Kong Input Parameters: 4349c4421ceaSFande Kong + snes - the SNES context 4350c4421ceaSFande Kong . f - the snes converged reason view function 4351c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4352c4421ceaSFande Kong snes converged reason view routine (use NULL if no context is desired) 4353c4421ceaSFande Kong - reasonviewdestroy - [optional] routine that frees reasonview context 4354c4421ceaSFande Kong (may be NULL) 4355c4421ceaSFande Kong 4356c4421ceaSFande Kong Options Database Keys: 4357c4421ceaSFande Kong + -snes_converged_reason - sets a default SNESConvergedReasonView() 4358c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4359c4421ceaSFande Kong been hardwired into a code by 4360c4421ceaSFande Kong calls to SNESConvergedReasonViewSet(), but 4361c4421ceaSFande Kong does not cancel those set via 4362c4421ceaSFande Kong the options database. 4363c4421ceaSFande Kong 4364c4421ceaSFande Kong Notes: 4365c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4366c4421ceaSFande Kong SNESConvergedReasonViewSet() multiple times; all will be called in the 4367c4421ceaSFande Kong order in which they were set. 4368c4421ceaSFande Kong 4369c4421ceaSFande Kong Level: intermediate 4370c4421ceaSFande Kong 4371db781477SPatrick Sanan .seealso: `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4372c4421ceaSFande Kong @*/ 43739371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) { 4374c4421ceaSFande Kong PetscInt i; 4375c4421ceaSFande Kong PetscBool identical; 4376c4421ceaSFande Kong 4377c4421ceaSFande Kong PetscFunctionBegin; 4378c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4379c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 43809566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 4381c4421ceaSFande Kong if (identical) PetscFunctionReturn(0); 4382c4421ceaSFande Kong } 43835f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4384c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4385c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4386c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 4387c4421ceaSFande Kong PetscFunctionReturn(0); 4388c4421ceaSFande Kong } 4389c4421ceaSFande Kong 439091f3e32bSBarry Smith /*@ 439119a666eeSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a SNESReason is to be viewed. 4392c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 43932a359c20SBarry Smith 43942a359c20SBarry Smith Collective on SNES 43952a359c20SBarry Smith 43962a359c20SBarry Smith Input Parameters: 43972a359c20SBarry Smith . snes - the SNES object 43982a359c20SBarry Smith 43992a359c20SBarry Smith Level: intermediate 44002a359c20SBarry Smith 4401db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 440219a666eeSBarry Smith 44032a359c20SBarry Smith @*/ 44049371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) { 44052a359c20SBarry Smith PetscViewer viewer; 44062a359c20SBarry Smith PetscBool flg; 44072a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 44082a359c20SBarry Smith PetscViewerFormat format; 4409c4421ceaSFande Kong PetscInt i; 44102a359c20SBarry Smith 44112a359c20SBarry Smith PetscFunctionBegin; 44122a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 44132a359c20SBarry Smith incall = PETSC_TRUE; 4414c4421ceaSFande Kong 4415c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 4416*48a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4417c4421ceaSFande Kong 4418c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 44199566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 44202a359c20SBarry Smith if (flg) { 44219566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 44229566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 44239566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 44249566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 44252a359c20SBarry Smith } 44262a359c20SBarry Smith incall = PETSC_FALSE; 44272a359c20SBarry Smith PetscFunctionReturn(0); 44282a359c20SBarry Smith } 44292a359c20SBarry Smith 4430487a658cSBarry Smith /*@ 4431f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4432f69a0ea3SMatthew Knepley Call SNESSolve() after calling SNESCreate() and optional routines of the form SNESSetXXX(). 44339b94acceSBarry Smith 4434c7afd0dbSLois Curfman McInnes Collective on SNES 4435c7afd0dbSLois Curfman McInnes 4436b2002411SLois Curfman McInnes Input Parameters: 4437c7afd0dbSLois Curfman McInnes + snes - the SNES context 44380298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 443985385478SLisandro Dalcin - x - the solution vector. 44409b94acceSBarry Smith 4441b2002411SLois Curfman McInnes Notes: 44428ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 44436b7fb656SBarry Smith for the nonlinear solve prior to calling SNESSolve(). In particular, 44448ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 44458ddd3da0SLois Curfman McInnes this vector to zero by calling VecSet(). 44468ddd3da0SLois Curfman McInnes 444736851e7fSLois Curfman McInnes Level: beginner 444836851e7fSLois Curfman McInnes 4449db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4450db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4451db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 44529b94acceSBarry Smith @*/ 44539371c9d4SSatish Balay PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) { 4454ace3abfcSBarry Smith PetscBool flg; 4455efd51863SBarry Smith PetscInt grid; 44560298fd71SBarry Smith Vec xcreated = NULL; 4457caa4e7f2SJed Brown DM dm; 4458052efed2SBarry Smith 44593a40ed3dSBarry Smith PetscFunctionBegin; 44600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4461a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4462a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 44630700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 446485385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 446585385478SLisandro Dalcin 446634b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 446706fc46c8SMatthew G. Knepley { 446806fc46c8SMatthew G. Knepley PetscViewer viewer; 446906fc46c8SMatthew G. Knepley PetscViewerFormat format; 44707c88af5aSMatthew G. Knepley PetscInt num; 447106fc46c8SMatthew G. Knepley PetscBool flg; 447206fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 447306fc46c8SMatthew G. Knepley 447406fc46c8SMatthew G. Knepley if (!incall) { 447534b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 44769566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 447706fc46c8SMatthew G. Knepley if (flg) { 447806fc46c8SMatthew G. Knepley PetscConvEst conv; 447946079b62SMatthew G. Knepley DM dm; 448046079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 448146079b62SMatthew G. Knepley PetscInt Nf; 448206fc46c8SMatthew G. Knepley 448306fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 44849566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 44859566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 44869566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 44879566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 44889566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 44899566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 44909566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 44919566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 44929566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 44939566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 44949566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 44959566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 44969566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 44979566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 449806fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 449906fc46c8SMatthew G. Knepley } 450034b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4501b2588ea6SMatthew G. Knepley num = 1; 45029566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 450334b4d3a8SMatthew G. Knepley if (flg) { 450434b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 450534b4d3a8SMatthew G. Knepley 450634b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 45079566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45089566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45099566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45109566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 45119566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 45129566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 45139566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 451434b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 451534b4d3a8SMatthew G. Knepley } 45167c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 45177c88af5aSMatthew G. Knepley num = 0; 45189566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 45197c88af5aSMatthew G. Knepley if (num) { 45207c88af5aSMatthew G. Knepley DMAdaptor adaptor; 45217c88af5aSMatthew G. Knepley 45227c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 45239566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45249566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45259566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45269566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 45279566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 45289566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 45299566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 45307c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 45317c88af5aSMatthew G. Knepley } 453206fc46c8SMatthew G. Knepley } 453306fc46c8SMatthew G. Knepley } 453441e867a5SStefano Zampini if (!x) { x = snes->vec_sol; } 4535caa4e7f2SJed Brown if (!x) { 45369566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45379566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4538a69afd8bSBarry Smith x = xcreated; 4539a69afd8bSBarry Smith } 45409566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4541f05ece33SBarry Smith 45429566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4543efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 454485385478SLisandro Dalcin /* set solution vector */ 45459566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 45469566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 454785385478SLisandro Dalcin snes->vec_sol = x; 45489566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4549caa4e7f2SJed Brown 4550caa4e7f2SJed Brown /* set affine vector if provided */ 45519566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 45529566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 455385385478SLisandro Dalcin snes->vec_rhs = b; 455485385478SLisandro Dalcin 45555f80ce2aSJacob 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"); 45565f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 45575f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 4558154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 45599566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); 45609566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->vec_sol_update)); 4561154060b5SMatthew G. Knepley } 45629566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 45639566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 45643f149594SLisandro Dalcin 45657eee914bSBarry Smith if (!grid) { 456625e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4567dd568438SSatish Balay } 4568d25893d9SBarry Smith 4569abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 45709371c9d4SSatish Balay if (snes->counters_reset) { 45719371c9d4SSatish Balay snes->nfuncs = 0; 45729371c9d4SSatish Balay snes->linear_its = 0; 45739371c9d4SSatish Balay snes->numFailures = 0; 45749371c9d4SSatish Balay } 4575d5e45103SBarry Smith 45769566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4577dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 45789566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 45795f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason"); 4580422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 45813f149594SLisandro Dalcin 458237ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 458337ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 458437ec4e1aSPeter Brune 45859566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 45869566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4587c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 45889566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 45895968eb51SBarry Smith 45905f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 45919c8e83a9SBarry Smith if (snes->reason < 0) break; 4592efd51863SBarry Smith if (grid < snes->gridsequence) { 4593efd51863SBarry Smith DM fine; 4594efd51863SBarry Smith Vec xnew; 4595efd51863SBarry Smith Mat interp; 4596efd51863SBarry Smith 45979566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 45985f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 45999566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 46009566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 46019566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 46029566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 46039566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4604efd51863SBarry Smith x = xnew; 4605efd51863SBarry Smith 46069566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 46079566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 46089566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 46099566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 46109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4611efd51863SBarry Smith } 4612efd51863SBarry Smith } 46139566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 46149566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 46159566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 46169566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 46173f7e2da0SPeter Brune 46189566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 46199566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 46203a40ed3dSBarry Smith PetscFunctionReturn(0); 46219b94acceSBarry Smith } 46229b94acceSBarry Smith 46239b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 46249b94acceSBarry Smith 462582bf6240SBarry Smith /*@C 46264b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 46279b94acceSBarry Smith 4628fee21e36SBarry Smith Collective on SNES 4629fee21e36SBarry Smith 4630c7afd0dbSLois Curfman McInnes Input Parameters: 4631c7afd0dbSLois Curfman McInnes + snes - the SNES context 4632454a90a3SBarry Smith - type - a known method 4633c7afd0dbSLois Curfman McInnes 4634c7afd0dbSLois Curfman McInnes Options Database Key: 4635454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 463604d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4637ae12b187SLois Curfman McInnes 46389b94acceSBarry Smith Notes: 4639e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 464004d7464bSBarry Smith + SNESNEWTONLS - Newton's method with line search 4641c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4642a2b725a8SWilliam Gropp - SNESNEWTONTR - Newton's method with trust region 4643c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 46449b94acceSBarry Smith 4645ae12b187SLois Curfman McInnes Normally, it is best to use the SNESSetFromOptions() command and then 4646ae12b187SLois Curfman McInnes set the SNES solver type from the options database rather than by using 4647ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4648ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4649ae12b187SLois Curfman McInnes The SNESSetType() routine is provided for those situations where it 4650ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4651ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4652ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4653ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4654b0a32e0cSBarry Smith appropriate method. 465536851e7fSLois Curfman McInnes 465695452b02SPatrick Sanan Developer Notes: 465795452b02SPatrick Sanan SNESRegister() adds a constructor for a new SNESType to SNESList, SNESSetType() locates 46588f6c3df8SBarry Smith the constructor in that list and calls it to create the spexific object. 46598f6c3df8SBarry Smith 466036851e7fSLois Curfman McInnes Level: intermediate 4661a703fe33SLois Curfman McInnes 4662db781477SPatrick Sanan .seealso: `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 4663435da068SBarry Smith 46649b94acceSBarry Smith @*/ 46659371c9d4SSatish Balay PetscErrorCode SNESSetType(SNES snes, SNESType type) { 4666ace3abfcSBarry Smith PetscBool match; 46675f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 46683a40ed3dSBarry Smith 46693a40ed3dSBarry Smith PetscFunctionBegin; 46700700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 46714482741eSBarry Smith PetscValidCharPointer(type, 2); 467282bf6240SBarry Smith 46739566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 46740f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 467592ff6ae8SBarry Smith 46769566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 46775f80ce2aSJacob Faibussowitsch PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 467875396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4679dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 468075396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 46819e5d0892SLisandro Dalcin snes->ops->setup = NULL; 46829e5d0892SLisandro Dalcin snes->ops->solve = NULL; 46839e5d0892SLisandro Dalcin snes->ops->view = NULL; 46849e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 46859e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 46867fe760d5SStefano Zampini 46877fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 46889566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 46897fe760d5SStefano Zampini 469075396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 469175396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4692f5af7f23SKarl Rupp 46939566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 46949566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 46953a40ed3dSBarry Smith PetscFunctionReturn(0); 46969b94acceSBarry Smith } 46979b94acceSBarry Smith 46989b94acceSBarry Smith /*@C 46999a28b0a6SLois Curfman McInnes SNESGetType - Gets the SNES method type and name (as a string). 47009b94acceSBarry Smith 4701c7afd0dbSLois Curfman McInnes Not Collective 4702c7afd0dbSLois Curfman McInnes 47039b94acceSBarry Smith Input Parameter: 47044b0e389bSBarry Smith . snes - nonlinear solver context 47059b94acceSBarry Smith 47069b94acceSBarry Smith Output Parameter: 47073a7fca6bSBarry Smith . type - SNES method (a character string) 47089b94acceSBarry Smith 470936851e7fSLois Curfman McInnes Level: intermediate 471036851e7fSLois Curfman McInnes 47119b94acceSBarry Smith @*/ 47129371c9d4SSatish Balay PetscErrorCode SNESGetType(SNES snes, SNESType *type) { 47133a40ed3dSBarry Smith PetscFunctionBegin; 47140700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47154482741eSBarry Smith PetscValidPointer(type, 2); 47167adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 47173a40ed3dSBarry Smith PetscFunctionReturn(0); 47189b94acceSBarry Smith } 47199b94acceSBarry Smith 47203cd8a7caSMatthew G. Knepley /*@ 47213cd8a7caSMatthew G. Knepley SNESSetSolution - Sets the solution vector for use by the SNES routines. 47223cd8a7caSMatthew G. Knepley 4723d083f849SBarry Smith Logically Collective on SNES 47243cd8a7caSMatthew G. Knepley 47253cd8a7caSMatthew G. Knepley Input Parameters: 47263cd8a7caSMatthew G. Knepley + snes - the SNES context obtained from SNESCreate() 47273cd8a7caSMatthew G. Knepley - u - the solution vector 47283cd8a7caSMatthew G. Knepley 47293cd8a7caSMatthew G. Knepley Level: beginner 47303cd8a7caSMatthew G. Knepley 47313cd8a7caSMatthew G. Knepley @*/ 47329371c9d4SSatish Balay PetscErrorCode SNESSetSolution(SNES snes, Vec u) { 47333cd8a7caSMatthew G. Knepley DM dm; 47343cd8a7caSMatthew G. Knepley 47353cd8a7caSMatthew G. Knepley PetscFunctionBegin; 47363cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47373cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 47389566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 47399566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 47403cd8a7caSMatthew G. Knepley 47413cd8a7caSMatthew G. Knepley snes->vec_sol = u; 47423cd8a7caSMatthew G. Knepley 47439566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 47449566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 47453cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 47463cd8a7caSMatthew G. Knepley } 47473cd8a7caSMatthew G. Knepley 474852baeb72SSatish Balay /*@ 47499b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4750c0df2a02SJed Brown stored. This is the fine grid solution when using SNESSetGridSequence(). 47519b94acceSBarry Smith 4752c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4753c7afd0dbSLois Curfman McInnes 47549b94acceSBarry Smith Input Parameter: 47559b94acceSBarry Smith . snes - the SNES context 47569b94acceSBarry Smith 47579b94acceSBarry Smith Output Parameter: 47589b94acceSBarry Smith . x - the solution 47599b94acceSBarry Smith 476070e92668SMatthew Knepley Level: intermediate 476136851e7fSLois Curfman McInnes 4762db781477SPatrick Sanan .seealso: `SNESGetSolutionUpdate()`, `SNESGetFunction()` 47639b94acceSBarry Smith @*/ 47649371c9d4SSatish Balay PetscErrorCode SNESGetSolution(SNES snes, Vec *x) { 47653a40ed3dSBarry Smith PetscFunctionBegin; 47660700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47674482741eSBarry Smith PetscValidPointer(x, 2); 476885385478SLisandro Dalcin *x = snes->vec_sol; 476970e92668SMatthew Knepley PetscFunctionReturn(0); 477070e92668SMatthew Knepley } 477170e92668SMatthew Knepley 477252baeb72SSatish Balay /*@ 47739b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 47749b94acceSBarry Smith stored. 47759b94acceSBarry Smith 4776c7afd0dbSLois Curfman McInnes Not Collective, but Vec is parallel if SNES is parallel 4777c7afd0dbSLois Curfman McInnes 47789b94acceSBarry Smith Input Parameter: 47799b94acceSBarry Smith . snes - the SNES context 47809b94acceSBarry Smith 47819b94acceSBarry Smith Output Parameter: 47829b94acceSBarry Smith . x - the solution update 47839b94acceSBarry Smith 478436851e7fSLois Curfman McInnes Level: advanced 478536851e7fSLois Curfman McInnes 4786db781477SPatrick Sanan .seealso: `SNESGetSolution()`, `SNESGetFunction()` 47879b94acceSBarry Smith @*/ 47889371c9d4SSatish Balay PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x) { 47893a40ed3dSBarry Smith PetscFunctionBegin; 47900700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47914482741eSBarry Smith PetscValidPointer(x, 2); 479285385478SLisandro Dalcin *x = snes->vec_sol_update; 47933a40ed3dSBarry Smith PetscFunctionReturn(0); 47949b94acceSBarry Smith } 47959b94acceSBarry Smith 47969b94acceSBarry Smith /*@C 47973638b69dSLois Curfman McInnes SNESGetFunction - Returns the vector where the function is stored. 47989b94acceSBarry Smith 4799a63bb30eSJed Brown Not Collective, but Vec is parallel if SNES is parallel. Collective if Vec is requested, but has not been created yet. 4800c7afd0dbSLois Curfman McInnes 48019b94acceSBarry Smith Input Parameter: 48029b94acceSBarry Smith . snes - the SNES context 48039b94acceSBarry Smith 4804d8d19677SJose E. Roman Output Parameters: 48050298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4806f8b49ee9SBarry Smith . f - the function (or NULL if you don't want it); see SNESFunction for calling sequence details 48070298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 48089b94acceSBarry Smith 480936851e7fSLois Curfman McInnes Level: advanced 481036851e7fSLois Curfman McInnes 481104edfde5SBarry Smith Notes: The vector r DOES NOT, in general contain the current value of the SNES nonlinear function 481204edfde5SBarry Smith 4813db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 48149b94acceSBarry Smith @*/ 48159371c9d4SSatish Balay PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) { 48166cab3a1bSJed Brown DM dm; 4817a63bb30eSJed Brown 48183a40ed3dSBarry Smith PetscFunctionBegin; 48190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4820a63bb30eSJed Brown if (r) { 4821a63bb30eSJed Brown if (!snes->vec_func) { 4822a63bb30eSJed Brown if (snes->vec_rhs) { 48239566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4824a63bb30eSJed Brown } else if (snes->vec_sol) { 48259566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4826a63bb30eSJed Brown } else if (snes->dm) { 48279566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4828a63bb30eSJed Brown } 4829a63bb30eSJed Brown } 4830a63bb30eSJed Brown *r = snes->vec_func; 4831a63bb30eSJed Brown } 48329566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48339566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 48343a40ed3dSBarry Smith PetscFunctionReturn(0); 48359b94acceSBarry Smith } 48369b94acceSBarry Smith 4837c79ef259SPeter Brune /*@C 4838be95d8f1SBarry Smith SNESGetNGS - Returns the NGS function and context. 4839c79ef259SPeter Brune 4840c79ef259SPeter Brune Input Parameter: 4841c79ef259SPeter Brune . snes - the SNES context 4842c79ef259SPeter Brune 4843d8d19677SJose E. Roman Output Parameters: 4844be95d8f1SBarry Smith + f - the function (or NULL) see SNESNGSFunction for details 48450298fd71SBarry Smith - ctx - the function context (or NULL) 4846c79ef259SPeter Brune 4847c79ef259SPeter Brune Level: advanced 4848c79ef259SPeter Brune 4849db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetFunction()` 4850c79ef259SPeter Brune @*/ 4851c79ef259SPeter Brune 48529371c9d4SSatish Balay PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) { 48536cab3a1bSJed Brown DM dm; 48546cab3a1bSJed Brown 4855646217ecSPeter Brune PetscFunctionBegin; 4856646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48579566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48589566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 4859646217ecSPeter Brune PetscFunctionReturn(0); 4860646217ecSPeter Brune } 4861646217ecSPeter Brune 48623c7409f5SSatish Balay /*@C 48633c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4864d850072dSLois Curfman McInnes SNES options in the database. 48653c7409f5SSatish Balay 48663f9fe445SBarry Smith Logically Collective on SNES 4867fee21e36SBarry Smith 4868d8d19677SJose E. Roman Input Parameters: 4869c7afd0dbSLois Curfman McInnes + snes - the SNES context 4870c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4871c7afd0dbSLois Curfman McInnes 4872d850072dSLois Curfman McInnes Notes: 4873a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4874c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4875d850072dSLois Curfman McInnes 487636851e7fSLois Curfman McInnes Level: advanced 487736851e7fSLois Curfman McInnes 4878db781477SPatrick Sanan .seealso: `SNESSetFromOptions()` 48793c7409f5SSatish Balay @*/ 48809371c9d4SSatish Balay PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) { 48813a40ed3dSBarry Smith PetscFunctionBegin; 48820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48839566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 48849566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 488535f5d045SPeter Brune if (snes->linesearch) { 48869566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 48879566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 488835f5d045SPeter Brune } 48899566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 48903a40ed3dSBarry Smith PetscFunctionReturn(0); 48913c7409f5SSatish Balay } 48923c7409f5SSatish Balay 48933c7409f5SSatish Balay /*@C 4894f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4895d850072dSLois Curfman McInnes SNES options in the database. 48963c7409f5SSatish Balay 48973f9fe445SBarry Smith Logically Collective on SNES 4898fee21e36SBarry Smith 4899c7afd0dbSLois Curfman McInnes Input Parameters: 4900c7afd0dbSLois Curfman McInnes + snes - the SNES context 4901c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4902c7afd0dbSLois Curfman McInnes 4903d850072dSLois Curfman McInnes Notes: 4904a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4905c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4906d850072dSLois Curfman McInnes 490736851e7fSLois Curfman McInnes Level: advanced 490836851e7fSLois Curfman McInnes 4909db781477SPatrick Sanan .seealso: `SNESGetOptionsPrefix()` 49103c7409f5SSatish Balay @*/ 49119371c9d4SSatish Balay PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) { 49123a40ed3dSBarry Smith PetscFunctionBegin; 49130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49149566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 49159566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 491635f5d045SPeter Brune if (snes->linesearch) { 49179566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 49189566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 491935f5d045SPeter Brune } 49209566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 49213a40ed3dSBarry Smith PetscFunctionReturn(0); 49223c7409f5SSatish Balay } 49233c7409f5SSatish Balay 49249ab63eb5SSatish Balay /*@C 49253c7409f5SSatish Balay SNESGetOptionsPrefix - Sets the prefix used for searching for all 49263c7409f5SSatish Balay SNES options in the database. 49273c7409f5SSatish Balay 4928c7afd0dbSLois Curfman McInnes Not Collective 4929c7afd0dbSLois Curfman McInnes 49303c7409f5SSatish Balay Input Parameter: 49313c7409f5SSatish Balay . snes - the SNES context 49323c7409f5SSatish Balay 49333c7409f5SSatish Balay Output Parameter: 49343c7409f5SSatish Balay . prefix - pointer to the prefix string used 49353c7409f5SSatish Balay 493695452b02SPatrick Sanan Notes: 493795452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 49389ab63eb5SSatish Balay sufficient length to hold the prefix. 49399ab63eb5SSatish Balay 494036851e7fSLois Curfman McInnes Level: advanced 494136851e7fSLois Curfman McInnes 4942db781477SPatrick Sanan .seealso: `SNESAppendOptionsPrefix()` 49433c7409f5SSatish Balay @*/ 49449371c9d4SSatish Balay PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) { 49453a40ed3dSBarry Smith PetscFunctionBegin; 49460700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49479566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 49483a40ed3dSBarry Smith PetscFunctionReturn(0); 49493c7409f5SSatish Balay } 49503c7409f5SSatish Balay 49513cea93caSBarry Smith /*@C 49521c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 49531c84c290SBarry Smith 49541c84c290SBarry Smith Not collective 49551c84c290SBarry Smith 49561c84c290SBarry Smith Input Parameters: 49571c84c290SBarry Smith + name_solver - name of a new user-defined solver 49581c84c290SBarry Smith - routine_create - routine to create method context 49591c84c290SBarry Smith 49601c84c290SBarry Smith Notes: 49611c84c290SBarry Smith SNESRegister() may be called multiple times to add several user-defined solvers. 49621c84c290SBarry Smith 49631c84c290SBarry Smith Sample usage: 49641c84c290SBarry Smith .vb 4965bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 49661c84c290SBarry Smith .ve 49671c84c290SBarry Smith 49681c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 49691c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 49701c84c290SBarry Smith or at runtime via the option 49711c84c290SBarry Smith $ -snes_type my_solver 49721c84c290SBarry Smith 49731c84c290SBarry Smith Level: advanced 49741c84c290SBarry Smith 49751c84c290SBarry Smith Note: If your function is not being put into a shared library then use SNESRegister() instead 49761c84c290SBarry Smith 4977db781477SPatrick Sanan .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()` 49783cea93caSBarry Smith 49797f6c08e0SMatthew Knepley Level: advanced 49803cea93caSBarry Smith @*/ 49819371c9d4SSatish Balay PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) { 4982b2002411SLois Curfman McInnes PetscFunctionBegin; 49839566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 49849566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 4985b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4986b2002411SLois Curfman McInnes } 4987da9b6338SBarry Smith 49889371c9d4SSatish Balay PetscErrorCode SNESTestLocalMin(SNES snes) { 498977431f27SBarry Smith PetscInt N, i, j; 4990da9b6338SBarry Smith Vec u, uh, fh; 4991da9b6338SBarry Smith PetscScalar value; 4992da9b6338SBarry Smith PetscReal norm; 4993da9b6338SBarry Smith 4994da9b6338SBarry Smith PetscFunctionBegin; 49959566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 49969566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 49979566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 4998da9b6338SBarry Smith 4999da9b6338SBarry Smith /* currently only works for sequential */ 50009566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 50019566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5002da9b6338SBarry Smith for (i = 0; i < N; i++) { 50039566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 500463a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5005da9b6338SBarry Smith for (j = -10; j < 11; j++) { 50068b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 50079566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 50089566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 50099566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 501063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5011da9b6338SBarry Smith value = -value; 50129566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5013da9b6338SBarry Smith } 5014da9b6338SBarry Smith } 50159566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 50169566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 5017da9b6338SBarry Smith PetscFunctionReturn(0); 5018da9b6338SBarry Smith } 501971f87433Sdalcinl 502071f87433Sdalcinl /*@ 5021fa9f3622SBarry Smith SNESKSPSetUseEW - Sets SNES use Eisenstat-Walker method for 502271f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 502371f87433Sdalcinl Newton method. 502471f87433Sdalcinl 50253f9fe445SBarry Smith Logically Collective on SNES 502671f87433Sdalcinl 502771f87433Sdalcinl Input Parameters: 502871f87433Sdalcinl + snes - SNES context 502971f87433Sdalcinl - flag - PETSC_TRUE or PETSC_FALSE 503071f87433Sdalcinl 503164ba62caSBarry Smith Options Database: 503264ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 503364ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 503464ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 503564ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 503664ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 503764ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 503864ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 503964ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 504064ba62caSBarry Smith 504171f87433Sdalcinl Notes: 504271f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 504371f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 504471f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 504571f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 504671f87433Sdalcinl solver. 504771f87433Sdalcinl 504871f87433Sdalcinl Level: advanced 504971f87433Sdalcinl 505071f87433Sdalcinl Reference: 505171f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 505271f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 505371f87433Sdalcinl 5054db781477SPatrick Sanan .seealso: `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 505571f87433Sdalcinl @*/ 50569371c9d4SSatish Balay PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) { 505771f87433Sdalcinl PetscFunctionBegin; 50580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5059acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 506071f87433Sdalcinl snes->ksp_ewconv = flag; 506171f87433Sdalcinl PetscFunctionReturn(0); 506271f87433Sdalcinl } 506371f87433Sdalcinl 506471f87433Sdalcinl /*@ 5065fa9f3622SBarry Smith SNESKSPGetUseEW - Gets if SNES is using Eisenstat-Walker method 506671f87433Sdalcinl for computing relative tolerance for linear solvers within an 506771f87433Sdalcinl inexact Newton method. 506871f87433Sdalcinl 506971f87433Sdalcinl Not Collective 507071f87433Sdalcinl 507171f87433Sdalcinl Input Parameter: 507271f87433Sdalcinl . snes - SNES context 507371f87433Sdalcinl 507471f87433Sdalcinl Output Parameter: 507571f87433Sdalcinl . flag - PETSC_TRUE or PETSC_FALSE 507671f87433Sdalcinl 507771f87433Sdalcinl Notes: 507871f87433Sdalcinl Currently, the default is to use a constant relative tolerance for 507971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 508071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 508171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 508271f87433Sdalcinl solver. 508371f87433Sdalcinl 508471f87433Sdalcinl Level: advanced 508571f87433Sdalcinl 508671f87433Sdalcinl Reference: 508771f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 508871f87433Sdalcinl inexact Newton method", SISC 17 (1), pp.16-32, 1996. 508971f87433Sdalcinl 5090db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 509171f87433Sdalcinl @*/ 50929371c9d4SSatish Balay PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) { 509371f87433Sdalcinl PetscFunctionBegin; 50940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5095534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 509671f87433Sdalcinl *flag = snes->ksp_ewconv; 509771f87433Sdalcinl PetscFunctionReturn(0); 509871f87433Sdalcinl } 509971f87433Sdalcinl 510071f87433Sdalcinl /*@ 5101fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 510271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 510371f87433Sdalcinl Newton method. 510471f87433Sdalcinl 51053f9fe445SBarry Smith Logically Collective on SNES 510671f87433Sdalcinl 510771f87433Sdalcinl Input Parameters: 510871f87433Sdalcinl + snes - SNES context 51090f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 511071f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 511171f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 511271f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 511371f87433Sdalcinl (0 <= gamma2 <= 1) 511471f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 511571f87433Sdalcinl . alpha2 - power for safeguard 511671f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 511771f87433Sdalcinl 511871f87433Sdalcinl Note: 511971f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 512071f87433Sdalcinl 512171f87433Sdalcinl Use PETSC_DEFAULT to retain the default for any of the parameters. 512271f87433Sdalcinl 512371f87433Sdalcinl Level: advanced 512471f87433Sdalcinl 512571f87433Sdalcinl Reference: 512671f87433Sdalcinl S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an 512771f87433Sdalcinl inexact Newton method", Utah State University Math. Stat. Dept. Res. 512871f87433Sdalcinl Report 6/94/75, June, 1994, to appear in SIAM J. Sci. Comput. 512971f87433Sdalcinl 5130db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 513171f87433Sdalcinl @*/ 51329371c9d4SSatish Balay PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) { 5133fa9f3622SBarry Smith SNESKSPEW *kctx; 51345fd66863SKarl Rupp 513571f87433Sdalcinl PetscFunctionBegin; 51360700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5137fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 51385f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5139c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5140c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5141c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5142c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5143c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5144c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5145c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 514671f87433Sdalcinl 514771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 514871f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 514971f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 515071f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 515171f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 515271f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 515371f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 515471f87433Sdalcinl 51550f0abf79SStefano 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); 51560b121fc5SBarry 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); 51570b121fc5SBarry 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); 51580b121fc5SBarry 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); 51590b121fc5SBarry 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); 51600b121fc5SBarry 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); 516171f87433Sdalcinl PetscFunctionReturn(0); 516271f87433Sdalcinl } 516371f87433Sdalcinl 516471f87433Sdalcinl /*@ 5165fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 516671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 516771f87433Sdalcinl Newton method. 516871f87433Sdalcinl 516971f87433Sdalcinl Not Collective 517071f87433Sdalcinl 517197bb3fdcSJose E. Roman Input Parameter: 51726b867d5aSJose E. Roman . snes - SNES context 517371f87433Sdalcinl 517471f87433Sdalcinl Output Parameters: 51750f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 517671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 517771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5178bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 517971f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 518071f87433Sdalcinl . alpha2 - power for safeguard 518171f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 518271f87433Sdalcinl 518371f87433Sdalcinl Level: advanced 518471f87433Sdalcinl 5185db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 518671f87433Sdalcinl @*/ 51879371c9d4SSatish Balay PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) { 5188fa9f3622SBarry Smith SNESKSPEW *kctx; 51895fd66863SKarl Rupp 519071f87433Sdalcinl PetscFunctionBegin; 51910700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5192fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 51935f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 519471f87433Sdalcinl if (version) *version = kctx->version; 519571f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 519671f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 519771f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 519871f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 519971f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 520071f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 520171f87433Sdalcinl PetscFunctionReturn(0); 520271f87433Sdalcinl } 520371f87433Sdalcinl 52049371c9d4SSatish Balay PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) { 5205fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 520671f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 520771f87433Sdalcinl 520871f87433Sdalcinl PetscFunctionBegin; 5209d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 521030058271SDmitry Karpeev if (!snes->iter) { 521130058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 52129566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 52130f0abf79SStefano Zampini } else { 521471f87433Sdalcinl if (kctx->version == 1) { 52150f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 521685ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 521771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 521871f87433Sdalcinl } else if (kctx->version == 2) { 521985ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 522085ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 522171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 522271f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 522385ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 522471f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 522585ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 522671f87433Sdalcinl stol = PetscMax(rtol, stol); 522771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 522871f87433Sdalcinl /* safeguard: avoid oversolving */ 522930058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 523071f87433Sdalcinl stol = PetscMax(rtol, stol); 523171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 52320f0abf79SStefano Zampini } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 52330f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 52340f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 52350f0abf79SStefano Zampini PetscReal rk = ared / pred; 52360f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 52370f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 52380f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 52390f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 52400f0abf79SStefano Zampini 52419371c9d4SSatish Balay if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 && kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) { 52420f0abf79SStefano Zampini rtol = kctx->v4_m4 * kctx->rtol_last; 52430f0abf79SStefano 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); 52440f0abf79SStefano Zampini } else { 52450f0abf79SStefano 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); 524671f87433Sdalcinl } 52470f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 52480f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 52490f0abf79SStefano Zampini kctx->rk_last = rk; 52500f0abf79SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version); 52510f0abf79SStefano Zampini } 52520f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 525371f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 52549566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 525563a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 525671f87433Sdalcinl PetscFunctionReturn(0); 525771f87433Sdalcinl } 525871f87433Sdalcinl 52599371c9d4SSatish Balay PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) { 5260fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 526171f87433Sdalcinl PCSide pcside; 526271f87433Sdalcinl Vec lres; 526371f87433Sdalcinl 526471f87433Sdalcinl PetscFunctionBegin; 5265d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 52669566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 526771dbe336SPeter Brune kctx->norm_last = snes->norm; 52680f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 52694f00ce20SMatthew G. Knepley PC pc; 52700f0abf79SStefano Zampini PetscBool getRes; 52714f00ce20SMatthew G. Knepley 52729566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 52730f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 52740f0abf79SStefano Zampini if (!getRes) { 52750f0abf79SStefano Zampini KSPNormType normtype; 52760f0abf79SStefano Zampini 52770f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 52780f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 52790f0abf79SStefano Zampini } 52809566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 52810f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 52829566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 528371f87433Sdalcinl } else { 528471f87433Sdalcinl /* KSP residual is preconditioned residual */ 528571f87433Sdalcinl /* compute true linear residual norm */ 52860f0abf79SStefano Zampini Mat J; 52870f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 52889566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 52890f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 52909566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 52919566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 52929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 529371f87433Sdalcinl } 529471f87433Sdalcinl } 529571f87433Sdalcinl PetscFunctionReturn(0); 529671f87433Sdalcinl } 529771f87433Sdalcinl 5298d4211eb9SBarry Smith /*@ 5299d4211eb9SBarry Smith SNESGetKSP - Returns the KSP context for a SNES solver. 5300d4211eb9SBarry Smith 5301d4211eb9SBarry Smith Not Collective, but if SNES object is parallel, then KSP object is parallel 5302d4211eb9SBarry Smith 5303d4211eb9SBarry Smith Input Parameter: 5304d4211eb9SBarry Smith . snes - the SNES context 5305d4211eb9SBarry Smith 5306d4211eb9SBarry Smith Output Parameter: 5307d4211eb9SBarry Smith . ksp - the KSP context 5308d4211eb9SBarry Smith 5309d4211eb9SBarry Smith Notes: 5310d4211eb9SBarry Smith The user can then directly manipulate the KSP context to set various 5311d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5312d4211eb9SBarry Smith PC contexts as well. 5313d4211eb9SBarry Smith 5314d4211eb9SBarry Smith Level: beginner 5315d4211eb9SBarry Smith 5316db781477SPatrick Sanan .seealso: `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5317d4211eb9SBarry Smith @*/ 53189371c9d4SSatish Balay PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) { 531971f87433Sdalcinl PetscFunctionBegin; 5320d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5321d4211eb9SBarry Smith PetscValidPointer(ksp, 2); 5322d4211eb9SBarry Smith 5323d4211eb9SBarry Smith if (!snes->ksp) { 53249566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 53259566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 53269566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->ksp)); 5327d4211eb9SBarry Smith 53289566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 53299566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5330a5c2985bSBarry Smith 53319566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 53329566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5333d4211eb9SBarry Smith } 5334d4211eb9SBarry Smith *ksp = snes->ksp; 533571f87433Sdalcinl PetscFunctionReturn(0); 533671f87433Sdalcinl } 53376c699258SBarry Smith 5338af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 53396c699258SBarry Smith /*@ 53402a808120SBarry Smith SNESSetDM - Sets the DM that may be used by some nonlinear solvers or their underlying preconditioners 53416c699258SBarry Smith 53423f9fe445SBarry Smith Logically Collective on SNES 53436c699258SBarry Smith 53446c699258SBarry Smith Input Parameters: 53452a808120SBarry Smith + snes - the nonlinear solver context 53462a808120SBarry Smith - dm - the dm, cannot be NULL 53476c699258SBarry Smith 5348e03a659cSJed Brown Notes: 5349e03a659cSJed Brown A DM can only be used for solving one problem at a time because information about the problem is stored on the DM, 5350e03a659cSJed Brown even when not using interfaces like DMSNESSetFunction(). Use DMClone() to get a distinct DM when solving different 5351e03a659cSJed Brown problems using the same function space. 5352e03a659cSJed Brown 53536c699258SBarry Smith Level: intermediate 53546c699258SBarry Smith 5355db781477SPatrick Sanan .seealso: `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 53566c699258SBarry Smith @*/ 53579371c9d4SSatish Balay PetscErrorCode SNESSetDM(SNES snes, DM dm) { 5358345fed2cSBarry Smith KSP ksp; 5359942e3340SBarry Smith DMSNES sdm; 53606c699258SBarry Smith 53616c699258SBarry Smith PetscFunctionBegin; 53620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 53632a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 53649566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5365942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 536651f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 53679566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 53689566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5369f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 53706cab3a1bSJed Brown } 53719566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 53729566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 53736cab3a1bSJed Brown } 53746c699258SBarry Smith snes->dm = dm; 5375116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5376f5af7f23SKarl Rupp 53779566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 53789566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 53799566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5380efd4aadfSBarry Smith if (snes->npc) { 53819566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 53829566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 53832c155ee1SBarry Smith } 53846c699258SBarry Smith PetscFunctionReturn(0); 53856c699258SBarry Smith } 53866c699258SBarry Smith 53876c699258SBarry Smith /*@ 53886c699258SBarry Smith SNESGetDM - Gets the DM that may be used by some preconditioners 53896c699258SBarry Smith 53903f9fe445SBarry Smith Not Collective but DM obtained is parallel on SNES 53916c699258SBarry Smith 53926c699258SBarry Smith Input Parameter: 53936c699258SBarry Smith . snes - the preconditioner context 53946c699258SBarry Smith 53956c699258SBarry Smith Output Parameter: 53966c699258SBarry Smith . dm - the dm 53976c699258SBarry Smith 53986c699258SBarry Smith Level: intermediate 53996c699258SBarry Smith 5400db781477SPatrick Sanan .seealso: `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 54016c699258SBarry Smith @*/ 54029371c9d4SSatish Balay PetscErrorCode SNESGetDM(SNES snes, DM *dm) { 54036c699258SBarry Smith PetscFunctionBegin; 54040700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54056cab3a1bSJed Brown if (!snes->dm) { 54069566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5407116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 54086cab3a1bSJed Brown } 54096c699258SBarry Smith *dm = snes->dm; 54106c699258SBarry Smith PetscFunctionReturn(0); 54116c699258SBarry Smith } 54120807856dSBarry Smith 541331823bd8SMatthew G Knepley /*@ 5414be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 541531823bd8SMatthew G Knepley 541631823bd8SMatthew G Knepley Collective on SNES 541731823bd8SMatthew G Knepley 541831823bd8SMatthew G Knepley Input Parameters: 541931823bd8SMatthew G Knepley + snes - iterative context obtained from SNESCreate() 542031823bd8SMatthew G Knepley - pc - the preconditioner object 542131823bd8SMatthew G Knepley 542231823bd8SMatthew G Knepley Notes: 5423be95d8f1SBarry Smith Use SNESGetNPC() to retrieve the preconditioner context (for example, 542431823bd8SMatthew G Knepley to configure it using the API). 542531823bd8SMatthew G Knepley 542631823bd8SMatthew G Knepley Level: developer 542731823bd8SMatthew G Knepley 5428db781477SPatrick Sanan .seealso: `SNESGetNPC()`, `SNESHasNPC()` 542931823bd8SMatthew G Knepley @*/ 54309371c9d4SSatish Balay PetscErrorCode SNESSetNPC(SNES snes, SNES pc) { 543131823bd8SMatthew G Knepley PetscFunctionBegin; 543231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 543331823bd8SMatthew G Knepley PetscValidHeaderSpecific(pc, SNES_CLASSID, 2); 543431823bd8SMatthew G Knepley PetscCheckSameComm(snes, 1, pc, 2); 54359566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)pc)); 54369566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5437efd4aadfSBarry Smith snes->npc = pc; 54389566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 543931823bd8SMatthew G Knepley PetscFunctionReturn(0); 544031823bd8SMatthew G Knepley } 544131823bd8SMatthew G Knepley 544231823bd8SMatthew G Knepley /*@ 5443be95d8f1SBarry Smith SNESGetNPC - Creates a nonlinear preconditioning solver (SNES) to be used to precondition the nonlinear solver. 544431823bd8SMatthew G Knepley 5445951fe5abSBarry Smith Not Collective; but any changes to the obtained SNES object must be applied collectively 544631823bd8SMatthew G Knepley 544731823bd8SMatthew G Knepley Input Parameter: 544831823bd8SMatthew G Knepley . snes - iterative context obtained from SNESCreate() 544931823bd8SMatthew G Knepley 545031823bd8SMatthew G Knepley Output Parameter: 545131823bd8SMatthew G Knepley . pc - preconditioner context 545231823bd8SMatthew G Knepley 5453b5badacbSBarry Smith Options Database: 5454b5badacbSBarry Smith . -npc_snes_type <type> - set the type of the SNES to use as the nonlinear preconditioner 5455b5badacbSBarry Smith 545695452b02SPatrick Sanan Notes: 5457b5badacbSBarry Smith If a SNES was previously set with SNESSetNPC() then that SNES is returned, otherwise a new SNES object is created. 5458be95d8f1SBarry Smith 5459951fe5abSBarry Smith The (preconditioner) SNES returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5460951fe5abSBarry Smith SNES during SNESSetUp() 5461951fe5abSBarry Smith 546231823bd8SMatthew G Knepley Level: developer 546331823bd8SMatthew G Knepley 5464db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 546531823bd8SMatthew G Knepley @*/ 54669371c9d4SSatish Balay PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) { 5467a64e098fSPeter Brune const char *optionsprefix; 546831823bd8SMatthew G Knepley 546931823bd8SMatthew G Knepley PetscFunctionBegin; 547031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 547131823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5472efd4aadfSBarry Smith if (!snes->npc) { 54739566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 54749566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 54759566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 54769566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 54779566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 54789566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 54799566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 548031823bd8SMatthew G Knepley } 5481efd4aadfSBarry Smith *pc = snes->npc; 548231823bd8SMatthew G Knepley PetscFunctionReturn(0); 548331823bd8SMatthew G Knepley } 548431823bd8SMatthew G Knepley 54853ad1a0b9SPatrick Farrell /*@ 54863ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 54873ad1a0b9SPatrick Farrell 54883ad1a0b9SPatrick Farrell Not Collective 54893ad1a0b9SPatrick Farrell 54903ad1a0b9SPatrick Farrell Input Parameter: 54913ad1a0b9SPatrick Farrell . snes - iterative context obtained from SNESCreate() 54923ad1a0b9SPatrick Farrell 54933ad1a0b9SPatrick Farrell Output Parameter: 54943ad1a0b9SPatrick Farrell . has_npc - whether the SNES has an NPC or not 54953ad1a0b9SPatrick Farrell 54963ad1a0b9SPatrick Farrell Level: developer 54973ad1a0b9SPatrick Farrell 5498db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESGetNPC()` 54993ad1a0b9SPatrick Farrell @*/ 55009371c9d4SSatish Balay PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) { 55013ad1a0b9SPatrick Farrell PetscFunctionBegin; 55023ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5503efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 55043ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 55053ad1a0b9SPatrick Farrell } 55063ad1a0b9SPatrick Farrell 5507c40d0f55SPeter Brune /*@ 5508be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5509c40d0f55SPeter Brune 5510c40d0f55SPeter Brune Logically Collective on SNES 5511c40d0f55SPeter Brune 5512c40d0f55SPeter Brune Input Parameter: 5513c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5514c40d0f55SPeter Brune 5515c40d0f55SPeter Brune Output Parameter: 5516c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5517c40d0f55SPeter Brune .vb 55182d547940SBarry Smith PC_LEFT - left preconditioning 55192d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5520c40d0f55SPeter Brune .ve 5521c40d0f55SPeter Brune 5522c40d0f55SPeter Brune Options Database Keys: 552367b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5524c40d0f55SPeter Brune 552595452b02SPatrick Sanan Notes: 552695452b02SPatrick Sanan SNESNRICHARDSON and SNESNCG only support left preconditioning. 55272d547940SBarry Smith 5528c40d0f55SPeter Brune Level: intermediate 5529c40d0f55SPeter Brune 5530db781477SPatrick Sanan .seealso: `SNESGetNPCSide()`, `KSPSetPCSide()` 5531c40d0f55SPeter Brune @*/ 55329371c9d4SSatish Balay PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) { 5533c40d0f55SPeter Brune PetscFunctionBegin; 5534c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5535c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5536b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 553754c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5538efd4aadfSBarry Smith snes->npcside = side; 5539c40d0f55SPeter Brune PetscFunctionReturn(0); 5540c40d0f55SPeter Brune } 5541c40d0f55SPeter Brune 5542c40d0f55SPeter Brune /*@ 5543be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5544c40d0f55SPeter Brune 5545c40d0f55SPeter Brune Not Collective 5546c40d0f55SPeter Brune 5547c40d0f55SPeter Brune Input Parameter: 5548c40d0f55SPeter Brune . snes - iterative context obtained from SNESCreate() 5549c40d0f55SPeter Brune 5550c40d0f55SPeter Brune Output Parameter: 5551c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5552c40d0f55SPeter Brune .vb 55532d547940SBarry Smith PC_LEFT - left preconditioning 55542d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5555c40d0f55SPeter Brune .ve 5556c40d0f55SPeter Brune 5557c40d0f55SPeter Brune Level: intermediate 5558c40d0f55SPeter Brune 5559db781477SPatrick Sanan .seealso: `SNESSetNPCSide()`, `KSPGetPCSide()` 5560c40d0f55SPeter Brune @*/ 55619371c9d4SSatish Balay PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) { 5562c40d0f55SPeter Brune PetscFunctionBegin; 5563c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5564c40d0f55SPeter Brune PetscValidPointer(side, 2); 5565efd4aadfSBarry Smith *side = snes->npcside; 5566c40d0f55SPeter Brune PetscFunctionReturn(0); 5567c40d0f55SPeter Brune } 5568c40d0f55SPeter Brune 55699e764e56SPeter Brune /*@ 55707601faf0SJed Brown SNESSetLineSearch - Sets the linesearch on the SNES instance. 55719e764e56SPeter Brune 55729e764e56SPeter Brune Collective on SNES 55739e764e56SPeter Brune 55749e764e56SPeter Brune Input Parameters: 55759e764e56SPeter Brune + snes - iterative context obtained from SNESCreate() 55769e764e56SPeter Brune - linesearch - the linesearch object 55779e764e56SPeter Brune 55789e764e56SPeter Brune Notes: 55797601faf0SJed Brown Use SNESGetLineSearch() to retrieve the preconditioner context (for example, 55809e764e56SPeter Brune to configure it using the API). 55819e764e56SPeter Brune 55829e764e56SPeter Brune Level: developer 55839e764e56SPeter Brune 5584db781477SPatrick Sanan .seealso: `SNESGetLineSearch()` 55859e764e56SPeter Brune @*/ 55869371c9d4SSatish Balay PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) { 55879e764e56SPeter Brune PetscFunctionBegin; 55889e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5589f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 55909e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 55919566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 55929566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5593f5af7f23SKarl Rupp 55949e764e56SPeter Brune snes->linesearch = linesearch; 5595f5af7f23SKarl Rupp 55969566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 55979e764e56SPeter Brune PetscFunctionReturn(0); 55989e764e56SPeter Brune } 55999e764e56SPeter Brune 5600a34ceb2aSJed Brown /*@ 56017601faf0SJed Brown SNESGetLineSearch - Returns a pointer to the line search context set with SNESSetLineSearch() 56028141a3b9SPeter Brune or creates a default line search instance associated with the SNES and returns it. 56039e764e56SPeter Brune 56049e764e56SPeter Brune Not Collective 56059e764e56SPeter Brune 56069e764e56SPeter Brune Input Parameter: 56079e764e56SPeter Brune . snes - iterative context obtained from SNESCreate() 56089e764e56SPeter Brune 56099e764e56SPeter Brune Output Parameter: 56109e764e56SPeter Brune . linesearch - linesearch context 56119e764e56SPeter Brune 5612162e0bf5SPeter Brune Level: beginner 56139e764e56SPeter Brune 5614db781477SPatrick Sanan .seealso: `SNESSetLineSearch()`, `SNESLineSearchCreate()` 56159e764e56SPeter Brune @*/ 56169371c9d4SSatish Balay PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) { 56179e764e56SPeter Brune const char *optionsprefix; 56189e764e56SPeter Brune 56199e764e56SPeter Brune PetscFunctionBegin; 56209e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 56219e764e56SPeter Brune PetscValidPointer(linesearch, 2); 56229e764e56SPeter Brune if (!snes->linesearch) { 56239566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 56249566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 56259566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 56269566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 56279566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 56289566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 56299e764e56SPeter Brune } 56309e764e56SPeter Brune *linesearch = snes->linesearch; 56319e764e56SPeter Brune PetscFunctionReturn(0); 56329e764e56SPeter Brune } 5633