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 /*@ 16f6dfbefdSBarry Smith SNESSetErrorIfNotConverged - Causes `SNESSolve()` to generate an error if the solver has not converged. 17e113a28aSBarry Smith 18f6dfbefdSBarry Smith Logically Collective on snes 19e113a28aSBarry Smith 20e113a28aSBarry Smith Input Parameters: 21f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 22f6dfbefdSBarry 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 29f6dfbefdSBarry Smith Note: 30f6dfbefdSBarry Smith Normally PETSc continues if a solver fails to converge, you can call `SNESGetConvergedReason()` after a `SNESSolve()` 31f6dfbefdSBarry Smith to determine if it has converged. Otherwise the solution may be inaccurate or wrong 32e113a28aSBarry Smith 33f6dfbefdSBarry Smith .seealso: `SNES`, `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 /*@ 44f6dfbefdSBarry Smith SNESGetErrorIfNotConverged - Indicates if `SNESSolve()` will generate an error if the solver does not converge? 45e113a28aSBarry Smith 46e113a28aSBarry Smith Not Collective 47e113a28aSBarry Smith 48e113a28aSBarry Smith Input Parameter: 49f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 50e113a28aSBarry Smith 51e113a28aSBarry Smith Output Parameter: 52f6dfbefdSBarry Smith . flag - `PETSC_TRUE` if it will generate an error, else `PETSC_FALSE` 53e113a28aSBarry Smith 54e113a28aSBarry Smith Level: intermediate 55e113a28aSBarry Smith 56f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `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 /*@ 67f6dfbefdSBarry Smith SNESSetAlwaysComputesFinalResidual - tells the `SNES` to always compute the residual at the final solution 684fc747eaSLawrence Mitchell 69f6dfbefdSBarry Smith Logically Collective on snes 704fc747eaSLawrence Mitchell 714fc747eaSLawrence Mitchell Input Parameters: 72f6dfbefdSBarry Smith + snes - the shell `SNES` 73f6dfbefdSBarry Smith - flg - `PETSC_TRUE` to always compute the residual 744fc747eaSLawrence Mitchell 754fc747eaSLawrence Mitchell Level: advanced 764fc747eaSLawrence Mitchell 77f6dfbefdSBarry Smith Note: 78f6dfbefdSBarry Smith Some solvers (such as smoothers in a `SNESFAS`) do not need the residual computed at the final solution so skip computing it 79f6dfbefdSBarry Smith to save time. 80f6dfbefdSBarry Smith 81f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetAlwaysComputesFinalResidual()` 824fc747eaSLawrence Mitchell @*/ 839371c9d4SSatish Balay PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) { 844fc747eaSLawrence Mitchell PetscFunctionBegin; 854fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 864fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 874fc747eaSLawrence Mitchell PetscFunctionReturn(0); 884fc747eaSLawrence Mitchell } 894fc747eaSLawrence Mitchell 904fc747eaSLawrence Mitchell /*@ 91f6dfbefdSBarry Smith SNESGetAlwaysComputesFinalResidual - checks if the `SNES` always computes the residual at the final solution 924fc747eaSLawrence Mitchell 93f6dfbefdSBarry Smith Logically Collective on snes 944fc747eaSLawrence Mitchell 954fc747eaSLawrence Mitchell Input Parameter: 96f6dfbefdSBarry Smith . snes - the `SNES` context 974fc747eaSLawrence Mitchell 984fc747eaSLawrence Mitchell Output Parameter: 99f6dfbefdSBarry Smith . flg - `PETSC_TRUE` if the residual is computed 1004fc747eaSLawrence Mitchell 1014fc747eaSLawrence Mitchell Level: advanced 1024fc747eaSLawrence Mitchell 103f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetAlwaysComputesFinalResidual()` 1044fc747eaSLawrence Mitchell @*/ 1059371c9d4SSatish Balay PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) { 1064fc747eaSLawrence Mitchell PetscFunctionBegin; 1074fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1084fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1094fc747eaSLawrence Mitchell PetscFunctionReturn(0); 1104fc747eaSLawrence Mitchell } 1114fc747eaSLawrence Mitchell 112e725d27bSBarry Smith /*@ 113f6dfbefdSBarry Smith SNESSetFunctionDomainError - tells `SNES` that the input vector, a proposed new solution, to your function you provided to `SNESSetFunction()` is not 114f0b84518SBarry Smith in the functions domain. For example, a step with negative pressure. 1154936397dSBarry Smith 116f6dfbefdSBarry Smith Logically Collective on snes 1174936397dSBarry Smith 1184936397dSBarry Smith Input Parameters: 119f6dfbefdSBarry Smith . snes - the `SNES` context 1204936397dSBarry Smith 12128529972SSatish Balay Level: advanced 1224936397dSBarry Smith 123f0b84518SBarry Smith Note: 124f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 125f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 126f0b84518SBarry Smith 127f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`, 128f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 1294936397dSBarry Smith @*/ 1309371c9d4SSatish Balay PetscErrorCode SNESSetFunctionDomainError(SNES snes) { 1314936397dSBarry Smith PetscFunctionBegin; 1320700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1335f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates input vector is not in the function domain"); 1344936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1354936397dSBarry Smith PetscFunctionReturn(0); 1364936397dSBarry Smith } 1374936397dSBarry Smith 1386a388c36SPeter Brune /*@ 139f6dfbefdSBarry Smith SNESSetJacobianDomainError - tells `SNES` that the function you provided to `SNESSetJacobian()` at the proposed step. For example there is a negative element transformation. 14007b62357SFande Kong 141f6dfbefdSBarry Smith Logically Collective on snes 14207b62357SFande Kong 14307b62357SFande Kong Input Parameters: 144f6dfbefdSBarry Smith . snes - the `SNES` context 14507b62357SFande Kong 14607b62357SFande Kong Level: advanced 14707b62357SFande Kong 148f0b84518SBarry Smith Note: 149f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 150f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 151f0b84518SBarry Smith 152f0b84518SBarry Smith .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`, 153f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 15407b62357SFande Kong @*/ 1559371c9d4SSatish Balay PetscErrorCode SNESSetJacobianDomainError(SNES snes) { 15607b62357SFande Kong PetscFunctionBegin; 15707b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1585f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates computeJacobian does not make sense"); 15907b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 16007b62357SFande Kong PetscFunctionReturn(0); 16107b62357SFande Kong } 16207b62357SFande Kong 16307b62357SFande Kong /*@ 164f6dfbefdSBarry Smith SNESSetCheckJacobianDomainError - tells `SNESSolve()` whether to check if the user called `SNESSetJacobianDomainError()` Jacobian domain error after 165f6dfbefdSBarry Smith each Jacobian evaluation. By default, we check Jacobian domain error in the debug mode, and do not check it in the optimized mode. 166b351a90bSFande Kong 167f6dfbefdSBarry Smith Logically Collective on snes 168b351a90bSFande Kong 169b351a90bSFande Kong Input Parameters: 170a2b725a8SWilliam Gropp + snes - the SNES context 171f6dfbefdSBarry Smith - flg - indicates if or not to check Jacobian domain error after each Jacobian evaluation 172b351a90bSFande Kong 173b351a90bSFande Kong Level: advanced 174b351a90bSFande Kong 175f6dfbefdSBarry Smith Note: 176f6dfbefdSBarry Smith Checks require one extra parallel synchronization for each Jacobian evaluation 177f6dfbefdSBarry Smith 178db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 179b351a90bSFande Kong @*/ 1809371c9d4SSatish Balay PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) { 181b351a90bSFande Kong PetscFunctionBegin; 182b351a90bSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 183b351a90bSFande Kong snes->checkjacdomainerror = flg; 184b351a90bSFande Kong PetscFunctionReturn(0); 185b351a90bSFande Kong } 186b351a90bSFande Kong 187b351a90bSFande Kong /*@ 1888383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 1898383d7d7SFande Kong 190f6dfbefdSBarry Smith Logically Collective on snes 1918383d7d7SFande Kong 1928383d7d7SFande Kong Input Parameters: 193f6dfbefdSBarry Smith . snes - the `SNES` context 1948383d7d7SFande Kong 1958383d7d7SFande Kong Output Parameters: 196f6dfbefdSBarry Smith . flg - `PETSC_FALSE` indicates that we don't check Jacobian domain errors after each Jacobian evaluation 1978383d7d7SFande Kong 1988383d7d7SFande Kong Level: advanced 1998383d7d7SFande Kong 200db781477SPatrick Sanan .seealso: `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 2018383d7d7SFande Kong @*/ 2029371c9d4SSatish Balay PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) { 2038383d7d7SFande Kong PetscFunctionBegin; 2048383d7d7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 205534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 2068383d7d7SFande Kong *flg = snes->checkjacdomainerror; 2078383d7d7SFande Kong PetscFunctionReturn(0); 2088383d7d7SFande Kong } 2098383d7d7SFande Kong 2108383d7d7SFande Kong /*@ 211f6dfbefdSBarry Smith SNESGetFunctionDomainError - Gets the status of the domain error after a call to `SNESComputeFunction()`; 2126a388c36SPeter Brune 213f6dfbefdSBarry Smith Logically Collective 2146a388c36SPeter Brune 2156a388c36SPeter Brune Input Parameters: 216f6dfbefdSBarry Smith . snes - the `SNES` context 2176a388c36SPeter Brune 2186a388c36SPeter Brune Output Parameters: 219f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise. 2206a388c36SPeter Brune 221f6dfbefdSBarry Smith Level: developer 2226a388c36SPeter Brune 223db781477SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 2246a388c36SPeter Brune @*/ 2259371c9d4SSatish Balay PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) { 2266a388c36SPeter Brune PetscFunctionBegin; 2276a388c36SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 228534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 2296a388c36SPeter Brune *domainerror = snes->domainerror; 2306a388c36SPeter Brune PetscFunctionReturn(0); 2316a388c36SPeter Brune } 2326a388c36SPeter Brune 23307b62357SFande Kong /*@ 234f6dfbefdSBarry Smith SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to `SNESComputeJacobian()`; 23507b62357SFande Kong 236f6dfbefdSBarry Smith Logically Collective on snes 23707b62357SFande Kong 23807b62357SFande Kong Input Parameters: 239f6dfbefdSBarry Smith . snes - the `SNES` context 24007b62357SFande Kong 24107b62357SFande Kong Output Parameters: 242f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a Jacobian domain error; `PETSC_FALSE` otherwise. 24307b62357SFande Kong 24407b62357SFande Kong Level: advanced 24507b62357SFande Kong 246c2e3fba1SPatrick Sanan .seealso: `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 24707b62357SFande Kong @*/ 2489371c9d4SSatish Balay PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) { 24907b62357SFande Kong PetscFunctionBegin; 25007b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 251534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 25207b62357SFande Kong *domainerror = snes->jacobiandomainerror; 25307b62357SFande Kong PetscFunctionReturn(0); 25407b62357SFande Kong } 25507b62357SFande Kong 25655849f57SBarry Smith /*@C 257f6dfbefdSBarry Smith SNESLoad - Loads a `SNES` that has been stored in `PETSCVIEWERBINARY` with `SNESView()`. 25855849f57SBarry Smith 259f6dfbefdSBarry Smith Collective on snes 26055849f57SBarry Smith 26155849f57SBarry Smith Input Parameters: 262f6dfbefdSBarry Smith + newdm - the newly loaded `SNES`, this needs to have been created with `SNESCreate()` or 263f6dfbefdSBarry Smith some related function before a call to `SNESLoad()`. 264f6dfbefdSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` 26555849f57SBarry Smith 26655849f57SBarry Smith Level: intermediate 26755849f57SBarry Smith 268f6dfbefdSBarry Smith Note: 269f6dfbefdSBarry Smith The type is determined by the data in the file, any type set into the `SNES` before this call is ignored. 27055849f57SBarry Smith 271f6dfbefdSBarry Smith .seealso: `SNESCreate()`, `SNESType`, `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()` 27255849f57SBarry Smith @*/ 2739371c9d4SSatish Balay PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) { 27455849f57SBarry Smith PetscBool isbinary; 275060da220SMatthew G. Knepley PetscInt classid; 27655849f57SBarry Smith char type[256]; 27755849f57SBarry Smith KSP ksp; 2782d53ad75SBarry Smith DM dm; 2792d53ad75SBarry Smith DMSNES dmsnes; 28055849f57SBarry Smith 28155849f57SBarry Smith PetscFunctionBegin; 2822d53ad75SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 28355849f57SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 2855f80ce2aSJacob Faibussowitsch PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 28655849f57SBarry Smith 2879566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 2885f80ce2aSJacob Faibussowitsch PetscCheck(classid == SNES_FILE_CLASSID, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Not SNES next in file"); 2899566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 2909566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 291dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, load, viewer); 2929566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 2939566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &dmsnes)); 2949566063dSJacob Faibussowitsch PetscCall(DMSNESLoad(dmsnes, viewer)); 2959566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 2969566063dSJacob Faibussowitsch PetscCall(KSPLoad(ksp, viewer)); 29755849f57SBarry Smith PetscFunctionReturn(0); 29855849f57SBarry Smith } 2996a388c36SPeter Brune 3009804daf3SBarry Smith #include <petscdraw.h> 301e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 302e04113cfSBarry Smith #include <petscviewersaws.h> 303bfb97211SBarry Smith #endif 3048404b7f3SBarry Smith 305fe2efc57SMark /*@C 306f6dfbefdSBarry Smith SNESViewFromOptions - View a `SNES` based on the options database 307fe2efc57SMark 308f6dfbefdSBarry Smith Collective on snes 309fe2efc57SMark 310fe2efc57SMark Input Parameters: 311f6dfbefdSBarry Smith + A - the `SNES` context 312736c3998SJose E. Roman . obj - Optional object 313736c3998SJose E. Roman - name - command line option 314fe2efc57SMark 315fe2efc57SMark Level: intermediate 316f6dfbefdSBarry Smith 317db781477SPatrick Sanan .seealso: `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 318fe2efc57SMark @*/ 3199371c9d4SSatish Balay PetscErrorCode SNESViewFromOptions(SNES A, PetscObject obj, const char name[]) { 320fe2efc57SMark PetscFunctionBegin; 321fe2efc57SMark PetscValidHeaderSpecific(A, SNES_CLASSID, 1); 3229566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 323fe2efc57SMark PetscFunctionReturn(0); 324fe2efc57SMark } 325fe2efc57SMark 326789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES, Vec, Mat, Mat, void *); 327789d8953SBarry Smith 3287e2c5f70SBarry Smith /*@C 329f6dfbefdSBarry Smith SNESView - Prints the `SNES` data structure. 3309b94acceSBarry Smith 331f6dfbefdSBarry Smith Collective on snes 332fee21e36SBarry Smith 333c7afd0dbSLois Curfman McInnes Input Parameters: 334f6dfbefdSBarry Smith + snes - the `SNES` context 335f6dfbefdSBarry Smith - viewer - the `PetscViewer` 336c7afd0dbSLois Curfman McInnes 3379b94acceSBarry Smith Options Database Key: 338f6dfbefdSBarry Smith . -snes_view - Calls `SNESView()` at end of `SNESSolve()` 3399b94acceSBarry Smith 3409b94acceSBarry Smith Notes: 3419b94acceSBarry Smith The available visualization contexts include 342f6dfbefdSBarry Smith + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 343f6dfbefdSBarry Smith - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 344c8a8ba5cSLois Curfman McInnes output where only the first processor opens 345c8a8ba5cSLois Curfman McInnes the file. All other processors send their 346c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3479b94acceSBarry Smith 348052bf0daSPierre Jolivet The available formats include 349f6dfbefdSBarry Smith + `PETSC_VIEWER_DEFAULT` - standard output (default) 350f6dfbefdSBarry Smith - `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for `SNESNASM` 351052bf0daSPierre Jolivet 3523e081fefSLois Curfman McInnes The user can open an alternative visualization context with 353f6dfbefdSBarry Smith `PetscViewerASCIIOpen()` - output to a specified file. 3549b94acceSBarry Smith 355f6dfbefdSBarry Smith In the debugger you can do "call `SNESView`(snes,0)" to display the `SNES` solver. (The same holds for any PETSc object viewer). 356595c91d4SBarry Smith 35736851e7fSLois Curfman McInnes Level: beginner 35836851e7fSLois Curfman McInnes 359f6dfbefdSBarry Smith .seealso: `SNES`, `SNESLoad()`, `SNESCreate()`, `PetscViewerASCIIOpen()` 3609b94acceSBarry Smith @*/ 3619371c9d4SSatish Balay PetscErrorCode SNESView(SNES snes, PetscViewer viewer) { 362fa9f3622SBarry Smith SNESKSPEW *kctx; 36394b7f48cSBarry Smith KSP ksp; 3647f1410a3SPeter Brune SNESLineSearch linesearch; 36572a02f06SBarry Smith PetscBool iascii, isstring, isbinary, isdraw; 3662d53ad75SBarry Smith DMSNES dmsnes; 367e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 368536b137fSBarry Smith PetscBool issaws; 369bfb97211SBarry Smith #endif 3709b94acceSBarry Smith 3713a40ed3dSBarry Smith PetscFunctionBegin; 3720700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 37348a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &viewer)); 3740700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 375c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, viewer, 2); 37674679c65SBarry Smith 3779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3789566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 3799566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 3809566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 381e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 3829566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 383bfb97211SBarry Smith #endif 38432077d6dSBarry Smith if (iascii) { 385dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3868404b7f3SBarry Smith DM dm; 3878404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES, Vec, Mat, Mat, void *); 3888404b7f3SBarry Smith void *ctx; 389789d8953SBarry Smith const char *pre = ""; 390dc0571f2SMatthew G. Knepley 3919566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes, viewer)); 39248a46eb9SPierre Jolivet if (!snes->setupcalled) PetscCall(PetscViewerASCIIPrintf(viewer, " SNES has not been set up so information may be incomplete\n")); 393e7788613SBarry Smith if (snes->ops->view) { 3949566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 395dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, view, viewer); 3969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 3970ef38995SBarry Smith } 39863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n", snes->max_its, snes->max_funcs)); 3999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerances: relative=%g, absolute=%g, solution=%g\n", (double)snes->rtol, (double)snes->abstol, (double)snes->stol)); 40048a46eb9SPierre Jolivet if (snes->usesksp) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of linear solver iterations=%" PetscInt_FMT "\n", snes->linear_its)); 40163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " total number of function evaluations=%" PetscInt_FMT "\n", snes->nfuncs)); 4029566063dSJacob Faibussowitsch PetscCall(SNESGetNormSchedule(snes, &normschedule)); 4039566063dSJacob Faibussowitsch if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer, " norm schedule %s\n", SNESNormSchedules[normschedule])); 40448a46eb9SPierre Jolivet if (snes->gridsequence) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of grid sequence refinements=%" PetscInt_FMT "\n", snes->gridsequence)); 4059b94acceSBarry Smith if (snes->ksp_ewconv) { 406fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 4079b94acceSBarry Smith if (kctx) { 40863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n", kctx->version)); 4099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " rtol_0=%g, rtol_max=%g, threshold=%g\n", (double)kctx->rtol_0, (double)kctx->rtol_max, (double)kctx->threshold)); 4109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " gamma=%g, alpha=%g, alpha2=%g\n", (double)kctx->gamma, (double)kctx->alpha, (double)kctx->alpha2)); 4119b94acceSBarry Smith } 4129b94acceSBarry Smith } 413eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 4149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is never rebuilt\n")); 415eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 41663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n", snes->lagpreconditioner)); 417eb1f6c34SBarry Smith } 418eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 4199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is never rebuilt\n")); 420eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 42163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n", snes->lagjacobian)); 422eb1f6c34SBarry Smith } 4239566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4249566063dSJacob Faibussowitsch PetscCall(DMSNESGetJacobian(dm, &cJ, &ctx)); 425789d8953SBarry Smith if (snes->mf_operator) { 4269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing\n")); 427789d8953SBarry Smith pre = "Preconditioning "; 428789d8953SBarry Smith } 4298404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 4309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences one column at a time\n", pre)); 4318404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 4329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences with coloring\n", pre)); 433789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 434789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 435789d8953SBarry Smith MatFDColoring fdcoloring; 4369566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 437789d8953SBarry Smith if (fdcoloring) { 4389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using colored finite differences on a DMDA\n", pre)); 439789d8953SBarry Smith } else { 4409566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using a DMDA local Jacobian\n", pre)); 441789d8953SBarry Smith } 442789d8953SBarry Smith } else if (snes->mf) { 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 4448404b7f3SBarry Smith } 4450f5bd95cSBarry Smith } else if (isstring) { 446317d6ea6SBarry Smith const char *type; 4479566063dSJacob Faibussowitsch PetscCall(SNESGetType(snes, &type)); 4489566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSPrintf(viewer, " SNESType: %-7.7s", type)); 449dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 45055849f57SBarry Smith } else if (isbinary) { 45155849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 45255849f57SBarry Smith MPI_Comm comm; 45355849f57SBarry Smith PetscMPIInt rank; 45455849f57SBarry Smith char type[256]; 45555849f57SBarry Smith 4569566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 4579566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 458dd400576SPatrick Sanan if (rank == 0) { 4599566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 4609566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type, ((PetscObject)snes)->type_name, sizeof(type))); 4619566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, type, sizeof(type), PETSC_CHAR)); 46255849f57SBarry Smith } 463dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 46472a02f06SBarry Smith } else if (isdraw) { 46572a02f06SBarry Smith PetscDraw draw; 46672a02f06SBarry Smith char str[36]; 46789fd9fafSBarry Smith PetscReal x, y, bottom, h; 46872a02f06SBarry Smith 4699566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 4709566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 4719566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(str, "SNES: ", sizeof(str))); 4729566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(str, ((PetscObject)snes)->type_name, sizeof(str))); 4739566063dSJacob Faibussowitsch PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLUE, PETSC_DRAW_BLACK, str, NULL, &h)); 47489fd9fafSBarry Smith bottom = y - h; 4759566063dSJacob Faibussowitsch PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 476dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 477e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 478536b137fSBarry Smith } else if (issaws) { 479d45a07a7SBarry Smith PetscMPIInt rank; 4802657e9d9SBarry Smith const char *name; 481d45a07a7SBarry Smith 4829566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)snes, &name)); 4839566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 484dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 485d45a07a7SBarry Smith char dir[1024]; 486d45a07a7SBarry Smith 4879566063dSJacob Faibussowitsch PetscCall(PetscObjectViewSAWs((PetscObject)snes, viewer)); 4889566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name)); 489792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, &snes->iter, 1, SAWs_READ, SAWs_INT)); 49048a46eb9SPierre Jolivet if (!snes->conv_hist) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, PETSC_DECIDE, PETSC_TRUE)); 4919566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/conv_hist", name)); 492792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, snes->conv_hist, 10, SAWs_READ, SAWs_DOUBLE)); 493f05ece33SBarry Smith } 494bfb97211SBarry Smith #endif 49572a02f06SBarry Smith } 49672a02f06SBarry Smith if (snes->linesearch) { 4979566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 4989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 4999566063dSJacob Faibussowitsch PetscCall(SNESLineSearchView(linesearch, viewer)); 5009566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 50119bcc07fSBarry Smith } 502efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 5039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5049566063dSJacob Faibussowitsch PetscCall(SNESView(snes->npc, viewer)); 5059566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5064a0c5b0cSMatthew G Knepley } 5079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5089566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &dmsnes)); 5099566063dSJacob Faibussowitsch PetscCall(DMSNESView(dmsnes, viewer)); 5109566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5112c155ee1SBarry Smith if (snes->usesksp) { 5129566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 5139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5149566063dSJacob Faibussowitsch PetscCall(KSPView(ksp, viewer)); 5159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5162c155ee1SBarry Smith } 51772a02f06SBarry Smith if (isdraw) { 51872a02f06SBarry Smith PetscDraw draw; 5199566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 5209566063dSJacob Faibussowitsch PetscCall(PetscDrawPopCurrentPoint(draw)); 5217f1410a3SPeter Brune } 5223a40ed3dSBarry Smith PetscFunctionReturn(0); 5239b94acceSBarry Smith } 5249b94acceSBarry Smith 52576b2cf59SMatthew Knepley /* 52676b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 52776b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 52876b2cf59SMatthew Knepley */ 52976b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 530a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5316849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 53276b2cf59SMatthew Knepley 533ac226902SBarry Smith /*@C 534f6dfbefdSBarry Smith SNESAddOptionsChecker - Adds an additional function to check for `SNES` options. 53576b2cf59SMatthew Knepley 53676b2cf59SMatthew Knepley Not Collective 53776b2cf59SMatthew Knepley 53876b2cf59SMatthew Knepley Input Parameter: 53976b2cf59SMatthew Knepley . snescheck - function that checks for options 54076b2cf59SMatthew Knepley 54176b2cf59SMatthew Knepley Level: developer 54276b2cf59SMatthew Knepley 543f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()` 54476b2cf59SMatthew Knepley @*/ 5459371c9d4SSatish Balay PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) { 54676b2cf59SMatthew Knepley PetscFunctionBegin; 54763a3b9bcSJacob Faibussowitsch PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 54876b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 54976b2cf59SMatthew Knepley PetscFunctionReturn(0); 55076b2cf59SMatthew Knepley } 55176b2cf59SMatthew Knepley 5529371c9d4SSatish Balay static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) { 553aa3661deSLisandro Dalcin Mat J; 554895c21f2SBarry Smith MatNullSpace nullsp; 555aa3661deSLisandro Dalcin 556aa3661deSLisandro Dalcin PetscFunctionBegin; 5570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 558aa3661deSLisandro Dalcin 55998613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 56098613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5619566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A ? A : B, NULL, &snes->vec_func)); 56298613b67SLisandro Dalcin } 56398613b67SLisandro Dalcin 564aa3661deSLisandro Dalcin if (version == 1) { 5659566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 5669566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 5679566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 5681e2ae407SBarry Smith /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 569aa3661deSLisandro Dalcin } else if (version == 2) { 5705f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "SNESSetFunction() must be called first"); 571570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 572f6dfbefdSBarry Smith PetscCall(MatCreateSNESMFMore(snes, snes->vec_func, &J)); 573aa3661deSLisandro Dalcin #else 5742479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 575aa3661deSLisandro Dalcin #endif 5762479783cSJose E. Roman } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 577aa3661deSLisandro Dalcin 578895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 579895c21f2SBarry Smith if (snes->jacobian) { 5809566063dSJacob Faibussowitsch PetscCall(MatGetNullSpace(snes->jacobian, &nullsp)); 5811baa6e33SBarry Smith if (nullsp) PetscCall(MatSetNullSpace(J, nullsp)); 582895c21f2SBarry Smith } 583895c21f2SBarry Smith 58463a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 585d3462f78SMatthew Knepley if (hasOperator) { 586aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 587aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 5889566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 589aa3661deSLisandro Dalcin } else { 590aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 5913232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 592b552625fSStefano Zampini if (snes->npcside == PC_LEFT && snes->npc) { 5939566063dSJacob Faibussowitsch if (!snes->jacobian) PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 594172a4300SPeter Brune } else { 595789d8953SBarry Smith KSP ksp; 596789d8953SBarry Smith PC pc; 597789d8953SBarry Smith PetscBool match; 598789d8953SBarry Smith 5999566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL)); 600aa3661deSLisandro Dalcin /* Force no preconditioner */ 6019566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 6029566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 6032698c518SLisandro Dalcin PetscCall(PetscObjectTypeCompareAny((PetscObject)pc, &match, PCSHELL, PCH2OPUS, "")); 604aa3661deSLisandro Dalcin if (!match) { 6059566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 6069566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, PCNONE)); 607aa3661deSLisandro Dalcin } 608aa3661deSLisandro Dalcin } 609789d8953SBarry Smith } 6109566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 611aa3661deSLisandro Dalcin PetscFunctionReturn(0); 612aa3661deSLisandro Dalcin } 613aa3661deSLisandro Dalcin 6149371c9d4SSatish Balay static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine, Mat Restrict, Vec Rscale, Mat Inject, DM dmcoarse, void *ctx) { 615dfe15315SJed Brown SNES snes = (SNES)ctx; 6160298fd71SBarry Smith Vec Xfine, Xfine_named = NULL, Xcoarse; 617dfe15315SJed Brown 618dfe15315SJed Brown PetscFunctionBegin; 61916ebb321SJed Brown if (PetscLogPrintInfo) { 62016ebb321SJed Brown PetscInt finelevel, coarselevel, fineclevel, coarseclevel; 6219566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmfine, &finelevel)); 6229566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmfine, &fineclevel)); 6239566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmcoarse, &coarselevel)); 6249566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmcoarse, &coarseclevel)); 62563a3b9bcSJacob 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)); 62616ebb321SJed Brown } 627dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 628dfe15315SJed Brown else { 6299566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 630dfe15315SJed Brown Xfine = Xfine_named; 631dfe15315SJed Brown } 6329566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 633907f5c5aSLawrence Mitchell if (Inject) { 6349566063dSJacob Faibussowitsch PetscCall(MatRestrict(Inject, Xfine, Xcoarse)); 635907f5c5aSLawrence Mitchell } else { 6369566063dSJacob Faibussowitsch PetscCall(MatRestrict(Restrict, Xfine, Xcoarse)); 6379566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Xcoarse, Xcoarse, Rscale)); 638907f5c5aSLawrence Mitchell } 6399566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 6409566063dSJacob Faibussowitsch if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 641dfe15315SJed Brown PetscFunctionReturn(0); 642dfe15315SJed Brown } 643dfe15315SJed Brown 6449371c9d4SSatish Balay static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm, DM dmc, void *ctx) { 64516ebb321SJed Brown PetscFunctionBegin; 6469566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmc, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, ctx)); 64716ebb321SJed Brown PetscFunctionReturn(0); 64816ebb321SJed Brown } 64916ebb321SJed Brown 650a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 651a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 6529371c9d4SSatish Balay static PetscErrorCode KSPComputeOperators_SNES(KSP ksp, Mat A, Mat B, void *ctx) { 653caa4e7f2SJed Brown SNES snes = (SNES)ctx; 6540298fd71SBarry Smith Vec X, Xnamed = NULL; 655dfe15315SJed Brown DM dmsave; 6564e269d77SPeter Brune void *ctxsave; 65725ce1634SJed Brown PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL; 658caa4e7f2SJed Brown 659caa4e7f2SJed Brown PetscFunctionBegin; 660dfe15315SJed Brown dmsave = snes->dm; 6619566063dSJacob Faibussowitsch PetscCall(KSPGetDM(ksp, &snes->dm)); 662dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 6639371c9d4SSatish Balay else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ PetscCall(DMGetNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 664dfe15315SJed Brown X = Xnamed; 6659566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, &ctxsave)); 6664e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 66748a46eb9SPierre Jolivet if (jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, SNESComputeJacobianDefaultColor, NULL)); 6684e269d77SPeter Brune } 6694dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 6704dde8bb0SMatthew G. Knepley { 6714dde8bb0SMatthew G. Knepley DMSNES sdm; 6724e269d77SPeter Brune 6739566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 67448a46eb9SPierre Jolivet if (!sdm->ops->computejacobian) PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 6754dde8bb0SMatthew G. Knepley } 6762b93b426SMatthew G. Knepley /* Compute the operators */ 6779566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, A, B)); 6782b93b426SMatthew G. Knepley /* Put the previous context back */ 67948a46eb9SPierre Jolivet if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, jac, ctxsave)); 6804e269d77SPeter Brune 6819566063dSJacob Faibussowitsch if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 682dfe15315SJed Brown snes->dm = dmsave; 683caa4e7f2SJed Brown PetscFunctionReturn(0); 684caa4e7f2SJed Brown } 685caa4e7f2SJed Brown 6866cab3a1bSJed Brown /*@ 687f6dfbefdSBarry Smith SNESSetUpMatrices - ensures that matrices are available for `SNES`, this is called by `SNESSetUp_XXX()` 6886cab3a1bSJed Brown 6896cab3a1bSJed Brown Collective 6906cab3a1bSJed Brown 6914165533cSJose E. Roman Input Parameter: 6926cab3a1bSJed Brown . snes - snes to configure 6936cab3a1bSJed Brown 6946cab3a1bSJed Brown Level: developer 6956cab3a1bSJed Brown 696f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetUp()` 6976cab3a1bSJed Brown @*/ 6989371c9d4SSatish Balay PetscErrorCode SNESSetUpMatrices(SNES snes) { 6996cab3a1bSJed Brown DM dm; 700942e3340SBarry Smith DMSNES sdm; 7016cab3a1bSJed Brown 7026cab3a1bSJed Brown PetscFunctionBegin; 7039566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 7049566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 70558b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7066cab3a1bSJed Brown Mat J; 7076cab3a1bSJed Brown void *functx; 7089566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7099566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7109566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7119566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 7129566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, NULL, NULL)); 7139566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 714caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7156cab3a1bSJed Brown Mat J, B; 7169566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7179566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7189566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7199566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 72006f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7219566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, B, NULL, NULL)); 7229566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 724caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7251ba9b98eSMatthew G. Knepley PetscDS prob; 7266cab3a1bSJed Brown Mat J, B; 7271ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7281ba9b98eSMatthew G. Knepley 7296cab3a1bSJed Brown J = snes->jacobian; 7309566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 7319566063dSJacob Faibussowitsch if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 7329566063dSJacob Faibussowitsch if (J) PetscCall(PetscObjectReference((PetscObject)J)); 7339566063dSJacob Faibussowitsch else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 7349566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 7359566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 7369566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 7386cab3a1bSJed Brown } 739caa4e7f2SJed Brown { 740caa4e7f2SJed Brown KSP ksp; 7419566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 7429566063dSJacob Faibussowitsch PetscCall(KSPSetComputeOperators(ksp, KSPComputeOperators_SNES, snes)); 7439566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 744caa4e7f2SJed Brown } 7456cab3a1bSJed Brown PetscFunctionReturn(0); 7466cab3a1bSJed Brown } 7476cab3a1bSJed Brown 7489371c9d4SSatish Balay static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) { 7495e7c47f3SMatthew G. Knepley PetscInt i; 7505e7c47f3SMatthew G. Knepley 7515e7c47f3SMatthew G. Knepley PetscFunctionBegin; 7525e7c47f3SMatthew G. Knepley if (!snes->pauseFinal) PetscFunctionReturn(0); 7535e7c47f3SMatthew G. Knepley for (i = 0; i < snes->numbermonitors; ++i) { 7545e7c47f3SMatthew G. Knepley PetscViewerAndFormat *vf = (PetscViewerAndFormat *)snes->monitorcontext[i]; 7555e7c47f3SMatthew G. Knepley PetscDraw draw; 7565e7c47f3SMatthew G. Knepley PetscReal lpause; 7575e7c47f3SMatthew G. Knepley 7585e7c47f3SMatthew G. Knepley if (!vf) continue; 7595e7c47f3SMatthew G. Knepley if (vf->lg) { 7605e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 7615e7c47f3SMatthew G. Knepley if (((PetscObject)vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 7629566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 7639566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7649566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7659566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7669566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7675e7c47f3SMatthew G. Knepley } else { 7685e7c47f3SMatthew G. Knepley PetscBool isdraw; 7695e7c47f3SMatthew G. Knepley 7705e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 7715e7c47f3SMatthew G. Knepley if (((PetscObject)vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 7729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &isdraw)); 7735e7c47f3SMatthew G. Knepley if (!isdraw) continue; 7749566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 7759566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7769566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7779566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7789566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7795e7c47f3SMatthew G. Knepley } 7805e7c47f3SMatthew G. Knepley } 7815e7c47f3SMatthew G. Knepley PetscFunctionReturn(0); 7825e7c47f3SMatthew G. Knepley } 7835e7c47f3SMatthew G. Knepley 784fde5950dSBarry Smith /*@C 785fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 786fde5950dSBarry Smith 787f6dfbefdSBarry Smith Collective on snes 788fde5950dSBarry Smith 789fde5950dSBarry Smith Input Parameters: 790fde5950dSBarry Smith + snes - SNES object you wish to monitor 791fde5950dSBarry Smith . name - the monitor type one is seeking 792fde5950dSBarry Smith . help - message indicating what monitoring is done 793fde5950dSBarry Smith . manual - manual page for the monitor 794fde5950dSBarry Smith . monitor - the monitor function 795f6dfbefdSBarry 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 796fde5950dSBarry Smith 797f6dfbefdSBarry Smith Options Database Key: 798f6dfbefdSBarry Smith . -name - trigger the use of this monitor in `SNESSetFromOptions()` 799f6dfbefdSBarry Smith 800f6dfbefdSBarry Smith Level: advanced 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 /*@ 849f6dfbefdSBarry Smith SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options. 8509b94acceSBarry Smith 851f6dfbefdSBarry Smith Collective on snes 852c7afd0dbSLois Curfman McInnes 8539b94acceSBarry Smith Input Parameter: 854f6dfbefdSBarry Smith . snes - the `SNES` context 8559b94acceSBarry Smith 85636851e7fSLois Curfman McInnes Options Database Keys: 857f6dfbefdSBarry 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. 874f6dfbefdSBarry Smith default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense 875f6dfbefdSBarry Smith of convergence test. correct_pressure S`NESConvergedCorrectPressure()` 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 891f6dfbefdSBarry Smith Options Database Keys 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 904f6dfbefdSBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix free, and computing explicitly with 905f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 90683e2fdc7SBarry Smith 90736851e7fSLois Curfman McInnes Level: beginner 90836851e7fSLois Curfman McInnes 909f6dfbefdSBarry Smith .seealso: `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9109b94acceSBarry Smith @*/ 9119371c9d4SSatish Balay PetscErrorCode SNESSetFromOptions(SNES snes) { 9128afaa268SBarry Smith PetscBool flg, pcset, persist, set; 913d8f46077SPeter Brune PetscInt i, indx, lag, grids; 91404d7464bSBarry Smith const char *deft = SNESNEWTONLS; 915649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 91685385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9170f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 918c40d0f55SPeter Brune PCSide pcside; 919a64e098fSPeter Brune const char *optionsprefix; 9209b94acceSBarry Smith 9213a40ed3dSBarry Smith PetscFunctionBegin; 9220700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9239566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 924d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 925639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9269566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 927d64ed03dSBarry Smith if (flg) { 9289566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9297adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9309566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 931d64ed03dSBarry Smith } 9329566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9339566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 934186905e3SBarry Smith 9359566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9369566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9379566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9389566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9399566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9409566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9419566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9429566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9439566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 94485385478SLisandro Dalcin 9459566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 946a8054027SBarry Smith if (flg) { 9475f80ce2aSJacob 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"); 9489566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 949a8054027SBarry Smith } 9509566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9511baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9529566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 953e35cf81dSBarry Smith if (flg) { 9545f80ce2aSJacob 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"); 9559566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 956e35cf81dSBarry Smith } 9579566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9581baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 95937ec4e1aSPeter Brune 9609566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9611baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 962a8054027SBarry Smith 9639566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg)); 96485385478SLisandro Dalcin if (flg) { 96585385478SLisandro Dalcin switch (indx) { 9669566063dSJacob Faibussowitsch case 0: PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); break; 9679566063dSJacob Faibussowitsch case 1: PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); break; 9689566063dSJacob Faibussowitsch case 2: PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); break; 96985385478SLisandro Dalcin } 97085385478SLisandro Dalcin } 97185385478SLisandro Dalcin 9729566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 9739566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 974fdacfa88SPeter Brune 9759566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 9769566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 977186905e3SBarry Smith 97885385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 97985385478SLisandro Dalcin 9809566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 981186905e3SBarry Smith 9820f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 9830f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 9840f0abf79SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)snes), ewprefix)); 9850f0abf79SStefano Zampini 9869566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_ksp_ew_version", "Version 1, 2 or 3", "SNESKSPSetParametersEW", kctx->version, &kctx->version, NULL)); 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0", "0 <= rtol0 < 1", "SNESKSPSetParametersEW", kctx->rtol_0, &kctx->rtol_0, NULL)); 9889566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax", "0 <= rtolmax < 1", "SNESKSPSetParametersEW", kctx->rtol_max, &kctx->rtol_max, NULL)); 9899566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma", "0 <= gamma <= 1", "SNESKSPSetParametersEW", kctx->gamma, &kctx->gamma, NULL)); 9909566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha", "1 < alpha <= 2", "SNESKSPSetParametersEW", kctx->alpha, &kctx->alpha, NULL)); 9919566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2", "alpha2", "SNESKSPSetParametersEW", kctx->alpha2, &kctx->alpha2, NULL)); 9929566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold", "0 < threshold < 1", "SNESKSPSetParametersEW", kctx->threshold, &kctx->threshold, NULL)); 993186905e3SBarry Smith 99490d69ab7SBarry Smith flg = PETSC_FALSE; 9959566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 9969566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 997eabae89aSBarry Smith 9989566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 9999566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10009566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1001eabae89aSBarry Smith 10029566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10039566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10049566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10059566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10069566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10079566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10089566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10099566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10102db13446SMatthew G. Knepley 10119566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10129566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10135180491cSLisandro Dalcin 101490d69ab7SBarry Smith flg = PETSC_FALSE; 10159566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1016459f5d12SBarry Smith if (flg) { 1017459f5d12SBarry Smith PetscViewer ctx; 1018e24b481bSBarry Smith 10199566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10209566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1021459f5d12SBarry Smith } 10222e7541e6SPeter Brune 102390d69ab7SBarry Smith flg = PETSC_FALSE; 10249566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10259566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1026c4421ceaSFande Kong 1027c4421ceaSFande Kong flg = PETSC_FALSE; 10289566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10294b27c08aSLois Curfman McInnes if (flg) { 10306cab3a1bSJed Brown void *functx; 1031b1f624c7SBarry Smith DM dm; 10329566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1033800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10349566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10359566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10369566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10379b94acceSBarry Smith } 1038639f9d9dSBarry Smith 103944848bc4SPeter Brune flg = PETSC_FALSE; 10409566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10411baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 104297584545SPeter Brune 104397584545SPeter Brune flg = PETSC_FALSE; 10449566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 104544848bc4SPeter Brune if (flg) { 1046c52e227fSPeter Brune DM dm; 10479566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1048800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10499566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10509566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 105144848bc4SPeter Brune } 105244848bc4SPeter Brune 1053aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10549566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1055d8f46077SPeter Brune if (flg && snes->mf_operator) { 1056a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1057d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1058a8248277SBarry Smith } 1059aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10609566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1061d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10629566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1063d28543b3SPeter Brune 1064c40d0f55SPeter Brune flg = PETSC_FALSE; 10659566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 10669566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 10679566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1068c40d0f55SPeter Brune 1069e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 10708a70d858SHong Zhang /* 10718a70d858SHong Zhang Publish convergence information using SAWs 10728a70d858SHong Zhang */ 10738a70d858SHong Zhang flg = PETSC_FALSE; 10749566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 10758a70d858SHong Zhang if (flg) { 10768a70d858SHong Zhang void *ctx; 10779566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 10789566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 10798a70d858SHong Zhang } 10808a70d858SHong Zhang #endif 10818a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1082b90c6cbeSBarry Smith { 1083b90c6cbeSBarry Smith PetscBool set; 1084b90c6cbeSBarry Smith flg = PETSC_FALSE; 10859566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 10861baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1087b90c6cbeSBarry Smith } 1088b90c6cbeSBarry Smith #endif 1089b90c6cbeSBarry Smith 109048a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 109176b2cf59SMatthew Knepley 1092dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 10935d973c19SBarry Smith 10945d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1095dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1096d0609cedSBarry Smith PetscOptionsEnd(); 10974bbc92c1SBarry Smith 1098d8d34be6SBarry Smith if (snes->linesearch) { 10999566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11009566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1101d8d34be6SBarry Smith } 11029e764e56SPeter Brune 11036aa5e7e9SBarry Smith if (snes->usesksp) { 11049566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11059566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11069566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11076aa5e7e9SBarry Smith } 11086991f827SBarry Smith 1109b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11109566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11119566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 111248a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11131baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1114b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 1115b3cd9a81SMatthew G. Knepley PetscFunctionReturn(0); 1116b3cd9a81SMatthew G. Knepley } 1117b3cd9a81SMatthew G. Knepley 1118b3cd9a81SMatthew G. Knepley /*@ 1119f6dfbefdSBarry Smith SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options 1120b3cd9a81SMatthew G. Knepley 1121f6dfbefdSBarry Smith Collective on snes 1122b3cd9a81SMatthew G. Knepley 1123b3cd9a81SMatthew G. Knepley Input Parameter: 1124f6dfbefdSBarry Smith . snes - the `SNES` context 1125b3cd9a81SMatthew G. Knepley 1126b3cd9a81SMatthew G. Knepley Level: beginner 1127b3cd9a81SMatthew G. Knepley 1128f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1129b3cd9a81SMatthew G. Knepley @*/ 11309371c9d4SSatish Balay PetscErrorCode SNESResetFromOptions(SNES snes) { 1131b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11329566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11333a40ed3dSBarry Smith PetscFunctionReturn(0); 11349b94acceSBarry Smith } 11359b94acceSBarry Smith 1136bb9467b5SJed Brown /*@C 1137d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1138d25893d9SBarry Smith the nonlinear solvers. 1139d25893d9SBarry Smith 1140f6dfbefdSBarry Smith Logically Collective on snes 1141d25893d9SBarry Smith 1142d25893d9SBarry Smith Input Parameters: 1143f6dfbefdSBarry Smith + snes - the `SNES` context 1144d25893d9SBarry Smith . compute - function to compute the context 1145d25893d9SBarry Smith - destroy - function to destroy the context 1146d25893d9SBarry Smith 1147d25893d9SBarry Smith Level: intermediate 1148d25893d9SBarry Smith 1149f6dfbefdSBarry Smith Note: 1150f6dfbefdSBarry Smith This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level. 1151f6dfbefdSBarry Smith 1152f6dfbefdSBarry Smith Use `SNESSetApplicationContext()` to see the context immediately 1153f6dfbefdSBarry Smith 1154f6dfbefdSBarry Smith Fortran Note: 1155bb9467b5SJed Brown This function is currently not available from Fortran. 1156bb9467b5SJed Brown 1157f6dfbefdSBarry Smith .seealso: `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESSetApplicationContext()` 1158d25893d9SBarry Smith @*/ 11599371c9d4SSatish Balay PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) { 1160d25893d9SBarry Smith PetscFunctionBegin; 1161d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1162d25893d9SBarry Smith snes->ops->usercompute = compute; 1163d25893d9SBarry Smith snes->ops->userdestroy = destroy; 1164d25893d9SBarry Smith PetscFunctionReturn(0); 1165d25893d9SBarry Smith } 1166a847f771SSatish Balay 1167b07ff414SBarry Smith /*@ 1168f6dfbefdSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers. 11699b94acceSBarry Smith 1170f6dfbefdSBarry Smith Logically Collective on snes 1171fee21e36SBarry Smith 1172c7afd0dbSLois Curfman McInnes Input Parameters: 1173f6dfbefdSBarry Smith + snes - the `SNES` context 1174c7afd0dbSLois Curfman McInnes - usrP - optional user context 1175c7afd0dbSLois Curfman McInnes 117636851e7fSLois Curfman McInnes Level: intermediate 117736851e7fSLois Curfman McInnes 1178f6dfbefdSBarry Smith Notes: 1179f6dfbefdSBarry Smith Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function 1180f6dfbefdSBarry Smith with `SNESGetApplicationContext()` 1181f6dfbefdSBarry Smith 1182f6dfbefdSBarry Smith To provide a function that computes the context for you use `SNESSetComputeApplicationContext()` 1183f6dfbefdSBarry Smith 1184f6dfbefdSBarry Smith Fortran Note: 118595452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1186daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1187daf670e6SBarry Smith 1188f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 11899b94acceSBarry Smith @*/ 11909371c9d4SSatish Balay PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) { 1191b07ff414SBarry Smith KSP ksp; 11921b2093e4SBarry Smith 11933a40ed3dSBarry Smith PetscFunctionBegin; 11940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 11959566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 11969566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 11979b94acceSBarry Smith snes->user = usrP; 11983a40ed3dSBarry Smith PetscFunctionReturn(0); 11999b94acceSBarry Smith } 120074679c65SBarry Smith 1201b07ff414SBarry Smith /*@ 12029b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 1203f6dfbefdSBarry Smith nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()` 12049b94acceSBarry Smith 1205c7afd0dbSLois Curfman McInnes Not Collective 1206c7afd0dbSLois Curfman McInnes 12079b94acceSBarry Smith Input Parameter: 1208f6dfbefdSBarry Smith . snes - `SNES` context 12099b94acceSBarry Smith 12109b94acceSBarry Smith Output Parameter: 12119b94acceSBarry Smith . usrP - user context 12129b94acceSBarry Smith 1213f6dfbefdSBarry Smith Fortran Note: 121495452b02SPatrick Sanan To use this from Fortran you must write a Fortran interface definition for this 1215daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1216daf670e6SBarry Smith 121736851e7fSLois Curfman McInnes Level: intermediate 121836851e7fSLois Curfman McInnes 1219db781477SPatrick Sanan .seealso: `SNESSetApplicationContext()` 12209b94acceSBarry Smith @*/ 12219371c9d4SSatish Balay PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) { 12223a40ed3dSBarry Smith PetscFunctionBegin; 12230700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1224e71120c6SJed Brown *(void **)usrP = snes->user; 12253a40ed3dSBarry Smith PetscFunctionReturn(0); 12269b94acceSBarry Smith } 122774679c65SBarry Smith 12289b94acceSBarry Smith /*@ 1229f6dfbefdSBarry Smith SNESSetUseMatrixFree - indicates that `SNES` should use matrix free finite difference matrix vector products to apply the Jacobian. 12303565c898SBarry Smith 1231f6dfbefdSBarry Smith Logically Collective on snes, the values must be the same on all MPI ranks 12323565c898SBarry Smith 12333565c898SBarry Smith Input Parameters: 1234f6dfbefdSBarry Smith + snes - `SNES` context 1235f6dfbefdSBarry Smith . mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1236f6dfbefdSBarry Smith - mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored. With 1237f6dfbefdSBarry Smith this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available 12383565c898SBarry Smith 1239f6dfbefdSBarry Smith Options Database Keys: 1240f6dfbefdSBarry Smith + -snes_mf_operator - use matrix free only for the mat operator 1241f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator 1242ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1243ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12443565c898SBarry Smith 12453565c898SBarry Smith Level: intermediate 12463565c898SBarry Smith 1247f6dfbefdSBarry Smith Note: 1248f6dfbefdSBarry Smith SNES supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 1249f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 1250ec5066bdSBarry Smith 1251f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12523565c898SBarry Smith @*/ 12539371c9d4SSatish Balay PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) { 12543565c898SBarry Smith PetscFunctionBegin; 12553565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 125688b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 125788b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12584ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12593565c898SBarry Smith snes->mf_operator = mf_operator; 12603565c898SBarry Smith PetscFunctionReturn(0); 12613565c898SBarry Smith } 12623565c898SBarry Smith 12633565c898SBarry Smith /*@ 1264f6dfbefdSBarry Smith SNESGetUseMatrixFree - indicates if the SNES uses matrix-free finite difference matrix vector products to apply the Jacobian. 12653565c898SBarry Smith 1266f6dfbefdSBarry Smith Not Collective, but the resulting flags will be the same on all MPI ranks 12673565c898SBarry Smith 12683565c898SBarry Smith Input Parameter: 1269f6dfbefdSBarry Smith . snes - `SNES` context 12703565c898SBarry Smith 12713565c898SBarry Smith Output Parameters: 1272f6dfbefdSBarry Smith + mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1273f6dfbefdSBarry Smith - mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored 12743565c898SBarry Smith 12753565c898SBarry Smith Level: intermediate 12763565c898SBarry Smith 1277f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 12783565c898SBarry Smith @*/ 12799371c9d4SSatish Balay PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) { 12803565c898SBarry Smith PetscFunctionBegin; 12813565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12823565c898SBarry Smith if (mf) *mf = snes->mf; 12833565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 12843565c898SBarry Smith PetscFunctionReturn(0); 12853565c898SBarry Smith } 12863565c898SBarry Smith 12873565c898SBarry Smith /*@ 1288c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1289c8228a4eSBarry Smith at this time. 12909b94acceSBarry Smith 1291c7afd0dbSLois Curfman McInnes Not Collective 1292c7afd0dbSLois Curfman McInnes 12939b94acceSBarry Smith Input Parameter: 1294f6dfbefdSBarry Smith . snes - `SNES` context 12959b94acceSBarry Smith 12969b94acceSBarry Smith Output Parameter: 12979b94acceSBarry Smith . iter - iteration number 12989b94acceSBarry Smith 1299c8228a4eSBarry Smith Notes: 1300c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1301c8228a4eSBarry Smith 1302c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 1303f6dfbefdSBarry Smith Jacobian at each `SNES` iteration). For example, the code 130408405cd6SLois Curfman McInnes .vb 130508405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 130608405cd6SLois Curfman McInnes if (!(it % 2)) { 130708405cd6SLois Curfman McInnes [compute Jacobian here] 130808405cd6SLois Curfman McInnes } 130908405cd6SLois Curfman McInnes .ve 1310f6dfbefdSBarry Smith can be used in your function that computes the Jacobian to cause the Jacobian to be 1311f6dfbefdSBarry Smith recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()` 1312c8228a4eSBarry Smith 1313f6dfbefdSBarry Smith After the `SNES` solve is complete this will return the number of nonlinear iterations used. 1314c04deec6SBarry Smith 131536851e7fSLois Curfman McInnes Level: intermediate 131636851e7fSLois Curfman McInnes 1317f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()` 13189b94acceSBarry Smith @*/ 13199371c9d4SSatish Balay PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) { 13203a40ed3dSBarry Smith PetscFunctionBegin; 13210700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13224482741eSBarry Smith PetscValidIntPointer(iter, 2); 13239b94acceSBarry Smith *iter = snes->iter; 13243a40ed3dSBarry Smith PetscFunctionReturn(0); 13259b94acceSBarry Smith } 132674679c65SBarry Smith 1327360c497dSPeter Brune /*@ 1328360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1329360c497dSPeter Brune 1330360c497dSPeter Brune Not Collective 1331360c497dSPeter Brune 1332d8d19677SJose E. Roman Input Parameters: 1333f6dfbefdSBarry Smith + snes - `SNES` context 1334a2b725a8SWilliam Gropp - iter - iteration number 1335360c497dSPeter Brune 1336360c497dSPeter Brune Level: developer 1337360c497dSPeter Brune 1338db781477SPatrick Sanan .seealso: `SNESGetLinearSolveIterations()` 1339360c497dSPeter Brune @*/ 13409371c9d4SSatish Balay PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) { 1341360c497dSPeter Brune PetscFunctionBegin; 1342360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13439566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1344360c497dSPeter Brune snes->iter = iter; 13459566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 1346360c497dSPeter Brune PetscFunctionReturn(0); 1347360c497dSPeter Brune } 1348360c497dSPeter Brune 13499b94acceSBarry Smith /*@ 1350b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13519b94acceSBarry Smith attempted by the nonlinear solver. 13529b94acceSBarry Smith 1353c7afd0dbSLois Curfman McInnes Not Collective 1354c7afd0dbSLois Curfman McInnes 13559b94acceSBarry Smith Input Parameter: 1356f6dfbefdSBarry Smith . snes - `SNES` context 13579b94acceSBarry Smith 13589b94acceSBarry Smith Output Parameter: 13599b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13609b94acceSBarry Smith 1361f6dfbefdSBarry Smith Note: 1362f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 1363c96a6f78SLois Curfman McInnes 136436851e7fSLois Curfman McInnes Level: intermediate 136536851e7fSLois Curfman McInnes 1366f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1367db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 13689b94acceSBarry Smith @*/ 13699371c9d4SSatish Balay PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) { 13703a40ed3dSBarry Smith PetscFunctionBegin; 13710700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13724482741eSBarry Smith PetscValidIntPointer(nfails, 2); 137350ffb88aSMatthew Knepley *nfails = snes->numFailures; 137450ffb88aSMatthew Knepley PetscFunctionReturn(0); 137550ffb88aSMatthew Knepley } 137650ffb88aSMatthew Knepley 137750ffb88aSMatthew Knepley /*@ 1378b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1379f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 138050ffb88aSMatthew Knepley 138150ffb88aSMatthew Knepley Not Collective 138250ffb88aSMatthew Knepley 138350ffb88aSMatthew Knepley Input Parameters: 1384f6dfbefdSBarry Smith + snes - `SNES` context 138550ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 138650ffb88aSMatthew Knepley 138750ffb88aSMatthew Knepley Level: intermediate 138850ffb88aSMatthew Knepley 1389f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1390db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 139150ffb88aSMatthew Knepley @*/ 13929371c9d4SSatish Balay PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) { 139350ffb88aSMatthew Knepley PetscFunctionBegin; 13940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 139550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 139650ffb88aSMatthew Knepley PetscFunctionReturn(0); 139750ffb88aSMatthew Knepley } 139850ffb88aSMatthew Knepley 139950ffb88aSMatthew Knepley /*@ 1400b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1401f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 140250ffb88aSMatthew Knepley 140350ffb88aSMatthew Knepley Not Collective 140450ffb88aSMatthew Knepley 140550ffb88aSMatthew Knepley Input Parameter: 140650ffb88aSMatthew Knepley . snes - SNES context 140750ffb88aSMatthew Knepley 140850ffb88aSMatthew Knepley Output Parameter: 140950ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 141050ffb88aSMatthew Knepley 141150ffb88aSMatthew Knepley Level: intermediate 141250ffb88aSMatthew Knepley 1413f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1414db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 141550ffb88aSMatthew Knepley @*/ 14169371c9d4SSatish Balay PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) { 141750ffb88aSMatthew Knepley PetscFunctionBegin; 14180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14194482741eSBarry Smith PetscValidIntPointer(maxFails, 2); 142050ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14213a40ed3dSBarry Smith PetscFunctionReturn(0); 14229b94acceSBarry Smith } 1423a847f771SSatish Balay 14242541af92SBarry Smith /*@ 14252541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1426f6dfbefdSBarry Smith done by the `SNES` object 14272541af92SBarry Smith 14282541af92SBarry Smith Not Collective 14292541af92SBarry Smith 14302541af92SBarry Smith Input Parameter: 1431f6dfbefdSBarry Smith . snes - `SNES` context 14322541af92SBarry Smith 14332541af92SBarry Smith Output Parameter: 14342541af92SBarry Smith . nfuncs - number of evaluations 14352541af92SBarry Smith 14362541af92SBarry Smith Level: intermediate 14372541af92SBarry Smith 1438f6dfbefdSBarry Smith Note: 1439f6dfbefdSBarry Smith Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used. 1440971e163fSPeter Brune 1441f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14422541af92SBarry Smith @*/ 14439371c9d4SSatish Balay PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) { 14442541af92SBarry Smith PetscFunctionBegin; 14450700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14462541af92SBarry Smith PetscValidIntPointer(nfuncs, 2); 14472541af92SBarry Smith *nfuncs = snes->nfuncs; 14482541af92SBarry Smith PetscFunctionReturn(0); 14492541af92SBarry Smith } 14502541af92SBarry Smith 14513d4c4710SBarry Smith /*@ 14523d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14533d4c4710SBarry Smith linear solvers. 14543d4c4710SBarry Smith 14553d4c4710SBarry Smith Not Collective 14563d4c4710SBarry Smith 14573d4c4710SBarry Smith Input Parameter: 1458f6dfbefdSBarry Smith . snes - `SNES` context 14593d4c4710SBarry Smith 14603d4c4710SBarry Smith Output Parameter: 14613d4c4710SBarry Smith . nfails - number of failed solves 14623d4c4710SBarry Smith 1463f6dfbefdSBarry Smith Options Database Key: 14649d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14659d85da0cSMatthew G. Knepley 1466f6dfbefdSBarry Smith Level: intermediate 1467f6dfbefdSBarry Smith 1468f6dfbefdSBarry Smith Note: 1469f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 14703d4c4710SBarry Smith 1471db781477SPatrick Sanan .seealso: `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 14723d4c4710SBarry Smith @*/ 14739371c9d4SSatish Balay PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) { 14743d4c4710SBarry Smith PetscFunctionBegin; 14750700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14763d4c4710SBarry Smith PetscValidIntPointer(nfails, 2); 14773d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 14783d4c4710SBarry Smith PetscFunctionReturn(0); 14793d4c4710SBarry Smith } 14803d4c4710SBarry Smith 14813d4c4710SBarry Smith /*@ 14823d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1483f6dfbefdSBarry Smith allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE` 14843d4c4710SBarry Smith 1485f6dfbefdSBarry Smith Logically Collective on snes 14863d4c4710SBarry Smith 14873d4c4710SBarry Smith Input Parameters: 1488f6dfbefdSBarry Smith + snes - `SNES` context 14893d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 14903d4c4710SBarry Smith 14913d4c4710SBarry Smith Level: intermediate 14923d4c4710SBarry Smith 1493f6dfbefdSBarry Smith Options Database Key: 14949d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 14959d85da0cSMatthew G. Knepley 1496f6dfbefdSBarry Smith Note: 1497f6dfbefdSBarry Smith By default this is 0; that is `SNES` returns on the first failed linear solve 14983d4c4710SBarry Smith 1499f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15003d4c4710SBarry Smith @*/ 15019371c9d4SSatish Balay PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) { 15023d4c4710SBarry Smith PetscFunctionBegin; 15030700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1504c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15053d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15063d4c4710SBarry Smith PetscFunctionReturn(0); 15073d4c4710SBarry Smith } 15083d4c4710SBarry Smith 15093d4c4710SBarry Smith /*@ 15103d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1511f6dfbefdSBarry Smith are allowed before `SNES` returns as unsuccessful 15123d4c4710SBarry Smith 15133d4c4710SBarry Smith Not Collective 15143d4c4710SBarry Smith 15153d4c4710SBarry Smith Input Parameter: 1516f6dfbefdSBarry Smith . snes - `SNES` context 15173d4c4710SBarry Smith 15183d4c4710SBarry Smith Output Parameter: 15193d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15203d4c4710SBarry Smith 15213d4c4710SBarry Smith Level: intermediate 15223d4c4710SBarry Smith 1523f6dfbefdSBarry Smith Note: 1524f6dfbefdSBarry Smith By default this is 1; that is `SNES` returns on the first failed linear solve 15253d4c4710SBarry Smith 1526f6dfbefdSBarry Smith .seealso: `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15273d4c4710SBarry Smith @*/ 15289371c9d4SSatish Balay PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) { 15293d4c4710SBarry Smith PetscFunctionBegin; 15300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15313d4c4710SBarry Smith PetscValidIntPointer(maxFails, 2); 15323d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15333d4c4710SBarry Smith PetscFunctionReturn(0); 15343d4c4710SBarry Smith } 15353d4c4710SBarry Smith 1536c96a6f78SLois Curfman McInnes /*@ 1537b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1538c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1539c96a6f78SLois Curfman McInnes 1540c7afd0dbSLois Curfman McInnes Not Collective 1541c7afd0dbSLois Curfman McInnes 1542c96a6f78SLois Curfman McInnes Input Parameter: 1543f6dfbefdSBarry Smith . snes - `SNES` context 1544c96a6f78SLois Curfman McInnes 1545c96a6f78SLois Curfman McInnes Output Parameter: 1546c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1547c96a6f78SLois Curfman McInnes 1548c96a6f78SLois Curfman McInnes Notes: 1549f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used. 1550c96a6f78SLois Curfman McInnes 1551f6dfbefdSBarry 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 1552f6dfbefdSBarry Smith then call `KSPGetIterationNumber()` after the failed solve. 1553010be392SBarry Smith 155436851e7fSLois Curfman McInnes Level: intermediate 155536851e7fSLois Curfman McInnes 1556f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1557c96a6f78SLois Curfman McInnes @*/ 15589371c9d4SSatish Balay PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) { 15593a40ed3dSBarry Smith PetscFunctionBegin; 15600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15614482741eSBarry Smith PetscValidIntPointer(lits, 2); 1562c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 15633a40ed3dSBarry Smith PetscFunctionReturn(0); 1564c96a6f78SLois Curfman McInnes } 1565c96a6f78SLois Curfman McInnes 1566971e163fSPeter Brune /*@ 1567971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1568f6dfbefdSBarry Smith are reset every time `SNESSolve()` is called. 1569971e163fSPeter Brune 1570f6dfbefdSBarry Smith Logically Collective on snes 1571971e163fSPeter Brune 1572d8d19677SJose E. Roman Input Parameters: 1573f6dfbefdSBarry Smith + snes - `SNES` context 1574f6dfbefdSBarry Smith - reset - whether to reset the counters or not, defaults to `PETSC_TRUE` 1575971e163fSPeter Brune 1576971e163fSPeter Brune Level: developer 1577971e163fSPeter Brune 1578db781477SPatrick Sanan .seealso: `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1579971e163fSPeter Brune @*/ 15809371c9d4SSatish Balay PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) { 1581971e163fSPeter Brune PetscFunctionBegin; 1582971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1583971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1584971e163fSPeter Brune snes->counters_reset = reset; 1585971e163fSPeter Brune PetscFunctionReturn(0); 1586971e163fSPeter Brune } 1587971e163fSPeter Brune 15882999313aSBarry Smith /*@ 1589f6dfbefdSBarry Smith SNESSetKSP - Sets a `KSP` context for the `SNES` object to use 15902999313aSBarry Smith 1591f6dfbefdSBarry Smith Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm 15922999313aSBarry Smith 15932999313aSBarry Smith Input Parameters: 1594f6dfbefdSBarry Smith + snes - the `SNES` context 1595f6dfbefdSBarry Smith - ksp - the `KSP` context 15962999313aSBarry Smith 15972999313aSBarry Smith Notes: 1598f6dfbefdSBarry Smith The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()` 15992999313aSBarry Smith so this routine is rarely needed. 16002999313aSBarry Smith 1601f6dfbefdSBarry Smith The `KSP` object that is already in the `SNES` object has its reference count 16022999313aSBarry Smith decreased by one. 16032999313aSBarry Smith 16042999313aSBarry Smith Level: developer 16052999313aSBarry Smith 1606f6dfbefdSBarry Smith .seealso: `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16072999313aSBarry Smith @*/ 16089371c9d4SSatish Balay PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) { 16092999313aSBarry Smith PetscFunctionBegin; 16100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16110700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16122999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16139566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16149566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16152999313aSBarry Smith snes->ksp = ksp; 16162999313aSBarry Smith PetscFunctionReturn(0); 16172999313aSBarry Smith } 16182999313aSBarry Smith 161952baeb72SSatish Balay /*@ 16209b94acceSBarry Smith SNESCreate - Creates a nonlinear solver context. 16219b94acceSBarry Smith 1622d083f849SBarry Smith Collective 1623c7afd0dbSLois Curfman McInnes 1624f6dfbefdSBarry Smith Input Parameter: 1625906ed7ccSBarry Smith . comm - MPI communicator 16269b94acceSBarry Smith 16279b94acceSBarry Smith Output Parameter: 16289b94acceSBarry Smith . outsnes - the new SNES context 16299b94acceSBarry Smith 1630c7afd0dbSLois Curfman McInnes Options Database Keys: 1631c7afd0dbSLois Curfman McInnes + -snes_mf - Activates default matrix-free Jacobian-vector products, 1632c7afd0dbSLois Curfman McInnes and no preconditioning matrix 1633c7afd0dbSLois Curfman McInnes . -snes_mf_operator - Activates default matrix-free Jacobian-vector 1634c7afd0dbSLois Curfman McInnes products, and a user-provided preconditioning matrix 1635c7afd0dbSLois Curfman McInnes as set by SNESSetJacobian() 1636c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1637c1f60f51SBarry Smith 163836851e7fSLois Curfman McInnes Level: beginner 163936851e7fSLois Curfman McInnes 164095452b02SPatrick Sanan Developer Notes: 1641f6dfbefdSBarry Smith `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is 1642efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1643f6dfbefdSBarry Smith particular method does use `KSP` and regulates if the information about the `KSP` is printed 1644f6dfbefdSBarry Smith in `SNESView()`. 1645efd4aadfSBarry Smith 1646f6dfbefdSBarry Smith `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused 1647f6dfbefdSBarry Smith by help messages about meaningless `SNES` options. 1648f6dfbefdSBarry Smith 1649f6dfbefdSBarry Smith `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should 1650efd4aadfSBarry Smith be fixed. 1651efd4aadfSBarry Smith 1652f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 16539b94acceSBarry Smith @*/ 16549371c9d4SSatish Balay PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) { 16559b94acceSBarry Smith SNES snes; 1656fa9f3622SBarry Smith SNESKSPEW *kctx; 165737fcc0dbSBarry Smith 16583a40ed3dSBarry Smith PetscFunctionBegin; 1659ed1caa07SMatthew Knepley PetscValidPointer(outsnes, 2); 16600298fd71SBarry Smith *outsnes = NULL; 16619566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 16628ba1e511SMatthew Knepley 16639566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 16647adad957SLisandro Dalcin 16658d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 16662c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 166788976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 16689b94acceSBarry Smith snes->max_its = 50; 16699750a799SBarry Smith snes->max_funcs = 10000; 16709b94acceSBarry Smith snes->norm = 0.0; 1671c1e67a49SFande Kong snes->xnorm = 0.0; 1672c1e67a49SFande Kong snes->ynorm = 0.0; 1673365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 16746c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 16753a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16763a2046daSBarry Smith snes->rtol = 1.e-5; 16773a2046daSBarry Smith #else 1678b4874afaSBarry Smith snes->rtol = 1.e-8; 16793a2046daSBarry Smith #endif 1680b4874afaSBarry Smith snes->ttol = 0.0; 16813a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16823a2046daSBarry Smith snes->abstol = 1.e-25; 16833a2046daSBarry Smith #else 168470441072SBarry Smith snes->abstol = 1.e-50; 16853a2046daSBarry Smith #endif 16867cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 16877cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 16887cd0ae37SLisandro Dalcin #else 1689c60f73f4SPeter Brune snes->stol = 1.e-8; 16907cd0ae37SLisandro Dalcin #endif 16913a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 16923a2046daSBarry Smith snes->deltatol = 1.e-6; 16933a2046daSBarry Smith #else 16944b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 16953a2046daSBarry Smith #endif 1696e37c518bSBarry Smith snes->divtol = 1.e4; 1697e37c518bSBarry Smith snes->rnorm0 = 0; 16989b94acceSBarry Smith snes->nfuncs = 0; 169950ffb88aSMatthew Knepley snes->numFailures = 0; 170050ffb88aSMatthew Knepley snes->maxFailures = 1; 17017a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1702e35cf81dSBarry Smith snes->lagjacobian = 1; 170337ec4e1aSPeter Brune snes->jac_iter = 0; 170437ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1705a8054027SBarry Smith snes->lagpreconditioner = 1; 170637ec4e1aSPeter Brune snes->pre_iter = 0; 170737ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1708639f9d9dSBarry Smith snes->numbermonitors = 0; 1709c4421ceaSFande Kong snes->numberreasonviews = 0; 17109e5d0892SLisandro Dalcin snes->data = NULL; 17114dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1712186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17136f24a144SLois Curfman McInnes snes->nwork = 0; 17149e5d0892SLisandro Dalcin snes->work = NULL; 171558c9b817SLisandro Dalcin snes->nvwork = 0; 17169e5d0892SLisandro Dalcin snes->vwork = NULL; 1717758f92a0SBarry Smith snes->conv_hist_len = 0; 1718758f92a0SBarry Smith snes->conv_hist_max = 0; 17190298fd71SBarry Smith snes->conv_hist = NULL; 17200298fd71SBarry Smith snes->conv_hist_its = NULL; 1721758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1722971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1723e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1724184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1725efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1726b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1727c40d0f55SPeter Brune 1728d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1729d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1730d8f46077SPeter Brune snes->mf_version = 1; 1731d8f46077SPeter Brune 17323d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17333d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17343d4c4710SBarry Smith 1735349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 173676bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1737349187a7SBarry Smith 17384fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17394fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17404fc747eaSLawrence Mitchell 17419b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17429566063dSJacob Faibussowitsch PetscCall(PetscNewLog(snes, &kctx)); 1743f5af7f23SKarl Rupp 17449b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17459b94acceSBarry Smith kctx->version = 2; 17460f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17479b94acceSBarry Smith this was too large for some test cases */ 174875567043SBarry Smith kctx->rtol_last = 0.0; 17490f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17509b94acceSBarry Smith kctx->gamma = 1.0; 17510f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 175271f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17530f0abf79SStefano Zampini kctx->threshold = 0.1; 175475567043SBarry Smith kctx->lresid_last = 0.0; 175575567043SBarry Smith kctx->norm_last = 0.0; 17569b94acceSBarry Smith 17570f0abf79SStefano Zampini kctx->rk_last = 0.0; 17580f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 17590f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 17600f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 17610f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 17620f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 17630f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 17640f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 17650f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 17660f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 17670f0abf79SStefano Zampini 17689b94acceSBarry Smith *outsnes = snes; 17693a40ed3dSBarry Smith PetscFunctionReturn(0); 17709b94acceSBarry Smith } 17719b94acceSBarry Smith 177288f0584fSBarry Smith /*MC 1773f6dfbefdSBarry Smith SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()` 177488f0584fSBarry Smith 177588f0584fSBarry Smith Synopsis: 1776411c0326SBarry Smith #include "petscsnes.h" 1777411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 177888f0584fSBarry Smith 17791843f636SBarry Smith Collective on snes 17801843f636SBarry Smith 178188f0584fSBarry Smith Input Parameters: 1782f6dfbefdSBarry Smith + snes - the `SNES` context 178388f0584fSBarry Smith . x - state at which to evaluate residual 1784f6dfbefdSBarry Smith - ctx - optional user-defined function context, passed in with `SNESSetFunction()` 178588f0584fSBarry Smith 178688f0584fSBarry Smith Output Parameter: 178788f0584fSBarry Smith . f - vector to put residual (function value) 178888f0584fSBarry Smith 1789878cb397SSatish Balay Level: intermediate 1790878cb397SSatish Balay 1791db781477SPatrick Sanan .seealso: `SNESSetFunction()`, `SNESGetFunction()` 179288f0584fSBarry Smith M*/ 179388f0584fSBarry Smith 17949b94acceSBarry Smith /*@C 17959b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 1796f6dfbefdSBarry Smith vector for use by the `SNES` routines in solving systems of nonlinear 17979b94acceSBarry Smith equations. 17989b94acceSBarry Smith 1799f6dfbefdSBarry Smith Logically Collective on snes 1800fee21e36SBarry Smith 1801c7afd0dbSLois Curfman McInnes Input Parameters: 1802f6dfbefdSBarry Smith + snes - the `SNES` context 18036b7fb656SBarry Smith . r - vector to store function values, may be NULL 1804f6dfbefdSBarry Smith . f - function evaluation routine; see `SNESFunction` for calling sequence details 1805c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 18060298fd71SBarry Smith function evaluation routine (may be NULL) 18079b94acceSBarry Smith 180836851e7fSLois Curfman McInnes Level: beginner 180936851e7fSLois Curfman McInnes 1810f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18119b94acceSBarry Smith @*/ 18129371c9d4SSatish Balay PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) { 18136cab3a1bSJed Brown DM dm; 18146cab3a1bSJed Brown 18153a40ed3dSBarry Smith PetscFunctionBegin; 18160700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1817d2a683ecSLisandro Dalcin if (r) { 1818d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1819d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18209566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18219566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 182285385478SLisandro Dalcin snes->vec_func = r; 1823d2a683ecSLisandro Dalcin } 18249566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18259566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 182648a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18273a40ed3dSBarry Smith PetscFunctionReturn(0); 18289b94acceSBarry Smith } 18299b94acceSBarry Smith 1830e4ed7901SPeter Brune /*@C 1831e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1832f6dfbefdSBarry Smith initial function value at the initialization of the method. In some 1833e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1834f6dfbefdSBarry Smith `SNESSolve()`. This function allows one to avoid a redundant call 1835f6dfbefdSBarry Smith to `SNESComputeFunction()` in that case. 1836e4ed7901SPeter Brune 1837f6dfbefdSBarry Smith Logically Collective on snes 1838e4ed7901SPeter Brune 1839e4ed7901SPeter Brune Input Parameters: 1840f6dfbefdSBarry Smith + snes - the `SNES` context 1841e4ed7901SPeter Brune - f - vector to store function value 1842e4ed7901SPeter Brune 1843e4ed7901SPeter Brune Notes: 1844e4ed7901SPeter Brune This should not be modified during the solution procedure. 1845e4ed7901SPeter Brune 1846f6dfbefdSBarry Smith This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning. 1847e4ed7901SPeter Brune 1848e4ed7901SPeter Brune Level: developer 1849e4ed7901SPeter Brune 1850f6dfbefdSBarry Smith .seealso: `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1851e4ed7901SPeter Brune @*/ 18529371c9d4SSatish Balay PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) { 1853e4ed7901SPeter Brune Vec vec_func; 1854e4ed7901SPeter Brune 1855e4ed7901SPeter Brune PetscFunctionBegin; 1856e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1857e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1858e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1859efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1860902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1861902f982fSPeter Brune PetscFunctionReturn(0); 1862902f982fSPeter Brune } 18639566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 18649566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1865f5af7f23SKarl Rupp 1866217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 1867e4ed7901SPeter Brune PetscFunctionReturn(0); 1868e4ed7901SPeter Brune } 1869e4ed7901SPeter Brune 1870534ebe21SPeter Brune /*@ 1871f6dfbefdSBarry Smith SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring 1872f6dfbefdSBarry Smith of the `SNES` method, when norms are computed in the solving process 1873534ebe21SPeter Brune 1874f6dfbefdSBarry Smith Logically Collective on snes 1875534ebe21SPeter Brune 1876534ebe21SPeter Brune Input Parameters: 1877f6dfbefdSBarry Smith + snes - the `SNES` context 1878365a6726SPeter Brune - normschedule - the frequency of norm computation 1879534ebe21SPeter Brune 1880517f1916SMatthew G. Knepley Options Database Key: 188167b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1882517f1916SMatthew G. Knepley 1883534ebe21SPeter Brune Notes: 1884f6dfbefdSBarry Smith Only certain `SNES` methods support certain `SNESNormSchedules`. Most require evaluation 1885534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1886534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1887f6dfbefdSBarry Smith `SNESNGS` and the like do not require the norm of the function to be computed, and therefore 1888534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1889534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1890534ebe21SPeter Brune their solution. 1891534ebe21SPeter Brune 1892f6dfbefdSBarry Smith Level: advanced 1893534ebe21SPeter Brune 1894f6dfbefdSBarry Smith .seealso: `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1895534ebe21SPeter Brune @*/ 18969371c9d4SSatish Balay PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) { 1897534ebe21SPeter Brune PetscFunctionBegin; 1898534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1899365a6726SPeter Brune snes->normschedule = normschedule; 1900534ebe21SPeter Brune PetscFunctionReturn(0); 1901534ebe21SPeter Brune } 1902534ebe21SPeter Brune 1903534ebe21SPeter Brune /*@ 1904f6dfbefdSBarry Smith SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring 1905f6dfbefdSBarry Smith of the `SNES` method. 1906534ebe21SPeter Brune 1907f6dfbefdSBarry Smith Logically Collective on snes 1908534ebe21SPeter Brune 1909534ebe21SPeter Brune Input Parameters: 1910f6dfbefdSBarry Smith + snes - the `SNES` context 1911365a6726SPeter Brune - normschedule - the type of the norm used 1912534ebe21SPeter Brune 1913534ebe21SPeter Brune Level: advanced 1914534ebe21SPeter Brune 1915f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1916534ebe21SPeter Brune @*/ 19179371c9d4SSatish Balay PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) { 1918534ebe21SPeter Brune PetscFunctionBegin; 1919534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1920365a6726SPeter Brune *normschedule = snes->normschedule; 1921534ebe21SPeter Brune PetscFunctionReturn(0); 1922534ebe21SPeter Brune } 1923534ebe21SPeter Brune 1924c5ce4427SMatthew G. Knepley /*@ 1925c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1926c5ce4427SMatthew G. Knepley 1927f6dfbefdSBarry Smith Logically Collective on snes 1928c5ce4427SMatthew G. Knepley 1929c5ce4427SMatthew G. Knepley Input Parameters: 1930f6dfbefdSBarry Smith + snes - the `SNES` context 1931f6dfbefdSBarry Smith - norm - the value of the norm 1932c5ce4427SMatthew G. Knepley 1933c5ce4427SMatthew G. Knepley Level: developer 1934c5ce4427SMatthew G. Knepley 1935f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1936c5ce4427SMatthew G. Knepley @*/ 19379371c9d4SSatish Balay PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) { 1938c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1939c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1940c5ce4427SMatthew G. Knepley snes->norm = norm; 1941c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1942c5ce4427SMatthew G. Knepley } 1943c5ce4427SMatthew G. Knepley 1944c5ce4427SMatthew G. Knepley /*@ 1945c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1946c5ce4427SMatthew G. Knepley 1947c5ce4427SMatthew G. Knepley Not Collective 1948c5ce4427SMatthew G. Knepley 1949c5ce4427SMatthew G. Knepley Input Parameter: 1950f6dfbefdSBarry Smith . snes - the `SNES` context 1951c5ce4427SMatthew G. Knepley 1952c5ce4427SMatthew G. Knepley Output Parameter: 1953c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1954c5ce4427SMatthew G. Knepley 1955c5ce4427SMatthew G. Knepley Level: developer 1956c5ce4427SMatthew G. Knepley 1957f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1958c5ce4427SMatthew G. Knepley @*/ 19599371c9d4SSatish Balay PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) { 1960c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1961c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1962dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 1963c5ce4427SMatthew G. Knepley *norm = snes->norm; 1964c5ce4427SMatthew G. Knepley PetscFunctionReturn(0); 1965c5ce4427SMatthew G. Knepley } 1966c5ce4427SMatthew G. Knepley 1967c1e67a49SFande Kong /*@ 1968f6dfbefdSBarry Smith SNESGetUpdateNorm - Gets the last computed norm of the solution update 1969c1e67a49SFande Kong 1970c1e67a49SFande Kong Not Collective 1971c1e67a49SFande Kong 1972c1e67a49SFande Kong Input Parameter: 1973f6dfbefdSBarry Smith . snes - the `SNES` context 1974c1e67a49SFande Kong 1975c1e67a49SFande Kong Output Parameter: 1976c1e67a49SFande Kong . ynorm - the last computed update norm 1977c1e67a49SFande Kong 1978c1e67a49SFande Kong Level: developer 1979c1e67a49SFande Kong 1980f6dfbefdSBarry Smith Note: 1981f6dfbefdSBarry Smith The new solution is the current solution plus the update, so this norm is an indication of the size of the update 1982f6dfbefdSBarry Smith 1983f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 1984c1e67a49SFande Kong @*/ 19859371c9d4SSatish Balay PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) { 1986c1e67a49SFande Kong PetscFunctionBegin; 1987c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1988dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 1989c1e67a49SFande Kong *ynorm = snes->ynorm; 1990c1e67a49SFande Kong PetscFunctionReturn(0); 1991c1e67a49SFande Kong } 1992c1e67a49SFande Kong 1993c1e67a49SFande Kong /*@ 19944591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 1995c1e67a49SFande Kong 1996c1e67a49SFande Kong Not Collective 1997c1e67a49SFande Kong 1998c1e67a49SFande Kong Input Parameter: 1999f6dfbefdSBarry Smith . snes - the `SNES` context 2000c1e67a49SFande Kong 2001c1e67a49SFande Kong Output Parameter: 2002c1e67a49SFande Kong . xnorm - the last computed solution norm 2003c1e67a49SFande Kong 2004c1e67a49SFande Kong Level: developer 2005c1e67a49SFande Kong 2006f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2007c1e67a49SFande Kong @*/ 20089371c9d4SSatish Balay PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) { 2009c1e67a49SFande Kong PetscFunctionBegin; 2010c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2011dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2012c1e67a49SFande Kong *xnorm = snes->xnorm; 2013c1e67a49SFande Kong PetscFunctionReturn(0); 2014c1e67a49SFande Kong } 2015c1e67a49SFande Kong 201647073ea2SPeter Brune /*@C 2017f6dfbefdSBarry Smith SNESSetFunctionType - Sets the `SNESFunctionType` 2018f6dfbefdSBarry Smith of the `SNES` method. 201947073ea2SPeter Brune 2020f6dfbefdSBarry Smith Logically Collective on snes 202147073ea2SPeter Brune 202247073ea2SPeter Brune Input Parameters: 2023f6dfbefdSBarry Smith + snes - the `SNES` context 2024f6dfbefdSBarry Smith - type - the function type 202547073ea2SPeter Brune 202647073ea2SPeter Brune Level: developer 202747073ea2SPeter Brune 2028f6dfbefdSBarry Smith Notes: 2029f6dfbefdSBarry Smith Possible values of the function type 2030f6dfbefdSBarry Smith + `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType` 2031f6dfbefdSBarry Smith . `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()` 2032f6dfbefdSBarry Smith - `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()` 2033f6dfbefdSBarry Smith 2034f6dfbefdSBarry Smith Different `SNESType`s use this value in different ways 2035f6dfbefdSBarry Smith 2036f6dfbefdSBarry Smith .seealso: `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 203747073ea2SPeter Brune @*/ 20389371c9d4SSatish Balay PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) { 203947073ea2SPeter Brune PetscFunctionBegin; 204047073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 204147073ea2SPeter Brune snes->functype = type; 204247073ea2SPeter Brune PetscFunctionReturn(0); 204347073ea2SPeter Brune } 204447073ea2SPeter Brune 204547073ea2SPeter Brune /*@C 2046f6dfbefdSBarry Smith SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()` 204747073ea2SPeter Brune of the SNES method. 204847073ea2SPeter Brune 2049f6dfbefdSBarry Smith Logically Collective on snes 205047073ea2SPeter Brune 205147073ea2SPeter Brune Input Parameters: 2052f6dfbefdSBarry Smith + snes - the `SNES` context 2053f6dfbefdSBarry Smith - type - the type of the function evaluation, see `SNESSetFunctionType()` 205447073ea2SPeter Brune 205547073ea2SPeter Brune Level: advanced 205647073ea2SPeter Brune 2057f6dfbefdSBarry Smith .seealso: `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 205847073ea2SPeter Brune @*/ 20599371c9d4SSatish Balay PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) { 206047073ea2SPeter Brune PetscFunctionBegin; 206147073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 206247073ea2SPeter Brune *type = snes->functype; 2063534ebe21SPeter Brune PetscFunctionReturn(0); 2064534ebe21SPeter Brune } 2065534ebe21SPeter Brune 2066bf388a1fSBarry Smith /*MC 2067f6dfbefdSBarry Smith SNESNGSFunction - function used to apply a Gauss-Seidel sweep on the nonlinear function 2068bf388a1fSBarry Smith 2069bf388a1fSBarry Smith Synopsis: 2070aaa7dc30SBarry Smith #include <petscsnes.h> 2071be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2072bf388a1fSBarry Smith 20731843f636SBarry Smith Collective on snes 20741843f636SBarry Smith 20751843f636SBarry Smith Input Parameters: 2076bf388a1fSBarry Smith + X - solution vector 2077bf388a1fSBarry Smith . B - RHS vector 2078bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2079bf388a1fSBarry Smith 20801843f636SBarry Smith Output Parameter: 20811843f636SBarry Smith . X - solution vector 20821843f636SBarry Smith 2083878cb397SSatish Balay Level: intermediate 2084878cb397SSatish Balay 2085f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESSetNGS()`, `SNESGetNGS()` 2086bf388a1fSBarry Smith M*/ 2087bf388a1fSBarry Smith 2088c79ef259SPeter Brune /*@C 2089be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2090c79ef259SPeter Brune use with composed nonlinear solvers. 2091c79ef259SPeter Brune 2092c79ef259SPeter Brune Input Parameters: 2093c79ef259SPeter Brune + snes - the SNES context 2094f6dfbefdSBarry Smith . f - function evaluation routine to apply Gauss-Seidel see `SNESNGSFunction` 2095c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 20960298fd71SBarry Smith smoother evaluation routine (may be NULL) 2097c79ef259SPeter Brune 2098f6dfbefdSBarry Smith Calling sequence of f: 2099f6dfbefdSBarry Smith $ PetscErrorCode f(SNES snes,Vec X,Vec B,void *ctx); 2100f6dfbefdSBarry Smith 2101f6dfbefdSBarry Smith Arguments of f: 2102f6dfbefdSBarry Smith + snes - the `SNES` context 2103f6dfbefdSBarry Smith . X - the current solution 2104f6dfbefdSBarry Smith . B - the right hand side vector (which may be NULL) 2105f6dfbefdSBarry Smith - ctx - a user provided context 2106f6dfbefdSBarry Smith 2107f6dfbefdSBarry Smith Note: 2108f6dfbefdSBarry Smith The `SNESNGS` routines are used by the composed nonlinear solver to generate 2109f6dfbefdSBarry Smith a problem appropriate update to the solution, particularly `SNESFAS`. 2110c79ef259SPeter Brune 2111d28543b3SPeter Brune Level: intermediate 2112c79ef259SPeter Brune 2113f6dfbefdSBarry Smith .seealso: `SNESGetNGS()`, `SNESNGSFunction`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()` 2114c79ef259SPeter Brune @*/ 21159371c9d4SSatish Balay PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) { 21166cab3a1bSJed Brown DM dm; 21176cab3a1bSJed Brown 2118646217ecSPeter Brune PetscFunctionBegin; 21196cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21209566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21219566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 2122646217ecSPeter Brune PetscFunctionReturn(0); 2123646217ecSPeter Brune } 2124646217ecSPeter Brune 2125bbc1464cSBarry Smith /* 2126bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2127bbc1464cSBarry Smith changed during the KSPSolve() 2128bbc1464cSBarry Smith */ 21299371c9d4SSatish Balay PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) { 2130bbc1464cSBarry Smith DM dm; 2131bbc1464cSBarry Smith DMSNES sdm; 2132bbc1464cSBarry Smith 2133bbc1464cSBarry Smith PetscFunctionBegin; 21349566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21359566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2136bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2137bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2138792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21399566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 21400df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2141ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2142792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21439566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2144bbc1464cSBarry Smith } else { 2145792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21469566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2147bbc1464cSBarry Smith } 2148bbc1464cSBarry Smith PetscFunctionReturn(0); 2149bbc1464cSBarry Smith } 2150bbc1464cSBarry Smith 21519371c9d4SSatish Balay PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) { 2152e03ab78fSPeter Brune DM dm; 2153942e3340SBarry Smith DMSNES sdm; 21546cab3a1bSJed Brown 21558b0a5094SBarry Smith PetscFunctionBegin; 21569566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21579566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 21588b0a5094SBarry Smith /* A(x)*x - b(x) */ 2159bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2160792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21619566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 2162792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 21639566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2164bbc1464cSBarry Smith } else { 2165792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 21669566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2167bbc1464cSBarry Smith } 21688b0a5094SBarry Smith PetscFunctionReturn(0); 21698b0a5094SBarry Smith } 21708b0a5094SBarry Smith 21719371c9d4SSatish Balay PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) { 21728b0a5094SBarry Smith PetscFunctionBegin; 2173e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2174bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 21759566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 21769566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 21778b0a5094SBarry Smith PetscFunctionReturn(0); 21788b0a5094SBarry Smith } 21798b0a5094SBarry Smith 21808b0a5094SBarry Smith /*@C 2181f6dfbefdSBarry Smith SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 21828b0a5094SBarry Smith 2183f6dfbefdSBarry Smith Logically Collective on snes 21848b0a5094SBarry Smith 21858b0a5094SBarry Smith Input Parameters: 2186f6dfbefdSBarry Smith + snes - the `SNES` context 21876b7fb656SBarry Smith . r - vector to store function values, may be NULL 21886b7fb656SBarry Smith . bp - function evaluation routine, may be NULL 21896b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2190e5d3d808SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as Amat) 21916b7fb656SBarry Smith . J - function to compute matrix values, see SNESJacobianFunction() for details on its calling sequence 21926b7fb656SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be NULL) 21938b0a5094SBarry Smith 21948b0a5094SBarry Smith Notes: 21956b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2196f450aa47SBarry 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. 2197f450aa47SBarry Smith 2198f6dfbefdSBarry Smith One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both 21998b0a5094SBarry Smith 22006b7fb656SBarry 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} 22016b7fb656SBarry 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. 22028b0a5094SBarry Smith 22038b0a5094SBarry Smith Run with -snes_mf_operator to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22048b0a5094SBarry Smith 22050d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22066b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22078b0a5094SBarry Smith 22088b0a5094SBarry 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 22098b0a5094SBarry 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 22108b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22118b0a5094SBarry Smith 2212f6dfbefdSBarry 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 and 2213f6dfbefdSBarry Smith A(x^{n}) is used to build the preconditioner 22146b7fb656SBarry Smith 22156b7fb656SBarry 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. 22166b7fb656SBarry Smith 22176b7fb656SBarry 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 22186b7fb656SBarry 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 2219f6dfbefdSBarry 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`. 22206b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2221bbc1464cSBarry Smith 2222f450aa47SBarry Smith Level: intermediate 22238b0a5094SBarry Smith 2224f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22258b0a5094SBarry Smith @*/ 22269371c9d4SSatish 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) { 2227e03ab78fSPeter Brune DM dm; 2228e03ab78fSPeter Brune 22298b0a5094SBarry Smith PetscFunctionBegin; 22308b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22319566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22329566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22339566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22349566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22359566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22368b0a5094SBarry Smith PetscFunctionReturn(0); 22378b0a5094SBarry Smith } 22388b0a5094SBarry Smith 22397971a8bfSPeter Brune /*@C 22407971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22417971a8bfSPeter Brune 2242f6dfbefdSBarry Smith Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet. 22437971a8bfSPeter Brune 22447971a8bfSPeter Brune Input Parameter: 2245f6dfbefdSBarry Smith . snes - the `SNES` context 22467971a8bfSPeter Brune 2247d8d19677SJose E. Roman Output Parameters: 22480298fd71SBarry Smith + r - the function (or NULL) 2249f6dfbefdSBarry Smith . f - the function (or NULL); see `SNESFunction` for calling sequence details 2250e4357dc4SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or NULL) 2251e4357dc4SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or NULL) 2252f6dfbefdSBarry Smith . J - the function for matrix evaluation (or NULL); see `SNESJacobianFunction` for calling sequence details 22530298fd71SBarry Smith - ctx - the function context (or NULL) 22547971a8bfSPeter Brune 22557971a8bfSPeter Brune Level: advanced 22567971a8bfSPeter Brune 2257f6dfbefdSBarry Smith .seealso: `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 22587971a8bfSPeter Brune @*/ 22599371c9d4SSatish 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) { 22607971a8bfSPeter Brune DM dm; 22617971a8bfSPeter Brune 22627971a8bfSPeter Brune PetscFunctionBegin; 22637971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22649566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 22659566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 22669566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22679566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 22687971a8bfSPeter Brune PetscFunctionReturn(0); 22697971a8bfSPeter Brune } 22707971a8bfSPeter Brune 2271d25893d9SBarry Smith /*@C 2272d25893d9SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the problem 2273d25893d9SBarry Smith 2274f6dfbefdSBarry Smith Logically Collective on snes 2275d25893d9SBarry Smith 2276d25893d9SBarry Smith Input Parameters: 2277f6dfbefdSBarry Smith + snes - the `SNES` context 2278d25893d9SBarry Smith . func - function evaluation routine 2279d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 22800298fd71SBarry Smith function evaluation routine (may be NULL) 2281d25893d9SBarry Smith 2282d25893d9SBarry Smith Calling sequence of func: 2283d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2284d25893d9SBarry Smith 2285d25893d9SBarry Smith . f - function vector 2286d25893d9SBarry Smith - ctx - optional user-defined function context 2287d25893d9SBarry Smith 2288d25893d9SBarry Smith Level: intermediate 2289d25893d9SBarry Smith 2290f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2291d25893d9SBarry Smith @*/ 22929371c9d4SSatish Balay PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx) { 2293d25893d9SBarry Smith PetscFunctionBegin; 2294d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2295d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2296d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 2297d25893d9SBarry Smith PetscFunctionReturn(0); 2298d25893d9SBarry Smith } 2299d25893d9SBarry Smith 23001096aae1SMatthew Knepley /*@C 23011096aae1SMatthew Knepley SNESGetRhs - Gets the vector for solving F(x) = rhs. If rhs is not set 23021096aae1SMatthew Knepley it assumes a zero right hand side. 23031096aae1SMatthew Knepley 2304f6dfbefdSBarry Smith Logically Collective on snes 23051096aae1SMatthew Knepley 23061096aae1SMatthew Knepley Input Parameter: 2307f6dfbefdSBarry Smith . snes - the `SNES` context 23081096aae1SMatthew Knepley 23091096aae1SMatthew Knepley Output Parameter: 23100298fd71SBarry Smith . rhs - the right hand side vector or NULL if the right hand side vector is null 23111096aae1SMatthew Knepley 23121096aae1SMatthew Knepley Level: intermediate 23131096aae1SMatthew Knepley 2314f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23151096aae1SMatthew Knepley @*/ 23169371c9d4SSatish Balay PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) { 23171096aae1SMatthew Knepley PetscFunctionBegin; 23180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23191096aae1SMatthew Knepley PetscValidPointer(rhs, 2); 232085385478SLisandro Dalcin *rhs = snes->vec_rhs; 23211096aae1SMatthew Knepley PetscFunctionReturn(0); 23221096aae1SMatthew Knepley } 23231096aae1SMatthew Knepley 23249b94acceSBarry Smith /*@ 2325f6dfbefdSBarry Smith SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`. 23269b94acceSBarry Smith 2327f6dfbefdSBarry Smith Collective on snes 2328c7afd0dbSLois Curfman McInnes 23299b94acceSBarry Smith Input Parameters: 2330f6dfbefdSBarry Smith + snes - the `SNES` context 2331c7afd0dbSLois Curfman McInnes - x - input vector 23329b94acceSBarry Smith 23339b94acceSBarry Smith Output Parameter: 2334f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetFunction()` 23359b94acceSBarry Smith 2336f6dfbefdSBarry Smith Note: 2337f6dfbefdSBarry Smith `SNESComputeFunction()` is typically used within nonlinear solvers 2338bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 233936851e7fSLois Curfman McInnes 234036851e7fSLois Curfman McInnes Level: developer 234136851e7fSLois Curfman McInnes 2342f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 23439b94acceSBarry Smith @*/ 23449371c9d4SSatish Balay PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) { 23456cab3a1bSJed Brown DM dm; 2346942e3340SBarry Smith DMSNES sdm; 23479b94acceSBarry Smith 23483a40ed3dSBarry Smith PetscFunctionBegin; 23490700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23500700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 23510700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2352c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2353c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2354*e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2355184914b5SBarry Smith 23569566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23579566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 235832f3f7c2SPeter Brune if (sdm->ops->computefunction) { 235948a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 23609566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 23618ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 23628ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2363800f99ffSJeremy L Thompson { 2364800f99ffSJeremy L Thompson void *ctx; 2365800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2366800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2367800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2368800f99ffSJeremy L Thompson } 23699566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 237048a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2371c90fad12SPeter Brune } else if (snes->vec_rhs) { 23729566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 2373644e2e5bSBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 23741baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2375ae3c334cSLois Curfman McInnes snes->nfuncs++; 2376422a814eSBarry Smith /* 2377422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2378422a814eSBarry Smith propagate the value to all processes 2379422a814eSBarry Smith */ 23801baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 23813a40ed3dSBarry Smith PetscFunctionReturn(0); 23829b94acceSBarry Smith } 23839b94acceSBarry Smith 2384c79ef259SPeter Brune /*@ 2385f6dfbefdSBarry Smith SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`. 2386bbc1464cSBarry Smith 2387f6dfbefdSBarry Smith Collective on snes 2388bbc1464cSBarry Smith 2389bbc1464cSBarry Smith Input Parameters: 2390f6dfbefdSBarry Smith + snes - the `SNES` context 2391bbc1464cSBarry Smith - x - input vector 2392bbc1464cSBarry Smith 2393bbc1464cSBarry Smith Output Parameter: 2394f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetMFFunction()` 2395bbc1464cSBarry Smith 2396bbc1464cSBarry Smith Notes: 2397f6dfbefdSBarry Smith `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()` 2398bbc1464cSBarry Smith so users would not generally call this routine themselves. 2399bbc1464cSBarry Smith 2400f6dfbefdSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()` 2401f6dfbefdSBarry Smith while `SNESComputeFunction()` does. As such, this routine cannot be used with `MatMFFDSetBase()` with a provided F function value even if it applies the 2402f6dfbefdSBarry 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. 2403bbc1464cSBarry Smith 2404bbc1464cSBarry Smith Level: developer 2405bbc1464cSBarry Smith 2406f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2407bbc1464cSBarry Smith @*/ 24089371c9d4SSatish Balay PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) { 2409bbc1464cSBarry Smith DM dm; 2410bbc1464cSBarry Smith DMSNES sdm; 2411bbc1464cSBarry Smith 2412bbc1464cSBarry Smith PetscFunctionBegin; 2413bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2414bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2415bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2416bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2417bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2418*e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2419bbc1464cSBarry Smith 24209566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24219566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24229566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24239566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2424bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2425bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2426792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24279566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24289566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2429bbc1464cSBarry Smith snes->nfuncs++; 2430bbc1464cSBarry Smith /* 2431bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2432bbc1464cSBarry Smith propagate the value to all processes 2433bbc1464cSBarry Smith */ 24341baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 2435bbc1464cSBarry Smith PetscFunctionReturn(0); 2436bbc1464cSBarry Smith } 2437bbc1464cSBarry Smith 2438bbc1464cSBarry Smith /*@ 2439f6dfbefdSBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`. 2440c79ef259SPeter Brune 2441f6dfbefdSBarry Smith Collective on snes 2442c79ef259SPeter Brune 2443c79ef259SPeter Brune Input Parameters: 2444f6dfbefdSBarry Smith + snes - the `SNES` context 2445c79ef259SPeter Brune . x - input vector 2446c79ef259SPeter Brune - b - rhs vector 2447c79ef259SPeter Brune 2448c79ef259SPeter Brune Output Parameter: 2449c79ef259SPeter Brune . x - new solution vector 2450c79ef259SPeter Brune 2451f6dfbefdSBarry Smith Note: 2452f6dfbefdSBarry Smith `SNESComputeNGS()` is typically used within composed nonlinear solver 2453c79ef259SPeter Brune implementations, so most users would not generally call this routine 2454c79ef259SPeter Brune themselves. 2455c79ef259SPeter Brune 2456c79ef259SPeter Brune Level: developer 2457c79ef259SPeter Brune 2458f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()` 2459c79ef259SPeter Brune @*/ 24609371c9d4SSatish Balay PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) { 24616cab3a1bSJed Brown DM dm; 2462942e3340SBarry Smith DMSNES sdm; 2463646217ecSPeter Brune 2464646217ecSPeter Brune PetscFunctionBegin; 2465646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2466064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2467064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2468064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2469064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 2470*e0f629ddSJacob Faibussowitsch if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE)); 24719566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 24729566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24739566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 247422c6f798SBarry Smith if (sdm->ops->computegs) { 24759566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2476792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 24779566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 2478be95d8f1SBarry Smith } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 24799566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 2480646217ecSPeter Brune PetscFunctionReturn(0); 2481646217ecSPeter Brune } 2482646217ecSPeter Brune 24839371c9d4SSatish Balay PetscErrorCode SNESTestJacobian(SNES snes) { 248412837594SBarry Smith Mat A, B, C, D, jacobian; 2485e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2486e885f1abSBarry Smith PetscReal nrm, gnorm; 248781e7118cSBarry Smith PetscReal threshold = 1.e-5; 24880e276705SLisandro Dalcin MatType mattype; 2489e885f1abSBarry Smith PetscInt m, n, M, N; 2490e885f1abSBarry Smith void *functx; 24912cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 24923325ff46SBarry Smith PetscViewer viewer, mviewer; 2493e885f1abSBarry Smith MPI_Comm comm; 2494e885f1abSBarry Smith PetscInt tabs; 249512837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 24963325ff46SBarry Smith PetscViewerFormat format; 2497e885f1abSBarry Smith 2498e885f1abSBarry Smith PetscFunctionBegin; 2499d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 25009566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 25019566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 25029566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 250318d89885SKarl Rupp if (!complete_print) { 25049566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 25059566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_display", "Display difference between hand-coded and finite difference Jacobians", "None", &mviewer, &format, &complete_print)); 250618d89885SKarl Rupp } 250718d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 25089566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 25099566063dSJacob 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)); 2510d0609cedSBarry Smith PetscOptionsEnd(); 2511e885f1abSBarry Smith if (!test) PetscFunctionReturn(0); 2512e885f1abSBarry Smith 25139566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25179566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 251812837594SBarry Smith if (!complete_print && !directionsprinted) { 25199566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 252112837594SBarry Smith } 252212837594SBarry Smith if (!directionsprinted) { 25239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 252512837594SBarry Smith directionsprinted = PETSC_TRUE; 2526e885f1abSBarry Smith } 25271baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2528e885f1abSBarry Smith 25299566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 253012837594SBarry Smith if (!flg) jacobian = snes->jacobian; 253112837594SBarry Smith else jacobian = snes->jacobian_pre; 253212837594SBarry Smith 2533a82339d0SMatthew G. Knepley if (!x) { 25349566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2535a82339d0SMatthew G. Knepley } else { 25369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2537a82339d0SMatthew G. Knepley } 2538a82339d0SMatthew G. Knepley if (!f) { 25399566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2540a82339d0SMatthew G. Knepley } else { 25419566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2542a82339d0SMatthew G. Knepley } 2543a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 25449566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 25459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 25469566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 254712837594SBarry Smith while (jacobian) { 25482cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 25492cd624f9SStefano Zampini 25502cd624f9SStefano Zampini if (istranspose) { 25519566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 25522cd624f9SStefano Zampini Jsave = jacobian; 25532cd624f9SStefano Zampini jacobian = JT; 25542cd624f9SStefano Zampini } 25559566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 255612837594SBarry Smith if (flg) { 255712837594SBarry Smith A = jacobian; 25589566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 255912837594SBarry Smith } else { 25609566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 256112837594SBarry Smith } 2562e885f1abSBarry Smith 25639566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 25649566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 25659566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 25669566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 25679566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 25689566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 25699566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 25709566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 25719566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2572e885f1abSBarry Smith 25739566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 25749566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 257512837594SBarry Smith 25769566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 25779566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 25789566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 25799566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 25809566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 258112837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 25829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 258312837594SBarry Smith 2584e885f1abSBarry Smith if (complete_print) { 25859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 25869566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 25879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 25889566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2589e885f1abSBarry Smith } 2590e885f1abSBarry Smith 2591df10fb39SFande Kong if (threshold_print || complete_print) { 2592e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2593e885f1abSBarry Smith PetscScalar *cvals; 2594e885f1abSBarry Smith const PetscInt *bcols; 2595e885f1abSBarry Smith const PetscScalar *bvals; 2596e885f1abSBarry Smith 25979566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 25989566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 25999566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 26009566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 26019566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 26029566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 26030e276705SLisandro Dalcin 26049566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26059566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2606e885f1abSBarry Smith 2607e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26089566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26099566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2610e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 261123a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2612e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2613e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2614e885f1abSBarry Smith cncols += 1; 2615e885f1abSBarry Smith } 2616e885f1abSBarry Smith } 261748a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26189566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26199566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2620e885f1abSBarry Smith } 26219566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26229566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26249566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26259566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2626e885f1abSBarry Smith } 26279566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26289566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26299566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 26302cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 263112837594SBarry Smith if (jacobian != snes->jacobian_pre) { 263212837594SBarry Smith jacobian = snes->jacobian_pre; 26339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 26349371c9d4SSatish Balay } else jacobian = NULL; 263512837594SBarry Smith } 26369566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 26371baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 26389566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 26399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 2640e885f1abSBarry Smith PetscFunctionReturn(0); 2641e885f1abSBarry Smith } 2642e885f1abSBarry Smith 264362fef451SLois Curfman McInnes /*@ 2644f6dfbefdSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`. 264562fef451SLois Curfman McInnes 2646f6dfbefdSBarry Smith Collective on snes 2647c7afd0dbSLois Curfman McInnes 264862fef451SLois Curfman McInnes Input Parameters: 2649f6dfbefdSBarry Smith + snes - the `SNES` context 2650c7afd0dbSLois Curfman McInnes - x - input vector 265162fef451SLois Curfman McInnes 265262fef451SLois Curfman McInnes Output Parameters: 2653c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2654f6dfbefdSBarry Smith - B - optional matrix for building the preconditioner 2655fee21e36SBarry Smith 2656e35cf81dSBarry Smith Options Database Keys: 265767b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 265867b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2659455a5933SJed 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. 2660455a5933SJed 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 2661693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2662693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2663693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 26644c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 266594d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2666a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2667c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2668c01495d3SJed Brown . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2669c01495d3SJed Brown . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by -snes_compare_coloring_threshold 2670a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2671a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2672c01495d3SJed Brown 2673f6dfbefdSBarry Smith Note: 267462fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 267562fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 267662fef451SLois Curfman McInnes 2677f6dfbefdSBarry Smith Developer Note: 267895452b02SPatrick 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 2679e885f1abSBarry Smith for with the SNESType of test that has been removed. 2680e885f1abSBarry Smith 268136851e7fSLois Curfman McInnes Level: developer 268236851e7fSLois Curfman McInnes 2683db781477SPatrick Sanan .seealso: `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 268462fef451SLois Curfman McInnes @*/ 26859371c9d4SSatish Balay PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) { 2686ace3abfcSBarry Smith PetscBool flag; 26876cab3a1bSJed Brown DM dm; 2688942e3340SBarry Smith DMSNES sdm; 2689e0e3a89bSBarry Smith KSP ksp; 26903a40ed3dSBarry Smith 26913a40ed3dSBarry Smith PetscFunctionBegin; 26920700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 26930700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2694c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 2695*e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE)); 26969566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 26979566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 26983232da50SPeter Brune 2699ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2700fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2701fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2702f5af7f23SKarl Rupp 27039566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2704fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 27059566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 27069566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2707ebd3b9afSBarry Smith if (flag) { 27089566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27099566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2710ebd3b9afSBarry Smith } 2711e35cf81dSBarry Smith PetscFunctionReturn(0); 271237ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 271363a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27149566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2715ebd3b9afSBarry Smith if (flag) { 27169566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27179566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2718ebd3b9afSBarry Smith } 2719e35cf81dSBarry Smith PetscFunctionReturn(0); 2720e35cf81dSBarry Smith } 2721efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27229566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27239566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2724d728fb7dSPeter Brune PetscFunctionReturn(0); 2725d728fb7dSPeter Brune } 2726e35cf81dSBarry Smith 27279566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27289566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2729800f99ffSJeremy L Thompson { 2730800f99ffSJeremy L Thompson void *ctx; 2731800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2732800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2733800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2734800f99ffSJeremy L Thompson } 27359566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 27369566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 273728d58a37SPierre Jolivet 273828d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 27399566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2740a8054027SBarry Smith 2741e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 27429566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 27433b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 27449566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 27459566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 27463b4f5425SBarry Smith snes->lagpreconditioner = -1; 27473b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 27489566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 27499566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 275037ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 275163a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 27529566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2753d1e9a80fSBarry Smith } else { 27549566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 27559566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2756a8054027SBarry Smith } 2757a8054027SBarry Smith 27589566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 27596d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 276094ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 276194ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2762693365a8SJed Brown { 2763693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 27649566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 27659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 27669566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 27679566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2768693365a8SJed Brown if (flag || flag_draw || flag_contour) { 27690298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2770693365a8SJed Brown PetscViewer vdraw, vstdout; 27716b3a5b13SJed Brown PetscBool flg; 2772693365a8SJed Brown if (flag_operator) { 27739566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2774693365a8SJed Brown Bexp = Bexp_mine; 2775693365a8SJed Brown } else { 2776693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 27779566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 277894ab13aaSBarry Smith if (flg) Bexp = B; 2779693365a8SJed Brown else { 2780693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 27819566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2782693365a8SJed Brown Bexp = Bexp_mine; 2783693365a8SJed Brown } 2784693365a8SJed Brown } 27859566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 27869566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 27879566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2788693365a8SJed Brown if (flag_draw || flag_contour) { 27899566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 27909566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 27910298fd71SBarry Smith } else vdraw = NULL; 27929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 27939566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 27949566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 27959566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 27969566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 27979566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 27989566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 27999566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 28009566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2801693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 28029566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28039566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 28049566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2805693365a8SJed Brown } 28069566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28079566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28099566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2810693365a8SJed Brown } 2811693365a8SJed Brown } 28124c30e9fbSJed Brown { 28136719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28146719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28169566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28179566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28189566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28199566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 282027b0f280SBarry Smith if (flag_threshold) { 28219566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28229566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 282327b0f280SBarry Smith } 28246719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28254c30e9fbSJed Brown Mat Bfd; 28264c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2827335efc43SPeter Brune MatColoring coloring; 28284c30e9fbSJed Brown ISColoring iscoloring; 28294c30e9fbSJed Brown MatFDColoring matfdcoloring; 28304c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 28314c30e9fbSJed Brown void *funcctx; 28326719d8e4SJed Brown PetscReal norm1, norm2, normmax; 28334c30e9fbSJed Brown 28349566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 28359566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 28369566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 28379566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 28389566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 28399566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 28409566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 28419566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28429566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 28439566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 28444c30e9fbSJed Brown 28454c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 28469566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 28479566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 28489566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 28499566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 28509566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28519566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 28529566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 28534c30e9fbSJed Brown 28549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 28554c30e9fbSJed Brown if (flag_draw || flag_contour) { 28569566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28579566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28580298fd71SBarry Smith } else vdraw = NULL; 28599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 28609566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 28619566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 28629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 28639566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 28649566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 28659566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 28669566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 28679566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 28689566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 28699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 28709566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 28714c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 28729566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28739566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 28749566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 28754c30e9fbSJed Brown } 28769566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28776719d8e4SJed Brown 28786719d8e4SJed Brown if (flag_threshold) { 28796719d8e4SJed Brown PetscInt bs, rstart, rend, i; 28809566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 28819566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 28826719d8e4SJed Brown for (i = rstart; i < rend; i++) { 28836719d8e4SJed Brown const PetscScalar *ba, *ca; 28846719d8e4SJed Brown const PetscInt *bj, *cj; 28856719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 28866719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 28879566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 28889566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 28895f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 28906719d8e4SJed Brown for (j = 0; j < bn; j++) { 28916719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 28926719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 28936719d8e4SJed Brown maxentrycol = bj[j]; 28946719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 28956719d8e4SJed Brown } 28966719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 28976719d8e4SJed Brown maxdiffcol = bj[j]; 28986719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 28996719d8e4SJed Brown } 29006719d8e4SJed Brown if (rdiff > maxrdiff) { 29016719d8e4SJed Brown maxrdiffcol = bj[j]; 29026719d8e4SJed Brown maxrdiff = rdiff; 29036719d8e4SJed Brown } 29046719d8e4SJed Brown } 29056719d8e4SJed Brown if (maxrdiff > 1) { 290663a3b9bcSJacob 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)); 29076719d8e4SJed Brown for (j = 0; j < bn; j++) { 29086719d8e4SJed Brown PetscReal rdiff; 29096719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 291048a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29116719d8e4SJed Brown } 291263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29136719d8e4SJed Brown } 29149566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29159566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29166719d8e4SJed Brown } 29176719d8e4SJed Brown } 29189566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29199566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29204c30e9fbSJed Brown } 29214c30e9fbSJed Brown } 29223a40ed3dSBarry Smith PetscFunctionReturn(0); 29239b94acceSBarry Smith } 29249b94acceSBarry Smith 2925bf388a1fSBarry Smith /*MC 2926f6dfbefdSBarry Smith SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES` 2927bf388a1fSBarry Smith 2928bf388a1fSBarry Smith Synopsis: 2929411c0326SBarry Smith #include "petscsnes.h" 2930411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2931bf388a1fSBarry Smith 29321843f636SBarry Smith Collective on snes 29331843f636SBarry Smith 29341843f636SBarry Smith Input Parameters: 29351843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 2936bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2937bf388a1fSBarry Smith 29381843f636SBarry Smith Output Parameters: 29391843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 29401843f636SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 29411843f636SBarry Smith 2942878cb397SSatish Balay Level: intermediate 2943878cb397SSatish Balay 2944f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 2945bf388a1fSBarry Smith M*/ 2946bf388a1fSBarry Smith 29479b94acceSBarry Smith /*@C 29489b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2949044dda88SLois Curfman McInnes location to store the matrix. 29509b94acceSBarry Smith 2951f6dfbefdSBarry Smith Logically Collective on snes 2952c7afd0dbSLois Curfman McInnes 29539b94acceSBarry Smith Input Parameters: 2954f6dfbefdSBarry Smith + snes - the `SNES` context 2955e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 2956e5d3d808SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as Amat. 2957f6dfbefdSBarry Smith . J - Jacobian evaluation routine (if NULL then `SNES` retains any previously set value), see `SNESJacobianFunction` for details 2958c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 29590298fd71SBarry Smith Jacobian evaluation routine (may be NULL) (if NULL then SNES retains any previously set value) 29609b94acceSBarry Smith 29619b94acceSBarry Smith Notes: 2962f6dfbefdSBarry Smith If the Amat matrix and Pmat matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on 296316913363SBarry Smith each matrix. 296416913363SBarry Smith 2965f6dfbefdSBarry Smith If you know the operator Amat has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 2966895c21f2SBarry Smith space to Amat and the KSP solvers will automatically use that null space as needed during the solution process. 2967895c21f2SBarry Smith 2968f6dfbefdSBarry Smith If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the ctx argument 2969f6dfbefdSBarry Smith must be a `MatFDColoring`. 2970a8a26c1eSJed Brown 2971c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 2972f6dfbefdSBarry Smith example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()` 2973c3cc8fd1SJed Brown 297436851e7fSLois Curfman McInnes Level: beginner 297536851e7fSLois Curfman McInnes 2976f6dfbefdSBarry Smith .seealso: `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, `J`, 2977db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 29789b94acceSBarry Smith @*/ 29799371c9d4SSatish Balay PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) { 29806cab3a1bSJed Brown DM dm; 29813a7fca6bSBarry Smith 29823a40ed3dSBarry Smith PetscFunctionBegin; 29830700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2984e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 2985e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 2986e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 2987e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 29889566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 29899566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 2990e5d3d808SBarry Smith if (Amat) { 29919566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 29929566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 2993f5af7f23SKarl Rupp 2994e5d3d808SBarry Smith snes->jacobian = Amat; 29953a7fca6bSBarry Smith } 2996e5d3d808SBarry Smith if (Pmat) { 29979566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 29989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 2999f5af7f23SKarl Rupp 3000e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30013a7fca6bSBarry Smith } 30023a40ed3dSBarry Smith PetscFunctionReturn(0); 30039b94acceSBarry Smith } 300462fef451SLois Curfman McInnes 3005c2aafc4cSSatish Balay /*@C 3006b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3007b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3008b4fd4287SBarry Smith 3009f6dfbefdSBarry Smith Not Collective, but `Mat` object will be parallel if `SNES` object is 3010c7afd0dbSLois Curfman McInnes 3011b4fd4287SBarry Smith Input Parameter: 3012b4fd4287SBarry Smith . snes - the nonlinear solver context 3013b4fd4287SBarry Smith 3014b4fd4287SBarry Smith Output Parameters: 3015e5d3d808SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or NULL) 3016e5d3d808SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or NULL) 3017411c0326SBarry Smith . J - location to put Jacobian function (or NULL), see SNESJacobianFunction for details on its calling sequence 30180298fd71SBarry Smith - ctx - location to stash Jacobian ctx (or NULL) 3019fee21e36SBarry Smith 302036851e7fSLois Curfman McInnes Level: advanced 302136851e7fSLois Curfman McInnes 3022f6dfbefdSBarry Smith .seealso: `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3023b4fd4287SBarry Smith @*/ 30249371c9d4SSatish Balay PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) { 30256cab3a1bSJed Brown DM dm; 30266cab3a1bSJed Brown 30273a40ed3dSBarry Smith PetscFunctionBegin; 30280700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3029e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3030e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 30319566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3032800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 30333a40ed3dSBarry Smith PetscFunctionReturn(0); 3034b4fd4287SBarry Smith } 3035b4fd4287SBarry Smith 30369371c9d4SSatish Balay static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) { 303758b371f3SBarry Smith DM dm; 303858b371f3SBarry Smith DMSNES sdm; 303958b371f3SBarry Smith 304058b371f3SBarry Smith PetscFunctionBegin; 30419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30429566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 304358b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 304458b371f3SBarry Smith DM dm; 304558b371f3SBarry Smith PetscBool isdense, ismf; 304658b371f3SBarry Smith 30479566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30489566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 30499566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 305058b371f3SBarry Smith if (isdense) { 30519566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 305258b371f3SBarry Smith } else if (!ismf) { 30539566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 305458b371f3SBarry Smith } 305558b371f3SBarry Smith } 305658b371f3SBarry Smith PetscFunctionReturn(0); 305758b371f3SBarry Smith } 305858b371f3SBarry Smith 30599b94acceSBarry Smith /*@ 30609b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3061272ac6f2SLois Curfman McInnes of a nonlinear solver. 30629b94acceSBarry Smith 3063f6dfbefdSBarry Smith Collective on snes 3064fee21e36SBarry Smith 3065c7afd0dbSLois Curfman McInnes Input Parameters: 3066f6dfbefdSBarry Smith . snes - the `SNES` context 3067c7afd0dbSLois Curfman McInnes 3068f6dfbefdSBarry Smith Note: 3069f6dfbefdSBarry Smith For basic use of the `SNES` solvers the user need not explicitly call 3070f6dfbefdSBarry Smith `SNESSetUp()`, since these actions will automatically occur during 3071f6dfbefdSBarry Smith the call to `SNESSolve()`. However, if one wishes to control this 3072f6dfbefdSBarry Smith phase separately, `SNESSetUp()` should be called after `SNESCreate()` 3073f6dfbefdSBarry Smith and optional routines of the form SNESSetXXX(), but before `SNESSolve()`. 3074272ac6f2SLois Curfman McInnes 307536851e7fSLois Curfman McInnes Level: advanced 307636851e7fSLois Curfman McInnes 3077f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 30789b94acceSBarry Smith @*/ 30799371c9d4SSatish Balay PetscErrorCode SNESSetUp(SNES snes) { 30806cab3a1bSJed Brown DM dm; 3081942e3340SBarry Smith DMSNES sdm; 3082c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 30836e2a1849SPeter Brune void *lsprectx, *lspostctx; 30846b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 30856b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 30866e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 30876e2a1849SPeter Brune Vec f, fpc; 30886e2a1849SPeter Brune void *funcctx; 3089d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 30901eb13d49SPeter Brune void *jacctx, *appctx; 309132b97717SPeter Brune Mat j, jpre; 30923a40ed3dSBarry Smith 30933a40ed3dSBarry Smith PetscFunctionBegin; 30940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 30954dc4c822SBarry Smith if (snes->setupcalled) PetscFunctionReturn(0); 30969566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Setup, snes, 0, 0, 0)); 30979b94acceSBarry Smith 309848a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 309985385478SLisandro Dalcin 31009566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 310158c9b817SLisandro Dalcin 31029566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31039566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 31049566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 310558b371f3SBarry Smith 310648a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3107efd51863SBarry Smith 310848a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3109b710008aSBarry Smith 3110d8d34be6SBarry Smith if (snes->linesearch) { 31119566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31129566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3113d8d34be6SBarry Smith } 31149e764e56SPeter Brune 3115b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3116172a4300SPeter Brune snes->mf = PETSC_TRUE; 3117172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3118172a4300SPeter Brune } 3119d8f46077SPeter Brune 3120efd4aadfSBarry Smith if (snes->npc) { 31216e2a1849SPeter Brune /* copy the DM over */ 31229566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31239566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 31246e2a1849SPeter Brune 31259566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 31269566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 31279566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 31289566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 31299566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 31309566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 31319566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 31329566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 31336e2a1849SPeter Brune 31346e2a1849SPeter Brune /* copy the function pointers over */ 31359566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 31366e2a1849SPeter Brune 31376e2a1849SPeter Brune /* default to 1 iteration */ 31389566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3139efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 31409566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3141a9936a0cSPeter Brune } else { 31429566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3143a9936a0cSPeter Brune } 31449566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 31456e2a1849SPeter Brune 31466e2a1849SPeter Brune /* copy the line search context over */ 3147d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 31489566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 31499566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 31509566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 31519566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 31529566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 31539566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 31549566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 31556e2a1849SPeter Brune } 3156d8d34be6SBarry Smith } 31571baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 315848a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 31596e2a1849SPeter Brune 316037ec4e1aSPeter Brune snes->jac_iter = 0; 316137ec4e1aSPeter Brune snes->pre_iter = 0; 316237ec4e1aSPeter Brune 3163dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 316458c9b817SLisandro Dalcin 31659566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 316658b371f3SBarry Smith 3167b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 31686c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3169d8d34be6SBarry Smith if (snes->linesearch) { 31709566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 31719566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 31726c67d002SPeter Brune } 31736c67d002SPeter Brune } 3174d8d34be6SBarry Smith } 31759566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Setup, snes, 0, 0, 0)); 31767aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 31773a40ed3dSBarry Smith PetscFunctionReturn(0); 31789b94acceSBarry Smith } 31799b94acceSBarry Smith 318037596af1SLisandro Dalcin /*@ 3181f6dfbefdSBarry Smith SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s 318237596af1SLisandro Dalcin 3183f6dfbefdSBarry Smith Collective on snes 318437596af1SLisandro Dalcin 318537596af1SLisandro Dalcin Input Parameter: 3186f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 318737596af1SLisandro Dalcin 3188d25893d9SBarry Smith Level: intermediate 3189d25893d9SBarry Smith 319095452b02SPatrick Sanan Notes: 3191f6dfbefdSBarry Smith Call this if you wish to reuse a `SNES` but with different size vectors 319237596af1SLisandro Dalcin 3193f6dfbefdSBarry Smith Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()` 3194f6dfbefdSBarry Smith 3195f6dfbefdSBarry Smith .seealso: `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 319637596af1SLisandro Dalcin @*/ 31979371c9d4SSatish Balay PetscErrorCode SNESReset(SNES snes) { 319837596af1SLisandro Dalcin PetscFunctionBegin; 319937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3200d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 32019566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 32020298fd71SBarry Smith snes->user = NULL; 3203d25893d9SBarry Smith } 32041baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 32058a23116dSBarry Smith 3206dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 32071baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 32089e764e56SPeter Brune 32091baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32109e764e56SPeter Brune 32119566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32129566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32139566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32149566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32159566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32169566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32179566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32189566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32199566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3220f5af7f23SKarl Rupp 322140fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 322240fdac6aSLawrence Mitchell 322337596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 322437596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 322537596af1SLisandro Dalcin PetscFunctionReturn(0); 322637596af1SLisandro Dalcin } 322737596af1SLisandro Dalcin 322852baeb72SSatish Balay /*@ 3229f6dfbefdSBarry Smith SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object. 3230c4421ceaSFande Kong 3231f6dfbefdSBarry Smith Collective on snes 3232c4421ceaSFande Kong 3233c4421ceaSFande Kong Input Parameter: 3234f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 3235c4421ceaSFande Kong 3236c4421ceaSFande Kong Level: intermediate 3237c4421ceaSFande Kong 3238f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3239c4421ceaSFande Kong @*/ 32409371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) { 3241c4421ceaSFande Kong PetscInt i; 3242c4421ceaSFande Kong 3243c4421ceaSFande Kong PetscFunctionBegin; 3244c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3245c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 324648a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3247c4421ceaSFande Kong } 3248c4421ceaSFande Kong snes->numberreasonviews = 0; 3249c4421ceaSFande Kong PetscFunctionReturn(0); 3250c4421ceaSFande Kong } 3251c4421ceaSFande Kong 32521fb7b255SJunchao Zhang /*@C 32539b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 3254f6dfbefdSBarry Smith with `SNESCreate()`. 32559b94acceSBarry Smith 3256f6dfbefdSBarry Smith Collective on snes 3257c7afd0dbSLois Curfman McInnes 32589b94acceSBarry Smith Input Parameter: 3259f6dfbefdSBarry Smith . snes - the `SNES` context 32609b94acceSBarry Smith 326136851e7fSLois Curfman McInnes Level: beginner 326236851e7fSLois Curfman McInnes 3263f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESSolve()` 32649b94acceSBarry Smith @*/ 32659371c9d4SSatish Balay PetscErrorCode SNESDestroy(SNES *snes) { 32663a40ed3dSBarry Smith PetscFunctionBegin; 32676bf464f9SBarry Smith if (!*snes) PetscFunctionReturn(0); 32686bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 32699371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 32709371c9d4SSatish Balay *snes = NULL; 32719371c9d4SSatish Balay PetscFunctionReturn(0); 32729371c9d4SSatish Balay } 3273d4bb536fSBarry Smith 32749566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 32759566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 32766b8b9a38SLisandro Dalcin 3277e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 32789566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3279dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 32806d4c513bSLisandro Dalcin 32819566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 32829566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 32839566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 32849566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 32856b8b9a38SLisandro Dalcin 32869566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 328748a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 328848a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 32899566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 32909566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 32919566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 32923a40ed3dSBarry Smith PetscFunctionReturn(0); 32939b94acceSBarry Smith } 32949b94acceSBarry Smith 32959b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 32969b94acceSBarry Smith 3297a8054027SBarry Smith /*@ 3298a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3299a8054027SBarry Smith 3300f6dfbefdSBarry Smith Logically Collective on snes 3301a8054027SBarry Smith 3302a8054027SBarry Smith Input Parameters: 3303f6dfbefdSBarry Smith + snes - the `SNES` context 3304d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 33053b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3306a8054027SBarry Smith 3307a8054027SBarry Smith Options Database Keys: 33083d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33093d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33103d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33113d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3312a8054027SBarry Smith 3313a8054027SBarry Smith Notes: 3314a8054027SBarry Smith The default is 1 3315f6dfbefdSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called 3316d8e291bfSBarry Smith 3317f6dfbefdSBarry Smith `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves. 3318a8054027SBarry Smith 3319a8054027SBarry Smith Level: intermediate 3320a8054027SBarry Smith 3321db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3322f6dfbefdSBarry Smith `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()` 3323a8054027SBarry Smith @*/ 33249371c9d4SSatish Balay PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) { 3325a8054027SBarry Smith PetscFunctionBegin; 33260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 33275f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 33285f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3329c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3330a8054027SBarry Smith snes->lagpreconditioner = lag; 3331a8054027SBarry Smith PetscFunctionReturn(0); 3332a8054027SBarry Smith } 3333a8054027SBarry Smith 3334efd51863SBarry Smith /*@ 3335f6dfbefdSBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do 3336efd51863SBarry Smith 3337f6dfbefdSBarry Smith Logically Collective on snes 3338efd51863SBarry Smith 3339efd51863SBarry Smith Input Parameters: 3340f6dfbefdSBarry Smith + snes - the `SNES` context 3341efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3342efd51863SBarry Smith 3343f6dfbefdSBarry Smith Options Database Key: 334467b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3345efd51863SBarry Smith 3346efd51863SBarry Smith Level: intermediate 3347efd51863SBarry Smith 3348f6dfbefdSBarry Smith Note: 3349f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3350c0df2a02SJed Brown 3351f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3352efd51863SBarry Smith @*/ 33539371c9d4SSatish Balay PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) { 3354efd51863SBarry Smith PetscFunctionBegin; 3355efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3356efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3357efd51863SBarry Smith snes->gridsequence = steps; 3358efd51863SBarry Smith PetscFunctionReturn(0); 3359efd51863SBarry Smith } 3360efd51863SBarry Smith 3361fa19ca70SBarry Smith /*@ 3362f6dfbefdSBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do 3363fa19ca70SBarry Smith 3364f6dfbefdSBarry Smith Logically Collective on snes 3365fa19ca70SBarry Smith 3366fa19ca70SBarry Smith Input Parameter: 3367f6dfbefdSBarry Smith . snes - the `SNES` context 3368fa19ca70SBarry Smith 3369fa19ca70SBarry Smith Output Parameter: 3370fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3371fa19ca70SBarry Smith 3372f6dfbefdSBarry Smith Options Database Key: 337367b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3374fa19ca70SBarry Smith 3375fa19ca70SBarry Smith Level: intermediate 3376fa19ca70SBarry Smith 3377f6dfbefdSBarry Smith Note: 3378f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3379fa19ca70SBarry Smith 3380db781477SPatrick Sanan .seealso: `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3381fa19ca70SBarry Smith @*/ 33829371c9d4SSatish Balay PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) { 3383fa19ca70SBarry Smith PetscFunctionBegin; 3384fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3385fa19ca70SBarry Smith *steps = snes->gridsequence; 3386fa19ca70SBarry Smith PetscFunctionReturn(0); 3387fa19ca70SBarry Smith } 3388fa19ca70SBarry Smith 3389a8054027SBarry Smith /*@ 3390f6dfbefdSBarry Smith SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt 3391a8054027SBarry Smith 33923f9fe445SBarry Smith Not Collective 3393a8054027SBarry Smith 3394a8054027SBarry Smith Input Parameter: 3395f6dfbefdSBarry Smith . snes - the `SNES` context 3396a8054027SBarry Smith 3397a8054027SBarry Smith Output Parameter: 3398a8054027SBarry 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 33993b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3400a8054027SBarry Smith 3401a8054027SBarry Smith Options Database Keys: 34023d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34033d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34043d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34053d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3406a8054027SBarry Smith 3407a8054027SBarry Smith Notes: 3408a8054027SBarry Smith The default is 1 3409f6dfbefdSBarry Smith 3410a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3411a8054027SBarry Smith 3412a8054027SBarry Smith Level: intermediate 3413a8054027SBarry Smith 3414f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3415a8054027SBarry Smith @*/ 34169371c9d4SSatish Balay PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) { 3417a8054027SBarry Smith PetscFunctionBegin; 34180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3419a8054027SBarry Smith *lag = snes->lagpreconditioner; 3420a8054027SBarry Smith PetscFunctionReturn(0); 3421a8054027SBarry Smith } 3422a8054027SBarry Smith 3423e35cf81dSBarry Smith /*@ 3424f6dfbefdSBarry Smith SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how 3425e35cf81dSBarry Smith often the preconditioner is rebuilt. 3426e35cf81dSBarry Smith 3427f6dfbefdSBarry Smith Logically Collective on snes 3428e35cf81dSBarry Smith 3429e35cf81dSBarry Smith Input Parameters: 3430f6dfbefdSBarry Smith + snes - the `SNES` context 3431e35cf81dSBarry 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 3432fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3433e35cf81dSBarry Smith 3434e35cf81dSBarry Smith Options Database Keys: 34353d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34363d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34373d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34383d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3439e35cf81dSBarry Smith 3440e35cf81dSBarry Smith Notes: 3441e35cf81dSBarry Smith The default is 1 3442f6dfbefdSBarry Smith 3443e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3444f6dfbefdSBarry Smith 3445fe3ffe1eSBarry 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 3446fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3447e35cf81dSBarry Smith 3448e35cf81dSBarry Smith Level: intermediate 3449e35cf81dSBarry Smith 3450f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3451e35cf81dSBarry Smith @*/ 34529371c9d4SSatish Balay PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) { 3453e35cf81dSBarry Smith PetscFunctionBegin; 34540700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 34555f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 34565f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3457c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3458e35cf81dSBarry Smith snes->lagjacobian = lag; 3459e35cf81dSBarry Smith PetscFunctionReturn(0); 3460e35cf81dSBarry Smith } 3461e35cf81dSBarry Smith 3462e35cf81dSBarry Smith /*@ 3463f6dfbefdSBarry Smith SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt 3464e35cf81dSBarry Smith 34653f9fe445SBarry Smith Not Collective 3466e35cf81dSBarry Smith 3467e35cf81dSBarry Smith Input Parameter: 3468f6dfbefdSBarry Smith . snes - the `SNES` context 3469e35cf81dSBarry Smith 3470e35cf81dSBarry Smith Output Parameter: 3471e35cf81dSBarry 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 3472e35cf81dSBarry Smith the Jacobian is built etc. 3473e35cf81dSBarry Smith 3474e35cf81dSBarry Smith Notes: 3475e35cf81dSBarry Smith The default is 1 3476f6dfbefdSBarry Smith 3477f6dfbefdSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called. 3478e35cf81dSBarry Smith 3479e35cf81dSBarry Smith Level: intermediate 3480e35cf81dSBarry Smith 3481f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3482e35cf81dSBarry Smith 3483e35cf81dSBarry Smith @*/ 34849371c9d4SSatish Balay PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) { 3485e35cf81dSBarry Smith PetscFunctionBegin; 34860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3487e35cf81dSBarry Smith *lag = snes->lagjacobian; 3488e35cf81dSBarry Smith PetscFunctionReturn(0); 3489e35cf81dSBarry Smith } 3490e35cf81dSBarry Smith 349137ec4e1aSPeter Brune /*@ 3492f6dfbefdSBarry Smith SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves 349337ec4e1aSPeter Brune 3494f6dfbefdSBarry Smith Logically collective on snes 349537ec4e1aSPeter Brune 3496d8d19677SJose E. Roman Input Parameters: 3497f6dfbefdSBarry Smith + snes - the `SNES` context 34989d7e2deaSPeter Brune - flg - jacobian lagging persists if true 349937ec4e1aSPeter Brune 350037ec4e1aSPeter Brune Options Database Keys: 35013d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35023d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35033d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35043d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35053d5a8a6aSBarry Smith 350695452b02SPatrick Sanan Notes: 3507f6dfbefdSBarry Smith Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3508f6dfbefdSBarry Smith 350995452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 351037ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 351137ec4e1aSPeter Brune timesteps may present huge efficiency gains. 351237ec4e1aSPeter Brune 3513f6dfbefdSBarry Smith Level: advanced 351437ec4e1aSPeter Brune 3515f6dfbefdSBarry Smith .seealso: `SNES, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 351637ec4e1aSPeter Brune @*/ 35179371c9d4SSatish Balay PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) { 351837ec4e1aSPeter Brune PetscFunctionBegin; 351937ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 352037ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 352137ec4e1aSPeter Brune snes->lagjac_persist = flg; 352237ec4e1aSPeter Brune PetscFunctionReturn(0); 352337ec4e1aSPeter Brune } 352437ec4e1aSPeter Brune 352537ec4e1aSPeter Brune /*@ 3526d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 352737ec4e1aSPeter Brune 3528f6dfbefdSBarry Smith Logically Collective on snes 352937ec4e1aSPeter Brune 3530d8d19677SJose E. Roman Input Parameters: 3531f6dfbefdSBarry Smith + snes - the `SNES` context 35329d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 353337ec4e1aSPeter Brune 353437ec4e1aSPeter Brune Options Database Keys: 35353d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35363d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35373d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35383d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 353937ec4e1aSPeter Brune 354095452b02SPatrick Sanan Notes: 3541f6dfbefdSBarry Smith Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3542f6dfbefdSBarry Smith 354395452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 354437ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 354537ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 354637ec4e1aSPeter Brune 354737ec4e1aSPeter Brune Level: developer 354837ec4e1aSPeter Brune 3549f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 355037ec4e1aSPeter Brune @*/ 35519371c9d4SSatish Balay PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) { 355237ec4e1aSPeter Brune PetscFunctionBegin; 355337ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 355437ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 355537ec4e1aSPeter Brune snes->lagpre_persist = flg; 355637ec4e1aSPeter Brune PetscFunctionReturn(0); 355737ec4e1aSPeter Brune } 355837ec4e1aSPeter Brune 35599b94acceSBarry Smith /*@ 3560f6dfbefdSBarry Smith SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm 3561be5caee7SBarry Smith 3562f6dfbefdSBarry Smith Logically Collective on snes 3563be5caee7SBarry Smith 3564be5caee7SBarry Smith Input Parameters: 3565f6dfbefdSBarry Smith + snes - the `SNES` context 3566f6dfbefdSBarry Smith - force - `PETSC_TRUE` require at least one iteration 3567be5caee7SBarry Smith 3568f6dfbefdSBarry Smith Options Database Key: 3569be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3570be5caee7SBarry Smith 3571f6dfbefdSBarry Smith Note: 3572f6dfbefdSBarry Smith This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution 3573be5caee7SBarry Smith 3574be5caee7SBarry Smith Level: intermediate 3575be5caee7SBarry Smith 3576f6dfbefdSBarry Smith .seealso: `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3577be5caee7SBarry Smith @*/ 35789371c9d4SSatish Balay PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) { 3579be5caee7SBarry Smith PetscFunctionBegin; 3580be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3581be5caee7SBarry Smith snes->forceiteration = force; 3582be5caee7SBarry Smith PetscFunctionReturn(0); 3583be5caee7SBarry Smith } 3584be5caee7SBarry Smith 358585216dc7SFande Kong /*@ 3586f6dfbefdSBarry Smith SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm 358785216dc7SFande Kong 3588f6dfbefdSBarry Smith Logically Collective on snes 358985216dc7SFande Kong 359085216dc7SFande Kong Input Parameters: 3591f6dfbefdSBarry Smith . snes - the `SNES` context 359285216dc7SFande Kong 359385216dc7SFande Kong Output Parameter: 359485216dc7SFande Kong . force - PETSC_TRUE requires at least one iteration. 359585216dc7SFande Kong 359606dd6b0eSSatish Balay Level: intermediate 359706dd6b0eSSatish Balay 3598f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 359985216dc7SFande Kong @*/ 36009371c9d4SSatish Balay PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) { 360185216dc7SFande Kong PetscFunctionBegin; 360285216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 360385216dc7SFande Kong *force = snes->forceiteration; 360485216dc7SFande Kong PetscFunctionReturn(0); 360585216dc7SFande Kong } 3606be5caee7SBarry Smith 3607be5caee7SBarry Smith /*@ 3608f6dfbefdSBarry Smith SNESSetTolerances - Sets `SNES` various parameters used in convergence tests. 36099b94acceSBarry Smith 3610f6dfbefdSBarry Smith Logically Collective on snes 3611c7afd0dbSLois Curfman McInnes 36129b94acceSBarry Smith Input Parameters: 3613f6dfbefdSBarry Smith + snes - the `SNES` context 361470441072SBarry Smith . abstol - absolute convergence tolerance 361533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 36165358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3617f6dfbefdSBarry Smith . maxit - maximum number of iterations, default 50. 3618f6dfbefdSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit), default 1000 3619fee21e36SBarry Smith 362033174efeSLois Curfman McInnes Options Database Keys: 362170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3622c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3623c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3624c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3625c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 36269b94acceSBarry Smith 362736851e7fSLois Curfman McInnes Level: intermediate 362836851e7fSLois Curfman McInnes 3629f6dfbefdSBarry Smith .seealso: `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 36309b94acceSBarry Smith @*/ 36319371c9d4SSatish Balay PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) { 36323a40ed3dSBarry Smith PetscFunctionBegin; 36330700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3634c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3635c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3636c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3637c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3638c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3639c5eb9154SBarry Smith 3640ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 36415f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3642ab54825eSJed Brown snes->abstol = abstol; 3643ab54825eSJed Brown } 3644ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 36455f80ce2aSJacob 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); 3646ab54825eSJed Brown snes->rtol = rtol; 3647ab54825eSJed Brown } 3648ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 36495f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3650c60f73f4SPeter Brune snes->stol = stol; 3651ab54825eSJed Brown } 3652ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 365363a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3654ab54825eSJed Brown snes->max_its = maxit; 3655ab54825eSJed Brown } 3656ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 365763a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3658ab54825eSJed Brown snes->max_funcs = maxf; 3659ab54825eSJed Brown } 366088976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 36613a40ed3dSBarry Smith PetscFunctionReturn(0); 36629b94acceSBarry Smith } 36639b94acceSBarry Smith 3664e4d06f11SPatrick Farrell /*@ 3665f6dfbefdSBarry Smith SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test. 3666e4d06f11SPatrick Farrell 3667f6dfbefdSBarry Smith Logically Collective on snes 3668e4d06f11SPatrick Farrell 3669e4d06f11SPatrick Farrell Input Parameters: 3670f6dfbefdSBarry Smith + snes - the `SNES` context 3671f6dfbefdSBarry Smith - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4 3672e4d06f11SPatrick Farrell 3673f6dfbefdSBarry Smith Options Database Key: 3674a2b725a8SWilliam Gropp . -snes_divergence_tolerance <divtol> - Sets divtol 3675e4d06f11SPatrick Farrell 3676e4d06f11SPatrick Farrell Level: intermediate 3677e4d06f11SPatrick Farrell 3678f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3679e4d06f11SPatrick Farrell @*/ 36809371c9d4SSatish Balay PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) { 3681e4d06f11SPatrick Farrell PetscFunctionBegin; 3682e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3683e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3684e4d06f11SPatrick Farrell 3685e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3686e4d06f11SPatrick Farrell snes->divtol = divtol; 36879371c9d4SSatish Balay } else { 3688e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3689e4d06f11SPatrick Farrell } 3690e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3691e4d06f11SPatrick Farrell } 3692e4d06f11SPatrick Farrell 36939b94acceSBarry Smith /*@ 369433174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 369533174efeSLois Curfman McInnes 3696c7afd0dbSLois Curfman McInnes Not Collective 3697c7afd0dbSLois Curfman McInnes 369833174efeSLois Curfman McInnes Input Parameters: 3699f6dfbefdSBarry Smith + snes - the `SNES` context 370085385478SLisandro Dalcin . atol - absolute convergence tolerance 370133174efeSLois Curfman McInnes . rtol - relative convergence tolerance 370233174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 370333174efeSLois Curfman McInnes of the change in the solution between steps 370433174efeSLois Curfman McInnes . maxit - maximum number of iterations 3705c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3706fee21e36SBarry Smith 3707f6dfbefdSBarry Smith Note: 37080298fd71SBarry Smith The user can specify NULL for any parameter that is not needed. 370933174efeSLois Curfman McInnes 371036851e7fSLois Curfman McInnes Level: intermediate 371136851e7fSLois Curfman McInnes 3712f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetTolerances()` 371333174efeSLois Curfman McInnes @*/ 37149371c9d4SSatish Balay PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) { 37153a40ed3dSBarry Smith PetscFunctionBegin; 37160700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 371785385478SLisandro Dalcin if (atol) *atol = snes->abstol; 371833174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3719c60f73f4SPeter Brune if (stol) *stol = snes->stol; 372033174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 372133174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 37223a40ed3dSBarry Smith PetscFunctionReturn(0); 372333174efeSLois Curfman McInnes } 372433174efeSLois Curfman McInnes 3725e4d06f11SPatrick Farrell /*@ 3726e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3727e4d06f11SPatrick Farrell 3728e4d06f11SPatrick Farrell Not Collective 3729e4d06f11SPatrick Farrell 3730e4d06f11SPatrick Farrell Input Parameters: 3731f6dfbefdSBarry Smith + snes - the `SNES` context 3732e4d06f11SPatrick Farrell - divtol - divergence tolerance 3733e4d06f11SPatrick Farrell 3734e4d06f11SPatrick Farrell Level: intermediate 3735e4d06f11SPatrick Farrell 3736f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetDivergenceTolerance()` 3737e4d06f11SPatrick Farrell @*/ 37389371c9d4SSatish Balay PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) { 3739e4d06f11SPatrick Farrell PetscFunctionBegin; 3740e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3741e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 3742e4d06f11SPatrick Farrell PetscFunctionReturn(0); 3743e4d06f11SPatrick Farrell } 3744e4d06f11SPatrick Farrell 374533174efeSLois Curfman McInnes /*@ 37469b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 37479b94acceSBarry Smith 3748f6dfbefdSBarry Smith Logically Collective on snes 3749fee21e36SBarry Smith 3750c7afd0dbSLois Curfman McInnes Input Parameters: 3751f6dfbefdSBarry Smith + snes - the `SNES` context 3752c7afd0dbSLois Curfman McInnes - tol - tolerance 3753c7afd0dbSLois Curfman McInnes 37549b94acceSBarry Smith Options Database Key: 3755c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 37569b94acceSBarry Smith 375736851e7fSLois Curfman McInnes Level: intermediate 375836851e7fSLois Curfman McInnes 3759f6dfbefdSBarry Smith .seealso: `SNES`, `SNESNEWTONTRDC`, `SNESSetTolerances()` 37609b94acceSBarry Smith @*/ 37619371c9d4SSatish Balay PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) { 37623a40ed3dSBarry Smith PetscFunctionBegin; 37630700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3764c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 37659b94acceSBarry Smith snes->deltatol = tol; 37663a40ed3dSBarry Smith PetscFunctionReturn(0); 37679b94acceSBarry Smith } 37689b94acceSBarry Smith 37696ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 37706ba87a44SLisandro Dalcin 37719371c9d4SSatish Balay PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) { 3772b271bb04SBarry Smith PetscDrawLG lg; 3773b271bb04SBarry Smith PetscReal x, y, per; 3774b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3775b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3776b271bb04SBarry Smith PetscDraw draw; 3777b271bb04SBarry Smith 3778459f5d12SBarry Smith PetscFunctionBegin; 37794d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 37809566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 37819566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 37829566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 37839566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3784b271bb04SBarry Smith x = (PetscReal)n; 378577b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 378694c9c6d3SKarl Rupp else y = -15.0; 37879566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 37886934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 37899566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 37909566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3791b271bb04SBarry Smith } 3792b271bb04SBarry Smith 37939566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 37949566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 37959566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 37969566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "% elemts > .2*max elemt")); 37979566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3798b271bb04SBarry Smith x = (PetscReal)n; 3799b271bb04SBarry Smith y = 100.0 * per; 38009566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38016934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38029566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38039566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3804b271bb04SBarry Smith } 3805b271bb04SBarry Smith 38069566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 38079371c9d4SSatish Balay if (!n) { 38089371c9d4SSatish Balay prev = rnorm; 38099371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 38109371c9d4SSatish Balay } 38119566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38129566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3813b271bb04SBarry Smith x = (PetscReal)n; 3814b271bb04SBarry Smith y = (prev - rnorm) / prev; 38159566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38166934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38179566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38189566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3819b271bb04SBarry Smith } 3820b271bb04SBarry Smith 38219566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 38229566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38239566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38249566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3825b271bb04SBarry Smith x = (PetscReal)n; 3826b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3827b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 38289566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3829b271bb04SBarry Smith } 38306934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38319566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38329566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3833b271bb04SBarry Smith } 3834b271bb04SBarry Smith prev = rnorm; 3835b271bb04SBarry Smith PetscFunctionReturn(0); 3836b271bb04SBarry Smith } 3837b271bb04SBarry Smith 3838228d79bcSJed Brown /*@ 3839228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3840228d79bcSJed Brown 3841f6dfbefdSBarry Smith Collective on snes 3842228d79bcSJed Brown 3843228d79bcSJed Brown Input Parameters: 3844f6dfbefdSBarry Smith + snes - nonlinear solver context obtained from `SNESCreate()` 3845228d79bcSJed Brown . iter - iteration number 3846228d79bcSJed Brown - rnorm - relative norm of the residual 3847228d79bcSJed Brown 3848f6dfbefdSBarry Smith Note: 3849f6dfbefdSBarry Smith This routine is called by the `SNES` implementations. 3850228d79bcSJed Brown It does not typically need to be called by the user. 3851228d79bcSJed Brown 3852228d79bcSJed Brown Level: developer 3853228d79bcSJed Brown 3854f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorSet()` 3855228d79bcSJed Brown @*/ 38569371c9d4SSatish Balay PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) { 38577a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 38587a03ce2fSLisandro Dalcin 38597a03ce2fSLisandro Dalcin PetscFunctionBegin; 38609566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 386148a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 38629566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 38637a03ce2fSLisandro Dalcin PetscFunctionReturn(0); 38647a03ce2fSLisandro Dalcin } 38657a03ce2fSLisandro Dalcin 38669b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 38679b94acceSBarry Smith 3868bf388a1fSBarry Smith /*MC 3869f6dfbefdSBarry Smith SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver 3870bf388a1fSBarry Smith 3871bf388a1fSBarry Smith Synopsis: 3872aaa7dc30SBarry Smith #include <petscsnes.h> 3873bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3874bf388a1fSBarry Smith 38751843f636SBarry Smith Collective on snes 38761843f636SBarry Smith 38771843f636SBarry Smith Input Parameters: 3878f6dfbefdSBarry Smith + snes - the `SNES` context 3879bf388a1fSBarry Smith . its - iteration number 3880bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3881bf388a1fSBarry Smith - mctx - [optional] monitoring context 3882bf388a1fSBarry Smith 3883878cb397SSatish Balay Level: advanced 3884878cb397SSatish Balay 3885f6dfbefdSBarry Smith .seealso: `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()` 3886bf388a1fSBarry Smith M*/ 3887bf388a1fSBarry Smith 38889b94acceSBarry Smith /*@C 3889a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 38909b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 38919b94acceSBarry Smith progress. 38929b94acceSBarry Smith 3893f6dfbefdSBarry Smith Logically Collective on snes 3894fee21e36SBarry Smith 3895c7afd0dbSLois Curfman McInnes Input Parameters: 3896f6dfbefdSBarry Smith + snes - the `SNES` context 3897f6dfbefdSBarry Smith . f - the monitor function, see `SNESMonitorFunction` for the calling sequence 3898b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 38990298fd71SBarry Smith monitor routine (use NULL if no context is desired) 3900b3006f0bSLois Curfman McInnes - monitordestroy - [optional] routine that frees monitor context 39010298fd71SBarry Smith (may be NULL) 39029b94acceSBarry Smith 39039665c990SLois Curfman McInnes Options Database Keys: 3904f6dfbefdSBarry Smith + -snes_monitor - sets `SNESMonitorDefault()` 3905798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 3906cca6129bSJed Brown - -snes_monitor_cancel - cancels all monitors that have 3907c7afd0dbSLois Curfman McInnes been hardwired into a code by 3908a6570f20SBarry Smith calls to SNESMonitorSet(), but 3909c7afd0dbSLois Curfman McInnes does not cancel those set via 3910c7afd0dbSLois Curfman McInnes the options database. 39119665c990SLois Curfman McInnes 3912f6dfbefdSBarry Smith Note: 39136bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3914f6dfbefdSBarry Smith `SNESMonitorSet()` multiple times; all will be called in the 39156bc08f3fSLois Curfman McInnes order in which they were set. 3916639f9d9dSBarry Smith 3917f6dfbefdSBarry Smith Fortran Note: 3918f6dfbefdSBarry Smith Only a single monitor function can be set for each `SNES` object 3919025f1a04SBarry Smith 392036851e7fSLois Curfman McInnes Level: intermediate 392136851e7fSLois Curfman McInnes 3922f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 39239b94acceSBarry Smith @*/ 39249371c9d4SSatish Balay PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) { 3925b90d0a6eSBarry Smith PetscInt i; 392678064530SBarry Smith PetscBool identical; 3927b90d0a6eSBarry Smith 39283a40ed3dSBarry Smith PetscFunctionBegin; 39290700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3930b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 39319566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 393278064530SBarry Smith if (identical) PetscFunctionReturn(0); 3933649052a6SBarry Smith } 39345f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 39356e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 3936b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 3937639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 39383a40ed3dSBarry Smith PetscFunctionReturn(0); 39399b94acceSBarry Smith } 39409b94acceSBarry Smith 3941a278d85bSSatish Balay /*@ 3942f6dfbefdSBarry Smith SNESMonitorCancel - Clears all the monitor functions for a `SNES` object. 39435cd90555SBarry Smith 3944f6dfbefdSBarry Smith Logically Collective on snes 3945c7afd0dbSLois Curfman McInnes 39465cd90555SBarry Smith Input Parameters: 3947f6dfbefdSBarry Smith . snes - the `SNES` context 39485cd90555SBarry Smith 39491a480d89SAdministrator Options Database Key: 3950a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 3951a6570f20SBarry Smith into a code by calls to SNESMonitorSet(), but does not cancel those 3952c7afd0dbSLois Curfman McInnes set via the options database 39535cd90555SBarry Smith 3954f6dfbefdSBarry Smith Note: 3955f6dfbefdSBarry Smith There is no way to clear one specific monitor from a `SNES` object. 39565cd90555SBarry Smith 395736851e7fSLois Curfman McInnes Level: intermediate 395836851e7fSLois Curfman McInnes 3959f6dfbefdSBarry Smith .seealso: `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()` 39605cd90555SBarry Smith @*/ 39619371c9d4SSatish Balay PetscErrorCode SNESMonitorCancel(SNES snes) { 3962d952e501SBarry Smith PetscInt i; 3963d952e501SBarry Smith 39645cd90555SBarry Smith PetscFunctionBegin; 39650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3966d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 396748a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 3968d952e501SBarry Smith } 39695cd90555SBarry Smith snes->numbermonitors = 0; 39705cd90555SBarry Smith PetscFunctionReturn(0); 39715cd90555SBarry Smith } 39725cd90555SBarry Smith 3973bf388a1fSBarry Smith /*MC 3974bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 3975bf388a1fSBarry Smith 3976bf388a1fSBarry Smith Synopsis: 3977aaa7dc30SBarry Smith #include <petscsnes.h> 3978bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 3979bf388a1fSBarry Smith 39801843f636SBarry Smith Collective on snes 39811843f636SBarry Smith 39821843f636SBarry Smith Input Parameters: 3983f6dfbefdSBarry Smith + snes - the `SNES` context 3984bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 3985bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 3986bf388a1fSBarry Smith . gnorm - 2-norm of current step 39871843f636SBarry Smith . f - 2-norm of function 39881843f636SBarry Smith - cctx - [optional] convergence context 39891843f636SBarry Smith 39901843f636SBarry Smith Output Parameter: 39911843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 3992bf388a1fSBarry Smith 3993878cb397SSatish Balay Level: intermediate 3994bf388a1fSBarry Smith 3995f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 3996bf388a1fSBarry Smith M*/ 3997bf388a1fSBarry Smith 39989b94acceSBarry Smith /*@C 39999b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40009b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40019b94acceSBarry Smith 4002f6dfbefdSBarry Smith Logically Collective on snes 4003fee21e36SBarry Smith 4004c7afd0dbSLois Curfman McInnes Input Parameters: 4005f6dfbefdSBarry Smith + snes - the `SNES` context 4006f6dfbefdSBarry Smith . `SNESConvergenceTestFunction` - routine to test for convergence 40070298fd71SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be NULL) 4008cf90aa19SBarry Smith - destroy - [optional] destructor for the context (may be NULL; PETSC_NULL_FUNCTION in Fortran) 40099b94acceSBarry Smith 401036851e7fSLois Curfman McInnes Level: advanced 401136851e7fSLois Curfman McInnes 4012f6dfbefdSBarry Smith .seealso: `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 40139b94acceSBarry Smith @*/ 40149371c9d4SSatish Balay PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) { 40153a40ed3dSBarry Smith PetscFunctionBegin; 40160700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4017e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 40181baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4019bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 40207f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 402185385478SLisandro Dalcin snes->cnvP = cctx; 40223a40ed3dSBarry Smith PetscFunctionReturn(0); 40239b94acceSBarry Smith } 40249b94acceSBarry Smith 402552baeb72SSatish Balay /*@ 4026f6dfbefdSBarry Smith SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped. 4027184914b5SBarry Smith 4028184914b5SBarry Smith Not Collective 4029184914b5SBarry Smith 4030184914b5SBarry Smith Input Parameter: 4031f6dfbefdSBarry Smith . snes - the `SNES` context 4032184914b5SBarry Smith 4033184914b5SBarry Smith Output Parameter: 4034f6dfbefdSBarry Smith . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists 4035184914b5SBarry Smith 4036f6dfbefdSBarry Smith Options Database Key: 40376a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 40386a4d7782SBarry Smith 4039184914b5SBarry Smith Level: intermediate 4040184914b5SBarry Smith 4041f6dfbefdSBarry Smith Note: 4042f6dfbefdSBarry Smith Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`. 4043184914b5SBarry Smith 4044f6dfbefdSBarry Smith .seealso: `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()` 4045184914b5SBarry Smith @*/ 40469371c9d4SSatish Balay PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) { 4047184914b5SBarry Smith PetscFunctionBegin; 40480700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 40494482741eSBarry Smith PetscValidPointer(reason, 2); 4050184914b5SBarry Smith *reason = snes->reason; 4051184914b5SBarry Smith PetscFunctionReturn(0); 4052184914b5SBarry Smith } 4053184914b5SBarry Smith 4054c4421ceaSFande Kong /*@C 4055f6dfbefdSBarry Smith SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason` 4056c4421ceaSFande Kong 4057c4421ceaSFande Kong Not Collective 4058c4421ceaSFande Kong 4059c4421ceaSFande Kong Input Parameter: 4060f6dfbefdSBarry Smith . snes - the `SNES` context 4061c4421ceaSFande Kong 4062c4421ceaSFande Kong Output Parameter: 4063c4421ceaSFande Kong . strreason - a human readable string that describes SNES converged reason 4064c4421ceaSFande Kong 406599c90e12SSatish Balay Level: beginner 4066c4421ceaSFande Kong 4067f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetConvergedReason()` 4068c4421ceaSFande Kong @*/ 40699371c9d4SSatish Balay PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) { 4070c4421ceaSFande Kong PetscFunctionBegin; 4071c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4072dadcf809SJacob Faibussowitsch PetscValidPointer(strreason, 2); 4073c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 4074c4421ceaSFande Kong PetscFunctionReturn(0); 4075c4421ceaSFande Kong } 4076c4421ceaSFande Kong 407733866048SMatthew G. Knepley /*@ 4078f6dfbefdSBarry Smith SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped. 407933866048SMatthew G. Knepley 408033866048SMatthew G. Knepley Not Collective 408133866048SMatthew G. Knepley 408233866048SMatthew G. Knepley Input Parameters: 4083f6dfbefdSBarry Smith + snes - the `SNES` context 4084f6dfbefdSBarry Smith - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the 408533866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 408633866048SMatthew G. Knepley 4087f6dfbefdSBarry Smith Level: developer 4088f6dfbefdSBarry Smith 4089f6dfbefdSBarry Smith Developer Note: 4090f6dfbefdSBarry Smith Called inside the various `SNESSolve()` implementations 409133866048SMatthew G. Knepley 4092db781477SPatrick Sanan .seealso: `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 409333866048SMatthew G. Knepley @*/ 40949371c9d4SSatish Balay PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) { 409533866048SMatthew G. Knepley PetscFunctionBegin; 409633866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 409733866048SMatthew G. Knepley snes->reason = reason; 409833866048SMatthew G. Knepley PetscFunctionReturn(0); 409933866048SMatthew G. Knepley } 410033866048SMatthew G. Knepley 4101c9005455SLois Curfman McInnes /*@ 4102c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4103c9005455SLois Curfman McInnes 4104f6dfbefdSBarry Smith Logically Collective on snes 4105fee21e36SBarry Smith 4106c7afd0dbSLois Curfman McInnes Input Parameters: 4107f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 41088c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4109cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4110758f92a0SBarry Smith . na - size of a and its 4111f6dfbefdSBarry Smith - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero, 4112758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4113c7afd0dbSLois Curfman McInnes 4114308dcc3eSBarry Smith Notes: 4115f6dfbefdSBarry Smith If 'a' and 'its' are NULL then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a 4116308dcc3eSBarry Smith default array of length 10000 is allocated. 4117308dcc3eSBarry Smith 4118c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4119c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4120c9005455SLois Curfman McInnes during the section of code that is being timed. 4121c9005455SLois Curfman McInnes 412236851e7fSLois Curfman McInnes Level: intermediate 412336851e7fSLois Curfman McInnes 4124f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()` 4125c9005455SLois Curfman McInnes @*/ 41269371c9d4SSatish Balay PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) { 41273a40ed3dSBarry Smith PetscFunctionBegin; 41280700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4129064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a, 2); 4130a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its, 3); 41317a1ec6d4SBarry Smith if (!a) { 4132308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 41339566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4134071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4135308dcc3eSBarry Smith } 4136c9005455SLois Curfman McInnes snes->conv_hist = a; 4137758f92a0SBarry Smith snes->conv_hist_its = its; 4138115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4139a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4140758f92a0SBarry Smith snes->conv_hist_reset = reset; 4141758f92a0SBarry Smith PetscFunctionReturn(0); 4142758f92a0SBarry Smith } 4143758f92a0SBarry Smith 4144308dcc3eSBarry Smith #if defined(PETSC_HAVE_MATLAB_ENGINE) 4145c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4146c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 414799e0435eSBarry Smith 41489371c9d4SSatish Balay PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) { 4149308dcc3eSBarry Smith mxArray *mat; 4150308dcc3eSBarry Smith PetscInt i; 4151308dcc3eSBarry Smith PetscReal *ar; 4152308dcc3eSBarry Smith 4153308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4154308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4155f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 415611cc89d2SBarry Smith return mat; 4157308dcc3eSBarry Smith } 4158308dcc3eSBarry Smith #endif 4159308dcc3eSBarry Smith 41600c4c9dddSBarry Smith /*@C 4161758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4162758f92a0SBarry Smith 41633f9fe445SBarry Smith Not Collective 4164758f92a0SBarry Smith 4165758f92a0SBarry Smith Input Parameter: 4166f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 4167758f92a0SBarry Smith 4168758f92a0SBarry Smith Output Parameters: 4169f6dfbefdSBarry Smith + a - array to hold history, usually was set with `SNESSetConvergenceHistory()` 4170758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4171758f92a0SBarry Smith negative if not converged) for each solve. 4172758f92a0SBarry Smith - na - size of a and its 4173758f92a0SBarry Smith 4174758f92a0SBarry Smith Notes: 4175758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4176758f92a0SBarry Smith $ call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4177758f92a0SBarry Smith 4178758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4179758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4180758f92a0SBarry Smith during the section of code that is being timed. 4181758f92a0SBarry Smith 4182758f92a0SBarry Smith Level: intermediate 4183758f92a0SBarry Smith 4184f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()` 4185758f92a0SBarry Smith @*/ 41869371c9d4SSatish Balay PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) { 4187758f92a0SBarry Smith PetscFunctionBegin; 41880700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4189758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4190758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4191115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 41923a40ed3dSBarry Smith PetscFunctionReturn(0); 4193c9005455SLois Curfman McInnes } 4194c9005455SLois Curfman McInnes 4195ac226902SBarry Smith /*@C 419676b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4197eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 41987e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 419976b2cf59SMatthew Knepley 4200f6dfbefdSBarry Smith Logically Collective on snes 420176b2cf59SMatthew Knepley 420276b2cf59SMatthew Knepley Input Parameters: 4203a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4204a2b725a8SWilliam Gropp - func - The function 420576b2cf59SMatthew Knepley 420676b2cf59SMatthew Knepley Calling sequence of func: 4207a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 420876b2cf59SMatthew Knepley 420976b2cf59SMatthew Knepley . step - The current step of the iteration 421076b2cf59SMatthew Knepley 4211fe97e370SBarry Smith Level: advanced 4212fe97e370SBarry Smith 42136b7fb656SBarry Smith Note: 4214f6dfbefdSBarry 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 function provided 4215f6dfbefdSBarry Smith to `SNESSetFunction()`, or `SNESSetPicard()` 4216fe97e370SBarry Smith This is not used by most users. 421776b2cf59SMatthew Knepley 42186b7fb656SBarry 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. 42196b7fb656SBarry Smith 4220f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4221db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 422276b2cf59SMatthew Knepley @*/ 42239371c9d4SSatish Balay PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) { 422476b2cf59SMatthew Knepley PetscFunctionBegin; 42250700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4226e7788613SBarry Smith snes->ops->update = func; 422776b2cf59SMatthew Knepley PetscFunctionReturn(0); 422876b2cf59SMatthew Knepley } 422976b2cf59SMatthew Knepley 42309b94acceSBarry Smith /* 42319b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 42329b94acceSBarry Smith positive parameter delta. 42339b94acceSBarry Smith 42349b94acceSBarry Smith Input Parameters: 4235f6dfbefdSBarry Smith + snes - the `SNES` context 42369b94acceSBarry Smith . y - approximate solution of linear system 42379b94acceSBarry Smith . fnorm - 2-norm of current function 4238c7afd0dbSLois Curfman McInnes - delta - trust region size 42399b94acceSBarry Smith 42409b94acceSBarry Smith Output Parameters: 4241c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 42429b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 42439b94acceSBarry Smith region, and exceeds zero otherwise. 4244c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 42459b94acceSBarry Smith 4246f6dfbefdSBarry Smith Level: developer 42479b94acceSBarry Smith 4248f6dfbefdSBarry Smith Note: 4249f6dfbefdSBarry Smith For non-trust region methods such as `SNESNEWTONLS`, the parameter delta 4250f6dfbefdSBarry Smith is set to be the maximum allowable step size. 42519b94acceSBarry Smith */ 42529371c9d4SSatish Balay PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm) { 4253064f8208SBarry Smith PetscReal nrm; 4254ea709b57SSatish Balay PetscScalar cnorm; 42553a40ed3dSBarry Smith 42563a40ed3dSBarry Smith PetscFunctionBegin; 42570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 42580700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 2); 4259c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 2); 4260184914b5SBarry Smith 42619566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 4262064f8208SBarry Smith if (nrm > *delta) { 4263064f8208SBarry Smith nrm = *delta / nrm; 4264064f8208SBarry Smith *gpnorm = (1.0 - nrm) * (*fnorm); 4265064f8208SBarry Smith cnorm = nrm; 42669566063dSJacob Faibussowitsch PetscCall(VecScale(y, cnorm)); 42679b94acceSBarry Smith *ynorm = *delta; 42689b94acceSBarry Smith } else { 42699b94acceSBarry Smith *gpnorm = 0.0; 4270064f8208SBarry Smith *ynorm = nrm; 42719b94acceSBarry Smith } 42723a40ed3dSBarry Smith PetscFunctionReturn(0); 42739b94acceSBarry Smith } 42749b94acceSBarry Smith 427591f3e32bSBarry Smith /*@C 4276f6dfbefdSBarry Smith SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer 42772a359c20SBarry Smith 4278f6dfbefdSBarry Smith Collective on snes 42792a359c20SBarry Smith 42802a359c20SBarry Smith Parameter: 4281f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 42822a359c20SBarry Smith - viewer - the viewer to display the reason 42832a359c20SBarry Smith 42842a359c20SBarry Smith Options Database Keys: 4285ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4286ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4287eafd5ff0SAlex Lindsay 4288f6dfbefdSBarry Smith Note: 4289f6dfbefdSBarry Smith To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default, 4290f6dfbefdSBarry Smith use `PETSC_VIEWER_FAILED` to only display a reason if it fails. 42912a359c20SBarry Smith 42922a359c20SBarry Smith Level: beginner 42932a359c20SBarry Smith 4294f6dfbefdSBarry Smith .seealso: `SNESConvergedReason`, `PetscViewer`, `SNES`, 4295f6dfbefdSBarry Smith `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, 4296f6dfbefdSBarry Smith `SNESConvergedReasonViewFromOptions()`, 4297db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 42982a359c20SBarry Smith @*/ 42999371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) { 430075cca76cSMatthew G. Knepley PetscViewerFormat format; 43012a359c20SBarry Smith PetscBool isAscii; 43022a359c20SBarry Smith 43032a359c20SBarry Smith PetscFunctionBegin; 430419a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 43059566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 43062a359c20SBarry Smith if (isAscii) { 43079566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 43089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 430975cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 431075cca76cSMatthew G. Knepley DM dm; 431175cca76cSMatthew G. Knepley Vec u; 431275cca76cSMatthew G. Knepley PetscDS prob; 431375cca76cSMatthew G. Knepley PetscInt Nf, f; 431495cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 431595cbbfd3SMatthew G. Knepley void **exactCtx; 431675cca76cSMatthew G. Knepley PetscReal error; 431775cca76cSMatthew G. Knepley 43189566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 43199566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 43209566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 43219566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 43229566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 43239566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 43249566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 43259566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 43269566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 432763a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 432875cca76cSMatthew G. Knepley } 4329eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 43302a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 433163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 43322a359c20SBarry Smith } else { 433363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 43342a359c20SBarry Smith } 4335eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 43362a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 433763a3b9bcSJacob 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)); 43382a359c20SBarry Smith } else { 433963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 43402a359c20SBarry Smith } 43412a359c20SBarry Smith } 43429566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 43432a359c20SBarry Smith } 43442a359c20SBarry Smith PetscFunctionReturn(0); 43452a359c20SBarry Smith } 43462a359c20SBarry Smith 4347c4421ceaSFande Kong /*@C 4348c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4349c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4350c4421ceaSFande Kong 4351f6dfbefdSBarry Smith Logically Collective on snes 4352c4421ceaSFande Kong 4353c4421ceaSFande Kong Input Parameters: 4354f6dfbefdSBarry Smith + snes - the `SNES` context 4355c4421ceaSFande Kong . f - the snes converged reason view function 4356c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4357c4421ceaSFande Kong snes converged reason view routine (use NULL if no context is desired) 4358c4421ceaSFande Kong - reasonviewdestroy - [optional] routine that frees reasonview context 4359c4421ceaSFande Kong (may be NULL) 4360c4421ceaSFande Kong 4361c4421ceaSFande Kong Options Database Keys: 4362f6dfbefdSBarry Smith + -snes_converged_reason - sets a default `SNESConvergedReasonView()` 4363c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4364c4421ceaSFande Kong been hardwired into a code by 4365f6dfbefdSBarry Smith calls to `SNESConvergedReasonViewSet()`, but 4366c4421ceaSFande Kong does not cancel those set via 4367c4421ceaSFande Kong the options database. 4368c4421ceaSFande Kong 4369f6dfbefdSBarry Smith Note: 4370c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4371f6dfbefdSBarry Smith `SNESConvergedReasonViewSet()` multiple times; all will be called in the 4372c4421ceaSFande Kong order in which they were set. 4373c4421ceaSFande Kong 4374c4421ceaSFande Kong Level: intermediate 4375c4421ceaSFande Kong 4376f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4377c4421ceaSFande Kong @*/ 43789371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) { 4379c4421ceaSFande Kong PetscInt i; 4380c4421ceaSFande Kong PetscBool identical; 4381c4421ceaSFande Kong 4382c4421ceaSFande Kong PetscFunctionBegin; 4383c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4384c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 43859566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 4386c4421ceaSFande Kong if (identical) PetscFunctionReturn(0); 4387c4421ceaSFande Kong } 43885f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4389c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4390c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4391c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 4392c4421ceaSFande Kong PetscFunctionReturn(0); 4393c4421ceaSFande Kong } 4394c4421ceaSFande Kong 439591f3e32bSBarry Smith /*@ 4396f6dfbefdSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed. 4397c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 43982a359c20SBarry Smith 4399f6dfbefdSBarry Smith Collective on snes 44002a359c20SBarry Smith 44012a359c20SBarry Smith Input Parameters: 4402f6dfbefdSBarry Smith . snes - the `SNES` object 44032a359c20SBarry Smith 4404f6dfbefdSBarry Smith Level: advanced 44052a359c20SBarry Smith 4406f6dfbefdSBarry Smith .seealso: `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, 4407f6dfbefdSBarry Smith `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 44082a359c20SBarry Smith @*/ 44099371c9d4SSatish Balay PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) { 44102a359c20SBarry Smith PetscViewer viewer; 44112a359c20SBarry Smith PetscBool flg; 44122a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 44132a359c20SBarry Smith PetscViewerFormat format; 4414c4421ceaSFande Kong PetscInt i; 44152a359c20SBarry Smith 44162a359c20SBarry Smith PetscFunctionBegin; 44172a359c20SBarry Smith if (incall) PetscFunctionReturn(0); 44182a359c20SBarry Smith incall = PETSC_TRUE; 4419c4421ceaSFande Kong 4420c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 442148a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4422c4421ceaSFande Kong 4423c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 44249566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 44252a359c20SBarry Smith if (flg) { 44269566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 44279566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 44289566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 44299566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 44302a359c20SBarry Smith } 44312a359c20SBarry Smith incall = PETSC_FALSE; 44322a359c20SBarry Smith PetscFunctionReturn(0); 44332a359c20SBarry Smith } 44342a359c20SBarry Smith 4435487a658cSBarry Smith /*@ 4436f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4437f6dfbefdSBarry Smith Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`. 44389b94acceSBarry Smith 4439f6dfbefdSBarry Smith Collective on snes 4440c7afd0dbSLois Curfman McInnes 4441b2002411SLois Curfman McInnes Input Parameters: 4442f6dfbefdSBarry Smith + snes - the `SNES` context 44430298fd71SBarry Smith . b - the constant part of the equation F(x) = b, or NULL to use zero. 444485385478SLisandro Dalcin - x - the solution vector. 44459b94acceSBarry Smith 4446f6dfbefdSBarry Smith Note: 44478ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 4448f6dfbefdSBarry Smith for the nonlinear solve prior to calling `SNESSolve()`. In particular, 44498ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 4450f6dfbefdSBarry Smith this vector to zero by calling `VecSet()`. 44518ddd3da0SLois Curfman McInnes 445236851e7fSLois Curfman McInnes Level: beginner 445336851e7fSLois Curfman McInnes 4454f6dfbefdSBarry Smith .seealso: `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4455db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4456db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 44579b94acceSBarry Smith @*/ 44589371c9d4SSatish Balay PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) { 4459ace3abfcSBarry Smith PetscBool flg; 4460efd51863SBarry Smith PetscInt grid; 44610298fd71SBarry Smith Vec xcreated = NULL; 4462caa4e7f2SJed Brown DM dm; 4463052efed2SBarry Smith 44643a40ed3dSBarry Smith PetscFunctionBegin; 44650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4466a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4467a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 44680700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 446985385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 447085385478SLisandro Dalcin 447134b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 447206fc46c8SMatthew G. Knepley { 447306fc46c8SMatthew G. Knepley PetscViewer viewer; 447406fc46c8SMatthew G. Knepley PetscViewerFormat format; 44757c88af5aSMatthew G. Knepley PetscInt num; 447606fc46c8SMatthew G. Knepley PetscBool flg; 447706fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 447806fc46c8SMatthew G. Knepley 447906fc46c8SMatthew G. Knepley if (!incall) { 448034b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 44819566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 448206fc46c8SMatthew G. Knepley if (flg) { 448306fc46c8SMatthew G. Knepley PetscConvEst conv; 448446079b62SMatthew G. Knepley DM dm; 448546079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 448646079b62SMatthew G. Knepley PetscInt Nf; 448706fc46c8SMatthew G. Knepley 448806fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 44899566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 44909566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 44919566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 44929566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 44939566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 44949566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 44959566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 44969566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 44979566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 44989566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 44999566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45009566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45019566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 45029566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 450306fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 450406fc46c8SMatthew G. Knepley } 450534b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4506b2588ea6SMatthew G. Knepley num = 1; 45079566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 450834b4d3a8SMatthew G. Knepley if (flg) { 450934b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 451034b4d3a8SMatthew G. Knepley 451134b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 45129566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45139566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45149566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45159566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 45169566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 45179566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 45189566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 451934b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 452034b4d3a8SMatthew G. Knepley } 45217c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 45227c88af5aSMatthew G. Knepley num = 0; 45239566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 45247c88af5aSMatthew G. Knepley if (num) { 45257c88af5aSMatthew G. Knepley DMAdaptor adaptor; 45267c88af5aSMatthew G. Knepley 45277c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 45289566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45299566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45309566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45319566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 45329566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 45339566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 45349566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 45357c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 45367c88af5aSMatthew G. Knepley } 453706fc46c8SMatthew G. Knepley } 453806fc46c8SMatthew G. Knepley } 4539ad540459SPierre Jolivet if (!x) x = snes->vec_sol; 4540caa4e7f2SJed Brown if (!x) { 45419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45429566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4543a69afd8bSBarry Smith x = xcreated; 4544a69afd8bSBarry Smith } 45459566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4546f05ece33SBarry Smith 45479566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4548efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 454985385478SLisandro Dalcin /* set solution vector */ 45509566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 45519566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 455285385478SLisandro Dalcin snes->vec_sol = x; 45539566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4554caa4e7f2SJed Brown 4555caa4e7f2SJed Brown /* set affine vector if provided */ 45569566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 45579566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 455885385478SLisandro Dalcin snes->vec_rhs = b; 455985385478SLisandro Dalcin 45605f80ce2aSJacob 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"); 45615f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 45625f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 4563154060b5SMatthew G. Knepley if (!snes->vec_sol_update /* && snes->vec_sol */) { 45649566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); 45659566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->vec_sol_update)); 4566154060b5SMatthew G. Knepley } 45679566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 45689566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 45693f149594SLisandro Dalcin 45707eee914bSBarry Smith if (!grid) { 457125e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4572dd568438SSatish Balay } 4573d25893d9SBarry Smith 4574abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 45759371c9d4SSatish Balay if (snes->counters_reset) { 45769371c9d4SSatish Balay snes->nfuncs = 0; 45779371c9d4SSatish Balay snes->linear_its = 0; 45789371c9d4SSatish Balay snes->numFailures = 0; 45799371c9d4SSatish Balay } 4580d5e45103SBarry Smith 45819566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4582dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 45839566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 45845f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason"); 4585422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 45863f149594SLisandro Dalcin 458737ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 458837ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 458937ec4e1aSPeter Brune 45909566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 45919566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4592c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 45939566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 45945968eb51SBarry Smith 45955f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 45969c8e83a9SBarry Smith if (snes->reason < 0) break; 4597efd51863SBarry Smith if (grid < snes->gridsequence) { 4598efd51863SBarry Smith DM fine; 4599efd51863SBarry Smith Vec xnew; 4600efd51863SBarry Smith Mat interp; 4601efd51863SBarry Smith 46029566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 46035f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 46049566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 46059566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 46069566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 46079566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 46089566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4609efd51863SBarry Smith x = xnew; 4610efd51863SBarry Smith 46119566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 46129566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 46139566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 46149566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 46159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4616efd51863SBarry Smith } 4617efd51863SBarry Smith } 46189566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 46199566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 46209566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 46219566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 46223f7e2da0SPeter Brune 46239566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 46249566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 46253a40ed3dSBarry Smith PetscFunctionReturn(0); 46269b94acceSBarry Smith } 46279b94acceSBarry Smith 46289b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 46299b94acceSBarry Smith 463082bf6240SBarry Smith /*@C 46314b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 46329b94acceSBarry Smith 4633f6dfbefdSBarry Smith Collective on snes 4634fee21e36SBarry Smith 4635c7afd0dbSLois Curfman McInnes Input Parameters: 4636f6dfbefdSBarry Smith + snes - the `SNES` context 4637454a90a3SBarry Smith - type - a known method 4638c7afd0dbSLois Curfman McInnes 4639c7afd0dbSLois Curfman McInnes Options Database Key: 4640454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 464104d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4642ae12b187SLois Curfman McInnes 46439b94acceSBarry Smith Notes: 4644e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 4645f6dfbefdSBarry Smith + `SNESNEWTONLS` - Newton's method with line search 4646c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4647f6dfbefdSBarry Smith - `SNESNEWTONTRDC` - Newton's method with trust region 4648c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 46499b94acceSBarry Smith 4650f6dfbefdSBarry Smith Normally, it is best to use the `SNESSetFromOptions()` command and then 4651f6dfbefdSBarry Smith set the `SNES` solver type from the options database rather than by using 4652ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4653ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4654f6dfbefdSBarry Smith The `SNESSetType()` routine is provided for those situations where it 4655ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4656ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4657ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4658ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4659b0a32e0cSBarry Smith appropriate method. 466036851e7fSLois Curfman McInnes 4661f6dfbefdSBarry Smith Developer Note: 4662f6dfbefdSBarry Smith `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates 4663f6dfbefdSBarry Smith the constructor in that list and calls it to create the specific object. 46648f6c3df8SBarry Smith 466536851e7fSLois Curfman McInnes Level: intermediate 4666a703fe33SLois Curfman McInnes 4667f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 46689b94acceSBarry Smith @*/ 46699371c9d4SSatish Balay PetscErrorCode SNESSetType(SNES snes, SNESType type) { 4670ace3abfcSBarry Smith PetscBool match; 46715f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 46723a40ed3dSBarry Smith 46733a40ed3dSBarry Smith PetscFunctionBegin; 46740700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 46754482741eSBarry Smith PetscValidCharPointer(type, 2); 467682bf6240SBarry Smith 46779566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 46780f5bd95cSBarry Smith if (match) PetscFunctionReturn(0); 467992ff6ae8SBarry Smith 46809566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 46815f80ce2aSJacob Faibussowitsch PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 468275396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4683dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 468475396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 46859e5d0892SLisandro Dalcin snes->ops->setup = NULL; 46869e5d0892SLisandro Dalcin snes->ops->solve = NULL; 46879e5d0892SLisandro Dalcin snes->ops->view = NULL; 46889e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 46899e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 46907fe760d5SStefano Zampini 46917fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 46929566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 46937fe760d5SStefano Zampini 469475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 469575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4696f5af7f23SKarl Rupp 46979566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 46989566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 46993a40ed3dSBarry Smith PetscFunctionReturn(0); 47009b94acceSBarry Smith } 47019b94acceSBarry Smith 47029b94acceSBarry Smith /*@C 4703f6dfbefdSBarry Smith SNESGetType - Gets the `SNES` method type and name (as a string). 47049b94acceSBarry Smith 4705c7afd0dbSLois Curfman McInnes Not Collective 4706c7afd0dbSLois Curfman McInnes 47079b94acceSBarry Smith Input Parameter: 47084b0e389bSBarry Smith . snes - nonlinear solver context 47099b94acceSBarry Smith 47109b94acceSBarry Smith Output Parameter: 4711f6dfbefdSBarry Smith . type - `SNES` method (a character string) 47129b94acceSBarry Smith 471336851e7fSLois Curfman McInnes Level: intermediate 471436851e7fSLois Curfman McInnes 4715f6dfbefdSBarry Smith .seealso: `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES` 47169b94acceSBarry Smith @*/ 47179371c9d4SSatish Balay PetscErrorCode SNESGetType(SNES snes, SNESType *type) { 47183a40ed3dSBarry Smith PetscFunctionBegin; 47190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47204482741eSBarry Smith PetscValidPointer(type, 2); 47217adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 47223a40ed3dSBarry Smith PetscFunctionReturn(0); 47239b94acceSBarry Smith } 47249b94acceSBarry Smith 47253cd8a7caSMatthew G. Knepley /*@ 4726f6dfbefdSBarry Smith SNESSetSolution - Sets the solution vector for use by the `SNES` routines. 47273cd8a7caSMatthew G. Knepley 4728f6dfbefdSBarry Smith Logically Collective on snes 47293cd8a7caSMatthew G. Knepley 47303cd8a7caSMatthew G. Knepley Input Parameters: 4731f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()` 47323cd8a7caSMatthew G. Knepley - u - the solution vector 47333cd8a7caSMatthew G. Knepley 47343cd8a7caSMatthew G. Knepley Level: beginner 47353cd8a7caSMatthew G. Knepley 4736f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec` 47373cd8a7caSMatthew G. Knepley @*/ 47389371c9d4SSatish Balay PetscErrorCode SNESSetSolution(SNES snes, Vec u) { 47393cd8a7caSMatthew G. Knepley DM dm; 47403cd8a7caSMatthew G. Knepley 47413cd8a7caSMatthew G. Knepley PetscFunctionBegin; 47423cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47433cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 47449566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 47459566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 47463cd8a7caSMatthew G. Knepley 47473cd8a7caSMatthew G. Knepley snes->vec_sol = u; 47483cd8a7caSMatthew G. Knepley 47499566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 47509566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 47513cd8a7caSMatthew G. Knepley PetscFunctionReturn(0); 47523cd8a7caSMatthew G. Knepley } 47533cd8a7caSMatthew G. Knepley 475452baeb72SSatish Balay /*@ 47559b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4756f6dfbefdSBarry Smith stored. This is the fine grid solution when using `SNESSetGridSequence()`. 47579b94acceSBarry Smith 4758f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4759c7afd0dbSLois Curfman McInnes 47609b94acceSBarry Smith Input Parameter: 4761f6dfbefdSBarry Smith . snes - the `SNES` context 47629b94acceSBarry Smith 47639b94acceSBarry Smith Output Parameter: 47649b94acceSBarry Smith . x - the solution 47659b94acceSBarry Smith 476670e92668SMatthew Knepley Level: intermediate 476736851e7fSLois Curfman McInnes 4768f6dfbefdSBarry Smith .seealso: `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()` 47699b94acceSBarry Smith @*/ 47709371c9d4SSatish Balay PetscErrorCode SNESGetSolution(SNES snes, Vec *x) { 47713a40ed3dSBarry Smith PetscFunctionBegin; 47720700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47734482741eSBarry Smith PetscValidPointer(x, 2); 477485385478SLisandro Dalcin *x = snes->vec_sol; 477570e92668SMatthew Knepley PetscFunctionReturn(0); 477670e92668SMatthew Knepley } 477770e92668SMatthew Knepley 477852baeb72SSatish Balay /*@ 47799b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 47809b94acceSBarry Smith stored. 47819b94acceSBarry Smith 4782f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4783c7afd0dbSLois Curfman McInnes 47849b94acceSBarry Smith Input Parameter: 4785f6dfbefdSBarry Smith . snes - the `SNES` context 47869b94acceSBarry Smith 47879b94acceSBarry Smith Output Parameter: 47889b94acceSBarry Smith . x - the solution update 47899b94acceSBarry Smith 479036851e7fSLois Curfman McInnes Level: advanced 479136851e7fSLois Curfman McInnes 4792f6dfbefdSBarry Smith .seealso: `SNES`, `SNESGetSolution()`, `SNESGetFunction()` 47939b94acceSBarry Smith @*/ 47949371c9d4SSatish Balay PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x) { 47953a40ed3dSBarry Smith PetscFunctionBegin; 47960700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47974482741eSBarry Smith PetscValidPointer(x, 2); 479885385478SLisandro Dalcin *x = snes->vec_sol_update; 47993a40ed3dSBarry Smith PetscFunctionReturn(0); 48009b94acceSBarry Smith } 48019b94acceSBarry Smith 48029b94acceSBarry Smith /*@C 4803f6dfbefdSBarry Smith SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()` 48049b94acceSBarry Smith 4805f6dfbefdSBarry Smith Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet. 4806c7afd0dbSLois Curfman McInnes 48079b94acceSBarry Smith Input Parameter: 4808f6dfbefdSBarry Smith . snes - the `SNES` context 48099b94acceSBarry Smith 4810d8d19677SJose E. Roman Output Parameters: 48110298fd71SBarry Smith + r - the vector that is used to store residuals (or NULL if you don't want it) 4812f6dfbefdSBarry Smith . f - the function (or NULL if you don't want it); see `SNESFunction` for calling sequence details 48130298fd71SBarry Smith - ctx - the function context (or NULL if you don't want it) 48149b94acceSBarry Smith 481536851e7fSLois Curfman McInnes Level: advanced 481636851e7fSLois Curfman McInnes 4817f6dfbefdSBarry Smith Note: 4818f6dfbefdSBarry Smith The vector r DOES NOT, in general, contain the current value of the `SNES` nonlinear function 481904edfde5SBarry Smith 4820f6dfbefdSBarry Smith .seealso: `SNES, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 48219b94acceSBarry Smith @*/ 48229371c9d4SSatish Balay PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) { 48236cab3a1bSJed Brown DM dm; 4824a63bb30eSJed Brown 48253a40ed3dSBarry Smith PetscFunctionBegin; 48260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4827a63bb30eSJed Brown if (r) { 4828a63bb30eSJed Brown if (!snes->vec_func) { 4829a63bb30eSJed Brown if (snes->vec_rhs) { 48309566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4831a63bb30eSJed Brown } else if (snes->vec_sol) { 48329566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4833a63bb30eSJed Brown } else if (snes->dm) { 48349566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4835a63bb30eSJed Brown } 4836a63bb30eSJed Brown } 4837a63bb30eSJed Brown *r = snes->vec_func; 4838a63bb30eSJed Brown } 48399566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48409566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 48413a40ed3dSBarry Smith PetscFunctionReturn(0); 48429b94acceSBarry Smith } 48439b94acceSBarry Smith 4844c79ef259SPeter Brune /*@C 4845f6dfbefdSBarry Smith SNESGetNGS - Returns the `SNESNGS` function and context set with `SNESSetNGS()` 4846c79ef259SPeter Brune 4847c79ef259SPeter Brune Input Parameter: 4848f6dfbefdSBarry Smith . snes - the `SNES` context 4849c79ef259SPeter Brune 4850d8d19677SJose E. Roman Output Parameters: 4851f6dfbefdSBarry Smith + f - the function (or NULL) see `SNESNGSFunction` for details 48520298fd71SBarry Smith - ctx - the function context (or NULL) 4853c79ef259SPeter Brune 4854c79ef259SPeter Brune Level: advanced 4855c79ef259SPeter Brune 4856db781477SPatrick Sanan .seealso: `SNESSetNGS()`, `SNESGetFunction()` 4857c79ef259SPeter Brune @*/ 4858c79ef259SPeter Brune 48599371c9d4SSatish Balay PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) { 48606cab3a1bSJed Brown DM dm; 48616cab3a1bSJed Brown 4862646217ecSPeter Brune PetscFunctionBegin; 4863646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48649566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48659566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 4866646217ecSPeter Brune PetscFunctionReturn(0); 4867646217ecSPeter Brune } 4868646217ecSPeter Brune 48693c7409f5SSatish Balay /*@C 48703c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4871f6dfbefdSBarry Smith `SNES` options in the database. 48723c7409f5SSatish Balay 4873f6dfbefdSBarry Smith Logically Collective on snes 4874fee21e36SBarry Smith 4875d8d19677SJose E. Roman Input Parameters: 4876f6dfbefdSBarry Smith + snes - the `SNES` context 4877c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4878c7afd0dbSLois Curfman McInnes 4879f6dfbefdSBarry Smith Note: 4880a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4881c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4882d850072dSLois Curfman McInnes 488336851e7fSLois Curfman McInnes Level: advanced 488436851e7fSLois Curfman McInnes 4885f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()` 48863c7409f5SSatish Balay @*/ 48879371c9d4SSatish Balay PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) { 48883a40ed3dSBarry Smith PetscFunctionBegin; 48890700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48909566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 48919566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 489235f5d045SPeter Brune if (snes->linesearch) { 48939566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 48949566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 489535f5d045SPeter Brune } 48969566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 48973a40ed3dSBarry Smith PetscFunctionReturn(0); 48983c7409f5SSatish Balay } 48993c7409f5SSatish Balay 49003c7409f5SSatish Balay /*@C 4901f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4902f6dfbefdSBarry Smith `SNES` options in the database. 49033c7409f5SSatish Balay 4904f6dfbefdSBarry Smith Logically Collective on snes 4905fee21e36SBarry Smith 4906c7afd0dbSLois Curfman McInnes Input Parameters: 4907f6dfbefdSBarry Smith + snes - the `SNES` context 4908c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4909c7afd0dbSLois Curfman McInnes 4910f6dfbefdSBarry Smith Note: 4911a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4912c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4913d850072dSLois Curfman McInnes 491436851e7fSLois Curfman McInnes Level: advanced 491536851e7fSLois Curfman McInnes 4916f6dfbefdSBarry Smith .seealso: `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()` 49173c7409f5SSatish Balay @*/ 49189371c9d4SSatish Balay PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) { 49193a40ed3dSBarry Smith PetscFunctionBegin; 49200700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49219566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 49229566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 492335f5d045SPeter Brune if (snes->linesearch) { 49249566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 49259566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 492635f5d045SPeter Brune } 49279566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 49283a40ed3dSBarry Smith PetscFunctionReturn(0); 49293c7409f5SSatish Balay } 49303c7409f5SSatish Balay 49319ab63eb5SSatish Balay /*@C 4932f6dfbefdSBarry Smith SNESGetOptionsPrefix - Gets the prefix used for searching for all 4933f6dfbefdSBarry Smith `SNES` options in the database. 49343c7409f5SSatish Balay 4935c7afd0dbSLois Curfman McInnes Not Collective 4936c7afd0dbSLois Curfman McInnes 49373c7409f5SSatish Balay Input Parameter: 4938f6dfbefdSBarry Smith . snes - the `SNES` context 49393c7409f5SSatish Balay 49403c7409f5SSatish Balay Output Parameter: 49413c7409f5SSatish Balay . prefix - pointer to the prefix string used 49423c7409f5SSatish Balay 4943f6dfbefdSBarry Smith Fortran Note: 494495452b02SPatrick Sanan On the fortran side, the user should pass in a string 'prefix' of 49459ab63eb5SSatish Balay sufficient length to hold the prefix. 49469ab63eb5SSatish Balay 494736851e7fSLois Curfman McInnes Level: advanced 494836851e7fSLois Curfman McInnes 4949f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()` 49503c7409f5SSatish Balay @*/ 49519371c9d4SSatish Balay PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) { 49523a40ed3dSBarry Smith PetscFunctionBegin; 49530700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49549566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 49553a40ed3dSBarry Smith PetscFunctionReturn(0); 49563c7409f5SSatish Balay } 49573c7409f5SSatish Balay 49583cea93caSBarry Smith /*@C 49591c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 49601c84c290SBarry Smith 49611c84c290SBarry Smith Not collective 49621c84c290SBarry Smith 49631c84c290SBarry Smith Input Parameters: 49641c84c290SBarry Smith + name_solver - name of a new user-defined solver 49651c84c290SBarry Smith - routine_create - routine to create method context 49661c84c290SBarry Smith 4967f6dfbefdSBarry Smith Note: 4968f6dfbefdSBarry Smith `SNESRegister()` may be called multiple times to add several user-defined solvers. 49691c84c290SBarry Smith 49701c84c290SBarry Smith Sample usage: 49711c84c290SBarry Smith .vb 4972bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 49731c84c290SBarry Smith .ve 49741c84c290SBarry Smith 49751c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 49761c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 49771c84c290SBarry Smith or at runtime via the option 49781c84c290SBarry Smith $ -snes_type my_solver 49791c84c290SBarry Smith 49801c84c290SBarry Smith Level: advanced 49811c84c290SBarry Smith 4982db781477SPatrick Sanan .seealso: `SNESRegisterAll()`, `SNESRegisterDestroy()` 49833cea93caSBarry Smith @*/ 49849371c9d4SSatish Balay PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) { 4985b2002411SLois Curfman McInnes PetscFunctionBegin; 49869566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 49879566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 4988b2002411SLois Curfman McInnes PetscFunctionReturn(0); 4989b2002411SLois Curfman McInnes } 4990da9b6338SBarry Smith 49919371c9d4SSatish Balay PetscErrorCode SNESTestLocalMin(SNES snes) { 499277431f27SBarry Smith PetscInt N, i, j; 4993da9b6338SBarry Smith Vec u, uh, fh; 4994da9b6338SBarry Smith PetscScalar value; 4995da9b6338SBarry Smith PetscReal norm; 4996da9b6338SBarry Smith 4997da9b6338SBarry Smith PetscFunctionBegin; 49989566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 49999566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 50009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 5001da9b6338SBarry Smith 5002da9b6338SBarry Smith /* currently only works for sequential */ 50039566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 50049566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5005da9b6338SBarry Smith for (i = 0; i < N; i++) { 50069566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 500763a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5008da9b6338SBarry Smith for (j = -10; j < 11; j++) { 50098b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 50109566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 50119566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 50129566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 501363a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5014da9b6338SBarry Smith value = -value; 50159566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5016da9b6338SBarry Smith } 5017da9b6338SBarry Smith } 50189566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 50199566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 5020da9b6338SBarry Smith PetscFunctionReturn(0); 5021da9b6338SBarry Smith } 502271f87433Sdalcinl 502371f87433Sdalcinl /*@ 5024f6dfbefdSBarry Smith SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for 502571f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 502671f87433Sdalcinl Newton method. 502771f87433Sdalcinl 5028f6dfbefdSBarry Smith Logically Collective on snes 502971f87433Sdalcinl 503071f87433Sdalcinl Input Parameters: 5031f6dfbefdSBarry Smith + snes - `SNES` context 5032f6dfbefdSBarry Smith - flag - `PETSC_TRUE` or `PETSC_FALSE` 503371f87433Sdalcinl 5034f6dfbefdSBarry Smith Options Database Keys: 503564ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 503664ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 503764ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 503864ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 503964ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 504064ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 504164ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 504264ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 504364ba62caSBarry Smith 5044f6dfbefdSBarry Smith Note: 5045f6dfbefdSBarry Smith The default is to use a constant relative tolerance for 504671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 504771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 504871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 504971f87433Sdalcinl solver. 505071f87433Sdalcinl 505171f87433Sdalcinl Level: advanced 505271f87433Sdalcinl 505371f87433Sdalcinl Reference: 5054f6dfbefdSBarry Smith . - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996. 505571f87433Sdalcinl 5056f6dfbefdSBarry Smith .seealso: `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 505771f87433Sdalcinl @*/ 50589371c9d4SSatish Balay PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) { 505971f87433Sdalcinl PetscFunctionBegin; 50600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5061acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 506271f87433Sdalcinl snes->ksp_ewconv = flag; 506371f87433Sdalcinl PetscFunctionReturn(0); 506471f87433Sdalcinl } 506571f87433Sdalcinl 506671f87433Sdalcinl /*@ 5067f6dfbefdSBarry Smith SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method 506871f87433Sdalcinl for computing relative tolerance for linear solvers within an 506971f87433Sdalcinl inexact Newton method. 507071f87433Sdalcinl 507171f87433Sdalcinl Not Collective 507271f87433Sdalcinl 507371f87433Sdalcinl Input Parameter: 5074f6dfbefdSBarry Smith . snes - `SNES` context 507571f87433Sdalcinl 507671f87433Sdalcinl Output Parameter: 5077f6dfbefdSBarry Smith . flag - `PETSC_TRUE` or `PETSC_FALSE` 507871f87433Sdalcinl 507971f87433Sdalcinl Level: advanced 508071f87433Sdalcinl 5081db781477SPatrick Sanan .seealso: `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 508271f87433Sdalcinl @*/ 50839371c9d4SSatish Balay PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) { 508471f87433Sdalcinl PetscFunctionBegin; 50850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5086534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 508771f87433Sdalcinl *flag = snes->ksp_ewconv; 508871f87433Sdalcinl PetscFunctionReturn(0); 508971f87433Sdalcinl } 509071f87433Sdalcinl 509171f87433Sdalcinl /*@ 5092fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 509371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 509471f87433Sdalcinl Newton method. 509571f87433Sdalcinl 5096f6dfbefdSBarry Smith Logically Collective on snes 509771f87433Sdalcinl 509871f87433Sdalcinl Input Parameters: 5099f6dfbefdSBarry Smith + snes - `SNES` context 51000f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 510171f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 510271f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 510371f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 510471f87433Sdalcinl (0 <= gamma2 <= 1) 510571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 510671f87433Sdalcinl . alpha2 - power for safeguard 510771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 510871f87433Sdalcinl 5109f6dfbefdSBarry Smith Notes: 511071f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 511171f87433Sdalcinl 5112f6dfbefdSBarry Smith Use `PETSC_DEFAULT` to retain the default for any of the parameters. 511371f87433Sdalcinl 511471f87433Sdalcinl Level: advanced 511571f87433Sdalcinl 5116f6dfbefdSBarry Smith .seealso: `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 511771f87433Sdalcinl @*/ 51189371c9d4SSatish Balay PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) { 5119fa9f3622SBarry Smith SNESKSPEW *kctx; 51205fd66863SKarl Rupp 512171f87433Sdalcinl PetscFunctionBegin; 51220700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5123fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 51245f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5125c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5126c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5127c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5128c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5129c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5130c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5131c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 513271f87433Sdalcinl 513371f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 513471f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 513571f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 513671f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 513771f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 513871f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 513971f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 514071f87433Sdalcinl 51410f0abf79SStefano 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); 51420b121fc5SBarry 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); 51430b121fc5SBarry 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); 51440b121fc5SBarry 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); 51450b121fc5SBarry 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); 51460b121fc5SBarry 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); 514771f87433Sdalcinl PetscFunctionReturn(0); 514871f87433Sdalcinl } 514971f87433Sdalcinl 515071f87433Sdalcinl /*@ 5151fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 515271f87433Sdalcinl convergence criteria for the linear solvers within an inexact 515371f87433Sdalcinl Newton method. 515471f87433Sdalcinl 515571f87433Sdalcinl Not Collective 515671f87433Sdalcinl 515797bb3fdcSJose E. Roman Input Parameter: 5158f6dfbefdSBarry Smith . snes - `SNES` context 515971f87433Sdalcinl 516071f87433Sdalcinl Output Parameters: 51610f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 516271f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 516371f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5164bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 516571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 516671f87433Sdalcinl . alpha2 - power for safeguard 516771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 516871f87433Sdalcinl 516971f87433Sdalcinl Level: advanced 517071f87433Sdalcinl 5171f6dfbefdSBarry Smith .seealso: `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 517271f87433Sdalcinl @*/ 51739371c9d4SSatish Balay PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) { 5174fa9f3622SBarry Smith SNESKSPEW *kctx; 51755fd66863SKarl Rupp 517671f87433Sdalcinl PetscFunctionBegin; 51770700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5178fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 51795f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 518071f87433Sdalcinl if (version) *version = kctx->version; 518171f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 518271f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 518371f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 518471f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 518571f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 518671f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 518771f87433Sdalcinl PetscFunctionReturn(0); 518871f87433Sdalcinl } 518971f87433Sdalcinl 51909371c9d4SSatish Balay PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) { 5191fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 519271f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 519371f87433Sdalcinl 519471f87433Sdalcinl PetscFunctionBegin; 5195d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 519630058271SDmitry Karpeev if (!snes->iter) { 519730058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 51989566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 51990f0abf79SStefano Zampini } else { 520071f87433Sdalcinl if (kctx->version == 1) { 52010f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 520285ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 520371f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 520471f87433Sdalcinl } else if (kctx->version == 2) { 520585ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 520685ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 520771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 520871f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 520985ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 521071f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 521185ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 521271f87433Sdalcinl stol = PetscMax(rtol, stol); 521371f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 521471f87433Sdalcinl /* safeguard: avoid oversolving */ 521530058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 521671f87433Sdalcinl stol = PetscMax(rtol, stol); 521771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 52180f0abf79SStefano Zampini } else if (kctx->version == 4) { /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 52190f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 52200f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 52210f0abf79SStefano Zampini PetscReal rk = ared / pred; 52220f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 52230f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 52240f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 52250f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 52260f0abf79SStefano Zampini 52279371c9d4SSatish 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) { 52280f0abf79SStefano Zampini rtol = kctx->v4_m4 * kctx->rtol_last; 52290f0abf79SStefano 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); 52300f0abf79SStefano Zampini } else { 52310f0abf79SStefano 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); 523271f87433Sdalcinl } 52330f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 52340f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 52350f0abf79SStefano Zampini kctx->rk_last = rk; 52360f0abf79SStefano Zampini } else SETERRQ(PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version); 52370f0abf79SStefano Zampini } 52380f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 523971f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 52409566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 524163a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 524271f87433Sdalcinl PetscFunctionReturn(0); 524371f87433Sdalcinl } 524471f87433Sdalcinl 52459371c9d4SSatish Balay PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) { 5246fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 524771f87433Sdalcinl PCSide pcside; 524871f87433Sdalcinl Vec lres; 524971f87433Sdalcinl 525071f87433Sdalcinl PetscFunctionBegin; 5251d4211eb9SBarry Smith if (!snes->ksp_ewconv) PetscFunctionReturn(0); 52529566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 525371dbe336SPeter Brune kctx->norm_last = snes->norm; 52540f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 52554f00ce20SMatthew G. Knepley PC pc; 52560f0abf79SStefano Zampini PetscBool getRes; 52574f00ce20SMatthew G. Knepley 52589566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 52590f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 52600f0abf79SStefano Zampini if (!getRes) { 52610f0abf79SStefano Zampini KSPNormType normtype; 52620f0abf79SStefano Zampini 52630f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 52640f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 52650f0abf79SStefano Zampini } 52669566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 52670f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 52689566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 526971f87433Sdalcinl } else { 527071f87433Sdalcinl /* KSP residual is preconditioned residual */ 527171f87433Sdalcinl /* compute true linear residual norm */ 52720f0abf79SStefano Zampini Mat J; 52730f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 52749566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 52750f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 52769566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 52779566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 52789566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 527971f87433Sdalcinl } 528071f87433Sdalcinl } 528171f87433Sdalcinl PetscFunctionReturn(0); 528271f87433Sdalcinl } 528371f87433Sdalcinl 5284d4211eb9SBarry Smith /*@ 5285f6dfbefdSBarry Smith SNESGetKSP - Returns the `KSP` context for a `SNES` solver. 5286d4211eb9SBarry Smith 5287f6dfbefdSBarry Smith Not Collective, but if snes is parallel, then ksp is parallel 5288d4211eb9SBarry Smith 5289d4211eb9SBarry Smith Input Parameter: 5290f6dfbefdSBarry Smith . snes - the `SNES` context 5291d4211eb9SBarry Smith 5292d4211eb9SBarry Smith Output Parameter: 5293f6dfbefdSBarry Smith . ksp - the `KSP` context 5294d4211eb9SBarry Smith 5295d4211eb9SBarry Smith Notes: 5296f6dfbefdSBarry Smith The user can then directly manipulate the `KSP` context to set various 5297d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5298f6dfbefdSBarry Smith `PC` contexts as well. 5299f6dfbefdSBarry Smith 5300f6dfbefdSBarry Smith Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function 5301d4211eb9SBarry Smith 5302d4211eb9SBarry Smith Level: beginner 5303d4211eb9SBarry Smith 5304f6dfbefdSBarry Smith .seealso: `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5305d4211eb9SBarry Smith @*/ 53069371c9d4SSatish Balay PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) { 530771f87433Sdalcinl PetscFunctionBegin; 5308d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5309d4211eb9SBarry Smith PetscValidPointer(ksp, 2); 5310d4211eb9SBarry Smith 5311d4211eb9SBarry Smith if (!snes->ksp) { 53129566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 53139566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 53149566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->ksp)); 5315d4211eb9SBarry Smith 53169566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 53179566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5318a5c2985bSBarry Smith 53199566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 53209566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5321d4211eb9SBarry Smith } 5322d4211eb9SBarry Smith *ksp = snes->ksp; 532371f87433Sdalcinl PetscFunctionReturn(0); 532471f87433Sdalcinl } 53256c699258SBarry Smith 5326af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 53276c699258SBarry Smith /*@ 5328f6dfbefdSBarry Smith SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners 53296c699258SBarry Smith 5330f6dfbefdSBarry Smith Logically Collective on snes 53316c699258SBarry Smith 53326c699258SBarry Smith Input Parameters: 53332a808120SBarry Smith + snes - the nonlinear solver context 53342a808120SBarry Smith - dm - the dm, cannot be NULL 53356c699258SBarry Smith 5336f6dfbefdSBarry Smith Note: 5337f6dfbefdSBarry Smith A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, 5338f6dfbefdSBarry Smith even when not using interfaces like `DMSNESSetFunction()`. Use `DMClone()` to get a distinct `DM` when solving different 5339e03a659cSJed Brown problems using the same function space. 5340e03a659cSJed Brown 53416c699258SBarry Smith Level: intermediate 53426c699258SBarry Smith 5343f6dfbefdSBarry Smith .seealso: `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 53446c699258SBarry Smith @*/ 53459371c9d4SSatish Balay PetscErrorCode SNESSetDM(SNES snes, DM dm) { 5346345fed2cSBarry Smith KSP ksp; 5347942e3340SBarry Smith DMSNES sdm; 53486c699258SBarry Smith 53496c699258SBarry Smith PetscFunctionBegin; 53500700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 53512a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 53529566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5353942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 535451f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 53559566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 53569566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5357f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 53586cab3a1bSJed Brown } 53599566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 53609566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 53616cab3a1bSJed Brown } 53626c699258SBarry Smith snes->dm = dm; 5363116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5364f5af7f23SKarl Rupp 53659566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 53669566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 53679566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5368efd4aadfSBarry Smith if (snes->npc) { 53699566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 53709566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 53712c155ee1SBarry Smith } 53726c699258SBarry Smith PetscFunctionReturn(0); 53736c699258SBarry Smith } 53746c699258SBarry Smith 53756c699258SBarry Smith /*@ 5376f6dfbefdSBarry Smith SNESGetDM - Gets the `DM` that may be used by some preconditioners 53776c699258SBarry Smith 5378f6dfbefdSBarry Smith Not Collective but dm obtained is parallel on snes 53796c699258SBarry Smith 53806c699258SBarry Smith Input Parameter: 53816c699258SBarry Smith . snes - the preconditioner context 53826c699258SBarry Smith 53836c699258SBarry Smith Output Parameter: 53846c699258SBarry Smith . dm - the dm 53856c699258SBarry Smith 53866c699258SBarry Smith Level: intermediate 53876c699258SBarry Smith 5388f6dfbefdSBarry Smith .seealso: `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 53896c699258SBarry Smith @*/ 53909371c9d4SSatish Balay PetscErrorCode SNESGetDM(SNES snes, DM *dm) { 53916c699258SBarry Smith PetscFunctionBegin; 53920700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 53936cab3a1bSJed Brown if (!snes->dm) { 53949566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5395116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 53966cab3a1bSJed Brown } 53976c699258SBarry Smith *dm = snes->dm; 53986c699258SBarry Smith PetscFunctionReturn(0); 53996c699258SBarry Smith } 54000807856dSBarry Smith 540131823bd8SMatthew G Knepley /*@ 5402be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 540331823bd8SMatthew G Knepley 5404f6dfbefdSBarry Smith Collective on snes 540531823bd8SMatthew G Knepley 540631823bd8SMatthew G Knepley Input Parameters: 5407f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 5408f6dfbefdSBarry Smith - npc - the preconditioner object 540931823bd8SMatthew G Knepley 541031823bd8SMatthew G Knepley Notes: 5411f6dfbefdSBarry Smith Use `SNESGetNPC()` to retrieve the preconditioner context (for example, 541231823bd8SMatthew G Knepley to configure it using the API). 541331823bd8SMatthew G Knepley 5414f6dfbefdSBarry Smith Only some `SNESType` can use a nonlinear preconditioner 5415f6dfbefdSBarry Smith 541631823bd8SMatthew G Knepley Level: developer 541731823bd8SMatthew G Knepley 5418f6dfbefdSBarry Smith .seealso: `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()` 541931823bd8SMatthew G Knepley @*/ 5420f6dfbefdSBarry Smith PetscErrorCode SNESSetNPC(SNES snes, SNES npc) { 542131823bd8SMatthew G Knepley PetscFunctionBegin; 542231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5423f6dfbefdSBarry Smith PetscValidHeaderSpecific(npc, SNES_CLASSID, 2); 5424f6dfbefdSBarry Smith PetscCheckSameComm(snes, 1, npc, 2); 5425f6dfbefdSBarry Smith PetscCall(PetscObjectReference((PetscObject)npc)); 54269566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5427f6dfbefdSBarry Smith snes->npc = npc; 54289566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 542931823bd8SMatthew G Knepley PetscFunctionReturn(0); 543031823bd8SMatthew G Knepley } 543131823bd8SMatthew G Knepley 543231823bd8SMatthew G Knepley /*@ 5433f6dfbefdSBarry Smith SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver. 543431823bd8SMatthew G Knepley 5435f6dfbefdSBarry Smith Not Collective; but any changes to the obtained the npc object must be applied collectively 543631823bd8SMatthew G Knepley 543731823bd8SMatthew G Knepley Input Parameter: 5438f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 543931823bd8SMatthew G Knepley 544031823bd8SMatthew G Knepley Output Parameter: 5441f6dfbefdSBarry Smith . npc - preconditioner context 544231823bd8SMatthew G Knepley 5443f6dfbefdSBarry Smith Options Database Key: 5444f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner 5445b5badacbSBarry Smith 544695452b02SPatrick Sanan Notes: 5447f6dfbefdSBarry Smith If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created. 5448be95d8f1SBarry Smith 5449f6dfbefdSBarry Smith The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5450f6dfbefdSBarry Smith `SNES` 5451951fe5abSBarry Smith 545231823bd8SMatthew G Knepley Level: developer 545331823bd8SMatthew G Knepley 5454db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 545531823bd8SMatthew G Knepley @*/ 54569371c9d4SSatish Balay PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) { 5457a64e098fSPeter Brune const char *optionsprefix; 545831823bd8SMatthew G Knepley 545931823bd8SMatthew G Knepley PetscFunctionBegin; 546031823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 546131823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5462efd4aadfSBarry Smith if (!snes->npc) { 54639566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 54649566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 54659566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->npc)); 54669566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 54679566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 54689566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 54699566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 547031823bd8SMatthew G Knepley } 5471efd4aadfSBarry Smith *pc = snes->npc; 547231823bd8SMatthew G Knepley PetscFunctionReturn(0); 547331823bd8SMatthew G Knepley } 547431823bd8SMatthew G Knepley 54753ad1a0b9SPatrick Farrell /*@ 54763ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 54773ad1a0b9SPatrick Farrell 54783ad1a0b9SPatrick Farrell Not Collective 54793ad1a0b9SPatrick Farrell 54803ad1a0b9SPatrick Farrell Input Parameter: 5481f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 54823ad1a0b9SPatrick Farrell 54833ad1a0b9SPatrick Farrell Output Parameter: 5484f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not 54853ad1a0b9SPatrick Farrell 54863ad1a0b9SPatrick Farrell Level: developer 54873ad1a0b9SPatrick Farrell 5488db781477SPatrick Sanan .seealso: `SNESSetNPC()`, `SNESGetNPC()` 54893ad1a0b9SPatrick Farrell @*/ 54909371c9d4SSatish Balay PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) { 54913ad1a0b9SPatrick Farrell PetscFunctionBegin; 54923ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5493efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 54943ad1a0b9SPatrick Farrell PetscFunctionReturn(0); 54953ad1a0b9SPatrick Farrell } 54963ad1a0b9SPatrick Farrell 5497c40d0f55SPeter Brune /*@ 5498be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5499c40d0f55SPeter Brune 5500f6dfbefdSBarry Smith Logically Collective on snes 5501c40d0f55SPeter Brune 5502c40d0f55SPeter Brune Input Parameter: 5503f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5504c40d0f55SPeter Brune 5505c40d0f55SPeter Brune Output Parameter: 5506c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5507c40d0f55SPeter Brune .vb 55082d547940SBarry Smith PC_LEFT - left preconditioning 55092d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5510c40d0f55SPeter Brune .ve 5511c40d0f55SPeter Brune 5512f6dfbefdSBarry Smith Options Database Key: 551367b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5514c40d0f55SPeter Brune 5515f6dfbefdSBarry Smith Note: 5516f6dfbefdSBarry Smith `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning. 55172d547940SBarry Smith 5518c40d0f55SPeter Brune Level: intermediate 5519c40d0f55SPeter Brune 5520f6dfbefdSBarry Smith .seealso: `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()` 5521c40d0f55SPeter Brune @*/ 55229371c9d4SSatish Balay PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) { 5523c40d0f55SPeter Brune PetscFunctionBegin; 5524c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5525c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5526b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 552754c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5528efd4aadfSBarry Smith snes->npcside = side; 5529c40d0f55SPeter Brune PetscFunctionReturn(0); 5530c40d0f55SPeter Brune } 5531c40d0f55SPeter Brune 5532c40d0f55SPeter Brune /*@ 5533be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5534c40d0f55SPeter Brune 5535c40d0f55SPeter Brune Not Collective 5536c40d0f55SPeter Brune 5537c40d0f55SPeter Brune Input Parameter: 5538f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5539c40d0f55SPeter Brune 5540c40d0f55SPeter Brune Output Parameter: 5541c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5542c40d0f55SPeter Brune .vb 5543f6dfbefdSBarry Smith `PC_LEFT` - left preconditioning 5544f6dfbefdSBarry Smith `PC_RIGHT` - right preconditioning (default for most nonlinear solvers) 5545c40d0f55SPeter Brune .ve 5546c40d0f55SPeter Brune 5547c40d0f55SPeter Brune Level: intermediate 5548c40d0f55SPeter Brune 5549f6dfbefdSBarry Smith .seealso: `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()` 5550c40d0f55SPeter Brune @*/ 55519371c9d4SSatish Balay PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) { 5552c40d0f55SPeter Brune PetscFunctionBegin; 5553c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5554c40d0f55SPeter Brune PetscValidPointer(side, 2); 5555efd4aadfSBarry Smith *side = snes->npcside; 5556c40d0f55SPeter Brune PetscFunctionReturn(0); 5557c40d0f55SPeter Brune } 5558c40d0f55SPeter Brune 55599e764e56SPeter Brune /*@ 5560f6dfbefdSBarry Smith SNESSetLineSearch - Sets the linesearch on the `SNES` instance. 55619e764e56SPeter Brune 5562f6dfbefdSBarry Smith Collective on snes 55639e764e56SPeter Brune 55649e764e56SPeter Brune Input Parameters: 5565f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 55669e764e56SPeter Brune - linesearch - the linesearch object 55679e764e56SPeter Brune 5568f6dfbefdSBarry Smith Note: 5569f6dfbefdSBarry Smith Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example, 55709e764e56SPeter Brune to configure it using the API). 55719e764e56SPeter Brune 55729e764e56SPeter Brune Level: developer 55739e764e56SPeter Brune 5574db781477SPatrick Sanan .seealso: `SNESGetLineSearch()` 55759e764e56SPeter Brune @*/ 55769371c9d4SSatish Balay PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) { 55779e764e56SPeter Brune PetscFunctionBegin; 55789e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5579f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 55809e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 55819566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 55829566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5583f5af7f23SKarl Rupp 55849e764e56SPeter Brune snes->linesearch = linesearch; 5585f5af7f23SKarl Rupp 55869566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 55879e764e56SPeter Brune PetscFunctionReturn(0); 55889e764e56SPeter Brune } 55899e764e56SPeter Brune 5590a34ceb2aSJed Brown /*@ 5591f6dfbefdSBarry Smith SNESGetLineSearch - Returns a pointer to the line search context set with `SNESSetLineSearch()` 5592f6dfbefdSBarry Smith or creates a default line search instance associated with the `SNES` and returns it. 55939e764e56SPeter Brune 55949e764e56SPeter Brune Not Collective 55959e764e56SPeter Brune 55969e764e56SPeter Brune Input Parameter: 5597f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 55989e764e56SPeter Brune 55999e764e56SPeter Brune Output Parameter: 56009e764e56SPeter Brune . linesearch - linesearch context 56019e764e56SPeter Brune 5602162e0bf5SPeter Brune Level: beginner 56039e764e56SPeter Brune 5604f6dfbefdSBarry Smith .seealso: `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()` 56059e764e56SPeter Brune @*/ 56069371c9d4SSatish Balay PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) { 56079e764e56SPeter Brune const char *optionsprefix; 56089e764e56SPeter Brune 56099e764e56SPeter Brune PetscFunctionBegin; 56109e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 56119e764e56SPeter Brune PetscValidPointer(linesearch, 2); 56129e764e56SPeter Brune if (!snes->linesearch) { 56139566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 56149566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 56159566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 56169566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 56179566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 56189566063dSJacob Faibussowitsch PetscCall(PetscLogObjectParent((PetscObject)snes, (PetscObject)snes->linesearch)); 56199e764e56SPeter Brune } 56209e764e56SPeter Brune *linesearch = snes->linesearch; 56219e764e56SPeter Brune PetscFunctionReturn(0); 56229e764e56SPeter Brune } 5623