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 1224936397dSBarry Smith Input Parameters: 123f6dfbefdSBarry Smith . snes - the `SNES` context 1244936397dSBarry Smith 12528529972SSatish Balay Level: advanced 1264936397dSBarry Smith 127f0b84518SBarry Smith Note: 128f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 129f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 130f0b84518SBarry Smith 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 14807b62357SFande Kong Input Parameters: 149f6dfbefdSBarry Smith . snes - the `SNES` context 15007b62357SFande Kong 15107b62357SFande Kong Level: advanced 15207b62357SFande Kong 153f0b84518SBarry Smith Note: 154f0b84518SBarry Smith You can direct `SNES` to avoid certain steps by using `SNESVISetVariableBounds()`, `SNESVISetComputeVariableBounds()` or 155f0b84518SBarry Smith `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()` 156f0b84518SBarry Smith 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 1998383d7d7SFande Kong Input Parameters: 200f6dfbefdSBarry Smith . snes - the `SNES` context 2018383d7d7SFande Kong 2028383d7d7SFande Kong Output Parameters: 203f6dfbefdSBarry Smith . flg - `PETSC_FALSE` indicates that we don't check Jacobian domain errors after each Jacobian evaluation 2048383d7d7SFande Kong 2058383d7d7SFande Kong Level: advanced 2068383d7d7SFande Kong 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 2236a388c36SPeter Brune Input Parameters: 224f6dfbefdSBarry Smith . snes - the `SNES` context 2256a388c36SPeter Brune 2266a388c36SPeter Brune Output Parameters: 227f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a domain error; `PETSC_FALSE` otherwise. 2286a388c36SPeter Brune 229f6dfbefdSBarry Smith Level: developer 2306a388c36SPeter Brune 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 24707b62357SFande Kong Input Parameters: 248f6dfbefdSBarry Smith . snes - the `SNES` context 24907b62357SFande Kong 25007b62357SFande Kong Output Parameters: 251f6dfbefdSBarry Smith . domainerror - Set to `PETSC_TRUE` if there's a Jacobian domain error; `PETSC_FALSE` otherwise. 25207b62357SFande Kong 25307b62357SFande Kong Level: advanced 25407b62357SFande Kong 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 852d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESEWSetFromOptions_Private(SNESKSPEW *kctx, MPI_Comm comm, const char *prefix) 853d71ae5a4SJacob Faibussowitsch { 8540f0abf79SStefano Zampini PetscFunctionBegin; 8550f0abf79SStefano Zampini PetscOptionsBegin(comm, prefix, "Eisenstat and Walker type forcing options", "KSP"); 8560f0abf79SStefano Zampini PetscCall(PetscOptionsInt("-ksp_ew_version", "Version 1, 2 or 3", NULL, kctx->version, &kctx->version, NULL)); 8570f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtol0", "0 <= rtol0 < 1", NULL, kctx->rtol_0, &kctx->rtol_0, NULL)); 8580f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_rtolmax", "0 <= rtolmax < 1", NULL, kctx->rtol_max, &kctx->rtol_max, NULL)); 8590f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_gamma", "0 <= gamma <= 1", NULL, kctx->gamma, &kctx->gamma, NULL)); 8600f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha", "1 < alpha <= 2", NULL, kctx->alpha, &kctx->alpha, NULL)); 8610f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_alpha2", "alpha2", NULL, kctx->alpha2, &kctx->alpha2, NULL)); 8620f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_threshold", "0 < threshold < 1", NULL, kctx->threshold, &kctx->threshold, NULL)); 8630f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p1", "p1", NULL, kctx->v4_p1, &kctx->v4_p1, NULL)); 8640f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p2", "p2", NULL, kctx->v4_p2, &kctx->v4_p2, NULL)); 8650f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_p3", "p3", NULL, kctx->v4_p3, &kctx->v4_p3, NULL)); 8660f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m1", "Scaling when rk-1 in [p2,p3)", NULL, kctx->v4_m1, &kctx->v4_m1, NULL)); 8670f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m2", "Scaling when rk-1 in [p3,+infty)", NULL, kctx->v4_m2, &kctx->v4_m2, NULL)); 8680f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m3", "Threshold for successive rtol (0.1 in Eq.7)", NULL, kctx->v4_m3, &kctx->v4_m3, NULL)); 8690f0abf79SStefano Zampini PetscCall(PetscOptionsReal("-ksp_ew_v4_m4", "Adaptation scaling (0.5 in Eq.7)", NULL, kctx->v4_m4, &kctx->v4_m4, NULL)); 8700f0abf79SStefano Zampini PetscOptionsEnd(); 8713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 8720f0abf79SStefano Zampini } 8730f0abf79SStefano Zampini 8749b94acceSBarry Smith /*@ 875f6dfbefdSBarry Smith SNESSetFromOptions - Sets various `SNES` and `KSP` parameters from user options. 8769b94acceSBarry Smith 877c3339decSBarry Smith Collective 878c7afd0dbSLois Curfman McInnes 8799b94acceSBarry Smith Input Parameter: 880f6dfbefdSBarry Smith . snes - the `SNES` context 8819b94acceSBarry Smith 88236851e7fSLois Curfman McInnes Options Database Keys: 883f6dfbefdSBarry Smith + -snes_type <type> - newtonls, newtontr, ngmres, ncg, nrichardson, qn, vi, fas, `SNESType` for complete list 88482738288SBarry Smith . -snes_stol - convergence tolerance in terms of the norm 88582738288SBarry Smith of the change in the solution between steps 88670441072SBarry Smith . -snes_atol <abstol> - absolute tolerance of residual norm 887b39c3a46SLois Curfman McInnes . -snes_rtol <rtol> - relative decrease in tolerance norm from initial 888e4d06f11SPatrick Farrell . -snes_divergence_tolerance <divtol> - if the residual goes above divtol*rnorm0, exit with divergence 889be5caee7SBarry Smith . -snes_force_iteration <force> - force SNESSolve() to take at least one iteration 890b39c3a46SLois Curfman McInnes . -snes_max_it <max_it> - maximum number of iterations 891b39c3a46SLois Curfman McInnes . -snes_max_funcs <max_funcs> - maximum number of function evaluations 8924839bfe8SBarry Smith . -snes_max_fail <max_fail> - maximum number of line search failures allowed before stopping, default is none 893ddf469c8SBarry Smith . -snes_max_linear_solve_fail - number of linear solver failures before SNESSolve() stops 894a8054027SBarry Smith . -snes_lag_preconditioner <lag> - how often preconditioner is rebuilt (use -1 to never rebuild) 8953d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - retains the -snes_lag_preconditioner information across multiple SNESSolve() 896e35cf81dSBarry Smith . -snes_lag_jacobian <lag> - how often Jacobian is rebuilt (use -1 to never rebuild) 8973d5a8a6aSBarry Smith . -snes_lag_jacobian_persists <true,false> - retains the -snes_lag_jacobian information across multiple SNESSolve() 8984a221d59SStefano Zampini . -snes_tr_tol <trtol> - trust region tolerance 899f362779dSJed Brown . -snes_convergence_test - <default,skip,correct_pressure> convergence test in nonlinear solver. 900f6dfbefdSBarry Smith default `SNESConvergedDefault()`. skip `SNESConvergedSkip()` means continue iterating until max_it or some other criterion is reached, saving expense 901f6dfbefdSBarry Smith of convergence test. correct_pressure S`NESConvergedCorrectPressure()` has special handling of a pressure null space. 902fde5950dSBarry Smith . -snes_monitor [ascii][:filename][:viewer format] - prints residual norm at each iteration. if no filename given prints to stdout 903fde5950dSBarry Smith . -snes_monitor_solution [ascii binary draw][:filename][:viewer format] - plots solution at each iteration 904fde5950dSBarry Smith . -snes_monitor_residual [ascii binary draw][:filename][:viewer format] - plots residual (not its norm) at each iteration 905fde5950dSBarry Smith . -snes_monitor_solution_update [ascii binary draw][:filename][:viewer format] - plots update to solution at each iteration 9064619e776SBarry Smith . -snes_monitor_lg_residualnorm - plots residual norm at each iteration 907459f5d12SBarry Smith . -snes_monitor_lg_range - plots residual norm at each iteration 9085e7c47f3SMatthew G. Knepley . -snes_monitor_pause_final - Pauses all monitor drawing after the solver ends 909e24b481bSBarry Smith . -snes_fd - use finite differences to compute Jacobian; very slow, only for testing 910e2e60de9SPeter Brune . -snes_fd_color - use finite differences with coloring to compute Jacobian 9115968eb51SBarry Smith . -snes_mf_ksp_monitor - if using matrix-free multiply then print h at each KSP iteration 912b5badacbSBarry Smith . -snes_converged_reason - print the reason for convergence/divergence after each solve 913e62ac41dSBarry Smith . -npc_snes_type <type> - the SNES type to use as a nonlinear preconditioner 914e62ac41dSBarry Smith . -snes_test_jacobian <optional threshold> - compare the user provided Jacobian with one computed via finite differences to check for errors. If a threshold is given, display only those entries whose difference is greater than the threshold. 915e62ac41dSBarry Smith - -snes_test_jacobian_view - display the user provided Jacobian, the finite difference Jacobian and the difference between them to help users detect the location of errors in the user provided Jacobian. 91682738288SBarry Smith 917f6dfbefdSBarry Smith Options Database Keys for Eisenstat-Walker method: 918fa9f3622SBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 9194b27c08aSLois Curfman McInnes . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 92036851e7fSLois Curfman McInnes . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 92136851e7fSLois Curfman McInnes . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 92236851e7fSLois Curfman McInnes . -snes_ksp_ew_gamma <gamma> - Sets gamma 92336851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha <alpha> - Sets alpha 92436851e7fSLois Curfman McInnes . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 92536851e7fSLois Curfman McInnes - -snes_ksp_ew_threshold <threshold> - Sets threshold 92682738288SBarry Smith 927dc4c0fb0SBarry Smith Level: beginner 928dc4c0fb0SBarry Smith 92911ca99fdSLois Curfman McInnes Notes: 930ec5066bdSBarry Smith To see all options, run your program with the -help option or consult the users manual 931ec5066bdSBarry Smith 932f6dfbefdSBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix free, and computing explicitly with 933f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 93483e2fdc7SBarry Smith 935dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESType`, `SNESSetOptionsPrefix()`, `SNESResetFromOptions()`, `SNES`, `SNESCreate()` 9369b94acceSBarry Smith @*/ 937d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFromOptions(SNES snes) 938d71ae5a4SJacob Faibussowitsch { 9398afaa268SBarry Smith PetscBool flg, pcset, persist, set; 940d8f46077SPeter Brune PetscInt i, indx, lag, grids; 94104d7464bSBarry Smith const char *deft = SNESNEWTONLS; 942649ef022SMatthew Knepley const char *convtests[] = {"default", "skip", "correct_pressure"}; 94385385478SLisandro Dalcin SNESKSPEW *kctx = NULL; 9440f0abf79SStefano Zampini char type[256], monfilename[PETSC_MAX_PATH_LEN], ewprefix[256]; 945c40d0f55SPeter Brune PCSide pcside; 946a64e098fSPeter Brune const char *optionsprefix; 9479b94acceSBarry Smith 9483a40ed3dSBarry Smith PetscFunctionBegin; 9490700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 9509566063dSJacob Faibussowitsch PetscCall(SNESRegisterAll()); 951d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 952639ff905SBarry Smith if (((PetscObject)snes)->type_name) deft = ((PetscObject)snes)->type_name; 9539566063dSJacob Faibussowitsch PetscCall(PetscOptionsFList("-snes_type", "Nonlinear solver method", "SNESSetType", SNESList, deft, type, 256, &flg)); 954d64ed03dSBarry Smith if (flg) { 9559566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, type)); 9567adad957SLisandro Dalcin } else if (!((PetscObject)snes)->type_name) { 9579566063dSJacob Faibussowitsch PetscCall(SNESSetType(snes, deft)); 958d64ed03dSBarry Smith } 9599566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_stol", "Stop if step length less than", "SNESSetTolerances", snes->stol, &snes->stol, NULL)); 9609566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_atol", "Stop if function norm less than", "SNESSetTolerances", snes->abstol, &snes->abstol, NULL)); 961186905e3SBarry Smith 9629566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_rtol", "Stop if decrease in function norm less than", "SNESSetTolerances", snes->rtol, &snes->rtol, NULL)); 9639566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_divergence_tolerance", "Stop if residual norm increases by this factor", "SNESSetDivergenceTolerance", snes->divtol, &snes->divtol, NULL)); 9649566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_it", "Maximum iterations", "SNESSetTolerances", snes->max_its, &snes->max_its, NULL)); 9659566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_funcs", "Maximum function evaluations", "SNESSetTolerances", snes->max_funcs, &snes->max_funcs, NULL)); 9669566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_fail", "Maximum nonlinear step failures", "SNESSetMaxNonlinearStepFailures", snes->maxFailures, &snes->maxFailures, NULL)); 9679566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_max_linear_solve_fail", "Maximum failures in linear solves allowed", "SNESSetMaxLinearSolveFailures", snes->maxLinearSolveFailures, &snes->maxLinearSolveFailures, NULL)); 9689566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_error_if_not_converged", "Generate error if solver does not converge", "SNESSetErrorIfNotConverged", snes->errorifnotconverged, &snes->errorifnotconverged, NULL)); 9699566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_force_iteration", "Force SNESSolve() to take at least one iteration", "SNESSetForceIteration", snes->forceiteration, &snes->forceiteration, NULL)); 9709566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_check_jacobian_domain_error", "Check Jacobian domain error after Jacobian evaluation", "SNESCheckJacobianDomainError", snes->checkjacdomainerror, &snes->checkjacdomainerror, NULL)); 97185385478SLisandro Dalcin 9729566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_preconditioner", "How often to rebuild preconditioner", "SNESSetLagPreconditioner", snes->lagpreconditioner, &lag, &flg)); 973a8054027SBarry Smith if (flg) { 9745f80ce2aSJacob Faibussowitsch PetscCheck(lag != -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_USER, "Cannot set the lag to -1 from the command line since the preconditioner must be built as least once, perhaps you mean -2"); 9759566063dSJacob Faibussowitsch PetscCall(SNESSetLagPreconditioner(snes, lag)); 976a8054027SBarry Smith } 9779566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_preconditioner_persists", "Preconditioner lagging through multiple SNES solves", "SNESSetLagPreconditionerPersists", snes->lagjac_persist, &persist, &flg)); 9781baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagPreconditionerPersists(snes, persist)); 9799566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_lag_jacobian", "How often to rebuild Jacobian", "SNESSetLagJacobian", snes->lagjacobian, &lag, &flg)); 980e35cf81dSBarry Smith if (flg) { 9815f80ce2aSJacob Faibussowitsch PetscCheck(lag != -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_USER, "Cannot set the lag to -1 from the command line since the Jacobian must be built as least once, perhaps you mean -2"); 9829566063dSJacob Faibussowitsch PetscCall(SNESSetLagJacobian(snes, lag)); 983e35cf81dSBarry Smith } 9849566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_lag_jacobian_persists", "Jacobian lagging through multiple SNES solves", "SNESSetLagJacobianPersists", snes->lagjac_persist, &persist, &flg)); 9851baa6e33SBarry Smith if (flg) PetscCall(SNESSetLagJacobianPersists(snes, persist)); 98637ec4e1aSPeter Brune 9879566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_grid_sequence", "Use grid sequencing to generate initial guess", "SNESSetGridSequence", snes->gridsequence, &grids, &flg)); 9881baa6e33SBarry Smith if (flg) PetscCall(SNESSetGridSequence(snes, grids)); 989a8054027SBarry Smith 9909566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_convergence_test", "Convergence test", "SNESSetConvergenceTest", convtests, sizeof(convtests) / sizeof(char *), "default", &indx, &flg)); 99185385478SLisandro Dalcin if (flg) { 99285385478SLisandro Dalcin switch (indx) { 993d71ae5a4SJacob Faibussowitsch case 0: 994d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedDefault, NULL, NULL)); 995d71ae5a4SJacob Faibussowitsch break; 996d71ae5a4SJacob Faibussowitsch case 1: 997d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedSkip, NULL, NULL)); 998d71ae5a4SJacob Faibussowitsch break; 999d71ae5a4SJacob Faibussowitsch case 2: 1000d71ae5a4SJacob Faibussowitsch PetscCall(SNESSetConvergenceTest(snes, SNESConvergedCorrectPressure, NULL, NULL)); 1001d71ae5a4SJacob Faibussowitsch break; 100285385478SLisandro Dalcin } 100385385478SLisandro Dalcin } 100485385478SLisandro Dalcin 10059566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_norm_schedule", "SNES Norm schedule", "SNESSetNormSchedule", SNESNormSchedules, 5, "function", &indx, &flg)); 10069566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNormSchedule(snes, (SNESNormSchedule)indx)); 1007fdacfa88SPeter Brune 10089566063dSJacob Faibussowitsch PetscCall(PetscOptionsEList("-snes_function_type", "SNES Norm schedule", "SNESSetFunctionType", SNESFunctionTypes, 2, "unpreconditioned", &indx, &flg)); 10099566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetFunctionType(snes, (SNESFunctionType)indx)); 1010186905e3SBarry Smith 101185385478SLisandro Dalcin kctx = (SNESKSPEW *)snes->kspconvctx; 101285385478SLisandro Dalcin 10139566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_ksp_ew", "Use Eisentat-Walker linear system convergence test", "SNESKSPSetUseEW", snes->ksp_ewconv, &snes->ksp_ewconv, NULL)); 1014186905e3SBarry Smith 10150f0abf79SStefano Zampini PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 10160f0abf79SStefano Zampini PetscCall(PetscSNPrintf(ewprefix, sizeof(ewprefix), "%s%s", optionsprefix ? optionsprefix : "", "snes_")); 10170f0abf79SStefano Zampini PetscCall(SNESEWSetFromOptions_Private(kctx, PetscObjectComm((PetscObject)snes), ewprefix)); 10180f0abf79SStefano Zampini 10199566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_ksp_ew_version", "Version 1, 2 or 3", "SNESKSPSetParametersEW", kctx->version, &kctx->version, NULL)); 10209566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtol0", "0 <= rtol0 < 1", "SNESKSPSetParametersEW", kctx->rtol_0, &kctx->rtol_0, NULL)); 10219566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_rtolmax", "0 <= rtolmax < 1", "SNESKSPSetParametersEW", kctx->rtol_max, &kctx->rtol_max, NULL)); 10229566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_gamma", "0 <= gamma <= 1", "SNESKSPSetParametersEW", kctx->gamma, &kctx->gamma, NULL)); 10239566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha", "1 < alpha <= 2", "SNESKSPSetParametersEW", kctx->alpha, &kctx->alpha, NULL)); 10249566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_alpha2", "alpha2", "SNESKSPSetParametersEW", kctx->alpha2, &kctx->alpha2, NULL)); 10259566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_ksp_ew_threshold", "0 < threshold < 1", "SNESKSPSetParametersEW", kctx->threshold, &kctx->threshold, NULL)); 1026186905e3SBarry Smith 102790d69ab7SBarry Smith flg = PETSC_FALSE; 10289566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_cancel", "Remove all monitors", "SNESMonitorCancel", flg, &flg, &set)); 10299566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESMonitorCancel(snes)); 1030eabae89aSBarry Smith 10319566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor", "Monitor norm of function", "SNESMonitorDefault", SNESMonitorDefault, SNESMonitorDefaultSetUp)); 10329566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_short", "Monitor norm of function with fewer digits", "SNESMonitorDefaultShort", SNESMonitorDefaultShort, NULL)); 10339566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_range", "Monitor range of elements of function", "SNESMonitorRange", SNESMonitorRange, NULL)); 1034eabae89aSBarry Smith 10359566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_ratio", "Monitor ratios of the norm of function for consecutive steps", "SNESMonitorRatio", SNESMonitorRatio, SNESMonitorRatioSetUp)); 10369566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_field", "Monitor norm of function (split into fields)", "SNESMonitorDefaultField", SNESMonitorDefaultField, NULL)); 10379566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution", "View solution at each iteration", "SNESMonitorSolution", SNESMonitorSolution, NULL)); 10389566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_solution_update", "View correction at each iteration", "SNESMonitorSolutionUpdate", SNESMonitorSolutionUpdate, NULL)); 10399566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_residual", "View residual at each iteration", "SNESMonitorResidual", SNESMonitorResidual, NULL)); 10409566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_jacupdate_spectrum", "Print the change in the spectrum of the Jacobian", "SNESMonitorJacUpdateSpectrum", SNESMonitorJacUpdateSpectrum, NULL)); 10419566063dSJacob Faibussowitsch PetscCall(SNESMonitorSetFromOptions(snes, "-snes_monitor_fields", "Monitor norm of function per field", "SNESMonitorSet", SNESMonitorFields, NULL)); 10429566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_pause_final", "Pauses all draw monitors at the final iterate", "SNESMonitorPauseFinal_Internal", PETSC_FALSE, &snes->pauseFinal, NULL)); 10432db13446SMatthew G. Knepley 10449566063dSJacob Faibussowitsch PetscCall(PetscOptionsString("-snes_monitor_python", "Use Python function", "SNESMonitorSet", NULL, monfilename, sizeof(monfilename), &flg)); 10459566063dSJacob Faibussowitsch if (flg) PetscCall(PetscPythonMonitorSet((PetscObject)snes, monfilename)); 10465180491cSLisandro Dalcin 104790d69ab7SBarry Smith flg = PETSC_FALSE; 10489566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_lg_range", "Plot function range at each iteration", "SNESMonitorLGRange", flg, &flg, NULL)); 1049459f5d12SBarry Smith if (flg) { 1050459f5d12SBarry Smith PetscViewer ctx; 1051e24b481bSBarry Smith 10529566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, NULL, PETSC_DECIDE, PETSC_DECIDE, 400, 300, &ctx)); 10539566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorLGRange, ctx, (PetscErrorCode(*)(void **))PetscViewerDestroy)); 1054459f5d12SBarry Smith } 10552e7541e6SPeter Brune 105690d69ab7SBarry Smith flg = PETSC_FALSE; 10579566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_converged_reason_view_cancel", "Remove all converged reason viewers", "SNESConvergedReasonViewCancel", flg, &flg, &set)); 10589566063dSJacob Faibussowitsch if (set && flg) PetscCall(SNESConvergedReasonViewCancel(snes)); 1059c4421ceaSFande Kong 1060c4421ceaSFande Kong flg = PETSC_FALSE; 10619566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd", "Use finite differences (slow) to compute Jacobian", "SNESComputeJacobianDefault", flg, &flg, NULL)); 10624b27c08aSLois Curfman McInnes if (flg) { 10636cab3a1bSJed Brown void *functx; 1064b1f624c7SBarry Smith DM dm; 10659566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1066800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10679566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 10689566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefault, functx)); 10699566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference Jacobian matrix\n")); 10709b94acceSBarry Smith } 1071639f9d9dSBarry Smith 107244848bc4SPeter Brune flg = PETSC_FALSE; 10739566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_function", "Use finite differences (slow) to compute function from user objective", "SNESObjectiveComputeFunctionDefaultFD", flg, &flg, NULL)); 10741baa6e33SBarry Smith if (flg) PetscCall(SNESSetFunction(snes, NULL, SNESObjectiveComputeFunctionDefaultFD, NULL)); 107597584545SPeter Brune 107697584545SPeter Brune flg = PETSC_FALSE; 10779566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_fd_color", "Use finite differences with coloring to compute Jacobian", "SNESComputeJacobianDefaultColor", flg, &flg, NULL)); 107844848bc4SPeter Brune if (flg) { 1079c52e227fSPeter Brune DM dm; 10809566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 1081800f99ffSJeremy L Thompson PetscCall(DMSNESUnsetJacobianContext_Internal(dm)); 10829566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, snes->jacobian, snes->jacobian_pre, SNESComputeJacobianDefaultColor, NULL)); 10839566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Setting default finite difference coloring Jacobian matrix\n")); 108444848bc4SPeter Brune } 108544848bc4SPeter Brune 1086aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10879566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf_operator", "Use a Matrix-Free Jacobian with user-provided preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf_operator, &flg)); 1088d8f46077SPeter Brune if (flg && snes->mf_operator) { 1089a8248277SBarry Smith snes->mf_operator = PETSC_TRUE; 1090d8f46077SPeter Brune snes->mf = PETSC_TRUE; 1091a8248277SBarry Smith } 1092aa3661deSLisandro Dalcin flg = PETSC_FALSE; 10939566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_mf", "Use a Matrix-Free Jacobian with no preconditioner matrix", "SNESSetUseMatrixFree", PETSC_FALSE, &snes->mf, &flg)); 1094d8f46077SPeter Brune if (!flg && snes->mf_operator) snes->mf = PETSC_TRUE; 10959566063dSJacob Faibussowitsch PetscCall(PetscOptionsInt("-snes_mf_version", "Matrix-Free routines version 1 or 2", "None", snes->mf_version, &snes->mf_version, NULL)); 1096d28543b3SPeter Brune 1097c40d0f55SPeter Brune flg = PETSC_FALSE; 10989566063dSJacob Faibussowitsch PetscCall(SNESGetNPCSide(snes, &pcside)); 10999566063dSJacob Faibussowitsch PetscCall(PetscOptionsEnum("-snes_npc_side", "SNES nonlinear preconditioner side", "SNESSetNPCSide", PCSides, (PetscEnum)pcside, (PetscEnum *)&pcside, &flg)); 11009566063dSJacob Faibussowitsch if (flg) PetscCall(SNESSetNPCSide(snes, pcside)); 1101c40d0f55SPeter Brune 1102e04113cfSBarry Smith #if defined(PETSC_HAVE_SAWS) 11038a70d858SHong Zhang /* 11048a70d858SHong Zhang Publish convergence information using SAWs 11058a70d858SHong Zhang */ 11068a70d858SHong Zhang flg = PETSC_FALSE; 11079566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_monitor_saws", "Publish SNES progress using SAWs", "SNESMonitorSet", flg, &flg, NULL)); 11088a70d858SHong Zhang if (flg) { 11098a70d858SHong Zhang void *ctx; 11109566063dSJacob Faibussowitsch PetscCall(SNESMonitorSAWsCreate(snes, &ctx)); 11119566063dSJacob Faibussowitsch PetscCall(SNESMonitorSet(snes, SNESMonitorSAWs, ctx, SNESMonitorSAWsDestroy)); 11128a70d858SHong Zhang } 11138a70d858SHong Zhang #endif 11148a70d858SHong Zhang #if defined(PETSC_HAVE_SAWS) 1115b90c6cbeSBarry Smith { 1116b90c6cbeSBarry Smith PetscBool set; 1117b90c6cbeSBarry Smith flg = PETSC_FALSE; 11189566063dSJacob Faibussowitsch PetscCall(PetscOptionsBool("-snes_saws_block", "Block for SAWs at end of SNESSolve", "PetscObjectSAWsBlock", ((PetscObject)snes)->amspublishblock, &flg, &set)); 11191baa6e33SBarry Smith if (set) PetscCall(PetscObjectSAWsSetBlock((PetscObject)snes, flg)); 1120b90c6cbeSBarry Smith } 1121b90c6cbeSBarry Smith #endif 1122b90c6cbeSBarry Smith 112348a46eb9SPierre Jolivet for (i = 0; i < numberofsetfromoptions; i++) PetscCall((*othersetfromoptions[i])(snes)); 112476b2cf59SMatthew Knepley 1125dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setfromoptions, PetscOptionsObject); 11265d973c19SBarry Smith 11275d973c19SBarry Smith /* process any options handlers added with PetscObjectAddOptionsHandler() */ 1128dbbe0bcdSBarry Smith PetscCall(PetscObjectProcessOptionsHandlers((PetscObject)snes, PetscOptionsObject)); 1129d0609cedSBarry Smith PetscOptionsEnd(); 11304bbc92c1SBarry Smith 1131d8d34be6SBarry Smith if (snes->linesearch) { 11329566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 11339566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFromOptions(snes->linesearch)); 1134d8d34be6SBarry Smith } 11359e764e56SPeter Brune 11366aa5e7e9SBarry Smith if (snes->usesksp) { 11379566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 11389566063dSJacob Faibussowitsch PetscCall(KSPSetOperators(snes->ksp, snes->jacobian, snes->jacobian_pre)); 11399566063dSJacob Faibussowitsch PetscCall(KSPSetFromOptions(snes->ksp)); 11406aa5e7e9SBarry Smith } 11416991f827SBarry Smith 1142b5badacbSBarry Smith /* if user has set the SNES NPC type via options database, create it. */ 11439566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 11449566063dSJacob Faibussowitsch PetscCall(PetscOptionsHasName(((PetscObject)snes)->options, optionsprefix, "-npc_snes_type", &pcset)); 114548a46eb9SPierre Jolivet if (pcset && (!snes->npc)) PetscCall(SNESGetNPC(snes, &snes->npc)); 11461baa6e33SBarry Smith if (snes->npc) PetscCall(SNESSetFromOptions(snes->npc)); 1147b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled++; 11483ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1149b3cd9a81SMatthew G. Knepley } 1150b3cd9a81SMatthew G. Knepley 1151b3cd9a81SMatthew G. Knepley /*@ 1152f6dfbefdSBarry Smith SNESResetFromOptions - Sets various `SNES` and `KSP` parameters from user options ONLY if the `SNESSetFromOptions()` was previously set from options 1153b3cd9a81SMatthew G. Knepley 1154c3339decSBarry Smith Collective 1155b3cd9a81SMatthew G. Knepley 1156b3cd9a81SMatthew G. Knepley Input Parameter: 1157f6dfbefdSBarry Smith . snes - the `SNES` context 1158b3cd9a81SMatthew G. Knepley 1159b3cd9a81SMatthew G. Knepley Level: beginner 1160b3cd9a81SMatthew G. Knepley 1161dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()`, `SNESSetOptionsPrefix()` 1162b3cd9a81SMatthew G. Knepley @*/ 1163d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESResetFromOptions(SNES snes) 1164d71ae5a4SJacob Faibussowitsch { 1165b3cd9a81SMatthew G. Knepley PetscFunctionBegin; 11669566063dSJacob Faibussowitsch if (snes->setfromoptionscalled) PetscCall(SNESSetFromOptions(snes)); 11673ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 11689b94acceSBarry Smith } 11699b94acceSBarry Smith 1170bb9467b5SJed Brown /*@C 1171d25893d9SBarry Smith SNESSetComputeApplicationContext - Sets an optional function to compute a user-defined context for 1172d25893d9SBarry Smith the nonlinear solvers. 1173d25893d9SBarry Smith 1174dc4c0fb0SBarry Smith Logically Collective; No Fortran Support 1175d25893d9SBarry Smith 1176d25893d9SBarry Smith Input Parameters: 1177f6dfbefdSBarry Smith + snes - the `SNES` context 1178d25893d9SBarry Smith . compute - function to compute the context 1179d25893d9SBarry Smith - destroy - function to destroy the context 1180d25893d9SBarry Smith 1181d25893d9SBarry Smith Level: intermediate 1182d25893d9SBarry Smith 1183f6dfbefdSBarry Smith Note: 1184f6dfbefdSBarry Smith This routine is useful if you are performing grid sequencing or using `SNESFAS` and need the appropriate context generated for each level. 1185f6dfbefdSBarry Smith 1186f6dfbefdSBarry Smith Use `SNESSetApplicationContext()` to see the context immediately 1187f6dfbefdSBarry Smith 1188dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetApplicationContext()`, `SNESSetComputeApplicationContext()`, `SNESSetApplicationContext()` 1189d25893d9SBarry Smith @*/ 1190d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeApplicationContext(SNES snes, PetscErrorCode (*compute)(SNES, void **), PetscErrorCode (*destroy)(void **)) 1191d71ae5a4SJacob Faibussowitsch { 1192d25893d9SBarry Smith PetscFunctionBegin; 1193d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1194d25893d9SBarry Smith snes->ops->usercompute = compute; 1195d25893d9SBarry Smith snes->ops->userdestroy = destroy; 11963ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1197d25893d9SBarry Smith } 1198a847f771SSatish Balay 1199b07ff414SBarry Smith /*@ 1200f6dfbefdSBarry Smith SNESSetApplicationContext - Sets the optional user-defined context for the nonlinear solvers. 12019b94acceSBarry Smith 1202c3339decSBarry Smith Logically Collective 1203fee21e36SBarry Smith 1204c7afd0dbSLois Curfman McInnes Input Parameters: 1205f6dfbefdSBarry Smith + snes - the `SNES` context 1206c7afd0dbSLois Curfman McInnes - usrP - optional user context 1207c7afd0dbSLois Curfman McInnes 120836851e7fSLois Curfman McInnes Level: intermediate 120936851e7fSLois Curfman McInnes 1210f6dfbefdSBarry Smith Notes: 1211f6dfbefdSBarry Smith Users can provide a context when constructing the `SNES` options and then access it inside their function, Jacobian, or other evaluation function 1212f6dfbefdSBarry Smith with `SNESGetApplicationContext()` 1213f6dfbefdSBarry Smith 1214f6dfbefdSBarry Smith To provide a function that computes the context for you use `SNESSetComputeApplicationContext()` 1215f6dfbefdSBarry Smith 1216f6dfbefdSBarry Smith Fortran Note: 1217dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1218daf670e6SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1219daf670e6SBarry Smith 1220dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetComputeApplicationContext()`, `SNESGetApplicationContext()` 12219b94acceSBarry Smith @*/ 1222d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetApplicationContext(SNES snes, void *usrP) 1223d71ae5a4SJacob Faibussowitsch { 1224b07ff414SBarry Smith KSP ksp; 12251b2093e4SBarry Smith 12263a40ed3dSBarry Smith PetscFunctionBegin; 12270700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 12289566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 12299566063dSJacob Faibussowitsch PetscCall(KSPSetApplicationContext(ksp, usrP)); 12309b94acceSBarry Smith snes->user = usrP; 12313ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12329b94acceSBarry Smith } 123374679c65SBarry Smith 1234b07ff414SBarry Smith /*@ 12359b94acceSBarry Smith SNESGetApplicationContext - Gets the user-defined context for the 1236f6dfbefdSBarry Smith nonlinear solvers set with `SNESGetApplicationContext()` or with `SNESSetComputeApplicationContext()` 12379b94acceSBarry Smith 1238c7afd0dbSLois Curfman McInnes Not Collective 1239c7afd0dbSLois Curfman McInnes 12409b94acceSBarry Smith Input Parameter: 1241f6dfbefdSBarry Smith . snes - `SNES` context 12429b94acceSBarry Smith 12439b94acceSBarry Smith Output Parameter: 12449b94acceSBarry Smith . usrP - user context 12459b94acceSBarry Smith 124636851e7fSLois Curfman McInnes Level: intermediate 124736851e7fSLois Curfman McInnes 1248dc4c0fb0SBarry Smith Fortran Note: 1249dc4c0fb0SBarry Smith You must write a Fortran interface definition for this 1250dc4c0fb0SBarry Smith function that tells Fortran the Fortran derived data type that you are passing in as the ctx argument. 1251dc4c0fb0SBarry Smith 1252dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetApplicationContext()` 12539b94acceSBarry Smith @*/ 1254d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetApplicationContext(SNES snes, void *usrP) 1255d71ae5a4SJacob Faibussowitsch { 12563a40ed3dSBarry Smith PetscFunctionBegin; 12570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1258e71120c6SJed Brown *(void **)usrP = snes->user; 12593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12609b94acceSBarry Smith } 126174679c65SBarry Smith 12629b94acceSBarry Smith /*@ 1263f6dfbefdSBarry Smith SNESSetUseMatrixFree - indicates that `SNES` should use matrix free finite difference matrix vector products to apply the Jacobian. 12643565c898SBarry Smith 1265dc4c0fb0SBarry Smith Logically Collective 12663565c898SBarry Smith 12673565c898SBarry Smith Input Parameters: 1268f6dfbefdSBarry Smith + snes - `SNES` context 1269f6dfbefdSBarry Smith . mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1270f6dfbefdSBarry Smith - mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored. With 1271f6dfbefdSBarry Smith this option no matrix element based preconditioners can be used in the linear solve since the matrix won't be explicitly available 12723565c898SBarry Smith 1273f6dfbefdSBarry Smith Options Database Keys: 1274f6dfbefdSBarry Smith + -snes_mf_operator - use matrix free only for the mat operator 1275f6dfbefdSBarry Smith . -snes_mf - use matrix-free for both the mat and pmat operator 1276ec5066bdSBarry Smith . -snes_fd_color - compute the Jacobian via coloring and finite differences. 1277ec5066bdSBarry Smith - -snes_fd - compute the Jacobian via finite differences (slow) 12783565c898SBarry Smith 12793565c898SBarry Smith Level: intermediate 12803565c898SBarry Smith 1281f6dfbefdSBarry Smith Note: 1282dc4c0fb0SBarry Smith `SNES` supports three approaches for computing (approximate) Jacobians: user provided via `SNESSetJacobian()`, matrix-free, and computing explicitly with 1283f6dfbefdSBarry Smith finite differences and coloring using `MatFDColoring`. It is also possible to use automatic differentiation and the `MatFDColoring` object. 1284ec5066bdSBarry Smith 1285dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetUseMatrixFree()`, `MatCreateSNESMF()`, `SNESComputeJacobianDefaultColor()` 12863565c898SBarry Smith @*/ 1287d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUseMatrixFree(SNES snes, PetscBool mf_operator, PetscBool mf) 1288d71ae5a4SJacob Faibussowitsch { 12893565c898SBarry Smith PetscFunctionBegin; 12903565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 129188b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf_operator, 2); 129288b4c220SStefano Zampini PetscValidLogicalCollectiveBool(snes, mf, 3); 12934ddffce6SLisandro Dalcin snes->mf = mf_operator ? PETSC_TRUE : mf; 12943565c898SBarry Smith snes->mf_operator = mf_operator; 12953ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 12963565c898SBarry Smith } 12973565c898SBarry Smith 12983565c898SBarry Smith /*@ 1299dc4c0fb0SBarry Smith SNESGetUseMatrixFree - indicates if the `SNES` uses matrix-free finite difference matrix vector products to apply the Jacobian. 13003565c898SBarry Smith 1301f6dfbefdSBarry Smith Not Collective, but the resulting flags will be the same on all MPI ranks 13023565c898SBarry Smith 13033565c898SBarry Smith Input Parameter: 1304f6dfbefdSBarry Smith . snes - `SNES` context 13053565c898SBarry Smith 13063565c898SBarry Smith Output Parameters: 1307f6dfbefdSBarry Smith + mf_operator - use matrix-free only for the Amat used by `SNESSetJacobian()`, this means the user provided Pmat will continue to be used 1308f6dfbefdSBarry Smith - mf - use matrix-free for both the Amat and Pmat used by `SNESSetJacobian()`, both the Amat and Pmat set in `SNESSetJacobian()` will be ignored 13093565c898SBarry Smith 13103565c898SBarry Smith Level: intermediate 13113565c898SBarry Smith 1312dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetUseMatrixFree()`, `MatCreateSNESMF()` 13133565c898SBarry Smith @*/ 1314d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUseMatrixFree(SNES snes, PetscBool *mf_operator, PetscBool *mf) 1315d71ae5a4SJacob Faibussowitsch { 13163565c898SBarry Smith PetscFunctionBegin; 13173565c898SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13183565c898SBarry Smith if (mf) *mf = snes->mf; 13193565c898SBarry Smith if (mf_operator) *mf_operator = snes->mf_operator; 13203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13213565c898SBarry Smith } 13223565c898SBarry Smith 13233565c898SBarry Smith /*@ 1324c8228a4eSBarry Smith SNESGetIterationNumber - Gets the number of nonlinear iterations completed 1325c8228a4eSBarry Smith at this time. 13269b94acceSBarry Smith 1327c7afd0dbSLois Curfman McInnes Not Collective 1328c7afd0dbSLois Curfman McInnes 13299b94acceSBarry Smith Input Parameter: 1330f6dfbefdSBarry Smith . snes - `SNES` context 13319b94acceSBarry Smith 13329b94acceSBarry Smith Output Parameter: 13339b94acceSBarry Smith . iter - iteration number 13349b94acceSBarry Smith 1335dc4c0fb0SBarry Smith Level: intermediate 1336dc4c0fb0SBarry Smith 1337c8228a4eSBarry Smith Notes: 1338c8228a4eSBarry Smith For example, during the computation of iteration 2 this would return 1. 1339c8228a4eSBarry Smith 1340c8228a4eSBarry Smith This is useful for using lagged Jacobians (where one does not recompute the 1341f6dfbefdSBarry Smith Jacobian at each `SNES` iteration). For example, the code 134208405cd6SLois Curfman McInnes .vb 134308405cd6SLois Curfman McInnes ierr = SNESGetIterationNumber(snes,&it); 134408405cd6SLois Curfman McInnes if (!(it % 2)) { 134508405cd6SLois Curfman McInnes [compute Jacobian here] 134608405cd6SLois Curfman McInnes } 134708405cd6SLois Curfman McInnes .ve 1348f6dfbefdSBarry Smith can be used in your function that computes the Jacobian to cause the Jacobian to be 1349f6dfbefdSBarry Smith recomputed every second `SNES` iteration. See also `SNESSetLagJacobian()` 1350c8228a4eSBarry Smith 1351f6dfbefdSBarry Smith After the `SNES` solve is complete this will return the number of nonlinear iterations used. 1352c04deec6SBarry Smith 1353dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetLagJacobian()`, `SNESGetLinearSolveIterations()` 13549b94acceSBarry Smith @*/ 1355d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetIterationNumber(SNES snes, PetscInt *iter) 1356d71ae5a4SJacob Faibussowitsch { 13573a40ed3dSBarry Smith PetscFunctionBegin; 13580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13594482741eSBarry Smith PetscValidIntPointer(iter, 2); 13609b94acceSBarry Smith *iter = snes->iter; 13613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 13629b94acceSBarry Smith } 136374679c65SBarry Smith 1364360c497dSPeter Brune /*@ 1365360c497dSPeter Brune SNESSetIterationNumber - Sets the current iteration number. 1366360c497dSPeter Brune 1367360c497dSPeter Brune Not Collective 1368360c497dSPeter Brune 1369d8d19677SJose E. Roman Input Parameters: 1370f6dfbefdSBarry Smith + snes - `SNES` context 1371a2b725a8SWilliam Gropp - iter - iteration number 1372360c497dSPeter Brune 1373360c497dSPeter Brune Level: developer 1374360c497dSPeter Brune 1375dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetLinearSolveIterations()` 1376360c497dSPeter Brune @*/ 1377d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetIterationNumber(SNES snes, PetscInt iter) 1378d71ae5a4SJacob Faibussowitsch { 1379360c497dSPeter Brune PetscFunctionBegin; 1380360c497dSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 13819566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsTakeAccess((PetscObject)snes)); 1382360c497dSPeter Brune snes->iter = iter; 13839566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsGrantAccess((PetscObject)snes)); 13843ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1385360c497dSPeter Brune } 1386360c497dSPeter Brune 13879b94acceSBarry Smith /*@ 1388b850b91aSLisandro Dalcin SNESGetNonlinearStepFailures - Gets the number of unsuccessful steps 13899b94acceSBarry Smith attempted by the nonlinear solver. 13909b94acceSBarry Smith 1391c7afd0dbSLois Curfman McInnes Not Collective 1392c7afd0dbSLois Curfman McInnes 13939b94acceSBarry Smith Input Parameter: 1394f6dfbefdSBarry Smith . snes - `SNES` context 13959b94acceSBarry Smith 13969b94acceSBarry Smith Output Parameter: 13979b94acceSBarry Smith . nfails - number of unsuccessful steps attempted 13989b94acceSBarry Smith 1399dc4c0fb0SBarry Smith Level: intermediate 1400dc4c0fb0SBarry Smith 1401f6dfbefdSBarry Smith Note: 1402f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 1403c96a6f78SLois Curfman McInnes 1404dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1405db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetMaxNonlinearStepFailures()` 14069b94acceSBarry Smith @*/ 1407d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNonlinearStepFailures(SNES snes, PetscInt *nfails) 1408d71ae5a4SJacob Faibussowitsch { 14093a40ed3dSBarry Smith PetscFunctionBegin; 14100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14114482741eSBarry Smith PetscValidIntPointer(nfails, 2); 141250ffb88aSMatthew Knepley *nfails = snes->numFailures; 14133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 141450ffb88aSMatthew Knepley } 141550ffb88aSMatthew Knepley 141650ffb88aSMatthew Knepley /*@ 1417b850b91aSLisandro Dalcin SNESSetMaxNonlinearStepFailures - Sets the maximum number of unsuccessful steps 1418f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 141950ffb88aSMatthew Knepley 142050ffb88aSMatthew Knepley Not Collective 142150ffb88aSMatthew Knepley 142250ffb88aSMatthew Knepley Input Parameters: 1423f6dfbefdSBarry Smith + snes - `SNES` context 142450ffb88aSMatthew Knepley - maxFails - maximum of unsuccessful steps 142550ffb88aSMatthew Knepley 142650ffb88aSMatthew Knepley Level: intermediate 142750ffb88aSMatthew Knepley 1428dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1429db781477SPatrick Sanan `SNESGetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 143050ffb88aSMatthew Knepley @*/ 1431d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxNonlinearStepFailures(SNES snes, PetscInt maxFails) 1432d71ae5a4SJacob Faibussowitsch { 143350ffb88aSMatthew Knepley PetscFunctionBegin; 14340700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 143550ffb88aSMatthew Knepley snes->maxFailures = maxFails; 14363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 143750ffb88aSMatthew Knepley } 143850ffb88aSMatthew Knepley 143950ffb88aSMatthew Knepley /*@ 1440b850b91aSLisandro Dalcin SNESGetMaxNonlinearStepFailures - Gets the maximum number of unsuccessful steps 1441f6dfbefdSBarry Smith attempted by the nonlinear solver before it gives up and generates an error 144250ffb88aSMatthew Knepley 144350ffb88aSMatthew Knepley Not Collective 144450ffb88aSMatthew Knepley 144550ffb88aSMatthew Knepley Input Parameter: 144620f4b53cSBarry Smith . snes - `SNES` context 144750ffb88aSMatthew Knepley 144850ffb88aSMatthew Knepley Output Parameter: 144950ffb88aSMatthew Knepley . maxFails - maximum of unsuccessful steps 145050ffb88aSMatthew Knepley 145150ffb88aSMatthew Knepley Level: intermediate 145250ffb88aSMatthew Knepley 1453dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, 1454db781477SPatrick Sanan `SNESSetMaxNonlinearStepFailures()`, `SNESGetNonlinearStepFailures()` 145550ffb88aSMatthew Knepley @*/ 1456d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxNonlinearStepFailures(SNES snes, PetscInt *maxFails) 1457d71ae5a4SJacob Faibussowitsch { 145850ffb88aSMatthew Knepley PetscFunctionBegin; 14590700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14604482741eSBarry Smith PetscValidIntPointer(maxFails, 2); 146150ffb88aSMatthew Knepley *maxFails = snes->maxFailures; 14623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14639b94acceSBarry Smith } 1464a847f771SSatish Balay 14652541af92SBarry Smith /*@ 14662541af92SBarry Smith SNESGetNumberFunctionEvals - Gets the number of user provided function evaluations 1467f6dfbefdSBarry Smith done by the `SNES` object 14682541af92SBarry Smith 14692541af92SBarry Smith Not Collective 14702541af92SBarry Smith 14712541af92SBarry Smith Input Parameter: 1472f6dfbefdSBarry Smith . snes - `SNES` context 14732541af92SBarry Smith 14742541af92SBarry Smith Output Parameter: 14752541af92SBarry Smith . nfuncs - number of evaluations 14762541af92SBarry Smith 14772541af92SBarry Smith Level: intermediate 14782541af92SBarry Smith 1479f6dfbefdSBarry Smith Note: 1480f6dfbefdSBarry Smith Reset every time `SNESSolve()` is called unless `SNESSetCountersReset()` is used. 1481971e163fSPeter Brune 1482dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, `SNESGetLinearSolveFailures()`, `SNESSetCountersReset()` 14832541af92SBarry Smith @*/ 1484d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNumberFunctionEvals(SNES snes, PetscInt *nfuncs) 1485d71ae5a4SJacob Faibussowitsch { 14862541af92SBarry Smith PetscFunctionBegin; 14870700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 14882541af92SBarry Smith PetscValidIntPointer(nfuncs, 2); 14892541af92SBarry Smith *nfuncs = snes->nfuncs; 14903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 14912541af92SBarry Smith } 14922541af92SBarry Smith 14933d4c4710SBarry Smith /*@ 14943d4c4710SBarry Smith SNESGetLinearSolveFailures - Gets the number of failed (non-converged) 14953d4c4710SBarry Smith linear solvers. 14963d4c4710SBarry Smith 14973d4c4710SBarry Smith Not Collective 14983d4c4710SBarry Smith 14993d4c4710SBarry Smith Input Parameter: 1500f6dfbefdSBarry Smith . snes - `SNES` context 15013d4c4710SBarry Smith 15023d4c4710SBarry Smith Output Parameter: 15033d4c4710SBarry Smith . nfails - number of failed solves 15043d4c4710SBarry Smith 1505f6dfbefdSBarry Smith Options Database Key: 15069d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15079d85da0cSMatthew G. Knepley 1508f6dfbefdSBarry Smith Level: intermediate 1509f6dfbefdSBarry Smith 1510f6dfbefdSBarry Smith Note: 1511f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()`. 15123d4c4710SBarry Smith 1513dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()` 15143d4c4710SBarry Smith @*/ 1515d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveFailures(SNES snes, PetscInt *nfails) 1516d71ae5a4SJacob Faibussowitsch { 15173d4c4710SBarry Smith PetscFunctionBegin; 15180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15193d4c4710SBarry Smith PetscValidIntPointer(nfails, 2); 15203d4c4710SBarry Smith *nfails = snes->numLinearSolveFailures; 15213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15223d4c4710SBarry Smith } 15233d4c4710SBarry Smith 15243d4c4710SBarry Smith /*@ 15253d4c4710SBarry Smith SNESSetMaxLinearSolveFailures - the number of failed linear solve attempts 1526f6dfbefdSBarry Smith allowed before `SNES` returns with a diverged reason of `SNES_DIVERGED_LINEAR_SOLVE` 15273d4c4710SBarry Smith 1528c3339decSBarry Smith Logically Collective 15293d4c4710SBarry Smith 15303d4c4710SBarry Smith Input Parameters: 1531f6dfbefdSBarry Smith + snes - `SNES` context 15323d4c4710SBarry Smith - maxFails - maximum allowed linear solve failures 15333d4c4710SBarry Smith 1534f6dfbefdSBarry Smith Options Database Key: 15359d85da0cSMatthew G. Knepley . -snes_max_linear_solve_fail <num> - The number of failures before the solve is terminated 15369d85da0cSMatthew G. Knepley 1537dc4c0fb0SBarry Smith Level: intermediate 1538dc4c0fb0SBarry Smith 1539f6dfbefdSBarry Smith Note: 1540f6dfbefdSBarry Smith By default this is 0; that is `SNES` returns on the first failed linear solve 15413d4c4710SBarry Smith 1542dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESGetLinearSolveIterations()` 15433d4c4710SBarry Smith @*/ 1544d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetMaxLinearSolveFailures(SNES snes, PetscInt maxFails) 1545d71ae5a4SJacob Faibussowitsch { 15463d4c4710SBarry Smith PetscFunctionBegin; 15470700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1548c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxFails, 2); 15493d4c4710SBarry Smith snes->maxLinearSolveFailures = maxFails; 15503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15513d4c4710SBarry Smith } 15523d4c4710SBarry Smith 15533d4c4710SBarry Smith /*@ 15543d4c4710SBarry Smith SNESGetMaxLinearSolveFailures - gets the maximum number of linear solve failures that 1555f6dfbefdSBarry Smith are allowed before `SNES` returns as unsuccessful 15563d4c4710SBarry Smith 15573d4c4710SBarry Smith Not Collective 15583d4c4710SBarry Smith 15593d4c4710SBarry Smith Input Parameter: 1560f6dfbefdSBarry Smith . snes - `SNES` context 15613d4c4710SBarry Smith 15623d4c4710SBarry Smith Output Parameter: 15633d4c4710SBarry Smith . maxFails - maximum of unsuccessful solves allowed 15643d4c4710SBarry Smith 15653d4c4710SBarry Smith Level: intermediate 15663d4c4710SBarry Smith 1567f6dfbefdSBarry Smith Note: 1568f6dfbefdSBarry Smith By default this is 1; that is `SNES` returns on the first failed linear solve 15693d4c4710SBarry Smith 1570dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetErrorIfNotConverged()`, `SNESGetLinearSolveFailures()`, `SNESGetLinearSolveIterations()`, `SNESSetMaxLinearSolveFailures()`, 15713d4c4710SBarry Smith @*/ 1572d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetMaxLinearSolveFailures(SNES snes, PetscInt *maxFails) 1573d71ae5a4SJacob Faibussowitsch { 15743d4c4710SBarry Smith PetscFunctionBegin; 15750700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 15763d4c4710SBarry Smith PetscValidIntPointer(maxFails, 2); 15773d4c4710SBarry Smith *maxFails = snes->maxLinearSolveFailures; 15783ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 15793d4c4710SBarry Smith } 15803d4c4710SBarry Smith 1581c96a6f78SLois Curfman McInnes /*@ 1582b850b91aSLisandro Dalcin SNESGetLinearSolveIterations - Gets the total number of linear iterations 1583c96a6f78SLois Curfman McInnes used by the nonlinear solver. 1584c96a6f78SLois Curfman McInnes 1585c7afd0dbSLois Curfman McInnes Not Collective 1586c7afd0dbSLois Curfman McInnes 1587c96a6f78SLois Curfman McInnes Input Parameter: 1588f6dfbefdSBarry Smith . snes - `SNES` context 1589c96a6f78SLois Curfman McInnes 1590c96a6f78SLois Curfman McInnes Output Parameter: 1591c96a6f78SLois Curfman McInnes . lits - number of linear iterations 1592c96a6f78SLois Curfman McInnes 1593dc4c0fb0SBarry Smith Level: intermediate 1594dc4c0fb0SBarry Smith 1595c96a6f78SLois Curfman McInnes Notes: 1596f6dfbefdSBarry Smith This counter is reset to zero for each successive call to `SNESSolve()` unless `SNESSetCountersReset()` is used. 1597c96a6f78SLois Curfman McInnes 1598f6dfbefdSBarry Smith If the linear solver fails inside the `SNESSolve()` the iterations for that call to the linear solver are not included. If you wish to count them 1599f6dfbefdSBarry Smith then call `KSPGetIterationNumber()` after the failed solve. 1600010be392SBarry Smith 1601dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetIterationNumber()`, `SNESGetLinearSolveFailures()`, `SNESGetMaxLinearSolveFailures()`, `SNESSetCountersReset()` 1602c96a6f78SLois Curfman McInnes @*/ 1603d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLinearSolveIterations(SNES snes, PetscInt *lits) 1604d71ae5a4SJacob Faibussowitsch { 16053a40ed3dSBarry Smith PetscFunctionBegin; 16060700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16074482741eSBarry Smith PetscValidIntPointer(lits, 2); 1608c96a6f78SLois Curfman McInnes *lits = snes->linear_its; 16093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1610c96a6f78SLois Curfman McInnes } 1611c96a6f78SLois Curfman McInnes 1612971e163fSPeter Brune /*@ 1613971e163fSPeter Brune SNESSetCountersReset - Sets whether or not the counters for linear iterations and function evaluations 1614f6dfbefdSBarry Smith are reset every time `SNESSolve()` is called. 1615971e163fSPeter Brune 1616c3339decSBarry Smith Logically Collective 1617971e163fSPeter Brune 1618d8d19677SJose E. Roman Input Parameters: 1619f6dfbefdSBarry Smith + snes - `SNES` context 1620f6dfbefdSBarry Smith - reset - whether to reset the counters or not, defaults to `PETSC_TRUE` 1621971e163fSPeter Brune 1622971e163fSPeter Brune Level: developer 1623971e163fSPeter Brune 1624dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetNumberFunctionEvals()`, `SNESGetLinearSolveIterations()`, `SNESGetNPC()` 1625971e163fSPeter Brune @*/ 1626d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetCountersReset(SNES snes, PetscBool reset) 1627d71ae5a4SJacob Faibussowitsch { 1628971e163fSPeter Brune PetscFunctionBegin; 1629971e163fSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1630971e163fSPeter Brune PetscValidLogicalCollectiveBool(snes, reset, 2); 1631971e163fSPeter Brune snes->counters_reset = reset; 16323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1633971e163fSPeter Brune } 1634971e163fSPeter Brune 16352999313aSBarry Smith /*@ 1636f6dfbefdSBarry Smith SNESSetKSP - Sets a `KSP` context for the `SNES` object to use 16372999313aSBarry Smith 1638f6dfbefdSBarry Smith Not Collective, but the `SNES` and `KSP` objects must live on the same MPI_Comm 16392999313aSBarry Smith 16402999313aSBarry Smith Input Parameters: 1641f6dfbefdSBarry Smith + snes - the `SNES` context 1642f6dfbefdSBarry Smith - ksp - the `KSP` context 16432999313aSBarry Smith 1644dc4c0fb0SBarry Smith Level: developer 1645dc4c0fb0SBarry Smith 16462999313aSBarry Smith Notes: 1647f6dfbefdSBarry Smith The `SNES` object already has its `KSP` object, you can obtain with `SNESGetKSP()` 16482999313aSBarry Smith so this routine is rarely needed. 16492999313aSBarry Smith 1650f6dfbefdSBarry Smith The `KSP` object that is already in the `SNES` object has its reference count 16512999313aSBarry Smith decreased by one. 16522999313aSBarry Smith 1653dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSP`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 16542999313aSBarry Smith @*/ 1655d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetKSP(SNES snes, KSP ksp) 1656d71ae5a4SJacob Faibussowitsch { 16572999313aSBarry Smith PetscFunctionBegin; 16580700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 16590700a824SBarry Smith PetscValidHeaderSpecific(ksp, KSP_CLASSID, 2); 16602999313aSBarry Smith PetscCheckSameComm(snes, 1, ksp, 2); 16619566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)ksp)); 16629566063dSJacob Faibussowitsch if (snes->ksp) PetscCall(PetscObjectDereference((PetscObject)snes->ksp)); 16632999313aSBarry Smith snes->ksp = ksp; 16643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 16652999313aSBarry Smith } 16662999313aSBarry Smith 166752baeb72SSatish Balay /*@ 1668dc4c0fb0SBarry Smith SNESCreate - Creates a nonlinear solver context used to manage a set of nonlinear solves 16699b94acceSBarry Smith 1670d083f849SBarry Smith Collective 1671c7afd0dbSLois Curfman McInnes 1672f6dfbefdSBarry Smith Input Parameter: 1673906ed7ccSBarry Smith . comm - MPI communicator 16749b94acceSBarry Smith 16759b94acceSBarry Smith Output Parameter: 167620f4b53cSBarry Smith . outsnes - the new `SNES` context 16779b94acceSBarry Smith 1678c7afd0dbSLois Curfman McInnes Options Database Keys: 1679dc4c0fb0SBarry Smith + -snes_mf - Activates default matrix-free Jacobian-vector products, and no preconditioning matrix 1680dc4c0fb0SBarry Smith . -snes_mf_operator - Activates default matrix-free Jacobian-vector products, and a user-provided preconditioning matrix 1681dc4c0fb0SBarry Smith as set by `SNESSetJacobian()` 1682dc4c0fb0SBarry Smith . -snes_fd_coloring - uses a relative fast computation of the Jacobian using finite differences and a graph coloring 1683c7afd0dbSLois Curfman McInnes - -snes_fd - Uses (slow!) finite differences to compute Jacobian 1684c1f60f51SBarry Smith 168536851e7fSLois Curfman McInnes Level: beginner 168636851e7fSLois Curfman McInnes 168795452b02SPatrick Sanan Developer Notes: 1688f6dfbefdSBarry Smith `SNES` always creates a `KSP` object even though many `SNES` methods do not use it. This is 1689efd4aadfSBarry Smith unfortunate and should be fixed at some point. The flag snes->usesksp indicates if the 1690f6dfbefdSBarry Smith particular method does use `KSP` and regulates if the information about the `KSP` is printed 1691f6dfbefdSBarry Smith in `SNESView()`. 1692efd4aadfSBarry Smith 1693f6dfbefdSBarry Smith `TSSetFromOptions()` does call `SNESSetFromOptions()` which can lead to users being confused 1694f6dfbefdSBarry Smith by help messages about meaningless `SNES` options. 1695f6dfbefdSBarry Smith 1696dc4c0fb0SBarry Smith `SNES` always creates the snes->kspconvctx even though it is used by only one type. This should be fixed. 1697efd4aadfSBarry Smith 1698dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESDestroy()`, `SNES`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 16999b94acceSBarry Smith @*/ 1700d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESCreate(MPI_Comm comm, SNES *outsnes) 1701d71ae5a4SJacob Faibussowitsch { 17029b94acceSBarry Smith SNES snes; 1703fa9f3622SBarry Smith SNESKSPEW *kctx; 170437fcc0dbSBarry Smith 17053a40ed3dSBarry Smith PetscFunctionBegin; 1706ed1caa07SMatthew Knepley PetscValidPointer(outsnes, 2); 17070298fd71SBarry Smith *outsnes = NULL; 17089566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 17098ba1e511SMatthew Knepley 17109566063dSJacob Faibussowitsch PetscCall(PetscHeaderCreate(snes, SNES_CLASSID, "SNES", "Nonlinear solver", "SNES", comm, SNESDestroy, SNESView)); 17117adad957SLisandro Dalcin 17128d359177SBarry Smith snes->ops->converged = SNESConvergedDefault; 17132c155ee1SBarry Smith snes->usesksp = PETSC_TRUE; 171488976e71SPeter Brune snes->tolerancesset = PETSC_FALSE; 17159b94acceSBarry Smith snes->max_its = 50; 17169750a799SBarry Smith snes->max_funcs = 10000; 17179b94acceSBarry Smith snes->norm = 0.0; 1718c1e67a49SFande Kong snes->xnorm = 0.0; 1719c1e67a49SFande Kong snes->ynorm = 0.0; 1720365a6726SPeter Brune snes->normschedule = SNES_NORM_ALWAYS; 17216c67d002SPeter Brune snes->functype = SNES_FUNCTION_DEFAULT; 1722*8ca48ce9SPierre Jolivet snes->rtol = PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8; 1723b4874afaSBarry Smith snes->ttol = 0.0; 1724*8ca48ce9SPierre Jolivet snes->abstol = PetscDefined(USE_REAL_SINGLE) ? 1.e-25 : 1.e-50; 1725*8ca48ce9SPierre Jolivet snes->stol = PetscDefined(USE_REAL_SINGLE) ? 1.e-5 : 1.e-8; 1726*8ca48ce9SPierre Jolivet snes->deltatol = PetscDefined(USE_REAL_SINGLE) ? 1.e-6 : 1.e-12; 1727e37c518bSBarry Smith snes->divtol = 1.e4; 1728e37c518bSBarry Smith snes->rnorm0 = 0; 17299b94acceSBarry Smith snes->nfuncs = 0; 173050ffb88aSMatthew Knepley snes->numFailures = 0; 173150ffb88aSMatthew Knepley snes->maxFailures = 1; 17327a00f4a9SLois Curfman McInnes snes->linear_its = 0; 1733e35cf81dSBarry Smith snes->lagjacobian = 1; 173437ec4e1aSPeter Brune snes->jac_iter = 0; 173537ec4e1aSPeter Brune snes->lagjac_persist = PETSC_FALSE; 1736a8054027SBarry Smith snes->lagpreconditioner = 1; 173737ec4e1aSPeter Brune snes->pre_iter = 0; 173837ec4e1aSPeter Brune snes->lagpre_persist = PETSC_FALSE; 1739639f9d9dSBarry Smith snes->numbermonitors = 0; 1740c4421ceaSFande Kong snes->numberreasonviews = 0; 17419e5d0892SLisandro Dalcin snes->data = NULL; 17424dc4c822SBarry Smith snes->setupcalled = PETSC_FALSE; 1743186905e3SBarry Smith snes->ksp_ewconv = PETSC_FALSE; 17446f24a144SLois Curfman McInnes snes->nwork = 0; 17459e5d0892SLisandro Dalcin snes->work = NULL; 174658c9b817SLisandro Dalcin snes->nvwork = 0; 17479e5d0892SLisandro Dalcin snes->vwork = NULL; 1748758f92a0SBarry Smith snes->conv_hist_len = 0; 1749758f92a0SBarry Smith snes->conv_hist_max = 0; 17500298fd71SBarry Smith snes->conv_hist = NULL; 17510298fd71SBarry Smith snes->conv_hist_its = NULL; 1752758f92a0SBarry Smith snes->conv_hist_reset = PETSC_TRUE; 1753971e163fSPeter Brune snes->counters_reset = PETSC_TRUE; 1754e4ed7901SPeter Brune snes->vec_func_init_set = PETSC_FALSE; 1755184914b5SBarry Smith snes->reason = SNES_CONVERGED_ITERATING; 1756efd4aadfSBarry Smith snes->npcside = PC_RIGHT; 1757b3cd9a81SMatthew G. Knepley snes->setfromoptionscalled = 0; 1758c40d0f55SPeter Brune 1759d8f46077SPeter Brune snes->mf = PETSC_FALSE; 1760d8f46077SPeter Brune snes->mf_operator = PETSC_FALSE; 1761d8f46077SPeter Brune snes->mf_version = 1; 1762d8f46077SPeter Brune 17633d4c4710SBarry Smith snes->numLinearSolveFailures = 0; 17643d4c4710SBarry Smith snes->maxLinearSolveFailures = 1; 17653d4c4710SBarry Smith 1766349187a7SBarry Smith snes->vizerotolerance = 1.e-8; 176776bd3646SJed Brown snes->checkjacdomainerror = PetscDefined(USE_DEBUG) ? PETSC_TRUE : PETSC_FALSE; 1768349187a7SBarry Smith 17694fc747eaSLawrence Mitchell /* Set this to true if the implementation of SNESSolve_XXX does compute the residual at the final solution. */ 17704fc747eaSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 17714fc747eaSLawrence Mitchell 17729b94acceSBarry Smith /* Create context to compute Eisenstat-Walker relative tolerance for KSP */ 17734dfa11a4SJacob Faibussowitsch PetscCall(PetscNew(&kctx)); 1774f5af7f23SKarl Rupp 17759b94acceSBarry Smith snes->kspconvctx = (void *)kctx; 17769b94acceSBarry Smith kctx->version = 2; 17770f0abf79SStefano Zampini kctx->rtol_0 = 0.3; /* Eisenstat and Walker suggest rtol_0=.5, but 17789b94acceSBarry Smith this was too large for some test cases */ 177975567043SBarry Smith kctx->rtol_last = 0.0; 17800f0abf79SStefano Zampini kctx->rtol_max = 0.9; 17819b94acceSBarry Smith kctx->gamma = 1.0; 17820f0abf79SStefano Zampini kctx->alpha = 0.5 * (1.0 + PetscSqrtReal(5.0)); 178371f87433Sdalcinl kctx->alpha2 = kctx->alpha; 17840f0abf79SStefano Zampini kctx->threshold = 0.1; 178575567043SBarry Smith kctx->lresid_last = 0.0; 178675567043SBarry Smith kctx->norm_last = 0.0; 17879b94acceSBarry Smith 17880f0abf79SStefano Zampini kctx->rk_last = 0.0; 17890f0abf79SStefano Zampini kctx->rk_last_2 = 0.0; 17900f0abf79SStefano Zampini kctx->rtol_last_2 = 0.0; 17910f0abf79SStefano Zampini kctx->v4_p1 = 0.1; 17920f0abf79SStefano Zampini kctx->v4_p2 = 0.4; 17930f0abf79SStefano Zampini kctx->v4_p3 = 0.7; 17940f0abf79SStefano Zampini kctx->v4_m1 = 0.8; 17950f0abf79SStefano Zampini kctx->v4_m2 = 0.5; 17960f0abf79SStefano Zampini kctx->v4_m3 = 0.1; 17970f0abf79SStefano Zampini kctx->v4_m4 = 0.5; 17980f0abf79SStefano Zampini 17999b94acceSBarry Smith *outsnes = snes; 18003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18019b94acceSBarry Smith } 18029b94acceSBarry Smith 180388f0584fSBarry Smith /*MC 1804f6dfbefdSBarry Smith SNESFunction - Functional form used to convey the nonlinear function to `SNES` in `SNESSetFunction()` 180588f0584fSBarry Smith 180688f0584fSBarry Smith Synopsis: 1807411c0326SBarry Smith #include "petscsnes.h" 1808411c0326SBarry Smith PetscErrorCode SNESFunction(SNES snes,Vec x,Vec f,void *ctx); 180988f0584fSBarry Smith 1810c3339decSBarry Smith Collective 18111843f636SBarry Smith 181288f0584fSBarry Smith Input Parameters: 1813f6dfbefdSBarry Smith + snes - the `SNES` context 181488f0584fSBarry Smith . x - state at which to evaluate residual 1815f6dfbefdSBarry Smith - ctx - optional user-defined function context, passed in with `SNESSetFunction()` 181688f0584fSBarry Smith 181788f0584fSBarry Smith Output Parameter: 181888f0584fSBarry Smith . f - vector to put residual (function value) 181988f0584fSBarry Smith 1820878cb397SSatish Balay Level: intermediate 1821878cb397SSatish Balay 1822dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunction()`, `SNESGetFunction()` 182388f0584fSBarry Smith M*/ 182488f0584fSBarry Smith 18259b94acceSBarry Smith /*@C 18269b94acceSBarry Smith SNESSetFunction - Sets the function evaluation routine and function 1827f6dfbefdSBarry Smith vector for use by the `SNES` routines in solving systems of nonlinear 18289b94acceSBarry Smith equations. 18299b94acceSBarry Smith 1830c3339decSBarry Smith Logically Collective 1831fee21e36SBarry Smith 1832c7afd0dbSLois Curfman McInnes Input Parameters: 1833f6dfbefdSBarry Smith + snes - the `SNES` context 1834dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 183520f4b53cSBarry Smith . f - function evaluation routine; for calling sequence see `SNESFunction` 1836c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 1837dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 18389b94acceSBarry Smith 183936851e7fSLois Curfman McInnes Level: beginner 184036851e7fSLois Curfman McInnes 1841dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetPicard()`, `SNESFunction` 18429b94acceSBarry Smith @*/ 1843d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunction(SNES snes, Vec r, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 1844d71ae5a4SJacob Faibussowitsch { 18456cab3a1bSJed Brown DM dm; 18466cab3a1bSJed Brown 18473a40ed3dSBarry Smith PetscFunctionBegin; 18480700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1849d2a683ecSLisandro Dalcin if (r) { 1850d2a683ecSLisandro Dalcin PetscValidHeaderSpecific(r, VEC_CLASSID, 2); 1851d2a683ecSLisandro Dalcin PetscCheckSameComm(snes, 1, r, 2); 18529566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)r)); 18539566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 185485385478SLisandro Dalcin snes->vec_func = r; 1855d2a683ecSLisandro Dalcin } 18569566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 18579566063dSJacob Faibussowitsch PetscCall(DMSNESSetFunction(dm, f, ctx)); 185848a46eb9SPierre Jolivet if (f == SNESPicardComputeFunction) PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 18593ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 18609b94acceSBarry Smith } 18619b94acceSBarry Smith 1862e4ed7901SPeter Brune /*@C 1863e4ed7901SPeter Brune SNESSetInitialFunction - Sets the function vector to be used as the 1864f6dfbefdSBarry Smith initial function value at the initialization of the method. In some 1865e4ed7901SPeter Brune instances, the user has precomputed the function before calling 1866f6dfbefdSBarry Smith `SNESSolve()`. This function allows one to avoid a redundant call 1867f6dfbefdSBarry Smith to `SNESComputeFunction()` in that case. 1868e4ed7901SPeter Brune 1869c3339decSBarry Smith Logically Collective 1870e4ed7901SPeter Brune 1871e4ed7901SPeter Brune Input Parameters: 1872f6dfbefdSBarry Smith + snes - the `SNES` context 1873e4ed7901SPeter Brune - f - vector to store function value 1874e4ed7901SPeter Brune 1875dc4c0fb0SBarry Smith Level: developer 1876dc4c0fb0SBarry Smith 1877e4ed7901SPeter Brune Notes: 1878e4ed7901SPeter Brune This should not be modified during the solution procedure. 1879e4ed7901SPeter Brune 1880f6dfbefdSBarry Smith This is used extensively in the `SNESFAS` hierarchy and in nonlinear preconditioning. 1881e4ed7901SPeter Brune 1882dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESFAS`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetInitialFunctionNorm()` 1883e4ed7901SPeter Brune @*/ 1884d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetInitialFunction(SNES snes, Vec f) 1885d71ae5a4SJacob Faibussowitsch { 1886e4ed7901SPeter Brune Vec vec_func; 1887e4ed7901SPeter Brune 1888e4ed7901SPeter Brune PetscFunctionBegin; 1889e4ed7901SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1890e4ed7901SPeter Brune PetscValidHeaderSpecific(f, VEC_CLASSID, 2); 1891e4ed7901SPeter Brune PetscCheckSameComm(snes, 1, f, 2); 1892efd4aadfSBarry Smith if (snes->npcside == PC_LEFT && snes->functype == SNES_FUNCTION_PRECONDITIONED) { 1893902f982fSPeter Brune snes->vec_func_init_set = PETSC_FALSE; 18943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1895902f982fSPeter Brune } 18969566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &vec_func, NULL, NULL)); 18979566063dSJacob Faibussowitsch PetscCall(VecCopy(f, vec_func)); 1898f5af7f23SKarl Rupp 1899217b9c2eSPeter Brune snes->vec_func_init_set = PETSC_TRUE; 19003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1901e4ed7901SPeter Brune } 1902e4ed7901SPeter Brune 1903534ebe21SPeter Brune /*@ 1904f6dfbefdSBarry Smith SNESSetNormSchedule - Sets the `SNESNormSchedule` used in convergence and monitoring 1905f6dfbefdSBarry Smith of the `SNES` method, when norms are computed in the solving process 1906534ebe21SPeter Brune 1907c3339decSBarry Smith Logically Collective 1908534ebe21SPeter Brune 1909534ebe21SPeter Brune Input Parameters: 1910f6dfbefdSBarry Smith + snes - the `SNES` context 1911365a6726SPeter Brune - normschedule - the frequency of norm computation 1912534ebe21SPeter Brune 1913517f1916SMatthew G. Knepley Options Database Key: 191467b8a455SSatish Balay . -snes_norm_schedule <none, always, initialonly, finalonly, initialfinalonly> - set the schedule 1915517f1916SMatthew G. Knepley 1916dc4c0fb0SBarry Smith Level: advanced 1917dc4c0fb0SBarry Smith 1918534ebe21SPeter Brune Notes: 1919f6dfbefdSBarry Smith Only certain `SNES` methods support certain `SNESNormSchedules`. Most require evaluation 1920534ebe21SPeter Brune of the nonlinear function and the taking of its norm at every iteration to 1921534ebe21SPeter Brune even ensure convergence at all. However, methods such as custom Gauss-Seidel methods 1922f6dfbefdSBarry Smith `SNESNGS` and the like do not require the norm of the function to be computed, and therefore 1923534ebe21SPeter Brune may either be monitored for convergence or not. As these are often used as nonlinear 1924534ebe21SPeter Brune preconditioners, monitoring the norm of their error is not a useful enterprise within 1925534ebe21SPeter Brune their solution. 1926534ebe21SPeter Brune 1927dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNormSchedule`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1928534ebe21SPeter Brune @*/ 1929d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNormSchedule(SNES snes, SNESNormSchedule normschedule) 1930d71ae5a4SJacob Faibussowitsch { 1931534ebe21SPeter Brune PetscFunctionBegin; 1932534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1933365a6726SPeter Brune snes->normschedule = normschedule; 19343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1935534ebe21SPeter Brune } 1936534ebe21SPeter Brune 1937534ebe21SPeter Brune /*@ 1938f6dfbefdSBarry Smith SNESGetNormSchedule - Gets the `SNESNormSchedule` used in convergence and monitoring 1939f6dfbefdSBarry Smith of the `SNES` method. 1940534ebe21SPeter Brune 1941c3339decSBarry Smith Logically Collective 1942534ebe21SPeter Brune 1943534ebe21SPeter Brune Input Parameters: 1944f6dfbefdSBarry Smith + snes - the `SNES` context 1945365a6726SPeter Brune - normschedule - the type of the norm used 1946534ebe21SPeter Brune 1947534ebe21SPeter Brune Level: advanced 1948534ebe21SPeter Brune 1949dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1950534ebe21SPeter Brune @*/ 1951d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNormSchedule(SNES snes, SNESNormSchedule *normschedule) 1952d71ae5a4SJacob Faibussowitsch { 1953534ebe21SPeter Brune PetscFunctionBegin; 1954534ebe21SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1955365a6726SPeter Brune *normschedule = snes->normschedule; 19563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1957534ebe21SPeter Brune } 1958534ebe21SPeter Brune 1959c5ce4427SMatthew G. Knepley /*@ 1960c5ce4427SMatthew G. Knepley SNESSetFunctionNorm - Sets the last computed residual norm. 1961c5ce4427SMatthew G. Knepley 1962c3339decSBarry Smith Logically Collective 1963c5ce4427SMatthew G. Knepley 1964c5ce4427SMatthew G. Knepley Input Parameters: 1965f6dfbefdSBarry Smith + snes - the `SNES` context 1966f6dfbefdSBarry Smith - norm - the value of the norm 1967c5ce4427SMatthew G. Knepley 1968c5ce4427SMatthew G. Knepley Level: developer 1969c5ce4427SMatthew G. Knepley 1970dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1971c5ce4427SMatthew G. Knepley @*/ 1972d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionNorm(SNES snes, PetscReal norm) 1973d71ae5a4SJacob Faibussowitsch { 1974c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1975c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1976c5ce4427SMatthew G. Knepley snes->norm = norm; 19773ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 1978c5ce4427SMatthew G. Knepley } 1979c5ce4427SMatthew G. Knepley 1980c5ce4427SMatthew G. Knepley /*@ 1981c5ce4427SMatthew G. Knepley SNESGetFunctionNorm - Gets the last computed norm of the residual 1982c5ce4427SMatthew G. Knepley 1983c5ce4427SMatthew G. Knepley Not Collective 1984c5ce4427SMatthew G. Knepley 1985c5ce4427SMatthew G. Knepley Input Parameter: 1986f6dfbefdSBarry Smith . snes - the `SNES` context 1987c5ce4427SMatthew G. Knepley 1988c5ce4427SMatthew G. Knepley Output Parameter: 1989c5ce4427SMatthew G. Knepley . norm - the last computed residual norm 1990c5ce4427SMatthew G. Knepley 1991c5ce4427SMatthew G. Knepley Level: developer 1992c5ce4427SMatthew G. Knepley 1993dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 1994c5ce4427SMatthew G. Knepley @*/ 1995d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionNorm(SNES snes, PetscReal *norm) 1996d71ae5a4SJacob Faibussowitsch { 1997c5ce4427SMatthew G. Knepley PetscFunctionBegin; 1998c5ce4427SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 1999dadcf809SJacob Faibussowitsch PetscValidRealPointer(norm, 2); 2000c5ce4427SMatthew G. Knepley *norm = snes->norm; 20013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2002c5ce4427SMatthew G. Knepley } 2003c5ce4427SMatthew G. Knepley 2004c1e67a49SFande Kong /*@ 2005f6dfbefdSBarry Smith SNESGetUpdateNorm - Gets the last computed norm of the solution update 2006c1e67a49SFande Kong 2007c1e67a49SFande Kong Not Collective 2008c1e67a49SFande Kong 2009c1e67a49SFande Kong Input Parameter: 2010f6dfbefdSBarry Smith . snes - the `SNES` context 2011c1e67a49SFande Kong 2012c1e67a49SFande Kong Output Parameter: 2013c1e67a49SFande Kong . ynorm - the last computed update norm 2014c1e67a49SFande Kong 2015c1e67a49SFande Kong Level: developer 2016c1e67a49SFande Kong 2017f6dfbefdSBarry Smith Note: 2018f6dfbefdSBarry Smith The new solution is the current solution plus the update, so this norm is an indication of the size of the update 2019f6dfbefdSBarry Smith 2020dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()` 2021c1e67a49SFande Kong @*/ 2022d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetUpdateNorm(SNES snes, PetscReal *ynorm) 2023d71ae5a4SJacob Faibussowitsch { 2024c1e67a49SFande Kong PetscFunctionBegin; 2025c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2026dadcf809SJacob Faibussowitsch PetscValidRealPointer(ynorm, 2); 2027c1e67a49SFande Kong *ynorm = snes->ynorm; 20283ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2029c1e67a49SFande Kong } 2030c1e67a49SFande Kong 2031c1e67a49SFande Kong /*@ 20324591eaf2SFande Kong SNESGetSolutionNorm - Gets the last computed norm of the solution 2033c1e67a49SFande Kong 2034c1e67a49SFande Kong Not Collective 2035c1e67a49SFande Kong 2036c1e67a49SFande Kong Input Parameter: 2037f6dfbefdSBarry Smith . snes - the `SNES` context 2038c1e67a49SFande Kong 2039c1e67a49SFande Kong Output Parameter: 2040c1e67a49SFande Kong . xnorm - the last computed solution norm 2041c1e67a49SFande Kong 2042c1e67a49SFande Kong Level: developer 2043c1e67a49SFande Kong 2044dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `SNESGetFunctionNorm()`, `SNESGetUpdateNorm()` 2045c1e67a49SFande Kong @*/ 2046d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionNorm(SNES snes, PetscReal *xnorm) 2047d71ae5a4SJacob Faibussowitsch { 2048c1e67a49SFande Kong PetscFunctionBegin; 2049c1e67a49SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2050dadcf809SJacob Faibussowitsch PetscValidRealPointer(xnorm, 2); 2051c1e67a49SFande Kong *xnorm = snes->xnorm; 20523ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2053c1e67a49SFande Kong } 2054c1e67a49SFande Kong 205547073ea2SPeter Brune /*@C 2056f6dfbefdSBarry Smith SNESSetFunctionType - Sets the `SNESFunctionType` 2057f6dfbefdSBarry Smith of the `SNES` method. 205847073ea2SPeter Brune 2059c3339decSBarry Smith Logically Collective 206047073ea2SPeter Brune 206147073ea2SPeter Brune Input Parameters: 2062f6dfbefdSBarry Smith + snes - the `SNES` context 2063f6dfbefdSBarry Smith - type - the function type 206447073ea2SPeter Brune 206547073ea2SPeter Brune Level: developer 206647073ea2SPeter Brune 2067f6dfbefdSBarry Smith Notes: 2068f6dfbefdSBarry Smith Possible values of the function type 2069f6dfbefdSBarry Smith + `SNES_FUNCTION_DEFAULT` - the default for the given `SNESType` 2070f6dfbefdSBarry Smith . `SNES_FUNCTION_UNPRECONDITIONED` - an unpreconditioned function evaluation (this is the function provided with `SNESSetFunction()` 2071f6dfbefdSBarry Smith - `SNES_FUNCTION_PRECONDITIONED` - a transformation of the function provided with `SNESSetFunction()` 2072f6dfbefdSBarry Smith 2073f6dfbefdSBarry Smith Different `SNESType`s use this value in different ways 2074f6dfbefdSBarry Smith 2075dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESFunctionType`, `SNESGetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 207647073ea2SPeter Brune @*/ 2077d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetFunctionType(SNES snes, SNESFunctionType type) 2078d71ae5a4SJacob Faibussowitsch { 207947073ea2SPeter Brune PetscFunctionBegin; 208047073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 208147073ea2SPeter Brune snes->functype = type; 20823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 208347073ea2SPeter Brune } 208447073ea2SPeter Brune 208547073ea2SPeter Brune /*@C 2086f6dfbefdSBarry Smith SNESGetFunctionType - Gets the `SNESFunctionType` used in convergence and monitoring set with `SNESSetFunctionType()` 208747073ea2SPeter Brune of the SNES method. 208847073ea2SPeter Brune 2089c3339decSBarry Smith Logically Collective 209047073ea2SPeter Brune 209147073ea2SPeter Brune Input Parameters: 2092f6dfbefdSBarry Smith + snes - the `SNES` context 2093f6dfbefdSBarry Smith - type - the type of the function evaluation, see `SNESSetFunctionType()` 209447073ea2SPeter Brune 209547073ea2SPeter Brune Level: advanced 209647073ea2SPeter Brune 2097dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunctionType()`, `SNESFunctionType`, `SNESSetNormSchedule()`, `SNESComputeFunction()`, `VecNorm()`, `SNESSetFunction()`, `SNESSetInitialFunction()`, `SNESNormSchedule` 209847073ea2SPeter Brune @*/ 2099d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunctionType(SNES snes, SNESFunctionType *type) 2100d71ae5a4SJacob Faibussowitsch { 210147073ea2SPeter Brune PetscFunctionBegin; 210247073ea2SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 210347073ea2SPeter Brune *type = snes->functype; 21043ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2105534ebe21SPeter Brune } 2106534ebe21SPeter Brune 2107bf388a1fSBarry Smith /*MC 2108f6dfbefdSBarry Smith SNESNGSFunction - function used to apply a Gauss-Seidel sweep on the nonlinear function 2109bf388a1fSBarry Smith 2110bf388a1fSBarry Smith Synopsis: 2111aaa7dc30SBarry Smith #include <petscsnes.h> 2112be95d8f1SBarry Smith $ SNESNGSFunction(SNES snes,Vec x,Vec b,void *ctx); 2113bf388a1fSBarry Smith 2114c3339decSBarry Smith Collective 21151843f636SBarry Smith 21161843f636SBarry Smith Input Parameters: 2117bf388a1fSBarry Smith + X - solution vector 2118bf388a1fSBarry Smith . B - RHS vector 2119bf388a1fSBarry Smith - ctx - optional user-defined Gauss-Seidel context 2120bf388a1fSBarry Smith 21211843f636SBarry Smith Output Parameter: 21221843f636SBarry Smith . X - solution vector 21231843f636SBarry Smith 2124878cb397SSatish Balay Level: intermediate 2125878cb397SSatish Balay 2126dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESSetNGS()`, `SNESGetNGS()` 2127bf388a1fSBarry Smith M*/ 2128bf388a1fSBarry Smith 2129c79ef259SPeter Brune /*@C 2130be95d8f1SBarry Smith SNESSetNGS - Sets the user nonlinear Gauss-Seidel routine for 2131c79ef259SPeter Brune use with composed nonlinear solvers. 2132c79ef259SPeter Brune 2133c79ef259SPeter Brune Input Parameters: 2134dc4c0fb0SBarry Smith + snes - the `SNES` context 2135f6dfbefdSBarry Smith . f - function evaluation routine to apply Gauss-Seidel see `SNESNGSFunction` 2136c79ef259SPeter Brune - ctx - [optional] user-defined context for private data for the 2137dc4c0fb0SBarry Smith smoother evaluation routine (may be `NULL`) 2138c79ef259SPeter Brune 213920f4b53cSBarry Smith Calling sequence of `f`: 214020f4b53cSBarry Smith $ PetscErrorCode f(SNES snes, Vec X, Vec B, void *ctx) 2141f6dfbefdSBarry Smith + snes - the `SNES` context 2142f6dfbefdSBarry Smith . X - the current solution 2143dc4c0fb0SBarry Smith . B - the right hand side vector (which may be `NULL`) 2144f6dfbefdSBarry Smith - ctx - a user provided context 2145f6dfbefdSBarry Smith 2146dc4c0fb0SBarry Smith Level: intermediate 2147dc4c0fb0SBarry Smith 2148f6dfbefdSBarry Smith Note: 2149f6dfbefdSBarry Smith The `SNESNGS` routines are used by the composed nonlinear solver to generate 2150f6dfbefdSBarry Smith a problem appropriate update to the solution, particularly `SNESFAS`. 2151c79ef259SPeter Brune 2152dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetNGS()`, `SNESNGSFunction`, `SNESNCG`, `SNESGetFunction()`, `SNESComputeNGS()` 2153c79ef259SPeter Brune @*/ 2154d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNGS(SNES snes, PetscErrorCode (*f)(SNES, Vec, Vec, void *), void *ctx) 2155d71ae5a4SJacob Faibussowitsch { 21566cab3a1bSJed Brown DM dm; 21576cab3a1bSJed Brown 2158646217ecSPeter Brune PetscFunctionBegin; 21596cab3a1bSJed Brown PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 21609566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21619566063dSJacob Faibussowitsch PetscCall(DMSNESSetNGS(dm, f, ctx)); 21623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2163646217ecSPeter Brune } 2164646217ecSPeter Brune 2165bbc1464cSBarry Smith /* 2166bbc1464cSBarry Smith This is used for -snes_mf_operator; it uses a duplicate of snes->jacobian_pre because snes->jacobian_pre cannot be 2167bbc1464cSBarry Smith changed during the KSPSolve() 2168bbc1464cSBarry Smith */ 2169d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeMFFunction(SNES snes, Vec x, Vec f, void *ctx) 2170d71ae5a4SJacob Faibussowitsch { 2171bbc1464cSBarry Smith DM dm; 2172bbc1464cSBarry Smith DMSNES sdm; 2173bbc1464cSBarry Smith 2174bbc1464cSBarry Smith PetscFunctionBegin; 21759566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21769566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 2177bbc1464cSBarry Smith /* A(x)*x - b(x) */ 2178bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2179792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 21809566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 21810df40c35SBarry Smith /* Cannot share nonzero pattern because of the possible use of SNESComputeJacobianDefault() */ 2182ef1023bdSBarry Smith if (!snes->picard) PetscCall(MatDuplicate(snes->jacobian_pre, MAT_DO_NOT_COPY_VALUES, &snes->picard)); 2183792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21849566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->picard, x, f, f)); 2185bbc1464cSBarry Smith } else { 2186792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->picard, snes->picard, sdm->pctx)); 21879566063dSJacob Faibussowitsch PetscCall(MatMult(snes->picard, x, f)); 2188bbc1464cSBarry Smith } 21893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2190bbc1464cSBarry Smith } 2191bbc1464cSBarry Smith 2192d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeFunction(SNES snes, Vec x, Vec f, void *ctx) 2193d71ae5a4SJacob Faibussowitsch { 2194e03ab78fSPeter Brune DM dm; 2195942e3340SBarry Smith DMSNES sdm; 21966cab3a1bSJed Brown 21978b0a5094SBarry Smith PetscFunctionBegin; 21989566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 21999566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 22008b0a5094SBarry Smith /* A(x)*x - b(x) */ 2201bbc1464cSBarry Smith if (sdm->ops->computepfunction) { 2202792fecdfSBarry Smith PetscCallBack("SNES Picard callback function", (*sdm->ops->computepfunction)(snes, x, f, sdm->pctx)); 22039566063dSJacob Faibussowitsch PetscCall(VecScale(f, -1.0)); 2204792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22059566063dSJacob Faibussowitsch PetscCall(MatMultAdd(snes->jacobian_pre, x, f, f)); 2206bbc1464cSBarry Smith } else { 2207792fecdfSBarry Smith PetscCallBack("SNES Picard callback Jacobian", (*sdm->ops->computepjacobian)(snes, x, snes->jacobian, snes->jacobian_pre, sdm->pctx)); 22089566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian_pre, x, f)); 2209bbc1464cSBarry Smith } 22103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22118b0a5094SBarry Smith } 22128b0a5094SBarry Smith 2213d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESPicardComputeJacobian(SNES snes, Vec x1, Mat J, Mat B, void *ctx) 2214d71ae5a4SJacob Faibussowitsch { 22158b0a5094SBarry Smith PetscFunctionBegin; 2216e03ab78fSPeter Brune /* the jacobian matrix should be pre-filled in SNESPicardComputeFunction */ 2217bbc1464cSBarry Smith /* must assembly if matrix-free to get the last SNES solution */ 22189566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(J, MAT_FINAL_ASSEMBLY)); 22199566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(J, MAT_FINAL_ASSEMBLY)); 22203ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22218b0a5094SBarry Smith } 22228b0a5094SBarry Smith 22238b0a5094SBarry Smith /*@C 2224f6dfbefdSBarry Smith SNESSetPicard - Use `SNES` to solve the system A(x) x = bp(x) + b via a Picard type iteration (Picard linearization) 22258b0a5094SBarry Smith 2226c3339decSBarry Smith Logically Collective 22278b0a5094SBarry Smith 22288b0a5094SBarry Smith Input Parameters: 2229f6dfbefdSBarry Smith + snes - the `SNES` context 2230dc4c0fb0SBarry Smith . r - vector to store function values, may be `NULL` 2231dc4c0fb0SBarry Smith . bp - function evaluation routine, may be `NULL` 22326b7fb656SBarry Smith . Amat - matrix with which A(x) x - bp(x) - b is to be computed 2233dc4c0fb0SBarry Smith . Pmat - matrix from which preconditioner is computed (usually the same as `Amat`) 223420f4b53cSBarry Smith . J - function to compute matrix values, for the calling sequence see `SNESJacobianFunction()` 2235dc4c0fb0SBarry Smith - ctx - [optional] user-defined context for private data for the function evaluation routine (may be `NULL`) 2236dc4c0fb0SBarry Smith 2237dc4c0fb0SBarry Smith Level: intermediate 22388b0a5094SBarry Smith 22398b0a5094SBarry Smith Notes: 22406b7fb656SBarry Smith It is often better to provide the nonlinear function F() and some approximation to its Jacobian directly and use 2241f450aa47SBarry 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. 2242f450aa47SBarry Smith 2243f6dfbefdSBarry Smith One can call `SNESSetPicard()` or `SNESSetFunction()` (and possibly `SNESSetJacobian()`) but cannot call both 22448b0a5094SBarry Smith 2245dc4c0fb0SBarry 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}. 2246dc4c0fb0SBarry Smith When an exact solver is used this corresponds to the "classic" Picard A(x^{n}) x^{n+1} = bp(x^{n}) + b iteration. 22478b0a5094SBarry Smith 2248dc4c0fb0SBarry Smith Run with `-snes_mf_operator` to solve the system with Newton's method using A(x^{n}) to construct the preconditioner. 22498b0a5094SBarry Smith 22500d04baf8SBarry Smith We implement the defect correction form of the Picard iteration because it converges much more generally when inexact linear solvers are used then 22516b7fb656SBarry Smith the direct Picard iteration A(x^n) x^{n+1} = bp(x^n) + b 22528b0a5094SBarry Smith 22538b0a5094SBarry 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 22548b0a5094SBarry 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 22558b0a5094SBarry Smith different please contact us at petsc-dev@mcs.anl.gov and we'll have an entirely new argument :-). 22568b0a5094SBarry Smith 2257dc4c0fb0SBarry 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 2258f6dfbefdSBarry Smith A(x^{n}) is used to build the preconditioner 22596b7fb656SBarry Smith 2260dc4c0fb0SBarry 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. 22616b7fb656SBarry Smith 2262dc4c0fb0SBarry 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 22636b7fb656SBarry 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 2264f6dfbefdSBarry 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`. 22656b7fb656SBarry Smith See the commment in src/snes/tutorials/ex15.c. 2266bbc1464cSBarry Smith 2267dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetFunction()`, `SNESSetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESGetPicard()`, `SNESLineSearchPreCheckPicard()`, `SNESJacobianFunction` 22688b0a5094SBarry Smith @*/ 2269d71ae5a4SJacob 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) 2270d71ae5a4SJacob Faibussowitsch { 2271e03ab78fSPeter Brune DM dm; 2272e03ab78fSPeter Brune 22738b0a5094SBarry Smith PetscFunctionBegin; 22748b0a5094SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 22759566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 22769566063dSJacob Faibussowitsch PetscCall(DMSNESSetPicard(dm, bp, J, ctx)); 22779566063dSJacob Faibussowitsch PetscCall(DMSNESSetMFFunction(dm, SNESPicardComputeMFFunction, ctx)); 22789566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes, r, SNESPicardComputeFunction, ctx)); 22799566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes, Amat, Pmat, SNESPicardComputeJacobian, ctx)); 22803ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 22818b0a5094SBarry Smith } 22828b0a5094SBarry Smith 22837971a8bfSPeter Brune /*@C 22847971a8bfSPeter Brune SNESGetPicard - Returns the context for the Picard iteration 22857971a8bfSPeter Brune 2286f6dfbefdSBarry Smith Not Collective, but `Vec` is parallel if `SNES` is parallel. Collective if `Vec` is requested, but has not been created yet. 22877971a8bfSPeter Brune 22887971a8bfSPeter Brune Input Parameter: 2289f6dfbefdSBarry Smith . snes - the `SNES` context 22907971a8bfSPeter Brune 2291d8d19677SJose E. Roman Output Parameters: 2292dc4c0fb0SBarry Smith + r - the function (or `NULL`) 229320f4b53cSBarry Smith . f - the function (or `NULL`); for calling sequence see `SNESFunction` 2294dc4c0fb0SBarry Smith . Amat - the matrix used to defined the operation A(x) x - b(x) (or `NULL`) 2295dc4c0fb0SBarry Smith . Pmat - the matrix from which the preconditioner will be constructed (or `NULL`) 229620f4b53cSBarry Smith . J - the function for matrix evaluation (or `NULL`); for calling sequence see `SNESJacobianFunction` 2297dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 22987971a8bfSPeter Brune 22997971a8bfSPeter Brune Level: advanced 23007971a8bfSPeter Brune 2301dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetFunction()`, `SNESSetPicard()`, `SNESGetFunction()`, `SNESGetJacobian()`, `SNESGetDM()`, `SNESFunction`, `SNESJacobianFunction` 23027971a8bfSPeter Brune @*/ 2303d71ae5a4SJacob 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) 2304d71ae5a4SJacob Faibussowitsch { 23057971a8bfSPeter Brune DM dm; 23067971a8bfSPeter Brune 23077971a8bfSPeter Brune PetscFunctionBegin; 23087971a8bfSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23099566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, r, NULL, NULL)); 23109566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, Amat, Pmat, NULL, NULL)); 23119566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 23129566063dSJacob Faibussowitsch PetscCall(DMSNESGetPicard(dm, f, J, ctx)); 23133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23147971a8bfSPeter Brune } 23157971a8bfSPeter Brune 2316d25893d9SBarry Smith /*@C 2317dc4c0fb0SBarry Smith SNESSetComputeInitialGuess - Sets a routine used to compute an initial guess for the nonlinear problem 2318d25893d9SBarry Smith 2319c3339decSBarry Smith Logically Collective 2320d25893d9SBarry Smith 2321d25893d9SBarry Smith Input Parameters: 2322f6dfbefdSBarry Smith + snes - the `SNES` context 2323d25893d9SBarry Smith . func - function evaluation routine 2324d25893d9SBarry Smith - ctx - [optional] user-defined context for private data for the 2325dc4c0fb0SBarry Smith function evaluation routine (may be `NULL`) 2326d25893d9SBarry Smith 232720f4b53cSBarry Smith Calling sequence of `func`: 232820f4b53cSBarry Smith $ PetscErrorCode func(SNES snes, Vec x, void *ctx); 232920f4b53cSBarry Smith + snes - the `SNES` solver 233020f4b53cSBarry Smith . x - vector to put initial guess 2331d25893d9SBarry Smith - ctx - optional user-defined function context 2332d25893d9SBarry Smith 2333d25893d9SBarry Smith Level: intermediate 2334d25893d9SBarry Smith 2335dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()` 2336d25893d9SBarry Smith @*/ 2337d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetComputeInitialGuess(SNES snes, PetscErrorCode (*func)(SNES, Vec, void *), void *ctx) 2338d71ae5a4SJacob Faibussowitsch { 2339d25893d9SBarry Smith PetscFunctionBegin; 2340d25893d9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2341d25893d9SBarry Smith if (func) snes->ops->computeinitialguess = func; 2342d25893d9SBarry Smith if (ctx) snes->initialguessP = ctx; 23433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2344d25893d9SBarry Smith } 2345d25893d9SBarry Smith 23461096aae1SMatthew Knepley /*@C 2347dc4c0fb0SBarry Smith SNESGetRhs - Gets the vector for solving F(x) = `rhs`. If `rhs` is not set 23481096aae1SMatthew Knepley it assumes a zero right hand side. 23491096aae1SMatthew Knepley 2350c3339decSBarry Smith Logically Collective 23511096aae1SMatthew Knepley 23521096aae1SMatthew Knepley Input Parameter: 2353f6dfbefdSBarry Smith . snes - the `SNES` context 23541096aae1SMatthew Knepley 23551096aae1SMatthew Knepley Output Parameter: 2356dc4c0fb0SBarry Smith . rhs - the right hand side vector or `NULL` if the right hand side vector is null 23571096aae1SMatthew Knepley 23581096aae1SMatthew Knepley Level: intermediate 23591096aae1SMatthew Knepley 2360dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()`, `SNESComputeFunction()`, `SNESSetJacobian()`, `SNESSetFunction()` 23611096aae1SMatthew Knepley @*/ 2362d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetRhs(SNES snes, Vec *rhs) 2363d71ae5a4SJacob Faibussowitsch { 23641096aae1SMatthew Knepley PetscFunctionBegin; 23650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23661096aae1SMatthew Knepley PetscValidPointer(rhs, 2); 236785385478SLisandro Dalcin *rhs = snes->vec_rhs; 23683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 23691096aae1SMatthew Knepley } 23701096aae1SMatthew Knepley 23719b94acceSBarry Smith /*@ 2372f6dfbefdSBarry Smith SNESComputeFunction - Calls the function that has been set with `SNESSetFunction()`. 23739b94acceSBarry Smith 2374c3339decSBarry Smith Collective 2375c7afd0dbSLois Curfman McInnes 23769b94acceSBarry Smith Input Parameters: 2377f6dfbefdSBarry Smith + snes - the `SNES` context 2378c7afd0dbSLois Curfman McInnes - x - input vector 23799b94acceSBarry Smith 23809b94acceSBarry Smith Output Parameter: 2381f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetFunction()` 23829b94acceSBarry Smith 2383dc4c0fb0SBarry Smith Level: developer 2384dc4c0fb0SBarry Smith 2385f6dfbefdSBarry Smith Note: 2386f6dfbefdSBarry Smith `SNESComputeFunction()` is typically used within nonlinear solvers 2387bbc1464cSBarry Smith implementations, so users would not generally call this routine themselves. 238836851e7fSLois Curfman McInnes 2389dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeMFFunction()` 23909b94acceSBarry Smith @*/ 2391d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeFunction(SNES snes, Vec x, Vec y) 2392d71ae5a4SJacob Faibussowitsch { 23936cab3a1bSJed Brown DM dm; 2394942e3340SBarry Smith DMSNES sdm; 23959b94acceSBarry Smith 23963a40ed3dSBarry Smith PetscFunctionBegin; 23970700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 23980700a824SBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 23990700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2400c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2401c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2402e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2403184914b5SBarry Smith 24049566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24059566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24060fdf79fbSJacob 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()."); 240732f3f7c2SPeter Brune if (sdm->ops->computefunction) { 240848a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24099566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 24108ddeebeaSSteve Benbow /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 24118ddeebeaSSteve Benbow snes->domainerror = PETSC_FALSE; 2412800f99ffSJeremy L Thompson { 2413800f99ffSJeremy L Thompson void *ctx; 2414800f99ffSJeremy L Thompson PetscErrorCode (*computefunction)(SNES, Vec, Vec, void *); 2415800f99ffSJeremy L Thompson PetscCall(DMSNESGetFunction(dm, &computefunction, &ctx)); 2416800f99ffSJeremy L Thompson PetscCallBack("SNES callback function", (*computefunction)(snes, x, y, ctx)); 2417800f99ffSJeremy L Thompson } 24189566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 241948a46eb9SPierre Jolivet if (sdm->ops->computefunction != SNESObjectiveComputeFunctionDefaultFD) PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 24200fdf79fbSJacob Faibussowitsch } else /* if (snes->vec_rhs) */ { 24219566063dSJacob Faibussowitsch PetscCall(MatMult(snes->jacobian, x, y)); 24220fdf79fbSJacob Faibussowitsch } 24231baa6e33SBarry Smith if (snes->vec_rhs) PetscCall(VecAXPY(y, -1.0, snes->vec_rhs)); 2424ae3c334cSLois Curfman McInnes snes->nfuncs++; 2425422a814eSBarry Smith /* 2426422a814eSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2427422a814eSBarry Smith propagate the value to all processes 2428422a814eSBarry Smith */ 24291baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 24319b94acceSBarry Smith } 24329b94acceSBarry Smith 2433c79ef259SPeter Brune /*@ 2434f6dfbefdSBarry Smith SNESComputeMFFunction - Calls the function that has been set with `SNESSetMFFunction()`. 2435bbc1464cSBarry Smith 2436c3339decSBarry Smith Collective 2437bbc1464cSBarry Smith 2438bbc1464cSBarry Smith Input Parameters: 2439f6dfbefdSBarry Smith + snes - the `SNES` context 2440bbc1464cSBarry Smith - x - input vector 2441bbc1464cSBarry Smith 2442bbc1464cSBarry Smith Output Parameter: 2443f6dfbefdSBarry Smith . y - function vector, as set by `SNESSetMFFunction()` 2444bbc1464cSBarry Smith 2445dc4c0fb0SBarry Smith Level: developer 2446dc4c0fb0SBarry Smith 2447bbc1464cSBarry Smith Notes: 2448f6dfbefdSBarry Smith `SNESComputeMFFunction()` is used within the matrix vector products called by the matrix created with `MatCreateSNESMF()` 2449bbc1464cSBarry Smith so users would not generally call this routine themselves. 2450bbc1464cSBarry Smith 2451f6dfbefdSBarry Smith Since this function is intended for use with finite differencing it does not subtract the right hand side vector provided with `SNESSolve()` 2452f6dfbefdSBarry Smith while `SNESComputeFunction()` does. As such, this routine cannot be used with `MatMFFDSetBase()` with a provided F function value even if it applies the 2453f6dfbefdSBarry 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. 2454bbc1464cSBarry Smith 2455dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESComputeFunction()`, `MatCreateSNESMF` 2456bbc1464cSBarry Smith @*/ 2457d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeMFFunction(SNES snes, Vec x, Vec y) 2458d71ae5a4SJacob Faibussowitsch { 2459bbc1464cSBarry Smith DM dm; 2460bbc1464cSBarry Smith DMSNES sdm; 2461bbc1464cSBarry Smith 2462bbc1464cSBarry Smith PetscFunctionBegin; 2463bbc1464cSBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2464bbc1464cSBarry Smith PetscValidHeaderSpecific(x, VEC_CLASSID, 2); 2465bbc1464cSBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 3); 2466bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, x, 2); 2467bbc1464cSBarry Smith PetscCheckSameComm(snes, 1, y, 3); 2468e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(x, 2, PETSC_TRUE)); 2469bbc1464cSBarry Smith 24709566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 24719566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 24729566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_FunctionEval, snes, x, y, 0)); 24739566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(x)); 2474bbc1464cSBarry Smith /* ensure domainerror is false prior to computefunction evaluation (may not have been reset) */ 2475bbc1464cSBarry Smith snes->domainerror = PETSC_FALSE; 2476792fecdfSBarry Smith PetscCallBack("SNES callback function", (*sdm->ops->computemffunction)(snes, x, y, sdm->mffunctionctx)); 24779566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(x)); 24789566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_FunctionEval, snes, x, y, 0)); 2479bbc1464cSBarry Smith snes->nfuncs++; 2480bbc1464cSBarry Smith /* 2481bbc1464cSBarry Smith domainerror might not be set on all processes; so we tag vector locally with Inf and the next inner product or norm will 2482bbc1464cSBarry Smith propagate the value to all processes 2483bbc1464cSBarry Smith */ 24841baa6e33SBarry Smith if (snes->domainerror) PetscCall(VecSetInf(y)); 24853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2486bbc1464cSBarry Smith } 2487bbc1464cSBarry Smith 2488bbc1464cSBarry Smith /*@ 2489f6dfbefdSBarry Smith SNESComputeNGS - Calls the Gauss-Seidel function that has been set with `SNESSetNGS()`. 2490c79ef259SPeter Brune 2491c3339decSBarry Smith Collective 2492c79ef259SPeter Brune 2493c79ef259SPeter Brune Input Parameters: 2494f6dfbefdSBarry Smith + snes - the `SNES` context 2495c79ef259SPeter Brune . x - input vector 2496c79ef259SPeter Brune - b - rhs vector 2497c79ef259SPeter Brune 2498c79ef259SPeter Brune Output Parameter: 2499c79ef259SPeter Brune . x - new solution vector 2500c79ef259SPeter Brune 2501dc4c0fb0SBarry Smith Level: developer 2502dc4c0fb0SBarry Smith 2503f6dfbefdSBarry Smith Note: 2504f6dfbefdSBarry Smith `SNESComputeNGS()` is typically used within composed nonlinear solver 2505c79ef259SPeter Brune implementations, so most users would not generally call this routine 2506c79ef259SPeter Brune themselves. 2507c79ef259SPeter Brune 2508dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESSetNGS()`, `SNESComputeFunction()` 2509c79ef259SPeter Brune @*/ 2510d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeNGS(SNES snes, Vec b, Vec x) 2511d71ae5a4SJacob Faibussowitsch { 25126cab3a1bSJed Brown DM dm; 2513942e3340SBarry Smith DMSNES sdm; 2514646217ecSPeter Brune 2515646217ecSPeter Brune PetscFunctionBegin; 2516646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 2517064a246eSJacob Faibussowitsch PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 2518064a246eSJacob Faibussowitsch if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 2519064a246eSJacob Faibussowitsch PetscCheckSameComm(snes, 1, x, 3); 2520064a246eSJacob Faibussowitsch if (b) PetscCheckSameComm(snes, 1, b, 2); 2521e0f629ddSJacob Faibussowitsch if (b) PetscCall(VecValidValues_Internal(b, 2, PETSC_TRUE)); 25229566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_NGSEval, snes, x, b, 0)); 25239566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 25249566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 25250fdf79fbSJacob Faibussowitsch PetscCheck(sdm->ops->computegs, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "Must call SNESSetNGS() before SNESComputeNGS(), likely called from SNESSolve()."); 25269566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPush(b)); 2527792fecdfSBarry Smith PetscCallBack("SNES callback NGS", (*sdm->ops->computegs)(snes, x, b, sdm->gsctx)); 25289566063dSJacob Faibussowitsch if (b) PetscCall(VecLockReadPop(b)); 25299566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_NGSEval, snes, x, b, 0)); 25303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2531646217ecSPeter Brune } 2532646217ecSPeter Brune 2533d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestJacobian(SNES snes) 2534d71ae5a4SJacob Faibussowitsch { 253512837594SBarry Smith Mat A, B, C, D, jacobian; 2536e885f1abSBarry Smith Vec x = snes->vec_sol, f = snes->vec_func; 2537e885f1abSBarry Smith PetscReal nrm, gnorm; 253881e7118cSBarry Smith PetscReal threshold = 1.e-5; 25390e276705SLisandro Dalcin MatType mattype; 2540e885f1abSBarry Smith PetscInt m, n, M, N; 2541e885f1abSBarry Smith void *functx; 25422cd624f9SStefano Zampini PetscBool complete_print = PETSC_FALSE, threshold_print = PETSC_FALSE, test = PETSC_FALSE, flg, istranspose; 25433325ff46SBarry Smith PetscViewer viewer, mviewer; 2544e885f1abSBarry Smith MPI_Comm comm; 2545e885f1abSBarry Smith PetscInt tabs; 254612837594SBarry Smith static PetscBool directionsprinted = PETSC_FALSE; 25473325ff46SBarry Smith PetscViewerFormat format; 2548e885f1abSBarry Smith 2549e885f1abSBarry Smith PetscFunctionBegin; 2550d0609cedSBarry Smith PetscObjectOptionsBegin((PetscObject)snes); 25519566063dSJacob Faibussowitsch PetscCall(PetscOptionsName("-snes_test_jacobian", "Compare hand-coded and finite difference Jacobians", "None", &test)); 25529566063dSJacob Faibussowitsch PetscCall(PetscOptionsReal("-snes_test_jacobian", "Threshold for element difference between hand-coded and finite difference being meaningful", "None", threshold, &threshold, NULL)); 25539566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_view", "View difference between hand-coded and finite difference Jacobians element entries", "None", &mviewer, &format, &complete_print)); 255418d89885SKarl Rupp if (!complete_print) { 25559566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display", "-snes_test_jacobian_view", "3.13", NULL)); 25569566063dSJacob Faibussowitsch PetscCall(PetscOptionsViewer("-snes_test_jacobian_display", "Display difference between hand-coded and finite difference Jacobians", "None", &mviewer, &format, &complete_print)); 255718d89885SKarl Rupp } 255818d89885SKarl Rupp /* for compatibility with PETSc 3.9 and older. */ 25599566063dSJacob Faibussowitsch PetscCall(PetscOptionsDeprecated("-snes_test_jacobian_display_threshold", "-snes_test_jacobian", "3.13", "-snes_test_jacobian accepts an optional threshold (since v3.10)")); 25609566063dSJacob 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)); 2561d0609cedSBarry Smith PetscOptionsEnd(); 25623ba16761SJacob Faibussowitsch if (!test) PetscFunctionReturn(PETSC_SUCCESS); 2563e885f1abSBarry Smith 25649566063dSJacob Faibussowitsch PetscCall(PetscObjectGetComm((PetscObject)snes, &comm)); 25659566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(comm, &viewer)); 25669566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetTab(viewer, &tabs)); 25679566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, ((PetscObject)snes)->tablevel)); 25689566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian -------------\n")); 256912837594SBarry Smith if (!complete_print && !directionsprinted) { 25709566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Run with -snes_test_jacobian_view and optionally -snes_test_jacobian <threshold> to show difference\n")); 25719566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " of hand-coded and finite difference Jacobian entries greater than <threshold>.\n")); 257212837594SBarry Smith } 257312837594SBarry Smith if (!directionsprinted) { 25749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Testing hand-coded Jacobian, if (for double precision runs) ||J - Jfd||_F/||J||_F is\n")); 25759566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " O(1.e-8), the hand-coded Jacobian is probably correct.\n")); 257612837594SBarry Smith directionsprinted = PETSC_TRUE; 2577e885f1abSBarry Smith } 25781baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPushFormat(mviewer, format)); 2579e885f1abSBarry Smith 25809566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes->jacobian, MATMFFD, &flg)); 258112837594SBarry Smith if (!flg) jacobian = snes->jacobian; 258212837594SBarry Smith else jacobian = snes->jacobian_pre; 258312837594SBarry Smith 2584a82339d0SMatthew G. Knepley if (!x) { 25859566063dSJacob Faibussowitsch PetscCall(MatCreateVecs(jacobian, &x, NULL)); 2586a82339d0SMatthew G. Knepley } else { 25879566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)x)); 2588a82339d0SMatthew G. Knepley } 2589a82339d0SMatthew G. Knepley if (!f) { 25909566063dSJacob Faibussowitsch PetscCall(VecDuplicate(x, &f)); 2591a82339d0SMatthew G. Knepley } else { 25929566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)f)); 2593a82339d0SMatthew G. Knepley } 2594a82339d0SMatthew G. Knepley /* evaluate the function at this point because SNESComputeJacobianDefault() assumes that the function has been evaluated and put into snes->vec_func */ 25959566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, x, f)); 25969566063dSJacob Faibussowitsch PetscCall(VecDestroy(&f)); 25979566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, SNESKSPTRANSPOSEONLY, &istranspose)); 259812837594SBarry Smith while (jacobian) { 25992cd624f9SStefano Zampini Mat JT = NULL, Jsave = NULL; 26002cd624f9SStefano Zampini 26012cd624f9SStefano Zampini if (istranspose) { 26029566063dSJacob Faibussowitsch PetscCall(MatCreateTranspose(jacobian, &JT)); 26032cd624f9SStefano Zampini Jsave = jacobian; 26042cd624f9SStefano Zampini jacobian = JT; 26052cd624f9SStefano Zampini } 26069566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)jacobian, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPISBAIJ, "")); 260712837594SBarry Smith if (flg) { 260812837594SBarry Smith A = jacobian; 26099566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)A)); 261012837594SBarry Smith } else { 26119566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(jacobian, MATAIJ, &A)); 261212837594SBarry Smith } 2613e885f1abSBarry Smith 26149566063dSJacob Faibussowitsch PetscCall(MatGetType(A, &mattype)); 26159566063dSJacob Faibussowitsch PetscCall(MatGetSize(A, &M, &N)); 26169566063dSJacob Faibussowitsch PetscCall(MatGetLocalSize(A, &m, &n)); 26179566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &B)); 26189566063dSJacob Faibussowitsch PetscCall(MatSetType(B, mattype)); 26199566063dSJacob Faibussowitsch PetscCall(MatSetSizes(B, m, n, M, N)); 26209566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(B, A, A)); 26219566063dSJacob Faibussowitsch PetscCall(MatSetUp(B)); 26229566063dSJacob Faibussowitsch PetscCall(MatSetOption(B, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 2623e885f1abSBarry Smith 26249566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, NULL, &functx)); 26259566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, x, B, B, functx)); 262612837594SBarry Smith 26279566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_COPY_VALUES, &D)); 26289566063dSJacob Faibussowitsch PetscCall(MatAYPX(D, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26299566063dSJacob Faibussowitsch PetscCall(MatNorm(D, NORM_FROBENIUS, &nrm)); 26309566063dSJacob Faibussowitsch PetscCall(MatNorm(A, NORM_FROBENIUS, &gnorm)); 26319566063dSJacob Faibussowitsch PetscCall(MatDestroy(&D)); 263212837594SBarry Smith if (!gnorm) gnorm = 1; /* just in case */ 26339566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ||J - Jfd||_F/||J||_F = %g, ||J - Jfd||_F = %g\n", (double)(nrm / gnorm), (double)nrm)); 263412837594SBarry Smith 2635e885f1abSBarry Smith if (complete_print) { 26369566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded Jacobian ----------\n")); 26379566063dSJacob Faibussowitsch PetscCall(MatView(A, mviewer)); 26389566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Finite difference Jacobian ----------\n")); 26399566063dSJacob Faibussowitsch PetscCall(MatView(B, mviewer)); 2640e885f1abSBarry Smith } 2641e885f1abSBarry Smith 2642df10fb39SFande Kong if (threshold_print || complete_print) { 2643e885f1abSBarry Smith PetscInt Istart, Iend, *ccols, bncols, cncols, j, row; 2644e885f1abSBarry Smith PetscScalar *cvals; 2645e885f1abSBarry Smith const PetscInt *bcols; 2646e885f1abSBarry Smith const PetscScalar *bvals; 2647e885f1abSBarry Smith 26489566063dSJacob Faibussowitsch PetscCall(MatCreate(PetscObjectComm((PetscObject)A), &C)); 26499566063dSJacob Faibussowitsch PetscCall(MatSetType(C, mattype)); 26509566063dSJacob Faibussowitsch PetscCall(MatSetSizes(C, m, n, M, N)); 26519566063dSJacob Faibussowitsch PetscCall(MatSetBlockSizesFromMats(C, A, A)); 26529566063dSJacob Faibussowitsch PetscCall(MatSetUp(C)); 26539566063dSJacob Faibussowitsch PetscCall(MatSetOption(C, MAT_NEW_NONZERO_ALLOCATION_ERR, PETSC_FALSE)); 26540e276705SLisandro Dalcin 26559566063dSJacob Faibussowitsch PetscCall(MatAYPX(B, -1.0, A, DIFFERENT_NONZERO_PATTERN)); 26569566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &Istart, &Iend)); 2657e885f1abSBarry Smith 2658e885f1abSBarry Smith for (row = Istart; row < Iend; row++) { 26599566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, row, &bncols, &bcols, &bvals)); 26609566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(bncols, &ccols, bncols, &cvals)); 2661e885f1abSBarry Smith for (j = 0, cncols = 0; j < bncols; j++) { 266223a52b1dSBarry Smith if (PetscAbsScalar(bvals[j]) > threshold) { 2663e885f1abSBarry Smith ccols[cncols] = bcols[j]; 2664e885f1abSBarry Smith cvals[cncols] = bvals[j]; 2665e885f1abSBarry Smith cncols += 1; 2666e885f1abSBarry Smith } 2667e885f1abSBarry Smith } 266848a46eb9SPierre Jolivet if (cncols) PetscCall(MatSetValues(C, 1, &row, cncols, ccols, cvals, INSERT_VALUES)); 26699566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, row, &bncols, &bcols, &bvals)); 26709566063dSJacob Faibussowitsch PetscCall(PetscFree2(ccols, cvals)); 2671e885f1abSBarry Smith } 26729566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(C, MAT_FINAL_ASSEMBLY)); 26739566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(C, MAT_FINAL_ASSEMBLY)); 26749566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " Hand-coded minus finite-difference Jacobian with tolerance %g ----------\n", (double)threshold)); 26759566063dSJacob Faibussowitsch PetscCall(MatView(C, complete_print ? mviewer : viewer)); 26769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&C)); 2677e885f1abSBarry Smith } 26789566063dSJacob Faibussowitsch PetscCall(MatDestroy(&A)); 26799566063dSJacob Faibussowitsch PetscCall(MatDestroy(&B)); 26809566063dSJacob Faibussowitsch PetscCall(MatDestroy(&JT)); 26812cd624f9SStefano Zampini if (Jsave) jacobian = Jsave; 268212837594SBarry Smith if (jacobian != snes->jacobian_pre) { 268312837594SBarry Smith jacobian = snes->jacobian_pre; 26849566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, " ---------- Testing Jacobian for preconditioner -------------\n")); 26859371c9d4SSatish Balay } else jacobian = NULL; 268612837594SBarry Smith } 26879566063dSJacob Faibussowitsch PetscCall(VecDestroy(&x)); 26881baa6e33SBarry Smith if (complete_print) PetscCall(PetscViewerPopFormat(mviewer)); 26899566063dSJacob Faibussowitsch if (mviewer) PetscCall(PetscViewerDestroy(&mviewer)); 26909566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISetTab(viewer, tabs)); 26913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2692e885f1abSBarry Smith } 2693e885f1abSBarry Smith 269462fef451SLois Curfman McInnes /*@ 2695f6dfbefdSBarry Smith SNESComputeJacobian - Computes the Jacobian matrix that has been set with `SNESSetJacobian()`. 269662fef451SLois Curfman McInnes 2697c3339decSBarry Smith Collective 2698c7afd0dbSLois Curfman McInnes 269962fef451SLois Curfman McInnes Input Parameters: 2700f6dfbefdSBarry Smith + snes - the `SNES` context 2701c7afd0dbSLois Curfman McInnes - x - input vector 270262fef451SLois Curfman McInnes 270362fef451SLois Curfman McInnes Output Parameters: 2704c7afd0dbSLois Curfman McInnes + A - Jacobian matrix 2705f6dfbefdSBarry Smith - B - optional matrix for building the preconditioner 2706fee21e36SBarry Smith 2707e35cf81dSBarry Smith Options Database Keys: 270867b8a455SSatish Balay + -snes_lag_preconditioner <lag> - how often to rebuild preconditioner 270967b8a455SSatish Balay . -snes_lag_jacobian <lag> - how often to rebuild Jacobian 2710455a5933SJed 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. 2711455a5933SJed 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 2712693365a8SJed Brown . -snes_compare_explicit - Compare the computed Jacobian to the finite difference Jacobian and output the differences 2713693365a8SJed Brown . -snes_compare_explicit_draw - Compare the computed Jacobian to the finite difference Jacobian and draw the result 2714693365a8SJed Brown . -snes_compare_explicit_contour - Compare the computed Jacobian to the finite difference Jacobian and draw a contour plot with the result 27154c30e9fbSJed Brown . -snes_compare_operator - Make the comparison options above use the operator instead of the preconditioning matrix 271694d6a431SBarry Smith . -snes_compare_coloring - Compute the finite difference Jacobian using coloring and display norms of difference 2717a5b23f4aSJose E. Roman . -snes_compare_coloring_display - Compute the finite difference Jacobian using coloring and display verbose differences 2718c01495d3SJed Brown . -snes_compare_coloring_threshold - Display only those matrix entries that differ by more than a given threshold 2719dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_atol - Absolute tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2720dc4c0fb0SBarry Smith . -snes_compare_coloring_threshold_rtol - Relative tolerance for difference in matrix entries to be displayed by `-snes_compare_coloring_threshold` 2721a5b23f4aSJose E. Roman . -snes_compare_coloring_draw - Compute the finite difference Jacobian using coloring and draw differences 2722a5b23f4aSJose E. Roman - -snes_compare_coloring_draw_contour - Compute the finite difference Jacobian using coloring and show contours of matrices and differences 2723c01495d3SJed Brown 2724dc4c0fb0SBarry Smith Level: developer 2725dc4c0fb0SBarry Smith 2726f6dfbefdSBarry Smith Note: 272762fef451SLois Curfman McInnes Most users should not need to explicitly call this routine, as it 272862fef451SLois Curfman McInnes is used internally within the nonlinear solvers. 272962fef451SLois Curfman McInnes 2730f6dfbefdSBarry Smith Developer Note: 2731dc4c0fb0SBarry 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 2732dc4c0fb0SBarry Smith for with the `SNESType` of test that has been removed. 2733e885f1abSBarry Smith 2734dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetJacobian()`, `KSPSetOperators()`, `MatStructure`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobian()` 273562fef451SLois Curfman McInnes @*/ 2736d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESComputeJacobian(SNES snes, Vec X, Mat A, Mat B) 2737d71ae5a4SJacob Faibussowitsch { 2738ace3abfcSBarry Smith PetscBool flag; 27396cab3a1bSJed Brown DM dm; 2740942e3340SBarry Smith DMSNES sdm; 2741e0e3a89bSBarry Smith KSP ksp; 27423a40ed3dSBarry Smith 27433a40ed3dSBarry Smith PetscFunctionBegin; 27440700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 27450700a824SBarry Smith PetscValidHeaderSpecific(X, VEC_CLASSID, 2); 2746c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, X, 2); 2747e0f629ddSJacob Faibussowitsch PetscCall(VecValidValues_Internal(X, 2, PETSC_TRUE)); 27489566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 27499566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 27503232da50SPeter Brune 2751ebd3b9afSBarry Smith /* make sure that MatAssemblyBegin/End() is called on A matrix if it is matrix free */ 2752fe3ffe1eSBarry Smith if (snes->lagjacobian == -2) { 2753fe3ffe1eSBarry Smith snes->lagjacobian = -1; 2754f5af7f23SKarl Rupp 27559566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Recomputing Jacobian/preconditioner because lag is -2 (means compute Jacobian, but then never again) \n")); 2756fe3ffe1eSBarry Smith } else if (snes->lagjacobian == -1) { 27579566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is -1\n")); 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); 276437ec4e1aSPeter Brune } else if (snes->lagjacobian > 1 && (snes->iter + snes->jac_iter) % snes->lagjacobian) { 276563a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing Jacobian/preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagjacobian, snes->iter)); 27669566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)A, MATMFFD, &flag)); 2767ebd3b9afSBarry Smith if (flag) { 27689566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27699566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 2770ebd3b9afSBarry Smith } 27713ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2772e35cf81dSBarry Smith } 2773efd4aadfSBarry Smith if (snes->npc && snes->npcside == PC_LEFT) { 27749566063dSJacob Faibussowitsch PetscCall(MatAssemblyBegin(A, MAT_FINAL_ASSEMBLY)); 27759566063dSJacob Faibussowitsch PetscCall(MatAssemblyEnd(A, MAT_FINAL_ASSEMBLY)); 27763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 2777d728fb7dSPeter Brune } 2778e35cf81dSBarry Smith 27799566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_JacobianEval, snes, X, A, B)); 27809566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(X)); 2781800f99ffSJeremy L Thompson { 2782800f99ffSJeremy L Thompson void *ctx; 2783800f99ffSJeremy L Thompson PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *); 2784800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, &J, &ctx)); 2785800f99ffSJeremy L Thompson PetscCallBack("SNES callback Jacobian", (*J)(snes, X, A, B, ctx)); 2786800f99ffSJeremy L Thompson } 27879566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(X)); 27889566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_JacobianEval, snes, X, A, B)); 278928d58a37SPierre Jolivet 279028d58a37SPierre Jolivet /* attach latest linearization point to the preconditioning matrix */ 27919566063dSJacob Faibussowitsch PetscCall(PetscObjectCompose((PetscObject)B, "__SNES_latest_X", (PetscObject)X)); 2792a8054027SBarry Smith 2793e0e3a89bSBarry Smith /* the next line ensures that snes->ksp exists */ 27949566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 27953b4f5425SBarry Smith if (snes->lagpreconditioner == -2) { 27969566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner exactly once since lag is -2\n")); 27979566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 27983b4f5425SBarry Smith snes->lagpreconditioner = -1; 27993b4f5425SBarry Smith } else if (snes->lagpreconditioner == -1) { 28009566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is -1\n")); 28019566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 280237ec4e1aSPeter Brune } else if (snes->lagpreconditioner > 1 && (snes->iter + snes->pre_iter) % snes->lagpreconditioner) { 280363a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Reusing preconditioner because lag is %" PetscInt_FMT " and SNES iteration is %" PetscInt_FMT "\n", snes->lagpreconditioner, snes->iter)); 28049566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_TRUE)); 2805d1e9a80fSBarry Smith } else { 28069566063dSJacob Faibussowitsch PetscCall(PetscInfo(snes, "Rebuilding preconditioner\n")); 28079566063dSJacob Faibussowitsch PetscCall(KSPSetReusePreconditioner(snes->ksp, PETSC_FALSE)); 2808a8054027SBarry Smith } 2809a8054027SBarry Smith 28109566063dSJacob Faibussowitsch PetscCall(SNESTestJacobian(snes)); 28116d84be18SBarry Smith /* make sure user returned a correct Jacobian and preconditioner */ 281294ab13aaSBarry Smith /* PetscValidHeaderSpecific(A,MAT_CLASSID,3); 281394ab13aaSBarry Smith PetscValidHeaderSpecific(B,MAT_CLASSID,4); */ 2814693365a8SJed Brown { 2815693365a8SJed Brown PetscBool flag = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_operator = PETSC_FALSE; 28169566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit", NULL, NULL, &flag)); 28179566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw", NULL, NULL, &flag_draw)); 28189566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_explicit_draw_contour", NULL, NULL, &flag_contour)); 28199566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_operator", NULL, NULL, &flag_operator)); 2820693365a8SJed Brown if (flag || flag_draw || flag_contour) { 28210298fd71SBarry Smith Mat Bexp_mine = NULL, Bexp, FDexp; 2822693365a8SJed Brown PetscViewer vdraw, vstdout; 28236b3a5b13SJed Brown PetscBool flg; 2824693365a8SJed Brown if (flag_operator) { 28259566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(A, MATAIJ, &Bexp_mine)); 2826693365a8SJed Brown Bexp = Bexp_mine; 2827693365a8SJed Brown } else { 2828693365a8SJed Brown /* See if the preconditioning matrix can be viewed and added directly */ 28299566063dSJacob Faibussowitsch PetscCall(PetscObjectBaseTypeCompareAny((PetscObject)B, &flg, MATSEQAIJ, MATMPIAIJ, MATSEQDENSE, MATMPIDENSE, MATSEQBAIJ, MATMPIBAIJ, MATSEQSBAIJ, MATMPIBAIJ, "")); 283094ab13aaSBarry Smith if (flg) Bexp = B; 2831693365a8SJed Brown else { 2832693365a8SJed Brown /* If the "preconditioning" matrix is itself MATSHELL or some other type without direct support */ 28339566063dSJacob Faibussowitsch PetscCall(MatComputeOperator(B, MATAIJ, &Bexp_mine)); 2834693365a8SJed Brown Bexp = Bexp_mine; 2835693365a8SJed Brown } 2836693365a8SJed Brown } 28379566063dSJacob Faibussowitsch PetscCall(MatConvert(Bexp, MATSAME, MAT_INITIAL_MATRIX, &FDexp)); 28389566063dSJacob Faibussowitsch PetscCall(SNESComputeJacobianDefault(snes, X, FDexp, FDexp, NULL)); 28399566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 2840693365a8SJed Brown if (flag_draw || flag_contour) { 28419566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Explicit Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 28429566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28430298fd71SBarry Smith } else vdraw = NULL; 28449566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit %s\n", flag_operator ? "Jacobian" : "preconditioning Jacobian")); 28459566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(Bexp, vstdout)); 28469566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bexp, vdraw)); 28479566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Finite difference Jacobian\n")); 28489566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 28499566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(FDexp, vdraw)); 28509566063dSJacob Faibussowitsch PetscCall(MatAYPX(FDexp, -1.0, Bexp, SAME_NONZERO_PATTERN)); 28519566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian\n")); 28529566063dSJacob Faibussowitsch if (flag) PetscCall(MatView(FDexp, vstdout)); 2853693365a8SJed Brown if (vdraw) { /* Always use contour for the difference */ 28549566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 28559566063dSJacob Faibussowitsch PetscCall(MatView(FDexp, vdraw)); 28569566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 2857693365a8SJed Brown } 28589566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 28599566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 28609566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bexp_mine)); 28619566063dSJacob Faibussowitsch PetscCall(MatDestroy(&FDexp)); 2862693365a8SJed Brown } 2863693365a8SJed Brown } 28644c30e9fbSJed Brown { 28656719d8e4SJed Brown PetscBool flag = PETSC_FALSE, flag_display = PETSC_FALSE, flag_draw = PETSC_FALSE, flag_contour = PETSC_FALSE, flag_threshold = PETSC_FALSE; 28666719d8e4SJed Brown PetscReal threshold_atol = PETSC_SQRT_MACHINE_EPSILON, threshold_rtol = 10 * PETSC_SQRT_MACHINE_EPSILON; 28679566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring", NULL, NULL, &flag)); 28689566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_display", NULL, NULL, &flag_display)); 28699566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw", NULL, NULL, &flag_draw)); 28709566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_draw_contour", NULL, NULL, &flag_contour)); 28719566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold", NULL, NULL, &flag_threshold)); 287227b0f280SBarry Smith if (flag_threshold) { 28739566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_rtol", &threshold_rtol, NULL)); 28749566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetReal(((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_compare_coloring_threshold_atol", &threshold_atol, NULL)); 287527b0f280SBarry Smith } 28766719d8e4SJed Brown if (flag || flag_display || flag_draw || flag_contour || flag_threshold) { 28774c30e9fbSJed Brown Mat Bfd; 28784c30e9fbSJed Brown PetscViewer vdraw, vstdout; 2879335efc43SPeter Brune MatColoring coloring; 28804c30e9fbSJed Brown ISColoring iscoloring; 28814c30e9fbSJed Brown MatFDColoring matfdcoloring; 28824c30e9fbSJed Brown PetscErrorCode (*func)(SNES, Vec, Vec, void *); 28834c30e9fbSJed Brown void *funcctx; 28846719d8e4SJed Brown PetscReal norm1, norm2, normmax; 28854c30e9fbSJed Brown 28869566063dSJacob Faibussowitsch PetscCall(MatDuplicate(B, MAT_DO_NOT_COPY_VALUES, &Bfd)); 28879566063dSJacob Faibussowitsch PetscCall(MatColoringCreate(Bfd, &coloring)); 28889566063dSJacob Faibussowitsch PetscCall(MatColoringSetType(coloring, MATCOLORINGSL)); 28899566063dSJacob Faibussowitsch PetscCall(MatColoringSetFromOptions(coloring)); 28909566063dSJacob Faibussowitsch PetscCall(MatColoringApply(coloring, &iscoloring)); 28919566063dSJacob Faibussowitsch PetscCall(MatColoringDestroy(&coloring)); 28929566063dSJacob Faibussowitsch PetscCall(MatFDColoringCreate(Bfd, iscoloring, &matfdcoloring)); 28939566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 28949566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetUp(Bfd, iscoloring, matfdcoloring)); 28959566063dSJacob Faibussowitsch PetscCall(ISColoringDestroy(&iscoloring)); 28964c30e9fbSJed Brown 28974c30e9fbSJed Brown /* This method of getting the function is currently unreliable since it doesn't work for DM local functions. */ 28989566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, NULL, &func, &funcctx)); 28999566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFunction(matfdcoloring, (PetscErrorCode(*)(void))func, funcctx)); 29009566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)matfdcoloring, ((PetscObject)snes)->prefix)); 29019566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)matfdcoloring, "coloring_")); 29029566063dSJacob Faibussowitsch PetscCall(MatFDColoringSetFromOptions(matfdcoloring)); 29039566063dSJacob Faibussowitsch PetscCall(MatFDColoringApply(Bfd, matfdcoloring, X, snes)); 29049566063dSJacob Faibussowitsch PetscCall(MatFDColoringDestroy(&matfdcoloring)); 29054c30e9fbSJed Brown 29069566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIGetStdout(PetscObjectComm((PetscObject)snes), &vstdout)); 29074c30e9fbSJed Brown if (flag_draw || flag_contour) { 29089566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawOpen(PetscObjectComm((PetscObject)snes), NULL, "Colored Jacobians", PETSC_DECIDE, PETSC_DECIDE, 300, 300, &vdraw)); 29099566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29100298fd71SBarry Smith } else vdraw = NULL; 29119566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Explicit preconditioning Jacobian\n")); 29129566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(B, vstdout)); 29139566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(B, vdraw)); 29149566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "Colored Finite difference Jacobian\n")); 29159566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29169566063dSJacob Faibussowitsch if (vdraw) PetscCall(MatView(Bfd, vdraw)); 29179566063dSJacob Faibussowitsch PetscCall(MatAYPX(Bfd, -1.0, B, SAME_NONZERO_PATTERN)); 29189566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_1, &norm1)); 29199566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_FROBENIUS, &norm2)); 29209566063dSJacob Faibussowitsch PetscCall(MatNorm(Bfd, NORM_MAX, &normmax)); 29219566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "User-provided matrix minus finite difference Jacobian, norm1=%g normFrob=%g normmax=%g\n", (double)norm1, (double)norm2, (double)normmax)); 29229566063dSJacob Faibussowitsch if (flag_display) PetscCall(MatView(Bfd, vstdout)); 29234c30e9fbSJed Brown if (vdraw) { /* Always use contour for the difference */ 29249566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(vdraw, PETSC_VIEWER_DRAW_CONTOUR)); 29259566063dSJacob Faibussowitsch PetscCall(MatView(Bfd, vdraw)); 29269566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(vdraw)); 29274c30e9fbSJed Brown } 29289566063dSJacob Faibussowitsch if (flag_contour) PetscCall(PetscViewerPopFormat(vdraw)); 29296719d8e4SJed Brown 29306719d8e4SJed Brown if (flag_threshold) { 29316719d8e4SJed Brown PetscInt bs, rstart, rend, i; 29329566063dSJacob Faibussowitsch PetscCall(MatGetBlockSize(B, &bs)); 29339566063dSJacob Faibussowitsch PetscCall(MatGetOwnershipRange(B, &rstart, &rend)); 29346719d8e4SJed Brown for (i = rstart; i < rend; i++) { 29356719d8e4SJed Brown const PetscScalar *ba, *ca; 29366719d8e4SJed Brown const PetscInt *bj, *cj; 29376719d8e4SJed Brown PetscInt bn, cn, j, maxentrycol = -1, maxdiffcol = -1, maxrdiffcol = -1; 29386719d8e4SJed Brown PetscReal maxentry = 0, maxdiff = 0, maxrdiff = 0; 29399566063dSJacob Faibussowitsch PetscCall(MatGetRow(B, i, &bn, &bj, &ba)); 29409566063dSJacob Faibussowitsch PetscCall(MatGetRow(Bfd, i, &cn, &cj, &ca)); 29415f80ce2aSJacob Faibussowitsch PetscCheck(bn == cn, ((PetscObject)A)->comm, PETSC_ERR_PLIB, "Unexpected different nonzero pattern in -snes_compare_coloring_threshold"); 29426719d8e4SJed Brown for (j = 0; j < bn; j++) { 29436719d8e4SJed Brown PetscReal rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 29446719d8e4SJed Brown if (PetscAbsScalar(ba[j]) > PetscAbs(maxentry)) { 29456719d8e4SJed Brown maxentrycol = bj[j]; 29466719d8e4SJed Brown maxentry = PetscRealPart(ba[j]); 29476719d8e4SJed Brown } 29486719d8e4SJed Brown if (PetscAbsScalar(ca[j]) > PetscAbs(maxdiff)) { 29496719d8e4SJed Brown maxdiffcol = bj[j]; 29506719d8e4SJed Brown maxdiff = PetscRealPart(ca[j]); 29516719d8e4SJed Brown } 29526719d8e4SJed Brown if (rdiff > maxrdiff) { 29536719d8e4SJed Brown maxrdiffcol = bj[j]; 29546719d8e4SJed Brown maxrdiff = rdiff; 29556719d8e4SJed Brown } 29566719d8e4SJed Brown } 29576719d8e4SJed Brown if (maxrdiff > 1) { 295863a3b9bcSJacob 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)); 29596719d8e4SJed Brown for (j = 0; j < bn; j++) { 29606719d8e4SJed Brown PetscReal rdiff; 29616719d8e4SJed Brown rdiff = PetscAbsScalar(ca[j]) / (threshold_atol + threshold_rtol * PetscAbsScalar(ba[j])); 296248a46eb9SPierre Jolivet if (rdiff > 1) PetscCall(PetscViewerASCIIPrintf(vstdout, " (%" PetscInt_FMT ",%g:%g)", bj[j], (double)PetscRealPart(ba[j]), (double)PetscRealPart(ca[j]))); 29636719d8e4SJed Brown } 296463a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(vstdout, "\n")); 29656719d8e4SJed Brown } 29669566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(B, i, &bn, &bj, &ba)); 29679566063dSJacob Faibussowitsch PetscCall(MatRestoreRow(Bfd, i, &cn, &cj, &ca)); 29686719d8e4SJed Brown } 29696719d8e4SJed Brown } 29709566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&vdraw)); 29719566063dSJacob Faibussowitsch PetscCall(MatDestroy(&Bfd)); 29724c30e9fbSJed Brown } 29734c30e9fbSJed Brown } 29743ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 29759b94acceSBarry Smith } 29769b94acceSBarry Smith 2977bf388a1fSBarry Smith /*MC 2978f6dfbefdSBarry Smith SNESJacobianFunction - Function used by `SNES` to compute the nonlinear Jacobian of the function to be solved by `SNES` 2979bf388a1fSBarry Smith 2980bf388a1fSBarry Smith Synopsis: 2981411c0326SBarry Smith #include "petscsnes.h" 2982411c0326SBarry Smith PetscErrorCode SNESJacobianFunction(SNES snes,Vec x,Mat Amat,Mat Pmat,void *ctx); 2983bf388a1fSBarry Smith 2984c3339decSBarry Smith Collective 29851843f636SBarry Smith 29861843f636SBarry Smith Input Parameters: 29871843f636SBarry Smith + x - input vector, the Jacobian is to be computed at this value 2988bf388a1fSBarry Smith - ctx - [optional] user-defined Jacobian context 2989bf388a1fSBarry Smith 29901843f636SBarry Smith Output Parameters: 29911843f636SBarry Smith + Amat - the matrix that defines the (approximate) Jacobian 2992dc4c0fb0SBarry Smith - Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 29931843f636SBarry Smith 2994878cb397SSatish Balay Level: intermediate 2995878cb397SSatish Balay 2996dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFunction()`, `SNESGetFunction()`, `SNESSetJacobian()`, `SNESGetJacobian()` 2997bf388a1fSBarry Smith M*/ 2998bf388a1fSBarry Smith 29999b94acceSBarry Smith /*@C 30009b94acceSBarry Smith SNESSetJacobian - Sets the function to compute Jacobian as well as the 3001044dda88SLois Curfman McInnes location to store the matrix. 30029b94acceSBarry Smith 3003c3339decSBarry Smith Logically Collective 3004c7afd0dbSLois Curfman McInnes 30059b94acceSBarry Smith Input Parameters: 3006f6dfbefdSBarry Smith + snes - the `SNES` context 3007e5d3d808SBarry Smith . Amat - the matrix that defines the (approximate) Jacobian 3008dc4c0fb0SBarry Smith . Pmat - the matrix to be used in constructing the preconditioner, usually the same as `Amat`. 3009dc4c0fb0SBarry Smith . J - Jacobian evaluation routine (if `NULL` then `SNES` retains any previously set value), see `SNESJacobianFunction` for details 3010c7afd0dbSLois Curfman McInnes - ctx - [optional] user-defined context for private data for the 3011dc4c0fb0SBarry Smith Jacobian evaluation routine (may be `NULL`) (if `NULL` then `SNES` retains any previously set value) 3012dc4c0fb0SBarry Smith 3013dc4c0fb0SBarry Smith Level: beginner 30149b94acceSBarry Smith 30159b94acceSBarry Smith Notes: 3016dc4c0fb0SBarry Smith If the `Amat` matrix and `Pmat` matrix are different you must call `MatAssemblyBegin()`/`MatAssemblyEnd()` on 301716913363SBarry Smith each matrix. 301816913363SBarry Smith 3019dc4c0fb0SBarry Smith If you know the operator `Amat` has a null space you can use `MatSetNullSpace()` and `MatSetTransposeNullSpace()` to supply the null 3020dc4c0fb0SBarry Smith space to `Amat` and the `KSP` solvers will automatically use that null space as needed during the solution process. 3021895c21f2SBarry Smith 3022dc4c0fb0SBarry Smith If using `SNESComputeJacobianDefaultColor()` to assemble a Jacobian, the `ctx` argument 3023f6dfbefdSBarry Smith must be a `MatFDColoring`. 3024a8a26c1eSJed Brown 3025c3cc8fd1SJed Brown Other defect-correction schemes can be used by computing a different matrix in place of the Jacobian. One common 3026f6dfbefdSBarry Smith example is to use the "Picard linearization" which only differentiates through the highest order parts of each term using `SNESSetPicard()` 3027c3cc8fd1SJed Brown 3028dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSPSetOperators()`, `SNESSetFunction()`, `MatMFFDComputeJacobian()`, `SNESComputeJacobianDefaultColor()`, `MatStructure`, 3029db781477SPatrick Sanan `SNESSetPicard()`, `SNESJacobianFunction` 30309b94acceSBarry Smith @*/ 3031d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetJacobian(SNES snes, Mat Amat, Mat Pmat, PetscErrorCode (*J)(SNES, Vec, Mat, Mat, void *), void *ctx) 3032d71ae5a4SJacob Faibussowitsch { 30336cab3a1bSJed Brown DM dm; 30343a7fca6bSBarry Smith 30353a40ed3dSBarry Smith PetscFunctionBegin; 30360700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3037e5d3d808SBarry Smith if (Amat) PetscValidHeaderSpecific(Amat, MAT_CLASSID, 2); 3038e5d3d808SBarry Smith if (Pmat) PetscValidHeaderSpecific(Pmat, MAT_CLASSID, 3); 3039e5d3d808SBarry Smith if (Amat) PetscCheckSameComm(snes, 1, Amat, 2); 3040e5d3d808SBarry Smith if (Pmat) PetscCheckSameComm(snes, 1, Pmat, 3); 30419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30429566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, J, ctx)); 3043e5d3d808SBarry Smith if (Amat) { 30449566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Amat)); 30459566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 3046f5af7f23SKarl Rupp 3047e5d3d808SBarry Smith snes->jacobian = Amat; 30483a7fca6bSBarry Smith } 3049e5d3d808SBarry Smith if (Pmat) { 30509566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)Pmat)); 30519566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 3052f5af7f23SKarl Rupp 3053e5d3d808SBarry Smith snes->jacobian_pre = Pmat; 30543a7fca6bSBarry Smith } 30553ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 30569b94acceSBarry Smith } 305762fef451SLois Curfman McInnes 3058c2aafc4cSSatish Balay /*@C 3059b4fd4287SBarry Smith SNESGetJacobian - Returns the Jacobian matrix and optionally the user 3060b4fd4287SBarry Smith provided context for evaluating the Jacobian. 3061b4fd4287SBarry Smith 3062f6dfbefdSBarry Smith Not Collective, but `Mat` object will be parallel if `SNES` object is 3063c7afd0dbSLois Curfman McInnes 3064b4fd4287SBarry Smith Input Parameter: 3065b4fd4287SBarry Smith . snes - the nonlinear solver context 3066b4fd4287SBarry Smith 3067b4fd4287SBarry Smith Output Parameters: 3068dc4c0fb0SBarry Smith + Amat - location to stash (approximate) Jacobian matrix (or `NULL`) 3069dc4c0fb0SBarry Smith . Pmat - location to stash matrix used to compute the preconditioner (or `NULL`) 307020f4b53cSBarry Smith . J - location to put Jacobian function (or `NULL`), for calling sequence see `SNESJacobianFunction` 3071dc4c0fb0SBarry Smith - ctx - location to stash Jacobian ctx (or `NULL`) 3072fee21e36SBarry Smith 307336851e7fSLois Curfman McInnes Level: advanced 307436851e7fSLois Curfman McInnes 3075dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `Mat`, `SNESSetJacobian()`, `SNESComputeJacobian()`, `SNESJacobianFunction`, `SNESGetFunction()` 3076b4fd4287SBarry Smith @*/ 3077d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetJacobian(SNES snes, Mat *Amat, Mat *Pmat, PetscErrorCode (**J)(SNES, Vec, Mat, Mat, void *), void **ctx) 3078d71ae5a4SJacob Faibussowitsch { 30796cab3a1bSJed Brown DM dm; 30806cab3a1bSJed Brown 30813a40ed3dSBarry Smith PetscFunctionBegin; 30820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3083e5d3d808SBarry Smith if (Amat) *Amat = snes->jacobian; 3084e5d3d808SBarry Smith if (Pmat) *Pmat = snes->jacobian_pre; 30859566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 3086800f99ffSJeremy L Thompson PetscCall(DMSNESGetJacobian(dm, J, ctx)); 30873ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3088b4fd4287SBarry Smith } 3089b4fd4287SBarry Smith 3090d71ae5a4SJacob Faibussowitsch static PetscErrorCode SNESSetDefaultComputeJacobian(SNES snes) 3091d71ae5a4SJacob Faibussowitsch { 309258b371f3SBarry Smith DM dm; 309358b371f3SBarry Smith DMSNES sdm; 309458b371f3SBarry Smith 309558b371f3SBarry Smith PetscFunctionBegin; 30969566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 30979566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 309858b371f3SBarry Smith if (!sdm->ops->computejacobian && snes->jacobian_pre) { 309958b371f3SBarry Smith DM dm; 310058b371f3SBarry Smith PetscBool isdense, ismf; 310158b371f3SBarry Smith 31029566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31039566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &isdense, MATSEQDENSE, MATMPIDENSE, MATDENSE, NULL)); 31049566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompareAny((PetscObject)snes->jacobian_pre, &ismf, MATMFFD, MATSHELL, NULL)); 310558b371f3SBarry Smith if (isdense) { 31069566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefault, NULL)); 310758b371f3SBarry Smith } else if (!ismf) { 31089566063dSJacob Faibussowitsch PetscCall(DMSNESSetJacobian(dm, SNESComputeJacobianDefaultColor, NULL)); 310958b371f3SBarry Smith } 311058b371f3SBarry Smith } 31113ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 311258b371f3SBarry Smith } 311358b371f3SBarry Smith 31149b94acceSBarry Smith /*@ 31159b94acceSBarry Smith SNESSetUp - Sets up the internal data structures for the later use 3116272ac6f2SLois Curfman McInnes of a nonlinear solver. 31179b94acceSBarry Smith 3118c3339decSBarry Smith Collective 3119fee21e36SBarry Smith 3120c7afd0dbSLois Curfman McInnes Input Parameters: 3121f6dfbefdSBarry Smith . snes - the `SNES` context 3122c7afd0dbSLois Curfman McInnes 3123dc4c0fb0SBarry Smith Level: advanced 3124dc4c0fb0SBarry Smith 3125f6dfbefdSBarry Smith Note: 3126f6dfbefdSBarry Smith For basic use of the `SNES` solvers the user need not explicitly call 3127f6dfbefdSBarry Smith `SNESSetUp()`, since these actions will automatically occur during 3128f6dfbefdSBarry Smith the call to `SNESSolve()`. However, if one wishes to control this 3129f6dfbefdSBarry Smith phase separately, `SNESSetUp()` should be called after `SNESCreate()` 3130f6dfbefdSBarry Smith and optional routines of the form SNESSetXXX(), but before `SNESSolve()`. 3131272ac6f2SLois Curfman McInnes 3132dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSolve()`, `SNESDestroy()` 31339b94acceSBarry Smith @*/ 3134d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUp(SNES snes) 3135d71ae5a4SJacob Faibussowitsch { 31366cab3a1bSJed Brown DM dm; 3137942e3340SBarry Smith DMSNES sdm; 3138c35f09e5SBarry Smith SNESLineSearch linesearch, pclinesearch; 31396e2a1849SPeter Brune void *lsprectx, *lspostctx; 31409b5c1c08SStefano Zampini PetscBool mf_operator, mf; 31419b5c1c08SStefano Zampini Vec f, fpc; 31429b5c1c08SStefano Zampini void *funcctx; 31439b5c1c08SStefano Zampini void *jacctx, *appctx; 31449b5c1c08SStefano Zampini Mat j, jpre; 31456b2b7091SBarry Smith PetscErrorCode (*precheck)(SNESLineSearch, Vec, Vec, PetscBool *, void *); 31466b2b7091SBarry Smith PetscErrorCode (*postcheck)(SNESLineSearch, Vec, Vec, Vec, PetscBool *, PetscBool *, void *); 31476e2a1849SPeter Brune PetscErrorCode (*func)(SNES, Vec, Vec, void *); 3148d1e9a80fSBarry Smith PetscErrorCode (*jac)(SNES, Vec, Mat, Mat, void *); 31493a40ed3dSBarry Smith 31503a40ed3dSBarry Smith PetscFunctionBegin; 31510700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 31523ba16761SJacob Faibussowitsch if (snes->setupcalled) PetscFunctionReturn(PETSC_SUCCESS); 3153fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventBegin(SNES_SetUp, snes, 0, 0, 0)); 31549b94acceSBarry Smith 315548a46eb9SPierre Jolivet if (!((PetscObject)snes)->type_name) PetscCall(SNESSetType(snes, SNESNEWTONLS)); 315685385478SLisandro Dalcin 31579566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &snes->vec_func, NULL, NULL)); 315858c9b817SLisandro Dalcin 31599566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31609566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(dm, &sdm)); 31619566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 316258b371f3SBarry Smith 316348a46eb9SPierre Jolivet if (!snes->vec_func) PetscCall(DMCreateGlobalVector(dm, &snes->vec_func)); 3164efd51863SBarry Smith 316548a46eb9SPierre Jolivet if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 3166b710008aSBarry Smith 3167d8d34be6SBarry Smith if (snes->linesearch) { 31689566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 31699566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(snes->linesearch, SNESComputeFunction)); 3170d8d34be6SBarry Smith } 31719e764e56SPeter Brune 31729b5c1c08SStefano Zampini PetscCall(SNESGetUseMatrixFree(snes, &mf_operator, &mf)); 3173b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 3174172a4300SPeter Brune snes->mf = PETSC_TRUE; 3175172a4300SPeter Brune snes->mf_operator = PETSC_FALSE; 3176172a4300SPeter Brune } 3177d8f46077SPeter Brune 3178efd4aadfSBarry Smith if (snes->npc) { 31796e2a1849SPeter Brune /* copy the DM over */ 31809566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 31819566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, dm)); 31826e2a1849SPeter Brune 31839566063dSJacob Faibussowitsch PetscCall(SNESGetFunction(snes, &f, &func, &funcctx)); 31849566063dSJacob Faibussowitsch PetscCall(VecDuplicate(f, &fpc)); 31859566063dSJacob Faibussowitsch PetscCall(SNESSetFunction(snes->npc, fpc, func, funcctx)); 31869566063dSJacob Faibussowitsch PetscCall(SNESGetJacobian(snes, &j, &jpre, &jac, &jacctx)); 31879566063dSJacob Faibussowitsch PetscCall(SNESSetJacobian(snes->npc, j, jpre, jac, jacctx)); 31889566063dSJacob Faibussowitsch PetscCall(SNESGetApplicationContext(snes, &appctx)); 31899566063dSJacob Faibussowitsch PetscCall(SNESSetApplicationContext(snes->npc, appctx)); 31909b5c1c08SStefano Zampini PetscCall(SNESSetUseMatrixFree(snes->npc, mf_operator, mf)); 31919566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fpc)); 31926e2a1849SPeter Brune 31936e2a1849SPeter Brune /* copy the function pointers over */ 31949566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)snes, (PetscObject)snes->npc)); 31956e2a1849SPeter Brune 31966e2a1849SPeter Brune /* default to 1 iteration */ 31979566063dSJacob Faibussowitsch PetscCall(SNESSetTolerances(snes->npc, 0.0, 0.0, 0.0, 1, snes->npc->max_funcs)); 3198efd4aadfSBarry Smith if (snes->npcside == PC_RIGHT) { 31999566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_FINAL_ONLY)); 3200a9936a0cSPeter Brune } else { 32019566063dSJacob Faibussowitsch PetscCall(SNESSetNormSchedule(snes->npc, SNES_NORM_NONE)); 3202a9936a0cSPeter Brune } 32039566063dSJacob Faibussowitsch PetscCall(SNESSetFromOptions(snes->npc)); 32046e2a1849SPeter Brune 32056e2a1849SPeter Brune /* copy the line search context over */ 3206d8d34be6SBarry Smith if (snes->linesearch && snes->npc->linesearch) { 32079566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32089566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes->npc, &pclinesearch)); 32099566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPreCheck(linesearch, &precheck, &lsprectx)); 32109566063dSJacob Faibussowitsch PetscCall(SNESLineSearchGetPostCheck(linesearch, &postcheck, &lspostctx)); 32119566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPreCheck(pclinesearch, precheck, lsprectx)); 32129566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetPostCheck(pclinesearch, postcheck, lspostctx)); 32139566063dSJacob Faibussowitsch PetscCall(PetscObjectCopyFortranFunctionPointers((PetscObject)linesearch, (PetscObject)pclinesearch)); 32146e2a1849SPeter Brune } 3215d8d34be6SBarry Smith } 32161baa6e33SBarry Smith if (snes->mf) PetscCall(SNESSetUpMatrixFree_Private(snes, snes->mf_operator, snes->mf_version)); 321748a46eb9SPierre Jolivet if (snes->ops->usercompute && !snes->user) PetscCall((*snes->ops->usercompute)(snes, (void **)&snes->user)); 32186e2a1849SPeter Brune 321937ec4e1aSPeter Brune snes->jac_iter = 0; 322037ec4e1aSPeter Brune snes->pre_iter = 0; 322137ec4e1aSPeter Brune 3222dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, setup); 322358c9b817SLisandro Dalcin 32249566063dSJacob Faibussowitsch PetscCall(SNESSetDefaultComputeJacobian(snes)); 322558b371f3SBarry Smith 3226b552625fSStefano Zampini if (snes->npc && snes->npcside == PC_LEFT) { 32276c67d002SPeter Brune if (snes->functype == SNES_FUNCTION_PRECONDITIONED) { 3228d8d34be6SBarry Smith if (snes->linesearch) { 32299566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &linesearch)); 32309566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetFunction(linesearch, SNESComputeFunctionDefaultNPC)); 32316c67d002SPeter Brune } 32326c67d002SPeter Brune } 3233d8d34be6SBarry Smith } 3234fc8bc0e3SRichard Tran Mills PetscCall(PetscLogEventEnd(SNES_SetUp, snes, 0, 0, 0)); 32357aaed0d8SBarry Smith snes->setupcalled = PETSC_TRUE; 32363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 32379b94acceSBarry Smith } 32389b94acceSBarry Smith 323937596af1SLisandro Dalcin /*@ 3240f6dfbefdSBarry Smith SNESReset - Resets a `SNES` context to the snessetupcalled = 0 state and removes any allocated `Vec`s and `Mat`s 324137596af1SLisandro Dalcin 3242c3339decSBarry Smith Collective 324337596af1SLisandro Dalcin 324437596af1SLisandro Dalcin Input Parameter: 3245f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 324637596af1SLisandro Dalcin 3247d25893d9SBarry Smith Level: intermediate 3248d25893d9SBarry Smith 324995452b02SPatrick Sanan Notes: 3250f6dfbefdSBarry Smith Call this if you wish to reuse a `SNES` but with different size vectors 325137596af1SLisandro Dalcin 3252f6dfbefdSBarry Smith Also calls the application context destroy routine set with `SNESSetComputeApplicationContext()` 3253f6dfbefdSBarry Smith 3254dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESDestroy()`, `SNESCreate()`, `SNESSetUp()`, `SNESSolve()` 325537596af1SLisandro Dalcin @*/ 3256d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESReset(SNES snes) 3257d71ae5a4SJacob Faibussowitsch { 325837596af1SLisandro Dalcin PetscFunctionBegin; 325937596af1SLisandro Dalcin PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3260d25893d9SBarry Smith if (snes->ops->userdestroy && snes->user) { 32619566063dSJacob Faibussowitsch PetscCall((*snes->ops->userdestroy)((void **)&snes->user)); 32620298fd71SBarry Smith snes->user = NULL; 3263d25893d9SBarry Smith } 32641baa6e33SBarry Smith if (snes->npc) PetscCall(SNESReset(snes->npc)); 32658a23116dSBarry Smith 3266dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, reset); 32671baa6e33SBarry Smith if (snes->ksp) PetscCall(KSPReset(snes->ksp)); 32689e764e56SPeter Brune 32691baa6e33SBarry Smith if (snes->linesearch) PetscCall(SNESLineSearchReset(snes->linesearch)); 32709e764e56SPeter Brune 32719566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 32729566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 32739566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol_update)); 32749566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_func)); 32759566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian)); 32769566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->jacobian_pre)); 32779566063dSJacob Faibussowitsch PetscCall(MatDestroy(&snes->picard)); 32789566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nwork, &snes->work)); 32799566063dSJacob Faibussowitsch PetscCall(VecDestroyVecs(snes->nvwork, &snes->vwork)); 3280f5af7f23SKarl Rupp 328140fdac6aSLawrence Mitchell snes->alwayscomputesfinalresidual = PETSC_FALSE; 328240fdac6aSLawrence Mitchell 328337596af1SLisandro Dalcin snes->nwork = snes->nvwork = 0; 328437596af1SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 32853ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 328637596af1SLisandro Dalcin } 328737596af1SLisandro Dalcin 328852baeb72SSatish Balay /*@ 3289f6dfbefdSBarry Smith SNESConvergedReasonViewCancel - Clears all the reason view functions for a `SNES` object. 3290c4421ceaSFande Kong 3291c3339decSBarry Smith Collective 3292c4421ceaSFande Kong 3293c4421ceaSFande Kong Input Parameter: 3294f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 3295c4421ceaSFande Kong 3296c4421ceaSFande Kong Level: intermediate 3297c4421ceaSFande Kong 3298dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESReset()` 3299c4421ceaSFande Kong @*/ 3300d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewCancel(SNES snes) 3301d71ae5a4SJacob Faibussowitsch { 3302c4421ceaSFande Kong PetscInt i; 3303c4421ceaSFande Kong 3304c4421ceaSFande Kong PetscFunctionBegin; 3305c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3306c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 330748a46eb9SPierre Jolivet if (snes->reasonviewdestroy[i]) PetscCall((*snes->reasonviewdestroy[i])(&snes->reasonviewcontext[i])); 3308c4421ceaSFande Kong } 3309c4421ceaSFande Kong snes->numberreasonviews = 0; 33103ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3311c4421ceaSFande Kong } 3312c4421ceaSFande Kong 33131fb7b255SJunchao Zhang /*@C 33149b94acceSBarry Smith SNESDestroy - Destroys the nonlinear solver context that was created 3315f6dfbefdSBarry Smith with `SNESCreate()`. 33169b94acceSBarry Smith 3317c3339decSBarry Smith Collective 3318c7afd0dbSLois Curfman McInnes 33199b94acceSBarry Smith Input Parameter: 3320f6dfbefdSBarry Smith . snes - the `SNES` context 33219b94acceSBarry Smith 332236851e7fSLois Curfman McInnes Level: beginner 332336851e7fSLois Curfman McInnes 3324dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESSolve()` 33259b94acceSBarry Smith @*/ 3326d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESDestroy(SNES *snes) 3327d71ae5a4SJacob Faibussowitsch { 33283a40ed3dSBarry Smith PetscFunctionBegin; 33293ba16761SJacob Faibussowitsch if (!*snes) PetscFunctionReturn(PETSC_SUCCESS); 33306bf464f9SBarry Smith PetscValidHeaderSpecific((*snes), SNES_CLASSID, 1); 33319371c9d4SSatish Balay if (--((PetscObject)(*snes))->refct > 0) { 33329371c9d4SSatish Balay *snes = NULL; 33333ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33349371c9d4SSatish Balay } 3335d4bb536fSBarry Smith 33369566063dSJacob Faibussowitsch PetscCall(SNESReset((*snes))); 33379566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&(*snes)->npc)); 33386b8b9a38SLisandro Dalcin 3339e04113cfSBarry Smith /* if memory was published with SAWs then destroy it */ 33409566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsViewOff((PetscObject)*snes)); 3341dbbe0bcdSBarry Smith PetscTryTypeMethod((*snes), destroy); 33426d4c513bSLisandro Dalcin 33439566063dSJacob Faibussowitsch if ((*snes)->dm) PetscCall(DMCoarsenHookRemove((*snes)->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, *snes)); 33449566063dSJacob Faibussowitsch PetscCall(DMDestroy(&(*snes)->dm)); 33459566063dSJacob Faibussowitsch PetscCall(KSPDestroy(&(*snes)->ksp)); 33469566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&(*snes)->linesearch)); 33476b8b9a38SLisandro Dalcin 33489566063dSJacob Faibussowitsch PetscCall(PetscFree((*snes)->kspconvctx)); 334948a46eb9SPierre Jolivet if ((*snes)->ops->convergeddestroy) PetscCall((*(*snes)->ops->convergeddestroy)((*snes)->cnvP)); 335048a46eb9SPierre Jolivet if ((*snes)->conv_hist_alloc) PetscCall(PetscFree2((*snes)->conv_hist, (*snes)->conv_hist_its)); 33519566063dSJacob Faibussowitsch PetscCall(SNESMonitorCancel((*snes))); 33529566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewCancel((*snes))); 33539566063dSJacob Faibussowitsch PetscCall(PetscHeaderDestroy(snes)); 33543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 33559b94acceSBarry Smith } 33569b94acceSBarry Smith 33579b94acceSBarry Smith /* ----------- Routines to set solver parameters ---------- */ 33589b94acceSBarry Smith 3359a8054027SBarry Smith /*@ 3360a8054027SBarry Smith SNESSetLagPreconditioner - Determines when the preconditioner is rebuilt in the nonlinear solve. 3361a8054027SBarry Smith 3362c3339decSBarry Smith Logically Collective 3363a8054027SBarry Smith 3364a8054027SBarry Smith Input Parameters: 3365f6dfbefdSBarry Smith + snes - the `SNES` context 3366d8e291bfSBarry Smith - lag - 1 means rebuild every time the Jacobian is computed within a single nonlinear solve, 2 means every second time 33673b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3368a8054027SBarry Smith 3369a8054027SBarry Smith Options Database Keys: 33703d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 33713d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 33723d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 33733d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3374a8054027SBarry Smith 3375a8054027SBarry Smith Notes: 3376dc4c0fb0SBarry Smith Level: intermediate 3377dc4c0fb0SBarry Smith 3378a8054027SBarry Smith The default is 1 3379f6dfbefdSBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagPreconditionerPersists()` was called 3380d8e291bfSBarry Smith 3381f6dfbefdSBarry Smith `SNESSetLagPreconditionerPersists()` allows using the same uniform lagging (for example every second linear solve) across multiple nonlinear solves. 3382a8054027SBarry Smith 3383dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetLagPreconditionerPersists()`, 3384f6dfbefdSBarry Smith `SNESSetLagJacobianPersists()`, `SNES`, `SNESSolve()` 3385a8054027SBarry Smith @*/ 3386d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditioner(SNES snes, PetscInt lag) 3387d71ae5a4SJacob Faibussowitsch { 3388a8054027SBarry Smith PetscFunctionBegin; 33890700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 33905f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 33915f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3392c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3393a8054027SBarry Smith snes->lagpreconditioner = lag; 33943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3395a8054027SBarry Smith } 3396a8054027SBarry Smith 3397efd51863SBarry Smith /*@ 3398f6dfbefdSBarry Smith SNESSetGridSequence - sets the number of steps of grid sequencing that `SNES` will do 3399efd51863SBarry Smith 3400c3339decSBarry Smith Logically Collective 3401efd51863SBarry Smith 3402efd51863SBarry Smith Input Parameters: 3403f6dfbefdSBarry Smith + snes - the `SNES` context 3404efd51863SBarry Smith - steps - the number of refinements to do, defaults to 0 3405efd51863SBarry Smith 3406f6dfbefdSBarry Smith Options Database Key: 340767b8a455SSatish Balay . -snes_grid_sequence <steps> - Use grid sequencing to generate initial guess 3408efd51863SBarry Smith 3409efd51863SBarry Smith Level: intermediate 3410efd51863SBarry Smith 3411f6dfbefdSBarry Smith Note: 3412f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3413c0df2a02SJed Brown 3414dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetGridSequence()` 3415efd51863SBarry Smith @*/ 3416d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetGridSequence(SNES snes, PetscInt steps) 3417d71ae5a4SJacob Faibussowitsch { 3418efd51863SBarry Smith PetscFunctionBegin; 3419efd51863SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3420efd51863SBarry Smith PetscValidLogicalCollectiveInt(snes, steps, 2); 3421efd51863SBarry Smith snes->gridsequence = steps; 34223ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3423efd51863SBarry Smith } 3424efd51863SBarry Smith 3425fa19ca70SBarry Smith /*@ 3426f6dfbefdSBarry Smith SNESGetGridSequence - gets the number of steps of grid sequencing that `SNES` will do 3427fa19ca70SBarry Smith 3428c3339decSBarry Smith Logically Collective 3429fa19ca70SBarry Smith 3430fa19ca70SBarry Smith Input Parameter: 3431f6dfbefdSBarry Smith . snes - the `SNES` context 3432fa19ca70SBarry Smith 3433fa19ca70SBarry Smith Output Parameter: 3434fa19ca70SBarry Smith . steps - the number of refinements to do, defaults to 0 3435fa19ca70SBarry Smith 3436f6dfbefdSBarry Smith Options Database Key: 343767b8a455SSatish Balay . -snes_grid_sequence <steps> - set number of refinements 3438fa19ca70SBarry Smith 3439fa19ca70SBarry Smith Level: intermediate 3440fa19ca70SBarry Smith 3441f6dfbefdSBarry Smith Note: 3442f6dfbefdSBarry Smith Use `SNESGetSolution()` to extract the fine grid solution after grid sequencing. 3443fa19ca70SBarry Smith 3444dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESSetGridSequence()` 3445fa19ca70SBarry Smith @*/ 3446d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetGridSequence(SNES snes, PetscInt *steps) 3447d71ae5a4SJacob Faibussowitsch { 3448fa19ca70SBarry Smith PetscFunctionBegin; 3449fa19ca70SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3450fa19ca70SBarry Smith *steps = snes->gridsequence; 34513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3452fa19ca70SBarry Smith } 3453fa19ca70SBarry Smith 3454a8054027SBarry Smith /*@ 3455f6dfbefdSBarry Smith SNESGetLagPreconditioner - Return how often the preconditioner is rebuilt 3456a8054027SBarry Smith 34573f9fe445SBarry Smith Not Collective 3458a8054027SBarry Smith 3459a8054027SBarry Smith Input Parameter: 3460f6dfbefdSBarry Smith . snes - the `SNES` context 3461a8054027SBarry Smith 3462a8054027SBarry Smith Output Parameter: 3463a8054027SBarry 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 34643b4f5425SBarry Smith the Jacobian is built etc. -2 indicates rebuild preconditioner at next chance but then never rebuild after that 3465a8054027SBarry Smith 3466a8054027SBarry Smith Options Database Keys: 34673d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 34683d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 34693d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 34703d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 3471a8054027SBarry Smith 3472dc4c0fb0SBarry Smith Level: intermediate 3473dc4c0fb0SBarry Smith 3474a8054027SBarry Smith Notes: 3475a8054027SBarry Smith The default is 1 3476f6dfbefdSBarry Smith 3477a8054027SBarry Smith The preconditioner is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3478a8054027SBarry Smith 3479dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3480a8054027SBarry Smith @*/ 3481d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagPreconditioner(SNES snes, PetscInt *lag) 3482d71ae5a4SJacob Faibussowitsch { 3483a8054027SBarry Smith PetscFunctionBegin; 34840700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3485a8054027SBarry Smith *lag = snes->lagpreconditioner; 34863ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3487a8054027SBarry Smith } 3488a8054027SBarry Smith 3489e35cf81dSBarry Smith /*@ 3490f6dfbefdSBarry Smith SNESSetLagJacobian - Set when the Jacobian is rebuilt in the nonlinear solve. See `SNESSetLagPreconditioner()` for determining how 3491e35cf81dSBarry Smith often the preconditioner is rebuilt. 3492e35cf81dSBarry Smith 3493c3339decSBarry Smith Logically Collective 3494e35cf81dSBarry Smith 3495e35cf81dSBarry Smith Input Parameters: 3496f6dfbefdSBarry Smith + snes - the `SNES` context 3497e35cf81dSBarry 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 3498fe3ffe1eSBarry Smith the Jacobian is built etc. -2 means rebuild at next chance but then never again 3499e35cf81dSBarry Smith 3500e35cf81dSBarry Smith Options Database Keys: 35013d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35023d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35033d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35043d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag. 3505e35cf81dSBarry Smith 3506dc4c0fb0SBarry Smith Level: intermediate 3507dc4c0fb0SBarry Smith 3508e35cf81dSBarry Smith Notes: 3509e35cf81dSBarry Smith The default is 1 3510f6dfbefdSBarry Smith 3511e35cf81dSBarry Smith The Jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 3512f6dfbefdSBarry Smith 3513fe3ffe1eSBarry 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 3514fe3ffe1eSBarry Smith at the next Newton step but never again (unless it is reset to another value) 3515e35cf81dSBarry Smith 3516dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESGetLagPreconditioner()`, `SNESSetLagPreconditioner()`, `SNESGetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3517e35cf81dSBarry Smith @*/ 3518d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobian(SNES snes, PetscInt lag) 3519d71ae5a4SJacob Faibussowitsch { 3520e35cf81dSBarry Smith PetscFunctionBegin; 35210700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 35225f80ce2aSJacob Faibussowitsch PetscCheck(lag >= -2, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag must be -2, -1, 1 or greater"); 35235f80ce2aSJacob Faibussowitsch PetscCheck(lag, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Lag cannot be 0"); 3524c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, lag, 2); 3525e35cf81dSBarry Smith snes->lagjacobian = lag; 35263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3527e35cf81dSBarry Smith } 3528e35cf81dSBarry Smith 3529e35cf81dSBarry Smith /*@ 3530f6dfbefdSBarry Smith SNESGetLagJacobian - Get how often the Jacobian is rebuilt. See `SNESGetLagPreconditioner()` to determine when the preconditioner is rebuilt 3531e35cf81dSBarry Smith 35323f9fe445SBarry Smith Not Collective 3533e35cf81dSBarry Smith 3534e35cf81dSBarry Smith Input Parameter: 3535f6dfbefdSBarry Smith . snes - the `SNES` context 3536e35cf81dSBarry Smith 3537e35cf81dSBarry Smith Output Parameter: 3538e35cf81dSBarry 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 3539e35cf81dSBarry Smith the Jacobian is built etc. 3540e35cf81dSBarry Smith 3541dc4c0fb0SBarry Smith Level: intermediate 3542dc4c0fb0SBarry Smith 3543e35cf81dSBarry Smith Notes: 3544e35cf81dSBarry Smith The default is 1 3545f6dfbefdSBarry Smith 3546f6dfbefdSBarry Smith The jacobian is ALWAYS built in the first iteration of a nonlinear solve unless lag is -1 or `SNESSetLagJacobianPersists()` was called. 3547e35cf81dSBarry Smith 3548dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetLagJacobian()`, `SNESSetLagPreconditioner()`, `SNESGetLagPreconditioner()`, `SNESSetLagJacobianPersists()`, `SNESSetLagPreconditionerPersists()` 3549e35cf81dSBarry Smith 3550e35cf81dSBarry Smith @*/ 3551d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLagJacobian(SNES snes, PetscInt *lag) 3552d71ae5a4SJacob Faibussowitsch { 3553e35cf81dSBarry Smith PetscFunctionBegin; 35540700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3555e35cf81dSBarry Smith *lag = snes->lagjacobian; 35563ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3557e35cf81dSBarry Smith } 3558e35cf81dSBarry Smith 355937ec4e1aSPeter Brune /*@ 3560f6dfbefdSBarry Smith SNESSetLagJacobianPersists - Set whether or not the Jacobian lagging persists through multiple nonlinear solves 356137ec4e1aSPeter Brune 3562c3339decSBarry Smith Logically collective 356337ec4e1aSPeter Brune 3564d8d19677SJose E. Roman Input Parameters: 3565f6dfbefdSBarry Smith + snes - the `SNES` context 35669d7e2deaSPeter Brune - flg - jacobian lagging persists if true 356737ec4e1aSPeter Brune 356837ec4e1aSPeter Brune Options Database Keys: 35693d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 35703d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 35713d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 35723d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 35733d5a8a6aSBarry Smith 3574dc4c0fb0SBarry Smith Level: advanced 3575dc4c0fb0SBarry Smith 357695452b02SPatrick Sanan Notes: 3577f6dfbefdSBarry Smith Normally when `SNESSetLagJacobian()` is used, the Jacobian is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3578f6dfbefdSBarry Smith 357995452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the Jacobian be stale by 358037ec4e1aSPeter Brune several solves, and for implicit time-stepping, where Jacobian lagging in the inner nonlinear solve over several 358137ec4e1aSPeter Brune timesteps may present huge efficiency gains. 358237ec4e1aSPeter Brune 3583dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES, `SNESSetLagPreconditionerPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagJacobianPersists()` 358437ec4e1aSPeter Brune @*/ 3585d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagJacobianPersists(SNES snes, PetscBool flg) 3586d71ae5a4SJacob Faibussowitsch { 358737ec4e1aSPeter Brune PetscFunctionBegin; 358837ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 358937ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 359037ec4e1aSPeter Brune snes->lagjac_persist = flg; 35913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 359237ec4e1aSPeter Brune } 359337ec4e1aSPeter Brune 359437ec4e1aSPeter Brune /*@ 3595d8e291bfSBarry Smith SNESSetLagPreconditionerPersists - Set whether or not the preconditioner lagging persists through multiple nonlinear solves 359637ec4e1aSPeter Brune 3597c3339decSBarry Smith Logically Collective 359837ec4e1aSPeter Brune 3599d8d19677SJose E. Roman Input Parameters: 3600f6dfbefdSBarry Smith + snes - the `SNES` context 36019d7e2deaSPeter Brune - flg - preconditioner lagging persists if true 360237ec4e1aSPeter Brune 360337ec4e1aSPeter Brune Options Database Keys: 36043d5a8a6aSBarry Smith + -snes_lag_jacobian_persists <true,false> - sets the persistence 36053d5a8a6aSBarry Smith . -snes_lag_jacobian <-2,1,2,...> - sets the lag 36063d5a8a6aSBarry Smith . -snes_lag_preconditioner_persists <true,false> - sets the persistence 36073d5a8a6aSBarry Smith - -snes_lag_preconditioner <-2,1,2,...> - sets the lag 360837ec4e1aSPeter Brune 3609dc4c0fb0SBarry Smith Level: developer 3610dc4c0fb0SBarry Smith 361195452b02SPatrick Sanan Notes: 3612f6dfbefdSBarry Smith Normally when `SNESSetLagPreconditioner()` is used, the preconditioner is always rebuilt at the beginning of each new nonlinear solve, this removes that. 3613f6dfbefdSBarry Smith 361495452b02SPatrick Sanan This is useful both for nonlinear preconditioning, where it's appropriate to have the preconditioner be stale 361537ec4e1aSPeter Brune by several solves, and for implicit time-stepping, where preconditioner lagging in the inner nonlinear solve over 361637ec4e1aSPeter Brune several timesteps may present huge efficiency gains. 361737ec4e1aSPeter Brune 3618dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetLagJacobianPersists()`, `SNESSetLagJacobian()`, `SNESGetLagJacobian()`, `SNESGetNPC()`, `SNESSetLagPreconditioner()` 361937ec4e1aSPeter Brune @*/ 3620d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLagPreconditionerPersists(SNES snes, PetscBool flg) 3621d71ae5a4SJacob Faibussowitsch { 362237ec4e1aSPeter Brune PetscFunctionBegin; 362337ec4e1aSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 362437ec4e1aSPeter Brune PetscValidLogicalCollectiveBool(snes, flg, 2); 362537ec4e1aSPeter Brune snes->lagpre_persist = flg; 36263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 362737ec4e1aSPeter Brune } 362837ec4e1aSPeter Brune 36299b94acceSBarry Smith /*@ 3630f6dfbefdSBarry Smith SNESSetForceIteration - force `SNESSolve()` to take at least one iteration regardless of the initial residual norm 3631be5caee7SBarry Smith 3632c3339decSBarry Smith Logically Collective 3633be5caee7SBarry Smith 3634be5caee7SBarry Smith Input Parameters: 3635f6dfbefdSBarry Smith + snes - the `SNES` context 3636f6dfbefdSBarry Smith - force - `PETSC_TRUE` require at least one iteration 3637be5caee7SBarry Smith 3638f6dfbefdSBarry Smith Options Database Key: 3639be5caee7SBarry Smith . -snes_force_iteration <force> - Sets forcing an iteration 3640be5caee7SBarry Smith 3641dc4c0fb0SBarry Smith Level: intermediate 3642dc4c0fb0SBarry Smith 3643f6dfbefdSBarry Smith Note: 3644f6dfbefdSBarry Smith This is used sometimes with `TS` to prevent `TS` from detecting a false steady state solution 3645be5caee7SBarry Smith 3646dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `TS`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 3647be5caee7SBarry Smith @*/ 3648d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetForceIteration(SNES snes, PetscBool force) 3649d71ae5a4SJacob Faibussowitsch { 3650be5caee7SBarry Smith PetscFunctionBegin; 3651be5caee7SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3652be5caee7SBarry Smith snes->forceiteration = force; 36533ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3654be5caee7SBarry Smith } 3655be5caee7SBarry Smith 365685216dc7SFande Kong /*@ 3657f6dfbefdSBarry Smith SNESGetForceIteration - Check whether or not `SNESSolve()` take at least one iteration regardless of the initial residual norm 365885216dc7SFande Kong 3659c3339decSBarry Smith Logically Collective 366085216dc7SFande Kong 366185216dc7SFande Kong Input Parameters: 3662f6dfbefdSBarry Smith . snes - the `SNES` context 366385216dc7SFande Kong 366485216dc7SFande Kong Output Parameter: 3665dc4c0fb0SBarry Smith . force - `PETSC_TRUE` requires at least one iteration. 366685216dc7SFande Kong 366706dd6b0eSSatish Balay Level: intermediate 366806dd6b0eSSatish Balay 3669dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetForceIteration()`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()` 367085216dc7SFande Kong @*/ 3671d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetForceIteration(SNES snes, PetscBool *force) 3672d71ae5a4SJacob Faibussowitsch { 367385216dc7SFande Kong PetscFunctionBegin; 367485216dc7SFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 367585216dc7SFande Kong *force = snes->forceiteration; 36763ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 367785216dc7SFande Kong } 3678be5caee7SBarry Smith 3679be5caee7SBarry Smith /*@ 3680f6dfbefdSBarry Smith SNESSetTolerances - Sets `SNES` various parameters used in convergence tests. 36819b94acceSBarry Smith 3682c3339decSBarry Smith Logically Collective 3683c7afd0dbSLois Curfman McInnes 36849b94acceSBarry Smith Input Parameters: 3685f6dfbefdSBarry Smith + snes - the `SNES` context 368670441072SBarry Smith . abstol - absolute convergence tolerance 368733174efeSLois Curfman McInnes . rtol - relative convergence tolerance 36885358d0d4SBarry Smith . stol - convergence tolerance in terms of the norm of the change in the solution between steps, || delta x || < stol*|| x || 3689f6dfbefdSBarry Smith . maxit - maximum number of iterations, default 50. 3690f6dfbefdSBarry Smith - maxf - maximum number of function evaluations (-1 indicates no limit), default 1000 3691fee21e36SBarry Smith 369233174efeSLois Curfman McInnes Options Database Keys: 369370441072SBarry Smith + -snes_atol <abstol> - Sets abstol 3694c7afd0dbSLois Curfman McInnes . -snes_rtol <rtol> - Sets rtol 3695c7afd0dbSLois Curfman McInnes . -snes_stol <stol> - Sets stol 3696c7afd0dbSLois Curfman McInnes . -snes_max_it <maxit> - Sets maxit 3697c7afd0dbSLois Curfman McInnes - -snes_max_funcs <maxf> - Sets maxf 36989b94acceSBarry Smith 369936851e7fSLois Curfman McInnes Level: intermediate 370036851e7fSLois Curfman McInnes 3701dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESolve()`, `SNES`, `SNESSetTrustRegionTolerance()`, `SNESSetDivergenceTolerance()`, `SNESSetForceIteration()` 37029b94acceSBarry Smith @*/ 3703d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTolerances(SNES snes, PetscReal abstol, PetscReal rtol, PetscReal stol, PetscInt maxit, PetscInt maxf) 3704d71ae5a4SJacob Faibussowitsch { 37053a40ed3dSBarry Smith PetscFunctionBegin; 37060700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3707c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, abstol, 2); 3708c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol, 3); 3709c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, stol, 4); 3710c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxit, 5); 3711c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, maxf, 6); 3712c5eb9154SBarry Smith 371313bcc0bdSJacob Faibussowitsch if (abstol != (PetscReal)PETSC_DEFAULT) { 37145f80ce2aSJacob Faibussowitsch PetscCheck(abstol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Absolute tolerance %g must be non-negative", (double)abstol); 3715ab54825eSJed Brown snes->abstol = abstol; 3716ab54825eSJed Brown } 371713bcc0bdSJacob Faibussowitsch if (rtol != (PetscReal)PETSC_DEFAULT) { 37185f80ce2aSJacob 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); 3719ab54825eSJed Brown snes->rtol = rtol; 3720ab54825eSJed Brown } 372113bcc0bdSJacob Faibussowitsch if (stol != (PetscReal)PETSC_DEFAULT) { 37225f80ce2aSJacob Faibussowitsch PetscCheck(stol >= 0.0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Step tolerance %g must be non-negative", (double)stol); 3723c60f73f4SPeter Brune snes->stol = stol; 3724ab54825eSJed Brown } 3725ab54825eSJed Brown if (maxit != PETSC_DEFAULT) { 372663a3b9bcSJacob Faibussowitsch PetscCheck(maxit >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of iterations %" PetscInt_FMT " must be non-negative", maxit); 3727ab54825eSJed Brown snes->max_its = maxit; 3728ab54825eSJed Brown } 3729ab54825eSJed Brown if (maxf != PETSC_DEFAULT) { 373063a3b9bcSJacob Faibussowitsch PetscCheck(maxf >= -1, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_OUTOFRANGE, "Maximum number of function evaluations %" PetscInt_FMT " must be -1 or nonnegative", maxf); 3731ab54825eSJed Brown snes->max_funcs = maxf; 3732ab54825eSJed Brown } 373388976e71SPeter Brune snes->tolerancesset = PETSC_TRUE; 37343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 37359b94acceSBarry Smith } 37369b94acceSBarry Smith 3737e4d06f11SPatrick Farrell /*@ 3738f6dfbefdSBarry Smith SNESSetDivergenceTolerance - Sets the divergence tolerance used for the `SNES` divergence test. 3739e4d06f11SPatrick Farrell 3740c3339decSBarry Smith Logically Collective 3741e4d06f11SPatrick Farrell 3742e4d06f11SPatrick Farrell Input Parameters: 3743f6dfbefdSBarry Smith + snes - the `SNES` context 3744f6dfbefdSBarry Smith - divtol - the divergence tolerance. Use -1 to deactivate the test, default is 1e4 3745e4d06f11SPatrick Farrell 3746f6dfbefdSBarry Smith Options Database Key: 3747dc4c0fb0SBarry Smith . -snes_divergence_tolerance <divtol> - Sets `divtol` 3748e4d06f11SPatrick Farrell 3749e4d06f11SPatrick Farrell Level: intermediate 3750e4d06f11SPatrick Farrell 3751dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetTolerances()`, `SNESGetDivergenceTolerance` 3752e4d06f11SPatrick Farrell @*/ 3753d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDivergenceTolerance(SNES snes, PetscReal divtol) 3754d71ae5a4SJacob Faibussowitsch { 3755e4d06f11SPatrick Farrell PetscFunctionBegin; 3756e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3757e4d06f11SPatrick Farrell PetscValidLogicalCollectiveReal(snes, divtol, 2); 3758e4d06f11SPatrick Farrell 375913bcc0bdSJacob Faibussowitsch if (divtol != (PetscReal)PETSC_DEFAULT) { 3760e4d06f11SPatrick Farrell snes->divtol = divtol; 37619371c9d4SSatish Balay } else { 3762e4d06f11SPatrick Farrell snes->divtol = 1.0e4; 3763e4d06f11SPatrick Farrell } 37643ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3765e4d06f11SPatrick Farrell } 3766e4d06f11SPatrick Farrell 37679b94acceSBarry Smith /*@ 376833174efeSLois Curfman McInnes SNESGetTolerances - Gets various parameters used in convergence tests. 376933174efeSLois Curfman McInnes 3770c7afd0dbSLois Curfman McInnes Not Collective 3771c7afd0dbSLois Curfman McInnes 377233174efeSLois Curfman McInnes Input Parameters: 3773f6dfbefdSBarry Smith + snes - the `SNES` context 377485385478SLisandro Dalcin . atol - absolute convergence tolerance 377533174efeSLois Curfman McInnes . rtol - relative convergence tolerance 377633174efeSLois Curfman McInnes . stol - convergence tolerance in terms of the norm 377733174efeSLois Curfman McInnes of the change in the solution between steps 377833174efeSLois Curfman McInnes . maxit - maximum number of iterations 3779c7afd0dbSLois Curfman McInnes - maxf - maximum number of function evaluations 3780fee21e36SBarry Smith 378136851e7fSLois Curfman McInnes Level: intermediate 378236851e7fSLois Curfman McInnes 3783dc4c0fb0SBarry Smith Note: 3784dc4c0fb0SBarry Smith The user can specify `NULL` for any parameter that is not needed. 3785dc4c0fb0SBarry Smith 3786dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetTolerances()` 378733174efeSLois Curfman McInnes @*/ 3788d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetTolerances(SNES snes, PetscReal *atol, PetscReal *rtol, PetscReal *stol, PetscInt *maxit, PetscInt *maxf) 3789d71ae5a4SJacob Faibussowitsch { 37903a40ed3dSBarry Smith PetscFunctionBegin; 37910700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 379285385478SLisandro Dalcin if (atol) *atol = snes->abstol; 379333174efeSLois Curfman McInnes if (rtol) *rtol = snes->rtol; 3794c60f73f4SPeter Brune if (stol) *stol = snes->stol; 379533174efeSLois Curfman McInnes if (maxit) *maxit = snes->max_its; 379633174efeSLois Curfman McInnes if (maxf) *maxf = snes->max_funcs; 37973ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 379833174efeSLois Curfman McInnes } 379933174efeSLois Curfman McInnes 3800e4d06f11SPatrick Farrell /*@ 3801e4d06f11SPatrick Farrell SNESGetDivergenceTolerance - Gets divergence tolerance used in divergence test. 3802e4d06f11SPatrick Farrell 3803e4d06f11SPatrick Farrell Not Collective 3804e4d06f11SPatrick Farrell 3805e4d06f11SPatrick Farrell Input Parameters: 3806f6dfbefdSBarry Smith + snes - the `SNES` context 3807e4d06f11SPatrick Farrell - divtol - divergence tolerance 3808e4d06f11SPatrick Farrell 3809e4d06f11SPatrick Farrell Level: intermediate 3810e4d06f11SPatrick Farrell 3811dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetDivergenceTolerance()` 3812e4d06f11SPatrick Farrell @*/ 3813d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDivergenceTolerance(SNES snes, PetscReal *divtol) 3814d71ae5a4SJacob Faibussowitsch { 3815e4d06f11SPatrick Farrell PetscFunctionBegin; 3816e4d06f11SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3817e4d06f11SPatrick Farrell if (divtol) *divtol = snes->divtol; 38183ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3819e4d06f11SPatrick Farrell } 3820e4d06f11SPatrick Farrell 382133174efeSLois Curfman McInnes /*@ 38229b94acceSBarry Smith SNESSetTrustRegionTolerance - Sets the trust region parameter tolerance. 38239b94acceSBarry Smith 3824c3339decSBarry Smith Logically Collective 3825fee21e36SBarry Smith 3826c7afd0dbSLois Curfman McInnes Input Parameters: 3827f6dfbefdSBarry Smith + snes - the `SNES` context 3828c7afd0dbSLois Curfman McInnes - tol - tolerance 3829c7afd0dbSLois Curfman McInnes 38309b94acceSBarry Smith Options Database Key: 38314a221d59SStefano Zampini . -snes_tr_tol <tol> - Sets tol 38329b94acceSBarry Smith 383336851e7fSLois Curfman McInnes Level: intermediate 383436851e7fSLois Curfman McInnes 38354a221d59SStefano Zampini .seealso: [](chapter_snes), `SNES`, `SNESNEWTONTR`, `SNESSetTolerances()` 38369b94acceSBarry Smith @*/ 3837d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetTrustRegionTolerance(SNES snes, PetscReal tol) 3838d71ae5a4SJacob Faibussowitsch { 38393a40ed3dSBarry Smith PetscFunctionBegin; 38400700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 3841c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, tol, 2); 38429b94acceSBarry Smith snes->deltatol = tol; 38433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 38449b94acceSBarry Smith } 38459b94acceSBarry Smith 38466ba87a44SLisandro Dalcin PETSC_INTERN PetscErrorCode SNESMonitorRange_Private(SNES, PetscInt, PetscReal *); 38476ba87a44SLisandro Dalcin 3848d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorLGRange(SNES snes, PetscInt n, PetscReal rnorm, void *monctx) 3849d71ae5a4SJacob Faibussowitsch { 3850b271bb04SBarry Smith PetscDrawLG lg; 3851b271bb04SBarry Smith PetscReal x, y, per; 3852b271bb04SBarry Smith PetscViewer v = (PetscViewer)monctx; 3853b271bb04SBarry Smith static PetscReal prev; /* should be in the context */ 3854b271bb04SBarry Smith PetscDraw draw; 3855b271bb04SBarry Smith 3856459f5d12SBarry Smith PetscFunctionBegin; 38574d4332d5SBarry Smith PetscValidHeaderSpecific(v, PETSC_VIEWER_CLASSID, 4); 38589566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 0, &lg)); 38599566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38609566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38619566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "Residual norm")); 3862b271bb04SBarry Smith x = (PetscReal)n; 386377b4d14cSPeter Brune if (rnorm > 0.0) y = PetscLog10Real(rnorm); 386494c9c6d3SKarl Rupp else y = -15.0; 38659566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38666934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38679566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38689566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3869b271bb04SBarry Smith } 3870b271bb04SBarry Smith 38719566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 1, &lg)); 38729566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 38739566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38749566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "% elemts > .2*max elemt")); 38759566063dSJacob Faibussowitsch PetscCall(SNESMonitorRange_Private(snes, n, &per)); 3876b271bb04SBarry Smith x = (PetscReal)n; 3877b271bb04SBarry Smith y = 100.0 * per; 38789566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38796934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38809566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38819566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3882b271bb04SBarry Smith } 3883b271bb04SBarry Smith 38849566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 2, &lg)); 38859371c9d4SSatish Balay if (!n) { 38869371c9d4SSatish Balay prev = rnorm; 38879371c9d4SSatish Balay PetscCall(PetscDrawLGReset(lg)); 38889371c9d4SSatish Balay } 38899566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 38909566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm")); 3891b271bb04SBarry Smith x = (PetscReal)n; 3892b271bb04SBarry Smith y = (prev - rnorm) / prev; 38939566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 38946934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 38959566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 38969566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3897b271bb04SBarry Smith } 3898b271bb04SBarry Smith 38999566063dSJacob Faibussowitsch PetscCall(PetscViewerDrawGetDrawLG(v, 3, &lg)); 39009566063dSJacob Faibussowitsch if (!n) PetscCall(PetscDrawLGReset(lg)); 39019566063dSJacob Faibussowitsch PetscCall(PetscDrawLGGetDraw(lg, &draw)); 39029566063dSJacob Faibussowitsch PetscCall(PetscDrawSetTitle(draw, "(norm -oldnorm)/oldnorm*(% > .2 max)")); 3903b271bb04SBarry Smith x = (PetscReal)n; 3904b271bb04SBarry Smith y = (prev - rnorm) / (prev * per); 3905b271bb04SBarry Smith if (n > 2) { /*skip initial crazy value */ 39069566063dSJacob Faibussowitsch PetscCall(PetscDrawLGAddPoint(lg, &x, &y)); 3907b271bb04SBarry Smith } 39086934998bSLisandro Dalcin if (n < 20 || !(n % 5) || snes->reason) { 39099566063dSJacob Faibussowitsch PetscCall(PetscDrawLGDraw(lg)); 39109566063dSJacob Faibussowitsch PetscCall(PetscDrawLGSave(lg)); 3911b271bb04SBarry Smith } 3912b271bb04SBarry Smith prev = rnorm; 39133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 3914b271bb04SBarry Smith } 3915b271bb04SBarry Smith 3916228d79bcSJed Brown /*@ 3917228d79bcSJed Brown SNESMonitor - runs the user provided monitor routines, if they exist 3918228d79bcSJed Brown 3919c3339decSBarry Smith Collective 3920228d79bcSJed Brown 3921228d79bcSJed Brown Input Parameters: 3922f6dfbefdSBarry Smith + snes - nonlinear solver context obtained from `SNESCreate()` 3923228d79bcSJed Brown . iter - iteration number 3924228d79bcSJed Brown - rnorm - relative norm of the residual 3925228d79bcSJed Brown 3926dc4c0fb0SBarry Smith Level: developer 3927dc4c0fb0SBarry Smith 3928f6dfbefdSBarry Smith Note: 3929f6dfbefdSBarry Smith This routine is called by the `SNES` implementations. 3930228d79bcSJed Brown It does not typically need to be called by the user. 3931228d79bcSJed Brown 3932dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorSet()` 3933228d79bcSJed Brown @*/ 3934d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitor(SNES snes, PetscInt iter, PetscReal rnorm) 3935d71ae5a4SJacob Faibussowitsch { 39367a03ce2fSLisandro Dalcin PetscInt i, n = snes->numbermonitors; 39377a03ce2fSLisandro Dalcin 39387a03ce2fSLisandro Dalcin PetscFunctionBegin; 39399566063dSJacob Faibussowitsch PetscCall(VecLockReadPush(snes->vec_sol)); 394048a46eb9SPierre Jolivet for (i = 0; i < n; i++) PetscCall((*snes->monitor[i])(snes, iter, rnorm, snes->monitorcontext[i])); 39419566063dSJacob Faibussowitsch PetscCall(VecLockReadPop(snes->vec_sol)); 39423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 39437a03ce2fSLisandro Dalcin } 39447a03ce2fSLisandro Dalcin 39459b94acceSBarry Smith /* ------------ Routines to set performance monitoring options ----------- */ 39469b94acceSBarry Smith 3947bf388a1fSBarry Smith /*MC 3948f6dfbefdSBarry Smith SNESMonitorFunction - functional form passed to `SNESMonitorSet()` to monitor convergence of nonlinear solver 3949bf388a1fSBarry Smith 3950bf388a1fSBarry Smith Synopsis: 3951aaa7dc30SBarry Smith #include <petscsnes.h> 3952bf388a1fSBarry Smith $ PetscErrorCode SNESMonitorFunction(SNES snes,PetscInt its, PetscReal norm,void *mctx) 3953bf388a1fSBarry Smith 3954c3339decSBarry Smith Collective 39551843f636SBarry Smith 39561843f636SBarry Smith Input Parameters: 3957f6dfbefdSBarry Smith + snes - the `SNES` context 3958bf388a1fSBarry Smith . its - iteration number 3959bf388a1fSBarry Smith . norm - 2-norm function value (may be estimated) 3960bf388a1fSBarry Smith - mctx - [optional] monitoring context 3961bf388a1fSBarry Smith 3962878cb397SSatish Balay Level: advanced 3963878cb397SSatish Balay 3964dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESMonitorSet()`, `SNESMonitorSet()`, `SNESMonitorGet()` 3965bf388a1fSBarry Smith M*/ 3966bf388a1fSBarry Smith 39679b94acceSBarry Smith /*@C 3968a6570f20SBarry Smith SNESMonitorSet - Sets an ADDITIONAL function that is to be used at every 39699b94acceSBarry Smith iteration of the nonlinear solver to display the iteration's 39709b94acceSBarry Smith progress. 39719b94acceSBarry Smith 3972c3339decSBarry Smith Logically Collective 3973fee21e36SBarry Smith 3974c7afd0dbSLois Curfman McInnes Input Parameters: 3975f6dfbefdSBarry Smith + snes - the `SNES` context 397620f4b53cSBarry Smith . f - the monitor function, for the calling sequence see `SNESMonitorFunction` 3977b8a78c4aSBarry Smith . mctx - [optional] user-defined context for private data for the 3978dc4c0fb0SBarry Smith monitor routine (use `NULL` if no context is desired) 3979dc4c0fb0SBarry Smith - monitordestroy - [optional] routine that frees monitor context (may be `NULL`) 39809b94acceSBarry Smith 39819665c990SLois Curfman McInnes Options Database Keys: 3982f6dfbefdSBarry Smith + -snes_monitor - sets `SNESMonitorDefault()` 3983798534f6SMatthew G. Knepley . -snes_monitor draw::draw_lg - sets line graph monitor, 3984dc4c0fb0SBarry 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 3985c7afd0dbSLois Curfman McInnes the options database. 39869665c990SLois Curfman McInnes 3987dc4c0fb0SBarry Smith Level: intermediate 3988dc4c0fb0SBarry Smith 3989f6dfbefdSBarry Smith Note: 39906bc08f3fSLois Curfman McInnes Several different monitoring routines may be set by calling 3991f6dfbefdSBarry Smith `SNESMonitorSet()` multiple times; all will be called in the 39926bc08f3fSLois Curfman McInnes order in which they were set. 3993639f9d9dSBarry Smith 3994f6dfbefdSBarry Smith Fortran Note: 3995f6dfbefdSBarry Smith Only a single monitor function can be set for each `SNES` object 3996025f1a04SBarry Smith 3997dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESMonitorDefault()`, `SNESMonitorCancel()`, `SNESMonitorFunction` 39989b94acceSBarry Smith @*/ 3999d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorSet(SNES snes, PetscErrorCode (*f)(SNES, PetscInt, PetscReal, void *), void *mctx, PetscErrorCode (*monitordestroy)(void **)) 4000d71ae5a4SJacob Faibussowitsch { 4001b90d0a6eSBarry Smith PetscInt i; 400278064530SBarry Smith PetscBool identical; 4003b90d0a6eSBarry Smith 40043a40ed3dSBarry Smith PetscFunctionBegin; 40050700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4006b90d0a6eSBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 40079566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, mctx, monitordestroy, (PetscErrorCode(*)(void))snes->monitor[i], snes->monitorcontext[i], snes->monitordestroy[i], &identical)); 40083ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4009649052a6SBarry Smith } 40105f80ce2aSJacob Faibussowitsch PetscCheck(snes->numbermonitors < MAXSNESMONITORS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many monitors set"); 40116e4dcb14SBarry Smith snes->monitor[snes->numbermonitors] = f; 4012b8a78c4aSBarry Smith snes->monitordestroy[snes->numbermonitors] = monitordestroy; 4013639f9d9dSBarry Smith snes->monitorcontext[snes->numbermonitors++] = (void *)mctx; 40143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40159b94acceSBarry Smith } 40169b94acceSBarry Smith 4017a278d85bSSatish Balay /*@ 4018f6dfbefdSBarry Smith SNESMonitorCancel - Clears all the monitor functions for a `SNES` object. 40195cd90555SBarry Smith 4020c3339decSBarry Smith Logically Collective 4021c7afd0dbSLois Curfman McInnes 40225cd90555SBarry Smith Input Parameters: 4023f6dfbefdSBarry Smith . snes - the `SNES` context 40245cd90555SBarry Smith 40251a480d89SAdministrator Options Database Key: 4026a6570f20SBarry Smith . -snes_monitor_cancel - cancels all monitors that have been hardwired 4027dc4c0fb0SBarry Smith into a code by calls to `SNESMonitorSet()`, but does not cancel those 4028c7afd0dbSLois Curfman McInnes set via the options database 40295cd90555SBarry Smith 4030dc4c0fb0SBarry Smith Level: intermediate 4031dc4c0fb0SBarry Smith 4032f6dfbefdSBarry Smith Note: 4033f6dfbefdSBarry Smith There is no way to clear one specific monitor from a `SNES` object. 40345cd90555SBarry Smith 4035dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESMonitorGet()`, `SNESMonitorDefault()`, `SNESMonitorSet()` 40365cd90555SBarry Smith @*/ 4037d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESMonitorCancel(SNES snes) 4038d71ae5a4SJacob Faibussowitsch { 4039d952e501SBarry Smith PetscInt i; 4040d952e501SBarry Smith 40415cd90555SBarry Smith PetscFunctionBegin; 40420700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4043d952e501SBarry Smith for (i = 0; i < snes->numbermonitors; i++) { 404448a46eb9SPierre Jolivet if (snes->monitordestroy[i]) PetscCall((*snes->monitordestroy[i])(&snes->monitorcontext[i])); 4045d952e501SBarry Smith } 40465cd90555SBarry Smith snes->numbermonitors = 0; 40473ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 40485cd90555SBarry Smith } 40495cd90555SBarry Smith 4050bf388a1fSBarry Smith /*MC 4051bf388a1fSBarry Smith SNESConvergenceTestFunction - functional form used for testing of convergence of nonlinear solver 4052bf388a1fSBarry Smith 4053bf388a1fSBarry Smith Synopsis: 4054aaa7dc30SBarry Smith #include <petscsnes.h> 4055bf388a1fSBarry Smith $ PetscErrorCode SNESConvergenceTest(SNES snes,PetscInt it,PetscReal xnorm,PetscReal gnorm,PetscReal f,SNESConvergedReason *reason,void *cctx) 4056bf388a1fSBarry Smith 4057c3339decSBarry Smith Collective 40581843f636SBarry Smith 40591843f636SBarry Smith Input Parameters: 4060f6dfbefdSBarry Smith + snes - the `SNES` context 4061bf388a1fSBarry Smith . it - current iteration (0 is the first and is before any Newton step) 4062bf388a1fSBarry Smith . xnorm - 2-norm of current iterate 4063bf388a1fSBarry Smith . gnorm - 2-norm of current step 40641843f636SBarry Smith . f - 2-norm of function 40651843f636SBarry Smith - cctx - [optional] convergence context 40661843f636SBarry Smith 40671843f636SBarry Smith Output Parameter: 40681843f636SBarry Smith . reason - reason for convergence/divergence, only needs to be set when convergence or divergence is detected 4069bf388a1fSBarry Smith 4070878cb397SSatish Balay Level: intermediate 4071bf388a1fSBarry Smith 4072dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve`, `SNESSetConvergenceTest()`, `SNESGetConvergenceTest()` 4073bf388a1fSBarry Smith M*/ 4074bf388a1fSBarry Smith 40759b94acceSBarry Smith /*@C 40769b94acceSBarry Smith SNESSetConvergenceTest - Sets the function that is to be used 40779b94acceSBarry Smith to test for convergence of the nonlinear iterative solution. 40789b94acceSBarry Smith 4079c3339decSBarry Smith Logically Collective 4080fee21e36SBarry Smith 4081c7afd0dbSLois Curfman McInnes Input Parameters: 4082f6dfbefdSBarry Smith + snes - the `SNES` context 4083f6dfbefdSBarry Smith . `SNESConvergenceTestFunction` - routine to test for convergence 4084dc4c0fb0SBarry Smith . cctx - [optional] context for private data for the convergence routine (may be `NULL`) 4085dc4c0fb0SBarry Smith - destroy - [optional] destructor for the context (may be `NULL`; `PETSC_NULL_FUNCTION` in Fortran) 40869b94acceSBarry Smith 408736851e7fSLois Curfman McInnes Level: advanced 408836851e7fSLois Curfman McInnes 4089dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedDefault()`, `SNESConvergedSkip()`, `SNESConvergenceTestFunction` 40909b94acceSBarry Smith @*/ 4091d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceTest(SNES snes, PetscErrorCode (*SNESConvergenceTestFunction)(SNES, PetscInt, PetscReal, PetscReal, PetscReal, SNESConvergedReason *, void *), void *cctx, PetscErrorCode (*destroy)(void *)) 4092d71ae5a4SJacob Faibussowitsch { 40933a40ed3dSBarry Smith PetscFunctionBegin; 40940700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4095e2a6519dSDmitry Karpeev if (!SNESConvergenceTestFunction) SNESConvergenceTestFunction = SNESConvergedSkip; 40961baa6e33SBarry Smith if (snes->ops->convergeddestroy) PetscCall((*snes->ops->convergeddestroy)(snes->cnvP)); 4097bf388a1fSBarry Smith snes->ops->converged = SNESConvergenceTestFunction; 40987f7931b9SBarry Smith snes->ops->convergeddestroy = destroy; 409985385478SLisandro Dalcin snes->cnvP = cctx; 41003ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 41019b94acceSBarry Smith } 41029b94acceSBarry Smith 410352baeb72SSatish Balay /*@ 4104f6dfbefdSBarry Smith SNESGetConvergedReason - Gets the reason the `SNES` iteration was stopped. 4105184914b5SBarry Smith 4106184914b5SBarry Smith Not Collective 4107184914b5SBarry Smith 4108184914b5SBarry Smith Input Parameter: 4109f6dfbefdSBarry Smith . snes - the `SNES` context 4110184914b5SBarry Smith 4111184914b5SBarry Smith Output Parameter: 4112f6dfbefdSBarry Smith . reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` for the individual convergence tests for complete lists 4113184914b5SBarry Smith 4114f6dfbefdSBarry Smith Options Database Key: 41156a4d7782SBarry Smith . -snes_converged_reason - prints the reason to standard out 41166a4d7782SBarry Smith 4117184914b5SBarry Smith Level: intermediate 4118184914b5SBarry Smith 4119f6dfbefdSBarry Smith Note: 4120f6dfbefdSBarry Smith Should only be called after the call the `SNESSolve()` is complete, if it is called earlier it returns the value `SNES__CONVERGED_ITERATING`. 4121184914b5SBarry Smith 4122dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSolve()`, `SNESSetConvergenceTest()`, `SNESSetConvergedReason()`, `SNESConvergedReason`, `SNESGetConvergedReasonString()` 4123184914b5SBarry Smith @*/ 4124d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReason(SNES snes, SNESConvergedReason *reason) 4125d71ae5a4SJacob Faibussowitsch { 4126184914b5SBarry Smith PetscFunctionBegin; 41270700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 41284482741eSBarry Smith PetscValidPointer(reason, 2); 4129184914b5SBarry Smith *reason = snes->reason; 41303ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4131184914b5SBarry Smith } 4132184914b5SBarry Smith 4133c4421ceaSFande Kong /*@C 4134f6dfbefdSBarry Smith SNESGetConvergedReasonString - Return a human readable string for `SNESConvergedReason` 4135c4421ceaSFande Kong 4136c4421ceaSFande Kong Not Collective 4137c4421ceaSFande Kong 4138c4421ceaSFande Kong Input Parameter: 4139f6dfbefdSBarry Smith . snes - the `SNES` context 4140c4421ceaSFande Kong 4141c4421ceaSFande Kong Output Parameter: 4142dc4c0fb0SBarry Smith . strreason - a human readable string that describes `SNES` converged reason 4143c4421ceaSFande Kong 414499c90e12SSatish Balay Level: beginner 4145c4421ceaSFande Kong 4146dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetConvergedReason()` 4147c4421ceaSFande Kong @*/ 4148d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergedReasonString(SNES snes, const char **strreason) 4149d71ae5a4SJacob Faibussowitsch { 4150c4421ceaSFande Kong PetscFunctionBegin; 4151c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4152dadcf809SJacob Faibussowitsch PetscValidPointer(strreason, 2); 4153c4421ceaSFande Kong *strreason = SNESConvergedReasons[snes->reason]; 41543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4155c4421ceaSFande Kong } 4156c4421ceaSFande Kong 415733866048SMatthew G. Knepley /*@ 4158f6dfbefdSBarry Smith SNESSetConvergedReason - Sets the reason the `SNES` iteration was stopped. 415933866048SMatthew G. Knepley 416033866048SMatthew G. Knepley Not Collective 416133866048SMatthew G. Knepley 416233866048SMatthew G. Knepley Input Parameters: 4163f6dfbefdSBarry Smith + snes - the `SNES` context 4164f6dfbefdSBarry Smith - reason - negative value indicates diverged, positive value converged, see `SNESConvergedReason` or the 416533866048SMatthew G. Knepley manual pages for the individual convergence tests for complete lists 416633866048SMatthew G. Knepley 4167f6dfbefdSBarry Smith Level: developer 4168f6dfbefdSBarry Smith 4169f6dfbefdSBarry Smith Developer Note: 4170f6dfbefdSBarry Smith Called inside the various `SNESSolve()` implementations 417133866048SMatthew G. Knepley 4172dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetConvergedReason()`, `SNESSetConvergenceTest()`, `SNESConvergedReason` 417333866048SMatthew G. Knepley @*/ 4174d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergedReason(SNES snes, SNESConvergedReason reason) 4175d71ae5a4SJacob Faibussowitsch { 417633866048SMatthew G. Knepley PetscFunctionBegin; 417733866048SMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 417833866048SMatthew G. Knepley snes->reason = reason; 41793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 418033866048SMatthew G. Knepley } 418133866048SMatthew G. Knepley 4182c9005455SLois Curfman McInnes /*@ 4183c9005455SLois Curfman McInnes SNESSetConvergenceHistory - Sets the array used to hold the convergence history. 4184c9005455SLois Curfman McInnes 4185c3339decSBarry Smith Logically Collective 4186fee21e36SBarry Smith 4187c7afd0dbSLois Curfman McInnes Input Parameters: 4188f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 41898c7482ecSBarry Smith . a - array to hold history, this array will contain the function norms computed at each step 4190cd5578b5SBarry Smith . its - integer array holds the number of linear iterations for each solve. 4191758f92a0SBarry Smith . na - size of a and its 4192f6dfbefdSBarry Smith - reset - `PETSC_TRUE` indicates each new nonlinear solve resets the history counter to zero, 4193758f92a0SBarry Smith else it continues storing new values for new nonlinear solves after the old ones 4194c7afd0dbSLois Curfman McInnes 4195dc4c0fb0SBarry Smith Level: intermediate 4196dc4c0fb0SBarry Smith 4197308dcc3eSBarry Smith Notes: 4198dc4c0fb0SBarry Smith If 'a' and 'its' are `NULL` then space is allocated for the history. If 'na' `PETSC_DECIDE` or `PETSC_DEFAULT` then a 4199308dcc3eSBarry Smith default array of length 10000 is allocated. 4200308dcc3eSBarry Smith 4201c9005455SLois Curfman McInnes This routine is useful, e.g., when running a code for purposes 4202c9005455SLois Curfman McInnes of accurate performance monitoring, when no I/O should be done 4203c9005455SLois Curfman McInnes during the section of code that is being timed. 4204c9005455SLois Curfman McInnes 4205dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetConvergenceHistory()` 4206c9005455SLois Curfman McInnes @*/ 4207d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetConvergenceHistory(SNES snes, PetscReal a[], PetscInt its[], PetscInt na, PetscBool reset) 4208d71ae5a4SJacob Faibussowitsch { 42093a40ed3dSBarry Smith PetscFunctionBegin; 42100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4211064a246eSJacob Faibussowitsch if (a) PetscValidRealPointer(a, 2); 4212a562a398SLisandro Dalcin if (its) PetscValidIntPointer(its, 3); 42137a1ec6d4SBarry Smith if (!a) { 4214308dcc3eSBarry Smith if (na == PETSC_DECIDE || na == PETSC_DEFAULT) na = 1000; 42159566063dSJacob Faibussowitsch PetscCall(PetscCalloc2(na, &a, na, &its)); 4216071fcb05SBarry Smith snes->conv_hist_alloc = PETSC_TRUE; 4217308dcc3eSBarry Smith } 4218c9005455SLois Curfman McInnes snes->conv_hist = a; 4219758f92a0SBarry Smith snes->conv_hist_its = its; 4220115dd874SBarry Smith snes->conv_hist_max = (size_t)na; 4221a12bc48fSLisandro Dalcin snes->conv_hist_len = 0; 4222758f92a0SBarry Smith snes->conv_hist_reset = reset; 42233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4224758f92a0SBarry Smith } 4225758f92a0SBarry Smith 4226d1e78c4fSBarry Smith #if defined(PETSC_HAVE_MATLAB) 4227c6db04a5SJed Brown #include <engine.h> /* MATLAB include file */ 4228c6db04a5SJed Brown #include <mex.h> /* MATLAB include file */ 422999e0435eSBarry Smith 4230d71ae5a4SJacob Faibussowitsch PETSC_EXTERN mxArray *SNESGetConvergenceHistoryMatlab(SNES snes) 4231d71ae5a4SJacob Faibussowitsch { 4232308dcc3eSBarry Smith mxArray *mat; 4233308dcc3eSBarry Smith PetscInt i; 4234308dcc3eSBarry Smith PetscReal *ar; 4235308dcc3eSBarry Smith 4236308dcc3eSBarry Smith mat = mxCreateDoubleMatrix(snes->conv_hist_len, 1, mxREAL); 4237308dcc3eSBarry Smith ar = (PetscReal *)mxGetData(mat); 4238f5af7f23SKarl Rupp for (i = 0; i < snes->conv_hist_len; i++) ar[i] = snes->conv_hist[i]; 423911cc89d2SBarry Smith return mat; 4240308dcc3eSBarry Smith } 4241308dcc3eSBarry Smith #endif 4242308dcc3eSBarry Smith 42430c4c9dddSBarry Smith /*@C 4244758f92a0SBarry Smith SNESGetConvergenceHistory - Gets the array used to hold the convergence history. 4245758f92a0SBarry Smith 42463f9fe445SBarry Smith Not Collective 4247758f92a0SBarry Smith 4248758f92a0SBarry Smith Input Parameter: 4249f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 4250758f92a0SBarry Smith 4251758f92a0SBarry Smith Output Parameters: 4252f6dfbefdSBarry Smith + a - array to hold history, usually was set with `SNESSetConvergenceHistory()` 4253758f92a0SBarry Smith . its - integer array holds the number of linear iterations (or 4254758f92a0SBarry Smith negative if not converged) for each solve. 425520f4b53cSBarry Smith - na - size of `a` and `its` 4256758f92a0SBarry Smith 4257dc4c0fb0SBarry Smith Level: intermediate 4258dc4c0fb0SBarry Smith 425920f4b53cSBarry Smith Note: 426020f4b53cSBarry Smith This routine is useful, e.g., when running a code for purposes 426120f4b53cSBarry Smith of accurate performance monitoring, when no I/O should be done 426220f4b53cSBarry Smith during the section of code that is being timed. 426320f4b53cSBarry Smith 426420f4b53cSBarry Smith Fortran Note: 4265758f92a0SBarry Smith The calling sequence for this routine in Fortran is 4266dc4c0fb0SBarry Smith .vb 4267dc4c0fb0SBarry Smith call SNESGetConvergenceHistory(SNES snes, integer na, integer ierr) 4268dc4c0fb0SBarry Smith .ve 4269758f92a0SBarry Smith 4270dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetConvergenceHistory()` 4271758f92a0SBarry Smith @*/ 4272d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetConvergenceHistory(SNES snes, PetscReal *a[], PetscInt *its[], PetscInt *na) 4273d71ae5a4SJacob Faibussowitsch { 4274758f92a0SBarry Smith PetscFunctionBegin; 42750700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4276758f92a0SBarry Smith if (a) *a = snes->conv_hist; 4277758f92a0SBarry Smith if (its) *its = snes->conv_hist_its; 4278115dd874SBarry Smith if (na) *na = (PetscInt)snes->conv_hist_len; 42793ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4280c9005455SLois Curfman McInnes } 4281c9005455SLois Curfman McInnes 4282ac226902SBarry Smith /*@C 428376b2cf59SMatthew Knepley SNESSetUpdate - Sets the general-purpose update function called 4284eec8f646SJed Brown at the beginning of every iteration of the nonlinear solve. Specifically 42857e4bb74cSBarry Smith it is called just before the Jacobian is "evaluated". 428676b2cf59SMatthew Knepley 4287c3339decSBarry Smith Logically Collective 428876b2cf59SMatthew Knepley 428976b2cf59SMatthew Knepley Input Parameters: 4290a2b725a8SWilliam Gropp + snes - The nonlinear solver context 4291a2b725a8SWilliam Gropp - func - The function 429276b2cf59SMatthew Knepley 429320f4b53cSBarry Smith Calling sequence of `func`: 429420f4b53cSBarry Smith $ PetscErrorCode func(SNES snes, PetscInt step); 429520f4b53cSBarry Smith + snes - the nonlinear solver context 429620f4b53cSBarry Smith - step - The current step of the iteration 429776b2cf59SMatthew Knepley 4298fe97e370SBarry Smith Level: advanced 4299fe97e370SBarry Smith 43006b7fb656SBarry Smith Note: 4301f6dfbefdSBarry 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 4302f6dfbefdSBarry Smith to `SNESSetFunction()`, or `SNESSetPicard()` 4303fe97e370SBarry Smith This is not used by most users. 430476b2cf59SMatthew Knepley 43056b7fb656SBarry Smith There are a varity of function hooks one many set that are called at different stages of the nonlinear solution process, see the functions listed below. 43066b7fb656SBarry Smith 4307dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESSetJacobian()`, `SNESSolve()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchSetPostCheck()`, `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRSetPostCheck()`, 4308db781477SPatrick Sanan `SNESMonitorSet()`, `SNESSetDivergenceTest()` 430976b2cf59SMatthew Knepley @*/ 4310d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetUpdate(SNES snes, PetscErrorCode (*func)(SNES, PetscInt)) 4311d71ae5a4SJacob Faibussowitsch { 431276b2cf59SMatthew Knepley PetscFunctionBegin; 43130700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4314e7788613SBarry Smith snes->ops->update = func; 43153ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 431676b2cf59SMatthew Knepley } 431776b2cf59SMatthew Knepley 43189b94acceSBarry Smith /* 43199b94acceSBarry Smith SNESScaleStep_Private - Scales a step so that its length is less than the 43209b94acceSBarry Smith positive parameter delta. 43219b94acceSBarry Smith 43229b94acceSBarry Smith Input Parameters: 4323f6dfbefdSBarry Smith + snes - the `SNES` context 43249b94acceSBarry Smith . y - approximate solution of linear system 43259b94acceSBarry Smith . fnorm - 2-norm of current function 4326c7afd0dbSLois Curfman McInnes - delta - trust region size 43279b94acceSBarry Smith 43289b94acceSBarry Smith Output Parameters: 4329c7afd0dbSLois Curfman McInnes + gpnorm - predicted function norm at the new point, assuming local 43309b94acceSBarry Smith linearization. The value is zero if the step lies within the trust 43319b94acceSBarry Smith region, and exceeds zero otherwise. 4332c7afd0dbSLois Curfman McInnes - ynorm - 2-norm of the step 43339b94acceSBarry Smith 4334f6dfbefdSBarry Smith Level: developer 43359b94acceSBarry Smith 4336f6dfbefdSBarry Smith Note: 4337f6dfbefdSBarry Smith For non-trust region methods such as `SNESNEWTONLS`, the parameter delta 4338f6dfbefdSBarry Smith is set to be the maximum allowable step size. 43399b94acceSBarry Smith */ 4340d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESScaleStep_Private(SNES snes, Vec y, PetscReal *fnorm, PetscReal *delta, PetscReal *gpnorm, PetscReal *ynorm) 4341d71ae5a4SJacob Faibussowitsch { 4342064f8208SBarry Smith PetscReal nrm; 4343ea709b57SSatish Balay PetscScalar cnorm; 43443a40ed3dSBarry Smith 43453a40ed3dSBarry Smith PetscFunctionBegin; 43460700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 43470700a824SBarry Smith PetscValidHeaderSpecific(y, VEC_CLASSID, 2); 4348c9780b6fSBarry Smith PetscCheckSameComm(snes, 1, y, 2); 4349184914b5SBarry Smith 43509566063dSJacob Faibussowitsch PetscCall(VecNorm(y, NORM_2, &nrm)); 4351064f8208SBarry Smith if (nrm > *delta) { 4352064f8208SBarry Smith nrm = *delta / nrm; 4353064f8208SBarry Smith *gpnorm = (1.0 - nrm) * (*fnorm); 4354064f8208SBarry Smith cnorm = nrm; 43559566063dSJacob Faibussowitsch PetscCall(VecScale(y, cnorm)); 43569b94acceSBarry Smith *ynorm = *delta; 43579b94acceSBarry Smith } else { 43589b94acceSBarry Smith *gpnorm = 0.0; 4359064f8208SBarry Smith *ynorm = nrm; 43609b94acceSBarry Smith } 43613ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 43629b94acceSBarry Smith } 43639b94acceSBarry Smith 436491f3e32bSBarry Smith /*@C 4365f6dfbefdSBarry Smith SNESConvergedReasonView - Displays the reason a `SNES` solve converged or diverged to a viewer 43662a359c20SBarry Smith 4367c3339decSBarry Smith Collective 43682a359c20SBarry Smith 43692a359c20SBarry Smith Parameter: 4370f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 43712a359c20SBarry Smith - viewer - the viewer to display the reason 43722a359c20SBarry Smith 43732a359c20SBarry Smith Options Database Keys: 4374ee300463SSatish Balay + -snes_converged_reason - print reason for converged or diverged, also prints number of iterations 4375ee300463SSatish Balay - -snes_converged_reason ::failed - only print reason and number of iterations when diverged 4376eafd5ff0SAlex Lindsay 4377f6dfbefdSBarry Smith Note: 4378f6dfbefdSBarry Smith To change the format of the output call `PetscViewerPushFormat`(viewer,format) before this call. Use `PETSC_VIEWER_DEFAULT` for the default, 4379f6dfbefdSBarry Smith use `PETSC_VIEWER_FAILED` to only display a reason if it fails. 43802a359c20SBarry Smith 43812a359c20SBarry Smith Level: beginner 43822a359c20SBarry Smith 4383dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESConvergedReason`, `PetscViewer`, `SNES`, 4384f6dfbefdSBarry Smith `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, 4385f6dfbefdSBarry Smith `SNESConvergedReasonViewFromOptions()`, 4386db781477SPatrick Sanan `PetscViewerPushFormat()`, `PetscViewerPopFormat()` 43872a359c20SBarry Smith @*/ 4388d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonView(SNES snes, PetscViewer viewer) 4389d71ae5a4SJacob Faibussowitsch { 439075cca76cSMatthew G. Knepley PetscViewerFormat format; 43912a359c20SBarry Smith PetscBool isAscii; 43922a359c20SBarry Smith 43932a359c20SBarry Smith PetscFunctionBegin; 439419a666eeSBarry Smith if (!viewer) viewer = PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)); 43959566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)viewer, PETSCVIEWERASCII, &isAscii)); 43962a359c20SBarry Smith if (isAscii) { 43979566063dSJacob Faibussowitsch PetscCall(PetscViewerGetFormat(viewer, &format)); 43989566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIAddTab(viewer, ((PetscObject)snes)->tablevel)); 439975cca76cSMatthew G. Knepley if (format == PETSC_VIEWER_ASCII_INFO_DETAIL) { 440075cca76cSMatthew G. Knepley DM dm; 440175cca76cSMatthew G. Knepley Vec u; 440275cca76cSMatthew G. Knepley PetscDS prob; 440375cca76cSMatthew G. Knepley PetscInt Nf, f; 440495cbbfd3SMatthew G. Knepley PetscErrorCode (**exactSol)(PetscInt, PetscReal, const PetscReal[], PetscInt, PetscScalar[], void *); 440595cbbfd3SMatthew G. Knepley void **exactCtx; 440675cca76cSMatthew G. Knepley PetscReal error; 440775cca76cSMatthew G. Knepley 44089566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 44099566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 44109566063dSJacob Faibussowitsch PetscCall(DMGetDS(dm, &prob)); 44119566063dSJacob Faibussowitsch PetscCall(PetscDSGetNumFields(prob, &Nf)); 44129566063dSJacob Faibussowitsch PetscCall(PetscMalloc2(Nf, &exactSol, Nf, &exactCtx)); 44139566063dSJacob Faibussowitsch for (f = 0; f < Nf; ++f) PetscCall(PetscDSGetExactSolution(prob, f, &exactSol[f], &exactCtx[f])); 44149566063dSJacob Faibussowitsch PetscCall(DMComputeL2Diff(dm, 0.0, exactSol, exactCtx, u, &error)); 44159566063dSJacob Faibussowitsch PetscCall(PetscFree2(exactSol, exactCtx)); 44169566063dSJacob Faibussowitsch if (error < 1.0e-11) PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: < 1.0e-11\n")); 441763a3b9bcSJacob Faibussowitsch else PetscCall(PetscViewerASCIIPrintf(viewer, "L_2 Error: %g\n", (double)error)); 441875cca76cSMatthew G. Knepley } 4419eafd5ff0SAlex Lindsay if (snes->reason > 0 && format != PETSC_VIEWER_FAILED) { 44202a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 442163a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear %s solve converged due to %s iterations %" PetscInt_FMT "\n", ((PetscObject)snes)->prefix, SNESConvergedReasons[snes->reason], snes->iter)); 44222a359c20SBarry Smith } else { 442363a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve converged due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44242a359c20SBarry Smith } 4425eafd5ff0SAlex Lindsay } else if (snes->reason <= 0) { 44262a359c20SBarry Smith if (((PetscObject)snes)->prefix) { 442763a3b9bcSJacob 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)); 44282a359c20SBarry Smith } else { 442963a3b9bcSJacob Faibussowitsch PetscCall(PetscViewerASCIIPrintf(viewer, "Nonlinear solve did not converge due to %s iterations %" PetscInt_FMT "\n", SNESConvergedReasons[snes->reason], snes->iter)); 44302a359c20SBarry Smith } 44312a359c20SBarry Smith } 44329566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIISubtractTab(viewer, ((PetscObject)snes)->tablevel)); 44332a359c20SBarry Smith } 44343ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 44352a359c20SBarry Smith } 44362a359c20SBarry Smith 4437c4421ceaSFande Kong /*@C 4438c4421ceaSFande Kong SNESConvergedReasonViewSet - Sets an ADDITIONAL function that is to be used at the 4439c4421ceaSFande Kong end of the nonlinear solver to display the conver reason of the nonlinear solver. 4440c4421ceaSFande Kong 4441c3339decSBarry Smith Logically Collective 4442c4421ceaSFande Kong 4443c4421ceaSFande Kong Input Parameters: 4444f6dfbefdSBarry Smith + snes - the `SNES` context 4445c4421ceaSFande Kong . f - the snes converged reason view function 4446c4421ceaSFande Kong . vctx - [optional] user-defined context for private data for the 4447dc4c0fb0SBarry Smith snes converged reason view routine (use `NULL` if no context is desired) 4448dc4c0fb0SBarry Smith - reasonviewdestroy - [optional] routine that frees reasonview context (may be `NULL`) 4449c4421ceaSFande Kong 4450c4421ceaSFande Kong Options Database Keys: 4451f6dfbefdSBarry Smith + -snes_converged_reason - sets a default `SNESConvergedReasonView()` 4452c4421ceaSFande Kong - -snes_converged_reason_view_cancel - cancels all converged reason viewers that have 4453c4421ceaSFande Kong been hardwired into a code by 4454f6dfbefdSBarry Smith calls to `SNESConvergedReasonViewSet()`, but 4455c4421ceaSFande Kong does not cancel those set via 4456c4421ceaSFande Kong the options database. 4457c4421ceaSFande Kong 4458dc4c0fb0SBarry Smith Level: intermediate 4459dc4c0fb0SBarry Smith 4460f6dfbefdSBarry Smith Note: 4461c4421ceaSFande Kong Several different converged reason view routines may be set by calling 4462f6dfbefdSBarry Smith `SNESConvergedReasonViewSet()` multiple times; all will be called in the 4463c4421ceaSFande Kong order in which they were set. 4464c4421ceaSFande Kong 4465dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESConvergedReason`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()`, `SNESConvergedReasonViewCancel()` 4466c4421ceaSFande Kong @*/ 4467d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewSet(SNES snes, PetscErrorCode (*f)(SNES, void *), void *vctx, PetscErrorCode (*reasonviewdestroy)(void **)) 4468d71ae5a4SJacob Faibussowitsch { 4469c4421ceaSFande Kong PetscInt i; 4470c4421ceaSFande Kong PetscBool identical; 4471c4421ceaSFande Kong 4472c4421ceaSFande Kong PetscFunctionBegin; 4473c4421ceaSFande Kong PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4474c4421ceaSFande Kong for (i = 0; i < snes->numberreasonviews; i++) { 44759566063dSJacob Faibussowitsch PetscCall(PetscMonitorCompare((PetscErrorCode(*)(void))f, vctx, reasonviewdestroy, (PetscErrorCode(*)(void))snes->reasonview[i], snes->reasonviewcontext[i], snes->reasonviewdestroy[i], &identical)); 44763ba16761SJacob Faibussowitsch if (identical) PetscFunctionReturn(PETSC_SUCCESS); 4477c4421ceaSFande Kong } 44785f80ce2aSJacob Faibussowitsch PetscCheck(snes->numberreasonviews < MAXSNESREASONVIEWS, PETSC_COMM_SELF, PETSC_ERR_ARG_OUTOFRANGE, "Too many SNES reasonview set"); 4479c4421ceaSFande Kong snes->reasonview[snes->numberreasonviews] = f; 4480c4421ceaSFande Kong snes->reasonviewdestroy[snes->numberreasonviews] = reasonviewdestroy; 4481c4421ceaSFande Kong snes->reasonviewcontext[snes->numberreasonviews++] = (void *)vctx; 44823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4483c4421ceaSFande Kong } 4484c4421ceaSFande Kong 448591f3e32bSBarry Smith /*@ 4486f6dfbefdSBarry Smith SNESConvergedReasonViewFromOptions - Processes command line options to determine if/how a `SNESConvergedReason` is to be viewed. 4487c4421ceaSFande Kong All the user-provided convergedReasonView routines will be involved as well, if they exist. 44882a359c20SBarry Smith 4489c3339decSBarry Smith Collective 44902a359c20SBarry Smith 44912a359c20SBarry Smith Input Parameters: 4492f6dfbefdSBarry Smith . snes - the `SNES` object 44932a359c20SBarry Smith 4494f6dfbefdSBarry Smith Level: advanced 44952a359c20SBarry Smith 4496dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESConvergedReason`, `SNESConvergedReasonViewSet()`, `SNESCreate()`, `SNESSetUp()`, `SNESDestroy()`, 4497f6dfbefdSBarry Smith `SNESSetTolerances()`, `SNESConvergedDefault()`, `SNESGetConvergedReason()`, `SNESConvergedReasonView()` 44982a359c20SBarry Smith @*/ 4499d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESConvergedReasonViewFromOptions(SNES snes) 4500d71ae5a4SJacob Faibussowitsch { 45012a359c20SBarry Smith PetscViewer viewer; 45022a359c20SBarry Smith PetscBool flg; 45032a359c20SBarry Smith static PetscBool incall = PETSC_FALSE; 45042a359c20SBarry Smith PetscViewerFormat format; 4505c4421ceaSFande Kong PetscInt i; 45062a359c20SBarry Smith 45072a359c20SBarry Smith PetscFunctionBegin; 45083ba16761SJacob Faibussowitsch if (incall) PetscFunctionReturn(PETSC_SUCCESS); 45092a359c20SBarry Smith incall = PETSC_TRUE; 4510c4421ceaSFande Kong 4511c4421ceaSFande Kong /* All user-provided viewers are called first, if they exist. */ 451248a46eb9SPierre Jolivet for (i = 0; i < snes->numberreasonviews; i++) PetscCall((*snes->reasonview[i])(snes, snes->reasonviewcontext[i])); 4513c4421ceaSFande Kong 4514c4421ceaSFande Kong /* Call PETSc default routine if users ask for it */ 45159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_converged_reason", &viewer, &format, &flg)); 45162a359c20SBarry Smith if (flg) { 45179566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45189566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonView(snes, viewer)); 45199566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45209566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45212a359c20SBarry Smith } 45222a359c20SBarry Smith incall = PETSC_FALSE; 45233ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 45242a359c20SBarry Smith } 45252a359c20SBarry Smith 4526487a658cSBarry Smith /*@ 4527f69a0ea3SMatthew Knepley SNESSolve - Solves a nonlinear system F(x) = b. 4528f6dfbefdSBarry Smith Call `SNESSolve()` after calling `SNESCreate()` and optional routines of the form `SNESSetXXX()`. 45299b94acceSBarry Smith 4530c3339decSBarry Smith Collective 4531c7afd0dbSLois Curfman McInnes 4532b2002411SLois Curfman McInnes Input Parameters: 4533f6dfbefdSBarry Smith + snes - the `SNES` context 4534dc4c0fb0SBarry Smith . b - the constant part of the equation F(x) = b, or `NULL` to use zero. 453585385478SLisandro Dalcin - x - the solution vector. 45369b94acceSBarry Smith 4537dc4c0fb0SBarry Smith Level: beginner 4538dc4c0fb0SBarry Smith 4539f6dfbefdSBarry Smith Note: 45408ddd3da0SLois Curfman McInnes The user should initialize the vector,x, with the initial guess 4541f6dfbefdSBarry Smith for the nonlinear solve prior to calling `SNESSolve()`. In particular, 45428ddd3da0SLois Curfman McInnes to employ an initial guess of zero, the user should explicitly set 4543f6dfbefdSBarry Smith this vector to zero by calling `VecSet()`. 45448ddd3da0SLois Curfman McInnes 4545dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESCreate()`, `SNESDestroy()`, `SNESSetFunction()`, `SNESSetJacobian()`, `SNESSetGridSequence()`, `SNESGetSolution()`, 4546db781477SPatrick Sanan `SNESNewtonTRSetPreCheck()`, `SNESNewtonTRGetPreCheck()`, `SNESNewtonTRSetPostCheck()`, `SNESNewtonTRGetPostCheck()`, 4547db781477SPatrick Sanan `SNESLineSearchSetPostCheck()`, `SNESLineSearchGetPostCheck()`, `SNESLineSearchSetPreCheck()`, `SNESLineSearchGetPreCheck()` 45489b94acceSBarry Smith @*/ 4549d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSolve(SNES snes, Vec b, Vec x) 4550d71ae5a4SJacob Faibussowitsch { 4551ace3abfcSBarry Smith PetscBool flg; 4552efd51863SBarry Smith PetscInt grid; 45530298fd71SBarry Smith Vec xcreated = NULL; 4554caa4e7f2SJed Brown DM dm; 4555052efed2SBarry Smith 45563a40ed3dSBarry Smith PetscFunctionBegin; 45570700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4558a69afd8bSBarry Smith if (x) PetscValidHeaderSpecific(x, VEC_CLASSID, 3); 4559a69afd8bSBarry Smith if (x) PetscCheckSameComm(snes, 1, x, 3); 45600700a824SBarry Smith if (b) PetscValidHeaderSpecific(b, VEC_CLASSID, 2); 456185385478SLisandro Dalcin if (b) PetscCheckSameComm(snes, 1, b, 2); 456285385478SLisandro Dalcin 456334b4d3a8SMatthew G. Knepley /* High level operations using the nonlinear solver */ 456406fc46c8SMatthew G. Knepley { 456506fc46c8SMatthew G. Knepley PetscViewer viewer; 456606fc46c8SMatthew G. Knepley PetscViewerFormat format; 45677c88af5aSMatthew G. Knepley PetscInt num; 456806fc46c8SMatthew G. Knepley PetscBool flg; 456906fc46c8SMatthew G. Knepley static PetscBool incall = PETSC_FALSE; 457006fc46c8SMatthew G. Knepley 457106fc46c8SMatthew G. Knepley if (!incall) { 457234b4d3a8SMatthew G. Knepley /* Estimate the convergence rate of the discretization */ 45739566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_convergence_estimate", &viewer, &format, &flg)); 457406fc46c8SMatthew G. Knepley if (flg) { 457506fc46c8SMatthew G. Knepley PetscConvEst conv; 457646079b62SMatthew G. Knepley DM dm; 457746079b62SMatthew G. Knepley PetscReal *alpha; /* Convergence rate of the solution error for each field in the L_2 norm */ 457846079b62SMatthew G. Knepley PetscInt Nf; 457906fc46c8SMatthew G. Knepley 458006fc46c8SMatthew G. Knepley incall = PETSC_TRUE; 45819566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 45829566063dSJacob Faibussowitsch PetscCall(DMGetNumFields(dm, &Nf)); 45839566063dSJacob Faibussowitsch PetscCall(PetscCalloc1(Nf, &alpha)); 45849566063dSJacob Faibussowitsch PetscCall(PetscConvEstCreate(PetscObjectComm((PetscObject)snes), &conv)); 45859566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetSolver(conv, (PetscObject)snes)); 45869566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetFromOptions(conv)); 45879566063dSJacob Faibussowitsch PetscCall(PetscConvEstSetUp(conv)); 45889566063dSJacob Faibussowitsch PetscCall(PetscConvEstGetConvRate(conv, alpha)); 45899566063dSJacob Faibussowitsch PetscCall(PetscViewerPushFormat(viewer, format)); 45909566063dSJacob Faibussowitsch PetscCall(PetscConvEstRateView(conv, alpha, viewer)); 45919566063dSJacob Faibussowitsch PetscCall(PetscViewerPopFormat(viewer)); 45929566063dSJacob Faibussowitsch PetscCall(PetscViewerDestroy(&viewer)); 45939566063dSJacob Faibussowitsch PetscCall(PetscConvEstDestroy(&conv)); 45949566063dSJacob Faibussowitsch PetscCall(PetscFree(alpha)); 459506fc46c8SMatthew G. Knepley incall = PETSC_FALSE; 459606fc46c8SMatthew G. Knepley } 459734b4d3a8SMatthew G. Knepley /* Adaptively refine the initial grid */ 4598b2588ea6SMatthew G. Knepley num = 1; 45999566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_initial", &num, &flg)); 460034b4d3a8SMatthew G. Knepley if (flg) { 460134b4d3a8SMatthew G. Knepley DMAdaptor adaptor; 460234b4d3a8SMatthew G. Knepley 460334b4d3a8SMatthew G. Knepley incall = PETSC_TRUE; 46049566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46059566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46069566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46079566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46089566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46099566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_INITIAL, &dm, &x)); 46109566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 461134b4d3a8SMatthew G. Knepley incall = PETSC_FALSE; 461234b4d3a8SMatthew G. Knepley } 46137c88af5aSMatthew G. Knepley /* Use grid sequencing to adapt */ 46147c88af5aSMatthew G. Knepley num = 0; 46159566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetInt(NULL, ((PetscObject)snes)->prefix, "-snes_adapt_sequence", &num, NULL)); 46167c88af5aSMatthew G. Knepley if (num) { 46177c88af5aSMatthew G. Knepley DMAdaptor adaptor; 46187c88af5aSMatthew G. Knepley 46197c88af5aSMatthew G. Knepley incall = PETSC_TRUE; 46209566063dSJacob Faibussowitsch PetscCall(DMAdaptorCreate(PetscObjectComm((PetscObject)snes), &adaptor)); 46219566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSolver(adaptor, snes)); 46229566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetSequenceLength(adaptor, num)); 46239566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetFromOptions(adaptor)); 46249566063dSJacob Faibussowitsch PetscCall(DMAdaptorSetUp(adaptor)); 46259566063dSJacob Faibussowitsch PetscCall(DMAdaptorAdapt(adaptor, x, DM_ADAPTATION_SEQUENTIAL, &dm, &x)); 46269566063dSJacob Faibussowitsch PetscCall(DMAdaptorDestroy(&adaptor)); 46277c88af5aSMatthew G. Knepley incall = PETSC_FALSE; 46287c88af5aSMatthew G. Knepley } 462906fc46c8SMatthew G. Knepley } 463006fc46c8SMatthew G. Knepley } 4631ad540459SPierre Jolivet if (!x) x = snes->vec_sol; 4632caa4e7f2SJed Brown if (!x) { 46339566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 46349566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(dm, &xcreated)); 4635a69afd8bSBarry Smith x = xcreated; 4636a69afd8bSBarry Smith } 46379566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view_pre")); 4638f05ece33SBarry Smith 46399566063dSJacob Faibussowitsch for (grid = 0; grid < snes->gridsequence; grid++) PetscCall(PetscViewerASCIIPushTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4640efd51863SBarry Smith for (grid = 0; grid < snes->gridsequence + 1; grid++) { 464185385478SLisandro Dalcin /* set solution vector */ 46429566063dSJacob Faibussowitsch if (!grid) PetscCall(PetscObjectReference((PetscObject)x)); 46439566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 464485385478SLisandro Dalcin snes->vec_sol = x; 46459566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 4646caa4e7f2SJed Brown 4647caa4e7f2SJed Brown /* set affine vector if provided */ 46489566063dSJacob Faibussowitsch if (b) PetscCall(PetscObjectReference((PetscObject)b)); 46499566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_rhs)); 465085385478SLisandro Dalcin snes->vec_rhs = b; 465185385478SLisandro Dalcin 46525f80ce2aSJacob 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"); 46535f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_func != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be function vector"); 46545f80ce2aSJacob Faibussowitsch PetscCheck(snes->vec_rhs != snes->vec_sol, PETSC_COMM_SELF, PETSC_ERR_ARG_IDN, "Solution vector cannot be right hand side vector"); 4655aa624791SPierre Jolivet if (!snes->vec_sol_update /* && snes->vec_sol */) PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_sol_update)); 46569566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, snes->vec_sol)); 46579566063dSJacob Faibussowitsch PetscCall(SNESSetUp(snes)); 46583f149594SLisandro Dalcin 46597eee914bSBarry Smith if (!grid) { 466025e27a38SBarry Smith if (snes->ops->computeinitialguess) PetscCallBack("SNES callback initial guess", (*snes->ops->computeinitialguess)(snes, snes->vec_sol, snes->initialguessP)); 4661dd568438SSatish Balay } 4662d25893d9SBarry Smith 4663abc0a331SBarry Smith if (snes->conv_hist_reset) snes->conv_hist_len = 0; 46649371c9d4SSatish Balay if (snes->counters_reset) { 46659371c9d4SSatish Balay snes->nfuncs = 0; 46669371c9d4SSatish Balay snes->linear_its = 0; 46679371c9d4SSatish Balay snes->numFailures = 0; 46689371c9d4SSatish Balay } 4669d5e45103SBarry Smith 46709566063dSJacob Faibussowitsch PetscCall(PetscLogEventBegin(SNES_Solve, snes, 0, 0, 0)); 4671dbbe0bcdSBarry Smith PetscUseTypeMethod(snes, solve); 46729566063dSJacob Faibussowitsch PetscCall(PetscLogEventEnd(SNES_Solve, snes, 0, 0, 0)); 46735f80ce2aSJacob Faibussowitsch PetscCheck(snes->reason, PETSC_COMM_SELF, PETSC_ERR_PLIB, "Internal error, solver returned without setting converged reason"); 4674422a814eSBarry Smith snes->domainerror = PETSC_FALSE; /* clear the flag if it has been set */ 46753f149594SLisandro Dalcin 467637ec4e1aSPeter Brune if (snes->lagjac_persist) snes->jac_iter += snes->iter; 467737ec4e1aSPeter Brune if (snes->lagpre_persist) snes->pre_iter += snes->iter; 467837ec4e1aSPeter Brune 46799566063dSJacob Faibussowitsch PetscCall(PetscOptionsGetViewer(PetscObjectComm((PetscObject)snes), ((PetscObject)snes)->options, ((PetscObject)snes)->prefix, "-snes_test_local_min", NULL, NULL, &flg)); 46809566063dSJacob Faibussowitsch if (flg && !PetscPreLoadingOn) PetscCall(SNESTestLocalMin(snes)); 4681c4421ceaSFande Kong /* Call converged reason views. This may involve user-provided viewers as well */ 46829566063dSJacob Faibussowitsch PetscCall(SNESConvergedReasonViewFromOptions(snes)); 46835968eb51SBarry Smith 46845f80ce2aSJacob Faibussowitsch if (snes->errorifnotconverged) PetscCheck(snes->reason >= 0, PetscObjectComm((PetscObject)snes), PETSC_ERR_NOT_CONVERGED, "SNESSolve has not converged"); 46859c8e83a9SBarry Smith if (snes->reason < 0) break; 4686efd51863SBarry Smith if (grid < snes->gridsequence) { 4687efd51863SBarry Smith DM fine; 4688efd51863SBarry Smith Vec xnew; 4689efd51863SBarry Smith Mat interp; 4690efd51863SBarry Smith 46919566063dSJacob Faibussowitsch PetscCall(DMRefine(snes->dm, PetscObjectComm((PetscObject)snes), &fine)); 46925f80ce2aSJacob Faibussowitsch PetscCheck(fine, PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_INCOMP, "DMRefine() did not perform any refinement, cannot continue grid sequencing"); 46939566063dSJacob Faibussowitsch PetscCall(DMCreateInterpolation(snes->dm, fine, &interp, NULL)); 46949566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(fine, &xnew)); 46959566063dSJacob Faibussowitsch PetscCall(MatInterpolate(interp, x, xnew)); 46969566063dSJacob Faibussowitsch PetscCall(DMInterpolate(snes->dm, interp, fine)); 46979566063dSJacob Faibussowitsch PetscCall(MatDestroy(&interp)); 4698efd51863SBarry Smith x = xnew; 4699efd51863SBarry Smith 47009566063dSJacob Faibussowitsch PetscCall(SNESReset(snes)); 47019566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes, fine)); 47029566063dSJacob Faibussowitsch PetscCall(SNESResetFromOptions(snes)); 47039566063dSJacob Faibussowitsch PetscCall(DMDestroy(&fine)); 47049566063dSJacob Faibussowitsch PetscCall(PetscViewerASCIIPopTab(PETSC_VIEWER_STDOUT_(PetscObjectComm((PetscObject)snes)))); 4705efd51863SBarry Smith } 4706efd51863SBarry Smith } 47079566063dSJacob Faibussowitsch PetscCall(SNESViewFromOptions(snes, NULL, "-snes_view")); 47089566063dSJacob Faibussowitsch PetscCall(VecViewFromOptions(snes->vec_sol, (PetscObject)snes, "-snes_view_solution")); 47099566063dSJacob Faibussowitsch PetscCall(DMMonitor(snes->dm)); 47109566063dSJacob Faibussowitsch PetscCall(SNESMonitorPauseFinal_Internal(snes)); 47113f7e2da0SPeter Brune 47129566063dSJacob Faibussowitsch PetscCall(VecDestroy(&xcreated)); 47139566063dSJacob Faibussowitsch PetscCall(PetscObjectSAWsBlock((PetscObject)snes)); 47143ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47159b94acceSBarry Smith } 47169b94acceSBarry Smith 47179b94acceSBarry Smith /* --------- Internal routines for SNES Package --------- */ 47189b94acceSBarry Smith 471982bf6240SBarry Smith /*@C 47204b0e389bSBarry Smith SNESSetType - Sets the method for the nonlinear solver. 47219b94acceSBarry Smith 4722c3339decSBarry Smith Collective 4723fee21e36SBarry Smith 4724c7afd0dbSLois Curfman McInnes Input Parameters: 4725f6dfbefdSBarry Smith + snes - the `SNES` context 4726454a90a3SBarry Smith - type - a known method 4727c7afd0dbSLois Curfman McInnes 4728c7afd0dbSLois Curfman McInnes Options Database Key: 4729454a90a3SBarry Smith . -snes_type <type> - Sets the method; use -help for a list 473004d7464bSBarry Smith of available methods (for instance, newtonls or newtontr) 4731ae12b187SLois Curfman McInnes 4732dc4c0fb0SBarry Smith Level: intermediate 4733dc4c0fb0SBarry Smith 47349b94acceSBarry Smith Notes: 4735e090d566SSatish Balay See "petsc/include/petscsnes.h" for available methods (for instance) 4736f6dfbefdSBarry Smith + `SNESNEWTONLS` - Newton's method with line search 4737c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47384a221d59SStefano Zampini - `SNESNEWTONTR` - Newton's method with trust region 4739c7afd0dbSLois Curfman McInnes (systems of nonlinear equations) 47409b94acceSBarry Smith 4741f6dfbefdSBarry Smith Normally, it is best to use the `SNESSetFromOptions()` command and then 4742f6dfbefdSBarry Smith set the `SNES` solver type from the options database rather than by using 4743ae12b187SLois Curfman McInnes this routine. Using the options database provides the user with 4744ae12b187SLois Curfman McInnes maximum flexibility in evaluating the many nonlinear solvers. 4745f6dfbefdSBarry Smith The `SNESSetType()` routine is provided for those situations where it 4746ae12b187SLois Curfman McInnes is necessary to set the nonlinear solver independently of the command 4747ae12b187SLois Curfman McInnes line or options database. This might be the case, for example, when 4748ae12b187SLois Curfman McInnes the choice of solver changes during the execution of the program, 4749ae12b187SLois Curfman McInnes and the user's application is taking responsibility for choosing the 4750b0a32e0cSBarry Smith appropriate method. 475136851e7fSLois Curfman McInnes 4752f6dfbefdSBarry Smith Developer Note: 4753f6dfbefdSBarry Smith `SNESRegister()` adds a constructor for a new `SNESType` to `SNESList`, `SNESSetType()` locates 4754f6dfbefdSBarry Smith the constructor in that list and calls it to create the specific object. 47558f6c3df8SBarry Smith 4756dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESType`, `SNESCreate()`, `SNESDestroy()`, `SNESGetType()`, `SNESSetFromOptions()` 47579b94acceSBarry Smith @*/ 4758d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetType(SNES snes, SNESType type) 4759d71ae5a4SJacob Faibussowitsch { 4760ace3abfcSBarry Smith PetscBool match; 47615f80ce2aSJacob Faibussowitsch PetscErrorCode (*r)(SNES); 47623a40ed3dSBarry Smith 47633a40ed3dSBarry Smith PetscFunctionBegin; 47640700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 47654482741eSBarry Smith PetscValidCharPointer(type, 2); 476682bf6240SBarry Smith 47679566063dSJacob Faibussowitsch PetscCall(PetscObjectTypeCompare((PetscObject)snes, type, &match)); 47683ba16761SJacob Faibussowitsch if (match) PetscFunctionReturn(PETSC_SUCCESS); 476992ff6ae8SBarry Smith 47709566063dSJacob Faibussowitsch PetscCall(PetscFunctionListFind(SNESList, type, &r)); 47715f80ce2aSJacob Faibussowitsch PetscCheck(r, PETSC_COMM_SELF, PETSC_ERR_ARG_UNKNOWN_TYPE, "Unable to find requested SNES type %s", type); 477275396ef9SLisandro Dalcin /* Destroy the previous private SNES context */ 4773dbbe0bcdSBarry Smith PetscTryTypeMethod(snes, destroy); 477475396ef9SLisandro Dalcin /* Reinitialize function pointers in SNESOps structure */ 47759e5d0892SLisandro Dalcin snes->ops->setup = NULL; 47769e5d0892SLisandro Dalcin snes->ops->solve = NULL; 47779e5d0892SLisandro Dalcin snes->ops->view = NULL; 47789e5d0892SLisandro Dalcin snes->ops->setfromoptions = NULL; 47799e5d0892SLisandro Dalcin snes->ops->destroy = NULL; 47807fe760d5SStefano Zampini 47817fe760d5SStefano Zampini /* It may happen the user has customized the line search before calling SNESSetType */ 47829566063dSJacob Faibussowitsch if (((PetscObject)snes)->type_name) PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 47837fe760d5SStefano Zampini 478475396ef9SLisandro Dalcin /* Call the SNESCreate_XXX routine for this particular Nonlinear solver */ 478575396ef9SLisandro Dalcin snes->setupcalled = PETSC_FALSE; 4786f5af7f23SKarl Rupp 47879566063dSJacob Faibussowitsch PetscCall(PetscObjectChangeTypeName((PetscObject)snes, type)); 47889566063dSJacob Faibussowitsch PetscCall((*r)(snes)); 47893ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 47909b94acceSBarry Smith } 47919b94acceSBarry Smith 47929b94acceSBarry Smith /*@C 4793f6dfbefdSBarry Smith SNESGetType - Gets the `SNES` method type and name (as a string). 47949b94acceSBarry Smith 4795c7afd0dbSLois Curfman McInnes Not Collective 4796c7afd0dbSLois Curfman McInnes 47979b94acceSBarry Smith Input Parameter: 47984b0e389bSBarry Smith . snes - nonlinear solver context 47999b94acceSBarry Smith 48009b94acceSBarry Smith Output Parameter: 4801f6dfbefdSBarry Smith . type - `SNES` method (a character string) 48029b94acceSBarry Smith 480336851e7fSLois Curfman McInnes Level: intermediate 480436851e7fSLois Curfman McInnes 4805dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetType()`, `SNESType`, `SNESSetFromOptions()`, `SNES` 48069b94acceSBarry Smith @*/ 4807d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetType(SNES snes, SNESType *type) 4808d71ae5a4SJacob Faibussowitsch { 48093a40ed3dSBarry Smith PetscFunctionBegin; 48100700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48114482741eSBarry Smith PetscValidPointer(type, 2); 48127adad957SLisandro Dalcin *type = ((PetscObject)snes)->type_name; 48133ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48149b94acceSBarry Smith } 48159b94acceSBarry Smith 48163cd8a7caSMatthew G. Knepley /*@ 4817f6dfbefdSBarry Smith SNESSetSolution - Sets the solution vector for use by the `SNES` routines. 48183cd8a7caSMatthew G. Knepley 4819c3339decSBarry Smith Logically Collective 48203cd8a7caSMatthew G. Knepley 48213cd8a7caSMatthew G. Knepley Input Parameters: 4822f6dfbefdSBarry Smith + snes - the `SNES` context obtained from `SNESCreate()` 48233cd8a7caSMatthew G. Knepley - u - the solution vector 48243cd8a7caSMatthew G. Knepley 48253cd8a7caSMatthew G. Knepley Level: beginner 48263cd8a7caSMatthew G. Knepley 4827dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSolve()`, `SNESGetSolution()`, `Vec` 48283cd8a7caSMatthew G. Knepley @*/ 4829d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetSolution(SNES snes, Vec u) 4830d71ae5a4SJacob Faibussowitsch { 48313cd8a7caSMatthew G. Knepley DM dm; 48323cd8a7caSMatthew G. Knepley 48333cd8a7caSMatthew G. Knepley PetscFunctionBegin; 48343cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48353cd8a7caSMatthew G. Knepley PetscValidHeaderSpecific(u, VEC_CLASSID, 2); 48369566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)u)); 48379566063dSJacob Faibussowitsch PetscCall(VecDestroy(&snes->vec_sol)); 48383cd8a7caSMatthew G. Knepley 48393cd8a7caSMatthew G. Knepley snes->vec_sol = u; 48403cd8a7caSMatthew G. Knepley 48419566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 48429566063dSJacob Faibussowitsch PetscCall(DMShellSetGlobalVector(dm, u)); 48433ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48443cd8a7caSMatthew G. Knepley } 48453cd8a7caSMatthew G. Knepley 484652baeb72SSatish Balay /*@ 48479b94acceSBarry Smith SNESGetSolution - Returns the vector where the approximate solution is 4848f6dfbefdSBarry Smith stored. This is the fine grid solution when using `SNESSetGridSequence()`. 48499b94acceSBarry Smith 4850f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4851c7afd0dbSLois Curfman McInnes 48529b94acceSBarry Smith Input Parameter: 4853f6dfbefdSBarry Smith . snes - the `SNES` context 48549b94acceSBarry Smith 48559b94acceSBarry Smith Output Parameter: 48569b94acceSBarry Smith . x - the solution 48579b94acceSBarry Smith 485870e92668SMatthew Knepley Level: intermediate 485936851e7fSLois Curfman McInnes 4860dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetSolution()`, `SNESSolve()`, `SNES`, `SNESGetSolutionUpdate()`, `SNESGetFunction()` 48619b94acceSBarry Smith @*/ 4862d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolution(SNES snes, Vec *x) 4863d71ae5a4SJacob Faibussowitsch { 48643a40ed3dSBarry Smith PetscFunctionBegin; 48650700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48664482741eSBarry Smith PetscValidPointer(x, 2); 486785385478SLisandro Dalcin *x = snes->vec_sol; 48683ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 486970e92668SMatthew Knepley } 487070e92668SMatthew Knepley 487152baeb72SSatish Balay /*@ 48729b94acceSBarry Smith SNESGetSolutionUpdate - Returns the vector where the solution update is 48739b94acceSBarry Smith stored. 48749b94acceSBarry Smith 4875f6dfbefdSBarry Smith Not Collective, but x is parallel if snes is parallel 4876c7afd0dbSLois Curfman McInnes 48779b94acceSBarry Smith Input Parameter: 4878f6dfbefdSBarry Smith . snes - the `SNES` context 48799b94acceSBarry Smith 48809b94acceSBarry Smith Output Parameter: 48819b94acceSBarry Smith . x - the solution update 48829b94acceSBarry Smith 488336851e7fSLois Curfman McInnes Level: advanced 488436851e7fSLois Curfman McInnes 4885dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESGetSolution()`, `SNESGetFunction()` 48869b94acceSBarry Smith @*/ 4887d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetSolutionUpdate(SNES snes, Vec *x) 4888d71ae5a4SJacob Faibussowitsch { 48893a40ed3dSBarry Smith PetscFunctionBegin; 48900700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 48914482741eSBarry Smith PetscValidPointer(x, 2); 489285385478SLisandro Dalcin *x = snes->vec_sol_update; 48933ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 48949b94acceSBarry Smith } 48959b94acceSBarry Smith 48969b94acceSBarry Smith /*@C 4897f6dfbefdSBarry Smith SNESGetFunction - Returns the function that defines the nonlinear system set with `SNESSetFunction()` 48989b94acceSBarry Smith 4899f6dfbefdSBarry Smith Not Collective, but r is parallel if snes is parallel. Collective if r is requested, but has not been created yet. 4900c7afd0dbSLois Curfman McInnes 49019b94acceSBarry Smith Input Parameter: 4902f6dfbefdSBarry Smith . snes - the `SNES` context 49039b94acceSBarry Smith 4904d8d19677SJose E. Roman Output Parameters: 4905dc4c0fb0SBarry Smith + r - the vector that is used to store residuals (or `NULL` if you don't want it) 490620f4b53cSBarry Smith . f - the function (or `NULL` if you don't want it); for calling sequence see `SNESFunction` 4907dc4c0fb0SBarry Smith - ctx - the function context (or `NULL` if you don't want it) 49089b94acceSBarry Smith 490936851e7fSLois Curfman McInnes Level: advanced 491036851e7fSLois Curfman McInnes 4911f6dfbefdSBarry Smith Note: 4912dc4c0fb0SBarry Smith The vector `r` DOES NOT, in general, contain the current value of the `SNES` nonlinear function 491304edfde5SBarry Smith 4914dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES, `SNESSolve()`, `SNESSetFunction()`, `SNESGetSolution()`, `SNESFunction` 49159b94acceSBarry Smith @*/ 4916d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetFunction(SNES snes, Vec *r, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4917d71ae5a4SJacob Faibussowitsch { 49186cab3a1bSJed Brown DM dm; 4919a63bb30eSJed Brown 49203a40ed3dSBarry Smith PetscFunctionBegin; 49210700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 4922a63bb30eSJed Brown if (r) { 4923a63bb30eSJed Brown if (!snes->vec_func) { 4924a63bb30eSJed Brown if (snes->vec_rhs) { 49259566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_rhs, &snes->vec_func)); 4926a63bb30eSJed Brown } else if (snes->vec_sol) { 49279566063dSJacob Faibussowitsch PetscCall(VecDuplicate(snes->vec_sol, &snes->vec_func)); 4928a63bb30eSJed Brown } else if (snes->dm) { 49299566063dSJacob Faibussowitsch PetscCall(DMCreateGlobalVector(snes->dm, &snes->vec_func)); 4930a63bb30eSJed Brown } 4931a63bb30eSJed Brown } 4932a63bb30eSJed Brown *r = snes->vec_func; 4933a63bb30eSJed Brown } 49349566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49359566063dSJacob Faibussowitsch PetscCall(DMSNESGetFunction(dm, f, ctx)); 49363ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49379b94acceSBarry Smith } 49389b94acceSBarry Smith 4939c79ef259SPeter Brune /*@C 4940f6dfbefdSBarry Smith SNESGetNGS - Returns the `SNESNGS` function and context set with `SNESSetNGS()` 4941c79ef259SPeter Brune 4942c79ef259SPeter Brune Input Parameter: 4943f6dfbefdSBarry Smith . snes - the `SNES` context 4944c79ef259SPeter Brune 4945d8d19677SJose E. Roman Output Parameters: 4946dc4c0fb0SBarry Smith + f - the function (or `NULL`) see `SNESNGSFunction` for details 4947dc4c0fb0SBarry Smith - ctx - the function context (or `NULL`) 4948c79ef259SPeter Brune 4949c79ef259SPeter Brune Level: advanced 4950c79ef259SPeter Brune 4951dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNGS()`, `SNESGetFunction()` 4952c79ef259SPeter Brune @*/ 4953c79ef259SPeter Brune 4954d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNGS(SNES snes, PetscErrorCode (**f)(SNES, Vec, Vec, void *), void **ctx) 4955d71ae5a4SJacob Faibussowitsch { 49566cab3a1bSJed Brown DM dm; 49576cab3a1bSJed Brown 4958646217ecSPeter Brune PetscFunctionBegin; 4959646217ecSPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49609566063dSJacob Faibussowitsch PetscCall(SNESGetDM(snes, &dm)); 49619566063dSJacob Faibussowitsch PetscCall(DMSNESGetNGS(dm, f, ctx)); 49623ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 4963646217ecSPeter Brune } 4964646217ecSPeter Brune 49653c7409f5SSatish Balay /*@C 49663c7409f5SSatish Balay SNESSetOptionsPrefix - Sets the prefix used for searching for all 4967f6dfbefdSBarry Smith `SNES` options in the database. 49683c7409f5SSatish Balay 4969c3339decSBarry Smith Logically Collective 4970fee21e36SBarry Smith 4971d8d19677SJose E. Roman Input Parameters: 4972f6dfbefdSBarry Smith + snes - the `SNES` context 4973c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 4974c7afd0dbSLois Curfman McInnes 4975dc4c0fb0SBarry Smith Level: advanced 4976dc4c0fb0SBarry Smith 4977f6dfbefdSBarry Smith Note: 4978a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 4979c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 4980d850072dSLois Curfman McInnes 4981dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetFromOptions()`, `SNESAppendOptionsPrefix()` 49823c7409f5SSatish Balay @*/ 4983d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetOptionsPrefix(SNES snes, const char prefix[]) 4984d71ae5a4SJacob Faibussowitsch { 49853a40ed3dSBarry Smith PetscFunctionBegin; 49860700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 49879566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes, prefix)); 49889566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 498935f5d045SPeter Brune if (snes->linesearch) { 49909566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 49919566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptionsPrefix((PetscObject)snes->linesearch, prefix)); 499235f5d045SPeter Brune } 49939566063dSJacob Faibussowitsch PetscCall(KSPSetOptionsPrefix(snes->ksp, prefix)); 49943ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 49953c7409f5SSatish Balay } 49963c7409f5SSatish Balay 49973c7409f5SSatish Balay /*@C 4998f525115eSLois Curfman McInnes SNESAppendOptionsPrefix - Appends to the prefix used for searching for all 4999f6dfbefdSBarry Smith `SNES` options in the database. 50003c7409f5SSatish Balay 5001c3339decSBarry Smith Logically Collective 5002fee21e36SBarry Smith 5003c7afd0dbSLois Curfman McInnes Input Parameters: 5004f6dfbefdSBarry Smith + snes - the `SNES` context 5005c7afd0dbSLois Curfman McInnes - prefix - the prefix to prepend to all option names 5006c7afd0dbSLois Curfman McInnes 5007dc4c0fb0SBarry Smith Level: advanced 5008dc4c0fb0SBarry Smith 5009f6dfbefdSBarry Smith Note: 5010a83b1b31SSatish Balay A hyphen (-) must NOT be given at the beginning of the prefix name. 5011c7afd0dbSLois Curfman McInnes The first character of all runtime options is AUTOMATICALLY the hyphen. 5012d850072dSLois Curfman McInnes 5013dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetOptionsPrefix()`, `SNESSetOptionsPrefix()` 50143c7409f5SSatish Balay @*/ 5015d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESAppendOptionsPrefix(SNES snes, const char prefix[]) 5016d71ae5a4SJacob Faibussowitsch { 50173a40ed3dSBarry Smith PetscFunctionBegin; 50180700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50199566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes, prefix)); 50209566063dSJacob Faibussowitsch if (!snes->ksp) PetscCall(SNESGetKSP(snes, &snes->ksp)); 502135f5d045SPeter Brune if (snes->linesearch) { 50229566063dSJacob Faibussowitsch PetscCall(SNESGetLineSearch(snes, &snes->linesearch)); 50239566063dSJacob Faibussowitsch PetscCall(PetscObjectAppendOptionsPrefix((PetscObject)snes->linesearch, prefix)); 502435f5d045SPeter Brune } 50259566063dSJacob Faibussowitsch PetscCall(KSPAppendOptionsPrefix(snes->ksp, prefix)); 50263ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50273c7409f5SSatish Balay } 50283c7409f5SSatish Balay 50299ab63eb5SSatish Balay /*@C 5030f6dfbefdSBarry Smith SNESGetOptionsPrefix - Gets the prefix used for searching for all 5031f6dfbefdSBarry Smith `SNES` options in the database. 50323c7409f5SSatish Balay 5033c7afd0dbSLois Curfman McInnes Not Collective 5034c7afd0dbSLois Curfman McInnes 50353c7409f5SSatish Balay Input Parameter: 5036f6dfbefdSBarry Smith . snes - the `SNES` context 50373c7409f5SSatish Balay 50383c7409f5SSatish Balay Output Parameter: 50393c7409f5SSatish Balay . prefix - pointer to the prefix string used 50403c7409f5SSatish Balay 504136851e7fSLois Curfman McInnes Level: advanced 504236851e7fSLois Curfman McInnes 5043dc4c0fb0SBarry Smith Fortran Note: 5044dc4c0fb0SBarry Smith The user should pass in a string 'prefix' of 5045dc4c0fb0SBarry Smith sufficient length to hold the prefix. 5046dc4c0fb0SBarry Smith 5047dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetOptionsPrefix()`, `SNESAppendOptionsPrefix()` 50483c7409f5SSatish Balay @*/ 5049d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetOptionsPrefix(SNES snes, const char *prefix[]) 5050d71ae5a4SJacob Faibussowitsch { 50513a40ed3dSBarry Smith PetscFunctionBegin; 50520700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 50539566063dSJacob Faibussowitsch PetscCall(PetscObjectGetOptionsPrefix((PetscObject)snes, prefix)); 50543ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 50553c7409f5SSatish Balay } 50563c7409f5SSatish Balay 50573cea93caSBarry Smith /*@C 50581c84c290SBarry Smith SNESRegister - Adds a method to the nonlinear solver package. 50591c84c290SBarry Smith 506020f4b53cSBarry Smith Not Collective 50611c84c290SBarry Smith 50621c84c290SBarry Smith Input Parameters: 506320f4b53cSBarry Smith + sname - name of a new user-defined solver 506420f4b53cSBarry Smith - function - routine to create method context 50651c84c290SBarry Smith 5066dc4c0fb0SBarry Smith Level: advanced 5067dc4c0fb0SBarry Smith 5068f6dfbefdSBarry Smith Note: 5069f6dfbefdSBarry Smith `SNESRegister()` may be called multiple times to add several user-defined solvers. 50701c84c290SBarry Smith 50711c84c290SBarry Smith Sample usage: 50721c84c290SBarry Smith .vb 5073bdf89e91SBarry Smith SNESRegister("my_solver",MySolverCreate); 50741c84c290SBarry Smith .ve 50751c84c290SBarry Smith 50761c84c290SBarry Smith Then, your solver can be chosen with the procedural interface via 50771c84c290SBarry Smith $ SNESSetType(snes,"my_solver") 50781c84c290SBarry Smith or at runtime via the option 50791c84c290SBarry Smith $ -snes_type my_solver 50801c84c290SBarry Smith 5081dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESRegisterAll()`, `SNESRegisterDestroy()` 50823cea93caSBarry Smith @*/ 5083d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESRegister(const char sname[], PetscErrorCode (*function)(SNES)) 5084d71ae5a4SJacob Faibussowitsch { 5085b2002411SLois Curfman McInnes PetscFunctionBegin; 50869566063dSJacob Faibussowitsch PetscCall(SNESInitializePackage()); 50879566063dSJacob Faibussowitsch PetscCall(PetscFunctionListAdd(&SNESList, sname, function)); 50883ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5089b2002411SLois Curfman McInnes } 5090da9b6338SBarry Smith 5091d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESTestLocalMin(SNES snes) 5092d71ae5a4SJacob Faibussowitsch { 509377431f27SBarry Smith PetscInt N, i, j; 5094da9b6338SBarry Smith Vec u, uh, fh; 5095da9b6338SBarry Smith PetscScalar value; 5096da9b6338SBarry Smith PetscReal norm; 5097da9b6338SBarry Smith 5098da9b6338SBarry Smith PetscFunctionBegin; 50999566063dSJacob Faibussowitsch PetscCall(SNESGetSolution(snes, &u)); 51009566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &uh)); 51019566063dSJacob Faibussowitsch PetscCall(VecDuplicate(u, &fh)); 5102da9b6338SBarry Smith 5103da9b6338SBarry Smith /* currently only works for sequential */ 51049566063dSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "Testing FormFunction() for local min\n")); 51059566063dSJacob Faibussowitsch PetscCall(VecGetSize(u, &N)); 5106da9b6338SBarry Smith for (i = 0; i < N; i++) { 51079566063dSJacob Faibussowitsch PetscCall(VecCopy(u, uh)); 510863a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), "i = %" PetscInt_FMT "\n", i)); 5109da9b6338SBarry Smith for (j = -10; j < 11; j++) { 51108b49ba18SBarry Smith value = PetscSign(j) * PetscExpReal(PetscAbs(j) - 10.0); 51119566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 51129566063dSJacob Faibussowitsch PetscCall(SNESComputeFunction(snes, uh, fh)); 51139566063dSJacob Faibussowitsch PetscCall(VecNorm(fh, NORM_2, &norm)); 511463a3b9bcSJacob Faibussowitsch PetscCall(PetscPrintf(PetscObjectComm((PetscObject)snes), " j norm %" PetscInt_FMT " %18.16e\n", j, (double)norm)); 5115da9b6338SBarry Smith value = -value; 51169566063dSJacob Faibussowitsch PetscCall(VecSetValue(uh, i, value, ADD_VALUES)); 5117da9b6338SBarry Smith } 5118da9b6338SBarry Smith } 51199566063dSJacob Faibussowitsch PetscCall(VecDestroy(&uh)); 51209566063dSJacob Faibussowitsch PetscCall(VecDestroy(&fh)); 51213ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5122da9b6338SBarry Smith } 512371f87433Sdalcinl 512471f87433Sdalcinl /*@ 5125f6dfbefdSBarry Smith SNESKSPSetUseEW - Sets `SNES` to the use Eisenstat-Walker method for 512671f87433Sdalcinl computing relative tolerance for linear solvers within an inexact 512771f87433Sdalcinl Newton method. 512871f87433Sdalcinl 5129c3339decSBarry Smith Logically Collective 513071f87433Sdalcinl 513171f87433Sdalcinl Input Parameters: 5132f6dfbefdSBarry Smith + snes - `SNES` context 5133f6dfbefdSBarry Smith - flag - `PETSC_TRUE` or `PETSC_FALSE` 513471f87433Sdalcinl 5135f6dfbefdSBarry Smith Options Database Keys: 513664ba62caSBarry Smith + -snes_ksp_ew - use Eisenstat-Walker method for determining linear system convergence 513764ba62caSBarry Smith . -snes_ksp_ew_version ver - version of Eisenstat-Walker method 513864ba62caSBarry Smith . -snes_ksp_ew_rtol0 <rtol0> - Sets rtol0 513964ba62caSBarry Smith . -snes_ksp_ew_rtolmax <rtolmax> - Sets rtolmax 514064ba62caSBarry Smith . -snes_ksp_ew_gamma <gamma> - Sets gamma 514164ba62caSBarry Smith . -snes_ksp_ew_alpha <alpha> - Sets alpha 514264ba62caSBarry Smith . -snes_ksp_ew_alpha2 <alpha2> - Sets alpha2 514364ba62caSBarry Smith - -snes_ksp_ew_threshold <threshold> - Sets threshold 514464ba62caSBarry Smith 5145dc4c0fb0SBarry Smith Level: advanced 5146dc4c0fb0SBarry Smith 5147f6dfbefdSBarry Smith Note: 5148f6dfbefdSBarry Smith The default is to use a constant relative tolerance for 514971f87433Sdalcinl the inner linear solvers. Alternatively, one can use the 515071f87433Sdalcinl Eisenstat-Walker method, where the relative convergence tolerance 515171f87433Sdalcinl is reset at each Newton iteration according progress of the nonlinear 515271f87433Sdalcinl solver. 515371f87433Sdalcinl 515471f87433Sdalcinl Reference: 5155f6dfbefdSBarry Smith . - * S. C. Eisenstat and H. F. Walker, "Choosing the forcing terms in an inexact Newton method", SISC 17 (1), pp.16-32, 1996. 515671f87433Sdalcinl 5157dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `KSP`, `SNES`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 515871f87433Sdalcinl @*/ 5159d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetUseEW(SNES snes, PetscBool flag) 5160d71ae5a4SJacob Faibussowitsch { 516171f87433Sdalcinl PetscFunctionBegin; 51620700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5163acfcf0e5SJed Brown PetscValidLogicalCollectiveBool(snes, flag, 2); 516471f87433Sdalcinl snes->ksp_ewconv = flag; 51653ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 516671f87433Sdalcinl } 516771f87433Sdalcinl 516871f87433Sdalcinl /*@ 5169f6dfbefdSBarry Smith SNESKSPGetUseEW - Gets if `SNES` is using Eisenstat-Walker method 517071f87433Sdalcinl for computing relative tolerance for linear solvers within an 517171f87433Sdalcinl inexact Newton method. 517271f87433Sdalcinl 517371f87433Sdalcinl Not Collective 517471f87433Sdalcinl 517571f87433Sdalcinl Input Parameter: 5176f6dfbefdSBarry Smith . snes - `SNES` context 517771f87433Sdalcinl 517871f87433Sdalcinl Output Parameter: 5179f6dfbefdSBarry Smith . flag - `PETSC_TRUE` or `PETSC_FALSE` 518071f87433Sdalcinl 518171f87433Sdalcinl Level: advanced 518271f87433Sdalcinl 5183dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESKSPSetUseEW()`, `SNESKSPGetParametersEW()`, `SNESKSPSetParametersEW()` 518471f87433Sdalcinl @*/ 5185d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetUseEW(SNES snes, PetscBool *flag) 5186d71ae5a4SJacob Faibussowitsch { 518771f87433Sdalcinl PetscFunctionBegin; 51880700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5189534a8f05SLisandro Dalcin PetscValidBoolPointer(flag, 2); 519071f87433Sdalcinl *flag = snes->ksp_ewconv; 51913ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 519271f87433Sdalcinl } 519371f87433Sdalcinl 519471f87433Sdalcinl /*@ 5195fa9f3622SBarry Smith SNESKSPSetParametersEW - Sets parameters for Eisenstat-Walker 519671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 519771f87433Sdalcinl Newton method. 519871f87433Sdalcinl 5199c3339decSBarry Smith Logically Collective 520071f87433Sdalcinl 520171f87433Sdalcinl Input Parameters: 5202f6dfbefdSBarry Smith + snes - `SNES` context 52030f0abf79SStefano Zampini . version - version 1, 2 (default is 2), 3 or 4 520471f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 520571f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 520671f87433Sdalcinl . gamma - multiplicative factor for version 2 rtol computation 520771f87433Sdalcinl (0 <= gamma2 <= 1) 520871f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 520971f87433Sdalcinl . alpha2 - power for safeguard 521071f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 521171f87433Sdalcinl 5212dc4c0fb0SBarry Smith Level: advanced 5213dc4c0fb0SBarry Smith 5214f6dfbefdSBarry Smith Notes: 521571f87433Sdalcinl Version 3 was contributed by Luis Chacon, June 2006. 521671f87433Sdalcinl 5217f6dfbefdSBarry Smith Use `PETSC_DEFAULT` to retain the default for any of the parameters. 521871f87433Sdalcinl 5219dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPGetParametersEW()` 522071f87433Sdalcinl @*/ 5221d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPSetParametersEW(SNES snes, PetscInt version, PetscReal rtol_0, PetscReal rtol_max, PetscReal gamma, PetscReal alpha, PetscReal alpha2, PetscReal threshold) 5222d71ae5a4SJacob Faibussowitsch { 5223fa9f3622SBarry Smith SNESKSPEW *kctx; 52245fd66863SKarl Rupp 522571f87433Sdalcinl PetscFunctionBegin; 52260700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5227fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52285f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 5229c5eb9154SBarry Smith PetscValidLogicalCollectiveInt(snes, version, 2); 5230c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_0, 3); 5231c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, rtol_max, 4); 5232c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, gamma, 5); 5233c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha, 6); 5234c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, alpha2, 7); 5235c5eb9154SBarry Smith PetscValidLogicalCollectiveReal(snes, threshold, 8); 523671f87433Sdalcinl 523771f87433Sdalcinl if (version != PETSC_DEFAULT) kctx->version = version; 523813bcc0bdSJacob Faibussowitsch if (rtol_0 != (PetscReal)PETSC_DEFAULT) kctx->rtol_0 = rtol_0; 523913bcc0bdSJacob Faibussowitsch if (rtol_max != (PetscReal)PETSC_DEFAULT) kctx->rtol_max = rtol_max; 524013bcc0bdSJacob Faibussowitsch if (gamma != (PetscReal)PETSC_DEFAULT) kctx->gamma = gamma; 524113bcc0bdSJacob Faibussowitsch if (alpha != (PetscReal)PETSC_DEFAULT) kctx->alpha = alpha; 524213bcc0bdSJacob Faibussowitsch if (alpha2 != (PetscReal)PETSC_DEFAULT) kctx->alpha2 = alpha2; 524313bcc0bdSJacob Faibussowitsch if (threshold != (PetscReal)PETSC_DEFAULT) kctx->threshold = threshold; 524471f87433Sdalcinl 52450f0abf79SStefano 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); 52460b121fc5SBarry 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); 52470b121fc5SBarry 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); 52480b121fc5SBarry 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); 52490b121fc5SBarry 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); 52500b121fc5SBarry 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); 52513ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 525271f87433Sdalcinl } 525371f87433Sdalcinl 525471f87433Sdalcinl /*@ 5255fa9f3622SBarry Smith SNESKSPGetParametersEW - Gets parameters for Eisenstat-Walker 525671f87433Sdalcinl convergence criteria for the linear solvers within an inexact 525771f87433Sdalcinl Newton method. 525871f87433Sdalcinl 525971f87433Sdalcinl Not Collective 526071f87433Sdalcinl 526197bb3fdcSJose E. Roman Input Parameter: 5262f6dfbefdSBarry Smith . snes - `SNES` context 526371f87433Sdalcinl 526471f87433Sdalcinl Output Parameters: 52650f0abf79SStefano Zampini + version - version 1, 2 (default is 2), 3 or 4 526671f87433Sdalcinl . rtol_0 - initial relative tolerance (0 <= rtol_0 < 1) 526771f87433Sdalcinl . rtol_max - maximum relative tolerance (0 <= rtol_max < 1) 5268bf388a1fSBarry Smith . gamma - multiplicative factor for version 2 rtol computation (0 <= gamma2 <= 1) 526971f87433Sdalcinl . alpha - power for version 2 rtol computation (1 < alpha <= 2) 527071f87433Sdalcinl . alpha2 - power for safeguard 527171f87433Sdalcinl - threshold - threshold for imposing safeguard (0 < threshold < 1) 527271f87433Sdalcinl 527371f87433Sdalcinl Level: advanced 527471f87433Sdalcinl 5275dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESKSPSetUseEW()`, `SNESKSPGetUseEW()`, `SNESKSPSetParametersEW()` 527671f87433Sdalcinl @*/ 5277d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESKSPGetParametersEW(SNES snes, PetscInt *version, PetscReal *rtol_0, PetscReal *rtol_max, PetscReal *gamma, PetscReal *alpha, PetscReal *alpha2, PetscReal *threshold) 5278d71ae5a4SJacob Faibussowitsch { 5279fa9f3622SBarry Smith SNESKSPEW *kctx; 52805fd66863SKarl Rupp 528171f87433Sdalcinl PetscFunctionBegin; 52820700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5283fa9f3622SBarry Smith kctx = (SNESKSPEW *)snes->kspconvctx; 52845f80ce2aSJacob Faibussowitsch PetscCheck(kctx, PETSC_COMM_SELF, PETSC_ERR_ARG_WRONGSTATE, "No Eisenstat-Walker context existing"); 528571f87433Sdalcinl if (version) *version = kctx->version; 528671f87433Sdalcinl if (rtol_0) *rtol_0 = kctx->rtol_0; 528771f87433Sdalcinl if (rtol_max) *rtol_max = kctx->rtol_max; 528871f87433Sdalcinl if (gamma) *gamma = kctx->gamma; 528971f87433Sdalcinl if (alpha) *alpha = kctx->alpha; 529071f87433Sdalcinl if (alpha2) *alpha2 = kctx->alpha2; 529171f87433Sdalcinl if (threshold) *threshold = kctx->threshold; 52923ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 529371f87433Sdalcinl } 529471f87433Sdalcinl 5295d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPreSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5296d71ae5a4SJacob Faibussowitsch { 5297fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 529871f87433Sdalcinl PetscReal rtol = PETSC_DEFAULT, stol; 529971f87433Sdalcinl 530071f87433Sdalcinl PetscFunctionBegin; 53013ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 530230058271SDmitry Karpeev if (!snes->iter) { 530330058271SDmitry Karpeev rtol = kctx->rtol_0; /* first time in, so use the original user rtol */ 53049566063dSJacob Faibussowitsch PetscCall(VecNorm(snes->vec_func, NORM_2, &kctx->norm_first)); 53050f0abf79SStefano Zampini } else { 53060fdf79fbSJacob 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); 530771f87433Sdalcinl if (kctx->version == 1) { 53080f0abf79SStefano Zampini rtol = PetscAbsReal(snes->norm - kctx->lresid_last) / kctx->norm_last; 530985ec1a3cSBarry Smith stol = PetscPowReal(kctx->rtol_last, kctx->alpha2); 531071f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 531171f87433Sdalcinl } else if (kctx->version == 2) { 531285ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 531385ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 531471f87433Sdalcinl if (stol > kctx->threshold) rtol = PetscMax(rtol, stol); 531571f87433Sdalcinl } else if (kctx->version == 3) { /* contributed by Luis Chacon, June 2006. */ 531685ec1a3cSBarry Smith rtol = kctx->gamma * PetscPowReal(snes->norm / kctx->norm_last, kctx->alpha); 531771f87433Sdalcinl /* safeguard: avoid sharp decrease of rtol */ 531885ec1a3cSBarry Smith stol = kctx->gamma * PetscPowReal(kctx->rtol_last, kctx->alpha); 531971f87433Sdalcinl stol = PetscMax(rtol, stol); 532071f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 532171f87433Sdalcinl /* safeguard: avoid oversolving */ 532230058271SDmitry Karpeev stol = kctx->gamma * (kctx->norm_first * snes->rtol) / snes->norm; 532371f87433Sdalcinl stol = PetscMax(rtol, stol); 532471f87433Sdalcinl rtol = PetscMin(kctx->rtol_0, stol); 53250fdf79fbSJacob Faibussowitsch } else /* if (kctx->version == 4) */ { 53260fdf79fbSJacob Faibussowitsch /* H.-B. An et al. Journal of Computational and Applied Mathematics 200 (2007) 47-60 */ 53270f0abf79SStefano Zampini PetscReal ared = PetscAbsReal(kctx->norm_last - snes->norm); 53280f0abf79SStefano Zampini PetscReal pred = PetscAbsReal(kctx->norm_last - kctx->lresid_last); 53290f0abf79SStefano Zampini PetscReal rk = ared / pred; 53300f0abf79SStefano Zampini if (rk < kctx->v4_p1) rtol = 1. - 2. * kctx->v4_p1; 53310f0abf79SStefano Zampini else if (rk < kctx->v4_p2) rtol = kctx->rtol_last; 53320f0abf79SStefano Zampini else if (rk < kctx->v4_p3) rtol = kctx->v4_m1 * kctx->rtol_last; 53330f0abf79SStefano Zampini else rtol = kctx->v4_m2 * kctx->rtol_last; 53340f0abf79SStefano Zampini 53359371c9d4SSatish Balay if (kctx->rtol_last_2 > kctx->v4_m3 && kctx->rtol_last > kctx->v4_m3 && kctx->rk_last_2 < kctx->v4_p1 && kctx->rk_last < kctx->v4_p1) { 53360f0abf79SStefano Zampini rtol = kctx->v4_m4 * kctx->rtol_last; 53370f0abf79SStefano Zampini //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g) (AD)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 53380f0abf79SStefano Zampini } else { 53390f0abf79SStefano Zampini //printf("iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g (rk %g ps %g %g %g)\n",snes->iter,kctx->version,(double)rtol,rk,kctx->v4_p1,kctx->v4_p2,kctx->v4_p3); 534071f87433Sdalcinl } 53410f0abf79SStefano Zampini kctx->rtol_last_2 = kctx->rtol_last; 53420f0abf79SStefano Zampini kctx->rk_last_2 = kctx->rk_last; 53430f0abf79SStefano Zampini kctx->rk_last = rk; 53440fdf79fbSJacob Faibussowitsch } 53450f0abf79SStefano Zampini } 53460f0abf79SStefano Zampini /* safeguard: avoid rtol greater than rtol_max */ 534771f87433Sdalcinl rtol = PetscMin(rtol, kctx->rtol_max); 53489566063dSJacob Faibussowitsch PetscCall(KSPSetTolerances(ksp, rtol, PETSC_DEFAULT, PETSC_DEFAULT, PETSC_DEFAULT)); 534963a3b9bcSJacob Faibussowitsch PetscCall(PetscInfo(snes, "iter %" PetscInt_FMT ", Eisenstat-Walker (version %" PetscInt_FMT ") KSP rtol=%g\n", snes->iter, kctx->version, (double)rtol)); 53503ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 535171f87433Sdalcinl } 535271f87433Sdalcinl 5353d71ae5a4SJacob Faibussowitsch PetscErrorCode KSPPostSolve_SNESEW(KSP ksp, Vec b, Vec x, SNES snes) 5354d71ae5a4SJacob Faibussowitsch { 5355fa9f3622SBarry Smith SNESKSPEW *kctx = (SNESKSPEW *)snes->kspconvctx; 535671f87433Sdalcinl PCSide pcside; 535771f87433Sdalcinl Vec lres; 535871f87433Sdalcinl 535971f87433Sdalcinl PetscFunctionBegin; 53603ba16761SJacob Faibussowitsch if (!snes->ksp_ewconv) PetscFunctionReturn(PETSC_SUCCESS); 53619566063dSJacob Faibussowitsch PetscCall(KSPGetTolerances(ksp, &kctx->rtol_last, NULL, NULL, NULL)); 536271dbe336SPeter Brune kctx->norm_last = snes->norm; 53630f0abf79SStefano Zampini if (kctx->version == 1 || kctx->version == 4) { 53644f00ce20SMatthew G. Knepley PC pc; 53650f0abf79SStefano Zampini PetscBool getRes; 53664f00ce20SMatthew G. Knepley 53679566063dSJacob Faibussowitsch PetscCall(KSPGetPC(ksp, &pc)); 53680f0abf79SStefano Zampini PetscCall(PetscObjectTypeCompare((PetscObject)pc, PCNONE, &getRes)); 53690f0abf79SStefano Zampini if (!getRes) { 53700f0abf79SStefano Zampini KSPNormType normtype; 53710f0abf79SStefano Zampini 53720f0abf79SStefano Zampini PetscCall(KSPGetNormType(ksp, &normtype)); 53730f0abf79SStefano Zampini getRes = (PetscBool)(normtype == KSP_NORM_UNPRECONDITIONED); 53740f0abf79SStefano Zampini } 53759566063dSJacob Faibussowitsch PetscCall(KSPGetPCSide(ksp, &pcside)); 53760f0abf79SStefano Zampini if (pcside == PC_RIGHT || getRes) { /* KSP residual is true linear residual */ 53779566063dSJacob Faibussowitsch PetscCall(KSPGetResidualNorm(ksp, &kctx->lresid_last)); 537871f87433Sdalcinl } else { 537971f87433Sdalcinl /* KSP residual is preconditioned residual */ 538071f87433Sdalcinl /* compute true linear residual norm */ 53810f0abf79SStefano Zampini Mat J; 53820f0abf79SStefano Zampini PetscCall(KSPGetOperators(ksp, &J, NULL)); 53839566063dSJacob Faibussowitsch PetscCall(VecDuplicate(b, &lres)); 53840f0abf79SStefano Zampini PetscCall(MatMult(J, x, lres)); 53859566063dSJacob Faibussowitsch PetscCall(VecAYPX(lres, -1.0, b)); 53869566063dSJacob Faibussowitsch PetscCall(VecNorm(lres, NORM_2, &kctx->lresid_last)); 53879566063dSJacob Faibussowitsch PetscCall(VecDestroy(&lres)); 538871f87433Sdalcinl } 538971f87433Sdalcinl } 53903ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 539171f87433Sdalcinl } 539271f87433Sdalcinl 5393d4211eb9SBarry Smith /*@ 5394f6dfbefdSBarry Smith SNESGetKSP - Returns the `KSP` context for a `SNES` solver. 5395d4211eb9SBarry Smith 5396f6dfbefdSBarry Smith Not Collective, but if snes is parallel, then ksp is parallel 5397d4211eb9SBarry Smith 5398d4211eb9SBarry Smith Input Parameter: 5399f6dfbefdSBarry Smith . snes - the `SNES` context 5400d4211eb9SBarry Smith 5401d4211eb9SBarry Smith Output Parameter: 5402f6dfbefdSBarry Smith . ksp - the `KSP` context 5403d4211eb9SBarry Smith 5404dc4c0fb0SBarry Smith Level: beginner 5405dc4c0fb0SBarry Smith 5406d4211eb9SBarry Smith Notes: 5407f6dfbefdSBarry Smith The user can then directly manipulate the `KSP` context to set various 5408d4211eb9SBarry Smith options, etc. Likewise, the user can then extract and manipulate the 5409f6dfbefdSBarry Smith `PC` contexts as well. 5410f6dfbefdSBarry Smith 5411f6dfbefdSBarry Smith Some `SNESType`s do not use a `KSP` but a `KSP` is still returned by this function 5412d4211eb9SBarry Smith 5413dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `KSP`, `PC`, `KSPGetPC()`, `SNESCreate()`, `KSPCreate()`, `SNESSetKSP()` 5414d4211eb9SBarry Smith @*/ 5415d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetKSP(SNES snes, KSP *ksp) 5416d71ae5a4SJacob Faibussowitsch { 541771f87433Sdalcinl PetscFunctionBegin; 5418d4211eb9SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5419d4211eb9SBarry Smith PetscValidPointer(ksp, 2); 5420d4211eb9SBarry Smith 5421d4211eb9SBarry Smith if (!snes->ksp) { 54229566063dSJacob Faibussowitsch PetscCall(KSPCreate(PetscObjectComm((PetscObject)snes), &snes->ksp)); 54239566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->ksp, (PetscObject)snes, 1)); 5424d4211eb9SBarry Smith 54259566063dSJacob Faibussowitsch PetscCall(KSPSetPreSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPreSolve_SNESEW, snes)); 54269566063dSJacob Faibussowitsch PetscCall(KSPSetPostSolve(snes->ksp, (PetscErrorCode(*)(KSP, Vec, Vec, void *))KSPPostSolve_SNESEW, snes)); 5427a5c2985bSBarry Smith 54289566063dSJacob Faibussowitsch PetscCall(KSPMonitorSetFromOptions(snes->ksp, "-snes_monitor_ksp", "snes_preconditioned_residual", snes)); 54299566063dSJacob Faibussowitsch PetscCall(PetscObjectSetOptions((PetscObject)snes->ksp, ((PetscObject)snes)->options)); 5430d4211eb9SBarry Smith } 5431d4211eb9SBarry Smith *ksp = snes->ksp; 54323ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 543371f87433Sdalcinl } 54346c699258SBarry Smith 5435af0996ceSBarry Smith #include <petsc/private/dmimpl.h> 54366c699258SBarry Smith /*@ 5437f6dfbefdSBarry Smith SNESSetDM - Sets the `DM` that may be used by some nonlinear solvers or their underlying preconditioners 54386c699258SBarry Smith 5439c3339decSBarry Smith Logically Collective 54406c699258SBarry Smith 54416c699258SBarry Smith Input Parameters: 54422a808120SBarry Smith + snes - the nonlinear solver context 5443dc4c0fb0SBarry Smith - dm - the dm, cannot be `NULL` 5444dc4c0fb0SBarry Smith 5445dc4c0fb0SBarry Smith Level: intermediate 54466c699258SBarry Smith 5447f6dfbefdSBarry Smith Note: 5448f6dfbefdSBarry Smith A `DM` can only be used for solving one problem at a time because information about the problem is stored on the `DM`, 5449f6dfbefdSBarry Smith even when not using interfaces like `DMSNESSetFunction()`. Use `DMClone()` to get a distinct `DM` when solving different 5450e03a659cSJed Brown problems using the same function space. 5451e03a659cSJed Brown 5452dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `DM`, `SNESGetDM()`, `KSPSetDM()`, `KSPGetDM()` 54536c699258SBarry Smith @*/ 5454d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetDM(SNES snes, DM dm) 5455d71ae5a4SJacob Faibussowitsch { 5456345fed2cSBarry Smith KSP ksp; 5457942e3340SBarry Smith DMSNES sdm; 54586c699258SBarry Smith 54596c699258SBarry Smith PetscFunctionBegin; 54600700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 54612a808120SBarry Smith PetscValidHeaderSpecific(dm, DM_CLASSID, 2); 54629566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)dm)); 5463942e3340SBarry Smith if (snes->dm) { /* Move the DMSNES context over to the new DM unless the new DM already has one */ 546451f4b3c7SToby Isaac if (snes->dm->dmsnes && !dm->dmsnes) { 54659566063dSJacob Faibussowitsch PetscCall(DMCopyDMSNES(snes->dm, dm)); 54669566063dSJacob Faibussowitsch PetscCall(DMGetDMSNES(snes->dm, &sdm)); 5467f5af7f23SKarl Rupp if (sdm->originaldm == snes->dm) sdm->originaldm = dm; /* Grant write privileges to the replacement DM */ 54686cab3a1bSJed Brown } 54699566063dSJacob Faibussowitsch PetscCall(DMCoarsenHookRemove(snes->dm, DMCoarsenHook_SNESVecSol, DMRestrictHook_SNESVecSol, snes)); 54709566063dSJacob Faibussowitsch PetscCall(DMDestroy(&snes->dm)); 54716cab3a1bSJed Brown } 54726c699258SBarry Smith snes->dm = dm; 5473116d1032SJed Brown snes->dmAuto = PETSC_FALSE; 5474f5af7f23SKarl Rupp 54759566063dSJacob Faibussowitsch PetscCall(SNESGetKSP(snes, &ksp)); 54769566063dSJacob Faibussowitsch PetscCall(KSPSetDM(ksp, dm)); 54779566063dSJacob Faibussowitsch PetscCall(KSPSetDMActive(ksp, PETSC_FALSE)); 5478efd4aadfSBarry Smith if (snes->npc) { 54799566063dSJacob Faibussowitsch PetscCall(SNESSetDM(snes->npc, snes->dm)); 54809566063dSJacob Faibussowitsch PetscCall(SNESSetNPCSide(snes, snes->npcside)); 54812c155ee1SBarry Smith } 54823ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 54836c699258SBarry Smith } 54846c699258SBarry Smith 54856c699258SBarry Smith /*@ 5486f6dfbefdSBarry Smith SNESGetDM - Gets the `DM` that may be used by some preconditioners 54876c699258SBarry Smith 5488f6dfbefdSBarry Smith Not Collective but dm obtained is parallel on snes 54896c699258SBarry Smith 54906c699258SBarry Smith Input Parameter: 54916c699258SBarry Smith . snes - the preconditioner context 54926c699258SBarry Smith 54936c699258SBarry Smith Output Parameter: 54946c699258SBarry Smith . dm - the dm 54956c699258SBarry Smith 54966c699258SBarry Smith Level: intermediate 54976c699258SBarry Smith 5498dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `DM`, `SNESSetDM()`, `KSPSetDM()`, `KSPGetDM()` 54996c699258SBarry Smith @*/ 5500d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetDM(SNES snes, DM *dm) 5501d71ae5a4SJacob Faibussowitsch { 55026c699258SBarry Smith PetscFunctionBegin; 55030700a824SBarry Smith PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 55046cab3a1bSJed Brown if (!snes->dm) { 55059566063dSJacob Faibussowitsch PetscCall(DMShellCreate(PetscObjectComm((PetscObject)snes), &snes->dm)); 5506116d1032SJed Brown snes->dmAuto = PETSC_TRUE; 55076cab3a1bSJed Brown } 55086c699258SBarry Smith *dm = snes->dm; 55093ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 55106c699258SBarry Smith } 55110807856dSBarry Smith 551231823bd8SMatthew G Knepley /*@ 5513be95d8f1SBarry Smith SNESSetNPC - Sets the nonlinear preconditioner to be used. 551431823bd8SMatthew G Knepley 5515c3339decSBarry Smith Collective 551631823bd8SMatthew G Knepley 551731823bd8SMatthew G Knepley Input Parameters: 5518f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 5519f6dfbefdSBarry Smith - npc - the preconditioner object 552031823bd8SMatthew G Knepley 5521dc4c0fb0SBarry Smith Level: developer 5522dc4c0fb0SBarry Smith 552331823bd8SMatthew G Knepley Notes: 5524f6dfbefdSBarry Smith Use `SNESGetNPC()` to retrieve the preconditioner context (for example, 552531823bd8SMatthew G Knepley to configure it using the API). 552631823bd8SMatthew G Knepley 5527f6dfbefdSBarry Smith Only some `SNESType` can use a nonlinear preconditioner 5528f6dfbefdSBarry Smith 5529dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESNGS`, `SNESFAS`, `SNESGetNPC()`, `SNESHasNPC()` 553031823bd8SMatthew G Knepley @*/ 5531d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPC(SNES snes, SNES npc) 5532d71ae5a4SJacob Faibussowitsch { 553331823bd8SMatthew G Knepley PetscFunctionBegin; 553431823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5535f6dfbefdSBarry Smith PetscValidHeaderSpecific(npc, SNES_CLASSID, 2); 5536f6dfbefdSBarry Smith PetscCheckSameComm(snes, 1, npc, 2); 5537f6dfbefdSBarry Smith PetscCall(PetscObjectReference((PetscObject)npc)); 55389566063dSJacob Faibussowitsch PetscCall(SNESDestroy(&snes->npc)); 5539f6dfbefdSBarry Smith snes->npc = npc; 55403ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 554131823bd8SMatthew G Knepley } 554231823bd8SMatthew G Knepley 554331823bd8SMatthew G Knepley /*@ 5544f6dfbefdSBarry Smith SNESGetNPC - Gets a nonlinear preconditioning solver SNES` to be used to precondition the original nonlinear solver. 554531823bd8SMatthew G Knepley 5546f6dfbefdSBarry Smith Not Collective; but any changes to the obtained the npc object must be applied collectively 554731823bd8SMatthew G Knepley 554831823bd8SMatthew G Knepley Input Parameter: 5549f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 555031823bd8SMatthew G Knepley 555131823bd8SMatthew G Knepley Output Parameter: 5552f6dfbefdSBarry Smith . npc - preconditioner context 555331823bd8SMatthew G Knepley 5554f6dfbefdSBarry Smith Options Database Key: 5555f6dfbefdSBarry Smith . -npc_snes_type <type> - set the type of the `SNES` to use as the nonlinear preconditioner 5556b5badacbSBarry Smith 5557dc4c0fb0SBarry Smith Level: developer 5558dc4c0fb0SBarry Smith 555995452b02SPatrick Sanan Notes: 5560f6dfbefdSBarry Smith If a `SNES` was previously set with `SNESSetNPC()` then that value is returned, otherwise a new `SNES` object is created. 5561be95d8f1SBarry Smith 5562f6dfbefdSBarry Smith The (preconditioner) `SNES` returned automatically inherits the same nonlinear function and Jacobian supplied to the original 5563f6dfbefdSBarry Smith `SNES` 5564951fe5abSBarry Smith 5565dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNPC()`, `SNESHasNPC()`, `SNES`, `SNESCreate()` 556631823bd8SMatthew G Knepley @*/ 5567d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPC(SNES snes, SNES *pc) 5568d71ae5a4SJacob Faibussowitsch { 5569a64e098fSPeter Brune const char *optionsprefix; 557031823bd8SMatthew G Knepley 557131823bd8SMatthew G Knepley PetscFunctionBegin; 557231823bd8SMatthew G Knepley PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 557331823bd8SMatthew G Knepley PetscValidPointer(pc, 2); 5574efd4aadfSBarry Smith if (!snes->npc) { 55759566063dSJacob Faibussowitsch PetscCall(SNESCreate(PetscObjectComm((PetscObject)snes), &snes->npc)); 55769566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->npc, (PetscObject)snes, 1)); 55779566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 55789566063dSJacob Faibussowitsch PetscCall(SNESSetOptionsPrefix(snes->npc, optionsprefix)); 55799566063dSJacob Faibussowitsch PetscCall(SNESAppendOptionsPrefix(snes->npc, "npc_")); 55809566063dSJacob Faibussowitsch PetscCall(SNESSetCountersReset(snes->npc, PETSC_FALSE)); 558131823bd8SMatthew G Knepley } 5582efd4aadfSBarry Smith *pc = snes->npc; 55833ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 558431823bd8SMatthew G Knepley } 558531823bd8SMatthew G Knepley 55863ad1a0b9SPatrick Farrell /*@ 55873ad1a0b9SPatrick Farrell SNESHasNPC - Returns whether a nonlinear preconditioner exists 55883ad1a0b9SPatrick Farrell 55893ad1a0b9SPatrick Farrell Not Collective 55903ad1a0b9SPatrick Farrell 55913ad1a0b9SPatrick Farrell Input Parameter: 5592f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 55933ad1a0b9SPatrick Farrell 55943ad1a0b9SPatrick Farrell Output Parameter: 5595f6dfbefdSBarry Smith . has_npc - whether the `SNES` has an NPC or not 55963ad1a0b9SPatrick Farrell 55973ad1a0b9SPatrick Farrell Level: developer 55983ad1a0b9SPatrick Farrell 5599dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESSetNPC()`, `SNESGetNPC()` 56003ad1a0b9SPatrick Farrell @*/ 5601d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESHasNPC(SNES snes, PetscBool *has_npc) 5602d71ae5a4SJacob Faibussowitsch { 56033ad1a0b9SPatrick Farrell PetscFunctionBegin; 56043ad1a0b9SPatrick Farrell PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5605efd4aadfSBarry Smith *has_npc = (PetscBool)(snes->npc ? PETSC_TRUE : PETSC_FALSE); 56063ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 56073ad1a0b9SPatrick Farrell } 56083ad1a0b9SPatrick Farrell 5609c40d0f55SPeter Brune /*@ 5610be95d8f1SBarry Smith SNESSetNPCSide - Sets the preconditioning side. 5611c40d0f55SPeter Brune 5612c3339decSBarry Smith Logically Collective 5613c40d0f55SPeter Brune 5614c40d0f55SPeter Brune Input Parameter: 5615f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5616c40d0f55SPeter Brune 5617c40d0f55SPeter Brune Output Parameter: 5618c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5619c40d0f55SPeter Brune .vb 56202d547940SBarry Smith PC_LEFT - left preconditioning 56212d547940SBarry Smith PC_RIGHT - right preconditioning (default for most nonlinear solvers) 5622c40d0f55SPeter Brune .ve 5623c40d0f55SPeter Brune 5624f6dfbefdSBarry Smith Options Database Key: 562567b8a455SSatish Balay . -snes_npc_side <right,left> - nonlinear preconditioner side 5626c40d0f55SPeter Brune 5627dc4c0fb0SBarry Smith Level: intermediate 5628dc4c0fb0SBarry Smith 5629f6dfbefdSBarry Smith Note: 5630f6dfbefdSBarry Smith `SNESNRICHARDSON` and `SNESNCG` only support left preconditioning. 56312d547940SBarry Smith 5632dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESType`, `SNESGetNPCSide()`, `KSPSetPCSide()` 5633c40d0f55SPeter Brune @*/ 5634d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetNPCSide(SNES snes, PCSide side) 5635d71ae5a4SJacob Faibussowitsch { 5636c40d0f55SPeter Brune PetscFunctionBegin; 5637c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5638c40d0f55SPeter Brune PetscValidLogicalCollectiveEnum(snes, side, 2); 5639b552625fSStefano Zampini if (side == PC_SIDE_DEFAULT) side = PC_RIGHT; 564054c59aa7SJacob Faibussowitsch PetscCheck((side == PC_LEFT) || (side == PC_RIGHT), PetscObjectComm((PetscObject)snes), PETSC_ERR_ARG_WRONG, "Only PC_LEFT and PC_RIGHT are supported"); 5641efd4aadfSBarry Smith snes->npcside = side; 56423ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5643c40d0f55SPeter Brune } 5644c40d0f55SPeter Brune 5645c40d0f55SPeter Brune /*@ 5646be95d8f1SBarry Smith SNESGetNPCSide - Gets the preconditioning side. 5647c40d0f55SPeter Brune 5648c40d0f55SPeter Brune Not Collective 5649c40d0f55SPeter Brune 5650c40d0f55SPeter Brune Input Parameter: 5651f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 5652c40d0f55SPeter Brune 5653c40d0f55SPeter Brune Output Parameter: 5654c40d0f55SPeter Brune . side - the preconditioning side, where side is one of 5655c40d0f55SPeter Brune .vb 5656f6dfbefdSBarry Smith `PC_LEFT` - left preconditioning 5657f6dfbefdSBarry Smith `PC_RIGHT` - right preconditioning (default for most nonlinear solvers) 5658c40d0f55SPeter Brune .ve 5659c40d0f55SPeter Brune 5660c40d0f55SPeter Brune Level: intermediate 5661c40d0f55SPeter Brune 5662dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNES`, `SNESSetNPCSide()`, `KSPGetPCSide()` 5663c40d0f55SPeter Brune @*/ 5664d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetNPCSide(SNES snes, PCSide *side) 5665d71ae5a4SJacob Faibussowitsch { 5666c40d0f55SPeter Brune PetscFunctionBegin; 5667c40d0f55SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5668c40d0f55SPeter Brune PetscValidPointer(side, 2); 5669efd4aadfSBarry Smith *side = snes->npcside; 56703ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 5671c40d0f55SPeter Brune } 5672c40d0f55SPeter Brune 56739e764e56SPeter Brune /*@ 5674f6dfbefdSBarry Smith SNESSetLineSearch - Sets the linesearch on the `SNES` instance. 56759e764e56SPeter Brune 5676c3339decSBarry Smith Collective 56779e764e56SPeter Brune 56789e764e56SPeter Brune Input Parameters: 5679f6dfbefdSBarry Smith + snes - iterative context obtained from `SNESCreate()` 56809e764e56SPeter Brune - linesearch - the linesearch object 56819e764e56SPeter Brune 5682dc4c0fb0SBarry Smith Level: developer 5683dc4c0fb0SBarry Smith 5684f6dfbefdSBarry Smith Note: 5685f6dfbefdSBarry Smith Use `SNESGetLineSearch()` to retrieve the preconditioner context (for example, 56869e764e56SPeter Brune to configure it using the API). 56879e764e56SPeter Brune 5688dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESGetLineSearch()` 56899e764e56SPeter Brune @*/ 5690d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESSetLineSearch(SNES snes, SNESLineSearch linesearch) 5691d71ae5a4SJacob Faibussowitsch { 56929e764e56SPeter Brune PetscFunctionBegin; 56939e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 5694f1c6b773SPeter Brune PetscValidHeaderSpecific(linesearch, SNESLINESEARCH_CLASSID, 2); 56959e764e56SPeter Brune PetscCheckSameComm(snes, 1, linesearch, 2); 56969566063dSJacob Faibussowitsch PetscCall(PetscObjectReference((PetscObject)linesearch)); 56979566063dSJacob Faibussowitsch PetscCall(SNESLineSearchDestroy(&snes->linesearch)); 5698f5af7f23SKarl Rupp 56999e764e56SPeter Brune snes->linesearch = linesearch; 5700f5af7f23SKarl Rupp 57013ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57029e764e56SPeter Brune } 57039e764e56SPeter Brune 5704a34ceb2aSJed Brown /*@ 5705dc4c0fb0SBarry Smith SNESGetLineSearch - Returns the line search context set with `SNESSetLineSearch()` 5706f6dfbefdSBarry Smith or creates a default line search instance associated with the `SNES` and returns it. 57079e764e56SPeter Brune 57089e764e56SPeter Brune Not Collective 57099e764e56SPeter Brune 57109e764e56SPeter Brune Input Parameter: 5711f6dfbefdSBarry Smith . snes - iterative context obtained from `SNESCreate()` 57129e764e56SPeter Brune 57139e764e56SPeter Brune Output Parameter: 57149e764e56SPeter Brune . linesearch - linesearch context 57159e764e56SPeter Brune 5716162e0bf5SPeter Brune Level: beginner 57179e764e56SPeter Brune 5718dc4c0fb0SBarry Smith .seealso: [](chapter_snes), `SNESLineSearch`, `SNESSetLineSearch()`, `SNESLineSearchCreate()` 57199e764e56SPeter Brune @*/ 5720d71ae5a4SJacob Faibussowitsch PetscErrorCode SNESGetLineSearch(SNES snes, SNESLineSearch *linesearch) 5721d71ae5a4SJacob Faibussowitsch { 57229e764e56SPeter Brune const char *optionsprefix; 57239e764e56SPeter Brune 57249e764e56SPeter Brune PetscFunctionBegin; 57259e764e56SPeter Brune PetscValidHeaderSpecific(snes, SNES_CLASSID, 1); 57269e764e56SPeter Brune PetscValidPointer(linesearch, 2); 57279e764e56SPeter Brune if (!snes->linesearch) { 57289566063dSJacob Faibussowitsch PetscCall(SNESGetOptionsPrefix(snes, &optionsprefix)); 57299566063dSJacob Faibussowitsch PetscCall(SNESLineSearchCreate(PetscObjectComm((PetscObject)snes), &snes->linesearch)); 57309566063dSJacob Faibussowitsch PetscCall(SNESLineSearchSetSNES(snes->linesearch, snes)); 57319566063dSJacob Faibussowitsch PetscCall(SNESLineSearchAppendOptionsPrefix(snes->linesearch, optionsprefix)); 57329566063dSJacob Faibussowitsch PetscCall(PetscObjectIncrementTabLevel((PetscObject)snes->linesearch, (PetscObject)snes, 1)); 57339e764e56SPeter Brune } 57349e764e56SPeter Brune *linesearch = snes->linesearch; 57353ba16761SJacob Faibussowitsch PetscFunctionReturn(PETSC_SUCCESS); 57369e764e56SPeter Brune } 5737