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