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; 13fc8bc0e3SRichard Tran Mills PetscLogEvent SNES_Solve, SNES_SetUp, SNES_FunctionEval, SNES_JacobianEval, SNES_NGSEval, SNES_NGSFuncEval, SNES_NPCSolve, SNES_ObjectiveEval; 14a09944afSBarry Smith 15e113a28aSBarry Smith /*@ 16*dc4c0fb0SBarry Smith SNESSetErrorIfNotConverged - Causes `SNESSolve()` to generate an error immediately if the solver has not converged. 17e113a28aSBarry Smith 18c3339decSBarry Smith Logically Collective 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 33*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 34e113a28aSBarry Smith @*/ 35d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetErrorIfNotConverged(SNES snes, PetscBool flg) 36d71ae5a4SJacob Faibussowitsch { 37e113a28aSBarry Smith PetscFunctionBegin; 38e113a28aSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 39acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flg, 2); 40e113a28aSBarry Smith snes->errorifnotconverged = flg; 413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 42e113a28aSBarry Smith } 43e113a28aSBarry Smith 44e113a28aSBarry Smith /*@ 45f6dfbefdSBarry Smith SNESGetErrorIfNotConverged - Indicates if `SNESSolve()` will generate an error if the solver does not converge? 46e113a28aSBarry Smith 47e113a28aSBarry Smith Not Collective 48e113a28aSBarry Smith 49e113a28aSBarry Smith Input Parameter: 50f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 51e113a28aSBarry Smith 52e113a28aSBarry Smith Output Parameter: 53f6dfbefdSBarry Smith . flag - `PETSC_TRUE` if it will generate an error, else `PETSC_FALSE` 54e113a28aSBarry Smith 55e113a28aSBarry Smith Level: intermediate 56e113a28aSBarry Smith 57*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetErrorIfNotConverged()`, `KSPGetErrorIfNotConverged()`, `KSPSetErrorIfNotConverged()` 58e113a28aSBarry Smith @*/ 59d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetErrorIfNotConverged(SNES snes, PetscBool *flag) 60d71ae5a4SJacob Faibussowitsch { 61e113a28aSBarry Smith PetscFunctionBegin; 62e113a28aSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 63534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 64e113a28aSBarry Smith *flag = snes->errorifnotconverged; 653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66e113a28aSBarry Smith } 67e113a28aSBarry Smith 684fc747eaSLawrence Mitchell /*@ 69*dc4c0fb0SBarry Smith SNESSetAlwaysComputesFinalResidual - tells the `SNES` to always compute the residual (nonlinear function value) at the final solution 704fc747eaSLawrence Mitchell 71c3339decSBarry Smith Logically Collective 724fc747eaSLawrence Mitchell 734fc747eaSLawrence Mitchell Input Parameters: 74f6dfbefdSBarry Smith + snes - the shell `SNES` 75f6dfbefdSBarry Smith - flg - `PETSC_TRUE` to always compute the residual 764fc747eaSLawrence Mitchell 774fc747eaSLawrence Mitchell Level: advanced 784fc747eaSLawrence Mitchell 79f6dfbefdSBarry Smith Note: 80f6dfbefdSBarry Smith Some solvers (such as smoothers in a `SNESFAS`) do not need the residual computed at the final solution so skip computing it 81f6dfbefdSBarry Smith to save time. 82f6dfbefdSBarry Smith 83*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetAlwaysComputesFinalResidual()` 844fc747eaSLawrence Mitchell @*/ 85d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetAlwaysComputesFinalResidual(SNES snes, PetscBool flg) 86d71ae5a4SJacob Faibussowitsch { 874fc747eaSLawrence Mitchell PetscFunctionBegin; 884fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 894fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = flg; 903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 914fc747eaSLawrence Mitchell } 924fc747eaSLawrence Mitchell 934fc747eaSLawrence Mitchell /*@ 94f6dfbefdSBarry Smith SNESGetAlwaysComputesFinalResidual - checks if the `SNES` always computes the residual at the final solution 954fc747eaSLawrence Mitchell 96c3339decSBarry Smith Logically Collective 974fc747eaSLawrence Mitchell 984fc747eaSLawrence Mitchell Input Parameter: 99f6dfbefdSBarry Smith . snes - the `SNES` context 1004fc747eaSLawrence Mitchell 1014fc747eaSLawrence Mitchell Output Parameter: 102f6dfbefdSBarry Smith . flg - `PETSC_TRUE` if the residual is computed 1034fc747eaSLawrence Mitchell 1044fc747eaSLawrence Mitchell Level: advanced 1054fc747eaSLawrence Mitchell 106*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetAlwaysComputesFinalResidual()` 1074fc747eaSLawrence Mitchell @*/ 108d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetAlwaysComputesFinalResidual(SNES snes, PetscBool *flg) 109d71ae5a4SJacob Faibussowitsch { 1104fc747eaSLawrence Mitchell PetscFunctionBegin; 1114fc747eaSLawrence Mitchell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1124fc747eaSLawrence Mitchell *flg = snes->alwayscomputesfinalresidual; 1133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1144fc747eaSLawrence Mitchell } 1154fc747eaSLawrence Mitchell 116e725d27bSBarry Smith /*@ 117f6dfbefdSBarry Smith SNESSetFunctionDomainError - tells `SNES` that the input vector, a proposed new solution, to your function you provided to `SNESSetFunction()` is not 118f0b84518SBarry Smith in the functions domain. For example, a step with negative pressure. 1194936397dSBarry Smith 120c3339decSBarry Smith Logically Collective 1214936397dSBarry Smith 1224936397dSBarry Smith Input Parameters: 123f6dfbefdSBarry Smith . snes - the `SNES` context 1244936397dSBarry Smith 12528529972SSatish Balay Level: advanced 1264936397dSBarry Smith 127f0b84518SBarry Smith Note: 128f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 129f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 130f0b84518SBarry Smith 131*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESCreate()`, `SNESSetFunction()`, `SNESFunction`, `SNESSetJacobianDomainError()`, `SNESVISetVariableBounds()`, 132f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 1334936397dSBarry Smith @*/ 134d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionDomainError(SNES snes) 135d71ae5a4SJacob Faibussowitsch { 1364936397dSBarry Smith PetscFunctionBegin; 1370700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1385f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates input vector is not in the function domain"); 1394936397dSBarry Smith snes->domainerror = PETSC_TRUE; 1403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1414936397dSBarry Smith } 1424936397dSBarry Smith 1436a388c36SPeter Brune /*@ 144f6dfbefdSBarry Smith SNESSetJacobianDomainError - tells `SNES` that the function you provided to `SNESSetJacobian()` at the proposed step. For example there is a negative element transformation. 14507b62357SFande Kong 146c3339decSBarry Smith Logically Collective 14707b62357SFande Kong 14807b62357SFande Kong Input Parameters: 149f6dfbefdSBarry Smith . snes - the `SNES` context 15007b62357SFande Kong 15107b62357SFande Kong Level: advanced 15207b62357SFande Kong 153f0b84518SBarry Smith Note: 154f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 155f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 156f0b84518SBarry Smith 157*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESVISetVariableBounds()`, 158f0b84518SBarry Smith `SNESVISetComputeVariableBounds()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 15907b62357SFande Kong @*/ 160d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobianDomainError(SNES snes) 161d71ae5a4SJacob Faibussowitsch { 16207b62357SFande Kong PetscFunctionBegin; 16307b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1645f80ce2aSJacob Faibussowitsch PetscCheck(!snes->errorifnotconverged, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "User code indicates computeJacobian does not make sense"); 16507b62357SFande Kong snes->jacobiandomainerror = PETSC_TRUE; 1663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16707b62357SFande Kong } 16807b62357SFande Kong 16907b62357SFande Kong /*@ 170f6dfbefdSBarry Smith SNESSetCheckJacobianDomainError - tells `SNESSolve()` whether to check if the user called `SNESSetJacobianDomainError()` Jacobian domain error after 171f6dfbefdSBarry Smith each Jacobian evaluation. By default, we check Jacobian domain error in the debug mode, and do not check it in the optimized mode. 172b351a90bSFande Kong 173c3339decSBarry Smith Logically Collective 174b351a90bSFande Kong 175b351a90bSFande Kong Input Parameters: 176a2b725a8SWilliam Gropp + snes - the SNES context 177f6dfbefdSBarry Smith - flg - indicates if or not to check Jacobian domain error after each Jacobian evaluation 178b351a90bSFande Kong 179b351a90bSFande Kong Level: advanced 180b351a90bSFande Kong 181f6dfbefdSBarry Smith Note: 182f6dfbefdSBarry Smith Checks require one extra parallel synchronization for each Jacobian evaluation 183f6dfbefdSBarry Smith 184*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedReason`, `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESGetCheckJacobianDomainError()` 185b351a90bSFande Kong @*/ 186d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCheckJacobianDomainError(SNES snes, PetscBool flg) 187d71ae5a4SJacob Faibussowitsch { 188b351a90bSFande Kong PetscFunctionBegin; 189b351a90bSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 190b351a90bSFande Kong snes->checkjacdomainerror = flg; 1913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 192b351a90bSFande Kong } 193b351a90bSFande Kong 194b351a90bSFande Kong /*@ 1958383d7d7SFande Kong SNESGetCheckJacobianDomainError - Get an indicator whether or not we are checking Jacobian domain errors after each Jacobian evaluation. 1968383d7d7SFande Kong 197c3339decSBarry Smith Logically Collective 1988383d7d7SFande Kong 1998383d7d7SFande Kong Input Parameters: 200f6dfbefdSBarry Smith . snes - the `SNES` context 2018383d7d7SFande Kong 2028383d7d7SFande Kong Output Parameters: 203f6dfbefdSBarry Smith . flg - `PETSC_FALSE` indicates that we don't check Jacobian domain errors after each Jacobian evaluation 2048383d7d7SFande Kong 2058383d7d7SFande Kong Level: advanced 2068383d7d7SFande Kong 207*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSetFunction()`, `SNESFunction()`, `SNESSetFunctionDomainError()`, `SNESSetCheckJacobianDomainError()` 2088383d7d7SFande Kong @*/ 209d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetCheckJacobianDomainError(SNES snes, PetscBool *flg) 210d71ae5a4SJacob Faibussowitsch { 2118383d7d7SFande Kong PetscFunctionBegin; 2128383d7d7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 213534a8f05SLisandro Dalcin PetscValidBoolPointer(flg, 2); 2148383d7d7SFande Kong *flg = snes->checkjacdomainerror; 2153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2168383d7d7SFande Kong } 2178383d7d7SFande Kong 2188383d7d7SFande Kong /*@ 219f6dfbefdSBarry Smith SNESGetFunctionDomainError - Gets the status of the domain error after a call to `SNESComputeFunction()`; 2206a388c36SPeter Brune 221f6dfbefdSBarry Smith Logically Collective 2226a388c36SPeter Brune 2236a388c36SPeter Brune Input Parameters: 224f6dfbefdSBarry Smith . snes - the `SNES` context 2256a388c36SPeter Brune 2266a388c36SPeter Brune Output Parameters: 227f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise. 2286a388c36SPeter Brune 229f6dfbefdSBarry Smith Level: developer 2306a388c36SPeter Brune 231*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunctionDomainError()`, `SNESComputeFunction()` 2326a388c36SPeter Brune @*/ 233d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionDomainError(SNES snes, PetscBool *domainerror) 234d71ae5a4SJacob Faibussowitsch { 2356a388c36SPeter Brune PetscFunctionBegin; 2366a388c36SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 237534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 2386a388c36SPeter Brune *domainerror = snes->domainerror; 2393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2406a388c36SPeter Brune } 2416a388c36SPeter Brune 24207b62357SFande Kong /*@ 243f6dfbefdSBarry Smith SNESGetJacobianDomainError - Gets the status of the Jacobian domain error after a call to `SNESComputeJacobian()`; 24407b62357SFande Kong 245c3339decSBarry Smith Logically Collective 24607b62357SFande Kong 24707b62357SFande Kong Input Parameters: 248f6dfbefdSBarry Smith . snes - the `SNES` context 24907b62357SFande Kong 25007b62357SFande Kong Output Parameters: 251f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a Jacobian domain error; `PETSC_FALSE` otherwise. 25207b62357SFande Kong 25307b62357SFande Kong Level: advanced 25407b62357SFande Kong 255*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunctionDomainError()`, `SNESComputeFunction()`, `SNESGetFunctionDomainError()` 25607b62357SFande Kong @*/ 257d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobianDomainError(SNES snes, PetscBool *domainerror) 258d71ae5a4SJacob Faibussowitsch { 25907b62357SFande Kong PetscFunctionBegin; 26007b62357SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 261534a8f05SLisandro Dalcin PetscValidBoolPointer(domainerror, 2); 26207b62357SFande Kong *domainerror = snes->jacobiandomainerror; 2633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 26407b62357SFande Kong } 26507b62357SFande Kong 26655849f57SBarry Smith /*@C 267f6dfbefdSBarry Smith SNESLoad - Loads a `SNES` that has been stored in `PETSCVIEWERBINARY` with `SNESView()`. 26855849f57SBarry Smith 269c3339decSBarry Smith Collective 27055849f57SBarry Smith 27155849f57SBarry Smith Input Parameters: 272f6dfbefdSBarry Smith + newdm - the newly loaded `SNES`, this needs to have been created with `SNESCreate()` or 273f6dfbefdSBarry Smith some related function before a call to `SNESLoad()`. 274f6dfbefdSBarry Smith - viewer - binary file viewer, obtained from `PetscViewerBinaryOpen()` 27555849f57SBarry Smith 27655849f57SBarry Smith Level: intermediate 27755849f57SBarry Smith 278f6dfbefdSBarry Smith Note: 279f6dfbefdSBarry Smith The type is determined by the data in the file, any type set into the `SNES` before this call is ignored. 28055849f57SBarry Smith 281*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `PetscViewer`, `SNESCreate()`, `SNESType`, `PetscViewerBinaryOpen()`, `SNESView()`, `MatLoad()`, `VecLoad()` 28255849f57SBarry Smith @*/ 283d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESLoad(SNES snes, PetscViewer viewer) 284d71ae5a4SJacob Faibussowitsch { 28555849f57SBarry Smith PetscBool isbinary; 286060da220SMatthew G. Knepley PetscInt classid; 28755849f57SBarry Smith char type[256]; 28855849f57SBarry Smith KSP ksp; 2892d53ad75SBarry Smith DM dm; 2902d53ad75SBarry Smith DMSNES dmsnes; 29155849f57SBarry Smith 29255849f57SBarry Smith PetscFunctionBegin; 2932d53ad75SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 29455849f57SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 2959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 2965f80ce2aSJacob Faibussowitsch PetscCheck(isbinary, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONG, "Invalid viewer; open viewer with PetscViewerBinaryOpen()"); 29755849f57SBarry Smith 2989566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, &classid, 1, NULL, PETSC_INT)); 2995f80ce2aSJacob Faibussowitsch PetscCheck(classid == SNES_FILE_CLASSID, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Not SNES next in file"); 3009566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryRead(viewer, type, 256, NULL, PETSC_CHAR)); 3019566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 302dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, load, viewer); 3039566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3049566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &dmsnes)); 3059566063dSJacob Faibussowitsch PetscCall(DMSNESLoad(dmsnes, viewer)); 3069566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 3079566063dSJacob Faibussowitsch PetscCall(KSPLoad(ksp, viewer)); 3083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30955849f57SBarry Smith } 3106a388c36SPeter Brune 3119804daf3SBarry Smith #include <petscdraw.h> 312e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 313e04113cfSBarry Smith #include <petscviewersaws.h> 314bfb97211SBarry Smith #endif 3158404b7f3SBarry Smith 316fe2efc57SMark /*@C 317*dc4c0fb0SBarry Smith SNESViewFromOptions - View a `SNES` based on values in the options database 318fe2efc57SMark 319c3339decSBarry Smith Collective 320fe2efc57SMark 321fe2efc57SMark Input Parameters: 322f6dfbefdSBarry Smith + A - the `SNES` context 323*dc4c0fb0SBarry Smith . obj - Optional object that provides the options prefix for the checks 324736c3998SJose E. Roman - name - command line option 325fe2efc57SMark 326fe2efc57SMark Level: intermediate 327f6dfbefdSBarry Smith 328*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESView`, `PetscObjectViewFromOptions()`, `SNESCreate()` 329fe2efc57SMark @*/ 330d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESViewFromOptions(SNES A, PetscObject obj, const char name[]) 331d71ae5a4SJacob Faibussowitsch { 332fe2efc57SMark PetscFunctionBegin; 333fe2efc57SMark PetscValidHeaderSpecific(A, SNES_CLASSID, 1); 3349566063dSJacob Faibussowitsch PetscCall(PetscObjectViewFromOptions((PetscObject)A, obj, name)); 3353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 336fe2efc57SMark } 337fe2efc57SMark 338789d8953SBarry Smith PETSC_EXTERN PetscErrorCode SNESComputeJacobian_DMDA(SNES, Vec, Mat, Mat, void *); 339789d8953SBarry Smith 3407e2c5f70SBarry Smith /*@C 341*dc4c0fb0SBarry Smith SNESView - Prints or visualizes the `SNES` data structure. 3429b94acceSBarry Smith 343c3339decSBarry Smith Collective 344fee21e36SBarry Smith 345c7afd0dbSLois Curfman McInnes Input Parameters: 346f6dfbefdSBarry Smith + snes - the `SNES` context 347f6dfbefdSBarry Smith - viewer - the `PetscViewer` 348c7afd0dbSLois Curfman McInnes 3499b94acceSBarry Smith Options Database Key: 350f6dfbefdSBarry Smith . -snes_view - Calls `SNESView()` at end of `SNESSolve()` 3519b94acceSBarry Smith 352*dc4c0fb0SBarry Smith Level: beginner 353*dc4c0fb0SBarry Smith 3549b94acceSBarry Smith Notes: 3559b94acceSBarry Smith The available visualization contexts include 356f6dfbefdSBarry Smith + `PETSC_VIEWER_STDOUT_SELF` - standard output (default) 357f6dfbefdSBarry Smith - `PETSC_VIEWER_STDOUT_WORLD` - synchronized standard 358c8a8ba5cSLois Curfman McInnes output where only the first processor opens 359c8a8ba5cSLois Curfman McInnes the file. All other processors send their 360c8a8ba5cSLois Curfman McInnes data to the first processor to print. 3619b94acceSBarry Smith 362052bf0daSPierre Jolivet The available formats include 363f6dfbefdSBarry Smith + `PETSC_VIEWER_DEFAULT` - standard output (default) 364f6dfbefdSBarry Smith - `PETSC_VIEWER_ASCII_INFO_DETAIL` - more verbose output for `SNESNASM` 365052bf0daSPierre Jolivet 3663e081fefSLois Curfman McInnes The user can open an alternative visualization context with 367f6dfbefdSBarry Smith `PetscViewerASCIIOpen()` - output to a specified file. 3689b94acceSBarry Smith 369f6dfbefdSBarry Smith In the debugger you can do "call `SNESView`(snes,0)" to display the `SNES` solver. (The same holds for any PETSc object viewer). 370595c91d4SBarry Smith 371*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESLoad()`, `SNESCreate()`, `PetscViewerASCIIOpen()` 3729b94acceSBarry Smith @*/ 373d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESView(SNES snes, PetscViewer viewer) 374d71ae5a4SJacob Faibussowitsch { 375fa9f3622SBarry Smith SNESKSPEW *kctx; 37694b7f48cSBarry Smith KSP ksp; 3777f1410a3SPeter Brune SNESLineSearch linesearch; 37872a02f06SBarry Smith PetscBool iascii, isstring, isbinary, isdraw; 3792d53ad75SBarry Smith DMSNES dmsnes; 380e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 381536b137fSBarry Smith PetscBool issaws; 382bfb97211SBarry Smith #endif 3839b94acceSBarry Smith 3843a40ed3dSBarry Smith PetscFunctionBegin; 3850700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 38648a46eb9SPierre Jolivet if (!viewer) PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &viewer)); 3870700a824SBarry Smith PetscValidHeaderSpecific(viewer, PETSC_VIEWER_CLASSID, 2); 388c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, viewer, 2); 38974679c65SBarry Smith 3909566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &iascii)); 3919566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSTRING, &isstring)); 3929566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERBINARY, &isbinary)); 3939566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERDRAW, &isdraw)); 394e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 3959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERSAWS, &issaws)); 396bfb97211SBarry Smith #endif 39732077d6dSBarry Smith if (iascii) { 398dc0571f2SMatthew G. Knepley SNESNormSchedule normschedule; 3998404b7f3SBarry Smith DM dm; 4008404b7f3SBarry Smith PetscErrorCode (*cJ)(SNES, Vec, Mat, Mat, void *); 4018404b7f3SBarry Smith void *ctx; 402789d8953SBarry Smith const char *pre = ""; 403dc0571f2SMatthew G. Knepley 4049566063dSJacob Faibussowitsch PetscCall(PetscObjectPrintClassNamePrefixType((PetscObject)snes, viewer)); 40548a46eb9SPierre Jolivet if (!snes->setupcalled) PetscCall(PetscViewerASCIIPrintf(viewer, " SNES has not been set up so information may be incomplete\n")); 406e7788613SBarry Smith if (snes->ops->view) { 4079566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 408dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, view, viewer); 4099566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 4100ef38995SBarry Smith } 41163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " maximum iterations=%" PetscInt_FMT ", maximum function evaluations=%" PetscInt_FMT "\n", snes->max_its, snes->max_funcs)); 4129566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " tolerances: relative=%g, absolute=%g, solution=%g\n", (double)snes->rtol, (double)snes->abstol, (double)snes->stol)); 41348a46eb9SPierre Jolivet if (snes->usesksp) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of linear solver iterations=%" PetscInt_FMT "\n", snes->linear_its)); 41463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " total number of function evaluations=%" PetscInt_FMT "\n", snes->nfuncs)); 4159566063dSJacob Faibussowitsch PetscCall(SNESGetNormSchedule(snes, &normschedule)); 4169566063dSJacob Faibussowitsch if (normschedule > 0) PetscCall(PetscViewerASCIIPrintf(viewer, " norm schedule %s\n", SNESNormSchedules[normschedule])); 41748a46eb9SPierre Jolivet if (snes->gridsequence) PetscCall(PetscViewerASCIIPrintf(viewer, " total number of grid sequence refinements=%" PetscInt_FMT "\n", snes->gridsequence)); 4189b94acceSBarry Smith if (snes->ksp_ewconv) { 419fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 4209b94acceSBarry Smith if (kctx) { 42163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Eisenstat-Walker computation of KSP relative tolerance (version %" PetscInt_FMT ")\n", kctx->version)); 4229566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " rtol_0=%g, rtol_max=%g, threshold=%g\n", (double)kctx->rtol_0, (double)kctx->rtol_max, (double)kctx->threshold)); 4239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " gamma=%g, alpha=%g, alpha2=%g\n", (double)kctx->gamma, (double)kctx->alpha, (double)kctx->alpha2)); 4249b94acceSBarry Smith } 4259b94acceSBarry Smith } 426eb1f6c34SBarry Smith if (snes->lagpreconditioner == -1) { 4279566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is never rebuilt\n")); 428eb1f6c34SBarry Smith } else if (snes->lagpreconditioner > 1) { 42963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Preconditioned is rebuilt every %" PetscInt_FMT " new Jacobians\n", snes->lagpreconditioner)); 430eb1f6c34SBarry Smith } 431eb1f6c34SBarry Smith if (snes->lagjacobian == -1) { 4329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is never rebuilt\n")); 433eb1f6c34SBarry Smith } else if (snes->lagjacobian > 1) { 43463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is rebuilt every %" PetscInt_FMT " SNES iterations\n", snes->lagjacobian)); 435eb1f6c34SBarry Smith } 4369566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4379566063dSJacob Faibussowitsch PetscCall(DMSNESGetJacobian(dm, &cJ, &ctx)); 438789d8953SBarry Smith if (snes->mf_operator) { 4399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing\n")); 440789d8953SBarry Smith pre = "Preconditioning "; 441789d8953SBarry Smith } 4428404b7f3SBarry Smith if (cJ == SNESComputeJacobianDefault) { 4439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences one column at a time\n", pre)); 4448404b7f3SBarry Smith } else if (cJ == SNESComputeJacobianDefaultColor) { 4459566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using finite differences with coloring\n", pre)); 446789d8953SBarry Smith /* it slightly breaks data encapsulation for access the DMDA information directly */ 447789d8953SBarry Smith } else if (cJ == SNESComputeJacobian_DMDA) { 448789d8953SBarry Smith MatFDColoring fdcoloring; 4499566063dSJacob Faibussowitsch PetscCall(PetscObjectQuery((PetscObject)dm, "DMDASNES_FDCOLORING", (PetscObject *)&fdcoloring)); 450789d8953SBarry Smith if (fdcoloring) { 4519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using colored finite differences on a DMDA\n", pre)); 452789d8953SBarry Smith } else { 4539566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " %sJacobian is built using a DMDA local Jacobian\n", pre)); 454789d8953SBarry Smith } 455789d8953SBarry Smith } else if (snes->mf) { 4569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Jacobian is applied matrix-free with differencing, no explicit Jacobian\n")); 4578404b7f3SBarry Smith } 4580f5bd95cSBarry Smith } else if (isstring) { 459317d6ea6SBarry Smith const char *type; 4609566063dSJacob Faibussowitsch PetscCall(SNESGetType(snes, &type)); 4619566063dSJacob Faibussowitsch PetscCall(PetscViewerStringSPrintf(viewer, " SNESType: %-7.7s", type)); 462dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 46355849f57SBarry Smith } else if (isbinary) { 46455849f57SBarry Smith PetscInt classid = SNES_FILE_CLASSID; 46555849f57SBarry Smith MPI_Comm comm; 46655849f57SBarry Smith PetscMPIInt rank; 46755849f57SBarry Smith char type[256]; 46855849f57SBarry Smith 4699566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 4709566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(comm, &rank)); 471dd400576SPatrick Sanan if (rank == 0) { 4729566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, &classid, 1, PETSC_INT)); 4739566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(type, ((PetscObject)snes)->type_name, sizeof(type))); 4749566063dSJacob Faibussowitsch PetscCall(PetscViewerBinaryWrite(viewer, type, sizeof(type), PETSC_CHAR)); 47555849f57SBarry Smith } 476dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 47772a02f06SBarry Smith } else if (isdraw) { 47872a02f06SBarry Smith PetscDraw draw; 47972a02f06SBarry Smith char str[36]; 48089fd9fafSBarry Smith PetscReal x, y, bottom, h; 48172a02f06SBarry Smith 4829566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 4839566063dSJacob Faibussowitsch PetscCall(PetscDrawGetCurrentPoint(draw, &x, &y)); 4849566063dSJacob Faibussowitsch PetscCall(PetscStrncpy(str, "SNES: ", sizeof(str))); 4859566063dSJacob Faibussowitsch PetscCall(PetscStrlcat(str, ((PetscObject)snes)->type_name, sizeof(str))); 4869566063dSJacob Faibussowitsch PetscCall(PetscDrawStringBoxed(draw, x, y, PETSC_DRAW_BLUE, PETSC_DRAW_BLACK, str, NULL, &h)); 48789fd9fafSBarry Smith bottom = y - h; 4889566063dSJacob Faibussowitsch PetscCall(PetscDrawPushCurrentPoint(draw, x, bottom)); 489dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, view, viewer); 490e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 491536b137fSBarry Smith } else if (issaws) { 492d45a07a7SBarry Smith PetscMPIInt rank; 4932657e9d9SBarry Smith const char *name; 494d45a07a7SBarry Smith 4959566063dSJacob Faibussowitsch PetscCall(PetscObjectGetName((PetscObject)snes, &name)); 4969566063dSJacob Faibussowitsch PetscCallMPI(MPI_Comm_rank(PETSC_COMM_WORLD, &rank)); 497dd400576SPatrick Sanan if (!((PetscObject)snes)->amsmem && rank == 0) { 498d45a07a7SBarry Smith char dir[1024]; 499d45a07a7SBarry Smith 5009566063dSJacob Faibussowitsch PetscCall(PetscObjectViewSAWs((PetscObject)snes, viewer)); 5019566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/its", name)); 502792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, &snes->iter, 1, SAWs_READ, SAWs_INT)); 50348a46eb9SPierre Jolivet if (!snes->conv_hist) PetscCall(SNESSetConvergenceHistory(snes, NULL, NULL, PETSC_DECIDE, PETSC_TRUE)); 5049566063dSJacob Faibussowitsch PetscCall(PetscSNPrintf(dir, 1024, "/PETSc/Objects/%s/conv_hist", name)); 505792fecdfSBarry Smith PetscCallSAWs(SAWs_Register, (dir, snes->conv_hist, 10, SAWs_READ, SAWs_DOUBLE)); 506f05ece33SBarry Smith } 507bfb97211SBarry Smith #endif 50872a02f06SBarry Smith } 50972a02f06SBarry Smith if (snes->linesearch) { 5109566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 5119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5129566063dSJacob Faibussowitsch PetscCall(SNESLineSearchView(linesearch, viewer)); 5139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 51419bcc07fSBarry Smith } 515efd4aadfSBarry Smith if (snes->npc && snes->usesnpc) { 5169566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5179566063dSJacob Faibussowitsch PetscCall(SNESView(snes->npc, viewer)); 5189566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5194a0c5b0cSMatthew G Knepley } 5209566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5219566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &dmsnes)); 5229566063dSJacob Faibussowitsch PetscCall(DMSNESView(dmsnes, viewer)); 5239566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5242c155ee1SBarry Smith if (snes->usesksp) { 5259566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 5269566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPushTab(viewer)); 5279566063dSJacob Faibussowitsch PetscCall(KSPView(ksp, viewer)); 5289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(viewer)); 5292c155ee1SBarry Smith } 53072a02f06SBarry Smith if (isdraw) { 53172a02f06SBarry Smith PetscDraw draw; 5329566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(viewer, 0, &draw)); 5339566063dSJacob Faibussowitsch PetscCall(PetscDrawPopCurrentPoint(draw)); 5347f1410a3SPeter Brune } 5353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5369b94acceSBarry Smith } 5379b94acceSBarry Smith 53876b2cf59SMatthew Knepley /* 53976b2cf59SMatthew Knepley We retain a list of functions that also take SNES command 54076b2cf59SMatthew Knepley line options. These are called at the end SNESSetFromOptions() 54176b2cf59SMatthew Knepley */ 54276b2cf59SMatthew Knepley #define MAXSETFROMOPTIONS 5 543a7cc72afSBarry Smith static PetscInt numberofsetfromoptions; 5446849ba73SBarry Smith static PetscErrorCode (*othersetfromoptions[MAXSETFROMOPTIONS])(SNES); 54576b2cf59SMatthew Knepley 546ac226902SBarry Smith /*@C 547f6dfbefdSBarry Smith SNESAddOptionsChecker - Adds an additional function to check for `SNES` options. 54876b2cf59SMatthew Knepley 54976b2cf59SMatthew Knepley Not Collective 55076b2cf59SMatthew Knepley 55176b2cf59SMatthew Knepley Input Parameter: 55276b2cf59SMatthew Knepley . snescheck - function that checks for options 55376b2cf59SMatthew Knepley 55476b2cf59SMatthew Knepley Level: developer 55576b2cf59SMatthew Knepley 556*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()` 55776b2cf59SMatthew Knepley @*/ 558d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAddOptionsChecker(PetscErrorCode (*snescheck)(SNES)) 559d71ae5a4SJacob Faibussowitsch { 56076b2cf59SMatthew Knepley PetscFunctionBegin; 56163a3b9bcSJacob Faibussowitsch PetscCheck(numberofsetfromoptions < MAXSETFROMOPTIONS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many options checkers, only %d allowed", MAXSETFROMOPTIONS); 56276b2cf59SMatthew Knepley othersetfromoptions[numberofsetfromoptions++] = snescheck; 5633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56476b2cf59SMatthew Knepley } 56576b2cf59SMatthew Knepley 566d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetUpMatrixFree_Private(SNES snes, PetscBool hasOperator, PetscInt version) 567d71ae5a4SJacob Faibussowitsch { 568aa3661deSLisandro Dalcin Mat J; 569895c21f2SBarry Smith MatNullSpace nullsp; 570aa3661deSLisandro Dalcin 571aa3661deSLisandro Dalcin PetscFunctionBegin; 5720700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 573aa3661deSLisandro Dalcin 57498613b67SLisandro Dalcin if (!snes->vec_func && (snes->jacobian || snes->jacobian_pre)) { 57598613b67SLisandro Dalcin Mat A = snes->jacobian, B = snes->jacobian_pre; 5769566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(A ? A : B, NULL, &snes->vec_func)); 57798613b67SLisandro Dalcin } 57898613b67SLisandro Dalcin 5790fdf79fbSJacob Faibussowitsch PetscCheck(version == 1 || version == 2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "matrix-free operator routines, only version 1 and 2"); 580aa3661deSLisandro Dalcin if (version == 1) { 5819566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 5829566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 5839566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 5841e2ae407SBarry Smith /* TODO: the version 2 code should be merged into the MatCreateSNESMF() and MatCreateMFFD() infrastructure and then removed */ 5850fdf79fbSJacob Faibussowitsch } else /* if (version == 2) */ { 5865f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "SNESSetFunction() must be called first"); 587570b7f6dSBarry Smith #if !defined(PETSC_USE_COMPLEX) && !defined(PETSC_USE_REAL_SINGLE) && !defined(PETSC_USE_REAL___FLOAT128) && !defined(PETSC_USE_REAL___FP16) 588f6dfbefdSBarry Smith PetscCall(MatCreateSNESMFMore(snes, snes->vec_func, &J)); 589aa3661deSLisandro Dalcin #else 5902479783cSJose E. Roman SETERRQ(PETSC_COMM_SELF, PETSC_ERR_SUP, "matrix-free operator routines (version 2)"); 591aa3661deSLisandro Dalcin #endif 5920fdf79fbSJacob Faibussowitsch } 593aa3661deSLisandro Dalcin 594895c21f2SBarry Smith /* attach any user provided null space that was on Amat to the newly created matrix free matrix */ 595895c21f2SBarry Smith if (snes->jacobian) { 5969566063dSJacob Faibussowitsch PetscCall(MatGetNullSpace(snes->jacobian, &nullsp)); 5971baa6e33SBarry Smith if (nullsp) PetscCall(MatSetNullSpace(J, nullsp)); 598895c21f2SBarry Smith } 599895c21f2SBarry Smith 60063a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free operator routines (version %" PetscInt_FMT ")\n", version)); 601d3462f78SMatthew Knepley if (hasOperator) { 602aa3661deSLisandro Dalcin /* This version replaces the user provided Jacobian matrix with a 603aa3661deSLisandro Dalcin matrix-free version but still employs the user-provided preconditioner matrix. */ 6049566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 605aa3661deSLisandro Dalcin } else { 606aa3661deSLisandro Dalcin /* This version replaces both the user-provided Jacobian and the user- 6073232da50SPeter Brune provided preconditioner Jacobian with the default matrix free version. */ 608b552625fSStefano Zampini if (snes->npcside == PC_LEFT && snes->npc) { 6099566063dSJacob Faibussowitsch if (!snes->jacobian) PetscCall(SNESSetJacobian(snes, J, NULL, NULL, NULL)); 610172a4300SPeter Brune } else { 611789d8953SBarry Smith KSP ksp; 612789d8953SBarry Smith PC pc; 613789d8953SBarry Smith PetscBool match; 614789d8953SBarry Smith 6159566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian, NULL)); 616aa3661deSLisandro Dalcin /* Force no preconditioner */ 6179566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 6189566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 6192698c518SLisandro Dalcin PetscCall(PetscObjectTypeCompareAny((PetscObject)pc, &match, PCSHELL, PCH2OPUS, "")); 620aa3661deSLisandro Dalcin if (!match) { 6219566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default matrix-free preconditioner routines\nThat is no preconditioner is being used\n")); 6229566063dSJacob Faibussowitsch PetscCall(PCSetType(pc, PCNONE)); 623aa3661deSLisandro Dalcin } 624aa3661deSLisandro Dalcin } 625789d8953SBarry Smith } 6269566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 6273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 628aa3661deSLisandro Dalcin } 629aa3661deSLisandro Dalcin 630d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMRestrictHook_SNESVecSol(DM dmfine, Mat Restrict, Vec Rscale, Mat Inject, DM dmcoarse, void *ctx) 631d71ae5a4SJacob Faibussowitsch { 632dfe15315SJed Brown SNES snes = (SNES)ctx; 6330298fd71SBarry Smith Vec Xfine, Xfine_named = NULL, Xcoarse; 634dfe15315SJed Brown 635dfe15315SJed Brown PetscFunctionBegin; 63616ebb321SJed Brown if (PetscLogPrintInfo) { 63716ebb321SJed Brown PetscInt finelevel, coarselevel, fineclevel, coarseclevel; 6389566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmfine, &finelevel)); 6399566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmfine, &fineclevel)); 6409566063dSJacob Faibussowitsch PetscCall(DMGetRefineLevel(dmcoarse, &coarselevel)); 6419566063dSJacob Faibussowitsch PetscCall(DMGetCoarsenLevel(dmcoarse, &coarseclevel)); 64263a3b9bcSJacob 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)); 64316ebb321SJed Brown } 644dfe15315SJed Brown if (dmfine == snes->dm) Xfine = snes->vec_sol; 645dfe15315SJed Brown else { 6469566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 647dfe15315SJed Brown Xfine = Xfine_named; 648dfe15315SJed Brown } 6499566063dSJacob Faibussowitsch PetscCall(DMGetNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 650907f5c5aSLawrence Mitchell if (Inject) { 6519566063dSJacob Faibussowitsch PetscCall(MatRestrict(Inject, Xfine, Xcoarse)); 652907f5c5aSLawrence Mitchell } else { 6539566063dSJacob Faibussowitsch PetscCall(MatRestrict(Restrict, Xfine, Xcoarse)); 6549566063dSJacob Faibussowitsch PetscCall(VecPointwiseMult(Xcoarse, Xcoarse, Rscale)); 655907f5c5aSLawrence Mitchell } 6569566063dSJacob Faibussowitsch PetscCall(DMRestoreNamedGlobalVector(dmcoarse, "SNESVecSol", &Xcoarse)); 6579566063dSJacob Faibussowitsch if (Xfine_named) PetscCall(DMRestoreNamedGlobalVector(dmfine, "SNESVecSol", &Xfine_named)); 6583ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 659dfe15315SJed Brown } 660dfe15315SJed Brown 661d71ae5a4SJacob Faibussowitsch static PetscErrorCode DMCoarsenHook_SNESVecSol(DM dm, DM dmc, void *ctx) 662d71ae5a4SJacob Faibussowitsch { 66316ebb321SJed Brown PetscFunctionBegin; 6649566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(dmc, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, ctx)); 6653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 66616ebb321SJed Brown } 66716ebb321SJed Brown 668a6950cb2SJed Brown /* This may be called to rediscretize the operator on levels of linear multigrid. The DM shuffle is so the user can 669a6950cb2SJed Brown * safely call SNESGetDM() in their residual evaluation routine. */ 670d71ae5a4SJacob Faibussowitsch static PetscErrorCode KSPComputeOperators_SNES(KSP ksp, Mat A, Mat B, void *ctx) 671d71ae5a4SJacob Faibussowitsch { 672caa4e7f2SJed Brown SNES snes = (SNES)ctx; 6730298fd71SBarry Smith Vec X, Xnamed = NULL; 674dfe15315SJed Brown DM dmsave; 6754e269d77SPeter Brune void *ctxsave; 67625ce1634SJed Brown PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *) = NULL; 677caa4e7f2SJed Brown 678caa4e7f2SJed Brown PetscFunctionBegin; 679dfe15315SJed Brown dmsave = snes->dm; 6809566063dSJacob Faibussowitsch PetscCall(KSPGetDM(ksp, &snes->dm)); 681dfe15315SJed Brown if (dmsave == snes->dm) X = snes->vec_sol; /* We are on the finest level */ 6829371c9d4SSatish Balay else { /* We are on a coarser level, this vec was initialized using a DM restrict hook */ PetscCall(DMGetNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 683dfe15315SJed Brown X = Xnamed; 6849566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, NULL, NULL, &jac, &ctxsave)); 6854e269d77SPeter Brune /* If the DM's don't match up, the MatFDColoring context needed for the jacobian won't match up either -- fixit. */ 68648a46eb9SPierre Jolivet if (jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, SNESComputeJacobianDefaultColor, NULL)); 6874e269d77SPeter Brune } 6884dde8bb0SMatthew G. Knepley /* Make sure KSP DM has the Jacobian computation routine */ 6894dde8bb0SMatthew G. Knepley { 6904dde8bb0SMatthew G. Knepley DMSNES sdm; 6914e269d77SPeter Brune 6929566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 69348a46eb9SPierre Jolivet if (!sdm->ops->computejacobian) PetscCall(DMCopyDMSNES(dmsave, snes->dm)); 6944dde8bb0SMatthew G. Knepley } 6952b93b426SMatthew G. Knepley /* Compute the operators */ 6969566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobian(snes, X, A, B)); 6972b93b426SMatthew G. Knepley /* Put the previous context back */ 69848a46eb9SPierre Jolivet if (snes->dm != dmsave && jac == SNESComputeJacobianDefaultColor) PetscCall(SNESSetJacobian(snes, NULL, NULL, jac, ctxsave)); 6994e269d77SPeter Brune 7009566063dSJacob Faibussowitsch if (Xnamed) PetscCall(DMRestoreNamedGlobalVector(snes->dm, "SNESVecSol", &Xnamed)); 701dfe15315SJed Brown snes->dm = dmsave; 7023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 703caa4e7f2SJed Brown } 704caa4e7f2SJed Brown 7056cab3a1bSJed Brown /*@ 706*dc4c0fb0SBarry Smith SNESSetUpMatrices - ensures that matrices are available for `SNES` Newton-like methods, this is called by `SNESSetUp_XXX()` 7076cab3a1bSJed Brown 7086cab3a1bSJed Brown Collective 7096cab3a1bSJed Brown 7104165533cSJose E. Roman Input Parameter: 7116cab3a1bSJed Brown . snes - snes to configure 7126cab3a1bSJed Brown 7136cab3a1bSJed Brown Level: developer 7146cab3a1bSJed Brown 715*dc4c0fb0SBarry Smith Note: 716*dc4c0fb0SBarry Smith If the matrices do not yet exist it attempts to create them based on options previously set for the `SNES` such as `-snes_mf` 717*dc4c0fb0SBarry Smith 718*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetUp()` 7196cab3a1bSJed Brown @*/ 720d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpMatrices(SNES snes) 721d71ae5a4SJacob Faibussowitsch { 7226cab3a1bSJed Brown DM dm; 723942e3340SBarry Smith DMSNES sdm; 7246cab3a1bSJed Brown 7256cab3a1bSJed Brown PetscFunctionBegin; 7269566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 7279566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 72858b371f3SBarry Smith if (!snes->jacobian && snes->mf) { 7296cab3a1bSJed Brown Mat J; 7306cab3a1bSJed Brown void *functx; 7319566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7329566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7339566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7349566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 7359566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, J, NULL, NULL)); 7369566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 737caa4e7f2SJed Brown } else if (snes->mf_operator && !snes->jacobian_pre && !snes->jacobian) { 7386cab3a1bSJed Brown Mat J, B; 7399566063dSJacob Faibussowitsch PetscCall(MatCreateSNESMF(snes, &J)); 7409566063dSJacob Faibussowitsch PetscCall(MatMFFDSetOptionsPrefix(J, ((PetscObject)snes)->prefix)); 7419566063dSJacob Faibussowitsch PetscCall(MatSetFromOptions(J)); 7429566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 74306f20277SJed Brown /* sdm->computejacobian was already set to reach here */ 7449566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J, B, NULL, NULL)); 7459566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7469566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 747caa4e7f2SJed Brown } else if (!snes->jacobian_pre) { 7481ba9b98eSMatthew G. Knepley PetscDS prob; 7496cab3a1bSJed Brown Mat J, B; 7501ba9b98eSMatthew G. Knepley PetscBool hasPrec = PETSC_FALSE; 7511ba9b98eSMatthew G. Knepley 7526cab3a1bSJed Brown J = snes->jacobian; 7539566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 7549566063dSJacob Faibussowitsch if (prob) PetscCall(PetscDSHasJacobianPreconditioner(prob, &hasPrec)); 7559566063dSJacob Faibussowitsch if (J) PetscCall(PetscObjectReference((PetscObject)J)); 7569566063dSJacob Faibussowitsch else if (hasPrec) PetscCall(DMCreateMatrix(snes->dm, &J)); 7579566063dSJacob Faibussowitsch PetscCall(DMCreateMatrix(snes->dm, &B)); 7589566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, J ? J : B, B, NULL, NULL)); 7599566063dSJacob Faibussowitsch PetscCall(MatDestroy(&J)); 7609566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 7616cab3a1bSJed Brown } 762caa4e7f2SJed Brown { 763caa4e7f2SJed Brown KSP ksp; 7649566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 7659566063dSJacob Faibussowitsch PetscCall(KSPSetComputeOperators(ksp, KSPComputeOperators_SNES, snes)); 7669566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookAdd(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 767caa4e7f2SJed Brown } 7683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 7696cab3a1bSJed Brown } 7706cab3a1bSJed Brown 771d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESMonitorPauseFinal_Internal(SNES snes) 772d71ae5a4SJacob Faibussowitsch { 7735e7c47f3SMatthew G. Knepley PetscInt i; 7745e7c47f3SMatthew G. Knepley 7755e7c47f3SMatthew G. Knepley PetscFunctionBegin; 7763ba16761SJacob Faibussowitsch if (!snes->pauseFinal) PetscFunctionReturn(PETSC_SUCCESS); 7775e7c47f3SMatthew G. Knepley for (i = 0; i < snes->numbermonitors; ++i) { 7785e7c47f3SMatthew G. Knepley PetscViewerAndFormat *vf = (PetscViewerAndFormat *)snes->monitorcontext[i]; 7795e7c47f3SMatthew G. Knepley PetscDraw draw; 7805e7c47f3SMatthew G. Knepley PetscReal lpause; 7815e7c47f3SMatthew G. Knepley 7825e7c47f3SMatthew G. Knepley if (!vf) continue; 7835e7c47f3SMatthew G. Knepley if (vf->lg) { 7845e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->lg, PETSC_OBJECT)) continue; 7855e7c47f3SMatthew G. Knepley if (((PetscObject)vf->lg)->classid != PETSC_DRAWLG_CLASSID) continue; 7869566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(vf->lg, &draw)); 7879566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 7889566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 7899566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 7909566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 7915e7c47f3SMatthew G. Knepley } else { 7925e7c47f3SMatthew G. Knepley PetscBool isdraw; 7935e7c47f3SMatthew G. Knepley 7945e7c47f3SMatthew G. Knepley if (!PetscCheckPointer(vf->viewer, PETSC_OBJECT)) continue; 7955e7c47f3SMatthew G. Knepley if (((PetscObject)vf->viewer)->classid != PETSC_VIEWER_CLASSID) continue; 7969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)vf->viewer, PETSCVIEWERDRAW, &isdraw)); 7975e7c47f3SMatthew G. Knepley if (!isdraw) continue; 7989566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDraw(vf->viewer, 0, &draw)); 7999566063dSJacob Faibussowitsch PetscCall(PetscDrawGetPause(draw, &lpause)); 8009566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, -1.0)); 8019566063dSJacob Faibussowitsch PetscCall(PetscDrawPause(draw)); 8029566063dSJacob Faibussowitsch PetscCall(PetscDrawSetPause(draw, lpause)); 8035e7c47f3SMatthew G. Knepley } 8045e7c47f3SMatthew G. Knepley } 8053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8065e7c47f3SMatthew G. Knepley } 8075e7c47f3SMatthew G. Knepley 808fde5950dSBarry Smith /*@C 809fde5950dSBarry Smith SNESMonitorSetFromOptions - Sets a monitor function and viewer appropriate for the type indicated by the user 810fde5950dSBarry Smith 811c3339decSBarry Smith Collective 812fde5950dSBarry Smith 813fde5950dSBarry Smith Input Parameters: 814*dc4c0fb0SBarry Smith + snes - `SNES` object you wish to monitor 815fde5950dSBarry Smith . name - the monitor type one is seeking 816fde5950dSBarry Smith . help - message indicating what monitoring is done 817fde5950dSBarry Smith . manual - manual page for the monitor 818fde5950dSBarry Smith . monitor - the monitor function 819f6dfbefdSBarry 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 820fde5950dSBarry Smith 821f6dfbefdSBarry Smith Options Database Key: 822f6dfbefdSBarry Smith . -name - trigger the use of this monitor in `SNESSetFromOptions()` 823f6dfbefdSBarry Smith 824f6dfbefdSBarry Smith Level: advanced 825fde5950dSBarry Smith 826*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `PetscOptionsGetViewer()`, `PetscOptionsGetReal()`, `PetscOptionsHasName()`, `PetscOptionsGetString()`, 827db781477SPatrick Sanan `PetscOptionsGetIntArray()`, `PetscOptionsGetRealArray()`, `PetscOptionsBool()` 828db781477SPatrick Sanan `PetscOptionsInt()`, `PetscOptionsString()`, `PetscOptionsReal()`, `PetscOptionsBool()`, 829db781477SPatrick Sanan `PetscOptionsName()`, `PetscOptionsBegin()`, `PetscOptionsEnd()`, `PetscOptionsHeadBegin()`, 830c2e3fba1SPatrick Sanan `PetscOptionsStringArray()`, `PetscOptionsRealArray()`, `PetscOptionsScalar()`, 831db781477SPatrick Sanan `PetscOptionsBoolGroupBegin()`, `PetscOptionsBoolGroup()`, `PetscOptionsBoolGroupEnd()`, 832db781477SPatrick Sanan `PetscOptionsFList()`, `PetscOptionsEList()` 833fde5950dSBarry Smith @*/ 834d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSetFromOptions(SNES snes, const char name[], const char help[], const char manual[], PetscErrorCode (*monitor)(SNES, PetscInt, PetscReal, PetscViewerAndFormat *), PetscErrorCode (*monitorsetup)(SNES, PetscViewerAndFormat *)) 835d71ae5a4SJacob Faibussowitsch { 836fde5950dSBarry Smith PetscViewer viewer; 837fde5950dSBarry Smith PetscViewerFormat format; 838fde5950dSBarry Smith PetscBool flg; 839fde5950dSBarry Smith 840fde5950dSBarry Smith PetscFunctionBegin; 8419566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, name, &viewer, &format, &flg)); 842fde5950dSBarry Smith if (flg) { 843d43b4f6eSBarry Smith PetscViewerAndFormat *vf; 8449566063dSJacob Faibussowitsch PetscCall(PetscViewerAndFormatCreate(viewer, format, &vf)); 8459566063dSJacob Faibussowitsch PetscCall(PetscObjectDereference((PetscObject)viewer)); 8461baa6e33SBarry Smith if (monitorsetup) PetscCall((*monitorsetup)(snes, vf)); 8479566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, (PetscErrorCode(*)(SNES, PetscInt, PetscReal, void *))monitor, vf, (PetscErrorCode(*)(void **))PetscViewerAndFormatDestroy)); 848fde5950dSBarry Smith } 8493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 850fde5950dSBarry Smith } 851fde5950dSBarry Smith 852d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, MPI_Comm comm, const char *prefix) 853d71ae5a4SJacob Faibussowitsch { 8540f0abf79SStefano Zampini PetscFunctionBegin; 8550f0abf79SStefano Zampini PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP"); 8560f0abf79SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", NULL, kctx->version, &kctx->version, NULL)); 8570f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", NULL, kctx->rtol_0, &kctx->rtol_0, NULL)); 8580f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", NULL, kctx->rtol_max, &kctx->rtol_max, NULL)); 8590f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", NULL, kctx->gamma, &kctx->gamma, NULL)); 8600f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", NULL, kctx->alpha, &kctx->alpha, NULL)); 8610f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL)); 8620f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", NULL, kctx->threshold, &kctx->threshold, NULL)); 8630f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL)); 8640f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL)); 8650f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL)); 8660f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL)); 8670f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL)); 8680f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL)); 8690f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL)); 8700f0abf79SStefano Zampini PetscOptionsEnd(); 8713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8720f0abf79SStefano Zampini } 8730f0abf79SStefano Zampini 8749b94acceSBarry Smith /*@ 875f6dfbefdSBarry Smith SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options. 8769b94acceSBarry Smith 877c3339decSBarry Smith Collective 878c7afd0dbSLois Curfman McInnes 8799b94acceSBarry Smith Input Parameter: 880f6dfbefdSBarry Smith . snes - the `SNES` context 8819b94acceSBarry Smith 88236851e7fSLois Curfman McInnes Options Database Keys: 883f6dfbefdSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, `SNESType` for complete list 88482738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 88582738288SBarry Smith of the change in the solution between steps 88670441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 887b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 888e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 889be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 890b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 891b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8924839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 893ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 894a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8953d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 896e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 8973d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 898b39c3a46SLois Curfman McInnes . -snes_trtol <trtol> - trust region tolerance 899f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 900f6dfbefdSBarry Smith default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense 901f6dfbefdSBarry Smith of convergence test. correct_pressure S`NESConvergedCorrectPressure()` has special handling of a pressure null space. 902fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 903fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 904fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 905fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 9064619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 907459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 9085e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 909e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 910e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 9115968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 912b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 913e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 914e62ac41dSBarry 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. 915e62ac41dSBarry 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. 91682738288SBarry Smith 917f6dfbefdSBarry Smith Options Database Keys for Eisenstat-Walker method: 918fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 9194b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 92036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 92136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 92236851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 92336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 92436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 92536851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 92682738288SBarry Smith 927*dc4c0fb0SBarry Smith Level: beginner 928*dc4c0fb0SBarry Smith 92911ca99fdSLois Curfman McInnes Notes: 930ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 931ec5066bdSBarry Smith 932f6dfbefdSBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix free, and computing explicitly with 933f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 93483e2fdc7SBarry Smith 935*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9369b94acceSBarry Smith @*/ 937d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions(SNES snes) 938d71ae5a4SJacob Faibussowitsch { 9398afaa268SBarry Smith PetscBool flg, pcset, persist, set; 940d8f46077SPeter Brune PetscInt i, indx, lag, grids; 94104d7464bSBarry Smith const char *deft = SNESNEWTONLS; 942649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 94385385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9440f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 945c40d0f55SPeter Brune PCSide pcside; 946a64e098fSPeter Brune const char *optionsprefix; 9479b94acceSBarry Smith 9483a40ed3dSBarry Smith PetscFunctionBegin; 9490700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9509566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 951d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 952639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9539566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 954d64ed03dSBarry Smith if (flg) { 9559566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9567adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9579566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 958d64ed03dSBarry Smith } 9599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9609566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 961186905e3SBarry Smith 9629566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9639566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9649566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9669566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9679566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9689566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9699566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9709566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 97185385478SLisandro Dalcin 9729566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 973a8054027SBarry Smith if (flg) { 9745f80ce2aSJacob 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"); 9759566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 976a8054027SBarry Smith } 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9781baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9799566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 980e35cf81dSBarry Smith if (flg) { 9815f80ce2aSJacob 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"); 9829566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 983e35cf81dSBarry Smith } 9849566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9851baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 98637ec4e1aSPeter Brune 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9881baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 989a8054027SBarry Smith 9909566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg)); 99185385478SLisandro Dalcin if (flg) { 99285385478SLisandro Dalcin switch (indx) { 993d71ae5a4SJacob Faibussowitsch case 0: 994d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); 995d71ae5a4SJacob Faibussowitsch break; 996d71ae5a4SJacob Faibussowitsch case 1: 997d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); 998d71ae5a4SJacob Faibussowitsch break; 999d71ae5a4SJacob Faibussowitsch case 2: 1000d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); 1001d71ae5a4SJacob Faibussowitsch break; 100285385478SLisandro Dalcin } 100385385478SLisandro Dalcin } 100485385478SLisandro Dalcin 10059566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 10069566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 1007fdacfa88SPeter Brune 10089566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 10099566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 1010186905e3SBarry Smith 101185385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 101285385478SLisandro Dalcin 10139566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 1014186905e3SBarry Smith 10150f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 10160f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 10170f0abf79SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)snes), ewprefix)); 10180f0abf79SStefano Zampini 10199566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_ksp_ew_version", "Version 1, 2 or 3", "SNESKSPSetParametersEW", kctx->version, &kctx->version, NULL)); 10209566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0", "0 <= rtol0 < 1", "SNESKSPSetParametersEW", kctx->rtol_0, &kctx->rtol_0, NULL)); 10219566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax", "0 <= rtolmax < 1", "SNESKSPSetParametersEW", kctx->rtol_max, &kctx->rtol_max, NULL)); 10229566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma", "0 <= gamma <= 1", "SNESKSPSetParametersEW", kctx->gamma, &kctx->gamma, NULL)); 10239566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha", "1 < alpha <= 2", "SNESKSPSetParametersEW", kctx->alpha, &kctx->alpha, NULL)); 10249566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2", "alpha2", "SNESKSPSetParametersEW", kctx->alpha2, &kctx->alpha2, NULL)); 10259566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold", "0 < threshold < 1", "SNESKSPSetParametersEW", kctx->threshold, &kctx->threshold, NULL)); 1026186905e3SBarry Smith 102790d69ab7SBarry Smith flg = PETSC_FALSE; 10289566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 10299566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1030eabae89aSBarry Smith 10319566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 10329566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10339566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1034eabae89aSBarry Smith 10359566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10369566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10379566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10389566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10399566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10409566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10419566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10429566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10432db13446SMatthew G. Knepley 10449566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10459566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10465180491cSLisandro Dalcin 104790d69ab7SBarry Smith flg = PETSC_FALSE; 10489566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1049459f5d12SBarry Smith if (flg) { 1050459f5d12SBarry Smith PetscViewer ctx; 1051e24b481bSBarry Smith 10529566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10539566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1054459f5d12SBarry Smith } 10552e7541e6SPeter Brune 105690d69ab7SBarry Smith flg = PETSC_FALSE; 10579566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10589566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1059c4421ceaSFande Kong 1060c4421ceaSFande Kong flg = PETSC_FALSE; 10619566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10624b27c08aSLois Curfman McInnes if (flg) { 10636cab3a1bSJed Brown void *functx; 1064b1f624c7SBarry Smith DM dm; 10659566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1066800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10679566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10689566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10699566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10709b94acceSBarry Smith } 1071639f9d9dSBarry Smith 107244848bc4SPeter Brune flg = PETSC_FALSE; 10739566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10741baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 107597584545SPeter Brune 107697584545SPeter Brune flg = PETSC_FALSE; 10779566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 107844848bc4SPeter Brune if (flg) { 1079c52e227fSPeter Brune DM dm; 10809566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1081800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10829566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10839566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 108444848bc4SPeter Brune } 108544848bc4SPeter Brune 1086aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10879566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1088d8f46077SPeter Brune if (flg && snes->mf_operator) { 1089a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1090d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1091a8248277SBarry Smith } 1092aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10939566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1094d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10959566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1096d28543b3SPeter Brune 1097c40d0f55SPeter Brune flg = PETSC_FALSE; 10989566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 10999566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 11009566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1101c40d0f55SPeter Brune 1102e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 11038a70d858SHong Zhang /* 11048a70d858SHong Zhang Publish convergence information using SAWs 11058a70d858SHong Zhang */ 11068a70d858SHong Zhang flg = PETSC_FALSE; 11079566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 11088a70d858SHong Zhang if (flg) { 11098a70d858SHong Zhang void *ctx; 11109566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 11119566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 11128a70d858SHong Zhang } 11138a70d858SHong Zhang #endif 11148a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1115b90c6cbeSBarry Smith { 1116b90c6cbeSBarry Smith PetscBool set; 1117b90c6cbeSBarry Smith flg = PETSC_FALSE; 11189566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 11191baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1120b90c6cbeSBarry Smith } 1121b90c6cbeSBarry Smith #endif 1122b90c6cbeSBarry Smith 112348a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 112476b2cf59SMatthew Knepley 1125dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 11265d973c19SBarry Smith 11275d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1128dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1129d0609cedSBarry Smith PetscOptionsEnd(); 11304bbc92c1SBarry Smith 1131d8d34be6SBarry Smith if (snes->linesearch) { 11329566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11339566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1134d8d34be6SBarry Smith } 11359e764e56SPeter Brune 11366aa5e7e9SBarry Smith if (snes->usesksp) { 11379566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11389566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11399566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11406aa5e7e9SBarry Smith } 11416991f827SBarry Smith 1142b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11439566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11449566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 114548a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11461baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1147b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 11483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1149b3cd9a81SMatthew G. Knepley } 1150b3cd9a81SMatthew G. Knepley 1151b3cd9a81SMatthew G. Knepley /*@ 1152f6dfbefdSBarry Smith SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options 1153b3cd9a81SMatthew G. Knepley 1154c3339decSBarry Smith Collective 1155b3cd9a81SMatthew G. Knepley 1156b3cd9a81SMatthew G. Knepley Input Parameter: 1157f6dfbefdSBarry Smith . snes - the `SNES` context 1158b3cd9a81SMatthew G. Knepley 1159b3cd9a81SMatthew G. Knepley Level: beginner 1160b3cd9a81SMatthew G. Knepley 1161*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1162b3cd9a81SMatthew G. Knepley @*/ 1163d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESResetFromOptions(SNES snes) 1164d71ae5a4SJacob Faibussowitsch { 1165b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11669566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11689b94acceSBarry Smith } 11699b94acceSBarry Smith 1170bb9467b5SJed Brown /*@C 1171d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1172d25893d9SBarry Smith the nonlinear solvers. 1173d25893d9SBarry Smith 1174*dc4c0fb0SBarry Smith Logically Collective; No Fortran Support 1175d25893d9SBarry Smith 1176d25893d9SBarry Smith Input Parameters: 1177f6dfbefdSBarry Smith + snes - the `SNES` context 1178d25893d9SBarry Smith . compute - function to compute the context 1179d25893d9SBarry Smith - destroy - function to destroy the context 1180d25893d9SBarry Smith 1181d25893d9SBarry Smith Level: intermediate 1182d25893d9SBarry Smith 1183f6dfbefdSBarry Smith Note: 1184f6dfbefdSBarry Smith This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level. 1185f6dfbefdSBarry Smith 1186f6dfbefdSBarry Smith Use `SNESSetApplicationContext()` to see the context immediately 1187f6dfbefdSBarry Smith 1188*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESSetApplicationContext()` 1189d25893d9SBarry Smith @*/ 1190d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) 1191d71ae5a4SJacob Faibussowitsch { 1192d25893d9SBarry Smith PetscFunctionBegin; 1193d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1194d25893d9SBarry Smith snes->ops->usercompute = compute; 1195d25893d9SBarry Smith snes->ops->userdestroy = destroy; 11963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1197d25893d9SBarry Smith } 1198a847f771SSatish Balay 1199b07ff414SBarry Smith /*@ 1200f6dfbefdSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers. 12019b94acceSBarry Smith 1202c3339decSBarry Smith Logically Collective 1203fee21e36SBarry Smith 1204c7afd0dbSLois Curfman McInnes Input Parameters: 1205f6dfbefdSBarry Smith + snes - the `SNES` context 1206c7afd0dbSLois Curfman McInnes - usrP - optional user context 1207c7afd0dbSLois Curfman McInnes 120836851e7fSLois Curfman McInnes Level: intermediate 120936851e7fSLois Curfman McInnes 1210f6dfbefdSBarry Smith Notes: 1211f6dfbefdSBarry Smith Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function 1212f6dfbefdSBarry Smith with `SNESGetApplicationContext()` 1213f6dfbefdSBarry Smith 1214f6dfbefdSBarry Smith To provide a function that computes the context for you use `SNESSetComputeApplicationContext()` 1215f6dfbefdSBarry Smith 1216f6dfbefdSBarry Smith Fortran Note: 1217*dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1218daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1219daf670e6SBarry Smith 1220*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 12219b94acceSBarry Smith @*/ 1222d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) 1223d71ae5a4SJacob Faibussowitsch { 1224b07ff414SBarry Smith KSP ksp; 12251b2093e4SBarry Smith 12263a40ed3dSBarry Smith PetscFunctionBegin; 12270700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12289566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 12299566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 12309b94acceSBarry Smith snes->user = usrP; 12313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12329b94acceSBarry Smith } 123374679c65SBarry Smith 1234b07ff414SBarry Smith /*@ 12359b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 1236f6dfbefdSBarry Smith nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()` 12379b94acceSBarry Smith 1238c7afd0dbSLois Curfman McInnes Not Collective 1239c7afd0dbSLois Curfman McInnes 12409b94acceSBarry Smith Input Parameter: 1241f6dfbefdSBarry Smith . snes - `SNES` context 12429b94acceSBarry Smith 12439b94acceSBarry Smith Output Parameter: 12449b94acceSBarry Smith . usrP - user context 12459b94acceSBarry Smith 124636851e7fSLois Curfman McInnes Level: intermediate 124736851e7fSLois Curfman McInnes 1248*dc4c0fb0SBarry Smith Fortran Note: 1249*dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1250*dc4c0fb0SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1251*dc4c0fb0SBarry Smith 1252*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetApplicationContext()` 12539b94acceSBarry Smith @*/ 1254d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) 1255d71ae5a4SJacob Faibussowitsch { 12563a40ed3dSBarry Smith PetscFunctionBegin; 12570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1258e71120c6SJed Brown *(void **)usrP = snes->user; 12593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12609b94acceSBarry Smith } 126174679c65SBarry Smith 12629b94acceSBarry Smith /*@ 1263f6dfbefdSBarry Smith SNESSetUseMatrixFree - indicates that `SNES` should use matrix free finite difference matrix vector products to apply the Jacobian. 12643565c898SBarry Smith 1265*dc4c0fb0SBarry Smith Logically Collective 12663565c898SBarry Smith 12673565c898SBarry Smith Input Parameters: 1268f6dfbefdSBarry Smith + snes - `SNES` context 1269f6dfbefdSBarry Smith . mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1270f6dfbefdSBarry 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 1271f6dfbefdSBarry Smith this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available 12723565c898SBarry Smith 1273f6dfbefdSBarry Smith Options Database Keys: 1274f6dfbefdSBarry Smith + -snes_mf_operator - use matrix free only for the mat operator 1275f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator 1276ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1277ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12783565c898SBarry Smith 12793565c898SBarry Smith Level: intermediate 12803565c898SBarry Smith 1281f6dfbefdSBarry Smith Note: 1282*dc4c0fb0SBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 1283f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 1284ec5066bdSBarry Smith 1285*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12863565c898SBarry Smith @*/ 1287d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) 1288d71ae5a4SJacob Faibussowitsch { 12893565c898SBarry Smith PetscFunctionBegin; 12903565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 129188b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 129288b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12934ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12943565c898SBarry Smith snes->mf_operator = mf_operator; 12953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12963565c898SBarry Smith } 12973565c898SBarry Smith 12983565c898SBarry Smith /*@ 1299*dc4c0fb0SBarry Smith SNESGetUseMatrixFree - indicates if the `SNES` uses matrix-free finite difference matrix vector products to apply the Jacobian. 13003565c898SBarry Smith 1301f6dfbefdSBarry Smith Not Collective, but the resulting flags will be the same on all MPI ranks 13023565c898SBarry Smith 13033565c898SBarry Smith Input Parameter: 1304f6dfbefdSBarry Smith . snes - `SNES` context 13053565c898SBarry Smith 13063565c898SBarry Smith Output Parameters: 1307f6dfbefdSBarry Smith + mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1308f6dfbefdSBarry 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 13093565c898SBarry Smith 13103565c898SBarry Smith Level: intermediate 13113565c898SBarry Smith 1312*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 13133565c898SBarry Smith @*/ 1314d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) 1315d71ae5a4SJacob Faibussowitsch { 13163565c898SBarry Smith PetscFunctionBegin; 13173565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13183565c898SBarry Smith if (mf) *mf = snes->mf; 13193565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13213565c898SBarry Smith } 13223565c898SBarry Smith 13233565c898SBarry Smith /*@ 1324c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1325c8228a4eSBarry Smith at this time. 13269b94acceSBarry Smith 1327c7afd0dbSLois Curfman McInnes Not Collective 1328c7afd0dbSLois Curfman McInnes 13299b94acceSBarry Smith Input Parameter: 1330f6dfbefdSBarry Smith . snes - `SNES` context 13319b94acceSBarry Smith 13329b94acceSBarry Smith Output Parameter: 13339b94acceSBarry Smith . iter - iteration number 13349b94acceSBarry Smith 1335*dc4c0fb0SBarry Smith Level: intermediate 1336*dc4c0fb0SBarry Smith 1337c8228a4eSBarry Smith Notes: 1338c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1339c8228a4eSBarry Smith 1340c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 1341f6dfbefdSBarry Smith Jacobian at each `SNES` iteration). For example, the code 134208405cd6SLois Curfman McInnes .vb 134308405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 134408405cd6SLois Curfman McInnes if (!(it % 2)) { 134508405cd6SLois Curfman McInnes [compute Jacobian here] 134608405cd6SLois Curfman McInnes } 134708405cd6SLois Curfman McInnes .ve 1348f6dfbefdSBarry Smith can be used in your function that computes the Jacobian to cause the Jacobian to be 1349f6dfbefdSBarry Smith recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()` 1350c8228a4eSBarry Smith 1351f6dfbefdSBarry Smith After the `SNES` solve is complete this will return the number of nonlinear iterations used. 1352c04deec6SBarry Smith 1353*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()` 13549b94acceSBarry Smith @*/ 1355d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) 1356d71ae5a4SJacob Faibussowitsch { 13573a40ed3dSBarry Smith PetscFunctionBegin; 13580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13594482741eSBarry Smith PetscValidIntPointer(iter, 2); 13609b94acceSBarry Smith *iter = snes->iter; 13613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13629b94acceSBarry Smith } 136374679c65SBarry Smith 1364360c497dSPeter Brune /*@ 1365360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1366360c497dSPeter Brune 1367360c497dSPeter Brune Not Collective 1368360c497dSPeter Brune 1369d8d19677SJose E. Roman Input Parameters: 1370f6dfbefdSBarry Smith + snes - `SNES` context 1371a2b725a8SWilliam Gropp - iter - iteration number 1372360c497dSPeter Brune 1373360c497dSPeter Brune Level: developer 1374360c497dSPeter Brune 1375*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetLinearSolveIterations()` 1376360c497dSPeter Brune @*/ 1377d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) 1378d71ae5a4SJacob Faibussowitsch { 1379360c497dSPeter Brune PetscFunctionBegin; 1380360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13819566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1382360c497dSPeter Brune snes->iter = iter; 13839566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 13843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1385360c497dSPeter Brune } 1386360c497dSPeter Brune 13879b94acceSBarry Smith /*@ 1388b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13899b94acceSBarry Smith attempted by the nonlinear solver. 13909b94acceSBarry Smith 1391c7afd0dbSLois Curfman McInnes Not Collective 1392c7afd0dbSLois Curfman McInnes 13939b94acceSBarry Smith Input Parameter: 1394f6dfbefdSBarry Smith . snes - `SNES` context 13959b94acceSBarry Smith 13969b94acceSBarry Smith Output Parameter: 13979b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13989b94acceSBarry Smith 1399*dc4c0fb0SBarry Smith Level: intermediate 1400*dc4c0fb0SBarry Smith 1401f6dfbefdSBarry Smith Note: 1402f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 1403c96a6f78SLois Curfman McInnes 1404*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1405db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 14069b94acceSBarry Smith @*/ 1407d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) 1408d71ae5a4SJacob Faibussowitsch { 14093a40ed3dSBarry Smith PetscFunctionBegin; 14100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14114482741eSBarry Smith PetscValidIntPointer(nfails, 2); 141250ffb88aSMatthew Knepley *nfails = snes->numFailures; 14133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 141450ffb88aSMatthew Knepley } 141550ffb88aSMatthew Knepley 141650ffb88aSMatthew Knepley /*@ 1417b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1418f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 141950ffb88aSMatthew Knepley 142050ffb88aSMatthew Knepley Not Collective 142150ffb88aSMatthew Knepley 142250ffb88aSMatthew Knepley Input Parameters: 1423f6dfbefdSBarry Smith + snes - `SNES` context 142450ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 142550ffb88aSMatthew Knepley 142650ffb88aSMatthew Knepley Level: intermediate 142750ffb88aSMatthew Knepley 1428*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1429db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 143050ffb88aSMatthew Knepley @*/ 1431d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1432d71ae5a4SJacob Faibussowitsch { 143350ffb88aSMatthew Knepley PetscFunctionBegin; 14340700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 143550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 14363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 143750ffb88aSMatthew Knepley } 143850ffb88aSMatthew Knepley 143950ffb88aSMatthew Knepley /*@ 1440b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1441f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 144250ffb88aSMatthew Knepley 144350ffb88aSMatthew Knepley Not Collective 144450ffb88aSMatthew Knepley 144550ffb88aSMatthew Knepley Input Parameter: 144650ffb88aSMatthew Knepley . snes - SNES context 144750ffb88aSMatthew Knepley 144850ffb88aSMatthew Knepley Output Parameter: 144950ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 145050ffb88aSMatthew Knepley 145150ffb88aSMatthew Knepley Level: intermediate 145250ffb88aSMatthew Knepley 1453*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1454db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 145550ffb88aSMatthew Knepley @*/ 1456d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1457d71ae5a4SJacob Faibussowitsch { 145850ffb88aSMatthew Knepley PetscFunctionBegin; 14590700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14604482741eSBarry Smith PetscValidIntPointer(maxFails, 2); 146150ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14639b94acceSBarry Smith } 1464a847f771SSatish Balay 14652541af92SBarry Smith /*@ 14662541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1467f6dfbefdSBarry Smith done by the `SNES` object 14682541af92SBarry Smith 14692541af92SBarry Smith Not Collective 14702541af92SBarry Smith 14712541af92SBarry Smith Input Parameter: 1472f6dfbefdSBarry Smith . snes - `SNES` context 14732541af92SBarry Smith 14742541af92SBarry Smith Output Parameter: 14752541af92SBarry Smith . nfuncs - number of evaluations 14762541af92SBarry Smith 14772541af92SBarry Smith Level: intermediate 14782541af92SBarry Smith 1479f6dfbefdSBarry Smith Note: 1480f6dfbefdSBarry Smith Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used. 1481971e163fSPeter Brune 1482*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14832541af92SBarry Smith @*/ 1484d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1485d71ae5a4SJacob Faibussowitsch { 14862541af92SBarry Smith PetscFunctionBegin; 14870700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14882541af92SBarry Smith PetscValidIntPointer(nfuncs, 2); 14892541af92SBarry Smith *nfuncs = snes->nfuncs; 14903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14912541af92SBarry Smith } 14922541af92SBarry Smith 14933d4c4710SBarry Smith /*@ 14943d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14953d4c4710SBarry Smith linear solvers. 14963d4c4710SBarry Smith 14973d4c4710SBarry Smith Not Collective 14983d4c4710SBarry Smith 14993d4c4710SBarry Smith Input Parameter: 1500f6dfbefdSBarry Smith . snes - `SNES` context 15013d4c4710SBarry Smith 15023d4c4710SBarry Smith Output Parameter: 15033d4c4710SBarry Smith . nfails - number of failed solves 15043d4c4710SBarry Smith 1505f6dfbefdSBarry Smith Options Database Key: 15069d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15079d85da0cSMatthew G. Knepley 1508f6dfbefdSBarry Smith Level: intermediate 1509f6dfbefdSBarry Smith 1510f6dfbefdSBarry Smith Note: 1511f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 15123d4c4710SBarry Smith 1513*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 15143d4c4710SBarry Smith @*/ 1515d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) 1516d71ae5a4SJacob Faibussowitsch { 15173d4c4710SBarry Smith PetscFunctionBegin; 15180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15193d4c4710SBarry Smith PetscValidIntPointer(nfails, 2); 15203d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15223d4c4710SBarry Smith } 15233d4c4710SBarry Smith 15243d4c4710SBarry Smith /*@ 15253d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1526f6dfbefdSBarry Smith allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE` 15273d4c4710SBarry Smith 1528c3339decSBarry Smith Logically Collective 15293d4c4710SBarry Smith 15303d4c4710SBarry Smith Input Parameters: 1531f6dfbefdSBarry Smith + snes - `SNES` context 15323d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15333d4c4710SBarry Smith 1534f6dfbefdSBarry Smith Options Database Key: 15359d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15369d85da0cSMatthew G. Knepley 1537*dc4c0fb0SBarry Smith Level: intermediate 1538*dc4c0fb0SBarry Smith 1539f6dfbefdSBarry Smith Note: 1540f6dfbefdSBarry Smith By default this is 0; that is `SNES` returns on the first failed linear solve 15413d4c4710SBarry Smith 1542*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15433d4c4710SBarry Smith @*/ 1544d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1545d71ae5a4SJacob Faibussowitsch { 15463d4c4710SBarry Smith PetscFunctionBegin; 15470700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1548c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15493d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15513d4c4710SBarry Smith } 15523d4c4710SBarry Smith 15533d4c4710SBarry Smith /*@ 15543d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1555f6dfbefdSBarry Smith are allowed before `SNES` returns as unsuccessful 15563d4c4710SBarry Smith 15573d4c4710SBarry Smith Not Collective 15583d4c4710SBarry Smith 15593d4c4710SBarry Smith Input Parameter: 1560f6dfbefdSBarry Smith . snes - `SNES` context 15613d4c4710SBarry Smith 15623d4c4710SBarry Smith Output Parameter: 15633d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15643d4c4710SBarry Smith 15653d4c4710SBarry Smith Level: intermediate 15663d4c4710SBarry Smith 1567f6dfbefdSBarry Smith Note: 1568f6dfbefdSBarry Smith By default this is 1; that is `SNES` returns on the first failed linear solve 15693d4c4710SBarry Smith 1570*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15713d4c4710SBarry Smith @*/ 1572d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1573d71ae5a4SJacob Faibussowitsch { 15743d4c4710SBarry Smith PetscFunctionBegin; 15750700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15763d4c4710SBarry Smith PetscValidIntPointer(maxFails, 2); 15773d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15793d4c4710SBarry Smith } 15803d4c4710SBarry Smith 1581c96a6f78SLois Curfman McInnes /*@ 1582b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1583c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1584c96a6f78SLois Curfman McInnes 1585c7afd0dbSLois Curfman McInnes Not Collective 1586c7afd0dbSLois Curfman McInnes 1587c96a6f78SLois Curfman McInnes Input Parameter: 1588f6dfbefdSBarry Smith . snes - `SNES` context 1589c96a6f78SLois Curfman McInnes 1590c96a6f78SLois Curfman McInnes Output Parameter: 1591c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1592c96a6f78SLois Curfman McInnes 1593*dc4c0fb0SBarry Smith Level: intermediate 1594*dc4c0fb0SBarry Smith 1595c96a6f78SLois Curfman McInnes Notes: 1596f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used. 1597c96a6f78SLois Curfman McInnes 1598f6dfbefdSBarry 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 1599f6dfbefdSBarry Smith then call `KSPGetIterationNumber()` after the failed solve. 1600010be392SBarry Smith 1601*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1602c96a6f78SLois Curfman McInnes @*/ 1603d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) 1604d71ae5a4SJacob Faibussowitsch { 16053a40ed3dSBarry Smith PetscFunctionBegin; 16060700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16074482741eSBarry Smith PetscValidIntPointer(lits, 2); 1608c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 16093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1610c96a6f78SLois Curfman McInnes } 1611c96a6f78SLois Curfman McInnes 1612971e163fSPeter Brune /*@ 1613971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1614f6dfbefdSBarry Smith are reset every time `SNESSolve()` is called. 1615971e163fSPeter Brune 1616c3339decSBarry Smith Logically Collective 1617971e163fSPeter Brune 1618d8d19677SJose E. Roman Input Parameters: 1619f6dfbefdSBarry Smith + snes - `SNES` context 1620f6dfbefdSBarry Smith - reset - whether to reset the counters or not, defaults to `PETSC_TRUE` 1621971e163fSPeter Brune 1622971e163fSPeter Brune Level: developer 1623971e163fSPeter Brune 1624*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1625971e163fSPeter Brune @*/ 1626d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) 1627d71ae5a4SJacob Faibussowitsch { 1628971e163fSPeter Brune PetscFunctionBegin; 1629971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1630971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1631971e163fSPeter Brune snes->counters_reset = reset; 16323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1633971e163fSPeter Brune } 1634971e163fSPeter Brune 16352999313aSBarry Smith /*@ 1636f6dfbefdSBarry Smith SNESSetKSP - Sets a `KSP` context for the `SNES` object to use 16372999313aSBarry Smith 1638f6dfbefdSBarry Smith Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm 16392999313aSBarry Smith 16402999313aSBarry Smith Input Parameters: 1641f6dfbefdSBarry Smith + snes - the `SNES` context 1642f6dfbefdSBarry Smith - ksp - the `KSP` context 16432999313aSBarry Smith 1644*dc4c0fb0SBarry Smith Level: developer 1645*dc4c0fb0SBarry Smith 16462999313aSBarry Smith Notes: 1647f6dfbefdSBarry Smith The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()` 16482999313aSBarry Smith so this routine is rarely needed. 16492999313aSBarry Smith 1650f6dfbefdSBarry Smith The `KSP` object that is already in the `SNES` object has its reference count 16512999313aSBarry Smith decreased by one. 16522999313aSBarry Smith 1653*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16542999313aSBarry Smith @*/ 1655d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) 1656d71ae5a4SJacob Faibussowitsch { 16572999313aSBarry Smith PetscFunctionBegin; 16580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16590700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16602999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16619566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16629566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16632999313aSBarry Smith snes->ksp = ksp; 16643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16652999313aSBarry Smith } 16662999313aSBarry Smith 166752baeb72SSatish Balay /*@ 1668*dc4c0fb0SBarry Smith SNESCreate - Creates a nonlinear solver context used to manage a set of nonlinear solves 16699b94acceSBarry Smith 1670d083f849SBarry Smith Collective 1671c7afd0dbSLois Curfman McInnes 1672f6dfbefdSBarry Smith Input Parameter: 1673906ed7ccSBarry Smith . comm - MPI communicator 16749b94acceSBarry Smith 16759b94acceSBarry Smith Output Parameter: 16769b94acceSBarry Smith . outsnes - the new SNES context 16779b94acceSBarry Smith 1678c7afd0dbSLois Curfman McInnes Options Database Keys: 1679*dc4c0fb0SBarry Smith + -snes_mf - Activates default matrix-free Jacobian-vector products, and no preconditioning matrix 1680*dc4c0fb0SBarry Smith . -snes_mf_operator - Activates default matrix-free Jacobian-vector products, and a user-provided preconditioning matrix 1681*dc4c0fb0SBarry Smith as set by `SNESSetJacobian()` 1682*dc4c0fb0SBarry Smith . -snes_fd_coloring - uses a relative fast computation of the Jacobian using finite differences and a graph coloring 1683c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1684c1f60f51SBarry Smith 168536851e7fSLois Curfman McInnes Level: beginner 168636851e7fSLois Curfman McInnes 168795452b02SPatrick Sanan Developer Notes: 1688f6dfbefdSBarry Smith `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is 1689efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1690f6dfbefdSBarry Smith particular method does use `KSP` and regulates if the information about the `KSP` is printed 1691f6dfbefdSBarry Smith in `SNESView()`. 1692efd4aadfSBarry Smith 1693f6dfbefdSBarry Smith `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused 1694f6dfbefdSBarry Smith by help messages about meaningless `SNES` options. 1695f6dfbefdSBarry Smith 1696*dc4c0fb0SBarry Smith `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should be fixed. 1697efd4aadfSBarry Smith 1698*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 16999b94acceSBarry Smith @*/ 1700d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) 1701d71ae5a4SJacob Faibussowitsch { 17029b94acceSBarry Smith SNES snes; 1703fa9f3622SBarry Smith SNESKSPEW *kctx; 170437fcc0dbSBarry Smith 17053a40ed3dSBarry Smith PetscFunctionBegin; 1706ed1caa07SMatthew Knepley PetscValidPointer(outsnes, 2); 17070298fd71SBarry Smith *outsnes = NULL; 17089566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 17098ba1e511SMatthew Knepley 17109566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 17117adad957SLisandro Dalcin 17128d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17132c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 171488976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17159b94acceSBarry Smith snes->max_its = 50; 17169750a799SBarry Smith snes->max_funcs = 10000; 17179b94acceSBarry Smith snes->norm = 0.0; 1718c1e67a49SFande Kong snes->xnorm = 0.0; 1719c1e67a49SFande Kong snes->ynorm = 0.0; 1720365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17216c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17223a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17233a2046daSBarry Smith snes->rtol = 1.e-5; 17243a2046daSBarry Smith #else 1725b4874afaSBarry Smith snes->rtol = 1.e-8; 17263a2046daSBarry Smith #endif 1727b4874afaSBarry Smith snes->ttol = 0.0; 17283a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17293a2046daSBarry Smith snes->abstol = 1.e-25; 17303a2046daSBarry Smith #else 173170441072SBarry Smith snes->abstol = 1.e-50; 17323a2046daSBarry Smith #endif 17337cd0ae37SLisandro Dalcin #if defined(PETSC_USE_REAL_SINGLE) 17347cd0ae37SLisandro Dalcin snes->stol = 1.e-5; 17357cd0ae37SLisandro Dalcin #else 1736c60f73f4SPeter Brune snes->stol = 1.e-8; 17377cd0ae37SLisandro Dalcin #endif 17383a2046daSBarry Smith #if defined(PETSC_USE_REAL_SINGLE) 17393a2046daSBarry Smith snes->deltatol = 1.e-6; 17403a2046daSBarry Smith #else 17414b27c08aSLois Curfman McInnes snes->deltatol = 1.e-12; 17423a2046daSBarry Smith #endif 1743e37c518bSBarry Smith snes->divtol = 1.e4; 1744e37c518bSBarry Smith snes->rnorm0 = 0; 17459b94acceSBarry Smith snes->nfuncs = 0; 174650ffb88aSMatthew Knepley snes->numFailures = 0; 174750ffb88aSMatthew Knepley snes->maxFailures = 1; 17487a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1749e35cf81dSBarry Smith snes->lagjacobian = 1; 175037ec4e1aSPeter Brune snes->jac_iter = 0; 175137ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1752a8054027SBarry Smith snes->lagpreconditioner = 1; 175337ec4e1aSPeter Brune snes->pre_iter = 0; 175437ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1755639f9d9dSBarry Smith snes->numbermonitors = 0; 1756c4421ceaSFande Kong snes->numberreasonviews = 0; 17579e5d0892SLisandro Dalcin snes->data = NULL; 17584dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1759186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17606f24a144SLois Curfman McInnes snes->nwork = 0; 17619e5d0892SLisandro Dalcin snes->work = NULL; 176258c9b817SLisandro Dalcin snes->nvwork = 0; 17639e5d0892SLisandro Dalcin snes->vwork = NULL; 1764758f92a0SBarry Smith snes->conv_hist_len = 0; 1765758f92a0SBarry Smith snes->conv_hist_max = 0; 17660298fd71SBarry Smith snes->conv_hist = NULL; 17670298fd71SBarry Smith snes->conv_hist_its = NULL; 1768758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1769971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1770e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1771184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1772efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1773b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1774c40d0f55SPeter Brune 1775d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1776d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1777d8f46077SPeter Brune snes->mf_version = 1; 1778d8f46077SPeter Brune 17793d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17803d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17813d4c4710SBarry Smith 1782349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 178376bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1784349187a7SBarry Smith 17854fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17864fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17874fc747eaSLawrence Mitchell 17889b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17894dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&kctx)); 1790f5af7f23SKarl Rupp 17919b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17929b94acceSBarry Smith kctx->version = 2; 17930f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17949b94acceSBarry Smith this was too large for some test cases */ 179575567043SBarry Smith kctx->rtol_last = 0.0; 17960f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17979b94acceSBarry Smith kctx->gamma = 1.0; 17980f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 179971f87433Sdalcinl kctx->alpha2 = kctx->alpha; 18000f0abf79SStefano Zampini kctx->threshold = 0.1; 180175567043SBarry Smith kctx->lresid_last = 0.0; 180275567043SBarry Smith kctx->norm_last = 0.0; 18039b94acceSBarry Smith 18040f0abf79SStefano Zampini kctx->rk_last = 0.0; 18050f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 18060f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 18070f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 18080f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 18090f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 18100f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 18110f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 18120f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 18130f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 18140f0abf79SStefano Zampini 18159b94acceSBarry Smith *outsnes = snes; 18163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18179b94acceSBarry Smith } 18189b94acceSBarry Smith 181988f0584fSBarry Smith /*MC 1820f6dfbefdSBarry Smith SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()` 182188f0584fSBarry Smith 182288f0584fSBarry Smith Synopsis: 1823411c0326SBarry Smith #include "petscsnes.h" 1824411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 182588f0584fSBarry Smith 1826c3339decSBarry Smith Collective 18271843f636SBarry Smith 182888f0584fSBarry Smith Input Parameters: 1829f6dfbefdSBarry Smith + snes - the `SNES` context 183088f0584fSBarry Smith . x - state at which to evaluate residual 1831f6dfbefdSBarry Smith - ctx - optional user-defined function context, passed in with `SNESSetFunction()` 183288f0584fSBarry Smith 183388f0584fSBarry Smith Output Parameter: 183488f0584fSBarry Smith . f - vector to put residual (function value) 183588f0584fSBarry Smith 1836878cb397SSatish Balay Level: intermediate 1837878cb397SSatish Balay 1838*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunction()`, `SNESGetFunction()` 183988f0584fSBarry Smith M*/ 184088f0584fSBarry Smith 18419b94acceSBarry Smith /*@C 18429b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 1843f6dfbefdSBarry Smith vector for use by the `SNES` routines in solving systems of nonlinear 18449b94acceSBarry Smith equations. 18459b94acceSBarry Smith 1846c3339decSBarry Smith Logically Collective 1847fee21e36SBarry Smith 1848c7afd0dbSLois Curfman McInnes Input Parameters: 1849f6dfbefdSBarry Smith + snes - the `SNES` context 1850*dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 1851f6dfbefdSBarry Smith . f - function evaluation routine; see `SNESFunction` for calling sequence details 1852c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1853*dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 18549b94acceSBarry Smith 185536851e7fSLois Curfman McInnes Level: beginner 185636851e7fSLois Curfman McInnes 1857*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18589b94acceSBarry Smith @*/ 1859d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 1860d71ae5a4SJacob Faibussowitsch { 18616cab3a1bSJed Brown DM dm; 18626cab3a1bSJed Brown 18633a40ed3dSBarry Smith PetscFunctionBegin; 18640700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1865d2a683ecSLisandro Dalcin if (r) { 1866d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1867d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18689566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18699566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 187085385478SLisandro Dalcin snes->vec_func = r; 1871d2a683ecSLisandro Dalcin } 18729566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18739566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 187448a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18769b94acceSBarry Smith } 18779b94acceSBarry Smith 1878e4ed7901SPeter Brune /*@C 1879e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1880f6dfbefdSBarry Smith initial function value at the initialization of the method. In some 1881e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1882f6dfbefdSBarry Smith `SNESSolve()`. This function allows one to avoid a redundant call 1883f6dfbefdSBarry Smith to `SNESComputeFunction()` in that case. 1884e4ed7901SPeter Brune 1885c3339decSBarry Smith Logically Collective 1886e4ed7901SPeter Brune 1887e4ed7901SPeter Brune Input Parameters: 1888f6dfbefdSBarry Smith + snes - the `SNES` context 1889e4ed7901SPeter Brune - f - vector to store function value 1890e4ed7901SPeter Brune 1891*dc4c0fb0SBarry Smith Level: developer 1892*dc4c0fb0SBarry Smith 1893e4ed7901SPeter Brune Notes: 1894e4ed7901SPeter Brune This should not be modified during the solution procedure. 1895e4ed7901SPeter Brune 1896f6dfbefdSBarry Smith This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning. 1897e4ed7901SPeter Brune 1898*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1899e4ed7901SPeter Brune @*/ 1900d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1901d71ae5a4SJacob Faibussowitsch { 1902e4ed7901SPeter Brune Vec vec_func; 1903e4ed7901SPeter Brune 1904e4ed7901SPeter Brune PetscFunctionBegin; 1905e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1906e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1907e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1908efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1909902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 19103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1911902f982fSPeter Brune } 19129566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 19139566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1914f5af7f23SKarl Rupp 1915217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 19163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1917e4ed7901SPeter Brune } 1918e4ed7901SPeter Brune 1919534ebe21SPeter Brune /*@ 1920f6dfbefdSBarry Smith SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring 1921f6dfbefdSBarry Smith of the `SNES` method, when norms are computed in the solving process 1922534ebe21SPeter Brune 1923c3339decSBarry Smith Logically Collective 1924534ebe21SPeter Brune 1925534ebe21SPeter Brune Input Parameters: 1926f6dfbefdSBarry Smith + snes - the `SNES` context 1927365a6726SPeter Brune - normschedule - the frequency of norm computation 1928534ebe21SPeter Brune 1929517f1916SMatthew G. Knepley Options Database Key: 193067b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1931517f1916SMatthew G. Knepley 1932*dc4c0fb0SBarry Smith Level: advanced 1933*dc4c0fb0SBarry Smith 1934534ebe21SPeter Brune Notes: 1935f6dfbefdSBarry Smith Only certain `SNES` methods support certain `SNESNormSchedules`. Most require evaluation 1936534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1937534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1938f6dfbefdSBarry Smith `SNESNGS` and the like do not require the norm of the function to be computed, and therefore 1939534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1940534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1941534ebe21SPeter Brune their solution. 1942534ebe21SPeter Brune 1943*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1944534ebe21SPeter Brune @*/ 1945d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1946d71ae5a4SJacob Faibussowitsch { 1947534ebe21SPeter Brune PetscFunctionBegin; 1948534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1949365a6726SPeter Brune snes->normschedule = normschedule; 19503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1951534ebe21SPeter Brune } 1952534ebe21SPeter Brune 1953534ebe21SPeter Brune /*@ 1954f6dfbefdSBarry Smith SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring 1955f6dfbefdSBarry Smith of the `SNES` method. 1956534ebe21SPeter Brune 1957c3339decSBarry Smith Logically Collective 1958534ebe21SPeter Brune 1959534ebe21SPeter Brune Input Parameters: 1960f6dfbefdSBarry Smith + snes - the `SNES` context 1961365a6726SPeter Brune - normschedule - the type of the norm used 1962534ebe21SPeter Brune 1963534ebe21SPeter Brune Level: advanced 1964534ebe21SPeter Brune 1965*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1966534ebe21SPeter Brune @*/ 1967d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1968d71ae5a4SJacob Faibussowitsch { 1969534ebe21SPeter Brune PetscFunctionBegin; 1970534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1971365a6726SPeter Brune *normschedule = snes->normschedule; 19723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1973534ebe21SPeter Brune } 1974534ebe21SPeter Brune 1975c5ce4427SMatthew G. Knepley /*@ 1976c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1977c5ce4427SMatthew G. Knepley 1978c3339decSBarry Smith Logically Collective 1979c5ce4427SMatthew G. Knepley 1980c5ce4427SMatthew G. Knepley Input Parameters: 1981f6dfbefdSBarry Smith + snes - the `SNES` context 1982f6dfbefdSBarry Smith - norm - the value of the norm 1983c5ce4427SMatthew G. Knepley 1984c5ce4427SMatthew G. Knepley Level: developer 1985c5ce4427SMatthew G. Knepley 1986*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1987c5ce4427SMatthew G. Knepley @*/ 1988d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1989d71ae5a4SJacob Faibussowitsch { 1990c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1991c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1992c5ce4427SMatthew G. Knepley snes->norm = norm; 19933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1994c5ce4427SMatthew G. Knepley } 1995c5ce4427SMatthew G. Knepley 1996c5ce4427SMatthew G. Knepley /*@ 1997c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1998c5ce4427SMatthew G. Knepley 1999c5ce4427SMatthew G. Knepley Not Collective 2000c5ce4427SMatthew G. Knepley 2001c5ce4427SMatthew G. Knepley Input Parameter: 2002f6dfbefdSBarry Smith . snes - the `SNES` context 2003c5ce4427SMatthew G. Knepley 2004c5ce4427SMatthew G. Knepley Output Parameter: 2005c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 2006c5ce4427SMatthew G. Knepley 2007c5ce4427SMatthew G. Knepley Level: developer 2008c5ce4427SMatthew G. Knepley 2009*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 2010c5ce4427SMatthew G. Knepley @*/ 2011d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 2012d71ae5a4SJacob Faibussowitsch { 2013c5ce4427SMatthew G. Knepley PetscFunctionBegin; 2014c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2015dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 2016c5ce4427SMatthew G. Knepley *norm = snes->norm; 20173ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2018c5ce4427SMatthew G. Knepley } 2019c5ce4427SMatthew G. Knepley 2020c1e67a49SFande Kong /*@ 2021f6dfbefdSBarry Smith SNESGetUpdateNorm - Gets the last computed norm of the solution update 2022c1e67a49SFande Kong 2023c1e67a49SFande Kong Not Collective 2024c1e67a49SFande Kong 2025c1e67a49SFande Kong Input Parameter: 2026f6dfbefdSBarry Smith . snes - the `SNES` context 2027c1e67a49SFande Kong 2028c1e67a49SFande Kong Output Parameter: 2029c1e67a49SFande Kong . ynorm - the last computed update norm 2030c1e67a49SFande Kong 2031c1e67a49SFande Kong Level: developer 2032c1e67a49SFande Kong 2033f6dfbefdSBarry Smith Note: 2034f6dfbefdSBarry Smith The new solution is the current solution plus the update, so this norm is an indication of the size of the update 2035f6dfbefdSBarry Smith 2036*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2037c1e67a49SFande Kong @*/ 2038d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2039d71ae5a4SJacob Faibussowitsch { 2040c1e67a49SFande Kong PetscFunctionBegin; 2041c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2042dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 2043c1e67a49SFande Kong *ynorm = snes->ynorm; 20443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2045c1e67a49SFande Kong } 2046c1e67a49SFande Kong 2047c1e67a49SFande Kong /*@ 20484591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2049c1e67a49SFande Kong 2050c1e67a49SFande Kong Not Collective 2051c1e67a49SFande Kong 2052c1e67a49SFande Kong Input Parameter: 2053f6dfbefdSBarry Smith . snes - the `SNES` context 2054c1e67a49SFande Kong 2055c1e67a49SFande Kong Output Parameter: 2056c1e67a49SFande Kong . xnorm - the last computed solution norm 2057c1e67a49SFande Kong 2058c1e67a49SFande Kong Level: developer 2059c1e67a49SFande Kong 2060*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2061c1e67a49SFande Kong @*/ 2062d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2063d71ae5a4SJacob Faibussowitsch { 2064c1e67a49SFande Kong PetscFunctionBegin; 2065c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2066dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2067c1e67a49SFande Kong *xnorm = snes->xnorm; 20683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2069c1e67a49SFande Kong } 2070c1e67a49SFande Kong 207147073ea2SPeter Brune /*@C 2072f6dfbefdSBarry Smith SNESSetFunctionType - Sets the `SNESFunctionType` 2073f6dfbefdSBarry Smith of the `SNES` method. 207447073ea2SPeter Brune 2075c3339decSBarry Smith Logically Collective 207647073ea2SPeter Brune 207747073ea2SPeter Brune Input Parameters: 2078f6dfbefdSBarry Smith + snes - the `SNES` context 2079f6dfbefdSBarry Smith - type - the function type 208047073ea2SPeter Brune 208147073ea2SPeter Brune Level: developer 208247073ea2SPeter Brune 2083f6dfbefdSBarry Smith Notes: 2084f6dfbefdSBarry Smith Possible values of the function type 2085f6dfbefdSBarry Smith + `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType` 2086f6dfbefdSBarry Smith . `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()` 2087f6dfbefdSBarry Smith - `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()` 2088f6dfbefdSBarry Smith 2089f6dfbefdSBarry Smith Different `SNESType`s use this value in different ways 2090f6dfbefdSBarry Smith 2091*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 209247073ea2SPeter Brune @*/ 2093d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 2094d71ae5a4SJacob Faibussowitsch { 209547073ea2SPeter Brune PetscFunctionBegin; 209647073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 209747073ea2SPeter Brune snes->functype = type; 20983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 209947073ea2SPeter Brune } 210047073ea2SPeter Brune 210147073ea2SPeter Brune /*@C 2102f6dfbefdSBarry Smith SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()` 210347073ea2SPeter Brune of the SNES method. 210447073ea2SPeter Brune 2105c3339decSBarry Smith Logically Collective 210647073ea2SPeter Brune 210747073ea2SPeter Brune Input Parameters: 2108f6dfbefdSBarry Smith + snes - the `SNES` context 2109f6dfbefdSBarry Smith - type - the type of the function evaluation, see `SNESSetFunctionType()` 211047073ea2SPeter Brune 211147073ea2SPeter Brune Level: advanced 211247073ea2SPeter Brune 2113*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 211447073ea2SPeter Brune @*/ 2115d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 2116d71ae5a4SJacob Faibussowitsch { 211747073ea2SPeter Brune PetscFunctionBegin; 211847073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 211947073ea2SPeter Brune *type = snes->functype; 21203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2121534ebe21SPeter Brune } 2122534ebe21SPeter Brune 2123bf388a1fSBarry Smith /*MC 2124f6dfbefdSBarry Smith SNESNGSFunction - function used to apply a Gauss-Seidel sweep on the nonlinear function 2125bf388a1fSBarry Smith 2126bf388a1fSBarry Smith Synopsis: 2127aaa7dc30SBarry Smith #include <petscsnes.h> 2128be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2129bf388a1fSBarry Smith 2130c3339decSBarry Smith Collective 21311843f636SBarry Smith 21321843f636SBarry Smith Input Parameters: 2133bf388a1fSBarry Smith + X - solution vector 2134bf388a1fSBarry Smith . B - RHS vector 2135bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2136bf388a1fSBarry Smith 21371843f636SBarry Smith Output Parameter: 21381843f636SBarry Smith . X - solution vector 21391843f636SBarry Smith 2140878cb397SSatish Balay Level: intermediate 2141878cb397SSatish Balay 2142*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESSetNGS()`, `SNESGetNGS()` 2143bf388a1fSBarry Smith M*/ 2144bf388a1fSBarry Smith 2145c79ef259SPeter Brune /*@C 2146be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2147c79ef259SPeter Brune use with composed nonlinear solvers. 2148c79ef259SPeter Brune 2149c79ef259SPeter Brune Input Parameters: 2150*dc4c0fb0SBarry Smith + snes - the `SNES` context 2151f6dfbefdSBarry Smith . f - function evaluation routine to apply Gauss-Seidel see `SNESNGSFunction` 2152c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 2153*dc4c0fb0SBarry Smith smoother evaluation routine (may be `NULL`) 2154c79ef259SPeter Brune 2155f6dfbefdSBarry Smith Calling sequence of f: 2156f6dfbefdSBarry Smith $ PetscErrorCode f(SNES snes,Vec X,Vec B,void *ctx); 2157f6dfbefdSBarry Smith 2158f6dfbefdSBarry Smith Arguments of f: 2159f6dfbefdSBarry Smith + snes - the `SNES` context 2160f6dfbefdSBarry Smith . X - the current solution 2161*dc4c0fb0SBarry Smith . B - the right hand side vector (which may be `NULL`) 2162f6dfbefdSBarry Smith - ctx - a user provided context 2163f6dfbefdSBarry Smith 2164*dc4c0fb0SBarry Smith Level: intermediate 2165*dc4c0fb0SBarry Smith 2166f6dfbefdSBarry Smith Note: 2167f6dfbefdSBarry Smith The `SNESNGS` routines are used by the composed nonlinear solver to generate 2168f6dfbefdSBarry Smith a problem appropriate update to the solution, particularly `SNESFAS`. 2169c79ef259SPeter Brune 2170*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetNGS()`, `SNESNGSFunction`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()` 2171c79ef259SPeter Brune @*/ 2172d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 2173d71ae5a4SJacob Faibussowitsch { 21746cab3a1bSJed Brown DM dm; 21756cab3a1bSJed Brown 2176646217ecSPeter Brune PetscFunctionBegin; 21776cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21789566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21799566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 21803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2181646217ecSPeter Brune } 2182646217ecSPeter Brune 2183bbc1464cSBarry Smith /* 2184bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2185bbc1464cSBarry Smith changed during the KSPSolve() 2186bbc1464cSBarry Smith */ 2187d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) 2188d71ae5a4SJacob Faibussowitsch { 2189bbc1464cSBarry Smith DM dm; 2190bbc1464cSBarry Smith DMSNES sdm; 2191bbc1464cSBarry Smith 2192bbc1464cSBarry Smith PetscFunctionBegin; 21939566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21949566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2195bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2196bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2197792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21989566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 21990df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2200ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2201792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 22029566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2203bbc1464cSBarry Smith } else { 2204792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 22059566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2206bbc1464cSBarry Smith } 22073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2208bbc1464cSBarry Smith } 2209bbc1464cSBarry Smith 2210d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) 2211d71ae5a4SJacob Faibussowitsch { 2212e03ab78fSPeter Brune DM dm; 2213942e3340SBarry Smith DMSNES sdm; 22146cab3a1bSJed Brown 22158b0a5094SBarry Smith PetscFunctionBegin; 22169566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22179566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 22188b0a5094SBarry Smith /* A(x)*x - b(x) */ 2219bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2220792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 22219566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 2222792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22239566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2224bbc1464cSBarry Smith } else { 2225792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22269566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2227bbc1464cSBarry Smith } 22283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22298b0a5094SBarry Smith } 22308b0a5094SBarry Smith 2231d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) 2232d71ae5a4SJacob Faibussowitsch { 22338b0a5094SBarry Smith PetscFunctionBegin; 2234e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2235bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 22369566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 22379566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 22383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22398b0a5094SBarry Smith } 22408b0a5094SBarry Smith 22418b0a5094SBarry Smith /*@C 2242f6dfbefdSBarry Smith SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22438b0a5094SBarry Smith 2244c3339decSBarry Smith Logically Collective 22458b0a5094SBarry Smith 22468b0a5094SBarry Smith Input Parameters: 2247f6dfbefdSBarry Smith + snes - the `SNES` context 2248*dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 2249*dc4c0fb0SBarry Smith . bp - function evaluation routine, may be `NULL` 22506b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2251*dc4c0fb0SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as `Amat`) 2252*dc4c0fb0SBarry Smith . J - function to compute matrix values, see `SNESJacobianFunction()` for details on its calling sequence 2253*dc4c0fb0SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`) 2254*dc4c0fb0SBarry Smith 2255*dc4c0fb0SBarry Smith Level: intermediate 22568b0a5094SBarry Smith 22578b0a5094SBarry Smith Notes: 22586b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2259f450aa47SBarry 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. 2260f450aa47SBarry Smith 2261f6dfbefdSBarry Smith One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both 22628b0a5094SBarry Smith 2263*dc4c0fb0SBarry 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}. 2264*dc4c0fb0SBarry Smith When an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 22658b0a5094SBarry Smith 2266*dc4c0fb0SBarry Smith Run with `-snes_mf_operator` to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22678b0a5094SBarry Smith 22680d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22696b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22708b0a5094SBarry Smith 22718b0a5094SBarry 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 22728b0a5094SBarry 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 22738b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22748b0a5094SBarry Smith 2275*dc4c0fb0SBarry 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 2276f6dfbefdSBarry Smith A(x^{n}) is used to build the preconditioner 22776b7fb656SBarry Smith 2278*dc4c0fb0SBarry 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. 22796b7fb656SBarry Smith 2280*dc4c0fb0SBarry 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 22816b7fb656SBarry 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 2282f6dfbefdSBarry 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`. 22836b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2284bbc1464cSBarry Smith 2285*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22868b0a5094SBarry Smith @*/ 2287d71ae5a4SJacob Faibussowitsch 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) 2288d71ae5a4SJacob Faibussowitsch { 2289e03ab78fSPeter Brune DM dm; 2290e03ab78fSPeter Brune 22918b0a5094SBarry Smith PetscFunctionBegin; 22928b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22939566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22949566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22959566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22969566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22979566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22983ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22998b0a5094SBarry Smith } 23008b0a5094SBarry Smith 23017971a8bfSPeter Brune /*@C 23027971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 23037971a8bfSPeter Brune 2304f6dfbefdSBarry Smith Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet. 23057971a8bfSPeter Brune 23067971a8bfSPeter Brune Input Parameter: 2307f6dfbefdSBarry Smith . snes - the `SNES` context 23087971a8bfSPeter Brune 2309d8d19677SJose E. Roman Output Parameters: 2310*dc4c0fb0SBarry Smith + r - the function (or `NULL`) 2311*dc4c0fb0SBarry Smith . f - the function (or `NULL`); see `SNESFunction` for calling sequence details 2312*dc4c0fb0SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or `NULL`) 2313*dc4c0fb0SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or `NULL`) 2314*dc4c0fb0SBarry Smith . J - the function for matrix evaluation (or `NULL`); see `SNESJacobianFunction` for calling sequence details 2315*dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 23167971a8bfSPeter Brune 23177971a8bfSPeter Brune Level: advanced 23187971a8bfSPeter Brune 2319*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 23207971a8bfSPeter Brune @*/ 2321d71ae5a4SJacob Faibussowitsch 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) 2322d71ae5a4SJacob Faibussowitsch { 23237971a8bfSPeter Brune DM dm; 23247971a8bfSPeter Brune 23257971a8bfSPeter Brune PetscFunctionBegin; 23267971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23279566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 23289566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 23299566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23309566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 23313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23327971a8bfSPeter Brune } 23337971a8bfSPeter Brune 2334d25893d9SBarry Smith /*@C 2335*dc4c0fb0SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the nonlinear problem 2336d25893d9SBarry Smith 2337c3339decSBarry Smith Logically Collective 2338d25893d9SBarry Smith 2339d25893d9SBarry Smith Input Parameters: 2340f6dfbefdSBarry Smith + snes - the `SNES` context 2341d25893d9SBarry Smith . func - function evaluation routine 2342d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 2343*dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 2344d25893d9SBarry Smith 2345d25893d9SBarry Smith Calling sequence of func: 2346d25893d9SBarry Smith $ func (SNES snes,Vec x,void *ctx); 2347d25893d9SBarry Smith 2348d25893d9SBarry Smith . f - function vector 2349d25893d9SBarry Smith - ctx - optional user-defined function context 2350d25893d9SBarry Smith 2351d25893d9SBarry Smith Level: intermediate 2352d25893d9SBarry Smith 2353*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2354d25893d9SBarry Smith @*/ 2355d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx) 2356d71ae5a4SJacob Faibussowitsch { 2357d25893d9SBarry Smith PetscFunctionBegin; 2358d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2359d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2360d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 23613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2362d25893d9SBarry Smith } 2363d25893d9SBarry Smith 23641096aae1SMatthew Knepley /*@C 2365*dc4c0fb0SBarry Smith SNESGetRhs - Gets the vector for solving F(x) = `rhs`. If `rhs` is not set 23661096aae1SMatthew Knepley it assumes a zero right hand side. 23671096aae1SMatthew Knepley 2368c3339decSBarry Smith Logically Collective 23691096aae1SMatthew Knepley 23701096aae1SMatthew Knepley Input Parameter: 2371f6dfbefdSBarry Smith . snes - the `SNES` context 23721096aae1SMatthew Knepley 23731096aae1SMatthew Knepley Output Parameter: 2374*dc4c0fb0SBarry Smith . rhs - the right hand side vector or `NULL` if the right hand side vector is null 23751096aae1SMatthew Knepley 23761096aae1SMatthew Knepley Level: intermediate 23771096aae1SMatthew Knepley 2378*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23791096aae1SMatthew Knepley @*/ 2380d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) 2381d71ae5a4SJacob Faibussowitsch { 23821096aae1SMatthew Knepley PetscFunctionBegin; 23830700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23841096aae1SMatthew Knepley PetscValidPointer(rhs, 2); 238585385478SLisandro Dalcin *rhs = snes->vec_rhs; 23863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23871096aae1SMatthew Knepley } 23881096aae1SMatthew Knepley 23899b94acceSBarry Smith /*@ 2390f6dfbefdSBarry Smith SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`. 23919b94acceSBarry Smith 2392c3339decSBarry Smith Collective 2393c7afd0dbSLois Curfman McInnes 23949b94acceSBarry Smith Input Parameters: 2395f6dfbefdSBarry Smith + snes - the `SNES` context 2396c7afd0dbSLois Curfman McInnes - x - input vector 23979b94acceSBarry Smith 23989b94acceSBarry Smith Output Parameter: 2399f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetFunction()` 24009b94acceSBarry Smith 2401*dc4c0fb0SBarry Smith Level: developer 2402*dc4c0fb0SBarry Smith 2403f6dfbefdSBarry Smith Note: 2404f6dfbefdSBarry Smith `SNESComputeFunction()` is typically used within nonlinear solvers 2405bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 240636851e7fSLois Curfman McInnes 2407*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 24089b94acceSBarry Smith @*/ 2409d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) 2410d71ae5a4SJacob Faibussowitsch { 24116cab3a1bSJed Brown DM dm; 2412942e3340SBarry Smith DMSNES sdm; 24139b94acceSBarry Smith 24143a40ed3dSBarry Smith PetscFunctionBegin; 24150700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 24160700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 24170700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2418c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2419c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2420e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2421184914b5SBarry Smith 24229566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24239566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24240fdf79fbSJacob Faibussowitsch PetscCheck(sdm->ops->computefunction || snes->vec_rhs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetFunction() or SNESSetDM() before SNESComputeFunction(), likely called from SNESSolve()."); 242532f3f7c2SPeter Brune if (sdm->ops->computefunction) { 242648a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24279566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 24288ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24298ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2430800f99ffSJeremy L Thompson { 2431800f99ffSJeremy L Thompson void *ctx; 2432800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2433800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2434800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2435800f99ffSJeremy L Thompson } 24369566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 243748a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 24380fdf79fbSJacob Faibussowitsch } else /* if (snes->vec_rhs) */ { 24399566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 24400fdf79fbSJacob Faibussowitsch } 24411baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2442ae3c334cSLois Curfman McInnes snes->nfuncs++; 2443422a814eSBarry Smith /* 2444422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2445422a814eSBarry Smith propagate the value to all processes 2446422a814eSBarry Smith */ 24471baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24499b94acceSBarry Smith } 24509b94acceSBarry Smith 2451c79ef259SPeter Brune /*@ 2452f6dfbefdSBarry Smith SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`. 2453bbc1464cSBarry Smith 2454c3339decSBarry Smith Collective 2455bbc1464cSBarry Smith 2456bbc1464cSBarry Smith Input Parameters: 2457f6dfbefdSBarry Smith + snes - the `SNES` context 2458bbc1464cSBarry Smith - x - input vector 2459bbc1464cSBarry Smith 2460bbc1464cSBarry Smith Output Parameter: 2461f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetMFFunction()` 2462bbc1464cSBarry Smith 2463*dc4c0fb0SBarry Smith Level: developer 2464*dc4c0fb0SBarry Smith 2465bbc1464cSBarry Smith Notes: 2466f6dfbefdSBarry Smith `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()` 2467bbc1464cSBarry Smith so users would not generally call this routine themselves. 2468bbc1464cSBarry Smith 2469f6dfbefdSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()` 2470f6dfbefdSBarry Smith while `SNESComputeFunction()` does. As such, this routine cannot be used with `MatMFFDSetBase()` with a provided F function value even if it applies the 2471f6dfbefdSBarry 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. 2472bbc1464cSBarry Smith 2473*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2474bbc1464cSBarry Smith @*/ 2475d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) 2476d71ae5a4SJacob Faibussowitsch { 2477bbc1464cSBarry Smith DM dm; 2478bbc1464cSBarry Smith DMSNES sdm; 2479bbc1464cSBarry Smith 2480bbc1464cSBarry Smith PetscFunctionBegin; 2481bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2482bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2483bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2484bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2485bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2486e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2487bbc1464cSBarry Smith 24889566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24899566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24909566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24919566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2492bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2493bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2494792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24959566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24969566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2497bbc1464cSBarry Smith snes->nfuncs++; 2498bbc1464cSBarry Smith /* 2499bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2500bbc1464cSBarry Smith propagate the value to all processes 2501bbc1464cSBarry Smith */ 25021baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 25033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2504bbc1464cSBarry Smith } 2505bbc1464cSBarry Smith 2506bbc1464cSBarry Smith /*@ 2507f6dfbefdSBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`. 2508c79ef259SPeter Brune 2509c3339decSBarry Smith Collective 2510c79ef259SPeter Brune 2511c79ef259SPeter Brune Input Parameters: 2512f6dfbefdSBarry Smith + snes - the `SNES` context 2513c79ef259SPeter Brune . x - input vector 2514c79ef259SPeter Brune - b - rhs vector 2515c79ef259SPeter Brune 2516c79ef259SPeter Brune Output Parameter: 2517c79ef259SPeter Brune . x - new solution vector 2518c79ef259SPeter Brune 2519*dc4c0fb0SBarry Smith Level: developer 2520*dc4c0fb0SBarry Smith 2521f6dfbefdSBarry Smith Note: 2522f6dfbefdSBarry Smith `SNESComputeNGS()` is typically used within composed nonlinear solver 2523c79ef259SPeter Brune implementations, so most users would not generally call this routine 2524c79ef259SPeter Brune themselves. 2525c79ef259SPeter Brune 2526*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()` 2527c79ef259SPeter Brune @*/ 2528d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) 2529d71ae5a4SJacob Faibussowitsch { 25306cab3a1bSJed Brown DM dm; 2531942e3340SBarry Smith DMSNES sdm; 2532646217ecSPeter Brune 2533646217ecSPeter Brune PetscFunctionBegin; 2534646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2535064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2536064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2537064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2538064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 2539e0f629ddSJacob Faibussowitsch if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE)); 25409566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 25419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 25429566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 25430fdf79fbSJacob Faibussowitsch PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 25449566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2545792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 25469566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 25479566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 25483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2549646217ecSPeter Brune } 2550646217ecSPeter Brune 2551d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestJacobian(SNES snes) 2552d71ae5a4SJacob Faibussowitsch { 255312837594SBarry Smith Mat A, B, C, D, jacobian; 2554e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2555e885f1abSBarry Smith PetscReal nrm, gnorm; 255681e7118cSBarry Smith PetscReal threshold = 1.e-5; 25570e276705SLisandro Dalcin MatType mattype; 2558e885f1abSBarry Smith PetscInt m, n, M, N; 2559e885f1abSBarry Smith void *functx; 25602cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 25613325ff46SBarry Smith PetscViewer viewer, mviewer; 2562e885f1abSBarry Smith MPI_Comm comm; 2563e885f1abSBarry Smith PetscInt tabs; 256412837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25653325ff46SBarry Smith PetscViewerFormat format; 2566e885f1abSBarry Smith 2567e885f1abSBarry Smith PetscFunctionBegin; 2568d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 25699566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 25709566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 25719566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 257218d89885SKarl Rupp if (!complete_print) { 25739566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 25749566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_display", "Display difference between hand-coded and finite difference Jacobians", "None", &mviewer, &format, &complete_print)); 257518d89885SKarl Rupp } 257618d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 25779566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 25789566063dSJacob 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)); 2579d0609cedSBarry Smith PetscOptionsEnd(); 25803ba16761SJacob Faibussowitsch if (!test) PetscFunctionReturn(PETSC_SUCCESS); 2581e885f1abSBarry Smith 25829566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25839566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25859566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25869566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 258712837594SBarry Smith if (!complete_print && !directionsprinted) { 25889566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25899566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 259012837594SBarry Smith } 259112837594SBarry Smith if (!directionsprinted) { 25929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25939566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 259412837594SBarry Smith directionsprinted = PETSC_TRUE; 2595e885f1abSBarry Smith } 25961baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2597e885f1abSBarry Smith 25989566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 259912837594SBarry Smith if (!flg) jacobian = snes->jacobian; 260012837594SBarry Smith else jacobian = snes->jacobian_pre; 260112837594SBarry Smith 2602a82339d0SMatthew G. Knepley if (!x) { 26039566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2604a82339d0SMatthew G. Knepley } else { 26059566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2606a82339d0SMatthew G. Knepley } 2607a82339d0SMatthew G. Knepley if (!f) { 26089566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2609a82339d0SMatthew G. Knepley } else { 26109566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2611a82339d0SMatthew G. Knepley } 2612a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 26139566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 26149566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 26159566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 261612837594SBarry Smith while (jacobian) { 26172cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 26182cd624f9SStefano Zampini 26192cd624f9SStefano Zampini if (istranspose) { 26209566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 26212cd624f9SStefano Zampini Jsave = jacobian; 26222cd624f9SStefano Zampini jacobian = JT; 26232cd624f9SStefano Zampini } 26249566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 262512837594SBarry Smith if (flg) { 262612837594SBarry Smith A = jacobian; 26279566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 262812837594SBarry Smith } else { 26299566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 263012837594SBarry Smith } 2631e885f1abSBarry Smith 26329566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 26339566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 26349566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 26359566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 26369566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 26379566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 26389566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 26399566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 26409566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2641e885f1abSBarry Smith 26429566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 26439566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 264412837594SBarry Smith 26459566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 26469566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26479566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 26489566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 26499566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 265012837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 26519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 265212837594SBarry Smith 2653e885f1abSBarry Smith if (complete_print) { 26549566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 26559566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 26569566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 26579566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2658e885f1abSBarry Smith } 2659e885f1abSBarry Smith 2660df10fb39SFande Kong if (threshold_print || complete_print) { 2661e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2662e885f1abSBarry Smith PetscScalar *cvals; 2663e885f1abSBarry Smith const PetscInt *bcols; 2664e885f1abSBarry Smith const PetscScalar *bvals; 2665e885f1abSBarry Smith 26669566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 26679566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 26689566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 26699566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 26709566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 26719566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 26720e276705SLisandro Dalcin 26739566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26749566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2675e885f1abSBarry Smith 2676e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26779566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26789566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2679e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 268023a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2681e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2682e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2683e885f1abSBarry Smith cncols += 1; 2684e885f1abSBarry Smith } 2685e885f1abSBarry Smith } 268648a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26879566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26889566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2689e885f1abSBarry Smith } 26909566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26919566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26929566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26939566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2695e885f1abSBarry Smith } 26969566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26989566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 26992cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 270012837594SBarry Smith if (jacobian != snes->jacobian_pre) { 270112837594SBarry Smith jacobian = snes->jacobian_pre; 27029566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 27039371c9d4SSatish Balay } else jacobian = NULL; 270412837594SBarry Smith } 27059566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 27061baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 27079566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 27089566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 27093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2710e885f1abSBarry Smith } 2711e885f1abSBarry Smith 271262fef451SLois Curfman McInnes /*@ 2713f6dfbefdSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`. 271462fef451SLois Curfman McInnes 2715c3339decSBarry Smith Collective 2716c7afd0dbSLois Curfman McInnes 271762fef451SLois Curfman McInnes Input Parameters: 2718f6dfbefdSBarry Smith + snes - the `SNES` context 2719c7afd0dbSLois Curfman McInnes - x - input vector 272062fef451SLois Curfman McInnes 272162fef451SLois Curfman McInnes Output Parameters: 2722c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2723f6dfbefdSBarry Smith - B - optional matrix for building the preconditioner 2724fee21e36SBarry Smith 2725e35cf81dSBarry Smith Options Database Keys: 272667b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 272767b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2728455a5933SJed 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. 2729455a5933SJed 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 2730693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2731693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2732693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27334c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 273494d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2735a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2736c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2737*dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2738*dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2739a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2740a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2741c01495d3SJed Brown 2742*dc4c0fb0SBarry Smith Level: developer 2743*dc4c0fb0SBarry Smith 2744f6dfbefdSBarry Smith Note: 274562fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 274662fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 274762fef451SLois Curfman McInnes 2748f6dfbefdSBarry Smith Developer Note: 2749*dc4c0fb0SBarry Smith 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 2750*dc4c0fb0SBarry Smith for with the `SNESType` of test that has been removed. 2751e885f1abSBarry Smith 2752*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 275362fef451SLois Curfman McInnes @*/ 2754d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) 2755d71ae5a4SJacob Faibussowitsch { 2756ace3abfcSBarry Smith PetscBool flag; 27576cab3a1bSJed Brown DM dm; 2758942e3340SBarry Smith DMSNES sdm; 2759e0e3a89bSBarry Smith KSP ksp; 27603a40ed3dSBarry Smith 27613a40ed3dSBarry Smith PetscFunctionBegin; 27620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 27630700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2764c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 2765e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE)); 27669566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 27679566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 27683232da50SPeter Brune 2769ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2770fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2771fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2772f5af7f23SKarl Rupp 27739566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2774fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 27759566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 27769566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2777ebd3b9afSBarry Smith if (flag) { 27789566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27799566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2780ebd3b9afSBarry Smith } 27813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 278237ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 278363a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2785ebd3b9afSBarry Smith if (flag) { 27869566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27879566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2788ebd3b9afSBarry Smith } 27893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2790e35cf81dSBarry Smith } 2791efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27929566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27939566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 27943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2795d728fb7dSPeter Brune } 2796e35cf81dSBarry Smith 27979566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27989566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2799800f99ffSJeremy L Thompson { 2800800f99ffSJeremy L Thompson void *ctx; 2801800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2802800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2803800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2804800f99ffSJeremy L Thompson } 28059566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 28069566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 280728d58a37SPierre Jolivet 280828d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 28099566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2810a8054027SBarry Smith 2811e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 28129566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 28133b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 28149566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 28159566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 28163b4f5425SBarry Smith snes->lagpreconditioner = -1; 28173b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 28189566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 28199566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 282037ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 282163a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 28229566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2823d1e9a80fSBarry Smith } else { 28249566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 28259566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2826a8054027SBarry Smith } 2827a8054027SBarry Smith 28289566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 28296d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 283094ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 283194ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2832693365a8SJed Brown { 2833693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 28349566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 28359566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 28369566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 28379566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2838693365a8SJed Brown if (flag || flag_draw || flag_contour) { 28390298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2840693365a8SJed Brown PetscViewer vdraw, vstdout; 28416b3a5b13SJed Brown PetscBool flg; 2842693365a8SJed Brown if (flag_operator) { 28439566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2844693365a8SJed Brown Bexp = Bexp_mine; 2845693365a8SJed Brown } else { 2846693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 28479566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 284894ab13aaSBarry Smith if (flg) Bexp = B; 2849693365a8SJed Brown else { 2850693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28519566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2852693365a8SJed Brown Bexp = Bexp_mine; 2853693365a8SJed Brown } 2854693365a8SJed Brown } 28559566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 28569566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 28579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2858693365a8SJed Brown if (flag_draw || flag_contour) { 28599566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28609566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28610298fd71SBarry Smith } else vdraw = NULL; 28629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 28639566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 28649566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 28659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 28669566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 28679566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 28689566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 28699566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 28709566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2871693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 28729566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28739566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 28749566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2875693365a8SJed Brown } 28769566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28779566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28799566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2880693365a8SJed Brown } 2881693365a8SJed Brown } 28824c30e9fbSJed Brown { 28836719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28846719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28859566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28869566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28879566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28889566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28899566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 289027b0f280SBarry Smith if (flag_threshold) { 28919566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28929566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 289327b0f280SBarry Smith } 28946719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28954c30e9fbSJed Brown Mat Bfd; 28964c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2897335efc43SPeter Brune MatColoring coloring; 28984c30e9fbSJed Brown ISColoring iscoloring; 28994c30e9fbSJed Brown MatFDColoring matfdcoloring; 29004c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 29014c30e9fbSJed Brown void *funcctx; 29026719d8e4SJed Brown PetscReal norm1, norm2, normmax; 29034c30e9fbSJed Brown 29049566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 29059566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 29069566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 29079566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 29089566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 29099566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 29109566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 29119566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29129566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 29139566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 29144c30e9fbSJed Brown 29154c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 29169566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 29179566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 29189566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 29199566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 29209566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29219566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 29229566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 29234c30e9fbSJed Brown 29249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 29254c30e9fbSJed Brown if (flag_draw || flag_contour) { 29269566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 29279566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29280298fd71SBarry Smith } else vdraw = NULL; 29299566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 29309566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 29319566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 29329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 29339566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29349566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 29359566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 29369566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 29379566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 29389566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 29399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 29409566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29414c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 29429566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29439566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 29449566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 29454c30e9fbSJed Brown } 29469566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 29476719d8e4SJed Brown 29486719d8e4SJed Brown if (flag_threshold) { 29496719d8e4SJed Brown PetscInt bs, rstart, rend, i; 29509566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 29519566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 29526719d8e4SJed Brown for (i = rstart; i < rend; i++) { 29536719d8e4SJed Brown const PetscScalar *ba, *ca; 29546719d8e4SJed Brown const PetscInt *bj, *cj; 29556719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 29566719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 29579566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 29589566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 29595f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29606719d8e4SJed Brown for (j = 0; j < bn; j++) { 29616719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 29626719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29636719d8e4SJed Brown maxentrycol = bj[j]; 29646719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29656719d8e4SJed Brown } 29666719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29676719d8e4SJed Brown maxdiffcol = bj[j]; 29686719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29696719d8e4SJed Brown } 29706719d8e4SJed Brown if (rdiff > maxrdiff) { 29716719d8e4SJed Brown maxrdiffcol = bj[j]; 29726719d8e4SJed Brown maxrdiff = rdiff; 29736719d8e4SJed Brown } 29746719d8e4SJed Brown } 29756719d8e4SJed Brown if (maxrdiff > 1) { 297663a3b9bcSJacob 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)); 29776719d8e4SJed Brown for (j = 0; j < bn; j++) { 29786719d8e4SJed Brown PetscReal rdiff; 29796719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 298048a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29816719d8e4SJed Brown } 298263a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29836719d8e4SJed Brown } 29849566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29859566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29866719d8e4SJed Brown } 29876719d8e4SJed Brown } 29889566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29899566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29904c30e9fbSJed Brown } 29914c30e9fbSJed Brown } 29923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29939b94acceSBarry Smith } 29949b94acceSBarry Smith 2995bf388a1fSBarry Smith /*MC 2996f6dfbefdSBarry Smith SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES` 2997bf388a1fSBarry Smith 2998bf388a1fSBarry Smith Synopsis: 2999411c0326SBarry Smith #include "petscsnes.h" 3000411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 3001bf388a1fSBarry Smith 3002c3339decSBarry Smith Collective 30031843f636SBarry Smith 30041843f636SBarry Smith Input Parameters: 30051843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 3006bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 3007bf388a1fSBarry Smith 30081843f636SBarry Smith Output Parameters: 30091843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 3010*dc4c0fb0SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 30111843f636SBarry Smith 3012878cb397SSatish Balay Level: intermediate 3013878cb397SSatish Balay 3014*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 3015bf388a1fSBarry Smith M*/ 3016bf388a1fSBarry Smith 30179b94acceSBarry Smith /*@C 30189b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 3019044dda88SLois Curfman McInnes location to store the matrix. 30209b94acceSBarry Smith 3021c3339decSBarry Smith Logically Collective 3022c7afd0dbSLois Curfman McInnes 30239b94acceSBarry Smith Input Parameters: 3024f6dfbefdSBarry Smith + snes - the `SNES` context 3025e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3026*dc4c0fb0SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 3027*dc4c0fb0SBarry Smith . J - Jacobian evaluation routine (if `NULL` then `SNES` retains any previously set value), see `SNESJacobianFunction` for details 3028c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 3029*dc4c0fb0SBarry Smith Jacobian evaluation routine (may be `NULL`) (if `NULL` then `SNES` retains any previously set value) 3030*dc4c0fb0SBarry Smith 3031*dc4c0fb0SBarry Smith Level: beginner 30329b94acceSBarry Smith 30339b94acceSBarry Smith Notes: 3034*dc4c0fb0SBarry Smith If the `Amat` matrix and `Pmat` matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on 303516913363SBarry Smith each matrix. 303616913363SBarry Smith 3037*dc4c0fb0SBarry Smith If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 3038*dc4c0fb0SBarry Smith space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process. 3039895c21f2SBarry Smith 3040*dc4c0fb0SBarry Smith If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the `ctx` argument 3041f6dfbefdSBarry Smith must be a `MatFDColoring`. 3042a8a26c1eSJed Brown 3043c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3044f6dfbefdSBarry Smith example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()` 3045c3cc8fd1SJed Brown 3046*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, 3047db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 30489b94acceSBarry Smith @*/ 3049d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 3050d71ae5a4SJacob Faibussowitsch { 30516cab3a1bSJed Brown DM dm; 30523a7fca6bSBarry Smith 30533a40ed3dSBarry Smith PetscFunctionBegin; 30540700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3055e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 3056e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 3057e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 3058e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 30599566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30609566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 3061e5d3d808SBarry Smith if (Amat) { 30629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 30639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 3064f5af7f23SKarl Rupp 3065e5d3d808SBarry Smith snes->jacobian = Amat; 30663a7fca6bSBarry Smith } 3067e5d3d808SBarry Smith if (Pmat) { 30689566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 30699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 3070f5af7f23SKarl Rupp 3071e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30723a7fca6bSBarry Smith } 30733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30749b94acceSBarry Smith } 307562fef451SLois Curfman McInnes 3076c2aafc4cSSatish Balay /*@C 3077b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3078b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3079b4fd4287SBarry Smith 3080f6dfbefdSBarry Smith Not Collective, but `Mat` object will be parallel if `SNES` object is 3081c7afd0dbSLois Curfman McInnes 3082b4fd4287SBarry Smith Input Parameter: 3083b4fd4287SBarry Smith . snes - the nonlinear solver context 3084b4fd4287SBarry Smith 3085b4fd4287SBarry Smith Output Parameters: 3086*dc4c0fb0SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or `NULL`) 3087*dc4c0fb0SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or `NULL`) 3088*dc4c0fb0SBarry Smith . J - location to put Jacobian function (or `NULL`), see `SNESJacobianFunction` for details on its calling sequence 3089*dc4c0fb0SBarry Smith - ctx - location to stash Jacobian ctx (or `NULL`) 3090fee21e36SBarry Smith 309136851e7fSLois Curfman McInnes Level: advanced 309236851e7fSLois Curfman McInnes 3093*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3094b4fd4287SBarry Smith @*/ 3095d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 3096d71ae5a4SJacob Faibussowitsch { 30976cab3a1bSJed Brown DM dm; 30986cab3a1bSJed Brown 30993a40ed3dSBarry Smith PetscFunctionBegin; 31000700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3101e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3102e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 31039566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3104800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 31053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3106b4fd4287SBarry Smith } 3107b4fd4287SBarry Smith 3108d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3109d71ae5a4SJacob Faibussowitsch { 311058b371f3SBarry Smith DM dm; 311158b371f3SBarry Smith DMSNES sdm; 311258b371f3SBarry Smith 311358b371f3SBarry Smith PetscFunctionBegin; 31149566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31159566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 311658b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 311758b371f3SBarry Smith DM dm; 311858b371f3SBarry Smith PetscBool isdense, ismf; 311958b371f3SBarry Smith 31209566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31219566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 31229566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 312358b371f3SBarry Smith if (isdense) { 31249566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 312558b371f3SBarry Smith } else if (!ismf) { 31269566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 312758b371f3SBarry Smith } 312858b371f3SBarry Smith } 31293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 313058b371f3SBarry Smith } 313158b371f3SBarry Smith 31329b94acceSBarry Smith /*@ 31339b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3134272ac6f2SLois Curfman McInnes of a nonlinear solver. 31359b94acceSBarry Smith 3136c3339decSBarry Smith Collective 3137fee21e36SBarry Smith 3138c7afd0dbSLois Curfman McInnes Input Parameters: 3139f6dfbefdSBarry Smith . snes - the `SNES` context 3140c7afd0dbSLois Curfman McInnes 3141*dc4c0fb0SBarry Smith Level: advanced 3142*dc4c0fb0SBarry Smith 3143f6dfbefdSBarry Smith Note: 3144f6dfbefdSBarry Smith For basic use of the `SNES` solvers the user need not explicitly call 3145f6dfbefdSBarry Smith `SNESSetUp()`, since these actions will automatically occur during 3146f6dfbefdSBarry Smith the call to `SNESSolve()`. However, if one wishes to control this 3147f6dfbefdSBarry Smith phase separately, `SNESSetUp()` should be called after `SNESCreate()` 3148f6dfbefdSBarry Smith and optional routines of the form SNESSetXXX(), but before `SNESSolve()`. 3149272ac6f2SLois Curfman McInnes 3150*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 31519b94acceSBarry Smith @*/ 3152d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp(SNES snes) 3153d71ae5a4SJacob Faibussowitsch { 31546cab3a1bSJed Brown DM dm; 3155942e3340SBarry Smith DMSNES sdm; 3156c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31576e2a1849SPeter Brune void *lsprectx, *lspostctx; 31589b5c1c08SStefano Zampini PetscBool mf_operator, mf; 31599b5c1c08SStefano Zampini Vec f, fpc; 31609b5c1c08SStefano Zampini void *funcctx; 31619b5c1c08SStefano Zampini void *jacctx, *appctx; 31629b5c1c08SStefano Zampini Mat j, jpre; 31636b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 31646b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 31656e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 3166d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 31673a40ed3dSBarry Smith 31683a40ed3dSBarry Smith PetscFunctionBegin; 31690700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 31703ba16761SJacob Faibussowitsch if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 3171fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0)); 31729b94acceSBarry Smith 317348a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 317485385478SLisandro Dalcin 31759566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 317658c9b817SLisandro Dalcin 31779566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31789566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 31799566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 318058b371f3SBarry Smith 318148a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3182efd51863SBarry Smith 318348a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3184b710008aSBarry Smith 3185d8d34be6SBarry Smith if (snes->linesearch) { 31869566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31879566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3188d8d34be6SBarry Smith } 31899e764e56SPeter Brune 31909b5c1c08SStefano Zampini PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf)); 3191b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3192172a4300SPeter Brune snes->mf = PETSC_TRUE; 3193172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3194172a4300SPeter Brune } 3195d8f46077SPeter Brune 3196efd4aadfSBarry Smith if (snes->npc) { 31976e2a1849SPeter Brune /* copy the DM over */ 31989566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31999566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 32006e2a1849SPeter Brune 32019566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 32029566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 32039566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 32049566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 32059566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 32069566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 32079566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 32089b5c1c08SStefano Zampini PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf)); 32099566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 32106e2a1849SPeter Brune 32116e2a1849SPeter Brune /* copy the function pointers over */ 32129566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 32136e2a1849SPeter Brune 32146e2a1849SPeter Brune /* default to 1 iteration */ 32159566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3216efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 32179566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3218a9936a0cSPeter Brune } else { 32199566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3220a9936a0cSPeter Brune } 32219566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 32226e2a1849SPeter Brune 32236e2a1849SPeter Brune /* copy the line search context over */ 3224d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 32259566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32269566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 32279566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 32289566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 32299566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 32309566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 32319566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 32326e2a1849SPeter Brune } 3233d8d34be6SBarry Smith } 32341baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 323548a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 32366e2a1849SPeter Brune 323737ec4e1aSPeter Brune snes->jac_iter = 0; 323837ec4e1aSPeter Brune snes->pre_iter = 0; 323937ec4e1aSPeter Brune 3240dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 324158c9b817SLisandro Dalcin 32429566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 324358b371f3SBarry Smith 3244b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 32456c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3246d8d34be6SBarry Smith if (snes->linesearch) { 32479566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32489566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 32496c67d002SPeter Brune } 32506c67d002SPeter Brune } 3251d8d34be6SBarry Smith } 3252fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0)); 32537aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32559b94acceSBarry Smith } 32569b94acceSBarry Smith 325737596af1SLisandro Dalcin /*@ 3258f6dfbefdSBarry Smith SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s 325937596af1SLisandro Dalcin 3260c3339decSBarry Smith Collective 326137596af1SLisandro Dalcin 326237596af1SLisandro Dalcin Input Parameter: 3263f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 326437596af1SLisandro Dalcin 3265d25893d9SBarry Smith Level: intermediate 3266d25893d9SBarry Smith 326795452b02SPatrick Sanan Notes: 3268f6dfbefdSBarry Smith Call this if you wish to reuse a `SNES` but with different size vectors 326937596af1SLisandro Dalcin 3270f6dfbefdSBarry Smith Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()` 3271f6dfbefdSBarry Smith 3272*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 327337596af1SLisandro Dalcin @*/ 3274d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset(SNES snes) 3275d71ae5a4SJacob Faibussowitsch { 327637596af1SLisandro Dalcin PetscFunctionBegin; 327737596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3278d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 32799566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 32800298fd71SBarry Smith snes->user = NULL; 3281d25893d9SBarry Smith } 32821baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 32838a23116dSBarry Smith 3284dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 32851baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 32869e764e56SPeter Brune 32871baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32889e764e56SPeter Brune 32899566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32909566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32919566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32929566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32939566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32949566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32959566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32969566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32979566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3298f5af7f23SKarl Rupp 329940fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 330040fdac6aSLawrence Mitchell 330137596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 330237596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 33033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 330437596af1SLisandro Dalcin } 330537596af1SLisandro Dalcin 330652baeb72SSatish Balay /*@ 3307f6dfbefdSBarry Smith SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object. 3308c4421ceaSFande Kong 3309c3339decSBarry Smith Collective 3310c4421ceaSFande Kong 3311c4421ceaSFande Kong Input Parameter: 3312f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 3313c4421ceaSFande Kong 3314c4421ceaSFande Kong Level: intermediate 3315c4421ceaSFande Kong 3316*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3317c4421ceaSFande Kong @*/ 3318d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3319d71ae5a4SJacob Faibussowitsch { 3320c4421ceaSFande Kong PetscInt i; 3321c4421ceaSFande Kong 3322c4421ceaSFande Kong PetscFunctionBegin; 3323c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3324c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 332548a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3326c4421ceaSFande Kong } 3327c4421ceaSFande Kong snes->numberreasonviews = 0; 33283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3329c4421ceaSFande Kong } 3330c4421ceaSFande Kong 33311fb7b255SJunchao Zhang /*@C 33329b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 3333f6dfbefdSBarry Smith with `SNESCreate()`. 33349b94acceSBarry Smith 3335c3339decSBarry Smith Collective 3336c7afd0dbSLois Curfman McInnes 33379b94acceSBarry Smith Input Parameter: 3338f6dfbefdSBarry Smith . snes - the `SNES` context 33399b94acceSBarry Smith 334036851e7fSLois Curfman McInnes Level: beginner 334136851e7fSLois Curfman McInnes 3342*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSolve()` 33439b94acceSBarry Smith @*/ 3344d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy(SNES *snes) 3345d71ae5a4SJacob Faibussowitsch { 33463a40ed3dSBarry Smith PetscFunctionBegin; 33473ba16761SJacob Faibussowitsch if (!*snes) PetscFunctionReturn(PETSC_SUCCESS); 33486bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 33499371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 33509371c9d4SSatish Balay *snes = NULL; 33513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33529371c9d4SSatish Balay } 3353d4bb536fSBarry Smith 33549566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 33559566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 33566b8b9a38SLisandro Dalcin 3357e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 33589566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3359dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 33606d4c513bSLisandro Dalcin 33619566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 33629566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 33639566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 33649566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 33656b8b9a38SLisandro Dalcin 33669566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 336748a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 336848a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 33699566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 33709566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 33719566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 33723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33739b94acceSBarry Smith } 33749b94acceSBarry Smith 33759b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 33769b94acceSBarry Smith 3377a8054027SBarry Smith /*@ 3378a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3379a8054027SBarry Smith 3380c3339decSBarry Smith Logically Collective 3381a8054027SBarry Smith 3382a8054027SBarry Smith Input Parameters: 3383f6dfbefdSBarry Smith + snes - the `SNES` context 3384d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 33853b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3386a8054027SBarry Smith 3387a8054027SBarry Smith Options Database Keys: 33883d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33893d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33903d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33913d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3392a8054027SBarry Smith 3393a8054027SBarry Smith Notes: 3394*dc4c0fb0SBarry Smith Level: intermediate 3395*dc4c0fb0SBarry Smith 3396a8054027SBarry Smith The default is 1 3397f6dfbefdSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called 3398d8e291bfSBarry Smith 3399f6dfbefdSBarry Smith `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves. 3400a8054027SBarry Smith 3401*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3402f6dfbefdSBarry Smith `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()` 3403a8054027SBarry Smith @*/ 3404d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) 3405d71ae5a4SJacob Faibussowitsch { 3406a8054027SBarry Smith PetscFunctionBegin; 34070700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 34085f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 34095f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3410c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3411a8054027SBarry Smith snes->lagpreconditioner = lag; 34123ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3413a8054027SBarry Smith } 3414a8054027SBarry Smith 3415efd51863SBarry Smith /*@ 3416f6dfbefdSBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do 3417efd51863SBarry Smith 3418c3339decSBarry Smith Logically Collective 3419efd51863SBarry Smith 3420efd51863SBarry Smith Input Parameters: 3421f6dfbefdSBarry Smith + snes - the `SNES` context 3422efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3423efd51863SBarry Smith 3424f6dfbefdSBarry Smith Options Database Key: 342567b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3426efd51863SBarry Smith 3427efd51863SBarry Smith Level: intermediate 3428efd51863SBarry Smith 3429f6dfbefdSBarry Smith Note: 3430f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3431c0df2a02SJed Brown 3432*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3433efd51863SBarry Smith @*/ 3434d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) 3435d71ae5a4SJacob Faibussowitsch { 3436efd51863SBarry Smith PetscFunctionBegin; 3437efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3438efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3439efd51863SBarry Smith snes->gridsequence = steps; 34403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3441efd51863SBarry Smith } 3442efd51863SBarry Smith 3443fa19ca70SBarry Smith /*@ 3444f6dfbefdSBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do 3445fa19ca70SBarry Smith 3446c3339decSBarry Smith Logically Collective 3447fa19ca70SBarry Smith 3448fa19ca70SBarry Smith Input Parameter: 3449f6dfbefdSBarry Smith . snes - the `SNES` context 3450fa19ca70SBarry Smith 3451fa19ca70SBarry Smith Output Parameter: 3452fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3453fa19ca70SBarry Smith 3454f6dfbefdSBarry Smith Options Database Key: 345567b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3456fa19ca70SBarry Smith 3457fa19ca70SBarry Smith Level: intermediate 3458fa19ca70SBarry Smith 3459f6dfbefdSBarry Smith Note: 3460f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3461fa19ca70SBarry Smith 3462*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3463fa19ca70SBarry Smith @*/ 3464d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) 3465d71ae5a4SJacob Faibussowitsch { 3466fa19ca70SBarry Smith PetscFunctionBegin; 3467fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3468fa19ca70SBarry Smith *steps = snes->gridsequence; 34693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3470fa19ca70SBarry Smith } 3471fa19ca70SBarry Smith 3472a8054027SBarry Smith /*@ 3473f6dfbefdSBarry Smith SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt 3474a8054027SBarry Smith 34753f9fe445SBarry Smith Not Collective 3476a8054027SBarry Smith 3477a8054027SBarry Smith Input Parameter: 3478f6dfbefdSBarry Smith . snes - the `SNES` context 3479a8054027SBarry Smith 3480a8054027SBarry Smith Output Parameter: 3481a8054027SBarry 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 34823b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3483a8054027SBarry Smith 3484a8054027SBarry Smith Options Database Keys: 34853d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34863d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34873d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34883d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3489a8054027SBarry Smith 3490*dc4c0fb0SBarry Smith Level: intermediate 3491*dc4c0fb0SBarry Smith 3492a8054027SBarry Smith Notes: 3493a8054027SBarry Smith The default is 1 3494f6dfbefdSBarry Smith 3495a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3496a8054027SBarry Smith 3497*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3498a8054027SBarry Smith @*/ 3499d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) 3500d71ae5a4SJacob Faibussowitsch { 3501a8054027SBarry Smith PetscFunctionBegin; 35020700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3503a8054027SBarry Smith *lag = snes->lagpreconditioner; 35043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3505a8054027SBarry Smith } 3506a8054027SBarry Smith 3507e35cf81dSBarry Smith /*@ 3508f6dfbefdSBarry Smith SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how 3509e35cf81dSBarry Smith often the preconditioner is rebuilt. 3510e35cf81dSBarry Smith 3511c3339decSBarry Smith Logically Collective 3512e35cf81dSBarry Smith 3513e35cf81dSBarry Smith Input Parameters: 3514f6dfbefdSBarry Smith + snes - the `SNES` context 3515e35cf81dSBarry 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 3516fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3517e35cf81dSBarry Smith 3518e35cf81dSBarry Smith Options Database Keys: 35193d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35203d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35213d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35223d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3523e35cf81dSBarry Smith 3524*dc4c0fb0SBarry Smith Level: intermediate 3525*dc4c0fb0SBarry Smith 3526e35cf81dSBarry Smith Notes: 3527e35cf81dSBarry Smith The default is 1 3528f6dfbefdSBarry Smith 3529e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3530f6dfbefdSBarry Smith 3531fe3ffe1eSBarry 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 3532fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3533e35cf81dSBarry Smith 3534*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3535e35cf81dSBarry Smith @*/ 3536d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) 3537d71ae5a4SJacob Faibussowitsch { 3538e35cf81dSBarry Smith PetscFunctionBegin; 35390700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 35405f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 35415f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3542c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3543e35cf81dSBarry Smith snes->lagjacobian = lag; 35443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3545e35cf81dSBarry Smith } 3546e35cf81dSBarry Smith 3547e35cf81dSBarry Smith /*@ 3548f6dfbefdSBarry Smith SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt 3549e35cf81dSBarry Smith 35503f9fe445SBarry Smith Not Collective 3551e35cf81dSBarry Smith 3552e35cf81dSBarry Smith Input Parameter: 3553f6dfbefdSBarry Smith . snes - the `SNES` context 3554e35cf81dSBarry Smith 3555e35cf81dSBarry Smith Output Parameter: 3556e35cf81dSBarry 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 3557e35cf81dSBarry Smith the Jacobian is built etc. 3558e35cf81dSBarry Smith 3559*dc4c0fb0SBarry Smith Level: intermediate 3560*dc4c0fb0SBarry Smith 3561e35cf81dSBarry Smith Notes: 3562e35cf81dSBarry Smith The default is 1 3563f6dfbefdSBarry Smith 3564f6dfbefdSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called. 3565e35cf81dSBarry Smith 3566*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3567e35cf81dSBarry Smith 3568e35cf81dSBarry Smith @*/ 3569d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) 3570d71ae5a4SJacob Faibussowitsch { 3571e35cf81dSBarry Smith PetscFunctionBegin; 35720700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3573e35cf81dSBarry Smith *lag = snes->lagjacobian; 35743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3575e35cf81dSBarry Smith } 3576e35cf81dSBarry Smith 357737ec4e1aSPeter Brune /*@ 3578f6dfbefdSBarry Smith SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves 357937ec4e1aSPeter Brune 3580c3339decSBarry Smith Logically collective 358137ec4e1aSPeter Brune 3582d8d19677SJose E. Roman Input Parameters: 3583f6dfbefdSBarry Smith + snes - the `SNES` context 35849d7e2deaSPeter Brune - flg - jacobian lagging persists if true 358537ec4e1aSPeter Brune 358637ec4e1aSPeter Brune Options Database Keys: 35873d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35883d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35893d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35903d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35913d5a8a6aSBarry Smith 3592*dc4c0fb0SBarry Smith Level: advanced 3593*dc4c0fb0SBarry Smith 359495452b02SPatrick Sanan Notes: 3595f6dfbefdSBarry Smith Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3596f6dfbefdSBarry Smith 359795452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 359837ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 359937ec4e1aSPeter Brune timesteps may present huge efficiency gains. 360037ec4e1aSPeter Brune 3601*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 360237ec4e1aSPeter Brune @*/ 3603d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) 3604d71ae5a4SJacob Faibussowitsch { 360537ec4e1aSPeter Brune PetscFunctionBegin; 360637ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 360737ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 360837ec4e1aSPeter Brune snes->lagjac_persist = flg; 36093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 361037ec4e1aSPeter Brune } 361137ec4e1aSPeter Brune 361237ec4e1aSPeter Brune /*@ 3613d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 361437ec4e1aSPeter Brune 3615c3339decSBarry Smith Logically Collective 361637ec4e1aSPeter Brune 3617d8d19677SJose E. Roman Input Parameters: 3618f6dfbefdSBarry Smith + snes - the `SNES` context 36199d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 362037ec4e1aSPeter Brune 362137ec4e1aSPeter Brune Options Database Keys: 36223d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36233d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36243d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36253d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 362637ec4e1aSPeter Brune 3627*dc4c0fb0SBarry Smith Level: developer 3628*dc4c0fb0SBarry Smith 362995452b02SPatrick Sanan Notes: 3630f6dfbefdSBarry Smith Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3631f6dfbefdSBarry Smith 363295452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 363337ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 363437ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 363537ec4e1aSPeter Brune 3636*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 363737ec4e1aSPeter Brune @*/ 3638d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) 3639d71ae5a4SJacob Faibussowitsch { 364037ec4e1aSPeter Brune PetscFunctionBegin; 364137ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 364237ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 364337ec4e1aSPeter Brune snes->lagpre_persist = flg; 36443ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 364537ec4e1aSPeter Brune } 364637ec4e1aSPeter Brune 36479b94acceSBarry Smith /*@ 3648f6dfbefdSBarry Smith SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm 3649be5caee7SBarry Smith 3650c3339decSBarry Smith Logically Collective 3651be5caee7SBarry Smith 3652be5caee7SBarry Smith Input Parameters: 3653f6dfbefdSBarry Smith + snes - the `SNES` context 3654f6dfbefdSBarry Smith - force - `PETSC_TRUE` require at least one iteration 3655be5caee7SBarry Smith 3656f6dfbefdSBarry Smith Options Database Key: 3657be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3658be5caee7SBarry Smith 3659*dc4c0fb0SBarry Smith Level: intermediate 3660*dc4c0fb0SBarry Smith 3661f6dfbefdSBarry Smith Note: 3662f6dfbefdSBarry Smith This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution 3663be5caee7SBarry Smith 3664*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3665be5caee7SBarry Smith @*/ 3666d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) 3667d71ae5a4SJacob Faibussowitsch { 3668be5caee7SBarry Smith PetscFunctionBegin; 3669be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3670be5caee7SBarry Smith snes->forceiteration = force; 36713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3672be5caee7SBarry Smith } 3673be5caee7SBarry Smith 367485216dc7SFande Kong /*@ 3675f6dfbefdSBarry Smith SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm 367685216dc7SFande Kong 3677c3339decSBarry Smith Logically Collective 367885216dc7SFande Kong 367985216dc7SFande Kong Input Parameters: 3680f6dfbefdSBarry Smith . snes - the `SNES` context 368185216dc7SFande Kong 368285216dc7SFande Kong Output Parameter: 3683*dc4c0fb0SBarry Smith . force - `PETSC_TRUE` requires at least one iteration. 368485216dc7SFande Kong 368506dd6b0eSSatish Balay Level: intermediate 368606dd6b0eSSatish Balay 3687*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 368885216dc7SFande Kong @*/ 3689d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) 3690d71ae5a4SJacob Faibussowitsch { 369185216dc7SFande Kong PetscFunctionBegin; 369285216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 369385216dc7SFande Kong *force = snes->forceiteration; 36943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 369585216dc7SFande Kong } 3696be5caee7SBarry Smith 3697be5caee7SBarry Smith /*@ 3698f6dfbefdSBarry Smith SNESSetTolerances - Sets `SNES` various parameters used in convergence tests. 36999b94acceSBarry Smith 3700c3339decSBarry Smith Logically Collective 3701c7afd0dbSLois Curfman McInnes 37029b94acceSBarry Smith Input Parameters: 3703f6dfbefdSBarry Smith + snes - the `SNES` context 370470441072SBarry Smith . abstol - absolute convergence tolerance 370533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 37065358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3707f6dfbefdSBarry Smith . maxit - maximum number of iterations, default 50. 3708f6dfbefdSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit), default 1000 3709fee21e36SBarry Smith 371033174efeSLois Curfman McInnes Options Database Keys: 371170441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3712c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3713c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3714c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3715c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 37169b94acceSBarry Smith 371736851e7fSLois Curfman McInnes Level: intermediate 371836851e7fSLois Curfman McInnes 3719*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 37209b94acceSBarry Smith @*/ 3721d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) 3722d71ae5a4SJacob Faibussowitsch { 37233a40ed3dSBarry Smith PetscFunctionBegin; 37240700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3725c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3726c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3727c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3728c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3729c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3730c5eb9154SBarry Smith 3731ab54825eSJed Brown if (abstol != PETSC_DEFAULT) { 37325f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3733ab54825eSJed Brown snes->abstol = abstol; 3734ab54825eSJed Brown } 3735ab54825eSJed Brown if (rtol != PETSC_DEFAULT) { 37365f80ce2aSJacob 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); 3737ab54825eSJed Brown snes->rtol = rtol; 3738ab54825eSJed Brown } 3739ab54825eSJed Brown if (stol != PETSC_DEFAULT) { 37405f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3741c60f73f4SPeter Brune snes->stol = stol; 3742ab54825eSJed Brown } 3743ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 374463a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3745ab54825eSJed Brown snes->max_its = maxit; 3746ab54825eSJed Brown } 3747ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 374863a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3749ab54825eSJed Brown snes->max_funcs = maxf; 3750ab54825eSJed Brown } 375188976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 37523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37539b94acceSBarry Smith } 37549b94acceSBarry Smith 3755e4d06f11SPatrick Farrell /*@ 3756f6dfbefdSBarry Smith SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test. 3757e4d06f11SPatrick Farrell 3758c3339decSBarry Smith Logically Collective 3759e4d06f11SPatrick Farrell 3760e4d06f11SPatrick Farrell Input Parameters: 3761f6dfbefdSBarry Smith + snes - the `SNES` context 3762f6dfbefdSBarry Smith - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4 3763e4d06f11SPatrick Farrell 3764f6dfbefdSBarry Smith Options Database Key: 3765*dc4c0fb0SBarry Smith . -snes_divergence_tolerance <divtol> - Sets `divtol` 3766e4d06f11SPatrick Farrell 3767e4d06f11SPatrick Farrell Level: intermediate 3768e4d06f11SPatrick Farrell 3769*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3770e4d06f11SPatrick Farrell @*/ 3771d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) 3772d71ae5a4SJacob Faibussowitsch { 3773e4d06f11SPatrick Farrell PetscFunctionBegin; 3774e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3775e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3776e4d06f11SPatrick Farrell 3777e4d06f11SPatrick Farrell if (divtol != PETSC_DEFAULT) { 3778e4d06f11SPatrick Farrell snes->divtol = divtol; 37799371c9d4SSatish Balay } else { 3780e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3781e4d06f11SPatrick Farrell } 37823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3783e4d06f11SPatrick Farrell } 3784e4d06f11SPatrick Farrell 37859b94acceSBarry Smith /*@ 378633174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 378733174efeSLois Curfman McInnes 3788c7afd0dbSLois Curfman McInnes Not Collective 3789c7afd0dbSLois Curfman McInnes 379033174efeSLois Curfman McInnes Input Parameters: 3791f6dfbefdSBarry Smith + snes - the `SNES` context 379285385478SLisandro Dalcin . atol - absolute convergence tolerance 379333174efeSLois Curfman McInnes . rtol - relative convergence tolerance 379433174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 379533174efeSLois Curfman McInnes of the change in the solution between steps 379633174efeSLois Curfman McInnes . maxit - maximum number of iterations 3797c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3798fee21e36SBarry Smith 379936851e7fSLois Curfman McInnes Level: intermediate 380036851e7fSLois Curfman McInnes 3801*dc4c0fb0SBarry Smith Note: 3802*dc4c0fb0SBarry Smith The user can specify `NULL` for any parameter that is not needed. 3803*dc4c0fb0SBarry Smith 3804*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTolerances()` 380533174efeSLois Curfman McInnes @*/ 3806d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) 3807d71ae5a4SJacob Faibussowitsch { 38083a40ed3dSBarry Smith PetscFunctionBegin; 38090700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 381085385478SLisandro Dalcin if (atol) *atol = snes->abstol; 381133174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3812c60f73f4SPeter Brune if (stol) *stol = snes->stol; 381333174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 381433174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 38153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 381633174efeSLois Curfman McInnes } 381733174efeSLois Curfman McInnes 3818e4d06f11SPatrick Farrell /*@ 3819e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3820e4d06f11SPatrick Farrell 3821e4d06f11SPatrick Farrell Not Collective 3822e4d06f11SPatrick Farrell 3823e4d06f11SPatrick Farrell Input Parameters: 3824f6dfbefdSBarry Smith + snes - the `SNES` context 3825e4d06f11SPatrick Farrell - divtol - divergence tolerance 3826e4d06f11SPatrick Farrell 3827e4d06f11SPatrick Farrell Level: intermediate 3828e4d06f11SPatrick Farrell 3829*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetDivergenceTolerance()` 3830e4d06f11SPatrick Farrell @*/ 3831d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) 3832d71ae5a4SJacob Faibussowitsch { 3833e4d06f11SPatrick Farrell PetscFunctionBegin; 3834e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3835e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 38363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3837e4d06f11SPatrick Farrell } 3838e4d06f11SPatrick Farrell 383933174efeSLois Curfman McInnes /*@ 38409b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 38419b94acceSBarry Smith 3842c3339decSBarry Smith Logically Collective 3843fee21e36SBarry Smith 3844c7afd0dbSLois Curfman McInnes Input Parameters: 3845f6dfbefdSBarry Smith + snes - the `SNES` context 3846c7afd0dbSLois Curfman McInnes - tol - tolerance 3847c7afd0dbSLois Curfman McInnes 38489b94acceSBarry Smith Options Database Key: 3849c7afd0dbSLois Curfman McInnes . -snes_trtol <tol> - Sets tol 38509b94acceSBarry Smith 385136851e7fSLois Curfman McInnes Level: intermediate 385236851e7fSLois Curfman McInnes 3853*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESNEWTONTRDC`, `SNESSetTolerances()` 38549b94acceSBarry Smith @*/ 3855d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) 3856d71ae5a4SJacob Faibussowitsch { 38573a40ed3dSBarry Smith PetscFunctionBegin; 38580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3859c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 38609b94acceSBarry Smith snes->deltatol = tol; 38613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38629b94acceSBarry Smith } 38639b94acceSBarry Smith 38646ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 38656ba87a44SLisandro Dalcin 3866d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) 3867d71ae5a4SJacob Faibussowitsch { 3868b271bb04SBarry Smith PetscDrawLG lg; 3869b271bb04SBarry Smith PetscReal x, y, per; 3870b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3871b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3872b271bb04SBarry Smith PetscDraw draw; 3873b271bb04SBarry Smith 3874459f5d12SBarry Smith PetscFunctionBegin; 38754d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 38769566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 38779566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38789566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38799566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3880b271bb04SBarry Smith x = (PetscReal)n; 388177b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 388294c9c6d3SKarl Rupp else y = -15.0; 38839566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38846934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38859566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38869566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3887b271bb04SBarry Smith } 3888b271bb04SBarry Smith 38899566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 38909566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38919566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38929566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "% elemts > .2*max elemt")); 38939566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3894b271bb04SBarry Smith x = (PetscReal)n; 3895b271bb04SBarry Smith y = 100.0 * per; 38969566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38976934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38989566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38999566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3900b271bb04SBarry Smith } 3901b271bb04SBarry Smith 39029566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 39039371c9d4SSatish Balay if (!n) { 39049371c9d4SSatish Balay prev = rnorm; 39059371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 39069371c9d4SSatish Balay } 39079566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 39089566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3909b271bb04SBarry Smith x = (PetscReal)n; 3910b271bb04SBarry Smith y = (prev - rnorm) / prev; 39119566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 39126934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39139566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39149566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3915b271bb04SBarry Smith } 3916b271bb04SBarry Smith 39179566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 39189566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 39199566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 39209566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3921b271bb04SBarry Smith x = (PetscReal)n; 3922b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3923b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 39249566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3925b271bb04SBarry Smith } 39266934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39279566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39289566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3929b271bb04SBarry Smith } 3930b271bb04SBarry Smith prev = rnorm; 39313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3932b271bb04SBarry Smith } 3933b271bb04SBarry Smith 3934228d79bcSJed Brown /*@ 3935228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3936228d79bcSJed Brown 3937c3339decSBarry Smith Collective 3938228d79bcSJed Brown 3939228d79bcSJed Brown Input Parameters: 3940f6dfbefdSBarry Smith + snes - nonlinear solver context obtained from `SNESCreate()` 3941228d79bcSJed Brown . iter - iteration number 3942228d79bcSJed Brown - rnorm - relative norm of the residual 3943228d79bcSJed Brown 3944*dc4c0fb0SBarry Smith Level: developer 3945*dc4c0fb0SBarry Smith 3946f6dfbefdSBarry Smith Note: 3947f6dfbefdSBarry Smith This routine is called by the `SNES` implementations. 3948228d79bcSJed Brown It does not typically need to be called by the user. 3949228d79bcSJed Brown 3950*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()` 3951228d79bcSJed Brown @*/ 3952d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) 3953d71ae5a4SJacob Faibussowitsch { 39547a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 39557a03ce2fSLisandro Dalcin 39567a03ce2fSLisandro Dalcin PetscFunctionBegin; 39579566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 395848a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 39599566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 39603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39617a03ce2fSLisandro Dalcin } 39627a03ce2fSLisandro Dalcin 39639b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 39649b94acceSBarry Smith 3965bf388a1fSBarry Smith /*MC 3966f6dfbefdSBarry Smith SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver 3967bf388a1fSBarry Smith 3968bf388a1fSBarry Smith Synopsis: 3969aaa7dc30SBarry Smith #include <petscsnes.h> 3970bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3971bf388a1fSBarry Smith 3972c3339decSBarry Smith Collective 39731843f636SBarry Smith 39741843f636SBarry Smith Input Parameters: 3975f6dfbefdSBarry Smith + snes - the `SNES` context 3976bf388a1fSBarry Smith . its - iteration number 3977bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3978bf388a1fSBarry Smith - mctx - [optional] monitoring context 3979bf388a1fSBarry Smith 3980878cb397SSatish Balay Level: advanced 3981878cb397SSatish Balay 3982*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()` 3983bf388a1fSBarry Smith M*/ 3984bf388a1fSBarry Smith 39859b94acceSBarry Smith /*@C 3986a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 39879b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 39889b94acceSBarry Smith progress. 39899b94acceSBarry Smith 3990c3339decSBarry Smith Logically Collective 3991fee21e36SBarry Smith 3992c7afd0dbSLois Curfman McInnes Input Parameters: 3993f6dfbefdSBarry Smith + snes - the `SNES` context 3994f6dfbefdSBarry Smith . f - the monitor function, see `SNESMonitorFunction` for the calling sequence 3995b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3996*dc4c0fb0SBarry Smith monitor routine (use `NULL` if no context is desired) 3997*dc4c0fb0SBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 39989b94acceSBarry Smith 39999665c990SLois Curfman McInnes Options Database Keys: 4000f6dfbefdSBarry Smith + -snes_monitor - sets `SNESMonitorDefault()` 4001798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 4002*dc4c0fb0SBarry Smith - -snes_monitor_cancel - cancels all monitors that have been hardwired into a code by calls to `SNESMonitorSet()`, but does not cancel those set via 4003c7afd0dbSLois Curfman McInnes the options database. 40049665c990SLois Curfman McInnes 4005*dc4c0fb0SBarry Smith Level: intermediate 4006*dc4c0fb0SBarry Smith 4007f6dfbefdSBarry Smith Note: 40086bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 4009f6dfbefdSBarry Smith `SNESMonitorSet()` multiple times; all will be called in the 40106bc08f3fSLois Curfman McInnes order in which they were set. 4011639f9d9dSBarry Smith 4012f6dfbefdSBarry Smith Fortran Note: 4013f6dfbefdSBarry Smith Only a single monitor function can be set for each `SNES` object 4014025f1a04SBarry Smith 4015*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 40169b94acceSBarry Smith @*/ 4017d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 4018d71ae5a4SJacob Faibussowitsch { 4019b90d0a6eSBarry Smith PetscInt i; 402078064530SBarry Smith PetscBool identical; 4021b90d0a6eSBarry Smith 40223a40ed3dSBarry Smith PetscFunctionBegin; 40230700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4024b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 40259566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 40263ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4027649052a6SBarry Smith } 40285f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 40296e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4030b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4031639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 40323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40339b94acceSBarry Smith } 40349b94acceSBarry Smith 4035a278d85bSSatish Balay /*@ 4036f6dfbefdSBarry Smith SNESMonitorCancel - Clears all the monitor functions for a `SNES` object. 40375cd90555SBarry Smith 4038c3339decSBarry Smith Logically Collective 4039c7afd0dbSLois Curfman McInnes 40405cd90555SBarry Smith Input Parameters: 4041f6dfbefdSBarry Smith . snes - the `SNES` context 40425cd90555SBarry Smith 40431a480d89SAdministrator Options Database Key: 4044a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4045*dc4c0fb0SBarry Smith into a code by calls to `SNESMonitorSet()`, but does not cancel those 4046c7afd0dbSLois Curfman McInnes set via the options database 40475cd90555SBarry Smith 4048*dc4c0fb0SBarry Smith Level: intermediate 4049*dc4c0fb0SBarry Smith 4050f6dfbefdSBarry Smith Note: 4051f6dfbefdSBarry Smith There is no way to clear one specific monitor from a `SNES` object. 40525cd90555SBarry Smith 4053*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()` 40545cd90555SBarry Smith @*/ 4055d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorCancel(SNES snes) 4056d71ae5a4SJacob Faibussowitsch { 4057d952e501SBarry Smith PetscInt i; 4058d952e501SBarry Smith 40595cd90555SBarry Smith PetscFunctionBegin; 40600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4061d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 406248a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4063d952e501SBarry Smith } 40645cd90555SBarry Smith snes->numbermonitors = 0; 40653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40665cd90555SBarry Smith } 40675cd90555SBarry Smith 4068bf388a1fSBarry Smith /*MC 4069bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4070bf388a1fSBarry Smith 4071bf388a1fSBarry Smith Synopsis: 4072aaa7dc30SBarry Smith #include <petscsnes.h> 4073bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4074bf388a1fSBarry Smith 4075c3339decSBarry Smith Collective 40761843f636SBarry Smith 40771843f636SBarry Smith Input Parameters: 4078f6dfbefdSBarry Smith + snes - the `SNES` context 4079bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4080bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4081bf388a1fSBarry Smith . gnorm - 2-norm of current step 40821843f636SBarry Smith . f - 2-norm of function 40831843f636SBarry Smith - cctx - [optional] convergence context 40841843f636SBarry Smith 40851843f636SBarry Smith Output Parameter: 40861843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4087bf388a1fSBarry Smith 4088878cb397SSatish Balay Level: intermediate 4089bf388a1fSBarry Smith 4090*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4091bf388a1fSBarry Smith M*/ 4092bf388a1fSBarry Smith 40939b94acceSBarry Smith /*@C 40949b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40959b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40969b94acceSBarry Smith 4097c3339decSBarry Smith Logically Collective 4098fee21e36SBarry Smith 4099c7afd0dbSLois Curfman McInnes Input Parameters: 4100f6dfbefdSBarry Smith + snes - the `SNES` context 4101f6dfbefdSBarry Smith . `SNESConvergenceTestFunction` - routine to test for convergence 4102*dc4c0fb0SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be `NULL`) 4103*dc4c0fb0SBarry Smith - destroy - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran) 41049b94acceSBarry Smith 410536851e7fSLois Curfman McInnes Level: advanced 410636851e7fSLois Curfman McInnes 4107*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 41089b94acceSBarry Smith @*/ 4109d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) 4110d71ae5a4SJacob Faibussowitsch { 41113a40ed3dSBarry Smith PetscFunctionBegin; 41120700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4113e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 41141baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4115bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 41167f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 411785385478SLisandro Dalcin snes->cnvP = cctx; 41183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41199b94acceSBarry Smith } 41209b94acceSBarry Smith 412152baeb72SSatish Balay /*@ 4122f6dfbefdSBarry Smith SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped. 4123184914b5SBarry Smith 4124184914b5SBarry Smith Not Collective 4125184914b5SBarry Smith 4126184914b5SBarry Smith Input Parameter: 4127f6dfbefdSBarry Smith . snes - the `SNES` context 4128184914b5SBarry Smith 4129184914b5SBarry Smith Output Parameter: 4130f6dfbefdSBarry Smith . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists 4131184914b5SBarry Smith 4132f6dfbefdSBarry Smith Options Database Key: 41336a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 41346a4d7782SBarry Smith 4135184914b5SBarry Smith Level: intermediate 4136184914b5SBarry Smith 4137f6dfbefdSBarry Smith Note: 4138f6dfbefdSBarry Smith Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`. 4139184914b5SBarry Smith 4140*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()` 4141184914b5SBarry Smith @*/ 4142d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) 4143d71ae5a4SJacob Faibussowitsch { 4144184914b5SBarry Smith PetscFunctionBegin; 41450700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41464482741eSBarry Smith PetscValidPointer(reason, 2); 4147184914b5SBarry Smith *reason = snes->reason; 41483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4149184914b5SBarry Smith } 4150184914b5SBarry Smith 4151c4421ceaSFande Kong /*@C 4152f6dfbefdSBarry Smith SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason` 4153c4421ceaSFande Kong 4154c4421ceaSFande Kong Not Collective 4155c4421ceaSFande Kong 4156c4421ceaSFande Kong Input Parameter: 4157f6dfbefdSBarry Smith . snes - the `SNES` context 4158c4421ceaSFande Kong 4159c4421ceaSFande Kong Output Parameter: 4160*dc4c0fb0SBarry Smith . strreason - a human readable string that describes `SNES` converged reason 4161c4421ceaSFande Kong 416299c90e12SSatish Balay Level: beginner 4163c4421ceaSFande Kong 4164*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetConvergedReason()` 4165c4421ceaSFande Kong @*/ 4166d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) 4167d71ae5a4SJacob Faibussowitsch { 4168c4421ceaSFande Kong PetscFunctionBegin; 4169c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4170dadcf809SJacob Faibussowitsch PetscValidPointer(strreason, 2); 4171c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 41723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4173c4421ceaSFande Kong } 4174c4421ceaSFande Kong 417533866048SMatthew G. Knepley /*@ 4176f6dfbefdSBarry Smith SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped. 417733866048SMatthew G. Knepley 417833866048SMatthew G. Knepley Not Collective 417933866048SMatthew G. Knepley 418033866048SMatthew G. Knepley Input Parameters: 4181f6dfbefdSBarry Smith + snes - the `SNES` context 4182f6dfbefdSBarry Smith - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the 418333866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 418433866048SMatthew G. Knepley 4185f6dfbefdSBarry Smith Level: developer 4186f6dfbefdSBarry Smith 4187f6dfbefdSBarry Smith Developer Note: 4188f6dfbefdSBarry Smith Called inside the various `SNESSolve()` implementations 418933866048SMatthew G. Knepley 4190*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 419133866048SMatthew G. Knepley @*/ 4192d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) 4193d71ae5a4SJacob Faibussowitsch { 419433866048SMatthew G. Knepley PetscFunctionBegin; 419533866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 419633866048SMatthew G. Knepley snes->reason = reason; 41973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 419833866048SMatthew G. Knepley } 419933866048SMatthew G. Knepley 4200c9005455SLois Curfman McInnes /*@ 4201c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4202c9005455SLois Curfman McInnes 4203c3339decSBarry Smith Logically Collective 4204fee21e36SBarry Smith 4205c7afd0dbSLois Curfman McInnes Input Parameters: 4206f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 42078c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4208cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4209758f92a0SBarry Smith . na - size of a and its 4210f6dfbefdSBarry Smith - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero, 4211758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4212c7afd0dbSLois Curfman McInnes 4213*dc4c0fb0SBarry Smith Level: intermediate 4214*dc4c0fb0SBarry Smith 4215308dcc3eSBarry Smith Notes: 4216*dc4c0fb0SBarry Smith If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a 4217308dcc3eSBarry Smith default array of length 10000 is allocated. 4218308dcc3eSBarry Smith 4219c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4220c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4221c9005455SLois Curfman McInnes during the section of code that is being timed. 4222c9005455SLois Curfman McInnes 4223*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()` 4224c9005455SLois Curfman McInnes @*/ 4225d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) 4226d71ae5a4SJacob Faibussowitsch { 42273a40ed3dSBarry Smith PetscFunctionBegin; 42280700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4229064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a, 2); 4230a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its, 3); 42317a1ec6d4SBarry Smith if (!a) { 4232308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 42339566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4234071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4235308dcc3eSBarry Smith } 4236c9005455SLois Curfman McInnes snes->conv_hist = a; 4237758f92a0SBarry Smith snes->conv_hist_its = its; 4238115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4239a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4240758f92a0SBarry Smith snes->conv_hist_reset = reset; 42413ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4242758f92a0SBarry Smith } 4243758f92a0SBarry Smith 4244d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB) 4245c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4246c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 424799e0435eSBarry Smith 4248d71ae5a4SJacob Faibussowitsch PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4249d71ae5a4SJacob Faibussowitsch { 4250308dcc3eSBarry Smith mxArray *mat; 4251308dcc3eSBarry Smith PetscInt i; 4252308dcc3eSBarry Smith PetscReal *ar; 4253308dcc3eSBarry Smith 4254308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4255308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4256f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 425711cc89d2SBarry Smith return mat; 4258308dcc3eSBarry Smith } 4259308dcc3eSBarry Smith #endif 4260308dcc3eSBarry Smith 42610c4c9dddSBarry Smith /*@C 4262758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4263758f92a0SBarry Smith 42643f9fe445SBarry Smith Not Collective 4265758f92a0SBarry Smith 4266758f92a0SBarry Smith Input Parameter: 4267f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 4268758f92a0SBarry Smith 4269758f92a0SBarry Smith Output Parameters: 4270f6dfbefdSBarry Smith + a - array to hold history, usually was set with `SNESSetConvergenceHistory()` 4271758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4272758f92a0SBarry Smith negative if not converged) for each solve. 4273758f92a0SBarry Smith - na - size of a and its 4274758f92a0SBarry Smith 4275*dc4c0fb0SBarry Smith Level: intermediate 4276*dc4c0fb0SBarry Smith 4277758f92a0SBarry Smith Notes: 4278758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4279*dc4c0fb0SBarry Smith .vb 4280*dc4c0fb0SBarry Smith call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4281*dc4c0fb0SBarry Smith .ve 4282758f92a0SBarry Smith 4283758f92a0SBarry Smith This routine is useful, e.g., when running a code for purposes 4284758f92a0SBarry Smith of accurate performance monitoring, when no I/O should be done 4285758f92a0SBarry Smith during the section of code that is being timed. 4286758f92a0SBarry Smith 4287*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()` 4288758f92a0SBarry Smith @*/ 4289d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) 4290d71ae5a4SJacob Faibussowitsch { 4291758f92a0SBarry Smith PetscFunctionBegin; 42920700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4293758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4294758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4295115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 42963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4297c9005455SLois Curfman McInnes } 4298c9005455SLois Curfman McInnes 4299ac226902SBarry Smith /*@C 430076b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4301eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 43027e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 430376b2cf59SMatthew Knepley 4304c3339decSBarry Smith Logically Collective 430576b2cf59SMatthew Knepley 430676b2cf59SMatthew Knepley Input Parameters: 4307a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4308a2b725a8SWilliam Gropp - func - The function 430976b2cf59SMatthew Knepley 431076b2cf59SMatthew Knepley Calling sequence of func: 4311a2b725a8SWilliam Gropp $ func (SNES snes, PetscInt step); 431276b2cf59SMatthew Knepley 431376b2cf59SMatthew Knepley . step - The current step of the iteration 431476b2cf59SMatthew Knepley 4315fe97e370SBarry Smith Level: advanced 4316fe97e370SBarry Smith 43176b7fb656SBarry Smith Note: 4318f6dfbefdSBarry 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 4319f6dfbefdSBarry Smith to `SNESSetFunction()`, or `SNESSetPicard()` 4320fe97e370SBarry Smith This is not used by most users. 432176b2cf59SMatthew Knepley 43226b7fb656SBarry 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. 43236b7fb656SBarry Smith 4324*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4325db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 432676b2cf59SMatthew Knepley @*/ 4327d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4328d71ae5a4SJacob Faibussowitsch { 432976b2cf59SMatthew Knepley PetscFunctionBegin; 43300700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4331e7788613SBarry Smith snes->ops->update = func; 43323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 433376b2cf59SMatthew Knepley } 433476b2cf59SMatthew Knepley 43359b94acceSBarry Smith /* 43369b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 43379b94acceSBarry Smith positive parameter delta. 43389b94acceSBarry Smith 43399b94acceSBarry Smith Input Parameters: 4340f6dfbefdSBarry Smith + snes - the `SNES` context 43419b94acceSBarry Smith . y - approximate solution of linear system 43429b94acceSBarry Smith . fnorm - 2-norm of current function 4343c7afd0dbSLois Curfman McInnes - delta - trust region size 43449b94acceSBarry Smith 43459b94acceSBarry Smith Output Parameters: 4346c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 43479b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 43489b94acceSBarry Smith region, and exceeds zero otherwise. 4349c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 43509b94acceSBarry Smith 4351f6dfbefdSBarry Smith Level: developer 43529b94acceSBarry Smith 4353f6dfbefdSBarry Smith Note: 4354f6dfbefdSBarry Smith For non-trust region methods such as `SNESNEWTONLS`, the parameter delta 4355f6dfbefdSBarry Smith is set to be the maximum allowable step size. 43569b94acceSBarry Smith */ 4357d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm) 4358d71ae5a4SJacob Faibussowitsch { 4359064f8208SBarry Smith PetscReal nrm; 4360ea709b57SSatish Balay PetscScalar cnorm; 43613a40ed3dSBarry Smith 43623a40ed3dSBarry Smith PetscFunctionBegin; 43630700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 43640700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 2); 4365c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 2); 4366184914b5SBarry Smith 43679566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 4368064f8208SBarry Smith if (nrm > *delta) { 4369064f8208SBarry Smith nrm = *delta / nrm; 4370064f8208SBarry Smith *gpnorm = (1.0 - nrm) * (*fnorm); 4371064f8208SBarry Smith cnorm = nrm; 43729566063dSJacob Faibussowitsch PetscCall(VecScale(y, cnorm)); 43739b94acceSBarry Smith *ynorm = *delta; 43749b94acceSBarry Smith } else { 43759b94acceSBarry Smith *gpnorm = 0.0; 4376064f8208SBarry Smith *ynorm = nrm; 43779b94acceSBarry Smith } 43783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43799b94acceSBarry Smith } 43809b94acceSBarry Smith 438191f3e32bSBarry Smith /*@C 4382f6dfbefdSBarry Smith SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer 43832a359c20SBarry Smith 4384c3339decSBarry Smith Collective 43852a359c20SBarry Smith 43862a359c20SBarry Smith Parameter: 4387f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 43882a359c20SBarry Smith - viewer - the viewer to display the reason 43892a359c20SBarry Smith 43902a359c20SBarry Smith Options Database Keys: 4391ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4392ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4393eafd5ff0SAlex Lindsay 4394f6dfbefdSBarry Smith Note: 4395f6dfbefdSBarry Smith To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default, 4396f6dfbefdSBarry Smith use `PETSC_VIEWER_FAILED` to only display a reason if it fails. 43972a359c20SBarry Smith 43982a359c20SBarry Smith Level: beginner 43992a359c20SBarry Smith 4400*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`, 4401f6dfbefdSBarry Smith `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, 4402f6dfbefdSBarry Smith `SNESConvergedReasonViewFromOptions()`, 4403db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 44042a359c20SBarry Smith @*/ 4405d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) 4406d71ae5a4SJacob Faibussowitsch { 440775cca76cSMatthew G. Knepley PetscViewerFormat format; 44082a359c20SBarry Smith PetscBool isAscii; 44092a359c20SBarry Smith 44102a359c20SBarry Smith PetscFunctionBegin; 441119a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 44129566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 44132a359c20SBarry Smith if (isAscii) { 44149566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 44159566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 441675cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 441775cca76cSMatthew G. Knepley DM dm; 441875cca76cSMatthew G. Knepley Vec u; 441975cca76cSMatthew G. Knepley PetscDS prob; 442075cca76cSMatthew G. Knepley PetscInt Nf, f; 442195cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 442295cbbfd3SMatthew G. Knepley void **exactCtx; 442375cca76cSMatthew G. Knepley PetscReal error; 442475cca76cSMatthew G. Knepley 44259566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 44269566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 44279566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 44289566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 44299566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 44309566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 44319566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 44329566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 44339566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 443463a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 443575cca76cSMatthew G. Knepley } 4436eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 44372a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 443863a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 44392a359c20SBarry Smith } else { 444063a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44412a359c20SBarry Smith } 4442eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 44432a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 444463a3b9bcSJacob 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)); 44452a359c20SBarry Smith } else { 444663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44472a359c20SBarry Smith } 44482a359c20SBarry Smith } 44499566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 44502a359c20SBarry Smith } 44513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44522a359c20SBarry Smith } 44532a359c20SBarry Smith 4454c4421ceaSFande Kong /*@C 4455c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4456c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4457c4421ceaSFande Kong 4458c3339decSBarry Smith Logically Collective 4459c4421ceaSFande Kong 4460c4421ceaSFande Kong Input Parameters: 4461f6dfbefdSBarry Smith + snes - the `SNES` context 4462c4421ceaSFande Kong . f - the snes converged reason view function 4463c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4464*dc4c0fb0SBarry Smith snes converged reason view routine (use `NULL` if no context is desired) 4465*dc4c0fb0SBarry Smith - reasonviewdestroy - [optional] routine that frees reasonview context (may be `NULL`) 4466c4421ceaSFande Kong 4467c4421ceaSFande Kong Options Database Keys: 4468f6dfbefdSBarry Smith + -snes_converged_reason - sets a default `SNESConvergedReasonView()` 4469c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4470c4421ceaSFande Kong been hardwired into a code by 4471f6dfbefdSBarry Smith calls to `SNESConvergedReasonViewSet()`, but 4472c4421ceaSFande Kong does not cancel those set via 4473c4421ceaSFande Kong the options database. 4474c4421ceaSFande Kong 4475*dc4c0fb0SBarry Smith Level: intermediate 4476*dc4c0fb0SBarry Smith 4477f6dfbefdSBarry Smith Note: 4478c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4479f6dfbefdSBarry Smith `SNESConvergedReasonViewSet()` multiple times; all will be called in the 4480c4421ceaSFande Kong order in which they were set. 4481c4421ceaSFande Kong 4482*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4483c4421ceaSFande Kong @*/ 4484d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) 4485d71ae5a4SJacob Faibussowitsch { 4486c4421ceaSFande Kong PetscInt i; 4487c4421ceaSFande Kong PetscBool identical; 4488c4421ceaSFande Kong 4489c4421ceaSFande Kong PetscFunctionBegin; 4490c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4491c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 44929566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 44933ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4494c4421ceaSFande Kong } 44955f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4496c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4497c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4498c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 44993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4500c4421ceaSFande Kong } 4501c4421ceaSFande Kong 450291f3e32bSBarry Smith /*@ 4503f6dfbefdSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed. 4504c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 45052a359c20SBarry Smith 4506c3339decSBarry Smith Collective 45072a359c20SBarry Smith 45082a359c20SBarry Smith Input Parameters: 4509f6dfbefdSBarry Smith . snes - the `SNES` object 45102a359c20SBarry Smith 4511f6dfbefdSBarry Smith Level: advanced 45122a359c20SBarry Smith 4513*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, 4514f6dfbefdSBarry Smith `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 45152a359c20SBarry Smith @*/ 4516d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4517d71ae5a4SJacob Faibussowitsch { 45182a359c20SBarry Smith PetscViewer viewer; 45192a359c20SBarry Smith PetscBool flg; 45202a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 45212a359c20SBarry Smith PetscViewerFormat format; 4522c4421ceaSFande Kong PetscInt i; 45232a359c20SBarry Smith 45242a359c20SBarry Smith PetscFunctionBegin; 45253ba16761SJacob Faibussowitsch if (incall) PetscFunctionReturn(PETSC_SUCCESS); 45262a359c20SBarry Smith incall = PETSC_TRUE; 4527c4421ceaSFande Kong 4528c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 452948a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4530c4421ceaSFande Kong 4531c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 45329566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 45332a359c20SBarry Smith if (flg) { 45349566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45359566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 45369566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45379566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45382a359c20SBarry Smith } 45392a359c20SBarry Smith incall = PETSC_FALSE; 45403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45412a359c20SBarry Smith } 45422a359c20SBarry Smith 4543487a658cSBarry Smith /*@ 4544f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4545f6dfbefdSBarry Smith Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`. 45469b94acceSBarry Smith 4547c3339decSBarry Smith Collective 4548c7afd0dbSLois Curfman McInnes 4549b2002411SLois Curfman McInnes Input Parameters: 4550f6dfbefdSBarry Smith + snes - the `SNES` context 4551*dc4c0fb0SBarry Smith . b - the constant part of the equation F(x) = b, or `NULL` to use zero. 455285385478SLisandro Dalcin - x - the solution vector. 45539b94acceSBarry Smith 4554*dc4c0fb0SBarry Smith Level: beginner 4555*dc4c0fb0SBarry Smith 4556f6dfbefdSBarry Smith Note: 45578ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 4558f6dfbefdSBarry Smith for the nonlinear solve prior to calling `SNESSolve()`. In particular, 45598ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 4560f6dfbefdSBarry Smith this vector to zero by calling `VecSet()`. 45618ddd3da0SLois Curfman McInnes 4562*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4563db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4564db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 45659b94acceSBarry Smith @*/ 4566d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) 4567d71ae5a4SJacob Faibussowitsch { 4568ace3abfcSBarry Smith PetscBool flg; 4569efd51863SBarry Smith PetscInt grid; 45700298fd71SBarry Smith Vec xcreated = NULL; 4571caa4e7f2SJed Brown DM dm; 4572052efed2SBarry Smith 45733a40ed3dSBarry Smith PetscFunctionBegin; 45740700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4575a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4576a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 45770700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 457885385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 457985385478SLisandro Dalcin 458034b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 458106fc46c8SMatthew G. Knepley { 458206fc46c8SMatthew G. Knepley PetscViewer viewer; 458306fc46c8SMatthew G. Knepley PetscViewerFormat format; 45847c88af5aSMatthew G. Knepley PetscInt num; 458506fc46c8SMatthew G. Knepley PetscBool flg; 458606fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 458706fc46c8SMatthew G. Knepley 458806fc46c8SMatthew G. Knepley if (!incall) { 458934b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 45909566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 459106fc46c8SMatthew G. Knepley if (flg) { 459206fc46c8SMatthew G. Knepley PetscConvEst conv; 459346079b62SMatthew G. Knepley DM dm; 459446079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 459546079b62SMatthew G. Knepley PetscInt Nf; 459606fc46c8SMatthew G. Knepley 459706fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 45989566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45999566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 46009566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 46019566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 46029566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 46039566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 46049566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 46059566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 46069566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 46079566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 46089566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 46099566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 46109566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 46119566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 461206fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 461306fc46c8SMatthew G. Knepley } 461434b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4615b2588ea6SMatthew G. Knepley num = 1; 46169566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 461734b4d3a8SMatthew G. Knepley if (flg) { 461834b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 461934b4d3a8SMatthew G. Knepley 462034b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 46219566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46229566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46239566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46249566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46259566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46269566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 46279566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 462834b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 462934b4d3a8SMatthew G. Knepley } 46307c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 46317c88af5aSMatthew G. Knepley num = 0; 46329566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 46337c88af5aSMatthew G. Knepley if (num) { 46347c88af5aSMatthew G. Knepley DMAdaptor adaptor; 46357c88af5aSMatthew G. Knepley 46367c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 46379566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46389566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46399566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46409566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46419566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46429566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 46439566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 46447c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 46457c88af5aSMatthew G. Knepley } 464606fc46c8SMatthew G. Knepley } 464706fc46c8SMatthew G. Knepley } 4648ad540459SPierre Jolivet if (!x) x = snes->vec_sol; 4649caa4e7f2SJed Brown if (!x) { 46509566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 46519566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4652a69afd8bSBarry Smith x = xcreated; 4653a69afd8bSBarry Smith } 46549566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4655f05ece33SBarry Smith 46569566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4657efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 465885385478SLisandro Dalcin /* set solution vector */ 46599566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 46609566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 466185385478SLisandro Dalcin snes->vec_sol = x; 46629566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4663caa4e7f2SJed Brown 4664caa4e7f2SJed Brown /* set affine vector if provided */ 46659566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 46669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 466785385478SLisandro Dalcin snes->vec_rhs = b; 466885385478SLisandro Dalcin 46695f80ce2aSJacob 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"); 46705f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 46715f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 46724dfa11a4SJacob Faibussowitsch if (!snes->vec_sol_update /* && snes->vec_sol */) { PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); } 46739566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 46749566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 46753f149594SLisandro Dalcin 46767eee914bSBarry Smith if (!grid) { 467725e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4678dd568438SSatish Balay } 4679d25893d9SBarry Smith 4680abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 46819371c9d4SSatish Balay if (snes->counters_reset) { 46829371c9d4SSatish Balay snes->nfuncs = 0; 46839371c9d4SSatish Balay snes->linear_its = 0; 46849371c9d4SSatish Balay snes->numFailures = 0; 46859371c9d4SSatish Balay } 4686d5e45103SBarry Smith 46879566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4688dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 46899566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 46905f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason"); 4691422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 46923f149594SLisandro Dalcin 469337ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 469437ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 469537ec4e1aSPeter Brune 46969566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 46979566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4698c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 46999566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 47005968eb51SBarry Smith 47015f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 47029c8e83a9SBarry Smith if (snes->reason < 0) break; 4703efd51863SBarry Smith if (grid < snes->gridsequence) { 4704efd51863SBarry Smith DM fine; 4705efd51863SBarry Smith Vec xnew; 4706efd51863SBarry Smith Mat interp; 4707efd51863SBarry Smith 47089566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 47095f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 47109566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 47119566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 47129566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 47139566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 47149566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4715efd51863SBarry Smith x = xnew; 4716efd51863SBarry Smith 47179566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 47189566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 47199566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 47209566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 47219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4722efd51863SBarry Smith } 4723efd51863SBarry Smith } 47249566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 47259566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 47269566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 47279566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 47283f7e2da0SPeter Brune 47299566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 47309566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 47313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47329b94acceSBarry Smith } 47339b94acceSBarry Smith 47349b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 47359b94acceSBarry Smith 473682bf6240SBarry Smith /*@C 47374b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 47389b94acceSBarry Smith 4739c3339decSBarry Smith Collective 4740fee21e36SBarry Smith 4741c7afd0dbSLois Curfman McInnes Input Parameters: 4742f6dfbefdSBarry Smith + snes - the `SNES` context 4743454a90a3SBarry Smith - type - a known method 4744c7afd0dbSLois Curfman McInnes 4745c7afd0dbSLois Curfman McInnes Options Database Key: 4746454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 474704d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4748ae12b187SLois Curfman McInnes 4749*dc4c0fb0SBarry Smith Level: intermediate 4750*dc4c0fb0SBarry Smith 47519b94acceSBarry Smith Notes: 4752e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 4753f6dfbefdSBarry Smith + `SNESNEWTONLS` - Newton's method with line search 4754c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 4755f6dfbefdSBarry Smith - `SNESNEWTONTRDC` - Newton's method with trust region 4756c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47579b94acceSBarry Smith 4758f6dfbefdSBarry Smith Normally, it is best to use the `SNESSetFromOptions()` command and then 4759f6dfbefdSBarry Smith set the `SNES` solver type from the options database rather than by using 4760ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4761ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4762f6dfbefdSBarry Smith The `SNESSetType()` routine is provided for those situations where it 4763ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4764ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4765ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4766ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4767b0a32e0cSBarry Smith appropriate method. 476836851e7fSLois Curfman McInnes 4769f6dfbefdSBarry Smith Developer Note: 4770f6dfbefdSBarry Smith `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates 4771f6dfbefdSBarry Smith the constructor in that list and calls it to create the specific object. 47728f6c3df8SBarry Smith 4773*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 47749b94acceSBarry Smith @*/ 4775d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetType(SNES snes, SNESType type) 4776d71ae5a4SJacob Faibussowitsch { 4777ace3abfcSBarry Smith PetscBool match; 47785f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 47793a40ed3dSBarry Smith 47803a40ed3dSBarry Smith PetscFunctionBegin; 47810700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47824482741eSBarry Smith PetscValidCharPointer(type, 2); 478382bf6240SBarry Smith 47849566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 47853ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 478692ff6ae8SBarry Smith 47879566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 47885f80ce2aSJacob Faibussowitsch PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 478975396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4790dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 479175396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 47929e5d0892SLisandro Dalcin snes->ops->setup = NULL; 47939e5d0892SLisandro Dalcin snes->ops->solve = NULL; 47949e5d0892SLisandro Dalcin snes->ops->view = NULL; 47959e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 47969e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 47977fe760d5SStefano Zampini 47987fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 47999566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 48007fe760d5SStefano Zampini 480175396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 480275396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4803f5af7f23SKarl Rupp 48049566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 48059566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 48063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48079b94acceSBarry Smith } 48089b94acceSBarry Smith 48099b94acceSBarry Smith /*@C 4810f6dfbefdSBarry Smith SNESGetType - Gets the `SNES` method type and name (as a string). 48119b94acceSBarry Smith 4812c7afd0dbSLois Curfman McInnes Not Collective 4813c7afd0dbSLois Curfman McInnes 48149b94acceSBarry Smith Input Parameter: 48154b0e389bSBarry Smith . snes - nonlinear solver context 48169b94acceSBarry Smith 48179b94acceSBarry Smith Output Parameter: 4818f6dfbefdSBarry Smith . type - `SNES` method (a character string) 48199b94acceSBarry Smith 482036851e7fSLois Curfman McInnes Level: intermediate 482136851e7fSLois Curfman McInnes 4822*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES` 48239b94acceSBarry Smith @*/ 4824d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetType(SNES snes, SNESType *type) 4825d71ae5a4SJacob Faibussowitsch { 48263a40ed3dSBarry Smith PetscFunctionBegin; 48270700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48284482741eSBarry Smith PetscValidPointer(type, 2); 48297adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 48303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48319b94acceSBarry Smith } 48329b94acceSBarry Smith 48333cd8a7caSMatthew G. Knepley /*@ 4834f6dfbefdSBarry Smith SNESSetSolution - Sets the solution vector for use by the `SNES` routines. 48353cd8a7caSMatthew G. Knepley 4836c3339decSBarry Smith Logically Collective 48373cd8a7caSMatthew G. Knepley 48383cd8a7caSMatthew G. Knepley Input Parameters: 4839f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()` 48403cd8a7caSMatthew G. Knepley - u - the solution vector 48413cd8a7caSMatthew G. Knepley 48423cd8a7caSMatthew G. Knepley Level: beginner 48433cd8a7caSMatthew G. Knepley 4844*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec` 48453cd8a7caSMatthew G. Knepley @*/ 4846d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4847d71ae5a4SJacob Faibussowitsch { 48483cd8a7caSMatthew G. Knepley DM dm; 48493cd8a7caSMatthew G. Knepley 48503cd8a7caSMatthew G. Knepley PetscFunctionBegin; 48513cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48523cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 48539566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 48549566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 48553cd8a7caSMatthew G. Knepley 48563cd8a7caSMatthew G. Knepley snes->vec_sol = u; 48573cd8a7caSMatthew G. Knepley 48589566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48599566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 48603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48613cd8a7caSMatthew G. Knepley } 48623cd8a7caSMatthew G. Knepley 486352baeb72SSatish Balay /*@ 48649b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4865f6dfbefdSBarry Smith stored. This is the fine grid solution when using `SNESSetGridSequence()`. 48669b94acceSBarry Smith 4867f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4868c7afd0dbSLois Curfman McInnes 48699b94acceSBarry Smith Input Parameter: 4870f6dfbefdSBarry Smith . snes - the `SNES` context 48719b94acceSBarry Smith 48729b94acceSBarry Smith Output Parameter: 48739b94acceSBarry Smith . x - the solution 48749b94acceSBarry Smith 487570e92668SMatthew Knepley Level: intermediate 487636851e7fSLois Curfman McInnes 4877*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()` 48789b94acceSBarry Smith @*/ 4879d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolution(SNES snes, Vec *x) 4880d71ae5a4SJacob Faibussowitsch { 48813a40ed3dSBarry Smith PetscFunctionBegin; 48820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48834482741eSBarry Smith PetscValidPointer(x, 2); 488485385478SLisandro Dalcin *x = snes->vec_sol; 48853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 488670e92668SMatthew Knepley } 488770e92668SMatthew Knepley 488852baeb72SSatish Balay /*@ 48899b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 48909b94acceSBarry Smith stored. 48919b94acceSBarry Smith 4892f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4893c7afd0dbSLois Curfman McInnes 48949b94acceSBarry Smith Input Parameter: 4895f6dfbefdSBarry Smith . snes - the `SNES` context 48969b94acceSBarry Smith 48979b94acceSBarry Smith Output Parameter: 48989b94acceSBarry Smith . x - the solution update 48999b94acceSBarry Smith 490036851e7fSLois Curfman McInnes Level: advanced 490136851e7fSLois Curfman McInnes 4902*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()` 49039b94acceSBarry Smith @*/ 4904d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x) 4905d71ae5a4SJacob Faibussowitsch { 49063a40ed3dSBarry Smith PetscFunctionBegin; 49070700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49084482741eSBarry Smith PetscValidPointer(x, 2); 490985385478SLisandro Dalcin *x = snes->vec_sol_update; 49103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49119b94acceSBarry Smith } 49129b94acceSBarry Smith 49139b94acceSBarry Smith /*@C 4914f6dfbefdSBarry Smith SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()` 49159b94acceSBarry Smith 4916f6dfbefdSBarry Smith Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet. 4917c7afd0dbSLois Curfman McInnes 49189b94acceSBarry Smith Input Parameter: 4919f6dfbefdSBarry Smith . snes - the `SNES` context 49209b94acceSBarry Smith 4921d8d19677SJose E. Roman Output Parameters: 4922*dc4c0fb0SBarry Smith + r - the vector that is used to store residuals (or `NULL` if you don't want it) 4923*dc4c0fb0SBarry Smith . f - the function (or `NULL` if you don't want it); see `SNESFunction` for calling sequence details 4924*dc4c0fb0SBarry Smith - ctx - the function context (or `NULL` if you don't want it) 49259b94acceSBarry Smith 492636851e7fSLois Curfman McInnes Level: advanced 492736851e7fSLois Curfman McInnes 4928f6dfbefdSBarry Smith Note: 4929*dc4c0fb0SBarry Smith The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function 493004edfde5SBarry Smith 4931*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 49329b94acceSBarry Smith @*/ 4933d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4934d71ae5a4SJacob Faibussowitsch { 49356cab3a1bSJed Brown DM dm; 4936a63bb30eSJed Brown 49373a40ed3dSBarry Smith PetscFunctionBegin; 49380700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4939a63bb30eSJed Brown if (r) { 4940a63bb30eSJed Brown if (!snes->vec_func) { 4941a63bb30eSJed Brown if (snes->vec_rhs) { 49429566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4943a63bb30eSJed Brown } else if (snes->vec_sol) { 49449566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4945a63bb30eSJed Brown } else if (snes->dm) { 49469566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4947a63bb30eSJed Brown } 4948a63bb30eSJed Brown } 4949a63bb30eSJed Brown *r = snes->vec_func; 4950a63bb30eSJed Brown } 49519566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49529566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 49533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49549b94acceSBarry Smith } 49559b94acceSBarry Smith 4956c79ef259SPeter Brune /*@C 4957f6dfbefdSBarry Smith SNESGetNGS - Returns the `SNESNGS` function and context set with `SNESSetNGS()` 4958c79ef259SPeter Brune 4959c79ef259SPeter Brune Input Parameter: 4960f6dfbefdSBarry Smith . snes - the `SNES` context 4961c79ef259SPeter Brune 4962d8d19677SJose E. Roman Output Parameters: 4963*dc4c0fb0SBarry Smith + f - the function (or `NULL`) see `SNESNGSFunction` for details 4964*dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 4965c79ef259SPeter Brune 4966c79ef259SPeter Brune Level: advanced 4967c79ef259SPeter Brune 4968*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNGS()`, `SNESGetFunction()` 4969c79ef259SPeter Brune @*/ 4970c79ef259SPeter Brune 4971d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4972d71ae5a4SJacob Faibussowitsch { 49736cab3a1bSJed Brown DM dm; 49746cab3a1bSJed Brown 4975646217ecSPeter Brune PetscFunctionBegin; 4976646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49779566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49789566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 49793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4980646217ecSPeter Brune } 4981646217ecSPeter Brune 49823c7409f5SSatish Balay /*@C 49833c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4984f6dfbefdSBarry Smith `SNES` options in the database. 49853c7409f5SSatish Balay 4986c3339decSBarry Smith Logically Collective 4987fee21e36SBarry Smith 4988d8d19677SJose E. Roman Input Parameters: 4989f6dfbefdSBarry Smith + snes - the `SNES` context 4990c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4991c7afd0dbSLois Curfman McInnes 4992*dc4c0fb0SBarry Smith Level: advanced 4993*dc4c0fb0SBarry Smith 4994f6dfbefdSBarry Smith Note: 4995a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4996c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4997d850072dSLois Curfman McInnes 4998*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()` 49993c7409f5SSatish Balay @*/ 5000d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) 5001d71ae5a4SJacob Faibussowitsch { 50023a40ed3dSBarry Smith PetscFunctionBegin; 50030700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50049566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 50059566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 500635f5d045SPeter Brune if (snes->linesearch) { 50079566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 50089566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 500935f5d045SPeter Brune } 50109566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 50113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50123c7409f5SSatish Balay } 50133c7409f5SSatish Balay 50143c7409f5SSatish Balay /*@C 5015f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 5016f6dfbefdSBarry Smith `SNES` options in the database. 50173c7409f5SSatish Balay 5018c3339decSBarry Smith Logically Collective 5019fee21e36SBarry Smith 5020c7afd0dbSLois Curfman McInnes Input Parameters: 5021f6dfbefdSBarry Smith + snes - the `SNES` context 5022c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5023c7afd0dbSLois Curfman McInnes 5024*dc4c0fb0SBarry Smith Level: advanced 5025*dc4c0fb0SBarry Smith 5026f6dfbefdSBarry Smith Note: 5027a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5028c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5029d850072dSLois Curfman McInnes 5030*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()` 50313c7409f5SSatish Balay @*/ 5032d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) 5033d71ae5a4SJacob Faibussowitsch { 50343a40ed3dSBarry Smith PetscFunctionBegin; 50350700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50369566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 50379566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 503835f5d045SPeter Brune if (snes->linesearch) { 50399566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 50409566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 504135f5d045SPeter Brune } 50429566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 50433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50443c7409f5SSatish Balay } 50453c7409f5SSatish Balay 50469ab63eb5SSatish Balay /*@C 5047f6dfbefdSBarry Smith SNESGetOptionsPrefix - Gets the prefix used for searching for all 5048f6dfbefdSBarry Smith `SNES` options in the database. 50493c7409f5SSatish Balay 5050c7afd0dbSLois Curfman McInnes Not Collective 5051c7afd0dbSLois Curfman McInnes 50523c7409f5SSatish Balay Input Parameter: 5053f6dfbefdSBarry Smith . snes - the `SNES` context 50543c7409f5SSatish Balay 50553c7409f5SSatish Balay Output Parameter: 50563c7409f5SSatish Balay . prefix - pointer to the prefix string used 50573c7409f5SSatish Balay 505836851e7fSLois Curfman McInnes Level: advanced 505936851e7fSLois Curfman McInnes 5060*dc4c0fb0SBarry Smith Fortran Note: 5061*dc4c0fb0SBarry Smith The user should pass in a string 'prefix' of 5062*dc4c0fb0SBarry Smith sufficient length to hold the prefix. 5063*dc4c0fb0SBarry Smith 5064*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()` 50653c7409f5SSatish Balay @*/ 5066d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) 5067d71ae5a4SJacob Faibussowitsch { 50683a40ed3dSBarry Smith PetscFunctionBegin; 50690700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50709566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 50713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50723c7409f5SSatish Balay } 50733c7409f5SSatish Balay 50743cea93caSBarry Smith /*@C 50751c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 50761c84c290SBarry Smith 50771c84c290SBarry Smith Not collective 50781c84c290SBarry Smith 50791c84c290SBarry Smith Input Parameters: 50801c84c290SBarry Smith + name_solver - name of a new user-defined solver 50811c84c290SBarry Smith - routine_create - routine to create method context 50821c84c290SBarry Smith 5083*dc4c0fb0SBarry Smith Level: advanced 5084*dc4c0fb0SBarry Smith 5085f6dfbefdSBarry Smith Note: 5086f6dfbefdSBarry Smith `SNESRegister()` may be called multiple times to add several user-defined solvers. 50871c84c290SBarry Smith 50881c84c290SBarry Smith Sample usage: 50891c84c290SBarry Smith .vb 5090bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 50911c84c290SBarry Smith .ve 50921c84c290SBarry Smith 50931c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 50941c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 50951c84c290SBarry Smith or at runtime via the option 50961c84c290SBarry Smith $ -snes_type my_solver 50971c84c290SBarry Smith 5098*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()` 50993cea93caSBarry Smith @*/ 5100d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) 5101d71ae5a4SJacob Faibussowitsch { 5102b2002411SLois Curfman McInnes PetscFunctionBegin; 51039566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 51049566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 51053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5106b2002411SLois Curfman McInnes } 5107da9b6338SBarry Smith 5108d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestLocalMin(SNES snes) 5109d71ae5a4SJacob Faibussowitsch { 511077431f27SBarry Smith PetscInt N, i, j; 5111da9b6338SBarry Smith Vec u, uh, fh; 5112da9b6338SBarry Smith PetscScalar value; 5113da9b6338SBarry Smith PetscReal norm; 5114da9b6338SBarry Smith 5115da9b6338SBarry Smith PetscFunctionBegin; 51169566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 51179566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 51189566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 5119da9b6338SBarry Smith 5120da9b6338SBarry Smith /* currently only works for sequential */ 51219566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 51229566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5123da9b6338SBarry Smith for (i = 0; i < N; i++) { 51249566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 512563a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5126da9b6338SBarry Smith for (j = -10; j < 11; j++) { 51278b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 51289566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 51299566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 51309566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 513163a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5132da9b6338SBarry Smith value = -value; 51339566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5134da9b6338SBarry Smith } 5135da9b6338SBarry Smith } 51369566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 51379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 51383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5139da9b6338SBarry Smith } 514071f87433Sdalcinl 514171f87433Sdalcinl /*@ 5142f6dfbefdSBarry Smith SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for 514371f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 514471f87433Sdalcinl Newton method. 514571f87433Sdalcinl 5146c3339decSBarry Smith Logically Collective 514771f87433Sdalcinl 514871f87433Sdalcinl Input Parameters: 5149f6dfbefdSBarry Smith + snes - `SNES` context 5150f6dfbefdSBarry Smith - flag - `PETSC_TRUE` or `PETSC_FALSE` 515171f87433Sdalcinl 5152f6dfbefdSBarry Smith Options Database Keys: 515364ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 515464ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 515564ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 515664ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 515764ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 515864ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 515964ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 516064ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 516164ba62caSBarry Smith 5162*dc4c0fb0SBarry Smith Level: advanced 5163*dc4c0fb0SBarry Smith 5164f6dfbefdSBarry Smith Note: 5165f6dfbefdSBarry Smith The default is to use a constant relative tolerance for 516671f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 516771f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 516871f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 516971f87433Sdalcinl solver. 517071f87433Sdalcinl 517171f87433Sdalcinl Reference: 5172f6dfbefdSBarry Smith . - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996. 517371f87433Sdalcinl 5174*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 517571f87433Sdalcinl @*/ 5176d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) 5177d71ae5a4SJacob Faibussowitsch { 517871f87433Sdalcinl PetscFunctionBegin; 51790700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5180acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 518171f87433Sdalcinl snes->ksp_ewconv = flag; 51823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 518371f87433Sdalcinl } 518471f87433Sdalcinl 518571f87433Sdalcinl /*@ 5186f6dfbefdSBarry Smith SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method 518771f87433Sdalcinl for computing relative tolerance for linear solvers within an 518871f87433Sdalcinl inexact Newton method. 518971f87433Sdalcinl 519071f87433Sdalcinl Not Collective 519171f87433Sdalcinl 519271f87433Sdalcinl Input Parameter: 5193f6dfbefdSBarry Smith . snes - `SNES` context 519471f87433Sdalcinl 519571f87433Sdalcinl Output Parameter: 5196f6dfbefdSBarry Smith . flag - `PETSC_TRUE` or `PETSC_FALSE` 519771f87433Sdalcinl 519871f87433Sdalcinl Level: advanced 519971f87433Sdalcinl 5200*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 520171f87433Sdalcinl @*/ 5202d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5203d71ae5a4SJacob Faibussowitsch { 520471f87433Sdalcinl PetscFunctionBegin; 52050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5206534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 520771f87433Sdalcinl *flag = snes->ksp_ewconv; 52083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 520971f87433Sdalcinl } 521071f87433Sdalcinl 521171f87433Sdalcinl /*@ 5212fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 521371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 521471f87433Sdalcinl Newton method. 521571f87433Sdalcinl 5216c3339decSBarry Smith Logically Collective 521771f87433Sdalcinl 521871f87433Sdalcinl Input Parameters: 5219f6dfbefdSBarry Smith + snes - `SNES` context 52200f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 522171f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 522271f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 522371f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 522471f87433Sdalcinl (0 <= gamma2 <= 1) 522571f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 522671f87433Sdalcinl . alpha2 - power for safeguard 522771f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 522871f87433Sdalcinl 5229*dc4c0fb0SBarry Smith Level: advanced 5230*dc4c0fb0SBarry Smith 5231f6dfbefdSBarry Smith Notes: 523271f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 523371f87433Sdalcinl 5234f6dfbefdSBarry Smith Use `PETSC_DEFAULT` to retain the default for any of the parameters. 523571f87433Sdalcinl 5236*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 523771f87433Sdalcinl @*/ 5238d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) 5239d71ae5a4SJacob Faibussowitsch { 5240fa9f3622SBarry Smith SNESKSPEW *kctx; 52415fd66863SKarl Rupp 524271f87433Sdalcinl PetscFunctionBegin; 52430700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5244fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52455f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5246c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5247c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5248c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5249c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5250c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5251c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5252c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 525371f87433Sdalcinl 525471f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 525571f87433Sdalcinl if (rtol_0 != PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 525671f87433Sdalcinl if (rtol_max != PETSC_DEFAULT) kctx->rtol_max = rtol_max; 525771f87433Sdalcinl if (gamma != PETSC_DEFAULT) kctx->gamma = gamma; 525871f87433Sdalcinl if (alpha != PETSC_DEFAULT) kctx->alpha = alpha; 525971f87433Sdalcinl if (alpha2 != PETSC_DEFAULT) kctx->alpha2 = alpha2; 526071f87433Sdalcinl if (threshold != PETSC_DEFAULT) kctx->threshold = threshold; 526171f87433Sdalcinl 52620f0abf79SStefano 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); 52630b121fc5SBarry 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); 52640b121fc5SBarry 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); 52650b121fc5SBarry 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); 52660b121fc5SBarry 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); 52670b121fc5SBarry 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); 52683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 526971f87433Sdalcinl } 527071f87433Sdalcinl 527171f87433Sdalcinl /*@ 5272fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 527371f87433Sdalcinl convergence criteria for the linear solvers within an inexact 527471f87433Sdalcinl Newton method. 527571f87433Sdalcinl 527671f87433Sdalcinl Not Collective 527771f87433Sdalcinl 527897bb3fdcSJose E. Roman Input Parameter: 5279f6dfbefdSBarry Smith . snes - `SNES` context 528071f87433Sdalcinl 528171f87433Sdalcinl Output Parameters: 52820f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 528371f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 528471f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5285bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 528671f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 528771f87433Sdalcinl . alpha2 - power for safeguard 528871f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 528971f87433Sdalcinl 529071f87433Sdalcinl Level: advanced 529171f87433Sdalcinl 5292*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 529371f87433Sdalcinl @*/ 5294d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) 5295d71ae5a4SJacob Faibussowitsch { 5296fa9f3622SBarry Smith SNESKSPEW *kctx; 52975fd66863SKarl Rupp 529871f87433Sdalcinl PetscFunctionBegin; 52990700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5300fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 53015f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 530271f87433Sdalcinl if (version) *version = kctx->version; 530371f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 530471f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 530571f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 530671f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 530771f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 530871f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 53093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 531071f87433Sdalcinl } 531171f87433Sdalcinl 5312d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5313d71ae5a4SJacob Faibussowitsch { 5314fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 531571f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 531671f87433Sdalcinl 531771f87433Sdalcinl PetscFunctionBegin; 53183ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 531930058271SDmitry Karpeev if (!snes->iter) { 532030058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 53219566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 53220f0abf79SStefano Zampini } else { 53230fdf79fbSJacob Faibussowitsch PetscCheck(kctx->version >= 1 && kctx->version <= 4, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Only versions 1-4 are supported: %" PetscInt_FMT, kctx->version); 532471f87433Sdalcinl if (kctx->version == 1) { 53250f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 532685ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 532771f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 532871f87433Sdalcinl } else if (kctx->version == 2) { 532985ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 533085ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 533171f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 533271f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 533385ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 533471f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 533585ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 533671f87433Sdalcinl stol = PetscMax(rtol, stol); 533771f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 533871f87433Sdalcinl /* safeguard: avoid oversolving */ 533930058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 534071f87433Sdalcinl stol = PetscMax(rtol, stol); 534171f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 53420fdf79fbSJacob Faibussowitsch } else /* if (kctx->version == 4) */ { 53430fdf79fbSJacob Faibussowitsch /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 53440f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 53450f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 53460f0abf79SStefano Zampini PetscReal rk = ared / pred; 53470f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 53480f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 53490f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 53500f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 53510f0abf79SStefano Zampini 53529371c9d4SSatish 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) { 53530f0abf79SStefano Zampini rtol = kctx->v4_m4 * kctx->rtol_last; 53540f0abf79SStefano 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); 53550f0abf79SStefano Zampini } else { 53560f0abf79SStefano 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); 535771f87433Sdalcinl } 53580f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 53590f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 53600f0abf79SStefano Zampini kctx->rk_last = rk; 53610fdf79fbSJacob Faibussowitsch } 53620f0abf79SStefano Zampini } 53630f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 536471f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 53659566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 536663a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 53673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 536871f87433Sdalcinl } 536971f87433Sdalcinl 5370d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5371d71ae5a4SJacob Faibussowitsch { 5372fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 537371f87433Sdalcinl PCSide pcside; 537471f87433Sdalcinl Vec lres; 537571f87433Sdalcinl 537671f87433Sdalcinl PetscFunctionBegin; 53773ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 53789566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 537971dbe336SPeter Brune kctx->norm_last = snes->norm; 53800f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 53814f00ce20SMatthew G. Knepley PC pc; 53820f0abf79SStefano Zampini PetscBool getRes; 53834f00ce20SMatthew G. Knepley 53849566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 53850f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 53860f0abf79SStefano Zampini if (!getRes) { 53870f0abf79SStefano Zampini KSPNormType normtype; 53880f0abf79SStefano Zampini 53890f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 53900f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 53910f0abf79SStefano Zampini } 53929566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 53930f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 53949566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 539571f87433Sdalcinl } else { 539671f87433Sdalcinl /* KSP residual is preconditioned residual */ 539771f87433Sdalcinl /* compute true linear residual norm */ 53980f0abf79SStefano Zampini Mat J; 53990f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 54009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 54010f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 54029566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 54039566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 54049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 540571f87433Sdalcinl } 540671f87433Sdalcinl } 54073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 540871f87433Sdalcinl } 540971f87433Sdalcinl 5410d4211eb9SBarry Smith /*@ 5411f6dfbefdSBarry Smith SNESGetKSP - Returns the `KSP` context for a `SNES` solver. 5412d4211eb9SBarry Smith 5413f6dfbefdSBarry Smith Not Collective, but if snes is parallel, then ksp is parallel 5414d4211eb9SBarry Smith 5415d4211eb9SBarry Smith Input Parameter: 5416f6dfbefdSBarry Smith . snes - the `SNES` context 5417d4211eb9SBarry Smith 5418d4211eb9SBarry Smith Output Parameter: 5419f6dfbefdSBarry Smith . ksp - the `KSP` context 5420d4211eb9SBarry Smith 5421*dc4c0fb0SBarry Smith Level: beginner 5422*dc4c0fb0SBarry Smith 5423d4211eb9SBarry Smith Notes: 5424f6dfbefdSBarry Smith The user can then directly manipulate the `KSP` context to set various 5425d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5426f6dfbefdSBarry Smith `PC` contexts as well. 5427f6dfbefdSBarry Smith 5428f6dfbefdSBarry Smith Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function 5429d4211eb9SBarry Smith 5430*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5431d4211eb9SBarry Smith @*/ 5432d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) 5433d71ae5a4SJacob Faibussowitsch { 543471f87433Sdalcinl PetscFunctionBegin; 5435d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5436d4211eb9SBarry Smith PetscValidPointer(ksp, 2); 5437d4211eb9SBarry Smith 5438d4211eb9SBarry Smith if (!snes->ksp) { 54399566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 54409566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 5441d4211eb9SBarry Smith 54429566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 54439566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5444a5c2985bSBarry Smith 54459566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 54469566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5447d4211eb9SBarry Smith } 5448d4211eb9SBarry Smith *ksp = snes->ksp; 54493ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 545071f87433Sdalcinl } 54516c699258SBarry Smith 5452af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 54536c699258SBarry Smith /*@ 5454f6dfbefdSBarry Smith SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners 54556c699258SBarry Smith 5456c3339decSBarry Smith Logically Collective 54576c699258SBarry Smith 54586c699258SBarry Smith Input Parameters: 54592a808120SBarry Smith + snes - the nonlinear solver context 5460*dc4c0fb0SBarry Smith - dm - the dm, cannot be `NULL` 5461*dc4c0fb0SBarry Smith 5462*dc4c0fb0SBarry Smith Level: intermediate 54636c699258SBarry Smith 5464f6dfbefdSBarry Smith Note: 5465f6dfbefdSBarry Smith A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, 5466f6dfbefdSBarry Smith even when not using interfaces like `DMSNESSetFunction()`. Use `DMClone()` to get a distinct `DM` when solving different 5467e03a659cSJed Brown problems using the same function space. 5468e03a659cSJed Brown 5469*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 54706c699258SBarry Smith @*/ 5471d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDM(SNES snes, DM dm) 5472d71ae5a4SJacob Faibussowitsch { 5473345fed2cSBarry Smith KSP ksp; 5474942e3340SBarry Smith DMSNES sdm; 54756c699258SBarry Smith 54766c699258SBarry Smith PetscFunctionBegin; 54770700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54782a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 54799566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5480942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 548151f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 54829566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 54839566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5484f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 54856cab3a1bSJed Brown } 54869566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 54879566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 54886cab3a1bSJed Brown } 54896c699258SBarry Smith snes->dm = dm; 5490116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5491f5af7f23SKarl Rupp 54929566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 54939566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 54949566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5495efd4aadfSBarry Smith if (snes->npc) { 54969566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 54979566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 54982c155ee1SBarry Smith } 54993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55006c699258SBarry Smith } 55016c699258SBarry Smith 55026c699258SBarry Smith /*@ 5503f6dfbefdSBarry Smith SNESGetDM - Gets the `DM` that may be used by some preconditioners 55046c699258SBarry Smith 5505f6dfbefdSBarry Smith Not Collective but dm obtained is parallel on snes 55066c699258SBarry Smith 55076c699258SBarry Smith Input Parameter: 55086c699258SBarry Smith . snes - the preconditioner context 55096c699258SBarry Smith 55106c699258SBarry Smith Output Parameter: 55116c699258SBarry Smith . dm - the dm 55126c699258SBarry Smith 55136c699258SBarry Smith Level: intermediate 55146c699258SBarry Smith 5515*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 55166c699258SBarry Smith @*/ 5517d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDM(SNES snes, DM *dm) 5518d71ae5a4SJacob Faibussowitsch { 55196c699258SBarry Smith PetscFunctionBegin; 55200700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 55216cab3a1bSJed Brown if (!snes->dm) { 55229566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5523116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 55246cab3a1bSJed Brown } 55256c699258SBarry Smith *dm = snes->dm; 55263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55276c699258SBarry Smith } 55280807856dSBarry Smith 552931823bd8SMatthew G Knepley /*@ 5530be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 553131823bd8SMatthew G Knepley 5532c3339decSBarry Smith Collective 553331823bd8SMatthew G Knepley 553431823bd8SMatthew G Knepley Input Parameters: 5535f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 5536f6dfbefdSBarry Smith - npc - the preconditioner object 553731823bd8SMatthew G Knepley 5538*dc4c0fb0SBarry Smith Level: developer 5539*dc4c0fb0SBarry Smith 554031823bd8SMatthew G Knepley Notes: 5541f6dfbefdSBarry Smith Use `SNESGetNPC()` to retrieve the preconditioner context (for example, 554231823bd8SMatthew G Knepley to configure it using the API). 554331823bd8SMatthew G Knepley 5544f6dfbefdSBarry Smith Only some `SNESType` can use a nonlinear preconditioner 5545f6dfbefdSBarry Smith 5546*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()` 554731823bd8SMatthew G Knepley @*/ 5548d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPC(SNES snes, SNES npc) 5549d71ae5a4SJacob Faibussowitsch { 555031823bd8SMatthew G Knepley PetscFunctionBegin; 555131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5552f6dfbefdSBarry Smith PetscValidHeaderSpecific(npc, SNES_CLASSID, 2); 5553f6dfbefdSBarry Smith PetscCheckSameComm(snes, 1, npc, 2); 5554f6dfbefdSBarry Smith PetscCall(PetscObjectReference((PetscObject)npc)); 55559566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5556f6dfbefdSBarry Smith snes->npc = npc; 55573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 555831823bd8SMatthew G Knepley } 555931823bd8SMatthew G Knepley 556031823bd8SMatthew G Knepley /*@ 5561f6dfbefdSBarry Smith SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver. 556231823bd8SMatthew G Knepley 5563f6dfbefdSBarry Smith Not Collective; but any changes to the obtained the npc object must be applied collectively 556431823bd8SMatthew G Knepley 556531823bd8SMatthew G Knepley Input Parameter: 5566f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 556731823bd8SMatthew G Knepley 556831823bd8SMatthew G Knepley Output Parameter: 5569f6dfbefdSBarry Smith . npc - preconditioner context 557031823bd8SMatthew G Knepley 5571f6dfbefdSBarry Smith Options Database Key: 5572f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner 5573b5badacbSBarry Smith 5574*dc4c0fb0SBarry Smith Level: developer 5575*dc4c0fb0SBarry Smith 557695452b02SPatrick Sanan Notes: 5577f6dfbefdSBarry Smith If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created. 5578be95d8f1SBarry Smith 5579f6dfbefdSBarry Smith The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5580f6dfbefdSBarry Smith `SNES` 5581951fe5abSBarry Smith 5582*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 558331823bd8SMatthew G Knepley @*/ 5584d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5585d71ae5a4SJacob Faibussowitsch { 5586a64e098fSPeter Brune const char *optionsprefix; 558731823bd8SMatthew G Knepley 558831823bd8SMatthew G Knepley PetscFunctionBegin; 558931823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 559031823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5591efd4aadfSBarry Smith if (!snes->npc) { 55929566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 55939566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 55949566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 55959566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 55969566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 55979566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 559831823bd8SMatthew G Knepley } 5599efd4aadfSBarry Smith *pc = snes->npc; 56003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 560131823bd8SMatthew G Knepley } 560231823bd8SMatthew G Knepley 56033ad1a0b9SPatrick Farrell /*@ 56043ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 56053ad1a0b9SPatrick Farrell 56063ad1a0b9SPatrick Farrell Not Collective 56073ad1a0b9SPatrick Farrell 56083ad1a0b9SPatrick Farrell Input Parameter: 5609f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 56103ad1a0b9SPatrick Farrell 56113ad1a0b9SPatrick Farrell Output Parameter: 5612f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not 56133ad1a0b9SPatrick Farrell 56143ad1a0b9SPatrick Farrell Level: developer 56153ad1a0b9SPatrick Farrell 5616*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNPC()`, `SNESGetNPC()` 56173ad1a0b9SPatrick Farrell @*/ 5618d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5619d71ae5a4SJacob Faibussowitsch { 56203ad1a0b9SPatrick Farrell PetscFunctionBegin; 56213ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5622efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 56233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56243ad1a0b9SPatrick Farrell } 56253ad1a0b9SPatrick Farrell 5626c40d0f55SPeter Brune /*@ 5627be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5628c40d0f55SPeter Brune 5629c3339decSBarry Smith Logically Collective 5630c40d0f55SPeter Brune 5631c40d0f55SPeter Brune Input Parameter: 5632f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5633c40d0f55SPeter Brune 5634c40d0f55SPeter Brune Output Parameter: 5635c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5636c40d0f55SPeter Brune .vb 56372d547940SBarry Smith PC_LEFT - left preconditioning 56382d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5639c40d0f55SPeter Brune .ve 5640c40d0f55SPeter Brune 5641f6dfbefdSBarry Smith Options Database Key: 564267b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5643c40d0f55SPeter Brune 5644*dc4c0fb0SBarry Smith Level: intermediate 5645*dc4c0fb0SBarry Smith 5646f6dfbefdSBarry Smith Note: 5647f6dfbefdSBarry Smith `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning. 56482d547940SBarry Smith 5649*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()` 5650c40d0f55SPeter Brune @*/ 5651d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) 5652d71ae5a4SJacob Faibussowitsch { 5653c40d0f55SPeter Brune PetscFunctionBegin; 5654c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5655c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5656b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 565754c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5658efd4aadfSBarry Smith snes->npcside = side; 56593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5660c40d0f55SPeter Brune } 5661c40d0f55SPeter Brune 5662c40d0f55SPeter Brune /*@ 5663be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5664c40d0f55SPeter Brune 5665c40d0f55SPeter Brune Not Collective 5666c40d0f55SPeter Brune 5667c40d0f55SPeter Brune Input Parameter: 5668f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5669c40d0f55SPeter Brune 5670c40d0f55SPeter Brune Output Parameter: 5671c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5672c40d0f55SPeter Brune .vb 5673f6dfbefdSBarry Smith `PC_LEFT` - left preconditioning 5674f6dfbefdSBarry Smith `PC_RIGHT` - right preconditioning (default for most nonlinear solvers) 5675c40d0f55SPeter Brune .ve 5676c40d0f55SPeter Brune 5677c40d0f55SPeter Brune Level: intermediate 5678c40d0f55SPeter Brune 5679*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()` 5680c40d0f55SPeter Brune @*/ 5681d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) 5682d71ae5a4SJacob Faibussowitsch { 5683c40d0f55SPeter Brune PetscFunctionBegin; 5684c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5685c40d0f55SPeter Brune PetscValidPointer(side, 2); 5686efd4aadfSBarry Smith *side = snes->npcside; 56873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5688c40d0f55SPeter Brune } 5689c40d0f55SPeter Brune 56909e764e56SPeter Brune /*@ 5691f6dfbefdSBarry Smith SNESSetLineSearch - Sets the linesearch on the `SNES` instance. 56929e764e56SPeter Brune 5693c3339decSBarry Smith Collective 56949e764e56SPeter Brune 56959e764e56SPeter Brune Input Parameters: 5696f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 56979e764e56SPeter Brune - linesearch - the linesearch object 56989e764e56SPeter Brune 5699*dc4c0fb0SBarry Smith Level: developer 5700*dc4c0fb0SBarry Smith 5701f6dfbefdSBarry Smith Note: 5702f6dfbefdSBarry Smith Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example, 57039e764e56SPeter Brune to configure it using the API). 57049e764e56SPeter Brune 5705*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetLineSearch()` 57069e764e56SPeter Brune @*/ 5707d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5708d71ae5a4SJacob Faibussowitsch { 57099e764e56SPeter Brune PetscFunctionBegin; 57109e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5711f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 57129e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 57139566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 57149566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5715f5af7f23SKarl Rupp 57169e764e56SPeter Brune snes->linesearch = linesearch; 5717f5af7f23SKarl Rupp 57183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57199e764e56SPeter Brune } 57209e764e56SPeter Brune 5721a34ceb2aSJed Brown /*@ 5722*dc4c0fb0SBarry Smith SNESGetLineSearch - Returns the line search context set with `SNESSetLineSearch()` 5723f6dfbefdSBarry Smith or creates a default line search instance associated with the `SNES` and returns it. 57249e764e56SPeter Brune 57259e764e56SPeter Brune Not Collective 57269e764e56SPeter Brune 57279e764e56SPeter Brune Input Parameter: 5728f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 57299e764e56SPeter Brune 57309e764e56SPeter Brune Output Parameter: 57319e764e56SPeter Brune . linesearch - linesearch context 57329e764e56SPeter Brune 5733162e0bf5SPeter Brune Level: beginner 57349e764e56SPeter Brune 5735*dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()` 57369e764e56SPeter Brune @*/ 5737d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5738d71ae5a4SJacob Faibussowitsch { 57399e764e56SPeter Brune const char *optionsprefix; 57409e764e56SPeter Brune 57419e764e56SPeter Brune PetscFunctionBegin; 57429e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 57439e764e56SPeter Brune PetscValidPointer(linesearch, 2); 57449e764e56SPeter Brune if (!snes->linesearch) { 57459566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 57469566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 57479566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 57489566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 57499566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 57509e764e56SPeter Brune } 57519e764e56SPeter Brune *linesearch = snes->linesearch; 57523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57539e764e56SPeter Brune } 5754