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 /*@ 16dc4c0fb0SBarry 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 2420f4b53cSBarry Smith Options Database Key: 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 33dc4c0fb0SBarry 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 57dc4c0fb0SBarry 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 /*@ 69dc4c0fb0SBarry 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 83dc4c0fb0SBarry 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 106dc4c0fb0SBarry 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 1222fe279fdSBarry Smith Input Parameter: 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 131dc4c0fb0SBarry 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 1482fe279fdSBarry Smith Input Parameter: 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 157dc4c0fb0SBarry 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: 17620f4b53cSBarry Smith + 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 184dc4c0fb0SBarry 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 1992fe279fdSBarry Smith Input Parameter: 200f6dfbefdSBarry Smith . snes - the `SNES` context 2018383d7d7SFande Kong 2022fe279fdSBarry Smith Output Parameter: 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 207dc4c0fb0SBarry 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 2232fe279fdSBarry Smith Input Parameter: 224f6dfbefdSBarry Smith . snes - the `SNES` context 2256a388c36SPeter Brune 2262fe279fdSBarry Smith Output Parameter: 227f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise. 2286a388c36SPeter Brune 229f6dfbefdSBarry Smith Level: developer 2306a388c36SPeter Brune 231dc4c0fb0SBarry 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 2472fe279fdSBarry Smith Input Parameter: 248f6dfbefdSBarry Smith . snes - the `SNES` context 24907b62357SFande Kong 2502fe279fdSBarry Smith Output Parameter: 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 255dc4c0fb0SBarry 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 281dc4c0fb0SBarry 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 317dc4c0fb0SBarry 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 323dc4c0fb0SBarry 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 328dc4c0fb0SBarry 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 341dc4c0fb0SBarry 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 352dc4c0fb0SBarry Smith Level: beginner 353dc4c0fb0SBarry 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 371dc4c0fb0SBarry 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 556dc4c0fb0SBarry 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 /*@ 706dc4c0fb0SBarry 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: 71120f4b53cSBarry Smith . snes - `SNES` object to configure 7126cab3a1bSJed Brown 7136cab3a1bSJed Brown Level: developer 7146cab3a1bSJed Brown 715dc4c0fb0SBarry Smith Note: 716dc4c0fb0SBarry 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` 717dc4c0fb0SBarry Smith 718dc4c0fb0SBarry 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: 814dc4c0fb0SBarry 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 826dc4c0fb0SBarry 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 852a4598233SStefano Zampini PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, PetscBool print_api, MPI_Comm comm, const char *prefix) 853d71ae5a4SJacob Faibussowitsch { 854a4598233SStefano Zampini const char *api = print_api ? "SNESKSPSetParametersEW" : NULL; 855a4598233SStefano Zampini 8560f0abf79SStefano Zampini PetscFunctionBegin; 8570f0abf79SStefano Zampini PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP"); 858a4598233SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", api, kctx->version, &kctx->version, NULL)); 859a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", api, kctx->rtol_0, &kctx->rtol_0, NULL)); 860a4598233SStefano Zampini kctx->rtol_max = PetscMax(kctx->rtol_0, kctx->rtol_max); 861a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", api, kctx->rtol_max, &kctx->rtol_max, NULL)); 862a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", api, kctx->gamma, &kctx->gamma, NULL)); 863a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", api, kctx->alpha, &kctx->alpha, NULL)); 8640f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL)); 865a4598233SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", api, kctx->threshold, &kctx->threshold, NULL)); 8660f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL)); 8670f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL)); 8680f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL)); 8690f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL)); 8700f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL)); 8710f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL)); 8720f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL)); 8730f0abf79SStefano Zampini PetscOptionsEnd(); 8743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8750f0abf79SStefano Zampini } 8760f0abf79SStefano Zampini 8779b94acceSBarry Smith /*@ 878f6dfbefdSBarry Smith SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options. 8799b94acceSBarry Smith 880c3339decSBarry Smith Collective 881c7afd0dbSLois Curfman McInnes 8829b94acceSBarry Smith Input Parameter: 883f6dfbefdSBarry Smith . snes - the `SNES` context 8849b94acceSBarry Smith 88536851e7fSLois Curfman McInnes Options Database Keys: 886f6dfbefdSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, `SNESType` for complete list 88782738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 88882738288SBarry Smith of the change in the solution between steps 88970441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 890b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 891e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 892be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 893b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 894b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8954839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 896ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 897a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8983d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 899e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 9003d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 9014a221d59SStefano Zampini . -snes_tr_tol <trtol> - trust region tolerance 902f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 903f6dfbefdSBarry Smith default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense 904f6dfbefdSBarry Smith of convergence test. correct_pressure S`NESConvergedCorrectPressure()` has special handling of a pressure null space. 905fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 906fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 907fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 908fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 9094619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 910459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 9115e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 912e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 913e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 9145968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 915b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 916e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 917e62ac41dSBarry 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. 918e62ac41dSBarry 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. 91982738288SBarry Smith 920f6dfbefdSBarry Smith Options Database Keys for Eisenstat-Walker method: 921fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 9224b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 92336851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 92436851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 92536851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 92636851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 92736851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 92836851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 92982738288SBarry Smith 930dc4c0fb0SBarry Smith Level: beginner 931dc4c0fb0SBarry Smith 93211ca99fdSLois Curfman McInnes Notes: 933ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 934ec5066bdSBarry Smith 935f6dfbefdSBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix free, and computing explicitly with 936f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 93783e2fdc7SBarry Smith 938dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9399b94acceSBarry Smith @*/ 940d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions(SNES snes) 941d71ae5a4SJacob Faibussowitsch { 9428afaa268SBarry Smith PetscBool flg, pcset, persist, set; 943d8f46077SPeter Brune PetscInt i, indx, lag, grids; 94404d7464bSBarry Smith const char *deft = SNESNEWTONLS; 945649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 94685385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9470f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 948c40d0f55SPeter Brune PCSide pcside; 949a64e098fSPeter Brune const char *optionsprefix; 9509b94acceSBarry Smith 9513a40ed3dSBarry Smith PetscFunctionBegin; 9520700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9539566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 954d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 955639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9569566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 957d64ed03dSBarry Smith if (flg) { 9589566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9597adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9609566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 961d64ed03dSBarry Smith } 9629566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9639566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 964186905e3SBarry Smith 9659566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9669566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9679566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9689566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9699566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9709566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9719566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9729566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9739566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 97485385478SLisandro Dalcin 9759566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 976a8054027SBarry Smith if (flg) { 9775f80ce2aSJacob 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"); 9789566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 979a8054027SBarry Smith } 9809566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9811baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9829566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 983e35cf81dSBarry Smith if (flg) { 9845f80ce2aSJacob 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"); 9859566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 986e35cf81dSBarry Smith } 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9881baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 98937ec4e1aSPeter Brune 9909566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9911baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 992a8054027SBarry Smith 9939566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg)); 99485385478SLisandro Dalcin if (flg) { 99585385478SLisandro Dalcin switch (indx) { 996d71ae5a4SJacob Faibussowitsch case 0: 997d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); 998d71ae5a4SJacob Faibussowitsch break; 999d71ae5a4SJacob Faibussowitsch case 1: 1000d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); 1001d71ae5a4SJacob Faibussowitsch break; 1002d71ae5a4SJacob Faibussowitsch case 2: 1003d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); 1004d71ae5a4SJacob Faibussowitsch break; 100585385478SLisandro Dalcin } 100685385478SLisandro Dalcin } 100785385478SLisandro Dalcin 10089566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 10099566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 1010fdacfa88SPeter Brune 10119566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 10129566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 1013186905e3SBarry Smith 101485385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 101585385478SLisandro Dalcin 10169566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 1017186905e3SBarry Smith 10180f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 10190f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 1020a4598233SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PETSC_TRUE, PetscObjectComm((PetscObject)snes), ewprefix)); 1021186905e3SBarry Smith 102290d69ab7SBarry Smith flg = PETSC_FALSE; 10239566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 10249566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1025eabae89aSBarry Smith 10269566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 10279566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10289566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1029eabae89aSBarry Smith 10309566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10319566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10329566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10339566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10349566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10359566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10369566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10379566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10382db13446SMatthew G. Knepley 10399566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10409566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10415180491cSLisandro Dalcin 104290d69ab7SBarry Smith flg = PETSC_FALSE; 10439566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1044459f5d12SBarry Smith if (flg) { 1045459f5d12SBarry Smith PetscViewer ctx; 1046e24b481bSBarry Smith 10479566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10489566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1049459f5d12SBarry Smith } 10502e7541e6SPeter Brune 105190d69ab7SBarry Smith flg = PETSC_FALSE; 10529566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10539566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1054c4421ceaSFande Kong 1055c4421ceaSFande Kong flg = PETSC_FALSE; 10569566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10574b27c08aSLois Curfman McInnes if (flg) { 10586cab3a1bSJed Brown void *functx; 1059b1f624c7SBarry Smith DM dm; 10609566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1061800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10629566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10639566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10649566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10659b94acceSBarry Smith } 1066639f9d9dSBarry Smith 106744848bc4SPeter Brune flg = PETSC_FALSE; 10689566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10691baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 107097584545SPeter Brune 107197584545SPeter Brune flg = PETSC_FALSE; 10729566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 107344848bc4SPeter Brune if (flg) { 1074c52e227fSPeter Brune DM dm; 10759566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1076800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10779566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10789566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 107944848bc4SPeter Brune } 108044848bc4SPeter Brune 1081aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10829566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1083d8f46077SPeter Brune if (flg && snes->mf_operator) { 1084a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1085d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1086a8248277SBarry Smith } 1087aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10889566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1089d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10909566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1091d28543b3SPeter Brune 1092c40d0f55SPeter Brune flg = PETSC_FALSE; 10939566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 10949566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 10959566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1096c40d0f55SPeter Brune 1097e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 10988a70d858SHong Zhang /* 10998a70d858SHong Zhang Publish convergence information using SAWs 11008a70d858SHong Zhang */ 11018a70d858SHong Zhang flg = PETSC_FALSE; 11029566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 11038a70d858SHong Zhang if (flg) { 11048a70d858SHong Zhang void *ctx; 11059566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 11069566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 11078a70d858SHong Zhang } 11088a70d858SHong Zhang #endif 11098a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1110b90c6cbeSBarry Smith { 1111b90c6cbeSBarry Smith PetscBool set; 1112b90c6cbeSBarry Smith flg = PETSC_FALSE; 11139566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 11141baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1115b90c6cbeSBarry Smith } 1116b90c6cbeSBarry Smith #endif 1117b90c6cbeSBarry Smith 111848a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 111976b2cf59SMatthew Knepley 1120dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 11215d973c19SBarry Smith 11225d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1123dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1124d0609cedSBarry Smith PetscOptionsEnd(); 11254bbc92c1SBarry Smith 1126d8d34be6SBarry Smith if (snes->linesearch) { 11279566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11289566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1129d8d34be6SBarry Smith } 11309e764e56SPeter Brune 11316aa5e7e9SBarry Smith if (snes->usesksp) { 11329566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11339566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11349566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11356aa5e7e9SBarry Smith } 11366991f827SBarry Smith 1137b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11389566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11399566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 114048a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11411baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1142b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 11433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1144b3cd9a81SMatthew G. Knepley } 1145b3cd9a81SMatthew G. Knepley 1146b3cd9a81SMatthew G. Knepley /*@ 1147f6dfbefdSBarry Smith SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options 1148b3cd9a81SMatthew G. Knepley 1149c3339decSBarry Smith Collective 1150b3cd9a81SMatthew G. Knepley 1151b3cd9a81SMatthew G. Knepley Input Parameter: 1152f6dfbefdSBarry Smith . snes - the `SNES` context 1153b3cd9a81SMatthew G. Knepley 1154b3cd9a81SMatthew G. Knepley Level: beginner 1155b3cd9a81SMatthew G. Knepley 1156dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1157b3cd9a81SMatthew G. Knepley @*/ 1158d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESResetFromOptions(SNES snes) 1159d71ae5a4SJacob Faibussowitsch { 1160b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11619566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11639b94acceSBarry Smith } 11649b94acceSBarry Smith 1165bb9467b5SJed Brown /*@C 1166d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1167d25893d9SBarry Smith the nonlinear solvers. 1168d25893d9SBarry Smith 1169dc4c0fb0SBarry Smith Logically Collective; No Fortran Support 1170d25893d9SBarry Smith 1171d25893d9SBarry Smith Input Parameters: 1172f6dfbefdSBarry Smith + snes - the `SNES` context 1173d25893d9SBarry Smith . compute - function to compute the context 1174d25893d9SBarry Smith - destroy - function to destroy the context 1175d25893d9SBarry Smith 1176d25893d9SBarry Smith Level: intermediate 1177d25893d9SBarry Smith 1178f6dfbefdSBarry Smith Note: 1179f6dfbefdSBarry Smith This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level. 1180f6dfbefdSBarry Smith 1181f6dfbefdSBarry Smith Use `SNESSetApplicationContext()` to see the context immediately 1182f6dfbefdSBarry Smith 1183dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESSetApplicationContext()` 1184d25893d9SBarry Smith @*/ 1185d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) 1186d71ae5a4SJacob Faibussowitsch { 1187d25893d9SBarry Smith PetscFunctionBegin; 1188d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1189d25893d9SBarry Smith snes->ops->usercompute = compute; 1190d25893d9SBarry Smith snes->ops->userdestroy = destroy; 11913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1192d25893d9SBarry Smith } 1193a847f771SSatish Balay 1194b07ff414SBarry Smith /*@ 1195f6dfbefdSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers. 11969b94acceSBarry Smith 1197c3339decSBarry Smith Logically Collective 1198fee21e36SBarry Smith 1199c7afd0dbSLois Curfman McInnes Input Parameters: 1200f6dfbefdSBarry Smith + snes - the `SNES` context 1201c7afd0dbSLois Curfman McInnes - usrP - optional user context 1202c7afd0dbSLois Curfman McInnes 120336851e7fSLois Curfman McInnes Level: intermediate 120436851e7fSLois Curfman McInnes 1205f6dfbefdSBarry Smith Notes: 1206f6dfbefdSBarry Smith Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function 1207f6dfbefdSBarry Smith with `SNESGetApplicationContext()` 1208f6dfbefdSBarry Smith 1209f6dfbefdSBarry Smith To provide a function that computes the context for you use `SNESSetComputeApplicationContext()` 1210f6dfbefdSBarry Smith 1211f6dfbefdSBarry Smith Fortran Note: 1212dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1213daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1214daf670e6SBarry Smith 1215dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 12169b94acceSBarry Smith @*/ 1217d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) 1218d71ae5a4SJacob Faibussowitsch { 1219b07ff414SBarry Smith KSP ksp; 12201b2093e4SBarry Smith 12213a40ed3dSBarry Smith PetscFunctionBegin; 12220700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12239566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 12249566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 12259b94acceSBarry Smith snes->user = usrP; 12263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12279b94acceSBarry Smith } 122874679c65SBarry Smith 1229b07ff414SBarry Smith /*@ 12309b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 1231f6dfbefdSBarry Smith nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()` 12329b94acceSBarry Smith 1233c7afd0dbSLois Curfman McInnes Not Collective 1234c7afd0dbSLois Curfman McInnes 12359b94acceSBarry Smith Input Parameter: 1236f6dfbefdSBarry Smith . snes - `SNES` context 12379b94acceSBarry Smith 12389b94acceSBarry Smith Output Parameter: 12399b94acceSBarry Smith . usrP - user context 12409b94acceSBarry Smith 124136851e7fSLois Curfman McInnes Level: intermediate 124236851e7fSLois Curfman McInnes 1243dc4c0fb0SBarry Smith Fortran Note: 1244dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1245dc4c0fb0SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1246dc4c0fb0SBarry Smith 1247dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetApplicationContext()` 12489b94acceSBarry Smith @*/ 1249d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) 1250d71ae5a4SJacob Faibussowitsch { 12513a40ed3dSBarry Smith PetscFunctionBegin; 12520700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1253e71120c6SJed Brown *(void **)usrP = snes->user; 12543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12559b94acceSBarry Smith } 125674679c65SBarry Smith 12579b94acceSBarry Smith /*@ 1258f6dfbefdSBarry Smith SNESSetUseMatrixFree - indicates that `SNES` should use matrix free finite difference matrix vector products to apply the Jacobian. 12593565c898SBarry Smith 1260dc4c0fb0SBarry Smith Logically Collective 12613565c898SBarry Smith 12623565c898SBarry Smith Input Parameters: 1263f6dfbefdSBarry Smith + snes - `SNES` context 1264f6dfbefdSBarry Smith . mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1265f6dfbefdSBarry 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 1266f6dfbefdSBarry Smith this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available 12673565c898SBarry Smith 1268f6dfbefdSBarry Smith Options Database Keys: 1269f6dfbefdSBarry Smith + -snes_mf_operator - use matrix free only for the mat operator 1270f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator 1271ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1272ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12733565c898SBarry Smith 12743565c898SBarry Smith Level: intermediate 12753565c898SBarry Smith 1276f6dfbefdSBarry Smith Note: 1277dc4c0fb0SBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 1278f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 1279ec5066bdSBarry Smith 1280dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12813565c898SBarry Smith @*/ 1282d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) 1283d71ae5a4SJacob Faibussowitsch { 12843565c898SBarry Smith PetscFunctionBegin; 12853565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 128688b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 128788b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12884ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12893565c898SBarry Smith snes->mf_operator = mf_operator; 12903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12913565c898SBarry Smith } 12923565c898SBarry Smith 12933565c898SBarry Smith /*@ 1294dc4c0fb0SBarry Smith SNESGetUseMatrixFree - indicates if the `SNES` uses matrix-free finite difference matrix vector products to apply the Jacobian. 12953565c898SBarry Smith 1296f6dfbefdSBarry Smith Not Collective, but the resulting flags will be the same on all MPI ranks 12973565c898SBarry Smith 12983565c898SBarry Smith Input Parameter: 1299f6dfbefdSBarry Smith . snes - `SNES` context 13003565c898SBarry Smith 13013565c898SBarry Smith Output Parameters: 1302f6dfbefdSBarry Smith + mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1303f6dfbefdSBarry 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 13043565c898SBarry Smith 13053565c898SBarry Smith Level: intermediate 13063565c898SBarry Smith 1307dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 13083565c898SBarry Smith @*/ 1309d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) 1310d71ae5a4SJacob Faibussowitsch { 13113565c898SBarry Smith PetscFunctionBegin; 13123565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13133565c898SBarry Smith if (mf) *mf = snes->mf; 13143565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13163565c898SBarry Smith } 13173565c898SBarry Smith 13183565c898SBarry Smith /*@ 1319c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1320c8228a4eSBarry Smith at this time. 13219b94acceSBarry Smith 1322c7afd0dbSLois Curfman McInnes Not Collective 1323c7afd0dbSLois Curfman McInnes 13249b94acceSBarry Smith Input Parameter: 1325f6dfbefdSBarry Smith . snes - `SNES` context 13269b94acceSBarry Smith 13279b94acceSBarry Smith Output Parameter: 13289b94acceSBarry Smith . iter - iteration number 13299b94acceSBarry Smith 1330dc4c0fb0SBarry Smith Level: intermediate 1331dc4c0fb0SBarry Smith 1332c8228a4eSBarry Smith Notes: 1333c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1334c8228a4eSBarry Smith 1335c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 1336f6dfbefdSBarry Smith Jacobian at each `SNES` iteration). For example, the code 133708405cd6SLois Curfman McInnes .vb 133808405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 133908405cd6SLois Curfman McInnes if (!(it % 2)) { 134008405cd6SLois Curfman McInnes [compute Jacobian here] 134108405cd6SLois Curfman McInnes } 134208405cd6SLois Curfman McInnes .ve 1343f6dfbefdSBarry Smith can be used in your function that computes the Jacobian to cause the Jacobian to be 1344f6dfbefdSBarry Smith recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()` 1345c8228a4eSBarry Smith 1346f6dfbefdSBarry Smith After the `SNES` solve is complete this will return the number of nonlinear iterations used. 1347c04deec6SBarry Smith 1348dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()` 13499b94acceSBarry Smith @*/ 1350d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) 1351d71ae5a4SJacob Faibussowitsch { 13523a40ed3dSBarry Smith PetscFunctionBegin; 13530700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13544482741eSBarry Smith PetscValidIntPointer(iter, 2); 13559b94acceSBarry Smith *iter = snes->iter; 13563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13579b94acceSBarry Smith } 135874679c65SBarry Smith 1359360c497dSPeter Brune /*@ 1360360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1361360c497dSPeter Brune 1362360c497dSPeter Brune Not Collective 1363360c497dSPeter Brune 1364d8d19677SJose E. Roman Input Parameters: 1365f6dfbefdSBarry Smith + snes - `SNES` context 1366a2b725a8SWilliam Gropp - iter - iteration number 1367360c497dSPeter Brune 1368360c497dSPeter Brune Level: developer 1369360c497dSPeter Brune 1370dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetLinearSolveIterations()` 1371360c497dSPeter Brune @*/ 1372d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) 1373d71ae5a4SJacob Faibussowitsch { 1374360c497dSPeter Brune PetscFunctionBegin; 1375360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13769566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1377360c497dSPeter Brune snes->iter = iter; 13789566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 13793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1380360c497dSPeter Brune } 1381360c497dSPeter Brune 13829b94acceSBarry Smith /*@ 1383b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13849b94acceSBarry Smith attempted by the nonlinear solver. 13859b94acceSBarry Smith 1386c7afd0dbSLois Curfman McInnes Not Collective 1387c7afd0dbSLois Curfman McInnes 13889b94acceSBarry Smith Input Parameter: 1389f6dfbefdSBarry Smith . snes - `SNES` context 13909b94acceSBarry Smith 13919b94acceSBarry Smith Output Parameter: 13929b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13939b94acceSBarry Smith 1394dc4c0fb0SBarry Smith Level: intermediate 1395dc4c0fb0SBarry Smith 1396f6dfbefdSBarry Smith Note: 1397f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 1398c96a6f78SLois Curfman McInnes 1399dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1400db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 14019b94acceSBarry Smith @*/ 1402d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) 1403d71ae5a4SJacob Faibussowitsch { 14043a40ed3dSBarry Smith PetscFunctionBegin; 14050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14064482741eSBarry Smith PetscValidIntPointer(nfails, 2); 140750ffb88aSMatthew Knepley *nfails = snes->numFailures; 14083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 140950ffb88aSMatthew Knepley } 141050ffb88aSMatthew Knepley 141150ffb88aSMatthew Knepley /*@ 1412b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1413f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 141450ffb88aSMatthew Knepley 141550ffb88aSMatthew Knepley Not Collective 141650ffb88aSMatthew Knepley 141750ffb88aSMatthew Knepley Input Parameters: 1418f6dfbefdSBarry Smith + snes - `SNES` context 141950ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 142050ffb88aSMatthew Knepley 142150ffb88aSMatthew Knepley Level: intermediate 142250ffb88aSMatthew Knepley 1423dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1424db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 142550ffb88aSMatthew Knepley @*/ 1426d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1427d71ae5a4SJacob Faibussowitsch { 142850ffb88aSMatthew Knepley PetscFunctionBegin; 14290700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 143050ffb88aSMatthew Knepley snes->maxFailures = maxFails; 14313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 143250ffb88aSMatthew Knepley } 143350ffb88aSMatthew Knepley 143450ffb88aSMatthew Knepley /*@ 1435b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1436f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 143750ffb88aSMatthew Knepley 143850ffb88aSMatthew Knepley Not Collective 143950ffb88aSMatthew Knepley 144050ffb88aSMatthew Knepley Input Parameter: 144120f4b53cSBarry Smith . snes - `SNES` context 144250ffb88aSMatthew Knepley 144350ffb88aSMatthew Knepley Output Parameter: 144450ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 144550ffb88aSMatthew Knepley 144650ffb88aSMatthew Knepley Level: intermediate 144750ffb88aSMatthew Knepley 1448dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1449db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 145050ffb88aSMatthew Knepley @*/ 1451d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1452d71ae5a4SJacob Faibussowitsch { 145350ffb88aSMatthew Knepley PetscFunctionBegin; 14540700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14554482741eSBarry Smith PetscValidIntPointer(maxFails, 2); 145650ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14589b94acceSBarry Smith } 1459a847f771SSatish Balay 14602541af92SBarry Smith /*@ 14612541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1462f6dfbefdSBarry Smith done by the `SNES` object 14632541af92SBarry Smith 14642541af92SBarry Smith Not Collective 14652541af92SBarry Smith 14662541af92SBarry Smith Input Parameter: 1467f6dfbefdSBarry Smith . snes - `SNES` context 14682541af92SBarry Smith 14692541af92SBarry Smith Output Parameter: 14702541af92SBarry Smith . nfuncs - number of evaluations 14712541af92SBarry Smith 14722541af92SBarry Smith Level: intermediate 14732541af92SBarry Smith 1474f6dfbefdSBarry Smith Note: 1475f6dfbefdSBarry Smith Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used. 1476971e163fSPeter Brune 1477dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14782541af92SBarry Smith @*/ 1479d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1480d71ae5a4SJacob Faibussowitsch { 14812541af92SBarry Smith PetscFunctionBegin; 14820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14832541af92SBarry Smith PetscValidIntPointer(nfuncs, 2); 14842541af92SBarry Smith *nfuncs = snes->nfuncs; 14853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14862541af92SBarry Smith } 14872541af92SBarry Smith 14883d4c4710SBarry Smith /*@ 14893d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14903d4c4710SBarry Smith linear solvers. 14913d4c4710SBarry Smith 14923d4c4710SBarry Smith Not Collective 14933d4c4710SBarry Smith 14943d4c4710SBarry Smith Input Parameter: 1495f6dfbefdSBarry Smith . snes - `SNES` context 14963d4c4710SBarry Smith 14973d4c4710SBarry Smith Output Parameter: 14983d4c4710SBarry Smith . nfails - number of failed solves 14993d4c4710SBarry Smith 1500f6dfbefdSBarry Smith Options Database Key: 15019d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15029d85da0cSMatthew G. Knepley 1503f6dfbefdSBarry Smith Level: intermediate 1504f6dfbefdSBarry Smith 1505f6dfbefdSBarry Smith Note: 1506f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 15073d4c4710SBarry Smith 1508dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 15093d4c4710SBarry Smith @*/ 1510d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) 1511d71ae5a4SJacob Faibussowitsch { 15123d4c4710SBarry Smith PetscFunctionBegin; 15130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15143d4c4710SBarry Smith PetscValidIntPointer(nfails, 2); 15153d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15163ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15173d4c4710SBarry Smith } 15183d4c4710SBarry Smith 15193d4c4710SBarry Smith /*@ 15203d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1521f6dfbefdSBarry Smith allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE` 15223d4c4710SBarry Smith 1523c3339decSBarry Smith Logically Collective 15243d4c4710SBarry Smith 15253d4c4710SBarry Smith Input Parameters: 1526f6dfbefdSBarry Smith + snes - `SNES` context 15273d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15283d4c4710SBarry Smith 1529f6dfbefdSBarry Smith Options Database Key: 15309d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15319d85da0cSMatthew G. Knepley 1532dc4c0fb0SBarry Smith Level: intermediate 1533dc4c0fb0SBarry Smith 1534f6dfbefdSBarry Smith Note: 1535f6dfbefdSBarry Smith By default this is 0; that is `SNES` returns on the first failed linear solve 15363d4c4710SBarry Smith 1537dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15383d4c4710SBarry Smith @*/ 1539d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1540d71ae5a4SJacob Faibussowitsch { 15413d4c4710SBarry Smith PetscFunctionBegin; 15420700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1543c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15443d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15463d4c4710SBarry Smith } 15473d4c4710SBarry Smith 15483d4c4710SBarry Smith /*@ 15493d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1550f6dfbefdSBarry Smith are allowed before `SNES` returns as unsuccessful 15513d4c4710SBarry Smith 15523d4c4710SBarry Smith Not Collective 15533d4c4710SBarry Smith 15543d4c4710SBarry Smith Input Parameter: 1555f6dfbefdSBarry Smith . snes - `SNES` context 15563d4c4710SBarry Smith 15573d4c4710SBarry Smith Output Parameter: 15583d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15593d4c4710SBarry Smith 15603d4c4710SBarry Smith Level: intermediate 15613d4c4710SBarry Smith 1562f6dfbefdSBarry Smith Note: 1563f6dfbefdSBarry Smith By default this is 1; that is `SNES` returns on the first failed linear solve 15643d4c4710SBarry Smith 1565dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15663d4c4710SBarry Smith @*/ 1567d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1568d71ae5a4SJacob Faibussowitsch { 15693d4c4710SBarry Smith PetscFunctionBegin; 15700700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15713d4c4710SBarry Smith PetscValidIntPointer(maxFails, 2); 15723d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15733ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15743d4c4710SBarry Smith } 15753d4c4710SBarry Smith 1576c96a6f78SLois Curfman McInnes /*@ 1577b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1578c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1579c96a6f78SLois Curfman McInnes 1580c7afd0dbSLois Curfman McInnes Not Collective 1581c7afd0dbSLois Curfman McInnes 1582c96a6f78SLois Curfman McInnes Input Parameter: 1583f6dfbefdSBarry Smith . snes - `SNES` context 1584c96a6f78SLois Curfman McInnes 1585c96a6f78SLois Curfman McInnes Output Parameter: 1586c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1587c96a6f78SLois Curfman McInnes 1588dc4c0fb0SBarry Smith Level: intermediate 1589dc4c0fb0SBarry Smith 1590c96a6f78SLois Curfman McInnes Notes: 1591f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used. 1592c96a6f78SLois Curfman McInnes 1593f6dfbefdSBarry 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 1594f6dfbefdSBarry Smith then call `KSPGetIterationNumber()` after the failed solve. 1595010be392SBarry Smith 1596dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1597c96a6f78SLois Curfman McInnes @*/ 1598d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) 1599d71ae5a4SJacob Faibussowitsch { 16003a40ed3dSBarry Smith PetscFunctionBegin; 16010700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16024482741eSBarry Smith PetscValidIntPointer(lits, 2); 1603c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 16043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1605c96a6f78SLois Curfman McInnes } 1606c96a6f78SLois Curfman McInnes 1607971e163fSPeter Brune /*@ 1608971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1609f6dfbefdSBarry Smith are reset every time `SNESSolve()` is called. 1610971e163fSPeter Brune 1611c3339decSBarry Smith Logically Collective 1612971e163fSPeter Brune 1613d8d19677SJose E. Roman Input Parameters: 1614f6dfbefdSBarry Smith + snes - `SNES` context 1615f6dfbefdSBarry Smith - reset - whether to reset the counters or not, defaults to `PETSC_TRUE` 1616971e163fSPeter Brune 1617971e163fSPeter Brune Level: developer 1618971e163fSPeter Brune 1619dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1620971e163fSPeter Brune @*/ 1621d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) 1622d71ae5a4SJacob Faibussowitsch { 1623971e163fSPeter Brune PetscFunctionBegin; 1624971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1625971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1626971e163fSPeter Brune snes->counters_reset = reset; 16273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1628971e163fSPeter Brune } 1629971e163fSPeter Brune 16302999313aSBarry Smith /*@ 1631f6dfbefdSBarry Smith SNESSetKSP - Sets a `KSP` context for the `SNES` object to use 16322999313aSBarry Smith 1633f6dfbefdSBarry Smith Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm 16342999313aSBarry Smith 16352999313aSBarry Smith Input Parameters: 1636f6dfbefdSBarry Smith + snes - the `SNES` context 1637f6dfbefdSBarry Smith - ksp - the `KSP` context 16382999313aSBarry Smith 1639dc4c0fb0SBarry Smith Level: developer 1640dc4c0fb0SBarry Smith 16412999313aSBarry Smith Notes: 1642f6dfbefdSBarry Smith The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()` 16432999313aSBarry Smith so this routine is rarely needed. 16442999313aSBarry Smith 1645f6dfbefdSBarry Smith The `KSP` object that is already in the `SNES` object has its reference count 16462999313aSBarry Smith decreased by one. 16472999313aSBarry Smith 1648dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16492999313aSBarry Smith @*/ 1650d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) 1651d71ae5a4SJacob Faibussowitsch { 16522999313aSBarry Smith PetscFunctionBegin; 16530700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16540700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16552999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16569566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16579566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16582999313aSBarry Smith snes->ksp = ksp; 16593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16602999313aSBarry Smith } 16612999313aSBarry Smith 166252baeb72SSatish Balay /*@ 1663dc4c0fb0SBarry Smith SNESCreate - Creates a nonlinear solver context used to manage a set of nonlinear solves 16649b94acceSBarry Smith 1665d083f849SBarry Smith Collective 1666c7afd0dbSLois Curfman McInnes 1667f6dfbefdSBarry Smith Input Parameter: 1668906ed7ccSBarry Smith . comm - MPI communicator 16699b94acceSBarry Smith 16709b94acceSBarry Smith Output Parameter: 167120f4b53cSBarry Smith . outsnes - the new `SNES` context 16729b94acceSBarry Smith 1673c7afd0dbSLois Curfman McInnes Options Database Keys: 1674dc4c0fb0SBarry Smith + -snes_mf - Activates default matrix-free Jacobian-vector products, and no preconditioning matrix 1675dc4c0fb0SBarry Smith . -snes_mf_operator - Activates default matrix-free Jacobian-vector products, and a user-provided preconditioning matrix 1676dc4c0fb0SBarry Smith as set by `SNESSetJacobian()` 1677dc4c0fb0SBarry Smith . -snes_fd_coloring - uses a relative fast computation of the Jacobian using finite differences and a graph coloring 1678c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1679c1f60f51SBarry Smith 168036851e7fSLois Curfman McInnes Level: beginner 168136851e7fSLois Curfman McInnes 168295452b02SPatrick Sanan Developer Notes: 1683f6dfbefdSBarry Smith `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is 1684efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1685f6dfbefdSBarry Smith particular method does use `KSP` and regulates if the information about the `KSP` is printed 1686f6dfbefdSBarry Smith in `SNESView()`. 1687efd4aadfSBarry Smith 1688f6dfbefdSBarry Smith `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused 1689f6dfbefdSBarry Smith by help messages about meaningless `SNES` options. 1690f6dfbefdSBarry Smith 1691dc4c0fb0SBarry Smith `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should be fixed. 1692efd4aadfSBarry Smith 1693dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 16949b94acceSBarry Smith @*/ 1695d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) 1696d71ae5a4SJacob Faibussowitsch { 16979b94acceSBarry Smith SNES snes; 1698fa9f3622SBarry Smith SNESKSPEW *kctx; 169937fcc0dbSBarry Smith 17003a40ed3dSBarry Smith PetscFunctionBegin; 1701ed1caa07SMatthew Knepley PetscValidPointer(outsnes, 2); 17020298fd71SBarry Smith *outsnes = NULL; 17039566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 17048ba1e511SMatthew Knepley 17059566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 17067adad957SLisandro Dalcin 17078d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17082c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 170988976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17109b94acceSBarry Smith snes->max_its = 50; 17119750a799SBarry Smith snes->max_funcs = 10000; 17129b94acceSBarry Smith snes->norm = 0.0; 1713c1e67a49SFande Kong snes->xnorm = 0.0; 1714c1e67a49SFande Kong snes->ynorm = 0.0; 1715365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17166c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 17178ca48ce9SPierre Jolivet snes->rtol = PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8; 1718b4874afaSBarry Smith snes->ttol = 0.0; 17198ca48ce9SPierre Jolivet snes->abstol = PetscDefined(USE_REAL_SINGLE) ? 1.e-25 : 1.e-50; 17208ca48ce9SPierre Jolivet snes->stol = PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8; 17218ca48ce9SPierre Jolivet snes->deltatol = PetscDefined(USE_REAL_SINGLE) ? 1.e-6 : 1.e-12; 1722e37c518bSBarry Smith snes->divtol = 1.e4; 1723e37c518bSBarry Smith snes->rnorm0 = 0; 17249b94acceSBarry Smith snes->nfuncs = 0; 172550ffb88aSMatthew Knepley snes->numFailures = 0; 172650ffb88aSMatthew Knepley snes->maxFailures = 1; 17277a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1728e35cf81dSBarry Smith snes->lagjacobian = 1; 172937ec4e1aSPeter Brune snes->jac_iter = 0; 173037ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1731a8054027SBarry Smith snes->lagpreconditioner = 1; 173237ec4e1aSPeter Brune snes->pre_iter = 0; 173337ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1734639f9d9dSBarry Smith snes->numbermonitors = 0; 1735c4421ceaSFande Kong snes->numberreasonviews = 0; 17369e5d0892SLisandro Dalcin snes->data = NULL; 17374dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1738186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17396f24a144SLois Curfman McInnes snes->nwork = 0; 17409e5d0892SLisandro Dalcin snes->work = NULL; 174158c9b817SLisandro Dalcin snes->nvwork = 0; 17429e5d0892SLisandro Dalcin snes->vwork = NULL; 1743758f92a0SBarry Smith snes->conv_hist_len = 0; 1744758f92a0SBarry Smith snes->conv_hist_max = 0; 17450298fd71SBarry Smith snes->conv_hist = NULL; 17460298fd71SBarry Smith snes->conv_hist_its = NULL; 1747758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1748971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1749e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1750184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1751efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1752b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1753c40d0f55SPeter Brune 1754d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1755d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1756d8f46077SPeter Brune snes->mf_version = 1; 1757d8f46077SPeter Brune 17583d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17593d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17603d4c4710SBarry Smith 1761349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 176276bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1763349187a7SBarry Smith 17644fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17654fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17664fc747eaSLawrence Mitchell 17679b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17684dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&kctx)); 1769f5af7f23SKarl Rupp 17709b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17719b94acceSBarry Smith kctx->version = 2; 17720f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17739b94acceSBarry Smith this was too large for some test cases */ 177475567043SBarry Smith kctx->rtol_last = 0.0; 17750f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17769b94acceSBarry Smith kctx->gamma = 1.0; 17770f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 177871f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17790f0abf79SStefano Zampini kctx->threshold = 0.1; 178075567043SBarry Smith kctx->lresid_last = 0.0; 178175567043SBarry Smith kctx->norm_last = 0.0; 17829b94acceSBarry Smith 17830f0abf79SStefano Zampini kctx->rk_last = 0.0; 17840f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 17850f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 17860f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 17870f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 17880f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 17890f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 17900f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 17910f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 17920f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 17930f0abf79SStefano Zampini 17949b94acceSBarry Smith *outsnes = snes; 17953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 17969b94acceSBarry Smith } 17979b94acceSBarry Smith 179888f0584fSBarry Smith /*MC 1799f6dfbefdSBarry Smith SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()` 180088f0584fSBarry Smith 180188f0584fSBarry Smith Synopsis: 1802411c0326SBarry Smith #include "petscsnes.h" 1803411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 180488f0584fSBarry Smith 1805c3339decSBarry Smith Collective 18061843f636SBarry Smith 180788f0584fSBarry Smith Input Parameters: 1808f6dfbefdSBarry Smith + snes - the `SNES` context 180988f0584fSBarry Smith . x - state at which to evaluate residual 1810f6dfbefdSBarry Smith - ctx - optional user-defined function context, passed in with `SNESSetFunction()` 181188f0584fSBarry Smith 181288f0584fSBarry Smith Output Parameter: 181388f0584fSBarry Smith . f - vector to put residual (function value) 181488f0584fSBarry Smith 1815878cb397SSatish Balay Level: intermediate 1816878cb397SSatish Balay 1817dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunction()`, `SNESGetFunction()` 181888f0584fSBarry Smith M*/ 181988f0584fSBarry Smith 18209b94acceSBarry Smith /*@C 18219b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 1822f6dfbefdSBarry Smith vector for use by the `SNES` routines in solving systems of nonlinear 18239b94acceSBarry Smith equations. 18249b94acceSBarry Smith 1825c3339decSBarry Smith Logically Collective 1826fee21e36SBarry Smith 1827c7afd0dbSLois Curfman McInnes Input Parameters: 1828f6dfbefdSBarry Smith + snes - the `SNES` context 1829dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 183020f4b53cSBarry Smith . f - function evaluation routine; for calling sequence see `SNESFunction` 1831c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1832dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 18339b94acceSBarry Smith 183436851e7fSLois Curfman McInnes Level: beginner 183536851e7fSLois Curfman McInnes 1836dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18379b94acceSBarry Smith @*/ 1838d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 1839d71ae5a4SJacob Faibussowitsch { 18406cab3a1bSJed Brown DM dm; 18416cab3a1bSJed Brown 18423a40ed3dSBarry Smith PetscFunctionBegin; 18430700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1844d2a683ecSLisandro Dalcin if (r) { 1845d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1846d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18479566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18489566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 184985385478SLisandro Dalcin snes->vec_func = r; 1850d2a683ecSLisandro Dalcin } 18519566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18529566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 185348a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18559b94acceSBarry Smith } 18569b94acceSBarry Smith 1857e4ed7901SPeter Brune /*@C 1858e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1859f6dfbefdSBarry Smith initial function value at the initialization of the method. In some 1860e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1861f6dfbefdSBarry Smith `SNESSolve()`. This function allows one to avoid a redundant call 1862f6dfbefdSBarry Smith to `SNESComputeFunction()` in that case. 1863e4ed7901SPeter Brune 1864c3339decSBarry Smith Logically Collective 1865e4ed7901SPeter Brune 1866e4ed7901SPeter Brune Input Parameters: 1867f6dfbefdSBarry Smith + snes - the `SNES` context 1868e4ed7901SPeter Brune - f - vector to store function value 1869e4ed7901SPeter Brune 1870dc4c0fb0SBarry Smith Level: developer 1871dc4c0fb0SBarry Smith 1872e4ed7901SPeter Brune Notes: 1873e4ed7901SPeter Brune This should not be modified during the solution procedure. 1874e4ed7901SPeter Brune 1875f6dfbefdSBarry Smith This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning. 1876e4ed7901SPeter Brune 1877dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1878e4ed7901SPeter Brune @*/ 1879d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1880d71ae5a4SJacob Faibussowitsch { 1881e4ed7901SPeter Brune Vec vec_func; 1882e4ed7901SPeter Brune 1883e4ed7901SPeter Brune PetscFunctionBegin; 1884e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1885e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1886e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1887efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1888902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 18893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1890902f982fSPeter Brune } 18919566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 18929566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1893f5af7f23SKarl Rupp 1894217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 18953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1896e4ed7901SPeter Brune } 1897e4ed7901SPeter Brune 1898534ebe21SPeter Brune /*@ 1899f6dfbefdSBarry Smith SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring 1900f6dfbefdSBarry Smith of the `SNES` method, when norms are computed in the solving process 1901534ebe21SPeter Brune 1902c3339decSBarry Smith Logically Collective 1903534ebe21SPeter Brune 1904534ebe21SPeter Brune Input Parameters: 1905f6dfbefdSBarry Smith + snes - the `SNES` context 1906365a6726SPeter Brune - normschedule - the frequency of norm computation 1907534ebe21SPeter Brune 1908517f1916SMatthew G. Knepley Options Database Key: 190967b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1910517f1916SMatthew G. Knepley 1911dc4c0fb0SBarry Smith Level: advanced 1912dc4c0fb0SBarry Smith 1913534ebe21SPeter Brune Notes: 1914f6dfbefdSBarry Smith Only certain `SNES` methods support certain `SNESNormSchedules`. Most require evaluation 1915534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1916534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1917f6dfbefdSBarry Smith `SNESNGS` and the like do not require the norm of the function to be computed, and therefore 1918534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1919534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1920534ebe21SPeter Brune their solution. 1921534ebe21SPeter Brune 1922dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1923534ebe21SPeter Brune @*/ 1924d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1925d71ae5a4SJacob Faibussowitsch { 1926534ebe21SPeter Brune PetscFunctionBegin; 1927534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1928365a6726SPeter Brune snes->normschedule = normschedule; 19293ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1930534ebe21SPeter Brune } 1931534ebe21SPeter Brune 1932534ebe21SPeter Brune /*@ 1933f6dfbefdSBarry Smith SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring 1934f6dfbefdSBarry Smith of the `SNES` method. 1935534ebe21SPeter Brune 1936c3339decSBarry Smith Logically Collective 1937534ebe21SPeter Brune 1938534ebe21SPeter Brune Input Parameters: 1939f6dfbefdSBarry Smith + snes - the `SNES` context 1940365a6726SPeter Brune - normschedule - the type of the norm used 1941534ebe21SPeter Brune 1942534ebe21SPeter Brune Level: advanced 1943534ebe21SPeter Brune 1944dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1945534ebe21SPeter Brune @*/ 1946d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1947d71ae5a4SJacob Faibussowitsch { 1948534ebe21SPeter Brune PetscFunctionBegin; 1949534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1950365a6726SPeter Brune *normschedule = snes->normschedule; 19513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1952534ebe21SPeter Brune } 1953534ebe21SPeter Brune 1954c5ce4427SMatthew G. Knepley /*@ 1955c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1956c5ce4427SMatthew G. Knepley 1957c3339decSBarry Smith Logically Collective 1958c5ce4427SMatthew G. Knepley 1959c5ce4427SMatthew G. Knepley Input Parameters: 1960f6dfbefdSBarry Smith + snes - the `SNES` context 1961f6dfbefdSBarry Smith - norm - the value of the norm 1962c5ce4427SMatthew G. Knepley 1963c5ce4427SMatthew G. Knepley Level: developer 1964c5ce4427SMatthew G. Knepley 1965dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1966c5ce4427SMatthew G. Knepley @*/ 1967d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1968d71ae5a4SJacob Faibussowitsch { 1969c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1970c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1971c5ce4427SMatthew G. Knepley snes->norm = norm; 19723ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1973c5ce4427SMatthew G. Knepley } 1974c5ce4427SMatthew G. Knepley 1975c5ce4427SMatthew G. Knepley /*@ 1976c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1977c5ce4427SMatthew G. Knepley 1978c5ce4427SMatthew G. Knepley Not Collective 1979c5ce4427SMatthew G. Knepley 1980c5ce4427SMatthew G. Knepley Input Parameter: 1981f6dfbefdSBarry Smith . snes - the `SNES` context 1982c5ce4427SMatthew G. Knepley 1983c5ce4427SMatthew G. Knepley Output Parameter: 1984c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1985c5ce4427SMatthew G. Knepley 1986c5ce4427SMatthew G. Knepley Level: developer 1987c5ce4427SMatthew G. Knepley 1988dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1989c5ce4427SMatthew G. Knepley @*/ 1990d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1991d71ae5a4SJacob Faibussowitsch { 1992c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1993c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1994dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 1995c5ce4427SMatthew G. Knepley *norm = snes->norm; 19963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1997c5ce4427SMatthew G. Knepley } 1998c5ce4427SMatthew G. Knepley 1999c1e67a49SFande Kong /*@ 2000f6dfbefdSBarry Smith SNESGetUpdateNorm - Gets the last computed norm of the solution update 2001c1e67a49SFande Kong 2002c1e67a49SFande Kong Not Collective 2003c1e67a49SFande Kong 2004c1e67a49SFande Kong Input Parameter: 2005f6dfbefdSBarry Smith . snes - the `SNES` context 2006c1e67a49SFande Kong 2007c1e67a49SFande Kong Output Parameter: 2008c1e67a49SFande Kong . ynorm - the last computed update norm 2009c1e67a49SFande Kong 2010c1e67a49SFande Kong Level: developer 2011c1e67a49SFande Kong 2012f6dfbefdSBarry Smith Note: 2013f6dfbefdSBarry Smith The new solution is the current solution plus the update, so this norm is an indication of the size of the update 2014f6dfbefdSBarry Smith 2015dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2016c1e67a49SFande Kong @*/ 2017d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2018d71ae5a4SJacob Faibussowitsch { 2019c1e67a49SFande Kong PetscFunctionBegin; 2020c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2021dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 2022c1e67a49SFande Kong *ynorm = snes->ynorm; 20233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2024c1e67a49SFande Kong } 2025c1e67a49SFande Kong 2026c1e67a49SFande Kong /*@ 20274591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2028c1e67a49SFande Kong 2029c1e67a49SFande Kong Not Collective 2030c1e67a49SFande Kong 2031c1e67a49SFande Kong Input Parameter: 2032f6dfbefdSBarry Smith . snes - the `SNES` context 2033c1e67a49SFande Kong 2034c1e67a49SFande Kong Output Parameter: 2035c1e67a49SFande Kong . xnorm - the last computed solution norm 2036c1e67a49SFande Kong 2037c1e67a49SFande Kong Level: developer 2038c1e67a49SFande Kong 2039dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2040c1e67a49SFande Kong @*/ 2041d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2042d71ae5a4SJacob Faibussowitsch { 2043c1e67a49SFande Kong PetscFunctionBegin; 2044c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2045dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2046c1e67a49SFande Kong *xnorm = snes->xnorm; 20473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2048c1e67a49SFande Kong } 2049c1e67a49SFande Kong 205047073ea2SPeter Brune /*@C 2051f6dfbefdSBarry Smith SNESSetFunctionType - Sets the `SNESFunctionType` 2052f6dfbefdSBarry Smith of the `SNES` method. 205347073ea2SPeter Brune 2054c3339decSBarry Smith Logically Collective 205547073ea2SPeter Brune 205647073ea2SPeter Brune Input Parameters: 2057f6dfbefdSBarry Smith + snes - the `SNES` context 2058f6dfbefdSBarry Smith - type - the function type 205947073ea2SPeter Brune 206047073ea2SPeter Brune Level: developer 206147073ea2SPeter Brune 2062f6dfbefdSBarry Smith Notes: 2063f6dfbefdSBarry Smith Possible values of the function type 2064f6dfbefdSBarry Smith + `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType` 2065f6dfbefdSBarry Smith . `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()` 2066f6dfbefdSBarry Smith - `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()` 2067f6dfbefdSBarry Smith 2068f6dfbefdSBarry Smith Different `SNESType`s use this value in different ways 2069f6dfbefdSBarry Smith 2070dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 207147073ea2SPeter Brune @*/ 2072d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 2073d71ae5a4SJacob Faibussowitsch { 207447073ea2SPeter Brune PetscFunctionBegin; 207547073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 207647073ea2SPeter Brune snes->functype = type; 20773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 207847073ea2SPeter Brune } 207947073ea2SPeter Brune 208047073ea2SPeter Brune /*@C 2081f6dfbefdSBarry Smith SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()` 208247073ea2SPeter Brune of the SNES method. 208347073ea2SPeter Brune 2084c3339decSBarry Smith Logically Collective 208547073ea2SPeter Brune 208647073ea2SPeter Brune Input Parameters: 2087f6dfbefdSBarry Smith + snes - the `SNES` context 2088f6dfbefdSBarry Smith - type - the type of the function evaluation, see `SNESSetFunctionType()` 208947073ea2SPeter Brune 209047073ea2SPeter Brune Level: advanced 209147073ea2SPeter Brune 2092dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 209347073ea2SPeter Brune @*/ 2094d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 2095d71ae5a4SJacob Faibussowitsch { 209647073ea2SPeter Brune PetscFunctionBegin; 209747073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 209847073ea2SPeter Brune *type = snes->functype; 20993ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2100534ebe21SPeter Brune } 2101534ebe21SPeter Brune 2102bf388a1fSBarry Smith /*MC 2103f6dfbefdSBarry Smith SNESNGSFunction - function used to apply a Gauss-Seidel sweep on the nonlinear function 2104bf388a1fSBarry Smith 2105bf388a1fSBarry Smith Synopsis: 2106aaa7dc30SBarry Smith #include <petscsnes.h> 2107be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2108bf388a1fSBarry Smith 2109c3339decSBarry Smith Collective 21101843f636SBarry Smith 21111843f636SBarry Smith Input Parameters: 2112bf388a1fSBarry Smith + X - solution vector 2113bf388a1fSBarry Smith . B - RHS vector 2114bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2115bf388a1fSBarry Smith 21161843f636SBarry Smith Output Parameter: 21171843f636SBarry Smith . X - solution vector 21181843f636SBarry Smith 2119878cb397SSatish Balay Level: intermediate 2120878cb397SSatish Balay 2121dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESSetNGS()`, `SNESGetNGS()` 2122bf388a1fSBarry Smith M*/ 2123bf388a1fSBarry Smith 2124c79ef259SPeter Brune /*@C 2125be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2126c79ef259SPeter Brune use with composed nonlinear solvers. 2127c79ef259SPeter Brune 2128c79ef259SPeter Brune Input Parameters: 2129dc4c0fb0SBarry Smith + snes - the `SNES` context 2130f6dfbefdSBarry Smith . f - function evaluation routine to apply Gauss-Seidel see `SNESNGSFunction` 2131c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 2132dc4c0fb0SBarry Smith smoother evaluation routine (may be `NULL`) 2133c79ef259SPeter Brune 213420f4b53cSBarry Smith Calling sequence of `f`: 213520f4b53cSBarry Smith $ PetscErrorCode f(SNES snes, Vec X, Vec B, void *ctx) 2136f6dfbefdSBarry Smith + snes - the `SNES` context 2137f6dfbefdSBarry Smith . X - the current solution 2138dc4c0fb0SBarry Smith . B - the right hand side vector (which may be `NULL`) 2139f6dfbefdSBarry Smith - ctx - a user provided context 2140f6dfbefdSBarry Smith 2141dc4c0fb0SBarry Smith Level: intermediate 2142dc4c0fb0SBarry Smith 2143f6dfbefdSBarry Smith Note: 2144f6dfbefdSBarry Smith The `SNESNGS` routines are used by the composed nonlinear solver to generate 2145f6dfbefdSBarry Smith a problem appropriate update to the solution, particularly `SNESFAS`. 2146c79ef259SPeter Brune 2147dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetNGS()`, `SNESNGSFunction`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()` 2148c79ef259SPeter Brune @*/ 2149d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 2150d71ae5a4SJacob Faibussowitsch { 21516cab3a1bSJed Brown DM dm; 21526cab3a1bSJed Brown 2153646217ecSPeter Brune PetscFunctionBegin; 21546cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21559566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21569566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 21573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2158646217ecSPeter Brune } 2159646217ecSPeter Brune 2160bbc1464cSBarry Smith /* 2161bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2162bbc1464cSBarry Smith changed during the KSPSolve() 2163bbc1464cSBarry Smith */ 2164d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) 2165d71ae5a4SJacob Faibussowitsch { 2166bbc1464cSBarry Smith DM dm; 2167bbc1464cSBarry Smith DMSNES sdm; 2168bbc1464cSBarry Smith 2169bbc1464cSBarry Smith PetscFunctionBegin; 21709566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21719566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2172bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2173bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2174792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21759566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 21760df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2177ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2178792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21799566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2180bbc1464cSBarry Smith } else { 2181792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21829566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2183bbc1464cSBarry Smith } 21843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2185bbc1464cSBarry Smith } 2186bbc1464cSBarry Smith 2187d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) 2188d71ae5a4SJacob Faibussowitsch { 2189e03ab78fSPeter Brune DM dm; 2190942e3340SBarry Smith DMSNES sdm; 21916cab3a1bSJed Brown 21928b0a5094SBarry Smith PetscFunctionBegin; 21939566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21949566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 21958b0a5094SBarry 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)); 2199792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22009566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2201bbc1464cSBarry Smith } else { 2202792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22039566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2204bbc1464cSBarry Smith } 22053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22068b0a5094SBarry Smith } 22078b0a5094SBarry Smith 2208d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) 2209d71ae5a4SJacob Faibussowitsch { 22108b0a5094SBarry Smith PetscFunctionBegin; 2211e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2212bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 22139566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 22149566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 22153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22168b0a5094SBarry Smith } 22178b0a5094SBarry Smith 22188b0a5094SBarry Smith /*@C 2219f6dfbefdSBarry Smith SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22208b0a5094SBarry Smith 2221c3339decSBarry Smith Logically Collective 22228b0a5094SBarry Smith 22238b0a5094SBarry Smith Input Parameters: 2224f6dfbefdSBarry Smith + snes - the `SNES` context 2225dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 2226dc4c0fb0SBarry Smith . bp - function evaluation routine, may be `NULL` 22276b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2228dc4c0fb0SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as `Amat`) 222920f4b53cSBarry Smith . J - function to compute matrix values, for the calling sequence see `SNESJacobianFunction()` 2230dc4c0fb0SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`) 2231dc4c0fb0SBarry Smith 2232dc4c0fb0SBarry Smith Level: intermediate 22338b0a5094SBarry Smith 22348b0a5094SBarry Smith Notes: 22356b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2236f450aa47SBarry 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. 2237f450aa47SBarry Smith 2238f6dfbefdSBarry Smith One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both 22398b0a5094SBarry Smith 2240dc4c0fb0SBarry 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}. 2241dc4c0fb0SBarry Smith When an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 22428b0a5094SBarry Smith 2243dc4c0fb0SBarry Smith Run with `-snes_mf_operator` to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22448b0a5094SBarry Smith 22450d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22466b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22478b0a5094SBarry Smith 22488b0a5094SBarry 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 22498b0a5094SBarry 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 22508b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22518b0a5094SBarry Smith 2252dc4c0fb0SBarry 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 2253f6dfbefdSBarry Smith A(x^{n}) is used to build the preconditioner 22546b7fb656SBarry Smith 2255dc4c0fb0SBarry 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. 22566b7fb656SBarry Smith 2257dc4c0fb0SBarry 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 22586b7fb656SBarry 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 2259f6dfbefdSBarry 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`. 2260aaa8cc7dSPierre Jolivet See the comment in src/snes/tutorials/ex15.c. 2261bbc1464cSBarry Smith 2262dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22638b0a5094SBarry Smith @*/ 2264d71ae5a4SJacob 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) 2265d71ae5a4SJacob Faibussowitsch { 2266e03ab78fSPeter Brune DM dm; 2267e03ab78fSPeter Brune 22688b0a5094SBarry Smith PetscFunctionBegin; 22698b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22709566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22719566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22729566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22739566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22749566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22753ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22768b0a5094SBarry Smith } 22778b0a5094SBarry Smith 22787971a8bfSPeter Brune /*@C 22797971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22807971a8bfSPeter Brune 2281f6dfbefdSBarry Smith Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet. 22827971a8bfSPeter Brune 22837971a8bfSPeter Brune Input Parameter: 2284f6dfbefdSBarry Smith . snes - the `SNES` context 22857971a8bfSPeter Brune 2286d8d19677SJose E. Roman Output Parameters: 2287dc4c0fb0SBarry Smith + r - the function (or `NULL`) 228820f4b53cSBarry Smith . f - the function (or `NULL`); for calling sequence see `SNESFunction` 2289dc4c0fb0SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or `NULL`) 2290dc4c0fb0SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or `NULL`) 229120f4b53cSBarry Smith . J - the function for matrix evaluation (or `NULL`); for calling sequence see `SNESJacobianFunction` 2292dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 22937971a8bfSPeter Brune 22947971a8bfSPeter Brune Level: advanced 22957971a8bfSPeter Brune 2296dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 22977971a8bfSPeter Brune @*/ 2298d71ae5a4SJacob 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) 2299d71ae5a4SJacob Faibussowitsch { 23007971a8bfSPeter Brune DM dm; 23017971a8bfSPeter Brune 23027971a8bfSPeter Brune PetscFunctionBegin; 23037971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23049566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 23059566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 23069566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23079566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 23083ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23097971a8bfSPeter Brune } 23107971a8bfSPeter Brune 2311d25893d9SBarry Smith /*@C 2312dc4c0fb0SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the nonlinear problem 2313d25893d9SBarry Smith 2314c3339decSBarry Smith Logically Collective 2315d25893d9SBarry Smith 2316d25893d9SBarry Smith Input Parameters: 2317f6dfbefdSBarry Smith + snes - the `SNES` context 2318d25893d9SBarry Smith . func - function evaluation routine 2319d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 2320dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 2321d25893d9SBarry Smith 232220f4b53cSBarry Smith Calling sequence of `func`: 232320f4b53cSBarry Smith $ PetscErrorCode func(SNES snes, Vec x, void *ctx); 232420f4b53cSBarry Smith + snes - the `SNES` solver 232520f4b53cSBarry Smith . x - vector to put initial guess 2326d25893d9SBarry Smith - ctx - optional user-defined function context 2327d25893d9SBarry Smith 2328d25893d9SBarry Smith Level: intermediate 2329d25893d9SBarry Smith 2330dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2331d25893d9SBarry Smith @*/ 2332d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx) 2333d71ae5a4SJacob Faibussowitsch { 2334d25893d9SBarry Smith PetscFunctionBegin; 2335d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2336d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2337d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 23383ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2339d25893d9SBarry Smith } 2340d25893d9SBarry Smith 23411096aae1SMatthew Knepley /*@C 2342dc4c0fb0SBarry Smith SNESGetRhs - Gets the vector for solving F(x) = `rhs`. If `rhs` is not set 23431096aae1SMatthew Knepley it assumes a zero right hand side. 23441096aae1SMatthew Knepley 2345c3339decSBarry Smith Logically Collective 23461096aae1SMatthew Knepley 23471096aae1SMatthew Knepley Input Parameter: 2348f6dfbefdSBarry Smith . snes - the `SNES` context 23491096aae1SMatthew Knepley 23501096aae1SMatthew Knepley Output Parameter: 2351dc4c0fb0SBarry Smith . rhs - the right hand side vector or `NULL` if the right hand side vector is null 23521096aae1SMatthew Knepley 23531096aae1SMatthew Knepley Level: intermediate 23541096aae1SMatthew Knepley 2355dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23561096aae1SMatthew Knepley @*/ 2357d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) 2358d71ae5a4SJacob Faibussowitsch { 23591096aae1SMatthew Knepley PetscFunctionBegin; 23600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23611096aae1SMatthew Knepley PetscValidPointer(rhs, 2); 236285385478SLisandro Dalcin *rhs = snes->vec_rhs; 23633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23641096aae1SMatthew Knepley } 23651096aae1SMatthew Knepley 23669b94acceSBarry Smith /*@ 2367f6dfbefdSBarry Smith SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`. 23689b94acceSBarry Smith 2369c3339decSBarry Smith Collective 2370c7afd0dbSLois Curfman McInnes 23719b94acceSBarry Smith Input Parameters: 2372f6dfbefdSBarry Smith + snes - the `SNES` context 2373c7afd0dbSLois Curfman McInnes - x - input vector 23749b94acceSBarry Smith 23759b94acceSBarry Smith Output Parameter: 2376f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetFunction()` 23779b94acceSBarry Smith 2378dc4c0fb0SBarry Smith Level: developer 2379dc4c0fb0SBarry Smith 2380f6dfbefdSBarry Smith Note: 2381f6dfbefdSBarry Smith `SNESComputeFunction()` is typically used within nonlinear solvers 2382bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 238336851e7fSLois Curfman McInnes 2384dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 23859b94acceSBarry Smith @*/ 2386d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) 2387d71ae5a4SJacob Faibussowitsch { 23886cab3a1bSJed Brown DM dm; 2389942e3340SBarry Smith DMSNES sdm; 23909b94acceSBarry Smith 23913a40ed3dSBarry Smith PetscFunctionBegin; 23920700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23930700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 23940700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2395c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2396c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2397e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2398184914b5SBarry Smith 23999566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24009566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24010fdf79fbSJacob 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()."); 240232f3f7c2SPeter Brune if (sdm->ops->computefunction) { 240348a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24049566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 24058ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24068ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2407800f99ffSJeremy L Thompson { 2408800f99ffSJeremy L Thompson void *ctx; 2409800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2410800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2411800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2412800f99ffSJeremy L Thompson } 24139566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 241448a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 24150fdf79fbSJacob Faibussowitsch } else /* if (snes->vec_rhs) */ { 24169566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 24170fdf79fbSJacob Faibussowitsch } 24181baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2419ae3c334cSLois Curfman McInnes snes->nfuncs++; 2420422a814eSBarry Smith /* 2421422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2422422a814eSBarry Smith propagate the value to all processes 2423422a814eSBarry Smith */ 24241baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24269b94acceSBarry Smith } 24279b94acceSBarry Smith 2428c79ef259SPeter Brune /*@ 2429f6dfbefdSBarry Smith SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`. 2430bbc1464cSBarry Smith 2431c3339decSBarry Smith Collective 2432bbc1464cSBarry Smith 2433bbc1464cSBarry Smith Input Parameters: 2434f6dfbefdSBarry Smith + snes - the `SNES` context 2435bbc1464cSBarry Smith - x - input vector 2436bbc1464cSBarry Smith 2437bbc1464cSBarry Smith Output Parameter: 2438f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetMFFunction()` 2439bbc1464cSBarry Smith 2440dc4c0fb0SBarry Smith Level: developer 2441dc4c0fb0SBarry Smith 2442bbc1464cSBarry Smith Notes: 2443f6dfbefdSBarry Smith `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()` 2444bbc1464cSBarry Smith so users would not generally call this routine themselves. 2445bbc1464cSBarry Smith 2446f6dfbefdSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()` 2447f6dfbefdSBarry Smith while `SNESComputeFunction()` does. As such, this routine cannot be used with `MatMFFDSetBase()` with a provided F function value even if it applies the 2448f6dfbefdSBarry 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. 2449bbc1464cSBarry Smith 2450dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2451bbc1464cSBarry Smith @*/ 2452d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) 2453d71ae5a4SJacob Faibussowitsch { 2454bbc1464cSBarry Smith DM dm; 2455bbc1464cSBarry Smith DMSNES sdm; 2456bbc1464cSBarry Smith 2457bbc1464cSBarry Smith PetscFunctionBegin; 2458bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2459bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2460bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2461bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2462bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2463e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2464bbc1464cSBarry Smith 24659566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24669566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24679566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24689566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2469bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2470bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2471792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24729566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24739566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2474bbc1464cSBarry Smith snes->nfuncs++; 2475bbc1464cSBarry Smith /* 2476bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2477bbc1464cSBarry Smith propagate the value to all processes 2478bbc1464cSBarry Smith */ 24791baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2481bbc1464cSBarry Smith } 2482bbc1464cSBarry Smith 2483bbc1464cSBarry Smith /*@ 2484f6dfbefdSBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`. 2485c79ef259SPeter Brune 2486c3339decSBarry Smith Collective 2487c79ef259SPeter Brune 2488c79ef259SPeter Brune Input Parameters: 2489f6dfbefdSBarry Smith + snes - the `SNES` context 2490c79ef259SPeter Brune . x - input vector 2491c79ef259SPeter Brune - b - rhs vector 2492c79ef259SPeter Brune 2493c79ef259SPeter Brune Output Parameter: 2494c79ef259SPeter Brune . x - new solution vector 2495c79ef259SPeter Brune 2496dc4c0fb0SBarry Smith Level: developer 2497dc4c0fb0SBarry Smith 2498f6dfbefdSBarry Smith Note: 2499f6dfbefdSBarry Smith `SNESComputeNGS()` is typically used within composed nonlinear solver 2500c79ef259SPeter Brune implementations, so most users would not generally call this routine 2501c79ef259SPeter Brune themselves. 2502c79ef259SPeter Brune 2503dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()` 2504c79ef259SPeter Brune @*/ 2505d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) 2506d71ae5a4SJacob Faibussowitsch { 25076cab3a1bSJed Brown DM dm; 2508942e3340SBarry Smith DMSNES sdm; 2509646217ecSPeter Brune 2510646217ecSPeter Brune PetscFunctionBegin; 2511646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2512064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2513064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2514064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2515064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 2516e0f629ddSJacob Faibussowitsch if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE)); 25179566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 25189566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 25199566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 25200fdf79fbSJacob Faibussowitsch PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 25219566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2522792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 25239566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 25249566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 25253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2526646217ecSPeter Brune } 2527646217ecSPeter Brune 2528d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestJacobian(SNES snes) 2529d71ae5a4SJacob Faibussowitsch { 253012837594SBarry Smith Mat A, B, C, D, jacobian; 2531e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2532e885f1abSBarry Smith PetscReal nrm, gnorm; 253381e7118cSBarry Smith PetscReal threshold = 1.e-5; 25340e276705SLisandro Dalcin MatType mattype; 2535e885f1abSBarry Smith PetscInt m, n, M, N; 2536e885f1abSBarry Smith void *functx; 25372cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 25383325ff46SBarry Smith PetscViewer viewer, mviewer; 2539e885f1abSBarry Smith MPI_Comm comm; 2540e885f1abSBarry Smith PetscInt tabs; 254112837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25423325ff46SBarry Smith PetscViewerFormat format; 2543e885f1abSBarry Smith 2544e885f1abSBarry Smith PetscFunctionBegin; 2545d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 25469566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 25479566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 25489566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 2549*4ead3382SBarry Smith PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 25509566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 2551*4ead3382SBarry Smith /* Cannot remove the what otherwise would be redundant call to (PetscOptionsReal("-snes_test_jacobian_display_threshold") below because its usage is different than the replacement usage */ 25529566063dSJacob 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)); 2553d0609cedSBarry Smith PetscOptionsEnd(); 25543ba16761SJacob Faibussowitsch if (!test) PetscFunctionReturn(PETSC_SUCCESS); 2555e885f1abSBarry Smith 25569566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25579566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25589566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25599566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25609566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 256112837594SBarry Smith if (!complete_print && !directionsprinted) { 25629566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25639566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 256412837594SBarry Smith } 256512837594SBarry Smith if (!directionsprinted) { 25669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 256812837594SBarry Smith directionsprinted = PETSC_TRUE; 2569e885f1abSBarry Smith } 25701baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2571e885f1abSBarry Smith 25729566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 257312837594SBarry Smith if (!flg) jacobian = snes->jacobian; 257412837594SBarry Smith else jacobian = snes->jacobian_pre; 257512837594SBarry Smith 2576a82339d0SMatthew G. Knepley if (!x) { 25779566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2578a82339d0SMatthew G. Knepley } else { 25799566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2580a82339d0SMatthew G. Knepley } 2581a82339d0SMatthew G. Knepley if (!f) { 25829566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2583a82339d0SMatthew G. Knepley } else { 25849566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2585a82339d0SMatthew G. Knepley } 2586a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 25879566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 25889566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 25899566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 259012837594SBarry Smith while (jacobian) { 25912cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 25922cd624f9SStefano Zampini 25932cd624f9SStefano Zampini if (istranspose) { 25949566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 25952cd624f9SStefano Zampini Jsave = jacobian; 25962cd624f9SStefano Zampini jacobian = JT; 25972cd624f9SStefano Zampini } 25989566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 259912837594SBarry Smith if (flg) { 260012837594SBarry Smith A = jacobian; 26019566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 260212837594SBarry Smith } else { 26039566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 260412837594SBarry Smith } 2605e885f1abSBarry Smith 26069566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 26079566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 26089566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 26099566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 26109566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 26119566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 26129566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 26139566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 26149566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2615e885f1abSBarry Smith 26169566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 26179566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 261812837594SBarry Smith 26199566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 26209566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26219566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 26229566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 26239566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 262412837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 26259566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 262612837594SBarry Smith 2627e885f1abSBarry Smith if (complete_print) { 26289566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 26299566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 26309566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 26319566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2632e885f1abSBarry Smith } 2633e885f1abSBarry Smith 2634df10fb39SFande Kong if (threshold_print || complete_print) { 2635e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2636e885f1abSBarry Smith PetscScalar *cvals; 2637e885f1abSBarry Smith const PetscInt *bcols; 2638e885f1abSBarry Smith const PetscScalar *bvals; 2639e885f1abSBarry Smith 26409566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 26419566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 26429566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 26439566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 26449566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 26459566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 26460e276705SLisandro Dalcin 26479566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26489566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2649e885f1abSBarry Smith 2650e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26519566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26529566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2653e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 265423a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2655e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2656e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2657e885f1abSBarry Smith cncols += 1; 2658e885f1abSBarry Smith } 2659e885f1abSBarry Smith } 266048a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26619566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26629566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2663e885f1abSBarry Smith } 26649566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26659566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26679566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2669e885f1abSBarry Smith } 26709566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26729566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 26732cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 267412837594SBarry Smith if (jacobian != snes->jacobian_pre) { 267512837594SBarry Smith jacobian = snes->jacobian_pre; 26769566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 26779371c9d4SSatish Balay } else jacobian = NULL; 267812837594SBarry Smith } 26799566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 26801baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 26819566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 26829566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 26833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2684e885f1abSBarry Smith } 2685e885f1abSBarry Smith 268662fef451SLois Curfman McInnes /*@ 2687f6dfbefdSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`. 268862fef451SLois Curfman McInnes 2689c3339decSBarry Smith Collective 2690c7afd0dbSLois Curfman McInnes 269162fef451SLois Curfman McInnes Input Parameters: 2692f6dfbefdSBarry Smith + snes - the `SNES` context 2693c7afd0dbSLois Curfman McInnes - x - input vector 269462fef451SLois Curfman McInnes 269562fef451SLois Curfman McInnes Output Parameters: 2696c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2697f6dfbefdSBarry Smith - B - optional matrix for building the preconditioner 2698fee21e36SBarry Smith 2699e35cf81dSBarry Smith Options Database Keys: 270067b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 270167b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2702455a5933SJed 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. 2703455a5933SJed 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 2704693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2705693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2706693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27074c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 270894d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2709a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2710c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2711dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2712dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2713a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2714a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2715c01495d3SJed Brown 2716dc4c0fb0SBarry Smith Level: developer 2717dc4c0fb0SBarry Smith 2718f6dfbefdSBarry Smith Note: 271962fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 272062fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 272162fef451SLois Curfman McInnes 2722f6dfbefdSBarry Smith Developer Note: 2723dc4c0fb0SBarry 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 2724dc4c0fb0SBarry Smith for with the `SNESType` of test that has been removed. 2725e885f1abSBarry Smith 2726dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 272762fef451SLois Curfman McInnes @*/ 2728d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) 2729d71ae5a4SJacob Faibussowitsch { 2730ace3abfcSBarry Smith PetscBool flag; 27316cab3a1bSJed Brown DM dm; 2732942e3340SBarry Smith DMSNES sdm; 2733e0e3a89bSBarry Smith KSP ksp; 27343a40ed3dSBarry Smith 27353a40ed3dSBarry Smith PetscFunctionBegin; 27360700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 27370700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2738c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 2739e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE)); 27409566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 27419566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 27423232da50SPeter Brune 2743ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2744fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2745fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2746f5af7f23SKarl Rupp 27479566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2748fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 27499566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 27509566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2751ebd3b9afSBarry Smith if (flag) { 27529566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27539566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2754ebd3b9afSBarry Smith } 27553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 275637ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 275763a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27589566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2759ebd3b9afSBarry Smith if (flag) { 27609566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27619566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2762ebd3b9afSBarry Smith } 27633ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2764e35cf81dSBarry Smith } 2765efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27669566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27679566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 27683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2769d728fb7dSPeter Brune } 2770e35cf81dSBarry Smith 27719566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27729566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2773800f99ffSJeremy L Thompson { 2774800f99ffSJeremy L Thompson void *ctx; 2775800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2776800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2777800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2778800f99ffSJeremy L Thompson } 27799566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 27809566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 278128d58a37SPierre Jolivet 278228d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 27839566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2784a8054027SBarry Smith 2785e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 27869566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 27873b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 27889566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 27899566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 27903b4f5425SBarry Smith snes->lagpreconditioner = -1; 27913b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 27929566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 27939566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 279437ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 279563a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 27969566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2797d1e9a80fSBarry Smith } else { 27989566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 27999566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2800a8054027SBarry Smith } 2801a8054027SBarry Smith 28029566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 28036d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 280494ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 280594ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2806693365a8SJed Brown { 2807693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 28089566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 28099566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 28109566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 28119566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2812693365a8SJed Brown if (flag || flag_draw || flag_contour) { 28130298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2814693365a8SJed Brown PetscViewer vdraw, vstdout; 28156b3a5b13SJed Brown PetscBool flg; 2816693365a8SJed Brown if (flag_operator) { 28179566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2818693365a8SJed Brown Bexp = Bexp_mine; 2819693365a8SJed Brown } else { 2820693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 28219566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 282294ab13aaSBarry Smith if (flg) Bexp = B; 2823693365a8SJed Brown else { 2824693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28259566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2826693365a8SJed Brown Bexp = Bexp_mine; 2827693365a8SJed Brown } 2828693365a8SJed Brown } 28299566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 28309566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 28319566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2832693365a8SJed Brown if (flag_draw || flag_contour) { 28339566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28349566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28350298fd71SBarry Smith } else vdraw = NULL; 28369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 28379566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 28389566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 28399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 28409566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 28419566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 28429566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 28439566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 28449566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2845693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 28469566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28479566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 28489566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2849693365a8SJed Brown } 28509566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28519566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28529566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28539566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2854693365a8SJed Brown } 2855693365a8SJed Brown } 28564c30e9fbSJed Brown { 28576719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28586719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28599566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28609566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28619566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28629566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28639566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 286427b0f280SBarry Smith if (flag_threshold) { 28659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28669566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 286727b0f280SBarry Smith } 28686719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28694c30e9fbSJed Brown Mat Bfd; 28704c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2871335efc43SPeter Brune MatColoring coloring; 28724c30e9fbSJed Brown ISColoring iscoloring; 28734c30e9fbSJed Brown MatFDColoring matfdcoloring; 28744c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 28754c30e9fbSJed Brown void *funcctx; 28766719d8e4SJed Brown PetscReal norm1, norm2, normmax; 28774c30e9fbSJed Brown 28789566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 28799566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 28809566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 28819566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 28829566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 28839566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 28849566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 28859566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28869566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 28879566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 28884c30e9fbSJed Brown 28894c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 28909566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 28919566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 28929566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 28939566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 28949566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28959566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 28969566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 28974c30e9fbSJed Brown 28989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 28994c30e9fbSJed Brown if (flag_draw || flag_contour) { 29009566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 29019566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29020298fd71SBarry Smith } else vdraw = NULL; 29039566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 29049566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 29059566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 29069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 29079566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29089566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 29099566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 29109566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 29119566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 29129566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 29139566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 29149566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29154c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 29169566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29179566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 29189566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 29194c30e9fbSJed Brown } 29209566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 29216719d8e4SJed Brown 29226719d8e4SJed Brown if (flag_threshold) { 29236719d8e4SJed Brown PetscInt bs, rstart, rend, i; 29249566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 29259566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 29266719d8e4SJed Brown for (i = rstart; i < rend; i++) { 29276719d8e4SJed Brown const PetscScalar *ba, *ca; 29286719d8e4SJed Brown const PetscInt *bj, *cj; 29296719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 29306719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 29319566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 29329566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 29335f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29346719d8e4SJed Brown for (j = 0; j < bn; j++) { 29356719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 29366719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29376719d8e4SJed Brown maxentrycol = bj[j]; 29386719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29396719d8e4SJed Brown } 29406719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29416719d8e4SJed Brown maxdiffcol = bj[j]; 29426719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29436719d8e4SJed Brown } 29446719d8e4SJed Brown if (rdiff > maxrdiff) { 29456719d8e4SJed Brown maxrdiffcol = bj[j]; 29466719d8e4SJed Brown maxrdiff = rdiff; 29476719d8e4SJed Brown } 29486719d8e4SJed Brown } 29496719d8e4SJed Brown if (maxrdiff > 1) { 295063a3b9bcSJacob 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)); 29516719d8e4SJed Brown for (j = 0; j < bn; j++) { 29526719d8e4SJed Brown PetscReal rdiff; 29536719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 295448a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29556719d8e4SJed Brown } 295663a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29576719d8e4SJed Brown } 29589566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29599566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29606719d8e4SJed Brown } 29616719d8e4SJed Brown } 29629566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29639566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29644c30e9fbSJed Brown } 29654c30e9fbSJed Brown } 29663ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29679b94acceSBarry Smith } 29689b94acceSBarry Smith 2969bf388a1fSBarry Smith /*MC 2970f6dfbefdSBarry Smith SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES` 2971bf388a1fSBarry Smith 2972bf388a1fSBarry Smith Synopsis: 2973411c0326SBarry Smith #include "petscsnes.h" 2974411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2975bf388a1fSBarry Smith 2976c3339decSBarry Smith Collective 29771843f636SBarry Smith 29781843f636SBarry Smith Input Parameters: 29791843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 2980bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2981bf388a1fSBarry Smith 29821843f636SBarry Smith Output Parameters: 29831843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 2984dc4c0fb0SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 29851843f636SBarry Smith 2986878cb397SSatish Balay Level: intermediate 2987878cb397SSatish Balay 2988dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 2989bf388a1fSBarry Smith M*/ 2990bf388a1fSBarry Smith 29919b94acceSBarry Smith /*@C 29929b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 2993044dda88SLois Curfman McInnes location to store the matrix. 29949b94acceSBarry Smith 2995c3339decSBarry Smith Logically Collective 2996c7afd0dbSLois Curfman McInnes 29979b94acceSBarry Smith Input Parameters: 2998f6dfbefdSBarry Smith + snes - the `SNES` context 2999e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3000dc4c0fb0SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 3001dc4c0fb0SBarry Smith . J - Jacobian evaluation routine (if `NULL` then `SNES` retains any previously set value), see `SNESJacobianFunction` for details 3002c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 3003dc4c0fb0SBarry Smith Jacobian evaluation routine (may be `NULL`) (if `NULL` then `SNES` retains any previously set value) 3004dc4c0fb0SBarry Smith 3005dc4c0fb0SBarry Smith Level: beginner 30069b94acceSBarry Smith 30079b94acceSBarry Smith Notes: 3008dc4c0fb0SBarry Smith If the `Amat` matrix and `Pmat` matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on 300916913363SBarry Smith each matrix. 301016913363SBarry Smith 3011dc4c0fb0SBarry Smith If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 3012dc4c0fb0SBarry Smith space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process. 3013895c21f2SBarry Smith 3014dc4c0fb0SBarry Smith If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the `ctx` argument 3015f6dfbefdSBarry Smith must be a `MatFDColoring`. 3016a8a26c1eSJed Brown 3017c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3018f6dfbefdSBarry Smith example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()` 3019c3cc8fd1SJed Brown 3020dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, 3021db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 30229b94acceSBarry Smith @*/ 3023d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 3024d71ae5a4SJacob Faibussowitsch { 30256cab3a1bSJed Brown DM dm; 30263a7fca6bSBarry Smith 30273a40ed3dSBarry Smith PetscFunctionBegin; 30280700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3029e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 3030e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 3031e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 3032e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 30339566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30349566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 3035e5d3d808SBarry Smith if (Amat) { 30369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 30379566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 3038f5af7f23SKarl Rupp 3039e5d3d808SBarry Smith snes->jacobian = Amat; 30403a7fca6bSBarry Smith } 3041e5d3d808SBarry Smith if (Pmat) { 30429566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 30439566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 3044f5af7f23SKarl Rupp 3045e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30463a7fca6bSBarry Smith } 30473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30489b94acceSBarry Smith } 304962fef451SLois Curfman McInnes 3050c2aafc4cSSatish Balay /*@C 3051b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3052b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3053b4fd4287SBarry Smith 3054f6dfbefdSBarry Smith Not Collective, but `Mat` object will be parallel if `SNES` object is 3055c7afd0dbSLois Curfman McInnes 3056b4fd4287SBarry Smith Input Parameter: 3057b4fd4287SBarry Smith . snes - the nonlinear solver context 3058b4fd4287SBarry Smith 3059b4fd4287SBarry Smith Output Parameters: 3060dc4c0fb0SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or `NULL`) 3061dc4c0fb0SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or `NULL`) 306220f4b53cSBarry Smith . J - location to put Jacobian function (or `NULL`), for calling sequence see `SNESJacobianFunction` 3063dc4c0fb0SBarry Smith - ctx - location to stash Jacobian ctx (or `NULL`) 3064fee21e36SBarry Smith 306536851e7fSLois Curfman McInnes Level: advanced 306636851e7fSLois Curfman McInnes 3067dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3068b4fd4287SBarry Smith @*/ 3069d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 3070d71ae5a4SJacob Faibussowitsch { 30716cab3a1bSJed Brown DM dm; 30726cab3a1bSJed Brown 30733a40ed3dSBarry Smith PetscFunctionBegin; 30740700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3075e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3076e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 30779566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3078800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 30793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3080b4fd4287SBarry Smith } 3081b4fd4287SBarry Smith 3082d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3083d71ae5a4SJacob Faibussowitsch { 308458b371f3SBarry Smith DM dm; 308558b371f3SBarry Smith DMSNES sdm; 308658b371f3SBarry Smith 308758b371f3SBarry Smith PetscFunctionBegin; 30889566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30899566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 309058b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 309158b371f3SBarry Smith DM dm; 309258b371f3SBarry Smith PetscBool isdense, ismf; 309358b371f3SBarry Smith 30949566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 30969566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 309758b371f3SBarry Smith if (isdense) { 30989566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 309958b371f3SBarry Smith } else if (!ismf) { 31009566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 310158b371f3SBarry Smith } 310258b371f3SBarry Smith } 31033ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 310458b371f3SBarry Smith } 310558b371f3SBarry Smith 31069b94acceSBarry Smith /*@ 31079b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3108272ac6f2SLois Curfman McInnes of a nonlinear solver. 31099b94acceSBarry Smith 3110c3339decSBarry Smith Collective 3111fee21e36SBarry Smith 31122fe279fdSBarry Smith Input Parameter: 3113f6dfbefdSBarry Smith . snes - the `SNES` context 3114c7afd0dbSLois Curfman McInnes 3115dc4c0fb0SBarry Smith Level: advanced 3116dc4c0fb0SBarry Smith 3117f6dfbefdSBarry Smith Note: 3118f6dfbefdSBarry Smith For basic use of the `SNES` solvers the user need not explicitly call 3119f6dfbefdSBarry Smith `SNESSetUp()`, since these actions will automatically occur during 3120f6dfbefdSBarry Smith the call to `SNESSolve()`. However, if one wishes to control this 3121f6dfbefdSBarry Smith phase separately, `SNESSetUp()` should be called after `SNESCreate()` 3122f6dfbefdSBarry Smith and optional routines of the form SNESSetXXX(), but before `SNESSolve()`. 3123272ac6f2SLois Curfman McInnes 3124dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 31259b94acceSBarry Smith @*/ 3126d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp(SNES snes) 3127d71ae5a4SJacob Faibussowitsch { 31286cab3a1bSJed Brown DM dm; 3129942e3340SBarry Smith DMSNES sdm; 3130c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31316e2a1849SPeter Brune void *lsprectx, *lspostctx; 31329b5c1c08SStefano Zampini PetscBool mf_operator, mf; 31339b5c1c08SStefano Zampini Vec f, fpc; 31349b5c1c08SStefano Zampini void *funcctx; 31359b5c1c08SStefano Zampini void *jacctx, *appctx; 31369b5c1c08SStefano Zampini Mat j, jpre; 31376b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 31386b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 31396e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 3140d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 31413a40ed3dSBarry Smith 31423a40ed3dSBarry Smith PetscFunctionBegin; 31430700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 31443ba16761SJacob Faibussowitsch if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 3145fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0)); 31469b94acceSBarry Smith 314748a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 314885385478SLisandro Dalcin 31499566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 315058c9b817SLisandro Dalcin 31519566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31529566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 31539566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 315458b371f3SBarry Smith 315548a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3156efd51863SBarry Smith 315748a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3158b710008aSBarry Smith 3159d8d34be6SBarry Smith if (snes->linesearch) { 31609566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31619566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3162d8d34be6SBarry Smith } 31639e764e56SPeter Brune 31649b5c1c08SStefano Zampini PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf)); 3165b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3166172a4300SPeter Brune snes->mf = PETSC_TRUE; 3167172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3168172a4300SPeter Brune } 3169d8f46077SPeter Brune 3170efd4aadfSBarry Smith if (snes->npc) { 31716e2a1849SPeter Brune /* copy the DM over */ 31729566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31739566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 31746e2a1849SPeter Brune 31759566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 31769566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 31779566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 31789566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 31799566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 31809566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 31819566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 31829b5c1c08SStefano Zampini PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf)); 31839566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 31846e2a1849SPeter Brune 31856e2a1849SPeter Brune /* copy the function pointers over */ 31869566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 31876e2a1849SPeter Brune 31886e2a1849SPeter Brune /* default to 1 iteration */ 31899566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3190efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 31919566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3192a9936a0cSPeter Brune } else { 31939566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3194a9936a0cSPeter Brune } 31959566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 31966e2a1849SPeter Brune 31976e2a1849SPeter Brune /* copy the line search context over */ 3198d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 31999566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32009566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 32019566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 32029566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 32039566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 32049566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 32059566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 32066e2a1849SPeter Brune } 3207d8d34be6SBarry Smith } 32081baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 320948a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 32106e2a1849SPeter Brune 321137ec4e1aSPeter Brune snes->jac_iter = 0; 321237ec4e1aSPeter Brune snes->pre_iter = 0; 321337ec4e1aSPeter Brune 3214dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 321558c9b817SLisandro Dalcin 32169566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 321758b371f3SBarry Smith 3218b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 32196c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3220d8d34be6SBarry Smith if (snes->linesearch) { 32219566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32229566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 32236c67d002SPeter Brune } 32246c67d002SPeter Brune } 3225d8d34be6SBarry Smith } 3226fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0)); 32277aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32299b94acceSBarry Smith } 32309b94acceSBarry Smith 323137596af1SLisandro Dalcin /*@ 3232f6dfbefdSBarry Smith SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s 323337596af1SLisandro Dalcin 3234c3339decSBarry Smith Collective 323537596af1SLisandro Dalcin 323637596af1SLisandro Dalcin Input Parameter: 3237f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 323837596af1SLisandro Dalcin 3239d25893d9SBarry Smith Level: intermediate 3240d25893d9SBarry Smith 324195452b02SPatrick Sanan Notes: 3242f6dfbefdSBarry Smith Call this if you wish to reuse a `SNES` but with different size vectors 324337596af1SLisandro Dalcin 3244f6dfbefdSBarry Smith Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()` 3245f6dfbefdSBarry Smith 3246dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 324737596af1SLisandro Dalcin @*/ 3248d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset(SNES snes) 3249d71ae5a4SJacob Faibussowitsch { 325037596af1SLisandro Dalcin PetscFunctionBegin; 325137596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3252d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 32539566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 32540298fd71SBarry Smith snes->user = NULL; 3255d25893d9SBarry Smith } 32561baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 32578a23116dSBarry Smith 3258dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 32591baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 32609e764e56SPeter Brune 32611baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32629e764e56SPeter Brune 32639566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32649566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32659566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32669566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32679566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32689566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32699566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32709566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32719566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3272f5af7f23SKarl Rupp 327340fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 327440fdac6aSLawrence Mitchell 327537596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 327637596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 32773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 327837596af1SLisandro Dalcin } 327937596af1SLisandro Dalcin 328052baeb72SSatish Balay /*@ 3281f6dfbefdSBarry Smith SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object. 3282c4421ceaSFande Kong 3283c3339decSBarry Smith Collective 3284c4421ceaSFande Kong 3285c4421ceaSFande Kong Input Parameter: 3286f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 3287c4421ceaSFande Kong 3288c4421ceaSFande Kong Level: intermediate 3289c4421ceaSFande Kong 3290dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3291c4421ceaSFande Kong @*/ 3292d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3293d71ae5a4SJacob Faibussowitsch { 3294c4421ceaSFande Kong PetscInt i; 3295c4421ceaSFande Kong 3296c4421ceaSFande Kong PetscFunctionBegin; 3297c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3298c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 329948a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3300c4421ceaSFande Kong } 3301c4421ceaSFande Kong snes->numberreasonviews = 0; 33023ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3303c4421ceaSFande Kong } 3304c4421ceaSFande Kong 33051fb7b255SJunchao Zhang /*@C 33069b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 3307f6dfbefdSBarry Smith with `SNESCreate()`. 33089b94acceSBarry Smith 3309c3339decSBarry Smith Collective 3310c7afd0dbSLois Curfman McInnes 33119b94acceSBarry Smith Input Parameter: 3312f6dfbefdSBarry Smith . snes - the `SNES` context 33139b94acceSBarry Smith 331436851e7fSLois Curfman McInnes Level: beginner 331536851e7fSLois Curfman McInnes 3316dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSolve()` 33179b94acceSBarry Smith @*/ 3318d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy(SNES *snes) 3319d71ae5a4SJacob Faibussowitsch { 33203a40ed3dSBarry Smith PetscFunctionBegin; 33213ba16761SJacob Faibussowitsch if (!*snes) PetscFunctionReturn(PETSC_SUCCESS); 33226bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 33239371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 33249371c9d4SSatish Balay *snes = NULL; 33253ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33269371c9d4SSatish Balay } 3327d4bb536fSBarry Smith 33289566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 33299566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 33306b8b9a38SLisandro Dalcin 3331e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 33329566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3333dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 33346d4c513bSLisandro Dalcin 33359566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 33369566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 33379566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 33389566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 33396b8b9a38SLisandro Dalcin 33409566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 334148a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 334248a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 33439566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 33449566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 33459566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 33463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33479b94acceSBarry Smith } 33489b94acceSBarry Smith 33499b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 33509b94acceSBarry Smith 3351a8054027SBarry Smith /*@ 3352a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3353a8054027SBarry Smith 3354c3339decSBarry Smith Logically Collective 3355a8054027SBarry Smith 3356a8054027SBarry Smith Input Parameters: 3357f6dfbefdSBarry Smith + snes - the `SNES` context 3358d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 33593b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3360a8054027SBarry Smith 3361a8054027SBarry Smith Options Database Keys: 33623d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33633d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33643d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33653d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3366a8054027SBarry Smith 3367a8054027SBarry Smith Notes: 3368dc4c0fb0SBarry Smith Level: intermediate 3369dc4c0fb0SBarry Smith 3370a8054027SBarry Smith The default is 1 3371f6dfbefdSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called 3372d8e291bfSBarry Smith 3373f6dfbefdSBarry Smith `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves. 3374a8054027SBarry Smith 3375dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3376f6dfbefdSBarry Smith `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()` 3377a8054027SBarry Smith @*/ 3378d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) 3379d71ae5a4SJacob Faibussowitsch { 3380a8054027SBarry Smith PetscFunctionBegin; 33810700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 33825f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 33835f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3384c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3385a8054027SBarry Smith snes->lagpreconditioner = lag; 33863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3387a8054027SBarry Smith } 3388a8054027SBarry Smith 3389efd51863SBarry Smith /*@ 3390f6dfbefdSBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do 3391efd51863SBarry Smith 3392c3339decSBarry Smith Logically Collective 3393efd51863SBarry Smith 3394efd51863SBarry Smith Input Parameters: 3395f6dfbefdSBarry Smith + snes - the `SNES` context 3396efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3397efd51863SBarry Smith 3398f6dfbefdSBarry Smith Options Database Key: 339967b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3400efd51863SBarry Smith 3401efd51863SBarry Smith Level: intermediate 3402efd51863SBarry Smith 3403f6dfbefdSBarry Smith Note: 3404f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3405c0df2a02SJed Brown 3406dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3407efd51863SBarry Smith @*/ 3408d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) 3409d71ae5a4SJacob Faibussowitsch { 3410efd51863SBarry Smith PetscFunctionBegin; 3411efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3412efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3413efd51863SBarry Smith snes->gridsequence = steps; 34143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3415efd51863SBarry Smith } 3416efd51863SBarry Smith 3417fa19ca70SBarry Smith /*@ 3418f6dfbefdSBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do 3419fa19ca70SBarry Smith 3420c3339decSBarry Smith Logically Collective 3421fa19ca70SBarry Smith 3422fa19ca70SBarry Smith Input Parameter: 3423f6dfbefdSBarry Smith . snes - the `SNES` context 3424fa19ca70SBarry Smith 3425fa19ca70SBarry Smith Output Parameter: 3426fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3427fa19ca70SBarry Smith 3428f6dfbefdSBarry Smith Options Database Key: 342967b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3430fa19ca70SBarry Smith 3431fa19ca70SBarry Smith Level: intermediate 3432fa19ca70SBarry Smith 3433f6dfbefdSBarry Smith Note: 3434f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3435fa19ca70SBarry Smith 3436dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3437fa19ca70SBarry Smith @*/ 3438d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) 3439d71ae5a4SJacob Faibussowitsch { 3440fa19ca70SBarry Smith PetscFunctionBegin; 3441fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3442fa19ca70SBarry Smith *steps = snes->gridsequence; 34433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3444fa19ca70SBarry Smith } 3445fa19ca70SBarry Smith 3446a8054027SBarry Smith /*@ 3447f6dfbefdSBarry Smith SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt 3448a8054027SBarry Smith 34493f9fe445SBarry Smith Not Collective 3450a8054027SBarry Smith 3451a8054027SBarry Smith Input Parameter: 3452f6dfbefdSBarry Smith . snes - the `SNES` context 3453a8054027SBarry Smith 3454a8054027SBarry Smith Output Parameter: 3455a8054027SBarry 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 34563b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3457a8054027SBarry Smith 3458a8054027SBarry Smith Options Database Keys: 34593d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34603d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34613d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34623d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3463a8054027SBarry Smith 3464dc4c0fb0SBarry Smith Level: intermediate 3465dc4c0fb0SBarry Smith 3466a8054027SBarry Smith Notes: 3467a8054027SBarry Smith The default is 1 3468f6dfbefdSBarry Smith 3469a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3470a8054027SBarry Smith 3471dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3472a8054027SBarry Smith @*/ 3473d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) 3474d71ae5a4SJacob Faibussowitsch { 3475a8054027SBarry Smith PetscFunctionBegin; 34760700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3477a8054027SBarry Smith *lag = snes->lagpreconditioner; 34783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3479a8054027SBarry Smith } 3480a8054027SBarry Smith 3481e35cf81dSBarry Smith /*@ 3482f6dfbefdSBarry Smith SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how 3483e35cf81dSBarry Smith often the preconditioner is rebuilt. 3484e35cf81dSBarry Smith 3485c3339decSBarry Smith Logically Collective 3486e35cf81dSBarry Smith 3487e35cf81dSBarry Smith Input Parameters: 3488f6dfbefdSBarry Smith + snes - the `SNES` context 3489e35cf81dSBarry 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 3490fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3491e35cf81dSBarry Smith 3492e35cf81dSBarry Smith Options Database Keys: 34933d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34943d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34953d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34963d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3497e35cf81dSBarry Smith 3498dc4c0fb0SBarry Smith Level: intermediate 3499dc4c0fb0SBarry Smith 3500e35cf81dSBarry Smith Notes: 3501e35cf81dSBarry Smith The default is 1 3502f6dfbefdSBarry Smith 3503e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3504f6dfbefdSBarry Smith 3505fe3ffe1eSBarry 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 3506fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3507e35cf81dSBarry Smith 3508dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3509e35cf81dSBarry Smith @*/ 3510d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) 3511d71ae5a4SJacob Faibussowitsch { 3512e35cf81dSBarry Smith PetscFunctionBegin; 35130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 35145f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 35155f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3516c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3517e35cf81dSBarry Smith snes->lagjacobian = lag; 35183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3519e35cf81dSBarry Smith } 3520e35cf81dSBarry Smith 3521e35cf81dSBarry Smith /*@ 3522f6dfbefdSBarry Smith SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt 3523e35cf81dSBarry Smith 35243f9fe445SBarry Smith Not Collective 3525e35cf81dSBarry Smith 3526e35cf81dSBarry Smith Input Parameter: 3527f6dfbefdSBarry Smith . snes - the `SNES` context 3528e35cf81dSBarry Smith 3529e35cf81dSBarry Smith Output Parameter: 3530e35cf81dSBarry 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 3531e35cf81dSBarry Smith the Jacobian is built etc. 3532e35cf81dSBarry Smith 3533dc4c0fb0SBarry Smith Level: intermediate 3534dc4c0fb0SBarry Smith 3535e35cf81dSBarry Smith Notes: 3536e35cf81dSBarry Smith The default is 1 3537f6dfbefdSBarry Smith 3538f6dfbefdSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called. 3539e35cf81dSBarry Smith 3540dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3541e35cf81dSBarry Smith 3542e35cf81dSBarry Smith @*/ 3543d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) 3544d71ae5a4SJacob Faibussowitsch { 3545e35cf81dSBarry Smith PetscFunctionBegin; 35460700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3547e35cf81dSBarry Smith *lag = snes->lagjacobian; 35483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3549e35cf81dSBarry Smith } 3550e35cf81dSBarry Smith 355137ec4e1aSPeter Brune /*@ 3552f6dfbefdSBarry Smith SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves 355337ec4e1aSPeter Brune 3554c3339decSBarry Smith Logically collective 355537ec4e1aSPeter Brune 3556d8d19677SJose E. Roman Input Parameters: 3557f6dfbefdSBarry Smith + snes - the `SNES` context 35589d7e2deaSPeter Brune - flg - jacobian lagging persists if true 355937ec4e1aSPeter Brune 356037ec4e1aSPeter Brune Options Database Keys: 35613d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35623d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35633d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35643d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35653d5a8a6aSBarry Smith 3566dc4c0fb0SBarry Smith Level: advanced 3567dc4c0fb0SBarry Smith 356895452b02SPatrick Sanan Notes: 3569f6dfbefdSBarry Smith Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3570f6dfbefdSBarry Smith 357195452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 357237ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 357337ec4e1aSPeter Brune timesteps may present huge efficiency gains. 357437ec4e1aSPeter Brune 3575dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 357637ec4e1aSPeter Brune @*/ 3577d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) 3578d71ae5a4SJacob Faibussowitsch { 357937ec4e1aSPeter Brune PetscFunctionBegin; 358037ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 358137ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 358237ec4e1aSPeter Brune snes->lagjac_persist = flg; 35833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 358437ec4e1aSPeter Brune } 358537ec4e1aSPeter Brune 358637ec4e1aSPeter Brune /*@ 3587d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 358837ec4e1aSPeter Brune 3589c3339decSBarry Smith Logically Collective 359037ec4e1aSPeter Brune 3591d8d19677SJose E. Roman Input Parameters: 3592f6dfbefdSBarry Smith + snes - the `SNES` context 35939d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 359437ec4e1aSPeter Brune 359537ec4e1aSPeter Brune Options Database Keys: 35963d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35973d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35983d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35993d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 360037ec4e1aSPeter Brune 3601dc4c0fb0SBarry Smith Level: developer 3602dc4c0fb0SBarry Smith 360395452b02SPatrick Sanan Notes: 3604f6dfbefdSBarry Smith Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3605f6dfbefdSBarry Smith 360695452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 360737ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 360837ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 360937ec4e1aSPeter Brune 3610dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 361137ec4e1aSPeter Brune @*/ 3612d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) 3613d71ae5a4SJacob Faibussowitsch { 361437ec4e1aSPeter Brune PetscFunctionBegin; 361537ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 361637ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 361737ec4e1aSPeter Brune snes->lagpre_persist = flg; 36183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 361937ec4e1aSPeter Brune } 362037ec4e1aSPeter Brune 36219b94acceSBarry Smith /*@ 3622f6dfbefdSBarry Smith SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm 3623be5caee7SBarry Smith 3624c3339decSBarry Smith Logically Collective 3625be5caee7SBarry Smith 3626be5caee7SBarry Smith Input Parameters: 3627f6dfbefdSBarry Smith + snes - the `SNES` context 3628f6dfbefdSBarry Smith - force - `PETSC_TRUE` require at least one iteration 3629be5caee7SBarry Smith 3630f6dfbefdSBarry Smith Options Database Key: 3631be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3632be5caee7SBarry Smith 3633dc4c0fb0SBarry Smith Level: intermediate 3634dc4c0fb0SBarry Smith 3635f6dfbefdSBarry Smith Note: 3636f6dfbefdSBarry Smith This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution 3637be5caee7SBarry Smith 3638dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3639be5caee7SBarry Smith @*/ 3640d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) 3641d71ae5a4SJacob Faibussowitsch { 3642be5caee7SBarry Smith PetscFunctionBegin; 3643be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3644be5caee7SBarry Smith snes->forceiteration = force; 36453ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3646be5caee7SBarry Smith } 3647be5caee7SBarry Smith 364885216dc7SFande Kong /*@ 3649f6dfbefdSBarry Smith SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm 365085216dc7SFande Kong 3651c3339decSBarry Smith Logically Collective 365285216dc7SFande Kong 36532fe279fdSBarry Smith Input Parameter: 3654f6dfbefdSBarry Smith . snes - the `SNES` context 365585216dc7SFande Kong 365685216dc7SFande Kong Output Parameter: 3657dc4c0fb0SBarry Smith . force - `PETSC_TRUE` requires at least one iteration. 365885216dc7SFande Kong 365906dd6b0eSSatish Balay Level: intermediate 366006dd6b0eSSatish Balay 3661dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 366285216dc7SFande Kong @*/ 3663d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) 3664d71ae5a4SJacob Faibussowitsch { 366585216dc7SFande Kong PetscFunctionBegin; 366685216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 366785216dc7SFande Kong *force = snes->forceiteration; 36683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 366985216dc7SFande Kong } 3670be5caee7SBarry Smith 3671be5caee7SBarry Smith /*@ 3672f6dfbefdSBarry Smith SNESSetTolerances - Sets `SNES` various parameters used in convergence tests. 36739b94acceSBarry Smith 3674c3339decSBarry Smith Logically Collective 3675c7afd0dbSLois Curfman McInnes 36769b94acceSBarry Smith Input Parameters: 3677f6dfbefdSBarry Smith + snes - the `SNES` context 367870441072SBarry Smith . abstol - absolute convergence tolerance 367933174efeSLois Curfman McInnes . rtol - relative convergence tolerance 36805358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3681f6dfbefdSBarry Smith . maxit - maximum number of iterations, default 50. 3682f6dfbefdSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit), default 1000 3683fee21e36SBarry Smith 368433174efeSLois Curfman McInnes Options Database Keys: 368570441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3686c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3687c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3688c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3689c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 36909b94acceSBarry Smith 369136851e7fSLois Curfman McInnes Level: intermediate 369236851e7fSLois Curfman McInnes 3693dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 36949b94acceSBarry Smith @*/ 3695d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) 3696d71ae5a4SJacob Faibussowitsch { 36973a40ed3dSBarry Smith PetscFunctionBegin; 36980700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3699c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3700c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3701c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3702c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3703c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3704c5eb9154SBarry Smith 370513bcc0bdSJacob Faibussowitsch if (abstol != (PetscReal)PETSC_DEFAULT) { 37065f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3707ab54825eSJed Brown snes->abstol = abstol; 3708ab54825eSJed Brown } 370913bcc0bdSJacob Faibussowitsch if (rtol != (PetscReal)PETSC_DEFAULT) { 37105f80ce2aSJacob 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); 3711ab54825eSJed Brown snes->rtol = rtol; 3712ab54825eSJed Brown } 371313bcc0bdSJacob Faibussowitsch if (stol != (PetscReal)PETSC_DEFAULT) { 37145f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3715c60f73f4SPeter Brune snes->stol = stol; 3716ab54825eSJed Brown } 3717ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 371863a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3719ab54825eSJed Brown snes->max_its = maxit; 3720ab54825eSJed Brown } 3721ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 372263a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3723ab54825eSJed Brown snes->max_funcs = maxf; 3724ab54825eSJed Brown } 372588976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 37263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37279b94acceSBarry Smith } 37289b94acceSBarry Smith 3729e4d06f11SPatrick Farrell /*@ 3730f6dfbefdSBarry Smith SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test. 3731e4d06f11SPatrick Farrell 3732c3339decSBarry Smith Logically Collective 3733e4d06f11SPatrick Farrell 3734e4d06f11SPatrick Farrell Input Parameters: 3735f6dfbefdSBarry Smith + snes - the `SNES` context 3736f6dfbefdSBarry Smith - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4 3737e4d06f11SPatrick Farrell 3738f6dfbefdSBarry Smith Options Database Key: 3739dc4c0fb0SBarry Smith . -snes_divergence_tolerance <divtol> - Sets `divtol` 3740e4d06f11SPatrick Farrell 3741e4d06f11SPatrick Farrell Level: intermediate 3742e4d06f11SPatrick Farrell 3743dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3744e4d06f11SPatrick Farrell @*/ 3745d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) 3746d71ae5a4SJacob Faibussowitsch { 3747e4d06f11SPatrick Farrell PetscFunctionBegin; 3748e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3749e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3750e4d06f11SPatrick Farrell 375113bcc0bdSJacob Faibussowitsch if (divtol != (PetscReal)PETSC_DEFAULT) { 3752e4d06f11SPatrick Farrell snes->divtol = divtol; 37539371c9d4SSatish Balay } else { 3754e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3755e4d06f11SPatrick Farrell } 37563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3757e4d06f11SPatrick Farrell } 3758e4d06f11SPatrick Farrell 37599b94acceSBarry Smith /*@ 376033174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 376133174efeSLois Curfman McInnes 3762c7afd0dbSLois Curfman McInnes Not Collective 3763c7afd0dbSLois Curfman McInnes 376433174efeSLois Curfman McInnes Input Parameters: 3765f6dfbefdSBarry Smith + snes - the `SNES` context 376685385478SLisandro Dalcin . atol - absolute convergence tolerance 376733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 376833174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 376933174efeSLois Curfman McInnes of the change in the solution between steps 377033174efeSLois Curfman McInnes . maxit - maximum number of iterations 3771c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3772fee21e36SBarry Smith 377336851e7fSLois Curfman McInnes Level: intermediate 377436851e7fSLois Curfman McInnes 3775dc4c0fb0SBarry Smith Note: 3776dc4c0fb0SBarry Smith The user can specify `NULL` for any parameter that is not needed. 3777dc4c0fb0SBarry Smith 3778dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTolerances()` 377933174efeSLois Curfman McInnes @*/ 3780d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) 3781d71ae5a4SJacob Faibussowitsch { 37823a40ed3dSBarry Smith PetscFunctionBegin; 37830700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 378485385478SLisandro Dalcin if (atol) *atol = snes->abstol; 378533174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3786c60f73f4SPeter Brune if (stol) *stol = snes->stol; 378733174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 378833174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 37893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379033174efeSLois Curfman McInnes } 379133174efeSLois Curfman McInnes 3792e4d06f11SPatrick Farrell /*@ 3793e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3794e4d06f11SPatrick Farrell 3795e4d06f11SPatrick Farrell Not Collective 3796e4d06f11SPatrick Farrell 3797e4d06f11SPatrick Farrell Input Parameters: 3798f6dfbefdSBarry Smith + snes - the `SNES` context 3799e4d06f11SPatrick Farrell - divtol - divergence tolerance 3800e4d06f11SPatrick Farrell 3801e4d06f11SPatrick Farrell Level: intermediate 3802e4d06f11SPatrick Farrell 3803dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetDivergenceTolerance()` 3804e4d06f11SPatrick Farrell @*/ 3805d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) 3806d71ae5a4SJacob Faibussowitsch { 3807e4d06f11SPatrick Farrell PetscFunctionBegin; 3808e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3809e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 38103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3811e4d06f11SPatrick Farrell } 3812e4d06f11SPatrick Farrell 381333174efeSLois Curfman McInnes /*@ 38149b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 38159b94acceSBarry Smith 3816c3339decSBarry Smith Logically Collective 3817fee21e36SBarry Smith 3818c7afd0dbSLois Curfman McInnes Input Parameters: 3819f6dfbefdSBarry Smith + snes - the `SNES` context 3820c7afd0dbSLois Curfman McInnes - tol - tolerance 3821c7afd0dbSLois Curfman McInnes 38229b94acceSBarry Smith Options Database Key: 38234a221d59SStefano Zampini . -snes_tr_tol <tol> - Sets tol 38249b94acceSBarry Smith 382536851e7fSLois Curfman McInnes Level: intermediate 382636851e7fSLois Curfman McInnes 38274a221d59SStefano Zampini .seealso: [](chapter_snes), `SNES`, `SNESNEWTONTR`, `SNESSetTolerances()` 38289b94acceSBarry Smith @*/ 3829d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) 3830d71ae5a4SJacob Faibussowitsch { 38313a40ed3dSBarry Smith PetscFunctionBegin; 38320700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3833c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 38349b94acceSBarry Smith snes->deltatol = tol; 38353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38369b94acceSBarry Smith } 38379b94acceSBarry Smith 38386ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 38396ba87a44SLisandro Dalcin 3840d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) 3841d71ae5a4SJacob Faibussowitsch { 3842b271bb04SBarry Smith PetscDrawLG lg; 3843b271bb04SBarry Smith PetscReal x, y, per; 3844b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3845b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3846b271bb04SBarry Smith PetscDraw draw; 3847b271bb04SBarry Smith 3848459f5d12SBarry Smith PetscFunctionBegin; 38494d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 38509566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 38519566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38529566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38539566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3854b271bb04SBarry Smith x = (PetscReal)n; 385577b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 385694c9c6d3SKarl Rupp else y = -15.0; 38579566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38586934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38599566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38609566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3861b271bb04SBarry Smith } 3862b271bb04SBarry Smith 38639566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 38649566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38659566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 3866aaa8cc7dSPierre Jolivet PetscCall(PetscDrawSetTitle(draw, "% elements > .2*max element")); 38679566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3868b271bb04SBarry Smith x = (PetscReal)n; 3869b271bb04SBarry Smith y = 100.0 * per; 38709566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38716934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38729566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38739566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3874b271bb04SBarry Smith } 3875b271bb04SBarry Smith 38769566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 38779371c9d4SSatish Balay if (!n) { 38789371c9d4SSatish Balay prev = rnorm; 38799371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 38809371c9d4SSatish Balay } 38819566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38829566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3883b271bb04SBarry Smith x = (PetscReal)n; 3884b271bb04SBarry Smith y = (prev - rnorm) / prev; 38859566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38866934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38879566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38889566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3889b271bb04SBarry Smith } 3890b271bb04SBarry Smith 38919566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 38929566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38939566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38949566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3895b271bb04SBarry Smith x = (PetscReal)n; 3896b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3897b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 38989566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3899b271bb04SBarry Smith } 39006934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39019566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39029566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3903b271bb04SBarry Smith } 3904b271bb04SBarry Smith prev = rnorm; 39053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3906b271bb04SBarry Smith } 3907b271bb04SBarry Smith 3908228d79bcSJed Brown /*@ 3909228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3910228d79bcSJed Brown 3911c3339decSBarry Smith Collective 3912228d79bcSJed Brown 3913228d79bcSJed Brown Input Parameters: 3914f6dfbefdSBarry Smith + snes - nonlinear solver context obtained from `SNESCreate()` 3915228d79bcSJed Brown . iter - iteration number 3916228d79bcSJed Brown - rnorm - relative norm of the residual 3917228d79bcSJed Brown 3918dc4c0fb0SBarry Smith Level: developer 3919dc4c0fb0SBarry Smith 3920f6dfbefdSBarry Smith Note: 3921f6dfbefdSBarry Smith This routine is called by the `SNES` implementations. 3922228d79bcSJed Brown It does not typically need to be called by the user. 3923228d79bcSJed Brown 3924dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()` 3925228d79bcSJed Brown @*/ 3926d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) 3927d71ae5a4SJacob Faibussowitsch { 39287a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 39297a03ce2fSLisandro Dalcin 39307a03ce2fSLisandro Dalcin PetscFunctionBegin; 39319566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 393248a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 39339566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 39343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39357a03ce2fSLisandro Dalcin } 39367a03ce2fSLisandro Dalcin 39379b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 39389b94acceSBarry Smith 3939bf388a1fSBarry Smith /*MC 3940f6dfbefdSBarry Smith SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver 3941bf388a1fSBarry Smith 3942bf388a1fSBarry Smith Synopsis: 3943aaa7dc30SBarry Smith #include <petscsnes.h> 3944bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3945bf388a1fSBarry Smith 3946c3339decSBarry Smith Collective 39471843f636SBarry Smith 39481843f636SBarry Smith Input Parameters: 3949f6dfbefdSBarry Smith + snes - the `SNES` context 3950bf388a1fSBarry Smith . its - iteration number 3951bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3952bf388a1fSBarry Smith - mctx - [optional] monitoring context 3953bf388a1fSBarry Smith 3954878cb397SSatish Balay Level: advanced 3955878cb397SSatish Balay 3956dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()` 3957bf388a1fSBarry Smith M*/ 3958bf388a1fSBarry Smith 39599b94acceSBarry Smith /*@C 3960a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 39619b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 39629b94acceSBarry Smith progress. 39639b94acceSBarry Smith 3964c3339decSBarry Smith Logically Collective 3965fee21e36SBarry Smith 3966c7afd0dbSLois Curfman McInnes Input Parameters: 3967f6dfbefdSBarry Smith + snes - the `SNES` context 396820f4b53cSBarry Smith . f - the monitor function, for the calling sequence see `SNESMonitorFunction` 3969b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3970dc4c0fb0SBarry Smith monitor routine (use `NULL` if no context is desired) 3971dc4c0fb0SBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 39729b94acceSBarry Smith 39739665c990SLois Curfman McInnes Options Database Keys: 3974f6dfbefdSBarry Smith + -snes_monitor - sets `SNESMonitorDefault()` 3975798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 3976dc4c0fb0SBarry 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 3977c7afd0dbSLois Curfman McInnes the options database. 39789665c990SLois Curfman McInnes 3979dc4c0fb0SBarry Smith Level: intermediate 3980dc4c0fb0SBarry Smith 3981f6dfbefdSBarry Smith Note: 39826bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3983f6dfbefdSBarry Smith `SNESMonitorSet()` multiple times; all will be called in the 39846bc08f3fSLois Curfman McInnes order in which they were set. 3985639f9d9dSBarry Smith 3986f6dfbefdSBarry Smith Fortran Note: 3987f6dfbefdSBarry Smith Only a single monitor function can be set for each `SNES` object 3988025f1a04SBarry Smith 3989dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 39909b94acceSBarry Smith @*/ 3991d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 3992d71ae5a4SJacob Faibussowitsch { 3993b90d0a6eSBarry Smith PetscInt i; 399478064530SBarry Smith PetscBool identical; 3995b90d0a6eSBarry Smith 39963a40ed3dSBarry Smith PetscFunctionBegin; 39970700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3998b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 39999566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 40003ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4001649052a6SBarry Smith } 40025f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 40036e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4004b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4005639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 40063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40079b94acceSBarry Smith } 40089b94acceSBarry Smith 4009a278d85bSSatish Balay /*@ 4010f6dfbefdSBarry Smith SNESMonitorCancel - Clears all the monitor functions for a `SNES` object. 40115cd90555SBarry Smith 4012c3339decSBarry Smith Logically Collective 4013c7afd0dbSLois Curfman McInnes 40142fe279fdSBarry Smith Input Parameter: 4015f6dfbefdSBarry Smith . snes - the `SNES` context 40165cd90555SBarry Smith 40171a480d89SAdministrator Options Database Key: 4018a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4019dc4c0fb0SBarry Smith into a code by calls to `SNESMonitorSet()`, but does not cancel those 4020c7afd0dbSLois Curfman McInnes set via the options database 40215cd90555SBarry Smith 4022dc4c0fb0SBarry Smith Level: intermediate 4023dc4c0fb0SBarry Smith 4024f6dfbefdSBarry Smith Note: 4025f6dfbefdSBarry Smith There is no way to clear one specific monitor from a `SNES` object. 40265cd90555SBarry Smith 4027dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()` 40285cd90555SBarry Smith @*/ 4029d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorCancel(SNES snes) 4030d71ae5a4SJacob Faibussowitsch { 4031d952e501SBarry Smith PetscInt i; 4032d952e501SBarry Smith 40335cd90555SBarry Smith PetscFunctionBegin; 40340700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4035d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 403648a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4037d952e501SBarry Smith } 40385cd90555SBarry Smith snes->numbermonitors = 0; 40393ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40405cd90555SBarry Smith } 40415cd90555SBarry Smith 4042bf388a1fSBarry Smith /*MC 4043bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4044bf388a1fSBarry Smith 4045bf388a1fSBarry Smith Synopsis: 4046aaa7dc30SBarry Smith #include <petscsnes.h> 4047bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4048bf388a1fSBarry Smith 4049c3339decSBarry Smith Collective 40501843f636SBarry Smith 40511843f636SBarry Smith Input Parameters: 4052f6dfbefdSBarry Smith + snes - the `SNES` context 4053bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4054bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4055bf388a1fSBarry Smith . gnorm - 2-norm of current step 40561843f636SBarry Smith . f - 2-norm of function 40571843f636SBarry Smith - cctx - [optional] convergence context 40581843f636SBarry Smith 40591843f636SBarry Smith Output Parameter: 40601843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4061bf388a1fSBarry Smith 4062878cb397SSatish Balay Level: intermediate 4063bf388a1fSBarry Smith 4064dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4065bf388a1fSBarry Smith M*/ 4066bf388a1fSBarry Smith 40679b94acceSBarry Smith /*@C 40689b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40699b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40709b94acceSBarry Smith 4071c3339decSBarry Smith Logically Collective 4072fee21e36SBarry Smith 4073c7afd0dbSLois Curfman McInnes Input Parameters: 4074f6dfbefdSBarry Smith + snes - the `SNES` context 4075f6dfbefdSBarry Smith . `SNESConvergenceTestFunction` - routine to test for convergence 4076dc4c0fb0SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be `NULL`) 4077dc4c0fb0SBarry Smith - destroy - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran) 40789b94acceSBarry Smith 407936851e7fSLois Curfman McInnes Level: advanced 408036851e7fSLois Curfman McInnes 4081dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 40829b94acceSBarry Smith @*/ 4083d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) 4084d71ae5a4SJacob Faibussowitsch { 40853a40ed3dSBarry Smith PetscFunctionBegin; 40860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4087e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 40881baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4089bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 40907f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 409185385478SLisandro Dalcin snes->cnvP = cctx; 40923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40939b94acceSBarry Smith } 40949b94acceSBarry Smith 409552baeb72SSatish Balay /*@ 4096f6dfbefdSBarry Smith SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped. 4097184914b5SBarry Smith 4098184914b5SBarry Smith Not Collective 4099184914b5SBarry Smith 4100184914b5SBarry Smith Input Parameter: 4101f6dfbefdSBarry Smith . snes - the `SNES` context 4102184914b5SBarry Smith 4103184914b5SBarry Smith Output Parameter: 4104f6dfbefdSBarry Smith . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists 4105184914b5SBarry Smith 4106f6dfbefdSBarry Smith Options Database Key: 41076a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 41086a4d7782SBarry Smith 4109184914b5SBarry Smith Level: intermediate 4110184914b5SBarry Smith 4111f6dfbefdSBarry Smith Note: 4112f6dfbefdSBarry Smith Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`. 4113184914b5SBarry Smith 4114dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()` 4115184914b5SBarry Smith @*/ 4116d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) 4117d71ae5a4SJacob Faibussowitsch { 4118184914b5SBarry Smith PetscFunctionBegin; 41190700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41204482741eSBarry Smith PetscValidPointer(reason, 2); 4121184914b5SBarry Smith *reason = snes->reason; 41223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4123184914b5SBarry Smith } 4124184914b5SBarry Smith 4125c4421ceaSFande Kong /*@C 4126f6dfbefdSBarry Smith SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason` 4127c4421ceaSFande Kong 4128c4421ceaSFande Kong Not Collective 4129c4421ceaSFande Kong 4130c4421ceaSFande Kong Input Parameter: 4131f6dfbefdSBarry Smith . snes - the `SNES` context 4132c4421ceaSFande Kong 4133c4421ceaSFande Kong Output Parameter: 4134dc4c0fb0SBarry Smith . strreason - a human readable string that describes `SNES` converged reason 4135c4421ceaSFande Kong 413699c90e12SSatish Balay Level: beginner 4137c4421ceaSFande Kong 4138dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetConvergedReason()` 4139c4421ceaSFande Kong @*/ 4140d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) 4141d71ae5a4SJacob Faibussowitsch { 4142c4421ceaSFande Kong PetscFunctionBegin; 4143c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4144dadcf809SJacob Faibussowitsch PetscValidPointer(strreason, 2); 4145c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 41463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4147c4421ceaSFande Kong } 4148c4421ceaSFande Kong 414933866048SMatthew G. Knepley /*@ 4150f6dfbefdSBarry Smith SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped. 415133866048SMatthew G. Knepley 415233866048SMatthew G. Knepley Not Collective 415333866048SMatthew G. Knepley 415433866048SMatthew G. Knepley Input Parameters: 4155f6dfbefdSBarry Smith + snes - the `SNES` context 4156f6dfbefdSBarry Smith - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the 415733866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 415833866048SMatthew G. Knepley 4159f6dfbefdSBarry Smith Level: developer 4160f6dfbefdSBarry Smith 4161f6dfbefdSBarry Smith Developer Note: 4162f6dfbefdSBarry Smith Called inside the various `SNESSolve()` implementations 416333866048SMatthew G. Knepley 4164dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 416533866048SMatthew G. Knepley @*/ 4166d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) 4167d71ae5a4SJacob Faibussowitsch { 416833866048SMatthew G. Knepley PetscFunctionBegin; 416933866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 417033866048SMatthew G. Knepley snes->reason = reason; 41713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 417233866048SMatthew G. Knepley } 417333866048SMatthew G. Knepley 4174c9005455SLois Curfman McInnes /*@ 4175c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4176c9005455SLois Curfman McInnes 4177c3339decSBarry Smith Logically Collective 4178fee21e36SBarry Smith 4179c7afd0dbSLois Curfman McInnes Input Parameters: 4180f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 41818c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4182cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4183758f92a0SBarry Smith . na - size of a and its 4184f6dfbefdSBarry Smith - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero, 4185758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4186c7afd0dbSLois Curfman McInnes 4187dc4c0fb0SBarry Smith Level: intermediate 4188dc4c0fb0SBarry Smith 4189308dcc3eSBarry Smith Notes: 4190dc4c0fb0SBarry Smith If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a 4191308dcc3eSBarry Smith default array of length 10000 is allocated. 4192308dcc3eSBarry Smith 4193c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4194c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4195c9005455SLois Curfman McInnes during the section of code that is being timed. 4196c9005455SLois Curfman McInnes 4197dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()` 4198c9005455SLois Curfman McInnes @*/ 4199d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) 4200d71ae5a4SJacob Faibussowitsch { 42013a40ed3dSBarry Smith PetscFunctionBegin; 42020700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4203064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a, 2); 4204a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its, 3); 42057a1ec6d4SBarry Smith if (!a) { 4206308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 42079566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4208071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4209308dcc3eSBarry Smith } 4210c9005455SLois Curfman McInnes snes->conv_hist = a; 4211758f92a0SBarry Smith snes->conv_hist_its = its; 4212115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4213a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4214758f92a0SBarry Smith snes->conv_hist_reset = reset; 42153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4216758f92a0SBarry Smith } 4217758f92a0SBarry Smith 4218d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB) 4219c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4220c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 422199e0435eSBarry Smith 4222d71ae5a4SJacob Faibussowitsch PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4223d71ae5a4SJacob Faibussowitsch { 4224308dcc3eSBarry Smith mxArray *mat; 4225308dcc3eSBarry Smith PetscInt i; 4226308dcc3eSBarry Smith PetscReal *ar; 4227308dcc3eSBarry Smith 4228308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4229308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4230f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 423111cc89d2SBarry Smith return mat; 4232308dcc3eSBarry Smith } 4233308dcc3eSBarry Smith #endif 4234308dcc3eSBarry Smith 42350c4c9dddSBarry Smith /*@C 4236758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4237758f92a0SBarry Smith 42383f9fe445SBarry Smith Not Collective 4239758f92a0SBarry Smith 4240758f92a0SBarry Smith Input Parameter: 4241f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 4242758f92a0SBarry Smith 4243758f92a0SBarry Smith Output Parameters: 4244f6dfbefdSBarry Smith + a - array to hold history, usually was set with `SNESSetConvergenceHistory()` 4245758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4246758f92a0SBarry Smith negative if not converged) for each solve. 424720f4b53cSBarry Smith - na - size of `a` and `its` 4248758f92a0SBarry Smith 4249dc4c0fb0SBarry Smith Level: intermediate 4250dc4c0fb0SBarry Smith 425120f4b53cSBarry Smith Note: 425220f4b53cSBarry Smith This routine is useful, e.g., when running a code for purposes 425320f4b53cSBarry Smith of accurate performance monitoring, when no I/O should be done 425420f4b53cSBarry Smith during the section of code that is being timed. 425520f4b53cSBarry Smith 425620f4b53cSBarry Smith Fortran Note: 4257758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4258dc4c0fb0SBarry Smith .vb 4259dc4c0fb0SBarry Smith call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4260dc4c0fb0SBarry Smith .ve 4261758f92a0SBarry Smith 4262dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()` 4263758f92a0SBarry Smith @*/ 4264d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) 4265d71ae5a4SJacob Faibussowitsch { 4266758f92a0SBarry Smith PetscFunctionBegin; 42670700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4268758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4269758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4270115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 42713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4272c9005455SLois Curfman McInnes } 4273c9005455SLois Curfman McInnes 4274ac226902SBarry Smith /*@C 427576b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4276eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 42777e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 427876b2cf59SMatthew Knepley 4279c3339decSBarry Smith Logically Collective 428076b2cf59SMatthew Knepley 428176b2cf59SMatthew Knepley Input Parameters: 4282a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4283a2b725a8SWilliam Gropp - func - The function 428476b2cf59SMatthew Knepley 428520f4b53cSBarry Smith Calling sequence of `func`: 428620f4b53cSBarry Smith $ PetscErrorCode func(SNES snes, PetscInt step); 428720f4b53cSBarry Smith + snes - the nonlinear solver context 428820f4b53cSBarry Smith - step - The current step of the iteration 428976b2cf59SMatthew Knepley 4290fe97e370SBarry Smith Level: advanced 4291fe97e370SBarry Smith 42926b7fb656SBarry Smith Note: 4293f6dfbefdSBarry 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 4294f6dfbefdSBarry Smith to `SNESSetFunction()`, or `SNESSetPicard()` 4295fe97e370SBarry Smith This is not used by most users. 429676b2cf59SMatthew Knepley 4297aaa8cc7dSPierre Jolivet There are a variety of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 42986b7fb656SBarry Smith 4299dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4300db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 430176b2cf59SMatthew Knepley @*/ 4302d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4303d71ae5a4SJacob Faibussowitsch { 430476b2cf59SMatthew Knepley PetscFunctionBegin; 43050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4306e7788613SBarry Smith snes->ops->update = func; 43073ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 430876b2cf59SMatthew Knepley } 430976b2cf59SMatthew Knepley 43109b94acceSBarry Smith /* 43119b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 43129b94acceSBarry Smith positive parameter delta. 43139b94acceSBarry Smith 43149b94acceSBarry Smith Input Parameters: 4315f6dfbefdSBarry Smith + snes - the `SNES` context 43169b94acceSBarry Smith . y - approximate solution of linear system 43179b94acceSBarry Smith . fnorm - 2-norm of current function 4318c7afd0dbSLois Curfman McInnes - delta - trust region size 43199b94acceSBarry Smith 43209b94acceSBarry Smith Output Parameters: 4321c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 43229b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 43239b94acceSBarry Smith region, and exceeds zero otherwise. 4324c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 43259b94acceSBarry Smith 4326f6dfbefdSBarry Smith Level: developer 43279b94acceSBarry Smith 4328f6dfbefdSBarry Smith Note: 4329f6dfbefdSBarry Smith For non-trust region methods such as `SNESNEWTONLS`, the parameter delta 4330f6dfbefdSBarry Smith is set to be the maximum allowable step size. 43319b94acceSBarry Smith */ 4332d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm) 4333d71ae5a4SJacob Faibussowitsch { 4334064f8208SBarry Smith PetscReal nrm; 4335ea709b57SSatish Balay PetscScalar cnorm; 43363a40ed3dSBarry Smith 43373a40ed3dSBarry Smith PetscFunctionBegin; 43380700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 43390700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 2); 4340c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 2); 4341184914b5SBarry Smith 43429566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 4343064f8208SBarry Smith if (nrm > *delta) { 4344064f8208SBarry Smith nrm = *delta / nrm; 4345064f8208SBarry Smith *gpnorm = (1.0 - nrm) * (*fnorm); 4346064f8208SBarry Smith cnorm = nrm; 43479566063dSJacob Faibussowitsch PetscCall(VecScale(y, cnorm)); 43489b94acceSBarry Smith *ynorm = *delta; 43499b94acceSBarry Smith } else { 43509b94acceSBarry Smith *gpnorm = 0.0; 4351064f8208SBarry Smith *ynorm = nrm; 43529b94acceSBarry Smith } 43533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43549b94acceSBarry Smith } 43559b94acceSBarry Smith 435691f3e32bSBarry Smith /*@C 4357f6dfbefdSBarry Smith SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer 43582a359c20SBarry Smith 4359c3339decSBarry Smith Collective 43602a359c20SBarry Smith 43612a359c20SBarry Smith Parameter: 4362f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 43632a359c20SBarry Smith - viewer - the viewer to display the reason 43642a359c20SBarry Smith 43652a359c20SBarry Smith Options Database Keys: 4366ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4367ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4368eafd5ff0SAlex Lindsay 4369f6dfbefdSBarry Smith Note: 4370f6dfbefdSBarry Smith To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default, 4371f6dfbefdSBarry Smith use `PETSC_VIEWER_FAILED` to only display a reason if it fails. 43722a359c20SBarry Smith 43732a359c20SBarry Smith Level: beginner 43742a359c20SBarry Smith 4375dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`, 4376f6dfbefdSBarry Smith `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, 4377f6dfbefdSBarry Smith `SNESConvergedReasonViewFromOptions()`, 4378db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 43792a359c20SBarry Smith @*/ 4380d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) 4381d71ae5a4SJacob Faibussowitsch { 438275cca76cSMatthew G. Knepley PetscViewerFormat format; 43832a359c20SBarry Smith PetscBool isAscii; 43842a359c20SBarry Smith 43852a359c20SBarry Smith PetscFunctionBegin; 438619a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 43879566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 43882a359c20SBarry Smith if (isAscii) { 43899566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 43909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 439175cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 439275cca76cSMatthew G. Knepley DM dm; 439375cca76cSMatthew G. Knepley Vec u; 439475cca76cSMatthew G. Knepley PetscDS prob; 439575cca76cSMatthew G. Knepley PetscInt Nf, f; 439695cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 439795cbbfd3SMatthew G. Knepley void **exactCtx; 439875cca76cSMatthew G. Knepley PetscReal error; 439975cca76cSMatthew G. Knepley 44009566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 44019566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 44029566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 44039566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 44049566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 44059566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 44069566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 44079566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 44089566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 440963a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 441075cca76cSMatthew G. Knepley } 4411eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 44122a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 441363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 44142a359c20SBarry Smith } else { 441563a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44162a359c20SBarry Smith } 4417eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 44182a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 441963a3b9bcSJacob 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)); 44202a359c20SBarry Smith } else { 442163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44222a359c20SBarry Smith } 44232a359c20SBarry Smith } 44249566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 44252a359c20SBarry Smith } 44263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44272a359c20SBarry Smith } 44282a359c20SBarry Smith 4429c4421ceaSFande Kong /*@C 4430c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4431aaa8cc7dSPierre Jolivet end of the nonlinear solver to display the convergence reason of the nonlinear solver. 4432c4421ceaSFande Kong 4433c3339decSBarry Smith Logically Collective 4434c4421ceaSFande Kong 4435c4421ceaSFande Kong Input Parameters: 4436f6dfbefdSBarry Smith + snes - the `SNES` context 4437c4421ceaSFande Kong . f - the snes converged reason view function 4438c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4439dc4c0fb0SBarry Smith snes converged reason view routine (use `NULL` if no context is desired) 4440dc4c0fb0SBarry Smith - reasonviewdestroy - [optional] routine that frees reasonview context (may be `NULL`) 4441c4421ceaSFande Kong 4442c4421ceaSFande Kong Options Database Keys: 4443f6dfbefdSBarry Smith + -snes_converged_reason - sets a default `SNESConvergedReasonView()` 4444c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4445c4421ceaSFande Kong been hardwired into a code by 4446f6dfbefdSBarry Smith calls to `SNESConvergedReasonViewSet()`, but 4447c4421ceaSFande Kong does not cancel those set via 4448c4421ceaSFande Kong the options database. 4449c4421ceaSFande Kong 4450dc4c0fb0SBarry Smith Level: intermediate 4451dc4c0fb0SBarry Smith 4452f6dfbefdSBarry Smith Note: 4453c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4454f6dfbefdSBarry Smith `SNESConvergedReasonViewSet()` multiple times; all will be called in the 4455c4421ceaSFande Kong order in which they were set. 4456c4421ceaSFande Kong 4457dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4458c4421ceaSFande Kong @*/ 4459d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) 4460d71ae5a4SJacob Faibussowitsch { 4461c4421ceaSFande Kong PetscInt i; 4462c4421ceaSFande Kong PetscBool identical; 4463c4421ceaSFande Kong 4464c4421ceaSFande Kong PetscFunctionBegin; 4465c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4466c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 44679566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 44683ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4469c4421ceaSFande Kong } 44705f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4471c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4472c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4473c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 44743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4475c4421ceaSFande Kong } 4476c4421ceaSFande Kong 447791f3e32bSBarry Smith /*@ 4478f6dfbefdSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed. 4479c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 44802a359c20SBarry Smith 4481c3339decSBarry Smith Collective 44822a359c20SBarry Smith 44832fe279fdSBarry Smith Input Parameter: 4484f6dfbefdSBarry Smith . snes - the `SNES` object 44852a359c20SBarry Smith 4486f6dfbefdSBarry Smith Level: advanced 44872a359c20SBarry Smith 4488dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, 4489f6dfbefdSBarry Smith `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 44902a359c20SBarry Smith @*/ 4491d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4492d71ae5a4SJacob Faibussowitsch { 44932a359c20SBarry Smith PetscViewer viewer; 44942a359c20SBarry Smith PetscBool flg; 44952a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 44962a359c20SBarry Smith PetscViewerFormat format; 4497c4421ceaSFande Kong PetscInt i; 44982a359c20SBarry Smith 44992a359c20SBarry Smith PetscFunctionBegin; 45003ba16761SJacob Faibussowitsch if (incall) PetscFunctionReturn(PETSC_SUCCESS); 45012a359c20SBarry Smith incall = PETSC_TRUE; 4502c4421ceaSFande Kong 4503c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 450448a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4505c4421ceaSFande Kong 4506c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 45079566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 45082a359c20SBarry Smith if (flg) { 45099566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45109566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 45119566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45129566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45132a359c20SBarry Smith } 45142a359c20SBarry Smith incall = PETSC_FALSE; 45153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45162a359c20SBarry Smith } 45172a359c20SBarry Smith 4518487a658cSBarry Smith /*@ 4519f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4520f6dfbefdSBarry Smith Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`. 45219b94acceSBarry Smith 4522c3339decSBarry Smith Collective 4523c7afd0dbSLois Curfman McInnes 4524b2002411SLois Curfman McInnes Input Parameters: 4525f6dfbefdSBarry Smith + snes - the `SNES` context 4526dc4c0fb0SBarry Smith . b - the constant part of the equation F(x) = b, or `NULL` to use zero. 452785385478SLisandro Dalcin - x - the solution vector. 45289b94acceSBarry Smith 4529dc4c0fb0SBarry Smith Level: beginner 4530dc4c0fb0SBarry Smith 4531f6dfbefdSBarry Smith Note: 45328ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 4533f6dfbefdSBarry Smith for the nonlinear solve prior to calling `SNESSolve()`. In particular, 45348ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 4535f6dfbefdSBarry Smith this vector to zero by calling `VecSet()`. 45368ddd3da0SLois Curfman McInnes 4537dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4538db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4539db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 45409b94acceSBarry Smith @*/ 4541d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) 4542d71ae5a4SJacob Faibussowitsch { 4543ace3abfcSBarry Smith PetscBool flg; 4544efd51863SBarry Smith PetscInt grid; 45450298fd71SBarry Smith Vec xcreated = NULL; 4546caa4e7f2SJed Brown DM dm; 4547052efed2SBarry Smith 45483a40ed3dSBarry Smith PetscFunctionBegin; 45490700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4550a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4551a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 45520700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 455385385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 455485385478SLisandro Dalcin 455534b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 455606fc46c8SMatthew G. Knepley { 455706fc46c8SMatthew G. Knepley PetscViewer viewer; 455806fc46c8SMatthew G. Knepley PetscViewerFormat format; 45597c88af5aSMatthew G. Knepley PetscInt num; 456006fc46c8SMatthew G. Knepley PetscBool flg; 456106fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 456206fc46c8SMatthew G. Knepley 456306fc46c8SMatthew G. Knepley if (!incall) { 456434b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 45659566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 456606fc46c8SMatthew G. Knepley if (flg) { 456706fc46c8SMatthew G. Knepley PetscConvEst conv; 456846079b62SMatthew G. Knepley DM dm; 456946079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 457046079b62SMatthew G. Knepley PetscInt Nf; 457106fc46c8SMatthew G. Knepley 457206fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 45739566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45749566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 45759566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 45769566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 45779566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 45789566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 45799566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 45809566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 45819566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45829566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 45839566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45849566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45859566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 45869566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 458706fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 458806fc46c8SMatthew G. Knepley } 458934b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4590b2588ea6SMatthew G. Knepley num = 1; 45919566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 459234b4d3a8SMatthew G. Knepley if (flg) { 459334b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 459434b4d3a8SMatthew G. Knepley 459534b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 45969566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 45979566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 45989566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 45999566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46009566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46019566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 46029566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 460334b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 460434b4d3a8SMatthew G. Knepley } 46057c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 46067c88af5aSMatthew G. Knepley num = 0; 46079566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 46087c88af5aSMatthew G. Knepley if (num) { 46097c88af5aSMatthew G. Knepley DMAdaptor adaptor; 46107c88af5aSMatthew G. Knepley 46117c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 46129566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46139566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46149566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46159566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46169566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46179566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 46189566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 46197c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 46207c88af5aSMatthew G. Knepley } 462106fc46c8SMatthew G. Knepley } 462206fc46c8SMatthew G. Knepley } 4623ad540459SPierre Jolivet if (!x) x = snes->vec_sol; 4624caa4e7f2SJed Brown if (!x) { 46259566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 46269566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4627a69afd8bSBarry Smith x = xcreated; 4628a69afd8bSBarry Smith } 46299566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4630f05ece33SBarry Smith 46319566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4632efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 463385385478SLisandro Dalcin /* set solution vector */ 46349566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 46359566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 463685385478SLisandro Dalcin snes->vec_sol = x; 46379566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4638caa4e7f2SJed Brown 4639caa4e7f2SJed Brown /* set affine vector if provided */ 46409566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 46419566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 464285385478SLisandro Dalcin snes->vec_rhs = b; 464385385478SLisandro Dalcin 46445f80ce2aSJacob 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"); 46455f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 46465f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 4647aa624791SPierre Jolivet if (!snes->vec_sol_update /* && snes->vec_sol */) PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); 46489566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 46499566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 46503f149594SLisandro Dalcin 46517eee914bSBarry Smith if (!grid) { 465225e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4653dd568438SSatish Balay } 4654d25893d9SBarry Smith 4655abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 46569371c9d4SSatish Balay if (snes->counters_reset) { 46579371c9d4SSatish Balay snes->nfuncs = 0; 46589371c9d4SSatish Balay snes->linear_its = 0; 46599371c9d4SSatish Balay snes->numFailures = 0; 46609371c9d4SSatish Balay } 4661d5e45103SBarry Smith 46629566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4663dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 46649566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 46655f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason"); 4666422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 46673f149594SLisandro Dalcin 466837ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 466937ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 467037ec4e1aSPeter Brune 46719566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 46729566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4673c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 46749566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 46755968eb51SBarry Smith 46765f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 46779c8e83a9SBarry Smith if (snes->reason < 0) break; 4678efd51863SBarry Smith if (grid < snes->gridsequence) { 4679efd51863SBarry Smith DM fine; 4680efd51863SBarry Smith Vec xnew; 4681efd51863SBarry Smith Mat interp; 4682efd51863SBarry Smith 46839566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 46845f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 46859566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 46869566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 46879566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 46889566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 46899566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4690efd51863SBarry Smith x = xnew; 4691efd51863SBarry Smith 46929566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 46939566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 46949566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 46959566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 46969566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4697efd51863SBarry Smith } 4698efd51863SBarry Smith } 46999566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 47009566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 47019566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 47029566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 47033f7e2da0SPeter Brune 47049566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 47059566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 47063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47079b94acceSBarry Smith } 47089b94acceSBarry Smith 47099b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 47109b94acceSBarry Smith 471182bf6240SBarry Smith /*@C 47124b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 47139b94acceSBarry Smith 4714c3339decSBarry Smith Collective 4715fee21e36SBarry Smith 4716c7afd0dbSLois Curfman McInnes Input Parameters: 4717f6dfbefdSBarry Smith + snes - the `SNES` context 4718454a90a3SBarry Smith - type - a known method 4719c7afd0dbSLois Curfman McInnes 4720c7afd0dbSLois Curfman McInnes Options Database Key: 4721454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 472204d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4723ae12b187SLois Curfman McInnes 4724dc4c0fb0SBarry Smith Level: intermediate 4725dc4c0fb0SBarry Smith 47269b94acceSBarry Smith Notes: 4727e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 4728f6dfbefdSBarry Smith + `SNESNEWTONLS` - Newton's method with line search 4729c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47304a221d59SStefano Zampini - `SNESNEWTONTR` - Newton's method with trust region 4731c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47329b94acceSBarry Smith 4733f6dfbefdSBarry Smith Normally, it is best to use the `SNESSetFromOptions()` command and then 4734f6dfbefdSBarry Smith set the `SNES` solver type from the options database rather than by using 4735ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4736ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4737f6dfbefdSBarry Smith The `SNESSetType()` routine is provided for those situations where it 4738ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4739ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4740ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4741ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4742b0a32e0cSBarry Smith appropriate method. 474336851e7fSLois Curfman McInnes 4744f6dfbefdSBarry Smith Developer Note: 4745f6dfbefdSBarry Smith `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates 4746f6dfbefdSBarry Smith the constructor in that list and calls it to create the specific object. 47478f6c3df8SBarry Smith 4748dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 47499b94acceSBarry Smith @*/ 4750d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetType(SNES snes, SNESType type) 4751d71ae5a4SJacob Faibussowitsch { 4752ace3abfcSBarry Smith PetscBool match; 47535f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 47543a40ed3dSBarry Smith 47553a40ed3dSBarry Smith PetscFunctionBegin; 47560700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47574482741eSBarry Smith PetscValidCharPointer(type, 2); 475882bf6240SBarry Smith 47599566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 47603ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 476192ff6ae8SBarry Smith 47629566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 47635f80ce2aSJacob Faibussowitsch PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 476475396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4765dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 476675396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 47679e5d0892SLisandro Dalcin snes->ops->setup = NULL; 47689e5d0892SLisandro Dalcin snes->ops->solve = NULL; 47699e5d0892SLisandro Dalcin snes->ops->view = NULL; 47709e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 47719e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 47727fe760d5SStefano Zampini 47737fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 47749566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 47757fe760d5SStefano Zampini 477675396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 477775396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4778f5af7f23SKarl Rupp 47799566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 47809566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 47813ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47829b94acceSBarry Smith } 47839b94acceSBarry Smith 47849b94acceSBarry Smith /*@C 4785f6dfbefdSBarry Smith SNESGetType - Gets the `SNES` method type and name (as a string). 47869b94acceSBarry Smith 4787c7afd0dbSLois Curfman McInnes Not Collective 4788c7afd0dbSLois Curfman McInnes 47899b94acceSBarry Smith Input Parameter: 47904b0e389bSBarry Smith . snes - nonlinear solver context 47919b94acceSBarry Smith 47929b94acceSBarry Smith Output Parameter: 4793f6dfbefdSBarry Smith . type - `SNES` method (a character string) 47949b94acceSBarry Smith 479536851e7fSLois Curfman McInnes Level: intermediate 479636851e7fSLois Curfman McInnes 4797dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES` 47989b94acceSBarry Smith @*/ 4799d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetType(SNES snes, SNESType *type) 4800d71ae5a4SJacob Faibussowitsch { 48013a40ed3dSBarry Smith PetscFunctionBegin; 48020700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48034482741eSBarry Smith PetscValidPointer(type, 2); 48047adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 48053ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48069b94acceSBarry Smith } 48079b94acceSBarry Smith 48083cd8a7caSMatthew G. Knepley /*@ 4809f6dfbefdSBarry Smith SNESSetSolution - Sets the solution vector for use by the `SNES` routines. 48103cd8a7caSMatthew G. Knepley 4811c3339decSBarry Smith Logically Collective 48123cd8a7caSMatthew G. Knepley 48133cd8a7caSMatthew G. Knepley Input Parameters: 4814f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()` 48153cd8a7caSMatthew G. Knepley - u - the solution vector 48163cd8a7caSMatthew G. Knepley 48173cd8a7caSMatthew G. Knepley Level: beginner 48183cd8a7caSMatthew G. Knepley 4819dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec` 48203cd8a7caSMatthew G. Knepley @*/ 4821d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4822d71ae5a4SJacob Faibussowitsch { 48233cd8a7caSMatthew G. Knepley DM dm; 48243cd8a7caSMatthew G. Knepley 48253cd8a7caSMatthew G. Knepley PetscFunctionBegin; 48263cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48273cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 48289566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 48299566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 48303cd8a7caSMatthew G. Knepley 48313cd8a7caSMatthew G. Knepley snes->vec_sol = u; 48323cd8a7caSMatthew G. Knepley 48339566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48349566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 48353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48363cd8a7caSMatthew G. Knepley } 48373cd8a7caSMatthew G. Knepley 483852baeb72SSatish Balay /*@ 48399b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4840f6dfbefdSBarry Smith stored. This is the fine grid solution when using `SNESSetGridSequence()`. 48419b94acceSBarry Smith 4842f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4843c7afd0dbSLois Curfman McInnes 48449b94acceSBarry Smith Input Parameter: 4845f6dfbefdSBarry Smith . snes - the `SNES` context 48469b94acceSBarry Smith 48479b94acceSBarry Smith Output Parameter: 48489b94acceSBarry Smith . x - the solution 48499b94acceSBarry Smith 485070e92668SMatthew Knepley Level: intermediate 485136851e7fSLois Curfman McInnes 4852dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()` 48539b94acceSBarry Smith @*/ 4854d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolution(SNES snes, Vec *x) 4855d71ae5a4SJacob Faibussowitsch { 48563a40ed3dSBarry Smith PetscFunctionBegin; 48570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48584482741eSBarry Smith PetscValidPointer(x, 2); 485985385478SLisandro Dalcin *x = snes->vec_sol; 48603ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 486170e92668SMatthew Knepley } 486270e92668SMatthew Knepley 486352baeb72SSatish Balay /*@ 48649b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 48659b94acceSBarry Smith stored. 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 update 48749b94acceSBarry Smith 487536851e7fSLois Curfman McInnes Level: advanced 487636851e7fSLois Curfman McInnes 4877dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()` 48789b94acceSBarry Smith @*/ 4879d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionUpdate(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_update; 48853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48869b94acceSBarry Smith } 48879b94acceSBarry Smith 48889b94acceSBarry Smith /*@C 4889f6dfbefdSBarry Smith SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()` 48909b94acceSBarry Smith 4891f6dfbefdSBarry Smith Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet. 4892c7afd0dbSLois Curfman McInnes 48939b94acceSBarry Smith Input Parameter: 4894f6dfbefdSBarry Smith . snes - the `SNES` context 48959b94acceSBarry Smith 4896d8d19677SJose E. Roman Output Parameters: 4897dc4c0fb0SBarry Smith + r - the vector that is used to store residuals (or `NULL` if you don't want it) 489820f4b53cSBarry Smith . f - the function (or `NULL` if you don't want it); for calling sequence see `SNESFunction` 4899dc4c0fb0SBarry Smith - ctx - the function context (or `NULL` if you don't want it) 49009b94acceSBarry Smith 490136851e7fSLois Curfman McInnes Level: advanced 490236851e7fSLois Curfman McInnes 4903f6dfbefdSBarry Smith Note: 4904dc4c0fb0SBarry Smith The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function 490504edfde5SBarry Smith 4906dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 49079b94acceSBarry Smith @*/ 4908d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4909d71ae5a4SJacob Faibussowitsch { 49106cab3a1bSJed Brown DM dm; 4911a63bb30eSJed Brown 49123a40ed3dSBarry Smith PetscFunctionBegin; 49130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4914a63bb30eSJed Brown if (r) { 4915a63bb30eSJed Brown if (!snes->vec_func) { 4916a63bb30eSJed Brown if (snes->vec_rhs) { 49179566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4918a63bb30eSJed Brown } else if (snes->vec_sol) { 49199566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4920a63bb30eSJed Brown } else if (snes->dm) { 49219566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4922a63bb30eSJed Brown } 4923a63bb30eSJed Brown } 4924a63bb30eSJed Brown *r = snes->vec_func; 4925a63bb30eSJed Brown } 49269566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49279566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 49283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49299b94acceSBarry Smith } 49309b94acceSBarry Smith 4931c79ef259SPeter Brune /*@C 4932f6dfbefdSBarry Smith SNESGetNGS - Returns the `SNESNGS` function and context set with `SNESSetNGS()` 4933c79ef259SPeter Brune 4934c79ef259SPeter Brune Input Parameter: 4935f6dfbefdSBarry Smith . snes - the `SNES` context 4936c79ef259SPeter Brune 4937d8d19677SJose E. Roman Output Parameters: 4938dc4c0fb0SBarry Smith + f - the function (or `NULL`) see `SNESNGSFunction` for details 4939dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 4940c79ef259SPeter Brune 4941c79ef259SPeter Brune Level: advanced 4942c79ef259SPeter Brune 4943dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNGS()`, `SNESGetFunction()` 4944c79ef259SPeter Brune @*/ 4945c79ef259SPeter Brune 4946d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4947d71ae5a4SJacob Faibussowitsch { 49486cab3a1bSJed Brown DM dm; 49496cab3a1bSJed Brown 4950646217ecSPeter Brune PetscFunctionBegin; 4951646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49529566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49539566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 49543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4955646217ecSPeter Brune } 4956646217ecSPeter Brune 49573c7409f5SSatish Balay /*@C 49583c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4959f6dfbefdSBarry Smith `SNES` options in the database. 49603c7409f5SSatish Balay 4961c3339decSBarry Smith Logically Collective 4962fee21e36SBarry Smith 4963d8d19677SJose E. Roman Input Parameters: 4964f6dfbefdSBarry Smith + snes - the `SNES` context 4965c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4966c7afd0dbSLois Curfman McInnes 4967dc4c0fb0SBarry Smith Level: advanced 4968dc4c0fb0SBarry Smith 4969f6dfbefdSBarry Smith Note: 4970a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4971c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4972d850072dSLois Curfman McInnes 4973dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()` 49743c7409f5SSatish Balay @*/ 4975d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) 4976d71ae5a4SJacob Faibussowitsch { 49773a40ed3dSBarry Smith PetscFunctionBegin; 49780700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49799566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 49809566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 498135f5d045SPeter Brune if (snes->linesearch) { 49829566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 49839566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 498435f5d045SPeter Brune } 49859566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 49863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49873c7409f5SSatish Balay } 49883c7409f5SSatish Balay 49893c7409f5SSatish Balay /*@C 4990f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4991f6dfbefdSBarry Smith `SNES` options in the database. 49923c7409f5SSatish Balay 4993c3339decSBarry Smith Logically Collective 4994fee21e36SBarry Smith 4995c7afd0dbSLois Curfman McInnes Input Parameters: 4996f6dfbefdSBarry Smith + snes - the `SNES` context 4997c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4998c7afd0dbSLois Curfman McInnes 4999dc4c0fb0SBarry Smith Level: advanced 5000dc4c0fb0SBarry Smith 5001f6dfbefdSBarry Smith Note: 5002a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5003c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5004d850072dSLois Curfman McInnes 5005dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()` 50063c7409f5SSatish Balay @*/ 5007d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) 5008d71ae5a4SJacob Faibussowitsch { 50093a40ed3dSBarry Smith PetscFunctionBegin; 50100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50119566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 50129566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 501335f5d045SPeter Brune if (snes->linesearch) { 50149566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 50159566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 501635f5d045SPeter Brune } 50179566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 50183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50193c7409f5SSatish Balay } 50203c7409f5SSatish Balay 50219ab63eb5SSatish Balay /*@C 5022f6dfbefdSBarry Smith SNESGetOptionsPrefix - Gets the prefix used for searching for all 5023f6dfbefdSBarry Smith `SNES` options in the database. 50243c7409f5SSatish Balay 5025c7afd0dbSLois Curfman McInnes Not Collective 5026c7afd0dbSLois Curfman McInnes 50273c7409f5SSatish Balay Input Parameter: 5028f6dfbefdSBarry Smith . snes - the `SNES` context 50293c7409f5SSatish Balay 50303c7409f5SSatish Balay Output Parameter: 50313c7409f5SSatish Balay . prefix - pointer to the prefix string used 50323c7409f5SSatish Balay 503336851e7fSLois Curfman McInnes Level: advanced 503436851e7fSLois Curfman McInnes 5035dc4c0fb0SBarry Smith Fortran Note: 5036dc4c0fb0SBarry Smith The user should pass in a string 'prefix' of 5037dc4c0fb0SBarry Smith sufficient length to hold the prefix. 5038dc4c0fb0SBarry Smith 5039dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()` 50403c7409f5SSatish Balay @*/ 5041d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) 5042d71ae5a4SJacob Faibussowitsch { 50433a40ed3dSBarry Smith PetscFunctionBegin; 50440700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50459566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 50463ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50473c7409f5SSatish Balay } 50483c7409f5SSatish Balay 50493cea93caSBarry Smith /*@C 50501c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 50511c84c290SBarry Smith 505220f4b53cSBarry Smith Not Collective 50531c84c290SBarry Smith 50541c84c290SBarry Smith Input Parameters: 505520f4b53cSBarry Smith + sname - name of a new user-defined solver 505620f4b53cSBarry Smith - function - routine to create method context 50571c84c290SBarry Smith 5058dc4c0fb0SBarry Smith Level: advanced 5059dc4c0fb0SBarry Smith 5060f6dfbefdSBarry Smith Note: 5061f6dfbefdSBarry Smith `SNESRegister()` may be called multiple times to add several user-defined solvers. 50621c84c290SBarry Smith 50631c84c290SBarry Smith Sample usage: 50641c84c290SBarry Smith .vb 5065bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 50661c84c290SBarry Smith .ve 50671c84c290SBarry Smith 50681c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 50691c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 50701c84c290SBarry Smith or at runtime via the option 50711c84c290SBarry Smith $ -snes_type my_solver 50721c84c290SBarry Smith 5073dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()` 50743cea93caSBarry Smith @*/ 5075d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) 5076d71ae5a4SJacob Faibussowitsch { 5077b2002411SLois Curfman McInnes PetscFunctionBegin; 50789566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 50799566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 50803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5081b2002411SLois Curfman McInnes } 5082da9b6338SBarry Smith 5083d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestLocalMin(SNES snes) 5084d71ae5a4SJacob Faibussowitsch { 508577431f27SBarry Smith PetscInt N, i, j; 5086da9b6338SBarry Smith Vec u, uh, fh; 5087da9b6338SBarry Smith PetscScalar value; 5088da9b6338SBarry Smith PetscReal norm; 5089da9b6338SBarry Smith 5090da9b6338SBarry Smith PetscFunctionBegin; 50919566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 50929566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 50939566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 5094da9b6338SBarry Smith 5095da9b6338SBarry Smith /* currently only works for sequential */ 50969566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 50979566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5098da9b6338SBarry Smith for (i = 0; i < N; i++) { 50999566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 510063a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5101da9b6338SBarry Smith for (j = -10; j < 11; j++) { 51028b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 51039566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 51049566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 51059566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 510663a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5107da9b6338SBarry Smith value = -value; 51089566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5109da9b6338SBarry Smith } 5110da9b6338SBarry Smith } 51119566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 51129566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 51133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5114da9b6338SBarry Smith } 511571f87433Sdalcinl 511671f87433Sdalcinl /*@ 5117f6dfbefdSBarry Smith SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for 511871f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 511971f87433Sdalcinl Newton method. 512071f87433Sdalcinl 5121c3339decSBarry Smith Logically Collective 512271f87433Sdalcinl 512371f87433Sdalcinl Input Parameters: 5124f6dfbefdSBarry Smith + snes - `SNES` context 5125f6dfbefdSBarry Smith - flag - `PETSC_TRUE` or `PETSC_FALSE` 512671f87433Sdalcinl 5127f6dfbefdSBarry Smith Options Database Keys: 512864ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 512964ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 513064ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 513164ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 513264ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 513364ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 513464ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 513564ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 513664ba62caSBarry Smith 5137dc4c0fb0SBarry Smith Level: advanced 5138dc4c0fb0SBarry Smith 5139f6dfbefdSBarry Smith Note: 5140f6dfbefdSBarry Smith The default is to use a constant relative tolerance for 514171f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 514271f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 514371f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 514471f87433Sdalcinl solver. 514571f87433Sdalcinl 514671f87433Sdalcinl Reference: 5147f6dfbefdSBarry Smith . - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996. 514871f87433Sdalcinl 5149dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 515071f87433Sdalcinl @*/ 5151d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) 5152d71ae5a4SJacob Faibussowitsch { 515371f87433Sdalcinl PetscFunctionBegin; 51540700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5155acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 515671f87433Sdalcinl snes->ksp_ewconv = flag; 51573ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 515871f87433Sdalcinl } 515971f87433Sdalcinl 516071f87433Sdalcinl /*@ 5161f6dfbefdSBarry Smith SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method 516271f87433Sdalcinl for computing relative tolerance for linear solvers within an 516371f87433Sdalcinl inexact Newton method. 516471f87433Sdalcinl 516571f87433Sdalcinl Not Collective 516671f87433Sdalcinl 516771f87433Sdalcinl Input Parameter: 5168f6dfbefdSBarry Smith . snes - `SNES` context 516971f87433Sdalcinl 517071f87433Sdalcinl Output Parameter: 5171f6dfbefdSBarry Smith . flag - `PETSC_TRUE` or `PETSC_FALSE` 517271f87433Sdalcinl 517371f87433Sdalcinl Level: advanced 517471f87433Sdalcinl 5175dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 517671f87433Sdalcinl @*/ 5177d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5178d71ae5a4SJacob Faibussowitsch { 517971f87433Sdalcinl PetscFunctionBegin; 51800700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5181534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 518271f87433Sdalcinl *flag = snes->ksp_ewconv; 51833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 518471f87433Sdalcinl } 518571f87433Sdalcinl 518671f87433Sdalcinl /*@ 5187fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 518871f87433Sdalcinl convergence criteria for the linear solvers within an inexact 518971f87433Sdalcinl Newton method. 519071f87433Sdalcinl 5191c3339decSBarry Smith Logically Collective 519271f87433Sdalcinl 519371f87433Sdalcinl Input Parameters: 5194f6dfbefdSBarry Smith + snes - `SNES` context 51950f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 519671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 519771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 519871f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 519971f87433Sdalcinl (0 <= gamma2 <= 1) 520071f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 520171f87433Sdalcinl . alpha2 - power for safeguard 520271f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 520371f87433Sdalcinl 5204dc4c0fb0SBarry Smith Level: advanced 5205dc4c0fb0SBarry Smith 5206f6dfbefdSBarry Smith Notes: 520771f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 520871f87433Sdalcinl 5209f6dfbefdSBarry Smith Use `PETSC_DEFAULT` to retain the default for any of the parameters. 521071f87433Sdalcinl 5211dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 521271f87433Sdalcinl @*/ 5213d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) 5214d71ae5a4SJacob Faibussowitsch { 5215fa9f3622SBarry Smith SNESKSPEW *kctx; 52165fd66863SKarl Rupp 521771f87433Sdalcinl PetscFunctionBegin; 52180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5219fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52205f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5221c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5222c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5223c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5224c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5225c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5226c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5227c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 522871f87433Sdalcinl 522971f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 523013bcc0bdSJacob Faibussowitsch if (rtol_0 != (PetscReal)PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 523113bcc0bdSJacob Faibussowitsch if (rtol_max != (PetscReal)PETSC_DEFAULT) kctx->rtol_max = rtol_max; 523213bcc0bdSJacob Faibussowitsch if (gamma != (PetscReal)PETSC_DEFAULT) kctx->gamma = gamma; 523313bcc0bdSJacob Faibussowitsch if (alpha != (PetscReal)PETSC_DEFAULT) kctx->alpha = alpha; 523413bcc0bdSJacob Faibussowitsch if (alpha2 != (PetscReal)PETSC_DEFAULT) kctx->alpha2 = alpha2; 523513bcc0bdSJacob Faibussowitsch if (threshold != (PetscReal)PETSC_DEFAULT) kctx->threshold = threshold; 523671f87433Sdalcinl 52370f0abf79SStefano 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); 52380b121fc5SBarry 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); 52390b121fc5SBarry 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); 52400b121fc5SBarry 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); 52410b121fc5SBarry 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); 52420b121fc5SBarry 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); 52433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 524471f87433Sdalcinl } 524571f87433Sdalcinl 524671f87433Sdalcinl /*@ 5247fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 524871f87433Sdalcinl convergence criteria for the linear solvers within an inexact 524971f87433Sdalcinl Newton method. 525071f87433Sdalcinl 525171f87433Sdalcinl Not Collective 525271f87433Sdalcinl 525397bb3fdcSJose E. Roman Input Parameter: 5254f6dfbefdSBarry Smith . snes - `SNES` context 525571f87433Sdalcinl 525671f87433Sdalcinl Output Parameters: 52570f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 525871f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 525971f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5260bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 526171f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 526271f87433Sdalcinl . alpha2 - power for safeguard 526371f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 526471f87433Sdalcinl 526571f87433Sdalcinl Level: advanced 526671f87433Sdalcinl 5267dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 526871f87433Sdalcinl @*/ 5269d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) 5270d71ae5a4SJacob Faibussowitsch { 5271fa9f3622SBarry Smith SNESKSPEW *kctx; 52725fd66863SKarl Rupp 527371f87433Sdalcinl PetscFunctionBegin; 52740700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5275fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52765f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 527771f87433Sdalcinl if (version) *version = kctx->version; 527871f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 527971f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 528071f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 528171f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 528271f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 528371f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 52843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 528571f87433Sdalcinl } 528671f87433Sdalcinl 5287d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5288d71ae5a4SJacob Faibussowitsch { 5289fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 529071f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 529171f87433Sdalcinl 529271f87433Sdalcinl PetscFunctionBegin; 52933ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 529430058271SDmitry Karpeev if (!snes->iter) { 529530058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 52969566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 52970f0abf79SStefano Zampini } else { 52980fdf79fbSJacob 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); 529971f87433Sdalcinl if (kctx->version == 1) { 53000f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 530185ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 530271f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 530371f87433Sdalcinl } else if (kctx->version == 2) { 530485ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 530585ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 530671f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 530771f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 530885ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 530971f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 531085ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 531171f87433Sdalcinl stol = PetscMax(rtol, stol); 531271f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 531371f87433Sdalcinl /* safeguard: avoid oversolving */ 531430058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 531571f87433Sdalcinl stol = PetscMax(rtol, stol); 531671f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 53170fdf79fbSJacob Faibussowitsch } else /* if (kctx->version == 4) */ { 53180fdf79fbSJacob Faibussowitsch /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 53190f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 53200f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 53210f0abf79SStefano Zampini PetscReal rk = ared / pred; 53220f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 53230f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 53240f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 53250f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 53260f0abf79SStefano Zampini 5327a4598233SStefano Zampini 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) rtol = kctx->v4_m4 * kctx->rtol_last; 53280f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 53290f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 53300f0abf79SStefano Zampini kctx->rk_last = rk; 53310fdf79fbSJacob Faibussowitsch } 53320f0abf79SStefano Zampini } 53330f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 533471f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 53359566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 533663a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 53373ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 533871f87433Sdalcinl } 533971f87433Sdalcinl 5340d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5341d71ae5a4SJacob Faibussowitsch { 5342fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 534371f87433Sdalcinl PCSide pcside; 534471f87433Sdalcinl Vec lres; 534571f87433Sdalcinl 534671f87433Sdalcinl PetscFunctionBegin; 53473ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 53489566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 534971dbe336SPeter Brune kctx->norm_last = snes->norm; 53500f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 53514f00ce20SMatthew G. Knepley PC pc; 53520f0abf79SStefano Zampini PetscBool getRes; 53534f00ce20SMatthew G. Knepley 53549566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 53550f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 53560f0abf79SStefano Zampini if (!getRes) { 53570f0abf79SStefano Zampini KSPNormType normtype; 53580f0abf79SStefano Zampini 53590f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 53600f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 53610f0abf79SStefano Zampini } 53629566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 53630f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 53649566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 536571f87433Sdalcinl } else { 536671f87433Sdalcinl /* KSP residual is preconditioned residual */ 536771f87433Sdalcinl /* compute true linear residual norm */ 53680f0abf79SStefano Zampini Mat J; 53690f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 53709566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 53710f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 53729566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 53739566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 53749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 537571f87433Sdalcinl } 537671f87433Sdalcinl } 53773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 537871f87433Sdalcinl } 537971f87433Sdalcinl 5380d4211eb9SBarry Smith /*@ 5381f6dfbefdSBarry Smith SNESGetKSP - Returns the `KSP` context for a `SNES` solver. 5382d4211eb9SBarry Smith 5383f6dfbefdSBarry Smith Not Collective, but if snes is parallel, then ksp is parallel 5384d4211eb9SBarry Smith 5385d4211eb9SBarry Smith Input Parameter: 5386f6dfbefdSBarry Smith . snes - the `SNES` context 5387d4211eb9SBarry Smith 5388d4211eb9SBarry Smith Output Parameter: 5389f6dfbefdSBarry Smith . ksp - the `KSP` context 5390d4211eb9SBarry Smith 5391dc4c0fb0SBarry Smith Level: beginner 5392dc4c0fb0SBarry Smith 5393d4211eb9SBarry Smith Notes: 5394f6dfbefdSBarry Smith The user can then directly manipulate the `KSP` context to set various 5395d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5396f6dfbefdSBarry Smith `PC` contexts as well. 5397f6dfbefdSBarry Smith 5398f6dfbefdSBarry Smith Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function 5399d4211eb9SBarry Smith 5400dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5401d4211eb9SBarry Smith @*/ 5402d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) 5403d71ae5a4SJacob Faibussowitsch { 540471f87433Sdalcinl PetscFunctionBegin; 5405d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5406d4211eb9SBarry Smith PetscValidPointer(ksp, 2); 5407d4211eb9SBarry Smith 5408d4211eb9SBarry Smith if (!snes->ksp) { 54099566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 54109566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 5411d4211eb9SBarry Smith 54129566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 54139566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5414a5c2985bSBarry Smith 54159566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 54169566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5417d4211eb9SBarry Smith } 5418d4211eb9SBarry Smith *ksp = snes->ksp; 54193ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 542071f87433Sdalcinl } 54216c699258SBarry Smith 5422af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 54236c699258SBarry Smith /*@ 5424f6dfbefdSBarry Smith SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners 54256c699258SBarry Smith 5426c3339decSBarry Smith Logically Collective 54276c699258SBarry Smith 54286c699258SBarry Smith Input Parameters: 54292a808120SBarry Smith + snes - the nonlinear solver context 5430dc4c0fb0SBarry Smith - dm - the dm, cannot be `NULL` 5431dc4c0fb0SBarry Smith 5432dc4c0fb0SBarry Smith Level: intermediate 54336c699258SBarry Smith 5434f6dfbefdSBarry Smith Note: 5435f6dfbefdSBarry Smith A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, 5436f6dfbefdSBarry Smith even when not using interfaces like `DMSNESSetFunction()`. Use `DMClone()` to get a distinct `DM` when solving different 5437e03a659cSJed Brown problems using the same function space. 5438e03a659cSJed Brown 5439dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 54406c699258SBarry Smith @*/ 5441d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDM(SNES snes, DM dm) 5442d71ae5a4SJacob Faibussowitsch { 5443345fed2cSBarry Smith KSP ksp; 5444942e3340SBarry Smith DMSNES sdm; 54456c699258SBarry Smith 54466c699258SBarry Smith PetscFunctionBegin; 54470700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54482a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 54499566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5450942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 545151f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 54529566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 54539566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5454f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 54556cab3a1bSJed Brown } 54569566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 54579566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 54586cab3a1bSJed Brown } 54596c699258SBarry Smith snes->dm = dm; 5460116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5461f5af7f23SKarl Rupp 54629566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 54639566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 54649566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5465efd4aadfSBarry Smith if (snes->npc) { 54669566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 54679566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 54682c155ee1SBarry Smith } 54693ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54706c699258SBarry Smith } 54716c699258SBarry Smith 54726c699258SBarry Smith /*@ 5473f6dfbefdSBarry Smith SNESGetDM - Gets the `DM` that may be used by some preconditioners 54746c699258SBarry Smith 5475f6dfbefdSBarry Smith Not Collective but dm obtained is parallel on snes 54766c699258SBarry Smith 54776c699258SBarry Smith Input Parameter: 54786c699258SBarry Smith . snes - the preconditioner context 54796c699258SBarry Smith 54806c699258SBarry Smith Output Parameter: 54816c699258SBarry Smith . dm - the dm 54826c699258SBarry Smith 54836c699258SBarry Smith Level: intermediate 54846c699258SBarry Smith 5485dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 54866c699258SBarry Smith @*/ 5487d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDM(SNES snes, DM *dm) 5488d71ae5a4SJacob Faibussowitsch { 54896c699258SBarry Smith PetscFunctionBegin; 54900700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54916cab3a1bSJed Brown if (!snes->dm) { 54929566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5493116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 54946cab3a1bSJed Brown } 54956c699258SBarry Smith *dm = snes->dm; 54963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54976c699258SBarry Smith } 54980807856dSBarry Smith 549931823bd8SMatthew G Knepley /*@ 5500be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 550131823bd8SMatthew G Knepley 5502c3339decSBarry Smith Collective 550331823bd8SMatthew G Knepley 550431823bd8SMatthew G Knepley Input Parameters: 5505f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 5506f6dfbefdSBarry Smith - npc - the preconditioner object 550731823bd8SMatthew G Knepley 5508dc4c0fb0SBarry Smith Level: developer 5509dc4c0fb0SBarry Smith 551031823bd8SMatthew G Knepley Notes: 5511f6dfbefdSBarry Smith Use `SNESGetNPC()` to retrieve the preconditioner context (for example, 551231823bd8SMatthew G Knepley to configure it using the API). 551331823bd8SMatthew G Knepley 5514f6dfbefdSBarry Smith Only some `SNESType` can use a nonlinear preconditioner 5515f6dfbefdSBarry Smith 5516dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()` 551731823bd8SMatthew G Knepley @*/ 5518d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPC(SNES snes, SNES npc) 5519d71ae5a4SJacob Faibussowitsch { 552031823bd8SMatthew G Knepley PetscFunctionBegin; 552131823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5522f6dfbefdSBarry Smith PetscValidHeaderSpecific(npc, SNES_CLASSID, 2); 5523f6dfbefdSBarry Smith PetscCheckSameComm(snes, 1, npc, 2); 5524f6dfbefdSBarry Smith PetscCall(PetscObjectReference((PetscObject)npc)); 55259566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5526f6dfbefdSBarry Smith snes->npc = npc; 55273ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 552831823bd8SMatthew G Knepley } 552931823bd8SMatthew G Knepley 553031823bd8SMatthew G Knepley /*@ 5531f6dfbefdSBarry Smith SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver. 553231823bd8SMatthew G Knepley 5533f6dfbefdSBarry Smith Not Collective; but any changes to the obtained the npc object must be applied collectively 553431823bd8SMatthew G Knepley 553531823bd8SMatthew G Knepley Input Parameter: 5536f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 553731823bd8SMatthew G Knepley 553831823bd8SMatthew G Knepley Output Parameter: 5539f6dfbefdSBarry Smith . npc - preconditioner context 554031823bd8SMatthew G Knepley 5541f6dfbefdSBarry Smith Options Database Key: 5542f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner 5543b5badacbSBarry Smith 5544dc4c0fb0SBarry Smith Level: developer 5545dc4c0fb0SBarry Smith 554695452b02SPatrick Sanan Notes: 5547f6dfbefdSBarry Smith If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created. 5548be95d8f1SBarry Smith 5549f6dfbefdSBarry Smith The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5550f6dfbefdSBarry Smith `SNES` 5551951fe5abSBarry Smith 5552dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 555331823bd8SMatthew G Knepley @*/ 5554d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5555d71ae5a4SJacob Faibussowitsch { 5556a64e098fSPeter Brune const char *optionsprefix; 555731823bd8SMatthew G Knepley 555831823bd8SMatthew G Knepley PetscFunctionBegin; 555931823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 556031823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5561efd4aadfSBarry Smith if (!snes->npc) { 5562ec785e5bSStefano Zampini void *ctx; 5563ec785e5bSStefano Zampini 55649566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 55659566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 55669566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 55679566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 55689566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 5569ec785e5bSStefano Zampini PetscCall(SNESGetApplicationContext(snes, &ctx)); 5570ec785e5bSStefano Zampini PetscCall(SNESSetApplicationContext(snes->npc, ctx)); 55719566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 557231823bd8SMatthew G Knepley } 5573efd4aadfSBarry Smith *pc = snes->npc; 55743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 557531823bd8SMatthew G Knepley } 557631823bd8SMatthew G Knepley 55773ad1a0b9SPatrick Farrell /*@ 55783ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 55793ad1a0b9SPatrick Farrell 55803ad1a0b9SPatrick Farrell Not Collective 55813ad1a0b9SPatrick Farrell 55823ad1a0b9SPatrick Farrell Input Parameter: 5583f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 55843ad1a0b9SPatrick Farrell 55853ad1a0b9SPatrick Farrell Output Parameter: 5586f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not 55873ad1a0b9SPatrick Farrell 55883ad1a0b9SPatrick Farrell Level: developer 55893ad1a0b9SPatrick Farrell 5590dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNPC()`, `SNESGetNPC()` 55913ad1a0b9SPatrick Farrell @*/ 5592d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5593d71ae5a4SJacob Faibussowitsch { 55943ad1a0b9SPatrick Farrell PetscFunctionBegin; 55953ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5596efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 55973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55983ad1a0b9SPatrick Farrell } 55993ad1a0b9SPatrick Farrell 5600c40d0f55SPeter Brune /*@ 5601be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5602c40d0f55SPeter Brune 5603c3339decSBarry Smith Logically Collective 5604c40d0f55SPeter Brune 5605c40d0f55SPeter Brune Input Parameter: 5606f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5607c40d0f55SPeter Brune 5608c40d0f55SPeter Brune Output Parameter: 5609c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5610c40d0f55SPeter Brune .vb 56112d547940SBarry Smith PC_LEFT - left preconditioning 56122d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5613c40d0f55SPeter Brune .ve 5614c40d0f55SPeter Brune 5615f6dfbefdSBarry Smith Options Database Key: 561667b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5617c40d0f55SPeter Brune 5618dc4c0fb0SBarry Smith Level: intermediate 5619dc4c0fb0SBarry Smith 5620f6dfbefdSBarry Smith Note: 5621f6dfbefdSBarry Smith `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning. 56222d547940SBarry Smith 5623dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()` 5624c40d0f55SPeter Brune @*/ 5625d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) 5626d71ae5a4SJacob Faibussowitsch { 5627c40d0f55SPeter Brune PetscFunctionBegin; 5628c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5629c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5630b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 563154c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5632efd4aadfSBarry Smith snes->npcside = side; 56333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5634c40d0f55SPeter Brune } 5635c40d0f55SPeter Brune 5636c40d0f55SPeter Brune /*@ 5637be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5638c40d0f55SPeter Brune 5639c40d0f55SPeter Brune Not Collective 5640c40d0f55SPeter Brune 5641c40d0f55SPeter Brune Input Parameter: 5642f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5643c40d0f55SPeter Brune 5644c40d0f55SPeter Brune Output Parameter: 5645c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5646c40d0f55SPeter Brune .vb 5647f6dfbefdSBarry Smith `PC_LEFT` - left preconditioning 5648f6dfbefdSBarry Smith `PC_RIGHT` - right preconditioning (default for most nonlinear solvers) 5649c40d0f55SPeter Brune .ve 5650c40d0f55SPeter Brune 5651c40d0f55SPeter Brune Level: intermediate 5652c40d0f55SPeter Brune 5653dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()` 5654c40d0f55SPeter Brune @*/ 5655d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) 5656d71ae5a4SJacob Faibussowitsch { 5657c40d0f55SPeter Brune PetscFunctionBegin; 5658c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5659c40d0f55SPeter Brune PetscValidPointer(side, 2); 5660efd4aadfSBarry Smith *side = snes->npcside; 56613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5662c40d0f55SPeter Brune } 5663c40d0f55SPeter Brune 56649e764e56SPeter Brune /*@ 5665f6dfbefdSBarry Smith SNESSetLineSearch - Sets the linesearch on the `SNES` instance. 56669e764e56SPeter Brune 5667c3339decSBarry Smith Collective 56689e764e56SPeter Brune 56699e764e56SPeter Brune Input Parameters: 5670f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 56719e764e56SPeter Brune - linesearch - the linesearch object 56729e764e56SPeter Brune 5673dc4c0fb0SBarry Smith Level: developer 5674dc4c0fb0SBarry Smith 5675f6dfbefdSBarry Smith Note: 5676f6dfbefdSBarry Smith Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example, 56779e764e56SPeter Brune to configure it using the API). 56789e764e56SPeter Brune 5679dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetLineSearch()` 56809e764e56SPeter Brune @*/ 5681d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5682d71ae5a4SJacob Faibussowitsch { 56839e764e56SPeter Brune PetscFunctionBegin; 56849e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5685f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 56869e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 56879566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 56889566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5689f5af7f23SKarl Rupp 56909e764e56SPeter Brune snes->linesearch = linesearch; 5691f5af7f23SKarl Rupp 56923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56939e764e56SPeter Brune } 56949e764e56SPeter Brune 5695a34ceb2aSJed Brown /*@ 5696dc4c0fb0SBarry Smith SNESGetLineSearch - Returns the line search context set with `SNESSetLineSearch()` 5697f6dfbefdSBarry Smith or creates a default line search instance associated with the `SNES` and returns it. 56989e764e56SPeter Brune 56999e764e56SPeter Brune Not Collective 57009e764e56SPeter Brune 57019e764e56SPeter Brune Input Parameter: 5702f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 57039e764e56SPeter Brune 57049e764e56SPeter Brune Output Parameter: 57059e764e56SPeter Brune . linesearch - linesearch context 57069e764e56SPeter Brune 5707162e0bf5SPeter Brune Level: beginner 57089e764e56SPeter Brune 5709dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()` 57109e764e56SPeter Brune @*/ 5711d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5712d71ae5a4SJacob Faibussowitsch { 57139e764e56SPeter Brune const char *optionsprefix; 57149e764e56SPeter Brune 57159e764e56SPeter Brune PetscFunctionBegin; 57169e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 57179e764e56SPeter Brune PetscValidPointer(linesearch, 2); 57189e764e56SPeter Brune if (!snes->linesearch) { 57199566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 57209566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 57219566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 57229566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 57239566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 57249e764e56SPeter Brune } 57259e764e56SPeter Brune *linesearch = snes->linesearch; 57263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57279e764e56SPeter Brune } 5728