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